778114d765e092dd891d49fc5b1ff77e1df40916
[openssl.git] / crypto / asn1 / d2i_pu.c
1 /*
2  * Copyright 1995-2016 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 <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/bn.h>
13 #include <openssl/evp.h>
14 #include <openssl/objects.h>
15 #include <openssl/asn1.h>
16 #include <openssl/rsa.h>
17 #include <openssl/dsa.h>
18 #include <openssl/ec.h>
19
20 #include "internal/evp_int.h"
21
22 EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
23                         long length)
24 {
25     EVP_PKEY *ret;
26
27     if ((a == NULL) || (*a == NULL)) {
28         if ((ret = EVP_PKEY_new()) == NULL) {
29             ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
30             return NULL;
31         }
32     } else
33         ret = *a;
34
35     if (type != EVP_PKEY_id(ret) && !EVP_PKEY_set_type(ret, type)) {
36         ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
37         goto err;
38     }
39
40     switch (EVP_PKEY_id(ret)) {
41 #ifndef OPENSSL_NO_RSA
42     case EVP_PKEY_RSA:
43         if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) {
44             ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
45             goto err;
46         }
47         break;
48 #endif
49 #ifndef OPENSSL_NO_DSA
50     case EVP_PKEY_DSA:
51         /* TMP UGLY CAST */
52         if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) {
53             ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
54             goto err;
55         }
56         break;
57 #endif
58 #ifndef OPENSSL_NO_EC
59     case EVP_PKEY_EC:
60         if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) {
61             ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
62             goto err;
63         }
64         break;
65 #endif
66     default:
67         ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
68         goto err;
69     }
70     if (a != NULL)
71         (*a) = ret;
72     return ret;
73  err:
74     if (a == NULL || *a != ret)
75         EVP_PKEY_free(ret);
76     return NULL;
77 }