Migrating i2o_ECPublicKey and o2i_ECPublicKey to OpenSSL 3.x #23820
-
Hi, 1. From piecing together documentation from different sources, I've made out i2o_ECPublicKey to be the following:
Based on the migration guide, I believe OSSL_ENCODER_to_data() to be the appropriate replacement. 2. If I'm calling i2o_ECPublicKey on an EC private key in OpenSSL 1.1.1: BIGNUM *bn = NULL;
EVP_PKEY *pkey = ...;
eckey = EVP_PKEY_get1_EC_KEY(pkey);
bn = EC_KEY_get0_private_key(eckey);
num_bytes = i2o_ECPublicKey(eckey, NULL); Would the appropriate OpenSSL 3 function calls be: unsigned char *data = NULL;
BIGNUM *bn = NULL;
EVP_PKEY *pkey = ...;
/* context, to preserve the same functionality as OpenSSL 1.1 */
OSSL_ENCODER_CTX *octet_encoding_ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY, ?, NULL, NULL);
/* encode public key to octets, get the number of bytes */
OSSL_ENCODER_to_data(octet_encoding_ctx, &data, &datalen); 3. And likewise if I'm calling i2o_ECPublicKey with both arguments, a la OSSL_ENCODER_CTX *octet_encoding_ctx = OSSL_ENCODER_CTX_new_for_pkey(pkey, EVP_PKEY_PUBLIC_KEY, ?, NULL, NULL);
OSSL_ENCODER_to_data(octet_encoding_ctx, &data, &datalen); Thanks for any help. Also wondering if i2o_ECPublicKey encoding the key in a "octet string" makes any difference in its output, or if it's the same number of bytes no matter the format of the encoded string? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
The easiest equivalent of i2o_ECPublicKey()/o2i_ECPublicKey() is to use EVP_PKEY_get1_encoded_public_key()/EVP_PKEY_set1_encoded_public_key(). See https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get1_encoded_public_key.html |
Beta Was this translation helpful? Give feedback.
-
@t8m Thanks, I'm getting the same results for the following, pub_len and data_len are both 65. /* Generate EC key */
EVP_PKEY *pkey = NULL;
OSSL_LIB_CTX *libctx = NULL;
const char *propq = NULL;
const char *curvename = "prime256v1";
pkey = EVP_PKEY_Q_keygen(libctx, propq, "EC", curvename);
/* OpenSSL 1 Implementation */
EC_KEY *eckey = NULL;
int pub_len;
unsigned char *data = NULL;
size_t data_len;
eckey = EVP_PKEY_get1_EC_KEY(pkey);
if (!eckey) {
fprintf(stderr, "unable to get EC key");
goto cleanup;
}
pub_len = i2o_ECPublicKey(eckey, NULL);
printf("OpenSSL 1.1 Encoding Length: %d\n", pub_len);
/* OpenSSL 3 Implementation */
data_len = EVP_PKEY_get1_encoded_public_key(pkey, &data);
printf("OpenSSL 3.0 Encoding Length: %d\n", data_len); Are there any new edge cases that come with the change in function? Do i2o_ECPublicKey and EVP_PKEY_get1_encoded_public_key modify the EC_KEY* and EVP_PKEY* at all? |
Beta Was this translation helpful? Give feedback.
The easiest equivalent of i2o_ECPublicKey()/o2i_ECPublicKey() is to use EVP_PKEY_get1_encoded_public_key()/EVP_PKEY_set1_encoded_public_key().
See https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get1_encoded_public_key.html