mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 04:34:41 +02:00
Add BIO_up_ref(), PEM_read_DHparam(), EVP_MD_nid() (#4348)
* add BIO_up_ref * add PEM_read_DHparams() * add EVP_MD_nid() * exclude PEM_read_DHparams when NO_FILESYSTEM defined * review feedback: single threaded, indents, EVP_MD_nid
This commit is contained in:
26
src/bio.c
26
src/bio.c
@@ -725,6 +725,32 @@ long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Increment the WOLFSSL_BIO ref count by one, prevents BIO from being
|
||||
* freed until ref count is back down to 1.
|
||||
*
|
||||
* bio the structure to increment ref count
|
||||
*
|
||||
* returns 1 on success, 0 on failure */
|
||||
|
||||
int wolfSSL_BIO_up_ref(WOLFSSL_BIO* bio)
|
||||
{
|
||||
if (bio) {
|
||||
#ifndef SINGLE_THREADED
|
||||
if (wc_LockMutex(&bio->refMutex) != 0) {
|
||||
WOLFSSL_MSG("Failed to lock BIO mutex");
|
||||
}
|
||||
#endif
|
||||
bio->refCount++;
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&bio->refMutex);
|
||||
#endif
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
93
src/ssl.c
93
src/ssl.c
@@ -44900,6 +44900,47 @@ end:
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* Reads DH parameters from a file pointer into WOLFSSL_DH structure.
|
||||
*
|
||||
* fp file pointer to read DH parameter file from
|
||||
* x output WOLFSSL_DH to be created and populated from fp
|
||||
* cb password callback, to be used to decrypt encrypted DH parameters PEM
|
||||
* u context pointer to user-defined data to be received back in password cb
|
||||
*
|
||||
* Returns new WOLFSSL_DH structure pointer on success, NULL on failure. */
|
||||
WOLFSSL_DH *wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH **x,
|
||||
pem_password_cb *cb, void *u)
|
||||
{
|
||||
WOLFSSL_BIO* fbio = NULL;
|
||||
WOLFSSL_DH* dh = NULL;
|
||||
|
||||
if (fp == NULL) {
|
||||
WOLFSSL_MSG("DH parameter file cannot be NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fbio = wolfSSL_BIO_new(wolfSSL_BIO_s_file());
|
||||
if (fbio == NULL) {
|
||||
WOLFSSL_MSG("Unable to create file BIO to process DH PEM");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_BIO_set_fp(fbio, fp, BIO_NOCLOSE) != WOLFSSL_SUCCESS) {
|
||||
wolfSSL_BIO_free(fbio);
|
||||
WOLFSSL_MSG("wolfSSL_BIO_set_fp error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* wolfSSL_PEM_read_bio_DHparams() sanitizes x, cb, u args */
|
||||
dh = wolfSSL_PEM_read_bio_DHparams(fbio, x, cb, u);
|
||||
|
||||
wolfSSL_BIO_free(fbio);
|
||||
return dh;
|
||||
}
|
||||
#endif /* !NO_FILESYSTEM */
|
||||
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
#if defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
|
||||
@@ -57164,7 +57205,19 @@ int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
|
||||
if (method->createCb) {
|
||||
method->createCb(bio);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
|
||||
bio->refCount = 1;
|
||||
#ifndef SINGLE_THREADED
|
||||
if (wc_InitMutex(&bio->refMutex) != 0) {
|
||||
wolfSSL_BIO_free(bio);
|
||||
WOLFSSL_MSG("wc_InitMutex failed for WOLFSSL_BIO");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
return bio;
|
||||
}
|
||||
|
||||
@@ -57209,13 +57262,14 @@ int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
|
||||
int wolfSSL_BIO_free(WOLFSSL_BIO* bio)
|
||||
{
|
||||
int ret;
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
|
||||
int doFree = 0;
|
||||
#endif
|
||||
|
||||
/* unchain?, doesn't matter in goahead since from free all */
|
||||
WOLFSSL_ENTER("wolfSSL_BIO_free");
|
||||
if (bio) {
|
||||
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
|
||||
wolfSSL_CRYPTO_cleanup_ex_data(&bio->ex_data);
|
||||
#endif
|
||||
|
||||
if (bio->infoCb) {
|
||||
/* info callback is called before free */
|
||||
ret = (int)bio->infoCb(bio, WOLFSSL_BIO_CB_FREE, NULL, 0, 0, 1);
|
||||
@@ -57224,6 +57278,37 @@ int wolfSSL_CONF_cmd(WOLFSSL_CONF_CTX* cctx, const char* cmd, const char* value)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
|
||||
#ifndef SINGLE_THREADED
|
||||
if (wc_LockMutex(&bio->refMutex) != 0) {
|
||||
WOLFSSL_MSG("Couldn't lock BIO mutex");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* only free if all references to it are done */
|
||||
bio->refCount--;
|
||||
if (bio->refCount == 0) {
|
||||
doFree = 1;
|
||||
}
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&bio->refMutex);
|
||||
#endif
|
||||
|
||||
if (!doFree) {
|
||||
/* return success if BIO ref count is not 1 yet */
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_FreeMutex(&bio->refMutex);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EX_DATA_CLEANUP_HOOKS
|
||||
wolfSSL_CRYPTO_cleanup_ex_data(&bio->ex_data);
|
||||
#endif
|
||||
|
||||
/* call custom set free callback */
|
||||
if (bio->method && bio->method->freeCb) {
|
||||
bio->method->freeCb(bio);
|
||||
|
84
tests/api.c
84
tests/api.c
@@ -37045,6 +37045,24 @@ static void test_wolfSSL_BIO_f_md(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_wolfSSL_BIO_up_ref(void)
|
||||
{
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
|
||||
BIO* bio;
|
||||
printf(testingFmt, "wolfSSL_BIO_up_ref()");
|
||||
|
||||
AssertNotNull(bio = BIO_new(BIO_f_md()));
|
||||
AssertIntEQ(BIO_up_ref(NULL), 0);
|
||||
AssertIntEQ(BIO_up_ref(bio), 1);
|
||||
BIO_free(bio);
|
||||
AssertIntEQ(BIO_up_ref(bio), 1);
|
||||
BIO_free(bio);
|
||||
BIO_free(bio);
|
||||
|
||||
printf(resultFmt, "passed");
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* !NO_BIO */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_IO_TESTS_DEPENDENCIES)
|
||||
@@ -38836,7 +38854,50 @@ static int test_wolfSSL_EVP_Cipher_extra(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_wolfSSL_PEM_read_DHparams(void)
|
||||
{
|
||||
#if defined(OPENSSL_ALL) && !defined(NO_BIO) && \
|
||||
!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA) && !defined(NO_FILESYSTEM)
|
||||
DH* dh;
|
||||
XFILE fp;
|
||||
unsigned char derOut[300];
|
||||
unsigned char* derOutBuf = derOut;
|
||||
int derOutSz = 0;
|
||||
|
||||
unsigned char derExpected[300];
|
||||
int derExpectedSz = 0;
|
||||
|
||||
printf(testingFmt, "wolfSSL_PEM_read_DHparams()");
|
||||
|
||||
XMEMSET(derOut, 0, sizeof(derOut));
|
||||
XMEMSET(derExpected, 0, sizeof(derExpected));
|
||||
|
||||
/* open DH param file, read into DH struct */
|
||||
AssertNotNull(fp = XFOPEN(dhParamFile, "rb"));
|
||||
|
||||
/* bad args */
|
||||
AssertNull(dh = PEM_read_DHparams(NULL, &dh, NULL, NULL));
|
||||
AssertNull(dh = PEM_read_DHparams(NULL, NULL, NULL, NULL));
|
||||
|
||||
/* good args */
|
||||
AssertNotNull(dh = PEM_read_DHparams(fp, &dh, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
|
||||
/* read in certs/dh2048.der for comparison against exported params */
|
||||
fp = XFOPEN("./certs/dh2048.der", "rb");
|
||||
AssertTrue(fp != XBADFILE);
|
||||
derExpectedSz = (int)XFREAD(derExpected, 1, sizeof(derExpected), fp);
|
||||
XFCLOSE(fp);
|
||||
|
||||
/* export DH back to DER and compare */
|
||||
derOutSz = wolfSSL_i2d_DHparams(dh, &derOutBuf);
|
||||
AssertIntEQ(derOutSz, derExpectedSz);
|
||||
AssertIntEQ(XMEMCMP(derOut, derExpected, derOutSz), 0);
|
||||
DH_free(dh);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_wolfSSL_AES_ecb_encrypt(void)
|
||||
{
|
||||
@@ -41416,6 +41477,26 @@ static void test_wolfSSL_EVP_get_digestbynid(void)
|
||||
printf(resultFmt, passed);
|
||||
#endif
|
||||
}
|
||||
static void test_wolfSSL_EVP_MD_nid(void)
|
||||
{
|
||||
#if defined(OPENSSL_ALL)
|
||||
|
||||
printf(testingFmt, "wolfSSL_EVP_MD_nid");
|
||||
|
||||
#ifndef NO_MD5
|
||||
AssertIntEQ(EVP_MD_nid(EVP_md5()), NID_md5);
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
AssertIntEQ(EVP_MD_nid(EVP_sha1()), NID_sha1);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
AssertIntEQ(EVP_MD_nid(EVP_sha256()), NID_sha256);
|
||||
#endif
|
||||
AssertIntEQ(EVP_MD_nid(NULL), NID_undef);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif
|
||||
}
|
||||
static void test_wolfSSL_EVP_PKEY_get0_EC_KEY(void)
|
||||
{
|
||||
#if defined(HAVE_ECC) && defined(OPENSSL_ALL)
|
||||
@@ -49285,6 +49366,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_BIO_accept();
|
||||
test_wolfSSL_BIO_printf();
|
||||
test_wolfSSL_BIO_f_md();
|
||||
test_wolfSSL_BIO_up_ref();
|
||||
#endif
|
||||
test_wolfSSL_cert_cb();
|
||||
test_wolfSSL_SESSION();
|
||||
@@ -49304,6 +49386,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_SHA();
|
||||
test_wolfSSL_DH_1536_prime();
|
||||
test_wolfSSL_PEM_write_DHparams();
|
||||
test_wolfSSL_PEM_read_DHparams();
|
||||
test_wolfSSL_AES_ecb_encrypt();
|
||||
test_wolfSSL_MD5();
|
||||
test_wolfSSL_MD5_Transform();
|
||||
@@ -49397,6 +49480,7 @@ void ApiTest(void)
|
||||
test_wolfSSL_EVP_aes_192_gcm();
|
||||
test_wolfSSL_EVP_ripemd160();
|
||||
test_wolfSSL_EVP_get_digestbynid();
|
||||
test_wolfSSL_EVP_MD_nid();
|
||||
test_wolfSSL_EVP_PKEY_get0_EC_KEY();
|
||||
test_wolfSSL_EVP_X_STATE();
|
||||
test_wolfSSL_EVP_X_STATE_LEN();
|
||||
|
@@ -3716,16 +3716,28 @@ const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Returns the NID of the WOLFSSL_EVP_MD passed in.
|
||||
*
|
||||
* type - pointer to WOLFSSL_EVP_MD for which to return NID value
|
||||
*
|
||||
* Returns NID on success, or NID_undef if none exists.
|
||||
*/
|
||||
int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
|
||||
{
|
||||
const struct s_ent *ent ;
|
||||
WOLFSSL_ENTER("EVP_MD_type");
|
||||
|
||||
if (type == NULL) {
|
||||
WOLFSSL_MSG("MD type arg is NULL");
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
for( ent = md_tbl; ent->name != NULL; ent++){
|
||||
if(XSTRNCMP((const char *)type, ent->name, XSTRLEN(ent->name)+1) == 0) {
|
||||
return ent->nid;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
#ifndef NO_MD4
|
||||
|
@@ -63,6 +63,7 @@
|
||||
#define BIO_ctrl_reset_read_request wolfSSL_BIO_ctrl_reset_read_request
|
||||
#define BIO_set_write_buf_size wolfSSL_BIO_set_write_buf_size
|
||||
#define BIO_make_bio_pair wolfSSL_BIO_make_bio_pair
|
||||
#define BIO_up_ref wolfSSL_BIO_up_ref
|
||||
|
||||
#define BIO_new_fd wolfSSL_BIO_new_fd
|
||||
#define BIO_set_fp wolfSSL_BIO_set_fp
|
||||
|
@@ -907,6 +907,7 @@ typedef WOLFSSL_ASN1_PCTX ASN1_PCTX;
|
||||
|
||||
#define EVP_get_cipherbynid wolfSSL_EVP_get_cipherbynid
|
||||
#define EVP_get_digestbynid wolfSSL_EVP_get_digestbynid
|
||||
#define EVP_MD_nid wolfSSL_EVP_MD_type
|
||||
#define EVP_get_cipherbyname wolfSSL_EVP_get_cipherbyname
|
||||
#define EVP_get_digestbyname wolfSSL_EVP_get_digestbyname
|
||||
|
||||
|
@@ -1069,6 +1069,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
|
||||
|
||||
#define DHparams_dup wolfSSL_DH_dup
|
||||
#define PEM_read_bio_DHparams wolfSSL_PEM_read_bio_DHparams
|
||||
#define PEM_read_DHparams wolfSSL_PEM_read_DHparams
|
||||
#define PEM_read_bio_DSAparams wolfSSL_PEM_read_bio_DSAparams
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY)
|
||||
|
@@ -530,6 +530,12 @@ struct WOLFSSL_BIO {
|
||||
#ifdef HAVE_EX_DATA
|
||||
WOLFSSL_CRYPTO_EX_DATA ex_data;
|
||||
#endif
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)
|
||||
#ifndef SINGLE_THREADED
|
||||
wolfSSL_Mutex refMutex; /* ref count mutex */
|
||||
#endif
|
||||
int refCount; /* reference count */
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct WOLFSSL_COMP_METHOD {
|
||||
@@ -1534,6 +1540,7 @@ WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int i
|
||||
|
||||
WOLFSSL_API int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *b, long size);
|
||||
WOLFSSL_API int wolfSSL_BIO_make_bio_pair(WOLFSSL_BIO *b1, WOLFSSL_BIO *b2);
|
||||
WOLFSSL_API int wolfSSL_BIO_up_ref(WOLFSSL_BIO *b);
|
||||
WOLFSSL_API int wolfSSL_BIO_ctrl_reset_read_request(WOLFSSL_BIO *b);
|
||||
WOLFSSL_API int wolfSSL_BIO_nread0(WOLFSSL_BIO *bio, char **buf);
|
||||
WOLFSSL_API int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num);
|
||||
@@ -4085,6 +4092,10 @@ WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_fp(XFILE fp, int c);
|
||||
WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*);
|
||||
WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp,
|
||||
WOLFSSL_DH **x, pem_password_cb *cb, void *u);
|
||||
#ifndef NO_FILESYSTEM
|
||||
WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_DHparams(XFILE fp, WOLFSSL_DH **x,
|
||||
pem_password_cb *cb, void *u);
|
||||
#endif
|
||||
WOLFSSL_API WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSAparams(WOLFSSL_BIO *bp,
|
||||
WOLFSSL_DSA **x, pem_password_cb *cb, void *u);
|
||||
WOLFSSL_API int wolfSSL_PEM_write_bio_X509_REQ(WOLFSSL_BIO *bp,WOLFSSL_X509 *x);
|
||||
|
Reference in New Issue
Block a user