1/*
2 * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stddef.h>
11#include <openssl/asn1.h>
12#include <openssl/objects.h>
13#include <openssl/err.h>
14#include <openssl/asn1t.h>
15#include <string.h>
16#include "asn1_local.h"
17
18static int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
19                               int embed);
20static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
21                              int embed);
22static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
23static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
24static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
25static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
26
27ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
28{
29    ASN1_VALUE *ret = NULL;
30    if (ASN1_item_ex_new(&ret, it) > 0)
31        return ret;
32    return NULL;
33}
34
35/* Allocate an ASN1 structure */
36
37int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
38{
39    return asn1_item_embed_new(pval, it, 0);
40}
41
42int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
43{
44    const ASN1_TEMPLATE *tt = NULL;
45    const ASN1_EXTERN_FUNCS *ef;
46    const ASN1_AUX *aux = it->funcs;
47    ASN1_aux_cb *asn1_cb;
48    ASN1_VALUE **pseqval;
49    int i;
50    if (aux && aux->asn1_cb)
51        asn1_cb = aux->asn1_cb;
52    else
53        asn1_cb = 0;
54
55#ifndef OPENSSL_NO_CRYPTO_MDEBUG
56    OPENSSL_mem_debug_push(it->sname ? it->sname : "asn1_item_embed_new");
57#endif
58
59    switch (it->itype) {
60
61    case ASN1_ITYPE_EXTERN:
62        ef = it->funcs;
63        if (ef && ef->asn1_ex_new) {
64            if (!ef->asn1_ex_new(pval, it))
65                goto memerr;
66        }
67        break;
68
69    case ASN1_ITYPE_PRIMITIVE:
70        if (it->templates) {
71            if (!asn1_template_new(pval, it->templates))
72                goto memerr;
73        } else if (!asn1_primitive_new(pval, it, embed))
74            goto memerr;
75        break;
76
77    case ASN1_ITYPE_MSTRING:
78        if (!asn1_primitive_new(pval, it, embed))
79            goto memerr;
80        break;
81
82    case ASN1_ITYPE_CHOICE:
83        if (asn1_cb) {
84            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
85            if (!i)
86                goto auxerr;
87            if (i == 2) {
88#ifndef OPENSSL_NO_CRYPTO_MDEBUG
89                OPENSSL_mem_debug_pop();
90#endif
91                return 1;
92            }
93        }
94        if (embed) {
95            memset(*pval, 0, it->size);
96        } else {
97            *pval = OPENSSL_zalloc(it->size);
98            if (*pval == NULL)
99                goto memerr;
100        }
101        asn1_set_choice_selector(pval, -1, it);
102        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
103            goto auxerr2;
104        break;
105
106    case ASN1_ITYPE_NDEF_SEQUENCE:
107    case ASN1_ITYPE_SEQUENCE:
108        if (asn1_cb) {
109            i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
110            if (!i)
111                goto auxerr;
112            if (i == 2) {
113#ifndef OPENSSL_NO_CRYPTO_MDEBUG
114                OPENSSL_mem_debug_pop();
115#endif
116                return 1;
117            }
118        }
119        if (embed) {
120            memset(*pval, 0, it->size);
121        } else {
122            *pval = OPENSSL_zalloc(it->size);
123            if (*pval == NULL)
124                goto memerr;
125        }
126        /* 0 : init. lock */
127        if (asn1_do_lock(pval, 0, it) < 0) {
128            if (!embed) {
129                OPENSSL_free(*pval);
130                *pval = NULL;
131            }
132            goto memerr;
133        }
134        asn1_enc_init(pval, it);
135        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
136            pseqval = asn1_get_field_ptr(pval, tt);
137            if (!asn1_template_new(pseqval, tt))
138                goto memerr2;
139        }
140        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
141            goto auxerr2;
142        break;
143    }
144#ifndef OPENSSL_NO_CRYPTO_MDEBUG
145    OPENSSL_mem_debug_pop();
146#endif
147    return 1;
148
149 memerr2:
150    asn1_item_embed_free(pval, it, embed);
151 memerr:
152    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
153#ifndef OPENSSL_NO_CRYPTO_MDEBUG
154    OPENSSL_mem_debug_pop();
155#endif
156    return 0;
157
158 auxerr2:
159    asn1_item_embed_free(pval, it, embed);
160 auxerr:
161    ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
162#ifndef OPENSSL_NO_CRYPTO_MDEBUG
163    OPENSSL_mem_debug_pop();
164#endif
165    return 0;
166
167}
168
169static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
170{
171    const ASN1_EXTERN_FUNCS *ef;
172
173    switch (it->itype) {
174
175    case ASN1_ITYPE_EXTERN:
176        ef = it->funcs;
177        if (ef && ef->asn1_ex_clear)
178            ef->asn1_ex_clear(pval, it);
179        else
180            *pval = NULL;
181        break;
182
183    case ASN1_ITYPE_PRIMITIVE:
184        if (it->templates)
185            asn1_template_clear(pval, it->templates);
186        else
187            asn1_primitive_clear(pval, it);
188        break;
189
190    case ASN1_ITYPE_MSTRING:
191        asn1_primitive_clear(pval, it);
192        break;
193
194    case ASN1_ITYPE_CHOICE:
195    case ASN1_ITYPE_SEQUENCE:
196    case ASN1_ITYPE_NDEF_SEQUENCE:
197        *pval = NULL;
198        break;
199    }
200}
201
202static int asn1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
203{
204    const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
205    int embed = tt->flags & ASN1_TFLG_EMBED;
206    ASN1_VALUE *tval;
207    int ret;
208    if (embed) {
209        tval = (ASN1_VALUE *)pval;
210        pval = &tval;
211    }
212    if (tt->flags & ASN1_TFLG_OPTIONAL) {
213        asn1_template_clear(pval, tt);
214        return 1;
215    }
216    /* If ANY DEFINED BY nothing to do */
217
218    if (tt->flags & ASN1_TFLG_ADB_MASK) {
219        *pval = NULL;
220        return 1;
221    }
222#ifndef OPENSSL_NO_CRYPTO_MDEBUG
223    OPENSSL_mem_debug_push(tt->field_name
224            ? tt->field_name : "asn1_template_new");
225#endif
226    /* If SET OF or SEQUENCE OF, its a STACK */
227    if (tt->flags & ASN1_TFLG_SK_MASK) {
228        STACK_OF(ASN1_VALUE) *skval;
229        skval = sk_ASN1_VALUE_new_null();
230        if (!skval) {
231            ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
232            ret = 0;
233            goto done;
234        }
235        *pval = (ASN1_VALUE *)skval;
236        ret = 1;
237        goto done;
238    }
239    /* Otherwise pass it back to the item routine */
240    ret = asn1_item_embed_new(pval, it, embed);
241 done:
242#ifndef OPENSSL_NO_CRYPTO_MDEBUG
243    OPENSSL_mem_debug_pop();
244#endif
245    return ret;
246}
247
248static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
249{
250    /* If ADB or STACK just NULL the field */
251    if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
252        *pval = NULL;
253    else
254        asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
255}
256
257/*
258 * NB: could probably combine most of the real XXX_new() behaviour and junk
259 * all the old functions.
260 */
261
262static int asn1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
263                              int embed)
264{
265    ASN1_TYPE *typ;
266    ASN1_STRING *str;
267    int utype;
268
269    if (!it)
270        return 0;
271
272    if (it->funcs) {
273        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
274        if (embed) {
275            if (pf->prim_clear) {
276                pf->prim_clear(pval, it);
277                return 1;
278            }
279        } else if (pf->prim_new) {
280            return pf->prim_new(pval, it);
281        }
282    }
283
284    if (it->itype == ASN1_ITYPE_MSTRING)
285        utype = -1;
286    else
287        utype = it->utype;
288    switch (utype) {
289    case V_ASN1_OBJECT:
290        *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
291        return 1;
292
293    case V_ASN1_BOOLEAN:
294        *(ASN1_BOOLEAN *)pval = it->size;
295        return 1;
296
297    case V_ASN1_NULL:
298        *pval = (ASN1_VALUE *)1;
299        return 1;
300
301    case V_ASN1_ANY:
302        if ((typ = OPENSSL_malloc(sizeof(*typ))) == NULL) {
303            ASN1err(ASN1_F_ASN1_PRIMITIVE_NEW, ERR_R_MALLOC_FAILURE);
304            return 0;
305        }
306        typ->value.ptr = NULL;
307        typ->type = -1;
308        *pval = (ASN1_VALUE *)typ;
309        break;
310
311    default:
312        if (embed) {
313            str = *(ASN1_STRING **)pval;
314            memset(str, 0, sizeof(*str));
315            str->type = utype;
316            str->flags = ASN1_STRING_FLAG_EMBED;
317        } else {
318            str = ASN1_STRING_type_new(utype);
319            *pval = (ASN1_VALUE *)str;
320        }
321        if (it->itype == ASN1_ITYPE_MSTRING && str)
322            str->flags |= ASN1_STRING_FLAG_MSTRING;
323        break;
324    }
325    if (*pval)
326        return 1;
327    return 0;
328}
329
330static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
331{
332    int utype;
333    if (it && it->funcs) {
334        const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
335        if (pf->prim_clear)
336            pf->prim_clear(pval, it);
337        else
338            *pval = NULL;
339        return;
340    }
341    if (!it || (it->itype == ASN1_ITYPE_MSTRING))
342        utype = -1;
343    else
344        utype = it->utype;
345    if (utype == V_ASN1_BOOLEAN)
346        *(ASN1_BOOLEAN *)pval = it->size;
347    else
348        *pval = NULL;
349}
350