From: Christos Tsantilas Date: Fri, 30 Dec 2016 08:55:40 +0000 (+1300) Subject: Bug 4599 pt5: various OpenSSL-1.x API compatibility fixes X-Git-Tag: M-staged-PR71~329 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a268a0;p=thirdparty%2Fsquid.git Bug 4599 pt5: various OpenSSL-1.x API compatibility fixes --- diff --git a/src/client_side.cc b/src/client_side.cc index 5263a810c9..a9e93ec3b8 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -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(b->ptr); + Ssl::ClientBio *bio = static_cast(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(b->ptr); + Ssl::ClientBio *bio = static_cast(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(b->ptr); + Ssl::ClientBio *bio = static_cast(BIO_get_data(b)); debugs(33, 5, "PeekAndSplice mode, proceed with client negotiation. Currrent state:" << SSL_state_string_long(ssl)); bio->hold(false); diff --git a/src/security/NegotiationHistory.cc b/src/security/NegotiationHistory.cc index 104d061290..f388d1e390 100644 --- a/src/security/NegotiationHistory.cc +++ b/src/security/NegotiationHistory.cc @@ -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(b->ptr); + Ssl::Bio *bio = static_cast(BIO_get_data(b)); debugs(83, 5, "SSL connection info on FD " << bio->fd() << " SSL version " << version_ << " negotiated cipher " << cipherName()); diff --git a/src/security/PeerConnector.cc b/src/security/PeerConnector.cc index 14bbbcd07a..3c77423d38 100644 --- a/src/security/PeerConnector.cc +++ b/src/security/PeerConnector.cc @@ -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(b->ptr); + Ssl::ServerBio *bio = static_cast(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(b->ptr); + Ssl::ServerBio *srvBio = static_cast(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(b->ptr); + Ssl::ServerBio *srvBio = static_cast(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(b->ptr); + Ssl::ServerBio *srvBio = static_cast(BIO_get_data(b)); const Security::CertList &certs = srvBio->serverCertificatesIfAny(); if (certs.size()) { diff --git a/src/ssl/bio.cc b/src/ssl/bio.cc index dac9d26deb..3975a18681 100644 --- a/src/ssl/bio.cc +++ b/src/ssl/bio.cc @@ -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; } diff --git a/src/ssl/gadgets.cc b/src/ssl/gadgets.cc index 6d4baa5968..c753905279 100644 --- a/src/ssl/gadgets.cc +++ b/src/ssl/gadgets.cc @@ -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) diff --git a/src/ssl/support.cc b/src/ssl/support.cc index 17cb7f8fb7..09c1dd0e36 100644 --- a/src/ssl/support.cc +++ b/src/ssl/support.cc @@ -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(ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)), sizeof(uri)); + xstrncpy(uri, + reinterpret_cast( +#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; diff --git a/src/tunnel.cc b/src/tunnel.cc index 6f8931b2ef..abece760fe 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -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(b->ptr); + Ssl::ServerBio *srvBio = static_cast(BIO_get_data(b)); tunnelState->preReadServerData = srvBio->rBufData(); tunnelStartShoveling(tunnelState); }