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 ?