/*
- * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
if (pkey->ameth != NULL && pkey->ameth->pkey_bits != NULL)
size = pkey->ameth->pkey_bits(pkey);
}
- return size < 0 ? 0 : size;
+ if (size <= 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_BITS);
+ return 0;
+ }
+ return size;
}
int EVP_PKEY_get_security_bits(const EVP_PKEY *pkey)
if (pkey->ameth != NULL && pkey->ameth->pkey_security_bits != NULL)
size = pkey->ameth->pkey_security_bits(pkey);
}
- return size < 0 ? 0 : size;
+ if (size <= 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_SECURITY_BITS);
+ return 0;
+ }
+ return size;
}
int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
{
switch (pkey->type) {
case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA_PSS:
pkey->foreign = pkey->pkey.rsa != NULL
&& ossl_rsa_is_foreign(pkey->pkey.rsa);
break;
# ifndef OPENSSL_NO_EC
case EVP_PKEY_SM2:
+ break;
case EVP_PKEY_EC:
pkey->foreign = pkey->pkey.ec != NULL
&& ossl_ec_key_is_foreign(pkey->pkey.ec);
}
# endif /* OPENSSL_NO_DSA */
-# ifndef OPENSSL_NO_EC
+# ifndef OPENSSL_NO_ECX
static const ECX_KEY *evp_pkey_get0_ECX_KEY(const EVP_PKEY *pkey, int type)
{
if (EVP_PKEY_get_base_id(pkey) != type) {
IMPLEMENT_ECX_VARIANT(ED25519)
IMPLEMENT_ECX_VARIANT(ED448)
-# endif
+# endif /* OPENSSL_NO_ECX */
# if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0)
if (pkey->keymgmt == NULL) {
switch (EVP_PKEY_get_base_id(pkey)) {
case EVP_PKEY_RSA:
+ case EVP_PKEY_RSA_PSS:
return 1;
# ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx)
{
- return print_pkey(pkey, out, indent, EVP_PKEY_KEYPAIR, NULL,
+ return print_pkey(pkey, out, indent, EVP_PKEY_PRIVATE_KEY, NULL,
(pkey->ameth != NULL ? pkey->ameth->priv_print : NULL),
pctx);
}
ret->type = EVP_PKEY_NONE;
ret->save_type = EVP_PKEY_NONE;
- ret->references = 1;
+
+ if (!CRYPTO_NEW_REF(&ret->references, 1))
+ goto err;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
return ret;
err:
+ CRYPTO_FREE_REF(&ret->references);
CRYPTO_THREAD_lock_free(ret->lock);
OPENSSL_free(ret);
return NULL;
{
int i;
- if (CRYPTO_UP_REF(&pkey->references, &i, pkey->lock) <= 0)
+ if (CRYPTO_UP_REF(&pkey->references, &i) <= 0)
return 0;
REF_PRINT_COUNT("EVP_PKEY", pkey);
static void evp_pkey_free_it(EVP_PKEY *x)
{
/* internal function; x is never NULL */
- evp_keymgmt_util_clear_operation_cache(x, 1);
+ evp_keymgmt_util_clear_operation_cache(x);
#ifndef FIPS_MODULE
evp_pkey_free_legacy(x);
#endif
if (x == NULL)
return;
- CRYPTO_DOWN_REF(&x->references, &i, x->lock);
+ CRYPTO_DOWN_REF(&x->references, &i);
REF_PRINT_COUNT("EVP_PKEY", x);
if (i > 0)
return;
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
#endif
CRYPTO_THREAD_lock_free(x->lock);
+ CRYPTO_FREE_REF(&x->references);
#ifndef FIPS_MODULE
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
#endif
size = pkey->ameth->pkey_size(pkey);
#endif
}
- return size < 0 ? 0 : size;
+ if (size <= 0) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_UNKNOWN_MAX_SIZE);
+ return 0;
+ }
+ return size;
}
const char *EVP_PKEY_get0_description(const EVP_PKEY *pkey)
* If |tmp_keymgmt| is present in the operation cache, it means
* that export doesn't need to be redone. In that case, we take
* token copies of the cached pointers, to have token success
- * values to return.
+ * values to return. It is possible (e.g. in a no-cached-fetch
+ * build), for op->keymgmt to be a different pointer to tmp_keymgmt
+ * even though the name/provider must be the same. In other words
+ * the keymgmt instance may be different but still equivalent, i.e.
+ * same algorithm/provider instance - but we make the simplifying
+ * assumption that the keydata can be used with either keymgmt
+ * instance. Not doing so introduces significant complexity and
+ * probably requires refactoring - since we would have to ripple
+ * the change in keymgmt instance up the call chain.
*/
if (op != NULL && op->keymgmt != NULL) {
keydata = op->keydata;
if (!CRYPTO_THREAD_write_lock(pk->lock))
goto end;
if (pk->ameth->dirty_cnt(pk) != pk->dirty_cnt_copy
- && !evp_keymgmt_util_clear_operation_cache(pk, 0)) {
+ && !evp_keymgmt_util_clear_operation_cache(pk)) {
CRYPTO_THREAD_unlock(pk->lock);
evp_keymgmt_freedata(tmp_keymgmt, keydata);
keydata = NULL;