/src/bind9/lib/dns/openssl_link.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) Internet Systems Consortium, Inc. ("ISC") |
3 | | * |
4 | | * SPDX-License-Identifier: MPL-2.0 AND ISC |
5 | | * |
6 | | * This Source Code Form is subject to the terms of the Mozilla Public |
7 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 | | * file, you can obtain one at https://mozilla.org/MPL/2.0/. |
9 | | * |
10 | | * See the COPYRIGHT file distributed with this work for additional |
11 | | * information regarding copyright ownership. |
12 | | */ |
13 | | |
14 | | /* |
15 | | * Copyright (C) Network Associates, Inc. |
16 | | * |
17 | | * Permission to use, copy, modify, and/or distribute this software for any |
18 | | * purpose with or without fee is hereby granted, provided that the above |
19 | | * copyright notice and this permission notice appear in all copies. |
20 | | * |
21 | | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
22 | | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
23 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
24 | | * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
25 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
26 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
27 | | * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
28 | | */ |
29 | | |
30 | | #include <isc/log.h> |
31 | | #include <isc/mem.h> |
32 | | #include <isc/mutex.h> |
33 | | #include <isc/result.h> |
34 | | #include <isc/string.h> |
35 | | #include <isc/thread.h> |
36 | | #include <isc/tls.h> |
37 | | #include <isc/util.h> |
38 | | |
39 | | #include "dst_internal.h" |
40 | | #include "dst_openssl.h" |
41 | | |
42 | | #if OPENSSL_VERSION_NUMBER >= 0x30000000L |
43 | | #include <openssl/core_names.h> |
44 | | #include <openssl/store.h> |
45 | | #endif |
46 | | |
47 | | #include "openssl_shim.h" |
48 | | |
49 | | static isc_result_t |
50 | | dst__openssl_fromlabel_provider(int key_base_id, const char *label, |
51 | | const char *pin, EVP_PKEY **ppub, |
52 | 0 | EVP_PKEY **ppriv) { |
53 | 0 | #if OPENSSL_VERSION_NUMBER >= 0x30000000L |
54 | 0 | isc_result_t result = DST_R_OPENSSLFAILURE; |
55 | 0 | OSSL_STORE_CTX *ctx = NULL; |
56 | |
|
57 | 0 | UNUSED(pin); |
58 | |
|
59 | 0 | ctx = OSSL_STORE_open(label, NULL, NULL, NULL, NULL); |
60 | 0 | if (!ctx) { |
61 | 0 | CLEANUP(dst__openssl_toresult(DST_R_OPENSSLFAILURE)); |
62 | 0 | } |
63 | | |
64 | 0 | while (!OSSL_STORE_eof(ctx)) { |
65 | 0 | OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); |
66 | 0 | if (info == NULL) { |
67 | 0 | continue; |
68 | 0 | } |
69 | 0 | switch (OSSL_STORE_INFO_get_type(info)) { |
70 | 0 | case OSSL_STORE_INFO_PKEY: |
71 | 0 | if (*ppriv != NULL) { |
72 | 0 | OSSL_STORE_INFO_free(info); |
73 | 0 | CLEANUP(DST_R_INVALIDPRIVATEKEY); |
74 | 0 | } |
75 | 0 | *ppriv = OSSL_STORE_INFO_get1_PKEY(info); |
76 | 0 | if (EVP_PKEY_get_base_id(*ppriv) != key_base_id) { |
77 | 0 | OSSL_STORE_INFO_free(info); |
78 | 0 | CLEANUP(DST_R_BADKEYTYPE); |
79 | 0 | } |
80 | 0 | break; |
81 | 0 | case OSSL_STORE_INFO_PUBKEY: |
82 | 0 | if (*ppub != NULL) { |
83 | 0 | OSSL_STORE_INFO_free(info); |
84 | 0 | CLEANUP(DST_R_INVALIDPUBLICKEY); |
85 | 0 | } |
86 | 0 | *ppub = OSSL_STORE_INFO_get1_PUBKEY(info); |
87 | 0 | if (EVP_PKEY_get_base_id(*ppub) != key_base_id) { |
88 | 0 | OSSL_STORE_INFO_free(info); |
89 | 0 | CLEANUP(DST_R_BADKEYTYPE); |
90 | 0 | } |
91 | 0 | break; |
92 | 0 | } |
93 | 0 | OSSL_STORE_INFO_free(info); |
94 | 0 | } |
95 | 0 | if (*ppriv != NULL && *ppub != NULL) { |
96 | 0 | result = ISC_R_SUCCESS; |
97 | 0 | } |
98 | 0 | cleanup: |
99 | 0 | OSSL_STORE_close(ctx); |
100 | 0 | return result; |
101 | | #else |
102 | | UNUSED(key_base_id); |
103 | | UNUSED(label); |
104 | | UNUSED(pin); |
105 | | UNUSED(ppub); |
106 | | UNUSED(ppriv); |
107 | | return DST_R_OPENSSLFAILURE; |
108 | | #endif |
109 | 0 | } |
110 | | |
111 | | isc_result_t |
112 | | dst__openssl_fromlabel(int key_base_id, const char *label, const char *pin, |
113 | 0 | EVP_PKEY **ppub, EVP_PKEY **ppriv) { |
114 | 0 | return dst__openssl_fromlabel_provider(key_base_id, label, pin, ppub, |
115 | 0 | ppriv); |
116 | 0 | } |
117 | | |
118 | | bool |
119 | 0 | dst__openssl_keypair_compare(const dst_key_t *key1, const dst_key_t *key2) { |
120 | 0 | EVP_PKEY *pkey1 = key1->keydata.pkeypair.pub; |
121 | 0 | EVP_PKEY *pkey2 = key2->keydata.pkeypair.pub; |
122 | |
|
123 | 0 | if (pkey1 == pkey2) { |
124 | 0 | return true; |
125 | 0 | } else if (pkey1 == NULL || pkey2 == NULL) { |
126 | 0 | return false; |
127 | 0 | } |
128 | | |
129 | | /* `EVP_PKEY_eq` checks only the public components and parameters. */ |
130 | 0 | if (EVP_PKEY_eq(pkey1, pkey2) != 1) { |
131 | 0 | return false; |
132 | 0 | } |
133 | | /* The private key presence must be same for keys to match. */ |
134 | 0 | if ((key1->keydata.pkeypair.priv != NULL) != |
135 | 0 | (key2->keydata.pkeypair.priv != NULL)) |
136 | 0 | { |
137 | 0 | return false; |
138 | 0 | } |
139 | 0 | return true; |
140 | 0 | } |
141 | | |
142 | | bool |
143 | 0 | dst__openssl_keypair_isprivate(const dst_key_t *key) { |
144 | 0 | return key->keydata.pkeypair.priv != NULL; |
145 | 0 | } |
146 | | |
147 | | void |
148 | 82 | dst__openssl_keypair_destroy(dst_key_t *key) { |
149 | 82 | if (key->keydata.pkeypair.priv != key->keydata.pkeypair.pub) { |
150 | 82 | EVP_PKEY_free(key->keydata.pkeypair.priv); |
151 | 82 | } |
152 | 82 | EVP_PKEY_free(key->keydata.pkeypair.pub); |
153 | 82 | key->keydata.pkeypair.pub = NULL; |
154 | | key->keydata.pkeypair.priv = NULL; |
155 | 82 | } |
156 | | |
157 | | /*! \file */ |