1160814Ssimon/* asn1_gen.c */ 2280304Sjkim/* 3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280304Sjkim * 2002. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7160814Ssimon * Copyright (c) 2002 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14280304Sjkim * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * licensing@OpenSSL.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon 60160814Ssimon#include "cryptlib.h" 61160814Ssimon#include <openssl/asn1.h> 62160814Ssimon#include <openssl/x509v3.h> 63160814Ssimon 64280304Sjkim#define ASN1_GEN_FLAG 0x10000 65280304Sjkim#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 66280304Sjkim#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 67280304Sjkim#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 68280304Sjkim#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 69280304Sjkim#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 70280304Sjkim#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 71280304Sjkim#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 72280304Sjkim#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 73160814Ssimon 74280304Sjkim#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 75160814Ssimon 76280304Sjkim#define ASN1_FLAG_EXP_MAX 20 77284285Sjkim/* Maximum number of nested sequences */ 78284285Sjkim#define ASN1_GEN_SEQ_MAX_DEPTH 50 79160814Ssimon 80160814Ssimon/* Input formats */ 81160814Ssimon 82160814Ssimon/* ASCII: default */ 83280304Sjkim#define ASN1_GEN_FORMAT_ASCII 1 84160814Ssimon/* UTF8 */ 85280304Sjkim#define ASN1_GEN_FORMAT_UTF8 2 86160814Ssimon/* Hex */ 87280304Sjkim#define ASN1_GEN_FORMAT_HEX 3 88160814Ssimon/* List of bits */ 89280304Sjkim#define ASN1_GEN_FORMAT_BITLIST 4 90160814Ssimon 91280304Sjkimstruct tag_name_st { 92280304Sjkim const char *strnam; 93280304Sjkim int len; 94280304Sjkim int tag; 95280304Sjkim}; 96160814Ssimon 97280304Sjkimtypedef struct { 98280304Sjkim int exp_tag; 99280304Sjkim int exp_class; 100280304Sjkim int exp_constructed; 101280304Sjkim int exp_pad; 102280304Sjkim long exp_len; 103280304Sjkim} tag_exp_type; 104160814Ssimon 105280304Sjkimtypedef struct { 106280304Sjkim int imp_tag; 107280304Sjkim int imp_class; 108280304Sjkim int utype; 109280304Sjkim int format; 110280304Sjkim const char *str; 111280304Sjkim tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 112280304Sjkim int exp_count; 113280304Sjkim} tag_exp_arg; 114160814Ssimon 115284285Sjkimstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 116284285Sjkim int *perr); 117160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr); 118160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr); 119280304Sjkimstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 120280304Sjkim int exp_constructed, int exp_pad, int imp_ok); 121280304Sjkimstatic int parse_tagging(const char *vstart, int vlen, int *ptag, 122280304Sjkim int *pclass); 123284285Sjkimstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 124284285Sjkim int depth, int *perr); 125160814Ssimonstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); 126160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len); 127160814Ssimon 128160814SsimonASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) 129280304Sjkim{ 130280304Sjkim X509V3_CTX cnf; 131160814Ssimon 132280304Sjkim if (!nconf) 133280304Sjkim return ASN1_generate_v3(str, NULL); 134160814Ssimon 135280304Sjkim X509V3_set_nconf(&cnf, nconf); 136280304Sjkim return ASN1_generate_v3(str, &cnf); 137280304Sjkim} 138160814Ssimon 139160814SsimonASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 140280304Sjkim{ 141284285Sjkim int err = 0; 142284285Sjkim ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); 143284285Sjkim if (err) 144284285Sjkim ASN1err(ASN1_F_ASN1_GENERATE_V3, err); 145284285Sjkim return ret; 146284285Sjkim} 147284285Sjkim 148284285Sjkimstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 149284285Sjkim int *perr) 150284285Sjkim{ 151280304Sjkim ASN1_TYPE *ret; 152280304Sjkim tag_exp_arg asn1_tags; 153280304Sjkim tag_exp_type *etmp; 154160814Ssimon 155280304Sjkim int i, len; 156160814Ssimon 157280304Sjkim unsigned char *orig_der = NULL, *new_der = NULL; 158280304Sjkim const unsigned char *cpy_start; 159280304Sjkim unsigned char *p; 160280304Sjkim const unsigned char *cp; 161280304Sjkim int cpy_len; 162280304Sjkim long hdr_len; 163280304Sjkim int hdr_constructed = 0, hdr_tag, hdr_class; 164280304Sjkim int r; 165160814Ssimon 166280304Sjkim asn1_tags.imp_tag = -1; 167280304Sjkim asn1_tags.imp_class = -1; 168280304Sjkim asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 169280304Sjkim asn1_tags.exp_count = 0; 170284285Sjkim if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { 171284285Sjkim *perr = ASN1_R_UNKNOWN_TAG; 172280304Sjkim return NULL; 173284285Sjkim } 174160814Ssimon 175280304Sjkim if ((asn1_tags.utype == V_ASN1_SEQUENCE) 176280304Sjkim || (asn1_tags.utype == V_ASN1_SET)) { 177280304Sjkim if (!cnf) { 178284285Sjkim *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; 179280304Sjkim return NULL; 180280304Sjkim } 181284285Sjkim if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { 182284285Sjkim *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; 183284285Sjkim return NULL; 184284285Sjkim } 185284285Sjkim ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); 186280304Sjkim } else 187280304Sjkim ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 188160814Ssimon 189280304Sjkim if (!ret) 190280304Sjkim return NULL; 191160814Ssimon 192280304Sjkim /* If no tagging return base type */ 193280304Sjkim if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 194280304Sjkim return ret; 195160814Ssimon 196280304Sjkim /* Generate the encoding */ 197280304Sjkim cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 198280304Sjkim ASN1_TYPE_free(ret); 199280304Sjkim ret = NULL; 200280304Sjkim /* Set point to start copying for modified encoding */ 201280304Sjkim cpy_start = orig_der; 202160814Ssimon 203280304Sjkim /* Do we need IMPLICIT tagging? */ 204280304Sjkim if (asn1_tags.imp_tag != -1) { 205280304Sjkim /* If IMPLICIT we will replace the underlying tag */ 206280304Sjkim /* Skip existing tag+len */ 207280304Sjkim r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 208280304Sjkim cpy_len); 209280304Sjkim if (r & 0x80) 210280304Sjkim goto err; 211280304Sjkim /* Update copy length */ 212280304Sjkim cpy_len -= cpy_start - orig_der; 213280304Sjkim /* 214280304Sjkim * For IMPLICIT tagging the length should match the original length 215280304Sjkim * and constructed flag should be consistent. 216280304Sjkim */ 217280304Sjkim if (r & 0x1) { 218280304Sjkim /* Indefinite length constructed */ 219280304Sjkim hdr_constructed = 2; 220280304Sjkim hdr_len = 0; 221280304Sjkim } else 222280304Sjkim /* Just retain constructed flag */ 223280304Sjkim hdr_constructed = r & V_ASN1_CONSTRUCTED; 224280304Sjkim /* 225280304Sjkim * Work out new length with IMPLICIT tag: ignore constructed because 226280304Sjkim * it will mess up if indefinite length 227280304Sjkim */ 228280304Sjkim len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 229280304Sjkim } else 230280304Sjkim len = cpy_len; 231160814Ssimon 232280304Sjkim /* Work out length in any EXPLICIT, starting from end */ 233160814Ssimon 234280304Sjkim for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 235280304Sjkim i < asn1_tags.exp_count; i++, etmp--) { 236280304Sjkim /* Content length: number of content octets + any padding */ 237280304Sjkim len += etmp->exp_pad; 238280304Sjkim etmp->exp_len = len; 239280304Sjkim /* Total object length: length including new header */ 240280304Sjkim len = ASN1_object_size(0, len, etmp->exp_tag); 241280304Sjkim } 242160814Ssimon 243280304Sjkim /* Allocate buffer for new encoding */ 244160814Ssimon 245280304Sjkim new_der = OPENSSL_malloc(len); 246280304Sjkim if (!new_der) 247280304Sjkim goto err; 248160814Ssimon 249280304Sjkim /* Generate tagged encoding */ 250160814Ssimon 251280304Sjkim p = new_der; 252160814Ssimon 253280304Sjkim /* Output explicit tags first */ 254160814Ssimon 255280304Sjkim for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 256280304Sjkim i++, etmp++) { 257280304Sjkim ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 258280304Sjkim etmp->exp_tag, etmp->exp_class); 259280304Sjkim if (etmp->exp_pad) 260280304Sjkim *p++ = 0; 261280304Sjkim } 262160814Ssimon 263280304Sjkim /* If IMPLICIT, output tag */ 264160814Ssimon 265280304Sjkim if (asn1_tags.imp_tag != -1) { 266280304Sjkim if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 267280304Sjkim && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 268280304Sjkim || asn1_tags.imp_tag == V_ASN1_SET)) 269280304Sjkim hdr_constructed = V_ASN1_CONSTRUCTED; 270280304Sjkim ASN1_put_object(&p, hdr_constructed, hdr_len, 271280304Sjkim asn1_tags.imp_tag, asn1_tags.imp_class); 272280304Sjkim } 273160814Ssimon 274280304Sjkim /* Copy across original encoding */ 275280304Sjkim memcpy(p, cpy_start, cpy_len); 276160814Ssimon 277280304Sjkim cp = new_der; 278160814Ssimon 279280304Sjkim /* Obtain new ASN1_TYPE structure */ 280280304Sjkim ret = d2i_ASN1_TYPE(NULL, &cp, len); 281160814Ssimon 282280304Sjkim err: 283280304Sjkim if (orig_der) 284280304Sjkim OPENSSL_free(orig_der); 285280304Sjkim if (new_der) 286280304Sjkim OPENSSL_free(new_der); 287160814Ssimon 288280304Sjkim return ret; 289160814Ssimon 290280304Sjkim} 291160814Ssimon 292160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr) 293280304Sjkim{ 294280304Sjkim tag_exp_arg *arg = bitstr; 295280304Sjkim int i; 296280304Sjkim int utype; 297280304Sjkim int vlen = 0; 298280304Sjkim const char *p, *vstart = NULL; 299160814Ssimon 300280304Sjkim int tmp_tag, tmp_class; 301160814Ssimon 302280304Sjkim if (elem == NULL) 303284285Sjkim return -1; 304160814Ssimon 305280304Sjkim for (i = 0, p = elem; i < len; p++, i++) { 306280304Sjkim /* Look for the ':' in name value pairs */ 307280304Sjkim if (*p == ':') { 308280304Sjkim vstart = p + 1; 309280304Sjkim vlen = len - (vstart - elem); 310280304Sjkim len = p - elem; 311280304Sjkim break; 312280304Sjkim } 313280304Sjkim } 314160814Ssimon 315280304Sjkim utype = asn1_str2tag(elem, len); 316160814Ssimon 317280304Sjkim if (utype == -1) { 318280304Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); 319280304Sjkim ERR_add_error_data(2, "tag=", elem); 320280304Sjkim return -1; 321280304Sjkim } 322160814Ssimon 323280304Sjkim /* If this is not a modifier mark end of string and exit */ 324280304Sjkim if (!(utype & ASN1_GEN_FLAG)) { 325280304Sjkim arg->utype = utype; 326280304Sjkim arg->str = vstart; 327280304Sjkim /* If no value and not end of string, error */ 328280304Sjkim if (!vstart && elem[len]) { 329280304Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); 330280304Sjkim return -1; 331280304Sjkim } 332280304Sjkim return 0; 333280304Sjkim } 334160814Ssimon 335280304Sjkim switch (utype) { 336160814Ssimon 337280304Sjkim case ASN1_GEN_FLAG_IMP: 338280304Sjkim /* Check for illegal multiple IMPLICIT tagging */ 339280304Sjkim if (arg->imp_tag != -1) { 340280304Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); 341280304Sjkim return -1; 342280304Sjkim } 343280304Sjkim if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 344280304Sjkim return -1; 345280304Sjkim break; 346160814Ssimon 347280304Sjkim case ASN1_GEN_FLAG_EXP: 348160814Ssimon 349280304Sjkim if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 350280304Sjkim return -1; 351280304Sjkim if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 352280304Sjkim return -1; 353280304Sjkim break; 354160814Ssimon 355280304Sjkim case ASN1_GEN_FLAG_SEQWRAP: 356280304Sjkim if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 357280304Sjkim return -1; 358280304Sjkim break; 359160814Ssimon 360280304Sjkim case ASN1_GEN_FLAG_SETWRAP: 361280304Sjkim if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 362280304Sjkim return -1; 363280304Sjkim break; 364160814Ssimon 365280304Sjkim case ASN1_GEN_FLAG_BITWRAP: 366280304Sjkim if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 367280304Sjkim return -1; 368280304Sjkim break; 369160814Ssimon 370280304Sjkim case ASN1_GEN_FLAG_OCTWRAP: 371280304Sjkim if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 372280304Sjkim return -1; 373280304Sjkim break; 374160814Ssimon 375280304Sjkim case ASN1_GEN_FLAG_FORMAT: 376284285Sjkim if (!vstart) { 377280304Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); 378280304Sjkim return -1; 379280304Sjkim } 380280304Sjkim if (!strncmp(vstart, "ASCII", 5)) 381280304Sjkim arg->format = ASN1_GEN_FORMAT_ASCII; 382280304Sjkim else if (!strncmp(vstart, "UTF8", 4)) 383280304Sjkim arg->format = ASN1_GEN_FORMAT_UTF8; 384280304Sjkim else if (!strncmp(vstart, "HEX", 3)) 385280304Sjkim arg->format = ASN1_GEN_FORMAT_HEX; 386280304Sjkim else if (!strncmp(vstart, "BITLIST", 7)) 387280304Sjkim arg->format = ASN1_GEN_FORMAT_BITLIST; 388280304Sjkim else { 389280304Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); 390280304Sjkim return -1; 391280304Sjkim } 392280304Sjkim break; 393160814Ssimon 394280304Sjkim } 395160814Ssimon 396280304Sjkim return 1; 397160814Ssimon 398280304Sjkim} 399280304Sjkim 400160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 401280304Sjkim{ 402280304Sjkim char erch[2]; 403280304Sjkim long tag_num; 404280304Sjkim char *eptr; 405280304Sjkim if (!vstart) 406280304Sjkim return 0; 407280304Sjkim tag_num = strtoul(vstart, &eptr, 10); 408280304Sjkim /* Check we haven't gone past max length: should be impossible */ 409280304Sjkim if (eptr && *eptr && (eptr > vstart + vlen)) 410280304Sjkim return 0; 411280304Sjkim if (tag_num < 0) { 412280304Sjkim ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); 413280304Sjkim return 0; 414280304Sjkim } 415280304Sjkim *ptag = tag_num; 416280304Sjkim /* If we have non numeric characters, parse them */ 417280304Sjkim if (eptr) 418280304Sjkim vlen -= eptr - vstart; 419280304Sjkim else 420280304Sjkim vlen = 0; 421280304Sjkim if (vlen) { 422280304Sjkim switch (*eptr) { 423160814Ssimon 424280304Sjkim case 'U': 425280304Sjkim *pclass = V_ASN1_UNIVERSAL; 426280304Sjkim break; 427160814Ssimon 428280304Sjkim case 'A': 429280304Sjkim *pclass = V_ASN1_APPLICATION; 430280304Sjkim break; 431160814Ssimon 432280304Sjkim case 'P': 433280304Sjkim *pclass = V_ASN1_PRIVATE; 434280304Sjkim break; 435160814Ssimon 436280304Sjkim case 'C': 437280304Sjkim *pclass = V_ASN1_CONTEXT_SPECIFIC; 438280304Sjkim break; 439160814Ssimon 440280304Sjkim default: 441280304Sjkim erch[0] = *eptr; 442280304Sjkim erch[1] = 0; 443280304Sjkim ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); 444280304Sjkim ERR_add_error_data(2, "Char=", erch); 445280304Sjkim return 0; 446280304Sjkim break; 447160814Ssimon 448280304Sjkim } 449280304Sjkim } else 450280304Sjkim *pclass = V_ASN1_CONTEXT_SPECIFIC; 451160814Ssimon 452280304Sjkim return 1; 453160814Ssimon 454280304Sjkim} 455160814Ssimon 456160814Ssimon/* Handle multiple types: SET and SEQUENCE */ 457160814Ssimon 458284285Sjkimstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 459284285Sjkim int depth, int *perr) 460280304Sjkim{ 461280304Sjkim ASN1_TYPE *ret = NULL; 462280304Sjkim STACK_OF(ASN1_TYPE) *sk = NULL; 463280304Sjkim STACK_OF(CONF_VALUE) *sect = NULL; 464280304Sjkim unsigned char *der = NULL; 465280304Sjkim int derlen; 466280304Sjkim int i; 467280304Sjkim sk = sk_ASN1_TYPE_new_null(); 468280304Sjkim if (!sk) 469280304Sjkim goto bad; 470280304Sjkim if (section) { 471280304Sjkim if (!cnf) 472280304Sjkim goto bad; 473280304Sjkim sect = X509V3_get_section(cnf, (char *)section); 474280304Sjkim if (!sect) 475280304Sjkim goto bad; 476280304Sjkim for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 477280304Sjkim ASN1_TYPE *typ = 478284285Sjkim generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, 479284285Sjkim depth + 1, perr); 480280304Sjkim if (!typ) 481280304Sjkim goto bad; 482280304Sjkim if (!sk_ASN1_TYPE_push(sk, typ)) 483280304Sjkim goto bad; 484280304Sjkim } 485280304Sjkim } 486160814Ssimon 487280304Sjkim /* 488280304Sjkim * Now we has a STACK of the components, convert to the correct form 489280304Sjkim */ 490160814Ssimon 491280304Sjkim if (utype == V_ASN1_SET) 492280304Sjkim derlen = i2d_ASN1_SET_ANY(sk, &der); 493280304Sjkim else 494280304Sjkim derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 495160814Ssimon 496280304Sjkim if (derlen < 0) 497280304Sjkim goto bad; 498160814Ssimon 499280304Sjkim if (!(ret = ASN1_TYPE_new())) 500280304Sjkim goto bad; 501160814Ssimon 502280304Sjkim if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 503280304Sjkim goto bad; 504160814Ssimon 505280304Sjkim ret->type = utype; 506160814Ssimon 507280304Sjkim ret->value.asn1_string->data = der; 508280304Sjkim ret->value.asn1_string->length = derlen; 509160814Ssimon 510280304Sjkim der = NULL; 511160814Ssimon 512280304Sjkim bad: 513160814Ssimon 514280304Sjkim if (der) 515280304Sjkim OPENSSL_free(der); 516160814Ssimon 517280304Sjkim if (sk) 518280304Sjkim sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 519280304Sjkim if (sect) 520280304Sjkim X509V3_section_free(cnf, sect); 521160814Ssimon 522280304Sjkim return ret; 523280304Sjkim} 524160814Ssimon 525280304Sjkimstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 526280304Sjkim int exp_constructed, int exp_pad, int imp_ok) 527280304Sjkim{ 528280304Sjkim tag_exp_type *exp_tmp; 529280304Sjkim /* Can only have IMPLICIT if permitted */ 530280304Sjkim if ((arg->imp_tag != -1) && !imp_ok) { 531280304Sjkim ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); 532280304Sjkim return 0; 533280304Sjkim } 534160814Ssimon 535280304Sjkim if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 536280304Sjkim ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); 537280304Sjkim return 0; 538280304Sjkim } 539160814Ssimon 540280304Sjkim exp_tmp = &arg->exp_list[arg->exp_count++]; 541160814Ssimon 542280304Sjkim /* 543280304Sjkim * If IMPLICIT set tag to implicit value then reset implicit tag since it 544280304Sjkim * has been used. 545280304Sjkim */ 546280304Sjkim if (arg->imp_tag != -1) { 547280304Sjkim exp_tmp->exp_tag = arg->imp_tag; 548280304Sjkim exp_tmp->exp_class = arg->imp_class; 549280304Sjkim arg->imp_tag = -1; 550280304Sjkim arg->imp_class = -1; 551280304Sjkim } else { 552280304Sjkim exp_tmp->exp_tag = exp_tag; 553280304Sjkim exp_tmp->exp_class = exp_class; 554280304Sjkim } 555280304Sjkim exp_tmp->exp_constructed = exp_constructed; 556280304Sjkim exp_tmp->exp_pad = exp_pad; 557160814Ssimon 558280304Sjkim return 1; 559280304Sjkim} 560160814Ssimon 561160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len) 562280304Sjkim{ 563280304Sjkim unsigned int i; 564280304Sjkim static const struct tag_name_st *tntmp, tnst[] = { 565280304Sjkim ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 566280304Sjkim ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 567280304Sjkim ASN1_GEN_STR("NULL", V_ASN1_NULL), 568280304Sjkim ASN1_GEN_STR("INT", V_ASN1_INTEGER), 569280304Sjkim ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 570280304Sjkim ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 571280304Sjkim ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 572280304Sjkim ASN1_GEN_STR("OID", V_ASN1_OBJECT), 573280304Sjkim ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 574280304Sjkim ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 575280304Sjkim ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 576280304Sjkim ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 577280304Sjkim ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 578280304Sjkim ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 579280304Sjkim ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 580280304Sjkim ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 581280304Sjkim ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 582280304Sjkim ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 583280304Sjkim ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 584280304Sjkim ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 585280304Sjkim ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 586280304Sjkim ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 587280304Sjkim ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 588280304Sjkim ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 589280304Sjkim ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 590280304Sjkim ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 591280304Sjkim ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 592280304Sjkim ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 593280304Sjkim ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 594280304Sjkim ASN1_GEN_STR("T61", V_ASN1_T61STRING), 595280304Sjkim ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 596280304Sjkim ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 597280304Sjkim ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 598280304Sjkim ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 599280304Sjkim ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 600280304Sjkim ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 601160814Ssimon 602280304Sjkim /* Special cases */ 603280304Sjkim ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 604280304Sjkim ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 605280304Sjkim ASN1_GEN_STR("SET", V_ASN1_SET), 606280304Sjkim /* type modifiers */ 607280304Sjkim /* Explicit tag */ 608280304Sjkim ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 609280304Sjkim ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 610280304Sjkim /* Implicit tag */ 611280304Sjkim ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 612280304Sjkim ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 613280304Sjkim /* OCTET STRING wrapper */ 614280304Sjkim ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 615280304Sjkim /* SEQUENCE wrapper */ 616280304Sjkim ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 617280304Sjkim /* SET wrapper */ 618280304Sjkim ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 619280304Sjkim /* BIT STRING wrapper */ 620280304Sjkim ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 621280304Sjkim ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 622280304Sjkim ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 623280304Sjkim }; 624160814Ssimon 625280304Sjkim if (len == -1) 626280304Sjkim len = strlen(tagstr); 627160814Ssimon 628280304Sjkim tntmp = tnst; 629280304Sjkim for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { 630280304Sjkim if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 631280304Sjkim return tntmp->tag; 632280304Sjkim } 633160814Ssimon 634280304Sjkim return -1; 635280304Sjkim} 636160814Ssimon 637280304Sjkimstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 638280304Sjkim{ 639280304Sjkim ASN1_TYPE *atmp = NULL; 640160814Ssimon 641280304Sjkim CONF_VALUE vtmp; 642160814Ssimon 643280304Sjkim unsigned char *rdata; 644280304Sjkim long rdlen; 645160814Ssimon 646280304Sjkim int no_unused = 1; 647160814Ssimon 648280304Sjkim if (!(atmp = ASN1_TYPE_new())) { 649280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 650280304Sjkim return NULL; 651280304Sjkim } 652160814Ssimon 653280304Sjkim if (!str) 654280304Sjkim str = ""; 655160814Ssimon 656280304Sjkim switch (utype) { 657160814Ssimon 658280304Sjkim case V_ASN1_NULL: 659280304Sjkim if (str && *str) { 660280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); 661280304Sjkim goto bad_form; 662280304Sjkim } 663280304Sjkim break; 664160814Ssimon 665280304Sjkim case V_ASN1_BOOLEAN: 666280304Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 667280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); 668280304Sjkim goto bad_form; 669280304Sjkim } 670280304Sjkim vtmp.name = NULL; 671280304Sjkim vtmp.section = NULL; 672280304Sjkim vtmp.value = (char *)str; 673280304Sjkim if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 674280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); 675280304Sjkim goto bad_str; 676280304Sjkim } 677280304Sjkim break; 678160814Ssimon 679280304Sjkim case V_ASN1_INTEGER: 680280304Sjkim case V_ASN1_ENUMERATED: 681280304Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 682280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 683280304Sjkim goto bad_form; 684280304Sjkim } 685280304Sjkim if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { 686280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); 687280304Sjkim goto bad_str; 688280304Sjkim } 689280304Sjkim break; 690160814Ssimon 691280304Sjkim case V_ASN1_OBJECT: 692280304Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 693280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 694280304Sjkim goto bad_form; 695280304Sjkim } 696280304Sjkim if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { 697280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); 698280304Sjkim goto bad_str; 699280304Sjkim } 700280304Sjkim break; 701160814Ssimon 702280304Sjkim case V_ASN1_UTCTIME: 703280304Sjkim case V_ASN1_GENERALIZEDTIME: 704280304Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 705280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); 706280304Sjkim goto bad_form; 707280304Sjkim } 708280304Sjkim if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 709280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 710280304Sjkim goto bad_str; 711280304Sjkim } 712280304Sjkim if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 713280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 714280304Sjkim goto bad_str; 715280304Sjkim } 716280304Sjkim atmp->value.asn1_string->type = utype; 717280304Sjkim if (!ASN1_TIME_check(atmp->value.asn1_string)) { 718280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); 719280304Sjkim goto bad_str; 720280304Sjkim } 721160814Ssimon 722280304Sjkim break; 723160814Ssimon 724280304Sjkim case V_ASN1_BMPSTRING: 725280304Sjkim case V_ASN1_PRINTABLESTRING: 726280304Sjkim case V_ASN1_IA5STRING: 727280304Sjkim case V_ASN1_T61STRING: 728280304Sjkim case V_ASN1_UTF8STRING: 729280304Sjkim case V_ASN1_VISIBLESTRING: 730280304Sjkim case V_ASN1_UNIVERSALSTRING: 731280304Sjkim case V_ASN1_GENERALSTRING: 732280304Sjkim case V_ASN1_NUMERICSTRING: 733160814Ssimon 734280304Sjkim if (format == ASN1_GEN_FORMAT_ASCII) 735280304Sjkim format = MBSTRING_ASC; 736280304Sjkim else if (format == ASN1_GEN_FORMAT_UTF8) 737280304Sjkim format = MBSTRING_UTF8; 738280304Sjkim else { 739280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); 740280304Sjkim goto bad_form; 741280304Sjkim } 742160814Ssimon 743280304Sjkim if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 744280304Sjkim -1, format, ASN1_tag2bit(utype)) <= 0) { 745280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 746280304Sjkim goto bad_str; 747280304Sjkim } 748160814Ssimon 749280304Sjkim break; 750160814Ssimon 751280304Sjkim case V_ASN1_BIT_STRING: 752160814Ssimon 753280304Sjkim case V_ASN1_OCTET_STRING: 754160814Ssimon 755280304Sjkim if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 756280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 757280304Sjkim goto bad_form; 758280304Sjkim } 759160814Ssimon 760280304Sjkim if (format == ASN1_GEN_FORMAT_HEX) { 761160814Ssimon 762280304Sjkim if (!(rdata = string_to_hex((char *)str, &rdlen))) { 763280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); 764280304Sjkim goto bad_str; 765280304Sjkim } 766160814Ssimon 767280304Sjkim atmp->value.asn1_string->data = rdata; 768280304Sjkim atmp->value.asn1_string->length = rdlen; 769280304Sjkim atmp->value.asn1_string->type = utype; 770160814Ssimon 771280304Sjkim } else if (format == ASN1_GEN_FORMAT_ASCII) 772280304Sjkim ASN1_STRING_set(atmp->value.asn1_string, str, -1); 773280304Sjkim else if ((format == ASN1_GEN_FORMAT_BITLIST) 774280304Sjkim && (utype == V_ASN1_BIT_STRING)) { 775280304Sjkim if (!CONF_parse_list 776280304Sjkim (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 777280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); 778280304Sjkim goto bad_str; 779280304Sjkim } 780280304Sjkim no_unused = 0; 781160814Ssimon 782280304Sjkim } else { 783280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 784280304Sjkim goto bad_form; 785280304Sjkim } 786160814Ssimon 787280304Sjkim if ((utype == V_ASN1_BIT_STRING) && no_unused) { 788280304Sjkim atmp->value.asn1_string->flags 789280304Sjkim &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 790280304Sjkim atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 791280304Sjkim } 792160814Ssimon 793280304Sjkim break; 794160814Ssimon 795280304Sjkim default: 796280304Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); 797280304Sjkim goto bad_str; 798280304Sjkim break; 799280304Sjkim } 800160814Ssimon 801280304Sjkim atmp->type = utype; 802280304Sjkim return atmp; 803160814Ssimon 804280304Sjkim bad_str: 805280304Sjkim ERR_add_error_data(2, "string=", str); 806280304Sjkim bad_form: 807160814Ssimon 808280304Sjkim ASN1_TYPE_free(atmp); 809280304Sjkim return NULL; 810160814Ssimon 811280304Sjkim} 812160814Ssimon 813160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr) 814280304Sjkim{ 815280304Sjkim long bitnum; 816280304Sjkim char *eptr; 817280304Sjkim if (!elem) 818280304Sjkim return 0; 819280304Sjkim bitnum = strtoul(elem, &eptr, 10); 820280304Sjkim if (eptr && *eptr && (eptr != elem + len)) 821280304Sjkim return 0; 822280304Sjkim if (bitnum < 0) { 823280304Sjkim ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); 824280304Sjkim return 0; 825280304Sjkim } 826280304Sjkim if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 827280304Sjkim ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); 828280304Sjkim return 0; 829280304Sjkim } 830280304Sjkim return 1; 831280304Sjkim} 832