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