--- kio/kssl/kssl.cc +++ kio/kssl/kssl.cc @@ -129,7 +129,7 @@ return false; if (m_bAutoReconfig) - m_cfg->load(); + m_cfg->load(); if (!m_cfg->tlsv1()) return false; @@ -138,6 +138,8 @@ d->m_meth = d->kossl->TLSv1_client_method(); d->lastInitTLS = true; + m_pi.reset(); + d->m_ctx = d->kossl->SSL_CTX_new(d->m_meth); if (d->m_ctx == 0L) { return false; @@ -172,9 +174,11 @@ m_pi.reset(); - if (m_cfg->sslv2() && !m_cfg->sslv3()) + if (!m_cfg->tlsv1() && !m_cfg->sslv3() && m_cfg->sslv2()) d->m_meth = d->kossl->SSLv2_client_method(); - else if (m_cfg->sslv3() && !m_cfg->sslv2()) + else if (m_cfg->tlsv1() && !m_cfg->sslv3() && !m_cfg->sslv2()) + d->m_meth = d->kossl->TLSv1_client_method(); + else if (!m_cfg->tlsv1() && m_cfg->sslv3() && !m_cfg->sslv2()) d->m_meth = d->kossl->SSLv3_client_method(); else d->m_meth = d->kossl->SSLv23_client_method(); @@ -304,10 +308,15 @@ } */ - if (!d->lastInitTLS) - d->kossl->SSL_set_options(d->m_ssl, SSL_OP_NO_TLSv1); + int off = SSL_OP_ALL; + if (!d->lastInitTLS && !m_cfg->tlsv1()) + off |= SSL_OP_NO_TLSv1; + if (!m_cfg->sslv3()) + off |= SSL_OP_NO_SSLv3; + if (!m_cfg->sslv2()) + off |= SSL_OP_NO_SSLv2; - d->kossl->SSL_set_options(d->m_ssl, SSL_OP_ALL); + d->kossl->SSL_set_options(d->m_ssl, off); rc = d->kossl->SSL_set_fd(d->m_ssl, sock); if (rc == 0) { @@ -390,10 +399,15 @@ } */ - if (!d->lastInitTLS) - d->kossl->SSL_set_options(d->m_ssl, SSL_OP_NO_TLSv1); + int off = SSL_OP_ALL; + if (!d->lastInitTLS && !m_cfg->tlsv1()) + off |= SSL_OP_NO_TLSv1; + if (!m_cfg->sslv3()) + off |= SSL_OP_NO_SSLv3; + if (!m_cfg->sslv2()) + off |= SSL_OP_NO_SSLv2; - d->kossl->SSL_set_options(d->m_ssl, SSL_OP_ALL); + d->kossl->SSL_set_options(d->m_ssl, off); rc = d->kossl->SSL_set_fd(d->m_ssl, sock); if (rc == 0) { @@ -499,6 +513,7 @@ if (err != SSL_ERROR_NONE && err != SSL_ERROR_ZERO_RETURN && err != SSL_ERROR_SYSCALL) { rc = -1; // OpenSSL returns 0 on error too + d->kossl->ERR_print_errors_fp(stderr); } // else if (err == SSL_ERROR_ZERO_RETURN) --- kio/kssl/kopenssl.h +++ kio/kssl/kopenssl.h @@ -882,6 +882,9 @@ /* Set the subject */ int X509_REQ_set_subject_name(X509_REQ*,X509_NAME*); + /* get list of available SSL_CIPHER's sorted by preference */ + STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL* ssl); + #endif private: --- kio/kssl/ksslsettings.cc +++ kio/kssl/ksslsettings.cc @@ -44,9 +44,18 @@ #include #undef crypt #endif - #include +#ifdef KSSL_HAVE_SSL +#define sk_new d->kossl->sk_new +#define sk_push d->kossl->sk_push +#define sk_free d->kossl->sk_free +#define sk_value d->kossl->sk_value +#define sk_num d->kossl->sk_num +#define sk_dup d->kossl->sk_dup +#define sk_pop d->kossl->sk_pop +#endif + class CipherNode { public: CipherNode(const char *_name, int _keylen) : @@ -128,63 +137,54 @@ QString tcipher; bool firstcipher = true; SSL_METHOD *meth = 0L; - QSortedList cipherSort; + QPtrList cipherList; - cipherSort.setAutoDelete(true); + cipherList.setAutoDelete(true); if (!d->kossl) d->kossl = KOSSL::self(); - if (m_bUseSSLv3) { - m_cfg->setGroup("SSLv3"); + if (m_bUseSSLv3 && m_bUseSSLv2) + meth = d->kossl->SSLv23_client_method(); + else if(m_bUseSSLv3) meth = d->kossl->SSLv3_client_method(); - for(int i = 0; ; i++) { - SSL_CIPHER *sc = (meth->get_cipher)(i); - if (!sc) - break; - tcipher.sprintf("cipher_%s", sc->name); - int bits = d->kossl->SSL_CIPHER_get_bits(sc, NULL); - - if (m_cfg->readBoolEntry(tcipher, bits >= 56)) { - CipherNode *xx = new CipherNode(sc->name,bits); - if (!cipherSort.contains(xx)) { - cipherSort.prepend(xx); - } else { - delete xx; - } - } - } - } - - if (m_bUseSSLv2) { - m_cfg->setGroup("SSLv2"); + else if (m_bUseSSLv2) meth = d->kossl->SSLv2_client_method(); - for(int i = 0; meth; i++) { - SSL_CIPHER *sc = (meth->get_cipher)(i); - if (!sc) - break; - tcipher.sprintf("cipher_%s", sc->name); - int bits = d->kossl->SSL_CIPHER_get_bits(sc, NULL); - - if (m_cfg->readBoolEntry(tcipher, bits >= 56)) { - CipherNode *xx = new CipherNode(sc->name,bits); - if (!cipherSort.contains(xx)) { - cipherSort.prepend(xx); - } else { - delete xx; - } - } + SSL_CTX *ctx = d->kossl->SSL_CTX_new(meth); + SSL* ssl = d->kossl->SSL_new(ctx); + STACK_OF(SSL_CIPHER)* sk = d->kossl->SSL_get_ciphers(ssl); + int cnt = sk_SSL_CIPHER_num(sk); + for (int i=0; i< cnt; i++) { + SSL_CIPHER *sc = sk_SSL_CIPHER_value(sk,i); + if (!sc) + break; + + if(!strcmp("SSLv2", d->kossl->SSL_CIPHER_get_version(sc))) + m_cfg->setGroup("SSLv2"); + else + m_cfg->setGroup("SSLv3"); + + tcipher.sprintf("cipher_%s", sc->name); + int bits = d->kossl->SSL_CIPHER_get_bits(sc, NULL); + if (m_cfg->readBoolEntry(tcipher, bits >= 56)) { + CipherNode *xx = new CipherNode(sc->name,bits); + if (!cipherList.contains(xx)) + cipherList.prepend(xx); + else + delete xx; } } + d->kossl->SSL_free(ssl); + d->kossl->SSL_CTX_free(ctx); // Remove any ADH ciphers as per RFC2246 // Also remove NULL ciphers and 168bit ciphers - for (unsigned int i = 0; i < cipherSort.count(); i++) { + for (unsigned int i = 0; i < cipherList.count(); i++) { CipherNode *j = 0L; - while ((j = cipherSort.at(i)) != 0L) { + while ((j = cipherList.at(i)) != 0L) { if (j->name.contains("ADH-") || j->name.contains("NULL-") || j->name.contains("DES-CBC3-SHA") || j->name.contains("FZA")) { - cipherSort.remove(j); + cipherList.remove(j); } else { break; } @@ -192,12 +192,12 @@ } // now assemble the list cipher1:cipher2:cipher3:...:ciphern - while (!cipherSort.isEmpty()) { + while (!cipherList.isEmpty()) { if (firstcipher) firstcipher = false; else clist.append(":"); - clist.append(cipherSort.getLast()->name); - cipherSort.removeLast(); + clist.append(cipherList.getLast()->name); + cipherList.removeLast(); } // while kdDebug(7029) << "Cipher list is: " << clist << endl; @@ -344,3 +344,13 @@ QString& KSSLSettings::getEGDPath() { return d->m_EGDPath; } +#ifdef KSSL_HAVE_SSL +#undef sk_new +#undef sk_push +#undef sk_free +#undef sk_value +#undef sk_num +#undef sk_pop +#undef sk_dup +#endif + --- kio/kssl/kopenssl.cc +++ kio/kssl/kopenssl.cc @@ -20,7 +20,6 @@ #include #endif - #ifdef KSSL_HAVE_SSL #include #endif @@ -197,6 +196,8 @@ static X509_NAME *(*K_X509_NAME_new)() = 0L; 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; + #endif } @@ -567,6 +568,7 @@ K_SSL_set_session = (int (*)(SSL*,SSL_SESSION*)) _sslLib->symbol("SSL_set_session"); K_d2i_SSL_SESSION = (SSL_SESSION* (*)(SSL_SESSION**,unsigned char**, long)) _sslLib->symbol("d2i_SSL_SESSION"); K_i2d_SSL_SESSION = (int (*)(SSL_SESSION*,unsigned char**)) _sslLib->symbol("i2d_SSL_SESSION"); + K_SSL_get_ciphers = (STACK *(*)(const SSL*)) _sslLib->symbol("SSL_get_ciphers"); #endif @@ -1543,5 +1545,10 @@ return 0L; } +STACK_OF(SSL_CIPHER) *KOpenSSLProxy::SSL_get_ciphers(const SSL* ssl) { + if (K_SSL_get_ciphers) return (K_SSL_get_ciphers)(ssl); + return 0L; +} + #endif