mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
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> Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
parent
ed3f51ec7d
commit
ad6ac17489
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
|
#include "crypto/x509.h"
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
@ -87,36 +88,41 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
|
|||||||
switch (OBJ_obj2nid(gen->d.otherName->type_id)) {
|
switch (OBJ_obj2nid(gen->d.otherName->type_id)) {
|
||||||
case NID_id_on_SmtpUTF8Mailbox:
|
case NID_id_on_SmtpUTF8Mailbox:
|
||||||
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
||||||
|| !X509V3_add_value_uchar("othername: SmtpUTF8Mailbox:",
|
|| !x509v3_add_len_value_uchar("othername: SmtpUTF8Mailbox:",
|
||||||
gen->d.otherName->value->value.utf8string->data,
|
gen->d.otherName->value->value.utf8string->data,
|
||||||
|
gen->d.otherName->value->value.utf8string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
case NID_XmppAddr:
|
case NID_XmppAddr:
|
||||||
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
||||||
|| !X509V3_add_value_uchar("othername: XmppAddr:",
|
|| !x509v3_add_len_value_uchar("othername: XmppAddr:",
|
||||||
gen->d.otherName->value->value.utf8string->data,
|
gen->d.otherName->value->value.utf8string->data,
|
||||||
|
gen->d.otherName->value->value.utf8string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
case NID_SRVName:
|
case NID_SRVName:
|
||||||
if (gen->d.otherName->value->type != V_ASN1_IA5STRING
|
if (gen->d.otherName->value->type != V_ASN1_IA5STRING
|
||||||
|| !X509V3_add_value_uchar("othername: SRVName:",
|
|| !x509v3_add_len_value_uchar("othername: SRVName:",
|
||||||
gen->d.otherName->value->value.ia5string->data,
|
gen->d.otherName->value->value.ia5string->data,
|
||||||
|
gen->d.otherName->value->value.ia5string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
case NID_ms_upn:
|
case NID_ms_upn:
|
||||||
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
||||||
|| !X509V3_add_value_uchar("othername: UPN:",
|
|| !x509v3_add_len_value_uchar("othername: UPN:",
|
||||||
gen->d.otherName->value->value.utf8string->data,
|
gen->d.otherName->value->value.utf8string->data,
|
||||||
|
gen->d.otherName->value->value.utf8string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
case NID_NAIRealm:
|
case NID_NAIRealm:
|
||||||
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
if (gen->d.otherName->value->type != V_ASN1_UTF8STRING
|
||||||
|| !X509V3_add_value_uchar("othername: NAIRealm:",
|
|| !x509v3_add_len_value_uchar("othername: NAIRealm:",
|
||||||
gen->d.otherName->value->value.utf8string->data,
|
gen->d.otherName->value->value.utf8string->data,
|
||||||
|
gen->d.otherName->value->value.utf8string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
@ -129,14 +135,16 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
|
|||||||
|
|
||||||
/* check if the value is something printable */
|
/* check if the value is something printable */
|
||||||
if (gen->d.otherName->value->type == V_ASN1_IA5STRING) {
|
if (gen->d.otherName->value->type == V_ASN1_IA5STRING) {
|
||||||
if (X509V3_add_value_uchar(othername,
|
if (x509v3_add_len_value_uchar(othername,
|
||||||
gen->d.otherName->value->value.ia5string->data,
|
gen->d.otherName->value->value.ia5string->data,
|
||||||
|
gen->d.otherName->value->value.ia5string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) {
|
if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) {
|
||||||
if (X509V3_add_value_uchar(othername,
|
if (x509v3_add_len_value_uchar(othername,
|
||||||
gen->d.otherName->value->value.utf8string->data,
|
gen->d.otherName->value->value.utf8string->data,
|
||||||
|
gen->d.otherName->value->value.utf8string->length,
|
||||||
&ret))
|
&ret))
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -157,17 +165,20 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GEN_EMAIL:
|
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;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GEN_DNS:
|
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;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GEN_URI:
|
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;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "e_os.h"
|
#include "e_os.h"
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "crypto/ctype.h"
|
#include "crypto/ctype.h"
|
||||||
#include <openssl/conf.h>
|
#include <openssl/conf.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
@ -36,17 +37,23 @@ static int ipv6_hex(unsigned char *out, const char *in, int inlen);
|
|||||||
|
|
||||||
/* Add a CONF_VALUE name value pair to stack */
|
/* Add a CONF_VALUE name value pair to stack */
|
||||||
|
|
||||||
int X509V3_add_value(const char *name, const char *value,
|
static int x509v3_add_len_value(const char *name, const char *value,
|
||||||
STACK_OF(CONF_VALUE) **extlist)
|
size_t vallen, STACK_OF(CONF_VALUE) **extlist)
|
||||||
{
|
{
|
||||||
CONF_VALUE *vtmp = NULL;
|
CONF_VALUE *vtmp = NULL;
|
||||||
char *tname = NULL, *tvalue = NULL;
|
char *tname = NULL, *tvalue = NULL;
|
||||||
int sk_allocated = (*extlist == NULL);
|
int sk_allocated = (*extlist == NULL);
|
||||||
|
|
||||||
if (name && (tname = OPENSSL_strdup(name)) == NULL)
|
if (name != NULL && (tname = OPENSSL_strdup(name)) == NULL)
|
||||||
goto err;
|
|
||||||
if (value && (tvalue = OPENSSL_strdup(value)) == NULL)
|
|
||||||
goto err;
|
goto err;
|
||||||
|
if (value != NULL) {
|
||||||
|
/* We don't allow embeded NUL characters */
|
||||||
|
if (memchr(value, 0, vallen) != NULL)
|
||||||
|
goto err;
|
||||||
|
tvalue = OPENSSL_strndup(value, vallen);
|
||||||
|
if (tvalue == NULL)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL)
|
if ((vtmp = OPENSSL_malloc(sizeof(*vtmp))) == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL)
|
if (sk_allocated && (*extlist = sk_CONF_VALUE_new_null()) == NULL)
|
||||||
@ -69,10 +76,26 @@ int X509V3_add_value(const char *name, const char *value,
|
|||||||
return 0;
|
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,
|
int X509V3_add_value_uchar(const char *name, const unsigned char *value,
|
||||||
STACK_OF(CONF_VALUE) **extlist)
|
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) */
|
/* Free function for STACK_OF(CONF_VALUE) */
|
||||||
|
@ -361,3 +361,6 @@ int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp);
|
|||||||
EVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **pp,
|
EVP_PKEY *ossl_d2i_PUBKEY_legacy(EVP_PKEY **a, const unsigned char **pp,
|
||||||
long length);
|
long length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int x509v3_add_len_value_uchar(const char *name, const unsigned char *value,
|
||||||
|
size_t vallen, STACK_OF(CONF_VALUE) **extlist);
|
||||||
|
Loading…
Reference in New Issue
Block a user