Skip to content

Commit 98c0aea

Browse files
ColtonWilleyclaude
authored andcommitted
Fix EC public key auto-derive version check for OpenSSL 4.0.0+
The EC public key auto-derivation feature (deriving public key from private key during fromdata()) was merged to OpenSSL master on Dec 15, 2025 via PR #29054. This feature will be in OpenSSL 4.0.0, not 3.6.x as previously assumed. The original version check `> 0x30600000L` incorrectly triggered for OpenSSL 3.6.x which does not have this feature, causing test_ec_import to fail because wolfProvider was auto-deriving public keys while OpenSSL 3.6.x was not. Changes: - Update version check from `> 0x30600000L` to `>= 0x40000000L` - Update comments to reference the actual OpenSSL PR - Clean up test code structure See: openssl/openssl#29054 Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 8d939d5 commit 98c0aea

File tree

2 files changed

+59
-77
lines changed

2 files changed

+59
-77
lines changed

src/wp_ecc_kmgmt.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,9 +1150,10 @@ static int wp_ecc_import_keypair(wp_Ecc* ecc, const OSSL_PARAM params[],
11501150
ecc->key.type = ECC_PRIVATEKEY;
11511151
ecc->hasPriv = 1;
11521152

1153-
/* Auto-derive public key if not already present and curve is
1154-
* set with OpenSSL version newer than 3.6.0 */
1155-
#if OPENSSL_VERSION_NUMBER > 0x30600000L
1153+
/* Auto-derive public key if not already present and curve is set.
1154+
* OpenSSL 4.0.0+ auto-derives public keys from private keys during
1155+
* fromdata() - see https://github.com/openssl/openssl/pull/29054 */
1156+
#if OPENSSL_VERSION_NUMBER >= 0x40000000L
11561157
if (!ecc->hasPub && ecc->curveId != 0) {
11571158
int rc;
11581159

@@ -1173,7 +1174,7 @@ static int wp_ecc_import_keypair(wp_Ecc* ecc, const OSSL_PARAM params[],
11731174
* We will fail later if public key is accessed. */
11741175
}
11751176
}
1176-
#endif /* OPENSSL_VERSION_NUMBER > 0x30600000L 3.6.0+ */
1177+
#endif /* OPENSSL_VERSION_NUMBER >= 0x40000000L */
11771178
}
11781179

11791180
WOLFPROV_LEAVE(WP_LOG_COMP_ECC, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);

test/test_ecc.c

Lines changed: 54 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,6 @@ int test_ec_decode(void* data)
18281828
static int test_ec_import_priv(void)
18291829
{
18301830
int err = 0;
1831-
size_t len = 0;
18321831
EVP_PKEY_CTX *ctx1 = NULL;
18331832
EVP_PKEY_CTX *ctx2 = NULL;
18341833
EVP_PKEY* pkey1 = NULL;
@@ -1877,93 +1876,75 @@ static int test_ec_import_priv(void)
18771876
err = EVP_PKEY_fromdata(ctx2, &pkey2, EVP_PKEY_KEYPAIR, params) != 1;
18781877
}
18791878

1880-
/* For imported private only keys, public key params behavior depends on OpenSSL version */
1881-
#if OPENSSL_VERSION_NUMBER > 0x30600000L
1882-
/* OpenSSL 3.6.0+ auto-derives public keys from private keys */
1883-
if (err == 0) {
1884-
err = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_X, &x1) != 1;
1885-
}
1886-
if (err == 0) {
1887-
err = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_X, &x2) != 1;
1888-
}
1889-
if (err == 0) {
1890-
err = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_Y, &y1) != 1;
1879+
/* For imported private only keys, public key params behavior depends on
1880+
* OpenSSL version. OpenSSL 4.0.0+ auto-derives public keys from private
1881+
* keys during fromdata() - see https://github.com/openssl/openssl/pull/29054 */
1882+
#if OPENSSL_VERSION_NUMBER >= 0x40000000L
1883+
/* OpenSSL 4.0.0+ auto-derives public keys from private keys */
1884+
{
1885+
int ossl_x = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_X, &x1);
1886+
int wp_x = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_X, &x2);
1887+
if (err == 0 && ossl_x != 1) err = 1;
1888+
if (err == 0 && wp_x != 1) err = 1;
18911889
}
1892-
if (err == 0) {
1893-
err = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_Y, &y2) != 1;
1890+
{
1891+
int ossl_y = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_Y, &y1);
1892+
int wp_y = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_Y, &y2);
1893+
if (err == 0 && ossl_y != 1) err = 1;
1894+
if (err == 0 && wp_y != 1) err = 1;
18941895
}
18951896

18961897
/* Verify public key is available */
1897-
if (err == 0) {
1898-
if (EVP_PKEY_get_octet_string_param(pkey1,
1899-
OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len) != 1) {
1900-
err = 1;
1901-
}
1902-
}
1903-
if (err == 0) {
1904-
if (EVP_PKEY_get_octet_string_param(pkey2,
1905-
OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len) != 1) {
1906-
err = 1;
1907-
}
1898+
{
1899+
size_t len1 = 0, len2 = 0;
1900+
int ossl_pub = EVP_PKEY_get_octet_string_param(pkey1, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len1);
1901+
int wp_pub = EVP_PKEY_get_octet_string_param(pkey2, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len2);
1902+
if (err == 0 && ossl_pub != 1) err = 1;
1903+
if (err == 0 && wp_pub != 1) err = 1;
19081904
}
19091905

19101906
/* Verify encoded public key is available */
1911-
if (err == 0) {
1912-
if (EVP_PKEY_get_octet_string_param(pkey1,
1913-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len) != 1) {
1914-
err = 1;
1915-
}
1916-
}
1917-
if (err == 0) {
1918-
if (EVP_PKEY_get_octet_string_param(pkey2,
1919-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len) != 1) {
1920-
err = 1;
1921-
}
1907+
{
1908+
size_t len1 = 0, len2 = 0;
1909+
int ossl_enc = EVP_PKEY_get_octet_string_param(pkey1, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len1);
1910+
int wp_enc = EVP_PKEY_get_octet_string_param(pkey2, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len2);
1911+
if (err == 0 && ossl_enc != 1) err = 1;
1912+
if (err == 0 && wp_enc != 1) err = 1;
19221913
}
19231914
#else
1924-
/* OpenSSL < 3.6.0: private-only keys should not have public components */
1925-
if (err == 0) {
1926-
err = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_X, &x1) == 1;
1915+
/* OpenSSL < 4.0.0: private-only keys should not have public components */
1916+
{
1917+
int ossl_x = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_X, &x1);
1918+
int wp_x = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_X, &x2);
1919+
if (err == 0 && ossl_x == 1) err = 1;
1920+
if (err == 0 && wp_x == 1) err = 1;
19271921
}
1928-
if (err == 0) {
1929-
err = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_X, &x2) == 1;
1930-
}
1931-
if (err == 0) {
1932-
err = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_Y, &y1) == 1;
1933-
}
1934-
if (err == 0) {
1935-
err = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_Y, &y2) == 1;
1922+
{
1923+
int ossl_y = EVP_PKEY_get_bn_param(pkey1, OSSL_PKEY_PARAM_EC_PUB_Y, &y1);
1924+
int wp_y = EVP_PKEY_get_bn_param(pkey2, OSSL_PKEY_PARAM_EC_PUB_Y, &y2);
1925+
if (err == 0 && ossl_y == 1) err = 1;
1926+
if (err == 0 && wp_y == 1) err = 1;
19361927
}
19371928

19381929
/* Attempts to get the public key len should fail */
1939-
if (err == 0) {
1940-
if (EVP_PKEY_get_octet_string_param(pkey1,
1941-
OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len) != 0) {
1942-
err = 1;
1943-
}
1944-
}
1945-
if (err == 0) {
1946-
if (EVP_PKEY_get_octet_string_param(pkey2,
1947-
OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len) != 0) {
1948-
err = 1;
1949-
}
1930+
{
1931+
size_t len1 = 0, len2 = 0;
1932+
int ossl_pub = EVP_PKEY_get_octet_string_param(pkey1, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len1);
1933+
int wp_pub = EVP_PKEY_get_octet_string_param(pkey2, OSSL_PKEY_PARAM_PUB_KEY, NULL, 0, &len2);
1934+
if (err == 0 && ossl_pub != 0) err = 1;
1935+
if (err == 0 && wp_pub != 0) err = 1;
19501936
}
19511937
/* Older versions of OpenSSL will segfault on this */
19521938
#if OPENSSL_VERSION_NUMBER >= 0x30006000L
1953-
if (err == 0) {
1954-
if (EVP_PKEY_get_octet_string_param(pkey1,
1955-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len) != 0) {
1956-
err = 1;
1957-
}
1958-
}
1959-
if (err == 0) {
1960-
if (EVP_PKEY_get_octet_string_param(pkey2,
1961-
OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len) != 0) {
1962-
err = 1;
1963-
}
1939+
{
1940+
size_t len1 = 0, len2 = 0;
1941+
int ossl_enc = EVP_PKEY_get_octet_string_param(pkey1, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len1);
1942+
int wp_enc = EVP_PKEY_get_octet_string_param(pkey2, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0, &len2);
1943+
if (err == 0 && ossl_enc != 0) err = 1;
1944+
if (err == 0 && wp_enc != 0) err = 1;
19641945
}
19651946
#endif /* OPENSSL_VERSION_NUMBER >= 0x30006000L 3.0.6+ */
1966-
#endif /* OPENSSL_VERSION_NUMBER > 0x30600000L 3.6.0+ */
1947+
#endif /* OPENSSL_VERSION_NUMBER >= 0x40000000L */
19671948

19681949
EVP_PKEY_free(pkey1);
19691950
EVP_PKEY_free(pkey2);
@@ -2105,7 +2086,7 @@ int test_ec_null_init(void* data)
21052086
return err;
21062087
}
21072088

2108-
#if OPENSSL_VERSION_NUMBER > 0x30600000L
2089+
#if OPENSSL_VERSION_NUMBER >= 0x40000000L
21092090
static int test_ec_auto_derive_pub(void)
21102091
{
21112092
int err = 0;
@@ -2190,14 +2171,14 @@ static int test_ec_auto_derive_pub(void)
21902171

21912172
return err;
21922173
}
2193-
#endif /* OPENSSL_VERSION_NUMBER > 0x30600000L */
2174+
#endif /* OPENSSL_VERSION_NUMBER >= 0x40000000L */
21942175

21952176
int test_ec_auto_derive_pubkey(void* data)
21962177
{
21972178
int err = 0;
21982179
(void)data;
21992180

2200-
#if OPENSSL_VERSION_NUMBER > 0x30600000L
2181+
#if OPENSSL_VERSION_NUMBER >= 0x40000000L
22012182
err = test_ec_auto_derive_pub();
22022183
#else
22032184
err = 0;

0 commit comments

Comments
 (0)