add Rsa Public Key To Der, non FIPS mode

This commit is contained in:
toddouska 2015-08-31 13:29:22 -07:00
parent cf38d1c022
commit 756cff4cb4
2 changed files with 171 additions and 140 deletions

View File

@ -4853,6 +4853,164 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz,
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN */
#if !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN))
/* Write a public RSA key to output */
static int SetRsaPublicKey(byte* output, RsaKey* key, int outLen)
{
#ifdef WOLFSSL_SMALL_STACK
byte* n = NULL;
byte* e = NULL;
byte* algo = NULL;
#else
byte n[MAX_RSA_INT_SZ];
byte e[MAX_RSA_E_SZ];
byte algo[MAX_ALGO_SZ];
#endif
byte seq[MAX_SEQ_SZ];
byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
int nSz;
int eSz;
int algoSz;
int seqSz;
int lenSz;
int idx;
int rawLen;
int leadingBit;
int err;
if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
return BAD_FUNC_ARG;
/* n */
#ifdef WOLFSSL_SMALL_STACK
n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (n == NULL)
return MEMORY_E;
#endif
leadingBit = mp_leading_bit(&key->n);
rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
n[0] = ASN_INTEGER;
nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
if (leadingBit)
n[nSz] = 0;
err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
if (err == MP_OKAY)
nSz += rawLen;
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MP_TO_E;
}
}
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
/* e */
#ifdef WOLFSSL_SMALL_STACK
e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (e == NULL) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
}
#endif
leadingBit = mp_leading_bit(&key->e);
rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
e[0] = ASN_INTEGER;
eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
if (leadingBit)
e[eSz] = 0;
err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
if (err == MP_OKAY)
eSz += rawLen;
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MP_TO_E;
}
}
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
#ifdef WOLFSSL_SMALL_STACK
algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (algo == NULL) {
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#endif
/* headers */
algoSz = SetAlgoID(RSAk, algo, keyType, 0);
seqSz = SetSequence(nSz + eSz, seq);
lenSz = SetLength(seqSz + nSz + eSz + 1, len);
len[lenSz++] = 0; /* trailing 0 */
/* write */
idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
/* 1 is for ASN_BIT_STRING */
/* check output size */
if ( (idx + algoSz + 1 + lenSz + seqSz + nSz + eSz) > outLen) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
/* algo */
XMEMCPY(output + idx, algo, algoSz);
idx += algoSz;
/* bit string */
output[idx++] = ASN_BIT_STRING;
/* length */
XMEMCPY(output + idx, len, lenSz);
idx += lenSz;
/* seq */
XMEMCPY(output + idx, seq, seqSz);
idx += seqSz;
/* n */
XMEMCPY(output + idx, n, nSz);
idx += nSz;
/* e */
XMEMCPY(output + idx, e, eSz);
idx += eSz;
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return idx;
}
#endif /* !defined(NO_RSA) && (defined(WOLFSSL_CERT_GEN) ||
defined(WOLFSSL_KEY_GEN)) */
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA)
@ -4986,6 +5144,14 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
return outLen;
}
/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
written */
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
{
return SetRsaPublicKey(output, key, inLen);
}
#endif /* WOLFSSL_KEY_GEN && !NO_RSA */
@ -5221,144 +5387,6 @@ static int SetEccPublicKey(byte* output, ecc_key* key)
#endif /* HAVE_ECC */
/* Write a public RSA key to output */
static int SetRsaPublicKey(byte* output, RsaKey* key)
{
#ifdef WOLFSSL_SMALL_STACK
byte* n = NULL;
byte* e = NULL;
byte* algo = NULL;
#else
byte n[MAX_RSA_INT_SZ];
byte e[MAX_RSA_E_SZ];
byte algo[MAX_ALGO_SZ];
#endif
byte seq[MAX_SEQ_SZ];
byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
int nSz;
int eSz;
int algoSz;
int seqSz;
int lenSz;
int idx;
int rawLen;
int leadingBit;
int err;
/* n */
#ifdef WOLFSSL_SMALL_STACK
n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (n == NULL)
return MEMORY_E;
#endif
leadingBit = mp_leading_bit(&key->n);
rawLen = mp_unsigned_bin_size(&key->n) + leadingBit;
n[0] = ASN_INTEGER;
nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
if (leadingBit)
n[nSz] = 0;
err = mp_to_unsigned_bin(&key->n, n + nSz + leadingBit);
if (err == MP_OKAY)
nSz += rawLen;
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MP_TO_E;
}
}
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
/* e */
#ifdef WOLFSSL_SMALL_STACK
e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (e == NULL) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
}
#endif
leadingBit = mp_leading_bit(&key->e);
rawLen = mp_unsigned_bin_size(&key->e) + leadingBit;
e[0] = ASN_INTEGER;
eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
if (leadingBit)
e[eSz] = 0;
err = mp_to_unsigned_bin(&key->e, e + eSz + leadingBit);
if (err == MP_OKAY)
eSz += rawLen;
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MP_TO_E;
}
}
else {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
#ifdef WOLFSSL_SMALL_STACK
algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (algo == NULL) {
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#endif
/* headers */
algoSz = SetAlgoID(RSAk, algo, keyType, 0);
seqSz = SetSequence(nSz + eSz, seq);
lenSz = SetLength(seqSz + nSz + eSz + 1, len);
len[lenSz++] = 0; /* trailing 0 */
/* write */
idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
/* 1 is for ASN_BIT_STRING */
/* algo */
XMEMCPY(output + idx, algo, algoSz);
idx += algoSz;
/* bit string */
output[idx++] = ASN_BIT_STRING;
/* length */
XMEMCPY(output + idx, len, lenSz);
idx += lenSz;
/* seq */
XMEMCPY(output + idx, seq, seqSz);
idx += seqSz;
/* n */
XMEMCPY(output + idx, n, nSz);
idx += nSz;
/* e */
XMEMCPY(output + idx, e, eSz);
idx += eSz;
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return idx;
}
static INLINE byte itob(int number)
@ -5811,7 +5839,8 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey,
if (cert->keyType == RSA_KEY) {
if (rsaKey == NULL)
return PUBLIC_KEY_E;
der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
sizeof(der->publicKey));
if (der->publicKeySz <= 0)
return PUBLIC_KEY_E;
}
@ -6225,7 +6254,8 @@ static int EncodeCertReq(Cert* cert, DerCert* der,
if (cert->keyType == RSA_KEY) {
if (rsaKey == NULL)
return PUBLIC_KEY_E;
der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey);
der->publicKeySz = SetRsaPublicKey(der->publicKey, rsaKey,
sizeof(der->publicKey));
if (der->publicKeySz <= 0)
return PUBLIC_KEY_E;
}

View File

@ -99,6 +99,7 @@ WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
const byte* e, word32 eSz, RsaKey* key);
#ifdef WOLFSSL_KEY_GEN
WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen);
#endif
#endif /* HAVE_FIPS*/
WOLFSSL_API int wc_RsaFlattenPublicKey(RsaKey*, byte*, word32*, byte*,