Fixes from review part 2

This commit is contained in:
Sean Parkinson
2022-10-26 10:28:54 +10:00
parent e68c7bb74d
commit 5db2d53d54
4 changed files with 321 additions and 276 deletions

531
src/pk.c
View File

@ -66,7 +66,7 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key);
* @return Negative on failure. * @return Negative on failure.
* @return Number of bytes consumed on success. * @return Number of bytes consumed on success.
*/ */
static int pem_mem_to_der(char* pem, int pemSz, wc_pem_password_cb* cb, static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb,
void* pass, int keyType, int* keyFormat, DerBuffer** der) void* pass, int keyType, int* keyFormat, DerBuffer** der)
{ {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
@ -86,7 +86,7 @@ static int pem_mem_to_der(char* pem, int pemSz, wc_pem_password_cb* cb,
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL,
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_ENCRYPTEDINFO);
if (info == NULL) { if (info == NULL) {
WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure"); WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure");
ret = MEMORY_E; ret = MEMORY_E;
@ -110,14 +110,14 @@ static int pem_mem_to_der(char* pem, int pemSz, wc_pem_password_cb* cb,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
#endif #endif
return ret; return ret;
} }
#endif #endif
#if defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || !defined(WOLFCRYPT_ONLY)) #if !defined(NO_RSA) || !defined(WOLFCRYPT_ONLY)
#ifndef NO_BIO #ifndef NO_BIO
/* Read PEM data from a BIO and decode to DER in a new buffer. /* Read PEM data from a BIO and decode to DER in a new buffer.
* *
@ -145,8 +145,16 @@ static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
/* Write left over data back to BIO if not a file BIO */ /* Write left over data back to BIO if not a file BIO */
if ((ret > 0) && ((memSz - ret) > 0) && if ((ret > 0) && ((memSz - ret) > 0) &&
(bio->type != WOLFSSL_BIO_FILE)) { (bio->type != WOLFSSL_BIO_FILE)) {
if (wolfSSL_BIO_write(bio, mem + ret, memSz - ret) <= 0) { int res;
WOLFSSL_ERROR_MSG("Unable to advance bio read pointer"); res = wolfSSL_BIO_write(bio, mem + ret, memSz - ret);
if (res != memSz - ret) {
WOLFSSL_ERROR_MSG("Unable to write back excess data");
if (res < 0) {
ret = res;
}
else {
ret = MEMORY_E;
}
} }
} }
if (alloced) { if (alloced) {
@ -159,7 +167,7 @@ static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb,
#endif /* !NO_BIO */ #endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM) #if !defined(NO_FILESYSTEM)
/* Read PEM data from a BIO and decode to DER in a new buffer. /* Read PEM data from a file and decode to DER in a new buffer.
* *
* @param [in] fp File pointer to read with. * @param [in] fp File pointer to read with.
* @param [in] cb Password callback when PEM encrypted. * @param [in] cb Password callback when PEM encrypted.
@ -191,31 +199,34 @@ static int pem_read_file_key(XFILE fp, wc_pem_password_cb* cb, void* pass,
#if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) \ #if defined(OPENSSL_EXTRA) && ((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) \
&& !defined(HAVE_USER_RSA)) || !defined(WOLFCRYPT_ONLY)) && !defined(HAVE_USER_RSA)) || !defined(WOLFCRYPT_ONLY))
#ifndef NO_BIO /* Convert DER data to PEM in an allocated buffer.
/* Write the DER data as PEM into BIO.
* *
* @param [in, out] bio BIO object to write with. * @param [in] der Buffer containing DER data.
* @param [in] der Buffer containing DER data. * @param [in] derSz Size of DER data in bytes.
* @param [in] derSz Size of DER data in bytes. * @param [in] type Type of key being encoded.
* @param [in] type Type of key being encoded. * @param [in] heap Heap hint for dynamic memory allocation.
* @param [out] out Allocated buffer containing PEM.
* @param [out] outSz Size of PEM encoding.
* @return WOLFSSL_FAILURE on error. * @return WOLFSSL_FAILURE on error.
* @return WOLFSSL_SUCCESS on success. * @return WOLFSSL_SUCCESS on success.
*/ */
static int pem_write_bio_der(WOLFSSL_BIO* bio, unsigned char* der, int derSz, static int der_to_pem_alloc(const unsigned char* der, int derSz, int type,
int type) void* heap, byte** out, int* outSz)
{ {
int ret = WOLFSSL_SUCCESS; int ret = WOLFSSL_SUCCESS;
int pemSz; int pemSz;
byte* pem = NULL; byte* pem = NULL;
int len; int len;
(void)heap;
pemSz = wc_DerToPem(der, derSz, NULL, 0, type); pemSz = wc_DerToPem(der, derSz, NULL, 0, type);
if (pemSz < 0) { if (pemSz < 0) {
ret = WOLFSSL_FAILURE; ret = WOLFSSL_FAILURE;
} }
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
pem = (byte*)XMALLOC(pemSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); pem = (byte*)XMALLOC(pemSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
if (pem == NULL) { if (pem == NULL) {
ret = WOLFSSL_FAILURE; ret = WOLFSSL_FAILURE;
} }
@ -228,8 +239,31 @@ static int pem_write_bio_der(WOLFSSL_BIO* bio, unsigned char* der, int derSz,
} }
} }
*out = pem;
*outSz = pemSz;
return ret;
}
#ifndef NO_BIO
/* Write the DER data as PEM into BIO.
*
* @param [in] der Buffer containing DER data.
* @param [in] derSz Size of DER data in bytes.
* @param [in, out] bio BIO object to write with.
* @param [in] type Type of key being encoded.
* @return WOLFSSL_FAILURE on error.
* @return WOLFSSL_SUCCESS on success.
*/
static int der_write_to_bio_as_pem(const unsigned char* der, int derSz,
WOLFSSL_BIO* bio, int type)
{
int ret;
int pemSz;
byte* pem = NULL;
ret = der_to_pem_alloc(der, derSz, type, bio->heap, &pem, &pemSz);
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
len = wolfSSL_BIO_write(bio, pem, pemSz); int len = wolfSSL_BIO_write(bio, pem, pemSz);
if (len != pemSz) { if (len != pemSz) {
WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO"); WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
ret = WOLFSSL_FAILURE; ret = WOLFSSL_FAILURE;
@ -237,56 +271,34 @@ static int pem_write_bio_der(WOLFSSL_BIO* bio, unsigned char* der, int derSz,
} }
XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pem, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_LEAVE("pem_write_bio_der", ret);
return ret; return ret;
} }
#endif #endif
#endif #endif
#if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) \ #if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
&& defined(OPENSSL_EXTRA)) || \ !defined(HAVE_USER_RSA)) || (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA))
((defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \
defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)) && \
!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA))
#if !defined(NO_FILESYSTEM) #if !defined(NO_FILESYSTEM)
/* Write the DER data as PEM into file pointer. /* Write the DER data as PEM into file pointer.
* *
* @param [in] fp File pointer to write with.
* @param [in] der Buffer containing DER data. * @param [in] der Buffer containing DER data.
* @param [in] derSz Size of DER data in bytes. * @param [in] derSz Size of DER data in bytes.
* @param [in] fp File pointer to write with.
* @param [in] type Type of key being encoded. * @param [in] type Type of key being encoded.
* @param [in] heap Heap hint for dynamic memory allocation.
* @return WOLFSSL_FAILURE on error. * @return WOLFSSL_FAILURE on error.
* @return WOLFSSL_SUCCESS on success. * @return WOLFSSL_SUCCESS on success.
*/ */
static int pem_write_file_der(XFILE fp, unsigned char* der, int derSz, static int der_write_to_file_as_pem(const unsigned char* der, int derSz,
int type) XFILE fp, int type, void* heap)
{ {
int ret = WOLFSSL_SUCCESS; int ret;
int pemSz; int pemSz;
byte* pem = NULL; byte* pem = NULL;
int len;
pemSz = wc_DerToPem(der, derSz, NULL, 0, type);
if (pemSz < 0) {
ret = WOLFSSL_FAILURE;
}
ret = der_to_pem_alloc(der, derSz, type, heap, &pem, &pemSz);
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); int len = (int)XFWRITE(pem, 1, pemSz, fp);
if (pem == NULL) {
ret = WOLFSSL_FAILURE;
}
}
if (ret == WOLFSSL_SUCCESS) {
len = wc_DerToPem(der, derSz, pem, pemSz, type);
if (len < 0) {
ret = WOLFSSL_FAILURE;
}
}
if (ret == WOLFSSL_SUCCESS) {
len = (int)XFWRITE(pem, 1, pemSz, fp);
if (len != pemSz) { if (len != pemSz) {
WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO"); WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO");
ret = WOLFSSL_FAILURE; ret = WOLFSSL_FAILURE;
@ -294,7 +306,6 @@ static int pem_write_file_der(XFILE fp, unsigned char* der, int derSz,
} }
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_LEAVE("pem_write_file_der", ret);
return ret; return ret;
} }
#endif #endif
@ -623,7 +634,8 @@ static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name,
#endif /* XSNPRINTF && !NO_BIO && !NO_RSA && !HAVE_FAST_RSA */ #endif /* XSNPRINTF && !NO_BIO && !NO_RSA && !HAVE_FAST_RSA */
#ifndef NO_RSA #if !defined(NO_RSA) || (!defined(NO_DH) && !defined(NO_CERTS) && \
defined(HAVE_FIPS) && !FIPS_VERSION_GT(2,0))
/* Uses the DER SEQUENCE to determine size of DER data. /* Uses the DER SEQUENCE to determine size of DER data.
* *
@ -678,7 +690,7 @@ WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Allocate RNG object . */ /* Allocate RNG object . */
rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_TMP_BUFFER); rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
#endif #endif
/* Check we have a local RNG object and initialize. */ /* Check we have a local RNG object and initialize. */
if ((rng != NULL) && (wc_InitRng(rng) == 0)) { if ((rng != NULL) && (wc_InitRng(rng) == 0)) {
@ -702,7 +714,7 @@ WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local)
if (ret != rng) { if (ret != rng) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rng, NULL, DYNAMIC_TYPE_RNG);
#endif #endif
} }
@ -1668,7 +1680,8 @@ int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf,
* returned through pointer. * returned through pointer.
* @param [in] in DER encoded RSA key data. * @param [in] in DER encoded RSA key data.
* @param [in] inSz Size of DER encoded data in bytes. * @param [in] inSz Size of DER encoded data in bytes.
* @param [in] opt Public or private key encoded in data. * @param [in] opt Public or private key encoded in data. Valid values:
* WOLFSSL_RSA_LOAD_PRIVATE, WOLFSSL_RSA_LOAD_PUBLIC.
* @return NULL on failure. * @return NULL on failure.
* @return WOLFSSL_RSA object on success. * @return WOLFSSL_RSA object on success.
*/ */
@ -1739,16 +1752,13 @@ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa)
ret = 0; ret = 0;
} }
} }
if ((ret == 1) && (pem_write_bio_der(bio, derBuf, derSz, PUBLICKEY_TYPE) != if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio,
WOLFSSL_SUCCESS)) { PUBLICKEY_TYPE) != WOLFSSL_SUCCESS)) {
ret = 0; ret = 0;
} }
if (derBuf != NULL) { /* Dispose of DER buffer. */
/* Dispose of DER buffer. */ XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
return ret; return ret;
} }
@ -1757,23 +1767,22 @@ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa)
#if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA)
#ifndef NO_FILESYSTEM #ifndef NO_FILESYSTEM
/* Writes PEM encoding of an RSA public key to a file pointer. /* Writes PEM encoding of an RSA public key to a file pointer.
* *
* Header/footer will contain: PUBLIC KEY * @param [in] fp File pointer to write to.
* * @param [in] rsa RSA key to write.
* @param [in] fp File pointer to write to. * @param [in] type PEM type to write out.
* @param [in] rsa RSA key to write.
* @return 1 on success. * @return 1 on success.
* @return 0 on failure. * @return 0 on failure.
*/ */
int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa) static int wolfssl_pem_write_rsa_public_key(XFILE fp, WOLFSSL_RSA* rsa,
int type)
{ {
int ret = 1; int ret = 1;
int derSz; int derSz;
byte* derBuf = NULL; byte* derBuf = NULL;
WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPublicKey");
/* Validate parameters. */ /* Validate parameters. */
if ((fp == XBADFILE) || (rsa == NULL)) { if ((fp == XBADFILE) || (rsa == NULL)) {
WOLFSSL_ERROR_MSG("Bad Function Arguments"); WOLFSSL_ERROR_MSG("Bad Function Arguments");
@ -1790,8 +1799,8 @@ int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa)
ret = 0; ret = 0;
} }
} }
if ((ret == 1) && (pem_write_file_der(fp, derBuf, derSz, PUBLICKEY_TYPE) != if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp, type,
WOLFSSL_SUCCESS)) { rsa->heap) != WOLFSSL_SUCCESS)) {
ret = 0; ret = 0;
} }
@ -1800,11 +1809,23 @@ int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa)
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
} }
WOLFSSL_LEAVE("wolfSSL_PEM_write_RSAPublicKey", ret);
return ret; return ret;
} }
/* Writes PEM encoding of an RSA public key to a file pointer.
*
* Header/footer will contain: PUBLIC KEY
*
* @param [in] fp File pointer to write to.
* @param [in] rsa RSA key to write.
* @return 1 on success.
* @return 0 on failure.
*/
int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA* rsa)
{
return wolfssl_pem_write_rsa_public_key(fp, rsa, PUBLICKEY_TYPE);
}
/* Writes PEM encoding of an RSA public key to a file pointer. /* Writes PEM encoding of an RSA public key to a file pointer.
* *
* Header/footer will contain: RSA PUBLIC KEY * Header/footer will contain: RSA PUBLIC KEY
@ -1816,41 +1837,7 @@ int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa)
*/ */
int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* rsa) int wolfSSL_PEM_write_RSAPublicKey(XFILE fp, WOLFSSL_RSA* rsa)
{ {
int ret = 1; return wolfssl_pem_write_rsa_public_key(fp, rsa, RSA_PUBLICKEY_TYPE);
int derSz;
byte* derBuf = NULL;
WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPublicKey");
/* Validate parameters. */
if ((fp == XBADFILE) || (rsa == NULL)) {
WOLFSSL_ERROR_MSG("Bad Function Arguments");
ret = 0;
}
if (ret == 1) {
if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1, rsa->heap)) < 0) {
WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed");
ret = 0;
}
if (derBuf == NULL) {
WOLFSSL_ERROR_MSG("wolfSSL_RSA_To_Der failed to get buffer");
ret = 0;
}
}
if ((ret == 1) && (pem_write_file_der(fp, derBuf, derSz, RSA_PUBLICKEY_TYPE)
!= WOLFSSL_SUCCESS)) {
ret = 0;
}
if (derBuf != NULL) {
/* Dispose of DER buffer. */
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
WOLFSSL_LEAVE("wolfSSL_PEM_write_RSAPublicKey", ret);
return ret;
} }
#endif /* !NO_FILESYSTEM */ #endif /* !NO_FILESYSTEM */
#endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */ #endif /* WOLFSSL_KEY_GEN && !HAVE_USER_RSA */
@ -1934,8 +1921,8 @@ WOLFSSL_RSA *wolfSSL_PEM_read_RSA_PUBKEY(XFILE fp,
* Header/footer should contain: RSA PUBLIC KEY * Header/footer should contain: RSA PUBLIC KEY
* PEM decoder supports either 'RSA PUBLIC KEY' or 'PUBLIC KEY'. * PEM decoder supports either 'RSA PUBLIC KEY' or 'PUBLIC KEY'.
* *
* @param [in] bio BIO object to read from. * @param [in] fp File pointer to read from.
* @param [out] out RSA key created. * @param [out] rsa RSA key created.
* @param [in] cb Password callback when PEM encrypted. May be NULL. * @param [in] cb Password callback when PEM encrypted. May be NULL.
* @param [in] pass NUL terminated string for passphrase when PEM encrypted. * @param [in] pass NUL terminated string for passphrase when PEM encrypted.
* May be NULL. * May be NULL.
@ -2103,7 +2090,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa,
WOLFSSL_ERROR_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed"); WOLFSSL_ERROR_MSG("wolfSSL_PEM_write_mem_RSAPrivateKey failed");
} }
} }
/* Write PEM to file pointer. */ /* Write PEM to BIO. */
if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, plen) <= 0)) { if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, plen) <= 0)) {
WOLFSSL_ERROR_MSG("RSA private key BIO write failed"); WOLFSSL_ERROR_MSG("RSA private key BIO write failed");
ret = 0; ret = 0;
@ -3201,7 +3188,7 @@ static int wolfssl_rsa_generate_key_native(WOLFSSL_RSA* rsa, int bits,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Dispose of any allocated RNG. */ /* Dispose of any allocated RNG. */
XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
#endif #endif
return ret; return ret;
@ -3497,7 +3484,7 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Dispose of any allocated RNG. */ /* Dispose of any allocated RNG. */
XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
#endif #endif
return ret; return ret;
@ -3930,7 +3917,7 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Dispose of any allocated RNG and encoded signature. */ /* Dispose of any allocated RNG and encoded signature. */
XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE); XFREE(encodedSig, NULL, DYNAMIC_TYPE_SIGNATURE);
#endif #endif
@ -4192,7 +4179,7 @@ int wolfSSL_RSA_public_encrypt(int len, const unsigned char* from,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Dispose of any allocated RNG. */ /* Dispose of any allocated RNG. */
XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
#endif #endif
/* wolfCrypt error means return -1. */ /* wolfCrypt error means return -1. */
@ -4468,7 +4455,7 @@ int wolfSSL_RSA_private_encrypt(int len, const unsigned char* from,
} }
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
/* Dispose of any allocated RNG. */ /* Dispose of any allocated RNG. */
XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG);
#endif #endif
/* wolfCrypt error means return -1. */ /* wolfCrypt error means return -1. */
@ -7124,11 +7111,102 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
} }
/* /*
* RSA to/from bin APIs * DH to/from bin APIs
*/ */
#ifndef NO_CERTS #ifndef NO_CERTS
/* Load the DER encoded DH parameters/key into DH key.
*
* @param [in, out] dh DH key to load parameters into.
* @param [in] der Buffer holding DER encoded parameters data.
* @param [in, out] idx On in, index at which DH key DER data starts.
* On out, index after DH key DER data.
* @param [in] derSz Size of DER buffer in bytes.
*
* @return 0 on success.
* @return 1 when decoding DER or setting the external key fails.
*/
static int wolfssl_dh_load_key(WOLFSSL_DH* dh, const unsigned char* der,
word32* idx, word32 derSz)
{
int err = 0;
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
int ret;
/* Decode DH parameters/key from DER. */
ret = wc_DhKeyDecode(der, idx, (DhKey*)dh->internal, derSz);
if (ret != 0) {
WOLFSSL_ERROR_MSG("DhKeyDecode() failed");
err = 1;
}
if (!err) {
/* wolfSSL DH key set. */
dh->inSet = 1;
/* Set the external DH key based on wolfSSL DH key. */
if (SetDhExternal(dh) != 1) {
WOLFSSL_ERROR_MSG("SetDhExternal failed");
err = 1;
}
}
#else
byte* p;
byte* g;
word32 pSz = MAX_DH_SIZE;
word32 gSz = MAX_DH_SIZE;
/* Only DH parameters supported. */
/* Load external and set internal. */
p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if ((p == NULL) || (g == NULL)) {
err = 1;
}
/* Extract the p and g as data from the DER encoded DH parameters. */
if ((!err) && (wc_DhParamsLoad(der + *idx, derSz - *idx, p, &pSz, g,
&gSz) < 0)) {
err = 1;
}
if (!err) {
/* Put p and g in as big numbers - free existing BNs. */
if (dh->p != NULL) {
wolfSSL_BN_free(dh->p);
dh->p = NULL;
}
if (dh->g != NULL) {
wolfSSL_BN_free(dh->g);
dh->g = NULL;
}
dh->p = wolfSSL_BN_bin2bn(p, (int)pSz, NULL);
dh->g = wolfSSL_BN_bin2bn(g, (int)gSz, NULL);
if (dh->p == NULL || dh->g == NULL) {
err = 1;
}
else {
/* External DH key parameters were set. */
dh->exSet = 1;
}
}
/* Set internal as the outside has been updated. */
if ((!err) && (SetDhInternal(dh) != 1)) {
WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
err = 1;
}
if (!err) {
*idx += wolfssl_der_length(der + *idx, derSz - *idx);
}
XFREE(p, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(g, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
#endif
return err;
}
#ifdef OPENSSL_ALL #ifdef OPENSSL_ALL
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) #if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
@ -7142,11 +7220,10 @@ WOLFSSL_BIGNUM* wolfSSL_DH_8192_prime(WOLFSSL_BIGNUM* bn)
* @return DH key on success. * @return DH key on success.
* @return NULL on failure. * @return NULL on failure.
*/ */
WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH** dh, const unsigned char** pp,
long length) long length)
{ {
WOLFSSL_DH *newDh = NULL; WOLFSSL_DH *newDh = NULL;
int ret;
word32 idx = 0; word32 idx = 0;
int err = 0; int err = 0;
@ -7163,22 +7240,11 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp,
WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed"); WOLFSSL_ERROR_MSG("wolfSSL_DH_new() failed");
err = 1; err = 1;
} }
/* Decode DH key from DER. */ if ((!err) && (wolfssl_dh_load_key(newDh, *pp, &idx,
if ((!err) && ((ret = wc_DhKeyDecode(*pp, &idx, (DhKey*)newDh->internal, (word32)length) != 0)) {
(word32)length)) != 0)) { WOLFSSL_ERROR_MSG("Loading DH parameters failed");
WOLFSSL_ERROR_MSG("DhKeyDecode() failed");
err = 1; err = 1;
} }
if (!err) {
/* wolfSSL DH key set. */
newDh->inSet = 1;
/* Set the external DH key based on wolfSSL DH key. */
if (SetDhExternal(newDh) != 1) {
WOLFSSL_ERROR_MSG("SetDhExternal failed");
err = 1;
}
}
if ((!err) && (dh != NULL)) { if ((!err) && (dh != NULL)) {
/* Return through parameter too. */ /* Return through parameter too. */
@ -7194,7 +7260,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp,
} }
return newDh; return newDh;
} }
#endif /* !(FIPS_VERSION == 1) */ #endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
/* Calculate the number of bytes require to represent a length value in ASN. /* Calculate the number of bytes require to represent a length value in ASN.
* *
@ -7333,14 +7399,7 @@ int wolfSSL_i2d_DHparams(const WOLFSSL_DH *dh, unsigned char **out)
int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
{ {
int ret = 1; int ret = 1;
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0)
word32 idx = 0; word32 idx = 0;
#else
byte* p = NULL;
byte* g = NULL;
word32 pSz = MAX_DH_SIZE;
word32 gSz = MAX_DH_SIZE;
#endif
/* Validate parameters. */ /* Validate parameters. */
if ((dh == NULL) || (dh->internal == NULL) || (derBuf == NULL) || if ((dh == NULL) || (dh->internal == NULL) || (derBuf == NULL) ||
@ -7349,67 +7408,11 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
ret = -1; ret = -1;
} }
#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) if ((ret == 1) && (wolfssl_dh_load_key(dh, derBuf, &idx,
/* Decode the parameters/key into the internal DH key. */ (word32)derSz) != 0)) {
if ((ret == 1) && (wc_DhKeyDecode(derBuf, &idx, (DhKey*)dh->internal, WOLFSSL_ERROR_MSG("DH key decode failed");
(word32)derSz) < 0)) {
WOLFSSL_ERROR_MSG("wc_DhKeyDecode failed");
ret = -1; ret = -1;
} }
if (ret == 1) {
/* Internal DH key has parameters. */
dh->inSet = 1;
/* Transfer parameters from internal to external DH key. */
if (SetDhExternal(dh) != 1) {
WOLFSSL_ERROR_MSG("SetDhExternal failed");
ret = -1;
}
}
#else
/* Only DH parameters supported. */
/* Load external and set internal. */
if (ret == 1) {
/* Load data in manually */
p = (byte*)XMALLOC(pSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
g = (byte*)XMALLOC(gSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if ((p == NULL) || (g == NULL)) {
ret = -1;
}
}
/* Extract the p and g as data from the DER encoded DH parameters. */
if ((ret == 1) && (wc_DhParamsLoad(derBuf, derSz, p, &pSz, g, &gSz) != 0)) {
ret = -1;
}
if (ret == 1) {
/* Put p and g in as big numbers - free existing BNs. */
if (dh->p != NULL) {
wolfSSL_BN_free(dh->p);
dh->p = NULL;
}
if (dh->g != NULL) {
wolfSSL_BN_free(dh->g);
dh->g = NULL;
}
dh->p = wolfSSL_BN_bin2bn(p, (int)pSz, NULL);
dh->g = wolfSSL_BN_bin2bn(g, (int)gSz, NULL);
if (dh->p == NULL || dh->g == NULL) {
ret = -1;
}
else {
/* External DH key parameters were set. */
dh->exSet = 1;
}
}
/* Set internal as the outside has been updated. */
if ((ret == 1) && (SetDhInternal(dh) != 1)) {
WOLFSSL_ERROR_MSG("Unable to set internal DH structure");
ret = -1;
}
#endif /* !HAVE_FIPS || FIPS_VERION > 2 */
return ret; return ret;
} }
@ -7426,29 +7429,22 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz)
#if !defined(NO_BIO) || !defined(NO_FILESYSTEM) #if !defined(NO_BIO) || !defined(NO_FILESYSTEM)
/* Create a DH key by reading the PEM encoded data from the BIO. /* Create a DH key by reading the PEM encoded data from the BIO.
* *
* DH parameters are public data and are not expected to be encrypted. * @param [in] bio BIO object to read from.
* * @param [in, out] dh DH key to use. May be NULL.
* @param [in] bio BIO object to read from. * @param [in] pem PEM data to decode.
* @param [in, out] dh DH key with parameters if not NULL. When pointer to * @param [in] pemSz Size of PEM data in bytes.
* NULL, a new DH key is created. * @param [in] memAlloced Indicates that pem was allocated and is to be
* @param [in] cb Password callback when PEM encrypted. Not used. * freed after use.
* @param [in] pass NUL terminated string for passphrase when PEM
* encrypted. Not used.
* @return DH key on success. * @return DH key on success.
* @return NULL on failure. * @return NULL on failure.
*/ */
static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out, static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **dh,
unsigned char* pem, int pemSz, int memAlloced, wc_pem_password_cb *cb, unsigned char* pem, int pemSz, int memAlloced)
void *pass)
{ {
WOLFSSL_DH* localDh = NULL; WOLFSSL_DH* localDh = NULL;
DerBuffer *der = NULL; DerBuffer *der = NULL;
int err = 0; int err = 0;
/* Parameters are public data and are not encrypted. */
(void)cb;
(void)pass;
/* Convert PEM to DER assuming DH Parameter format. */ /* Convert PEM to DER assuming DH Parameter format. */
if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL, if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL,
NULL) < 0)) { NULL) < 0)) {
@ -7465,8 +7461,8 @@ static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out,
if (!err) { if (!err) {
/* Use the DH key passed in or allocate a new one. */ /* Use the DH key passed in or allocate a new one. */
if (out != NULL) { if (dh != NULL) {
localDh = *out; localDh = *dh;
} }
if (localDh == NULL) { if (localDh == NULL) {
localDh = wolfSSL_DH_new(); localDh = wolfSSL_DH_new();
@ -7479,15 +7475,15 @@ static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out,
if ((!err) && (wolfSSL_DH_LoadDer(localDh, der->buffer, der->length) if ((!err) && (wolfSSL_DH_LoadDer(localDh, der->buffer, der->length)
!= 1)) { != 1)) {
/* Free an allocated DH key. */ /* Free an allocated DH key. */
if ((out == NULL) || (localDh != *out)) { if ((dh == NULL) || (localDh != *dh)) {
wolfSSL_DH_free(localDh); wolfSSL_DH_free(localDh);
} }
localDh = NULL; localDh = NULL;
err = 1; err = 1;
} }
/* Return the DH key on success. */ /* Return the DH key on success. */
if ((!err) && (out != NULL)) { if ((!err) && (dh != NULL)) {
*out = localDh; *dh = localDh;
} }
/* Dispose of DER data. */ /* Dispose of DER data. */
@ -7504,7 +7500,7 @@ static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out,
* DH parameters are public data and are not expected to be encrypted. * DH parameters are public data and are not expected to be encrypted.
* *
* @param [in] bio BIO object to read from. * @param [in] bio BIO object to read from.
* @param [in, out] dh DH key with parameters if not NULL. When pointer to * @param [in, out] dh DH key to When pointer to
* NULL, a new DH key is created. * NULL, a new DH key is created.
* @param [in] cb Password callback when PEM encrypted. Not used. * @param [in] cb Password callback when PEM encrypted. Not used.
* @param [in] pass NUL terminated string for passphrase when PEM * @param [in] pass NUL terminated string for passphrase when PEM
@ -7512,7 +7508,7 @@ static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out,
* @return DH key on success. * @return DH key on success.
* @return NULL on failure. * @return NULL on failure.
*/ */
WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **out, WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **dh,
wc_pem_password_cb *cb, void *pass) wc_pem_password_cb *cb, void *pass)
{ {
WOLFSSL_DH* localDh = NULL; WOLFSSL_DH* localDh = NULL;
@ -7523,6 +7519,9 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **out,
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams"); WOLFSSL_ENTER("wolfSSL_PEM_read_bio_DHparams");
(void)cb;
(void)pass;
/* Validate parameters. */ /* Validate parameters. */
if (bio == NULL) { if (bio == NULL) {
WOLFSSL_ERROR_MSG("Bad Function Argument bio is NULL"); WOLFSSL_ERROR_MSG("Bad Function Argument bio is NULL");
@ -7537,8 +7536,7 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **out,
} }
if (!err) { if (!err) {
/* Create a DH key from the PEM - try two different headers. */ /* Create a DH key from the PEM - try two different headers. */
localDh = wolfssl_dhparams_read_pem(out, mem, size, memAlloced, cb, localDh = wolfssl_dhparams_read_pem(dh, mem, size, memAlloced);
pass);
} }
return localDh; return localDh;
@ -7569,12 +7567,15 @@ WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh,
unsigned char* mem = NULL; unsigned char* mem = NULL;
int size = 0; int size = 0;
(void)cb;
(void)pass;
/* Read data from file pointer. */ /* Read data from file pointer. */
if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) { if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) {
err = 1; err = 1;
} }
if (!err) { if (!err) {
localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1, cb, pass); localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1);
} }
return localDh; return localDh;
@ -7585,7 +7586,7 @@ WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh,
/* Encoded parameter data in DH key as DER. /* Encoded parameter data in DH key as DER.
* *
* @param [in, out] dh DH key object to encode. * @param [in, out] dh DH key object to encode.
* @param [out] der Buffer containing DER encoding. * @param [out] out Buffer containing DER encoding.
* @param [in] heap Heap hint. * @param [in] heap Heap hint.
* @return <0 on error. * @return <0 on error.
* @return Length of DER encoded DH parameters in bytes. * @return Length of DER encoded DH parameters in bytes.
@ -7670,8 +7671,8 @@ int wolfSSL_PEM_write_DHparams(XFILE fp, WOLFSSL_DH* dh)
ret = 0; ret = 0;
} }
} }
if ((ret == 1) && (pem_write_file_der(fp, derBuf, derSz, DH_PARAM_TYPE) != if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp,
WOLFSSL_SUCCESS)) { DH_PARAM_TYPE, NULL) != WOLFSSL_SUCCESS)) {
ret = 0; ret = 0;
} }
@ -7779,6 +7780,7 @@ int SetDhExternal_ex(WOLFSSL_DH *dh, int elm)
*/ */
int SetDhExternal(WOLFSSL_DH *dh) int SetDhExternal(WOLFSSL_DH *dh)
{ {
/* Assuming Q not required when using this API. */
int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV; int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV;
WOLFSSL_ENTER("SetDhExternal"); WOLFSSL_ENTER("SetDhExternal");
return SetDhExternal_ex(dh, elements); return SetDhExternal_ex(dh, elements);
@ -7919,6 +7921,12 @@ void wolfSSL_DH_get0_pqg(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **p,
* Ownership of p, q and g get taken over by "dh" on success and should be * Ownership of p, q and g get taken over by "dh" on success and should be
* free'd with a call to wolfSSL_DH_free -- not individually. * free'd with a call to wolfSSL_DH_free -- not individually.
* *
* @param [in, out] dh DH key to set.
* @parma [in] p Prime value to set. May be NULL when value already
* present.
* @parma [in] q Order value to set. May be NULL.
* @parma [in] g Generator value to set. May be NULL when value already
* present.
* @return 1 on success. * @return 1 on success.
* @return 0 on failure. * @return 0 on failure.
*/ */
@ -7929,8 +7937,18 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
WOLFSSL_ENTER("wolfSSL_DH_set0_pqg"); WOLFSSL_ENTER("wolfSSL_DH_set0_pqg");
/* Validata parameters - q is optional. */ /* Validate parameters - q is optional. */
if ((dh == NULL) || (p == NULL) || (g == NULL)) { if (dh == NULL) {
WOLFSSL_ERROR_MSG("Bad function arguments");
ret = 0;
}
/* p can be NULL if we already have one set. */
if ((ret == 1) && (p == NULL) && (dh->p == NULL)) {
WOLFSSL_ERROR_MSG("Bad function arguments");
ret = 0;
}
/* g can be NULL if we already have one set. */
if ((ret == 1) && (g == NULL) && (dh->g == NULL)) {
WOLFSSL_ERROR_MSG("Bad function arguments"); WOLFSSL_ERROR_MSG("Bad function arguments");
ret = 0; ret = 0;
} }
@ -7939,14 +7957,20 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p,
/* Invalidate internal key. */ /* Invalidate internal key. */
dh->inSet = 0; dh->inSet = 0;
/* Free external representation of parameters. */ /* Free external representation of parameters and set with those passed
wolfSSL_BN_free(dh->p); * in. */
wolfSSL_BN_free(dh->q); if (p != NULL) {
wolfSSL_BN_free(dh->g); wolfSSL_BN_free(dh->p);
/* Set parameters to be the parameters passed in. */ dh->p = p;
dh->p = p; }
dh->q = q; if (q != NULL) {
dh->g = g; wolfSSL_BN_free(dh->q);
dh->q = q;
}
if (g != NULL) {
wolfSSL_BN_free(dh->g);
dh->g = g;
}
/* External DH key parameters were set. */ /* External DH key parameters were set. */
dh->exSet = 1; dh->exSet = 1;
@ -8010,7 +8034,7 @@ void wolfSSL_DH_get0_key(const WOLFSSL_DH *dh, const WOLFSSL_BIGNUM **pub_key,
/* Get only when valid DH passed in. */ /* Get only when valid DH passed in. */
if (dh != NULL) { if (dh != NULL) {
/* Return public key if available and available. */ /* Return public key if required and available. */
if ((pub_key != NULL) && (dh->pub_key != NULL)) { if ((pub_key != NULL) && (dh->pub_key != NULL)) {
*pub_key = dh->pub_key; *pub_key = dh->pub_key;
} }
@ -8033,6 +8057,9 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
WOLFSSL_BIGNUM *priv_key) WOLFSSL_BIGNUM *priv_key)
{ {
int ret = 1; int ret = 1;
#ifdef WOLFSSL_DH_EXTRA
DhKey *key = NULL;
#endif
WOLFSSL_ENTER("wolfSSL_DH_set0_key"); WOLFSSL_ENTER("wolfSSL_DH_set0_key");
@ -8040,22 +8067,32 @@ int wolfSSL_DH_set0_key(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *pub_key,
if (dh == NULL) { if (dh == NULL) {
ret = 0; ret = 0;
} }
#ifdef WOLFSSL_DH_EXTRA
else {
key = (DhKey*)dh->internal;
}
#endif
/* Replace public key when one passed in. */ /* Replace public key when one passed in. */
if ((ret == 1) && (pub_key != NULL)) { if ((ret == 1) && (pub_key != NULL)) {
wolfSSL_BN_free(dh->pub_key); wolfSSL_BN_free(dh->pub_key);
dh->pub_key = pub_key; dh->pub_key = pub_key;
#ifdef WOLFSSL_DH_EXTRA
if (SetIndividualInternal(dh->pub_key, &key->pub) != 1) {
ret = 0;
}
#endif
} }
/* Replace private key when one passed in. */ /* Replace private key when one passed in. */
if ((ret == 1) && (priv_key != NULL)) { if ((ret == 1) && (priv_key != NULL)) {
wolfSSL_BN_free(dh->priv_key); wolfSSL_BN_clear_free(dh->priv_key);
dh->priv_key = priv_key; dh->priv_key = priv_key;
} #ifdef WOLFSSL_DH_EXTRA
if (SetIndividualInternal(dh->priv_key, &key->priv) != 1) {
/* Update internal key if parameters set. */ ret = 0;
if ((ret == 1) && ((dh->p != NULL) && (dh->g != NULL))) { }
ret = SetDhInternal(dh); #endif
} }
return ret; return ret;
@ -8117,7 +8154,7 @@ static int wolfssl_dh_check_prime(WOLFSSL_BIGNUM* n, int* isPrime)
* *
* Checks that the generator and prime are available. * Checks that the generator and prime are available.
* Checks that the prime is prime. * Checks that the prime is prime.
* OpenSSL does not return 0 when no operational failures buf error codes set. * OpenSSL expects codes to be non-NULL.
* *
* @param [in] dh DH key to check. * @param [in] dh DH key to check.
* @param [out] codes Codes of checks that failed. * @param [out] codes Codes of checks that failed.
@ -8151,7 +8188,7 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
/* Test if dh->p is prime. */ /* Test if dh->p is prime. */
int isPrime = MP_NO; int isPrime = MP_NO;
ret = wolfssl_dh_check_prime(dh->p, &isPrime); ret = wolfssl_dh_check_prime(dh->p, &isPrime);
/* Set error if parameter p is not prime. */ /* Set error code if parameter p is not prime. */
if ((ret == 1) && (isPrime != MP_YES)) { if ((ret == 1) && (isPrime != MP_YES)) {
errors |= DH_CHECK_P_NOT_PRIME; errors |= DH_CHECK_P_NOT_PRIME;
} }
@ -8162,8 +8199,8 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes)
if (codes != NULL) { if (codes != NULL) {
*codes = errors; *codes = errors;
} }
if (errors) { else if (errors) {
ret = 0; ret = 0;
} }
return ret; return ret;

View File

@ -28268,7 +28268,7 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
ret = pem_write_pubkey(key, bio->heap, &derBuf, &derSz); ret = pem_write_pubkey(key, bio->heap, &derBuf, &derSz);
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {
ret = pem_write_bio_der(bio, derBuf, derSz, PUBLICKEY_TYPE); ret = der_write_to_bio_as_pem(derBuf, derSz, bio, PUBLICKEY_TYPE);
XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_DER);
} }
@ -28350,7 +28350,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key,
type = PRIVATEKEY_TYPE; type = PRIVATEKEY_TYPE;
} }
return pem_write_bio_der(bio, keyDer, key->pkey_sz, type); return der_write_to_bio_as_pem(keyDer, key->pkey_sz, bio, type);
} }
#endif /* !NO_BIO */ #endif /* !NO_BIO */

View File

@ -27,7 +27,7 @@
#if !defined(WOLFSSL_SSL_MISC_INCLUDED) #if !defined(WOLFSSL_SSL_MISC_INCLUDED)
#ifndef WOLFSSL_IGNORE_FILE_WARN #ifndef WOLFSSL_IGNORE_FILE_WARN
#warning misc.c does not need to be compiled separately from ssl.c #warning ssl_misc.c does not need to be compiled separately from ssl.c
#endif #endif
#else #else
@ -42,12 +42,12 @@
* *
* Allocates a chunk and reads into it until it is full. * Allocates a chunk and reads into it until it is full.
* *
* @param [in, out] bio BIO object to read with. * @param [in, out] bio BIO object to read with.
* @param [out] pem Read data in a new buffer. * @param [out] data Read data in a new buffer.
* @return Negative on error. * @return Negative on error.
* @return Number of bytes read on success. * @return Number of bytes read on success.
*/ */
static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** pem) static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** data)
{ {
int ret = 0; int ret = 0;
char* mem; char* mem;
@ -110,20 +110,20 @@ static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** pem)
} }
} }
*pem = mem; *data = mem;
return ret; return ret;
} }
#endif #endif
/* Read exactly the required amount into a newly allocated buffer. /* Read exactly the required amount into a newly allocated buffer.
* *
* @param [in, out] bio BIO object to read with. * @param [in, out] bio BIO object to read with.
* @param [in sz Amount of data to read. * @param [in sz Amount of data to read.
* @param [out] pem Read data in a new buffer. * @param [out] data Read data in a new buffer.
* @return Negative on error. * @return Negative on error.
* @return Number of bytes read on success. * @return Number of bytes read on success.
*/ */
static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** pem) static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** data)
{ {
int ret = 0; int ret = 0;
char* mem; char* mem;
@ -141,27 +141,27 @@ static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** pem)
ret = MEMORY_E; ret = MEMORY_E;
} }
*pem = mem; *data = mem;
return ret; return ret;
} }
/* Read all the data from a BIO. /* Read all the data from a BIO.
* *
* @param [in, out] bio BIO object to read with. * @param [in, out] bio BIO object to read with.
* @param [out] pem Read data in a buffer. * @param [out] data Read data in a buffer.
* @param [out] pemSz Amount of data read in bytes. * @param [out] dataSz Amount of data read in bytes.
* @param [out] memAlloced Indicates whether return buffer was allocated. * @param [out] memAlloced Indicates whether return buffer was allocated.
* @return Negative on error. * @return Negative on error.
* @return 0 on success. * @return 0 on success.
*/ */
static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** pem, int* pemSz, static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** data, int* dataSz,
int* memAlloced) int* memAlloced)
{ {
int ret; int ret;
int sz; int sz;
if (bio->type == WOLFSSL_BIO_MEMORY) { if (bio->type == WOLFSSL_BIO_MEMORY) {
ret = wolfSSL_BIO_get_mem_data(bio, pem); ret = wolfSSL_BIO_get_mem_data(bio, data);
if (ret > 0) { if (ret > 0) {
bio->rdIdx += ret; bio->rdIdx += ret;
} }
@ -170,20 +170,20 @@ static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** pem, int* pemSz,
#ifndef WOLFSSL_NO_FSEEK #ifndef WOLFSSL_NO_FSEEK
/* Get pending or, when a file BIO, get length of file. */ /* Get pending or, when a file BIO, get length of file. */
else if ((sz = wolfSSL_BIO_get_len(bio)) > 0) { else if ((sz = wolfSSL_BIO_get_len(bio)) > 0) {
ret = wolfssl_read_bio_len(bio, sz, pem); ret = wolfssl_read_bio_len(bio, sz, data);
if (ret > 0) { if (ret > 0) {
*memAlloced = 1; *memAlloced = 1;
} }
} }
#else #else
else if ((sz = wolfSSL_BIO_pending(bio)) > 0) { else if ((sz = wolfSSL_BIO_pending(bio)) > 0) {
ret = wolfssl_read_bio_len(bio, sz, pem); ret = wolfssl_read_bio_len(bio, sz, data);
if (ret > 0) { if (ret > 0) {
*memAlloced = 1; *memAlloced = 1;
} }
} }
else if (bio->type == WOLFSSL_BIO_FILE) { else if (bio->type == WOLFSSL_BIO_FILE) {
ret = wolfssl_read_bio_file(bio, pem); ret = wolfssl_read_bio_file(bio, data);
if (ret > 0) { if (ret > 0) {
*memAlloced = 1; *memAlloced = 1;
} }
@ -196,7 +196,7 @@ static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** pem, int* pemSz,
} }
if (ret >= 0) { if (ret >= 0) {
*pemSz = ret; *dataSz = ret;
ret = 0; ret = 0;
} }
@ -224,7 +224,7 @@ static int wolfssl_file_len(XFILE fp, long* fileSz)
if (ret == 0) { if (ret == 0) {
/* Get file offset at end of file. */ /* Get file offset at end of file. */
curr = (long)XFTELL(fp); curr = (long)XFTELL(fp);
if (sz < 0) { if (curr < 0) {
ret = WOLFSSL_BAD_FILE; ret = WOLFSSL_BAD_FILE;
} }
} }
@ -259,7 +259,8 @@ static int wolfssl_file_len(XFILE fp, long* fileSz)
* @param [in] fp File pointer to read with. * @param [in] fp File pointer to read with.
* @param [out] data Read data in an allocated buffer. * @param [out] data Read data in an allocated buffer.
* @param [out] dataSz Amount of data read in bytes. * @param [out] dataSz Amount of data read in bytes.
* @return WOLFSSL_BAD_FILE on error. * @return WOLFSSL_BAD_FILE when reading fails.
* @return MEMORY_E when memory allocation fails.
* @return 0 on success. * @return 0 on success.
*/ */
static int wolfssl_read_file(XFILE fp, char** data, int* dataSz) static int wolfssl_read_file(XFILE fp, char** data, int* dataSz)
@ -270,10 +271,10 @@ static int wolfssl_read_file(XFILE fp, char** data, int* dataSz)
ret = wolfssl_file_len(fp, &sz); ret = wolfssl_file_len(fp, &sz);
if (ret == 0) { if (ret == 0) {
/* Allocate memory to big enough to hold whole file. */ /* Allocate memory big enough to hold whole file. */
mem = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM); mem = (char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM);
if (mem == NULL) { if (mem == NULL) {
ret = WOLFSSL_BAD_FILE; ret = MEMORY_E;
} }
} }
/* Read whole file into new buffer. */ /* Read whole file into new buffer. */

View File

@ -55487,7 +55487,10 @@ static int test_wolfSSL_DH(void)
AssertIntEQ(BN_set_word(g, 2), 1); AssertIntEQ(BN_set_word(g, 2), 1);
q = wolfSSL_BN_new(); q = wolfSSL_BN_new();
AssertNotNull(q); AssertNotNull(q);
AssertIntEQ(wolfSSL_DH_set0_pqg(dh, p, q, g), 1); AssertIntEQ(wolfSSL_DH_set0_pqg(dh, p, NULL, NULL), 1);
AssertIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, q, NULL), 1);
AssertIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, NULL, g), 1);
AssertIntEQ(wolfSSL_DH_set0_pqg(dh, NULL, NULL, NULL), 1);
/* p, q and g are now owned by dh - don't free. */ /* p, q and g are now owned by dh - don't free. */
DH_free(dh); DH_free(dh);
@ -55685,7 +55688,8 @@ static int test_wolfSSL_DH_check(void)
/* Break dh prime to test if codes = DH_CHECK_P_NOT_PRIME */ /* Break dh prime to test if codes = DH_CHECK_P_NOT_PRIME */
pTmp = dh->p; pTmp = dh->p;
dh->p = NULL; dh->p = NULL;
AssertIntEQ(wolfSSL_DH_check(dh, &codes), 0); AssertIntEQ(wolfSSL_DH_check(dh, &codes), 1);
AssertIntEQ(wolfSSL_DH_check(dh, NULL), 0);
AssertIntEQ(codes, DH_CHECK_P_NOT_PRIME); AssertIntEQ(codes, DH_CHECK_P_NOT_PRIME);
/* set dh->p back to normal so it wont fail on next tests */ /* set dh->p back to normal so it wont fail on next tests */
dh->p = pTmp; dh->p = pTmp;
@ -55694,7 +55698,8 @@ static int test_wolfSSL_DH_check(void)
/* Break dh generator to test if codes = DH_NOT_SUITABLE_GENERATOR */ /* Break dh generator to test if codes = DH_NOT_SUITABLE_GENERATOR */
gTmp = dh->g; gTmp = dh->g;
dh->g = NULL; dh->g = NULL;
AssertIntEQ(wolfSSL_DH_check(dh, &codes), 0); AssertIntEQ(wolfSSL_DH_check(dh, &codes), 1);
AssertIntEQ(wolfSSL_DH_check(dh, NULL), 0);
AssertIntEQ(codes, DH_NOT_SUITABLE_GENERATOR); AssertIntEQ(codes, DH_NOT_SUITABLE_GENERATOR);
dh->g = gTmp; dh->g = gTmp;
gTmp = NULL; gTmp = NULL;
@ -55705,7 +55710,8 @@ static int test_wolfSSL_DH_check(void)
dh = DH_new(); dh = DH_new();
AssertNotNull(dh); AssertNotNull(dh);
/* Check empty DH. */ /* Check empty DH. */
AssertIntEQ(wolfSSL_DH_check(dh, &codes), 0); AssertIntEQ(wolfSSL_DH_check(dh, &codes), 1);
AssertIntEQ(wolfSSL_DH_check(dh, NULL), 0);
AssertIntEQ(codes, DH_NOT_SUITABLE_GENERATOR | DH_CHECK_P_NOT_PRIME); AssertIntEQ(codes, DH_NOT_SUITABLE_GENERATOR | DH_CHECK_P_NOT_PRIME);
/* Check non-prime valued p. */ /* Check non-prime valued p. */
AssertNotNull(p = BN_new()); AssertNotNull(p = BN_new());
@ -55713,7 +55719,8 @@ static int test_wolfSSL_DH_check(void)
AssertNotNull(g = BN_new()); AssertNotNull(g = BN_new());
AssertIntEQ(BN_set_word(g, 2), 1); AssertIntEQ(BN_set_word(g, 2), 1);
AssertIntEQ(DH_set0_pqg(dh, p, NULL, g), 1); AssertIntEQ(DH_set0_pqg(dh, p, NULL, g), 1);
AssertIntEQ(wolfSSL_DH_check(dh, &codes), 0); AssertIntEQ(wolfSSL_DH_check(dh, &codes), 1);
AssertIntEQ(wolfSSL_DH_check(dh, NULL), 0);
AssertIntEQ(codes, DH_CHECK_P_NOT_PRIME); AssertIntEQ(codes, DH_CHECK_P_NOT_PRIME);
DH_free(dh); DH_free(dh);