]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUILD: ssl: use ASN1_STRING accessors for OpenSSL 4.0 compatibility
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 11 Mar 2026 09:53:00 +0000 (10:53 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Wed, 11 Mar 2026 15:59:54 +0000 (16:59 +0100)
In OpenSSL 4.0, the ASN1_STRING struct was made opaque and direct access
to its members (->data, ->length, ->type) no longer compiles. Replace
these accesses in ssl_sock_get_serial(), ssl_sock_get_time(), and
asn1_generalizedtime_to_epoch() with the proper accessor functions
ASN1_STRING_get0_data(), ASN1_STRING_length(), and ASN1_STRING_type().

The old direct access is preserved under USE_OPENSSL_WOLFSSL since
WolfSSL does not provide these accessor functions.

Original patch from Alexandr Nedvedicky <sashan@openssl.org>:
https://www.mail-archive.com/haproxy@formilux.org/msg46696.html

src/ssl_utils.c

index eadcec24b6a41616712fc897b75b647792337d14..6ecd0303902b5c92b9dbfd320af5291a450bd598 100644 (file)
@@ -74,11 +74,20 @@ int ssl_sock_get_serial(X509 *crt, struct buffer *out)
        if (!serial)
                return 0;
 
+#ifdef USE_OPENSSL_WOLFSSL
        if (out->size < serial->length)
                return -1;
 
        memcpy(out->area, serial->data, serial->length);
        out->data = serial->length;
+#else
+       if (out->size < ASN1_STRING_length(serial))
+               return -1;
+
+       out->data = ASN1_STRING_length(serial);
+       memcpy(out->area, ASN1_STRING_get0_data(serial), out->data);
+#endif
+
        return 1;
 }
 
@@ -110,35 +119,68 @@ int ssl_sock_crt2der(X509 *crt, struct buffer *out)
  */
 int ssl_sock_get_time(ASN1_TIME *tm, struct buffer *out)
 {
-       if (tm->type == V_ASN1_GENERALIZEDTIME) {
-               ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
-
-               if (gentm->length < 12)
+#ifdef USE_OPENSSL_WOLFSSL
+        if (tm->type == V_ASN1_GENERALIZEDTIME) {
+                ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
+
+                if (gentm->length < 12)
+                        return 0;
+                if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
+                        return 0;
+                if (out->size < gentm->length-2)
+                        return -1;
+
+                memcpy(out->area, gentm->data+2, gentm->length-2);
+                out->data = gentm->length-2;
+                return 1;
+        }
+        else if (tm->type == V_ASN1_UTCTIME) {
+                ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
+
+                if (utctm->length < 10)
+                        return 0;
+                if (utctm->data[0] >= 0x35)
+                        return 0;
+                if (out->size < utctm->length)
+                        return -1;
+
+                memcpy(out->area, utctm->data, utctm->length);
+                out->data = utctm->length;
+                return 1;
+        }
+
+#else
+       const unsigned char *data;
+
+       if (ASN1_STRING_type(tm) == V_ASN1_GENERALIZEDTIME) {
+               data = ASN1_STRING_get0_data(tm);
+
+               if (ASN1_STRING_length(tm) < 12)
                        return 0;
-               if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
+               if (data[0] != 0x32 || data[1] != 0x30)
                        return 0;
-               if (out->size < gentm->length-2)
+               if (out->size < ASN1_STRING_length(tm) - 2)
                        return -1;
 
-               memcpy(out->area, gentm->data+2, gentm->length-2);
-               out->data = gentm->length-2;
+               out->data = ASN1_STRING_length(tm) - 2;
+               memcpy(out->area, data + 2, out->data);
                return 1;
        }
-       else if (tm->type == V_ASN1_UTCTIME) {
-               ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
+       else if (ASN1_STRING_type(tm) == V_ASN1_UTCTIME) {
+               data = ASN1_STRING_get0_data(tm);
 
-               if (utctm->length < 10)
+               if (ASN1_STRING_length(tm) < 10)
                        return 0;
-               if (utctm->data[0] >= 0x35)
+               if (data[0] >= 0x35)
                        return 0;
-               if (out->size < utctm->length)
+               if (out->size < ASN1_STRING_length(tm))
                        return -1;
 
-               memcpy(out->area, utctm->data, utctm->length);
-               out->data = utctm->length;
+               out->data = ASN1_STRING_length(tm);
+               memcpy(out->area, data, out->data);
                return 1;
        }
-
+#endif
        return 0;
 }
 
@@ -629,16 +671,26 @@ INITCALL0(STG_REGISTER, init_x509_v_err_tab);
 long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
 {
        long epoch;
-       char *p, *end;
        const unsigned short month_offset[12] = {
                0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
        };
        unsigned long year, month;
 
+#ifdef USE_OPENSSL_WOLFSSL
+       char *p, *end;
+
        if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
 
        p = (char *)d->data;
        end = p + d->length;
+#else
+       const unsigned char *p, *end;
+
+       if (!d || (ASN1_STRING_type(d) != V_ASN1_GENERALIZEDTIME)) return -1;
+
+       p = ASN1_STRING_get0_data(d);
+       end = p + ASN1_STRING_length(d);
+#endif
 
        if (end - p < 4) return -1;
        year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';