add ECC private key export for unencrypted PKCS#8

pull/1268/head
Chris Conlon 2017-12-12 10:17:00 -07:00
parent 26019b3441
commit 43ef843257
5 changed files with 96 additions and 4 deletions

1
.gitignore vendored
View File

@ -90,6 +90,7 @@ ntru-key.raw
key.der
key.pem
ecc-public-key.der
ecc-key-pkcs8.der
ecc-key.der
ecc-key.pem
certreq.der

View File

@ -33,6 +33,7 @@ CLEANFILES+= cert.der \
key.der \
key.pem \
ntru-cert.der \
ecc-key-pkcs8.der \
ntru-cert.pem \
ntru-key.raw \
othercert.der \

View File

@ -10012,6 +10012,75 @@ int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
return wc_BuildEccKeyDer(key, output, inLen, 0);
}
/* Write only private ecc key to unencrypted PKCS#8 format.
*
* If output is NULL, places required PKCS#8 buffer size in outLen and
* returns LENGTH_ONLY_E.
*
* return length on success else < 0 */
int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
{
int ret, tmpDerSz;
int algoID = 0;
word32 oidSz = 0;
word32 pkcs8Sz = 0;
const byte* curveOID = NULL;
byte* tmpDer = NULL;
if (key == NULL || outLen == NULL)
return BAD_FUNC_ARG;
/* set algoID, get curve OID */
algoID = ECDSAk;
ret = wc_ecc_get_oid(key->dp->oidSum, &curveOID, &oidSz);
if (ret < 0)
return ret;
/* temp buffer for plain DER key */
tmpDer = (byte*)XMALLOC(ECC_BUFSIZE, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (tmpDer == NULL)
return MEMORY_E;
XMEMSET(tmpDer, 0, ECC_BUFSIZE);
tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, ECC_BUFSIZE, 0);
if (tmpDerSz < 0) {
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return tmpDerSz;
}
/* get pkcs8 expected output size */
ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,
curveOID, oidSz);
if (ret != LENGTH_ONLY_E) {
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
if (output == NULL) {
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
*outLen = pkcs8Sz;
return LENGTH_ONLY_E;
} else if (*outLen < pkcs8Sz) {
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_MSG("Input buffer too small for ECC PKCS#8 key");
return BUFFER_E;
}
ret = wc_CreatePKCS8Key(output, &pkcs8Sz, tmpDer, tmpDerSz,
algoID, curveOID, oidSz);
if (ret < 0) {
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
*outLen = ret;
return ret;
}
#endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ECC */

View File

@ -6874,6 +6874,7 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out)
static const char* eccCaKeyPemFile = CERT_PREFIX "ecc-key.pem";
static const char* eccPubKeyDerFile = CERT_PREFIX "ecc-public-key.der";
static const char* eccCaKeyTempFile = CERT_PREFIX "ecc-key.der";
static const char* eccPkcs8KeyDerFile = CERT_PREFIX "ecc-key-pkcs8.der";
#endif
#if defined(WOLFSSL_CERT_GEN) || \
(defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT))
@ -11173,10 +11174,11 @@ done:
#ifdef WOLFSSL_KEY_GEN
static int ecc_test_key_gen(WC_RNG* rng, int keySize)
{
int ret = 0;
int derSz;
byte* der;
byte* pem;
int ret = 0;
int derSz;
word32 pkcs8Sz;
byte* der;
byte* pem;
ecc_key userA;
der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
@ -11230,6 +11232,23 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize)
goto done;
}
/* test export of PKCS#8 unecrypted private key */
pkcs8Sz = FOURK_BUF;
derSz = wc_EccPrivateKeyToPKCS8(&userA, der, &pkcs8Sz);
if (derSz < 0) {
ERROR_OUT(derSz, done);
}
if (derSz == 0) {
ERROR_OUT(-6516, done);
}
ret = SaveDerAndPem(der, derSz, NULL, 0, eccPkcs8KeyDerFile,
NULL, 0, -6517);
if (ret != 0) {
goto done;
}
done:
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);

View File

@ -283,6 +283,8 @@ WOLFSSL_API int wc_SetExtKeyUsage(Cert *cert, const char *value);
WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen);
WOLFSSL_API int wc_EccPrivateKeyToDer(ecc_key* key, byte* output,
word32 inLen);
WOLFSSL_API int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output,
word32* outLen);
/* public key helper */
WOLFSSL_API int wc_EccPublicKeyDecode(const byte*, word32*,