add EccPrivateKeyToDer()

This commit is contained in:
Chris Conlon
2017-03-30 13:56:48 -06:00
parent 14efd9735d
commit 6735dd7031
2 changed files with 58 additions and 32 deletions

View File

@ -9323,13 +9323,15 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
#ifdef WOLFSSL_KEY_GEN #ifdef WOLFSSL_KEY_GEN
/* Write a Private ecc key to DER format, length on success else < 0 */ /* build DER formatted ECC key, include optional public key if requested,
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen) * return length on success, negative on error */
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
int public)
{ {
byte curve[MAX_ALGO_SZ+2]; byte curve[MAX_ALGO_SZ+2];
byte ver[MAX_VERSION_SZ]; byte ver[MAX_VERSION_SZ];
byte seq[MAX_SEQ_SZ]; byte seq[MAX_SEQ_SZ];
byte *prv, *pub; byte *prv = NULL, *pub = NULL;
int ret, totalSz, curveSz, verSz; int ret, totalSz, curveSz, verSz;
int privHdrSz = ASN_ECC_HEADER_SZ; int privHdrSz = ASN_ECC_HEADER_SZ;
int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ; int pubHdrSz = ASN_ECC_CONTEXT_SZ + ASN_ECC_HEADER_SZ;
@ -9367,34 +9369,36 @@ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
prvidx += privSz; prvidx += privSz;
/* public */ /* public */
ret = wc_ecc_export_x963(key, NULL, &pubSz); if (public) {
if (ret != LENGTH_ONLY_E) { ret = wc_ecc_export_x963(key, NULL, &pubSz);
XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (ret != LENGTH_ONLY_E) {
return ret; XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
} return ret;
}
pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ, pub = (byte*)XMALLOC(pubSz + pubHdrSz + MAX_SEQ_SZ,
key->heap, DYNAMIC_TYPE_TMP_BUFFER); key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (pub == NULL) { if (pub == NULL) {
XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E; return MEMORY_E;
} }
pub[pubidx++] = ECC_PREFIX_1; pub[pubidx++] = ECC_PREFIX_1;
if (pubSz > 128) /* leading zero + extra size byte */ if (pubSz > 128) /* leading zero + extra size byte */
pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx); pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 2, pub+pubidx);
else /* leading zero */ else /* leading zero */
pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx); pubidx += SetLength(pubSz + ASN_ECC_CONTEXT_SZ + 1, pub+pubidx);
pub[pubidx++] = ASN_BIT_STRING; pub[pubidx++] = ASN_BIT_STRING;
pubidx += SetLength(pubSz + 1, pub+pubidx); pubidx += SetLength(pubSz + 1, pub+pubidx);
pub[pubidx++] = (byte)0; /* leading zero */ pub[pubidx++] = (byte)0; /* leading zero */
ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz); ret = wc_ecc_export_x963(key, pub + pubidx, &pubSz);
if (ret != 0) { if (ret != 0) {
XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return ret; return ret;
}
pubidx += pubSz;
} }
pubidx += pubSz;
/* make headers */ /* make headers */
verSz = SetMyVersion(1, ver, FALSE); verSz = SetMyVersion(1, ver, FALSE);
@ -9403,7 +9407,9 @@ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
totalSz = prvidx + pubidx + curveidx + verSz + seqSz; totalSz = prvidx + pubidx + curveidx + verSz + seqSz;
if (totalSz > (int)inLen) { if (totalSz > (int)inLen) {
XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(prv, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (public) {
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -9426,13 +9432,31 @@ int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
idx += curveidx; idx += curveidx;
/* public */ /* public */
XMEMCPY(output + idx, pub, pubidx); if (public) {
/* idx += pubidx; not used after write, if more data remove comment */ XMEMCPY(output + idx, pub, pubidx);
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); /* idx += pubidx; not used after write, if more data remove comment */
XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
return totalSz; return totalSz;
} }
/* Write a Private ecc key, including public to DER format,
* length on success else < 0 */
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen)
{
return wc_BuildEccKeyDer(key, output, inLen, 1);
}
/* Write only private ecc key to DER format,
* length on success else < 0 */
int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
{
return wc_BuildEccKeyDer(key, output, inLen, 0);
}
#endif /* WOLFSSL_KEY_GEN */ #endif /* WOLFSSL_KEY_GEN */
#endif /* HAVE_ECC */ #endif /* HAVE_ECC */

View File

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