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 */ /* Found PKCS8 header */
/* ToTraditional_ex moves buff and returns adjusted length */ /* ToTraditional_ex moves buff and returns adjusted length */
der->length = ret; der->length = ret;
keyFormat = algId;
} }
ret = 0; /* failures should be ignored */ 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 */ /* No operation, just skip the next section */
} }
else if (type == PRIVATEKEY_TYPE && format != WOLFSSL_FILETYPE_RAW) { 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, ret = ProcessBufferTryDecode(ctx, ssl, der, &keySz, &idx, &resetSuites,
&keyFormat, heap, devId); &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, WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
const unsigned char **in, long inSz) const unsigned char **in, long inSz)
{ {
int ret;
word32 idx = 0, algId;
byte hasPkcs8Header = 0;
WOLFSSL_EVP_PKEY* local; WOLFSSL_EVP_PKEY* local;
word32 idx = 0;
int ret;
word32 algId;
WOLFSSL_ENTER("wolfSSL_d2i_PrivateKey"); 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. */ * have a PKCS8 header then do not error out. */
if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, (word32)inSz, if ((ret = ToTraditionalInline_ex((const byte*)(*in), &idx, (word32)inSz,
&algId)) > 0) { &algId)) > 0) {
WOLFSSL_MSG("Found and removed PKCS8 header"); WOLFSSL_MSG("Found PKCS8 header");
hasPkcs8Header = 1;
(void)idx; /* not used */
} }
else { else {
if (ret != ASN_PARSE_E) { if (ret != ASN_PARSE_E) {
@@ -8181,24 +8180,17 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
return NULL; 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->type = type;
local->pkey_sz = (int)inSz - idx; local->pkey_sz = (int)inSz;
local->pkey.ptr = (char*)XMALLOC(inSz - idx, NULL, DYNAMIC_TYPE_PUBLIC_KEY); local->hasPkcs8Header = hasPkcs8Header;
local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (local->pkey.ptr == NULL) { if (local->pkey.ptr == NULL) {
wolfSSL_EVP_PKEY_free(local); wolfSSL_EVP_PKEY_free(local);
local = NULL; local = NULL;
return NULL; return NULL;
} }
else { else {
XMEMCPY(local->pkey.ptr, *in + idx, inSz - idx); XMEMCPY(local->pkey.ptr, *in, inSz);
} }
switch (type) { switch (type) {
@@ -8278,8 +8270,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out,
/* advance pointer with success */ /* advance pointer with success */
if (local != NULL) { if (local != NULL) {
if ((idx + local->pkey_sz) <= (word32)inSz) { if (local->pkey_sz <= (int)inSz) {
*in = *in + idx + local->pkey_sz; *in += local->pkey_sz;
} }
if (out != NULL) { 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->inSet = src->pub_key->inSet;
dup->pub_key->exSet = src->pub_key->exSet; dup->pub_key->exSet = src->pub_key->exSet;
dup->hasPkcs8Header = src->hasPkcs8Header;
/* Copy private key */ /* Copy private key */
if (src->priv_key->internal == NULL || dup->priv_key->internal == NULL) { 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)); XMEMSET(info, 0, sizeof(EncryptedInfo));
info->passwd_cb = localCb; info->passwd_cb = localCb;
info->passwd_userdata = pass; info->passwd_userdata = pass;
/* Do not strip PKCS8 header */
ret = PemToDer((const unsigned char*)mem, memSz, keyType, der, ret = PemToDer((const unsigned char*)mem, memSz, keyType, der,
NULL, info, eccFlag); NULL, info, eccFlag);
if (ret < 0) { if (ret < 0) {
WOLFSSL_MSG("Bad Pem To Der"); WOLFSSL_MSG("Bad PEM To DER");
} }
else { else {
/* write left over data back to bio */ /* 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 wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
int derSz, int opt) int derSz, int opt)
{ {
int ret;
word32 idx = 0; word32 idx = 0;
int ret; word32 algId;
WOLFSSL_ENTER("wolfSSL_RSA_LoadDer"); 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; 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) { if (opt == WOLFSSL_RSA_LOAD_PRIVATE) {
ret = wc_RsaPrivateKeyDecode(derBuf, &idx, (RsaKey*)rsa->internal, derSz); 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 wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
int derSz, int opt) int derSz, int opt)
{ {
int ret;
word32 idx = 0; word32 idx = 0;
int ret; word32 algId;
WOLFSSL_ENTER("wolfSSL_EC_KEY_LoadDer"); 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; 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) { if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE) {
ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal, ret = wc_EccPrivateKeyDecode(derBuf, &idx, (ecc_key*)key->internal,
derSz); derSz);

View File

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

View File

@@ -2866,10 +2866,21 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz) word32 inSz)
{ {
int version, length; int version, length;
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
word32 algId = 0;
#endif
if (inOutIdx == NULL || input == NULL || key == NULL) { if (inOutIdx == NULL || input == NULL || key == NULL) {
return BAD_FUNC_ARG; 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) if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
@@ -3020,7 +3031,6 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
word32 tmpSz = 0; word32 tmpSz = 0;
word32 sz; word32 sz;
/* If out is NULL then return the max size needed /* If out is NULL then return the max size needed
* + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */ * + 2 for ASN_OBJECT_ID and ASN_OCTET_STRING tags */
if (out == NULL && outSz != NULL) { if (out == NULL && outSz != NULL) {
@@ -3093,6 +3103,7 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
sz = SetSequence(tmpSz, out); sz = SetSequence(tmpSz, out);
XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz); XMEMMOVE(out + sz, out + MAX_SEQ_SZ, tmpSz);
*outSz = tmpSz + sz;
return 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) if (input == NULL || inOutIdx == NULL || key == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
if (GetSequence(input, inOutIdx, &length, inSz) < 0) if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E; 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, int DsaPrivateKeyDecode(const byte* input, word32* inOutIdx, DsaKey* key,
word32 inSz) 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 */ /* Sanity checks on input */
if (input == NULL || inOutIdx == NULL || key == NULL) { if (input == NULL || inOutIdx == NULL || key == NULL) {
return BAD_FUNC_ARG; 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) if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
@@ -11268,6 +11289,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
DerBuffer* der; DerBuffer* der;
#if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS) #if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS)
word32 algId = 0; word32 algId = 0;
word32 idx;
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_WOLFSSL_SKIP_TRAILING_PAD) #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_WOLFSSL_SKIP_TRAILING_PAD)
int padVal = 0; int padVal = 0;
#endif #endif
@@ -11433,7 +11455,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
#endif /* WOLFSSL_ENCRYPTED_KEYS */ #endif /* WOLFSSL_ENCRYPTED_KEYS */
/* find footer */ /* 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 (!footerEnd) {
if (info) if (info)
info->consumed = longSz; /* No more certs if no footer */ 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) ) && !encrypted_key)
{ {
#ifdef HAVE_PKCS8 #ifdef HAVE_PKCS8
/* pkcs8 key, convert and adjust length */ /* detect pkcs8 key and get alg type */
if ((ret = ToTraditional_ex(der->buffer, der->length, &algId)) > 0) { /* keep PKCS8 header */
der->length = ret; idx = 0;
if (keyFormat) { ret = ToTraditionalInline_ex(der->buffer, &idx, der->length, &algId);
if (ret > 0) {
if (keyFormat)
*keyFormat = algId; *keyFormat = algId;
}
} }
else { else {
/* ignore failure here and assume key is not pkcs8 wrapped */ /* ignore failure here and assume key is not pkcs8 wrapped */
} }
#endif #endif
return 0; return 0;
} }
@@ -11522,15 +11545,21 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
/* convert and adjust length */ /* convert and adjust length */
if (header == BEGIN_ENC_PRIV_KEY) { if (header == BEGIN_ENC_PRIV_KEY) {
#ifndef NO_PWDBASED #ifndef NO_PWDBASED
ret = ToTraditionalEnc(der->buffer, der->length, ret = wc_DecryptPKCS8Key(der->buffer, der->length,
password, passwordSz, &algId); password, passwordSz);
if (ret > 0) {
if (ret >= 0) { /* update length by decrypted content */
der->length = ret; der->length = ret;
if (keyFormat) { idx = 0;
*keyFormat = algId; /* 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 #else
ret = NOT_COMPILED_IN; 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, 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 */ /* 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; (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, int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz, const char* pass) unsigned char* buff, int buffSz, const char* pass)
{ {
int eccKey = 0; int ret;
int ret; int keyFormat = 0;
DerBuffer* der = NULL; DerBuffer* der = NULL;
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
EncryptedInfo* info = NULL; EncryptedInfo* info = NULL;
#else #else
@@ -11641,10 +11670,10 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
#endif #endif
XMEMSET(info, 0, sizeof(EncryptedInfo)); XMEMSET(info, 0, sizeof(EncryptedInfo));
info->passwd_cb = OurPasswordCb; info->passwd_cb = KeyPemToDerPassCb;
info->passwd_userdata = (void*)pass; 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 #ifdef WOLFSSL_SMALL_STACK
XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
@@ -11663,6 +11692,7 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
} }
(void)keyFormat;
FreeDer(&der); FreeDer(&der);
return ret; return ret;
@@ -11673,9 +11703,9 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz,
int wc_CertPemToDer(const unsigned char* pem, int pemSz, int wc_CertPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz, int type) unsigned char* buff, int buffSz, int type)
{ {
int eccKey = 0; int ret;
int ret; int keyFormat = 0;
DerBuffer* der = NULL; DerBuffer* der = NULL;
WOLFSSL_ENTER("wc_CertPemToDer"); 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) { if (ret < 0 || der == NULL) {
WOLFSSL_MSG("Bad Pem To Der"); WOLFSSL_MSG("Bad Pem To Der");
} }
@@ -11704,6 +11734,7 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
} }
(void)keyFormat;
FreeDer(&der); FreeDer(&der);
return ret; return ret;
@@ -11720,6 +11751,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
unsigned char* buff, int buffSz) unsigned char* buff, int buffSz)
{ {
int ret; int ret;
int keyFormat = 0;
DerBuffer* der = NULL; DerBuffer* der = NULL;
WOLFSSL_ENTER("wc_PubKeyPemToDer"); WOLFSSL_ENTER("wc_PubKeyPemToDer");
@@ -11729,7 +11761,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
return BAD_FUNC_ARG; 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) { if (ret < 0 || der == NULL) {
WOLFSSL_MSG("Bad Pem To Der"); WOLFSSL_MSG("Bad Pem To Der");
} }
@@ -11743,6 +11775,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz,
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
} }
(void)keyFormat;
FreeDer(&der); FreeDer(&der);
return ret; return ret;
@@ -11924,136 +11957,81 @@ int wc_PemPubKeyToDer(const char* fileName,
static int SetRsaPublicKey(byte* output, RsaKey* key, static int SetRsaPublicKey(byte* output, RsaKey* key,
int outLen, int with_header) int outLen, int with_header)
{ {
#ifdef WOLFSSL_SMALL_STACK int idx, nSz, eSz, seqSz, headSz = 0, bitStringSz = 0, algoSz = 0;
byte* n = NULL;
byte* e = NULL;
#else
byte n[MAX_RSA_INT_SZ];
byte e[MAX_RSA_E_SZ];
#endif
byte seq[MAX_SEQ_SZ]; byte seq[MAX_SEQ_SZ];
byte headSeq[MAX_SEQ_SZ];
byte bitString[1 + MAX_LENGTH_SZ + 1]; byte bitString[1 + MAX_LENGTH_SZ + 1];
int nSz; byte algo[MAX_ALGO_SZ]; /* 20 bytes */
int eSz;
int seqSz;
int bitStringSz;
int idx;
if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ) if (key == NULL) {
return BAD_FUNC_ARG; 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 #ifdef HAVE_USER_RSA
nSz = SetASNIntRSA(key->n, n); nSz = SetASNIntRSA(key->n, NULL);
#else #else
nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, n); nSz = SetASNIntMP(&key->n, MAX_RSA_INT_SZ, NULL);
#endif
if (nSz < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
if (nSz < 0)
return nSz; 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 #ifdef HAVE_USER_RSA
eSz = SetASNIntRSA(key->e, e); eSz = SetASNIntRSA(key->e, NULL);
#else #else
eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, e); eSz = SetASNIntMP(&key->e, MAX_RSA_INT_SZ, NULL);
#endif
if (eSz < 0) {
#ifdef WOLFSSL_SMALL_STACK
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
if (eSz < 0)
return eSz; return eSz;
} seqSz = SetSequence(nSz + eSz, seq);
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;
}
/* headers */ /* headers */
if (with_header) { 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); 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 */ /* check output size */
if ( (idx + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) { if ((headSz + algoSz + bitStringSz + seqSz + nSz + eSz) > outLen) {
#ifdef WOLFSSL_SMALL_STACK return BUFFER_E;
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;
}
/* write output */
idx = 0;
if (with_header) {
/* header size */
XMEMCPY(output + idx, headSeq, headSz);
idx += headSz;
/* algo */ /* algo */
XMEMCPY(output + idx, algo, algoSz); XMEMCPY(output + idx, algo, algoSz);
idx += algoSz; idx += algoSz;
/* bit string */ /* bit string */
XMEMCPY(output + idx, bitString, bitStringSz); XMEMCPY(output + idx, bitString, bitStringSz);
idx += bitStringSz; idx += bitStringSz;
#ifdef WOLFSSL_SMALL_STACK
XFREE(algo, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
} }
else
idx = 0;
/* seq */ /* seq */
XMEMCPY(output + idx, seq, seqSz); XMEMCPY(output + idx, seq, seqSz);
idx += seqSz; idx += seqSz;
/* n */ /* 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; idx += nSz;
/* e */ /* e */
XMEMCPY(output + idx, e, eSz); #ifdef HAVE_USER_RSA
idx += eSz; eSz = SetASNIntRSA(key->e, output + idx);
#else
#ifdef WOLFSSL_SMALL_STACK eSz = SetASNIntMP(&key->e, eSz, output + idx);
XFREE(n, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
idx += eSz;
return idx; return idx;
} }
@@ -12118,7 +12096,8 @@ int wc_RsaPublicKeyDerSize(RsaKey* key, int with_header)
#endif /* !NO_RSA && WOLFSSL_CERT_GEN */ #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) static mp_int* GetRsaInt(RsaKey* key, int idx)
{ {
@@ -12142,32 +12121,18 @@ static mp_int* GetRsaInt(RsaKey* key, int idx)
return NULL; 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 /* 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) 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]; word32 sizes[RSA_INTS];
int i, j, outLen, ret = 0, mpSz;
byte seq[MAX_SEQ_SZ]; byte seq[MAX_SEQ_SZ];
byte ver[MAX_VERSION_SZ]; byte ver[MAX_VERSION_SZ];
byte* tmps[RSA_INTS]; byte* tmps[RSA_INTS];
if (!key) if (key == NULL)
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
if (key->type != RSA_PRIVATE) if (key->type != RSA_PRIVATE)
@@ -12181,11 +12146,13 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
mp_int* keyInt = GetRsaInt(key, i); mp_int* keyInt = GetRsaInt(key, i);
rawLen = mp_unsigned_bin_size(keyInt) + 1; 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); DYNAMIC_TYPE_RSA);
if (tmps[i] == NULL) { if (tmps[i] == NULL) {
ret = MEMORY_E; ret = MEMORY_E;
break; break;
}
} }
mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]); 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); intTotalLen += (sizes[i] = mpSz);
} }
if (ret != 0) { if (ret == 0) {
FreeTmpRsas(tmps, key->heap); /* make headers */
return ret; verSz = SetMyVersion(0, ver, FALSE);
seqSz = SetSequence(verSz + intTotalLen, seq);
outLen = seqSz + verSz + intTotalLen;
if (output != NULL && outLen > (int)inLen)
ret = BUFFER_E;
} }
if (ret == 0 && output != NULL) {
/* 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;
}
/* write to output */ /* write to output */
XMEMCPY(output, seq, seqSz); XMEMCPY(output, seq, seqSz);
j = seqSz; j = seqSz;
@@ -12223,13 +12184,17 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
j += sizes[i]; 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 /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
written */ written */
int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen) 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 #else
byte priv[ECC_MAXSIZE+1]; byte priv[ECC_MAXSIZE+1];
byte pub[2*(ECC_MAXSIZE+1)]; /* public key has two parts plus header */ 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 #endif
byte* pubData = NULL; byte* pubData = NULL;
if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0)
return BAD_FUNC_ARG; 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) if (GetSequence(input, inOutIdx, &length, inSz) < 0)
return ASN_PARSE_E; 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) #if defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
/* build DER formatted ECC key, include optional public key if requested, /* build DER formatted ECC key, include optional public key if requested,
* return length on success, negative on error */ * return length on success, negative on error */
static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen, static int wc_BuildEccKeyDer_ex(ecc_key* key, byte* output, word32 *inLen,
int pubIn) int pubIn, int curveIn)
{ {
byte curve[MAX_ALGO_SZ+2]; byte curve[MAX_ALGO_SZ+2];
byte ver[MAX_VERSION_SZ]; 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)) if (key == NULL || (output == NULL && inLen == NULL))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
/* curve */ if (curveIn) {
curve[curveidx++] = ECC_PREFIX_0; /* curve */
curveidx++ /* to put the size after computation */; curve[curveidx++] = ECC_PREFIX_0;
curveSz = SetCurve(key, curve+curveidx); curveidx++ /* to put the size after computation */;
if (curveSz < 0) curveSz = SetCurve(key, curve+curveidx);
return curveSz; if (curveSz < 0)
/* set computed size */ return curveSz;
curve[1] = (byte)curveSz; /* set computed size */
curveidx += curveSz; curve[1] = (byte)curveSz;
curveidx += curveSz;
}
/* private */ /* private */
privSz = key->dp->size; privSz = key->dp->size;
@@ -16987,6 +16964,12 @@ static int wc_BuildEccKeyDer(ecc_key* key, byte* output, word32 *inLen,
return totalSz; 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, /* Write a Private ecc key, including public to DER format,
* length on success else < 0 */ * length on success else < 0 */
int wc_EccKeyToDer(ecc_key* key, byte* output, word32 inLen) 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 #endif
XMEMSET(tmpDer, 0, ECC_BUFSIZE); XMEMSET(tmpDer, 0, ECC_BUFSIZE);
tmpDerSz = wc_BuildEccKeyDer(key, tmpDer, &sz, includePublic); /* The outer PKCS8 has the curve info (so don't include here */
if (tmpDerSz < 0) { ret = wc_BuildEccKeyDer_ex(key, tmpDer, &sz, includePublic, 0);
if (ret < 0) {
#ifndef WOLFSSL_NO_MALLOC #ifndef WOLFSSL_NO_MALLOC
XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpDer, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif #endif
return tmpDerSz; return ret;
} }
tmpDerSz = ret;
/* get pkcs8 expected output size */ /* get pkcs8 expected output size */
ret = wc_CreatePKCS8Key(NULL, &pkcs8Sz, tmpDer, tmpDerSz, algoID, 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 */ #endif /* HAVE_AESGCM */
/* returns WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */ /* 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, unsigned char *out, int *outl,
const unsigned char *in, int inl) 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 * 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 * 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. */ * 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) unsigned char *out, int *outl)
{ {
int fl; int fl;
@@ -1772,7 +1772,7 @@ int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx)
* RETURNS: * RETURNS:
* returns WOLFSSL_SUCCESS on success, otherwise returns -2 * 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; 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 * 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) size_t *siglen, const unsigned char *tbs, size_t tbslen)
{ {
int len = 0; int len = 0;
@@ -2037,7 +2037,7 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to,
} }
#ifndef NO_WOLFSSL_STUB #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; (void)pkey;
/* not using missing params callback and returning zero to indicate success */ /* 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 * define WOLFSSL_ERROR_CODE_OPENSSL so that WS_RETURN_CODE translates return
* codes to match OpenSSL equivalent behavior. * 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 ret = -1; /* failure */
int a_sz = 0, b_sz = 0; 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); 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, const WOLFSSL_EVP_MD* type,
WOLFSSL_ENGINE *impl) WOLFSSL_ENGINE *impl)
{ {
@@ -3076,7 +3076,7 @@ int wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
#endif /* !NO_PWDBASED !NO_SHA*/ #endif /* !NO_PWDBASED !NO_SHA*/
#if !defined(NO_PWDBASED) #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, const unsigned char *salt,
int saltlen, int iter, int saltlen, int iter,
const WOLFSSL_EVP_MD *digest, const WOLFSSL_EVP_MD *digest,
@@ -3676,7 +3676,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
return ctx; 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) { if (ctx) {
WOLFSSL_ENTER("EVP_MD_CTX_free"); 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) 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)
int derMax = 0; int ret;
int derSz = 0; int derSz = 0;
int pkcs8Sz = 0;
byte* derBuf = NULL; byte* derBuf = NULL;
RsaKey* rsa = NULL; RsaKey* rsa = NULL;
#endif #endif
WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA"); WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_RSA");
if ((pkey == NULL) || (key == NULL)) if (pkey == NULL || key == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) { if (wolfSSL_RSA_up_ref(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("wolfSSL_RSA_up_ref failed"); WOLFSSL_MSG("wolfSSL_RSA_up_ref failed");
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
if (pkey->rsa != NULL && pkey->ownRsa == 1) { if (pkey->rsa != NULL && pkey->ownRsa == 1) {
wolfSSL_RSA_free(pkey->rsa); wolfSSL_RSA_free(pkey->rsa);
} }
pkey->rsa = key; pkey->rsa = key;
pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */ pkey->ownRsa = 1; /* pkey does not own RSA but needs to call free on it */
pkey->type = EVP_PKEY_RSA; pkey->type = EVP_PKEY_RSA;
pkey->hasPkcs8Header = key->hasPkcs8Header;
if (key->inSet == 0) { if (key->inSet == 0) {
if (SetRsaInternal(key) != WOLFSSL_SUCCESS) { if (SetRsaInternal(key) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetRsaInternal failed"); 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; 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) { if (rsa->type == RSA_PRIVATE) {
/* Private key to DER */ ret = wc_RsaKeyToDer(rsa, NULL, 0);
derSz = wc_RsaKeyToDer(rsa, derBuf, derMax); 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 { else {
/* Public key to DER */ ret = wc_RsaKeyToPublicDer(rsa, NULL, 0);
derSz = wc_RsaKeyToPublicDer(rsa, derBuf, derMax); 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) { 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 { 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; return WOLFSSL_FAILURE;
} }
pkey->pkey.ptr = (char*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER); pkey->pkey.ptr = (char*)derBuf;
if (pkey->pkey.ptr == NULL) {
WOLFSSL_MSG("key malloc failed");
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
pkey->pkey_sz = derSz; pkey->pkey_sz = derSz;
XMEMCPY(pkey->pkey.ptr, derBuf, derSz); #endif /* (WOLFSSL_KEY_GEN || OPENSSL_EXTRA) && !HAVE_USER_RSA */
XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */
#ifdef WC_RSA_BLINDING #ifdef WC_RSA_BLINDING
if (key->ownRng == 0) { 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"); WOLFSSL_MSG("Error setting RSA rng");
return WOLFSSL_FAILURE; 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 (key->type == EVP_PKEY_EC) {
if (wolfSSL_EC_KEY_LoadDer(local, (const unsigned char*)key->pkey.ptr, 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 */ /* now try public key */
if (wolfSSL_EC_KEY_LoadDer_ex(local, if (wolfSSL_EC_KEY_LoadDer_ex(local,
(const unsigned char*)key->pkey.ptr, (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); wolfSSL_EC_KEY_free(local);
local = NULL; local = NULL;
@@ -6511,32 +6548,60 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key)
#if defined(HAVE_ECC) #if defined(HAVE_ECC)
/* try and populate public pkey_sz and pkey.ptr */ /* 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; int derSz = 0;
if (!pkey || !ecc) ecc_key* ecc;
if (pkey == NULL || key == NULL || key->internal == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
if (wc_EccKeyToPKCS8(ecc, NULL, &derSz) == LENGTH_ONLY_E) {
byte* derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); ecc = (ecc_key*)key->internal;
if (derBuf) { if (key->hasPkcs8Header) {
if (wc_EccKeyToPKCS8(ecc, derBuf, &derSz) >= 0) { /* when key has pkcs8 header the pkey should too */
if (pkey->pkey.ptr) { if (wc_EccKeyToPKCS8(ecc, NULL, (word32*)&derSz) == LENGTH_ONLY_E) {
XFREE(pkey->pkey.ptr, NULL, DYNAMIC_TYPE_OPENSSL); 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; 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 #ifdef HAVE_ECC
if((pkey == NULL) || (key ==NULL))return WOLFSSL_FAILURE; 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->ecc = key;
pkey->ownEcc = 0; /* pkey does not own EC key */ pkey->ownEcc = 0; /* pkey does not own EC key */
pkey->type = EVP_PKEY_EC; pkey->type = EVP_PKEY_EC;
return ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); return ECC_populate_EVP_PKEY(pkey, key);
#else #else
(void)pkey; (void)pkey;
(void)key; (void)key;
@@ -6601,7 +6666,7 @@ int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key)
pkey->ownEcc = 1; pkey->ownEcc = 1;
/* try and populate public pkey_sz and pkey.ptr */ /* 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 */ #endif /* HAVE_ECC */

View File

@@ -137,6 +137,13 @@ void* wolfSSL_Malloc(size_t size)
} }
else { else {
#ifndef WOLFSSL_NO_MALLOC #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); res = malloc(size);
#else #else
WOLFSSL_MSG("No malloc available"); WOLFSSL_MSG("No malloc available");

View File

@@ -117,10 +117,13 @@ struct WOLFSSL_EC_KEY {
WOLFSSL_BIGNUM *priv_key; WOLFSSL_BIGNUM *priv_key;
void* internal; /* our ECC 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 char form; /* Either POINT_CONVERSION_UNCOMPRESSED or
* POINT_CONVERSION_COMPRESSED */ * 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 { struct WOLFSSL_EC_BUILTIN_CURVE {

View File

@@ -77,9 +77,6 @@ typedef struct WOLFSSL_RSA {
WOLFSSL_BIGNUM* iqmp; /* u */ WOLFSSL_BIGNUM* iqmp; /* u */
void* heap; void* heap;
void* internal; /* our RSA */ 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) #if defined(OPENSSL_EXTRA)
WOLFSSL_RSA_METHOD* meth; WOLFSSL_RSA_METHOD* meth;
#endif #endif
@@ -90,6 +87,12 @@ typedef struct WOLFSSL_RSA {
wolfSSL_Mutex refMutex; /* ref count mutex */ wolfSSL_Mutex refMutex; /* ref count mutex */
int refCount; /* reference count */ int refCount; /* reference count */
#endif #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; } WOLFSSL_RSA;
#endif #endif

View File

@@ -352,28 +352,31 @@ struct WOLFSSL_EVP_PKEY {
union { union {
char* ptr; /* der format of key / or raw for NTRU */ char* ptr; /* der format of key / or raw for NTRU */
} pkey; } pkey;
#if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
#ifndef NO_RSA #ifndef NO_RSA
WOLFSSL_RSA* rsa; WOLFSSL_RSA* rsa;
byte ownRsa; /* if struct owns RSA and should free it */
#endif #endif
#ifndef NO_DSA #ifndef NO_DSA
WOLFSSL_DSA* dsa; WOLFSSL_DSA* dsa;
byte ownDsa; /* if struct owns DSA and should free it */
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
WOLFSSL_EC_KEY* ecc; WOLFSSL_EC_KEY* ecc;
byte ownEcc; /* if struct owns ECC and should free it */
#endif #endif
#ifndef NO_DH #ifndef NO_DH
WOLFSSL_DH* dh; WOLFSSL_DH* dh;
byte ownDh; /* if struct owns DH and should free it */
#endif #endif
WC_RNG rng; WC_RNG rng;
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef HAVE_ECC #ifdef HAVE_ECC
int pkey_curve; int pkey_curve;
#endif #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; typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO;
#ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ #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 #ifdef WOLFSSL_PEM_TO_DER
WOLFSSL_API int wc_PemToDer(const unsigned char* buff, long longSz, int type, 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, WOLFSSL_API int wc_KeyPemToDer(const unsigned char*, int,
unsigned char*, int, const char*); unsigned char*, int, const char*);

View File

@@ -294,7 +294,7 @@ WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx,
RsaKey*, word32); RsaKey*, word32);
WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz,
const byte* e, word32 eSz, RsaKey* key); 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); WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen);
#endif #endif