0

As the question states, I am unable to load public keys and create an EVP_PKEY from them.

Our applications requires ECDH key exchange between an arbitrary number of clients. As ECDH requires the public key of the other participant to be loaded in, we are currently working on implementing the encode and decode logics.

Creating an EVP_PKEY from a private key (EC) works just fine, but is of course not intended, as we cannot share private key material.

This is how we create the EC Key and encode it in DER format:

auto key = EVP_EC_gen(SN_brainpoolP256r1);

unsigned char* publicKey = nullptr;
unsigned char* privateKey = nullptr;
size_t publicLen = 0;
size_t privateLen = 0;
auto ptr = OSSL_ENCODER_CTX_new_for_pkey(
                                         key,
                                         EVP_PKEY_PUBLIC_KEY,
                                         FORMAT,
                                         nullptr,
                                         nullptr
                                         );
OSSL_ENCODER_to_data(ptr, &publicKey, &publicLen);
OPENSSL_free(ptr);
ptr = OSSL_ENCODER_CTX_new_for_pkey(
                                    key,
                                    EVP_PKEY_KEYPAIR,
                                    FORMAT,
                                    nullptr,
                                    nullptr
                                    );
OSSL_ENCODER_to_data(ptr, &privateKey, &privateLen);
OPENSSL_free(ptr);
return ECKey { publicKey, publicLen, privateKey, privateLen };

Loading the private key works just fine. However, as stated, when trying to create an EVP_PKEY from the public key material, an DECODER routines::unsupported error is presented to us.

This is how the decoding is done:

EVP_PKEY_CTX* ctx = nullptr;
EVP_PKEY* key = nullptr;

auto mineStr = mine.PrivateKey();
size_t mineLen = mine.PublicLen();
const char* structure = nullptr;
auto ptr = OSSL_DECODER_CTX_new_for_pkey(&key, FORMAT, structure, TYPE, EVP_PKEY_PUBLIC_KEY, nullptr, nullptr);
auto result = OSSL_DECODER_from_data(ptr, &theirs, &theirsLen);
auto err = ERR_get_error();
auto buff = new char[512];

When the EVP_PKEY_PUBLIC_KEY query is replaced by EVP_PKEY_KEYPAIR, and a private key is used instead, the process works just fine.

Am I supposed to use a different function ?

  • I think you've hit a bug in OpenSSL. I raised an issue here: https://github.com/openssl/openssl/issues/16977 – Matt Caswell Nov 05 '21 at 10:21
  • @MattCaswell Looking at this issue I can say it is similar, but not equal. I can create PEM and DER strings from the publicKey just fine, however importing them again seems to be broken. Might be related to the same internal bug though. – broken-bytes Nov 05 '21 at 16:02
  • @MattCaswell However, I could be in the wrong here as I am not fully sure how an exported EC key should look like. I didn't have to inspect before, as we used the low level EC methods before, where we worked on bytes, rather than an actual format – broken-bytes Nov 05 '21 at 16:13

0 Answers0