]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 4599 pt5: various OpenSSL-1.x API compatibility fixes
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Fri, 30 Dec 2016 08:55:40 +0000 (21:55 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Fri, 30 Dec 2016 08:55:40 +0000 (21:55 +1300)
src/client_side.cc
src/security/NegotiationHistory.cc
src/security/PeerConnector.cc
src/ssl/bio.cc
src/ssl/gadgets.cc
src/ssl/support.cc
src/tunnel.cc

index 5263a810c9a5524fc062accf9cfdd41ba68d4141..a9e93ec3b82d4e7c0dd8baa7705d85d9a90313e5 100644 (file)
@@ -3074,7 +3074,7 @@ ConnStateData::getSslContextDone(Security::ContextPointer &ctx, bool isNew)
 
     auto ssl = fd_table[clientConnection->fd].ssl.get();
     BIO *b = SSL_get_rbio(ssl);
-    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(b->ptr);
+    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(BIO_get_data(b));
     bio->setReadBufData(inBuf);
     inBuf.clear();
     clientNegotiateSSL(clientConnection->fd, this);
@@ -3267,7 +3267,7 @@ ConnStateData::startPeekAndSplice()
 
     auto ssl = fd_table[clientConnection->fd].ssl.get();
     BIO *b = SSL_get_rbio(ssl);
-    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(b->ptr);
+    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(BIO_get_data(b));
     bio->setReadBufData(inBuf);
     bio->hold(true);
 
@@ -3298,7 +3298,7 @@ ConnStateData::doPeekAndSpliceStep()
     auto ssl = fd_table[clientConnection->fd].ssl.get();
     BIO *b = SSL_get_rbio(ssl);
     assert(b);
-    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(b->ptr);
+    Ssl::ClientBio *bio = static_cast<Ssl::ClientBio *>(BIO_get_data(b));
 
     debugs(33, 5, "PeekAndSplice mode, proceed with client negotiation. Currrent state:" << SSL_state_string_long(ssl));
     bio->hold(false);
index 104d061290145045a3ad3b8b3a56311c5594a2bf..f388d1e3907ed5f417379fccc95d211c5e5ae390 100644 (file)
@@ -72,12 +72,12 @@ Security::NegotiationHistory::retrieveNegotiatedInfo(const Security::SessionPoin
         // Set the negotiated version only if the cipher negotiated
         // else probably the negotiation is not completed and version
         // is not the final negotiated version
-        version_ = toProtocolVersion(session->version);
+        version_ = toProtocolVersion(SSL_version(session.get()));
     }
 
     if (Debug::Enabled(83, 5)) {
         BIO *b = SSL_get_rbio(session.get());
-        Ssl::Bio *bio = static_cast<Ssl::Bio *>(b->ptr);
+        Ssl::Bio *bio = static_cast<Ssl::Bio *>(BIO_get_data(b));
         debugs(83, 5, "SSL connection info on FD " << bio->fd() <<
                " SSL version " << version_ <<
                " negotiated cipher " << cipherName());
index 14bbbcd07a04185ca401a45dc86c855a70857dd6..3c77423d384861aa86b7b27706b042b50f279f02 100644 (file)
@@ -162,7 +162,7 @@ Security::PeerConnector::recordNegotiationDetails()
 #if USE_OPENSSL
     // retrieve TLS parsed extra info
     BIO *b = SSL_get_rbio(session.get());
-    Ssl::ServerBio *bio = static_cast<Ssl::ServerBio *>(b->ptr);
+    Ssl::ServerBio *bio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     if (const Security::TlsDetails::Pointer &details = bio->receivedHelloDetails())
         serverConnection()->tlsNegotiations()->retrieveParsedInfo(details);
 #endif
@@ -398,7 +398,7 @@ Security::PeerConnector::noteWantRead()
 #if USE_OPENSSL
     Security::SessionPointer session(fd_table[fd].ssl);
     BIO *b = SSL_get_rbio(session.get());
-    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     if (srvBio->holdRead()) {
         if (srvBio->gotHello()) {
             if (checkForMissingCertificates())
@@ -587,7 +587,7 @@ Security::PeerConnector::certDownloadingDone(SBuf &obj, int downloadStatus)
     const int fd = serverConnection()->fd;
     Security::SessionPointer session(fd_table[fd].ssl);
     BIO *b = SSL_get_rbio(session.get());
-    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
 
     // Parse Certificate. Assume that it is in DER format.
     // According to RFC 4325:
@@ -633,7 +633,7 @@ Security::PeerConnector::checkForMissingCertificates()
     const int fd = serverConnection()->fd;
     Security::SessionPointer session(fd_table[fd].ssl);
     BIO *b = SSL_get_rbio(session.get());
-    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     const Security::CertList &certs = srvBio->serverCertificatesIfAny();
 
     if (certs.size()) {
index dac9d26debe1653e488f95c14987ed7b9e9ab5a6..3975a18681fa3af82abd79d90b2a58f7681069d7 100644 (file)
@@ -65,10 +65,7 @@ BIO *
 Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
 {
 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
-    if (BIO *bio = BIO_new(&SquidMethods)) {
-        BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
-        return bio;
-    }
+    BIO_METHOD *useMethod = &SquidMethods;
 #else
     if (!SquidMethods) {
         SquidMethods = BIO_meth_new(BIO_TYPE_SOCKET, "squid");
@@ -80,7 +77,13 @@ Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
         BIO_meth_set_create(SquidMethods, squid_bio_create);
         BIO_meth_set_destroy(SquidMethods, squid_bio_destroy);
     }
+    const BIO_METHOD *useMethod = SquidMethods;
 #endif
+    
+    if (BIO *bio = BIO_new(useMethod)) {
+        BIO_int_ctrl(bio, BIO_C_SET_FD, type, fd);
+        return bio;
+    }
     return NULL;
 }
 
index 6d4baa5968924b01acbb7bcfb9da7fa9fa8a84c9..c753905279fd2211a2d6e6f68ec92fbbddf6c305 100644 (file)
@@ -20,7 +20,20 @@ EVP_PKEY * Ssl::createSslPrivateKey()
     if (!pkey)
         return NULL;
 
-    Ssl::RSA_Pointer rsa(RSA_generate_key(1024, RSA_F4, NULL, NULL));
+    BIGNUM_Pointer bn(BN_new());
+    if (!bn)
+        return NULL;
+
+    if (!BN_set_word(bn.get(), RSA_F4))
+        return NULL;
+
+    Ssl::RSA_Pointer rsa(RSA_new());
+    if (!rsa)
+        return NULL;
+    
+    int num = 2048; // Maybe use 4096 RSA keys, or better make it configurable?
+    if (!RSA_generate_key_ex(rsa.get(), num, bn.get(), NULL))
+        return NULL;
 
     if (!rsa)
         return NULL;
@@ -301,7 +314,7 @@ mimicAuthorityKeyId(Security::CertPointer &cert, Security::CertPointer const &mi
     Ssl::ASN1_INT_Pointer issuerSerial;
     if (issuerKeyId.get() == nullptr || addIssuer) {
         issuerName.reset(X509_NAME_dup(X509_get_issuer_name(issuerCert.get())));
-        issuerSerial.reset(M_ASN1_INTEGER_dup(X509_get_serialNumber(issuerCert.get())));
+        issuerSerial.reset(ASN1_INTEGER_dup(X509_get_serialNumber(issuerCert.get())));
     }
 
     Ssl::AUTHORITY_KEYID_Pointer theAuthKeyId(AUTHORITY_KEYID_new());
@@ -332,7 +345,7 @@ mimicAuthorityKeyId(Security::CertPointer &cert, Security::CertPointer const &mi
 
     unsigned char *ext_der = NULL;
     int ext_len = ASN1_item_i2d((ASN1_VALUE *)theAuthKeyId.get(), &ext_der, ASN1_ITEM_ptr(method->it));
-    Ssl::ASN1_OCTET_STRING_Pointer extOct(M_ASN1_OCTET_STRING_new());
+    Ssl::ASN1_OCTET_STRING_Pointer extOct(ASN1_OCTET_STRING_new());
     extOct.get()->data = ext_der;
     extOct.get()->length = ext_len;
     Ssl::X509_EXTENSION_Pointer extAuthKeyId(X509_EXTENSION_create_by_NID(NULL, NID_authority_key_identifier, 0, extOct.get()));
@@ -374,7 +387,14 @@ mimicExtensions(Security::CertPointer & cert, Security::CertPointer const &mimic
         DecipherOnly
     };
 
-    int mimicAlgo = OBJ_obj2nid(mimicCert.get()->cert_info->key->algor->algorithm);
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+    const int mimicAlgo = OBJ_obj2nid(mimicCert.get()->cert_info->key->algor->algorithm);
+    const bool rsaPkey = (mimicAlgo == NID_rsaEncryption);
+#else
+    EVP_PKEY *certKey = X509_get_pubkey(mimicCert.get());
+    const bool rsaPkey = (EVP_PKEY_get0_RSA(certKey) != NULL);
+#endif
+
 
     int added = 0;
     int nid;
@@ -384,7 +404,7 @@ mimicExtensions(Security::CertPointer & cert, Security::CertPointer const &mimic
             // Mimic extension exactly.
             if (X509_add_ext(cert.get(), ext, -1))
                 ++added;
-            if ( nid == NID_key_usage && mimicAlgo != NID_rsaEncryption ) {
+            if (nid == NID_key_usage && !rsaPkey) {
                 // NSS does not requre the KeyEncipherment flag on EC keys
                 // but it does require it for RSA keys.  Since ssl-bump
                 // substitutes RSA keys for EC ones, we need to ensure that
@@ -403,12 +423,12 @@ mimicExtensions(Security::CertPointer & cert, Security::CertPointer const &mimic
                                                 &ext_der,
                                                 (const ASN1_ITEM *)ASN1_ITEM_ptr(method->it));
 
-                    ASN1_OCTET_STRING *ext_oct = M_ASN1_OCTET_STRING_new();
+                    ASN1_OCTET_STRING *ext_oct = ASN1_OCTET_STRING_new();
                     ext_oct->data = ext_der;
                     ext_oct->length = ext_len;
                     X509_EXTENSION_set_data(ext, ext_oct);
 
-                    M_ASN1_OCTET_STRING_free(ext_oct);
+                    ASN1_OCTET_STRING_free(ext_oct);
                     ASN1_BIT_STRING_free(keyusage);
                 }
             }
@@ -797,7 +817,7 @@ bool Ssl::certificateMatchesProperties(X509 *cert, CertificateProperties const &
     if (cert1_altnames) {
         int numalts = sk_GENERAL_NAME_num(cert1_altnames);
         for (int i = 0; match && i < numalts; ++i) {
-            const GENERAL_NAME *aName = sk_GENERAL_NAME_value(cert1_altnames, i);
+            GENERAL_NAME *aName = sk_GENERAL_NAME_value(cert1_altnames, i);
             match = sk_GENERAL_NAME_find(cert2_altnames, aName);
         }
     } else if (cert2_altnames)
index 17cb7f8fb74ed1925d6a80b25ec93d0ef96c4faa..09c1dd0e3610a6af8e07547c41013ac52f07aa21 100644 (file)
@@ -235,12 +235,19 @@ bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
     return matchX509CommonNames(cert, (void *)server, check_domain);
 }
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+static inline X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
+{
+    return ctx->cert;
+}
+#endif
+
 /// \ingroup ServerProtocolSSLInternal
 static int
 ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 {
     // preserve original ctx->error before SSL_ calls can overwrite it
-    Security::ErrorCode error_no = ok ? SSL_ERROR_NONE : ctx->error;
+    Security::ErrorCode error_no = ok ? SSL_ERROR_NONE : X509_STORE_CTX_get_error(ctx);
 
     char buffer[256] = "";
     SSL *ssl = (SSL *)X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
@@ -250,7 +257,7 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     ACLChecklist *check = (ACLChecklist*)SSL_get_ex_data(ssl, ssl_ex_index_cert_error_check);
     X509 *peeked_cert = (X509 *)SSL_get_ex_data(ssl, ssl_ex_index_ssl_peeked_cert);
     Security::CertPointer peer_cert;
-    peer_cert.resetAndLock(ctx->cert);
+    peer_cert.resetAndLock(X509_STORE_CTX_get0_cert(ctx));
 
     X509_NAME_oneline(X509_get_subject_name(peer_cert.get()), buffer, sizeof(buffer));
 
@@ -372,9 +379,15 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 }
 
 // "dup" function for SSL_get_ex_new_index("cert_err_check")
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+static int
+ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
+                    int, long, void *)
+#else
 static int
 ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
                     int, long, void *)
+#endif
 {
     // We do not support duplication of ACLCheckLists.
     // If duplication is needed, we can count copies with cbdata.
@@ -1121,7 +1134,15 @@ hasAuthorityInfoAccessCaIssuers(X509 *cert)
         ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
         if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
             if (ad->location->type == GEN_URI) {
-                xstrncpy(uri, reinterpret_cast<char *>(ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)), sizeof(uri));
+                xstrncpy(uri,
+                         reinterpret_cast<const char *>(
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+                             ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)
+#else
+                             ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier)
+#endif
+                             ),
+                         sizeof(uri));
             }
             break;
         }
@@ -1250,8 +1271,13 @@ completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) *untrustedCerts)
 {
     debugs(83, 2,  "completing " << sk_X509_num(untrustedCerts) << " OpenSSL untrusted certs using " << SquidUntrustedCerts.size() << " configured untrusted certificates");
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
     int depth = ctx->param->depth;
-    X509 *current = ctx->cert;
+#else
+    const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
+    int depth = X509_VERIFY_PARAM_get_depth(param);
+#endif
+    X509 *current = X509_STORE_CTX_get0_cert(ctx);
     int i = 0;
     for (i = 0; current && (i < depth); ++i) {
         if (X509_check_issued(current, current)) {
@@ -1285,7 +1311,11 @@ untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data)
     // OpenSSL already maintains ctx->untrusted but we cannot modify
     // internal OpenSSL list directly. We have to give OpenSSL our own
     // list, but it must include certificates on the OpenSSL ctx->untrusted
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
     STACK_OF(X509) *oldUntrusted = ctx->untrusted;
+#else
+    STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
+#endif
     STACK_OF(X509) *sk = sk_X509_dup(oldUntrusted); // oldUntrusted is always not NULL
 
     for (int i = 0; i < sk_X509_num(sslUntrustedStack); ++i) {
@@ -1300,7 +1330,11 @@ untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data)
 
     X509_STORE_CTX_set_chain(ctx, sk); // No locking/unlocking, just sets ctx->untrusted
     int ret = X509_verify_cert(ctx);
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
     X509_STORE_CTX_set_chain(ctx, oldUntrusted); // Set back the old untrusted list
+#else
+    X509_STORE_CTX_set0_untrusted(ctx, oldUntrusted);
+#endif
     sk_X509_free(sk); // Release sk list
     return ret;
 }
@@ -1472,8 +1506,13 @@ store_session_cb(SSL *ssl, SSL_SESSION *session)
 
     SSL_SESSION_set_timeout(session, Config.SSL.session_ttl);
 
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
     unsigned char *id = session->session_id;
     unsigned int idlen = session->session_id_length;
+#else
+    unsigned int idlen;
+    const unsigned char *id = SSL_SESSION_get_id(session, &idlen);
+#endif
     unsigned char key[MEMMAP_SLOT_KEY_SIZE];
     // Session ids are of size 32bytes. They should always fit to a
     // MemMap::Slot::key
@@ -1516,7 +1555,11 @@ remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID)
 }
 
 static SSL_SESSION *
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
 get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy)
+#else
+get_session_cb(SSL *, const unsigned char *sessionID, int len, int *copy)
+#endif
 {
     if (!Ssl::SessionCache)
         return NULL;
index 6f8931b2ef2fa73813485075162e6d739f3ca120..abece760fe381b0a3cdd362f959d0ad1e72a690e 100644 (file)
@@ -1314,7 +1314,7 @@ switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm::
     auto ssl = fd_table[srvConn->fd].ssl.get();
     assert(ssl);
     BIO *b = SSL_get_rbio(ssl);
-    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+    Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     tunnelState->preReadServerData = srvBio->rBufData();
     tunnelStartShoveling(tunnelState);
 }