forked from wolfSSL/wolfssl
Fixes for key size detection when using PK callbacks (HSM) and no private key has been loaded (affects HAVE_PK_CALLBACKS
on server side only when no dummy private key is loaded). Fix for possible leak during ECC min key size failure with small stack. Added new API wc_RsaPublicKeyDecode_ex
for parsing an RSA public key for the modulus and exponent. Changed wolfSSL_CTX_SetTmpEC_DHE_Sz
to support a size == 0
for using the long-term private key's size. Changed ECDHE_SIZE
so it can be overridden and build-time. Added tests for wolfSSL_CTX_SetTmpEC_DHE_Sz
and wolfSSL_SetTmpEC_DHE_Sz
.
This commit is contained in:
@ -1433,6 +1433,17 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* Use ECDHE key size that matches long term key.
|
||||
* Zero means use ctx->privateKeySz.
|
||||
* Default ECDHE_SIZE is 32 bytes
|
||||
*/
|
||||
if (wolfSSL_CTX_SetTmpEC_DHE_Sz(ctx, 0) != WOLFSSL_SUCCESS){
|
||||
err_sys_ex(runWithErrors, "Error setting ECDHE size");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (useAnon) {
|
||||
#ifdef HAVE_ANON
|
||||
wolfSSL_CTX_allow_anon_cipher(ctx);
|
||||
|
114
src/ssl.c
114
src/ssl.c
@ -4468,6 +4468,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
int resetSuites = 0;
|
||||
void* heap = wolfSSL_CTX_GetHeap(ctx, ssl);
|
||||
int devId = wolfSSL_CTX_GetDevId(ctx, ssl);
|
||||
word32 idx;
|
||||
int keySz = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
EncryptedInfo* info = NULL;
|
||||
#else
|
||||
@ -4476,6 +4478,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
|
||||
(void)rsaKey;
|
||||
(void)devId;
|
||||
(void)idx;
|
||||
(void)keySz;
|
||||
|
||||
if (used)
|
||||
*used = sz; /* used bytes default to sz, PEM chain may shorten*/
|
||||
@ -4676,7 +4680,6 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
#ifndef NO_RSA
|
||||
if (!eccKey && !ed25519Key) {
|
||||
/* make sure RSA key can be used */
|
||||
word32 idx = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
RsaKey* key = NULL;
|
||||
#else
|
||||
@ -4691,6 +4694,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
|
||||
ret = wc_InitRsaKey_ex(key, heap, devId);
|
||||
if (ret == 0) {
|
||||
idx = 0;
|
||||
if (wc_RsaPrivateKeyDecode(der->buffer, &idx, key, der->length)
|
||||
!= 0) {
|
||||
#ifdef HAVE_ECC
|
||||
@ -4705,22 +4709,21 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
}
|
||||
else {
|
||||
/* check that the size of the RSA key is enough */
|
||||
int rsaSz = wc_RsaEncryptSize((RsaKey*)key);
|
||||
int minRsaSz;
|
||||
|
||||
minRsaSz = ssl ? ssl->options.minRsaKeySz : ctx->minRsaKeySz;
|
||||
if (rsaSz < minRsaSz) {
|
||||
int minRsaSz = ssl ? ssl->options.minRsaKeySz :
|
||||
ctx->minRsaKeySz;
|
||||
keySz = wc_RsaEncryptSize((RsaKey*)key);
|
||||
if (keySz < minRsaSz) {
|
||||
ret = RSA_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Private Key size too small");
|
||||
}
|
||||
|
||||
if (ssl) {
|
||||
ssl->buffers.keyType = rsa_sa_algo;
|
||||
ssl->buffers.keySz = rsaSz;
|
||||
ssl->buffers.keySz = keySz;
|
||||
}
|
||||
else if(ctx) {
|
||||
ctx->privateKeyType = rsa_sa_algo;
|
||||
ctx->privateKeySz = rsaSz;
|
||||
ctx->privateKeySz = keySz;
|
||||
}
|
||||
|
||||
rsaKey = 1;
|
||||
@ -4746,7 +4749,6 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
#ifdef HAVE_ECC
|
||||
if (!rsaKey && !ed25519Key) {
|
||||
/* make sure ECC key can be used */
|
||||
word32 idx = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ecc_key* key = NULL;
|
||||
#else
|
||||
@ -4760,17 +4762,16 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
#endif
|
||||
|
||||
if (wc_ecc_init_ex(key, heap, devId) == 0) {
|
||||
idx = 0;
|
||||
if (wc_EccPrivateKeyDecode(der->buffer, &idx, key,
|
||||
der->length) == 0) {
|
||||
int keySz = wc_ecc_size(key);
|
||||
int minKeySz;
|
||||
|
||||
/* check for minimum ECC key size and then free */
|
||||
minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz;
|
||||
int minKeySz = ssl ? ssl->options.minEccKeySz :
|
||||
ctx->minEccKeySz;
|
||||
keySz = wc_ecc_size(key);
|
||||
if (keySz < minKeySz) {
|
||||
wc_ecc_free(key);
|
||||
WOLFSSL_MSG("ECC private key too small");
|
||||
return ECC_KEY_SIZE_E;
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
}
|
||||
|
||||
eccKey = 1;
|
||||
@ -4798,12 +4799,14 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(key, heap, DYNAMIC_TYPE_ECC);
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
#ifdef HAVE_ED25519
|
||||
if (!rsaKey && !eccKey) {
|
||||
/* make sure Ed25519 key can be used */
|
||||
word32 idx = 0;
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
ed25519_key* key = NULL;
|
||||
#else
|
||||
@ -4819,6 +4822,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
|
||||
ret = wc_ed25519_init(key);
|
||||
if (ret == 0) {
|
||||
idx = 0;
|
||||
if (wc_Ed25519PrivateKeyDecode(der->buffer, &idx, key,
|
||||
der->length) != 0) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
@ -4828,7 +4832,8 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
/* check for minimum key size and then free */
|
||||
int minKeySz = ssl ? ssl->options.minEccKeySz :
|
||||
ctx->minEccKeySz;
|
||||
if (ED25519_KEY_SIZE < minKeySz) {
|
||||
keySz = ED25519_KEY_SIZE;
|
||||
if (keySz < minKeySz) {
|
||||
WOLFSSL_MSG("ED25519 private key too small");
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
}
|
||||
@ -4836,11 +4841,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
if (ret == 0) {
|
||||
if (ssl) {
|
||||
ssl->buffers.keyType = ed25519_sa_algo;
|
||||
ssl->buffers.keySz = ED25519_KEY_SIZE;
|
||||
ssl->buffers.keySz = keySz;
|
||||
}
|
||||
else if (ctx) {
|
||||
ctx->privateKeyType = ed25519_sa_algo;
|
||||
ctx->privateKeySz = ED25519_KEY_SIZE;
|
||||
ctx->privateKeySz = keySz;
|
||||
}
|
||||
|
||||
ed25519Key = 1;
|
||||
@ -4872,7 +4877,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
DecodedCert cert[1];
|
||||
#endif
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
int keyType = 0, keySz = 0;
|
||||
int keyType = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -4962,71 +4967,78 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
switch (cert->keyOID) {
|
||||
#ifndef NO_RSA
|
||||
case RSAk:
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = rsa_sa_algo;
|
||||
#endif
|
||||
/* Determine RSA key size by parsing public key */
|
||||
idx = 0;
|
||||
ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx,
|
||||
cert->pubKeySize, NULL, (word32*)&keySz, NULL, NULL);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (ssl && !ssl->options.verifyNone) {
|
||||
if (ssl->options.minRsaKeySz < 0 ||
|
||||
cert->pubKeySize < (word16)ssl->options.minRsaKeySz) {
|
||||
keySz < (int)ssl->options.minRsaKeySz) {
|
||||
ret = RSA_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate RSA key size too small");
|
||||
}
|
||||
}
|
||||
else if (ctx && !ctx->verifyNone) {
|
||||
if (ctx->minRsaKeySz < 0 ||
|
||||
cert->pubKeySize < (word16)ctx->minRsaKeySz) {
|
||||
keySz < (int)ctx->minRsaKeySz) {
|
||||
ret = RSA_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate RSA key size too small");
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = rsa_sa_algo;
|
||||
/* pubKeySize is the encoded public key */
|
||||
/* mask lsb 5-bits to round by 16 to get actual key size */
|
||||
keySz = cert->pubKeySize & ~0x1FL;
|
||||
#endif
|
||||
break;
|
||||
#endif /* !NO_RSA */
|
||||
#ifdef HAVE_ECC
|
||||
case ECDSAk:
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = ecc_dsa_sa_algo;
|
||||
#endif
|
||||
/* Determine ECC key size based on curve */
|
||||
keySz = wc_ecc_get_curve_size_from_id(
|
||||
wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL));
|
||||
|
||||
if (ssl && !ssl->options.verifyNone) {
|
||||
if (ssl->options.minEccKeySz < 0 ||
|
||||
cert->pubKeySize < (word16)ssl->options.minEccKeySz) {
|
||||
keySz < (int)ssl->options.minEccKeySz) {
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate ECC key size error");
|
||||
}
|
||||
}
|
||||
else if (ctx && !ctx->verifyNone) {
|
||||
if (ctx->minEccKeySz < 0 ||
|
||||
cert->pubKeySize < (word16)ctx->minEccKeySz) {
|
||||
keySz < (int)ctx->minEccKeySz) {
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate ECC key size error");
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = ecc_dsa_sa_algo;
|
||||
/* pubKeySize is encByte + x + y */
|
||||
keySz = (cert->pubKeySize - 1) / 2;
|
||||
#endif
|
||||
break;
|
||||
#endif /* HAVE_ECC */
|
||||
#ifdef HAVE_ED25519
|
||||
case ED25519k:
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = ed25519_sa_algo;
|
||||
#endif
|
||||
/* ED25519 is fixed key size */
|
||||
keySz = ED25519_KEY_SIZE;
|
||||
if (ssl && !ssl->options.verifyNone) {
|
||||
if (ssl->options.minEccKeySz < 0 ||
|
||||
ED25519_KEY_SIZE < (word16)ssl->options.minEccKeySz) {
|
||||
keySz < (int)ssl->options.minEccKeySz) {
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate Ed key size error");
|
||||
}
|
||||
}
|
||||
else if (ctx && !ctx->verifyNone) {
|
||||
if (ctx->minEccKeySz < 0 ||
|
||||
ED25519_KEY_SIZE < (word16)ctx->minEccKeySz) {
|
||||
keySz < (int)ctx->minEccKeySz) {
|
||||
ret = ECC_KEY_SIZE_E;
|
||||
WOLFSSL_MSG("Certificate ECC key size error");
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
keyType = ed25519_sa_algo;
|
||||
keySz = ED25519_KEY_SIZE;
|
||||
#endif
|
||||
break;
|
||||
#endif /* HAVE_ED25519 */
|
||||
|
||||
@ -5059,7 +5071,6 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
|
||||
if (ssl && resetSuites) {
|
||||
word16 havePSK = 0;
|
||||
word16 haveRSA = 0;
|
||||
int keySz = 0;
|
||||
|
||||
#ifndef NO_PSK
|
||||
if (ssl->options.havePSK) {
|
||||
@ -7455,7 +7466,24 @@ int wolfSSL_use_certificate_chain_file_format(WOLFSSL* ssl, const char* file,
|
||||
/* Set Temp CTX EC-DHE size in octets, should be 20 - 66 for 160 - 521 bit */
|
||||
int wolfSSL_CTX_SetTmpEC_DHE_Sz(WOLFSSL_CTX* ctx, word16 sz)
|
||||
{
|
||||
if (ctx == NULL || sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
|
||||
if (ctx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (sz == 0) {
|
||||
/* applies only to ECDSA */
|
||||
if (ctx->privateKeyType != ecc_dsa_sa_algo)
|
||||
return WOLFSSL_SUCCESS;
|
||||
|
||||
if (ctx->privateKeySz == 0) {
|
||||
WOLFSSL_MSG("Must set private key/cert first");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
sz = (word16)ctx->privateKeySz;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (sz < ECC_MINSIZE || sz > ECC_MAXSIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ctx->eccTempKeySz = sz;
|
||||
|
37
tests/api.c
37
tests/api.c
@ -10237,6 +10237,8 @@ static int test_wc_RsaPublicKeyDecode (void)
|
||||
byte* tmp;
|
||||
word32 idx = 0;
|
||||
int bytes = 0;
|
||||
word32 keySz = 0;
|
||||
word32 tstKeySz = 0;
|
||||
|
||||
tmp = (byte*)XMALLOC(GEN_BUF, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (tmp == NULL) {
|
||||
@ -10249,9 +10251,11 @@ static int test_wc_RsaPublicKeyDecode (void)
|
||||
#ifdef USE_CERT_BUFFERS_1024
|
||||
XMEMCPY(tmp, client_keypub_der_1024, sizeof_client_keypub_der_1024);
|
||||
bytes = sizeof_client_keypub_der_1024;
|
||||
keySz = 1024;
|
||||
#else
|
||||
XMEMCPY(tmp, client_keypub_der_2048, sizeof_client_keypub_der_2048);
|
||||
bytes = sizeof_client_keypub_der_2048;
|
||||
keySz = 2048;
|
||||
#endif
|
||||
|
||||
printf(testingFmt, "wc_RsaPublicKeyDecode()");
|
||||
@ -10292,13 +10296,22 @@ static int test_wc_RsaPublicKeyDecode (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tmp != NULL) {
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (wc_FreeRsaKey(&keyPub) || ret != 0) {
|
||||
ret = WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Test for getting modulus key size */
|
||||
idx = 0;
|
||||
ret = wc_RsaPublicKeyDecode_ex(tmp, &idx, (word32)bytes, NULL,
|
||||
&tstKeySz, NULL, NULL);
|
||||
ret = (ret == 0 && tstKeySz == keySz/8) ? 0 : WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
if (tmp != NULL) {
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
|
||||
printf(resultFmt, ret == 0 ? passed : failed);
|
||||
|
||||
|
||||
@ -22076,6 +22089,23 @@ static void test_wolfSSL_CTX_LoadCRL()
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_SetTmpEC_DHE_Sz(void)
|
||||
{
|
||||
#if defined(HAVE_ECC) && !defined(NO_WOLFSSL_CLIENT)
|
||||
WOLFSSL_CTX *ctx;
|
||||
WOLFSSL *ssl;
|
||||
|
||||
AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_CTX_SetTmpEC_DHE_Sz(ctx, 32));
|
||||
AssertNotNull(ssl = wolfSSL_new(ctx));
|
||||
AssertIntEQ(WOLFSSL_SUCCESS, wolfSSL_SetTmpEC_DHE_Sz(ssl, 32));
|
||||
|
||||
wolfSSL_free(ssl);
|
||||
wolfSSL_CTX_free(ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*
|
||||
| Main
|
||||
*----------------------------------------------------------------------------*/
|
||||
@ -22110,6 +22140,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_SetTmpDH_file();
|
||||
test_wolfSSL_SetTmpDH_buffer();
|
||||
test_wolfSSL_SetMinMaxDhKey_Sz();
|
||||
test_SetTmpEC_DHE_Sz();
|
||||
#if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER)
|
||||
test_wolfSSL_read_write();
|
||||
#endif
|
||||
|
@ -3438,23 +3438,21 @@ exit_dc:
|
||||
#ifndef NO_RSA
|
||||
|
||||
#ifndef HAVE_USER_RSA
|
||||
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 inSz)
|
||||
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz,
|
||||
const byte** n, word32* nSz, const byte** e, word32* eSz)
|
||||
{
|
||||
int length;
|
||||
int ret = 0;
|
||||
int length;
|
||||
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
|
||||
byte b;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
if (input == NULL || inOutIdx == NULL || key == NULL)
|
||||
if (input == NULL || inOutIdx == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
key->type = RSA_PUBLIC;
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
|
||||
if ((*inOutIdx + 1) > inSz)
|
||||
return BUFFER_E;
|
||||
@ -3488,20 +3486,47 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
if (GetInt(&key->n, input, inOutIdx, inSz) < 0)
|
||||
return ASN_RSA_KEY_E;
|
||||
if (GetInt(&key->e, input, inOutIdx, inSz) < 0) {
|
||||
mp_clear(&key->n);
|
||||
/* Get modulus */
|
||||
ret = GetASNInt(input, inOutIdx, &length, inSz);
|
||||
if (ret < 0) {
|
||||
return ASN_RSA_KEY_E;
|
||||
}
|
||||
if (nSz)
|
||||
*nSz = length;
|
||||
if (n)
|
||||
*n = &input[*inOutIdx];
|
||||
*inOutIdx += length;
|
||||
|
||||
#ifdef WOLFSSL_XILINX_CRYPT
|
||||
if (wc_InitRsaHw(key) != 0) {
|
||||
return BAD_STATE_E;
|
||||
/* Get exponent */
|
||||
ret = GetASNInt(input, inOutIdx, &length, inSz);
|
||||
if (ret < 0) {
|
||||
return ASN_RSA_KEY_E;
|
||||
}
|
||||
#endif
|
||||
if (eSz)
|
||||
*eSz = length;
|
||||
if (e)
|
||||
*e = &input[*inOutIdx];
|
||||
*inOutIdx += length;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 inSz)
|
||||
{
|
||||
int ret;
|
||||
const byte *n = NULL, *e = NULL;
|
||||
word32 nSz = 0, eSz = 0;
|
||||
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* import RSA public key elements (n, e) into RsaKey structure (key) */
|
||||
@ -3554,7 +3579,7 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_USER_RSA */
|
||||
#endif
|
||||
#endif /* !NO_RSA */
|
||||
|
||||
#ifndef NO_DH
|
||||
|
||||
@ -4114,7 +4139,7 @@ WOLFSSL_LOCAL int OBJ_sn2nid(const char *sn)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
for(i=0; sn2nid[i].sn != NULL; i++) {
|
||||
if(XSTRNCMP(sn, sn2nid[i].sn, XSTRLEN(sn2nid[i].sn)) == 0) {
|
||||
return sn2nid[i].nid;
|
||||
@ -9119,7 +9144,6 @@ int RsaPublicKeyDerSize(RsaKey* key, int with_header)
|
||||
|
||||
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||
|
||||
|
||||
static mp_int* GetRsaInt(RsaKey* key, int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
@ -9235,7 +9259,7 @@ int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
|
||||
return SetRsaPublicKey(output, key, inLen, 1);
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA */
|
||||
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !NO_RSA && !HAVE_USER_RSA */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
@ -9368,6 +9392,7 @@ static word32 SetUTF8String(word32 len, byte* output)
|
||||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)
|
||||
|
||||
/* Write a public ECC key to output */
|
||||
@ -11983,7 +12008,7 @@ int wc_SetAuthKeyId(Cert *cert, const char* file)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* NO_FILESYSTEM */
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
|
||||
/* Set KeyUsage from human readable string */
|
||||
int wc_SetKeyUsage(Cert *cert, const char *value)
|
||||
@ -12576,7 +12601,7 @@ int wc_SetAltNames(Cert* cert, const char* file)
|
||||
|
||||
#endif /* WOLFSSL_ALT_NAMES */
|
||||
|
||||
#endif /* NO_FILESYSTEM */
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
|
||||
/* Set cert issuer from DER buffer */
|
||||
int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
|
||||
@ -12871,7 +12896,7 @@ static int ASNToHexString(const byte* input, word32* inOutIdx, char** out,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLFSSL_CUSTOM_CURVES */
|
||||
|
||||
int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
ecc_key* key, word32 inSz)
|
||||
@ -13003,7 +13028,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
return ret;
|
||||
#else
|
||||
return ASN_PARSE_E;
|
||||
#endif
|
||||
#endif /* WOLFSSL_CUSTOM_CURVES */
|
||||
}
|
||||
else {
|
||||
/* ecc params information */
|
||||
@ -13151,7 +13176,6 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 inLen,
|
||||
return totalSz;
|
||||
}
|
||||
|
||||
#ifndef NO_ASN_CRYPT
|
||||
/* 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)
|
||||
@ -13166,7 +13190,6 @@ int wc_EccPrivateKeyToDer(ecc_key* key, byte* output, word32 inLen)
|
||||
{
|
||||
return wc_BuildEccKeyDer(key, output, inLen, 0);
|
||||
}
|
||||
#endif /* !NO_ASN_CRYPT */
|
||||
|
||||
/* Write only private ecc key to unencrypted PKCS#8 format.
|
||||
*
|
||||
@ -13237,8 +13260,8 @@ int wc_EccPrivateKeyToPKCS8(ecc_key* key, byte* output, word32* outLen)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ECC_KEY_EXPORT */
|
||||
#endif /* HAVE_ECC */
|
||||
#endif /* HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
|
||||
#ifdef HAVE_ED25519
|
||||
@ -13415,7 +13438,7 @@ int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen)
|
||||
|
||||
#endif /* WOLFSSL_KEY_GEN */
|
||||
|
||||
#endif /* HAVE_ED25519 */
|
||||
#endif /* HAVE_ED25519 */
|
||||
|
||||
|
||||
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
||||
@ -13438,7 +13461,7 @@ static int GetBasicDate(const byte* source, word32* idx, byte* date,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_OCSP || HAVE_CRL */
|
||||
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
@ -14196,7 +14219,7 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* HAVE_OCSP */
|
||||
|
||||
|
||||
/* store WC_SHA hash of NAME */
|
||||
|
@ -100,6 +100,8 @@ WOLFSSL_API int wc_RsaEncryptSize(RsaKey* key);
|
||||
|
||||
WOLFSSL_API int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||
RsaKey*, word32);
|
||||
WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
|
||||
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);
|
||||
WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
|
||||
RsaKey*, word32);
|
||||
WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
|
||||
@ -133,5 +135,3 @@ WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
|
||||
|
||||
#endif /* NO_RSA */
|
||||
#endif /* USER_WOLF_CRYPT_RSA_H */
|
||||
|
||||
|
||||
|
@ -833,32 +833,61 @@ static int GetLength(const byte* input, word32* inOutIdx, int* len,
|
||||
return length;
|
||||
}
|
||||
|
||||
static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
|
||||
word32 maxIdx)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
byte b;
|
||||
int length;
|
||||
|
||||
if ((idx + 1) > maxIdx)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
b = input[idx++];
|
||||
if (b != tag)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
if (GetLength(input, &idx, &length, maxIdx) < 0)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
*len = length;
|
||||
*inOutIdx = idx;
|
||||
return length;
|
||||
}
|
||||
|
||||
static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (*len > 0) {
|
||||
/* remove leading zero, unless there is only one 0x00 byte */
|
||||
if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
|
||||
(*inOutIdx)++;
|
||||
(*len)--;
|
||||
|
||||
if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetInt(IppsBigNumState** mpi, const byte* input, word32* inOutIdx,
|
||||
word32 maxIdx)
|
||||
{
|
||||
IppStatus ret;
|
||||
word32 idx = *inOutIdx;
|
||||
byte b;
|
||||
int length;
|
||||
int ctxSz;
|
||||
|
||||
if ((idx + 1) > maxIdx)
|
||||
if (GetASNInt(input, &idx, &length, maxIdx) < 0) {
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
b = input[idx++];
|
||||
if (b != 0x02)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
if (GetLength(input, &idx, &length, maxIdx) < 0)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
if (length > 0) {
|
||||
/* remove leading zero */
|
||||
if ( (b = input[idx++]) == 0x00)
|
||||
length--;
|
||||
else
|
||||
idx--;
|
||||
}
|
||||
|
||||
ret = ippsBigNumGetSize(length, &ctxSz);
|
||||
@ -1061,28 +1090,25 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
}
|
||||
|
||||
|
||||
/* read in a public RSA key */
|
||||
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 inSz)
|
||||
int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
|
||||
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz)
|
||||
{
|
||||
int length;
|
||||
int ctxSz;
|
||||
IppStatus ret;
|
||||
IppStatus ret = 0;
|
||||
int length;
|
||||
int keySz = 0;
|
||||
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
|
||||
byte b;
|
||||
#endif
|
||||
|
||||
if (input == NULL || inOutIdx == NULL || key == NULL) {
|
||||
if (input == NULL || inOutIdx == NULL) {
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
|
||||
USER_DEBUG(("Entering wc_RsaPublicKeyDecode\n"));
|
||||
USER_DEBUG(("Entering wc_RsaPublicKeyDecode_ex\n"));
|
||||
|
||||
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
key->type = RSA_PUBLIC;
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
|
||||
if ((*inOutIdx + 1) > inSz)
|
||||
return USER_CRYPTO_ERROR;
|
||||
@ -1133,63 +1159,56 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
}
|
||||
#endif /* OPENSSL_EXTRA || RSA_DECODE_EXTRA */
|
||||
|
||||
if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
|
||||
GetInt(&key->e, input, inOutIdx, inSz) < 0) {
|
||||
/* Get modulus */
|
||||
ret = GetASNInt(input, inOutIdx, &length, inSz);
|
||||
if (ret < 0) {
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
if (nSz)
|
||||
*nSz = length;
|
||||
if (n)
|
||||
*n = &input[*inOutIdx];
|
||||
*inOutIdx += length;
|
||||
|
||||
/* get sizes set for IPP BN states */
|
||||
ret = ippsGetSize_BN(key->n, &key->nSz);
|
||||
if (ret != ippStsNoErr) {
|
||||
USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
|
||||
/* Get exponent */
|
||||
ret = GetASNInt(input, inOutIdx, &length, inSz);
|
||||
if (ret < 0) {
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
if (eSz)
|
||||
*eSz = length;
|
||||
if (e)
|
||||
*e = &input[*inOutIdx];
|
||||
*inOutIdx += length;
|
||||
|
||||
ret = ippsGetSize_BN(key->e, &key->eSz);
|
||||
if (ret != ippStsNoErr) {
|
||||
USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
USER_DEBUG(("\tExit wc_RsaPublicKeyDecode_ex\n"));
|
||||
|
||||
key->sz = key->nSz; /* set modulus size */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert to size in bits */
|
||||
key->nSz = key->nSz * 8;
|
||||
key->eSz = key->eSz * 8;
|
||||
/* read in a public RSA key */
|
||||
int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 inSz)
|
||||
{
|
||||
IppStatus ret;
|
||||
const byte *n = NULL, *e = NULL;
|
||||
word32 nSz = 0, eSz = 0;
|
||||
|
||||
/* set up public key state */
|
||||
ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
|
||||
if (ret != ippStsNoErr) {
|
||||
USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
|
||||
ippGetStatusString(ret)));
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
|
||||
key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
|
||||
DYNAMIC_TYPE_USER_CRYPTO);
|
||||
if (key->pPub == NULL)
|
||||
if (key == NULL)
|
||||
return USER_CRYPTO_ERROR;
|
||||
|
||||
ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
|
||||
if (ret != ippStsNoErr) {
|
||||
USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
|
||||
ippGetStatusString(ret)));
|
||||
return USER_CRYPTO_ERROR;
|
||||
}
|
||||
USER_DEBUG(("Entering wc_RsaPublicKeyDecode\n"));
|
||||
|
||||
ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
|
||||
if (ret != ippStsNoErr) {
|
||||
USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
|
||||
ippGetStatusString(ret)));
|
||||
return USER_CRYPTO_ERROR;
|
||||
ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
|
||||
}
|
||||
|
||||
USER_DEBUG(("\tExit RsaPublicKeyDecode\n"));
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* import RSA public key elements (n, e) into RsaKey structure (key) */
|
||||
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
|
||||
word32 eSz, RsaKey* key)
|
||||
|
@ -1323,7 +1323,9 @@ enum Misc {
|
||||
|
||||
EVP_SALT_SIZE = 8, /* evp salt size 64 bits */
|
||||
|
||||
#ifndef ECDHE_SIZE /* allow this to be overriden at compile-time */
|
||||
ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */
|
||||
#endif
|
||||
MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */
|
||||
MAX_CURVE_NAME_SZ = 16, /* Maximum size of curve name string */
|
||||
|
||||
|
@ -417,6 +417,11 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
|
||||
word32 outputSz, byte *cipherIno, int type);
|
||||
#endif
|
||||
|
||||
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
|
||||
WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
|
||||
word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* private key helpers */
|
||||
WOLFSSL_API int wc_EccPrivateKeyDecode(const byte*, word32*,
|
||||
|
Reference in New Issue
Block a user