Backport of: From 804edf772d254620f5a9f0b87135cfda15a59ee8 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Tue, 17 Jan 2023 17:45:42 +0000 Subject: [PATCH] CVE-2023-0286: Fix GENERAL_NAME_cmp for x400Address (1.1.1) --- CHANGES | 18 +++++++++++++++++- crypto/x509v3/v3_genn.c | 2 +- include/openssl/x509v3.h | 2 +- test/v3nametest.c | 8 ++++++++ 4 files changed, 27 insertions(+), 3 deletions(-) #diff --git a/CHANGES b/CHANGES #index 7d5f10da6d..ff82b6957d 100644 #--- a/CHANGES #+++ b/CHANGES #@@ -9,7 +9,23 @@ # # Changes between 1.1.1s and 1.1.1t [xx XXX xxxx] # #- *) #+ *) Fixed a type confusion vulnerability relating to X.400 address processing #+ inside an X.509 GeneralName. X.400 addresses were parsed as an ASN1_STRING #+ but subsequently interpreted by GENERAL_NAME_cmp as an ASN1_TYPE. This #+ vulnerability may allow an attacker who can provide a certificate chain and #+ CRL (neither of which need have a valid signature) to pass arbitrary #+ pointers to a memcmp call, creating a possible read primitive, subject to #+ some constraints. Refer to the advisory for more information. Thanks to #+ David Benjamin for discovering this issue. (CVE-2023-0286) #+ #+ This issue has been fixed by changing the public header file definition of #+ GENERAL_NAME so that x400Address reflects the implementation. It was not #+ possible for any existing application to successfully use the existing #+ definition; however, if any application references the x400Address field #+ (e.g. in dead code), note that the type of this field has changed. There is #+ no ABI change. #+ #+ [Hugo Landau] # # Changes between 1.1.1r and 1.1.1s [1 Nov 2022] # --- a/crypto/x509v3/v3_genn.c +++ b/crypto/x509v3/v3_genn.c @@ -148,7 +148,7 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GE return -1; switch (a->type) { case GEN_X400: - result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address); + result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address); break; case GEN_EDIPARTY: --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -190,7 +190,7 @@ typedef struct GENERAL_NAME_st { OTHERNAME *otherName; /* otherName */ ASN1_IA5STRING *rfc822Name; ASN1_IA5STRING *dNSName; - ASN1_TYPE *x400Address; + ASN1_STRING *x400Address; X509_NAME *directoryName; EDIPARTYNAME *ediPartyName; ASN1_IA5STRING *uniformResourceIdentifier;