forked from wolfSSL/wolfssl
adds server side Certificate Status Request extension;
missing: Finish SendCertificateStatus();
This commit is contained in:
@@ -725,6 +725,9 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
|
|||||||
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
|
wolfSSL_CTX_EnableOCSPStapling(ctx);
|
||||||
|
#endif
|
||||||
#ifdef HAVE_PK_CALLBACKS
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
if (pkCallbacks)
|
if (pkCallbacks)
|
||||||
SetupPkCallbacks(ctx, ssl);
|
SetupPkCallbacks(ctx, ssl);
|
||||||
|
@@ -4368,7 +4368,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
|
if (ssl->ctx->cm->ocspEnabled && ssl->ctx->cm->ocspCheckAll) {
|
||||||
WOLFSSL_MSG("Doing Non Leaf OCSP check");
|
WOLFSSL_MSG("Doing Non Leaf OCSP check");
|
||||||
ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
|
ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL);
|
||||||
doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
|
doCrlLookup = (ret == OCSP_CERT_UNKNOWN);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
doCrlLookup = 0;
|
doCrlLookup = 0;
|
||||||
@@ -4469,7 +4469,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
|||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (doLookup && ssl->ctx->cm->ocspEnabled) {
|
if (doLookup && ssl->ctx->cm->ocspEnabled) {
|
||||||
WOLFSSL_MSG("Doing Leaf OCSP check");
|
WOLFSSL_MSG("Doing Leaf OCSP check");
|
||||||
ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert);
|
ret = CheckCertOCSP(ssl->ctx->cm->ocsp, dCert, NULL);
|
||||||
doLookup = (ret == OCSP_CERT_UNKNOWN);
|
doLookup = (ret == OCSP_CERT_UNKNOWN);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
WOLFSSL_MSG("\tOCSP Lookup not ok");
|
WOLFSSL_MSG("\tOCSP Lookup not ok");
|
||||||
@@ -8141,6 +8141,86 @@ int SendCertificateRequest(WOLFSSL* ssl)
|
|||||||
else
|
else
|
||||||
return SendBuffered(ssl);
|
return SendBuffered(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int SendCertificateStatus(WOLFSSL* ssl)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
byte status_type = 0;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("SendCertificateStatus");
|
||||||
|
|
||||||
|
(void) ssl;
|
||||||
|
|
||||||
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
status_type = ssl->status_request;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (status_type) {
|
||||||
|
#if defined HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
case WOLFSSL_CSR_OCSP: {
|
||||||
|
buffer response = {NULL, 0};
|
||||||
|
buffer der = ssl->buffers.certificate;
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
DecodedCert* cert = NULL;
|
||||||
|
#else
|
||||||
|
DecodedCert cert[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* unable to fetch status. skip. */
|
||||||
|
if (ssl->ctx->cm == NULL || ssl->ctx->cm->ocspStaplingEnabled == 0)
|
||||||
|
return 0;
|
||||||
|
if (der.buffer == NULL || der.length == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (cert == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InitDecodedCert(cert, der.buffer, der.length, NULL);
|
||||||
|
|
||||||
|
if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY,
|
||||||
|
ssl->ctx->cm)) != 0) {
|
||||||
|
WOLFSSL_MSG("ParseCert failed");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = CheckCertOCSP(ssl->ctx->cm->ocsp_stapling, cert,
|
||||||
|
&response);
|
||||||
|
|
||||||
|
if (response.buffer) {
|
||||||
|
if (ret == OCSP_CERT_REVOKED || ret == OCSP_CERT_UNKNOWN) {
|
||||||
|
ret = 0; /* Forward status to client */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
XFREE(response.buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == OCSP_LOOKUP_FAIL)
|
||||||
|
ret = 0; /* Suppressing, not critical */
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeDecodedCert(cert);
|
||||||
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !NO_CERTS */
|
#endif /* !NO_CERTS */
|
||||||
|
|
||||||
|
|
||||||
|
85
src/ocsp.c
85
src/ocsp.c
@@ -77,6 +77,10 @@ static void FreeOcspEntry(OcspEntry* entry)
|
|||||||
|
|
||||||
for (status = entry->status; status; status = next) {
|
for (status = entry->status; status; status = next) {
|
||||||
next = status->next;
|
next = status->next;
|
||||||
|
|
||||||
|
if (status->rawOcspResponse)
|
||||||
|
XFREE(status->rawOcspResponse, NULL, DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
|
|
||||||
XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS);
|
XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,7 +118,7 @@ static int xstat2err(int stat)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
|
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert, void* encodedResponse)
|
||||||
{
|
{
|
||||||
int ret = OCSP_LOOKUP_FAIL;
|
int ret = OCSP_LOOKUP_FAIL;
|
||||||
|
|
||||||
@@ -137,7 +141,7 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) {
|
if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) {
|
||||||
ret = CheckOcspRequest(ocsp, ocspRequest);
|
ret = CheckOcspRequest(ocsp, ocspRequest, encodedResponse);
|
||||||
|
|
||||||
FreeOcspRequest(ocspRequest);
|
FreeOcspRequest(ocspRequest);
|
||||||
}
|
}
|
||||||
@@ -186,7 +190,7 @@ static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
|
|||||||
|
|
||||||
|
|
||||||
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
|
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
|
||||||
OcspEntry* entry, CertStatus** status)
|
OcspEntry* entry, CertStatus** status, buffer* responseBuffer)
|
||||||
{
|
{
|
||||||
int ret = OCSP_INVALID_STATUS;
|
int ret = OCSP_INVALID_STATUS;
|
||||||
|
|
||||||
@@ -204,11 +208,27 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
|
|||||||
&& !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
|
&& !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (*status) {
|
if (responseBuffer && *status && !(*status)->rawOcspResponse) {
|
||||||
|
/* force fetching again */
|
||||||
|
ret = OCSP_INVALID_STATUS;
|
||||||
|
}
|
||||||
|
else if (*status) {
|
||||||
if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE)
|
if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE)
|
||||||
&& ((*status)->nextDate[0] != 0)
|
&& ((*status)->nextDate[0] != 0)
|
||||||
&& ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER))
|
&& ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER))
|
||||||
ret = xstat2err((*status)->status);
|
ret = xstat2err((*status)->status);
|
||||||
|
|
||||||
|
if (responseBuffer) {
|
||||||
|
responseBuffer->buffer = (byte*)XMALLOC(
|
||||||
|
(*status)->rawOcspResponseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (responseBuffer->buffer) {
|
||||||
|
responseBuffer->length = (*status)->rawOcspResponseSz;
|
||||||
|
XMEMCPY(responseBuffer->buffer,
|
||||||
|
(*status)->rawOcspResponse,
|
||||||
|
(*status)->rawOcspResponseSz);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnLockMutex(&ocsp->ocspLock);
|
UnLockMutex(&ocsp->ocspLock);
|
||||||
@@ -216,16 +236,18 @@ static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest)
|
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest,
|
||||||
|
void* encodedResponse)
|
||||||
{
|
{
|
||||||
OcspEntry* entry = NULL;
|
OcspEntry* entry = NULL;
|
||||||
CertStatus* status = NULL;
|
CertStatus* status = NULL;
|
||||||
byte* request = NULL;
|
byte* request = NULL;
|
||||||
int requestSz = 2048;
|
int requestSz = 2048;
|
||||||
byte* response = NULL;
|
byte* response = NULL;
|
||||||
const char* url;
|
buffer* responseBuffer = (buffer*) encodedResponse;
|
||||||
int urlSz;
|
const char* url = NULL;
|
||||||
int ret = -1;
|
int urlSz = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
CertStatus* newStatus;
|
CertStatus* newStatus;
|
||||||
@@ -237,11 +259,16 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest)
|
|||||||
|
|
||||||
WOLFSSL_ENTER("CheckOcspRequest");
|
WOLFSSL_ENTER("CheckOcspRequest");
|
||||||
|
|
||||||
|
if (responseBuffer) {
|
||||||
|
responseBuffer->buffer = NULL;
|
||||||
|
responseBuffer->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = GetOcspEntry(ocsp, ocspRequest, &entry);
|
ret = GetOcspEntry(ocsp, ocspRequest, &entry);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = GetOcspStatus(ocsp, ocspRequest, entry, &status);
|
ret = GetOcspStatus(ocsp, ocspRequest, entry, &status, responseBuffer);
|
||||||
if (ret != OCSP_INVALID_STATUS)
|
if (ret != OCSP_INVALID_STATUS)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -300,14 +327,29 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest)
|
|||||||
ret = OCSP_LOOKUP_FAIL;
|
ret = OCSP_LOOKUP_FAIL;
|
||||||
else {
|
else {
|
||||||
if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
|
if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
|
||||||
|
if (responseBuffer) {
|
||||||
|
responseBuffer->buffer = (byte*)XMALLOC(ret, NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
|
||||||
|
if (responseBuffer->buffer) {
|
||||||
|
responseBuffer->length = ret;
|
||||||
|
XMEMCPY(responseBuffer->buffer, response, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = xstat2err(ocspResponse->status->status);
|
ret = xstat2err(ocspResponse->status->status);
|
||||||
|
|
||||||
if (LockMutex(&ocsp->ocspLock) != 0)
|
if (LockMutex(&ocsp->ocspLock) != 0)
|
||||||
ret = BAD_MUTEX_E;
|
ret = BAD_MUTEX_E;
|
||||||
else {
|
else {
|
||||||
if (status != NULL)
|
if (status != NULL) {
|
||||||
|
if (status->rawOcspResponse)
|
||||||
|
XFREE(status->rawOcspResponse, NULL,
|
||||||
|
DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
|
|
||||||
/* Replace existing certificate entry with updated */
|
/* Replace existing certificate entry with updated */
|
||||||
XMEMCPY(status, newStatus, sizeof(CertStatus));
|
XMEMCPY(status, newStatus, sizeof(CertStatus));
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
/* Save new certificate entry */
|
/* Save new certificate entry */
|
||||||
status = (CertStatus*)XMALLOC(sizeof(CertStatus),
|
status = (CertStatus*)XMALLOC(sizeof(CertStatus),
|
||||||
@@ -320,6 +362,19 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (responseBuffer && responseBuffer->buffer) {
|
||||||
|
status->rawOcspResponse = (byte*)XMALLOC(
|
||||||
|
responseBuffer->length, NULL,
|
||||||
|
DYNAMIC_TYPE_OCSP_STATUS);
|
||||||
|
|
||||||
|
if (status->rawOcspResponse) {
|
||||||
|
status->rawOcspResponseSz = responseBuffer->length;
|
||||||
|
XMEMCPY(status->rawOcspResponse,
|
||||||
|
responseBuffer->buffer,
|
||||||
|
responseBuffer->length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UnLockMutex(&ocsp->ocspLock);
|
UnLockMutex(&ocsp->ocspLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
61
src/ssl.c
61
src/ssl.c
@@ -1643,6 +1643,10 @@ void wolfSSL_CertManagerFree(WOLFSSL_CERT_MANAGER* cm)
|
|||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
if (cm->ocsp)
|
if (cm->ocsp)
|
||||||
FreeOCSP(cm->ocsp, 1);
|
FreeOCSP(cm->ocsp, 1);
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
|
if (cm->ocsp_stapling)
|
||||||
|
FreeOCSP(cm->ocsp_stapling, 1);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
|
FreeSignerTable(cm->caTable, CA_TABLE_SIZE, NULL);
|
||||||
FreeMutex(&cm->caLock);
|
FreeMutex(&cm->caLock);
|
||||||
@@ -3460,6 +3464,42 @@ int wolfSSL_CertManagerDisableOCSP(WOLFSSL_CERT_MANAGER* cm)
|
|||||||
return SSL_SUCCESS;
|
return SSL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* turn on OCSP Stapling if off and compiled in, set options */
|
||||||
|
int wolfSSL_CertManagerEnableOCSPStapling(WOLFSSL_CERT_MANAGER* cm)
|
||||||
|
{
|
||||||
|
int ret = SSL_SUCCESS;
|
||||||
|
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CertManagerEnableOCSPStapling");
|
||||||
|
if (cm == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
|
if (cm->ocsp_stapling == NULL) {
|
||||||
|
cm->ocsp_stapling = (WOLFSSL_OCSP*)XMALLOC(sizeof(WOLFSSL_OCSP),
|
||||||
|
cm->heap, DYNAMIC_TYPE_OCSP);
|
||||||
|
if (cm->ocsp_stapling == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
|
||||||
|
if (InitOCSP(cm->ocsp_stapling, cm) != 0) {
|
||||||
|
WOLFSSL_MSG("Init OCSP failed");
|
||||||
|
FreeOCSP(cm->ocsp_stapling, 1);
|
||||||
|
cm->ocsp_stapling = NULL;
|
||||||
|
return SSL_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cm->ocspStaplingEnabled = 1;
|
||||||
|
|
||||||
|
#ifndef WOLFSSL_USER_IO
|
||||||
|
cm->ocspIOCb = EmbedOcspLookup;
|
||||||
|
cm->ocspRespFreeCb = EmbedOcspRespFree;
|
||||||
|
#endif /* WOLFSSL_USER_IO */
|
||||||
|
#else
|
||||||
|
ret = NOT_COMPILED_IN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
|
|
||||||
@@ -3494,7 +3534,7 @@ int wolfSSL_CertManagerCheckOCSP(WOLFSSL_CERT_MANAGER* cm, byte* der, int sz)
|
|||||||
if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
|
if ((ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, cm)) != 0) {
|
||||||
WOLFSSL_MSG("ParseCert failed");
|
WOLFSSL_MSG("ParseCert failed");
|
||||||
}
|
}
|
||||||
else if ((ret = CheckCertOCSP(cm->ocsp, cert)) != 0) {
|
else if ((ret = CheckCertOCSP(cm->ocsp, cert, NULL)) != 0) {
|
||||||
WOLFSSL_MSG("CheckCertOCSP failed");
|
WOLFSSL_MSG("CheckCertOCSP failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3629,6 +3669,16 @@ int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX* ctx, CbOCSPIO ioCb,
|
|||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
|
int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX* ctx)
|
||||||
|
{
|
||||||
|
WOLFSSL_ENTER("wolfSSL_CTX_EnableOCSPStapling");
|
||||||
|
if (ctx)
|
||||||
|
return wolfSSL_CertManagerEnableOCSPStapling(ctx->cm);
|
||||||
|
else
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* HAVE_OCSP */
|
#endif /* HAVE_OCSP */
|
||||||
|
|
||||||
@@ -6132,6 +6182,15 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl,
|
|||||||
WOLFSSL_MSG("accept state CERT_SENT");
|
WOLFSSL_MSG("accept state CERT_SENT");
|
||||||
|
|
||||||
case CERT_SENT :
|
case CERT_SENT :
|
||||||
|
if (!ssl->options.resuming)
|
||||||
|
if ( (ssl->error = SendCertificateStatus(ssl)) != 0) {
|
||||||
|
WOLFSSL_ERROR(ssl->error);
|
||||||
|
return SSL_FATAL_ERROR;
|
||||||
|
}
|
||||||
|
ssl->options.acceptState = CERT_STATUS_SENT;
|
||||||
|
WOLFSSL_MSG("accept state CERT_STATUS_SENT");
|
||||||
|
|
||||||
|
case CERT_STATUS_SENT :
|
||||||
if (!ssl->options.resuming)
|
if (!ssl->options.resuming)
|
||||||
if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
|
if ( (ssl->error = SendServerKeyExchange(ssl)) != 0) {
|
||||||
WOLFSSL_ERROR(ssl->error);
|
WOLFSSL_ERROR(ssl->error);
|
||||||
|
59
src/tls.c
59
src/tls.c
@@ -1891,11 +1891,6 @@ int TLSX_UseTruncatedHMAC(TLSX** extensions)
|
|||||||
|
|
||||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||||
|
|
||||||
#ifndef HAVE_OCSP
|
|
||||||
#error Status Request Extension requires OCSP. \
|
|
||||||
Use --enable-ocsp in the configure script or define HAVE_OCSP.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void TLSX_CSR_Free(CertificateStatusRequest* csr)
|
static void TLSX_CSR_Free(CertificateStatusRequest* csr)
|
||||||
{
|
{
|
||||||
switch (csr->status_type) {
|
switch (csr->status_type) {
|
||||||
@@ -1972,7 +1967,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
|
|||||||
static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||||
byte isRequest)
|
byte isRequest)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
/* shut up compiler warnings */
|
/* shut up compiler warnings */
|
||||||
(void) ssl; (void) input;
|
(void) ssl; (void) input;
|
||||||
@@ -2019,8 +2014,56 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
|||||||
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
|
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
#ifndef NO_WOLFSSL_SERVER
|
||||||
|
byte status_type;
|
||||||
|
word16 offset = 0;
|
||||||
|
word16 size = 0;
|
||||||
|
|
||||||
return ret;
|
if (length < ENUM_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
status_type = input[offset++];
|
||||||
|
|
||||||
|
switch (status_type) {
|
||||||
|
case WOLFSSL_CSR_OCSP: {
|
||||||
|
|
||||||
|
/* skip responder_id_list */
|
||||||
|
if (length - offset < OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
ato16(input + offset, &size);
|
||||||
|
offset += OPAQUE16_LEN + size;
|
||||||
|
|
||||||
|
/* skip request_extensions */
|
||||||
|
if (length - offset < OPAQUE16_LEN)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
ato16(input + offset, &size);
|
||||||
|
offset += OPAQUE16_LEN + size;
|
||||||
|
|
||||||
|
if (offset > length)
|
||||||
|
return BUFFER_ERROR;
|
||||||
|
|
||||||
|
/* is able to send OCSP response? */
|
||||||
|
if (ssl->ctx->cm == NULL || !ssl->ctx->cm->ocspStaplingEnabled)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type,
|
||||||
|
0);
|
||||||
|
if (ret != SSL_SUCCESS)
|
||||||
|
return ret; /* throw error */
|
||||||
|
|
||||||
|
TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST);
|
||||||
|
ssl->status_request = status_type;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert)
|
int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert)
|
||||||
@@ -2078,7 +2121,7 @@ int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
|
|||||||
case WOLFSSL_CSR_OCSP:
|
case WOLFSSL_CSR_OCSP:
|
||||||
if (ssl->ctx->cm->ocspEnabled)
|
if (ssl->ctx->cm->ocspEnabled)
|
||||||
return CheckOcspRequest(ssl->ctx->cm->ocsp,
|
return CheckOcspRequest(ssl->ctx->cm->ocsp,
|
||||||
&csr->request.ocsp);
|
&csr->request.ocsp, NULL);
|
||||||
else
|
else
|
||||||
return OCSP_LOOKUP_FAIL;
|
return OCSP_LOOKUP_FAIL;
|
||||||
}
|
}
|
||||||
|
@@ -8776,20 +8776,13 @@ void InitOcspResponse(OcspResponse* resp, CertStatus* status,
|
|||||||
{
|
{
|
||||||
WOLFSSL_ENTER("InitOcspResponse");
|
WOLFSSL_ENTER("InitOcspResponse");
|
||||||
|
|
||||||
|
XMEMSET(status, 0, sizeof(CertStatus));
|
||||||
|
XMEMSET(resp, 0, sizeof(OcspResponse));
|
||||||
|
|
||||||
resp->responseStatus = -1;
|
resp->responseStatus = -1;
|
||||||
resp->response = NULL;
|
resp->status = status;
|
||||||
resp->responseSz = 0;
|
resp->source = source;
|
||||||
resp->producedDateFormat = 0;
|
resp->maxIdx = inSz;
|
||||||
resp->issuerHash = NULL;
|
|
||||||
resp->issuerKeyHash = NULL;
|
|
||||||
resp->sig = NULL;
|
|
||||||
resp->sigSz = 0;
|
|
||||||
resp->sigOID = 0;
|
|
||||||
resp->status = status;
|
|
||||||
resp->nonce = NULL;
|
|
||||||
resp->nonceSz = 0;
|
|
||||||
resp->source = source;
|
|
||||||
resp->maxIdx = inSz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1361,22 +1361,26 @@ struct WOLFSSL_CRL {
|
|||||||
/* wolfSSL Certificate Manager */
|
/* wolfSSL Certificate Manager */
|
||||||
struct WOLFSSL_CERT_MANAGER {
|
struct WOLFSSL_CERT_MANAGER {
|
||||||
Signer* caTable[CA_TABLE_SIZE]; /* the CA signer table */
|
Signer* caTable[CA_TABLE_SIZE]; /* the CA signer table */
|
||||||
void* heap; /* heap helper */
|
void* heap; /* heap helper */
|
||||||
WOLFSSL_CRL* crl; /* CRL checker */
|
WOLFSSL_CRL* crl; /* CRL checker */
|
||||||
WOLFSSL_OCSP* ocsp; /* OCSP checker */
|
WOLFSSL_OCSP* ocsp; /* OCSP checker */
|
||||||
char* ocspOverrideURL; /* use this responder */
|
#if !defined(NO_WOLFSSL_SEVER) && defined(HAVE_CERTIFICATE_STATUS_REQUEST)
|
||||||
void* ocspIOCtx; /* I/O callback CTX */
|
WOLFSSL_OCSP* ocsp_stapling; /* OCSP checker for OCSP stapling */
|
||||||
CallbackCACache caCacheCallback; /* CA cache addition callback */
|
#endif
|
||||||
CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */
|
char* ocspOverrideURL; /* use this responder */
|
||||||
CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */
|
void* ocspIOCtx; /* I/O callback CTX */
|
||||||
CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */
|
CallbackCACache caCacheCallback; /* CA cache addition callback */
|
||||||
wolfSSL_Mutex caLock; /* CA list lock */
|
CbMissingCRL cbMissingCRL; /* notify through cb of missing crl */
|
||||||
byte crlEnabled; /* is CRL on ? */
|
CbOCSPIO ocspIOCb; /* I/O callback for OCSP lookup */
|
||||||
byte crlCheckAll; /* always leaf, but all ? */
|
CbOCSPRespFree ocspRespFreeCb; /* Frees OCSP Response from IO Cb */
|
||||||
byte ocspEnabled; /* is OCSP on ? */
|
wolfSSL_Mutex caLock; /* CA list lock */
|
||||||
byte ocspCheckAll; /* always leaf, but all ? */
|
byte crlEnabled; /* is CRL on ? */
|
||||||
byte ocspSendNonce; /* send the OCSP nonce ? */
|
byte crlCheckAll; /* always leaf, but all ? */
|
||||||
byte ocspUseOverrideURL; /* ignore cert's responder, override */
|
byte ocspEnabled; /* is OCSP on ? */
|
||||||
|
byte ocspCheckAll; /* always leaf, but all ? */
|
||||||
|
byte ocspSendNonce; /* send the OCSP nonce ? */
|
||||||
|
byte ocspUseOverrideURL; /* ignore cert's responder, override */
|
||||||
|
byte ocspStaplingEnabled; /* is OCSP Stapling on ? */
|
||||||
};
|
};
|
||||||
|
|
||||||
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
|
WOLFSSL_LOCAL int CM_SaveCertCache(WOLFSSL_CERT_MANAGER*, const char*);
|
||||||
@@ -2033,6 +2037,7 @@ enum AcceptState {
|
|||||||
ACCEPT_FIRST_REPLY_DONE,
|
ACCEPT_FIRST_REPLY_DONE,
|
||||||
SERVER_HELLO_SENT,
|
SERVER_HELLO_SENT,
|
||||||
CERT_SENT,
|
CERT_SENT,
|
||||||
|
CERT_STATUS_SENT,
|
||||||
KEY_EXCHANGE_SENT,
|
KEY_EXCHANGE_SENT,
|
||||||
CERT_REQ_SENT,
|
CERT_REQ_SENT,
|
||||||
SERVER_HELLO_DONE,
|
SERVER_HELLO_DONE,
|
||||||
@@ -2640,6 +2645,7 @@ WOLFSSL_LOCAL int DoClientTicket(WOLFSSL*, const byte*, word32);
|
|||||||
WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
|
WOLFSSL_LOCAL int SendData(WOLFSSL*, const void*, int);
|
||||||
WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
|
WOLFSSL_LOCAL int SendCertificate(WOLFSSL*);
|
||||||
WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
|
WOLFSSL_LOCAL int SendCertificateRequest(WOLFSSL*);
|
||||||
|
WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL*);
|
||||||
WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*);
|
WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL*);
|
||||||
WOLFSSL_LOCAL int SendBuffered(WOLFSSL*);
|
WOLFSSL_LOCAL int SendBuffered(WOLFSSL*);
|
||||||
WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int);
|
WOLFSSL_LOCAL int ReceiveData(WOLFSSL*, byte*, int, int);
|
||||||
|
@@ -39,9 +39,9 @@ typedef struct WOLFSSL_OCSP WOLFSSL_OCSP;
|
|||||||
WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*);
|
WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*);
|
||||||
WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic);
|
WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic);
|
||||||
|
|
||||||
WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*);
|
WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*, void*);
|
||||||
WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp,
|
WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp,
|
||||||
OcspRequest* ocspRequest);
|
OcspRequest* ocspRequest, void*);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
@@ -1269,6 +1269,9 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl);
|
|||||||
WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER*,
|
WOLFSSL_API int wolfSSL_CertManagerSetOCSP_Cb(WOLFSSL_CERT_MANAGER*,
|
||||||
CbOCSPIO, CbOCSPRespFree, void*);
|
CbOCSPIO, CbOCSPRespFree, void*);
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_CertManagerEnableOCSPStapling(
|
||||||
|
WOLFSSL_CERT_MANAGER* cm);
|
||||||
|
|
||||||
WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options);
|
WOLFSSL_API int wolfSSL_EnableCRL(WOLFSSL* ssl, int options);
|
||||||
WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl);
|
WOLFSSL_API int wolfSSL_DisableCRL(WOLFSSL* ssl);
|
||||||
WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int);
|
WOLFSSL_API int wolfSSL_LoadCRL(WOLFSSL*, const char*, int, int);
|
||||||
@@ -1287,6 +1290,8 @@ WOLFSSL_API void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl);
|
|||||||
WOLFSSL_API int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX*, const char*);
|
WOLFSSL_API int wolfSSL_CTX_SetOCSP_OverrideURL(WOLFSSL_CTX*, const char*);
|
||||||
WOLFSSL_API int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX*,
|
WOLFSSL_API int wolfSSL_CTX_SetOCSP_Cb(WOLFSSL_CTX*,
|
||||||
CbOCSPIO, CbOCSPRespFree, void*);
|
CbOCSPIO, CbOCSPRespFree, void*);
|
||||||
|
|
||||||
|
WOLFSSL_API int wolfSSL_CTX_EnableOCSPStapling(WOLFSSL_CTX*);
|
||||||
#endif /* !NO_CERTS */
|
#endif /* !NO_CERTS */
|
||||||
|
|
||||||
/* end of handshake frees temporary arrays, if user needs for get_keys or
|
/* end of handshake frees temporary arrays, if user needs for get_keys or
|
||||||
|
@@ -675,6 +675,9 @@ struct CertStatus {
|
|||||||
byte nextDate[MAX_DATE_SIZE];
|
byte nextDate[MAX_DATE_SIZE];
|
||||||
byte thisDateFormat;
|
byte thisDateFormat;
|
||||||
byte nextDateFormat;
|
byte nextDateFormat;
|
||||||
|
|
||||||
|
byte* rawOcspResponse;
|
||||||
|
word32 rawOcspResponseSz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user