From: tb Date: Mon, 10 Jan 2022 11:52:43 +0000 (+0000) Subject: Prepare to provide EVP_PKEY_check() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c0f4ec487aa75ec95b5c178b8b2e05d40595731f;p=openbsd Prepare to provide EVP_PKEY_check() This allows checking the validity of an EVP_PKEY. Only RSA and EC keys are supported. If a check function is set the EVP_PKEY_METHOD, it will be used, otherwise the check function on the EVP_PKEY_ASN1_METHOD is used. The default ASN.1 methods wrap RSA_check_key() and EC_KEY_check_key(), respectively. The corresponding setters are EVP_PKEY_{asn1,meth}_set_check(). It is unclear why the PKEY method has no const while the ASN.1 method has const. Requested by tobhe and used by PHP 8.1. Based on OpenSSL commit 2aee35d3 ok inoguchi jsing --- diff --git a/lib/libcrypto/asn1/ameth_lib.c b/lib/libcrypto/asn1/ameth_lib.c index ed7f5bd3e40..96669bbd2f5 100644 --- a/lib/libcrypto/asn1/ameth_lib.c +++ b/lib/libcrypto/asn1/ameth_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ameth_lib.c,v 1.23 2021/12/12 21:30:13 tb Exp $ */ +/* $OpenBSD: ameth_lib.c,v 1.24 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -429,3 +429,10 @@ EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, { ameth->pkey_ctrl = pkey_ctrl; } + +void +EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check)(const EVP_PKEY *pk)) +{ + ameth->pkey_check = pkey_check; +} diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h index 3b949dba654..31fcbef20d7 100644 --- a/lib/libcrypto/asn1/asn1_locl.h +++ b/lib/libcrypto/asn1/asn1_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_locl.h,v 1.15 2021/12/25 12:00:22 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.16 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -124,6 +124,7 @@ struct evp_pkey_asn1_method_st { int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); + int (*pkey_check)(const EVP_PKEY *pk); } /* EVP_PKEY_ASN1_METHOD */; /* Method to handle CRL access. diff --git a/lib/libcrypto/ec/ec_ameth.c b/lib/libcrypto/ec/ec_ameth.c index c96c46dd53c..8316683f8f9 100644 --- a/lib/libcrypto/ec/ec_ameth.c +++ b/lib/libcrypto/ec/ec_ameth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_ameth.c,v 1.29 2021/12/12 21:30:13 tb Exp $ */ +/* $OpenBSD: ec_ameth.c,v 1.30 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -67,6 +67,7 @@ #include #include "asn1_locl.h" +#include "ec_lcl.h" #include "evp_locl.h" #ifndef OPENSSL_NO_CMS @@ -620,6 +621,19 @@ ec_pkey_ctrl(EVP_PKEY * pkey, int op, long arg1, void *arg2) } +static int +ec_pkey_check(const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + + if (eckey->priv_key == NULL) { + ECerror(EC_R_MISSING_PRIVATE_KEY); + return 0; + } + + return EC_KEY_check_key(eckey); +} + #ifndef OPENSSL_NO_CMS static int @@ -981,5 +995,7 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { .pkey_free = int_ec_free, .pkey_ctrl = ec_pkey_ctrl, .old_priv_decode = old_ec_priv_decode, - .old_priv_encode = old_ec_priv_encode + .old_priv_encode = old_ec_priv_encode, + + .pkey_check = ec_pkey_check, }; diff --git a/lib/libcrypto/evp/evp.h b/lib/libcrypto/evp/evp.h index aa5b35f67ce..e122a6b3297 100644 --- a/lib/libcrypto/evp/evp.h +++ b/lib/libcrypto/evp/evp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp.h,v 1.92 2022/01/09 15:15:25 tb Exp $ */ +/* $OpenBSD: evp.h,v 1.93 2022/01/10 11:52:43 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1087,6 +1087,11 @@ void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2)); +#if defined(LIBRESSL_CRYPTO_INTERNAL) || defined(LIBRESSL_NEXT_API) +void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_check)(const EVP_PKEY *pk)); +#endif + #define EVP_PKEY_OP_UNDEFINED 0 #define EVP_PKEY_OP_PARAMGEN (1<<1) #define EVP_PKEY_OP_KEYGEN (1<<2) @@ -1213,6 +1218,9 @@ int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +#if defined(LIBRESSL_CRYPTO_INTERNAL) || defined(LIBRESSL_NEXT_API) +int EVP_PKEY_check(EVP_PKEY_CTX *ctx); +#endif void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); @@ -1279,6 +1287,11 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value)); +#if defined(LIBRESSL_CRYPTO_INTERNAL) || defined(LIBRESSL_NEXT_API) +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check)(EVP_PKEY *pkey)); +#endif + /* Authenticated Encryption with Additional Data. * * AEAD couples confidentiality and integrity in a single primtive. AEAD diff --git a/lib/libcrypto/evp/evp_locl.h b/lib/libcrypto/evp/evp_locl.h index 5eef0b244f6..3ff8e8ad997 100644 --- a/lib/libcrypto/evp/evp_locl.h +++ b/lib/libcrypto/evp/evp_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_locl.h,v 1.18 2022/01/09 15:15:25 tb Exp $ */ +/* $OpenBSD: evp_locl.h,v 1.19 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -347,6 +347,8 @@ struct evp_pkey_method_st { int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value); + + int (*check)(EVP_PKEY *pkey); } /* EVP_PKEY_METHOD */; void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); diff --git a/lib/libcrypto/evp/pmeth_gn.c b/lib/libcrypto/evp/pmeth_gn.c index 066291b8007..a8a4cc97db6 100644 --- a/lib/libcrypto/evp/pmeth_gn.c +++ b/lib/libcrypto/evp/pmeth_gn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmeth_gn.c,v 1.8 2021/12/04 16:08:32 tb Exp $ */ +/* $OpenBSD: pmeth_gn.c,v 1.9 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -64,6 +64,7 @@ #include #include +#include "asn1_locl.h" #include "bn_lcl.h" #include "evp_locl.h" @@ -222,3 +223,24 @@ merr: EVP_PKEY_CTX_free(mac_ctx); return mac_key; } + +int +EVP_PKEY_check(EVP_PKEY_CTX *ctx) +{ + EVP_PKEY *pkey; + + if ((pkey = ctx->pkey) == NULL) { + EVPerror(EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pmeth->check != NULL) + return ctx->pmeth->check(pkey); + + if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) { + EVPerror(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + return pkey->ameth->pkey_check(pkey); +} diff --git a/lib/libcrypto/evp/pmeth_lib.c b/lib/libcrypto/evp/pmeth_lib.c index 33924dbd663..92328dd2468 100644 --- a/lib/libcrypto/evp/pmeth_lib.c +++ b/lib/libcrypto/evp/pmeth_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmeth_lib.c,v 1.18 2021/12/03 14:19:57 tb Exp $ */ +/* $OpenBSD: pmeth_lib.c,v 1.19 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -582,3 +582,9 @@ EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl = ctrl; pmeth->ctrl_str = ctrl_str; } + +void +EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, int (*check)(EVP_PKEY *pkey)) +{ + pmeth->check = check; +} diff --git a/lib/libcrypto/rsa/rsa_ameth.c b/lib/libcrypto/rsa/rsa_ameth.c index d373d7c1327..57fe46a9760 100644 --- a/lib/libcrypto/rsa/rsa_ameth.c +++ b/lib/libcrypto/rsa/rsa_ameth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rsa_ameth.c,v 1.24 2019/11/20 10:46:17 inoguchi Exp $ */ +/* $OpenBSD: rsa_ameth.c,v 1.25 2022/01/10 11:52:43 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -916,6 +916,12 @@ rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, return 2; } +static int +rsa_pkey_check(const EVP_PKEY *pkey) +{ + return RSA_check_key(pkey->pkey.rsa); +} + #ifndef OPENSSL_NO_CMS static RSA_OAEP_PARAMS * rsa_oaep_decode(const X509_ALGOR *alg) @@ -1105,14 +1111,18 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { .old_priv_decode = old_rsa_priv_decode, .old_priv_encode = old_rsa_priv_encode, .item_verify = rsa_item_verify, - .item_sign = rsa_item_sign + .item_sign = rsa_item_sign, + + .pkey_check = rsa_pkey_check, }, { .pkey_id = EVP_PKEY_RSA2, .pkey_base_id = EVP_PKEY_RSA, - .pkey_flags = ASN1_PKEY_ALIAS - } + .pkey_flags = ASN1_PKEY_ALIAS, + + .pkey_check = rsa_pkey_check, + }, }; const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = {