/src/openssl/crypto/asn1/d2i_pu.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 1995-2022 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 | | /* |
11 | | * DSA low level APIs are deprecated for public use, but still ok for |
12 | | * internal use. |
13 | | */ |
14 | | #include "internal/deprecated.h" |
15 | | |
16 | | #include <stdio.h> |
17 | | #include "internal/cryptlib.h" |
18 | | #include <openssl/bn.h> |
19 | | #include <openssl/evp.h> |
20 | | #include <openssl/objects.h> |
21 | | #include <openssl/asn1.h> |
22 | | #include <openssl/rsa.h> |
23 | | #include <openssl/dsa.h> |
24 | | #include <openssl/ec.h> |
25 | | |
26 | | #include "crypto/evp.h" |
27 | | |
28 | | EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, |
29 | | long length) |
30 | 0 | { |
31 | 0 | EVP_PKEY *ret; |
32 | 0 | EVP_PKEY *copy = NULL; |
33 | |
|
34 | 0 | if ((a == NULL) || (*a == NULL)) { |
35 | 0 | if ((ret = EVP_PKEY_new()) == NULL) { |
36 | 0 | ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); |
37 | 0 | return NULL; |
38 | 0 | } |
39 | 0 | } else { |
40 | 0 | ret = *a; |
41 | |
|
42 | 0 | #ifndef OPENSSL_NO_EC |
43 | 0 | if (evp_pkey_is_provided(ret) |
44 | 0 | && EVP_PKEY_get_base_id(ret) == EVP_PKEY_EC) { |
45 | 0 | if (!evp_pkey_copy_downgraded(©, ret)) |
46 | 0 | goto err; |
47 | 0 | } |
48 | 0 | #endif |
49 | 0 | } |
50 | | |
51 | 0 | if ((type != EVP_PKEY_get_id(ret) || copy != NULL) |
52 | 0 | && !EVP_PKEY_set_type(ret, type)) { |
53 | 0 | ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); |
54 | 0 | goto err; |
55 | 0 | } |
56 | | |
57 | 0 | switch (EVP_PKEY_get_base_id(ret)) { |
58 | 0 | case EVP_PKEY_RSA: |
59 | 0 | if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) { |
60 | 0 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
61 | 0 | goto err; |
62 | 0 | } |
63 | 0 | break; |
64 | 0 | #ifndef OPENSSL_NO_DSA |
65 | 0 | case EVP_PKEY_DSA: |
66 | 0 | if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { |
67 | 0 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
68 | 0 | goto err; |
69 | 0 | } |
70 | 0 | break; |
71 | 0 | #endif |
72 | 0 | #ifndef OPENSSL_NO_EC |
73 | 0 | case EVP_PKEY_EC: |
74 | 0 | if (copy != NULL) { |
75 | | /* use downgraded parameters from copy */ |
76 | 0 | ret->pkey.ec = copy->pkey.ec; |
77 | 0 | copy->pkey.ec = NULL; |
78 | 0 | } |
79 | 0 | if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { |
80 | 0 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
81 | 0 | goto err; |
82 | 0 | } |
83 | 0 | break; |
84 | 0 | #endif |
85 | 0 | default: |
86 | 0 | ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); |
87 | 0 | goto err; |
88 | 0 | } |
89 | 0 | if (a != NULL) |
90 | 0 | (*a) = ret; |
91 | 0 | EVP_PKEY_free(copy); |
92 | 0 | return ret; |
93 | 0 | err: |
94 | 0 | if (a == NULL || *a != ret) |
95 | 0 | EVP_PKEY_free(ret); |
96 | 0 | EVP_PKEY_free(copy); |
97 | 0 | return NULL; |
98 | 0 | } |