diff --git a/src/pk.c b/src/pk.c index c1773fb80..16b554acf 100644 --- a/src/pk.c +++ b/src/pk.c @@ -66,7 +66,7 @@ static int pem_write_bio_pubkey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key); * @return Negative on failure. * @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) { #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 info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, - DYNAMIC_TYPE_TMP_BUFFER); + DYNAMIC_TYPE_ENCRYPTEDINFO); if (info == NULL) { WOLFSSL_ERROR_MSG("Error getting memory for EncryptedInfo structure"); 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 - XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO); #endif return ret; } #endif -#if defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || !defined(WOLFCRYPT_ONLY)) +#if !defined(NO_RSA) || !defined(WOLFCRYPT_ONLY) #ifndef NO_BIO /* 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 */ if ((ret > 0) && ((memSz - ret) > 0) && (bio->type != WOLFSSL_BIO_FILE)) { - if (wolfSSL_BIO_write(bio, mem + ret, memSz - ret) <= 0) { - WOLFSSL_ERROR_MSG("Unable to advance bio read pointer"); + int res; + 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) { @@ -159,7 +167,7 @@ static int pem_read_bio_key(WOLFSSL_BIO* bio, wc_pem_password_cb* cb, #endif /* !NO_BIO */ #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] 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) \ && !defined(HAVE_USER_RSA)) || !defined(WOLFCRYPT_ONLY)) -#ifndef NO_BIO -/* Write the DER data as PEM into BIO. +/* Convert DER data to PEM in an allocated buffer. * - * @param [in, out] bio BIO object to write with. - * @param [in] der Buffer containing DER data. - * @param [in] derSz Size of DER data in bytes. - * @param [in] type Type of key being encoded. + * @param [in] der Buffer containing DER data. + * @param [in] derSz Size of DER data in bytes. + * @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_SUCCESS on success. */ -static int pem_write_bio_der(WOLFSSL_BIO* bio, unsigned char* der, int derSz, - int type) +static int der_to_pem_alloc(const unsigned char* der, int derSz, int type, + void* heap, byte** out, int* outSz) { int ret = WOLFSSL_SUCCESS; int pemSz; byte* pem = NULL; int len; + (void)heap; + pemSz = wc_DerToPem(der, derSz, NULL, 0, type); if (pemSz < 0) { ret = WOLFSSL_FAILURE; } 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) { 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) { - len = wolfSSL_BIO_write(bio, pem, pemSz); + int len = wolfSSL_BIO_write(bio, pem, pemSz); if (len != pemSz) { WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO"); 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); - WOLFSSL_LEAVE("pem_write_bio_der", ret); return ret; } #endif #endif -#if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(HAVE_USER_RSA) \ - && defined(OPENSSL_EXTRA)) || \ - ((defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \ - defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA)) && \ - !defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) +#if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_USER_RSA)) || (!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) #if !defined(NO_FILESYSTEM) /* 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] 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] heap Heap hint for dynamic memory allocation. * @return WOLFSSL_FAILURE on error. * @return WOLFSSL_SUCCESS on success. */ -static int pem_write_file_der(XFILE fp, unsigned char* der, int derSz, - int type) +static int der_write_to_file_as_pem(const unsigned char* der, int derSz, + XFILE fp, int type, void* heap) { - int ret = WOLFSSL_SUCCESS; + int ret; int pemSz; 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) { - pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - 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); + int len = (int)XFWRITE(pem, 1, pemSz, fp); if (len != pemSz) { WOLFSSL_ERROR_MSG("Unable to write full PEM to BIO"); 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); - WOLFSSL_LEAVE("pem_write_file_der", ret); return ret; } #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 */ -#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. * @@ -678,7 +690,7 @@ WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local) #ifdef WOLFSSL_SMALL_STACK /* 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 /* Check we have a local RNG object and initialize. */ if ((rng != NULL) && (wc_InitRng(rng) == 0)) { @@ -702,7 +714,7 @@ WC_RNG* wolfssl_make_rng(WC_RNG* rng, int* local) if (ret != rng) { #ifdef WOLFSSL_SMALL_STACK - XFREE(rng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(rng, NULL, DYNAMIC_TYPE_RNG); #endif } @@ -1668,7 +1680,8 @@ int wolfSSL_RSA_LoadDer_ex(WOLFSSL_RSA* rsa, const unsigned char* derBuf, * returned through pointer. * @param [in] in DER encoded RSA key data. * @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 WOLFSSL_RSA object on success. */ @@ -1739,16 +1752,13 @@ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa) ret = 0; } } - if ((ret == 1) && (pem_write_bio_der(bio, derBuf, derSz, PUBLICKEY_TYPE) != - WOLFSSL_SUCCESS)) { + if ((ret == 1) && (der_write_to_bio_as_pem(derBuf, derSz, bio, + PUBLICKEY_TYPE) != WOLFSSL_SUCCESS)) { ret = 0; } - if (derBuf != NULL) { - /* Dispose of DER buffer. */ - XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - } - + /* Dispose of DER buffer. */ + XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); 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) #ifndef NO_FILESYSTEM + /* 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] rsa RSA key to write. + * @param [in] type PEM type to write out. * @return 1 on success. * @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 derSz; byte* derBuf = NULL; - WOLFSSL_ENTER("wolfSSL_PEM_write_RSAPublicKey"); - /* Validate parameters. */ if ((fp == XBADFILE) || (rsa == NULL)) { WOLFSSL_ERROR_MSG("Bad Function Arguments"); @@ -1790,8 +1799,8 @@ int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *rsa) ret = 0; } } - if ((ret == 1) && (pem_write_file_der(fp, derBuf, derSz, PUBLICKEY_TYPE) != - WOLFSSL_SUCCESS)) { + if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp, type, + rsa->heap) != WOLFSSL_SUCCESS)) { 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); } - WOLFSSL_LEAVE("wolfSSL_PEM_write_RSAPublicKey", 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. * * 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 ret = 1; - 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; + return wolfssl_pem_write_rsa_public_key(fp, rsa, RSA_PUBLICKEY_TYPE); } #endif /* !NO_FILESYSTEM */ #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 * PEM decoder supports either 'RSA PUBLIC KEY' or 'PUBLIC KEY'. * - * @param [in] bio BIO object to read from. - * @param [out] out RSA key created. + * @param [in] fp File pointer to read from. + * @param [out] rsa RSA key created. * @param [in] cb Password callback when PEM encrypted. May be NULL. * @param [in] pass NUL terminated string for passphrase when PEM encrypted. * 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"); } } - /* Write PEM to file pointer. */ + /* Write PEM to BIO. */ if ((ret == 1) && (wolfSSL_BIO_write(bio, pem, plen) <= 0)) { WOLFSSL_ERROR_MSG("RSA private key BIO write failed"); ret = 0; @@ -3201,7 +3188,7 @@ static int wolfssl_rsa_generate_key_native(WOLFSSL_RSA* rsa, int bits, } #ifdef WOLFSSL_SMALL_STACK /* Dispose of any allocated RNG. */ - XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return ret; @@ -3497,7 +3484,7 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em, } #ifdef WOLFSSL_SMALL_STACK /* Dispose of any allocated RNG. */ - XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif return ret; @@ -3930,7 +3917,7 @@ int wolfSSL_RSA_sign_generic_padding(int hashAlg, const unsigned char* hash, } #ifdef WOLFSSL_SMALL_STACK /* 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); #endif @@ -4192,7 +4179,7 @@ int wolfSSL_RSA_public_encrypt(int len, const unsigned char* from, } #ifdef WOLFSSL_SMALL_STACK /* Dispose of any allocated RNG. */ - XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif /* wolfCrypt error means return -1. */ @@ -4468,7 +4455,7 @@ int wolfSSL_RSA_private_encrypt(int len, const unsigned char* from, } #ifdef WOLFSSL_SMALL_STACK /* Dispose of any allocated RNG. */ - XFREE(tmpRng, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(tmpRng, NULL, DYNAMIC_TYPE_RNG); #endif /* 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 +/* 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 #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 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) { WOLFSSL_DH *newDh = NULL; - int ret; word32 idx = 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"); err = 1; } - /* Decode DH key from DER. */ - if ((!err) && ((ret = wc_DhKeyDecode(*pp, &idx, (DhKey*)newDh->internal, - (word32)length)) != 0)) { - WOLFSSL_ERROR_MSG("DhKeyDecode() failed"); + if ((!err) && (wolfssl_dh_load_key(newDh, *pp, &idx, + (word32)length) != 0)) { + WOLFSSL_ERROR_MSG("Loading DH parameters failed"); 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)) { /* Return through parameter too. */ @@ -7194,7 +7260,7 @@ WOLFSSL_DH *wolfSSL_d2i_DHparams(WOLFSSL_DH **dh, const unsigned char **pp, } 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. * @@ -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 ret = 1; -#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) word32 idx = 0; -#else - byte* p = NULL; - byte* g = NULL; - word32 pSz = MAX_DH_SIZE; - word32 gSz = MAX_DH_SIZE; -#endif /* Validate parameters. */ 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; } -#if !defined(HAVE_FIPS) || FIPS_VERSION_GT(2,0) - /* Decode the parameters/key into the internal DH key. */ - if ((ret == 1) && (wc_DhKeyDecode(derBuf, &idx, (DhKey*)dh->internal, - (word32)derSz) < 0)) { - WOLFSSL_ERROR_MSG("wc_DhKeyDecode failed"); + if ((ret == 1) && (wolfssl_dh_load_key(dh, derBuf, &idx, + (word32)derSz) != 0)) { + WOLFSSL_ERROR_MSG("DH key decode failed"); 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; } @@ -7426,29 +7429,22 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) #if !defined(NO_BIO) || !defined(NO_FILESYSTEM) /* 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 with parameters if not NULL. When pointer to - * NULL, a new DH key is created. - * @param [in] cb Password callback when PEM encrypted. Not used. - * @param [in] pass NUL terminated string for passphrase when PEM - * encrypted. Not used. + * @param [in] bio BIO object to read from. + * @param [in, out] dh DH key to use. May be NULL. + * @param [in] pem PEM data to decode. + * @param [in] pemSz Size of PEM data in bytes. + * @param [in] memAlloced Indicates that pem was allocated and is to be + * freed after use. * @return DH key on success. * @return NULL on failure. */ -static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out, - unsigned char* pem, int pemSz, int memAlloced, wc_pem_password_cb *cb, - void *pass) +static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **dh, + unsigned char* pem, int pemSz, int memAlloced) { WOLFSSL_DH* localDh = NULL; DerBuffer *der = NULL; int err = 0; - /* Parameters are public data and are not encrypted. */ - (void)cb; - (void)pass; - /* Convert PEM to DER assuming DH Parameter format. */ if ((!err) && (PemToDer(pem, pemSz, DH_PARAM_TYPE, &der, NULL, NULL, NULL) < 0)) { @@ -7465,8 +7461,8 @@ static WOLFSSL_DH *wolfssl_dhparams_read_pem(WOLFSSL_DH **out, if (!err) { /* Use the DH key passed in or allocate a new one. */ - if (out != NULL) { - localDh = *out; + if (dh != NULL) { + localDh = *dh; } if (localDh == NULL) { 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) != 1)) { /* Free an allocated DH key. */ - if ((out == NULL) || (localDh != *out)) { + if ((dh == NULL) || (localDh != *dh)) { wolfSSL_DH_free(localDh); } localDh = NULL; err = 1; } /* Return the DH key on success. */ - if ((!err) && (out != NULL)) { - *out = localDh; + if ((!err) && (dh != NULL)) { + *dh = localDh; } /* 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. * * @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. * @param [in] cb Password callback when PEM encrypted. Not used. * @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 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) { 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"); + (void)cb; + (void)pass; + /* Validate parameters. */ if (bio == 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) { /* Create a DH key from the PEM - try two different headers. */ - localDh = wolfssl_dhparams_read_pem(out, mem, size, memAlloced, cb, - pass); + localDh = wolfssl_dhparams_read_pem(dh, mem, size, memAlloced); } return localDh; @@ -7569,12 +7567,15 @@ WOLFSSL_DH* wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH** dh, unsigned char* mem = NULL; int size = 0; + (void)cb; + (void)pass; + /* Read data from file pointer. */ if (wolfssl_read_file(fp, (char**)&mem, &size) != 0) { err = 1; } if (!err) { - localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1, cb, pass); + localDh = wolfssl_dhparams_read_pem(dh, mem, size, 1); } 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. * * @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. * @return <0 on error. * @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; } } - if ((ret == 1) && (pem_write_file_der(fp, derBuf, derSz, DH_PARAM_TYPE) != - WOLFSSL_SUCCESS)) { + if ((ret == 1) && (der_write_to_file_as_pem(derBuf, derSz, fp, + DH_PARAM_TYPE, NULL) != WOLFSSL_SUCCESS)) { ret = 0; } @@ -7779,6 +7780,7 @@ int SetDhExternal_ex(WOLFSSL_DH *dh, int elm) */ int SetDhExternal(WOLFSSL_DH *dh) { + /* Assuming Q not required when using this API. */ int elements = ELEMENT_P | ELEMENT_G | ELEMENT_PUB | ELEMENT_PRV; WOLFSSL_ENTER("SetDhExternal"); 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 * 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 0 on failure. */ @@ -7929,8 +7937,18 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, WOLFSSL_ENTER("wolfSSL_DH_set0_pqg"); - /* Validata parameters - q is optional. */ - if ((dh == NULL) || (p == NULL) || (g == NULL)) { + /* Validate parameters - q is optional. */ + 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"); ret = 0; } @@ -7939,14 +7957,20 @@ int wolfSSL_DH_set0_pqg(WOLFSSL_DH *dh, WOLFSSL_BIGNUM *p, /* Invalidate internal key. */ dh->inSet = 0; - /* Free external representation of parameters. */ - wolfSSL_BN_free(dh->p); - wolfSSL_BN_free(dh->q); - wolfSSL_BN_free(dh->g); - /* Set parameters to be the parameters passed in. */ - dh->p = p; - dh->q = q; - dh->g = g; + /* Free external representation of parameters and set with those passed + * in. */ + if (p != NULL) { + wolfSSL_BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + 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. */ 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. */ 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)) { *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) { int ret = 1; +#ifdef WOLFSSL_DH_EXTRA + DhKey *key = NULL; +#endif 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) { ret = 0; } +#ifdef WOLFSSL_DH_EXTRA + else { + key = (DhKey*)dh->internal; + } +#endif /* Replace public key when one passed in. */ if ((ret == 1) && (pub_key != NULL)) { wolfSSL_BN_free(dh->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. */ if ((ret == 1) && (priv_key != NULL)) { - wolfSSL_BN_free(dh->priv_key); + wolfSSL_BN_clear_free(dh->priv_key); dh->priv_key = priv_key; - } - - /* Update internal key if parameters set. */ - if ((ret == 1) && ((dh->p != NULL) && (dh->g != NULL))) { - ret = SetDhInternal(dh); + #ifdef WOLFSSL_DH_EXTRA + if (SetIndividualInternal(dh->priv_key, &key->priv) != 1) { + ret = 0; + } + #endif } 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 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 [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. */ int isPrime = MP_NO; 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)) { errors |= DH_CHECK_P_NOT_PRIME; } @@ -8162,8 +8199,8 @@ int wolfSSL_DH_check(const WOLFSSL_DH *dh, int *codes) if (codes != NULL) { *codes = errors; } - if (errors) { - ret = 0; + else if (errors) { + ret = 0; } return ret; diff --git a/src/ssl.c b/src/ssl.c index df029e121..e527cc133 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -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); 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); } @@ -28350,7 +28350,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, 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 */ diff --git a/src/ssl_misc.c b/src/ssl_misc.c index 785a8e974..8db6931d1 100644 --- a/src/ssl_misc.c +++ b/src/ssl_misc.c @@ -27,7 +27,7 @@ #if !defined(WOLFSSL_SSL_MISC_INCLUDED) #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 #else @@ -42,12 +42,12 @@ * * Allocates a chunk and reads into it until it is full. * - * @param [in, out] bio BIO object to read with. - * @param [out] pem Read data in a new buffer. + * @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** pem) +static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** data) { int ret = 0; char* mem; @@ -110,20 +110,20 @@ static int wolfssl_read_bio_file(WOLFSSL_BIO* bio, char** pem) } } - *pem = mem; + *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] pem Read data in a new 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** pem) +static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** data) { int ret = 0; char* mem; @@ -141,27 +141,27 @@ static int wolfssl_read_bio_len(WOLFSSL_BIO* bio, int sz, char** pem) ret = MEMORY_E; } - *pem = mem; + *data = mem; return ret; } /* Read all the data from a BIO. * * @param [in, out] bio BIO object to read with. - * @param [out] pem Read data in a buffer. - * @param [out] pemSz Amount of data read in bytes. + * @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** pem, int* pemSz, +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, pem); + ret = wolfSSL_BIO_get_mem_data(bio, data); if (ret > 0) { bio->rdIdx += ret; } @@ -170,20 +170,20 @@ static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** pem, int* pemSz, #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, pem); + 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, pem); + 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, pem); + ret = wolfssl_read_bio_file(bio, data); if (ret > 0) { *memAlloced = 1; } @@ -196,7 +196,7 @@ static int wolfssl_read_bio(WOLFSSL_BIO* bio, char** pem, int* pemSz, } if (ret >= 0) { - *pemSz = ret; + *dataSz = ret; ret = 0; } @@ -224,7 +224,7 @@ static int wolfssl_file_len(XFILE fp, long* fileSz) if (ret == 0) { /* Get file offset at end of file. */ curr = (long)XFTELL(fp); - if (sz < 0) { + if (curr < 0) { 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 [out] data Read data in an allocated buffer. * @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. */ 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); 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); if (mem == NULL) { - ret = WOLFSSL_BAD_FILE; + ret = MEMORY_E; } } /* Read whole file into new buffer. */ diff --git a/tests/api.c b/tests/api.c index 67d32b966..077b02a99 100644 --- a/tests/api.c +++ b/tests/api.c @@ -55487,7 +55487,10 @@ static int test_wolfSSL_DH(void) AssertIntEQ(BN_set_word(g, 2), 1); q = wolfSSL_BN_new(); 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. */ 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 */ pTmp = dh->p; 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); /* set dh->p back to normal so it wont fail on next tests */ 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 */ gTmp = dh->g; 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); dh->g = gTmp; gTmp = NULL; @@ -55705,7 +55710,8 @@ static int test_wolfSSL_DH_check(void) dh = DH_new(); AssertNotNull(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); /* Check non-prime valued p. */ AssertNotNull(p = BN_new()); @@ -55713,7 +55719,8 @@ static int test_wolfSSL_DH_check(void) AssertNotNull(g = BN_new()); AssertIntEQ(BN_set_word(g, 2), 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); DH_free(dh);