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