diff options
author | Matt Caswell <matt@openssl.org> | 2021-08-18 12:24:22 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-08-24 13:18:19 +0100 |
commit | 174ba8048a7f2f5e1fca31cfb93b1730d9db8300 (patch) | |
tree | 00d27afe9bf28f1259ebdadd79e6002a5fbdd8c5 | |
parent | 4f850d7221ef6d9010053434d8ae43da13ad8fde (diff) |
Fix i2v_GENERAL_NAME to not assume NUL terminated strings
ASN.1 strings may not be NUL terminated. Don't assume they are.
CVE-2021-3712
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
-rw-r--r-- | crypto/x509v3/v3_alt.c | 10 | ||||
-rw-r--r-- | crypto/x509v3/v3_utl.c | 38 | ||||
-rw-r--r-- | include/crypto/x509.h | 5 |
3 files changed, 44 insertions, 9 deletions
diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c index 4dce004101..6e5f9f8b0e 100644 --- a/crypto/x509v3/v3_alt.c +++ b/crypto/x509v3/v3_alt.c @@ -9,6 +9,7 @@ #include <stdio.h> #include "internal/cryptlib.h" +#include "crypto/x509.h" #include <openssl/conf.h> #include <openssl/x509v3.h> #include "ext_dat.h" @@ -99,17 +100,20 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, break; case GEN_EMAIL: - if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) + if (!x509v3_add_len_value_uchar("email", gen->d.ia5->data, + gen->d.ia5->length, &ret)) return NULL; break; case GEN_DNS: - if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) + if (!x509v3_add_len_value_uchar("DNS", gen->d.ia5->data, + gen->d.ia5->length, &ret)) return NULL; break; case GEN_URI: - if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) + if (!x509v3_add_len_value_uchar("URI", gen->d.ia5->data, + gen->d.ia5->length, &ret)) return NULL; break; diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c index 7281a7b917..004ef55df9 100644 --- a/crypto/x509v3/v3_utl.c +++ b/crypto/x509v3/v3_utl.c @@ -12,6 +12,7 @@ #include "e_os.h" #include "internal/cryptlib.h" #include <stdio.h> +#include <string.h> #include "crypto/ctype.h" #include <openssl/conf.h> #include <openssl/crypto.h> @@ -34,17 +35,26 @@ static int ipv6_hex(unsigned char *out, const char *in, int inlen); /* Add a CONF_VALUE name value pair to stack */ -int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist) +static int x509v3_add_len_value(const char *name, const char *value, + size_t vallen, STACK_OF(CONF_VALUE) **extlist) { CONF_VALUE *vtmp = NULL; char *tname = NULL, *tvalue = NULL; int sk_allocated = (*extlist == NULL); - if (name && (tname = OPENSSL_strdup(name)) == NULL) - goto err; - if (value && (tvalue = OPENSSL_strdup(value)) == NULL) + if (name != NULL && (tname = OPENSSL_strdup(name)) == NULL) goto err; + if (value != NULL && vallen > 0) { + /* + * We tolerate a single trailing NUL character, but otherwise no + * embedded NULs + */ + if (memchr(value, 0, vallen - 1) != NULL) + goto err; + tvalue = OPENSSL_strndup(value, vallen); + if (tvalue == NULL) + goto err; + } if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL) goto err; if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL) @@ -67,10 +77,26 @@ int X509V3_add_value(const char *name, const char *value, return 0; } +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return x509v3_add_len_value(name, value, + value != NULL ? strlen((const char *)value) : 0, + extlist); +} + int X509V3_add_value_uchar(const char *name, const unsigned char *value, STACK_OF(CONF_VALUE) **extlist) { - return X509V3_add_value(name, (const char *)value, extlist); + return x509v3_add_len_value(name, (const char *)value, + value != NULL ? strlen((const char *)value) : 0, + extlist); +} + +int x509v3_add_len_value_uchar(const char *name, const unsigned char *value, + size_t vallen, STACK_OF(CONF_VALUE) **extlist) +{ + return x509v3_add_len_value(name, (const char *)value, vallen, extlist); } /* Free function for STACK_OF(CONF_VALUE) */ diff --git a/include/crypto/x509.h b/include/crypto/x509.h index b53c2b03c3..7ffb8abfe7 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -8,6 +8,8 @@ */ #include "internal/refcount.h" +#include <openssl/x509.h> +#include <openssl/conf.h> /* Internal X509 structures and functions: not for application use */ @@ -284,3 +286,6 @@ int a2i_ipadd(unsigned char *ipout, const char *ipasc); int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm); void x509_init_sig_info(X509 *x); + +int x509v3_add_len_value_uchar(const char *name, const unsigned char *value, + size_t vallen, STACK_OF(CONF_VALUE) **extlist); |