1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2002-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 11e1051a39Sopenharmony_ci#include <openssl/asn1.h> 12e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 13e1051a39Sopenharmony_ci 14e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG 0x10000 15e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) 16e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) 17e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) 18e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) 19e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) 20e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) 21e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) 22e1051a39Sopenharmony_ci#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci#define ASN1_FLAG_EXP_MAX 20 27e1051a39Sopenharmony_ci/* Maximum number of nested sequences */ 28e1051a39Sopenharmony_ci#define ASN1_GEN_SEQ_MAX_DEPTH 50 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci/* Input formats */ 31e1051a39Sopenharmony_ci 32e1051a39Sopenharmony_ci/* ASCII: default */ 33e1051a39Sopenharmony_ci#define ASN1_GEN_FORMAT_ASCII 1 34e1051a39Sopenharmony_ci/* UTF8 */ 35e1051a39Sopenharmony_ci#define ASN1_GEN_FORMAT_UTF8 2 36e1051a39Sopenharmony_ci/* Hex */ 37e1051a39Sopenharmony_ci#define ASN1_GEN_FORMAT_HEX 3 38e1051a39Sopenharmony_ci/* List of bits */ 39e1051a39Sopenharmony_ci#define ASN1_GEN_FORMAT_BITLIST 4 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_cistruct tag_name_st { 42e1051a39Sopenharmony_ci const char *strnam; 43e1051a39Sopenharmony_ci int len; 44e1051a39Sopenharmony_ci int tag; 45e1051a39Sopenharmony_ci}; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_citypedef struct { 48e1051a39Sopenharmony_ci int exp_tag; 49e1051a39Sopenharmony_ci int exp_class; 50e1051a39Sopenharmony_ci int exp_constructed; 51e1051a39Sopenharmony_ci int exp_pad; 52e1051a39Sopenharmony_ci long exp_len; 53e1051a39Sopenharmony_ci} tag_exp_type; 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_citypedef struct { 56e1051a39Sopenharmony_ci int imp_tag; 57e1051a39Sopenharmony_ci int imp_class; 58e1051a39Sopenharmony_ci int utype; 59e1051a39Sopenharmony_ci int format; 60e1051a39Sopenharmony_ci const char *str; 61e1051a39Sopenharmony_ci tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; 62e1051a39Sopenharmony_ci int exp_count; 63e1051a39Sopenharmony_ci} tag_exp_arg; 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_cistatic ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, 66e1051a39Sopenharmony_ci int *perr); 67e1051a39Sopenharmony_cistatic int bitstr_cb(const char *elem, int len, void *bitstr); 68e1051a39Sopenharmony_cistatic int asn1_cb(const char *elem, int len, void *bitstr); 69e1051a39Sopenharmony_cistatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 70e1051a39Sopenharmony_ci int exp_constructed, int exp_pad, int imp_ok); 71e1051a39Sopenharmony_cistatic int parse_tagging(const char *vstart, int vlen, int *ptag, 72e1051a39Sopenharmony_ci int *pclass); 73e1051a39Sopenharmony_cistatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 74e1051a39Sopenharmony_ci int depth, int *perr); 75e1051a39Sopenharmony_cistatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); 76e1051a39Sopenharmony_cistatic int asn1_str2tag(const char *tagstr, int len); 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ciASN1_TYPE *ASN1_generate_nconf(const char *str, CONF *nconf) 79e1051a39Sopenharmony_ci{ 80e1051a39Sopenharmony_ci X509V3_CTX cnf; 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci if (!nconf) 83e1051a39Sopenharmony_ci return ASN1_generate_v3(str, NULL); 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci X509V3_set_nconf(&cnf, nconf); 86e1051a39Sopenharmony_ci return ASN1_generate_v3(str, &cnf); 87e1051a39Sopenharmony_ci} 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ciASN1_TYPE *ASN1_generate_v3(const char *str, X509V3_CTX *cnf) 90e1051a39Sopenharmony_ci{ 91e1051a39Sopenharmony_ci int err = 0; 92e1051a39Sopenharmony_ci ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); 93e1051a39Sopenharmony_ci if (err) 94e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, err); 95e1051a39Sopenharmony_ci return ret; 96e1051a39Sopenharmony_ci} 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_cistatic ASN1_TYPE *generate_v3(const char *str, X509V3_CTX *cnf, int depth, 99e1051a39Sopenharmony_ci int *perr) 100e1051a39Sopenharmony_ci{ 101e1051a39Sopenharmony_ci ASN1_TYPE *ret; 102e1051a39Sopenharmony_ci tag_exp_arg asn1_tags; 103e1051a39Sopenharmony_ci tag_exp_type *etmp; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci int i, len; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci unsigned char *orig_der = NULL, *new_der = NULL; 108e1051a39Sopenharmony_ci const unsigned char *cpy_start; 109e1051a39Sopenharmony_ci unsigned char *p; 110e1051a39Sopenharmony_ci const unsigned char *cp; 111e1051a39Sopenharmony_ci int cpy_len; 112e1051a39Sopenharmony_ci long hdr_len = 0; 113e1051a39Sopenharmony_ci int hdr_constructed = 0, hdr_tag, hdr_class; 114e1051a39Sopenharmony_ci int r; 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci asn1_tags.imp_tag = -1; 117e1051a39Sopenharmony_ci asn1_tags.imp_class = -1; 118e1051a39Sopenharmony_ci asn1_tags.format = ASN1_GEN_FORMAT_ASCII; 119e1051a39Sopenharmony_ci asn1_tags.exp_count = 0; 120e1051a39Sopenharmony_ci if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { 121e1051a39Sopenharmony_ci *perr = ASN1_R_UNKNOWN_TAG; 122e1051a39Sopenharmony_ci return NULL; 123e1051a39Sopenharmony_ci } 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci if ((asn1_tags.utype == V_ASN1_SEQUENCE) 126e1051a39Sopenharmony_ci || (asn1_tags.utype == V_ASN1_SET)) { 127e1051a39Sopenharmony_ci if (!cnf) { 128e1051a39Sopenharmony_ci *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; 129e1051a39Sopenharmony_ci return NULL; 130e1051a39Sopenharmony_ci } 131e1051a39Sopenharmony_ci if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { 132e1051a39Sopenharmony_ci *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; 133e1051a39Sopenharmony_ci return NULL; 134e1051a39Sopenharmony_ci } 135e1051a39Sopenharmony_ci ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); 136e1051a39Sopenharmony_ci } else 137e1051a39Sopenharmony_ci ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); 138e1051a39Sopenharmony_ci 139e1051a39Sopenharmony_ci if (!ret) 140e1051a39Sopenharmony_ci return NULL; 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci /* If no tagging return base type */ 143e1051a39Sopenharmony_ci if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) 144e1051a39Sopenharmony_ci return ret; 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci /* Generate the encoding */ 147e1051a39Sopenharmony_ci cpy_len = i2d_ASN1_TYPE(ret, &orig_der); 148e1051a39Sopenharmony_ci ASN1_TYPE_free(ret); 149e1051a39Sopenharmony_ci ret = NULL; 150e1051a39Sopenharmony_ci /* Set point to start copying for modified encoding */ 151e1051a39Sopenharmony_ci cpy_start = orig_der; 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci /* Do we need IMPLICIT tagging? */ 154e1051a39Sopenharmony_ci if (asn1_tags.imp_tag != -1) { 155e1051a39Sopenharmony_ci /* If IMPLICIT we will replace the underlying tag */ 156e1051a39Sopenharmony_ci /* Skip existing tag+len */ 157e1051a39Sopenharmony_ci r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, 158e1051a39Sopenharmony_ci cpy_len); 159e1051a39Sopenharmony_ci if (r & 0x80) 160e1051a39Sopenharmony_ci goto err; 161e1051a39Sopenharmony_ci /* Update copy length */ 162e1051a39Sopenharmony_ci cpy_len -= cpy_start - orig_der; 163e1051a39Sopenharmony_ci /* 164e1051a39Sopenharmony_ci * For IMPLICIT tagging the length should match the original length 165e1051a39Sopenharmony_ci * and constructed flag should be consistent. 166e1051a39Sopenharmony_ci */ 167e1051a39Sopenharmony_ci if (r & 0x1) { 168e1051a39Sopenharmony_ci /* Indefinite length constructed */ 169e1051a39Sopenharmony_ci hdr_constructed = 2; 170e1051a39Sopenharmony_ci hdr_len = 0; 171e1051a39Sopenharmony_ci } else 172e1051a39Sopenharmony_ci /* Just retain constructed flag */ 173e1051a39Sopenharmony_ci hdr_constructed = r & V_ASN1_CONSTRUCTED; 174e1051a39Sopenharmony_ci /* 175e1051a39Sopenharmony_ci * Work out new length with IMPLICIT tag: ignore constructed because 176e1051a39Sopenharmony_ci * it will mess up if indefinite length 177e1051a39Sopenharmony_ci */ 178e1051a39Sopenharmony_ci len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); 179e1051a39Sopenharmony_ci } else 180e1051a39Sopenharmony_ci len = cpy_len; 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci /* Work out length in any EXPLICIT, starting from end */ 183e1051a39Sopenharmony_ci 184e1051a39Sopenharmony_ci for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; 185e1051a39Sopenharmony_ci i < asn1_tags.exp_count; i++, etmp--) { 186e1051a39Sopenharmony_ci /* Content length: number of content octets + any padding */ 187e1051a39Sopenharmony_ci len += etmp->exp_pad; 188e1051a39Sopenharmony_ci etmp->exp_len = len; 189e1051a39Sopenharmony_ci /* Total object length: length including new header */ 190e1051a39Sopenharmony_ci len = ASN1_object_size(0, len, etmp->exp_tag); 191e1051a39Sopenharmony_ci } 192e1051a39Sopenharmony_ci 193e1051a39Sopenharmony_ci /* Allocate buffer for new encoding */ 194e1051a39Sopenharmony_ci 195e1051a39Sopenharmony_ci new_der = OPENSSL_malloc(len); 196e1051a39Sopenharmony_ci if (new_der == NULL) 197e1051a39Sopenharmony_ci goto err; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci /* Generate tagged encoding */ 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci p = new_der; 202e1051a39Sopenharmony_ci 203e1051a39Sopenharmony_ci /* Output explicit tags first */ 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; 206e1051a39Sopenharmony_ci i++, etmp++) { 207e1051a39Sopenharmony_ci ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, 208e1051a39Sopenharmony_ci etmp->exp_tag, etmp->exp_class); 209e1051a39Sopenharmony_ci if (etmp->exp_pad) 210e1051a39Sopenharmony_ci *p++ = 0; 211e1051a39Sopenharmony_ci } 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci /* If IMPLICIT, output tag */ 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci if (asn1_tags.imp_tag != -1) { 216e1051a39Sopenharmony_ci if (asn1_tags.imp_class == V_ASN1_UNIVERSAL 217e1051a39Sopenharmony_ci && (asn1_tags.imp_tag == V_ASN1_SEQUENCE 218e1051a39Sopenharmony_ci || asn1_tags.imp_tag == V_ASN1_SET)) 219e1051a39Sopenharmony_ci hdr_constructed = V_ASN1_CONSTRUCTED; 220e1051a39Sopenharmony_ci ASN1_put_object(&p, hdr_constructed, hdr_len, 221e1051a39Sopenharmony_ci asn1_tags.imp_tag, asn1_tags.imp_class); 222e1051a39Sopenharmony_ci } 223e1051a39Sopenharmony_ci 224e1051a39Sopenharmony_ci /* Copy across original encoding */ 225e1051a39Sopenharmony_ci memcpy(p, cpy_start, cpy_len); 226e1051a39Sopenharmony_ci 227e1051a39Sopenharmony_ci cp = new_der; 228e1051a39Sopenharmony_ci 229e1051a39Sopenharmony_ci /* Obtain new ASN1_TYPE structure */ 230e1051a39Sopenharmony_ci ret = d2i_ASN1_TYPE(NULL, &cp, len); 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci err: 233e1051a39Sopenharmony_ci OPENSSL_free(orig_der); 234e1051a39Sopenharmony_ci OPENSSL_free(new_der); 235e1051a39Sopenharmony_ci 236e1051a39Sopenharmony_ci return ret; 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci} 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_cistatic int asn1_cb(const char *elem, int len, void *bitstr) 241e1051a39Sopenharmony_ci{ 242e1051a39Sopenharmony_ci tag_exp_arg *arg = bitstr; 243e1051a39Sopenharmony_ci int i; 244e1051a39Sopenharmony_ci int utype; 245e1051a39Sopenharmony_ci int vlen = 0; 246e1051a39Sopenharmony_ci const char *p, *vstart = NULL; 247e1051a39Sopenharmony_ci 248e1051a39Sopenharmony_ci int tmp_tag, tmp_class; 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ci if (elem == NULL) 251e1051a39Sopenharmony_ci return -1; 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci for (i = 0, p = elem; i < len; p++, i++) { 254e1051a39Sopenharmony_ci /* Look for the ':' in name value pairs */ 255e1051a39Sopenharmony_ci if (*p == ':') { 256e1051a39Sopenharmony_ci vstart = p + 1; 257e1051a39Sopenharmony_ci vlen = len - (vstart - elem); 258e1051a39Sopenharmony_ci len = p - elem; 259e1051a39Sopenharmony_ci break; 260e1051a39Sopenharmony_ci } 261e1051a39Sopenharmony_ci } 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci utype = asn1_str2tag(elem, len); 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci if (utype == -1) { 266e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG, "tag=%s", elem); 267e1051a39Sopenharmony_ci return -1; 268e1051a39Sopenharmony_ci } 269e1051a39Sopenharmony_ci 270e1051a39Sopenharmony_ci /* If this is not a modifier mark end of string and exit */ 271e1051a39Sopenharmony_ci if (!(utype & ASN1_GEN_FLAG)) { 272e1051a39Sopenharmony_ci arg->utype = utype; 273e1051a39Sopenharmony_ci arg->str = vstart; 274e1051a39Sopenharmony_ci /* If no value and not end of string, error */ 275e1051a39Sopenharmony_ci if (!vstart && elem[len]) { 276e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_MISSING_VALUE); 277e1051a39Sopenharmony_ci return -1; 278e1051a39Sopenharmony_ci } 279e1051a39Sopenharmony_ci return 0; 280e1051a39Sopenharmony_ci } 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci switch (utype) { 283e1051a39Sopenharmony_ci 284e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_IMP: 285e1051a39Sopenharmony_ci /* Check for illegal multiple IMPLICIT tagging */ 286e1051a39Sopenharmony_ci if (arg->imp_tag != -1) { 287e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING); 288e1051a39Sopenharmony_ci return -1; 289e1051a39Sopenharmony_ci } 290e1051a39Sopenharmony_ci if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) 291e1051a39Sopenharmony_ci return -1; 292e1051a39Sopenharmony_ci break; 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_EXP: 295e1051a39Sopenharmony_ci 296e1051a39Sopenharmony_ci if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) 297e1051a39Sopenharmony_ci return -1; 298e1051a39Sopenharmony_ci if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) 299e1051a39Sopenharmony_ci return -1; 300e1051a39Sopenharmony_ci break; 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_SEQWRAP: 303e1051a39Sopenharmony_ci if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) 304e1051a39Sopenharmony_ci return -1; 305e1051a39Sopenharmony_ci break; 306e1051a39Sopenharmony_ci 307e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_SETWRAP: 308e1051a39Sopenharmony_ci if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) 309e1051a39Sopenharmony_ci return -1; 310e1051a39Sopenharmony_ci break; 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_BITWRAP: 313e1051a39Sopenharmony_ci if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) 314e1051a39Sopenharmony_ci return -1; 315e1051a39Sopenharmony_ci break; 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_OCTWRAP: 318e1051a39Sopenharmony_ci if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) 319e1051a39Sopenharmony_ci return -1; 320e1051a39Sopenharmony_ci break; 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci case ASN1_GEN_FLAG_FORMAT: 323e1051a39Sopenharmony_ci if (!vstart) { 324e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); 325e1051a39Sopenharmony_ci return -1; 326e1051a39Sopenharmony_ci } 327e1051a39Sopenharmony_ci if (strncmp(vstart, "ASCII", 5) == 0) 328e1051a39Sopenharmony_ci arg->format = ASN1_GEN_FORMAT_ASCII; 329e1051a39Sopenharmony_ci else if (strncmp(vstart, "UTF8", 4) == 0) 330e1051a39Sopenharmony_ci arg->format = ASN1_GEN_FORMAT_UTF8; 331e1051a39Sopenharmony_ci else if (strncmp(vstart, "HEX", 3) == 0) 332e1051a39Sopenharmony_ci arg->format = ASN1_GEN_FORMAT_HEX; 333e1051a39Sopenharmony_ci else if (strncmp(vstart, "BITLIST", 7) == 0) 334e1051a39Sopenharmony_ci arg->format = ASN1_GEN_FORMAT_BITLIST; 335e1051a39Sopenharmony_ci else { 336e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT); 337e1051a39Sopenharmony_ci return -1; 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci break; 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci } 342e1051a39Sopenharmony_ci 343e1051a39Sopenharmony_ci return 1; 344e1051a39Sopenharmony_ci 345e1051a39Sopenharmony_ci} 346e1051a39Sopenharmony_ci 347e1051a39Sopenharmony_cistatic int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) 348e1051a39Sopenharmony_ci{ 349e1051a39Sopenharmony_ci long tag_num; 350e1051a39Sopenharmony_ci char *eptr; 351e1051a39Sopenharmony_ci if (!vstart) 352e1051a39Sopenharmony_ci return 0; 353e1051a39Sopenharmony_ci tag_num = strtoul(vstart, &eptr, 10); 354e1051a39Sopenharmony_ci /* Check we haven't gone past max length: should be impossible */ 355e1051a39Sopenharmony_ci if (eptr && *eptr && (eptr > vstart + vlen)) 356e1051a39Sopenharmony_ci return 0; 357e1051a39Sopenharmony_ci if (tag_num < 0) { 358e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER); 359e1051a39Sopenharmony_ci return 0; 360e1051a39Sopenharmony_ci } 361e1051a39Sopenharmony_ci *ptag = tag_num; 362e1051a39Sopenharmony_ci /* If we have non numeric characters, parse them */ 363e1051a39Sopenharmony_ci if (eptr) 364e1051a39Sopenharmony_ci vlen -= eptr - vstart; 365e1051a39Sopenharmony_ci else 366e1051a39Sopenharmony_ci vlen = 0; 367e1051a39Sopenharmony_ci if (vlen) { 368e1051a39Sopenharmony_ci switch (*eptr) { 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci case 'U': 371e1051a39Sopenharmony_ci *pclass = V_ASN1_UNIVERSAL; 372e1051a39Sopenharmony_ci break; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci case 'A': 375e1051a39Sopenharmony_ci *pclass = V_ASN1_APPLICATION; 376e1051a39Sopenharmony_ci break; 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_ci case 'P': 379e1051a39Sopenharmony_ci *pclass = V_ASN1_PRIVATE; 380e1051a39Sopenharmony_ci break; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci case 'C': 383e1051a39Sopenharmony_ci *pclass = V_ASN1_CONTEXT_SPECIFIC; 384e1051a39Sopenharmony_ci break; 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci default: 387e1051a39Sopenharmony_ci ERR_raise_data(ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER, 388e1051a39Sopenharmony_ci "Char=%c", *eptr); 389e1051a39Sopenharmony_ci return 0; 390e1051a39Sopenharmony_ci 391e1051a39Sopenharmony_ci } 392e1051a39Sopenharmony_ci } else 393e1051a39Sopenharmony_ci *pclass = V_ASN1_CONTEXT_SPECIFIC; 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci return 1; 396e1051a39Sopenharmony_ci 397e1051a39Sopenharmony_ci} 398e1051a39Sopenharmony_ci 399e1051a39Sopenharmony_ci/* Handle multiple types: SET and SEQUENCE */ 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_cistatic ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, 402e1051a39Sopenharmony_ci int depth, int *perr) 403e1051a39Sopenharmony_ci{ 404e1051a39Sopenharmony_ci ASN1_TYPE *ret = NULL; 405e1051a39Sopenharmony_ci STACK_OF(ASN1_TYPE) *sk = NULL; 406e1051a39Sopenharmony_ci STACK_OF(CONF_VALUE) *sect = NULL; 407e1051a39Sopenharmony_ci unsigned char *der = NULL; 408e1051a39Sopenharmony_ci int derlen; 409e1051a39Sopenharmony_ci int i; 410e1051a39Sopenharmony_ci sk = sk_ASN1_TYPE_new_null(); 411e1051a39Sopenharmony_ci if (!sk) 412e1051a39Sopenharmony_ci goto bad; 413e1051a39Sopenharmony_ci if (section) { 414e1051a39Sopenharmony_ci if (!cnf) 415e1051a39Sopenharmony_ci goto bad; 416e1051a39Sopenharmony_ci sect = X509V3_get_section(cnf, (char *)section); 417e1051a39Sopenharmony_ci if (!sect) 418e1051a39Sopenharmony_ci goto bad; 419e1051a39Sopenharmony_ci for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { 420e1051a39Sopenharmony_ci ASN1_TYPE *typ = 421e1051a39Sopenharmony_ci generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, 422e1051a39Sopenharmony_ci depth + 1, perr); 423e1051a39Sopenharmony_ci if (!typ) 424e1051a39Sopenharmony_ci goto bad; 425e1051a39Sopenharmony_ci if (!sk_ASN1_TYPE_push(sk, typ)) 426e1051a39Sopenharmony_ci goto bad; 427e1051a39Sopenharmony_ci } 428e1051a39Sopenharmony_ci } 429e1051a39Sopenharmony_ci 430e1051a39Sopenharmony_ci /* 431e1051a39Sopenharmony_ci * Now we has a STACK of the components, convert to the correct form 432e1051a39Sopenharmony_ci */ 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci if (utype == V_ASN1_SET) 435e1051a39Sopenharmony_ci derlen = i2d_ASN1_SET_ANY(sk, &der); 436e1051a39Sopenharmony_ci else 437e1051a39Sopenharmony_ci derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); 438e1051a39Sopenharmony_ci 439e1051a39Sopenharmony_ci if (derlen < 0) 440e1051a39Sopenharmony_ci goto bad; 441e1051a39Sopenharmony_ci if ((ret = ASN1_TYPE_new()) == NULL) 442e1051a39Sopenharmony_ci goto bad; 443e1051a39Sopenharmony_ci if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL) 444e1051a39Sopenharmony_ci goto bad; 445e1051a39Sopenharmony_ci 446e1051a39Sopenharmony_ci ret->type = utype; 447e1051a39Sopenharmony_ci ret->value.asn1_string->data = der; 448e1051a39Sopenharmony_ci ret->value.asn1_string->length = derlen; 449e1051a39Sopenharmony_ci 450e1051a39Sopenharmony_ci der = NULL; 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ci bad: 453e1051a39Sopenharmony_ci 454e1051a39Sopenharmony_ci OPENSSL_free(der); 455e1051a39Sopenharmony_ci 456e1051a39Sopenharmony_ci sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); 457e1051a39Sopenharmony_ci X509V3_section_free(cnf, sect); 458e1051a39Sopenharmony_ci 459e1051a39Sopenharmony_ci return ret; 460e1051a39Sopenharmony_ci} 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_cistatic int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, 463e1051a39Sopenharmony_ci int exp_constructed, int exp_pad, int imp_ok) 464e1051a39Sopenharmony_ci{ 465e1051a39Sopenharmony_ci tag_exp_type *exp_tmp; 466e1051a39Sopenharmony_ci /* Can only have IMPLICIT if permitted */ 467e1051a39Sopenharmony_ci if ((arg->imp_tag != -1) && !imp_ok) { 468e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); 469e1051a39Sopenharmony_ci return 0; 470e1051a39Sopenharmony_ci } 471e1051a39Sopenharmony_ci 472e1051a39Sopenharmony_ci if (arg->exp_count == ASN1_FLAG_EXP_MAX) { 473e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED); 474e1051a39Sopenharmony_ci return 0; 475e1051a39Sopenharmony_ci } 476e1051a39Sopenharmony_ci 477e1051a39Sopenharmony_ci exp_tmp = &arg->exp_list[arg->exp_count++]; 478e1051a39Sopenharmony_ci 479e1051a39Sopenharmony_ci /* 480e1051a39Sopenharmony_ci * If IMPLICIT set tag to implicit value then reset implicit tag since it 481e1051a39Sopenharmony_ci * has been used. 482e1051a39Sopenharmony_ci */ 483e1051a39Sopenharmony_ci if (arg->imp_tag != -1) { 484e1051a39Sopenharmony_ci exp_tmp->exp_tag = arg->imp_tag; 485e1051a39Sopenharmony_ci exp_tmp->exp_class = arg->imp_class; 486e1051a39Sopenharmony_ci arg->imp_tag = -1; 487e1051a39Sopenharmony_ci arg->imp_class = -1; 488e1051a39Sopenharmony_ci } else { 489e1051a39Sopenharmony_ci exp_tmp->exp_tag = exp_tag; 490e1051a39Sopenharmony_ci exp_tmp->exp_class = exp_class; 491e1051a39Sopenharmony_ci } 492e1051a39Sopenharmony_ci exp_tmp->exp_constructed = exp_constructed; 493e1051a39Sopenharmony_ci exp_tmp->exp_pad = exp_pad; 494e1051a39Sopenharmony_ci 495e1051a39Sopenharmony_ci return 1; 496e1051a39Sopenharmony_ci} 497e1051a39Sopenharmony_ci 498e1051a39Sopenharmony_cistatic int asn1_str2tag(const char *tagstr, int len) 499e1051a39Sopenharmony_ci{ 500e1051a39Sopenharmony_ci unsigned int i; 501e1051a39Sopenharmony_ci static const struct tag_name_st *tntmp, tnst[] = { 502e1051a39Sopenharmony_ci ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), 503e1051a39Sopenharmony_ci ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), 504e1051a39Sopenharmony_ci ASN1_GEN_STR("NULL", V_ASN1_NULL), 505e1051a39Sopenharmony_ci ASN1_GEN_STR("INT", V_ASN1_INTEGER), 506e1051a39Sopenharmony_ci ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), 507e1051a39Sopenharmony_ci ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), 508e1051a39Sopenharmony_ci ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), 509e1051a39Sopenharmony_ci ASN1_GEN_STR("OID", V_ASN1_OBJECT), 510e1051a39Sopenharmony_ci ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), 511e1051a39Sopenharmony_ci ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), 512e1051a39Sopenharmony_ci ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), 513e1051a39Sopenharmony_ci ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), 514e1051a39Sopenharmony_ci ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), 515e1051a39Sopenharmony_ci ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), 516e1051a39Sopenharmony_ci ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), 517e1051a39Sopenharmony_ci ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), 518e1051a39Sopenharmony_ci ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), 519e1051a39Sopenharmony_ci ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), 520e1051a39Sopenharmony_ci ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), 521e1051a39Sopenharmony_ci ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), 522e1051a39Sopenharmony_ci ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), 523e1051a39Sopenharmony_ci ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), 524e1051a39Sopenharmony_ci ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), 525e1051a39Sopenharmony_ci ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), 526e1051a39Sopenharmony_ci ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), 527e1051a39Sopenharmony_ci ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), 528e1051a39Sopenharmony_ci ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), 529e1051a39Sopenharmony_ci ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), 530e1051a39Sopenharmony_ci ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), 531e1051a39Sopenharmony_ci ASN1_GEN_STR("T61", V_ASN1_T61STRING), 532e1051a39Sopenharmony_ci ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), 533e1051a39Sopenharmony_ci ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), 534e1051a39Sopenharmony_ci ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), 535e1051a39Sopenharmony_ci ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), 536e1051a39Sopenharmony_ci ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), 537e1051a39Sopenharmony_ci ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), 538e1051a39Sopenharmony_ci 539e1051a39Sopenharmony_ci /* Special cases */ 540e1051a39Sopenharmony_ci ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), 541e1051a39Sopenharmony_ci ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), 542e1051a39Sopenharmony_ci ASN1_GEN_STR("SET", V_ASN1_SET), 543e1051a39Sopenharmony_ci /* type modifiers */ 544e1051a39Sopenharmony_ci /* Explicit tag */ 545e1051a39Sopenharmony_ci ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), 546e1051a39Sopenharmony_ci ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), 547e1051a39Sopenharmony_ci /* Implicit tag */ 548e1051a39Sopenharmony_ci ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), 549e1051a39Sopenharmony_ci ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), 550e1051a39Sopenharmony_ci /* OCTET STRING wrapper */ 551e1051a39Sopenharmony_ci ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), 552e1051a39Sopenharmony_ci /* SEQUENCE wrapper */ 553e1051a39Sopenharmony_ci ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), 554e1051a39Sopenharmony_ci /* SET wrapper */ 555e1051a39Sopenharmony_ci ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), 556e1051a39Sopenharmony_ci /* BIT STRING wrapper */ 557e1051a39Sopenharmony_ci ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), 558e1051a39Sopenharmony_ci ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), 559e1051a39Sopenharmony_ci ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), 560e1051a39Sopenharmony_ci }; 561e1051a39Sopenharmony_ci 562e1051a39Sopenharmony_ci if (len == -1) 563e1051a39Sopenharmony_ci len = strlen(tagstr); 564e1051a39Sopenharmony_ci 565e1051a39Sopenharmony_ci tntmp = tnst; 566e1051a39Sopenharmony_ci for (i = 0; i < OSSL_NELEM(tnst); i++, tntmp++) { 567e1051a39Sopenharmony_ci if ((len == tntmp->len) 568e1051a39Sopenharmony_ci && (OPENSSL_strncasecmp(tntmp->strnam, tagstr, len) == 0)) 569e1051a39Sopenharmony_ci return tntmp->tag; 570e1051a39Sopenharmony_ci } 571e1051a39Sopenharmony_ci 572e1051a39Sopenharmony_ci return -1; 573e1051a39Sopenharmony_ci} 574e1051a39Sopenharmony_ci 575e1051a39Sopenharmony_cistatic ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) 576e1051a39Sopenharmony_ci{ 577e1051a39Sopenharmony_ci ASN1_TYPE *atmp = NULL; 578e1051a39Sopenharmony_ci CONF_VALUE vtmp; 579e1051a39Sopenharmony_ci unsigned char *rdata; 580e1051a39Sopenharmony_ci long rdlen; 581e1051a39Sopenharmony_ci int no_unused = 1; 582e1051a39Sopenharmony_ci 583e1051a39Sopenharmony_ci if ((atmp = ASN1_TYPE_new()) == NULL) { 584e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 585e1051a39Sopenharmony_ci return NULL; 586e1051a39Sopenharmony_ci } 587e1051a39Sopenharmony_ci 588e1051a39Sopenharmony_ci if (!str) 589e1051a39Sopenharmony_ci str = ""; 590e1051a39Sopenharmony_ci 591e1051a39Sopenharmony_ci switch (utype) { 592e1051a39Sopenharmony_ci 593e1051a39Sopenharmony_ci case V_ASN1_NULL: 594e1051a39Sopenharmony_ci if (str && *str) { 595e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE); 596e1051a39Sopenharmony_ci goto bad_form; 597e1051a39Sopenharmony_ci } 598e1051a39Sopenharmony_ci break; 599e1051a39Sopenharmony_ci 600e1051a39Sopenharmony_ci case V_ASN1_BOOLEAN: 601e1051a39Sopenharmony_ci if (format != ASN1_GEN_FORMAT_ASCII) { 602e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT); 603e1051a39Sopenharmony_ci goto bad_form; 604e1051a39Sopenharmony_ci } 605e1051a39Sopenharmony_ci vtmp.name = NULL; 606e1051a39Sopenharmony_ci vtmp.section = NULL; 607e1051a39Sopenharmony_ci vtmp.value = (char *)str; 608e1051a39Sopenharmony_ci if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { 609e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN); 610e1051a39Sopenharmony_ci goto bad_str; 611e1051a39Sopenharmony_ci } 612e1051a39Sopenharmony_ci break; 613e1051a39Sopenharmony_ci 614e1051a39Sopenharmony_ci case V_ASN1_INTEGER: 615e1051a39Sopenharmony_ci case V_ASN1_ENUMERATED: 616e1051a39Sopenharmony_ci if (format != ASN1_GEN_FORMAT_ASCII) { 617e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); 618e1051a39Sopenharmony_ci goto bad_form; 619e1051a39Sopenharmony_ci } 620e1051a39Sopenharmony_ci if ((atmp->value.integer 621e1051a39Sopenharmony_ci = s2i_ASN1_INTEGER(NULL, str)) == NULL) { 622e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER); 623e1051a39Sopenharmony_ci goto bad_str; 624e1051a39Sopenharmony_ci } 625e1051a39Sopenharmony_ci break; 626e1051a39Sopenharmony_ci 627e1051a39Sopenharmony_ci case V_ASN1_OBJECT: 628e1051a39Sopenharmony_ci if (format != ASN1_GEN_FORMAT_ASCII) { 629e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); 630e1051a39Sopenharmony_ci goto bad_form; 631e1051a39Sopenharmony_ci } 632e1051a39Sopenharmony_ci if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) { 633e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT); 634e1051a39Sopenharmony_ci goto bad_str; 635e1051a39Sopenharmony_ci } 636e1051a39Sopenharmony_ci break; 637e1051a39Sopenharmony_ci 638e1051a39Sopenharmony_ci case V_ASN1_UTCTIME: 639e1051a39Sopenharmony_ci case V_ASN1_GENERALIZEDTIME: 640e1051a39Sopenharmony_ci if (format != ASN1_GEN_FORMAT_ASCII) { 641e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); 642e1051a39Sopenharmony_ci goto bad_form; 643e1051a39Sopenharmony_ci } 644e1051a39Sopenharmony_ci if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { 645e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 646e1051a39Sopenharmony_ci goto bad_str; 647e1051a39Sopenharmony_ci } 648e1051a39Sopenharmony_ci if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { 649e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 650e1051a39Sopenharmony_ci goto bad_str; 651e1051a39Sopenharmony_ci } 652e1051a39Sopenharmony_ci atmp->value.asn1_string->type = utype; 653e1051a39Sopenharmony_ci if (!ASN1_TIME_check(atmp->value.asn1_string)) { 654e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE); 655e1051a39Sopenharmony_ci goto bad_str; 656e1051a39Sopenharmony_ci } 657e1051a39Sopenharmony_ci 658e1051a39Sopenharmony_ci break; 659e1051a39Sopenharmony_ci 660e1051a39Sopenharmony_ci case V_ASN1_BMPSTRING: 661e1051a39Sopenharmony_ci case V_ASN1_PRINTABLESTRING: 662e1051a39Sopenharmony_ci case V_ASN1_IA5STRING: 663e1051a39Sopenharmony_ci case V_ASN1_T61STRING: 664e1051a39Sopenharmony_ci case V_ASN1_UTF8STRING: 665e1051a39Sopenharmony_ci case V_ASN1_VISIBLESTRING: 666e1051a39Sopenharmony_ci case V_ASN1_UNIVERSALSTRING: 667e1051a39Sopenharmony_ci case V_ASN1_GENERALSTRING: 668e1051a39Sopenharmony_ci case V_ASN1_NUMERICSTRING: 669e1051a39Sopenharmony_ci if (format == ASN1_GEN_FORMAT_ASCII) 670e1051a39Sopenharmony_ci format = MBSTRING_ASC; 671e1051a39Sopenharmony_ci else if (format == ASN1_GEN_FORMAT_UTF8) 672e1051a39Sopenharmony_ci format = MBSTRING_UTF8; 673e1051a39Sopenharmony_ci else { 674e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT); 675e1051a39Sopenharmony_ci goto bad_form; 676e1051a39Sopenharmony_ci } 677e1051a39Sopenharmony_ci 678e1051a39Sopenharmony_ci if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, 679e1051a39Sopenharmony_ci -1, format, ASN1_tag2bit(utype)) <= 0) { 680e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 681e1051a39Sopenharmony_ci goto bad_str; 682e1051a39Sopenharmony_ci } 683e1051a39Sopenharmony_ci 684e1051a39Sopenharmony_ci break; 685e1051a39Sopenharmony_ci 686e1051a39Sopenharmony_ci case V_ASN1_BIT_STRING: 687e1051a39Sopenharmony_ci case V_ASN1_OCTET_STRING: 688e1051a39Sopenharmony_ci if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) { 689e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 690e1051a39Sopenharmony_ci goto bad_form; 691e1051a39Sopenharmony_ci } 692e1051a39Sopenharmony_ci 693e1051a39Sopenharmony_ci if (format == ASN1_GEN_FORMAT_HEX) { 694e1051a39Sopenharmony_ci if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) { 695e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX); 696e1051a39Sopenharmony_ci goto bad_str; 697e1051a39Sopenharmony_ci } 698e1051a39Sopenharmony_ci atmp->value.asn1_string->data = rdata; 699e1051a39Sopenharmony_ci atmp->value.asn1_string->length = rdlen; 700e1051a39Sopenharmony_ci atmp->value.asn1_string->type = utype; 701e1051a39Sopenharmony_ci } else if (format == ASN1_GEN_FORMAT_ASCII) 702e1051a39Sopenharmony_ci ASN1_STRING_set(atmp->value.asn1_string, str, -1); 703e1051a39Sopenharmony_ci else if ((format == ASN1_GEN_FORMAT_BITLIST) 704e1051a39Sopenharmony_ci && (utype == V_ASN1_BIT_STRING)) { 705e1051a39Sopenharmony_ci if (!CONF_parse_list 706e1051a39Sopenharmony_ci (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { 707e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_LIST_ERROR); 708e1051a39Sopenharmony_ci goto bad_str; 709e1051a39Sopenharmony_ci } 710e1051a39Sopenharmony_ci no_unused = 0; 711e1051a39Sopenharmony_ci 712e1051a39Sopenharmony_ci } else { 713e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); 714e1051a39Sopenharmony_ci goto bad_form; 715e1051a39Sopenharmony_ci } 716e1051a39Sopenharmony_ci 717e1051a39Sopenharmony_ci if ((utype == V_ASN1_BIT_STRING) && no_unused) { 718e1051a39Sopenharmony_ci atmp->value.asn1_string->flags 719e1051a39Sopenharmony_ci &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); 720e1051a39Sopenharmony_ci atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; 721e1051a39Sopenharmony_ci } 722e1051a39Sopenharmony_ci 723e1051a39Sopenharmony_ci break; 724e1051a39Sopenharmony_ci 725e1051a39Sopenharmony_ci default: 726e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE); 727e1051a39Sopenharmony_ci goto bad_str; 728e1051a39Sopenharmony_ci } 729e1051a39Sopenharmony_ci 730e1051a39Sopenharmony_ci atmp->type = utype; 731e1051a39Sopenharmony_ci return atmp; 732e1051a39Sopenharmony_ci 733e1051a39Sopenharmony_ci bad_str: 734e1051a39Sopenharmony_ci ERR_add_error_data(2, "string=", str); 735e1051a39Sopenharmony_ci bad_form: 736e1051a39Sopenharmony_ci 737e1051a39Sopenharmony_ci ASN1_TYPE_free(atmp); 738e1051a39Sopenharmony_ci return NULL; 739e1051a39Sopenharmony_ci 740e1051a39Sopenharmony_ci} 741e1051a39Sopenharmony_ci 742e1051a39Sopenharmony_cistatic int bitstr_cb(const char *elem, int len, void *bitstr) 743e1051a39Sopenharmony_ci{ 744e1051a39Sopenharmony_ci long bitnum; 745e1051a39Sopenharmony_ci char *eptr; 746e1051a39Sopenharmony_ci if (!elem) 747e1051a39Sopenharmony_ci return 0; 748e1051a39Sopenharmony_ci bitnum = strtoul(elem, &eptr, 10); 749e1051a39Sopenharmony_ci if (eptr && *eptr && (eptr != elem + len)) 750e1051a39Sopenharmony_ci return 0; 751e1051a39Sopenharmony_ci if (bitnum < 0) { 752e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER); 753e1051a39Sopenharmony_ci return 0; 754e1051a39Sopenharmony_ci } 755e1051a39Sopenharmony_ci if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { 756e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 757e1051a39Sopenharmony_ci return 0; 758e1051a39Sopenharmony_ci } 759e1051a39Sopenharmony_ci return 1; 760e1051a39Sopenharmony_ci} 761e1051a39Sopenharmony_ci 762e1051a39Sopenharmony_cistatic int mask_cb(const char *elem, int len, void *arg) 763e1051a39Sopenharmony_ci{ 764e1051a39Sopenharmony_ci unsigned long *pmask = arg, tmpmask; 765e1051a39Sopenharmony_ci int tag; 766e1051a39Sopenharmony_ci if (elem == NULL) 767e1051a39Sopenharmony_ci return 0; 768e1051a39Sopenharmony_ci if ((len == 3) && (strncmp(elem, "DIR", 3) == 0)) { 769e1051a39Sopenharmony_ci *pmask |= B_ASN1_DIRECTORYSTRING; 770e1051a39Sopenharmony_ci return 1; 771e1051a39Sopenharmony_ci } 772e1051a39Sopenharmony_ci tag = asn1_str2tag(elem, len); 773e1051a39Sopenharmony_ci if (!tag || (tag & ASN1_GEN_FLAG)) 774e1051a39Sopenharmony_ci return 0; 775e1051a39Sopenharmony_ci tmpmask = ASN1_tag2bit(tag); 776e1051a39Sopenharmony_ci if (!tmpmask) 777e1051a39Sopenharmony_ci return 0; 778e1051a39Sopenharmony_ci *pmask |= tmpmask; 779e1051a39Sopenharmony_ci return 1; 780e1051a39Sopenharmony_ci} 781e1051a39Sopenharmony_ci 782e1051a39Sopenharmony_ciint ASN1_str2mask(const char *str, unsigned long *pmask) 783e1051a39Sopenharmony_ci{ 784e1051a39Sopenharmony_ci *pmask = 0; 785e1051a39Sopenharmony_ci return CONF_parse_list(str, '|', 1, mask_cb, pmask); 786e1051a39Sopenharmony_ci} 787