forked from wolfSSL/wolfssl
Fix to handle non-blocking OCSP when WOLFSSL_NONBLOCK_OCSP
is defined and not using async. OCSP callback should return OCSP_WANT_READ
. Added ability to simulate non-blocking OCSP using TEST_NONBLOCK_CERTS
.
This commit is contained in:
@ -1582,8 +1582,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
|
||||
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE
|
||||
| WOLFSSL_OCSP_URL_OVERRIDE);
|
||||
}
|
||||
else
|
||||
else {
|
||||
wolfSSL_CTX_EnableOCSP(ctx, 0);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
wolfSSL_CTX_SetOCSP_Cb(ctx, OCSPIOCb, OCSPRespFreeCb, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -7752,6 +7752,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ProcPeerCertArgs* args = (ProcPeerCertArgs*)ssl->async.args;
|
||||
typedef char args_test[sizeof(ssl->async.args) >= sizeof(*args) ? 1 : -1];
|
||||
(void)sizeof(args_test);
|
||||
#elif defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
ProcPeerCertArgs* args = ssl->nonblockarg;
|
||||
#else
|
||||
ProcPeerCertArgs args[1];
|
||||
#endif
|
||||
@ -7771,6 +7773,15 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
goto exit_ppc;
|
||||
}
|
||||
else
|
||||
#elif defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
if (args == NULL) {
|
||||
args = (ProcPeerCertArgs*)XMALLOC(
|
||||
sizeof(ProcPeerCertArgs), ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (args == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_ppc);
|
||||
}
|
||||
}
|
||||
if (ssl->nonblockarg == NULL) /* new args */
|
||||
#endif
|
||||
{
|
||||
/* Reset state */
|
||||
@ -7781,6 +7792,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
args->begin = *inOutIdx;
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
ssl->async.freeArgs = FreeProcPeerCertArgs;
|
||||
#elif defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
ssl->nonblockarg = args;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -8229,9 +8242,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
WOLFSSL_MSG("Doing Non Leaf OCSP check");
|
||||
ret = CheckCertOCSP_ex(ssl->ctx->cm->ocsp,
|
||||
args->dCert, NULL, ssl);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* non-blocking socket re-entry requires async */
|
||||
if (ret == WANT_READ) {
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
if (ret == OCSP_WANT_READ) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
@ -8249,9 +8261,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ssl->ctx->cm->crlCheckAll) {
|
||||
WOLFSSL_MSG("Doing Non Leaf CRL check");
|
||||
ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* non-blocking socket re-entry requires async */
|
||||
if (ret == WANT_READ) {
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
if (ret == OCSP_WANT_READ) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
@ -8379,7 +8390,21 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SECURE_RENEGOTIATION */
|
||||
} /* if (count > 0) */
|
||||
|
||||
/* Check for error */
|
||||
if (args->fatal && ret != 0) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_VERIFY;
|
||||
} /* case TLS_ASYNC_DO */
|
||||
FALL_THROUGH;
|
||||
|
||||
case TLS_ASYNC_VERIFY:
|
||||
{
|
||||
if (args->count > 0) {
|
||||
#if defined(HAVE_OCSP) || defined(HAVE_CRL)
|
||||
if (args->fatal == 0) {
|
||||
int doLookup = 1;
|
||||
@ -8406,9 +8431,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
WOLFSSL_MSG("Doing Leaf OCSP check");
|
||||
ret = CheckCertOCSP_ex(ssl->ctx->cm->ocsp,
|
||||
args->dCert, NULL, ssl);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* non-blocking socket re-entry requires async */
|
||||
if (ret == WANT_READ) {
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
if (ret == OCSP_WANT_READ) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
@ -8427,9 +8451,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
if (doLookup && ssl->ctx->cm->crlEnabled) {
|
||||
WOLFSSL_MSG("Doing Leaf CRL check");
|
||||
ret = CheckCertCRL(ssl->ctx->cm->crl, args->dCert);
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
/* non-blocking socket re-entry requires async */
|
||||
if (ret == WANT_READ) {
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
if (ret == OCSP_WANT_READ) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
#endif
|
||||
@ -8499,21 +8522,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
}
|
||||
|
||||
ssl->options.havePeerCert = 1;
|
||||
} /* if (count > 0) */
|
||||
|
||||
/* Check for error */
|
||||
if (args->fatal && ret != 0) {
|
||||
goto exit_ppc;
|
||||
}
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->options.asyncState = TLS_ASYNC_VERIFY;
|
||||
} /* case TLS_ASYNC_DO */
|
||||
FALL_THROUGH;
|
||||
|
||||
case TLS_ASYNC_VERIFY:
|
||||
{
|
||||
if (args->count > 0) {
|
||||
args->domain = (char*)XMALLOC(ASN_NAME_MAX, ssl->heap,
|
||||
DYNAMIC_TYPE_STRING);
|
||||
if (args->domain == NULL) {
|
||||
@ -8898,16 +8907,23 @@ exit_ppc:
|
||||
|
||||
WOLFSSL_LEAVE("ProcessPeerCerts", ret);
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
if (ret == WC_PENDING_E || ret == WANT_READ) {
|
||||
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
if (ret == WC_PENDING_E || ret == OCSP_WANT_READ) {
|
||||
/* Mark message as not recevied so it can process again */
|
||||
ssl->msgsReceived.got_certificate = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT */
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT || WOLFSSL_NONBLOCK_OCSP */
|
||||
|
||||
FreeProcPeerCertArgs(ssl, args);
|
||||
|
||||
#if !defined(WOLFSSL_ASYNC_CRYPT) && defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
XFREE(args, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ssl->nonblockarg = NULL;
|
||||
#endif
|
||||
|
||||
FreeKeyExchange(ssl);
|
||||
|
||||
return ret;
|
||||
@ -9703,9 +9719,9 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
ret = DECODE_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
#if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
/* if async, offset index so this msg will be processed again */
|
||||
if (ret == WC_PENDING_E && *inOutIdx > 0) {
|
||||
if ((ret == WC_PENDING_E || ret == OCSP_WANT_READ) && *inOutIdx > 0) {
|
||||
*inOutIdx -= HANDSHAKE_HEADER_SZ;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
if (ssl->options.dtls) {
|
||||
@ -9713,7 +9729,12 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef WOLFSSL_NONBLOCK_OCSP
|
||||
if (ret == OCSP_WANT_READ) {
|
||||
ret = WANT_READ; /* treat as normal WANT_READ for non-block handling */
|
||||
}
|
||||
#endif
|
||||
#endif /* WOLFSSL_ASYNC_CRYPT || WOLFSSL_NONBLOCK_OCSP */
|
||||
|
||||
WOLFSSL_LEAVE("DoHandShakeMsgType()", ret);
|
||||
return ret;
|
||||
@ -14451,6 +14472,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
|
||||
case OCSP_INVALID_STATUS:
|
||||
return "Invalid OCSP Status Error";
|
||||
|
||||
case OCSP_WANT_READ:
|
||||
return "OCSP nonblock wants read";
|
||||
|
||||
case RSA_KEY_SIZE_E:
|
||||
return "RSA key too small";
|
||||
|
||||
|
@ -459,7 +459,7 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
|
||||
request, requestSz, &response);
|
||||
}
|
||||
if (responseSz == WOLFSSL_CBIO_ERR_WANT_READ) {
|
||||
ret = WANT_READ;
|
||||
ret = OCSP_WANT_READ;
|
||||
}
|
||||
|
||||
XFREE(request, ocsp->cm->heap, DYNAMIC_TYPE_OCSP);
|
||||
|
@ -142,7 +142,7 @@ enum wolfSSL_ErrorCodes {
|
||||
UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/
|
||||
BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */
|
||||
OCSP_INVALID_STATUS = -407, /* Invalid OCSP Status */
|
||||
|
||||
OCSP_WANT_READ = -408, /* OCSP callback response WOLFSSL_CBIO_ERR_WANT_READ */
|
||||
RSA_KEY_SIZE_E = -409, /* RSA key too small */
|
||||
ECC_KEY_SIZE_E = -410, /* ECC key too small */
|
||||
|
||||
|
@ -3282,6 +3282,8 @@ struct WOLFSSL {
|
||||
#endif
|
||||
#ifdef WOLFSSL_ASYNC_CRYPT
|
||||
struct WOLFSSL_ASYNC async;
|
||||
#elif defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
void* nonblockarg; /* dynamic arg for handling non-block resume */
|
||||
#endif
|
||||
void* hsKey; /* Handshake key (RsaKey or ecc_key) allocated from heap */
|
||||
word32 hsType; /* Type of Handshake key (hsKey) */
|
||||
|
@ -1128,6 +1128,42 @@ static INLINE unsigned int my_psk_server_cb(WOLFSSL* ssl, const char* identity,
|
||||
#endif /* USE_WINDOWS_API */
|
||||
|
||||
|
||||
#if defined(HAVE_OCSP) && defined(WOLFSSL_NONBLOCK_OCSP)
|
||||
static INLINE int OCSPIOCb(void* ioCtx, const char* url, int urlSz,
|
||||
unsigned char* request, int requestSz, unsigned char** response)
|
||||
{
|
||||
#ifdef TEST_NONBLOCK_CERTS
|
||||
static int ioCbCnt = 0;
|
||||
#endif
|
||||
|
||||
(void)ioCtx;
|
||||
(void)url;
|
||||
(void)urlSz;
|
||||
(void)request;
|
||||
(void)requestSz;
|
||||
(void)response;
|
||||
|
||||
#ifdef TEST_NONBLOCK_CERTS
|
||||
if (ioCbCnt) {
|
||||
ioCbCnt = 0;
|
||||
return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
|
||||
}
|
||||
else {
|
||||
ioCbCnt = 1;
|
||||
return WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
}
|
||||
#else
|
||||
return EmbedOcspLookup(ioCtx, url, urlSz, request, requestSz, response);
|
||||
#endif
|
||||
}
|
||||
|
||||
static INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response)
|
||||
{
|
||||
(void)ioCtx;
|
||||
(void)response;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(NO_CERTS)
|
||||
#if !defined(NO_FILESYSTEM) || \
|
||||
(defined(NO_FILESYSTEM) && defined(FORCE_BUFFER_TEST))
|
||||
|
Reference in New Issue
Block a user