]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/tasn_new.c
2 * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
11 #include <openssl/asn1.h>
12 #include <openssl/objects.h>
13 #include <openssl/err.h>
14 #include <openssl/asn1t.h>
16 #include "asn1_local.h"
18 static int asn1_item_embed_new(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
19 int embed
, OSSL_LIB_CTX
*libctx
,
21 static int asn1_primitive_new(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
23 static void asn1_item_clear(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
);
24 static int asn1_template_new(ASN1_VALUE
**pval
, const ASN1_TEMPLATE
*tt
,
25 OSSL_LIB_CTX
*libctx
, const char *propq
);
26 static void asn1_template_clear(ASN1_VALUE
**pval
, const ASN1_TEMPLATE
*tt
);
27 static void asn1_primitive_clear(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
);
29 ASN1_VALUE
*ASN1_item_new(const ASN1_ITEM
*it
)
31 ASN1_VALUE
*ret
= NULL
;
32 if (ASN1_item_ex_new(&ret
, it
) > 0)
37 ASN1_VALUE
*ASN1_item_new_ex(const ASN1_ITEM
*it
, OSSL_LIB_CTX
*libctx
,
40 ASN1_VALUE
*ret
= NULL
;
41 if (asn1_item_embed_new(&ret
, it
, 0, libctx
, propq
) > 0)
46 /* Allocate an ASN1 structure */
49 int ossl_asn1_item_ex_new_intern(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
50 OSSL_LIB_CTX
*libctx
, const char *propq
)
52 return asn1_item_embed_new(pval
, it
, 0, libctx
, propq
);
55 int ASN1_item_ex_new(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
)
57 return asn1_item_embed_new(pval
, it
, 0, NULL
, NULL
);
60 int asn1_item_embed_new(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
, int embed
,
61 OSSL_LIB_CTX
*libctx
, const char *propq
)
63 const ASN1_TEMPLATE
*tt
= NULL
;
64 const ASN1_EXTERN_FUNCS
*ef
;
65 const ASN1_AUX
*aux
= it
->funcs
;
69 if (aux
&& aux
->asn1_cb
)
70 asn1_cb
= aux
->asn1_cb
;
76 case ASN1_ITYPE_EXTERN
:
79 if (ef
->asn1_ex_new_ex
!= NULL
) {
80 if (!ef
->asn1_ex_new_ex(pval
, it
, libctx
, propq
))
82 } else if (ef
->asn1_ex_new
!= NULL
) {
83 if (!ef
->asn1_ex_new(pval
, it
))
89 case ASN1_ITYPE_PRIMITIVE
:
91 if (!asn1_template_new(pval
, it
->templates
, libctx
, propq
))
93 } else if (!asn1_primitive_new(pval
, it
, embed
))
97 case ASN1_ITYPE_MSTRING
:
98 if (!asn1_primitive_new(pval
, it
, embed
))
102 case ASN1_ITYPE_CHOICE
:
104 i
= asn1_cb(ASN1_OP_NEW_PRE
, pval
, it
, NULL
);
112 memset(*pval
, 0, it
->size
);
114 *pval
= OPENSSL_zalloc(it
->size
);
118 ossl_asn1_set_choice_selector(pval
, -1, it
);
119 if (asn1_cb
&& !asn1_cb(ASN1_OP_NEW_POST
, pval
, it
, NULL
))
123 case ASN1_ITYPE_NDEF_SEQUENCE
:
124 case ASN1_ITYPE_SEQUENCE
:
126 i
= asn1_cb(ASN1_OP_NEW_PRE
, pval
, it
, NULL
);
134 memset(*pval
, 0, it
->size
);
136 *pval
= OPENSSL_zalloc(it
->size
);
141 if (ossl_asn1_do_lock(pval
, 0, it
) < 0) {
148 ossl_asn1_enc_init(pval
, it
);
149 for (i
= 0, tt
= it
->templates
; i
< it
->tcount
; tt
++, i
++) {
150 pseqval
= ossl_asn1_get_field_ptr(pval
, tt
);
151 if (!asn1_template_new(pseqval
, tt
, libctx
, propq
))
154 if (asn1_cb
&& !asn1_cb(ASN1_OP_NEW_POST
, pval
, it
, NULL
))
161 ossl_asn1_item_embed_free(pval
, it
, embed
);
163 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
167 ossl_asn1_item_embed_free(pval
, it
, embed
);
169 ERR_raise(ERR_LIB_ASN1
, ASN1_R_AUX_ERROR
);
174 static void asn1_item_clear(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
)
176 const ASN1_EXTERN_FUNCS
*ef
;
180 case ASN1_ITYPE_EXTERN
:
182 if (ef
&& ef
->asn1_ex_clear
)
183 ef
->asn1_ex_clear(pval
, it
);
188 case ASN1_ITYPE_PRIMITIVE
:
190 asn1_template_clear(pval
, it
->templates
);
192 asn1_primitive_clear(pval
, it
);
195 case ASN1_ITYPE_MSTRING
:
196 asn1_primitive_clear(pval
, it
);
199 case ASN1_ITYPE_CHOICE
:
200 case ASN1_ITYPE_SEQUENCE
:
201 case ASN1_ITYPE_NDEF_SEQUENCE
:
207 static int asn1_template_new(ASN1_VALUE
**pval
, const ASN1_TEMPLATE
*tt
,
208 OSSL_LIB_CTX
*libctx
, const char *propq
)
210 const ASN1_ITEM
*it
= ASN1_ITEM_ptr(tt
->item
);
211 int embed
= tt
->flags
& ASN1_TFLG_EMBED
;
215 tval
= (ASN1_VALUE
*)pval
;
218 if (tt
->flags
& ASN1_TFLG_OPTIONAL
) {
219 asn1_template_clear(pval
, tt
);
222 /* If ANY DEFINED BY nothing to do */
224 if (tt
->flags
& ASN1_TFLG_ADB_MASK
) {
228 /* If SET OF or SEQUENCE OF, its a STACK */
229 if (tt
->flags
& ASN1_TFLG_SK_MASK
) {
230 STACK_OF(ASN1_VALUE
) *skval
;
231 skval
= sk_ASN1_VALUE_new_null();
233 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
237 *pval
= (ASN1_VALUE
*)skval
;
241 /* Otherwise pass it back to the item routine */
242 ret
= asn1_item_embed_new(pval
, it
, embed
, libctx
, propq
);
247 static void asn1_template_clear(ASN1_VALUE
**pval
, const ASN1_TEMPLATE
*tt
)
249 /* If ADB or STACK just NULL the field */
250 if (tt
->flags
& (ASN1_TFLG_ADB_MASK
| ASN1_TFLG_SK_MASK
))
253 asn1_item_clear(pval
, ASN1_ITEM_ptr(tt
->item
));
257 * NB: could probably combine most of the real XXX_new() behaviour and junk
258 * all the old functions.
261 static int asn1_primitive_new(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
,
272 const ASN1_PRIMITIVE_FUNCS
*pf
= it
->funcs
;
274 if (pf
->prim_clear
) {
275 pf
->prim_clear(pval
, it
);
278 } else if (pf
->prim_new
) {
279 return pf
->prim_new(pval
, it
);
283 if (it
->itype
== ASN1_ITYPE_MSTRING
)
289 *pval
= (ASN1_VALUE
*)OBJ_nid2obj(NID_undef
);
293 *(ASN1_BOOLEAN
*)pval
= it
->size
;
297 *pval
= (ASN1_VALUE
*)1;
301 if ((typ
= OPENSSL_malloc(sizeof(*typ
))) == NULL
) {
302 ERR_raise(ERR_LIB_ASN1
, ERR_R_MALLOC_FAILURE
);
305 typ
->value
.ptr
= NULL
;
307 *pval
= (ASN1_VALUE
*)typ
;
312 str
= *(ASN1_STRING
**)pval
;
313 memset(str
, 0, sizeof(*str
));
315 str
->flags
= ASN1_STRING_FLAG_EMBED
;
317 str
= ASN1_STRING_type_new(utype
);
318 *pval
= (ASN1_VALUE
*)str
;
320 if (it
->itype
== ASN1_ITYPE_MSTRING
&& str
)
321 str
->flags
|= ASN1_STRING_FLAG_MSTRING
;
329 static void asn1_primitive_clear(ASN1_VALUE
**pval
, const ASN1_ITEM
*it
)
332 if (it
&& it
->funcs
) {
333 const ASN1_PRIMITIVE_FUNCS
*pf
= it
->funcs
;
335 pf
->prim_clear(pval
, it
);
340 if (!it
|| (it
->itype
== ASN1_ITYPE_MSTRING
))
344 if (utype
== V_ASN1_BOOLEAN
)
345 *(ASN1_BOOLEAN
*)pval
= it
->size
;