diff options
author | tb <> | 2023-12-29 18:46:24 +0000 |
---|---|---|
committer | tb <> | 2023-12-29 18:46:24 +0000 |
commit | 5f197d54aa3750390380be33ac4bd1fe910b7fcd (patch) | |
tree | 8a548b19bfcf1d635ebf2e7cbd2dac3ea68a2c37 /src/lib | |
parent | ee1a6831815b66f5ddf67219918fb3b797c7361e (diff) | |
download | openbsd-5f197d54aa3750390380be33ac4bd1fe910b7fcd.tar.gz openbsd-5f197d54aa3750390380be33ac4bd1fe910b7fcd.tar.bz2 openbsd-5f197d54aa3750390380be33ac4bd1fe910b7fcd.zip |
Rework eckey_priv_decode()
Factor out the pubkey computation and bring it into more sensible form.
This removes lots of pointless setting of errors (twice) and makes the
code a bit easier on the eyes. Other than that perform some stylistic
cleanup like single exit and add an error check for EVP_PKEY_assign().
ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/ec/ec_ameth.c | 102 |
1 files changed, 53 insertions, 49 deletions
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c index 245001edfa..2b3b3db63d 100644 --- a/src/lib/libcrypto/ec/ec_ameth.c +++ b/src/lib/libcrypto/ec/ec_ameth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_ameth.c,v 1.46 2023/12/29 18:45:39 tb Exp $ */ | 1 | /* $OpenBSD: ec_ameth.c,v 1.47 2023/12/29 18:46:24 tb Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2006. | 3 | * project 2006. |
4 | */ | 4 | */ |
@@ -302,68 +302,72 @@ eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) | |||
302 | } | 302 | } |
303 | 303 | ||
304 | static int | 304 | static int |
305 | eckey_compute_pubkey(EC_KEY *eckey) | ||
306 | { | ||
307 | const BIGNUM *priv_key; | ||
308 | const EC_GROUP *group; | ||
309 | EC_POINT *pub_key = NULL; | ||
310 | int ret = 0; | ||
311 | |||
312 | if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) | ||
313 | goto err; | ||
314 | if ((group = EC_KEY_get0_group(eckey)) == NULL) | ||
315 | goto err; | ||
316 | if ((pub_key = EC_POINT_new(group)) == NULL) | ||
317 | goto err; | ||
318 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) | ||
319 | goto err; | ||
320 | if (!EC_KEY_set_public_key(eckey, pub_key)) | ||
321 | goto err; | ||
322 | pub_key = NULL; | ||
323 | |||
324 | ret = 1; | ||
325 | |||
326 | err: | ||
327 | EC_POINT_free(pub_key); | ||
328 | |||
329 | return ret; | ||
330 | } | ||
331 | |||
332 | static int | ||
305 | eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) | 333 | eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) |
306 | { | 334 | { |
307 | const unsigned char *p = NULL; | 335 | const unsigned char *priv = NULL; |
336 | int priv_len; | ||
308 | const void *pval; | 337 | const void *pval; |
309 | int ptype, pklen; | 338 | int ptype; |
310 | EC_KEY *eckey = NULL; | 339 | EC_KEY *eckey = NULL; |
311 | const X509_ALGOR *palg; | 340 | const X509_ALGOR *palg; |
341 | int ret = 0; | ||
312 | 342 | ||
313 | if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) | 343 | if (!PKCS8_pkey_get0(NULL, &priv, &priv_len, &palg, p8)) |
314 | return 0; | 344 | goto err; |
315 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
316 | 345 | ||
346 | X509_ALGOR_get0(NULL, &ptype, &pval, palg); | ||
317 | if (!eckey_from_params(ptype, pval, &eckey)) | 347 | if (!eckey_from_params(ptype, pval, &eckey)) |
318 | goto ecliberr; | 348 | goto err; |
319 | 349 | ||
320 | /* We have parameters now set private key */ | 350 | /* Decode private key into eckey. */ |
321 | if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { | 351 | if (d2i_ECPrivateKey(&eckey, &priv, priv_len) == NULL) { |
322 | ECerror(EC_R_DECODE_ERROR); | 352 | ECerror(EC_R_DECODE_ERROR); |
323 | goto ecerr; | 353 | goto err; |
324 | } | 354 | } |
325 | /* calculate public key (if necessary) */ | 355 | /* If public key was missing from SEC1 key, compute it. */ |
326 | if (EC_KEY_get0_public_key(eckey) == NULL) { | 356 | if (EC_KEY_get0_public_key(eckey) == NULL) { |
327 | const BIGNUM *priv_key; | 357 | if (!eckey_compute_pubkey(eckey)) |
328 | const EC_GROUP *group; | 358 | goto err; |
329 | EC_POINT *pub_key; | ||
330 | /* | ||
331 | * the public key was not included in the SEC1 private key => | ||
332 | * calculate the public key | ||
333 | */ | ||
334 | group = EC_KEY_get0_group(eckey); | ||
335 | pub_key = EC_POINT_new(group); | ||
336 | if (pub_key == NULL) { | ||
337 | ECerror(ERR_R_EC_LIB); | ||
338 | goto ecliberr; | ||
339 | } | ||
340 | if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { | ||
341 | EC_POINT_free(pub_key); | ||
342 | ECerror(ERR_R_EC_LIB); | ||
343 | goto ecliberr; | ||
344 | } | ||
345 | priv_key = EC_KEY_get0_private_key(eckey); | ||
346 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { | ||
347 | EC_POINT_free(pub_key); | ||
348 | ECerror(ERR_R_EC_LIB); | ||
349 | goto ecliberr; | ||
350 | } | ||
351 | if (EC_KEY_set_public_key(eckey, pub_key) == 0) { | ||
352 | EC_POINT_free(pub_key); | ||
353 | ECerror(ERR_R_EC_LIB); | ||
354 | goto ecliberr; | ||
355 | } | ||
356 | EC_POINT_free(pub_key); | ||
357 | } | 359 | } |
358 | EVP_PKEY_assign_EC_KEY(pkey, eckey); | ||
359 | return 1; | ||
360 | 360 | ||
361 | ecliberr: | 361 | if (!EVP_PKEY_assign_EC_KEY(pkey, eckey)) |
362 | ECerror(ERR_R_EC_LIB); | 362 | goto err; |
363 | ecerr: | 363 | eckey = NULL; |
364 | if (eckey) | 364 | |
365 | EC_KEY_free(eckey); | 365 | ret = 1; |
366 | return 0; | 366 | |
367 | err: | ||
368 | EC_KEY_free(eckey); | ||
369 | |||
370 | return ret; | ||
367 | } | 371 | } |
368 | 372 | ||
369 | static int | 373 | static int |