Rich Salz | 2039c42 | 2016-05-17 14:51:34 -0400 | [diff] [blame] | 1 | /* |
Matt Caswell | 38fc02a | 2021-06-17 13:24:59 +0100 | [diff] [blame] | 2 | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 3 | * |
Richard Levitte | 365a2d9 | 2018-12-06 13:17:34 +0100 | [diff] [blame] | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
Rich Salz | 2039c42 | 2016-05-17 14:51:34 -0400 | [diff] [blame] | 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 |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 8 | */ |
| 9 | |
Pauli | f41ac0e | 2020-01-30 07:23:39 +1000 | [diff] [blame] | 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 | |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 16 | #include <stdio.h> |
Richard Levitte | b39fc56 | 2015-05-14 16:56:48 +0200 | [diff] [blame] | 17 | #include "internal/cryptlib.h" |
Bodo Möller | ec57782 | 1999-04-23 22:13:45 +0000 | [diff] [blame] | 18 | #include <openssl/bn.h> |
| 19 | #include <openssl/evp.h> |
| 20 | #include <openssl/objects.h> |
Bodo Möller | f66c303 | 1999-07-24 03:09:01 +0000 | [diff] [blame] | 21 | #include <openssl/asn1.h> |
Rich Salz | 3c27208 | 2016-03-18 14:30:20 -0400 | [diff] [blame] | 22 | #include <openssl/rsa.h> |
| 23 | #include <openssl/dsa.h> |
| 24 | #include <openssl/ec.h> |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 25 | |
Dr. Matthias St. Pierre | 25f2138 | 2019-09-28 00:45:33 +0200 | [diff] [blame] | 26 | #include "crypto/evp.h" |
Dr. Stephen Henson | 3aeb934 | 2016-01-19 00:21:12 +0000 | [diff] [blame] | 27 | |
Richard Levitte | 875a644 | 2004-03-15 23:15:26 +0000 | [diff] [blame] | 28 | EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 29 | long length) |
| 30 | { |
| 31 | EVP_PKEY *ret; |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 32 | EVP_PKEY *copy = NULL; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 33 | |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 34 | if ((a == NULL) || (*a == NULL)) { |
| 35 | if ((ret = EVP_PKEY_new()) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 36 | ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 37 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 38 | } |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 39 | } else { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 40 | ret = *a; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 41 | |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 42 | #ifndef OPENSSL_NO_EC |
| 43 | if (evp_pkey_is_provided(ret) |
| 44 | && EVP_PKEY_get_base_id(ret) == EVP_PKEY_EC) { |
| 45 | if (!evp_pkey_copy_downgraded(©, ret)) |
| 46 | goto err; |
| 47 | } |
| 48 | #endif |
| 49 | } |
| 50 | |
| 51 | if ((type != EVP_PKEY_get_id(ret) || copy != NULL) |
| 52 | && !EVP_PKEY_set_type(ret, type)) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 53 | ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 54 | goto err; |
| 55 | } |
Dr. Stephen Henson | c18e51b | 2009-11-12 19:56:56 +0000 | [diff] [blame] | 56 | |
zhaozg | 8582dcc | 2022-01-01 22:45:12 +0800 | [diff] [blame] | 57 | switch (EVP_PKEY_get_base_id(ret)) { |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 58 | case EVP_PKEY_RSA: |
Dr. Stephen Henson | 3aeb934 | 2016-01-19 00:21:12 +0000 | [diff] [blame] | 59 | if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) == NULL) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 60 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 61 | goto err; |
| 62 | } |
| 63 | break; |
Richard Levitte | cf1b7d9 | 2001-02-19 16:06:34 +0000 | [diff] [blame] | 64 | #ifndef OPENSSL_NO_DSA |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 65 | case EVP_PKEY_DSA: |
Dr. Stephen Henson | 3aeb934 | 2016-01-19 00:21:12 +0000 | [diff] [blame] | 66 | if (!d2i_DSAPublicKey(&ret->pkey.dsa, pp, length)) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 67 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 68 | goto err; |
| 69 | } |
| 70 | break; |
Ralf S. Engelschall | d02b48c | 1998-12-21 10:52:47 +0000 | [diff] [blame] | 71 | #endif |
Bodo Möller | 14a7cfb | 2002-08-07 10:49:54 +0000 | [diff] [blame] | 72 | #ifndef OPENSSL_NO_EC |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 73 | case EVP_PKEY_EC: |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 74 | if (copy != NULL) { |
| 75 | /* use downgraded parameters from copy */ |
| 76 | ret->pkey.ec = copy->pkey.ec; |
| 77 | copy->pkey.ec = NULL; |
| 78 | } |
Dr. Stephen Henson | 3aeb934 | 2016-01-19 00:21:12 +0000 | [diff] [blame] | 79 | if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 80 | ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 81 | goto err; |
| 82 | } |
| 83 | break; |
Bodo Möller | 4d94ae0 | 2002-02-13 18:21:51 +0000 | [diff] [blame] | 84 | #endif |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 85 | default: |
Richard Levitte | 9311d0c | 2020-11-04 12:23:19 +0100 | [diff] [blame] | 86 | ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 87 | goto err; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 88 | } |
| 89 | if (a != NULL) |
| 90 | (*a) = ret; |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 91 | EVP_PKEY_free(copy); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 92 | return ret; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 93 | err: |
Rich Salz | c5ba2d9 | 2015-03-28 10:54:15 -0400 | [diff] [blame] | 94 | if (a == NULL || *a != ret) |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 95 | EVP_PKEY_free(ret); |
Tomas Mraz | 615a9b8 | 2021-11-18 20:09:57 +0100 | [diff] [blame] | 96 | EVP_PKEY_free(copy); |
KaoruToda | 26a7d93 | 2017-10-17 23:04:09 +0900 | [diff] [blame] | 97 | return NULL; |
Matt Caswell | 0f113f3 | 2015-01-22 03:40:55 +0000 | [diff] [blame] | 98 | } |