diff options
| author | tb <> | 2023-12-29 18:46:24 +0000 |
|---|---|---|
| committer | tb <> | 2023-12-29 18:46:24 +0000 |
| commit | daac9ac8c298b481db05bf3ee249b871385f2a4d (patch) | |
| tree | 8a548b19bfcf1d635ebf2e7cbd2dac3ea68a2c37 /src/lib/libc | |
| parent | 5218d2b40b3ebc8e390ec1c40a2323ecf21637dd (diff) | |
| download | openbsd-daac9ac8c298b481db05bf3ee249b871385f2a4d.tar.gz openbsd-daac9ac8c298b481db05bf3ee249b871385f2a4d.tar.bz2 openbsd-daac9ac8c298b481db05bf3ee249b871385f2a4d.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 '')
| -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 |
