Improvements to PKCS8 handling.

* Fixes for handling PKCS8 in keys with EVP PKEY. Resolves QT test issues. Replacement to PR #3925.
* Improved code handling for PKCS 8 headers. Change PemToDer to not strip the PKCS8 header.
* Add support in the ECC/RSA/DH key import code to support detection / handling of the PKCS8 header.
* Fix for `wc_RsaKeyToDer` to be exposed with `OPENSSL_EXTRA`.
* Adds EVP PKCS8 test case for RSA and ECC.
* Refactor `test_wolfSSL_OPENSSL_hexstr2buf` to resolve g++ compiler warning.
* Added new `WOLFSSL_TRAP_MALLOC_SZ` build option to trap mallocs that are over a specified size.
This commit is contained in:
David Garske
2021-07-01 09:40:04 -07:00
parent 673becee74
commit fd52424dd5
10 changed files with 482 additions and 306 deletions

View File

@ -5536,6 +5536,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
/* Found PKCS8 header */
/* ToTraditional_ex moves buff and returns adjusted length */
der->length = ret;
keyFormat = algId;
}
ret = 0; /* failures should be ignored */
}
@ -5653,10 +5654,6 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
/* No operation, just skip the next section */
}
else if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) {
#if defined(WOLFSSL_ENCRYPTED_KEYS) || defined(HAVE_PKCS8)
keyFormat = algId;
#endif
ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
&keyFormat, heap, devId);
@ -8147,10 +8144,10 @@ int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
const unsigned char **in, long inSz)
{
int ret;
word32 idx = 0, algId;
byte hasPkcs8Header = 0;
WOLFSSL_EVP_PKEY* local;
word32 idx = 0;
int ret;
word32 algId;
WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey");
@ -8163,7 +8160,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
* have a PKCS8 header then do not error out. */
if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, (word32)inSz,
&algId)) > 0) {
WOLFSSL_MSG("Found and removed PKCS8 header");
WOLFSSL_MSG("Found PKCS8 header");
hasPkcs8Header = 1;
(void)idx; /* not used */
}
else {
if (ret != ASN_PARSE_E) {
@ -8181,24 +8180,17 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
return NULL;
}
/* sanity check on idx before use */
if ((int)idx > inSz) {
WOLFSSL_MSG("Issue with index pointer");
wolfSSL_EVP_PKEY_free(local);
local = NULL;
return NULL;
}
local->type = type;
local->pkey_sz = (int)inSz - idx;
local->pkey.ptr = (char*)XMALLOC(inSz - idx, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
local->pkey_sz = (int)inSz;
local->hasPkcs8Header = hasPkcs8Header;
local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (local->pkey.ptr == NULL) {
wolfSSL_EVP_PKEY_free(local);
local = NULL;
return NULL;
}
else {
XMEMCPY(local->pkey.ptr, *in + idx, inSz - idx);
XMEMCPY(local->pkey.ptr, *in, inSz);
}
switch (type) {
@ -8278,8 +8270,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
/* advance pointer with success */
if (local != NULL) {
if ((idx + local->pkey_sz) <= (word32)inSz) {
*in = *in + idx + local->pkey_sz;
if (local->pkey_sz <= (int)inSz) {
*in += local->pkey_sz;
}
if (out != NULL) {
@ -21828,6 +21820,7 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src)
dup->pub_key->inSet = src->pub_key->inSet;
dup->pub_key->exSet = src->pub_key->exSet;
dup->hasPkcs8Header = src->hasPkcs8Header;
/* Copy private key */
if (src->priv_key->internal == NULL || dup->priv_key->internal == NULL) {
@ -38966,11 +38959,13 @@ static int pem_read_bio_key(WOLFSSL_BIO* bio, pem_password_cb* cb, void* pass,
XMEMSET(info, 0, sizeof(EncryptedInfo));
info->passwd_cb = localCb;
info->passwd_userdata = pass;
/* Do not strip PKCS8 header */
ret = PemToDer((const unsigned char*)mem, memSz, keyType, der,
NULL, info, eccFlag);
if (ret < 0) {
WOLFSSL_MSG("Bad Pem To Der");
WOLFSSL_MSG("Bad PEM To DER");
}
else {
/* write left over data back to bio */
@ -39587,9 +39582,9 @@ int wolfSSL_RSA_LoadDer(WOLFSSL_RSA* rsa, const unsigned char* derBuf, int derSz
int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
int derSz, int opt)
{
int ret;
word32 idx = 0;
int ret;
word32 algId;
WOLFSSL_ENTER("wolfSSL_RSA_LoadDer");
@ -39598,6 +39593,23 @@ int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
return WOLFSSL_FATAL_ERROR;
}
rsa->hasPkcs8Header = 0;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
/* Check if input buffer has PKCS8 header. In the case that it does not
* have a PKCS8 header then do not error out. */
if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz,
&algId)) > 0) {
WOLFSSL_MSG("Found PKCS8 header");
rsa->hasPkcs8Header = 1;
}
else {
if (ret != ASN_PARSE_E) {
WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
return WOLFSSL_FATAL_ERROR;
}
}
#endif
if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz);
}
@ -40117,8 +40129,9 @@ int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
int derSz, int opt)
{
int ret;
word32 idx = 0;
int ret;
word32 algId;
WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer");
@ -40127,6 +40140,23 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
return WOLFSSL_FATAL_ERROR;
}
key->hasPkcs8Header = 0;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
/* Check if input buffer has PKCS8 header. In the case that it does not
* have a PKCS8 header then do not error out. */
if ((ret = ToTraditionalInline_ex((const byte*)derBuf, &idx, (word32)derSz,
&algId)) > 0) {
WOLFSSL_MSG("Found PKCS8 header");
key->hasPkcs8Header = 1;
}
else {
if (ret != ASN_PARSE_E) {
WOLFSSL_MSG("Unexpected error with trying to remove PKCS8 header");
return WOLFSSL_FATAL_ERROR;
}
}
#endif
if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
derSz);

View File

@ -16805,8 +16805,7 @@ static int test_wc_RsaKeyToDer (void)
static int test_wc_RsaKeyToPublicDer (void)
{
int ret = 0;
#if !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) &&\
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
RsaKey key;
WC_RNG rng;
byte* der;
@ -16837,6 +16836,12 @@ static int test_wc_RsaKeyToPublicDer (void)
printf(testingFmt, "wc_RsaKeyToPublicDer()");
if (ret == 0) {
/* test getting size only */
ret = wc_RsaKeyToPublicDer(&key, NULL, derLen);
if (ret >= 0)
ret = 0;
}
if (ret == 0) {
ret = wc_RsaKeyToPublicDer(&key, der, derLen);
if (ret >= 0) {
@ -16850,13 +16855,10 @@ static int test_wc_RsaKeyToPublicDer (void)
/* Pass in bad args. */
if (ret == 0) {
ret = wc_RsaKeyToPublicDer(NULL, der, derLen);
if (ret == BAD_FUNC_ARG) {
ret = wc_RsaKeyToPublicDer(&key, NULL, derLen);
}
if (ret == BAD_FUNC_ARG) {
ret = wc_RsaKeyToPublicDer(&key, der, -1);
}
if (ret == BAD_FUNC_ARG) {
if (ret == BUFFER_E || ret == BAD_FUNC_ARG) {
ret = 0;
} else {
ret = WOLFSSL_FATAL_ERROR;
@ -16866,9 +16868,6 @@ static int test_wc_RsaKeyToPublicDer (void)
/* Pass in bad args. */
if (ret == 0) {
ret = wc_RsaKeyToPublicDer(NULL, der, derLen);
if (ret == USER_CRYPTO_ERROR) {
ret = wc_RsaKeyToPublicDer(&key, NULL, derLen);
}
if (ret == USER_CRYPTO_ERROR) {
ret = wc_RsaKeyToPublicDer(&key, der, -1);
}
@ -28254,10 +28253,14 @@ static void test_wolfSSL_PEM_PrivateKey(void)
{
XFILE file;
const char* fname = "./certs/server-key.pem";
const char* fname_rsa_p8 = "./certs/server-keyPkcs8.pem";
size_t sz;
byte* buf;
EVP_PKEY* pkey2;
EVP_PKEY* pkey3;
RSA* rsa_key = NULL;
file = XFOPEN(fname, "rb");
AssertTrue((file != XBADFILE));
AssertTrue(XFSEEK(file, 0, XSEEK_END) == 0);
@ -28283,6 +28286,38 @@ static void test_wolfSSL_PEM_PrivateKey(void)
EVP_PKEY_free(pkey2);
EVP_PKEY_free(pkey);
pkey = NULL;
/* Qt unit test case : rsa pkcs8 key */
file = XFOPEN(fname_rsa_p8, "rb");
AssertTrue((file != XBADFILE));
AssertTrue(XFSEEK(file, 0, XSEEK_END) == 0);
sz = XFTELL(file);
XREWIND(file);
AssertNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
if (buf)
AssertIntEQ(XFREAD(buf, 1, sz, file), sz);
XFCLOSE(file);
AssertNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
AssertNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
BIO_free(bio);
bio = NULL;
AssertNotNull(pkey3 = EVP_PKEY_new());
AssertNotNull(rsa_key = EVP_PKEY_get1_RSA(pkey));
AssertIntEQ(EVP_PKEY_set1_RSA(pkey3, rsa_key), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
#else
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
#endif
RSA_free(rsa_key);
EVP_PKEY_free(pkey3);
EVP_PKEY_free(pkey);
pkey = NULL;
}
#endif
@ -28291,9 +28326,13 @@ static void test_wolfSSL_PEM_PrivateKey(void)
{
XFILE file;
const char* fname = "./certs/ecc-key.pem";
const char* fname_ecc_p8 = "./certs/ecc-keyPkcs8.pem";
size_t sz;
byte* buf;
EVP_PKEY* pkey2;
EVP_PKEY* pkey3;
EC_KEY* ec_key;
int nid = 0;
file = XFOPEN(fname, "rb");
@ -28313,17 +28352,58 @@ static void test_wolfSSL_PEM_PrivateKey(void)
BIO_free(bio);
bio = NULL;
AssertNotNull(pkey2 = EVP_PKEY_new());
AssertNotNull(pkey3 = EVP_PKEY_new());
pkey2->type = EVP_PKEY_EC;
/* Test parameter copy */
AssertIntEQ(EVP_PKEY_copy_parameters(pkey2, pkey), 1);
/* Qt unit test case 1*/
AssertNotNull(ec_key = EVP_PKEY_get1_EC_KEY(pkey));
AssertIntEQ(EVP_PKEY_set1_EC_KEY(pkey3, ec_key), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
#else
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
#endif
/* Test default digest */
AssertIntEQ(EVP_PKEY_get_default_digest_nid(pkey, &nid), 1);
AssertIntEQ(nid, NID_sha256);
EC_KEY_free(ec_key);
EVP_PKEY_free(pkey3);
EVP_PKEY_free(pkey2);
EVP_PKEY_free(pkey);
pkey = NULL;
/* Qt unit test case ec pkcs8 key */
file = XFOPEN(fname_ecc_p8, "rb");
AssertTrue((file != XBADFILE));
AssertTrue(XFSEEK(file, 0, XSEEK_END) == 0);
sz = XFTELL(file);
XREWIND(file);
AssertNotNull(buf = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE));
if (buf)
AssertIntEQ(XFREAD(buf, 1, sz, file), sz);
XFCLOSE(file);
AssertNotNull(bio = BIO_new_mem_buf(buf, (int)sz));
AssertNotNull((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL)));
XFREE(buf, NULL, DYNAMIC_TYPE_FILE);
BIO_free(bio);
bio = NULL;
AssertNotNull(pkey3 = EVP_PKEY_new());
/* Qt unit test case */
AssertNotNull(ec_key = EVP_PKEY_get1_EC_KEY(pkey));
AssertIntEQ(EVP_PKEY_set1_EC_KEY(pkey3, ec_key), WOLFSSL_SUCCESS);
#ifdef WOLFSSL_ERROR_CODE_OPENSSL
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 1/* match */);
#else
AssertIntEQ(EVP_PKEY_cmp(pkey, pkey3), 0);
#endif
EC_KEY_free(ec_key);
EVP_PKEY_free(pkey3);
EVP_PKEY_free(pkey);
pkey = NULL;
}
#endif
#endif /* !HAVE_ECC && !NO_FILESYSTEM */
#if !defined(NO_RSA) && (defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN))
{
@ -36854,11 +36934,12 @@ static void test_wolfSSL_OpenSSL_add_all_algorithms(void){
static void test_wolfSSL_OPENSSL_hexstr2buf(void)
{
#if defined(OPENSSL_EXTRA)
#define MAX_HEXSTR_BUFSZ 9
#define NUM_CASES 5
struct Output {
const unsigned char* buffer;
const unsigned char buffer[MAX_HEXSTR_BUFSZ];
long ret;
};
enum { NUM_CASES = 5 };
int i;
int j;
@ -36870,12 +36951,11 @@ static void test_wolfSSL_OPENSSL_hexstr2buf(void)
":ab:ac:d"
};
struct Output expectedOutputs[NUM_CASES] = {
{(const unsigned char []){0xaa, 0xbc, 0xd1, 0x35, 0x7e}, 5},
{(const unsigned char []){0x01, 0x12, 0x23, 0x34, 0xa5, 0xb6, 0xc7,
0xd8, 0xe9}, 9},
{(const unsigned char []){0x01, 0x02}, 2},
{NULL, 0},
{NULL, 0}
{{0xaa, 0xbc, 0xd1, 0x35, 0x7e}, 5},
{{0x01, 0x12, 0x23, 0x34, 0xa5, 0xb6, 0xc7, 0xd8, 0xe9}, 9},
{{0x01, 0x02}, 2},
{{}, 0},
{{}, 0}
};
long len = 0;
unsigned char* returnedBuf = NULL;
@ -36886,7 +36966,7 @@ static void test_wolfSSL_OPENSSL_hexstr2buf(void)
returnedBuf = wolfSSL_OPENSSL_hexstr2buf(inputs[i], &len);
if (returnedBuf == NULL) {
AssertNull(expectedOutputs[i].buffer);
AssertIntEQ(expectedOutputs[i].ret, 0);
continue;
}

View File

@ -2866,10 +2866,21 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
int version, length;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
word32 algId = 0;
#endif
if (inOutIdx == NULL || input == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
/* if has pkcs8 header skip it */
if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
/* ignore error, did not have pkcs8 header */
}
#endif
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
@ -3020,7 +3031,6 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
word32 tmpSz = 0;
word32 sz;
/* If out is NULL then return the max size needed
* + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
if (out == NULL && outSz != NULL) {
@ -3093,6 +3103,7 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
sz = SetSequence(tmpSz, out);
XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
*outSz = tmpSz + sz;
return tmpSz + sz;
}
@ -4945,7 +4956,7 @@ int DsaPublicKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG;
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
@ -5010,13 +5021,23 @@ int wc_DsaParamsDecode(const byte* input, word32* inOutIdx, DsaKey* key,
int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz)
{
int length, version, ret = 0, temp = 0;
int length, version, ret = 0, temp = 0;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
word32 algId = 0;
#endif
/* Sanity checks on input */
if (input == NULL || inOutIdx == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
/* if has pkcs8 header skip it */
if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
/* ignore error, did not have pkcs8 header */
}
#endif
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
@ -11268,6 +11289,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
DerBuffer* der;
#if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS)
word32 algId = 0;
word32 idx;
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
int padVal = 0;
#endif
@ -11433,7 +11455,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
#endif /* WOLFSSL_ENCRYPTED_KEYS */
/* find footer */
footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff + sz - headerEnd));
footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff +
sz - headerEnd));
if (!footerEnd) {
if (info)
info->consumed = longSz; /* No more certs if no footer */
@ -11478,18 +11501,18 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
) && !encrypted_key)
{
#ifdef HAVE_PKCS8
/* pkcs8 key, convert and adjust length */
if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) {
der->length = ret;
if (keyFormat) {
/* detect pkcs8 key and get alg type */
/* keep PKCS8 header */
idx = 0;
ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
if (ret > 0) {
if (keyFormat)
*keyFormat = algId;
}
}
else {
/* ignore failure here and assume key is not pkcs8 wrapped */
}
#endif
return 0;
}
@ -11522,15 +11545,21 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
/* convert and adjust length */
if (header == BEGIN_ENC_PRIV_KEY) {
#ifndef NO_PWDBASED
ret = ToTraditionalEnc(der->buffer, der->length,
password, passwordSz, &algId);
if (ret >= 0) {
ret = wc_DecryptPKCS8Key(der->buffer, der->length,
password, passwordSz);
if (ret > 0) {
/* update length by decrypted content */
der->length = ret;
if (keyFormat) {
*keyFormat = algId;
idx = 0;
/* detect pkcs8 key and get alg type */
/* keep PKCS8 header */
ret = ToTraditionalInline_ex(der->buffer, &idx, der->length,
&algId);
if (ret >= 0) {
if (keyFormat)
*keyFormat = algId;
ret = 0;
}
ret = 0;
}
#else
ret = NOT_COMPILED_IN;
@ -11595,14 +11624,14 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
}
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey)
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
{
return PemToDer(buff, longSz, type, pDer, heap, info, eccKey);
return PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
}
/* our KeyPemToDer password callback, password in userData */
static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
static int KeyPemToDerPassCb(char* passwd, int sz, int rw, void* userdata)
{
(void)rw;
@ -11617,9 +11646,9 @@ static WC_INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz, const char* pass)
{
int eccKey = 0;
int ret;
DerBuffer* der = NULL;
int ret;
int keyFormat = 0;
DerBuffer* der = NULL;
#ifdef WOLFSSL_SMALL_STACK
EncryptedInfo* info = NULL;
#else
@ -11641,10 +11670,10 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
#endif
XMEMSET(info, 0, sizeof(EncryptedInfo));
info->passwd_cb = OurPasswordCb;
info->passwd_cb = KeyPemToDerPassCb;
info->passwd_userdata = (void*)pass;
ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &eccKey);
ret = PemToDer(pem, pemSz, PRIVATEKEY_TYPE, &der, NULL, info, &keyFormat);
#ifdef WOLFSSL_SMALL_STACK
XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
@ -11663,6 +11692,7 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG;
}
}
(void)keyFormat;
FreeDer(&der);
return ret;
@ -11673,9 +11703,9 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
int wc_CertPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz, int type)
{
int eccKey = 0;
int ret;
DerBuffer* der = NULL;
int ret;
int keyFormat = 0;
DerBuffer* der = NULL;
WOLFSSL_ENTER("wc_CertPemToDer");
@ -11690,7 +11720,7 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz,
}
ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &eccKey);
ret = PemToDer(pem, pemSz, type, &der, NULL, NULL, &keyFormat);
if (ret < 0 || der == NULL) {
WOLFSSL_MSG("Bad Pem To Der");
}
@ -11704,6 +11734,7 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG;
}
}
(void)keyFormat;
FreeDer(&der);
return ret;
@ -11720,6 +11751,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz)
{
int ret;
int keyFormat = 0;
DerBuffer* der = NULL;
WOLFSSL_ENTER("wc_PubKeyPemToDer");
@ -11729,7 +11761,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
return BAD_FUNC_ARG;
}
ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, NULL);
ret = PemToDer(pem, pemSz, PUBLICKEY_TYPE, &der, NULL, NULL, &keyFormat);
if (ret < 0 || der == NULL) {
WOLFSSL_MSG("Bad Pem To Der");
}
@ -11743,6 +11775,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG;
}
}
(void)keyFormat;
FreeDer(&der);
return ret;
@ -11924,136 +11957,81 @@ int wc_PemPubKeyToDer(const char* fileName,
static int SetRsaPublicKey(byte* output, RsaKey* key,
int outLen, int with_header)
{
#ifdef WOLFSSL_SMALL_STACK
byte* n = NULL;
byte* e = NULL;
#else
byte n[MAX_RSA_INT_SZ];
byte e[MAX_RSA_E_SZ];
#endif
int idx, nSz, eSz, seqSz, headSz = 0, bitStringSz = 0, algoSz = 0;
byte seq[MAX_SEQ_SZ];
byte headSeq[MAX_SEQ_SZ];
byte bitString[1 + MAX_LENGTH_SZ + 1];
int nSz;
int eSz;
int seqSz;
int bitStringSz;
int idx;
byte algo[MAX_ALGO_SZ]; /* 20 bytes */
if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
if (key == NULL) {
return BAD_FUNC_ARG;
/* n */
#ifdef WOLFSSL_SMALL_STACK
n = (byte*)XMALLOC(MAX_RSA_INT_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (n == NULL)
return MEMORY_E;
#endif
}
#ifdef HAVE_USER_RSA
nSz = SetASNIntRSA(key->n, n);
nSz = SetASNIntRSA(key->n, NULL);
#else
nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n);
#endif
if (nSz < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
#endif
if (nSz < 0)
return nSz;
}
/* e */
#ifdef WOLFSSL_SMALL_STACK
e = (byte*)XMALLOC(MAX_RSA_E_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (e == NULL) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return MEMORY_E;
}
#endif
#ifdef HAVE_USER_RSA
eSz = SetASNIntRSA(key->e, e);
eSz = SetASNIntRSA(key->e, NULL);
#else
eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e);
#endif
if (eSz < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
#endif
if (eSz < 0)
return eSz;
}
seqSz = SetSequence(nSz + eSz, seq);
/* check output size */
if ( (seqSz + nSz + eSz) > outLen) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
seqSz = SetSequence(nSz + eSz, seq);
/* headers */
if (with_header) {
int algoSz;
#ifdef WOLFSSL_SMALL_STACK
byte* algo;
algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (algo == NULL) {
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
return MEMORY_E;
}
#else
byte algo[MAX_ALGO_SZ];
#endif
algoSz = SetAlgoID(RSAk, algo, oidKeyType, 0);
bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
bitStringSz = SetBitString(seqSz + nSz + eSz, 0, bitString);
headSz = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, headSeq);
}
idx = SetSequence(nSz + eSz + seqSz + bitStringSz + algoSz, output);
/* if getting length only */
if (output == NULL) {
return headSz + algoSz + bitStringSz + seqSz + nSz + eSz;
}
/* check output size */
if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BUFFER_E;
}
/* check output size */
if ((headSz + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
return BUFFER_E;
}
/* write output */
idx = 0;
if (with_header) {
/* header size */
XMEMCPY(output + idx, headSeq, headSz);
idx += headSz;
/* algo */
XMEMCPY(output + idx, algo, algoSz);
idx += algoSz;
/* bit string */
XMEMCPY(output + idx, bitString, bitStringSz);
idx += bitStringSz;
#ifdef WOLFSSL_SMALL_STACK
XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
}
else
idx = 0;
/* seq */
XMEMCPY(output + idx, seq, seqSz);
idx += seqSz;
/* n */
XMEMCPY(output + idx, n, nSz);
#ifdef HAVE_USER_RSA
nSz = SetASNIntRSA(key->n, output + idx);
#else
nSz = SetASNIntMP(&key->n, nSz, output + idx);
#endif
idx += nSz;
/* e */
XMEMCPY(output + idx, e, eSz);
idx += eSz;
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#ifdef HAVE_USER_RSA
eSz = SetASNIntRSA(key->e, output + idx);
#else
eSz = SetASNIntMP(&key->e, eSz, output + idx);
#endif
idx += eSz;
return idx;
}
@ -12118,7 +12096,8 @@ int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
#endif /* !NO_RSA && WOLFSSL_CERT_GEN */
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && \
!defined(NO_RSA) && !defined(HAVE_USER_RSA)
static mp_int* GetRsaInt(RsaKey* key, int idx)
{
@ -12142,32 +12121,18 @@ static mp_int* GetRsaInt(RsaKey* key, int idx)
return NULL;
}
/* Release Tmp RSA resources */
static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
{
int i;
(void)heap;
for (i = 0; i < RSA_INTS; i++)
XFREE(tmps[i], heap, DYNAMIC_TYPE_RSA);
}
/* Convert RsaKey key to DER format, write to output (inLen), return bytes
written */
written. If output is NULL then length only will be returned */
int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
{
word32 seqSz, verSz, rawLen, intTotalLen = 0;
int ret = 0, i, j, outLen = 0, mpSz;
word32 seqSz = 0, verSz, rawLen, intTotalLen = 0;
word32 sizes[RSA_INTS];
int i, j, outLen, ret = 0, mpSz;
byte seq[MAX_SEQ_SZ];
byte ver[MAX_VERSION_SZ];
byte* tmps[RSA_INTS];
if (!key)
if (key == NULL)
return BAD_FUNC_ARG;
if (key->type != RSA_PRIVATE)
@ -12181,11 +12146,13 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
mp_int* keyInt = GetRsaInt(key, i);
rawLen = mp_unsigned_bin_size(keyInt) + 1;
tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
if (output != NULL) {
tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
DYNAMIC_TYPE_RSA);
if (tmps[i] == NULL) {
ret = MEMORY_E;
break;
if (tmps[i] == NULL) {
ret = MEMORY_E;
break;
}
}
mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]);
@ -12196,22 +12163,16 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
intTotalLen += (sizes[i] = mpSz);
}
if (ret != 0) {
FreeTmpRsas(tmps, key->heap);
return ret;
if (ret == 0) {
/* make headers */
verSz = SetMyVersion(0, ver, FALSE);
seqSz = SetSequence(verSz + intTotalLen, seq);
outLen = seqSz + verSz + intTotalLen;
if (output != NULL && outLen > (int)inLen)
ret = BUFFER_E;
}
/* make headers */
verSz = SetMyVersion(0, ver, FALSE);
seqSz = SetSequence(verSz + intTotalLen, seq);
outLen = seqSz + verSz + intTotalLen;
if (output) {
if (outLen > (int)inLen) {
FreeTmpRsas(tmps, key->heap);
return BAD_FUNC_ARG;
}
if (ret == 0 && output != NULL) {
/* write to output */
XMEMCPY(output, seq, seqSz);
j = seqSz;
@ -12223,13 +12184,17 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
j += sizes[i];
}
}
FreeTmpRsas(tmps, key->heap);
return outLen;
for (i = 0; i < RSA_INTS; i++) {
if (tmps[i])
XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA);
}
if (ret == 0)
ret = outLen;
return ret;
}
#endif
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
/* Convert Rsa Public key to DER format, write to output (inLen), return bytes
written */
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
@ -16380,12 +16345,22 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key,
#else
byte priv[ECC_MAXSIZE+1];
byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */
#endif
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
word32 algId = 0;
#endif
byte* pubData = NULL;
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
return BAD_FUNC_ARG;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
/* if has pkcs8 header skip it */
if (ToTraditionalInline_ex(input, inOutIdx, inSz, &algId) < 0) {
/* ignore error, did not have pkcs8 header */
}
#endif
if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E;
@ -16819,8 +16794,8 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx,
#if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
/* build DER formatted ECC key, include optional public key if requested,
* return length on success, negative on error */
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
int pubIn)
static int wc_BuildEccKeyDer_ex(ecc_key* key, byte* output, word32 *inLen,
int pubIn, int curveIn)
{
byte curve[MAX_ALGO_SZ+2];
byte ver[MAX_VERSION_SZ];
@ -16842,15 +16817,17 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
if (key == NULL || (output == NULL && inLen == NULL))
return BAD_FUNC_ARG;
/* curve */
curve[curveidx++] = ECC_PREFIX_0;
curveidx++ /* to put the size after computation */;
curveSz = SetCurve(key, curve+curveidx);
if (curveSz < 0)
return curveSz;
/* set computed size */
curve[1] = (byte)curveSz;
curveidx += curveSz;
if (curveIn) {
/* curve */
curve[curveidx++] = ECC_PREFIX_0;
curveidx++ /* to put the size after computation */;
curveSz = SetCurve(key, curve+curveidx);
if (curveSz < 0)
return curveSz;
/* set computed size */
curve[1] = (byte)curveSz;
curveidx += curveSz;
}
/* private */
privSz = key->dp->size;
@ -16987,6 +16964,12 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
return totalSz;
}
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
int pubIn)
{
return wc_BuildEccKeyDer_ex(key, output, inLen, pubIn, 1);
}
/* 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)
@ -17058,13 +17041,15 @@ static int eccToPKCS8(ecc_key* key, byte* output, word32* outLen,
#endif
XMEMSET(tmpDer, 0, ECC_BUFSIZE);
tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic);
if (tmpDerSz < 0) {
/* The outer PKCS8 has the curve info (so don't include here */
ret = wc_BuildEccKeyDer_ex(key, tmpDer, &sz, includePublic, 0);
if (ret < 0) {
#ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return tmpDerSz;
return ret;
}
tmpDerSz = ret;
/* get pkcs8 expected output size */
ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID,

View File

@ -650,7 +650,7 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
#endif /* HAVE_AESGCM */
/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */
WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl,
const unsigned char *in, int inl)
{
@ -937,7 +937,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx,
* Note, you don't know if the padding is good or bad with the old
* encrypt, but it is likely to be or bad. It will update the output
* length with the block_size so the last block is still captured. */
WOLFSSL_API int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl)
{
int fl;
@ -1772,7 +1772,7 @@ int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
* RETURNS:
* returns WOLFSSL_SUCCESS on success, otherwise returns -2
*/
WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
{
int ret = -2;
@ -1801,7 +1801,7 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx)
* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE
*/
WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig,
size_t *siglen, const unsigned char *tbs, size_t tbslen)
{
int len = 0;
@ -2037,7 +2037,7 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to,
}
#ifndef NO_WOLFSSL_STUB
WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)
int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)
{
(void)pkey;
/* not using missing params callback and returning zero to indicate success */
@ -2058,7 +2058,7 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey)
* define WOLFSSL_ERROR_CODE_OPENSSL so that WS_RETURN_CODE translates return
* codes to match OpenSSL equivalent behavior.
*/
WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b)
int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b)
{
int ret = -1; /* failure */
int a_sz = 0, b_sz = 0;
@ -2269,7 +2269,7 @@ int wolfSSL_EVP_SignInit(WOLFSSL_EVP_MD_CTX *ctx, const WOLFSSL_EVP_MD *type)
return wolfSSL_EVP_DigestInit(ctx,type);
}
WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
const WOLFSSL_EVP_MD* type,
WOLFSSL_ENGINE *impl)
{
@ -3076,7 +3076,7 @@ int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
#endif /* !NO_PWDBASED !NO_SHA*/
#if !defined(NO_PWDBASED)
WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
const unsigned char *salt,
int saltlen, int iter,
const WOLFSSL_EVP_MD *digest,
@ -3676,7 +3676,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
return ctx;
}
WOLFSSL_API void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
void wolfSSL_EVP_MD_CTX_free(WOLFSSL_EVP_MD_CTX *ctx)
{
if (ctx) {
WOLFSSL_ENTER("EVP_MD_CTX_free");
@ -6095,26 +6095,29 @@ WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key)
*/
int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key)
{
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)
int derMax = 0;
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)
int ret;
int derSz = 0;
int pkcs8Sz = 0;
byte* derBuf = NULL;
RsaKey* rsa = NULL;
#endif
WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA");
if ((pkey == NULL) || (key == NULL))
if (pkey == NULL || key == NULL)
return WOLFSSL_FAILURE;
if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_RSA_up_ref failed");
return WOLFSSL_FAILURE;
}
if (pkey->rsa != NULL && pkey->ownRsa == 1) {
wolfSSL_RSA_free(pkey->rsa);
}
pkey->rsa = key;
pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */
pkey->type = EVP_PKEY_RSA;
pkey->hasPkcs8Header = key->hasPkcs8Header;
if (key->inSet == 0) {
if (SetRsaInternal(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetRsaInternal failed");
@ -6122,52 +6125,86 @@ int wolfSSL_EVP_PKEY_set1_RSA(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_RSA *key)
}
}
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)
#if (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(HAVE_USER_RSA)
rsa = (RsaKey*)key->internal;
/* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional
* information */
derMax = 5 * wolfSSL_RSA_size(key) + (2 * AES_BLOCK_SIZE);
derBuf = (byte*)XMALLOC(derMax, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
WOLFSSL_MSG("malloc failed");
return WOLFSSL_FAILURE;
}
/* Get DER size */
derSz = 0;
if (rsa->type == RSA_PRIVATE) {
/* Private key to DER */
derSz = wc_RsaKeyToDer(rsa, derBuf, derMax);
ret = wc_RsaKeyToDer(rsa, NULL, 0);
if (ret > 0) {
derSz = ret;
#ifdef HAVE_PKCS8
if (key->hasPkcs8Header) {
ret = wc_CreatePKCS8Key(NULL, (word32*)&pkcs8Sz, NULL, derSz,
RSAk, NULL, 0);
if (ret == LENGTH_ONLY_E) ret = 0;
}
#endif
}
}
else {
/* Public key to DER */
derSz = wc_RsaKeyToPublicDer(rsa, derBuf, derMax);
ret = wc_RsaKeyToPublicDer(rsa, NULL, 0);
if (ret > 0)
derSz = ret;
}
if (derSz < 0) {
if (ret >= 0 && derSz >= 0) {
derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER);
if (derBuf == NULL) {
WOLFSSL_MSG("EVP_PKEY_set1_RSA malloc failed");
return WOLFSSL_FAILURE;
}
if (rsa->type == RSA_PRIVATE) {
WOLFSSL_MSG("wc_RsaKeyToDer failed");
ret = wc_RsaKeyToDer(rsa, derBuf, derSz);
if (ret > 0) {
derSz = ret;
#ifdef HAVE_PKCS8
if (key->hasPkcs8Header) {
byte* keyBuf = derBuf;
int keySz = derSz;
derSz = pkcs8Sz;
derBuf = (byte*)XMALLOC(pkcs8Sz, pkey->heap,
DYNAMIC_TYPE_DER);
if (derBuf == NULL)
ret = MEMORY_E;
else {
ret = wc_CreatePKCS8Key(derBuf, (word32*)&derSz, keyBuf,
keySz, RSAk, NULL, 0);
}
XFREE(keyBuf, pkey->heap, DYNAMIC_TYPE_DER);
}
#endif
}
}
else {
WOLFSSL_MSG("wc_RsaKeyToPublicDer failed");
/* Public key to DER */
ret = wc_RsaKeyToPublicDer(rsa, derBuf, derSz);
if (ret > 0)
derSz = ret;
}
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
if (ret < 0) {
if (rsa->type == RSA_PRIVATE) {
WOLFSSL_MSG("EVP_PKEY_set1_RSA private failed");
}
else {
WOLFSSL_MSG("EVP_PKEY_set1_RSA public failed");
}
if (derBuf)
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_DER);
return WOLFSSL_FAILURE;
}
pkey->pkey.ptr = (char*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER);
if (pkey->pkey.ptr == NULL) {
WOLFSSL_MSG("key malloc failed");
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
pkey->pkey.ptr = (char*)derBuf;
pkey->pkey_sz = derSz;
XMEMCPY(pkey->pkey.ptr, derBuf, derSz);
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */
#endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !HAVE_USER_RSA */
#ifdef WC_RSA_BLINDING
if (key->ownRng == 0) {
if (wc_RsaSetRNG((RsaKey*)(pkey->rsa->internal), &(pkey->rng)) != 0) {
if (wc_RsaSetRNG((RsaKey*)pkey->rsa->internal, &pkey->rng) != 0) {
WOLFSSL_MSG("Error setting RSA rng");
return WOLFSSL_FAILURE;
}
@ -6323,11 +6360,11 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key)
if (key->type == EVP_PKEY_EC) {
if (wolfSSL_EC_KEY_LoadDer(local, (const unsigned char*)key->pkey.ptr,
key->pkey_sz) != SSL_SUCCESS) {
key->pkey_sz) != WOLFSSL_SUCCESS) {
/* now try public key */
if (wolfSSL_EC_KEY_LoadDer_ex(local,
(const unsigned char*)key->pkey.ptr,
key->pkey_sz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != SSL_SUCCESS) {
key->pkey_sz, WOLFSSL_EC_KEY_LOAD_PUBLIC) != WOLFSSL_SUCCESS) {
wolfSSL_EC_KEY_free(local);
local = NULL;
@ -6511,32 +6548,60 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key)
#if defined(HAVE_ECC)
/* try and populate public pkey_sz and pkey.ptr */
static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, ecc_key* ecc)
static int ECC_populate_EVP_PKEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY *key)
{
word32 derSz = 0;
if (!pkey || !ecc)
int derSz = 0;
ecc_key* ecc;
if (pkey == NULL || key == NULL || key->internal == NULL)
return WOLFSSL_FAILURE;
if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) {
byte* derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL);
if (derBuf) {
if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) >= 0) {
if (pkey->pkey.ptr) {
XFREE(pkey->pkey.ptr, NULL, DYNAMIC_TYPE_OPENSSL);
ecc = (ecc_key*)key->internal;
if (key->hasPkcs8Header) {
/* when key has pkcs8 header the pkey should too */
if (wc_EccKeyToPKCS8(ecc, NULL, (word32*)&derSz) == LENGTH_ONLY_E) {
byte* derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL);
if (derBuf) {
if (wc_EccKeyToPKCS8(ecc, derBuf, (word32*)&derSz) >= 0) {
if (pkey->pkey.ptr) {
XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL);
}
pkey->pkey_sz = (int)derSz;
pkey->pkey.ptr = (char*)derBuf;
pkey->hasPkcs8Header = 1;
return WOLFSSL_SUCCESS;
}
else {
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL);
derBuf = NULL;
}
pkey->pkey_sz = (int)derSz;
pkey->pkey.ptr = (char*)derBuf;
return WOLFSSL_SUCCESS;
}
else {
XFREE(derBuf, NULL, DYNAMIC_TYPE_OPENSSL);
derBuf = NULL;
}
}
else {
/* if not, the pkey will be traditional ecc key */
if ((derSz = wc_EccKeyDerSize(ecc, 1)) > 0) {
byte* derBuf = (byte*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_OPENSSL);
if (derBuf) {
if (wc_EccKeyToDer(ecc, derBuf, derSz) >= 0) {
if (pkey->pkey.ptr) {
XFREE(pkey->pkey.ptr, pkey->heap, DYNAMIC_TYPE_OPENSSL);
}
pkey->pkey_sz = (int)derSz;
pkey->pkey.ptr = (char*)derBuf;
return WOLFSSL_SUCCESS;
}
else {
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_OPENSSL);
derBuf = NULL;
}
}
}
}
return WOLFSSL_FAILURE;
}
WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key)
int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key)
{
#ifdef HAVE_ECC
if((pkey == NULL) || (key ==NULL))return WOLFSSL_FAILURE;
@ -6565,7 +6630,7 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_
pkey->ecc = key;
pkey->ownEcc = 0; /* pkey does not own EC key */
pkey->type = EVP_PKEY_EC;
return ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal);
return ECC_populate_EVP_PKEY(pkey, key);
#else
(void)pkey;
(void)key;
@ -6601,7 +6666,7 @@ int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key)
pkey->ownEcc = 1;
/* try and populate public pkey_sz and pkey.ptr */
return ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal);
return ECC_populate_EVP_PKEY(pkey, key);
}
#endif /* HAVE_ECC */

View File

@ -137,6 +137,13 @@ void* wolfSSL_Malloc(size_t size)
}
else {
#ifndef WOLFSSL_NO_MALLOC
#ifdef WOLFSSL_TRAP_MALLOC_SZ
if (size > WOLFSSL_TRAP_MALLOC_SZ) {
WOLFSSL_MSG("Malloc too big!");
return NULL;
}
#endif
res = malloc(size);
#else
WOLFSSL_MSG("No malloc available");

View File

@ -117,10 +117,13 @@ struct WOLFSSL_EC_KEY {
WOLFSSL_BIGNUM *priv_key;
void* internal; /* our ECC Key */
char inSet; /* internal set from external ? */
char exSet; /* external set from internal ? */
char form; /* Either POINT_CONVERSION_UNCOMPRESSED or
* POINT_CONVERSION_COMPRESSED */
/* option bits */
byte inSet:1; /* internal set from external ? */
byte exSet:1; /* external set from internal ? */
byte hasPkcs8Header:1;
};
struct WOLFSSL_EC_BUILTIN_CURVE {

View File

@ -77,9 +77,6 @@ typedef struct WOLFSSL_RSA {
WOLFSSL_BIGNUM* iqmp; /* u */
void* heap;
void* internal; /* our RSA */
char inSet; /* internal set from external ? */
char exSet; /* external set from internal ? */
char ownRng; /* flag for if the rng should be free'd */
#if defined(OPENSSL_EXTRA)
WOLFSSL_RSA_METHOD* meth;
#endif
@ -90,6 +87,12 @@ typedef struct WOLFSSL_RSA {
wolfSSL_Mutex refMutex; /* ref count mutex */
int refCount; /* reference count */
#endif
/* bits */
byte inSet:1; /* internal set from external ? */
byte exSet:1; /* external set from internal ? */
byte ownRng:1; /* flag for if the rng should be free'd */
byte hasPkcs8Header:1;
} WOLFSSL_RSA;
#endif

View File

@ -352,28 +352,31 @@ struct WOLFSSL_EVP_PKEY {
union {
char* ptr; /* der format of key / or raw for NTRU */
} pkey;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
#ifndef NO_RSA
WOLFSSL_RSA* rsa;
byte ownRsa; /* if struct owns RSA and should free it */
WOLFSSL_RSA* rsa;
#endif
#ifndef NO_DSA
WOLFSSL_DSA* dsa;
byte ownDsa; /* if struct owns DSA and should free it */
#ifndef NO_DSA
WOLFSSL_DSA* dsa;
#endif
#ifdef HAVE_ECC
WOLFSSL_EC_KEY* ecc;
byte ownEcc; /* if struct owns ECC and should free it */
WOLFSSL_EC_KEY* ecc;
#endif
#ifndef NO_DH
WOLFSSL_DH* dh;
byte ownDh; /* if struct owns DH and should free it */
WOLFSSL_DH* dh;
#endif
WC_RNG rng;
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef HAVE_ECC
int pkey_curve;
#endif
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef HAVE_ECC
int pkey_curve;
#endif
/* option bits */
byte ownDh:1; /* if struct owns DH and should free it */
byte ownEcc:1; /* if struct owns ECC and should free it */
byte ownDsa:1; /* if struct owns DSA and should free it */
byte ownRsa:1; /* if struct owns RSA and should free it */
byte hasPkcs8Header:1;
};
typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO;
#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */

View File

@ -485,7 +485,7 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer);
#ifdef WOLFSSL_PEM_TO_DER
WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type,
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* eccKey);
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat);
WOLFSSL_API int wc_KeyPemToDer(const unsigned char*, int,
unsigned char*, int, const char*);

View File

@ -294,7 +294,7 @@ WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
RsaKey*, word32);
WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
const byte* e, word32 eSz, RsaKey* key);
#ifdef WOLFSSL_KEY_GEN
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)
WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
#endif