Add more DSA parameters support

- Implement wc_DsaParamsDecode and wc_DsaKeyToParamsDer
- Don't include NIDs without OpenSSL builds
This commit is contained in:
Juliusz Sosinowicz
2021-03-31 17:31:52 +02:00
parent c3fcb2e95f
commit c5b6d20483
3 changed files with 82 additions and 24 deletions

View File

@ -4708,6 +4708,7 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
int length;
int ret = 0;
word32 oid;
word32 maxIdx;
if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG;
@ -4715,10 +4716,11 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
if (GetInt(&key->p, input, inOutIdx, inSz) < 0 ||
GetInt(&key->q, input, inOutIdx, inSz) < 0 ||
GetInt(&key->g, input, inOutIdx, inSz) < 0 ||
GetInt(&key->y, input, inOutIdx, inSz) < 0 )
maxIdx = (word32)(*inOutIdx + length);
if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->g, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->y, input, inOutIdx, maxIdx) < 0 )
ret = ASN_DH_KEY_E;
if (ret != 0) {
@ -4750,6 +4752,27 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
return ret;
}
int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
{
int length;
word32 maxIdx;
if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG;
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
maxIdx = (word32)(*inOutIdx + length);
if (GetInt(&key->p, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->q, input, inOutIdx, maxIdx) < 0 ||
GetInt(&key->g, input, inOutIdx, maxIdx) < 0)
return ASN_DH_KEY_E;
return 0;
}
int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
@ -4828,6 +4851,7 @@ int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
static mp_int* GetDsaInt(DsaKey* key, int idx)
{
/* Other functions depend on this order. Please don't change it. */
if (idx == 0)
return &key->p;
if (idx == 1)
@ -4843,11 +4867,11 @@ static mp_int* GetDsaInt(DsaKey* key, int idx)
}
/* Release Tmp DSA resources */
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap)
static WC_INLINE void FreeTmpDsas(byte** tmps, void* heap, int ints)
{
int i;
for (i = 0; i < DSA_INTS; i++)
for (i = 0; i < ints; i++)
XFREE(tmps[i], heap, DYNAMIC_TYPE_DSA);
(void)heap;
@ -5047,11 +5071,10 @@ int wc_DsaKeyToPublicDer(DsaKey* key, byte* output, word32 inLen)
}
#endif /* !HAVE_SELFTEST && (WOLFSSL_KEY_GEN || WOLFSSL_CERT_GEN) */
/* Convert private DsaKey key to DER format, write to output (inLen),
return bytes written */
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
static int DsaKeyIntsToDer(DsaKey* key, byte* output, word32 inLen,
int ints, int includeVersion)
{
word32 seqSz, verSz, rawLen, intTotalLen = 0;
word32 seqSz = 0, verSz = 0, rawLen, intTotalLen = 0;
word32 sizes[DSA_INTS];
int i, j, outLen, ret = 0, mpSz;
@ -5059,17 +5082,14 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
byte ver[MAX_VERSION_SZ];
byte* tmps[DSA_INTS];
if (!key || !output)
if (ints > DSA_INTS)
return BAD_FUNC_ARG;
if (key->type != DSA_PRIVATE)
return BAD_FUNC_ARG;
for (i = 0; i < DSA_INTS; i++)
for (i = 0; i < ints; i++)
tmps[i] = NULL;
/* write all big ints from key to DER tmps */
for (i = 0; i < DSA_INTS; i++) {
for (i = 0; i < ints; i++) {
mp_int* keyInt = GetDsaInt(key, i);
rawLen = mp_unsigned_bin_size(keyInt) + 1;
@ -5089,35 +5109,62 @@ int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
}
if (ret != 0) {
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return ret;
}
/* make headers */
verSz = SetMyVersion(0, ver, FALSE);
if (includeVersion)
verSz = SetMyVersion(0, ver, FALSE);
seqSz = SetSequence(verSz + intTotalLen, seq);
outLen = seqSz + verSz + intTotalLen;
if (outLen > (int)inLen) {
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return BAD_FUNC_ARG;
}
/* write to output */
XMEMCPY(output, seq, seqSz);
j = seqSz;
XMEMCPY(output + j, ver, verSz);
j += verSz;
if (includeVersion) {
XMEMCPY(output + j, ver, verSz);
j += verSz;
}
for (i = 0; i < DSA_INTS; i++) {
for (i = 0; i < ints; i++) {
XMEMCPY(output + j, tmps[i], sizes[i]);
j += sizes[i];
}
FreeTmpDsas(tmps, key->heap);
FreeTmpDsas(tmps, key->heap, ints);
return outLen;
}
/* Convert private DsaKey key to DER format, write to output (inLen),
return bytes written */
int wc_DsaKeyToDer(DsaKey* key, byte* output, word32 inLen)
{
if (!key || !output)
return BAD_FUNC_ARG;
if (key->type != DSA_PRIVATE)
return BAD_FUNC_ARG;
return DsaKeyIntsToDer(key, output, inLen, DSA_INTS, 1);
}
/* Convert DsaKey parameters to DER format, write to output (inLen),
return bytes written. Version is excluded to be compatible with
OpenSSL d2i_DSAparams */
int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen)
{
if (!key || !output)
return BAD_FUNC_ARG;
return DsaKeyIntsToDer(key, output, inLen, DSA_PARAM_INTS, 0);
}
#endif /* NO_DSA */
void InitDecodedCert(DecodedCert* cert,

View File

@ -196,6 +196,7 @@ extern const WOLFSSL_ObjectInfo wolfssl_object_info[];
#define WOLFSSL_TLS_FEATURE_SUM 92
#endif
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* NIDs */
enum
{
@ -254,6 +255,7 @@ enum
NID_X9_62_prime_field = 406 /* 1.2.840.10045.1.1 */
};
#endif /* OPENSSL_EXTRA */
enum ECC_TYPES
{
@ -305,6 +307,7 @@ enum Misc_ASN {
KEYID_SIZE = WC_SHA_DIGEST_SIZE,
#endif
RSA_INTS = 8, /* RSA ints in private key */
DSA_PARAM_INTS = 3, /* DSA paramater ints */
DSA_INTS = 5, /* DSA ints in private key */
MIN_DATE_SIZE = 12,
MAX_DATE_SIZE = 32,
@ -330,7 +333,7 @@ enum Misc_ASN {
MAX_ENCODED_DIG_ASN_SZ= 9, /* enum(bit or octet) + length(4) */
MAX_ENCODED_DIG_SZ = 64 + MAX_ENCODED_DIG_ASN_SZ, /* asn header + sha512 */
MAX_RSA_INT_SZ = 517, /* RSA raw sz 4096 for bits + tag + len(4) */
MAX_DSA_INT_SZ = 261, /* DSA raw sz 2048 for bits + tag + len(4) */
MAX_DSA_INT_SZ = 389, /* DSA raw sz 3072 for bits + tag + len(4) */
MAX_NTRU_KEY_SZ = 610, /* NTRU 112 bit public key */
MAX_NTRU_ENC_SZ = 628, /* NTRU 112 bit DER public encoding */
MAX_LENGTH_SZ = 4, /* Max length size for DER encoding */

View File

@ -32,6 +32,7 @@ This library defines the interface APIs for X509 certificates.
#define WOLF_CRYPT_ASN_PUBLIC_H
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/dsa.h>
#ifdef __cplusplus
extern "C" {
@ -509,6 +510,13 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
WOLFSSL_API int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header);
#endif
#ifndef NO_DSA
/* DSA parameter DER helper functions */
WOLFSSL_API int wc_DsaParamsDecode(const byte* input, word32* inOutIdx,
DsaKey*, word32);
WOLFSSL_API int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen);
#endif
#ifdef HAVE_ECC
/* private key helpers */
WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,