On 17/05/2017 07:56 μμ, Alex Rousskov wrote:
On 05/17/2017 10:35 AM, Christos Tsantilas wrote:
+#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
+    X509 * cert = SSL_CTX_get0_certificate(ctx.get());

If it is possible to replace this version check with a ./configure-time
detection of SSL_CTX_get0_certificate() availability, please do that.
Avoiding OPENSSL_VERSION_NUMBER macros in new code may help with future
support for LibreSSL and/or other libraries that lie about OpenSSL API
version they provide.

For the t2 patch I am using the AC_CHECK_LIB autoconf macro to check for the function availability.




    http://bugs.squid-cache.org/show_bug.cgi?id=4662

Agrr... Using the openSSL version was the faster/easier way. Touching autoconf may result to 2-3 full squid rebuilds to implement/test similar fixes.



Thank you,

Alex.

Squid crashes when ServerFirst bumping mode is used with  openSSL-1.1.0 release

When OpenSSL-1.1.0 or later is used:
  - The SQUID_USE_SSLGETCERTIFICATE_HACK configure test is false
  - The SQUID_SSLGETCERTIFICATE_BUGGY configure test is true
  - Squid hits an assert(0) inside Ssl::verifySslCertificate when trying to
    retrieve a generated certificate from cache.

This is a Measurement Factory project

=== modified file 'configure.ac'
--- configure.ac	2017-03-31 18:43:20 +0000
+++ configure.ac	2017-05-18 09:13:03 +0000
@@ -1307,40 +1307,43 @@
       AC_MSG_ERROR([library 'crypto' is required for OpenSSL])
     ],$LIBOPENSSL_LIBS)
     AC_CHECK_LIB(ssl,[SSL_library_init],[LIBOPENSSL_LIBS="-lssl $LIBOPENSSL_LIBS"],[
       AC_MSG_ERROR([library 'ssl' is required for OpenSSL])
     ],$LIBOPENSSL_LIBS)
   ])
 
   # This is a workaround for RedHat 9 brain damage..
   if test -d /usr/kerberos/include -a -f /usr/include/openssl/kssl.h; then
     AC_MSG_NOTICE([OpenSSL depends on Kerberos])
     LIBOPENSSL_LIBS="-L/usr/kerberos/lib $LIBOPENSSL_LIBS"
     CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
   fi
   SQUID_STATE_ROLLBACK(squid_openssl_state) #de-pollute LIBS
 
   if test "x$LIBOPENSSL_LIBS" != "x"; then
     CXXFLAGS="$LIBOPENSSL_CFLAGS $CXXFLAGS"
     SSLLIB="$LIBOPENSSL_PATH $LIBOPENSSL_LIBS $SSLLIB"
     AC_DEFINE(USE_OPENSSL,1,[OpenSSL support is available])
 
+    # check for API functions
+    AC_CHECK_LIB(ssl, SSL_CTX_get0_certificate, [AC_DEFINE(HAVE_SSL_CTX_GET0_CERTIFICATE, 1, [SSL_CTX_get0_certificate is available])], [])
+
     # check for other specific broken implementations
     SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS
     SQUID_CHECK_OPENSSL_CONST_SSL_METHOD
     SQUID_CHECK_OPENSSL_TXTDB
     SQUID_CHECK_OPENSSL_HELLO_OVERWRITE_HACK
   fi
   if test "x$SSLLIB" = "x"; then
     AC_MSG_ERROR([Required OpenSSL library not found])
   fi
 fi
 AC_MSG_NOTICE([OpenSSL library support: ${with_openssl:=no} ${LIBOPENSSL_PATH} ${LIBOPENSSL_LIBS}])
 AM_CONDITIONAL(ENABLE_SSL,[ test "x$with_openssl" = "xyes" ])
 AC_SUBST(SSLLIB)
 
 dnl User may specify MIT Kerberos is needed from a non-standard location
 AC_ARG_WITH(mit-krb5,
   AS_HELP_STRING([--without-mit-krb5],
 		 [Compile without MIT Kerberos support.]), [
 case "$with_mit_krb5" in
   yes|no)

=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc	2017-04-29 16:19:15 +0000
+++ src/ssl/support.cc	2017-05-18 09:15:54 +0000
@@ -969,43 +969,45 @@
     Security::CertPointer cert;
     Ssl::EVP_PKEY_Pointer pkey;
     if (!readCertAndPrivateKeyFromMemory(cert, pkey, data))
         return false;
 
     if (!cert || !pkey)
         return false;
 
     if (!SSL_use_certificate(ssl, cert.get()))
         return false;
 
     if (!SSL_use_PrivateKey(ssl, pkey.get()))
         return false;
 
     return true;
 }
 
 bool
 Ssl::verifySslCertificate(Security::ContextPointer &ctx, CertificateProperties const &properties)
 {
+#if HAVE_SSL_CTX_GET0_CERTIFICATE
+    X509 * cert = SSL_CTX_get0_certificate(ctx.get());
+#elif SQUID_USE_SSLGETCERTIFICATE_HACK
     // SSL_get_certificate is buggy in openssl versions 1.0.1d and 1.0.1e
     // Try to retrieve certificate directly from Security::ContextPointer object
-#if SQUID_USE_SSLGETCERTIFICATE_HACK
     X509 ***pCert = (X509 ***)ctx->cert;
     X509 * cert = pCert && *pCert ? **pCert : NULL;
 #elif SQUID_SSLGETCERTIFICATE_BUGGY
     X509 * cert = NULL;
     assert(0);
 #else
     // Temporary ssl for getting X509 certificate from SSL_CTX.
     Security::SessionPointer ssl(Security::NewSessionObject(ctx));
     X509 * cert = SSL_get_certificate(ssl.get());
 #endif
     if (!cert)
         return false;
     ASN1_TIME * time_notBefore = X509_get_notBefore(cert);
     ASN1_TIME * time_notAfter = X509_get_notAfter(cert);
     bool ret = (X509_cmp_current_time(time_notBefore) < 0 && X509_cmp_current_time(time_notAfter) > 0);
     if (!ret)
         return false;
 
     return certificateMatchesProperties(cert, properties);
 }

_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to