1160814Ssimon/* asn1_gen.c */ 2194206Ssimon/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3160814Ssimon * project 2002. 4160814Ssimon */ 5160814Ssimon/* ==================================================================== 6160814Ssimon * Copyright (c) 2002 The OpenSSL Project. All rights reserved. 7160814Ssimon * 8160814Ssimon * Redistribution and use in source and binary forms, with or without 9160814Ssimon * modification, are permitted provided that the following conditions 10160814Ssimon * are met: 11160814Ssimon * 12160814Ssimon * 1. Redistributions of source code must retain the above copyright 13160814Ssimon * notice, this list of conditions and the following disclaimer. 14160814Ssimon * 15160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 16160814Ssimon * notice, this list of conditions and the following disclaimer in 17160814Ssimon * the documentation and/or other materials provided with the 18160814Ssimon * distribution. 19160814Ssimon * 20160814Ssimon * 3. All advertising materials mentioning features or use of this 21160814Ssimon * software must display the following acknowledgment: 22160814Ssimon * "This product includes software developed by the OpenSSL Project 23160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24160814Ssimon * 25160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26160814Ssimon * endorse or promote products derived from this software without 27160814Ssimon * prior written permission. For written permission, please contact 28160814Ssimon * licensing@OpenSSL.org. 29160814Ssimon * 30160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 31160814Ssimon * nor may "OpenSSL" appear in their names without prior written 32160814Ssimon * permission of the OpenSSL Project. 33160814Ssimon * 34160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 35160814Ssimon * acknowledgment: 36160814Ssimon * "This product includes software developed by the OpenSSL Project 37160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38160814Ssimon * 39160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 51160814Ssimon * ==================================================================== 52160814Ssimon * 53160814Ssimon * This product includes cryptographic software written by Eric Young 54160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 55160814Ssimon * Hudson (tjh@cryptsoft.com). 56160814Ssimon * 57160814Ssimon */ 58160814Ssimon 59160814Ssimon#include "cryptlib.h" 60160814Ssimon#include <openssl/asn1.h> 61160814Ssimon#include <openssl/x509v3.h> 62160814Ssimon 63160814Ssimon#define ASN1_GEN_FLAG 0x10000 64160814Ssimon#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 65160814Ssimon#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 66160814Ssimon#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 67160814Ssimon#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 68160814Ssimon#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 69160814Ssimon#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 70160814Ssimon#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 71160814Ssimon#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 72160814Ssimon 73160814Ssimon#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 74160814Ssimon 75160814Ssimon#define ASN1_FLAG_EXP_MAX 20 76160814Ssimon 77160814Ssimon/* Input formats */ 78160814Ssimon 79160814Ssimon/* ASCII: default */ 80160814Ssimon#define ASN1_GEN_FORMAT_ASCII 1 81160814Ssimon/* UTF8 */ 82160814Ssimon#define ASN1_GEN_FORMAT_UTF8 2 83160814Ssimon/* Hex */ 84160814Ssimon#define ASN1_GEN_FORMAT_HEX 3 85160814Ssimon/* List of bits */ 86160814Ssimon#define ASN1_GEN_FORMAT_BITLIST 4 87160814Ssimon 88160814Ssimon 89160814Ssimonstruct tag_name_st 90160814Ssimon { 91160814Ssimon const char *strnam; 92160814Ssimon int len; 93160814Ssimon int tag; 94160814Ssimon }; 95160814Ssimon 96160814Ssimontypedef struct 97160814Ssimon { 98160814Ssimon int exp_tag; 99160814Ssimon int exp_class; 100160814Ssimon int exp_constructed; 101160814Ssimon int exp_pad; 102160814Ssimon long exp_len; 103160814Ssimon } tag_exp_type; 104160814Ssimon 105160814Ssimontypedef struct 106160814Ssimon { 107160814Ssimon int imp_tag; 108160814Ssimon int imp_class; 109160814Ssimon int utype; 110160814Ssimon int format; 111160814Ssimon const char *str; 112160814Ssimon tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 113160814Ssimon int exp_count; 114160814Ssimon } tag_exp_arg; 115160814Ssimon 116160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr); 117160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr); 118160814Ssimonstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok); 119160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass); 120160814Ssimonstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf); 121160814Ssimonstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); 122160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len); 123160814Ssimon 124160814SsimonASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) 125160814Ssimon { 126160814Ssimon X509V3_CTX cnf; 127160814Ssimon 128160814Ssimon if (!nconf) 129160814Ssimon return ASN1_generate_v3(str, NULL); 130160814Ssimon 131160814Ssimon X509V3_set_nconf(&cnf, nconf); 132160814Ssimon return ASN1_generate_v3(str, &cnf); 133160814Ssimon } 134160814Ssimon 135160814SsimonASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 136160814Ssimon { 137160814Ssimon ASN1_TYPE *ret; 138160814Ssimon tag_exp_arg asn1_tags; 139160814Ssimon tag_exp_type *etmp; 140160814Ssimon 141160814Ssimon int i, len; 142160814Ssimon 143160814Ssimon unsigned char *orig_der = NULL, *new_der = NULL; 144160814Ssimon const unsigned char *cpy_start; 145160814Ssimon unsigned char *p; 146160814Ssimon const unsigned char *cp; 147160814Ssimon int cpy_len; 148160814Ssimon long hdr_len; 149160814Ssimon int hdr_constructed = 0, hdr_tag, hdr_class; 150160814Ssimon int r; 151160814Ssimon 152160814Ssimon asn1_tags.imp_tag = -1; 153160814Ssimon asn1_tags.imp_class = -1; 154160814Ssimon asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 155160814Ssimon asn1_tags.exp_count = 0; 156160814Ssimon if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) 157160814Ssimon return NULL; 158160814Ssimon 159160814Ssimon if ((asn1_tags.utype == V_ASN1_SEQUENCE) || (asn1_tags.utype == V_ASN1_SET)) 160160814Ssimon { 161160814Ssimon if (!cnf) 162160814Ssimon { 163160814Ssimon ASN1err(ASN1_F_ASN1_GENERATE_V3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); 164160814Ssimon return NULL; 165160814Ssimon } 166160814Ssimon ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf); 167160814Ssimon } 168160814Ssimon else 169160814Ssimon ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 170160814Ssimon 171160814Ssimon if (!ret) 172160814Ssimon return NULL; 173160814Ssimon 174160814Ssimon /* If no tagging return base type */ 175160814Ssimon if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 176160814Ssimon return ret; 177160814Ssimon 178160814Ssimon /* Generate the encoding */ 179160814Ssimon cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 180160814Ssimon ASN1_TYPE_free(ret); 181160814Ssimon ret = NULL; 182160814Ssimon /* Set point to start copying for modified encoding */ 183160814Ssimon cpy_start = orig_der; 184160814Ssimon 185160814Ssimon /* Do we need IMPLICIT tagging? */ 186160814Ssimon if (asn1_tags.imp_tag != -1) 187160814Ssimon { 188160814Ssimon /* If IMPLICIT we will replace the underlying tag */ 189160814Ssimon /* Skip existing tag+len */ 190160814Ssimon r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, cpy_len); 191160814Ssimon if (r & 0x80) 192160814Ssimon goto err; 193160814Ssimon /* Update copy length */ 194160814Ssimon cpy_len -= cpy_start - orig_der; 195160814Ssimon /* For IMPLICIT tagging the length should match the 196160814Ssimon * original length and constructed flag should be 197160814Ssimon * consistent. 198160814Ssimon */ 199160814Ssimon if (r & 0x1) 200160814Ssimon { 201160814Ssimon /* Indefinite length constructed */ 202160814Ssimon hdr_constructed = 2; 203160814Ssimon hdr_len = 0; 204160814Ssimon } 205160814Ssimon else 206160814Ssimon /* Just retain constructed flag */ 207160814Ssimon hdr_constructed = r & V_ASN1_CONSTRUCTED; 208160814Ssimon /* Work out new length with IMPLICIT tag: ignore constructed 209160814Ssimon * because it will mess up if indefinite length 210160814Ssimon */ 211160814Ssimon len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 212160814Ssimon } 213160814Ssimon else 214160814Ssimon len = cpy_len; 215160814Ssimon 216160814Ssimon /* Work out length in any EXPLICIT, starting from end */ 217160814Ssimon 218160814Ssimon for(i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; i < asn1_tags.exp_count; i++, etmp--) 219160814Ssimon { 220160814Ssimon /* Content length: number of content octets + any padding */ 221160814Ssimon len += etmp->exp_pad; 222160814Ssimon etmp->exp_len = len; 223160814Ssimon /* Total object length: length including new header */ 224160814Ssimon len = ASN1_object_size(0, len, etmp->exp_tag); 225160814Ssimon } 226160814Ssimon 227160814Ssimon /* Allocate buffer for new encoding */ 228160814Ssimon 229160814Ssimon new_der = OPENSSL_malloc(len); 230205128Ssimon if (!new_der) 231205128Ssimon goto err; 232160814Ssimon 233160814Ssimon /* Generate tagged encoding */ 234160814Ssimon 235160814Ssimon p = new_der; 236160814Ssimon 237160814Ssimon /* Output explicit tags first */ 238160814Ssimon 239160814Ssimon for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; i++, etmp++) 240160814Ssimon { 241160814Ssimon ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 242160814Ssimon etmp->exp_tag, etmp->exp_class); 243160814Ssimon if (etmp->exp_pad) 244160814Ssimon *p++ = 0; 245160814Ssimon } 246160814Ssimon 247160814Ssimon /* If IMPLICIT, output tag */ 248160814Ssimon 249160814Ssimon if (asn1_tags.imp_tag != -1) 250238405Sjkim { 251238405Sjkim if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 252238405Sjkim && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 253238405Sjkim || asn1_tags.imp_tag == V_ASN1_SET) ) 254238405Sjkim hdr_constructed = V_ASN1_CONSTRUCTED; 255160814Ssimon ASN1_put_object(&p, hdr_constructed, hdr_len, 256160814Ssimon asn1_tags.imp_tag, asn1_tags.imp_class); 257238405Sjkim } 258160814Ssimon 259160814Ssimon /* Copy across original encoding */ 260160814Ssimon memcpy(p, cpy_start, cpy_len); 261160814Ssimon 262160814Ssimon cp = new_der; 263160814Ssimon 264160814Ssimon /* Obtain new ASN1_TYPE structure */ 265160814Ssimon ret = d2i_ASN1_TYPE(NULL, &cp, len); 266160814Ssimon 267160814Ssimon err: 268160814Ssimon if (orig_der) 269160814Ssimon OPENSSL_free(orig_der); 270160814Ssimon if (new_der) 271160814Ssimon OPENSSL_free(new_der); 272160814Ssimon 273160814Ssimon return ret; 274160814Ssimon 275160814Ssimon } 276160814Ssimon 277160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr) 278160814Ssimon { 279160814Ssimon tag_exp_arg *arg = bitstr; 280160814Ssimon int i; 281160814Ssimon int utype; 282160814Ssimon int vlen = 0; 283160814Ssimon const char *p, *vstart = NULL; 284160814Ssimon 285160814Ssimon int tmp_tag, tmp_class; 286160814Ssimon 287160814Ssimon for(i = 0, p = elem; i < len; p++, i++) 288160814Ssimon { 289160814Ssimon /* Look for the ':' in name value pairs */ 290160814Ssimon if (*p == ':') 291160814Ssimon { 292160814Ssimon vstart = p + 1; 293160814Ssimon vlen = len - (vstart - elem); 294160814Ssimon len = p - elem; 295160814Ssimon break; 296160814Ssimon } 297160814Ssimon } 298160814Ssimon 299160814Ssimon utype = asn1_str2tag(elem, len); 300160814Ssimon 301160814Ssimon if (utype == -1) 302160814Ssimon { 303160814Ssimon ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); 304160814Ssimon ERR_add_error_data(2, "tag=", elem); 305160814Ssimon return -1; 306160814Ssimon } 307160814Ssimon 308160814Ssimon /* If this is not a modifier mark end of string and exit */ 309160814Ssimon if (!(utype & ASN1_GEN_FLAG)) 310160814Ssimon { 311160814Ssimon arg->utype = utype; 312160814Ssimon arg->str = vstart; 313160814Ssimon /* If no value and not end of string, error */ 314160814Ssimon if (!vstart && elem[len]) 315160814Ssimon { 316160814Ssimon ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); 317160814Ssimon return -1; 318160814Ssimon } 319160814Ssimon return 0; 320160814Ssimon } 321160814Ssimon 322160814Ssimon switch(utype) 323160814Ssimon { 324160814Ssimon 325160814Ssimon case ASN1_GEN_FLAG_IMP: 326160814Ssimon /* Check for illegal multiple IMPLICIT tagging */ 327160814Ssimon if (arg->imp_tag != -1) 328160814Ssimon { 329160814Ssimon ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); 330160814Ssimon return -1; 331160814Ssimon } 332160814Ssimon if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 333160814Ssimon return -1; 334160814Ssimon break; 335160814Ssimon 336160814Ssimon case ASN1_GEN_FLAG_EXP: 337160814Ssimon 338160814Ssimon if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 339160814Ssimon return -1; 340160814Ssimon if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 341160814Ssimon return -1; 342160814Ssimon break; 343160814Ssimon 344160814Ssimon case ASN1_GEN_FLAG_SEQWRAP: 345160814Ssimon if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 346160814Ssimon return -1; 347160814Ssimon break; 348160814Ssimon 349160814Ssimon case ASN1_GEN_FLAG_SETWRAP: 350160814Ssimon if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 351160814Ssimon return -1; 352160814Ssimon break; 353160814Ssimon 354160814Ssimon case ASN1_GEN_FLAG_BITWRAP: 355160814Ssimon if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 356160814Ssimon return -1; 357160814Ssimon break; 358160814Ssimon 359160814Ssimon case ASN1_GEN_FLAG_OCTWRAP: 360160814Ssimon if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 361160814Ssimon return -1; 362160814Ssimon break; 363160814Ssimon 364160814Ssimon case ASN1_GEN_FLAG_FORMAT: 365160814Ssimon if (!strncmp(vstart, "ASCII", 5)) 366160814Ssimon arg->format = ASN1_GEN_FORMAT_ASCII; 367160814Ssimon else if (!strncmp(vstart, "UTF8", 4)) 368160814Ssimon arg->format = ASN1_GEN_FORMAT_UTF8; 369160814Ssimon else if (!strncmp(vstart, "HEX", 3)) 370160814Ssimon arg->format = ASN1_GEN_FORMAT_HEX; 371160814Ssimon else if (!strncmp(vstart, "BITLIST", 3)) 372160814Ssimon arg->format = ASN1_GEN_FORMAT_BITLIST; 373160814Ssimon else 374160814Ssimon { 375160814Ssimon ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); 376160814Ssimon return -1; 377160814Ssimon } 378160814Ssimon break; 379160814Ssimon 380160814Ssimon } 381160814Ssimon 382160814Ssimon return 1; 383160814Ssimon 384160814Ssimon } 385160814Ssimon 386160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 387160814Ssimon { 388160814Ssimon char erch[2]; 389160814Ssimon long tag_num; 390160814Ssimon char *eptr; 391160814Ssimon if (!vstart) 392160814Ssimon return 0; 393160814Ssimon tag_num = strtoul(vstart, &eptr, 10); 394160814Ssimon /* Check we haven't gone past max length: should be impossible */ 395160814Ssimon if (eptr && *eptr && (eptr > vstart + vlen)) 396160814Ssimon return 0; 397160814Ssimon if (tag_num < 0) 398160814Ssimon { 399160814Ssimon ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); 400160814Ssimon return 0; 401160814Ssimon } 402160814Ssimon *ptag = tag_num; 403160814Ssimon /* If we have non numeric characters, parse them */ 404160814Ssimon if (eptr) 405160814Ssimon vlen -= eptr - vstart; 406160814Ssimon else 407160814Ssimon vlen = 0; 408160814Ssimon if (vlen) 409160814Ssimon { 410160814Ssimon switch (*eptr) 411160814Ssimon { 412160814Ssimon 413160814Ssimon case 'U': 414160814Ssimon *pclass = V_ASN1_UNIVERSAL; 415160814Ssimon break; 416160814Ssimon 417160814Ssimon case 'A': 418160814Ssimon *pclass = V_ASN1_APPLICATION; 419160814Ssimon break; 420160814Ssimon 421160814Ssimon case 'P': 422160814Ssimon *pclass = V_ASN1_PRIVATE; 423160814Ssimon break; 424160814Ssimon 425160814Ssimon case 'C': 426160814Ssimon *pclass = V_ASN1_CONTEXT_SPECIFIC; 427160814Ssimon break; 428160814Ssimon 429160814Ssimon default: 430160814Ssimon erch[0] = *eptr; 431160814Ssimon erch[1] = 0; 432160814Ssimon ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); 433160814Ssimon ERR_add_error_data(2, "Char=", erch); 434160814Ssimon return 0; 435160814Ssimon break; 436160814Ssimon 437160814Ssimon } 438160814Ssimon } 439160814Ssimon else 440160814Ssimon *pclass = V_ASN1_CONTEXT_SPECIFIC; 441160814Ssimon 442160814Ssimon return 1; 443160814Ssimon 444160814Ssimon } 445160814Ssimon 446160814Ssimon/* Handle multiple types: SET and SEQUENCE */ 447160814Ssimon 448160814Ssimonstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) 449160814Ssimon { 450238405Sjkim ASN1_TYPE *ret = NULL; 451160814Ssimon STACK_OF(ASN1_TYPE) *sk = NULL; 452160814Ssimon STACK_OF(CONF_VALUE) *sect = NULL; 453238405Sjkim unsigned char *der = NULL; 454160814Ssimon int derlen; 455238405Sjkim int i; 456160814Ssimon sk = sk_ASN1_TYPE_new_null(); 457205128Ssimon if (!sk) 458205128Ssimon goto bad; 459160814Ssimon if (section) 460160814Ssimon { 461160814Ssimon if (!cnf) 462160814Ssimon goto bad; 463160814Ssimon sect = X509V3_get_section(cnf, (char *)section); 464160814Ssimon if (!sect) 465160814Ssimon goto bad; 466160814Ssimon for (i = 0; i < sk_CONF_VALUE_num(sect); i++) 467160814Ssimon { 468238405Sjkim ASN1_TYPE *typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); 469160814Ssimon if (!typ) 470160814Ssimon goto bad; 471205128Ssimon if (!sk_ASN1_TYPE_push(sk, typ)) 472205128Ssimon goto bad; 473160814Ssimon } 474160814Ssimon } 475160814Ssimon 476160814Ssimon /* Now we has a STACK of the components, convert to the correct form */ 477160814Ssimon 478160814Ssimon if (utype == V_ASN1_SET) 479238405Sjkim derlen = i2d_ASN1_SET_ANY(sk, &der); 480160814Ssimon else 481238405Sjkim derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 482160814Ssimon 483238405Sjkim if (derlen < 0) 484205128Ssimon goto bad; 485160814Ssimon 486160814Ssimon if (!(ret = ASN1_TYPE_new())) 487160814Ssimon goto bad; 488160814Ssimon 489160814Ssimon if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 490160814Ssimon goto bad; 491160814Ssimon 492160814Ssimon ret->type = utype; 493160814Ssimon 494160814Ssimon ret->value.asn1_string->data = der; 495160814Ssimon ret->value.asn1_string->length = derlen; 496160814Ssimon 497160814Ssimon der = NULL; 498160814Ssimon 499160814Ssimon bad: 500160814Ssimon 501160814Ssimon if (der) 502160814Ssimon OPENSSL_free(der); 503160814Ssimon 504160814Ssimon if (sk) 505160814Ssimon sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 506160814Ssimon if (sect) 507160814Ssimon X509V3_section_free(cnf, sect); 508160814Ssimon 509160814Ssimon return ret; 510160814Ssimon } 511160814Ssimon 512160814Ssimonstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed, int exp_pad, int imp_ok) 513160814Ssimon { 514160814Ssimon tag_exp_type *exp_tmp; 515160814Ssimon /* Can only have IMPLICIT if permitted */ 516160814Ssimon if ((arg->imp_tag != -1) && !imp_ok) 517160814Ssimon { 518160814Ssimon ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); 519160814Ssimon return 0; 520160814Ssimon } 521160814Ssimon 522160814Ssimon if (arg->exp_count == ASN1_FLAG_EXP_MAX) 523160814Ssimon { 524160814Ssimon ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); 525160814Ssimon return 0; 526160814Ssimon } 527160814Ssimon 528160814Ssimon exp_tmp = &arg->exp_list[arg->exp_count++]; 529160814Ssimon 530160814Ssimon /* If IMPLICIT set tag to implicit value then 531160814Ssimon * reset implicit tag since it has been used. 532160814Ssimon */ 533160814Ssimon if (arg->imp_tag != -1) 534160814Ssimon { 535160814Ssimon exp_tmp->exp_tag = arg->imp_tag; 536160814Ssimon exp_tmp->exp_class = arg->imp_class; 537160814Ssimon arg->imp_tag = -1; 538160814Ssimon arg->imp_class = -1; 539160814Ssimon } 540160814Ssimon else 541160814Ssimon { 542160814Ssimon exp_tmp->exp_tag = exp_tag; 543160814Ssimon exp_tmp->exp_class = exp_class; 544160814Ssimon } 545160814Ssimon exp_tmp->exp_constructed = exp_constructed; 546160814Ssimon exp_tmp->exp_pad = exp_pad; 547160814Ssimon 548160814Ssimon return 1; 549160814Ssimon } 550160814Ssimon 551160814Ssimon 552160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len) 553160814Ssimon { 554160814Ssimon unsigned int i; 555238405Sjkim static const struct tag_name_st *tntmp, tnst [] = { 556160814Ssimon ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 557160814Ssimon ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 558160814Ssimon ASN1_GEN_STR("NULL", V_ASN1_NULL), 559160814Ssimon ASN1_GEN_STR("INT", V_ASN1_INTEGER), 560160814Ssimon ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 561160814Ssimon ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 562160814Ssimon ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 563160814Ssimon ASN1_GEN_STR("OID", V_ASN1_OBJECT), 564160814Ssimon ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 565160814Ssimon ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 566160814Ssimon ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 567160814Ssimon ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 568160814Ssimon ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 569160814Ssimon ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 570160814Ssimon ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 571160814Ssimon ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 572160814Ssimon ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 573160814Ssimon ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 574160814Ssimon ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 575160814Ssimon ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 576160814Ssimon ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 577160814Ssimon ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 578160814Ssimon ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 579160814Ssimon ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 580160814Ssimon ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 581160814Ssimon ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 582160814Ssimon ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 583160814Ssimon ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 584160814Ssimon ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 585160814Ssimon ASN1_GEN_STR("T61", V_ASN1_T61STRING), 586160814Ssimon ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 587160814Ssimon ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 588160814Ssimon ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 589160814Ssimon ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 590238405Sjkim ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 591238405Sjkim ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 592160814Ssimon 593160814Ssimon /* Special cases */ 594160814Ssimon ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 595160814Ssimon ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 596160814Ssimon ASN1_GEN_STR("SET", V_ASN1_SET), 597160814Ssimon /* type modifiers */ 598160814Ssimon /* Explicit tag */ 599160814Ssimon ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 600160814Ssimon ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 601160814Ssimon /* Implicit tag */ 602160814Ssimon ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 603160814Ssimon ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 604160814Ssimon /* OCTET STRING wrapper */ 605160814Ssimon ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 606160814Ssimon /* SEQUENCE wrapper */ 607160814Ssimon ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 608160814Ssimon /* SET wrapper */ 609160814Ssimon ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 610160814Ssimon /* BIT STRING wrapper */ 611160814Ssimon ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 612160814Ssimon ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 613160814Ssimon ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 614160814Ssimon }; 615160814Ssimon 616160814Ssimon if (len == -1) 617160814Ssimon len = strlen(tagstr); 618160814Ssimon 619160814Ssimon tntmp = tnst; 620160814Ssimon for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) 621160814Ssimon { 622160814Ssimon if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 623160814Ssimon return tntmp->tag; 624160814Ssimon } 625160814Ssimon 626160814Ssimon return -1; 627160814Ssimon } 628160814Ssimon 629160814Ssimonstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 630160814Ssimon { 631160814Ssimon ASN1_TYPE *atmp = NULL; 632160814Ssimon 633160814Ssimon CONF_VALUE vtmp; 634160814Ssimon 635160814Ssimon unsigned char *rdata; 636160814Ssimon long rdlen; 637160814Ssimon 638160814Ssimon int no_unused = 1; 639160814Ssimon 640160814Ssimon if (!(atmp = ASN1_TYPE_new())) 641160814Ssimon { 642160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 643160814Ssimon return NULL; 644160814Ssimon } 645160814Ssimon 646160814Ssimon if (!str) 647160814Ssimon str = ""; 648160814Ssimon 649160814Ssimon switch(utype) 650160814Ssimon { 651160814Ssimon 652160814Ssimon case V_ASN1_NULL: 653160814Ssimon if (str && *str) 654160814Ssimon { 655160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); 656160814Ssimon goto bad_form; 657160814Ssimon } 658160814Ssimon break; 659160814Ssimon 660160814Ssimon case V_ASN1_BOOLEAN: 661160814Ssimon if (format != ASN1_GEN_FORMAT_ASCII) 662160814Ssimon { 663160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); 664160814Ssimon goto bad_form; 665160814Ssimon } 666160814Ssimon vtmp.name = NULL; 667160814Ssimon vtmp.section = NULL; 668160814Ssimon vtmp.value = (char *)str; 669160814Ssimon if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) 670160814Ssimon { 671160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); 672160814Ssimon goto bad_str; 673160814Ssimon } 674160814Ssimon break; 675160814Ssimon 676160814Ssimon case V_ASN1_INTEGER: 677160814Ssimon case V_ASN1_ENUMERATED: 678160814Ssimon if (format != ASN1_GEN_FORMAT_ASCII) 679160814Ssimon { 680160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 681160814Ssimon goto bad_form; 682160814Ssimon } 683160814Ssimon if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) 684160814Ssimon { 685160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); 686160814Ssimon goto bad_str; 687160814Ssimon } 688160814Ssimon break; 689160814Ssimon 690160814Ssimon case V_ASN1_OBJECT: 691160814Ssimon if (format != ASN1_GEN_FORMAT_ASCII) 692160814Ssimon { 693160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 694160814Ssimon goto bad_form; 695160814Ssimon } 696160814Ssimon if (!(atmp->value.object = OBJ_txt2obj(str, 0))) 697160814Ssimon { 698160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); 699160814Ssimon goto bad_str; 700160814Ssimon } 701160814Ssimon break; 702160814Ssimon 703160814Ssimon case V_ASN1_UTCTIME: 704160814Ssimon case V_ASN1_GENERALIZEDTIME: 705160814Ssimon if (format != ASN1_GEN_FORMAT_ASCII) 706160814Ssimon { 707160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); 708160814Ssimon goto bad_form; 709160814Ssimon } 710160814Ssimon if (!(atmp->value.asn1_string = ASN1_STRING_new())) 711160814Ssimon { 712160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 713160814Ssimon goto bad_str; 714160814Ssimon } 715160814Ssimon if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) 716160814Ssimon { 717160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 718160814Ssimon goto bad_str; 719160814Ssimon } 720160814Ssimon atmp->value.asn1_string->type = utype; 721160814Ssimon if (!ASN1_TIME_check(atmp->value.asn1_string)) 722160814Ssimon { 723160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); 724160814Ssimon goto bad_str; 725160814Ssimon } 726160814Ssimon 727160814Ssimon break; 728160814Ssimon 729160814Ssimon case V_ASN1_BMPSTRING: 730160814Ssimon case V_ASN1_PRINTABLESTRING: 731160814Ssimon case V_ASN1_IA5STRING: 732160814Ssimon case V_ASN1_T61STRING: 733160814Ssimon case V_ASN1_UTF8STRING: 734160814Ssimon case V_ASN1_VISIBLESTRING: 735160814Ssimon case V_ASN1_UNIVERSALSTRING: 736160814Ssimon case V_ASN1_GENERALSTRING: 737238405Sjkim case V_ASN1_NUMERICSTRING: 738160814Ssimon 739160814Ssimon if (format == ASN1_GEN_FORMAT_ASCII) 740160814Ssimon format = MBSTRING_ASC; 741160814Ssimon else if (format == ASN1_GEN_FORMAT_UTF8) 742160814Ssimon format = MBSTRING_UTF8; 743160814Ssimon else 744160814Ssimon { 745160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); 746160814Ssimon goto bad_form; 747160814Ssimon } 748160814Ssimon 749160814Ssimon 750160814Ssimon if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 751160814Ssimon -1, format, ASN1_tag2bit(utype)) <= 0) 752160814Ssimon { 753160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 754160814Ssimon goto bad_str; 755160814Ssimon } 756160814Ssimon 757160814Ssimon 758160814Ssimon break; 759160814Ssimon 760160814Ssimon case V_ASN1_BIT_STRING: 761160814Ssimon 762160814Ssimon case V_ASN1_OCTET_STRING: 763160814Ssimon 764160814Ssimon if (!(atmp->value.asn1_string = ASN1_STRING_new())) 765160814Ssimon { 766160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 767160814Ssimon goto bad_form; 768160814Ssimon } 769160814Ssimon 770160814Ssimon if (format == ASN1_GEN_FORMAT_HEX) 771160814Ssimon { 772160814Ssimon 773160814Ssimon if (!(rdata = string_to_hex((char *)str, &rdlen))) 774160814Ssimon { 775160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); 776160814Ssimon goto bad_str; 777160814Ssimon } 778160814Ssimon 779160814Ssimon atmp->value.asn1_string->data = rdata; 780160814Ssimon atmp->value.asn1_string->length = rdlen; 781160814Ssimon atmp->value.asn1_string->type = utype; 782160814Ssimon 783160814Ssimon } 784160814Ssimon else if (format == ASN1_GEN_FORMAT_ASCII) 785160814Ssimon ASN1_STRING_set(atmp->value.asn1_string, str, -1); 786160814Ssimon else if ((format == ASN1_GEN_FORMAT_BITLIST) && (utype == V_ASN1_BIT_STRING)) 787160814Ssimon { 788160814Ssimon if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string)) 789160814Ssimon { 790160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); 791160814Ssimon goto bad_str; 792160814Ssimon } 793160814Ssimon no_unused = 0; 794160814Ssimon 795160814Ssimon } 796160814Ssimon else 797160814Ssimon { 798160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 799160814Ssimon goto bad_form; 800160814Ssimon } 801160814Ssimon 802160814Ssimon if ((utype == V_ASN1_BIT_STRING) && no_unused) 803160814Ssimon { 804160814Ssimon atmp->value.asn1_string->flags 805160814Ssimon &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); 806160814Ssimon atmp->value.asn1_string->flags 807160814Ssimon |= ASN1_STRING_FLAG_BITS_LEFT; 808160814Ssimon } 809160814Ssimon 810160814Ssimon 811160814Ssimon break; 812160814Ssimon 813160814Ssimon default: 814160814Ssimon ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); 815160814Ssimon goto bad_str; 816160814Ssimon break; 817160814Ssimon } 818160814Ssimon 819160814Ssimon 820160814Ssimon atmp->type = utype; 821160814Ssimon return atmp; 822160814Ssimon 823160814Ssimon 824160814Ssimon bad_str: 825160814Ssimon ERR_add_error_data(2, "string=", str); 826160814Ssimon bad_form: 827160814Ssimon 828160814Ssimon ASN1_TYPE_free(atmp); 829160814Ssimon return NULL; 830160814Ssimon 831160814Ssimon } 832160814Ssimon 833160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr) 834160814Ssimon { 835160814Ssimon long bitnum; 836160814Ssimon char *eptr; 837160814Ssimon if (!elem) 838160814Ssimon return 0; 839160814Ssimon bitnum = strtoul(elem, &eptr, 10); 840160814Ssimon if (eptr && *eptr && (eptr != elem + len)) 841160814Ssimon return 0; 842160814Ssimon if (bitnum < 0) 843160814Ssimon { 844160814Ssimon ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); 845160814Ssimon return 0; 846160814Ssimon } 847160814Ssimon if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) 848160814Ssimon { 849160814Ssimon ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); 850160814Ssimon return 0; 851160814Ssimon } 852160814Ssimon return 1; 853160814Ssimon } 854160814Ssimon 855