mirror of
https://github.com/openssl/openssl.git
synced 2024-12-15 06:01:37 +08:00
4ce64ed79d
The EVP_PKEY_fromdata man page has some code examples with various errors in them. This fixes those errors. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16973)
279 lines
8.9 KiB
Plaintext
279 lines
8.9 KiB
Plaintext
=pod
|
|
|
|
=head1 NAME
|
|
|
|
EVP_PKEY_fromdata_init, EVP_PKEY_fromdata, EVP_PKEY_fromdata_settable
|
|
- functions to create keys and key parameters from user data
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
int EVP_PKEY_fromdata_init(EVP_PKEY_CTX *ctx);
|
|
int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, int selection,
|
|
OSSL_PARAM params[]);
|
|
const OSSL_PARAM *EVP_PKEY_fromdata_settable(EVP_PKEY_CTX *ctx, int selection);
|
|
|
|
=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 primarily
|
|
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_fromdata_init() initializes a public key algorithm context
|
|
for creating a key or key parameters from user data.
|
|
|
|
EVP_PKEY_fromdata() creates the structure to store a key or key parameters,
|
|
given data from I<params>, I<selection> and a context that's been initialized
|
|
with EVP_PKEY_fromdata_init(). The result is written to I<*ppkey>.
|
|
I<selection> is described in L</Selections>.
|
|
The parameters that can be used for various types of key are as described by the
|
|
diverse "Common parameters" sections of the
|
|
L<B<EVP_PKEY-RSA>(7)|EVP_PKEY-RSA(7)/Common RSA parameters>,
|
|
L<B<EVP_PKEY-DSA>(7)|EVP_PKEY-DSA(7)/Common DSA & DH parameters>,
|
|
L<B<EVP_PKEY-DH>(7)|EVP_PKEY-DH(7)/Common DH parameters>,
|
|
L<B<EVP_PKEY-EC>(7)|EVP_PKEY-EC(7)/Common EC parameters>,
|
|
L<B<EVP_PKEY-ED448>(7)|EVP_PKEY-ED448(7)/Common X25519, X448, ED25519 and ED448 parameters>,
|
|
L<B<EVP_PKEY-X25519>(7)|EVP_PKEY-X25519(7)/Common X25519, X448, ED25519 and ED448 parameters>,
|
|
L<B<EVP_PKEY-X448>(7)|EVP_PKEY-X448(7)/Common X25519, X448, ED25519 and ED448 parameters>,
|
|
and L<B<EVP_PKEY-ED25519>(7)|EVP_PKEY-ED25519(7)/Common X25519, X448, ED25519 and ED448 parameters> pages.
|
|
|
|
=for comment the awful list of links above is made this way so we get nice
|
|
rendering as a man-page while still getting proper links in HTML
|
|
|
|
EVP_PKEY_fromdata_settable() gets a constant B<OSSL_PARAM> array that describes
|
|
the settable parameters that can be used with EVP_PKEY_fromdata().
|
|
I<selection> is described in L</Selections>.
|
|
See L<OSSL_PARAM(3)> for the use of B<OSSL_PARAM> as parameter descriptor.
|
|
|
|
=head2 Selections
|
|
|
|
The following constants can be used for I<selection>:
|
|
|
|
=over 4
|
|
|
|
=item B<EVP_PKEY_KEY_PARAMETERS>
|
|
|
|
Only key parameters will be selected.
|
|
|
|
=item B<EVP_PKEY_PUBLIC_KEY>
|
|
|
|
Only public key components will be selected. This includes optional key
|
|
parameters.
|
|
|
|
=item B<EVP_PKEY_KEYPAIR>
|
|
|
|
Any keypair components will be selected. This includes the private key,
|
|
public key and key parameters.
|
|
|
|
=back
|
|
|
|
=head1 NOTES
|
|
|
|
These functions only work with key management methods coming from a provider.
|
|
This is the mirror function to L<EVP_PKEY_todata(3)>.
|
|
|
|
=for comment We may choose to make this available for legacy methods too...
|
|
|
|
=head1 RETURN VALUES
|
|
|
|
EVP_PKEY_fromdata_init() and 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.
|
|
*/
|
|
unsigned long rsa_n = 0xbc747fc5;
|
|
unsigned long rsa_e = 0x10001;
|
|
unsigned long rsa_d = 0x7b133399;
|
|
OSSL_PARAM params[] = {
|
|
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_fromdata_init(ctx) <= 0
|
|
|| EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
|
|
exit(1);
|
|
|
|
/* Do what you want with |pkey| */
|
|
}
|
|
|
|
=head2 Creating an ECC keypair using raw key data
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/param_build.h>
|
|
#include <openssl/ec.h>
|
|
|
|
/*
|
|
* Fixed data to represent the private and public key.
|
|
*/
|
|
const unsigned char priv_data[] = {
|
|
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
|
|
};
|
|
/* UNCOMPRESSED FORMAT */
|
|
const unsigned char pub_data[] = {
|
|
POINT_CONVERSION_UNCOMPRESSED,
|
|
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
|
|
};
|
|
|
|
int main()
|
|
{
|
|
EVP_PKEY_CTX *ctx;
|
|
EVP_PKEY *pkey = NULL;
|
|
BIGNUM *priv;
|
|
OSSL_PARAM_BLD *param_bld;
|
|
OSSL_PARAM *params = NULL;
|
|
int exitcode = 0;
|
|
|
|
priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL);
|
|
|
|
param_bld = OSSL_PARAM_BLD_new();
|
|
if (priv != NULL && param_bld != NULL
|
|
&& OSSL_PARAM_BLD_push_utf8_string(param_bld, "group",
|
|
"prime256v1", 0)
|
|
&& OSSL_PARAM_BLD_push_BN(param_bld, "priv", priv)
|
|
&& OSSL_PARAM_BLD_push_octet_string(param_bld, "pub",
|
|
pub_data, sizeof(pub_data)))
|
|
params = OSSL_PARAM_BLD_to_param(param_bld);
|
|
|
|
ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL);
|
|
if (ctx == NULL
|
|
|| params == NULL
|
|
|| EVP_PKEY_fromdata_init(ctx) <= 0
|
|
|| EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
|
|
exitcode = 1;
|
|
} else {
|
|
/* Do what you want with |pkey| */
|
|
}
|
|
|
|
EVP_PKEY_free(pkey);
|
|
EVP_PKEY_CTX_free(ctx);
|
|
OSSL_PARAM_free(params);
|
|
OSSL_PARAM_BLD_free(param_bld);
|
|
BN_free(priv);
|
|
|
|
exit(exitcode);
|
|
}
|
|
|
|
=head2 Finding out params for an unknown key type
|
|
|
|
#include <openssl/evp.h>
|
|
#include <openssl/core.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)
|
|
exit(1);
|
|
settable_params = EVP_PKEY_fromdata_settable(ctx, EVP_PKEY_KEYPAIR);
|
|
if (settable_params == 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)\n");
|
|
else
|
|
printf("(maximum size %zu)\n", settable_params->data_size);
|
|
}
|
|
}
|
|
|
|
The descriptor L<OSSL_PARAM(3)> returned by
|
|
EVP_PKEY_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<OSSL_PARAM(3)>, L<EVP_PKEY_todata(3)>,
|
|
L<EVP_PKEY-RSA(7)>, L<EVP_PKEY-DSA(7)>, L<EVP_PKEY-DH(7)>, L<EVP_PKEY-EC(7)>,
|
|
L<EVP_PKEY-ED448(7)>, L<EVP_PKEY-X25519(7)>, L<EVP_PKEY-X448(7)>,
|
|
L<EVP_PKEY-ED25519(7)>
|
|
|
|
=head1 HISTORY
|
|
|
|
These functions were added in OpenSSL 3.0.
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
Copyright 2019-2021 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
|
|
in the file LICENSE in the source distribution or at
|
|
L<https://www.openssl.org/source/license.html>.
|
|
|
|
=cut
|
|
|