1160814Ssimon/* asn1_gen.c */ 2280297Sjkim/* 3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4280297Sjkim * 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 14280297Sjkim * 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 64280297Sjkim#define ASN1_GEN_FLAG 0x10000 65280297Sjkim#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 66280297Sjkim#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 67280297Sjkim#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 68280297Sjkim#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 69280297Sjkim#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 70280297Sjkim#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 71280297Sjkim#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 72280297Sjkim#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 73160814Ssimon 74280297Sjkim#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 75160814Ssimon 76280297Sjkim#define ASN1_FLAG_EXP_MAX 20 77284283Sjkim/* Maximum number of nested sequences */ 78284283Sjkim#define ASN1_GEN_SEQ_MAX_DEPTH 50 79160814Ssimon 80160814Ssimon/* Input formats */ 81160814Ssimon 82160814Ssimon/* ASCII: default */ 83280297Sjkim#define ASN1_GEN_FORMAT_ASCII 1 84160814Ssimon/* UTF8 */ 85280297Sjkim#define ASN1_GEN_FORMAT_UTF8 2 86160814Ssimon/* Hex */ 87280297Sjkim#define ASN1_GEN_FORMAT_HEX 3 88160814Ssimon/* List of bits */ 89280297Sjkim#define ASN1_GEN_FORMAT_BITLIST 4 90160814Ssimon 91280297Sjkimstruct tag_name_st { 92280297Sjkim const char *strnam; 93280297Sjkim int len; 94280297Sjkim int tag; 95280297Sjkim}; 96160814Ssimon 97280297Sjkimtypedef struct { 98280297Sjkim int exp_tag; 99280297Sjkim int exp_class; 100280297Sjkim int exp_constructed; 101280297Sjkim int exp_pad; 102280297Sjkim long exp_len; 103280297Sjkim} tag_exp_type; 104160814Ssimon 105280297Sjkimtypedef struct { 106280297Sjkim int imp_tag; 107280297Sjkim int imp_class; 108280297Sjkim int utype; 109280297Sjkim int format; 110280297Sjkim const char *str; 111280297Sjkim tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 112280297Sjkim int exp_count; 113280297Sjkim} tag_exp_arg; 114160814Ssimon 115284283Sjkimstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 116284283Sjkim int *perr); 117160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr); 118160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr); 119280297Sjkimstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 120280297Sjkim int exp_constructed, int exp_pad, int imp_ok); 121280297Sjkimstatic int parse_tagging(const char *vstart, int vlen, int *ptag, 122280297Sjkim int *pclass); 123284283Sjkimstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 124284283Sjkim 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) 129280297Sjkim{ 130280297Sjkim X509V3_CTX cnf; 131160814Ssimon 132280297Sjkim if (!nconf) 133280297Sjkim return ASN1_generate_v3(str, NULL); 134160814Ssimon 135280297Sjkim X509V3_set_nconf(&cnf, nconf); 136280297Sjkim return ASN1_generate_v3(str, &cnf); 137280297Sjkim} 138160814Ssimon 139160814SsimonASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 140280297Sjkim{ 141284283Sjkim int err = 0; 142284283Sjkim ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); 143284283Sjkim if (err) 144284283Sjkim ASN1err(ASN1_F_ASN1_GENERATE_V3, err); 145284283Sjkim return ret; 146284283Sjkim} 147284283Sjkim 148284283Sjkimstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 149284283Sjkim int *perr) 150284283Sjkim{ 151280297Sjkim ASN1_TYPE *ret; 152280297Sjkim tag_exp_arg asn1_tags; 153280297Sjkim tag_exp_type *etmp; 154160814Ssimon 155280297Sjkim int i, len; 156160814Ssimon 157280297Sjkim unsigned char *orig_der = NULL, *new_der = NULL; 158280297Sjkim const unsigned char *cpy_start; 159280297Sjkim unsigned char *p; 160280297Sjkim const unsigned char *cp; 161280297Sjkim int cpy_len; 162280297Sjkim long hdr_len; 163280297Sjkim int hdr_constructed = 0, hdr_tag, hdr_class; 164280297Sjkim int r; 165160814Ssimon 166280297Sjkim asn1_tags.imp_tag = -1; 167280297Sjkim asn1_tags.imp_class = -1; 168280297Sjkim asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 169280297Sjkim asn1_tags.exp_count = 0; 170284283Sjkim if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { 171284283Sjkim *perr = ASN1_R_UNKNOWN_TAG; 172280297Sjkim return NULL; 173284283Sjkim } 174160814Ssimon 175280297Sjkim if ((asn1_tags.utype == V_ASN1_SEQUENCE) 176280297Sjkim || (asn1_tags.utype == V_ASN1_SET)) { 177280297Sjkim if (!cnf) { 178284283Sjkim *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; 179280297Sjkim return NULL; 180280297Sjkim } 181284283Sjkim if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { 182284283Sjkim *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; 183284283Sjkim return NULL; 184284283Sjkim } 185284283Sjkim ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); 186280297Sjkim } else 187280297Sjkim ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 188160814Ssimon 189280297Sjkim if (!ret) 190280297Sjkim return NULL; 191160814Ssimon 192280297Sjkim /* If no tagging return base type */ 193280297Sjkim if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 194280297Sjkim return ret; 195160814Ssimon 196280297Sjkim /* Generate the encoding */ 197280297Sjkim cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 198280297Sjkim ASN1_TYPE_free(ret); 199280297Sjkim ret = NULL; 200280297Sjkim /* Set point to start copying for modified encoding */ 201280297Sjkim cpy_start = orig_der; 202160814Ssimon 203280297Sjkim /* Do we need IMPLICIT tagging? */ 204280297Sjkim if (asn1_tags.imp_tag != -1) { 205280297Sjkim /* If IMPLICIT we will replace the underlying tag */ 206280297Sjkim /* Skip existing tag+len */ 207280297Sjkim r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 208280297Sjkim cpy_len); 209280297Sjkim if (r & 0x80) 210280297Sjkim goto err; 211280297Sjkim /* Update copy length */ 212280297Sjkim cpy_len -= cpy_start - orig_der; 213280297Sjkim /* 214280297Sjkim * For IMPLICIT tagging the length should match the original length 215280297Sjkim * and constructed flag should be consistent. 216280297Sjkim */ 217280297Sjkim if (r & 0x1) { 218280297Sjkim /* Indefinite length constructed */ 219280297Sjkim hdr_constructed = 2; 220280297Sjkim hdr_len = 0; 221280297Sjkim } else 222280297Sjkim /* Just retain constructed flag */ 223280297Sjkim hdr_constructed = r & V_ASN1_CONSTRUCTED; 224280297Sjkim /* 225280297Sjkim * Work out new length with IMPLICIT tag: ignore constructed because 226280297Sjkim * it will mess up if indefinite length 227280297Sjkim */ 228280297Sjkim len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 229280297Sjkim } else 230280297Sjkim len = cpy_len; 231160814Ssimon 232280297Sjkim /* Work out length in any EXPLICIT, starting from end */ 233160814Ssimon 234280297Sjkim for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 235280297Sjkim i < asn1_tags.exp_count; i++, etmp--) { 236280297Sjkim /* Content length: number of content octets + any padding */ 237280297Sjkim len += etmp->exp_pad; 238280297Sjkim etmp->exp_len = len; 239280297Sjkim /* Total object length: length including new header */ 240280297Sjkim len = ASN1_object_size(0, len, etmp->exp_tag); 241280297Sjkim } 242160814Ssimon 243280297Sjkim /* Allocate buffer for new encoding */ 244160814Ssimon 245280297Sjkim new_der = OPENSSL_malloc(len); 246280297Sjkim if (!new_der) 247280297Sjkim goto err; 248160814Ssimon 249280297Sjkim /* Generate tagged encoding */ 250160814Ssimon 251280297Sjkim p = new_der; 252160814Ssimon 253280297Sjkim /* Output explicit tags first */ 254160814Ssimon 255280297Sjkim for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 256280297Sjkim i++, etmp++) { 257280297Sjkim ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 258280297Sjkim etmp->exp_tag, etmp->exp_class); 259280297Sjkim if (etmp->exp_pad) 260280297Sjkim *p++ = 0; 261280297Sjkim } 262160814Ssimon 263280297Sjkim /* If IMPLICIT, output tag */ 264160814Ssimon 265280297Sjkim if (asn1_tags.imp_tag != -1) { 266280297Sjkim if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 267280297Sjkim && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 268280297Sjkim || asn1_tags.imp_tag == V_ASN1_SET)) 269280297Sjkim hdr_constructed = V_ASN1_CONSTRUCTED; 270280297Sjkim ASN1_put_object(&p, hdr_constructed, hdr_len, 271280297Sjkim asn1_tags.imp_tag, asn1_tags.imp_class); 272280297Sjkim } 273160814Ssimon 274280297Sjkim /* Copy across original encoding */ 275280297Sjkim memcpy(p, cpy_start, cpy_len); 276160814Ssimon 277280297Sjkim cp = new_der; 278160814Ssimon 279280297Sjkim /* Obtain new ASN1_TYPE structure */ 280280297Sjkim ret = d2i_ASN1_TYPE(NULL, &cp, len); 281160814Ssimon 282280297Sjkim err: 283280297Sjkim if (orig_der) 284280297Sjkim OPENSSL_free(orig_der); 285280297Sjkim if (new_der) 286280297Sjkim OPENSSL_free(new_der); 287160814Ssimon 288280297Sjkim return ret; 289160814Ssimon 290280297Sjkim} 291160814Ssimon 292160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr) 293280297Sjkim{ 294280297Sjkim tag_exp_arg *arg = bitstr; 295280297Sjkim int i; 296280297Sjkim int utype; 297280297Sjkim int vlen = 0; 298280297Sjkim const char *p, *vstart = NULL; 299160814Ssimon 300280297Sjkim int tmp_tag, tmp_class; 301160814Ssimon 302280297Sjkim if (elem == NULL) 303284283Sjkim return -1; 304160814Ssimon 305280297Sjkim for (i = 0, p = elem; i < len; p++, i++) { 306280297Sjkim /* Look for the ':' in name value pairs */ 307280297Sjkim if (*p == ':') { 308280297Sjkim vstart = p + 1; 309280297Sjkim vlen = len - (vstart - elem); 310280297Sjkim len = p - elem; 311280297Sjkim break; 312280297Sjkim } 313280297Sjkim } 314160814Ssimon 315280297Sjkim utype = asn1_str2tag(elem, len); 316160814Ssimon 317280297Sjkim if (utype == -1) { 318280297Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); 319280297Sjkim ERR_add_error_data(2, "tag=", elem); 320280297Sjkim return -1; 321280297Sjkim } 322160814Ssimon 323280297Sjkim /* If this is not a modifier mark end of string and exit */ 324280297Sjkim if (!(utype & ASN1_GEN_FLAG)) { 325280297Sjkim arg->utype = utype; 326280297Sjkim arg->str = vstart; 327280297Sjkim /* If no value and not end of string, error */ 328280297Sjkim if (!vstart && elem[len]) { 329280297Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); 330280297Sjkim return -1; 331280297Sjkim } 332280297Sjkim return 0; 333280297Sjkim } 334160814Ssimon 335280297Sjkim switch (utype) { 336160814Ssimon 337280297Sjkim case ASN1_GEN_FLAG_IMP: 338280297Sjkim /* Check for illegal multiple IMPLICIT tagging */ 339280297Sjkim if (arg->imp_tag != -1) { 340280297Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); 341280297Sjkim return -1; 342280297Sjkim } 343280297Sjkim if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 344280297Sjkim return -1; 345280297Sjkim break; 346160814Ssimon 347280297Sjkim case ASN1_GEN_FLAG_EXP: 348160814Ssimon 349280297Sjkim if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 350280297Sjkim return -1; 351280297Sjkim if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 352280297Sjkim return -1; 353280297Sjkim break; 354160814Ssimon 355280297Sjkim case ASN1_GEN_FLAG_SEQWRAP: 356280297Sjkim if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 357280297Sjkim return -1; 358280297Sjkim break; 359160814Ssimon 360280297Sjkim case ASN1_GEN_FLAG_SETWRAP: 361280297Sjkim if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 362280297Sjkim return -1; 363280297Sjkim break; 364160814Ssimon 365280297Sjkim case ASN1_GEN_FLAG_BITWRAP: 366280297Sjkim if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 367280297Sjkim return -1; 368280297Sjkim break; 369160814Ssimon 370280297Sjkim case ASN1_GEN_FLAG_OCTWRAP: 371280297Sjkim if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 372280297Sjkim return -1; 373280297Sjkim break; 374160814Ssimon 375280297Sjkim case ASN1_GEN_FLAG_FORMAT: 376284283Sjkim if (!vstart) { 377280297Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); 378280297Sjkim return -1; 379280297Sjkim } 380280297Sjkim if (!strncmp(vstart, "ASCII", 5)) 381280297Sjkim arg->format = ASN1_GEN_FORMAT_ASCII; 382280297Sjkim else if (!strncmp(vstart, "UTF8", 4)) 383280297Sjkim arg->format = ASN1_GEN_FORMAT_UTF8; 384280297Sjkim else if (!strncmp(vstart, "HEX", 3)) 385280297Sjkim arg->format = ASN1_GEN_FORMAT_HEX; 386280297Sjkim else if (!strncmp(vstart, "BITLIST", 7)) 387280297Sjkim arg->format = ASN1_GEN_FORMAT_BITLIST; 388280297Sjkim else { 389280297Sjkim ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); 390280297Sjkim return -1; 391280297Sjkim } 392280297Sjkim break; 393160814Ssimon 394280297Sjkim } 395160814Ssimon 396280297Sjkim return 1; 397160814Ssimon 398280297Sjkim} 399280297Sjkim 400160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 401280297Sjkim{ 402280297Sjkim char erch[2]; 403280297Sjkim long tag_num; 404280297Sjkim char *eptr; 405280297Sjkim if (!vstart) 406280297Sjkim return 0; 407280297Sjkim tag_num = strtoul(vstart, &eptr, 10); 408280297Sjkim /* Check we haven't gone past max length: should be impossible */ 409280297Sjkim if (eptr && *eptr && (eptr > vstart + vlen)) 410280297Sjkim return 0; 411280297Sjkim if (tag_num < 0) { 412280297Sjkim ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); 413280297Sjkim return 0; 414280297Sjkim } 415280297Sjkim *ptag = tag_num; 416280297Sjkim /* If we have non numeric characters, parse them */ 417280297Sjkim if (eptr) 418280297Sjkim vlen -= eptr - vstart; 419280297Sjkim else 420280297Sjkim vlen = 0; 421280297Sjkim if (vlen) { 422280297Sjkim switch (*eptr) { 423160814Ssimon 424280297Sjkim case 'U': 425280297Sjkim *pclass = V_ASN1_UNIVERSAL; 426280297Sjkim break; 427160814Ssimon 428280297Sjkim case 'A': 429280297Sjkim *pclass = V_ASN1_APPLICATION; 430280297Sjkim break; 431160814Ssimon 432280297Sjkim case 'P': 433280297Sjkim *pclass = V_ASN1_PRIVATE; 434280297Sjkim break; 435160814Ssimon 436280297Sjkim case 'C': 437280297Sjkim *pclass = V_ASN1_CONTEXT_SPECIFIC; 438280297Sjkim break; 439160814Ssimon 440280297Sjkim default: 441280297Sjkim erch[0] = *eptr; 442280297Sjkim erch[1] = 0; 443280297Sjkim ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); 444280297Sjkim ERR_add_error_data(2, "Char=", erch); 445280297Sjkim return 0; 446280297Sjkim break; 447160814Ssimon 448280297Sjkim } 449280297Sjkim } else 450280297Sjkim *pclass = V_ASN1_CONTEXT_SPECIFIC; 451160814Ssimon 452280297Sjkim return 1; 453160814Ssimon 454280297Sjkim} 455160814Ssimon 456160814Ssimon/* Handle multiple types: SET and SEQUENCE */ 457160814Ssimon 458284283Sjkimstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 459284283Sjkim int depth, int *perr) 460280297Sjkim{ 461280297Sjkim ASN1_TYPE *ret = NULL; 462280297Sjkim STACK_OF(ASN1_TYPE) *sk = NULL; 463280297Sjkim STACK_OF(CONF_VALUE) *sect = NULL; 464280297Sjkim unsigned char *der = NULL; 465280297Sjkim int derlen; 466280297Sjkim int i; 467280297Sjkim sk = sk_ASN1_TYPE_new_null(); 468280297Sjkim if (!sk) 469280297Sjkim goto bad; 470280297Sjkim if (section) { 471280297Sjkim if (!cnf) 472280297Sjkim goto bad; 473280297Sjkim sect = X509V3_get_section(cnf, (char *)section); 474280297Sjkim if (!sect) 475280297Sjkim goto bad; 476280297Sjkim for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 477280297Sjkim ASN1_TYPE *typ = 478284283Sjkim generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, 479284283Sjkim depth + 1, perr); 480280297Sjkim if (!typ) 481280297Sjkim goto bad; 482280297Sjkim if (!sk_ASN1_TYPE_push(sk, typ)) 483280297Sjkim goto bad; 484280297Sjkim } 485280297Sjkim } 486160814Ssimon 487280297Sjkim /* 488280297Sjkim * Now we has a STACK of the components, convert to the correct form 489280297Sjkim */ 490160814Ssimon 491280297Sjkim if (utype == V_ASN1_SET) 492280297Sjkim derlen = i2d_ASN1_SET_ANY(sk, &der); 493280297Sjkim else 494280297Sjkim derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 495160814Ssimon 496280297Sjkim if (derlen < 0) 497280297Sjkim goto bad; 498160814Ssimon 499280297Sjkim if (!(ret = ASN1_TYPE_new())) 500280297Sjkim goto bad; 501160814Ssimon 502280297Sjkim if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 503280297Sjkim goto bad; 504160814Ssimon 505280297Sjkim ret->type = utype; 506160814Ssimon 507280297Sjkim ret->value.asn1_string->data = der; 508280297Sjkim ret->value.asn1_string->length = derlen; 509160814Ssimon 510280297Sjkim der = NULL; 511160814Ssimon 512280297Sjkim bad: 513160814Ssimon 514280297Sjkim if (der) 515280297Sjkim OPENSSL_free(der); 516160814Ssimon 517280297Sjkim if (sk) 518280297Sjkim sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 519280297Sjkim if (sect) 520280297Sjkim X509V3_section_free(cnf, sect); 521160814Ssimon 522280297Sjkim return ret; 523280297Sjkim} 524160814Ssimon 525280297Sjkimstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 526280297Sjkim int exp_constructed, int exp_pad, int imp_ok) 527280297Sjkim{ 528280297Sjkim tag_exp_type *exp_tmp; 529280297Sjkim /* Can only have IMPLICIT if permitted */ 530280297Sjkim if ((arg->imp_tag != -1) && !imp_ok) { 531280297Sjkim ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); 532280297Sjkim return 0; 533280297Sjkim } 534160814Ssimon 535280297Sjkim if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 536280297Sjkim ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); 537280297Sjkim return 0; 538280297Sjkim } 539160814Ssimon 540280297Sjkim exp_tmp = &arg->exp_list[arg->exp_count++]; 541160814Ssimon 542280297Sjkim /* 543280297Sjkim * If IMPLICIT set tag to implicit value then reset implicit tag since it 544280297Sjkim * has been used. 545280297Sjkim */ 546280297Sjkim if (arg->imp_tag != -1) { 547280297Sjkim exp_tmp->exp_tag = arg->imp_tag; 548280297Sjkim exp_tmp->exp_class = arg->imp_class; 549280297Sjkim arg->imp_tag = -1; 550280297Sjkim arg->imp_class = -1; 551280297Sjkim } else { 552280297Sjkim exp_tmp->exp_tag = exp_tag; 553280297Sjkim exp_tmp->exp_class = exp_class; 554280297Sjkim } 555280297Sjkim exp_tmp->exp_constructed = exp_constructed; 556280297Sjkim exp_tmp->exp_pad = exp_pad; 557160814Ssimon 558280297Sjkim return 1; 559280297Sjkim} 560160814Ssimon 561160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len) 562280297Sjkim{ 563280297Sjkim unsigned int i; 564280297Sjkim static const struct tag_name_st *tntmp, tnst[] = { 565280297Sjkim ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 566280297Sjkim ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 567280297Sjkim ASN1_GEN_STR("NULL", V_ASN1_NULL), 568280297Sjkim ASN1_GEN_STR("INT", V_ASN1_INTEGER), 569280297Sjkim ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 570280297Sjkim ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 571280297Sjkim ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 572280297Sjkim ASN1_GEN_STR("OID", V_ASN1_OBJECT), 573280297Sjkim ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 574280297Sjkim ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 575280297Sjkim ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 576280297Sjkim ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 577280297Sjkim ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 578280297Sjkim ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 579280297Sjkim ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 580280297Sjkim ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 581280297Sjkim ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 582280297Sjkim ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 583280297Sjkim ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 584280297Sjkim ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 585280297Sjkim ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 586280297Sjkim ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 587280297Sjkim ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 588280297Sjkim ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 589280297Sjkim ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 590280297Sjkim ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 591280297Sjkim ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 592280297Sjkim ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 593280297Sjkim ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 594280297Sjkim ASN1_GEN_STR("T61", V_ASN1_T61STRING), 595280297Sjkim ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 596280297Sjkim ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 597280297Sjkim ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 598280297Sjkim ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 599280297Sjkim ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 600280297Sjkim ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 601160814Ssimon 602280297Sjkim /* Special cases */ 603280297Sjkim ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 604280297Sjkim ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 605280297Sjkim ASN1_GEN_STR("SET", V_ASN1_SET), 606280297Sjkim /* type modifiers */ 607280297Sjkim /* Explicit tag */ 608280297Sjkim ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 609280297Sjkim ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 610280297Sjkim /* Implicit tag */ 611280297Sjkim ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 612280297Sjkim ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 613280297Sjkim /* OCTET STRING wrapper */ 614280297Sjkim ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 615280297Sjkim /* SEQUENCE wrapper */ 616280297Sjkim ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 617280297Sjkim /* SET wrapper */ 618280297Sjkim ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 619280297Sjkim /* BIT STRING wrapper */ 620280297Sjkim ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 621280297Sjkim ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 622280297Sjkim ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 623280297Sjkim }; 624160814Ssimon 625280297Sjkim if (len == -1) 626280297Sjkim len = strlen(tagstr); 627160814Ssimon 628280297Sjkim tntmp = tnst; 629280297Sjkim for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { 630280297Sjkim if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 631280297Sjkim return tntmp->tag; 632280297Sjkim } 633160814Ssimon 634280297Sjkim return -1; 635280297Sjkim} 636160814Ssimon 637280297Sjkimstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 638280297Sjkim{ 639280297Sjkim ASN1_TYPE *atmp = NULL; 640160814Ssimon 641280297Sjkim CONF_VALUE vtmp; 642160814Ssimon 643280297Sjkim unsigned char *rdata; 644280297Sjkim long rdlen; 645160814Ssimon 646280297Sjkim int no_unused = 1; 647160814Ssimon 648280297Sjkim if (!(atmp = ASN1_TYPE_new())) { 649280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 650280297Sjkim return NULL; 651280297Sjkim } 652160814Ssimon 653280297Sjkim if (!str) 654280297Sjkim str = ""; 655160814Ssimon 656280297Sjkim switch (utype) { 657160814Ssimon 658280297Sjkim case V_ASN1_NULL: 659280297Sjkim if (str && *str) { 660280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); 661280297Sjkim goto bad_form; 662280297Sjkim } 663280297Sjkim break; 664160814Ssimon 665280297Sjkim case V_ASN1_BOOLEAN: 666280297Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 667280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); 668280297Sjkim goto bad_form; 669280297Sjkim } 670280297Sjkim vtmp.name = NULL; 671280297Sjkim vtmp.section = NULL; 672280297Sjkim vtmp.value = (char *)str; 673280297Sjkim if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 674280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); 675280297Sjkim goto bad_str; 676280297Sjkim } 677280297Sjkim break; 678160814Ssimon 679280297Sjkim case V_ASN1_INTEGER: 680280297Sjkim case V_ASN1_ENUMERATED: 681280297Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 682280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 683280297Sjkim goto bad_form; 684280297Sjkim } 685280297Sjkim if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { 686280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); 687280297Sjkim goto bad_str; 688280297Sjkim } 689280297Sjkim break; 690160814Ssimon 691280297Sjkim case V_ASN1_OBJECT: 692280297Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 693280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 694280297Sjkim goto bad_form; 695280297Sjkim } 696280297Sjkim if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { 697280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); 698280297Sjkim goto bad_str; 699280297Sjkim } 700280297Sjkim break; 701160814Ssimon 702280297Sjkim case V_ASN1_UTCTIME: 703280297Sjkim case V_ASN1_GENERALIZEDTIME: 704280297Sjkim if (format != ASN1_GEN_FORMAT_ASCII) { 705280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); 706280297Sjkim goto bad_form; 707280297Sjkim } 708280297Sjkim if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 709280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 710280297Sjkim goto bad_str; 711280297Sjkim } 712280297Sjkim if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 713280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 714280297Sjkim goto bad_str; 715280297Sjkim } 716280297Sjkim atmp->value.asn1_string->type = utype; 717280297Sjkim if (!ASN1_TIME_check(atmp->value.asn1_string)) { 718280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); 719280297Sjkim goto bad_str; 720280297Sjkim } 721160814Ssimon 722280297Sjkim break; 723160814Ssimon 724280297Sjkim case V_ASN1_BMPSTRING: 725280297Sjkim case V_ASN1_PRINTABLESTRING: 726280297Sjkim case V_ASN1_IA5STRING: 727280297Sjkim case V_ASN1_T61STRING: 728280297Sjkim case V_ASN1_UTF8STRING: 729280297Sjkim case V_ASN1_VISIBLESTRING: 730280297Sjkim case V_ASN1_UNIVERSALSTRING: 731280297Sjkim case V_ASN1_GENERALSTRING: 732280297Sjkim case V_ASN1_NUMERICSTRING: 733160814Ssimon 734280297Sjkim if (format == ASN1_GEN_FORMAT_ASCII) 735280297Sjkim format = MBSTRING_ASC; 736280297Sjkim else if (format == ASN1_GEN_FORMAT_UTF8) 737280297Sjkim format = MBSTRING_UTF8; 738280297Sjkim else { 739280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); 740280297Sjkim goto bad_form; 741280297Sjkim } 742160814Ssimon 743280297Sjkim if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 744280297Sjkim -1, format, ASN1_tag2bit(utype)) <= 0) { 745280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 746280297Sjkim goto bad_str; 747280297Sjkim } 748160814Ssimon 749280297Sjkim break; 750160814Ssimon 751280297Sjkim case V_ASN1_BIT_STRING: 752160814Ssimon 753280297Sjkim case V_ASN1_OCTET_STRING: 754160814Ssimon 755280297Sjkim if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 756280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 757280297Sjkim goto bad_form; 758280297Sjkim } 759160814Ssimon 760280297Sjkim if (format == ASN1_GEN_FORMAT_HEX) { 761160814Ssimon 762280297Sjkim if (!(rdata = string_to_hex((char *)str, &rdlen))) { 763280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); 764280297Sjkim goto bad_str; 765280297Sjkim } 766160814Ssimon 767280297Sjkim atmp->value.asn1_string->data = rdata; 768280297Sjkim atmp->value.asn1_string->length = rdlen; 769280297Sjkim atmp->value.asn1_string->type = utype; 770160814Ssimon 771280297Sjkim } else if (format == ASN1_GEN_FORMAT_ASCII) 772280297Sjkim ASN1_STRING_set(atmp->value.asn1_string, str, -1); 773280297Sjkim else if ((format == ASN1_GEN_FORMAT_BITLIST) 774280297Sjkim && (utype == V_ASN1_BIT_STRING)) { 775280297Sjkim if (!CONF_parse_list 776280297Sjkim (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 777280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); 778280297Sjkim goto bad_str; 779280297Sjkim } 780280297Sjkim no_unused = 0; 781160814Ssimon 782280297Sjkim } else { 783280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 784280297Sjkim goto bad_form; 785280297Sjkim } 786160814Ssimon 787280297Sjkim if ((utype == V_ASN1_BIT_STRING) && no_unused) { 788280297Sjkim atmp->value.asn1_string->flags 789280297Sjkim &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 790280297Sjkim atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 791280297Sjkim } 792160814Ssimon 793280297Sjkim break; 794160814Ssimon 795280297Sjkim default: 796280297Sjkim ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); 797280297Sjkim goto bad_str; 798280297Sjkim break; 799280297Sjkim } 800160814Ssimon 801280297Sjkim atmp->type = utype; 802280297Sjkim return atmp; 803160814Ssimon 804280297Sjkim bad_str: 805280297Sjkim ERR_add_error_data(2, "string=", str); 806280297Sjkim bad_form: 807160814Ssimon 808280297Sjkim ASN1_TYPE_free(atmp); 809280297Sjkim return NULL; 810160814Ssimon 811280297Sjkim} 812160814Ssimon 813160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr) 814280297Sjkim{ 815280297Sjkim long bitnum; 816280297Sjkim char *eptr; 817280297Sjkim if (!elem) 818280297Sjkim return 0; 819280297Sjkim bitnum = strtoul(elem, &eptr, 10); 820280297Sjkim if (eptr && *eptr && (eptr != elem + len)) 821280297Sjkim return 0; 822280297Sjkim if (bitnum < 0) { 823280297Sjkim ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); 824280297Sjkim return 0; 825280297Sjkim } 826280297Sjkim if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 827280297Sjkim ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); 828280297Sjkim return 0; 829280297Sjkim } 830280297Sjkim return 1; 831280297Sjkim} 832