X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fx509v3%2Fv3_alt.c;h=832e6d1285712ee9ad481492657761f64c0bdc36;hb=ddb634fe6f9aeea34fe036cf804903b4240d38ac;hp=c0c63a98786567491d53533456d0b60e7f9f67f7;hpb=86885c289580066792415218754bd935b449f170;p=openssl.git diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509v3/v3_alt.c index c0c63a9878..832e6d1285 100644 --- a/crypto/x509v3/v3_alt.c +++ b/crypto/x509v3/v3_alt.c @@ -1,66 +1,17 @@ -/* v3_alt.c */ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). + * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html */ #include -#include "cryptlib.h" +#include "internal/cryptlib.h" #include #include +#include "ext_dat.h" static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, @@ -70,10 +21,10 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, STACK_OF(CONF_VALUE) *nval); static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); -static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); -static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); +static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx); -const X509V3_EXT_METHOD v3_alt[] = { +const X509V3_EXT_METHOD v3_alt[3] = { {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), 0, 0, 0, 0, 0, 0, @@ -117,60 +68,71 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, unsigned char *p; char oline[256], htmp[5]; int i; + switch (gen->type) { case GEN_OTHERNAME: - X509V3_add_value("othername", "", &ret); + if (!X509V3_add_value("othername", "", &ret)) + return NULL; break; case GEN_X400: - X509V3_add_value("X400Name", "", &ret); + if (!X509V3_add_value("X400Name", "", &ret)) + return NULL; break; case GEN_EDIPARTY: - X509V3_add_value("EdiPartyName", "", &ret); + if (!X509V3_add_value("EdiPartyName", "", &ret)) + return NULL; break; case GEN_EMAIL: - X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_DNS: - X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_URI: - X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_DIRNAME: - X509_NAME_oneline(gen->d.dirn, oline, 256); - X509V3_add_value("DirName", oline, &ret); + if (X509_NAME_oneline(gen->d.dirn, oline, sizeof(oline)) == NULL + || !X509V3_add_value("DirName", oline, &ret)) + return NULL; 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]); + 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]); + BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); p += 2; strcat(oline, htmp); if (i != 7) strcat(oline, ":"); } } else { - X509V3_add_value("IP Address", "", &ret); + if (!X509V3_add_value("IP Address", "", &ret)) + return NULL; break; } - X509V3_add_value("IP Address", oline, &ret); + if (!X509V3_add_value("IP Address", oline, &ret)) + return NULL; break; case GEN_RID: i2t_ASN1_OBJECT(oline, 256, gen->d.rid); - X509V3_add_value("Registered ID", oline, &ret); + if (!X509V3_add_value("Registered ID", oline, &ret)) + return NULL; break; } return ret; @@ -207,7 +169,7 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) break; case GEN_DIRNAME: - BIO_printf(out, "DirName: "); + BIO_printf(out, "DirName:"); X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); break; @@ -229,7 +191,7 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) break; case GEN_RID: - BIO_printf(out, "Registered ID"); + BIO_printf(out, "Registered ID:"); i2a_ASN1_OBJECT(out, gen->d.rid); break; } @@ -240,24 +202,28 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; + const int num = sk_CONF_VALUE_num(nval); + GENERAL_NAMES *gens = sk_GENERAL_NAME_new_reserve(NULL, num); int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { + + if (gens == NULL) { X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); + sk_GENERAL_NAME_free(gens); return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); + for (i = 0; i < num; i++) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "issuer") && cnf->value && strcmp(cnf->value, "copy") == 0) { if (!copy_issuer(ctx, gens)) goto err; } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + GENERAL_NAME *gen = v2i_GENERAL_NAME(method, ctx, cnf); + + if (gen == NULL) goto err; - sk_GENERAL_NAME_push(gens, gen); + sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ } } return gens; @@ -273,7 +239,8 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) GENERAL_NAMES *ialt; GENERAL_NAME *gen; X509_EXTENSION *ext; - int i; + int i, num; + if (ctx && (ctx->flags == CTX_TEST)) return 1; if (!ctx || !ctx->issuer_cert) { @@ -283,18 +250,21 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); if (i < 0) return 1; - if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext))) { + if ((ext = X509_get_ext(ctx->issuer_cert, i)) == NULL + || (ialt = X509V3_EXT_d2i(ext)) == NULL) { X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); goto err; } - for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + num = sk_GENERAL_NAME_num(ialt); + if (!sk_GENERAL_NAME_reserve(gens, num)) { + X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (i = 0; i < num; i++) { gen = sk_GENERAL_NAME_value(ialt, i); - if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); - goto err; - } + sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ } sk_GENERAL_NAME_free(ialt); @@ -309,14 +279,19 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { - GENERAL_NAMES *gens = NULL; + GENERAL_NAMES *gens; CONF_VALUE *cnf; + const int num = sk_CONF_VALUE_num(nval); int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { + + gens = sk_GENERAL_NAME_new_reserve(NULL, num); + if (gens == NULL) { X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); + sk_GENERAL_NAME_free(gens); return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + + for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); if (!name_cmp(cnf->name, "email") && cnf->value && strcmp(cnf->value, "copy") == 0) { @@ -328,9 +303,9 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, goto err; } else { GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) goto err; - sk_GENERAL_NAME_push(gens, gen); + sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ } } return gens; @@ -349,10 +324,12 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) ASN1_IA5STRING *email = NULL; X509_NAME_ENTRY *ne; GENERAL_NAME *gen = NULL; - int i; + int i = -1; + if (ctx != NULL && ctx->flags == CTX_TEST) return 1; - if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + if (ctx == NULL + || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); goto err; } @@ -363,7 +340,6 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) nm = X509_REQ_get_subject_name(ctx->subject_req); /* Now add any email address(es) to STACK */ - i = -1; while ((i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i)) >= 0) { ne = X509_NAME_get_entry(nm, i); @@ -373,7 +349,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) X509_NAME_ENTRY_free(ne); i--; } - if (!email || !(gen = GENERAL_NAME_new())) { + if (email == NULL || (gen = GENERAL_NAME_new()) == NULL) { X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); goto err; } @@ -400,18 +376,23 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) { GENERAL_NAME *gen; - GENERAL_NAMES *gens = NULL; + GENERAL_NAMES *gens; CONF_VALUE *cnf; + const int num = sk_CONF_VALUE_num(nval); int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { + + gens = sk_GENERAL_NAME_new_reserve(NULL, num); + if (gens == NULL) { X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); + sk_GENERAL_NAME_free(gens); return NULL; } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + + for (i = 0; i < num; i++) { cnf = sk_CONF_VALUE_value(nval, i); - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + if ((gen = v2i_GENERAL_NAME(method, ctx, cnf)) == NULL) goto err; - sk_GENERAL_NAME_push(gens, gen); + sk_GENERAL_NAME_push(gens, gen); /* no failure as it was reserved */ } return gens; err: @@ -427,7 +408,7 @@ GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, char *value, + X509V3_CTX *ctx, int gen_type, const char *value, int is_nc) { char is_string = 0; @@ -458,7 +439,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, case GEN_RID: { ASN1_OBJECT *obj; - if (!(obj = OBJ_txt2obj(value, 0))) { + if ((obj = OBJ_txt2obj(value, 0)) == NULL) { X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); ERR_add_error_data(2, "value=", value); goto err; @@ -498,7 +479,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, } if (is_string) { - if (!(gen->d.ia5 = ASN1_IA5STRING_new()) || + if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, strlen(value))) { X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); @@ -556,27 +537,26 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, } -static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +static int do_othername(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { char *objtmp = NULL, *p; int objlen; - if (!(p = strchr(value, ';'))) + + if ((p = strchr(value, ';')) == NULL) return 0; - if (!(gen->d.otherName = OTHERNAME_new())) + if ((gen->d.otherName = OTHERNAME_new()) == NULL) return 0; /* * Free this up because we will overwrite it. no need to free type_id * because it is static */ ASN1_TYPE_free(gen->d.otherName->value); - if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + if ((gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx)) == NULL) return 0; objlen = p - value; - objtmp = OPENSSL_malloc(objlen + 1); + objtmp = OPENSSL_strndup(value, objlen); if (objtmp == NULL) return 0; - strncpy(objtmp, value, objlen); - objtmp[objlen] = 0; gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); OPENSSL_free(objtmp); if (!gen->d.otherName->type_id) @@ -584,12 +564,13 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) return 1; } -static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +static int do_dirname(GENERAL_NAME *gen, const char *value, X509V3_CTX *ctx) { int ret = 0; STACK_OF(CONF_VALUE) *sk = NULL; - X509_NAME *nm = NULL; - if (!(nm = X509_NAME_new())) + X509_NAME *nm; + + if ((nm = X509_NAME_new()) == NULL) goto err; sk = X509V3_get_section(ctx, value); if (!sk) {