Document the change in behaviour of the the low level key getters/setters
authorMatt Caswell <matt@openssl.org>
Thu, 25 Feb 2021 17:00:38 +0000 (17:00 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 8 Mar 2021 15:11:31 +0000 (15:11 +0000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14319)

CHANGES.md
doc/internal/man3/evp_pkey_export_to_provider.pod
doc/internal/man7/EVP_PKEY.pod
doc/man3/EVP_PKEY_set1_RSA.pod
doc/man7/evp.pod

index b9ce4e8657f96efae08c0cf41f2d9be2e0865544..0ff517f2d01bd39a3a95a168893dab4dc8eb2c08 100644 (file)
@@ -23,6 +23,24 @@ OpenSSL 3.0
 
 ### Changes between 1.1.1 and 3.0 [xx XXX xxxx]
 
+ * The deprecated functions EVP_PKEY_get0(), EVP_PKEY_get0_RSA(),
+   EVP_PKEY_get0_DSA(), EVP_PKEY_get0_EC_KEY(), EVP_PKEY_get0_DH(),
+   EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and EVP_PKEY_get0_siphash() as
+   well as the similarly named "get1" functions behave slightly differently in
+   OpenSSL 3.0. Previously they returned a pointer to the low-level key used
+   internally by libcrypto. From OpenSSL 3.0 this key may now be held in a
+   provider. Calling these functions will only return a handle on the internal
+   key where the EVP_PKEY was constructed using this key in the first place, for
+   example using a function or macro such as EVP_PKEY_assign_RSA(),
+   EVP_PKEY_set1_RSA(), etc. Where the EVP_PKEY holds a provider managed key,
+   then these functions now return a cached copy of the key. Changes to
+   the internal provider key that take place after the first time the cached key
+   is accessed will not be reflected back in the cached copy. Similarly any
+   changed made to the cached copy by application code will not be reflected
+   back in the internal provider key.
+
+   *Matt Caswell*
+
  * A number of functions handling low level keys or engines were deprecated
    including EVP_PKEY_set1_engine(), EVP_PKEY_get0_engine(), EVP_PKEY_assign(),
    EVP_PKEY_get0(), EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305() and
@@ -701,12 +719,12 @@ OpenSSL 3.0
    time.  Instead applications should use L<EVP_DigestSignInit_ex(3)>,
    L<EVP_DigestSignUpdate(3)> and L<EVP_DigestSignFinal(3)>.
 
-   Finaly functions that assign or obtain DH objects from an EVP_PKEY such as
+   Finaly functions that assign or obtain DSA objects from an EVP_PKEY such as
    `EVP_PKEY_assign_DSA()`, `EVP_PKEY_get0_DSA()`, `EVP_PKEY_get1_DSA()`, and
    `EVP_PKEY_set1_DSA()` are also deprecated.
    Applications should instead either read or write an
-   EVP_PKEY directly using the OSSL_DECODER and OSSL_ENCODER APIs.
-   Or load an EVP_PKEY directly from DSA data using `EVP_PKEY_fromdata()`.
+   EVP_PKEY directly using the OSSL_DECODER and OSSL_ENCODER APIs,
+   or load an EVP_PKEY directly from DSA data using `EVP_PKEY_fromdata()`.
 
    *Paul Dale*
 
index 65fb7109e06872973ca6f28c413568431474ca49..833ff44d53b20f8323ca63eefb9714e7d647096e 100644 (file)
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_downgrade
+evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_get_legacy
 - internal EVP_PKEY support functions for providers
 
 =head1 SYNOPSIS
@@ -14,7 +14,7 @@ evp_pkey_export_to_provider, evp_pkey_copy_downgraded, evp_pkey_downgrade
                                    EVP_KEYMGMT **keymgmt,
                                    const char *propquery);
  int evp_pkey_copy_downgraded(EVP_PKEY **dest, const EVP_PKEY *src);
int evp_pkey_downgrade(EVP_PKEY *pk);
void *evp_pkey_get_legacy(EVP_PKEY *pk);
 
 =head1 DESCRIPTION
 
@@ -37,11 +37,14 @@ For example, L<PEM_write_bio_PrivateKey_traditional(3)> uses this to try its
 best to get "traditional" PEM output even if the input B<EVP_PKEY> has a
 provider-native internal key.
 
-evp_pkey_downgrade() converts an B<EVP_PKEY> with a provider side "origin" key
-to one with a legacy "origin", if there's a corresponding legacy implementation.
-This clears the operation cache, except for the provider side "origin" key.
-This function is used in spots where provider side keys aren't yet supported,
-in an attempt to keep operating with available implementations.
+evp_pkey_get_legacy() obtains and returns a legacy key structure. If the
+EVP_PKEY already contains a legacy key then it is simply returned. If it is a
+provider based key, then a new legacy key is constructed based on the provider
+key. The legacy key is cached inside the EVP_PKEY and its value returned from
+this function. Subsequent calls to evp_pkey_get_legacy() will return the cached
+key. Subsequent changes to the provider key are not reflected back in the
+legacy key. Similarly changes to the legacy key are not reflected back in the
+provider key.
 
 =head1 RETURN VALUES
 
@@ -49,7 +52,7 @@ evp_pkey_export_to_provider() returns the provider key data if there was any
 allocated.  It also either sets I<*keymgmt> to the B<EVP_KEYMGMT> associated
 with the returned key data, or NULL on error.
 
-evp_pkey_downgrade() returns 1 on success or 0 on error.
+evp_pkey_get_legacy() returns the legacy key or NULL on error.
 
 =head1 NOTES
 
index 7088b6cc08a6db66d694b8ee3650e8da320f7f78..cc738b9c28ebcc58177ae2c6accc132f384c3803 100644 (file)
@@ -65,7 +65,10 @@ The B<EVP_PKEY> internal keys are mutable.
 
 This is especially visible with internal legacy keys, since they can
 be extracted with functions like L<EVP_PKEY_get0_RSA(3)> and then
-modified at will with functions like L<RSA_set0_key(3)>.
+modified at will with functions like L<RSA_set0_key(3)>. Note that if the
+internal key is a provider key then the return value from functions such as
+L<EVP_PKEY_get0_RSA(3)> is a cached copy of the key. Changes to the cached
+copy are not reflected back in the provider key.
 
 Internal provider native keys are also possible to be modified, if the
 associated L<EVP_KEYMGMT(3)> implementation allows it.  This is done
@@ -187,11 +190,11 @@ takes care of the needs of the diverse operation the application may want to
 perform.
 
 Similarly an B<EVP_PKEY> with a provider native origin, will I<never> be
-downgraded to be I<transformed> into an B<EVP_PKEY> with a legacy origin.
-Instead we may have a cached copy of the provider key in legacy form. Once the
-cached copy is created it is never updated. Changes made to the provider key
-are not reflected back in the cached legacy copy. Similarly changes made to the
-cached legacy copy are not reflected back in the provider key.
+I<transformed> into an B<EVP_PKEY> with a legacy origin. Instead we may have a
+cached copy of the provider key in legacy form. Once the cached copy is created
+it is never updated. Changes made to the provider key are not reflected back in
+the cached legacy copy. Similarly changes made to the cached legacy copy are not
+reflected back in the provider key.
 
 =head1 SEE ALSO
 
index 32b1e1b8d537d31736dfbae8c9f7649f55a72940..85cf5b6fe4c01b3e5856d9cb82f92b66be2f4925 100644 (file)
@@ -84,7 +84,7 @@ L<EVP_PKEY_fromdata(3)>.
 
 EVP_PKEY_get1_RSA(), EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and
 EVP_PKEY_get1_EC_KEY() return the referenced key in I<pkey> or NULL if the
-key is not of the correct type.  The returned key must be freed after use.
+key is not of the correct type. The returned key must be freed after use.
 These functions are deprecated. Applications should instead use the EVP_PKEY
 directly where possible. If access to the low level key parameters is required
 then applications should use L<EVP_PKEY_get_params(3)> and other similar
@@ -94,14 +94,29 @@ L<OSSL_ENCODER_CTX_new_for_pkey(3)>).
 EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
 EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() and
 EVP_PKEY_get0_EC_KEY() return the referenced key in I<pkey> or NULL if the
-key is not of the correct type but the reference count of the returned key
-is B<not> incremented and so must not be freed after use. These functions are
-deprecated. Applications should instead use the EVP_PKEY directly where
+key is not of the correct type. The reference count of the returned key is
+B<not> incremented and so the key must not be freed after use. These functions
+are deprecated. Applications should instead use the EVP_PKEY directly where
 possible. If access to the low level key parameters is required then
 applications should use L<EVP_PKEY_get_params(3)> and other similar functions.
 To write an EVP_PKEY out use the OSSL_ENCODER APIs (see
 L<OSSL_ENCODER_CTX_new_for_pkey(3)>).
 
+Note that if an EVP_PKEY was not constructed using one of the deprecated
+functions such as EVP_PKEY_set1_RSA(), EVP_PKEY_set1_DSA(), EVP_PKEY_set1_DH()
+or EVP_PKEY_set1_EC_KEY(), or via the similarly named B<EVP_PKEY_assign> macros
+described above then the internal key will be managed by a provider (see
+L<provider(7)>). In that case the key returned by EVP_PKEY_get1_RSA(),
+EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH(), EVP_PKEY_get1_EC_KEY(),
+EVP_PKEY_get0_hmac(), EVP_PKEY_get0_poly1305(), EVP_PKEY_get0_siphash(),
+EVP_PKEY_get0_RSA(), EVP_PKEY_get0_DSA(), EVP_PKEY_get0_DH() or
+EVP_PKEY_get0_EC_KEY() will be a cached copy of the provider's key. Subsequent
+updates to the provider's key will not be reflected back in the cached copy, and
+updates made by an application to the returned key will not be reflected back in
+the provider's key. Subsequent calls to EVP_PKEY_get1_RSA(),
+EVP_PKEY_get1_DSA(), EVP_PKEY_get1_DH() and EVP_PKEY_get1_EC_KEY() will always
+return the cached copy returned by the first call.
+
 EVP_PKEY_get0_engine() returns a reference to the ENGINE handling I<pkey>. This
 function is deprecated. Applications should use providers instead of engines
 (see L<provider(7)> for details).
index d8f5a2c1d36ba6a9f85c49b74fde5b1c68a176f5..c97abba3ddc2095a45b4d4bbd1b74e53960e930e 100644 (file)
@@ -29,7 +29,7 @@ The B<EVP_PKEY>I<XXX> functions provide a high-level interface to
 asymmetric algorithms. To create a new EVP_PKEY see
 L<EVP_PKEY_new(3)>. EVP_PKEYs can be associated
 with a private key of a particular algorithm by using the functions
-described on the L<EVP_PKEY_set1_RSA(3)> page, or
+described on the L<EVP_PKEY_fromdata(3)> page, or
 new keys can be generated using L<EVP_PKEY_keygen(3)>.
 EVP_PKEYs can be compared using L<EVP_PKEY_cmp(3)>, or printed using
 L<EVP_PKEY_print_private(3)>.
@@ -90,7 +90,7 @@ L<EVP_SignInit(3)>,
 L<EVP_VerifyInit(3)>,
 L<EVP_EncodeInit(3)>,
 L<EVP_PKEY_new(3)>,
-L<EVP_PKEY_set1_RSA(3)>,
+L<EVP_PKEY_fromdata(3)>,
 L<EVP_PKEY_keygen(3)>,
 L<EVP_PKEY_print_private(3)>,
 L<EVP_PKEY_decrypt(3)>,