mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
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:
80
src/ssl.c
80
src/ssl.c
@ -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);
|
||||
|
120
tests/api.c
120
tests/api.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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*);
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user