1160814Ssimon/* asn1_gen.c */ 2296465Sdelphij/* 3296465Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296465Sdelphij * 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 14296465Sdelphij * 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 64296465Sdelphij#define ASN1_GEN_FLAG 0x10000 65296465Sdelphij#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 66296465Sdelphij#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 67296465Sdelphij#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 68296465Sdelphij#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 69296465Sdelphij#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 70296465Sdelphij#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 71296465Sdelphij#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 72296465Sdelphij#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 73160814Ssimon 74296465Sdelphij#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 75160814Ssimon 76296465Sdelphij#define ASN1_FLAG_EXP_MAX 20 77160814Ssimon 78160814Ssimon/* Input formats */ 79160814Ssimon 80160814Ssimon/* ASCII: default */ 81296465Sdelphij#define ASN1_GEN_FORMAT_ASCII 1 82160814Ssimon/* UTF8 */ 83296465Sdelphij#define ASN1_GEN_FORMAT_UTF8 2 84160814Ssimon/* Hex */ 85296465Sdelphij#define ASN1_GEN_FORMAT_HEX 3 86160814Ssimon/* List of bits */ 87296465Sdelphij#define ASN1_GEN_FORMAT_BITLIST 4 88160814Ssimon 89296465Sdelphijstruct tag_name_st { 90296465Sdelphij const char *strnam; 91296465Sdelphij int len; 92296465Sdelphij int tag; 93296465Sdelphij}; 94160814Ssimon 95296465Sdelphijtypedef struct { 96296465Sdelphij int exp_tag; 97296465Sdelphij int exp_class; 98296465Sdelphij int exp_constructed; 99296465Sdelphij int exp_pad; 100296465Sdelphij long exp_len; 101296465Sdelphij} tag_exp_type; 102160814Ssimon 103296465Sdelphijtypedef struct { 104296465Sdelphij int imp_tag; 105296465Sdelphij int imp_class; 106296465Sdelphij int utype; 107296465Sdelphij int format; 108296465Sdelphij const char *str; 109296465Sdelphij tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 110296465Sdelphij int exp_count; 111296465Sdelphij} tag_exp_arg; 112160814Ssimon 113160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr); 114160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr); 115296465Sdelphijstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 116296465Sdelphij int exp_constructed, int exp_pad, int imp_ok); 117296465Sdelphijstatic int parse_tagging(const char *vstart, int vlen, int *ptag, 118296465Sdelphij int *pclass); 119160814Ssimonstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf); 120160814Ssimonstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); 121160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len); 122160814Ssimon 123160814SsimonASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) 124296465Sdelphij{ 125296465Sdelphij X509V3_CTX cnf; 126160814Ssimon 127296465Sdelphij if (!nconf) 128296465Sdelphij return ASN1_generate_v3(str, NULL); 129160814Ssimon 130296465Sdelphij X509V3_set_nconf(&cnf, nconf); 131296465Sdelphij return ASN1_generate_v3(str, &cnf); 132296465Sdelphij} 133160814Ssimon 134160814SsimonASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 135296465Sdelphij{ 136296465Sdelphij ASN1_TYPE *ret; 137296465Sdelphij tag_exp_arg asn1_tags; 138296465Sdelphij tag_exp_type *etmp; 139160814Ssimon 140296465Sdelphij int i, len; 141160814Ssimon 142296465Sdelphij unsigned char *orig_der = NULL, *new_der = NULL; 143296465Sdelphij const unsigned char *cpy_start; 144296465Sdelphij unsigned char *p; 145296465Sdelphij const unsigned char *cp; 146296465Sdelphij int cpy_len; 147296465Sdelphij long hdr_len; 148296465Sdelphij int hdr_constructed = 0, hdr_tag, hdr_class; 149296465Sdelphij int r; 150160814Ssimon 151296465Sdelphij asn1_tags.imp_tag = -1; 152296465Sdelphij asn1_tags.imp_class = -1; 153296465Sdelphij asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 154296465Sdelphij asn1_tags.exp_count = 0; 155296465Sdelphij if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) 156296465Sdelphij return NULL; 157160814Ssimon 158296465Sdelphij if ((asn1_tags.utype == V_ASN1_SEQUENCE) 159296465Sdelphij || (asn1_tags.utype == V_ASN1_SET)) { 160296465Sdelphij if (!cnf) { 161296465Sdelphij ASN1err(ASN1_F_ASN1_GENERATE_V3, 162296465Sdelphij ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG); 163296465Sdelphij return NULL; 164296465Sdelphij } 165296465Sdelphij ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf); 166296465Sdelphij } else 167296465Sdelphij ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 168160814Ssimon 169296465Sdelphij if (!ret) 170296465Sdelphij return NULL; 171160814Ssimon 172296465Sdelphij /* If no tagging return base type */ 173296465Sdelphij if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 174296465Sdelphij return ret; 175160814Ssimon 176296465Sdelphij /* Generate the encoding */ 177296465Sdelphij cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 178296465Sdelphij ASN1_TYPE_free(ret); 179296465Sdelphij ret = NULL; 180296465Sdelphij /* Set point to start copying for modified encoding */ 181296465Sdelphij cpy_start = orig_der; 182160814Ssimon 183296465Sdelphij /* Do we need IMPLICIT tagging? */ 184296465Sdelphij if (asn1_tags.imp_tag != -1) { 185296465Sdelphij /* If IMPLICIT we will replace the underlying tag */ 186296465Sdelphij /* Skip existing tag+len */ 187296465Sdelphij r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 188296465Sdelphij cpy_len); 189296465Sdelphij if (r & 0x80) 190296465Sdelphij goto err; 191296465Sdelphij /* Update copy length */ 192296465Sdelphij cpy_len -= cpy_start - orig_der; 193296465Sdelphij /* 194296465Sdelphij * For IMPLICIT tagging the length should match the original length 195296465Sdelphij * and constructed flag should be consistent. 196296465Sdelphij */ 197296465Sdelphij if (r & 0x1) { 198296465Sdelphij /* Indefinite length constructed */ 199296465Sdelphij hdr_constructed = 2; 200296465Sdelphij hdr_len = 0; 201296465Sdelphij } else 202296465Sdelphij /* Just retain constructed flag */ 203296465Sdelphij hdr_constructed = r & V_ASN1_CONSTRUCTED; 204296465Sdelphij /* 205296465Sdelphij * Work out new length with IMPLICIT tag: ignore constructed because 206296465Sdelphij * it will mess up if indefinite length 207296465Sdelphij */ 208296465Sdelphij len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 209296465Sdelphij } else 210296465Sdelphij len = cpy_len; 211160814Ssimon 212296465Sdelphij /* Work out length in any EXPLICIT, starting from end */ 213160814Ssimon 214296465Sdelphij for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 215296465Sdelphij i < asn1_tags.exp_count; i++, etmp--) { 216296465Sdelphij /* Content length: number of content octets + any padding */ 217296465Sdelphij len += etmp->exp_pad; 218296465Sdelphij etmp->exp_len = len; 219296465Sdelphij /* Total object length: length including new header */ 220296465Sdelphij len = ASN1_object_size(0, len, etmp->exp_tag); 221296465Sdelphij } 222160814Ssimon 223296465Sdelphij /* Allocate buffer for new encoding */ 224160814Ssimon 225296465Sdelphij new_der = OPENSSL_malloc(len); 226296465Sdelphij if (!new_der) 227296465Sdelphij goto err; 228160814Ssimon 229296465Sdelphij /* Generate tagged encoding */ 230160814Ssimon 231296465Sdelphij p = new_der; 232160814Ssimon 233296465Sdelphij /* Output explicit tags first */ 234160814Ssimon 235296465Sdelphij for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 236296465Sdelphij i++, etmp++) { 237296465Sdelphij ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 238296465Sdelphij etmp->exp_tag, etmp->exp_class); 239296465Sdelphij if (etmp->exp_pad) 240296465Sdelphij *p++ = 0; 241296465Sdelphij } 242160814Ssimon 243296465Sdelphij /* If IMPLICIT, output tag */ 244160814Ssimon 245296465Sdelphij if (asn1_tags.imp_tag != -1) 246296465Sdelphij ASN1_put_object(&p, hdr_constructed, hdr_len, 247296465Sdelphij asn1_tags.imp_tag, asn1_tags.imp_class); 248160814Ssimon 249296465Sdelphij /* Copy across original encoding */ 250296465Sdelphij memcpy(p, cpy_start, cpy_len); 251160814Ssimon 252296465Sdelphij cp = new_der; 253160814Ssimon 254296465Sdelphij /* Obtain new ASN1_TYPE structure */ 255296465Sdelphij ret = d2i_ASN1_TYPE(NULL, &cp, len); 256160814Ssimon 257296465Sdelphij err: 258296465Sdelphij if (orig_der) 259296465Sdelphij OPENSSL_free(orig_der); 260296465Sdelphij if (new_der) 261296465Sdelphij OPENSSL_free(new_der); 262160814Ssimon 263296465Sdelphij return ret; 264160814Ssimon 265296465Sdelphij} 266160814Ssimon 267160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr) 268296465Sdelphij{ 269296465Sdelphij tag_exp_arg *arg = bitstr; 270296465Sdelphij int i; 271296465Sdelphij int utype; 272296465Sdelphij int vlen = 0; 273296465Sdelphij const char *p, *vstart = NULL; 274160814Ssimon 275296465Sdelphij int tmp_tag, tmp_class; 276160814Ssimon 277296465Sdelphij for (i = 0, p = elem; i < len; p++, i++) { 278296465Sdelphij /* Look for the ':' in name value pairs */ 279296465Sdelphij if (*p == ':') { 280296465Sdelphij vstart = p + 1; 281296465Sdelphij vlen = len - (vstart - elem); 282296465Sdelphij len = p - elem; 283296465Sdelphij break; 284296465Sdelphij } 285296465Sdelphij } 286160814Ssimon 287296465Sdelphij utype = asn1_str2tag(elem, len); 288160814Ssimon 289296465Sdelphij if (utype == -1) { 290296465Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); 291296465Sdelphij ERR_add_error_data(2, "tag=", elem); 292296465Sdelphij return -1; 293296465Sdelphij } 294160814Ssimon 295296465Sdelphij /* If this is not a modifier mark end of string and exit */ 296296465Sdelphij if (!(utype & ASN1_GEN_FLAG)) { 297296465Sdelphij arg->utype = utype; 298296465Sdelphij arg->str = vstart; 299296465Sdelphij /* If no value and not end of string, error */ 300296465Sdelphij if (!vstart && elem[len]) { 301296465Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); 302296465Sdelphij return -1; 303296465Sdelphij } 304296465Sdelphij return 0; 305296465Sdelphij } 306160814Ssimon 307296465Sdelphij switch (utype) { 308160814Ssimon 309296465Sdelphij case ASN1_GEN_FLAG_IMP: 310296465Sdelphij /* Check for illegal multiple IMPLICIT tagging */ 311296465Sdelphij if (arg->imp_tag != -1) { 312296465Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); 313296465Sdelphij return -1; 314296465Sdelphij } 315296465Sdelphij if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 316296465Sdelphij return -1; 317296465Sdelphij break; 318160814Ssimon 319296465Sdelphij case ASN1_GEN_FLAG_EXP: 320160814Ssimon 321296465Sdelphij if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 322296465Sdelphij return -1; 323296465Sdelphij if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 324296465Sdelphij return -1; 325296465Sdelphij break; 326160814Ssimon 327296465Sdelphij case ASN1_GEN_FLAG_SEQWRAP: 328296465Sdelphij if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 329296465Sdelphij return -1; 330296465Sdelphij break; 331160814Ssimon 332296465Sdelphij case ASN1_GEN_FLAG_SETWRAP: 333296465Sdelphij if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 334296465Sdelphij return -1; 335296465Sdelphij break; 336160814Ssimon 337296465Sdelphij case ASN1_GEN_FLAG_BITWRAP: 338296465Sdelphij if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 339296465Sdelphij return -1; 340296465Sdelphij break; 341160814Ssimon 342296465Sdelphij case ASN1_GEN_FLAG_OCTWRAP: 343296465Sdelphij if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 344296465Sdelphij return -1; 345296465Sdelphij break; 346160814Ssimon 347296465Sdelphij case ASN1_GEN_FLAG_FORMAT: 348296465Sdelphij if (!strncmp(vstart, "ASCII", 5)) 349296465Sdelphij arg->format = ASN1_GEN_FORMAT_ASCII; 350296465Sdelphij else if (!strncmp(vstart, "UTF8", 4)) 351296465Sdelphij arg->format = ASN1_GEN_FORMAT_UTF8; 352296465Sdelphij else if (!strncmp(vstart, "HEX", 3)) 353296465Sdelphij arg->format = ASN1_GEN_FORMAT_HEX; 354296465Sdelphij else if (!strncmp(vstart, "BITLIST", 3)) 355296465Sdelphij arg->format = ASN1_GEN_FORMAT_BITLIST; 356296465Sdelphij else { 357296465Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); 358296465Sdelphij return -1; 359296465Sdelphij } 360296465Sdelphij break; 361160814Ssimon 362296465Sdelphij } 363160814Ssimon 364296465Sdelphij return 1; 365160814Ssimon 366296465Sdelphij} 367160814Ssimon 368160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 369296465Sdelphij{ 370296465Sdelphij char erch[2]; 371296465Sdelphij long tag_num; 372296465Sdelphij char *eptr; 373296465Sdelphij if (!vstart) 374296465Sdelphij return 0; 375296465Sdelphij tag_num = strtoul(vstart, &eptr, 10); 376296465Sdelphij /* Check we haven't gone past max length: should be impossible */ 377296465Sdelphij if (eptr && *eptr && (eptr > vstart + vlen)) 378296465Sdelphij return 0; 379296465Sdelphij if (tag_num < 0) { 380296465Sdelphij ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); 381296465Sdelphij return 0; 382296465Sdelphij } 383296465Sdelphij *ptag = tag_num; 384296465Sdelphij /* If we have non numeric characters, parse them */ 385296465Sdelphij if (eptr) 386296465Sdelphij vlen -= eptr - vstart; 387296465Sdelphij else 388296465Sdelphij vlen = 0; 389296465Sdelphij if (vlen) { 390296465Sdelphij switch (*eptr) { 391160814Ssimon 392296465Sdelphij case 'U': 393296465Sdelphij *pclass = V_ASN1_UNIVERSAL; 394296465Sdelphij break; 395160814Ssimon 396296465Sdelphij case 'A': 397296465Sdelphij *pclass = V_ASN1_APPLICATION; 398296465Sdelphij break; 399160814Ssimon 400296465Sdelphij case 'P': 401296465Sdelphij *pclass = V_ASN1_PRIVATE; 402296465Sdelphij break; 403160814Ssimon 404296465Sdelphij case 'C': 405296465Sdelphij *pclass = V_ASN1_CONTEXT_SPECIFIC; 406296465Sdelphij break; 407160814Ssimon 408296465Sdelphij default: 409296465Sdelphij erch[0] = *eptr; 410296465Sdelphij erch[1] = 0; 411296465Sdelphij ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); 412296465Sdelphij ERR_add_error_data(2, "Char=", erch); 413296465Sdelphij return 0; 414296465Sdelphij break; 415160814Ssimon 416296465Sdelphij } 417296465Sdelphij } else 418296465Sdelphij *pclass = V_ASN1_CONTEXT_SPECIFIC; 419160814Ssimon 420296465Sdelphij return 1; 421160814Ssimon 422296465Sdelphij} 423160814Ssimon 424160814Ssimon/* Handle multiple types: SET and SEQUENCE */ 425160814Ssimon 426160814Ssimonstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) 427296465Sdelphij{ 428296465Sdelphij ASN1_TYPE *ret = NULL, *typ = NULL; 429296465Sdelphij STACK_OF(ASN1_TYPE) *sk = NULL; 430296465Sdelphij STACK_OF(CONF_VALUE) *sect = NULL; 431296465Sdelphij unsigned char *der = NULL, *p; 432296465Sdelphij int derlen; 433296465Sdelphij int i, is_set; 434296465Sdelphij sk = sk_ASN1_TYPE_new_null(); 435296465Sdelphij if (!sk) 436296465Sdelphij goto bad; 437296465Sdelphij if (section) { 438296465Sdelphij if (!cnf) 439296465Sdelphij goto bad; 440296465Sdelphij sect = X509V3_get_section(cnf, (char *)section); 441296465Sdelphij if (!sect) 442296465Sdelphij goto bad; 443296465Sdelphij for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 444296465Sdelphij typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); 445296465Sdelphij if (!typ) 446296465Sdelphij goto bad; 447296465Sdelphij if (!sk_ASN1_TYPE_push(sk, typ)) 448296465Sdelphij goto bad; 449296465Sdelphij typ = NULL; 450296465Sdelphij } 451296465Sdelphij } 452160814Ssimon 453296465Sdelphij /* 454296465Sdelphij * Now we has a STACK of the components, convert to the correct form 455296465Sdelphij */ 456160814Ssimon 457296465Sdelphij if (utype == V_ASN1_SET) 458296465Sdelphij is_set = 1; 459296465Sdelphij else 460296465Sdelphij is_set = 0; 461160814Ssimon 462296465Sdelphij derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, 463296465Sdelphij V_ASN1_UNIVERSAL, is_set); 464296465Sdelphij der = OPENSSL_malloc(derlen); 465296465Sdelphij if (!der) 466296465Sdelphij goto bad; 467296465Sdelphij p = der; 468296465Sdelphij i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, 469296465Sdelphij V_ASN1_UNIVERSAL, is_set); 470160814Ssimon 471296465Sdelphij if (!(ret = ASN1_TYPE_new())) 472296465Sdelphij goto bad; 473160814Ssimon 474296465Sdelphij if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 475296465Sdelphij goto bad; 476160814Ssimon 477296465Sdelphij ret->type = utype; 478160814Ssimon 479296465Sdelphij ret->value.asn1_string->data = der; 480296465Sdelphij ret->value.asn1_string->length = derlen; 481160814Ssimon 482296465Sdelphij der = NULL; 483160814Ssimon 484296465Sdelphij bad: 485160814Ssimon 486296465Sdelphij if (der) 487296465Sdelphij OPENSSL_free(der); 488160814Ssimon 489296465Sdelphij if (sk) 490296465Sdelphij sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 491296465Sdelphij if (typ) 492296465Sdelphij ASN1_TYPE_free(typ); 493296465Sdelphij if (sect) 494296465Sdelphij X509V3_section_free(cnf, sect); 495160814Ssimon 496296465Sdelphij return ret; 497296465Sdelphij} 498160814Ssimon 499296465Sdelphijstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 500296465Sdelphij int exp_constructed, int exp_pad, int imp_ok) 501296465Sdelphij{ 502296465Sdelphij tag_exp_type *exp_tmp; 503296465Sdelphij /* Can only have IMPLICIT if permitted */ 504296465Sdelphij if ((arg->imp_tag != -1) && !imp_ok) { 505296465Sdelphij ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); 506296465Sdelphij return 0; 507296465Sdelphij } 508160814Ssimon 509296465Sdelphij if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 510296465Sdelphij ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); 511296465Sdelphij return 0; 512296465Sdelphij } 513160814Ssimon 514296465Sdelphij exp_tmp = &arg->exp_list[arg->exp_count++]; 515160814Ssimon 516296465Sdelphij /* 517296465Sdelphij * If IMPLICIT set tag to implicit value then reset implicit tag since it 518296465Sdelphij * has been used. 519296465Sdelphij */ 520296465Sdelphij if (arg->imp_tag != -1) { 521296465Sdelphij exp_tmp->exp_tag = arg->imp_tag; 522296465Sdelphij exp_tmp->exp_class = arg->imp_class; 523296465Sdelphij arg->imp_tag = -1; 524296465Sdelphij arg->imp_class = -1; 525296465Sdelphij } else { 526296465Sdelphij exp_tmp->exp_tag = exp_tag; 527296465Sdelphij exp_tmp->exp_class = exp_class; 528296465Sdelphij } 529296465Sdelphij exp_tmp->exp_constructed = exp_constructed; 530296465Sdelphij exp_tmp->exp_pad = exp_pad; 531160814Ssimon 532296465Sdelphij return 1; 533296465Sdelphij} 534160814Ssimon 535296465Sdelphijstatic int asn1_str2tag(const char *tagstr, int len) 536296465Sdelphij{ 537296465Sdelphij unsigned int i; 538296465Sdelphij static struct tag_name_st *tntmp, tnst[] = { 539296465Sdelphij ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 540296465Sdelphij ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 541296465Sdelphij ASN1_GEN_STR("NULL", V_ASN1_NULL), 542296465Sdelphij ASN1_GEN_STR("INT", V_ASN1_INTEGER), 543296465Sdelphij ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 544296465Sdelphij ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 545296465Sdelphij ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 546296465Sdelphij ASN1_GEN_STR("OID", V_ASN1_OBJECT), 547296465Sdelphij ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 548296465Sdelphij ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 549296465Sdelphij ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 550296465Sdelphij ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 551296465Sdelphij ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 552296465Sdelphij ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 553296465Sdelphij ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 554296465Sdelphij ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 555296465Sdelphij ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 556296465Sdelphij ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 557296465Sdelphij ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 558296465Sdelphij ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 559296465Sdelphij ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 560296465Sdelphij ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 561296465Sdelphij ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 562296465Sdelphij ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 563296465Sdelphij ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 564296465Sdelphij ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 565296465Sdelphij ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 566296465Sdelphij ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 567296465Sdelphij ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 568296465Sdelphij ASN1_GEN_STR("T61", V_ASN1_T61STRING), 569296465Sdelphij ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 570296465Sdelphij ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 571296465Sdelphij ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 572296465Sdelphij ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 573160814Ssimon 574296465Sdelphij /* Special cases */ 575296465Sdelphij ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 576296465Sdelphij ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 577296465Sdelphij ASN1_GEN_STR("SET", V_ASN1_SET), 578296465Sdelphij /* type modifiers */ 579296465Sdelphij /* Explicit tag */ 580296465Sdelphij ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 581296465Sdelphij ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 582296465Sdelphij /* Implicit tag */ 583296465Sdelphij ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 584296465Sdelphij ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 585296465Sdelphij /* OCTET STRING wrapper */ 586296465Sdelphij ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 587296465Sdelphij /* SEQUENCE wrapper */ 588296465Sdelphij ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 589296465Sdelphij /* SET wrapper */ 590296465Sdelphij ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 591296465Sdelphij /* BIT STRING wrapper */ 592296465Sdelphij ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 593296465Sdelphij ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 594296465Sdelphij ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 595296465Sdelphij }; 596160814Ssimon 597296465Sdelphij if (len == -1) 598296465Sdelphij len = strlen(tagstr); 599160814Ssimon 600296465Sdelphij tntmp = tnst; 601296465Sdelphij for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { 602296465Sdelphij if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 603296465Sdelphij return tntmp->tag; 604296465Sdelphij } 605160814Ssimon 606296465Sdelphij return -1; 607296465Sdelphij} 608160814Ssimon 609160814Ssimonstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 610296465Sdelphij{ 611296465Sdelphij ASN1_TYPE *atmp = NULL; 612160814Ssimon 613296465Sdelphij CONF_VALUE vtmp; 614160814Ssimon 615296465Sdelphij unsigned char *rdata; 616296465Sdelphij long rdlen; 617160814Ssimon 618296465Sdelphij int no_unused = 1; 619160814Ssimon 620296465Sdelphij if (!(atmp = ASN1_TYPE_new())) { 621296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 622296465Sdelphij return NULL; 623296465Sdelphij } 624160814Ssimon 625296465Sdelphij if (!str) 626296465Sdelphij str = ""; 627160814Ssimon 628296465Sdelphij switch (utype) { 629160814Ssimon 630296465Sdelphij case V_ASN1_NULL: 631296465Sdelphij if (str && *str) { 632296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); 633296465Sdelphij goto bad_form; 634296465Sdelphij } 635296465Sdelphij break; 636160814Ssimon 637296465Sdelphij case V_ASN1_BOOLEAN: 638296465Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 639296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); 640296465Sdelphij goto bad_form; 641296465Sdelphij } 642296465Sdelphij vtmp.name = NULL; 643296465Sdelphij vtmp.section = NULL; 644296465Sdelphij vtmp.value = (char *)str; 645296465Sdelphij if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 646296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); 647296465Sdelphij goto bad_str; 648296465Sdelphij } 649296465Sdelphij break; 650160814Ssimon 651296465Sdelphij case V_ASN1_INTEGER: 652296465Sdelphij case V_ASN1_ENUMERATED: 653296465Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 654296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 655296465Sdelphij goto bad_form; 656296465Sdelphij } 657296465Sdelphij if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { 658296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); 659296465Sdelphij goto bad_str; 660296465Sdelphij } 661296465Sdelphij break; 662160814Ssimon 663296465Sdelphij case V_ASN1_OBJECT: 664296465Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 665296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 666296465Sdelphij goto bad_form; 667296465Sdelphij } 668296465Sdelphij if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { 669296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); 670296465Sdelphij goto bad_str; 671296465Sdelphij } 672296465Sdelphij break; 673160814Ssimon 674296465Sdelphij case V_ASN1_UTCTIME: 675296465Sdelphij case V_ASN1_GENERALIZEDTIME: 676296465Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 677296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); 678296465Sdelphij goto bad_form; 679296465Sdelphij } 680296465Sdelphij if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 681296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 682296465Sdelphij goto bad_str; 683296465Sdelphij } 684296465Sdelphij if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 685296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 686296465Sdelphij goto bad_str; 687296465Sdelphij } 688296465Sdelphij atmp->value.asn1_string->type = utype; 689296465Sdelphij if (!ASN1_TIME_check(atmp->value.asn1_string)) { 690296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); 691296465Sdelphij goto bad_str; 692296465Sdelphij } 693160814Ssimon 694296465Sdelphij break; 695160814Ssimon 696296465Sdelphij case V_ASN1_BMPSTRING: 697296465Sdelphij case V_ASN1_PRINTABLESTRING: 698296465Sdelphij case V_ASN1_IA5STRING: 699296465Sdelphij case V_ASN1_T61STRING: 700296465Sdelphij case V_ASN1_UTF8STRING: 701296465Sdelphij case V_ASN1_VISIBLESTRING: 702296465Sdelphij case V_ASN1_UNIVERSALSTRING: 703296465Sdelphij case V_ASN1_GENERALSTRING: 704160814Ssimon 705296465Sdelphij if (format == ASN1_GEN_FORMAT_ASCII) 706296465Sdelphij format = MBSTRING_ASC; 707296465Sdelphij else if (format == ASN1_GEN_FORMAT_UTF8) 708296465Sdelphij format = MBSTRING_UTF8; 709296465Sdelphij else { 710296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); 711296465Sdelphij goto bad_form; 712296465Sdelphij } 713160814Ssimon 714296465Sdelphij if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 715296465Sdelphij -1, format, ASN1_tag2bit(utype)) <= 0) { 716296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 717296465Sdelphij goto bad_str; 718296465Sdelphij } 719160814Ssimon 720296465Sdelphij break; 721160814Ssimon 722296465Sdelphij case V_ASN1_BIT_STRING: 723160814Ssimon 724296465Sdelphij case V_ASN1_OCTET_STRING: 725160814Ssimon 726296465Sdelphij if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 727296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 728296465Sdelphij goto bad_form; 729296465Sdelphij } 730160814Ssimon 731296465Sdelphij if (format == ASN1_GEN_FORMAT_HEX) { 732160814Ssimon 733296465Sdelphij if (!(rdata = string_to_hex((char *)str, &rdlen))) { 734296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); 735296465Sdelphij goto bad_str; 736296465Sdelphij } 737160814Ssimon 738296465Sdelphij atmp->value.asn1_string->data = rdata; 739296465Sdelphij atmp->value.asn1_string->length = rdlen; 740296465Sdelphij atmp->value.asn1_string->type = utype; 741160814Ssimon 742296465Sdelphij } else if (format == ASN1_GEN_FORMAT_ASCII) 743296465Sdelphij ASN1_STRING_set(atmp->value.asn1_string, str, -1); 744296465Sdelphij else if ((format == ASN1_GEN_FORMAT_BITLIST) 745296465Sdelphij && (utype == V_ASN1_BIT_STRING)) { 746296465Sdelphij if (!CONF_parse_list 747296465Sdelphij (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 748296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); 749296465Sdelphij goto bad_str; 750296465Sdelphij } 751296465Sdelphij no_unused = 0; 752160814Ssimon 753296465Sdelphij } else { 754296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 755296465Sdelphij goto bad_form; 756296465Sdelphij } 757160814Ssimon 758296465Sdelphij if ((utype == V_ASN1_BIT_STRING) && no_unused) { 759296465Sdelphij atmp->value.asn1_string->flags 760296465Sdelphij &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 761296465Sdelphij atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 762296465Sdelphij } 763160814Ssimon 764296465Sdelphij break; 765160814Ssimon 766296465Sdelphij default: 767296465Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); 768296465Sdelphij goto bad_str; 769296465Sdelphij break; 770296465Sdelphij } 771160814Ssimon 772296465Sdelphij atmp->type = utype; 773296465Sdelphij return atmp; 774160814Ssimon 775296465Sdelphij bad_str: 776296465Sdelphij ERR_add_error_data(2, "string=", str); 777296465Sdelphij bad_form: 778160814Ssimon 779296465Sdelphij ASN1_TYPE_free(atmp); 780296465Sdelphij return NULL; 781160814Ssimon 782296465Sdelphij} 783160814Ssimon 784160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr) 785296465Sdelphij{ 786296465Sdelphij long bitnum; 787296465Sdelphij char *eptr; 788296465Sdelphij if (!elem) 789296465Sdelphij return 0; 790296465Sdelphij bitnum = strtoul(elem, &eptr, 10); 791296465Sdelphij if (eptr && *eptr && (eptr != elem + len)) 792296465Sdelphij return 0; 793296465Sdelphij if (bitnum < 0) { 794296465Sdelphij ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); 795296465Sdelphij return 0; 796296465Sdelphij } 797296465Sdelphij if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 798296465Sdelphij ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); 799296465Sdelphij return 0; 800296465Sdelphij } 801296465Sdelphij return 1; 802296465Sdelphij} 803