On Wed, Mar 18, 2020 at 07:20:00AM +0100, Rafael Sadowski wrote:
> On Tue Mar 17, 2020 at 06:09:20PM +0100, Theo Buehler wrote:
> > X509_getm_notBefore(), aka the gift that keeps on giving...
> > 
> > jca pointed out to me that kde/libs failed to build on ld.bfd
> > architectures due to a linking error in libkio [1]:
> > 
> > /usr/obj/ports/kdelibs-4.14.10/build-sparc64/lib/libkio.so.50.3: undefined 
> > reference to `X509_getm_notBefore'
> > /usr/obj/ports/kdelibs-4.14.10/build-sparc64/lib/libkio.so.50.3: undefined 
> > reference to `X509_getm_notAfter'
> > 
> > This started happening after I fixed a qt4 SSL-related runtime failure
> > that rsadowski@ showed me during p2k19.
> > 
> > Before that fix, it linked, but only by accident. This was defintely
> > broken on all architectures since August 2018.
> > 
> > This is what happened (the notAfter case is the same):
> > 
> > X509_get_notBefore(x) used to be a macro that reached inside the X509 x.
> > In OpenSSL, this macro was replaced with a function,
> > X509_getm_notBefore(), and openssl/x509.h now contains
> > 
> > #define X509_get_notBefore      X509_getm_notBefore
> > 
> > so when an linking a program that uses X509_get_notBefore() this means
> > ld.bfd will look up X509_getm_notBefore().
> > 
> > When trying to adapt the Qt4 openssl symbols sausage factory to this, I
> > accidentally exposed a bogus symbol X509_getm_notBefore() in QtNetwork,
> > which was enough to make ld.bfd happy.  The Qt symbol lookup madness got
> > rightfully confused by this, and this led to the segfault rsadowski
> > showed me. The Qt4 side was fixed last November (although there should
> > have been a major bump for QtNetwork and some other Qt libraries).
> > 
> > The diff below fixes libkio by adding a symbol lookup similar to other
> > libcrypto symbols and using it in ksslcertificate.cpp in place of the
> > macro. Note that this is internal only, so no library bump required.
> > 
> > check_sym shows the expected removal of the two external references to
> > X509_getm_notBefore and X509_getm_notAfter for libkio.
> > 
> > I have build tested this on amd64 and sparc64.
> 
> With some meaningful comments in the new patches, ok with me but please
> wait for jca@' feedback. Thanks tb

Thanks. I added comments to the patches and fixed a copy-paste error in
a code comment for kio/kssl/kopenssl.h.

Index: Makefile
===================================================================
RCS file: /var/cvs/ports/x11/kde4/libs/Makefile,v
retrieving revision 1.93
diff -u -p -r1.93 Makefile
--- Makefile    23 Nov 2019 15:25:31 -0000      1.93
+++ Makefile    18 Mar 2020 07:18:08 -0000
@@ -12,7 +12,7 @@ PKGNAME-langlist =    kde4-langlist-$V
 PKG_ARCH-en_US =       *
 PKG_ARCH-langlist =    *
 PKGSPEC-main =         kdelibs-${MODKDE4_SPEC}
-REVISION-main =                19
+REVISION-main =                20
 REVISION-en_US =       0
 REVISION-langlist =    0
 
Index: patches/patch-kio_kssl_kopenssl_cpp
===================================================================
RCS file: patches/patch-kio_kssl_kopenssl_cpp
diff -N patches/patch-kio_kssl_kopenssl_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-kio_kssl_kopenssl_cpp 18 Mar 2020 07:09:42 -0000
@@ -0,0 +1,46 @@
+$OpenBSD$
+
+Resolve X509_getm_notBefore() and X509_getm_notAfter() at runtime
+to fix use of X509_get_notBefore() and X509_get_notAfter() in
+kio/kssl/ksslcertificate.cpp after openssl/x509.h rev 1.70.
+
+Index: kio/kssl/kopenssl.cpp
+--- kio/kssl/kopenssl.cpp.orig
++++ kio/kssl/kopenssl.cpp
+@@ -80,6 +80,8 @@ static void (*K_X509_free) (X509 *) = 0L;
+ static char *(*K_X509_NAME_oneline) (X509_NAME *,char *,int) = 0L;
+ static X509_NAME *(*K_X509_get_subject_name) (X509 *) = 0L;
+ static X509_NAME *(*K_X509_get_issuer_name) (X509 *) = 0L;
++static ASN1_TIME *(*K_X509_getm_notBefore) (const X509 *) = 0L;
++static ASN1_TIME *(*K_X509_getm_notAfter) (const X509 *) = 0L;
+ static X509_LOOKUP *(*K_X509_STORE_add_lookup) (X509_STORE *, 
X509_LOOKUP_METHOD *) = 0L;
+ static X509_LOOKUP_METHOD *(*K_X509_LOOKUP_file)(void) = 0L;
+ static void (*K_X509_LOOKUP_free)(X509_LOOKUP *) = 0L;
+@@ -422,6 +424,8 @@ KOpenSSLProxy::KOpenSSLProxy()
+       K_X509_NAME_oneline = (char * (*) (X509_NAME *,char *,int)) 
d->cryptoLib->resolveFunction("X509_NAME_oneline");
+       K_X509_get_subject_name = (X509_NAME * (*) (X509 *)) 
d->cryptoLib->resolveFunction("X509_get_subject_name");
+       K_X509_get_issuer_name = (X509_NAME * (*) (X509 *)) 
d->cryptoLib->resolveFunction("X509_get_issuer_name");
++      K_X509_getm_notBefore = (ASN1_TIME  * (*) (const X509 *)) 
d->cryptoLib->resolveFunction("X509_getm_notBefore");
++      K_X509_getm_notAfter = (ASN1_TIME  * (*) (const X509 *)) 
d->cryptoLib->resolveFunction("X509_getm_notAfter");
+       K_X509_STORE_add_lookup = (X509_LOOKUP *(*) (X509_STORE *, 
X509_LOOKUP_METHOD *)) d->cryptoLib->resolveFunction("X509_STORE_add_lookup");
+       K_X509_LOOKUP_file = (X509_LOOKUP_METHOD *(*)(void)) 
d->cryptoLib->resolveFunction("X509_LOOKUP_file");
+       K_X509_LOOKUP_free = (void (*)(X509_LOOKUP *)) 
d->cryptoLib->resolveFunction("X509_LOOKUP_free");
+@@ -902,6 +906,18 @@ X509_NAME *KOpenSSLProxy::X509_get_subject_name(X509 *
+ 
+ X509_NAME *KOpenSSLProxy::X509_get_issuer_name(X509 *a) {
+    if (K_X509_get_issuer_name) return (K_X509_get_issuer_name)(a);
++   return 0L;
++}
++
++
++ASN1_TIME *KOpenSSLProxy::X509_getm_notBefore(const X509 *a) {
++   if (K_X509_getm_notBefore) return (K_X509_getm_notBefore)(a);
++   return 0L;
++}
++
++
++ASN1_TIME *KOpenSSLProxy::X509_getm_notAfter(const X509 *a) {
++   if (K_X509_getm_notAfter) return (K_X509_getm_notAfter)(a);
+    return 0L;
+ }
+ 
Index: patches/patch-kio_kssl_kopenssl_h
===================================================================
RCS file: patches/patch-kio_kssl_kopenssl_h
diff -N patches/patch-kio_kssl_kopenssl_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-kio_kssl_kopenssl_h   18 Mar 2020 07:12:16 -0000
@@ -0,0 +1,25 @@
+$OpenBSD$
+
+Fix use of X509_get_notBefore() and X509_get_notAfter() in
+kio/kssl/ksslcertificate.cpp after openssl/x509.h rev 1.70.
+
+Index: kio/kssl/kopenssl.h
+--- kio/kssl/kopenssl.h.orig
++++ kio/kssl/kopenssl.h
+@@ -361,6 +361,16 @@ class KOpenSSLProxy { (public)
+ 
+ 
+    /*
++    *   X509_getm_notBefore - start of validity
++    */
++   ASN1_TIME *X509_getm_notBefore(const X509 *a);
++
++   /*
++    *   X509_getm_notAfter - end of validity
++    */
++   ASN1_TIME *X509_getm_notAfter(const X509 *a);
++
++   /*
+     *   X509_STORE_add_lookup - add a lookup file/method to an X509 store
+     */
+    X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
Index: patches/patch-kio_kssl_ksslcertificate_cpp
===================================================================
RCS file: patches/patch-kio_kssl_ksslcertificate_cpp
diff -N patches/patch-kio_kssl_ksslcertificate_cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-kio_kssl_ksslcertificate_cpp  18 Mar 2020 07:14:37 -0000
@@ -0,0 +1,46 @@
+$OpenBSD$
+
+The X509_get_notBefore() and X509_get_notAfter() macros were changed in
+openssl/x509.h rev 1.70 to reference the functions X509_getm_notBefore() 
+and X509_getm_notAfter(), so these need to be resolved at runtime.
+See also the patches for kio/kssl/kopenssl.{cpp,h}.
+
+Index: kio/kssl/ksslcertificate.cpp
+--- kio/kssl/ksslcertificate.cpp.orig
++++ kio/kssl/ksslcertificate.cpp
+@@ -978,7 +978,7 @@ KSSLCertificate::KSSLValidation KSSLCertificate::proce
+ 
+ QString KSSLCertificate::getNotBefore() const {
+ #ifdef KSSL_HAVE_SSL
+-    return ASN1_UTCTIME_QString(X509_get_notBefore(d->m_cert));
++    return ASN1_UTCTIME_QString(d->kossl->X509_getm_notBefore(d->m_cert));
+ #else
+     return QString();
+ #endif
+@@ -987,7 +987,7 @@ QString KSSLCertificate::getNotBefore() const {
+ 
+ QString KSSLCertificate::getNotAfter() const {
+ #ifdef KSSL_HAVE_SSL
+-    return ASN1_UTCTIME_QString(X509_get_notAfter(d->m_cert));
++    return ASN1_UTCTIME_QString(d->kossl->X509_getm_notAfter(d->m_cert));
+ #else
+     return QString();
+ #endif
+@@ -996,7 +996,7 @@ QString KSSLCertificate::getNotAfter() const {
+ 
+ QDateTime KSSLCertificate::getQDTNotBefore() const {
+ #ifdef KSSL_HAVE_SSL
+-    return ASN1_UTCTIME_QDateTime(X509_get_notBefore(d->m_cert), NULL);
++    return ASN1_UTCTIME_QDateTime(d->kossl->X509_getm_notBefore(d->m_cert), 
NULL);
+ #else
+     return QDateTime::currentDateTime();
+ #endif
+@@ -1005,7 +1005,7 @@ QDateTime KSSLCertificate::getQDTNotBefore() const {
+ 
+ QDateTime KSSLCertificate::getQDTNotAfter() const {
+ #ifdef KSSL_HAVE_SSL
+-    return ASN1_UTCTIME_QDateTime(X509_get_notAfter(d->m_cert), NULL);
++    return ASN1_UTCTIME_QDateTime(d->kossl->X509_getm_notAfter(d->m_cert), 
NULL);
+ #else
+     return QDateTime::currentDateTime();
+ #endif

Reply via email to