Bug Summary

File:out/../deps/openssl/openssl/crypto/evp/keymgmt_lib.c
Warning:line 117, column 13
Access to field 'name_id' results in a dereference of a null pointer (loaded from field 'keymgmt')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name keymgmt_lib.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D OPENSSL_NO_HW -D OPENSSL_API_COMPAT=0x10100001L -D STATIC_LEGACY -D NDEBUG -D OPENSSL_USE_NODELETE -D L_ENDIAN -D OPENSSL_BUILDING_OPENSSL -D AES_ASM -D BSAES_ASM -D CMLL_ASM -D ECP_NISTZ256_ASM -D GHASH_ASM -D KECCAK1600_ASM -D MD5_ASM -D OPENSSL_BN_ASM_GF2m -D OPENSSL_BN_ASM_MONT -D OPENSSL_BN_ASM_MONT5 -D OPENSSL_CPUID_OBJ -D OPENSSL_IA32_SSE2 -D PADLOCK_ASM -D POLY1305_ASM -D SHA1_ASM -D SHA256_ASM -D SHA512_ASM -D VPAES_ASM -D WHIRLPOOL_ASM -D X25519_ASM -D OPENSSL_PIC -D MODULESDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl/lib/openssl-modules" -D OPENSSLDIR="/home/maurizio/node-v18.6.0/out/Release/obj.target/deps/openssl" -D OPENSSLDIR="/etc/ssl" -D ENGINESDIR="/dev/null" -D TERMIOS -I ../deps/openssl/openssl -I ../deps/openssl/openssl/include -I ../deps/openssl/openssl/crypto -I ../deps/openssl/openssl/crypto/include -I ../deps/openssl/openssl/crypto/modes -I ../deps/openssl/openssl/crypto/ec/curve448 -I ../deps/openssl/openssl/crypto/ec/curve448/arch_32 -I ../deps/openssl/openssl/providers/common/include -I ../deps/openssl/openssl/providers/implementations/include -I ../deps/openssl/config -I ../deps/openssl/config/archs/linux-x86_64/asm -I ../deps/openssl/config/archs/linux-x86_64/asm/include -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto -I ../deps/openssl/config/archs/linux-x86_64/asm/crypto/include/internal -I ../deps/openssl/config/archs/linux-x86_64/asm/providers/common/include -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-missing-field-initializers -Wno-old-style-declaration -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c ../deps/openssl/openssl/crypto/evp/keymgmt_lib.c
1/*
2 * Copyright 2019-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#include <openssl/core_names.h>
11#include "internal/cryptlib.h"
12#include "internal/nelem.h"
13#include "crypto/evp.h"
14#include "internal/core.h"
15#include "internal/provider.h"
16#include "evp_local.h"
17
18/*
19 * match_type() checks if two EVP_KEYMGMT are matching key types. This
20 * function assumes that the caller has made all the necessary NULL checks.
21 */
22static int match_type(const EVP_KEYMGMT *keymgmt1, const EVP_KEYMGMT *keymgmt2)
23{
24 const char *name2 = EVP_KEYMGMT_get0_name(keymgmt2);
25
26 return EVP_KEYMGMT_is_a(keymgmt1, name2);
27}
28
29int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg)
30{
31 struct evp_keymgmt_util_try_import_data_st *data = arg;
32 int delete_on_error = 0;
33
34 /* Just in time creation of keydata */
35 if (data->keydata == NULL((void*)0)) {
36 if ((data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL((void*)0)) {
37 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
,37,__func__), ERR_set_error)((6),((256|((0x1 << 18L)|(
0x2 << 18L)))),((void*)0))
;
38 return 0;
39 }
40 delete_on_error = 1;
41 }
42
43 /*
44 * It's fine if there was no data to transfer, we just end up with an
45 * empty destination key.
46 */
47 if (params[0].key == NULL((void*)0))
48 return 1;
49
50 if (evp_keymgmt_import(data->keymgmt, data->keydata, data->selection,
51 params))
52 return 1;
53 if (delete_on_error) {
54 evp_keymgmt_freedata(data->keymgmt, data->keydata);
55 data->keydata = NULL((void*)0);
56 }
57 return 0;
58}
59
60int evp_keymgmt_util_assign_pkey(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt,
61 void *keydata)
62{
63 if (pkey == NULL((void*)0) || keymgmt == NULL((void*)0) || keydata == NULL((void*)0)
64 || !EVP_PKEY_set_type_by_keymgmt(pkey, keymgmt)) {
65 ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
,65,__func__), ERR_set_error)((6),((259|((0x1 << 18L)|(
0x2 << 18L)))),((void*)0))
;
66 return 0;
67 }
68 pkey->keydata = keydata;
69 evp_keymgmt_util_cache_keyinfo(pkey);
70 return 1;
71}
72
73EVP_PKEY *evp_keymgmt_util_make_pkey(EVP_KEYMGMT *keymgmt, void *keydata)
74{
75 EVP_PKEY *pkey = NULL((void*)0);
76
77 if (keymgmt == NULL((void*)0)
78 || keydata == NULL((void*)0)
79 || (pkey = EVP_PKEY_new()) == NULL((void*)0)
80 || !evp_keymgmt_util_assign_pkey(pkey, keymgmt, keydata)) {
81 EVP_PKEY_free(pkey);
82 return NULL((void*)0);
83 }
84 return pkey;
85}
86
87int evp_keymgmt_util_export(const EVP_PKEY *pk, int selection,
88 OSSL_CALLBACK *export_cb, void *export_cbarg)
89{
90 if (pk == NULL((void*)0) || export_cb == NULL((void*)0))
91 return 0;
92 return evp_keymgmt_export(pk->keymgmt, pk->keydata, selection,
93 export_cb, export_cbarg);
94}
95
96void *evp_keymgmt_util_export_to_provider(EVP_PKEY *pk, EVP_KEYMGMT *keymgmt)
97{
98 struct evp_keymgmt_util_try_import_data_st import_data;
99 OP_CACHE_ELEM *op;
100
101 /* Export to where? */
102 if (keymgmt
11.1
'keymgmt' is not equal to NULL
== NULL((void*)0))
12
Taking false branch
103 return NULL((void*)0);
104
105 /* If we have an unassigned key, give up */
106 if (pk->keydata
12.1
Field 'keydata' is not equal to NULL
== NULL((void*)0))
107 return NULL((void*)0);
108
109 /*
110 * If |keymgmt| matches the "origin" |keymgmt|, there is no more to do.
111 * The "origin" is determined by the |keymgmt| pointers being identical
112 * or when the provider and the name ID match. The latter case handles the
113 * situation where the fetch cache is flushed and a "new" key manager is
114 * created.
115 */
116 if (pk->keymgmt == keymgmt
12.2
'keymgmt' is not equal to field 'keymgmt'
117 || (pk->keymgmt->name_id == keymgmt->name_id
13
Access to field 'name_id' results in a dereference of a null pointer (loaded from field 'keymgmt')
118 && pk->keymgmt->prov == keymgmt->prov)) 119 return pk->keydata; 120 121 if (!CRYPTO_THREAD_read_lock(pk->lock)) 122 return NULL((void*)0); 123 /* 124 * If the provider native "origin" hasn't changed since last time, we 125 * try to find our keymgmt in the operation cache. If it has changed 126 * and our keymgmt isn't found, we will clear the cache further down. 127 */ 128 if (pk->dirty_cnt == pk->dirty_cnt_copy) { 129 /* If this key is already exported to |keymgmt|, no more to do */ 130 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt); 131 if (op != NULL((void*)0) && op->keymgmt != NULL((void*)0)) { 132 void *ret = op->keydata; 133 134 CRYPTO_THREAD_unlock(pk->lock); 135 return ret; 136 } 137 } 138 CRYPTO_THREAD_unlock(pk->lock); 139 140 /* If the "origin" |keymgmt| doesn't support exporting, give up */ 141 if (pk->keymgmt->export == NULL((void*)0)) 142 return NULL((void*)0); 143 144 /* 145 * Make sure that the type of the keymgmt to export to matches the type 146 * of the "origin" 147 */ 148 if (!ossl_assert(match_type(pk->keymgmt, keymgmt))((match_type(pk->keymgmt, keymgmt)) != 0)) 149 return NULL((void*)0); 150 151 /* 152 * We look at the already cached provider keys, and import from the 153 * first that supports it (i.e. use its export function), and export 154 * the imported data to the new provider. 155 */ 156 157 /* Setup for the export callback */ 158 import_data.keydata = NULL((void*)0); /* evp_keymgmt_util_try_import will create it */ 159 import_data.keymgmt = keymgmt; 160 import_data.selection = OSSL_KEYMGMT_SELECT_ALL( ( 0x01 | 0x02 ) | ( 0x04 | 0x80) ); 161 162 /* 163 * The export function calls the callback (evp_keymgmt_util_try_import), 164 * which does the import for us. If successful, we're done. 165 */ 166 if (!evp_keymgmt_util_export(pk, OSSL_KEYMGMT_SELECT_ALL( ( 0x01 | 0x02 ) | ( 0x04 | 0x80) ), 167 &evp_keymgmt_util_try_import, &import_data)) 168 /* If there was an error, bail out */ 169 return NULL((void*)0); 170 171 if (!CRYPTO_THREAD_write_lock(pk->lock)) { 172 evp_keymgmt_freedata(keymgmt, import_data.keydata); 173 return NULL((void*)0); 174 } 175 /* Check to make sure some other thread didn't get there first */ 176 op = evp_keymgmt_util_find_operation_cache(pk, keymgmt); 177 if (op != NULL((void*)0) && op->keydata != NULL((void*)0)) { 178 void *ret = op->keydata; 179 180 CRYPTO_THREAD_unlock(pk->lock); 181 182 /* 183 * Another thread seemms to have already exported this so we abandon 184 * all the work we just did. 185 */ 186 evp_keymgmt_freedata(keymgmt, import_data.keydata); 187 188 return ret; 189 } 190 191 /* 192 * If the dirty counter changed since last time, then clear the 193 * operation cache. In that case, we know that |i| is zero. 194 */ 195 if (pk->dirty_cnt != pk->dirty_cnt_copy) 196 evp_keymgmt_util_clear_operation_cache(pk, 0); 197 198 /* Add the new export to the operation cache */ 199 if (!evp_keymgmt_util_cache_keydata(pk, keymgmt, import_data.keydata)) { 200 CRYPTO_THREAD_unlock(pk->lock); 201 evp_keymgmt_freedata(keymgmt, import_data.keydata); 202 return NULL((void*)0); 203 } 204 205 /* Synchronize the dirty count */ 206 pk->dirty_cnt_copy = pk->dirty_cnt; 207 208 CRYPTO_THREAD_unlock(pk->lock); 209 210 return import_data.keydata; 211} 212 213static void op_cache_free(OP_CACHE_ELEM *e) 214{ 215 evp_keymgmt_freedata(e->keymgmt, e->keydata); 216 EVP_KEYMGMT_free(e->keymgmt); 217 OPENSSL_free(e)CRYPTO_free(e, "../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
, 217)
; 218} 219 220int evp_keymgmt_util_clear_operation_cache(EVP_PKEY *pk, int locking) 221{ 222 if (pk != NULL((void*)0)) { 223 if (locking && pk->lock != NULL((void*)0) && !CRYPTO_THREAD_write_lock(pk->lock)) 224 return 0; 225 sk_OP_CACHE_ELEM_pop_free(pk->operation_cache, op_cache_free); 226 pk->operation_cache = NULL((void*)0); 227 if (locking && pk->lock != NULL((void*)0)) 228 CRYPTO_THREAD_unlock(pk->lock); 229 } 230 231 return 1; 232} 233 234OP_CACHE_ELEM *evp_keymgmt_util_find_operation_cache(EVP_PKEY *pk, 235 EVP_KEYMGMT *keymgmt) 236{ 237 int i, end = sk_OP_CACHE_ELEM_num(pk->operation_cache); 238 OP_CACHE_ELEM *p; 239 240 /* 241 * A comparison and sk_P_CACHE_ELEM_find() are avoided to not cause 242 * problems when we've only a read lock. 243 */ 244 for (i = 0; i < end; i++) { 245 p = sk_OP_CACHE_ELEM_value(pk->operation_cache, i); 246 if (keymgmt == p->keymgmt) 247 return p; 248 } 249 return NULL((void*)0); 250} 251 252int evp_keymgmt_util_cache_keydata(EVP_PKEY *pk, 253 EVP_KEYMGMT *keymgmt, void *keydata) 254{ 255 OP_CACHE_ELEM *p = NULL((void*)0); 256 257 if (keydata != NULL((void*)0)) { 258 if (pk->operation_cache == NULL((void*)0)) { 259 pk->operation_cache = sk_OP_CACHE_ELEM_new_null(); 260 if (pk->operation_cache == NULL((void*)0)) 261 return 0; 262 } 263 264 p = OPENSSL_malloc(sizeof(*p))CRYPTO_malloc(sizeof(*p), "../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
, 264)
; 265 if (p == NULL((void*)0)) 266 return 0; 267 p->keydata = keydata; 268 p->keymgmt = keymgmt; 269 270 if (!EVP_KEYMGMT_up_ref(keymgmt)) { 271 OPENSSL_free(p)CRYPTO_free(p, "../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
, 271)
; 272 return 0; 273 } 274 275 if (!sk_OP_CACHE_ELEM_push(pk->operation_cache, p)) { 276 EVP_KEYMGMT_free(keymgmt); 277 OPENSSL_free(p)CRYPTO_free(p, "../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
, 277)
; 278 return 0; 279 } 280 } 281 return 1; 282} 283 284void evp_keymgmt_util_cache_keyinfo(EVP_PKEY *pk) 285{ 286 /* 287 * Cache information about the provider "origin" key. 288 * 289 * This services functions like EVP_PKEY_get_size, EVP_PKEY_get_bits, etc 290 */ 291 if (pk->keydata != NULL((void*)0)) { 292 int bits = 0; 293 int security_bits = 0; 294 int size = 0; 295 OSSL_PARAM params[4]; 296 297 params[0] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_BITS"bits", &bits); 298 params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_SECURITY_BITS"security-bits", 299 &security_bits); 300 params[2] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_MAX_SIZE"max-size", &size); 301 params[3] = OSSL_PARAM_construct_end(); 302 if (evp_keymgmt_get_params(pk->keymgmt, pk->keydata, params)) { 303 pk->cache.size = size; 304 pk->cache.bits = bits; 305 pk->cache.security_bits = security_bits; 306 } 307 } 308} 309 310void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 311 int selection, const OSSL_PARAM params[]) 312{ 313 void *keydata = NULL((void*)0); 314 315 if ((keydata = evp_keymgmt_newdata(keymgmt)) == NULL((void*)0) 316 || !evp_keymgmt_import(keymgmt, keydata, selection, params) 317 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 318 evp_keymgmt_freedata(keymgmt, keydata); 319 keydata = NULL((void*)0); 320 } 321 return keydata; 322} 323 324int evp_keymgmt_util_has(EVP_PKEY *pk, int selection) 325{ 326 /* Check if key is even assigned */ 327 if (pk->keymgmt == NULL((void*)0)) 328 return 0; 329 330 return evp_keymgmt_has(pk->keymgmt, pk->keydata, selection); 331} 332 333/* 334 * evp_keymgmt_util_match() doesn't just look at the provider side "origin", 335 * but also in the operation cache to see if there's any common keymgmt that 336 * supplies OP_keymgmt_match. 337 * 338 * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq() 339 * and EVP_PKEY_parameters_eq() return, i.e.: 340 * 341 * 1 same key 342 * 0 not same key 343 * -1 not same key type 344 * -2 unsupported operation 345 */ 346int evp_keymgmt_util_match(EVP_PKEY *pk1, EVP_PKEY *pk2, int selection) 347{ 348 EVP_KEYMGMT *keymgmt1 = NULL((void*)0), *keymgmt2 = NULL((void*)0); 349 void *keydata1 = NULL((void*)0), *keydata2 = NULL((void*)0); 350 351 if (pk1 == NULL((void*)0) || pk2 == NULL((void*)0)) {
1
Assuming 'pk1' is not equal to NULL
2
Assuming 'pk2' is not equal to NULL
3
Taking false branch
352 if (pk1 == NULL((void*)0) && pk2 == NULL((void*)0)) 353 return 1; 354 return 0; 355 } 356 357 keymgmt1 = pk1->keymgmt; 358 keydata1 = pk1->keydata; 359 keymgmt2 = pk2->keymgmt; 360 keydata2 = pk2->keydata; 361 362 if (keymgmt1 != keymgmt2) {
4
Assuming 'keymgmt1' is not equal to 'keymgmt2'
5
Taking true branch
363 /* 364 * The condition for a successful cross export is that the 365 * keydata to be exported is NULL (typed, but otherwise empty 366 * EVP_PKEY), or that it was possible to export it with 367 * evp_keymgmt_util_export_to_provider(). 368 * 369 * We use |ok| to determine if it's ok to cross export one way, 370 * but also to determine if we should attempt a cross export 371 * the other way. There's no point doing it both ways. 372 */ 373 int ok = 0; 374 375 /* Complex case, where the keymgmt differ */ 376 if (keymgmt1 != NULL((void*)0)
6
Assuming 'keymgmt1' is equal to NULL
377 && keymgmt2 != NULL((void*)0) 378 && !match_type(keymgmt1, keymgmt2)) { 379 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
,379,__func__), ERR_set_error)((6),(101),((void*)0))
; 380 return -1; /* Not the same type */ 381 } 382 383 /* 384 * The key types are determined to match, so we try cross export, 385 * but only to keymgmt's that supply a matching function. 386 */ 387 if (keymgmt2
6.1
'keymgmt2' is not equal to NULL
!= NULL((void*)0)
8
Taking true branch
388 && keymgmt2->match != NULL((void*)0)) {
7
Assuming field 'match' is not equal to NULL
389 void *tmp_keydata = NULL((void*)0); 390 391 ok = 1; 392 if (keydata1 != NULL((void*)0)) {
9
Assuming 'keydata1' is not equal to NULL
10
Taking true branch
393 tmp_keydata = 394 evp_keymgmt_util_export_to_provider(pk1, keymgmt2);
11
Calling 'evp_keymgmt_util_export_to_provider'
395 ok = (tmp_keydata != NULL((void*)0)); 396 } 397 if (ok) { 398 keymgmt1 = keymgmt2; 399 keydata1 = tmp_keydata; 400 } 401 } 402 /* 403 * If we've successfully cross exported one way, there's no point 404 * doing it the other way, hence the |!ok| check. 405 */ 406 if (!ok 407 && keymgmt1 != NULL((void*)0) 408 && keymgmt1->match != NULL((void*)0)) { 409 void *tmp_keydata = NULL((void*)0); 410 411 ok = 1; 412 if (keydata2 != NULL((void*)0)) { 413 tmp_keydata = 414 evp_keymgmt_util_export_to_provider(pk2, keymgmt1); 415 ok = (tmp_keydata != NULL((void*)0)); 416 } 417 if (ok) { 418 keymgmt2 = keymgmt1; 419 keydata2 = tmp_keydata; 420 } 421 } 422 } 423 424 /* If we still don't have matching keymgmt implementations, we give up */ 425 if (keymgmt1 != keymgmt2) 426 return -2; 427 428 /* If both keydata are NULL, then they're the same key */ 429 if (keydata1 == NULL((void*)0) && keydata2 == NULL((void*)0)) 430 return 1; 431 /* If only one of the keydata is NULL, then they're different keys */ 432 if (keydata1 == NULL((void*)0) || keydata2 == NULL((void*)0)) 433 return 0; 434 /* If both keydata are non-NULL, we let the backend decide */ 435 return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); 436} 437 438int evp_keymgmt_util_copy(EVP_PKEY *to, EVP_PKEY *from, int selection) 439{ 440 /* Save copies of pointers we want to play with without affecting |to| */ 441 EVP_KEYMGMT *to_keymgmt = to->keymgmt; 442 void *to_keydata = to->keydata, *alloc_keydata = NULL((void*)0); 443 444 /* An unassigned key can't be copied */ 445 if (from == NULL((void*)0) || from->keydata == NULL((void*)0)) 446 return 0; 447 448 /* 449 * If |to| is unassigned, ensure it gets the same KEYMGMT as |from|, 450 * Note that the final setting of KEYMGMT is done further down, with 451 * EVP_PKEY_set_type_by_keymgmt(); we don't want to do that prematurely. 452 */ 453 if (to_keymgmt == NULL((void*)0)) 454 to_keymgmt = from->keymgmt; 455 456 if (to_keymgmt == from->keymgmt && to_keymgmt->dup != NULL((void*)0) 457 && to_keydata == NULL((void*)0)) { 458 to_keydata = alloc_keydata = evp_keymgmt_dup(to_keymgmt, 459 from->keydata, 460 selection); 461 if (to_keydata == NULL((void*)0)) 462 return 0; 463 } else if (match_type(to_keymgmt, from->keymgmt)) { 464 struct evp_keymgmt_util_try_import_data_st import_data; 465 466 import_data.keymgmt = to_keymgmt; 467 import_data.keydata = to_keydata; 468 import_data.selection = selection; 469 470 if (!evp_keymgmt_util_export(from, selection, 471 &evp_keymgmt_util_try_import, 472 &import_data)) 473 return 0; 474 475 /* 476 * In case to_keydata was previously unallocated, 477 * evp_keymgmt_util_try_import() may have created it for us. 478 */ 479 if (to_keydata == NULL((void*)0)) 480 to_keydata = alloc_keydata = import_data.keydata; 481 } else { 482 ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/evp/keymgmt_lib.c"
,482,__func__), ERR_set_error)((6),(101),((void*)0))
; 483 return 0; 484 } 485 486 /* 487 * We only need to set the |to| type when its |keymgmt| isn't set. 488 * We can then just set its |keydata| to what we have, which might 489 * be exactly what it had when entering this function. 490 * This is a bit different from using evp_keymgmt_util_assign_pkey(), 491 * which isn't as careful with |to|'s original |keymgmt|, since it's 492 * meant to forcibly reassign an EVP_PKEY no matter what, which is 493 * why we don't use that one here. 494 */ 495 if (to->keymgmt == NULL((void*)0) 496 && !EVP_PKEY_set_type_by_keymgmt(to, to_keymgmt)) { 497 evp_keymgmt_freedata(to_keymgmt, alloc_keydata); 498 return 0; 499 } 500 to->keydata = to_keydata; 501 evp_keymgmt_util_cache_keyinfo(to); 502 503 return 1; 504} 505 506void *evp_keymgmt_util_gen(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, 507 void *genctx, OSSL_CALLBACK *cb, void *cbarg) 508{ 509 void *keydata = NULL((void*)0); 510 511 if ((keydata = evp_keymgmt_gen(keymgmt, genctx, cb, cbarg)) == NULL((void*)0) 512 || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { 513 evp_keymgmt_freedata(keymgmt, keydata); 514 keydata = NULL((void*)0); 515 } 516 517 return keydata; 518} 519 520/* 521 * Returns the same numbers as EVP_PKEY_get_default_digest_name() 522 * When the string from the EVP_KEYMGMT implementation is "", we use 523 * SN_undef, since that corresponds to what EVP_PKEY_get_default_nid() 524 * returns for no digest. 525 */ 526int evp_keymgmt_util_get_deflt_digest_name(EVP_KEYMGMT *keymgmt, 527 void *keydata, 528 char *mdname, size_t mdname_sz) 529{ 530 OSSL_PARAM params[3]; 531 char mddefault[100] = ""; 532 char mdmandatory[100] = ""; 533 char *result = NULL((void*)0); 534 int rv = -2; 535 536 params[0] = 537 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST"default-digest", 538 mddefault, sizeof(mddefault)); 539 params[1] = 540 OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST"mandatory-digest", 541 mdmandatory, 542 sizeof(mdmandatory)); 543 params[2] = OSSL_PARAM_construct_end(); 544 545 if (!evp_keymgmt_get_params(keymgmt, keydata, params)) 546 return 0; 547 548 if (OSSL_PARAM_modified(params + 1)) { 549 if (params[1].return_size <= 1) /* Only a NUL byte */ 550 result = SN_undef"UNDEF"; 551 else 552 result = mdmandatory; 553 rv = 2; 554 } else if (OSSL_PARAM_modified(params)) { 555 if (params[0].return_size <= 1) /* Only a NUL byte */ 556 result = SN_undef"UNDEF"; 557 else 558 result = mddefault; 559 rv = 1; 560 } 561 if (rv > 0) 562 OPENSSL_strlcpy(mdname, result, mdname_sz); 563 return rv; 564} 565 566/* 567 * If |keymgmt| has the method function |query_operation_name|, use it to get 568 * the name of a supported operation identity. Otherwise, return the keytype, 569 * assuming that it works as a default operation name. 570 */ 571const char *evp_keymgmt_util_query_operation_name(EVP_KEYMGMT *keymgmt, 572 int op_id) 573{ 574 const char *name = NULL((void*)0); 575 576 if (keymgmt != NULL((void*)0)) { 577 if (keymgmt->query_operation_name != NULL((void*)0)) 578 name = keymgmt->query_operation_name(op_id); 579 if (name == NULL((void*)0)) 580 name = EVP_KEYMGMT_get0_name(keymgmt); 581 } 582 return name; 583}