X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fasn1%2Fasn1_gen.c;h=493a693aa3840c4b79b69710a70406d59d5f89a4;hp=9ef89f6121f3c0f13deb860970b19b62927ed994;hb=687b48685931638ca5fca2a7d5e13516ad40ea4b;hpb=0f113f3ee4d629ef9a4a30911b22b224772085e5 diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c index 9ef89f6121..493a693aa3 100644 --- a/crypto/asn1/asn1_gen.c +++ b/crypto/asn1/asn1_gen.c @@ -1,63 +1,13 @@ -/* asn1_gen.c */ /* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2002 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 2002-2016 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 "cryptlib.h" +#include "internal/cryptlib.h" #include #include @@ -74,6 +24,8 @@ #define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} #define ASN1_FLAG_EXP_MAX 20 +/* Maximum number of nested sequences */ +#define ASN1_GEN_SEQ_MAX_DEPTH 50 /* Input formats */ @@ -110,17 +62,20 @@ typedef struct { int exp_count; } tag_exp_arg; +static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, + int *perr); static int bitstr_cb(const char *elem, int len, void *bitstr); static int asn1_cb(const char *elem, int len, void *bitstr); static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok); static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass); -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf); +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr); static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); static int asn1_str2tag(const char *tagstr, int len); -ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) +ASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf) { X509V3_CTX cnf; @@ -131,7 +86,17 @@ ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) return ASN1_generate_v3(str, &cnf); } -ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) +ASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) +{ + int err = 0; + ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); + if (err) + ASN1err(ASN1_F_ASN1_GENERATE_V3, err); + return ret; +} + +static ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, + int *perr) { ASN1_TYPE *ret; tag_exp_arg asn1_tags; @@ -144,7 +109,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) unsigned char *p; const unsigned char *cp; int cpy_len; - long hdr_len; + long hdr_len = 0; int hdr_constructed = 0, hdr_tag, hdr_class; int r; @@ -152,17 +117,22 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) asn1_tags.imp_class = -1; asn1_tags.format = ASN1_GEN_FORMAT_ASCII; asn1_tags.exp_count = 0; - if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) + if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { + *perr = ASN1_R_UNKNOWN_TAG; return NULL; + } if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) { if (!cnf) { - ASN1err(ASN1_F_ASN1_GENERATE_V3, - ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); + *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; return NULL; } - ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf); + if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { + *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; + return NULL; + } + ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); } else ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); @@ -223,7 +193,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) /* Allocate buffer for new encoding */ new_der = OPENSSL_malloc(len); - if (!new_der) + if (new_der == NULL) goto err; /* Generate tagged encoding */ @@ -260,10 +230,8 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) ret = d2i_ASN1_TYPE(NULL, &cp, len); err: - if (orig_der) - OPENSSL_free(orig_der); - if (new_der) - OPENSSL_free(new_der); + OPENSSL_free(orig_der); + OPENSSL_free(new_der); return ret; @@ -279,6 +247,9 @@ static int asn1_cb(const char *elem, int len, void *bitstr) int tmp_tag, tmp_class; + if (elem == NULL) + return -1; + for (i = 0, p = elem; i < len; p++, i++) { /* Look for the ':' in name value pairs */ if (*p == ':') { @@ -350,13 +321,17 @@ static int asn1_cb(const char *elem, int len, void *bitstr) break; case ASN1_GEN_FLAG_FORMAT: - if (!strncmp(vstart, "ASCII", 5)) + if (!vstart) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + if (strncmp(vstart, "ASCII", 5) == 0) arg->format = ASN1_GEN_FORMAT_ASCII; - else if (!strncmp(vstart, "UTF8", 4)) + else if (strncmp(vstart, "UTF8", 4) == 0) arg->format = ASN1_GEN_FORMAT_UTF8; - else if (!strncmp(vstart, "HEX", 3)) + else if (strncmp(vstart, "HEX", 3) == 0) arg->format = ASN1_GEN_FORMAT_HEX; - else if (!strncmp(vstart, "BITLIST", 3)) + else if (strncmp(vstart, "BITLIST", 7) == 0) arg->format = ASN1_GEN_FORMAT_BITLIST; else { ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); @@ -416,7 +391,6 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); ERR_add_error_data(2, "Char=", erch); return 0; - break; } } else @@ -428,7 +402,8 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) /* Handle multiple types: SET and SEQUENCE */ -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr) { ASN1_TYPE *ret = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; @@ -447,7 +422,8 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { ASN1_TYPE *typ = - ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); + generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, + depth + 1, perr); if (!typ) goto bad; if (!sk_ASN1_TYPE_push(sk, typ)) @@ -466,15 +442,12 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) if (derlen < 0) goto bad; - - if (!(ret = ASN1_TYPE_new())) + if ((ret = ASN1_TYPE_new()) == NULL) goto bad; - - if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) + if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL) goto bad; ret->type = utype; - ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; @@ -482,13 +455,10 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) bad: - if (der) - OPENSSL_free(der); + OPENSSL_free(der); - if (sk) - sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); - if (sect) - X509V3_section_free(cnf, sect); + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + X509V3_section_free(cnf, sect); return ret; } @@ -597,8 +567,8 @@ static int asn1_str2tag(const char *tagstr, int len) len = strlen(tagstr); tntmp = tnst; - for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { - if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) + for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) { + if ((len == tntmp->len) && (strncmp(tntmp->strnam, tagstr, len) == 0)) return tntmp->tag; } @@ -608,15 +578,12 @@ static int asn1_str2tag(const char *tagstr, int len) static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) { ASN1_TYPE *atmp = NULL; - CONF_VALUE vtmp; - unsigned char *rdata; long rdlen; - int no_unused = 1; - if (!(atmp = ASN1_TYPE_new())) { + if ((atmp = ASN1_TYPE_new()) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); return NULL; } @@ -653,7 +620,8 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); goto bad_form; } - if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + if ((atmp->value.integer + = s2i_ASN1_INTEGER(NULL, str)) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); goto bad_str; } @@ -664,7 +632,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); goto bad_form; } - if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); goto bad_str; } @@ -676,7 +644,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); goto bad_form; } - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_str; } @@ -701,7 +669,6 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) case V_ASN1_UNIVERSALSTRING: case V_ASN1_GENERALSTRING: case V_ASN1_NUMERICSTRING: - if (format == ASN1_GEN_FORMAT_ASCII) format = MBSTRING_ASC; else if (format == ASN1_GEN_FORMAT_UTF8) @@ -720,25 +687,20 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) break; case V_ASN1_BIT_STRING: - case V_ASN1_OCTET_STRING: - - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); goto bad_form; } if (format == ASN1_GEN_FORMAT_HEX) { - - if (!(rdata = string_to_hex((char *)str, &rdlen))) { + if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); goto bad_str; } - atmp->value.asn1_string->data = rdata; atmp->value.asn1_string->length = rdlen; atmp->value.asn1_string->type = utype; - } else if (format == ASN1_GEN_FORMAT_ASCII) ASN1_STRING_set(atmp->value.asn1_string, str, -1); else if ((format == ASN1_GEN_FORMAT_BITLIST) @@ -766,7 +728,6 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) default: ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); goto bad_str; - break; } atmp->type = utype; @@ -805,7 +766,9 @@ static int mask_cb(const char *elem, int len, void *arg) { unsigned long *pmask = arg, tmpmask; int tag; - if (len == 3 && !strncmp(elem, "DIR", 3)) { + if (elem == NULL) + return 0; + if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) { *pmask |= B_ASN1_DIRECTORYSTRING; return 1; }