Merge pull request #5608 from SparkiDev/pk_c_rework_2

pull/5774/head
Hayden Roche 2022-11-04 13:32:36 -07:00 committed by GitHub
commit 4a917219f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 4141 additions and 2748 deletions

View File

@ -1612,7 +1612,7 @@ int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
{
int len;
#ifndef NO_FILESYSTEM
long memSz = 0, curr = 0;
long memSz = 0;
XFILE file;
#endif
@ -1628,26 +1628,11 @@ int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
else if (bio->type == WOLFSSL_BIO_FILE) {
if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
len = BAD_FUNC_ARG;
if (file == NULL)
len = WOLFSSL_BAD_FILE;
if (len == 0) {
curr = XFTELL(file);
if (curr < 0) {
len = WOLFSSL_BAD_FILE;
}
if (XFSEEK(file, 0, XSEEK_END) != 0)
len = WOLFSSL_BAD_FILE;
len = wolfssl_file_len(file, &memSz);
}
if (len == 0) {
memSz = XFTELL(file);
if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0)
len = WOLFSSL_BAD_FILE;
}
if (len == 0) {
memSz -= curr;
len = (int)memSz;
if (XFSEEK(file, curr, SEEK_SET) != 0)
len = WOLFSSL_BAD_FILE;
}
}
#endif

View File

@ -18,6 +18,7 @@ MAINTAINERCLEANFILES+= $(FIPS_FILES)
EXTRA_DIST += src/bio.c
EXTRA_DIST += src/conf.c
EXTRA_DIST += src/ssl_misc.c
EXTRA_DIST += src/pk.c
EXTRA_DIST += src/x509.c
EXTRA_DIST += src/x509_str.c

View File

@ -32188,7 +32188,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
/* Final cleanup */
if (
#ifdef WOLFSSL_ASYNC_IO
args != NULL &&
args != NULL &&
#endif
args->input != NULL) {
XFREE(args->input, ssl->heap, DYNAMIC_TYPE_IN_BUFFER);

4314
src/pk.c

File diff suppressed because it is too large Load Diff

564
src/ssl.c
View File

@ -189,6 +189,9 @@
* wolfSSL_CTX_load_system_CA_certs.
*/
#define WOLFSSL_SSL_MISC_INCLUDED
#include "src/ssl_misc.c"
#define WOLFSSL_EVP_INCLUDED
#include "wolfcrypt/src/evp.c"
@ -2147,6 +2150,49 @@ int wolfSSL_SetMinRsaKey_Sz(WOLFSSL* ssl, short keySz)
#endif /* !NO_RSA */
#ifndef NO_DH
#ifdef OPENSSL_EXTRA
long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh)
{
int pSz, gSz;
byte *p, *g;
int ret = 0;
WOLFSSL_ENTER("wolfSSL_set_tmp_dh");
if (!ssl || !dh)
return BAD_FUNC_ARG;
/* Get needed size for p and g */
pSz = wolfSSL_BN_bn2bin(dh->p, NULL);
gSz = wolfSSL_BN_bn2bin(dh->g, NULL);
if (pSz <= 0 || gSz <= 0)
return -1;
p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (!p)
return MEMORY_E;
g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (!g) {
XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
return MEMORY_E;
}
pSz = wolfSSL_BN_bn2bin(dh->p, p);
gSz = wolfSSL_BN_bn2bin(dh->g, g);
if (pSz >= 0 && gSz >= 0) /* Conversion successful */
ret = wolfSSL_SetTmpDH(ssl, p, pSz, g, gSz);
XFREE(p, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(g, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
return pSz > 0 && gSz > 0 ? ret : -1;
}
#endif /* OPENSSL_EXTRA */
/* server Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */
int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
const unsigned char* g, int gSz)
@ -5547,7 +5593,8 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
#endif /* !NO_SESSION_CACHE */
#if !defined(WC_NO_RNG) && (defined(OPENSSL_EXTRA) || \
(defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA)))
(defined(OPENSSL_EXTRA_X509_SMALL) && !defined(NO_RSA)) || \
(defined(OPENSSL_ALL) && !defined(NO_DH)))
#define HAVE_GLOBAL_RNG /* consolidate flags for using globalRNG */
static WC_RNG globalRNG;
@ -9044,7 +9091,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
static WOLFSSL_EVP_PKEY* d2iGenericKey(WOLFSSL_EVP_PKEY** out,
const unsigned char** in, long inSz, int priv)
const unsigned char** in, long inSz, int priv)
{
WOLFSSL_EVP_PKEY* pkey = NULL;
@ -9102,20 +9149,13 @@ static WOLFSSL_EVP_PKEY* d2iGenericKey(WOLFSSL_EVP_PKEY** out,
}
pkey->ownRsa = 1;
pkey->rsa = wolfSSL_RSA_new();
pkey->rsa = wolfssl_rsa_d2i(NULL, mem, inSz,
priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC);
if (pkey->rsa == NULL) {
wolfSSL_EVP_PKEY_free(pkey);
return NULL;
}
if (wolfSSL_RSA_LoadDer_ex(pkey->rsa,
(const unsigned char*)pkey->pkey.ptr,
pkey->pkey_sz, priv ? WOLFSSL_RSA_LOAD_PRIVATE
: WOLFSSL_RSA_LOAD_PUBLIC) != 1) {
wolfSSL_EVP_PKEY_free(pkey);
return NULL;
}
return pkey;
}
else {
@ -9858,16 +9898,11 @@ static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out,
switch (type) {
#ifndef NO_RSA
case EVP_PKEY_RSA:
local->ownRsa = 1;
local->rsa = wolfSSL_RSA_new();
if (local->rsa == NULL) {
wolfSSL_EVP_PKEY_free(local);
return NULL;
}
opt = priv ? WOLFSSL_RSA_LOAD_PRIVATE : WOLFSSL_RSA_LOAD_PUBLIC;
if (wolfSSL_RSA_LoadDer_ex(local->rsa,
(const unsigned char*)local->pkey.ptr, local->pkey_sz,
opt) != WOLFSSL_SUCCESS) {
local->ownRsa = 1;
local->rsa = wolfssl_rsa_d2i(NULL,
(const unsigned char*)local->pkey.ptr, local->pkey_sz, opt);
if (local->rsa == NULL) {
wolfSSL_EVP_PKEY_free(local);
return NULL;
}
@ -28154,16 +28189,16 @@ int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher,
}
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
#ifndef NO_BIO
static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
#if !defined(NO_BIO)
static int pem_write_pubkey(WOLFSSL_EVP_PKEY* key, void* heap, byte** derBuf,
int* derSz)
{
int ret;
int pemSz;
byte* pemBuf;
int derSz = 0;
byte* derBuf = NULL;
byte* buf = NULL;
int sz = 0;
if (bio == NULL || key == NULL) {
(void)heap;
if (key == NULL) {
WOLFSSL_MSG("Bad parameters");
return WOLFSSL_FAILURE;
}
@ -28171,7 +28206,7 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
switch (key->type) {
#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)
case EVP_PKEY_RSA:
if ((derSz = wolfSSL_RSA_To_Der(key->rsa, &derBuf, 1, bio->heap))
if ((sz = wolfSSL_RSA_To_Der(key->rsa, &buf, 1, heap))
< 0) {
WOLFSSL_MSG("wolfSSL_RSA_To_Der failed");
break;
@ -28185,16 +28220,15 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
WOLFSSL_MSG("key->dsa is null");
break;
}
derSz = MAX_DSA_PUBKEY_SZ;
derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
sz = MAX_DSA_PUBKEY_SZ;
buf = (byte*)XMALLOC(sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL) {
WOLFSSL_MSG("malloc failed");
break;
}
/* Key to DER */
derSz = wc_DsaKeyToPublicDer((DsaKey*)key->dsa->internal, derBuf,
derSz);
if (derSz < 0) {
sz = wc_DsaKeyToPublicDer((DsaKey*)key->dsa->internal, buf, sz);
if (sz < 0) {
WOLFSSL_MSG("wc_DsaKeyToDer failed");
break;
}
@ -28207,19 +28241,18 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
WOLFSSL_MSG("key->ecc is null");
break;
}
derSz = wc_EccPublicKeyDerSize((ecc_key*)key->ecc->internal, 1);
if (derSz <= 0) {
sz = wc_EccPublicKeyDerSize((ecc_key*)key->ecc->internal, 1);
if (sz <= 0) {
WOLFSSL_MSG("wc_EccPublicKeyDerSize failed");
break;
}
derBuf = (byte*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
buf = (byte*)XMALLOC(sz, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (buf == NULL) {
WOLFSSL_MSG("malloc failed");
break;
}
derSz = wc_EccPublicKeyToDer((ecc_key*)key->ecc->internal, derBuf,
derSz, 1);
if (derSz < 0) {
sz = wc_EccPublicKeyToDer((ecc_key*)key->ecc->internal, buf, sz, 1);
if (sz < 0) {
WOLFSSL_MSG("wc_EccPublicKeyToDer failed");
break;
}
@ -28236,52 +28269,51 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
break;
}
if (derBuf == NULL || derSz <= 0) {
if (derBuf != NULL)
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
return WOLFSSL_FAILURE;
}
pemSz = wc_DerToPem(derBuf, derSz, NULL, 0, PUBLICKEY_TYPE);
if (pemSz < 0) {
WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
return WOLFSSL_FAILURE;
}
pemBuf = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBuf == NULL) {
WOLFSSL_LEAVE("pem_write_bio_pubkey", pemSz);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
return WOLFSSL_FAILURE;
}
ret = wc_DerToPem(derBuf, derSz, pemBuf, pemSz, PUBLICKEY_TYPE);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
if (ret < 0) {
WOLFSSL_LEAVE("pem_write_bio_pubkey", ret);
XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
ret = wolfSSL_BIO_write(bio, pemBuf, pemSz);
XFREE(pemBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (ret != pemSz) {
WOLFSSL_MSG("Unable to write full PEM to BIO");
if (buf == NULL || sz <= 0) {
if (buf != NULL)
XFREE(buf, heap, DYNAMIC_TYPE_DER);
return WOLFSSL_FAILURE;
}
*derBuf = buf;
*derSz = sz;
return WOLFSSL_SUCCESS;
}
#endif
#ifndef NO_BIO
static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
{
int ret;
int derSz = 0;
byte* derBuf = NULL;
ret = pem_write_pubkey(key, bio->heap, &derBuf, &derSz);
if (ret == WOLFSSL_SUCCESS) {
ret = der_write_to_bio_as_pem(derBuf, derSz, bio, PUBLICKEY_TYPE);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
}
return ret;
}
/* Takes a public key and writes it out to a WOLFSSL_BIO
* Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE
*/
int wolfSSL_PEM_write_bio_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
{
int ret;
WOLFSSL_ENTER("wolfSSL_PEM_write_bio_PUBKEY");
return pem_write_bio_pubkey(bio, key);
if ((bio == NULL) || (key == NULL)) {
ret = WOLFSSL_FAILURE;
}
else {
ret = pem_write_bio_pubkey(bio, key);
}
return ret;
}
/* Takes a private key and writes it out to a WOLFSSL_BIO
@ -28293,10 +28325,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
wc_pem_password_cb* cb, void* arg)
{
byte* keyDer;
int pemSz;
int type;
int ret;
byte* tmp;
(void)cipher;
(void)passwd;
@ -28343,31 +28372,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
type = PRIVATEKEY_TYPE;
}
pemSz = wc_DerToPem(keyDer, key->pkey_sz, NULL, 0, type);
if (pemSz < 0) {
WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", pemSz);
return WOLFSSL_FAILURE;
}
tmp = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (tmp == NULL) {
return MEMORY_E;
}
ret = wc_DerToPem(keyDer, key->pkey_sz, tmp, pemSz, type);
if (ret < 0) {
WOLFSSL_LEAVE("wolfSSL_PEM_write_bio_PrivateKey", ret);
XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
return WOLFSSL_FAILURE;
}
ret = wolfSSL_BIO_write(bio, tmp, pemSz);
XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (ret != pemSz) {
WOLFSSL_MSG("Unable to write full PEM to BIO");
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
return der_write_to_bio_as_pem(keyDer, key->pkey_sz, bio, type);
}
#endif /* !NO_BIO */
@ -28618,171 +28623,6 @@ int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list)
#endif /* HAVE_ECC */
#ifndef NO_BIO
/* Number of bytes to read from a file at a time. */
#define PEM_READ_FILE_CHUNK_SZ 100
static int pem_read_bio_file(WOLFSSL_BIO* bio, char** pem)
{
int ret = 0;
int idx = 0;
int sz = PEM_READ_FILE_CHUNK_SZ; /* read from file by chunks */
int memSz = 0;
char* mem = NULL;
char* tmp;
/* Allocate a chunk to read into. */
tmp = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (tmp == NULL) {
WOLFSSL_MSG("Memory error");
ret = MEMORY_E;
}
while (ret == 0 && (sz = wolfSSL_BIO_read(bio, tmp, sz)) > 0) {
char* newMem;
/* sanity check for signed overflow */
if (memSz + sz < 0) {
break;
}
/* Reallocate to make space for read data. */
newMem = (char*)XREALLOC(mem, memSz + sz, bio->heap,
DYNAMIC_TYPE_OPENSSL);
if (newMem == NULL) {
WOLFSSL_MSG("Memory error");
ret = MEMORY_E;
break;
}
mem = newMem;
/* Copy in new data. */
XMEMCPY(mem + idx, tmp, sz);
memSz += sz;
idx += sz;
sz = PEM_READ_FILE_CHUNK_SZ; /* read another chunk from file */
}
XFREE(tmp, bio->heap, DYNAMIC_TYPE_OPENSSL);
tmp = NULL;
if (ret == 0) {
/* Check data was read. */
if (memSz <= 0) {
WOLFSSL_MSG("No data to read from bio");
ret = BUFFER_E;
}
else {
/* Return size of data read. */
ret = memSz;
}
}
/* Dispose of any allocated memory on error. */
if (ret < 0) {
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
mem = NULL;
}
*pem = mem;
return ret;
}
static int pem_read_bio_pending(WOLFSSL_BIO* bio, int pendingSz, char** pem)
{
int ret = 0;
char* mem;
/* Allocate buffer to hold pending data. */
mem = (char*)XMALLOC(pendingSz, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (mem == NULL) {
WOLFSSL_MSG("Memory error");
ret = MEMORY_E;
}
else if ((ret = wolfSSL_BIO_read(bio, mem, pendingSz)) <= 0) {
/* Pending data not read. */
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
mem = NULL;
ret = MEMORY_E;
}
*pem = mem;
return ret;
}
static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
void* pass, int keyType, int* eccFlag,
DerBuffer** der)
{
#ifdef WOLFSSL_SMALL_STACK
EncryptedInfo* info = NULL;
#else
EncryptedInfo info[1];
#endif /* WOLFSSL_SMALL_STACK */
wc_pem_password_cb* localCb = NULL;
char* mem = NULL;
int ret;
if (cb != NULL) {
localCb = cb;
}
else if (pass != NULL) {
localCb = wolfSSL_PEM_def_callback;
}
if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
ret = pem_read_bio_pending(bio, ret, &mem);
}
else if (bio->type == WOLFSSL_BIO_FILE) {
ret = pem_read_bio_file(bio, &mem);
}
else {
WOLFSSL_MSG("No data to read from bio");
ret = NOT_COMPILED_IN;
}
#ifdef WOLFSSL_SMALL_STACK
if (ret >= 0) {
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (info == NULL) {
WOLFSSL_MSG("Error getting memory for EncryptedInfo structure");
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
mem = NULL;
ret = MEMORY_E;
}
}
#endif /* WOLFSSL_SMALL_STACK */
if (ret >= 0) {
int memSz = ret;
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");
}
/* Write left over data back to BIO if not a file BIO */
else if ((memSz - (int)info->consumed) > 0 &&
bio->type != WOLFSSL_BIO_FILE) {
if (wolfSSL_BIO_write(bio, mem + (int)info->consumed,
memSz - (int)info->consumed) <= 0) {
WOLFSSL_MSG("Unable to advance bio read pointer");
}
}
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
return ret;
}
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
WOLFSSL_EVP_PKEY** key,
wc_pem_password_cb* cb,
@ -28798,8 +28638,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
if (bio == NULL)
return pkey;
if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
&der) >= 0) {
if (pem_read_bio_key(bio, cb, pass, PRIVATEKEY_TYPE, &keyFormat, &der)
>= 0) {
const unsigned char* ptr = der->buffer;
if (keyFormat) {
@ -28852,7 +28692,8 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
if (bio == NULL)
return pkey;
if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der) >= 0) {
if (pem_read_bio_key(bio, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der)
>= 0) {
const unsigned char* ptr = der->buffer;
/* handle case where reuse is attempted */
@ -28874,41 +28715,42 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_bio_PUBKEY(WOLFSSL_BIO* bio,
return pkey;
}
#endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM)
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **x,
wc_pem_password_cb *cb, void *u)
WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, WOLFSSL_EVP_PKEY **key,
wc_pem_password_cb *cb, void *pass)
{
int err = 0;
WOLFSSL_EVP_PKEY* ret = NULL;
WOLFSSL_BIO* bio = NULL;
WOLFSSL_EVP_PKEY* pkey = NULL;
DerBuffer* der = NULL;
int keyFormat = 0;
WOLFSSL_ENTER("wolfSSL_PEM_read_PUBKEY");
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_PUBKEY");
if (fp == XBADFILE) {
err = 1;
}
if (err == 0) {
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
err = bio == NULL;
}
if (err == 0) {
err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
}
if (err == 0) {
ret = wolfSSL_PEM_read_bio_PUBKEY(bio, x, cb, u);
if (pem_read_file_key(fp, cb, pass, PUBLICKEY_TYPE, &keyFormat, &der)
>= 0) {
const unsigned char* ptr = der->buffer;
/* handle case where reuse is attempted */
if (key != NULL && *key != NULL)
pkey = *key;
wolfSSL_d2i_PUBKEY(&pkey, &ptr, der->length);
if (pkey == NULL) {
WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
}
}
if (bio != NULL) {
wolfSSL_BIO_free(bio);
}
FreeDer(&der);
WOLFSSL_LEAVE("wolfSSL_PEM_read_PUBKEY", 0);
if (key != NULL && pkey != NULL)
*key = pkey;
return ret;
WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_PUBKEY", 0);
return pkey;
}
#endif /* NO_FILESYSTEM */
#endif /* !NO_BIO */
#endif /* OPENSSL_EXTRA */
#ifdef WOLFSSL_ALT_CERT_CHAINS
@ -29768,39 +29610,57 @@ int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)
#if !defined(NO_FILESYSTEM)
#ifndef NO_BIO
WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_PrivateKey(XFILE fp,
WOLFSSL_EVP_PKEY **x, wc_pem_password_cb *cb, void *u)
WOLFSSL_EVP_PKEY **key, wc_pem_password_cb *cb, void *pass)
{
int err = 0;
WOLFSSL_EVP_PKEY* ret = NULL;
WOLFSSL_BIO* bio = NULL;
WOLFSSL_EVP_PKEY* pkey = NULL;
DerBuffer* der = NULL;
int keyFormat = 0;
int type = -1;
WOLFSSL_ENTER("wolfSSL_PEM_read_PrivateKey");
if (fp == XBADFILE) {
err = 1;
}
if (err == 0) {
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
err = bio == NULL;
}
if (err == 0) {
err = wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS;
}
if (err == 0) {
ret = wolfSSL_PEM_read_bio_PrivateKey(bio, x, cb, u);
if (pem_read_file_key(fp, cb, pass, PRIVATEKEY_TYPE, &keyFormat,
&der) >= 0) {
const unsigned char* ptr = der->buffer;
if (keyFormat) {
/* keyFormat is Key_Sum enum */
if (keyFormat == RSAk)
type = EVP_PKEY_RSA;
else if (keyFormat == ECDSAk)
type = EVP_PKEY_EC;
else if (keyFormat == DSAk)
type = EVP_PKEY_DSA;
else if (keyFormat == DHk)
type = EVP_PKEY_DH;
}
else {
/* Default to RSA if format is not set */
type = EVP_PKEY_RSA;
}
/* handle case where reuse is attempted */
if (key != NULL && *key != NULL)
pkey = *key;
wolfSSL_d2i_PrivateKey(type, &pkey, &ptr, der->length);
if (pkey == NULL) {
WOLFSSL_MSG("Error loading DER buffer into WOLFSSL_EVP_PKEY");
}
}
if (bio != NULL) {
wolfSSL_BIO_free(bio);
}
FreeDer(&der);
return ret;
if (key != NULL && pkey != NULL)
*key = pkey;
WOLFSSL_LEAVE("wolfSSL_PEM_read_PrivateKey", 0);
return pkey;
}
#endif
#endif
#endif
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL*/
@ -30061,15 +29921,10 @@ int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
if (name == NULL || header == NULL || data == NULL || len == NULL)
return WOLFSSL_FAILURE;
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
bio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE);
if (bio == NULL)
return 0;
if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
wolfSSL_BIO_free(bio);
bio = NULL;
}
ret = wolfSSL_PEM_read_bio(bio, name, header, data, len);
if (bio != NULL)
@ -30087,15 +29942,10 @@ int wolfSSL_ASN1_STRING_canon(WOLFSSL_ASN1_STRING* asn_out,
if (name == NULL || header == NULL || data == NULL)
return 0;
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
bio = wolfSSL_BIO_new_fp(fp, BIO_NOCLOSE);
if (bio == NULL)
return 0;
if (wolfSSL_BIO_set_fp(bio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
wolfSSL_BIO_free(bio);
bio = NULL;
}
ret = wolfSSL_PEM_write_bio(bio, name, header, data, len);
if (bio != NULL)
@ -34581,32 +34431,33 @@ static int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names)
goto leave;
XMEMCPY(name, names + start, len);
name[len] = 0;
name[len++] = 0;
if ((XSTRCMP(name, "prime256v1") == 0) ||
(XSTRCMP(name, "secp256r1") == 0) ||
(XSTRCMP(name, "P-256") == 0))
/* Use XSTRNCMP to avoid valgrind error. */
if ((XSTRNCMP(name, "prime256v1", len) == 0) ||
(XSTRNCMP(name, "secp256r1", len) == 0) ||
(XSTRNCMP(name, "P-256", len) == 0))
{
curve = WOLFSSL_ECC_SECP256R1;
}
else if ((XSTRCMP(name, "secp384r1") == 0) ||
(XSTRCMP(name, "P-384") == 0))
else if ((XSTRNCMP(name, "secp384r1", len) == 0) ||
(XSTRNCMP(name, "P-384", len) == 0))
{
curve = WOLFSSL_ECC_SECP384R1;
}
else if ((XSTRCMP(name, "secp521r1") == 0) ||
(XSTRCMP(name, "P-521") == 0))
else if ((XSTRNCMP(name, "secp521r1", len) == 0) ||
(XSTRNCMP(name, "P-521", len) == 0))
{
curve = WOLFSSL_ECC_SECP521R1;
}
#ifdef HAVE_CURVE25519
else if (XSTRCMP(name, "X25519") == 0)
else if (XSTRNCMP(name, "X25519", len) == 0)
{
curve = WOLFSSL_ECC_X25519;
}
#endif
#ifdef HAVE_CURVE448
else if (XSTRCMP(name, "X448") == 0)
else if (XSTRNCMP(name, "X448", len) == 0)
{
curve = WOLFSSL_ECC_X448;
}
@ -37975,41 +37826,8 @@ static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
{
int ret = 0;
byte* mem = NULL;
#ifndef NO_FILESYSTEM
long memSz;
XFILE file;
long curr;
#endif
if ((ret = wolfSSL_BIO_pending(bio)) > 0) {
}
#ifndef NO_FILESYSTEM
else if (bio->type == WOLFSSL_BIO_FILE) {
if (wolfSSL_BIO_get_fp(bio, &file) != WOLFSSL_SUCCESS)
ret = BAD_FUNC_ARG;
if (ret == 0) {
curr = XFTELL(file);
if (curr < 0) {
ret = WOLFSSL_BAD_FILE;
}
if (XFSEEK(file, 0, XSEEK_END) != 0)
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
memSz = XFTELL(file);
if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
ret = WOLFSSL_BAD_FILE;
}
}
if (ret == 0) {
memSz -= curr;
ret = (int)memSz;
if (XFSEEK(file, curr, SEEK_SET) != 0)
ret = WOLFSSL_BAD_FILE;
}
}
#endif
ret = wolfSSL_BIO_get_len(bio);
if (ret > 0) {
mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (mem == NULL) {

296
src/ssl_misc.c 100644
View File

@ -0,0 +1,296 @@
/* ssl_misc.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if !defined(WOLFSSL_SSL_MISC_INCLUDED)
#ifndef WOLFSSL_IGNORE_FILE_WARN
#warning ssl_misc.c does not need to be compiled separately from ssl.c
#endif
#else
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
#ifndef NO_BIO
#ifdef WOLFSSL_NO_FSEEK
/* Amount of memory to allocate/add. */
#define READ_BIO_FILE_CHUNK 128
/* Read a file in chunks.
*
* Allocates a chunk and reads into it until it is full.
*
* @param [in, out] bio BIO object to read with.
* @param [out] data Read data in a new buffer.
* @return Negative on error.
* @return Number of bytes read on success.
*/
static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** data)
{
int ret = 0;
char* mem;
char* p;
/* Allocate buffer to hold a chunk of data. */
mem = (char*)XMALLOC(READ_BIO_FILE_CHUNK, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (mem == NULL) {
WOLFSSL_ERROR_MSG("Memory allocation error");
ret = MEMORY_E;
}
if (ret == 0) {
int sz;
/* ret is the number of bytes read and is zero. */
/* p is where to read in next chunk. */
p = mem;
/* Memory available to read into is one chunk. */
sz = READ_BIO_FILE_CHUNK;
/* Keep reading in chunks until no more or an error. */
while ((sz = wolfSSL_BIO_read(bio, p, sz)) > 0) {
int remaining;
/* Update total read. */
ret += sz;
/* Calculate remaining unused memory. */
remaining = READ_BIO_FILE_CHUNK - (ret % READ_BIO_FILE_CHUNK);
/* Check for space remaining. */
if (remaining != READ_BIO_FILE_CHUNK) {
/* Update where data is read into. */
p += sz;
/* Maximum possible size is the remaining buffer size. */
sz = remaining;
}
else {
/* No space left for more data to be read - add a chunk. */
p = (char*)XREALLOC(mem, ret + READ_BIO_FILE_CHUNK, bio->heap,
DYNAMIC_TYPE_OPENSSL);
if (p == NULL) {
sz = MEMORY_E;
break;
}
/* Set mem to new pointer. */
mem = p;
/* Set p to where to read in next chunk. */
p += ret;
/* Read in a new chunk. */
sz = READ_BIO_FILE_CHUNK;
}
}
if ((sz < 0) || (ret == 0)) {
/* Dispose of memory on error or no data read. */
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
mem = NULL;
/* Return error. */
ret = sz;
}
}
*data = mem;
return ret;
}
#endif
/* Read exactly the required amount into a newly allocated buffer.
*
* @param [in, out] bio BIO object to read with.
* @param [in sz Amount of data to read.
* @param [out] data Read data in a new buffer.
* @return Negative on error.
* @return Number of bytes read on success.
*/
static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** data)
{
int ret = 0;
char* mem;
/* Allocate buffer to hold data. */
mem = (char*)XMALLOC(sz, bio->heap, DYNAMIC_TYPE_OPENSSL);
if (mem == NULL) {
WOLFSSL_ERROR_MSG("Memory allocation error");
ret = MEMORY_E;
}
else if ((ret = wolfSSL_BIO_read(bio, mem, sz)) != sz) {
/* Pending data not read. */
XFREE(mem, bio->heap, DYNAMIC_TYPE_OPENSSL);
mem = NULL;
ret = MEMORY_E;
}
*data = mem;
return ret;
}
/* Read all the data from a BIO.
*
* @param [in, out] bio BIO object to read with.
* @param [out] data Read data in a buffer.
* @param [out] dataSz Amount of data read in bytes.
* @param [out] memAlloced Indicates whether return buffer was allocated.
* @return Negative on error.
* @return 0 on success.
*/
static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** data, int* dataSz,
int* memAlloced)
{
int ret;
int sz;
if (bio->type == WOLFSSL_BIO_MEMORY) {
ret = wolfSSL_BIO_get_mem_data(bio, data);
if (ret > 0) {
bio->rdIdx += ret;
}
*memAlloced = 0;
}
#ifndef WOLFSSL_NO_FSEEK
/* Get pending or, when a file BIO, get length of file. */
else if ((sz = wolfSSL_BIO_get_len(bio)) > 0) {
ret = wolfssl_read_bio_len(bio, sz, data);
if (ret > 0) {
*memAlloced = 1;
}
}
#else
else if ((sz = wolfSSL_BIO_pending(bio)) > 0) {
ret = wolfssl_read_bio_len(bio, sz, data);
if (ret > 0) {
*memAlloced = 1;
}
}
else if (bio->type == WOLFSSL_BIO_FILE) {
ret = wolfssl_read_bio_file(bio, data);
if (ret > 0) {
*memAlloced = 1;
}
}
#endif
else {
WOLFSSL_ERROR_MSG("No data read from bio");
*memAlloced = 0;
ret = NOT_COMPILED_IN;
}
if (ret >= 0) {
*dataSz = ret;
ret = 0;
}
return ret;
}
#endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM)
/* Read all the data from a file.
*
* @param [in] fp File pointer to read with.
* @param [out] fileSz Amount of data remaining in file in bytes.
* @return WOLFSSL_BAD_FILE on error.
* @return 0 on success.
*/
static int wolfssl_file_len(XFILE fp, long* fileSz)
{
int ret = 0;
long sz = 0;
long curr = 0;
if (fp == XBADFILE) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
/* Get file offset at end of file. */
curr = (long)XFTELL(fp);
if (curr < 0) {
ret = WOLFSSL_BAD_FILE;
}
}
/* Move to end of file. */
if ((ret == 0) && (XFSEEK(fp, 0, SEEK_END) != 0)) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
/* Get file offset at end of file and subtract current offset. */
sz = (long)XFTELL(fp) - curr;
if (sz < 0) {
ret = WOLFSSL_BAD_FILE;
}
}
/* Go back to original offset in file. */
if ((ret == 0) && (XFSEEK(fp, curr, SEEK_SET) != 0)) {
ret = WOLFSSL_BAD_FILE;
}
/* Validate size. */
if ((ret == 0) && ((sz > MAX_WOLFSSL_FILE_SIZE) || (sz <= 0L))) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
*fileSz = sz;
}
return ret;
}
/* Read all the data from a file.
*
* @param [in] fp File pointer to read with.
* @param [out] data Read data in an allocated buffer.
* @param [out] dataSz Amount of data read in bytes.
* @return WOLFSSL_BAD_FILE when reading fails.
* @return MEMORY_E when memory allocation fails.
* @return 0 on success.
*/
static int wolfssl_read_file(XFILE fp, char** data, int* dataSz)
{
int ret = 0;
long sz = 0;
char* mem = NULL;
ret = wolfssl_file_len(fp, &sz);
if (ret == 0) {
/* Allocate memory big enough to hold whole file. */
mem = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (mem == NULL) {
ret = MEMORY_E;
}
}
/* Read whole file into new buffer. */
if ((ret == 0) && ((int)XFREAD(mem, 1, sz, fp) != sz)) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
*dataSz = (int)sz;
*data = mem;
mem = NULL;
}
XFREE(mem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
#endif /* !NO_FILESYSTEM */
#endif /* OPENSSL_EXTRA && !WOLFCRYPT_ONLY */
#endif /* !WOLFSSL_SSL_MISC_INCLUDED */

View File

@ -7277,7 +7277,7 @@ WOLFSSL_API int wolfSSL_X509_load_cert_crl_file(WOLFSSL_X509_LOOKUP *ctx,
#endif
}
wolfSSL_sk_X509_INFO_pop_free(info, wolfSSL_X509_INFO_free);
#else
#elif defined(HAVE_CRL)
/* Only supports one certificate or CRL in the file. */
WOLFSSL_X509_CRL* crl = NULL;
XFILE fp = XFOPEN(file, "rb");
@ -7659,6 +7659,7 @@ const WOLFSSL_ASN1_TIME* wolfSSL_X509_REVOKED_get0_revocation_date(const
#endif
#ifndef NO_BIO
/* print serial number out
* return WOLFSSL_SUCCESS on success
*/
@ -7718,7 +7719,9 @@ static int X509CRLPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
return WOLFSSL_SUCCESS;
}
#endif /* !NO_BIO */
#if !defined(NO_BIO) && defined(XSNPRINTF)
/* print out the extensions in human readable format for use with
* wolfSSL_X509_CRL_print()
* return WOLFSSL_SUCCESS on success
@ -7959,7 +7962,6 @@ static int X509CRLPrintDates(WOLFSSL_BIO* bio, WOLFSSL_X509_CRL* crl,
}
#endif
#if !defined(NO_BIO) && defined(XSNPRINTF)
/* Writes the human readable form of x509 to bio.
*
* bio WOLFSSL_BIO to write to.

File diff suppressed because it is too large Load Diff

View File

@ -10116,7 +10116,7 @@ int wc_DhParamsToDer(DhKey* key, byte* output, word32* outSz)
ret = LENGTH_ONLY_E;
}
/* Check buffer is big enough for encoding. */
if ((ret == 0) && ((int)*outSz < sz)) {
if ((ret == 0) && (*outSz < (word32)sz)) {
ret = BUFFER_E;
}
if (ret == 0) {
@ -22733,6 +22733,11 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer)
if (footer) *footer = END_PUB_KEY;
ret = 0;
break;
case RSA_PUBLICKEY_TYPE:
if (header) *header = BEGIN_RSA_PUB;
if (footer) *footer = END_RSA_PUB;
ret = 0;
break;
#ifndef NO_DH
case DH_PRIVATEKEY_TYPE:
#endif

View File

@ -1137,9 +1137,13 @@ enum {
/* set maximum DH key size allowed */
#ifndef WOLFSSL_MAX_DHKEY_BITS
#if (defined(USE_FAST_MATH) && defined(FP_MAX_BITS) && FP_MAX_BITS >= 16384)
#define WOLFSSL_MAX_DHKEY_BITS (FP_MAX_BITS / 2)
#define WOLFSSL_MAX_DHKEY_BITS (FP_MAX_BITS / 2)
#elif (defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)) && \
defined(SP_INT_BITS)
/* SP implementation supports numbers of SP_INT_BITS bits. */
#define WOLFSSL_MAX_DHKEY_BITS (((SP_INT_BITS + 7) / 8) * 8)
#else
#define WOLFSSL_MAX_DHKEY_BITS 4096
#define WOLFSSL_MAX_DHKEY_BITS 4096
#endif
#endif
#if (WOLFSSL_MAX_DHKEY_BITS % 8)

View File

@ -52,6 +52,24 @@ typedef struct WOLFSSL_BIGNUM {
#define BN_ULONG WOLFSSL_BN_ULONG
#endif
#ifndef WOLFSSL_MAX_BN_BITS
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH)
/* SP implementation supports numbers of SP_INT_BITS bits. */
#define WOLFSSL_MAX_BN_BITS SP_INT_BITS
#elif defined(USE_FAST_MATH)
/* FP implementation support numbers up to FP_MAX_BITS / 2 bits. */
#define WOLFSSL_MAX_BN_BITS (FP_MAX_BITS / 2)
#else
#ifdef WOLFSSL_MYSQL_COMPATIBLE
/* Integer maths is dynamic but we only go up to 8192 bits. */
#define WOLFSSL_MAX_BN_BITS 8192
#else
/* Integer maths is dynamic but we only go up to 4096 bits. */
#define WOLFSSL_MAX_BN_BITS 4096
#endif
#endif
#endif
typedef struct WOLFSSL_BN_CTX WOLFSSL_BN_CTX;
typedef struct WOLFSSL_BN_GENCB WOLFSSL_BN_GENCB;

View File

@ -50,10 +50,7 @@ struct WOLFSSL_DH {
* lighttpd src code.
*/
int length;
#ifndef SINGLE_THREADED
wolfSSL_Mutex refMutex; /* ref count mutex */
#endif
int refCount; /* reference count */
wolfSSL_Ref ref; /* Reference count information. */
};
WOLFSSL_API WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh,