Merge pull request #4658 from julek-wolfssl/apache-2.4.51

Add Apache 2.4.51 support
pull/4672/head
David Garske 2021-12-16 08:52:10 -08:00 committed by GitHub
commit dec78169bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 525 additions and 237 deletions

View File

@ -4854,6 +4854,8 @@ then
AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DWOLFSSL_SIGNER_DER_CERT" AM_CFLAGS="$AM_CFLAGS -DHAVE_EX_DATA -DWOLFSSL_SIGNER_DER_CERT"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_KEEP_SNI"
AM_CFLAGS="$AM_CFLAGS -DOPENSSL_COMPATIBLE_DEFAULTS"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_OCSP_ISSUER_CHECK"
# Requires OCSP make sure on # Requires OCSP make sure on
if test "x$ENABLED_OCSP" = "xno" if test "x$ENABLED_OCSP" = "xno"

View File

@ -1895,7 +1895,11 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
if (bio == NULL) if (bio == NULL)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
if (bio->type == WOLFSSL_BIO_FILE) { if (bio->method != NULL && bio->method->ctrlCb != NULL) {
WOLFSSL_MSG("Calling custom BIO flush callback");
return (int)bio->method->ctrlCb(bio, BIO_CTRL_FLUSH, 0, NULL);
}
else if (bio->type == WOLFSSL_BIO_FILE) {
#if !defined(NO_FILESYSTEM) && defined(XFFLUSH) #if !defined(NO_FILESYSTEM) && defined(XFFLUSH)
if (XFFLUSH((FILE *)bio->ptr) != 0) if (XFFLUSH((FILE *)bio->ptr) != 0)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;

View File

@ -5876,7 +5876,11 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
ret = WOLFSSL_SUCCESS; /* set default ret */ ret = WOLFSSL_SUCCESS; /* set default ret */
ssl->ctx = ctx; /* only for passing to calls, options could change */ ssl->ctx = ctx; /* only for passing to calls, options could change */
ssl->version = ctx->method->version; /* Don't change version on a SSL object that has already started a
* handshake */
if (!ssl->msgsReceived.got_client_hello &&
!ssl->msgsReceived.got_server_hello)
ssl->version = ctx->method->version;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
ssl->options.mask = ctx->mask; ssl->options.mask = ctx->mask;
ssl->options.minProto = ctx->minProto; ssl->options.minProto = ctx->minProto;
@ -9343,6 +9347,9 @@ int CheckAvailableSize(WOLFSSL *ssl, int size)
static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx, static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
RecordLayerHeader* rh, word16 *size) RecordLayerHeader* rh, word16 *size)
{ {
#ifdef OPENSSL_ALL
word32 start = *inOutIdx;
#endif
if (!ssl->options.dtls) { if (!ssl->options.dtls) {
#ifdef HAVE_FUZZER #ifdef HAVE_FUZZER
if (ssl->fuzzerCb) if (ssl->fuzzerCb)
@ -9453,6 +9460,22 @@ static int GetRecordHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
break; break;
case no_type: case no_type:
default: default:
#ifdef OPENSSL_ALL
{
char *method = (char*)input + start;
/* Attempt to identify if this is a plain HTTP request.
* No size checks because this function assumes at least
* RECORD_HEADER_SZ size of data has been read which is
* also the longest string comparison in this if. */
if (XSTRNCMP(method, "GET ", XSTR_SIZEOF("GET ")) == 0 ||
XSTRNCMP(method, "POST ", XSTR_SIZEOF("POST ")) == 0 ||
XSTRNCMP(method, "HEAD ", XSTR_SIZEOF("HEAD ")) == 0 ||
XSTRNCMP(method, "PUT ", XSTR_SIZEOF("PUT ")) == 0) {
WOLFSSL_MSG("Plain HTTP request detected");
return SSL_R_HTTP_REQUEST;
}
}
#endif
WOLFSSL_MSG("Unknown Record Type"); WOLFSSL_MSG("Unknown Record Type");
return UNKNOWN_RECORD_TYPE; return UNKNOWN_RECORD_TYPE;
} }
@ -12445,9 +12468,12 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
} }
#endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */ #endif /* SESSION_CERTS && WOLFSSL_ALT_CERT_CHAINS */
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
/* Check peer's certificate version number. TLS 1.2 / 1.3 /* Check peer's certificate version number. TLS 1.2 / 1.3
* requires the clients certificate be version 3 unless a * requires the clients certificate be version 3 unless a
* different version has been negotiated using RFC 7250 */ * different version has been negotiated using RFC 7250.
* OpenSSL doesn't appear to be performing this check.
* For TLS 1.3 see RFC8446 Section 4.4.2.3 */
if (ssl->options.side == WOLFSSL_SERVER_END) { if (ssl->options.side == WOLFSSL_SERVER_END) {
if (args->dCert->version != WOLFSSL_X509_V3) { if (args->dCert->version != WOLFSSL_X509_V3) {
WOLFSSL_MSG("Peers certificate was not version 3!"); WOLFSSL_MSG("Peers certificate was not version 3!");
@ -12456,6 +12482,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
* giving the user a chance to override */ * giving the user a chance to override */
} }
} }
#endif
/* check if fatal error */ /* check if fatal error */
if (args->verifyErr) { if (args->verifyErr) {
@ -30023,8 +30050,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (ret == 0 && ssl->options.dtls) if (ret == 0 && ssl->options.dtls)
DtlsMsgPoolReset(ssl); DtlsMsgPoolReset(ssl);
#endif #endif
WOLFSSL_LEAVE("DoClientHello", ret);
WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
out: out:
@ -30037,6 +30062,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = CertSetupCbWrapper(ssl); ret = CertSetupCbWrapper(ssl);
#endif #endif
WOLFSSL_LEAVE("DoClientHello", ret);
WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO);
return ret; return ret;
} }

View File

@ -2102,7 +2102,8 @@ int SetCipherSpecs(WOLFSSL* ssl)
} /* if ECC / Normal suites else */ } /* if ECC / Normal suites else */
/* set TLS if it hasn't been turned off */ /* set TLS if it hasn't been turned off */
if (ssl->version.major == 3 && ssl->version.minor >= 1) { if (ssl->version.major == SSLv3_MAJOR &&
ssl->version.minor >= TLSv1_MINOR) {
#ifndef NO_TLS #ifndef NO_TLS
ssl->options.tls = 1; ssl->options.tls = 1;
#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY) #if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_AEAD_ONLY)
@ -2112,9 +2113,9 @@ int SetCipherSpecs(WOLFSSL* ssl)
ssl->hmac = Renesas_cmn_TLS_hmac; ssl->hmac = Renesas_cmn_TLS_hmac;
#endif #endif
#endif #endif
if (ssl->version.minor >= 2) { if (ssl->version.minor >= TLSv1_1_MINOR) {
ssl->options.tls1_1 = 1; ssl->options.tls1_1 = 1;
if (ssl->version.minor >= 4) if (ssl->version.minor >= TLSv1_3_MINOR)
ssl->options.tls1_3 = 1; ssl->options.tls1_3 = 1;
} }
#endif #endif

View File

@ -1217,17 +1217,46 @@ int wolfSSL_OCSP_id_get0_info(WOLFSSL_ASN1_STRING **name,
return 1; return 1;
} }
#ifndef NO_WOLFSSL_STUB
int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val, int wolfSSL_OCSP_request_add1_nonce(OcspRequest* req, unsigned char* val,
int sz) int sz)
{ {
WOLFSSL_STUB("wolfSSL_OCSP_request_add1_nonce"); WC_RNG rng;
(void)req;
(void)val; WOLFSSL_ENTER("wolfSSL_OCSP_request_add1_nonce");
(void)sz;
return WOLFSSL_FATAL_ERROR; if (req == NULL || sz > MAX_OCSP_NONCE_SZ) {
} WOLFSSL_MSG("Bad parameter");
return WOLFSSL_FAILURE;
}
if (sz <= 0)
sz = MAX_OCSP_NONCE_SZ;
if (val != NULL) {
XMEMCPY(req->nonce, val, sz);
}
else {
if (
#ifndef HAVE_FIPS
wc_InitRng_ex(&rng, req->heap, INVALID_DEVID)
#else
wc_InitRng(&rng)
#endif #endif
!= 0) {
WOLFSSL_MSG("RNG init failed");
return WOLFSSL_FAILURE;
}
if (wc_RNG_GenerateBlock(&rng, req->nonce, sz) != 0) {
WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
wc_FreeRng(&rng);
return WOLFSSL_FAILURE;
}
wc_FreeRng(&rng);
}
req->nonceSz = sz;
return WOLFSSL_SUCCESS;
}
/* Returns result of OCSP nonce comparison. Return values: /* Returns result of OCSP nonce comparison. Return values:
* 1 - nonces are both present and equal * 1 - nonces are both present and equal

372
src/ssl.c
View File

@ -77,6 +77,7 @@
#ifdef OPENSSL_EXTRA #ifdef OPENSSL_EXTRA
/* openssl headers begin */ /* openssl headers begin */
#include <wolfssl/openssl/ssl.h>
#include <wolfssl/openssl/aes.h> #include <wolfssl/openssl/aes.h>
#ifndef WOLFCRYPT_ONLY #ifndef WOLFCRYPT_ONLY
#include <wolfssl/openssl/hmac.h> #include <wolfssl/openssl/hmac.h>
@ -17748,6 +17749,7 @@ cleanup:
{ {
WOLFSSL_ENTER("wolfSSL_ERR_get_error"); WOLFSSL_ENTER("wolfSSL_ERR_get_error");
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
{ {
unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL, unsigned long ret = wolfSSL_ERR_peek_error_line_data(NULL, NULL,
@ -17755,7 +17757,7 @@ cleanup:
wc_RemoveErrorNode(-1); wc_RemoveErrorNode(-1);
return ret; return ret;
} }
#elif (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)) #else
{ {
int ret = wc_PullErrorNode(NULL, NULL, NULL); int ret = wc_PullErrorNode(NULL, NULL, NULL);
@ -17771,12 +17773,13 @@ cleanup:
return (unsigned long)ret; return (unsigned long)ret;
} }
#endif
#else #else
return (unsigned long)(0 - NOT_COMPILED_IN); return (unsigned long)(0 - NOT_COMPILED_IN);
#endif #endif
} }
#if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)) #ifdef WOLFSSL_HAVE_ERROR_QUEUE
#ifndef NO_BIO #ifndef NO_BIO
/* print out and clear all errors */ /* print out and clear all errors */
void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio) void wolfSSL_ERR_print_errors(WOLFSSL_BIO* bio)
@ -17809,7 +17812,7 @@ cleanup:
} }
} }
#endif /* !NO_BIO */ #endif /* !NO_BIO */
#endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ #endif /* WOLFSSL_HAVE_ERROR_QUEUE */
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */ #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
@ -19537,9 +19540,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
void wolfSSL_ERR_clear_error(void) void wolfSSL_ERR_clear_error(void)
{ {
WOLFSSL_ENTER("wolfSSL_ERR_clear_error"); WOLFSSL_ENTER("wolfSSL_ERR_clear_error");
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
wc_ClearErrorNodes(); wc_ClearErrorNodes();
#endif #endif
} }
@ -19808,6 +19809,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
ssl->options.isClosed = 0; ssl->options.isClosed = 0;
ssl->options.connReset = 0; ssl->options.connReset = 0;
ssl->options.sentNotify = 0; ssl->options.sentNotify = 0;
ssl->options.closeNotify = 0;
ssl->options.sendVerify = 0; ssl->options.sendVerify = 0;
ssl->options.serverState = NULL_STATE; ssl->options.serverState = NULL_STATE;
ssl->options.clientState = NULL_STATE; ssl->options.clientState = NULL_STATE;
@ -20042,7 +20044,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
*/ */
unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line) unsigned long wolfSSL_ERR_get_error_line(const char** file, int* line)
{ {
#ifdef DEBUG_WOLFSSL #ifdef WOLFSSL_HAVE_ERROR_QUEUE
int ret = wc_PullErrorNode(file, NULL, line); int ret = wc_PullErrorNode(file, NULL, line);
if (ret < 0) { if (ret < 0) {
if (ret == BAD_STATE_E) return 0; /* no errors in queue */ if (ret == BAD_STATE_E) return 0; /* no errors in queue */
@ -20148,9 +20150,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line, unsigned long wolfSSL_ERR_get_error_line_data(const char** file, int* line,
const char** data, int *flags) const char** data, int *flags)
{ {
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
int ret; int ret;
WOLFSSL_STUB("wolfSSL_ERR_get_error_line_data"); WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
if (flags != NULL) { if (flags != NULL) {
if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) { if ((*flags & ERR_TXT_STRING) == ERR_TXT_STRING) {
@ -20181,6 +20184,15 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,
} }
return (unsigned long)ret; return (unsigned long)ret;
#else
WOLFSSL_ENTER("wolfSSL_ERR_get_error_line_data");
WOLFSSL_MSG("Error queue turned off, can not get error line");
(void)file;
(void)line;
(void)data;
(void)flags;
return 0;
#endif
} }
#endif /* OPENSSL_EXTRA */ #endif /* OPENSSL_EXTRA */
@ -23093,10 +23105,24 @@ int wolfSSL_get_shutdown(const WOLFSSL* ssl)
WOLFSSL_ENTER("wolfSSL_get_shutdown"); WOLFSSL_ENTER("wolfSSL_get_shutdown");
if (ssl) { if (ssl) {
/* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent * #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
* WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */ if (ssl->options.handShakeState == NULL_STATE) {
isShutdown = ((ssl->options.closeNotify||ssl->options.connReset) << 1) /* The SSL object was possibly cleared with wolfSSL_clear after
| (ssl->options.sentNotify); * a successful shutdown. Simulate a response for a full
* bidirectional shutdown. */
isShutdown = WOLFSSL_SENT_SHUTDOWN | WOLFSSL_RECEIVED_SHUTDOWN;
}
else
#endif
{
/* in OpenSSL, WOLFSSL_SENT_SHUTDOWN = 1, when closeNotifySent *
* WOLFSSL_RECEIVED_SHUTDOWN = 2, from close notify or fatal err */
if (ssl->options.sentNotify)
isShutdown |= WOLFSSL_SENT_SHUTDOWN;
if (ssl->options.closeNotify||ssl->options.connReset)
isShutdown |= WOLFSSL_RECEIVED_SHUTDOWN;
}
} }
return isShutdown; return isShutdown;
} }
@ -23404,6 +23430,9 @@ WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl)
if (ssl) { if (ssl) {
ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0; ssl->cipher.cipherSuite0 = ssl->options.cipherSuite0;
ssl->cipher.cipherSuite = ssl->options.cipherSuite; ssl->cipher.cipherSuite = ssl->options.cipherSuite;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
ssl->cipher.bits = ssl->specs.key_size * 8;
#endif
return &ssl->cipher; return &ssl->cipher;
} }
else else
@ -28069,6 +28098,8 @@ int wolfSSL_ERR_GET_LIB(unsigned long err)
value = (err & 0xFFFFFFL); value = (err & 0xFFFFFFL);
switch (value) { switch (value) {
case -SSL_R_HTTP_REQUEST:
return ERR_LIB_SSL;
case PEM_R_NO_START_LINE: case PEM_R_NO_START_LINE:
case PEM_R_PROBLEMS_GETTING_PASSWORD: case PEM_R_PROBLEMS_GETTING_PASSWORD:
case PEM_R_BAD_PASSWORD_READ: case PEM_R_BAD_PASSWORD_READ:
@ -28103,6 +28134,8 @@ int wolfSSL_ERR_GET_REASON(unsigned long err)
/* Nginx looks for this error to know to stop parsing certificates. */ /* Nginx looks for this error to know to stop parsing certificates. */
if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE)) if (err == ((ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE))
return PEM_R_NO_START_LINE; return PEM_R_NO_START_LINE;
if (err == ((ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST))
return SSL_R_HTTP_REQUEST;
#endif #endif
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON) #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
if (err == ((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG)) if (err == ((ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG))
@ -44398,23 +44431,6 @@ err:
} }
return ret; return ret;
} }
/* sets the values of X509_PKEY based on certificate passed in
* return WOLFSSL_SUCCESS on success */
static int wolfSSL_X509_PKEY_set(WOLFSSL_X509_PKEY* xPkey,
WOLFSSL_X509* x509)
{
if (xPkey == NULL || x509 == NULL) {
return BAD_FUNC_ARG;
}
wolfSSL_EVP_PKEY_free(xPkey->dec_pkey);
xPkey->dec_pkey = wolfSSL_X509_get_pubkey(x509);
if (xPkey->dec_pkey == NULL) {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* !NO_BIO */ #endif /* !NO_BIO */
@ -44430,47 +44446,9 @@ err:
#ifndef NO_BIO #ifndef NO_BIO
/* Takes control of x509 on success #define PEM_COMPARE_HEADER(start, end, header) \
* helper function to break out code needed to set WOLFSSL_X509_INFO up end - start == XSTR_SIZEOF(header) && XMEMCMP(start, header, \
* free's "info" passed in if is not defaults XSTR_SIZEOF(header)) == 0
*
* returns WOLFSSL_SUCCESS on success
*/
static int wolfSSL_X509_INFO_set(WOLFSSL_X509_INFO** info,
WOLFSSL_X509* x509)
{
if (info == NULL || x509 == NULL) {
return BAD_FUNC_ARG;
}
if (*info == NULL) {
return BAD_FUNC_ARG;
}
/* check is fresh "info" passed in, if not free it */
if ((*info)->x509 != NULL || (*info)->x_pkey != NULL) {
WOLFSSL_X509_INFO* tmp;
tmp = wolfSSL_X509_INFO_new();
if (tmp == NULL) {
WOLFSSL_MSG("Unable to create new structure");
return MEMORY_E;
}
wolfSSL_X509_INFO_free(*info);
(*info) = tmp;
}
(*info)->x509 = x509;
/* @TODO info->num */
/* @TODO info->enc_cipher */
/* @TODO info->enc_len */
/* @TODO info->enc_data */
/* @TODO info->crl */
(*info)->x_pkey = wolfSSL_X509_PKEY_new(x509->heap);
return wolfSSL_X509_PKEY_set((*info)->x_pkey, x509);
}
/** /**
* This read one structure from bio and returns the read structure * This read one structure from bio and returns the read structure
@ -44498,8 +44476,7 @@ err:
#ifdef HAVE_CRL #ifdef HAVE_CRL
DerBuffer* der = NULL; DerBuffer* der = NULL;
#endif #endif
WOLFSSL_BIO* pemBio = NULL;
(void)cb;
if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) { if (!bio || !x509 || *x509 || !crl || *crl || !x_pkey || *x_pkey) {
WOLFSSL_MSG("Bad input parameter or output parameters " WOLFSSL_MSG("Bad input parameter or output parameters "
@ -44508,10 +44485,8 @@ err:
} }
if ((l = wolfSSL_BIO_get_len(bio)) <= 0) { if ((l = wolfSSL_BIO_get_len(bio)) <= 0) {
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX)
/* No certificate in buffer */ /* No certificate in buffer */
WOLFSSL_ERROR(ASN_NO_PEM_HEADER); WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
#endif
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@ -44521,6 +44496,7 @@ err:
if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) != if (wolfSSL_BIO_read(bio, &pem[0], pem_struct_min_sz) !=
pem_struct_min_sz) { pem_struct_min_sz) {
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
goto err; goto err;
} }
@ -44580,10 +44556,8 @@ err:
goto err; goto err;
} }
else { else {
if (headerEnd - header == if (PEM_COMPARE_HEADER(header, headerEnd,
XSTR_SIZEOF("-----BEGIN CERTIFICATE-----") && "-----BEGIN CERTIFICATE-----")) {
XMEMCMP(header, "-----BEGIN CERTIFICATE-----",
XSTR_SIZEOF("-----BEGIN CERTIFICATE-----")) == 0) {
/* We have a certificate */ /* We have a certificate */
WOLFSSL_MSG("Parsing x509 cert"); WOLFSSL_MSG("Parsing x509 cert");
*x509 = wolfSSL_X509_load_certificate_buffer( *x509 = wolfSSL_X509_load_certificate_buffer(
@ -44595,10 +44569,8 @@ err:
} }
} }
#ifdef HAVE_CRL #ifdef HAVE_CRL
else if (headerEnd - header == else if (PEM_COMPARE_HEADER(header, headerEnd,
XSTR_SIZEOF("-----BEGIN X509 CRL-----") && "-----BEGIN X509 CRL-----")) {
XMEMCMP(header, "-----BEGIN X509 CRL-----",
XSTR_SIZEOF("-----BEGIN X509 CRL-----")) == 0) {
/* We have a crl */ /* We have a crl */
WOLFSSL_MSG("Parsing crl"); WOLFSSL_MSG("Parsing crl");
if((PemToDer((const unsigned char*) header, footerEnd - header, if((PemToDer((const unsigned char*) header, footerEnd - header,
@ -44614,9 +44586,31 @@ err:
} }
#endif #endif
else { else {
/* TODO support WOLFSSL_X509_PKEY as well */ WOLFSSL_MSG("Parsing x509 key");
WOLFSSL_MSG("Unsupported PEM structure");
goto err; if (!(*x_pkey = wolfSSL_X509_PKEY_new(NULL))) {
WOLFSSL_MSG("wolfSSL_X509_PKEY_new error");
goto err;
}
if (!(pemBio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()))) {
WOLFSSL_MSG("wolfSSL_BIO_new error");
goto err;
}
if (wolfSSL_BIO_write(pemBio, header,
(int)(footerEnd - header)) != footerEnd - header) {
WOLFSSL_MSG("wolfSSL_BIO_new error");
goto err;
}
if (wolfSSL_PEM_read_bio_PrivateKey(pemBio,
&(*x_pkey)->dec_pkey, cb, NULL) == NULL) {
WOLFSSL_MSG("wolfSSL_PEM_read_bio_PrivateKey error");
goto err;
}
wolfSSL_BIO_free(pemBio);
} }
} }
@ -44633,6 +44627,12 @@ err:
if (der) if (der)
FreeDer(&der); FreeDer(&der);
#endif #endif
if (*x_pkey) {
wolfSSL_X509_PKEY_free(*x_pkey);
*x_pkey = NULL;
}
if (pemBio)
wolfSSL_BIO_free(pemBio);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */ #endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
} }
@ -44666,75 +44666,115 @@ err:
{ {
WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL; WOLF_STACK_OF(WOLFSSL_X509_INFO)* localSk = NULL;
int ret = WOLFSSL_SUCCESS; int ret = WOLFSSL_SUCCESS;
WOLFSSL_X509_INFO* current = NULL;
WOLFSSL_X509* x509 = NULL;
WOLFSSL_X509_CRL* crl = NULL;
WOLFSSL_X509_PKEY* x_pkey = NULL;
(void)u; (void)u;
WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio"); WOLFSSL_ENTER("wolfSSL_PEM_X509_INFO_read_bio");
/* attempt to use passed in stack or create a new one */
if (sk != NULL) {
localSk = sk;
}
else {
localSk = wolfSSL_sk_X509_INFO_new_null();
}
if (localSk == NULL) {
WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
MEMORY_E);
return NULL;
}
/* parse through BIO and push new info's found onto stack */ /* parse through BIO and push new info's found onto stack */
while (1) { while (1) {
WOLFSSL_X509 *x509 = NULL; x509 = NULL;
WOLFSSL_X509_CRL *crl = NULL; crl = NULL;
WOLFSSL_X509_PKEY *x_pkey = NULL; x_pkey = NULL;
if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb, if (wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio(bio, cb,
&x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) { &x509, &crl, &x_pkey) == WOLFSSL_SUCCESS) {
WOLFSSL_X509_INFO* current; if (current == NULL ||
(x509 && current->x509) ||
current = wolfSSL_X509_INFO_new(); (crl && current->crl) ||
if (current == NULL) { (x_pkey && current->x_pkey)) {
WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", MEMORY_E); /* Need to create new current since existing one already
wolfSSL_sk_pop_free(localSk, NULL); * has the member filled or this is the first successful
return NULL; * read. */
current = wolfSSL_X509_INFO_new();
if (current == NULL) {
ret = MEMORY_E;
break;
}
if (wolfSSL_sk_X509_INFO_push(localSk, current) !=
WOLFSSL_SUCCESS) {
wolfSSL_X509_INFO_free(current);
current = NULL;
ret = WOLFSSL_FAILURE;
break;
}
} }
if (x509) { if (x509) {
ret = wolfSSL_X509_INFO_set(&current, x509); current->x509 = x509;
} }
else if (crl) { else if (crl) {
current->crl = crl; current->crl = crl;
ret = WOLFSSL_SUCCESS;
} }
else if (x_pkey) { else if (x_pkey) {
current->x_pkey = x_pkey; current->x_pkey = x_pkey;
ret = WOLFSSL_SUCCESS;
} }
else { else {
WOLFSSL_MSG("No output parameters set"); WOLFSSL_MSG("No output parameters set");
WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", WOLFSSL_FAILURE); ret = WOLFSSL_FAILURE;
wolfSSL_sk_pop_free(localSk, NULL); break;
wolfSSL_X509_INFO_free(current);
return NULL;
}
if (ret != WOLFSSL_SUCCESS) {
wolfSSL_X509_free(x509);
#ifdef HAVE_CRL
wolfSSL_X509_CRL_free(crl);
#endif
wolfSSL_X509_PKEY_free(x_pkey);
}
else {
if (!localSk) {
/* attempt to used passed in stack
* or create a new one */
if (sk != NULL) {
localSk = sk;
}
else {
localSk = wolfSSL_sk_X509_INFO_new_null();
}
if (localSk == NULL) {
WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio",
MEMORY_E);
return NULL;
}
}
wolfSSL_sk_X509_INFO_push(localSk, current);
} }
} }
else { else {
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
int err = (int)wolfSSL_ERR_peek_last_error();
if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
/*
* wolfSSL_PEM_X509_X509_CRL_X509_PKEY_read_bio pushes an
* ASN_NO_PEM_HEADER error to the error queue on file end.
* This should not be left for the caller to find so we
* clear the last error. This also indicates that nothing
* more was found in the BIO.
*/
wc_RemoveErrorNode(-1);
}
#else
if (wolfSSL_sk_X509_INFO_num(localSk) > 0) {
WOLFSSL_MSG("At least one X509_INFO object on stack."
"Assuming error means EOF or no more PEM"
"headers found.");
}
#endif
else {
ret = WOLFSSL_FAILURE;
}
break; break;
} }
} }
if (ret != WOLFSSL_SUCCESS ||
wolfSSL_sk_X509_INFO_num(localSk) == 0) {
/* current should always be pushed onto the localsk stack at this
* point. The only case when it isn't is when
* wolfSSL_sk_X509_INFO_push fails but in that case the current
* free is handled inside the loop. */
if (localSk != sk) {
wolfSSL_sk_pop_free(localSk, NULL);
}
wolfSSL_X509_free(x509);
#ifdef HAVE_CRL
wolfSSL_X509_CRL_free(crl);
#endif
wolfSSL_X509_PKEY_free(x_pkey);
localSk = NULL;
}
WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret); WOLFSSL_LEAVE("wolfSSL_PEM_X509_INFO_read_bio", ret);
return localSk; return localSk;
} }
@ -45990,8 +46030,7 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line)
(void)line; (void)line;
(void)file; (void)file;
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(DEBUG_WOLFSSL) || \ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
defined(WOLFSSL_HAPROXY)
{ {
int ret; int ret;
@ -47819,24 +47858,19 @@ int wolfSSL_sk_X509_INFO_num(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
{ {
WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num"); WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_num");
if (sk == NULL) return wolfSSL_sk_num(sk);
return -1;
return (int)sk->num;
} }
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i) WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value(
const WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk, int i)
{ {
WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value"); WOLFSSL_ENTER("wolfSSL_sk_X509_INFO_value");
for (; sk != NULL && i > 0; i--) return wolfSSL_sk_value(sk, i);
sk = sk->next;
if (i != 0 || sk == NULL)
return NULL;
return sk->data.info;
} }
WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk) WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop(
WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk)
{ {
WOLFSSL_STACK* node; WOLFSSL_STACK* node;
WOLFSSL_X509_INFO* info; WOLFSSL_X509_INFO* info;
@ -47886,37 +47920,7 @@ void wolfSSL_sk_X509_INFO_free(WOLF_STACK_OF(WOLFSSL_X509_INFO) *sk)
int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk, int wolfSSL_sk_X509_INFO_push(WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk,
WOLFSSL_X509_INFO* in) WOLFSSL_X509_INFO* in)
{ {
WOLFSSL_STACK* node; return wolfSSL_sk_push(sk, in);
if (sk == NULL || in == NULL) {
return WOLFSSL_FAILURE;
}
/* no previous values in stack */
if (sk->data.info == NULL) {
sk->data.info = in;
sk->num += 1;
return WOLFSSL_SUCCESS;
}
/* stack already has value(s) create a new node and add more */
node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL,
DYNAMIC_TYPE_X509);
if (node == NULL) {
WOLFSSL_MSG("Memory error");
return WOLFSSL_FAILURE;
}
XMEMSET(node, 0, sizeof(WOLFSSL_STACK));
/* push new obj onto head of stack */
node->data.info = sk->data.info;
node->next = sk->next;
node->type = sk->type;
sk->next = node;
sk->data.info = in;
sk->num += 1;
return WOLFSSL_SUCCESS;
} }
/* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME). /* Creates a duplicate of WOLF_STACK_OF(WOLFSSL_X509_NAME).
@ -48387,7 +48391,7 @@ unsigned long wolfSSL_ERR_peek_last_error(void)
{ {
WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error"); WOLFSSL_ENTER("wolfSSL_ERR_peek_last_error");
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_NGINX) #ifdef WOLFSSL_HAVE_ERROR_QUEUE
{ {
int ret; int ret;
@ -49465,9 +49469,7 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
*flags = 0; *flags = 0;
} }
#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_MYSQL_COMPATIBLE)
{ {
int ret = 0; int ret = 0;
@ -49484,6 +49486,11 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line,
if (ret == -ASN_NO_PEM_HEADER) if (ret == -ASN_NO_PEM_HEADER)
return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE; return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE;
#ifdef OPENSSL_ALL
/* PARSE_ERROR is returned if an HTTP request is detected. */
if (ret == -SSL_R_HTTP_REQUEST)
return (ERR_LIB_SSL << 24) | -SSL_R_HTTP_REQUEST;
#endif
#if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON) #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON)
if (ret == ASN1_R_HEADER_TOO_LONG) { if (ret == ASN1_R_HEADER_TOO_LONG) {
return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG; return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG;
@ -59524,21 +59531,20 @@ void wolfSSL_BIO_set_init(WOLFSSL_BIO* bio, int init)
(void)bio; (void)bio;
(void)init; (void)init;
} }
#endif /* NO_WOLFSSL_STUB */
void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut) void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO* bio, int shut)
{ {
WOLFSSL_STUB("wolfSSL_BIO_set_shutdown"); WOLFSSL_ENTER("wolfSSL_BIO_set_shutdown");
(void)bio; if (bio != NULL)
(void)shut; bio->shutdown = shut;
} }
int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio) int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO* bio)
{ {
WOLFSSL_STUB("wolfSSL_BIO_get_shutdown"); WOLFSSL_ENTER("wolfSSL_BIO_get_shutdown");
(void)bio; return bio != NULL && bio->shutdown;
return 0;
} }
#endif /* NO_WOLFSSL_STUB */
void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio) void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio)
{ {

View File

@ -8825,7 +8825,11 @@ static void test_set_x509_badversion(WOLFSSL_CTX* ctx)
/* override certificate version error */ /* override certificate version error */
static int test_override_x509(int preverify, WOLFSSL_X509_STORE_CTX* store) static int test_override_x509(int preverify, WOLFSSL_X509_STORE_CTX* store)
{ {
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
AssertIntEQ(store->error, ASN_VERSION_E); AssertIntEQ(store->error, ASN_VERSION_E);
#else
AssertIntEQ(store->error, 0);
#endif
AssertIntEQ((int)wolfSSL_X509_get_version(store->current_cert), 1); AssertIntEQ((int)wolfSSL_X509_get_version(store->current_cert), 1);
(void)preverify; (void)preverify;
return 1; return 1;
@ -8897,8 +8901,13 @@ static void test_wolfSSL_X509_TLS_version(void)
test_client_nofail(&client_args, NULL); test_client_nofail(&client_args, NULL);
join_thread(serverThread); join_thread(serverThread);
#ifndef OPENSSL_COMPATIBLE_DEFAULTS
AssertIntEQ(client_args.return_code, TEST_FAIL); AssertIntEQ(client_args.return_code, TEST_FAIL);
AssertIntEQ(server_args.return_code, TEST_FAIL); AssertIntEQ(server_args.return_code, TEST_FAIL);
#else
AssertIntEQ(client_args.return_code, TEST_SUCCESS);
AssertIntEQ(server_args.return_code, TEST_SUCCESS);
#endif
FreeTcpReady(&ready); FreeTcpReady(&ready);
@ -29760,6 +29769,68 @@ static void test_wolfSSL_X509_NAME_hash(void)
#endif #endif
} }
#ifndef NO_BIO
static void test_wolfSSL_X509_INFO_multiple_info(void)
{
#if defined(OPENSSL_ALL) && !defined(NO_RSA)
STACK_OF(X509_INFO) *info_stack;
X509_INFO *info;
int len;
int i;
const char* files[] = {
cliCertFile,
cliKeyFile,
/* This needs to be the order as svrCertFile contains the
* intermediate cert as well. */
svrKeyFile,
svrCertFile,
NULL,
};
const char** curFile;
BIO *fileBIO;
BIO *concatBIO = NULL;
byte tmp[FOURK_BUF];
/* concatenate the cert and the key file to force PEM_X509_INFO_read_bio
* to group objects together. */
AssertNotNull(concatBIO = BIO_new(BIO_s_mem()));
for (curFile = files; *curFile != NULL; curFile++) {
int fileLen;
AssertNotNull(fileBIO = BIO_new_file(*curFile, "rb"));
fileLen = wolfSSL_BIO_get_len(fileBIO);
while ((len = BIO_read(fileBIO, tmp, sizeof(tmp))) > 0) {
AssertIntEQ(BIO_write(concatBIO, tmp, len), len);
fileLen -= len;
}
/* Make sure we read the entire file */
AssertIntEQ(fileLen, 0);
BIO_free(fileBIO);
}
AssertNotNull(info_stack = PEM_X509_INFO_read_bio(concatBIO, NULL, NULL,
NULL));
AssertIntEQ(sk_X509_INFO_num(info_stack), 3);
for (i = 0; i < sk_X509_INFO_num(info_stack); i++) {
AssertNotNull(info = sk_X509_INFO_value(info_stack, i));
AssertNotNull(info->x509);
AssertNull(info->crl);
if (i != 0) {
AssertNotNull(info->x_pkey);
AssertIntEQ(X509_check_private_key(info->x509,
info->x_pkey->dec_pkey), 1);
}
else {
AssertNull(info->x_pkey);
}
}
sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
BIO_free(concatBIO);
#endif
}
#endif
#ifndef NO_BIO #ifndef NO_BIO
static void test_wolfSSL_X509_INFO(void) static void test_wolfSSL_X509_INFO(void)
{ {
@ -29795,6 +29866,7 @@ static void test_wolfSSL_X509_INFO(void)
AssertNotNull(info = sk_X509_INFO_value(info_stack, i)); AssertNotNull(info = sk_X509_INFO_value(info_stack, i));
AssertNotNull(info->x509); AssertNotNull(info->x509);
AssertNull(info->crl); AssertNull(info->crl);
AssertNull(info->x_pkey);
} }
sk_X509_INFO_pop_free(info_stack, X509_INFO_free); sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
BIO_free(cert); BIO_free(cert);
@ -43307,6 +43379,34 @@ static void test_wolfSSL_EVP_PKEY_id(void)
printf(resultFmt, passed); printf(resultFmt, passed);
#endif #endif
} }
static void test_wolfSSL_EVP_PKEY_paramgen(void)
{
#if defined(OPENSSL_ALL) && \
!defined(NO_ECC_SECP) && \
/* This last bit is taken from ecc.c. It is the condition that
* defines ECC256 */ \
((!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \
ECC_MIN_KEY_SZ <= 256)
EVP_PKEY_CTX* ctx;
EVP_PKEY* pkey = NULL;
printf(testingFmt, "wolfSSL_EVP_PKEY_paramgen");
AssertNotNull(ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL));
AssertIntEQ(EVP_PKEY_paramgen_init(ctx), 1);
AssertIntEQ(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, NID_X9_62_prime256v1), 1);
AssertIntEQ(EVP_PKEY_CTX_set_ec_param_enc(ctx, OPENSSL_EC_NAMED_CURVE), 1);
AssertIntEQ(EVP_PKEY_keygen_init(ctx), 1);
AssertIntEQ(EVP_PKEY_keygen(ctx, &pkey), 1);
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_EVP_PKEY_keygen(void) static void test_wolfSSL_EVP_PKEY_keygen(void)
{ {
#if defined(OPENSSL_ALL) #if defined(OPENSSL_ALL)
@ -48860,9 +48960,6 @@ static void test_wolfSSL_PEM_X509_INFO_read_bio(void)
/* using dereference to maintain testing for Apache port*/ /* using dereference to maintain testing for Apache port*/
AssertNotNull(info = sk_X509_INFO_pop(sk)); AssertNotNull(info = sk_X509_INFO_pop(sk));
AssertNotNull(info->x_pkey);
AssertNotNull(info->x_pkey->dec_pkey);
AssertIntEQ(EVP_PKEY_bits(info->x_pkey->dec_pkey), 2048);
AssertNotNull(subject = AssertNotNull(subject =
X509_NAME_oneline(X509_get_subject_name(info->x509), 0, 0)); X509_NAME_oneline(X509_get_subject_name(info->x509), 0, 0));
@ -52114,6 +52211,7 @@ void ApiTest(void)
test_wolfSSL_X509_NAME(); test_wolfSSL_X509_NAME();
test_wolfSSL_X509_NAME_hash(); test_wolfSSL_X509_NAME_hash();
#ifndef NO_BIO #ifndef NO_BIO
test_wolfSSL_X509_INFO_multiple_info();
test_wolfSSL_X509_INFO(); test_wolfSSL_X509_INFO();
#endif #endif
test_wolfSSL_X509_subject_name_hash(); test_wolfSSL_X509_subject_name_hash();
@ -52367,6 +52465,7 @@ void ApiTest(void)
test_wolfSSL_EVP_PKEY_assign(); test_wolfSSL_EVP_PKEY_assign();
test_wolfSSL_EVP_PKEY_base_id(); test_wolfSSL_EVP_PKEY_base_id();
test_wolfSSL_EVP_PKEY_id(); test_wolfSSL_EVP_PKEY_id();
test_wolfSSL_EVP_PKEY_paramgen();
test_wolfSSL_EVP_PKEY_keygen(); test_wolfSSL_EVP_PKEY_keygen();
test_wolfSSL_EVP_PKEY_keygen_init(); test_wolfSSL_EVP_PKEY_keygen_init();
test_wolfSSL_EVP_PKEY_missing_parameters(); test_wolfSSL_EVP_PKEY_missing_parameters();

View File

@ -29581,43 +29581,68 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
WOLFSSL_ENTER("OcspResponseDecode"); WOLFSSL_ENTER("OcspResponseDecode");
/* peel the outer SEQUENCE wrapper */ /* peel the outer SEQUENCE wrapper */
if (GetSequence(source, &idx, &length, size) < 0) if (GetSequence(source, &idx, &length, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
}
/* First get the responseStatus, an ENUMERATED */ /* First get the responseStatus, an ENUMERATED */
if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) if (GetEnumerated(source, &idx, &resp->responseStatus, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
}
if (resp->responseStatus != OCSP_SUCCESSFUL) if (resp->responseStatus != OCSP_SUCCESSFUL) {
WOLFSSL_LEAVE("OcspResponseDecode", 0);
return 0; return 0;
}
/* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */ /* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
if (idx >= size) if (idx >= size) {
return ASN_INPUT_E; WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
if (GetASNTag(source, &idx, &tag, size) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) }
if (GetASNTag(source, &idx, &tag, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
if (GetLength(source, &idx, &length, size) < 0) }
if (tag != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC)) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
}
if (GetLength(source, &idx, &length, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E;
}
/* Get the responseBytes SEQUENCE */ /* Get the responseBytes SEQUENCE */
if (GetSequence(source, &idx, &length, size) < 0) if (GetSequence(source, &idx, &length, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
}
/* Check ObjectID for the resposeBytes */ /* Check ObjectID for the resposeBytes */
if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) if (GetObjectId(source, &idx, &oid, oidOcspType, size) < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
if (oid != OCSP_BASIC_OID) }
if (oid != OCSP_BASIC_OID) {
WOLFSSL_LEAVE("OcspResponseDecode", ASN_PARSE_E);
return ASN_PARSE_E; return ASN_PARSE_E;
}
ret = GetOctetString(source, &idx, &length, size); ret = GetOctetString(source, &idx, &length, size);
if (ret < 0) if (ret < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ret);
return ret; return ret;
}
ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify); ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify);
if (ret < 0) if (ret < 0) {
WOLFSSL_LEAVE("OcspResponseDecode", ret);
return ret; return ret;
}
WOLFSSL_LEAVE("OcspResponseDecode", 0);
return 0; return 0;
#else #else
DECL_ASNGETDATA(dataASN, ocspResponseASN_Length); DECL_ASNGETDATA(dataASN, ocspResponseASN_Length);
@ -29658,6 +29683,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify)
} }
FREE_ASNGETDATA(dataASN, resp->heap); FREE_ASNGETDATA(dataASN, resp->heap);
WOLFSSL_LEAVE("OcspResponseDecode", ret);
return ret; return ret;
#endif /* WOLFSSL_ASN_TEMPLATE */ #endif /* WOLFSSL_ASN_TEMPLATE */
} }

View File

@ -1420,6 +1420,9 @@ WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_E
ctx->pkey = pkey; ctx->pkey = pkey;
#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) #if !defined(NO_RSA) && !defined(HAVE_USER_RSA)
ctx->padding = RSA_PKCS1_PADDING; ctx->padding = RSA_PKCS1_PADDING;
#endif
#ifdef HAVE_ECC
ctx->curveNID = ECC_CURVE_DEF;
#endif #endif
if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) { if (wolfSSL_EVP_PKEY_up_ref(pkey) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Couldn't increase key reference count"); WOLFSSL_MSG("Couldn't increase key reference count");
@ -1920,6 +1923,49 @@ int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey)
} }
int wolfSSL_EVP_PKEY_paramgen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
{
(void)ctx;
return WOLFSSL_SUCCESS;
}
int wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(WOLFSSL_EVP_PKEY_CTX *ctx,
int nid)
{
WOLFSSL_ENTER("wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid");
#ifdef HAVE_ECC
if (ctx != NULL && ctx->pkey != NULL && ctx->pkey->type == EVP_PKEY_EC) {
ctx->curveNID = nid;
return WOLFSSL_SUCCESS;
}
else
#endif
{
#ifndef HAVE_ECC
(void)ctx;
(void)nid;
WOLFSSL_MSG("Support not compiled in");
#else
WOLFSSL_MSG("Bad parameter");
#endif
return WOLFSSL_FAILURE;
}
}
/* wolfSSL only supports writing out named curves so no need to store the flag.
* In short, it is preferred to write out the name of the curve chosen instead
* of the explicit parameters.
* The difference is nicely explained and illustrated in section
* "ECDH and Named Curves" of
* https://wiki.openssl.org/index.php/Elliptic_Curve_Diffie_Hellman */
int EVP_PKEY_CTX_set_ec_param_enc(WOLFSSL_EVP_PKEY_CTX *ctx,
int flag)
{
(void)ctx;
(void)flag;
return WOLFSSL_SUCCESS;
}
int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx) int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
{ {
(void)ctx; (void)ctx;
@ -1933,14 +1979,23 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
int ownPkey = 0; int ownPkey = 0;
WOLFSSL_EVP_PKEY* pkey; WOLFSSL_EVP_PKEY* pkey;
WOLFSSL_ENTER("wolfSSL_EVP_PKEY_keygen");
if (ctx == NULL || ppkey == NULL) { if (ctx == NULL || ppkey == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
pkey = *ppkey; pkey = *ppkey;
if (pkey == NULL) { if (pkey == NULL) {
if (ctx->pkey == NULL ||
(ctx->pkey->type != EVP_PKEY_EC &&
ctx->pkey->type != EVP_PKEY_RSA)) {
WOLFSSL_MSG("Key not set or key type not supported");
return BAD_FUNC_ARG;
}
ownPkey = 1; ownPkey = 1;
pkey = wolfSSL_EVP_PKEY_new(); pkey = wolfSSL_EVP_PKEY_new();
pkey->type = ctx->pkey->type;
if (pkey == NULL) if (pkey == NULL)
return ret; return ret;
@ -1962,7 +2017,7 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
#endif #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC
case EVP_PKEY_EC: case EVP_PKEY_EC:
pkey->ecc = wolfSSL_EC_KEY_new(); pkey->ecc = wolfSSL_EC_KEY_new_by_curve_name(ctx->curveNID);
if (pkey->ecc) { if (pkey->ecc) {
ret = wolfSSL_EC_KEY_generate_key(pkey->ecc); ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);
if (ret == WOLFSSL_SUCCESS) { if (ret == WOLFSSL_SUCCESS) {

View File

@ -456,8 +456,7 @@ WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void)
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_EXTRA) defined(OPENSSL_EXTRA)
#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(NO_ERROR_QUEUE)) \ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
|| defined(DEBUG_WOLFSSL_VERBOSE)
void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line, void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
const char* file, void* usrCtx) const char* file, void* usrCtx)
#else #else
@ -470,8 +469,7 @@ void WOLFSSL_ERROR(int error)
{ {
char buffer[WOLFSSL_MAX_ERROR_SZ]; char buffer[WOLFSSL_MAX_ERROR_SZ];
#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
!defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE)
(void)usrCtx; /* a user ctx for future flexibility */ (void)usrCtx; /* a user ctx for future flexibility */
(void)func; (void)func;
@ -577,6 +575,7 @@ int wc_LoggingCleanup(void)
int wc_PeekErrorNode(int idx, const char **file, const char **reason, int wc_PeekErrorNode(int idx, const char **file, const char **reason,
int *line) int *line)
{ {
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
struct wc_error_queue* err; struct wc_error_queue* err;
if (wc_LockMutex(&debug_mutex) != 0) { if (wc_LockMutex(&debug_mutex) != 0) {
@ -622,6 +621,14 @@ int wc_PeekErrorNode(int idx, const char **file, const char **reason,
wc_UnLockMutex(&debug_mutex); wc_UnLockMutex(&debug_mutex);
return err->value; return err->value;
#else
(void)idx;
(void)file;
(void)reason;
(void)line;
WOLFSSL_MSG("Error queue turned off, can not peak nodes");
return NOT_COMPILED_IN;
#endif
} }
@ -637,6 +644,7 @@ int wc_PeekErrorNode(int idx, const char **file, const char **reason,
*/ */
int wc_PullErrorNode(const char **file, const char **reason, int *line) int wc_PullErrorNode(const char **file, const char **reason, int *line)
{ {
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
struct wc_error_queue* err; struct wc_error_queue* err;
int value; int value;
@ -669,6 +677,13 @@ int wc_PullErrorNode(const char **file, const char **reason, int *line)
wc_UnLockMutex(&debug_mutex); wc_UnLockMutex(&debug_mutex);
return value; return value;
#else
(void)file;
(void)reason;
(void)line;
WOLFSSL_MSG("Error queue turned off, can not pull nodes");
return NOT_COMPILED_IN;
#endif
} }
@ -677,13 +692,7 @@ int wc_PullErrorNode(const char **file, const char **reason, int *line)
* function. debug_mutex should be locked before a call to this function. */ * function. debug_mutex should be locked before a call to this function. */
int wc_AddErrorNode(int error, int line, char* buf, char* file) int wc_AddErrorNode(int error, int line, char* buf, char* file)
{ {
#if defined(NO_ERROR_QUEUE) #ifdef WOLFSSL_HAVE_ERROR_QUEUE
(void)error;
(void)line;
(void)buf;
(void)file;
WOLFSSL_MSG("Error queue turned off, can not add nodes");
#else
struct wc_error_queue* err; struct wc_error_queue* err;
if (wc_error_queue_count >= ERROR_QUEUE_MAX) { if (wc_error_queue_count >= ERROR_QUEUE_MAX) {
@ -757,8 +766,15 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file)
} }
wc_error_queue_count++; wc_error_queue_count++;
} }
#endif
return 0; return 0;
#else
(void)error;
(void)line;
(void)buf;
(void)file;
WOLFSSL_MSG("Error queue turned off, can not add nodes");
return NOT_COMPILED_IN;
#endif
} }
/* Removes the error node at the specified index. /* Removes the error node at the specified index.
@ -767,6 +783,7 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file)
*/ */
void wc_RemoveErrorNode(int idx) void wc_RemoveErrorNode(int idx)
{ {
#ifdef WOLFSSL_HAVE_ERROR_QUEUE
struct wc_error_queue* current; struct wc_error_queue* current;
if (wc_LockMutex(&debug_mutex) != 0) { if (wc_LockMutex(&debug_mutex) != 0) {
@ -797,6 +814,10 @@ void wc_RemoveErrorNode(int idx)
} }
wc_UnLockMutex(&debug_mutex); wc_UnLockMutex(&debug_mutex);
#else
(void)idx;
WOLFSSL_MSG("Error queue turned off, can not remove nodes");
#endif
} }
@ -804,9 +825,7 @@ void wc_RemoveErrorNode(int idx)
*/ */
void wc_ClearErrorNodes(void) void wc_ClearErrorNodes(void)
{ {
#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
if (wc_LockMutex(&debug_mutex) != 0) { if (wc_LockMutex(&debug_mutex) != 0) {
WOLFSSL_MSG("Lock debug mutex failed"); WOLFSSL_MSG("Lock debug mutex failed");
return; return;
@ -830,7 +849,9 @@ void wc_ClearErrorNodes(void)
wc_last_node = NULL; wc_last_node = NULL;
wc_current_node = NULL; wc_current_node = NULL;
wc_UnLockMutex(&debug_mutex); wc_UnLockMutex(&debug_mutex);
#endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */ #else
WOLFSSL_MSG("Error queue turned off, can not clear nodes");
#endif
} }
int wc_SetLoggingHeap(void* h) int wc_SetLoggingHeap(void* h)

View File

@ -76,7 +76,8 @@ enum {
NID_ED25519 = ED25519k, NID_ED25519 = ED25519k,
#endif #endif
OPENSSL_EC_NAMED_CURVE = 0x001 OPENSSL_EC_EXPLICIT_CURVE = 0x000,
OPENSSL_EC_NAMED_CURVE = 0x001,
}; };
#ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */ #ifndef WOLFSSL_EC_TYPE_DEFINED /* guard on redeclaration */

View File

@ -412,6 +412,9 @@ struct WOLFSSL_EVP_PKEY_CTX {
int op; /* operation */ int op; /* operation */
int padding; int padding;
int nbits; int nbits;
#ifdef HAVE_ECC
int curveNID;
#endif
}; };
struct WOLFSSL_ASN1_PCTX { struct WOLFSSL_ASN1_PCTX {
@ -625,6 +628,11 @@ WOLFSSL_API const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PK
WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx);
WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx,
unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen);
WOLFSSL_API int wolfSSL_EVP_PKEY_paramgen_init(WOLFSSL_EVP_PKEY_CTX *ctx);
WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid(WOLFSSL_EVP_PKEY_CTX *ctx,
int nid);
WOLFSSL_API int EVP_PKEY_CTX_set_ec_param_enc(WOLFSSL_EVP_PKEY_CTX *ctx,
int flag);
WOLFSSL_API int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx);
WOLFSSL_API int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, WOLFSSL_API int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
WOLFSSL_EVP_PKEY **ppkey); WOLFSSL_EVP_PKEY **ppkey);
@ -925,6 +933,8 @@ WOLFSSL_API void wolfSSL_EVP_MD_do_all(void (*fn) (const WOLFSSL_EVP_MD *md,
#define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex #define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex
#define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init #define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init
#define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign #define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign
#define EVP_PKEY_paramgen_init wolfSSL_EVP_PKEY_paramgen_init
#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid wolfSSL_EVP_PKEY_CTX_set_ec_paramgen_curve_nid
#define EVP_PKEY_keygen wolfSSL_EVP_PKEY_keygen #define EVP_PKEY_keygen wolfSSL_EVP_PKEY_keygen
#define EVP_PKEY_keygen_init wolfSSL_EVP_PKEY_keygen_init #define EVP_PKEY_keygen_init wolfSSL_EVP_PKEY_keygen_init
#define EVP_PKEY_bits wolfSSL_EVP_PKEY_bits #define EVP_PKEY_bits wolfSSL_EVP_PKEY_bits

View File

@ -298,7 +298,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define SSL_CTX_free wolfSSL_CTX_free #define SSL_CTX_free wolfSSL_CTX_free
#define SSL_free wolfSSL_free #define SSL_free wolfSSL_free
#define SSL_shutdown wolfSSL_shutdown #define SSL_shutdown wolfSSL_shutdown
#define SSL_set_timeout wolfSSL_set_timeout #define SSL_set_timeout wolfSSL_SSL_SESSION_set_timeout
#define SSL_CTX_set_quiet_shutdown wolfSSL_CTX_set_quiet_shutdown #define SSL_CTX_set_quiet_shutdown wolfSSL_CTX_set_quiet_shutdown
#define SSL_set_quiet_shutdown wolfSSL_set_quiet_shutdown #define SSL_set_quiet_shutdown wolfSSL_set_quiet_shutdown
@ -1441,8 +1441,9 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define ERR_LIB_USER 15 #define ERR_LIB_USER 15
#if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_EXTRA) || \
defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) defined(HAVE_LIGHTY) || defined(HAVE_STUNNEL) || \
defined(WOLFSSL_WPAS_SMALL)
#include <wolfssl/error-ssl.h> #include <wolfssl/error-ssl.h>

View File

@ -105,6 +105,12 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void);
WOLFSSL_API const char *wolfSSL_global_cflags(void); WOLFSSL_API const char *wolfSSL_global_cflags(void);
#endif #endif
#if (defined(OPENSSL_EXTRA) && !defined(_WIN32) && \
!defined(NO_ERROR_QUEUE)) || defined(DEBUG_WOLFSSL_VERBOSE)
#define WOLFSSL_HAVE_ERROR_QUEUE
#endif
#if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
WOLFSSL_LOCAL int wc_LoggingInit(void); WOLFSSL_LOCAL int wc_LoggingInit(void);
WOLFSSL_LOCAL int wc_LoggingCleanup(void); WOLFSSL_LOCAL int wc_LoggingCleanup(void);
@ -175,8 +181,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void);
#if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\ #if defined(DEBUG_WOLFSSL) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) ||\
defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA)
#if (!defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && !defined(_WIN32))\ #ifdef WOLFSSL_HAVE_ERROR_QUEUE
|| defined(DEBUG_WOLFSSL_VERBOSE)
WOLFSSL_API void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line, WOLFSSL_API void WOLFSSL_ERROR_LINE(int err, const char* func, unsigned int line,
const char* file, void* ctx); const char* file, void* ctx);
#define WOLFSSL_ERROR(x) \ #define WOLFSSL_ERROR(x) \