1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 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 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/asn1t.h> 13 14 #ifndef NO_OLD_ASN1 15 16 void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, const void *x) 17 { 18 unsigned char *b, *p; 19 const unsigned char *p2; 20 int i; 21 char *ret; 22 23 if (x == NULL) 24 return NULL; 25 26 i = i2d(x, NULL); 27 if (i <= 0) 28 return NULL; 29 30 b = OPENSSL_malloc(i + 10); 31 if (b == NULL) { 32 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 33 return NULL; 34 } 35 p = b; 36 i = i2d(x, &p); 37 p2 = b; 38 ret = d2i(NULL, &p2, i); 39 OPENSSL_free(b); 40 return ret; 41 } 42 43 #endif 44 45 /* 46 * ASN1_ITEM version of dup: this follows the model above except we don't 47 * need to allocate the buffer. At some point this could be rewritten to 48 * directly dup the underlying structure instead of doing and encode and 49 * decode. 50 */ 51 52 void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) 53 { 54 ASN1_aux_cb *asn1_cb = NULL; 55 unsigned char *b = NULL; 56 const unsigned char *p; 57 long i; 58 ASN1_VALUE *ret; 59 OSSL_LIB_CTX *libctx = NULL; 60 const char *propq = NULL; 61 62 if (x == NULL) 63 return NULL; 64 65 if (it->itype == ASN1_ITYPE_SEQUENCE || it->itype == ASN1_ITYPE_CHOICE 66 || it->itype == ASN1_ITYPE_NDEF_SEQUENCE) { 67 const ASN1_AUX *aux = it->funcs; 68 69 asn1_cb = aux != NULL ? aux->asn1_cb : NULL; 70 } 71 72 if (asn1_cb != NULL) { 73 if (!asn1_cb(ASN1_OP_DUP_PRE, (ASN1_VALUE **)&x, it, NULL) 74 || !asn1_cb(ASN1_OP_GET0_LIBCTX, (ASN1_VALUE **)&x, it, &libctx) 75 || !asn1_cb(ASN1_OP_GET0_PROPQ, (ASN1_VALUE **)&x, it, &propq)) 76 goto auxerr; 77 } 78 79 i = ASN1_item_i2d(x, &b, it); 80 if (b == NULL) { 81 ERR_raise(ERR_LIB_ASN1, ERR_R_MALLOC_FAILURE); 82 return NULL; 83 } 84 p = b; 85 ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq); 86 OPENSSL_free(b); 87 88 if (asn1_cb != NULL 89 && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) 90 goto auxerr; 91 92 return ret; 93 94 auxerr: 95 ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname); 96 return NULL; 97 } 98