diff -bwu -x .svn kdelibssvn-3.5/kio/kssl/kopenssl.cc kdelibs-3.5.6/kio/kssl/kopenssl.cc --- kdelibssvn-3.5/kio/kssl/kopenssl.cc 2008-02-18 15:04:33.000000000 +0200 +++ kdelibs-3.5.6/kio/kssl/kopenssl.cc 2008-02-18 21:43:26.000000000 +0200 @@ -197,7 +197,28 @@ static int (*K_X509_REQ_set_subject_name)(X509_REQ*,X509_NAME*) = 0L; static unsigned char *(*K_ASN1_STRING_data)(ASN1_STRING*) = 0L; static STACK_OF(SSL_CIPHER) *(*K_SSL_get_ciphers)(const SSL *ssl) = 0L; - +//engine handling +static ENGINE *(*K_ENGINE_get_first)(void) = 0L; +static const char *(*K_ENGINE_get_id)(const ENGINE *e)= 0L; +static const char *(*K_ENGINE_get_name)(const ENGINE *e)= 0L; +static ENGINE *(*K_ENGINE_get_next)(ENGINE *e)= 0L; +static int (*K_ENGINE_free)(ENGINE *e)= 0L; + +static void (*K_ENGINE_load_builtin_engines)(void) = 0L; +static ENGINE * (*K_ENGINE_by_id)(const char *id) = 0L; +static int (*K_ENGINE_init)(ENGINE *e) = 0L; +static int (*K_ENGINE_finish)(ENGINE *e) = 0L; +static int (*K_ENGINE_ctrl_cmd_string)(ENGINE *e, const char *cmd_name, + const char *arg,int cmd_optional) = 0L; +static int (*K_ENGINE_ctrl_cmd)(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional) = 0L; +static EVP_PKEY * (*K_ENGINE_load_private_key)(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) = 0L; +static UI_METHOD *(*K_UI_create_method)(char *name) = 0L; +static int (*K_UI_method_set_reader)(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)) = 0L; +static const char *(*K_UI_get0_output_string)(UI_STRING *uis) = 0L; +static int (*K_UI_set_result)(UI *ui, UI_STRING *uis, const char *result) = 0L; +static void * (*K_UI_get_ex_data)(UI *r, int idx) = 0L; #endif } @@ -494,6 +515,29 @@ K_X509_NAME_new = (X509_NAME *(*)()) _cryptoLib->symbol("X509_NAME_new"); K_X509_REQ_set_subject_name = (int (*)(X509_REQ*,X509_NAME*)) _cryptoLib->symbol("X509_REQ_set_subject_name"); K_ASN1_STRING_data = (unsigned char *(*)(ASN1_STRING*)) _cryptoLib->symbol("ASN1_STRING_data"); + + K_ENGINE_get_first = (ENGINE *(*)(void)) _cryptoLib->symbol("ENGINE_get_first"); + K_ENGINE_get_id = (const char *(*)(const ENGINE *e)) _cryptoLib->symbol("ENGINE_get_id"); + K_ENGINE_get_name= (const char *(*)(const ENGINE *e)) _cryptoLib->symbol("ENGINE_get_name"); + K_ENGINE_get_next = (ENGINE *(*)(ENGINE *e)) _cryptoLib->symbol("ENGINE_get_next"); + K_ENGINE_free = (int (*)(ENGINE *e)) _cryptoLib->symbol("ENGINE_free"); + + K_ENGINE_by_id=(ENGINE * (*)(const char *id)) _cryptoLib->symbol("ENGINE_by_id"); + K_ENGINE_init=(int (*)(ENGINE *e)) _cryptoLib->symbol("ENGINE_init"); + K_ENGINE_finish=(int (*)(ENGINE *e)) _cryptoLib->symbol("ENGINE_finish"); + K_ENGINE_ctrl_cmd_string=(int (*)(ENGINE *e, const char *cmd_name, + const char *arg,int cmd_optional)) _cryptoLib->symbol("ENGINE_ctrl_cmd_string"); + K_ENGINE_ctrl_cmd=(int (*)(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional)) _cryptoLib->symbol("ENGINE_ctrl_cmd"); + K_ENGINE_load_private_key=(EVP_PKEY * (*)(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data)) _cryptoLib->symbol("ENGINE_load_private_key"); + K_UI_create_method =(UI_METHOD* (*)(char *name)) _cryptoLib->symbol("UI_create_method"); + K_UI_method_set_reader = (int (*)(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis))) + _cryptoLib->symbol("UI_method_set_reader"); + + K_UI_get0_output_string = (const char *(*)(UI_STRING *uis)) _cryptoLib->symbol("UI_get0_output_string"); + K_UI_set_result = (int (*)(UI *ui, UI_STRING *uis, const char *result)) _cryptoLib->symbol("UI_set_result"); + K_UI_get_ex_data = (void * (*)(UI *r, int idx)) _cryptoLib->symbol("UI_get_ex_data"); #endif } @@ -577,6 +621,11 @@ x = _sslLib->symbol("SSL_library_init"); if (_cryptoLib) { if (x) ((int (*)())x)(); + + //i dont know if this has to be here, my openssl complains about double engine initializations if it is + /*x = _cryptoLib->symbol("OPENSSL_config"); + if (x) ((void (*)(const char*))x)(NULL); */ + x = _cryptoLib->symbol("OpenSSL_add_all_algorithms"); if (!x) x = _cryptoLib->symbol("OPENSSL_add_all_algorithms"); @@ -605,6 +654,16 @@ x = _cryptoLib->symbol("OPENSSL_add_all_digests"); if (x) ((void (*)())x)(); } + + ENGINE *eng = K_ENGINE_get_first(); + while(eng) { + kdDebug(7029) << "initializing engine id '" + << K_ENGINE_get_id(eng) << "' name " << K_ENGINE_get_name(eng) << endl; + int ini = K_ENGINE_init(eng); + kdDebug(7029) << "initresult : " << ini << endl; + eng = K_ENGINE_get_next(eng); + } + K_ENGINE_free(eng); } } @@ -1550,5 +1609,58 @@ return 0L; } + +ENGINE * KOpenSSLProxy::ENGINE_get_first(void) { + if (K_ENGINE_get_first) return K_ENGINE_get_first(); + return 0L; +} + +ENGINE * KOpenSSLProxy::ENGINE_get_next(ENGINE *e) { + if (K_ENGINE_get_next) return K_ENGINE_get_next(e); + return 0L; +} + +int KOpenSSLProxy::ENGINE_free(ENGINE *e) { + if (K_ENGINE_free) return K_ENGINE_free(e); + return -1; +} + +int KOpenSSLProxy::ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional) { + if (K_ENGINE_ctrl_cmd) return K_ENGINE_ctrl_cmd(e,cmd_name,i,p,f,cmd_optional); + return -1; +} + +EVP_PKEY * KOpenSSLProxy::ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) { + if (K_ENGINE_load_private_key) return K_ENGINE_load_private_key(e,key_id,ui_method,callback_data); + return 0L; +} + +UI_METHOD * KOpenSSLProxy::UI_create_method(char *name) { + if (K_UI_create_method) return K_UI_create_method(name); + return 0L; +} + +int KOpenSSLProxy::UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)) { + if (K_UI_method_set_reader) return K_UI_method_set_reader(method,reader); + return -1; +} + +const char * KOpenSSLProxy::UI_get0_output_string(UI_STRING *uis) { + if (K_UI_get0_output_string) return K_UI_get0_output_string(uis); + return 0L; +} + +int KOpenSSLProxy::UI_set_result(UI *ui, UI_STRING *uis, const char *result) { + if (K_UI_set_result) return K_UI_set_result(ui,uis,result); + return -1; +} + +void * KOpenSSLProxy::UI_get_ex_data(UI *r, int idx) { + if (K_UI_get_ex_data) return K_UI_get_ex_data(r,idx); + return 0L; +} + #endif diff -bwu -x .svn kdelibssvn-3.5/kio/kssl/kopenssl.h kdelibs-3.5.6/kio/kssl/kopenssl.h --- kdelibssvn-3.5/kio/kssl/kopenssl.h 2008-02-18 15:04:33.000000000 +0200 +++ kdelibs-3.5.6/kio/kssl/kopenssl.h 2008-02-18 17:50:33.000000000 +0200 @@ -47,6 +47,7 @@ #include #include #include +#include #undef crypt #endif @@ -885,6 +886,22 @@ /* get list of available SSL_CIPHER's sorted by preference */ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL* ssl); + ENGINE * ENGINE_get_first(void); + + ENGINE * ENGINE_get_next(ENGINE *e); + + int ENGINE_free(ENGINE *e); + + int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f)(void), int cmd_optional); + + EVP_PKEY * ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); + UI_METHOD * UI_create_method(char *name); + int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis)); + const char * UI_get0_output_string(UI_STRING *uis); + int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + void * UI_get_ex_data(UI *r, int idx); #endif private: Common subdirectories: kdelibssvn-3.5/kio/kssl/kssl and kdelibs-3.5.6/kio/kssl/kssl diff -bwu -x .svn kdelibssvn-3.5/kio/kssl/ksslcertificatehome.cc kdelibs-3.5.6/kio/kssl/ksslcertificatehome.cc --- kdelibssvn-3.5/kio/kssl/ksslcertificatehome.cc 2008-02-18 15:04:33.000000000 +0200 +++ kdelibs-3.5.6/kio/kssl/ksslcertificatehome.cc 2008-02-18 23:23:22.000000000 +0200 @@ -24,15 +24,61 @@ #include #include +#include using namespace KNetwork; +#define MAX_ENGINE_SLOTS 8 + +#include +#include + +QStringList getEngineCerts() { + QStringList certList; + KOSSL * kossl = KOpenSSLProxy::self(); + + ENGINE *engine = kossl->ENGINE_get_first(); + while(engine) { + int idCount = 1; + for (int slot = 0 ; slot < MAX_ENGINE_SLOTS ; slot++ ) { + QString slotid = "slot_" + QString().setNum(slot) + "-id_" + QString().setNum(idCount) ; + struct { + const char * slot_id; + X509 * cert; + } parms = {slotid,NULL}; + kossl->ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL",0, &parms, NULL, 0); + if (!parms.cert) { idCount = 1 ; continue; } + idCount++; + + KSSLCertificate * _cert = KSSLCertificate::fromX509(parms.cert); //list SSLClient certs only for now + if (!_cert) continue; + QString certName = _cert->getSubject(); + bool isSSLClient = _cert->x509V3Extensions().certTypeSSLClient(); + delete _cert; + + if (!isSSLClient) { + kdDebug(7029) << "cert " << certName << " isnt certTypeSSLClient" << endl; + continue; + } + + certList.append(certName); + } + engine = kossl->ENGINE_get_next(engine); + } + kossl->ENGINE_free(engine); + + return certList; + } + QStringList KSSLCertificateHome::getCertificateList() { + QStringList engineList = getEngineCerts(); + KSimpleConfig cfg("ksslcertificates", false); QStringList list = cfg.groupList(); QString defaultstr(""); QString blankstr(""); + list+= getEngineCerts(); list.remove(defaultstr); list.remove(blankstr); @@ -130,6 +176,10 @@ // KDE 4: make it const QString & KSSLPKCS12* KSSLCertificateHome::getCertificateByName(QString name) { + if (getEngineCerts().contains(name)) { + return KSSLPKCS12::fromEngine(name); + } + KSimpleConfig cfg("ksslcertificates", false); if (!cfg.hasGroup(name)) return NULL; @@ -141,6 +191,8 @@ // KDE 4: make it const QString & bool KSSLCertificateHome::hasCertificateByName(QString name) { + if (getEngineCerts().contains(name)) return true; + KSimpleConfig cfg("ksslcertificates", false); if (!cfg.hasGroup(name)) return false; return true; diff -bwu -x .svn kdelibssvn-3.5/kio/kssl/ksslpkcs12.cc kdelibs-3.5.6/kio/kssl/ksslpkcs12.cc --- kdelibssvn-3.5/kio/kssl/ksslpkcs12.cc 2008-02-18 15:04:33.000000000 +0200 +++ kdelibs-3.5.6/kio/kssl/ksslpkcs12.cc 2008-02-18 23:29:50.000000000 +0200 @@ -44,6 +44,18 @@ #define sk_pop kossl->sk_pop #endif +#include +#include +#include + +#define MAX_ENGINE_SLOTS 8 + +class KSSLPKCS12Private { +public: + KSSLPKCS12Private() : eng(NULL),slot_id("") {} + QString slot_id; + ENGINE *eng; +}; KSSLPKCS12::KSSLPKCS12() { _pkcs = NULL; @@ -51,6 +63,7 @@ _cert = NULL; _caStack = NULL; kossl = KOSSL::self(); + d = new KSSLPKCS12Private(); } @@ -69,8 +82,114 @@ if (_pkcs) kossl->PKCS12_free(_pkcs); #endif if (_cert) delete _cert; + delete d; } +//hack, UI code lifted from slavebase.cpp + +static long s_seqNr = 0; + +bool doPassDlg(KIO::AuthInfo &info) { + QCString replyType; + QByteArray params; + QByteArray reply; + KIO::AuthInfo authResult; + + DCOPClient *dcopClient = KApplication::dcopClient(); + if (!dcopClient->isAttached()) + dcopClient->attach(); + + UIServer_stub uiserver( "kio_uiserver", "UIServer" ); + + QDataStream stream(params, IO_WriteOnly); + + stream << info << QString::null << (long)0 << s_seqNr << (unsigned long)0; + bool callOK = dcopClient->call( "kded", "kpasswdserver", "queryAuthInfo(KIO::AuthInfo, QString, long int, long int, unsigned long int)", + params, replyType, reply ); + if (!callOK) + { + kdWarning(7019) << "Can't communicate with kded_kpasswdserver!" << endl; + return false; + } + if ( replyType == "KIO::AuthInfo" ) + { + QDataStream stream2( reply, IO_ReadOnly ); + stream2 >> authResult >> s_seqNr; + info.password = authResult.password; + } + else + { + kdError(7019) << "DCOP function queryAuthInfo(...) returns " + << replyType << ", expected KIO::AuthInfo" << endl; + return false; + } + return true; +} + +static int my_ui_method_read(UI *ui, UI_STRING *uis) { + KOSSL * kossl = KOpenSSLProxy::self(); + char *ex = (char *) kossl->UI_get_ex_data(ui,0); + const char *prompt = kossl->UI_get0_output_string(uis); + kdDebug(7029) << "prompt :" << prompt << ": ex:" << ex << ":" << endl; + + KIO::AuthInfo ai; + ai.prompt = prompt; + ai.caption = "SSL token password"; + ai.url.setProtocol("kssl"); + ai.url.setHost(ex); + ai.username = ex; + ai.password = ""; + ai.readOnly = true; + ai.keepPassword= false; + if (!doPassDlg(ai)) return 0; + + if (!ai.password.length()) return 0; + kossl->UI_set_result(ui, uis, ai.password); + return 1; +} + + +KSSLPKCS12* KSSLPKCS12::fromEngine(QString name) { + + KSSLPKCS12 *c = NULL; + + KOSSL * kossl = KOpenSSLProxy::self(); + + ENGINE *engine = kossl->ENGINE_get_first(); + while(engine) { + int idCount = 1; //follow incremental numbering for ids + for (int slot = 0 ; slot < MAX_ENGINE_SLOTS ; slot++ ) { + QString slotid = "slot_" + QString().setNum(slot) + "-id_" + QString().setNum(idCount); + struct { + const char * slot_id; + X509 * cert; + } parms = {slotid,NULL}; + kossl->ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL",0, &parms, NULL, 0); + if (!parms.cert) { idCount = 1 ; continue; } + idCount++; + + KSSLCertificate *_cert = KSSLCertificate::fromX509(parms.cert); + if (!_cert) continue; + QString certName = _cert->getSubject(); + //kdDebug(7029) << "slotid: " << slotid << " KSSLPKCS12::getEngineCert '" << certName << "'" << endl; + if (certName != name) {delete _cert;continue;} + + kdDebug(7029) << "KSSLPKCS12::fromEngine, found '" << name << "'" << endl; + + c = new KSSLPKCS12; + c->_cert = _cert; + c->d->eng = engine; + c->d->slot_id = slotid; + c->_pkey = NULL; + return c; + } + engine = kossl->ENGINE_get_next(engine); + } + kossl->ENGINE_free(engine); + + return NULL; + + } KSSLPKCS12* KSSLPKCS12::fromString(QString base64, QString password) { #ifdef KSSL_HAVE_SSL @@ -184,6 +303,18 @@ EVP_PKEY *KSSLPKCS12::getPrivateKey() { + if (!_pkey && d->eng ) { //initialize on first use + UI_METHOD * ui_method = NULL; + ui_method = kossl->UI_create_method("kssl ui meth"); + kossl->UI_method_set_reader(ui_method, my_ui_method_read); + QString certName = _cert->getSubject(); //keep in temp object, we need the pointer + const char *param = certName; + kdDebug(7029) << "doing loadprivkey slotid:'" << d->slot_id << "' certsubj:'" << param << "'" << endl; + _pkey = kossl->ENGINE_load_private_key(d->eng,d->slot_id,ui_method, (void *)param); + if (_pkey) + kdDebug(7029) << "got key!" << endl; + } + return _pkey; } diff -bwu -x .svn kdelibssvn-3.5/kio/kssl/ksslpkcs12.h kdelibs-3.5.6/kio/kssl/ksslpkcs12.h --- kdelibssvn-3.5/kio/kssl/ksslpkcs12.h 2008-02-18 15:04:33.000000000 +0200 +++ kdelibs-3.5.6/kio/kssl/ksslpkcs12.h 2008-02-18 02:19:51.000000000 +0200 @@ -74,6 +74,8 @@ */ QString name(); + static KSSLPKCS12* fromEngine(QString name); + /** * Create a KSSLPKCS12 object from a Base64 in a QString. * @param base64 the base64 encoded certificate