mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
DOC: Add more description of EVP_PKEY_fromdata(), and examples
Fixes #11131 Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/11220)
This commit is contained in:
parent
031c9bd3f3
commit
476de2e5e5
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user