summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2023-12-29 18:46:24 +0000
committertb <>2023-12-29 18:46:24 +0000
commit5f197d54aa3750390380be33ac4bd1fe910b7fcd (patch)
tree8a548b19bfcf1d635ebf2e7cbd2dac3ea68a2c37 /src/lib
parentee1a6831815b66f5ddf67219918fb3b797c7361e (diff)
downloadopenbsd-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.c102
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
304static int 304static int
305eckey_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
332static int
305eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) 333eckey_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
369static int 373static int