1160814Ssimon/* asn1_gen.c */ 2296341Sdelphij/* 3296341Sdelphij * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 4296341Sdelphij * 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 14296341Sdelphij * 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 64296341Sdelphij#define ASN1_GEN_FLAG 0x10000 65296341Sdelphij#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 66296341Sdelphij#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 67296341Sdelphij#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 68296341Sdelphij#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 69296341Sdelphij#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 70296341Sdelphij#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 71296341Sdelphij#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 72296341Sdelphij#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 73160814Ssimon 74296341Sdelphij#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 75160814Ssimon 76296341Sdelphij#define ASN1_FLAG_EXP_MAX 20 77296341Sdelphij/* Maximum number of nested sequences */ 78296341Sdelphij#define ASN1_GEN_SEQ_MAX_DEPTH 50 79160814Ssimon 80160814Ssimon/* Input formats */ 81160814Ssimon 82160814Ssimon/* ASCII: default */ 83296341Sdelphij#define ASN1_GEN_FORMAT_ASCII 1 84160814Ssimon/* UTF8 */ 85296341Sdelphij#define ASN1_GEN_FORMAT_UTF8 2 86160814Ssimon/* Hex */ 87296341Sdelphij#define ASN1_GEN_FORMAT_HEX 3 88160814Ssimon/* List of bits */ 89296341Sdelphij#define ASN1_GEN_FORMAT_BITLIST 4 90160814Ssimon 91296341Sdelphijstruct tag_name_st { 92296341Sdelphij const char *strnam; 93296341Sdelphij int len; 94296341Sdelphij int tag; 95296341Sdelphij}; 96160814Ssimon 97296341Sdelphijtypedef struct { 98296341Sdelphij int exp_tag; 99296341Sdelphij int exp_class; 100296341Sdelphij int exp_constructed; 101296341Sdelphij int exp_pad; 102296341Sdelphij long exp_len; 103296341Sdelphij} tag_exp_type; 104160814Ssimon 105296341Sdelphijtypedef struct { 106296341Sdelphij int imp_tag; 107296341Sdelphij int imp_class; 108296341Sdelphij int utype; 109296341Sdelphij int format; 110296341Sdelphij const char *str; 111296341Sdelphij tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 112296341Sdelphij int exp_count; 113296341Sdelphij} tag_exp_arg; 114160814Ssimon 115296341Sdelphijstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 116296341Sdelphij int *perr); 117160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr); 118160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr); 119296341Sdelphijstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 120296341Sdelphij int exp_constructed, int exp_pad, int imp_ok); 121296341Sdelphijstatic int parse_tagging(const char *vstart, int vlen, int *ptag, 122296341Sdelphij int *pclass); 123296341Sdelphijstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 124296341Sdelphij 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) 129296341Sdelphij{ 130296341Sdelphij X509V3_CTX cnf; 131160814Ssimon 132296341Sdelphij if (!nconf) 133296341Sdelphij return ASN1_generate_v3(str, NULL); 134160814Ssimon 135296341Sdelphij X509V3_set_nconf(&cnf, nconf); 136296341Sdelphij return ASN1_generate_v3(str, &cnf); 137296341Sdelphij} 138160814Ssimon 139160814SsimonASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) 140296341Sdelphij{ 141296341Sdelphij int err = 0; 142296341Sdelphij ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); 143296341Sdelphij if (err) 144296341Sdelphij ASN1err(ASN1_F_ASN1_GENERATE_V3, err); 145296341Sdelphij return ret; 146296341Sdelphij} 147160814Ssimon 148296341Sdelphijstatic ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, 149296341Sdelphij int *perr) 150296341Sdelphij{ 151296341Sdelphij ASN1_TYPE *ret; 152296341Sdelphij tag_exp_arg asn1_tags; 153296341Sdelphij tag_exp_type *etmp; 154160814Ssimon 155296341Sdelphij int i, len; 156160814Ssimon 157296341Sdelphij unsigned char *orig_der = NULL, *new_der = NULL; 158296341Sdelphij const unsigned char *cpy_start; 159296341Sdelphij unsigned char *p; 160296341Sdelphij const unsigned char *cp; 161296341Sdelphij int cpy_len; 162296341Sdelphij long hdr_len; 163296341Sdelphij int hdr_constructed = 0, hdr_tag, hdr_class; 164296341Sdelphij int r; 165160814Ssimon 166296341Sdelphij asn1_tags.imp_tag = -1; 167296341Sdelphij asn1_tags.imp_class = -1; 168296341Sdelphij asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 169296341Sdelphij asn1_tags.exp_count = 0; 170296341Sdelphij if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { 171296341Sdelphij *perr = ASN1_R_UNKNOWN_TAG; 172296341Sdelphij return NULL; 173296341Sdelphij } 174160814Ssimon 175296341Sdelphij if ((asn1_tags.utype == V_ASN1_SEQUENCE) 176296341Sdelphij || (asn1_tags.utype == V_ASN1_SET)) { 177296341Sdelphij if (!cnf) { 178296341Sdelphij *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; 179296341Sdelphij return NULL; 180296341Sdelphij } 181296341Sdelphij if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { 182296341Sdelphij *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; 183296341Sdelphij return NULL; 184296341Sdelphij } 185296341Sdelphij ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); 186296341Sdelphij } else 187296341Sdelphij ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 188160814Ssimon 189296341Sdelphij if (!ret) 190296341Sdelphij return NULL; 191160814Ssimon 192296341Sdelphij /* If no tagging return base type */ 193296341Sdelphij if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 194296341Sdelphij return ret; 195160814Ssimon 196296341Sdelphij /* Generate the encoding */ 197296341Sdelphij cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 198296341Sdelphij ASN1_TYPE_free(ret); 199296341Sdelphij ret = NULL; 200296341Sdelphij /* Set point to start copying for modified encoding */ 201296341Sdelphij cpy_start = orig_der; 202160814Ssimon 203296341Sdelphij /* Do we need IMPLICIT tagging? */ 204296341Sdelphij if (asn1_tags.imp_tag != -1) { 205296341Sdelphij /* If IMPLICIT we will replace the underlying tag */ 206296341Sdelphij /* Skip existing tag+len */ 207296341Sdelphij r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 208296341Sdelphij cpy_len); 209296341Sdelphij if (r & 0x80) 210296341Sdelphij goto err; 211296341Sdelphij /* Update copy length */ 212296341Sdelphij cpy_len -= cpy_start - orig_der; 213296341Sdelphij /* 214296341Sdelphij * For IMPLICIT tagging the length should match the original length 215296341Sdelphij * and constructed flag should be consistent. 216296341Sdelphij */ 217296341Sdelphij if (r & 0x1) { 218296341Sdelphij /* Indefinite length constructed */ 219296341Sdelphij hdr_constructed = 2; 220296341Sdelphij hdr_len = 0; 221296341Sdelphij } else 222296341Sdelphij /* Just retain constructed flag */ 223296341Sdelphij hdr_constructed = r & V_ASN1_CONSTRUCTED; 224296341Sdelphij /* 225296341Sdelphij * Work out new length with IMPLICIT tag: ignore constructed because 226296341Sdelphij * it will mess up if indefinite length 227296341Sdelphij */ 228296341Sdelphij len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 229296341Sdelphij } else 230296341Sdelphij len = cpy_len; 231160814Ssimon 232296341Sdelphij /* Work out length in any EXPLICIT, starting from end */ 233160814Ssimon 234296341Sdelphij for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 235296341Sdelphij i < asn1_tags.exp_count; i++, etmp--) { 236296341Sdelphij /* Content length: number of content octets + any padding */ 237296341Sdelphij len += etmp->exp_pad; 238296341Sdelphij etmp->exp_len = len; 239296341Sdelphij /* Total object length: length including new header */ 240296341Sdelphij len = ASN1_object_size(0, len, etmp->exp_tag); 241296341Sdelphij } 242160814Ssimon 243296341Sdelphij /* Allocate buffer for new encoding */ 244160814Ssimon 245296341Sdelphij new_der = OPENSSL_malloc(len); 246296341Sdelphij if (!new_der) 247296341Sdelphij goto err; 248160814Ssimon 249296341Sdelphij /* Generate tagged encoding */ 250160814Ssimon 251296341Sdelphij p = new_der; 252160814Ssimon 253296341Sdelphij /* Output explicit tags first */ 254160814Ssimon 255296341Sdelphij for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 256296341Sdelphij i++, etmp++) { 257296341Sdelphij ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 258296341Sdelphij etmp->exp_tag, etmp->exp_class); 259296341Sdelphij if (etmp->exp_pad) 260296341Sdelphij *p++ = 0; 261296341Sdelphij } 262160814Ssimon 263296341Sdelphij /* If IMPLICIT, output tag */ 264160814Ssimon 265296341Sdelphij if (asn1_tags.imp_tag != -1) { 266296341Sdelphij if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 267296341Sdelphij && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 268296341Sdelphij || asn1_tags.imp_tag == V_ASN1_SET)) 269296341Sdelphij hdr_constructed = V_ASN1_CONSTRUCTED; 270296341Sdelphij ASN1_put_object(&p, hdr_constructed, hdr_len, 271296341Sdelphij asn1_tags.imp_tag, asn1_tags.imp_class); 272296341Sdelphij } 273160814Ssimon 274296341Sdelphij /* Copy across original encoding */ 275296341Sdelphij memcpy(p, cpy_start, cpy_len); 276160814Ssimon 277296341Sdelphij cp = new_der; 278160814Ssimon 279296341Sdelphij /* Obtain new ASN1_TYPE structure */ 280296341Sdelphij ret = d2i_ASN1_TYPE(NULL, &cp, len); 281160814Ssimon 282296341Sdelphij err: 283296341Sdelphij if (orig_der) 284296341Sdelphij OPENSSL_free(orig_der); 285296341Sdelphij if (new_der) 286296341Sdelphij OPENSSL_free(new_der); 287160814Ssimon 288296341Sdelphij return ret; 289160814Ssimon 290296341Sdelphij} 291296341Sdelphij 292160814Ssimonstatic int asn1_cb(const char *elem, int len, void *bitstr) 293296341Sdelphij{ 294296341Sdelphij tag_exp_arg *arg = bitstr; 295296341Sdelphij int i; 296296341Sdelphij int utype; 297296341Sdelphij int vlen = 0; 298296341Sdelphij const char *p, *vstart = NULL; 299160814Ssimon 300296341Sdelphij int tmp_tag, tmp_class; 301160814Ssimon 302296341Sdelphij if (elem == NULL) 303296341Sdelphij return -1; 304160814Ssimon 305296341Sdelphij for (i = 0, p = elem; i < len; p++, i++) { 306296341Sdelphij /* Look for the ':' in name value pairs */ 307296341Sdelphij if (*p == ':') { 308296341Sdelphij vstart = p + 1; 309296341Sdelphij vlen = len - (vstart - elem); 310296341Sdelphij len = p - elem; 311296341Sdelphij break; 312296341Sdelphij } 313296341Sdelphij } 314160814Ssimon 315296341Sdelphij utype = asn1_str2tag(elem, len); 316160814Ssimon 317296341Sdelphij if (utype == -1) { 318296341Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); 319296341Sdelphij ERR_add_error_data(2, "tag=", elem); 320296341Sdelphij return -1; 321296341Sdelphij } 322160814Ssimon 323296341Sdelphij /* If this is not a modifier mark end of string and exit */ 324296341Sdelphij if (!(utype & ASN1_GEN_FLAG)) { 325296341Sdelphij arg->utype = utype; 326296341Sdelphij arg->str = vstart; 327296341Sdelphij /* If no value and not end of string, error */ 328296341Sdelphij if (!vstart && elem[len]) { 329296341Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); 330296341Sdelphij return -1; 331296341Sdelphij } 332296341Sdelphij return 0; 333296341Sdelphij } 334160814Ssimon 335296341Sdelphij switch (utype) { 336160814Ssimon 337296341Sdelphij case ASN1_GEN_FLAG_IMP: 338296341Sdelphij /* Check for illegal multiple IMPLICIT tagging */ 339296341Sdelphij if (arg->imp_tag != -1) { 340296341Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); 341296341Sdelphij return -1; 342296341Sdelphij } 343296341Sdelphij if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 344296341Sdelphij return -1; 345296341Sdelphij break; 346160814Ssimon 347296341Sdelphij case ASN1_GEN_FLAG_EXP: 348160814Ssimon 349296341Sdelphij if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 350296341Sdelphij return -1; 351296341Sdelphij if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 352296341Sdelphij return -1; 353296341Sdelphij break; 354160814Ssimon 355296341Sdelphij case ASN1_GEN_FLAG_SEQWRAP: 356296341Sdelphij if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 357296341Sdelphij return -1; 358296341Sdelphij break; 359160814Ssimon 360296341Sdelphij case ASN1_GEN_FLAG_SETWRAP: 361296341Sdelphij if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 362296341Sdelphij return -1; 363296341Sdelphij break; 364160814Ssimon 365296341Sdelphij case ASN1_GEN_FLAG_BITWRAP: 366296341Sdelphij if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 367296341Sdelphij return -1; 368296341Sdelphij break; 369160814Ssimon 370296341Sdelphij case ASN1_GEN_FLAG_OCTWRAP: 371296341Sdelphij if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 372296341Sdelphij return -1; 373296341Sdelphij break; 374160814Ssimon 375296341Sdelphij case ASN1_GEN_FLAG_FORMAT: 376296341Sdelphij if (!vstart) { 377296341Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); 378296341Sdelphij return -1; 379296341Sdelphij } 380296341Sdelphij if (!strncmp(vstart, "ASCII", 5)) 381296341Sdelphij arg->format = ASN1_GEN_FORMAT_ASCII; 382296341Sdelphij else if (!strncmp(vstart, "UTF8", 4)) 383296341Sdelphij arg->format = ASN1_GEN_FORMAT_UTF8; 384296341Sdelphij else if (!strncmp(vstart, "HEX", 3)) 385296341Sdelphij arg->format = ASN1_GEN_FORMAT_HEX; 386296341Sdelphij else if (!strncmp(vstart, "BITLIST", 7)) 387296341Sdelphij arg->format = ASN1_GEN_FORMAT_BITLIST; 388296341Sdelphij else { 389296341Sdelphij ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); 390296341Sdelphij return -1; 391296341Sdelphij } 392296341Sdelphij break; 393160814Ssimon 394296341Sdelphij } 395160814Ssimon 396296341Sdelphij return 1; 397160814Ssimon 398296341Sdelphij} 399296341Sdelphij 400160814Ssimonstatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 401296341Sdelphij{ 402296341Sdelphij char erch[2]; 403296341Sdelphij long tag_num; 404296341Sdelphij char *eptr; 405296341Sdelphij if (!vstart) 406296341Sdelphij return 0; 407296341Sdelphij tag_num = strtoul(vstart, &eptr, 10); 408296341Sdelphij /* Check we haven't gone past max length: should be impossible */ 409296341Sdelphij if (eptr && *eptr && (eptr > vstart + vlen)) 410296341Sdelphij return 0; 411296341Sdelphij if (tag_num < 0) { 412296341Sdelphij ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); 413296341Sdelphij return 0; 414296341Sdelphij } 415296341Sdelphij *ptag = tag_num; 416296341Sdelphij /* If we have non numeric characters, parse them */ 417296341Sdelphij if (eptr) 418296341Sdelphij vlen -= eptr - vstart; 419296341Sdelphij else 420296341Sdelphij vlen = 0; 421296341Sdelphij if (vlen) { 422296341Sdelphij switch (*eptr) { 423160814Ssimon 424296341Sdelphij case 'U': 425296341Sdelphij *pclass = V_ASN1_UNIVERSAL; 426296341Sdelphij break; 427160814Ssimon 428296341Sdelphij case 'A': 429296341Sdelphij *pclass = V_ASN1_APPLICATION; 430296341Sdelphij break; 431160814Ssimon 432296341Sdelphij case 'P': 433296341Sdelphij *pclass = V_ASN1_PRIVATE; 434296341Sdelphij break; 435160814Ssimon 436296341Sdelphij case 'C': 437296341Sdelphij *pclass = V_ASN1_CONTEXT_SPECIFIC; 438296341Sdelphij break; 439160814Ssimon 440296341Sdelphij default: 441296341Sdelphij erch[0] = *eptr; 442296341Sdelphij erch[1] = 0; 443296341Sdelphij ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); 444296341Sdelphij ERR_add_error_data(2, "Char=", erch); 445296341Sdelphij return 0; 446296341Sdelphij break; 447160814Ssimon 448296341Sdelphij } 449296341Sdelphij } else 450296341Sdelphij *pclass = V_ASN1_CONTEXT_SPECIFIC; 451160814Ssimon 452296341Sdelphij return 1; 453160814Ssimon 454296341Sdelphij} 455160814Ssimon 456160814Ssimon/* Handle multiple types: SET and SEQUENCE */ 457160814Ssimon 458296341Sdelphijstatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 459296341Sdelphij int depth, int *perr) 460296341Sdelphij{ 461296341Sdelphij ASN1_TYPE *ret = NULL; 462296341Sdelphij STACK_OF(ASN1_TYPE) *sk = NULL; 463296341Sdelphij STACK_OF(CONF_VALUE) *sect = NULL; 464296341Sdelphij unsigned char *der = NULL; 465296341Sdelphij int derlen; 466296341Sdelphij int i; 467296341Sdelphij sk = sk_ASN1_TYPE_new_null(); 468296341Sdelphij if (!sk) 469296341Sdelphij goto bad; 470296341Sdelphij if (section) { 471296341Sdelphij if (!cnf) 472296341Sdelphij goto bad; 473296341Sdelphij sect = X509V3_get_section(cnf, (char *)section); 474296341Sdelphij if (!sect) 475296341Sdelphij goto bad; 476296341Sdelphij for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 477296341Sdelphij ASN1_TYPE *typ = 478296341Sdelphij generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, 479296341Sdelphij depth + 1, perr); 480296341Sdelphij if (!typ) 481296341Sdelphij goto bad; 482296341Sdelphij if (!sk_ASN1_TYPE_push(sk, typ)) 483296341Sdelphij goto bad; 484296341Sdelphij } 485296341Sdelphij } 486160814Ssimon 487296341Sdelphij /* 488296341Sdelphij * Now we has a STACK of the components, convert to the correct form 489296341Sdelphij */ 490160814Ssimon 491296341Sdelphij if (utype == V_ASN1_SET) 492296341Sdelphij derlen = i2d_ASN1_SET_ANY(sk, &der); 493296341Sdelphij else 494296341Sdelphij derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 495160814Ssimon 496296341Sdelphij if (derlen < 0) 497296341Sdelphij goto bad; 498160814Ssimon 499296341Sdelphij if (!(ret = ASN1_TYPE_new())) 500296341Sdelphij goto bad; 501160814Ssimon 502296341Sdelphij if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) 503296341Sdelphij goto bad; 504160814Ssimon 505296341Sdelphij ret->type = utype; 506160814Ssimon 507296341Sdelphij ret->value.asn1_string->data = der; 508296341Sdelphij ret->value.asn1_string->length = derlen; 509160814Ssimon 510296341Sdelphij der = NULL; 511160814Ssimon 512296341Sdelphij bad: 513160814Ssimon 514296341Sdelphij if (der) 515296341Sdelphij OPENSSL_free(der); 516160814Ssimon 517296341Sdelphij if (sk) 518296341Sdelphij sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 519296341Sdelphij if (sect) 520296341Sdelphij X509V3_section_free(cnf, sect); 521160814Ssimon 522296341Sdelphij return ret; 523296341Sdelphij} 524160814Ssimon 525296341Sdelphijstatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 526296341Sdelphij int exp_constructed, int exp_pad, int imp_ok) 527296341Sdelphij{ 528296341Sdelphij tag_exp_type *exp_tmp; 529296341Sdelphij /* Can only have IMPLICIT if permitted */ 530296341Sdelphij if ((arg->imp_tag != -1) && !imp_ok) { 531296341Sdelphij ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); 532296341Sdelphij return 0; 533296341Sdelphij } 534160814Ssimon 535296341Sdelphij if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 536296341Sdelphij ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); 537296341Sdelphij return 0; 538296341Sdelphij } 539160814Ssimon 540296341Sdelphij exp_tmp = &arg->exp_list[arg->exp_count++]; 541160814Ssimon 542296341Sdelphij /* 543296341Sdelphij * If IMPLICIT set tag to implicit value then reset implicit tag since it 544296341Sdelphij * has been used. 545296341Sdelphij */ 546296341Sdelphij if (arg->imp_tag != -1) { 547296341Sdelphij exp_tmp->exp_tag = arg->imp_tag; 548296341Sdelphij exp_tmp->exp_class = arg->imp_class; 549296341Sdelphij arg->imp_tag = -1; 550296341Sdelphij arg->imp_class = -1; 551296341Sdelphij } else { 552296341Sdelphij exp_tmp->exp_tag = exp_tag; 553296341Sdelphij exp_tmp->exp_class = exp_class; 554296341Sdelphij } 555296341Sdelphij exp_tmp->exp_constructed = exp_constructed; 556296341Sdelphij exp_tmp->exp_pad = exp_pad; 557160814Ssimon 558296341Sdelphij return 1; 559296341Sdelphij} 560160814Ssimon 561160814Ssimonstatic int asn1_str2tag(const char *tagstr, int len) 562296341Sdelphij{ 563296341Sdelphij unsigned int i; 564296341Sdelphij static const struct tag_name_st *tntmp, tnst[] = { 565296341Sdelphij ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 566296341Sdelphij ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 567296341Sdelphij ASN1_GEN_STR("NULL", V_ASN1_NULL), 568296341Sdelphij ASN1_GEN_STR("INT", V_ASN1_INTEGER), 569296341Sdelphij ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 570296341Sdelphij ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 571296341Sdelphij ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 572296341Sdelphij ASN1_GEN_STR("OID", V_ASN1_OBJECT), 573296341Sdelphij ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 574296341Sdelphij ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 575296341Sdelphij ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 576296341Sdelphij ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 577296341Sdelphij ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 578296341Sdelphij ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 579296341Sdelphij ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 580296341Sdelphij ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 581296341Sdelphij ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 582296341Sdelphij ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 583296341Sdelphij ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 584296341Sdelphij ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 585296341Sdelphij ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 586296341Sdelphij ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 587296341Sdelphij ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 588296341Sdelphij ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 589296341Sdelphij ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 590296341Sdelphij ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 591296341Sdelphij ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 592296341Sdelphij ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 593296341Sdelphij ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 594296341Sdelphij ASN1_GEN_STR("T61", V_ASN1_T61STRING), 595296341Sdelphij ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 596296341Sdelphij ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 597296341Sdelphij ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 598296341Sdelphij ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 599296341Sdelphij ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 600296341Sdelphij ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 601160814Ssimon 602296341Sdelphij /* Special cases */ 603296341Sdelphij ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 604296341Sdelphij ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 605296341Sdelphij ASN1_GEN_STR("SET", V_ASN1_SET), 606296341Sdelphij /* type modifiers */ 607296341Sdelphij /* Explicit tag */ 608296341Sdelphij ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 609296341Sdelphij ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 610296341Sdelphij /* Implicit tag */ 611296341Sdelphij ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 612296341Sdelphij ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 613296341Sdelphij /* OCTET STRING wrapper */ 614296341Sdelphij ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 615296341Sdelphij /* SEQUENCE wrapper */ 616296341Sdelphij ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 617296341Sdelphij /* SET wrapper */ 618296341Sdelphij ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 619296341Sdelphij /* BIT STRING wrapper */ 620296341Sdelphij ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 621296341Sdelphij ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 622296341Sdelphij ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 623296341Sdelphij }; 624160814Ssimon 625296341Sdelphij if (len == -1) 626296341Sdelphij len = strlen(tagstr); 627160814Ssimon 628296341Sdelphij tntmp = tnst; 629296341Sdelphij for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { 630296341Sdelphij if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) 631296341Sdelphij return tntmp->tag; 632296341Sdelphij } 633160814Ssimon 634296341Sdelphij return -1; 635296341Sdelphij} 636160814Ssimon 637296341Sdelphijstatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 638296341Sdelphij{ 639296341Sdelphij ASN1_TYPE *atmp = NULL; 640160814Ssimon 641296341Sdelphij CONF_VALUE vtmp; 642160814Ssimon 643296341Sdelphij unsigned char *rdata; 644296341Sdelphij long rdlen; 645160814Ssimon 646296341Sdelphij int no_unused = 1; 647160814Ssimon 648296341Sdelphij if (!(atmp = ASN1_TYPE_new())) { 649296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 650296341Sdelphij return NULL; 651296341Sdelphij } 652160814Ssimon 653296341Sdelphij if (!str) 654296341Sdelphij str = ""; 655160814Ssimon 656296341Sdelphij switch (utype) { 657160814Ssimon 658296341Sdelphij case V_ASN1_NULL: 659296341Sdelphij if (str && *str) { 660296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); 661296341Sdelphij goto bad_form; 662296341Sdelphij } 663296341Sdelphij break; 664160814Ssimon 665296341Sdelphij case V_ASN1_BOOLEAN: 666296341Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 667296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); 668296341Sdelphij goto bad_form; 669296341Sdelphij } 670296341Sdelphij vtmp.name = NULL; 671296341Sdelphij vtmp.section = NULL; 672296341Sdelphij vtmp.value = (char *)str; 673296341Sdelphij if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 674296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); 675296341Sdelphij goto bad_str; 676296341Sdelphij } 677296341Sdelphij break; 678160814Ssimon 679296341Sdelphij case V_ASN1_INTEGER: 680296341Sdelphij case V_ASN1_ENUMERATED: 681296341Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 682296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 683296341Sdelphij goto bad_form; 684296341Sdelphij } 685296341Sdelphij if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { 686296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); 687296341Sdelphij goto bad_str; 688296341Sdelphij } 689296341Sdelphij break; 690160814Ssimon 691296341Sdelphij case V_ASN1_OBJECT: 692296341Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 693296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 694296341Sdelphij goto bad_form; 695296341Sdelphij } 696296341Sdelphij if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { 697296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); 698296341Sdelphij goto bad_str; 699296341Sdelphij } 700296341Sdelphij break; 701160814Ssimon 702296341Sdelphij case V_ASN1_UTCTIME: 703296341Sdelphij case V_ASN1_GENERALIZEDTIME: 704296341Sdelphij if (format != ASN1_GEN_FORMAT_ASCII) { 705296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); 706296341Sdelphij goto bad_form; 707296341Sdelphij } 708296341Sdelphij if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 709296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 710296341Sdelphij goto bad_str; 711296341Sdelphij } 712296341Sdelphij if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 713296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 714296341Sdelphij goto bad_str; 715296341Sdelphij } 716296341Sdelphij atmp->value.asn1_string->type = utype; 717296341Sdelphij if (!ASN1_TIME_check(atmp->value.asn1_string)) { 718296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); 719296341Sdelphij goto bad_str; 720296341Sdelphij } 721160814Ssimon 722296341Sdelphij break; 723160814Ssimon 724296341Sdelphij case V_ASN1_BMPSTRING: 725296341Sdelphij case V_ASN1_PRINTABLESTRING: 726296341Sdelphij case V_ASN1_IA5STRING: 727296341Sdelphij case V_ASN1_T61STRING: 728296341Sdelphij case V_ASN1_UTF8STRING: 729296341Sdelphij case V_ASN1_VISIBLESTRING: 730296341Sdelphij case V_ASN1_UNIVERSALSTRING: 731296341Sdelphij case V_ASN1_GENERALSTRING: 732296341Sdelphij case V_ASN1_NUMERICSTRING: 733160814Ssimon 734296341Sdelphij if (format == ASN1_GEN_FORMAT_ASCII) 735296341Sdelphij format = MBSTRING_ASC; 736296341Sdelphij else if (format == ASN1_GEN_FORMAT_UTF8) 737296341Sdelphij format = MBSTRING_UTF8; 738296341Sdelphij else { 739296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); 740296341Sdelphij goto bad_form; 741296341Sdelphij } 742160814Ssimon 743296341Sdelphij if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 744296341Sdelphij -1, format, ASN1_tag2bit(utype)) <= 0) { 745296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 746296341Sdelphij goto bad_str; 747296341Sdelphij } 748160814Ssimon 749296341Sdelphij break; 750160814Ssimon 751296341Sdelphij case V_ASN1_BIT_STRING: 752160814Ssimon 753296341Sdelphij case V_ASN1_OCTET_STRING: 754160814Ssimon 755296341Sdelphij if (!(atmp->value.asn1_string = ASN1_STRING_new())) { 756296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); 757296341Sdelphij goto bad_form; 758296341Sdelphij } 759160814Ssimon 760296341Sdelphij if (format == ASN1_GEN_FORMAT_HEX) { 761160814Ssimon 762296341Sdelphij if (!(rdata = string_to_hex((char *)str, &rdlen))) { 763296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); 764296341Sdelphij goto bad_str; 765296341Sdelphij } 766160814Ssimon 767296341Sdelphij atmp->value.asn1_string->data = rdata; 768296341Sdelphij atmp->value.asn1_string->length = rdlen; 769296341Sdelphij atmp->value.asn1_string->type = utype; 770160814Ssimon 771296341Sdelphij } else if (format == ASN1_GEN_FORMAT_ASCII) 772296341Sdelphij ASN1_STRING_set(atmp->value.asn1_string, str, -1); 773296341Sdelphij else if ((format == ASN1_GEN_FORMAT_BITLIST) 774296341Sdelphij && (utype == V_ASN1_BIT_STRING)) { 775296341Sdelphij if (!CONF_parse_list 776296341Sdelphij (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 777296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); 778296341Sdelphij goto bad_str; 779296341Sdelphij } 780296341Sdelphij no_unused = 0; 781160814Ssimon 782296341Sdelphij } else { 783296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 784296341Sdelphij goto bad_form; 785296341Sdelphij } 786160814Ssimon 787296341Sdelphij if ((utype == V_ASN1_BIT_STRING) && no_unused) { 788296341Sdelphij atmp->value.asn1_string->flags 789296341Sdelphij &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 790296341Sdelphij atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 791296341Sdelphij } 792160814Ssimon 793296341Sdelphij break; 794160814Ssimon 795296341Sdelphij default: 796296341Sdelphij ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); 797296341Sdelphij goto bad_str; 798296341Sdelphij break; 799296341Sdelphij } 800160814Ssimon 801296341Sdelphij atmp->type = utype; 802296341Sdelphij return atmp; 803160814Ssimon 804296341Sdelphij bad_str: 805296341Sdelphij ERR_add_error_data(2, "string=", str); 806296341Sdelphij bad_form: 807160814Ssimon 808296341Sdelphij ASN1_TYPE_free(atmp); 809296341Sdelphij return NULL; 810160814Ssimon 811296341Sdelphij} 812160814Ssimon 813160814Ssimonstatic int bitstr_cb(const char *elem, int len, void *bitstr) 814296341Sdelphij{ 815296341Sdelphij long bitnum; 816296341Sdelphij char *eptr; 817296341Sdelphij if (!elem) 818296341Sdelphij return 0; 819296341Sdelphij bitnum = strtoul(elem, &eptr, 10); 820296341Sdelphij if (eptr && *eptr && (eptr != elem + len)) 821296341Sdelphij return 0; 822296341Sdelphij if (bitnum < 0) { 823296341Sdelphij ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); 824296341Sdelphij return 0; 825296341Sdelphij } 826296341Sdelphij if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 827296341Sdelphij ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); 828296341Sdelphij return 0; 829296341Sdelphij } 830296341Sdelphij return 1; 831296341Sdelphij} 832