The branch master has been updated via ccb47dbf47b36da849301aae38c32ed019e75a21 (commit) via 476de2e5e598b46289c6087df04d1bc1886d6ef2 (commit) from 031c9bd3f3e9a02fa126c7dbc47f3d934678a195 (commit)
- Log ----------------------------------------------------------------- commit ccb47dbf47b36da849301aae38c32ed019e75a21 Author: Richard Levitte <levi...@openssl.org> Date: Fri Mar 6 14:55:49 2020 +0100 DOC: Extend the description of EVP_PKEY_CTX_new_from_name() This adds text the should lead the user to documentation on different KEYMGMT implementations. Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/11220) commit 476de2e5e598b46289c6087df04d1bc1886d6ef2 Author: Richard Levitte <levi...@openssl.org> Date: Mon Mar 2 14:39:30 2020 +0100 DOC: Add more description of EVP_PKEY_fromdata(), and examples Fixes #11131 Reviewed-by: Paul Dale <paul.d...@oracle.com> (Merged from https://github.com/openssl/openssl/pull/11220) ----------------------------------------------------------------------- Summary of changes: doc/man3/EVP_PKEY_CTX_new.pod | 32 ++++++-- doc/man3/EVP_PKEY_fromdata.pod | 172 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 192 insertions(+), 12 deletions(-) diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod index 5f8a01242d..327d09f348 100644 --- a/doc/man3/EVP_PKEY_CTX_new.pod +++ b/doc/man3/EVP_PKEY_CTX_new.pod @@ -32,7 +32,8 @@ The EVP_PKEY_CTX_new_from_name() function allocates a public key algorithm context using the library context I<libctx> (see L<OPENSSL_CTX(3)>), the key type specified by I<name> and the property query I<propquery>. None of the arguments are duplicated, so they must remain unchanged for the -lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates. +lifetime of the returned B<EVP_PKEY_CTX> or of any of its duplicates. Read +further about the possible names in L</NOTES> below. The EVP_PKEY_CTX_new_from_pkey() function allocates a public key algorithm context using the library context I<libctx> (see L<OPENSSL_CTX(3)>) and the @@ -52,16 +53,14 @@ If I<ctx> is NULL, nothing is done. =head1 NOTES -=over 4 - -=item 1. +=head2 On B<EVP_PKEY_CTX> The B<EVP_PKEY_CTX> structure is an opaque public key algorithm context used by the OpenSSL high level public key API. Contexts B<MUST NOT> be shared between threads: that is it is not permissible to use the same context simultaneously in two threads. -=item 2. +=head2 On Key Types We mention "key type" in this manual, which is the same as "algorithm" in most cases, allowing either term to be used @@ -69,6 +68,29 @@ interchangeably. There are algorithms where the I<key type> and the I<algorithm> of the operations that use the keys are not the same, such as EC keys being used for ECDSA and ECDH operations. +Key types are given in two different manners: + +=over 4 + +=item Legacy NID or EVP_PKEY type + +This is the I<id> used with EVP_PKEY_CTX_new_id(). + +These are B<EVP_PKEY_RSA>, B<EVP_PKEY_RSA_PSS>, B<EVP_PKEY_DSA>, +B<EVP_PKEY_DH>, B<EVP_PKEY_EC>, B<EVP_PKEY_SM2>, B<EVP_PKEY_X25519>, +B<EVP_PKEY_X448>, and are used by legacy methods. + +=item Name strings + +This is the I<name> used with EVP_PKEY_CTX_new_from_name(). + +These are names like "RSA", "DSA", and what's available depends on what +providers are currently accessible. + +The OpenSSL providers offer a set of key types available this way, please +see L<OSSL_PROVIDER-FIPS(7)> and L<OSSL_PROVIDER-default(7)> and related +documentation for more information. + =back =head1 RETURN VALUES diff --git a/doc/man3/EVP_PKEY_fromdata.pod b/doc/man3/EVP_PKEY_fromdata.pod index e3ddf68058..0d85e80b95 100644 --- a/doc/man3/EVP_PKEY_fromdata.pod +++ b/doc/man3/EVP_PKEY_fromdata.pod @@ -18,18 +18,29 @@ EVP_PKEY_param_fromdata_settable, EVP_PKEY_key_fromdata_settable =head1 DESCRIPTION +The functions described here are used to create new keys from user +provided key data, such as I<n>, I<e> and I<d> for a minimal RSA +keypair. + +These functions use an B<EVP_PKEY_CTX> context, which should primarly +be created with L<EVP_PKEY_CTX_new_from_name(3)> or +L<EVP_PKEY_CTX_new_id(3)>. + +The exact key data that the user can pass depends on the key type. +These are passed as an L<OSSL_PARAM(3)> array. + EVP_PKEY_param_fromdata_init() initializes a public key algorithm context for creating key parameters from user data. EVP_PKEY_key_fromdata_init() initializes a public key algorithm context for creating a key from user data. -EVP_PKEY_fromdata() creates key parameters or a key, given data from -I<params> and a context that's been initialized with -EVP_PKEY_param_fromdata_init() or EVP_PKEY_key_fromdata_init(). The result is -written to I<*ppkey>. The parameters that can be used for various types of key -are as described in the "Built-in RSA Import/Export Types" section on the -L<provider-keymgmt(7)> page. +EVP_PKEY_fromdata() creates the structure to store key parameters or a +key, given data from I<params> and a context that's been initialized with +EVP_PKEY_param_fromdata_init() or EVP_PKEY_key_fromdata_init(). The result +is written to I<*ppkey>. The parameters that can be used are specific to +the L<provider-keymgmt(7)> implementations, please see +L<EVP_PKEY_CTX_new_from_name(3)> for further information. EVP_PKEY_param_fromdata_settable() and EVP_PKEY_key_fromdata_settable() get a constant B<OSSL_PARAM> array that describes the settable parameters @@ -50,9 +61,156 @@ EVP_PKEY_fromdata() return 1 for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. +=head1 EXAMPLES + +These examples are very terse for the sake of staying on topic, which +is the EVP_PKEY_fromdata() set of functions. In real applications, +BIGNUMs would be handled and converted to byte arrays with +BN_bn2nativepad(), but that's off topic here. + +=begin comment + +TODO Write a set of cookbook documents and link to them. + +=end comment + +=head2 Creating an RSA keypair using raw key data + + #include <openssl/evp.h> + + /* + * These are extremely small to make this example simple. A real + * and secure application will not use such small numbers. A real + * and secure application is expected to use BIGNUMs, and to build + * this array dynamically. + */ + const unsigned long rsa_n = 0xbc747fc5; + const unsigned long rsa_e = 0x10001; + const unsigned long rsa_d = 0x7b133399; + const OSSL_PARAM[] = { + OSSL_PARAM_ulong("n", &rsa_n), + OSSL_PARAM_ulong("e", &rsa_e), + OSSL_PARAM_ulong("d", &rsa_d), + OSSL_PARAM_END + }; + + int main() + { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + EVP_PKEY *pkey = NULL; + + if (ctx == NULL + || !EVP_PKEY_key_fromdata_init(ctx) + || !EVP_PKEY_fromdata(ctx, &pkey, params)) + exit(1); + + /* Do what you want with |pkey| */ + } + +=head2 Creating an ECC keypair using raw key data + + #include <openssl/evp.h> + + /* + * These arrays represent large numbers, big endian organization. + * In a real application, these would probably be bignums that get + * converted to the native integer organization with BN_bn2nativepad(). + * We're not doing that here, since this is not an example of BIGNUM + * functionality, but an example of EVP_PKEY_fromdata(). + */ + #ifndef B_ENDIAN + # error "We haven't prepared little endian arrays" + #endif + const unsigned char priv[] = { + 0xb9, 0x2f, 0x3c, 0xe6, 0x2f, 0xfb, 0x45, 0x68, + 0x39, 0x96, 0xf0, 0x2a, 0xaf, 0x6c, 0xda, 0xf2, + 0x89, 0x8a, 0x27, 0xbf, 0x39, 0x9b, 0x7e, 0x54, + 0x21, 0xc2, 0xa1, 0xe5, 0x36, 0x12, 0x48, 0x5d + }; + const unsigned char pub[] = { + 0x04, 0xcf, 0x20, 0xfb, 0x9a, 0x1d, 0x11, 0x6c, + 0x5e, 0x9f, 0xec, 0x38, 0x87, 0x6c, 0x1d, 0x2f, + 0x58, 0x47, 0xab, 0xa3, 0x9b, 0x79, 0x23, 0xe6, + 0xeb, 0x94, 0x6f, 0x97, 0xdb, 0xa3, 0x7d, 0xbd, + 0xe5, 0x26, 0xca, 0x07, 0x17, 0x8d, 0x26, 0x75, + 0xff, 0xcb, 0x8e, 0xb6, 0x84, 0xd0, 0x24, 0x02, + 0x25, 0x8f, 0xb9, 0x33, 0x6e, 0xcf, 0x12, 0x16, + 0x2f, 0x5c, 0xcd, 0x86, 0x71, 0xa8, 0xbf, 0x1a, + 0x47 + }; + const OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string("curve-name", "prime256v1"), + OSSL_PARAM_BN("priv", priv, sizeof(priv)), + OSSL_PARAM_BN("pub", pub, sizeof(pub)), + OSSL_PARAM_END + }; + + int main() + { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + EVP_PKEY *pkey = NULL; + + if (ctx == NULL + || !EVP_PKEY_key_fromdata_init(ctx) + || !EVP_PKEY_fromdata(ctx, &pkey, params)) + exit(1); + + /* Do what you want with |pkey| */ + } + +=head2 Finding out params for an unknown key type + + #include <openssl/evp.h> + + /* Program expects a key type as first argument */ + int main(int argc, char *argv[]) + { + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, argv[1], NULL); + const *OSSL_PARAM *settable_params = NULL; + + if (ctx == NULL + || (settable_params = EVP_PKEY_key_fromdata_settable(ctx)) == NULL) + exit(1); + + for (; settable_params->key != NULL; settable_params++) { + const char *datatype = NULL; + + switch (settable_params->data_type) { + case OSSL_PARAM_INTEGER: + datatype = "integer"; + break; + case OSSL_PARAM_UNSIGNED_INTEGER: + datatype = "unsigned integer"; + break; + case OSSL_PARAM_UTF8_STRING: + datatype = "printable string (utf-8 encoding expected)"; + break; + case OSSL_PARAM_UTF8_PTR: + datatype = "printable string pointer (utf-8 encoding expected)"; + break; + case OSSL_PARAM_OCTET_STRING: + datatype = "octet string"; + break; + case OSSL_PARAM_OCTET_PTR: + datatype = "octet string pointer"; + break; + } + printf("%s : %s ", settable_params->key, datatype); + if (settable_params->data_size == 0) + printf("(unlimited size)"); + else + printf("(maximum size %zu)", settable_params->data_size); + } + } + +The descriptor L<OSSL_PARAM(3)> returned by +EVP_PKEY_key_fromdata_settable() may also be used programmatically, for +example with L<OSSL_PARAM_allocate_from_text(3)>. + =head1 SEE ALSO -L<EVP_PKEY_CTX_new(3)>, L<provider(7)>, L<EVP_PKEY_gettable_params(3)> +L<EVP_PKEY_CTX_new(3)>, L<provider(7)>, L<EVP_PKEY_gettable_params(3)>, +L<OSSL_PARAM(3)> =head1 HISTORY