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