From e7ae68f8707483b9ec213ab533acfb06fb116e89 Mon Sep 17 00:00:00 2001
From: Ken Zalewski <ken.zalewski@gmail.com>
Date: Fri, 10 Apr 2026 14:29:26 -0400
Subject: [PATCH] Patch to openssl-1.1.1zg.  This version addresses four
 vulnerabilities:  CVE-2026-28387, CVE-2026-28388, CVE-2026-28389, and
 CVE-2026-28390

---
 CHANGES                    | 75 ++++++++++++++++++++++++++++++++++++++
 NEWS                       | 10 +++++
 README                     |  2 +-
 crypto/dh/dh_ameth.c       | 13 +++++--
 crypto/ec/ec_ameth.c       | 13 +++++--
 crypto/rsa/rsa_ameth.c     | 30 ++++++++++-----
 crypto/x509/x509_vfy.c     |  8 ++--
 include/openssl/opensslv.h |  4 +-
 8 files changed, 130 insertions(+), 25 deletions(-)

diff --git a/CHANGES b/CHANGES
index 1abcd76..f7e81b3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,81 @@
  https://github.com/openssl/openssl/commits/ and pick the appropriate
  release branch.
 
+ Changes between 1.1.1ze and 1.1.1zg [7 Apr 2026]
+
+ *) Fixed potential use-after-free in DANE client code.
+
+    Severity: Low
+
+    Issue summary: An uncommon configuration of clients performing DANE
+    TLSA-based server authentication, when paired with uncommon server DANE
+    TLSA records, may result in a use-after-free and/or double-free on the
+    client side.
+
+    Impact summary: A use after free can have a range of potential consequences
+    such as the corruption of valid data, crashes, or execution of arbitrary
+    code.
+
+    Reported by: Igor Morgenstern (Aisle Research).
+
+    (CVE-2026-28387)
+    [Viktor Dukhovni]
+
+ *) Fixed NULL pointer dereference when processing a delta CRL.
+
+    Severity: Low
+
+    Issue summary: When a delta CRL that contains a Delta CRL Indicator
+    extension is processed, a NULL pointer dereference might happen if the
+    required CRL Number extension is missing.
+
+    Impact summary: A NULL pointer dereference can trigger a crash which leads
+    to a Denial of Service for an application.
+
+    Reported by: Igor Morgenstern (Aisle Research).
+
+    (CVE-2026-28388)
+    [Igor Morgenstern]
+
+ *) Fixed possible NULL dereference when processing CMS KeyAgreeRecipientInfo.
+
+    Severity: Low
+
+    Issue summary: During processing of a crafted CMS EnvelopedData message
+    with KeyAgreeRecipientInfo a NULL pointer dereference can happen.
+
+    Impact summary: Applications that process attacker-controlled CMS data may
+    crash before authentication or cryptographic operations occur resulting in
+    Denial of Service.
+
+    Reported by: Nathan Sportsman (Praetorian), Daniel Rhea,
+    Jaeho Nam (Seoul National University), Muhammad Daffa,
+    Zhanpeng Liu (Tencent Xuanwu Lab), Guannan Wang (Tencent Xuanwu Lab),
+    Guancheng Li (Tencent Xuanwu Lab), and Joshua Rogers.
+
+    (CVE-2026-28389)
+    [Neil Horman]
+
+ *) Fixed possible NULL dereference when processing CMS
+    KeyTransportRecipientInfo.
+
+    Severity: Low
+
+    Issue summary: During processing of a crafted CMS EnvelopedData message
+    with KeyTransportRecipientInfo a NULL pointer dereference can happen.
+
+    Impact summary: Applications that process attacker-controlled CMS data may
+    crash before authentication or cryptographic operations occur resulting in
+    Denial of Service.
+
+    Reported by: Muhammad Daffa, Zhanpeng Liu (Tencent Xuanwu Lab),
+    Guannan Wang (Tencent Xuanwu Lab), Guancheng Li (Tencent Xuanwu Lab),
+    Joshua Rogers, and Chanho Kim.
+
+    (CVE-2026-28390)
+    [Neil Horman]
+
+
  Changes between 1.1.1zd and 1.1.1ze [27 Jan 2026]
 
  *) Fixed Heap out-of-bounds write in BIO_f_linebuffer on short writes.
diff --git a/NEWS b/NEWS
index c9d06c5..d01ce10 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,16 @@
   This file gives a brief overview of the major changes between each OpenSSL
   release. For more details please read the CHANGES file.
 
+  Major changes between 1.1.1ze and 1.1.1zg [7 Apr 2026]
+
+      o Fixed potential use-after-free in DANE client code. (CVE-2026-28387)
+      o Fixed NULL pointer dereference when processing a delta CRL.
+        (CVE-2026-28388)
+      o Fixed possible NULL dereference when processing CMS
+        KeyAgreeRecipientInfo. (CVE-2026-28389)
+      o Fixed possible NULL dereference when processing CMS
+        KeyTransportRecipientInfo. (CVE-2026-28390)
+
   Major changes between 1.1.1zd and 1.1.1ze [27 Jan 2026]
 
       o Fixed Heap out-of-bounds write in BIO_f_linebuffer on short writes.
diff --git a/README b/README
index f388077..2bd7fdf 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 
- OpenSSL 1.1.1ze 27 Jan 2026
+ OpenSSL 1.1.1zg 7 Apr 2026
 
  Copyright (c) 1998-2026 The OpenSSL Project
  Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c
index 576409c..6615cb9 100644
--- a/crypto/dh/dh_ameth.c
+++ b/crypto/dh/dh_ameth.c
@@ -681,15 +681,20 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
     int keylen, plen;
     const EVP_CIPHER *kekcipher;
     EVP_CIPHER_CTX *kekctx;
+    const ASN1_OBJECT *aoid;
+    const void *parameter = NULL;
+    int ptype = 0;
 
     if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
         goto err;
 
+    X509_ALGOR_get0(&aoid, &ptype, &parameter, alg);
+
     /*
      * For DH we only have one OID permissible. If ever any more get defined
      * we will need something cleverer.
      */
-    if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+    if (OBJ_obj2nid(aoid) != NID_id_smime_alg_ESDH) {
         DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
         goto err;
     }
@@ -700,11 +705,11 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
     if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
         goto err;
 
-    if (alg->parameter->type != V_ASN1_SEQUENCE)
+    if (ptype != V_ASN1_SEQUENCE)
         goto err;
 
-    p = alg->parameter->value.sequence->data;
-    plen = alg->parameter->value.sequence->length;
+    p = ASN1_STRING_get0_data(parameter);
+    plen = ASN1_STRING_length(parameter);
     kekalg = d2i_X509_ALGOR(NULL, &p, plen);
     if (!kekalg)
         goto err;
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 5a63590..dffc89b 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -749,20 +749,25 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
     int plen, keylen;
     const EVP_CIPHER *kekcipher;
     EVP_CIPHER_CTX *kekctx;
+    const ASN1_OBJECT *aoid = NULL;
+    int ptype = 0;
+    const void *parameter = NULL;
 
     if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
         return 0;
 
-    if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) {
+    X509_ALGOR_get0(&aoid, &ptype, &parameter, alg);
+
+    if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(aoid))) {
         ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR);
         return 0;
     }
 
-    if (alg->parameter->type != V_ASN1_SEQUENCE)
+    if (ptype != V_ASN1_SEQUENCE)
         return 0;
 
-    p = alg->parameter->value.sequence->data;
-    plen = alg->parameter->value.sequence->length;
+    p = ASN1_STRING_get0_data(parameter);
+    plen = ASN1_STRING_length(parameter);
     kekalg = d2i_X509_ALGOR(NULL, &p, plen);
     if (!kekalg)
         goto err;
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index 00ed982..b06b106 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -922,10 +922,13 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
     X509_ALGOR *cmsalg;
     int nid;
     int rv = -1;
-    unsigned char *label = NULL;
+    const unsigned char *label = NULL;
     int labellen = 0;
     const EVP_MD *mgf1md = NULL, *md = NULL;
     RSA_OAEP_PARAMS *oaep;
+    const ASN1_OBJECT *aoid;
+    const void *parameter = NULL;
+    int ptype = 0;
 
     pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
     if (pkctx == NULL)
@@ -955,21 +958,19 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
         goto err;
 
     if (oaep->pSourceFunc != NULL) {
-        X509_ALGOR *plab = oaep->pSourceFunc;
+        X509_ALGOR_get0(&aoid, &ptype, &parameter, oaep->pSourceFunc);
 
-        if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) {
+        if (OBJ_obj2nid(aoid) != NID_pSpecified) {
             RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE);
             goto err;
         }
-        if (plab->parameter->type != V_ASN1_OCTET_STRING) {
+        if (ptype != V_ASN1_OCTET_STRING) {
             RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL);
             goto err;
         }
 
-        label = plab->parameter->value.octet_string->data;
-        /* Stop label being freed when OAEP parameters are freed */
-        plab->parameter->value.octet_string->data = NULL;
-        labellen = plab->parameter->value.octet_string->length;
+        label = ASN1_STRING_get0_data(parameter);
+        labellen = ASN1_STRING_length(parameter);
     }
 
     if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0)
@@ -978,8 +979,17 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
         goto err;
     if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0)
         goto err;
-    if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0)
-        goto err;
+    if (label != NULL) {
+        unsigned char *dup_label = OPENSSL_memdup(label, labellen);
+
+        if (dup_label == NULL)
+            goto err;
+
+        if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, dup_label, labellen) <= 0) {
+            OPENSSL_free(dup_label);
+            goto err;
+        }
+    }
     /* Carry on */
     rv = 1;
 
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 66b532a..8a288cc 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1136,9 +1136,9 @@ static int check_delta_base(X509_CRL *delta, X509_CRL *base)
     if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
         return 0;
     /* Delta CRL number must exceed full CRL number */
-    if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
-        return 1;
-    return 0;
+    if (delta->crl_number == NULL)
+        return 0;
+    return ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0;
 }
 
 /*
@@ -2761,7 +2761,7 @@ static int dane_match(X509_STORE_CTX *ctx, X509 *cert, int depth)
             if (matched || dane->mdpth < 0) {
                 dane->mdpth = depth;
                 dane->mtlsa = t;
-                OPENSSL_free(dane->mcert);
+                X509_free(dane->mcert);
                 dane->mcert = cert;
                 X509_up_ref(cert);
             }
diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h
index 7ea9cd7..0dcdd92 100644
--- a/include/openssl/opensslv.h
+++ b/include/openssl/opensslv.h
@@ -39,8 +39,8 @@ extern "C" {
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-# define OPENSSL_VERSION_NUMBER  0x101011efL
-# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1ze  27 Jan 2026"
+# define OPENSSL_VERSION_NUMBER  0x1010120fL
+# define OPENSSL_VERSION_TEXT    "OpenSSL 1.1.1zg  7 Apr 2026"
 
 /*-
  * The macros below are to be used for shared library (.so, .dll, ...)
