Skip to content

Commit d03ed0b

Browse files
committed
Ed25519 support in the OpenSSL compatibility layer
wolfCrypt has full Ed25519 (keygen, sign/verify, ASN.1 import/export) and the TLS 1.3 stack already authenticates with Ed25519 certificates, but the OpenSSL-compatibility surface was missing the dispatch for several common operations, so an application driving Ed25519 purely through the OpenSSL API (EVP_PKEY_keygen, i2d_PUBKEY, X509_sign of an in-memory self-signed cert, then loading it into an SSL_CTX) could not use it. Fill those gaps, each mirroring the adjacent RSA/ECC/X25519 case: - EVP_PKEY_keygen (wolfcrypt/src/evp.c): generate an Ed25519 key and cache the PKCS#8 PrivateKeyInfo DER, like the EC/RSA cases. - wolfSSL_i2d_PublicKey / i2d_PUBKEY (wolfcrypt/src/evp_pk.c): encode an Ed25519 SubjectPublicKeyInfo. - pkcs8_encode (src/pk.c): return the already-PKCS#8 cached DER for Ed25519 (as the DH case does), so i2d_PKCS8_PRIV_KEY_INFO works. - d2iTryEd25519Key (wolfcrypt/src/evp_pk.c): derive the public key after decoding a PKCS#8 private key (v1 carries only the seed) so the decoded EVP_PKEY is complete. - d2i_AutoPrivateKey (wolfcrypt/src/evp_pk.c): detect Ed25519 by its algorithm id and decode the full PKCS#8 (its inner key is an OCTET STRING, which the RSA/ECC sequence-counting heuristic cannot classify). - X509_sign / X509_resign_cert / sigTypeFromPKEY / wolfssl_x509_make_der (src/x509.c): sign a certificate with an Ed25519 key (NULL digest), resolving the signature OID as ED25519k and building the SubjectPublicKey from an ed25519_key. - X509_set_pubkey / X509_get_pubkey (src/x509.c): set and retrieve an Ed25519 public key, keeping the X.509 public-key buffer as the raw key bytes to match how DecodeCert/StoreKey store it. tests/api.c gains test_wolfSSL_EVP_PKEY_ED25519_openssl, which exercises the whole sequence (keygen, i2d_PUBKEY, i2d_PKCS8_PRIV_KEY_INFO, d2i_AutoPrivateKey, self-signed X509_sign with a NULL digest, X509_get_pubkey round-trip, and loading the key+cert into an SSL_CTX). Requires --enable-ed25519 --enable-certgen. Signed-off-by: Antonio Quartulli <antonio@mandelbit.com>
1 parent 5929586 commit d03ed0b

5 files changed

Lines changed: 371 additions & 1 deletion

File tree

src/pk.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7373,6 +7373,22 @@ int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
73737373
curveOid = NULL;
73747374
oidSz = 0;
73757375
}
7376+
#endif
7377+
#if defined(HAVE_ED25519)
7378+
else if (pkey->type == WC_EVP_PKEY_ED25519) {
7379+
/* The cached DER is already a PKCS#8 PrivateKeyInfo (set when the
7380+
* key was generated or decoded), so return it as-is (same as the
7381+
* DH special case above). */
7382+
if (keySz == NULL)
7383+
return BAD_FUNC_ARG;
7384+
7385+
*keySz = (word32)pkey->pkey_sz;
7386+
if (key == NULL)
7387+
return LENGTH_ONLY_E;
7388+
7389+
XMEMCPY(key, pkey->pkey.ptr, (size_t)pkey->pkey_sz);
7390+
return pkey->pkey_sz;
7391+
}
73767392
#endif
73777393
else {
73787394
ret = NOT_COMPILED_IN;

src/x509.c

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6481,6 +6481,11 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
64816481
x509->pubKeyOID == ML_DSA_87k) {
64826482
key->type = WC_EVP_PKEY_DILITHIUM;
64836483
}
6484+
#endif
6485+
#if defined(HAVE_ED25519)
6486+
else if (x509->pubKeyOID == ED25519k) {
6487+
key->type = WC_EVP_PKEY_ED25519;
6488+
}
64846489
#endif
64856490
else {
64866491
key->type = WC_EVP_PKEY_EC;
@@ -6572,6 +6577,37 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
65726577
}
65736578
}
65746579
#endif /* NO_DSA */
6580+
6581+
/* decode Ed25519 key */
6582+
#if defined(HAVE_ED25519)
6583+
if (key->type == WC_EVP_PKEY_ED25519) {
6584+
key->ed25519 = (ed25519_key*)XMALLOC(sizeof(ed25519_key),
6585+
x509->heap, DYNAMIC_TYPE_ED25519);
6586+
if (key->ed25519 == NULL) {
6587+
wolfSSL_EVP_PKEY_free(key);
6588+
return NULL;
6589+
}
6590+
if (wc_ed25519_init_ex(key->ed25519, x509->heap,
6591+
INVALID_DEVID) != 0) {
6592+
XFREE(key->ed25519, x509->heap, DYNAMIC_TYPE_ED25519);
6593+
key->ed25519 = NULL;
6594+
wolfSSL_EVP_PKEY_free(key);
6595+
return NULL;
6596+
}
6597+
key->ownEd25519 = 1;
6598+
6599+
/* The X.509 public key buffer holds the raw Ed25519 key
6600+
* (CopyDecodedToX509 / StoreKey store the BIT STRING
6601+
* contents), so import it directly. */
6602+
if (wc_ed25519_import_public(
6603+
(const unsigned char*)key->pkey.ptr,
6604+
(word32)key->pkey_sz, key->ed25519) != 0) {
6605+
WOLFSSL_MSG("wc_ed25519_import_public failed");
6606+
wolfSSL_EVP_PKEY_free(key);
6607+
return NULL;
6608+
}
6609+
}
6610+
#endif /* HAVE_ED25519 */
65756611
}
65766612
}
65776613
return key;
@@ -12225,6 +12261,14 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1222512261
int hashType;
1222612262
int sigType = WOLFSSL_FAILURE;
1222712263

12264+
#if defined(HAVE_ED25519)
12265+
/* Ed25519 carries its own hash, so md is unused (and may be NULL).
12266+
* Resolve it before touching md. */
12267+
if (pkey->type == WC_EVP_PKEY_ED25519) {
12268+
return ED25519k;
12269+
}
12270+
#endif
12271+
1222812272
/* Convert key type and hash algorithm to a signature algorithm */
1222912273
if (wolfSSL_EVP_get_hashinfo(md, &hashType, NULL)
1223012274
== WC_NO_ERR_TRACE(WOLFSSL_FAILURE))
@@ -12337,6 +12381,9 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1233712381
#ifndef NO_DSA
1233812382
DsaKey* dsa = NULL;
1233912383
#endif
12384+
#if defined(HAVE_ED25519)
12385+
ed25519_key* ed25519 = NULL;
12386+
#endif
1234012387
#if defined(HAVE_FALCON)
1234112388
falcon_key* falcon = NULL;
1234212389
#endif
@@ -12472,6 +12519,36 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1247212519
key = (void*)dsa;
1247312520
}
1247412521
#endif
12522+
#if defined(HAVE_ED25519)
12523+
if (x509->pubKeyOID == ED25519k) {
12524+
ed25519 = (ed25519_key*)XMALLOC(sizeof(ed25519_key), NULL,
12525+
DYNAMIC_TYPE_ED25519);
12526+
if (ed25519 == NULL) {
12527+
WOLFSSL_MSG("Failed to allocate memory for ed25519_key");
12528+
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12529+
return WOLFSSL_FAILURE;
12530+
}
12531+
12532+
type = ED25519_TYPE;
12533+
ret = wc_ed25519_init(ed25519);
12534+
if (ret != 0) {
12535+
XFREE(ed25519, NULL, DYNAMIC_TYPE_ED25519);
12536+
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12537+
return ret;
12538+
}
12539+
/* The X.509 public key buffer holds the raw Ed25519 key. */
12540+
ret = wc_ed25519_import_public(x509->pubKey.buffer,
12541+
x509->pubKey.length, ed25519);
12542+
if (ret != 0) {
12543+
WOLFSSL_ERROR_VERBOSE(ret);
12544+
wc_ed25519_free(ed25519);
12545+
XFREE(ed25519, NULL, DYNAMIC_TYPE_ED25519);
12546+
XFREE(cert, NULL, DYNAMIC_TYPE_CERT);
12547+
return ret;
12548+
}
12549+
key = (void*)ed25519;
12550+
}
12551+
#endif
1247512552
#if defined(HAVE_FALCON)
1247612553
if ((x509->pubKeyOID == FALCON_LEVEL1k) ||
1247712554
(x509->pubKeyOID == FALCON_LEVEL5k)) {
@@ -12723,6 +12800,12 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1272312800
XFREE(ecc, NULL, DYNAMIC_TYPE_ECC);
1272412801
}
1272512802
#endif
12803+
#if defined(HAVE_ED25519)
12804+
if (x509->pubKeyOID == ED25519k) {
12805+
wc_ed25519_free(ed25519);
12806+
XFREE(ed25519, NULL, DYNAMIC_TYPE_ED25519);
12807+
}
12808+
#endif
1272612809
#ifndef NO_DSA
1272712810
if (x509->pubKeyOID == DSAk) {
1272812811
wc_FreeDsaKey(dsa);
@@ -12807,6 +12890,12 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509)
1280712890
key = pkey->ecc->internal;
1280812891
}
1280912892
#endif
12893+
#if defined(HAVE_ED25519)
12894+
if (pkey->type == WC_EVP_PKEY_ED25519) {
12895+
type = ED25519_TYPE;
12896+
key = pkey->ed25519;
12897+
}
12898+
#endif
1281012899

1281112900
/* Sign the certificate (request) body. */
1281212901
ret = wc_InitRng(&rng);
@@ -12895,7 +12984,14 @@ int wolfSSL_X509_sign(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey,
1289512984

1289612985
WOLFSSL_ENTER("wolfSSL_X509_sign");
1289712986

12898-
if (x509 == NULL || pkey == NULL || md == NULL) {
12987+
/* Ed25519 signs with a NULL digest (the key has a built-in hash); every
12988+
* other key type requires an explicit md. */
12989+
if (x509 == NULL || pkey == NULL ||
12990+
(md == NULL
12991+
#if defined(HAVE_ED25519)
12992+
&& pkey->type != WC_EVP_PKEY_ED25519
12993+
#endif
12994+
)) {
1289912995
ret = WOLFSSL_FAILURE;
1290012996
goto out;
1290112997
}
@@ -16408,6 +16504,30 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
1640816504
cert->pubKeyOID = ECDSAk;
1640916505
}
1641016506
break;
16507+
#endif
16508+
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
16509+
case WC_EVP_PKEY_ED25519:
16510+
{
16511+
word32 rawLen = ED25519_PUB_KEY_SIZE;
16512+
16513+
if (pkey->ed25519 == NULL)
16514+
return WOLFSSL_FAILURE;
16515+
16516+
/* Store the RAW public key: wolfSSL keeps an X.509 Ed25519
16517+
* public key as the bare key bytes (see StoreKey /
16518+
* CopyDecodedToX509), not a SubjectPublicKeyInfo. */
16519+
p = (byte*)XMALLOC(rawLen, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16520+
if (p == NULL)
16521+
return WOLFSSL_FAILURE;
16522+
16523+
if (wc_ed25519_export_public(pkey->ed25519, p, &rawLen) != 0) {
16524+
XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
16525+
return WOLFSSL_FAILURE;
16526+
}
16527+
derSz = (int)rawLen;
16528+
cert->pubKeyOID = ED25519k;
16529+
}
16530+
break;
1641116531
#endif
1641216532
default:
1641316533
return WOLFSSL_FAILURE;

tests/api.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10074,6 +10074,117 @@ static int test_wolfSSL_PKCS8(void)
1007410074
return EXPECT_RESULT();
1007510075
}
1007610076

10077+
/* Exercise Ed25519 through the OpenSSL-compatibility EVP/X509 surface the
10078+
* way an application does: generate a key, serialise the public
10079+
* (SubjectPublicKeyInfo) and private (PKCS#8) parts, build and sign an
10080+
* in-memory self-signed certificate with a NULL digest, read the public key
10081+
* back out, and load the key + cert into an SSL_CTX. */
10082+
static int test_wolfSSL_EVP_PKEY_ED25519_openssl(void)
10083+
{
10084+
EXPECT_DECLS;
10085+
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED25519) && \
10086+
defined(HAVE_ED25519_KEY_EXPORT) && defined(HAVE_ED25519_KEY_IMPORT) && \
10087+
defined(WOLFSSL_CERT_GEN) && !defined(NO_CERTS)
10088+
WOLFSSL_EVP_PKEY_CTX* ctx = NULL;
10089+
WOLFSSL_EVP_PKEY* pkey = NULL;
10090+
WOLFSSL_EVP_PKEY* certPub = NULL;
10091+
WOLFSSL_X509* x509 = NULL;
10092+
WOLFSSL_X509_NAME* name = NULL;
10093+
WOLFSSL_ASN1_TIME* notBefore = NULL;
10094+
WOLFSSL_ASN1_TIME* notAfter = NULL;
10095+
unsigned char* spki = NULL;
10096+
unsigned char* spki2 = NULL;
10097+
int spkiSz = 0;
10098+
int spki2Sz = 0;
10099+
time_t t = 0;
10100+
10101+
/* (1) Generate an Ed25519 key purely through the EVP API. */
10102+
ExpectNotNull(ctx = wolfSSL_EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL));
10103+
ExpectIntEQ(wolfSSL_EVP_PKEY_keygen_init(ctx), WOLFSSL_SUCCESS);
10104+
ExpectIntEQ(wolfSSL_EVP_PKEY_keygen(ctx, &pkey), WOLFSSL_SUCCESS);
10105+
ExpectNotNull(pkey);
10106+
10107+
/* (2) Encode the public key as SubjectPublicKeyInfo. */
10108+
ExpectIntGT((spkiSz = wolfSSL_i2d_PUBKEY(pkey, &spki)), 0);
10109+
10110+
/* (3) Encode the private key as PKCS#8 PrivateKeyInfo and (7) decode it
10111+
* back. These compat helpers (EVP_PKEY2PKCS8, i2d_PKCS8_PKEY,
10112+
* d2i_AutoPrivateKey) are only built with OPENSSL_ALL. */
10113+
#if defined(OPENSSL_ALL) && !defined(NO_AES)
10114+
{
10115+
WOLFSSL_PKCS8_PRIV_KEY_INFO* p8 = NULL;
10116+
WOLFSSL_EVP_PKEY* decPriv = NULL;
10117+
unsigned char* p8der = NULL;
10118+
const unsigned char* tmp = NULL;
10119+
int p8Sz = 0;
10120+
10121+
ExpectNotNull(p8 = wolfSSL_EVP_PKEY2PKCS8(pkey));
10122+
ExpectIntGT((p8Sz = wolfSSL_i2d_PKCS8_PKEY(p8, &p8der)), 0);
10123+
tmp = p8der;
10124+
ExpectNotNull(decPriv = wolfSSL_d2i_AutoPrivateKey(NULL, &tmp, p8Sz));
10125+
10126+
XFREE(p8der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
10127+
wolfSSL_EVP_PKEY_free(decPriv);
10128+
wolfSSL_EVP_PKEY_free((WOLFSSL_EVP_PKEY*)p8);
10129+
}
10130+
#endif
10131+
10132+
/* (4)(5) Build an in-memory self-signed cert; Ed25519 signs with a NULL
10133+
* digest (it carries its own hash). */
10134+
ExpectNotNull(x509 = wolfSSL_X509_new());
10135+
ExpectIntEQ(wolfSSL_X509_set_version(x509, 2), WOLFSSL_SUCCESS);
10136+
ExpectNotNull(name = wolfSSL_X509_NAME_new());
10137+
ExpectIntEQ(wolfSSL_X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
10138+
(const byte*)"ed25519 test", -1, -1, 0), WOLFSSL_SUCCESS);
10139+
ExpectIntEQ(wolfSSL_X509_set_subject_name(x509, name), WOLFSSL_SUCCESS);
10140+
ExpectIntEQ(wolfSSL_X509_set_issuer_name(x509, name), WOLFSSL_SUCCESS);
10141+
ExpectIntEQ(wolfSSL_X509_set_pubkey(x509, pkey), WOLFSSL_SUCCESS);
10142+
t = XTIME(NULL);
10143+
ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
10144+
ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
10145+
ExpectTrue(wolfSSL_X509_set_notBefore(x509, notBefore));
10146+
ExpectTrue(wolfSSL_X509_set_notAfter(x509, notAfter));
10147+
ExpectIntGT(wolfSSL_X509_sign(x509, pkey, NULL), 0);
10148+
10149+
/* (8) The certificate's public key round-trips to the same SPKI. */
10150+
ExpectNotNull(certPub = wolfSSL_X509_get_pubkey(x509));
10151+
ExpectIntGT((spki2Sz = wolfSSL_i2d_PUBKEY(certPub, &spki2)), 0);
10152+
ExpectIntEQ(spki2Sz, spkiSz);
10153+
if ((spki != NULL) && (spki2 != NULL) && (spkiSz == spki2Sz)) {
10154+
ExpectIntEQ(XMEMCMP(spki, spki2, (size_t)spkiSz), 0);
10155+
}
10156+
10157+
/* (6) Load the generated key and cert into an SSL_CTX. */
10158+
#if !defined(NO_TLS) && \
10159+
(!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER))
10160+
{
10161+
WOLFSSL_CTX* sslCtx = NULL;
10162+
#ifndef NO_WOLFSSL_SERVER
10163+
ExpectNotNull(sslCtx = wolfSSL_CTX_new(wolfSSLv23_server_method()));
10164+
#else
10165+
ExpectNotNull(sslCtx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
10166+
#endif
10167+
ExpectIntEQ(wolfSSL_CTX_use_certificate(sslCtx, x509),
10168+
WOLFSSL_SUCCESS);
10169+
ExpectIntEQ(wolfSSL_CTX_use_PrivateKey(sslCtx, pkey),
10170+
WOLFSSL_SUCCESS);
10171+
wolfSSL_CTX_free(sslCtx);
10172+
}
10173+
#endif
10174+
10175+
XFREE(spki, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
10176+
XFREE(spki2, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
10177+
wolfSSL_ASN1_TIME_free(notBefore);
10178+
wolfSSL_ASN1_TIME_free(notAfter);
10179+
wolfSSL_X509_NAME_free(name);
10180+
wolfSSL_X509_free(x509);
10181+
wolfSSL_EVP_PKEY_free(certPub);
10182+
wolfSSL_EVP_PKEY_free(pkey);
10183+
wolfSSL_EVP_PKEY_CTX_free(ctx);
10184+
#endif
10185+
return EXPECT_RESULT();
10186+
}
10187+
1007710188
static int test_wolfSSL_PKCS8_ED25519(void)
1007810189
{
1007910190
EXPECT_DECLS;
@@ -35068,6 +35179,7 @@ TEST_CASE testCases[] = {
3506835179
/* PKCS8 testing */
3506935180
TEST_DECL(test_wolfSSL_no_password_cb),
3507035181
TEST_DECL(test_wolfSSL_PKCS8),
35182+
TEST_DECL(test_wolfSSL_EVP_PKEY_ED25519_openssl),
3507135183
TEST_DECL(test_wolfSSL_PKCS8_ED25519),
3507235184
TEST_DECL(test_wolfSSL_PKCS8_ED448),
3507335185

wolfcrypt/src/evp.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3820,6 +3820,9 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
38203820
#endif
38213821
#ifdef HAVE_CURVE448
38223822
ctx->pkey->type != WC_EVP_PKEY_X448 &&
3823+
#endif
3824+
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
3825+
ctx->pkey->type != WC_EVP_PKEY_ED25519 &&
38233826
#endif
38243827
ctx->pkey->type != WC_EVP_PKEY_DH)) {
38253828
WOLFSSL_MSG("Key not set or key type not supported");
@@ -3932,6 +3935,52 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
39323935
ret = WOLFSSL_SUCCESS;
39333936
}
39343937
break;
3938+
#endif
3939+
#if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_EXPORT)
3940+
case WC_EVP_PKEY_ED25519:
3941+
if (pkey->ed25519 == NULL) {
3942+
pkey->ed25519 = (ed25519_key*)XMALLOC(sizeof(ed25519_key),
3943+
pkey->heap, DYNAMIC_TYPE_ED25519);
3944+
if (pkey->ed25519 == NULL) {
3945+
ret = MEMORY_E;
3946+
break;
3947+
}
3948+
if (wc_ed25519_init_ex(pkey->ed25519, pkey->heap,
3949+
INVALID_DEVID) != 0) {
3950+
XFREE(pkey->ed25519, pkey->heap, DYNAMIC_TYPE_ED25519);
3951+
pkey->ed25519 = NULL;
3952+
break;
3953+
}
3954+
pkey->ownEd25519 = 1;
3955+
}
3956+
/* Reuse the RNG already initialized on the EVP_PKEY. */
3957+
if (wc_ed25519_make_key(&pkey->rng, ED25519_KEY_SIZE,
3958+
pkey->ed25519) == 0) {
3959+
/* Cache the PKCS#8 PrivateKeyInfo DER so the EVP/SSL paths
3960+
* (use_PrivateKey, EVP_PKEY2PKCS8) can load and serialize the
3961+
* key, mirroring the state the decode path produces. */
3962+
int edDerSz = wc_Ed25519PrivateKeyToDer(pkey->ed25519, NULL, 0);
3963+
if (edDerSz > 0) {
3964+
byte* edDer = (byte*)XMALLOC((size_t)edDerSz, pkey->heap,
3965+
DYNAMIC_TYPE_OPENSSL);
3966+
if (edDer != NULL) {
3967+
if (wc_Ed25519PrivateKeyToDer(pkey->ed25519, edDer,
3968+
(word32)edDerSz) == edDerSz) {
3969+
if (pkey->pkey.ptr != NULL) {
3970+
XFREE(pkey->pkey.ptr, pkey->heap,
3971+
DYNAMIC_TYPE_OPENSSL);
3972+
}
3973+
pkey->pkey.ptr = (char*)edDer;
3974+
pkey->pkey_sz = edDerSz;
3975+
ret = WOLFSSL_SUCCESS;
3976+
}
3977+
else {
3978+
XFREE(edDer, pkey->heap, DYNAMIC_TYPE_OPENSSL);
3979+
}
3980+
}
3981+
}
3982+
}
3983+
break;
39353984
#endif
39363985
default:
39373986
break;

0 commit comments

Comments
 (0)