xref: /freebsd/crypto/openssl/crypto/asn1/a_dup.c (revision b077aed3)
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