X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fx509%2Fv3_alt.c;h=dd45546f6c69fd545a923b223f76850be0993194;hb=f000e82898af251442ca52e81fc1ee45996090dc;hp=307994042c881d1b60d3387854a6e93129d5b123;hpb=bab6046146c4fc8f088c1aaca11598ede7609c04;p=openssl.git diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index 307994042c..dd45546f6c 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,8 +11,12 @@ #include "internal/cryptlib.h" #include #include +#include #include "ext_dat.h" +DEFINE_STACK_OF(CONF_VALUE) +DEFINE_STACK_OF(GENERAL_NAME) + static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); @@ -52,11 +56,24 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, { int i; GENERAL_NAME *gen; + STACK_OF(CONF_VALUE) *tmpret = NULL, *origret = ret; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); - ret = i2v_GENERAL_NAME(method, gen, ret); + /* + * i2v_GENERAL_NAME allocates ret if it is NULL. If something goes + * wrong we need to free the stack - but only if it was empty when we + * originally entered this function. + */ + tmpret = i2v_GENERAL_NAME(method, gen, ret); + if (tmpret == NULL) { + if (origret == NULL) + sk_CONF_VALUE_pop_free(ret, X509V3_conf_free); + return NULL; + } + ret = tmpret; } - if (!ret) + if (ret == NULL) return sk_CONF_VALUE_new_null(); return ret; } @@ -65,14 +82,71 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret) { - unsigned char *p; - char oline[256], htmp[5]; - int i; + char othername[300]; + char oline[256], *tmp; switch (gen->type) { case GEN_OTHERNAME: - if (!X509V3_add_value("othername", "", &ret)) - return NULL; + switch (OBJ_obj2nid(gen->d.otherName->type_id)) { + case NID_id_on_SmtpUTF8Mailbox: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: SmtpUTF8Mailbox:", + gen->d.otherName->value->value.utf8string->data, + &ret)) + return NULL; + break; + case NID_XmppAddr: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: XmppAddr:", + gen->d.otherName->value->value.utf8string->data, + &ret)) + return NULL; + break; + case NID_SRVName: + if (gen->d.otherName->value->type != V_ASN1_IA5STRING + || !X509V3_add_value_uchar("othername: SRVName:", + gen->d.otherName->value->value.ia5string->data, + &ret)) + return NULL; + break; + case NID_ms_upn: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: UPN:", + gen->d.otherName->value->value.utf8string->data, + &ret)) + return NULL; + break; + case NID_NAIRealm: + if (gen->d.otherName->value->type != V_ASN1_UTF8STRING + || !X509V3_add_value_uchar("othername: NAIRealm:", + gen->d.otherName->value->value.utf8string->data, + &ret)) + return NULL; + break; + default: + if (OBJ_obj2txt(oline, sizeof(oline), gen->d.otherName->type_id, 0) > 0) + BIO_snprintf(othername, sizeof(othername), "othername: %s:", + oline); + else + OPENSSL_strlcpy(othername, "othername:", sizeof(othername)); + + /* check if the value is something printable */ + if (gen->d.otherName->value->type == V_ASN1_IA5STRING) { + if (X509V3_add_value_uchar(othername, + gen->d.otherName->value->value.ia5string->data, + &ret)) + return ret; + } + if (gen->d.otherName->value->type == V_ASN1_UTF8STRING) { + if (X509V3_add_value_uchar(othername, + gen->d.otherName->value->value.utf8string->data, + &ret)) + return ret; + } + if (!X509V3_add_value(othername, "", &ret)) + return NULL; + break; + } break; case GEN_X400: @@ -107,26 +181,10 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, break; case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_snprintf(oline, sizeof(oline), "%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - oline[0] = 0; - for (i = 0; i < 8; i++) { - BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); - p += 2; - strcat(oline, htmp); - if (i != 7) - strcat(oline, ":"); - } - } else { - if (!X509V3_add_value("IP Address", "", &ret)) - return NULL; - break; - } - if (!X509V3_add_value("IP Address", oline, &ret)) - return NULL; + tmp = ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); + if (tmp == NULL || !X509V3_add_value("IP Address", tmp, &ret)) + ret = NULL; + OPENSSL_free(tmp); break; case GEN_RID: @@ -140,11 +198,46 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) { - unsigned char *p; - int i; + char *tmp; + int nid; + switch (gen->type) { case GEN_OTHERNAME: - BIO_printf(out, "othername:"); + nid = OBJ_obj2nid(gen->d.otherName->type_id); + /* Validate the types are as we expect before we use them */ + if ((nid == NID_SRVName + && gen->d.otherName->value->type != V_ASN1_IA5STRING) + || (nid != NID_SRVName + && gen->d.otherName->value->type != V_ASN1_UTF8STRING)) { + BIO_printf(out, "othername:"); + break; + } + + switch (nid) { + case NID_id_on_SmtpUTF8Mailbox: + BIO_printf(out, "othername:SmtpUTF8Mailbox:%s", + gen->d.otherName->value->value.utf8string->data); + break; + case NID_XmppAddr: + BIO_printf(out, "othername:XmppAddr:%s", + gen->d.otherName->value->value.utf8string->data); + break; + case NID_SRVName: + BIO_printf(out, "othername:SRVName:%s", + gen->d.otherName->value->value.ia5string->data); + break; + case NID_ms_upn: + BIO_printf(out, "othername:UPN:%s", + gen->d.otherName->value->value.utf8string->data); + break; + case NID_NAIRealm: + BIO_printf(out, "othername:NAIRealm:%s", + gen->d.otherName->value->value.utf8string->data); + break; + default: + BIO_printf(out, "othername:"); + break; + } break; case GEN_X400: @@ -177,19 +270,11 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) break; case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) { - BIO_printf(out, ":%X", p[0] << 8 | p[1]); - p += 2; - } - } else { - BIO_printf(out, "IP Address:"); - break; - } + tmp = ipaddr_to_asc(gen->d.ip->data, gen->d.ip->length); + if (tmp == NULL) + return 0; + BIO_printf(out, "IP Address:%s", tmp); + OPENSSL_free(tmp); break; case GEN_RID: @@ -216,7 +301,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, for (i = 0; i < num; i++) { CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "issuer") + if (!v3_name_cmp(cnf->name, "issuer") && cnf->value && strcmp(cnf->value, "copy") == 0) { if (!copy_issuer(ctx, gens)) goto err; @@ -295,11 +380,11 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "email") + if (!v3_name_cmp(cnf->name, "email") && cnf->value && strcmp(cnf->value, "copy") == 0) { if (!copy_email(ctx, gens, 0)) goto err; - } else if (!name_cmp(cnf->name, "email") + } else if (!v3_name_cmp(cnf->name, "email") && cnf->value && strcmp(cnf->value, "move") == 0) { if (!copy_email(ctx, gens, 1)) goto err; @@ -515,19 +600,19 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, return NULL; } - if (!name_cmp(name, "email")) + if (!v3_name_cmp(name, "email")) type = GEN_EMAIL; - else if (!name_cmp(name, "URI")) + else if (!v3_name_cmp(name, "URI")) type = GEN_URI; - else if (!name_cmp(name, "DNS")) + else if (!v3_name_cmp(name, "DNS")) type = GEN_DNS; - else if (!name_cmp(name, "RID")) + else if (!v3_name_cmp(name, "RID")) type = GEN_RID; - else if (!name_cmp(name, "IP")) + else if (!v3_name_cmp(name, "IP")) type = GEN_IPADD; - else if (!name_cmp(name, "dirName")) + else if (!v3_name_cmp(name, "dirName")) type = GEN_DIRNAME; - else if (!name_cmp(name, "otherName")) + else if (!v3_name_cmp(name, "otherName")) type = GEN_OTHERNAME; else { X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION);