wolfSSL_EVP_PKEY_set1_EC_KEY should generate PKCS8 internal DER buffer

This PKCS8 buffer should include both the private and the public parts of the key.
This commit is contained in:
Juliusz Sosinowicz
2020-11-24 13:24:29 +01:00
parent cd4affddac
commit 23a4d64caf
5 changed files with 78 additions and 50 deletions

View File

@@ -7927,7 +7927,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
} }
break; break;
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */
#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)
#ifndef NO_DSA #ifndef NO_DSA
case EVP_PKEY_DSA: case EVP_PKEY_DSA:
local->ownDsa = 1; local->ownDsa = 1;
@@ -7962,7 +7962,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
break; break;
#endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */ #endif /* !HAVE_FIPS || HAVE_FIPS_VERSION > 2 */
#endif /* HAVE_DH */ #endif /* HAVE_DH */
#endif /* WOLFSSL_QT || OPENSSL_ALL */ #endif /* WOLFSSL_QT || OPENSSL_ALL || WOLFSSL_OPENSSH */
default: default:
WOLFSSL_MSG("Unsupported key type"); WOLFSSL_MSG("Unsupported key type");
wolfSSL_EVP_PKEY_free(local); wolfSSL_EVP_PKEY_free(local);
@@ -36868,13 +36868,12 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
void *out, size_t *outlen)) void *out, size_t *outlen))
{ {
word32 len; word32 len;
(void)KDF;
(void)KDF;
ecc_key* key; ecc_key* key;
#ifdef ECC_TIMING_RESISTANT #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
&& !defined(HAVE_FIPS)
int setGlobalRNG = 0; int setGlobalRNG = 0;
#endif #endif
(void)KDF;
WOLFSSL_ENTER("wolfSSL_ECDH_compute_key"); WOLFSSL_ENTER("wolfSSL_ECDH_compute_key");
@@ -36898,7 +36897,8 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
len = (word32)outlen; len = (word32)outlen;
key = (ecc_key*)ecdh->internal; key = (ecc_key*)ecdh->internal;
#ifdef ECC_TIMING_RESISTANT #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
&& !defined(HAVE_FIPS)
if (key->rng == NULL) { if (key->rng == NULL) {
if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) { if (initGlobalRNG == 0 && wolfSSL_RAND_Init() != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("No RNG to use"); WOLFSSL_MSG("No RNG to use");
@@ -36916,7 +36916,8 @@ int wolfSSL_ECDH_compute_key(void *out, size_t outlen,
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
} }
#ifdef ECC_TIMING_RESISTANT #if defined(ECC_TIMING_RESISTANT) && !defined(HAVE_SELFTEST) \
&& !defined(HAVE_FIPS)
if (setGlobalRNG) if (setGlobalRNG)
key->rng = NULL; key->rng = NULL;
#endif #endif
@@ -51813,35 +51814,11 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
if (cert == NULL || pkey == NULL) if (cert == NULL || pkey == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
if (pkey->type == EVP_PKEY_RSA) if (pkey->type == EVP_PKEY_RSA
cert->pubKeyOID = RSAk; #ifndef NO_DSA
else if (pkey->type == EVP_PKEY_EC) || pkey->type == EVP_PKEY_DSA
cert->pubKeyOID = ECDSAk; #endif /* !NO_DSA */
else if (pkey->type == EVP_PKEY_DSA) ) {
cert->pubKeyOID = DSAk;
else
return WOLFSSL_FAILURE;
#ifdef OPENSSL_EXTRA
#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \
!defined(NO_RSA) && !defined(HAVE_USER_RSA)
if (pkey->type == EVP_PKEY_RSA) {
int pLen;
/* Public and private key formats differ. Make sure to put in the
* public key format in the cert. */
if ((pLen = wolfSSL_i2d_RSAPublicKey(pkey->rsa, (const byte**)&p)) <= 0) {
WOLFSSL_MSG("wolfSSL_i2d_RSAPublicKey error");
return WOLFSSL_FAILURE;
}
if (cert->pubKey.buffer != NULL)
XFREE(cert->pubKey.buffer, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
cert->pubKey.buffer = p;
cert->pubKey.length = pLen;
}
else
#endif
#endif /* OPENSSL_EXTRA */
{
p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY); p = (byte*)XMALLOC(pkey->pkey_sz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (p == NULL) if (p == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
@@ -51851,7 +51828,42 @@ int wolfSSL_X509_set_pubkey(WOLFSSL_X509 *cert, WOLFSSL_EVP_PKEY *pkey)
cert->pubKey.buffer = p; cert->pubKey.buffer = p;
XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz); XMEMCPY(cert->pubKey.buffer, pkey->pkey.ptr, pkey->pkey_sz);
cert->pubKey.length = pkey->pkey_sz; cert->pubKey.length = pkey->pkey_sz;
#ifndef NO_DSA
if (pkey->type == EVP_PKEY_DSA)
cert->pubKeyOID = DSAk;
else
#endif /* !NO_DSA */
cert->pubKeyOID = RSAk;
} }
#ifdef HAVE_ECC
else if (pkey->type == EVP_PKEY_EC) {
/* Generate since pkey->pkey.ptr may contain private key */
ecc_key* ecc;
int derSz;
if (pkey->ecc == NULL || pkey->ecc->internal == NULL)
return WOLFSSL_FAILURE;
ecc = (ecc_key*)pkey->ecc->internal;
derSz = wc_EccPublicKeyDerSize(ecc, 1);
if (derSz <= 0)
return WOLFSSL_FAILURE;
p = (byte*)XMALLOC(derSz, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (p == NULL)
return WOLFSSL_FAILURE;
if ((derSz = wc_EccPublicKeyToDer(ecc, p, derSz, 1)) <= 0) {
XFREE(p, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
return WOLFSSL_FAILURE;
}
cert->pubKey.buffer = p;
cert->pubKey.length = derSz;
cert->pubKeyOID = ECDSAk;
}
#endif /* HAVE_ECC */
else
return WOLFSSL_FAILURE;
return WOLFSSL_SUCCESS; return WOLFSSL_SUCCESS;
} }

View File

@@ -16598,13 +16598,15 @@ int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
} }
#ifdef HAVE_PKCS8 #ifdef HAVE_PKCS8
/* Write only private ecc key to unencrypted PKCS#8 format. /* Write only private ecc key or both private and public parts to unencrypted
* PKCS#8 format.
* *
* If output is NULL, places required PKCS#8 buffer size in outLen and * If output is NULL, places required PKCS#8 buffer size in outLen and
* returns LENGTH_ONLY_E. * returns LENGTH_ONLY_E.
* *
* return length on success else < 0 */ * return length on success else < 0 */
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen) static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
int includePublic)
{ {
int ret, tmpDerSz; int ret, tmpDerSz;
int algoID = 0; int algoID = 0;
@@ -16617,7 +16619,7 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
byte* tmpDer = NULL; byte* tmpDer = NULL;
#endif #endif
if (key == NULL || outLen == NULL) if (key == NULL || key->dp == NULL || outLen == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* set algoID, get curve OID */ /* set algoID, get curve OID */
@@ -16634,7 +16636,7 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
#endif #endif
XMEMSET(tmpDer, 0, ECC_BUFSIZE); XMEMSET(tmpDer, 0, ECC_BUFSIZE);
tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0); tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, includePublic);
if (tmpDerSz < 0) { if (tmpDerSz < 0) {
#ifndef WOLFSSL_NO_MALLOC #ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
@@ -16684,6 +16686,20 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
*outLen = ret; *outLen = ret;
return ret; return ret;
} }
/* Write only private ecc key to unencrypted PKCS#8 format.
*
* return length on success else < 0 */
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
{
return eccToPKCS8(key, output, outLen, 0);
}
int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
word32* outLen)
{
return eccToPKCS8(key, output, outLen, 1);
}
#endif /* HAVE_PKCS8 */ #endif /* HAVE_PKCS8 */
#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */ #endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */

View File

@@ -4072,7 +4072,7 @@ int wc_ecc_shared_secret_ex(ecc_key* private_key, ecc_point* point,
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG == NULL) if (tmpRNG == NULL)
return WOLFSSL_FAILURE; return MEMORY_E;
#endif #endif
if ((err = wc_InitRng(tmpRNG)) != MP_OKAY) { if ((err = wc_InitRng(tmpRNG)) != MP_OKAY) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK

View File

@@ -6178,20 +6178,18 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key)
/* try and populate public pkey_sz and pkey.ptr */ /* try and populate public pkey_sz and pkey.ptr */
static void ECC_populate_EVP_PKEY(EVP_PKEY* pkey, ecc_key* ecc) static void ECC_populate_EVP_PKEY(EVP_PKEY* pkey, ecc_key* ecc)
{ {
int ret; word32 derSz = 0;
if (!pkey || !ecc) if (!pkey || !ecc)
return; return;
if ((ret = wc_EccPublicKeyDerSize(ecc, 1)) > 0) { if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) {
int derSz = ret; byte* derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
char* derBuf = (char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf) { if (derBuf) {
ret = wc_EccPublicKeyToDer(ecc, (byte*)derBuf, derSz, 1); if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) >= 0) {
if (ret >= 0) {
if (pkey->pkey.ptr) { if (pkey->pkey.ptr) {
XFREE(pkey->pkey.ptr, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(pkey->pkey.ptr, NULL, DYNAMIC_TYPE_OPENSSL);
} }
pkey->pkey_sz = ret; pkey->pkey_sz = (int)derSz;
pkey->pkey.ptr = derBuf; pkey->pkey.ptr = (char*)derBuf;
} }
else { /* failure - okay to ignore */ else { /* failure - okay to ignore */
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);

View File

@@ -517,6 +517,8 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
word32 inLen); word32 inLen);
WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output,
word32* outLen); word32* outLen);
WOLFSSL_API int wc_EccKeyToPKCS8(ecc_key* key, byte* output,
word32* outLen);
/* public key helper */ /* public key helper */
WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*, WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*,