1e71b7053SJung-uk Kim /*
2b077aed3SPierre Pronchery * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
374664626SKris Kennaway *
4b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5e71b7053SJung-uk Kim * this file except in compliance with the License. You can obtain a copy
6e71b7053SJung-uk Kim * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim * https://www.openssl.org/source/license.html
874664626SKris Kennaway */
974664626SKris Kennaway
1074664626SKris Kennaway #include <stdio.h>
11e71b7053SJung-uk Kim #include "internal/cryptlib.h"
12b077aed3SPierre Pronchery #include <openssl/asn1t.h>
1374664626SKris Kennaway
145c87c606SMark Murray #ifndef NO_OLD_ASN1
1574664626SKris Kennaway
ASN1_dup(i2d_of_void * i2d,d2i_of_void * d2i,const void * x)16b077aed3SPierre Pronchery void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x)
1774664626SKris Kennaway {
1874664626SKris Kennaway unsigned char *b, *p;
193b4e3dcbSSimon L. B. Nielsen const unsigned char *p2;
203b4e3dcbSSimon L. B. Nielsen int i;
2174664626SKris Kennaway char *ret;
2274664626SKris Kennaway
236f9291ceSJung-uk Kim if (x == NULL)
24e71b7053SJung-uk Kim return NULL;
2574664626SKris Kennaway
263b4e3dcbSSimon L. B. Nielsen i = i2d(x, NULL);
27b077aed3SPierre Pronchery if (i <= 0)
28b077aed3SPierre Pronchery return NULL;
29b077aed3SPierre Pronchery
303b4e3dcbSSimon L. B. Nielsen b = OPENSSL_malloc(i + 10);
316f9291ceSJung-uk Kim if (b == NULL) {
32b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
33e71b7053SJung-uk Kim return NULL;
346f9291ceSJung-uk Kim }
3574664626SKris Kennaway p = b;
3674664626SKris Kennaway i = i2d(x, &p);
373b4e3dcbSSimon L. B. Nielsen p2 = b;
383b4e3dcbSSimon L. B. Nielsen ret = d2i(NULL, &p2, i);
39ddd58736SKris Kennaway OPENSSL_free(b);
40e71b7053SJung-uk Kim return ret;
4174664626SKris Kennaway }
425c87c606SMark Murray
435c87c606SMark Murray #endif
445c87c606SMark Murray
456f9291ceSJung-uk Kim /*
466f9291ceSJung-uk Kim * ASN1_ITEM version of dup: this follows the model above except we don't
476f9291ceSJung-uk Kim * need to allocate the buffer. At some point this could be rewritten to
486f9291ceSJung-uk Kim * directly dup the underlying structure instead of doing and encode and
496f9291ceSJung-uk Kim * decode.
505c87c606SMark Murray */
515c87c606SMark Murray
ASN1_item_dup(const ASN1_ITEM * it,const void * x)52b077aed3SPierre Pronchery void *ASN1_item_dup(const ASN1_ITEM *it, const void *x)
535c87c606SMark Murray {
54b077aed3SPierre Pronchery ASN1_aux_cb *asn1_cb = NULL;
553b4e3dcbSSimon L. B. Nielsen unsigned char *b = NULL;
563b4e3dcbSSimon L. B. Nielsen const unsigned char *p;
575c87c606SMark Murray long i;
58b077aed3SPierre Pronchery ASN1_VALUE *ret;
59b077aed3SPierre Pronchery OSSL_LIB_CTX *libctx = NULL;
60b077aed3SPierre Pronchery const char *propq = NULL;
615c87c606SMark Murray
626f9291ceSJung-uk Kim if (x == NULL)
63e71b7053SJung-uk Kim return NULL;
645c87c606SMark Murray
65b077aed3SPierre Pronchery if (it->itype == ASN1_ITYPE_SEQUENCE || it->itype == ASN1_ITYPE_CHOICE
66b077aed3SPierre Pronchery || it->itype == ASN1_ITYPE_NDEF_SEQUENCE) {
67b077aed3SPierre Pronchery const ASN1_AUX *aux = it->funcs;
68b077aed3SPierre Pronchery
69b077aed3SPierre Pronchery asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
70b077aed3SPierre Pronchery }
71b077aed3SPierre Pronchery
72b077aed3SPierre Pronchery if (asn1_cb != NULL) {
73b077aed3SPierre Pronchery if (!asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL)
74b077aed3SPierre Pronchery || !asn1_cb(ASN1_OP_GET0_LIBCTX, (ASN1_VALUE **)&x, it, &libctx)
75b077aed3SPierre Pronchery || !asn1_cb(ASN1_OP_GET0_PROPQ, (ASN1_VALUE **)&x, it, &propq))
76b077aed3SPierre Pronchery goto auxerr;
77b077aed3SPierre Pronchery }
78b077aed3SPierre Pronchery
795c87c606SMark Murray i = ASN1_item_i2d(x, &b, it);
806f9291ceSJung-uk Kim if (b == NULL) {
81b077aed3SPierre Pronchery ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE);
82e71b7053SJung-uk Kim return NULL;
836f9291ceSJung-uk Kim }
845c87c606SMark Murray p = b;
85b077aed3SPierre Pronchery ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq);
865c87c606SMark Murray OPENSSL_free(b);
87b077aed3SPierre Pronchery
88b077aed3SPierre Pronchery if (asn1_cb != NULL
89b077aed3SPierre Pronchery && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x))
90b077aed3SPierre Pronchery goto auxerr;
91b077aed3SPierre Pronchery
92e71b7053SJung-uk Kim return ret;
93b077aed3SPierre Pronchery
94b077aed3SPierre Pronchery auxerr:
95b077aed3SPierre Pronchery ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname);
96b077aed3SPierre Pronchery return NULL;
975c87c606SMark Murray }
98