NAME

EVP_PKEY_param_fromdata_init, EVP_PKEY_key_fromdata_init, EVP_PKEY_fromdata, EVP_PKEY_param_fromdata_settable, EVP_PKEY_key_fromdata_settable - functions to create key parameters and keys from user data

SYNOPSIS

 #include <openssl/evp.h>

 int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx);
 int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[]);
 const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
 const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);

DESCRIPTION

The functions described here are used to create new keys from user provided key data, such as n, e and d for a minimal RSA keypair.

These functions use an EVP_PKEY_CTX context, which should primarly be created with 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 EVP_PKEY-RSA(7), EVP_PKEY-DH(7), EVP_PKEY-ED448(7), EVP_PKEY-X448(7), and OSSL_PARAM(3) for the use of OSSL_PARAM as parameter descriptor.

NOTES

These functions only work with key management methods coming from a provider.

RETURN VALUES

EVP_PKEY_key_fromdata_init(), EVP_PKEY_param_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.

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.

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| */
 }

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| */
 }

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 OSSL_PARAM_allocate_from_text(3).

SEE ALSO

provider(7), OSSL_PARAM(3), EVP_PKEY-DSA(7), EVP_PKEY-EC(7), EVP_PKEY-X25519(7), EVP_PKEY-ED25519(7)

HISTORY

These functions were added in OpenSSL 3.0.

COPYRIGHT

Copyright 2019-2020 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 https://www.openssl.org/source/license.html.