adds contingence plan (force OCSP check when the server answer the status_request extension but doesn't sends a CertificateStatus message);

adds back status_request to context level;
This commit is contained in:
Moisés Guimarães
2015-10-25 21:21:41 -03:00
parent 42380793c9
commit 14fa980dad
12 changed files with 332 additions and 206 deletions

View File

@@ -983,10 +983,13 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
}
#endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
if (statusRequest)
if (statusRequest) {
if (wolfSSL_UseCertificateStatusRequest(ssl, WOLFSSL_CSR_OCSP)
!= SSL_SUCCESS)
err_sys("UseCertificateStatusRequest failed");
wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE);
}
#endif
tcp_connect(&sockfd, host, port, doDTLS, ssl);

View File

@@ -4451,15 +4451,9 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
if (ssl->options.side == WOLFSSL_CLIENT_END) {
switch (ssl->status_request) {
case WOLFSSL_CSR_OCSP: {
OcspRequest* request =
TLSX_CSR_GetRequest(ssl->extensions);
fatal = InitOcspRequest(request, dCert, 0, NULL, 0);
doLookup = 0;
}
break;
if (ssl->status_request) {
fatal = TLSX_CSR_InitRequest(ssl->extensions, dCert);
doLookup = 0;
}
}
#endif
@@ -5112,8 +5106,11 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
if (ssl->msgsReceived.got_certificate_status == 0) {
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
if (ssl->status_request) {
int ret;
WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
return OUT_OF_ORDER_E;
if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0)
return ret;
}
#endif
}
@@ -8736,14 +8733,17 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case RSA_SIGN_FAULT:
return "RSA Signature Fault Error";
case HANDSHAKE_SIZE_ERROR:
return "Handshake message too large Error";
case UNKNOWN_ALPN_PROTOCOL_NAME_E:
return "Unrecognized protocol name Error";
case BAD_CERTIFICATE_STATUS_ERROR:
return "Bad Certificate Status Message Error";
case HANDSHAKE_SIZE_ERROR:
return "Handshake message too large Error";
case OCSP_INVALID_STATUS:
return "Invalid OCSP Status Error";
default :
return "unknown error number";

View File

@@ -34,59 +34,68 @@
#include <wolfssl/ocsp.h>
#include <wolfssl/internal.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#include <wolfcrypt/src/misc.c>
#endif
int InitOCSP(WOLFSSL_OCSP* ocsp, WOLFSSL_CERT_MANAGER* cm)
{
WOLFSSL_ENTER("InitOCSP");
XMEMSET(ocsp, 0, sizeof(*ocsp));
ocsp->cm = cm;
ForceZero(ocsp, sizeof(WOLFSSL_OCSP));
if (InitMutex(&ocsp->ocspLock) != 0)
return BAD_MUTEX_E;
return 0;
}
static int InitOCSP_Entry(OCSP_Entry* ocspe, DecodedCert* cert)
{
WOLFSSL_ENTER("InitOCSP_Entry");
XMEMSET(ocspe, 0, sizeof(*ocspe));
XMEMCPY(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE);
XMEMCPY(ocspe->issuerKeyHash, cert->issuerKeyHash, SHA_DIGEST_SIZE);
ocsp->cm = cm;
return 0;
}
static void FreeOCSP_Entry(OCSP_Entry* ocspe)
static int InitOcspEntry(OcspEntry* entry, OcspRequest* request)
{
CertStatus* tmp = ocspe->status;
WOLFSSL_ENTER("InitOcspEntry");
WOLFSSL_ENTER("FreeOCSP_Entry");
ForceZero(entry, sizeof(OcspEntry));
while (tmp) {
CertStatus* next = tmp->next;
XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_STATUS);
tmp = next;
XMEMCPY(entry->issuerHash, request->issuerHash, OCSP_DIGEST_SIZE);
XMEMCPY(entry->issuerKeyHash, request->issuerKeyHash, OCSP_DIGEST_SIZE);
return 0;
}
static void FreeOcspEntry(OcspEntry* entry)
{
CertStatus *status, *next;
WOLFSSL_ENTER("FreeOcspEntry");
for (status = entry->status; status; status = next) {
next = status->next;
XFREE(status, NULL, DYNAMIC_TYPE_OCSP_STATUS);
}
}
void FreeOCSP(WOLFSSL_OCSP* ocsp, int dynamic)
{
OCSP_Entry* tmp = ocsp->ocspList;
OcspEntry *entry, *next;
WOLFSSL_ENTER("FreeOCSP");
while (tmp) {
OCSP_Entry* next = tmp->next;
FreeOCSP_Entry(tmp);
XFREE(tmp, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
tmp = next;
for (entry = ocsp->ocspList; entry; entry = next) {
next = entry->next;
FreeOcspEntry(entry);
XFREE(entry, NULL, DYNAMIC_TYPE_OCSP_ENTRY);
}
FreeMutex(&ocsp->ocspLock);
if (dynamic)
XFREE(ocsp, NULL, DYNAMIC_TYPE_OCSP);
}
@@ -107,84 +116,135 @@ static int xstat2err(int stat)
int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
{
byte* ocspReqBuf = NULL;
int ocspReqSz = 2048;
byte* ocspRespBuf = NULL;
int result = -1;
OCSP_Entry* ocspe;
CertStatus* certStatus = NULL;
const char *url;
int urlSz;
int ret = OCSP_LOOKUP_FAIL;
#ifdef WOLFSSL_SMALL_STACK
CertStatus* newStatus;
OcspRequest* ocspRequest;
OcspResponse* ocspResponse;
#else
CertStatus newStatus[1];
OcspRequest ocspRequest[1];
OcspResponse ocspResponse[1];
#endif
WOLFSSL_ENTER("CheckCertOCSP");
#ifdef WOLFSSL_SMALL_STACK
ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (ocspRequest == NULL) {
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
return MEMORY_E;
}
#endif
if (InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce) == 0) {
ret = CheckOcspRequest(ocsp, ocspRequest);
FreeOcspRequest(ocspRequest);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
WOLFSSL_LEAVE("CheckCertOCSP", ret);
return ret;
}
static int GetOcspEntry(WOLFSSL_OCSP* ocsp, OcspRequest* request,
OcspEntry** entry)
{
WOLFSSL_ENTER("GetOcspEntry");
*entry = NULL;
if (LockMutex(&ocsp->ocspLock) != 0) {
WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
return BAD_MUTEX_E;
}
ocspe = ocsp->ocspList;
while (ocspe) {
if (XMEMCMP(ocspe->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0
&& XMEMCMP(ocspe->issuerKeyHash, cert->issuerKeyHash,
SHA_DIGEST_SIZE) == 0)
for (*entry = ocsp->ocspList; *entry; *entry = (*entry)->next)
if (XMEMCMP((*entry)->issuerHash, request->issuerHash,
OCSP_DIGEST_SIZE) == 0
&& XMEMCMP((*entry)->issuerKeyHash, request->issuerKeyHash,
OCSP_DIGEST_SIZE) == 0)
break;
else
ocspe = ocspe->next;
}
if (ocspe == NULL) {
ocspe = (OCSP_Entry*)XMALLOC(sizeof(OCSP_Entry),
NULL, DYNAMIC_TYPE_OCSP_ENTRY);
if (ocspe != NULL) {
InitOCSP_Entry(ocspe, cert);
ocspe->next = ocsp->ocspList;
ocsp->ocspList = ocspe;
}
else {
UnLockMutex(&ocsp->ocspLock);
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
return MEMORY_ERROR;
}
}
else {
certStatus = ocspe->status;
while (certStatus) {
if (certStatus->serialSz == cert->serialSz &&
XMEMCMP(certStatus->serial, cert->serial, cert->serialSz) == 0)
break;
else
certStatus = certStatus->next;
}
}
if (certStatus != NULL) {
if (!ValidateDate(certStatus->thisDate,
certStatus->thisDateFormat, BEFORE) ||
(certStatus->nextDate[0] == 0) ||
!ValidateDate(certStatus->nextDate,
certStatus->nextDateFormat, AFTER)) {
WOLFSSL_MSG("\tinvalid status date, looking up cert");
}
else {
result = xstat2err(certStatus->status);
UnLockMutex(&ocsp->ocspLock);
WOLFSSL_LEAVE("CheckCertOCSP", result);
return result;
if (*entry == NULL) {
*entry = (OcspEntry*)XMALLOC(sizeof(OcspEntry),
NULL, DYNAMIC_TYPE_OCSP_ENTRY);
if (*entry) {
InitOcspEntry(*entry, request);
(*entry)->next = ocsp->ocspList;
ocsp->ocspList = *entry;
}
}
UnLockMutex(&ocsp->ocspLock);
return *entry ? 0 : MEMORY_ERROR;
}
static int GetOcspStatus(WOLFSSL_OCSP* ocsp, OcspRequest* request,
OcspEntry* entry, CertStatus** status)
{
int ret = OCSP_INVALID_STATUS;
WOLFSSL_ENTER("GetOcspStatus");
*status = NULL;
if (LockMutex(&ocsp->ocspLock) != 0) {
WOLFSSL_LEAVE("CheckCertOCSP", BAD_MUTEX_E);
return BAD_MUTEX_E;
}
for (*status = entry->status; *status; *status = (*status)->next)
if ((*status)->serialSz == request->serialSz
&& !XMEMCMP((*status)->serial, request->serial, (*status)->serialSz))
break;
if (*status) {
if (ValidateDate((*status)->thisDate, (*status)->thisDateFormat, BEFORE)
&& ((*status)->nextDate[0] != 0)
&& ValidateDate((*status)->nextDate, (*status)->nextDateFormat, AFTER))
ret = xstat2err((*status)->status);
}
UnLockMutex(&ocsp->ocspLock);
return ret;
}
int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest)
{
OcspEntry* entry = NULL;
CertStatus* status = NULL;
byte* request = NULL;
int requestSz = 2048;
byte* response = NULL;
const char* url;
int urlSz;
int ret = -1;
#ifdef WOLFSSL_SMALL_STACK
CertStatus* newStatus;
OcspResponse* ocspResponse;
#else
CertStatus newStatus[1];
OcspResponse ocspResponse[1];
#endif
WOLFSSL_ENTER("CheckOcspRequest");
ret = GetOcspEntry(ocsp, ocspRequest, &entry);
if (ret != 0)
return ret;
ret = GetOcspStatus(ocsp, ocspRequest, entry, &status);
if (ret != OCSP_INVALID_STATUS)
return ret;
if (ocsp->cm->ocspUseOverrideURL) {
url = ocsp->cm->ocspOverrideURL;
if (url != NULL && url[0] != '\0')
@@ -192,17 +252,17 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
else
return OCSP_NEED_URL;
}
else if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
url = (const char *)cert->extAuthInfo;
urlSz = cert->extAuthInfoSz;
else if (ocspRequest->urlSz != 0 && ocspRequest->url != NULL) {
url = (const char *)ocspRequest->url;
urlSz = ocspRequest->urlSz;
}
else {
/* cert doesn't have extAuthInfo, assuming CERT_GOOD */
return 0;
}
ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
if (ocspReqBuf == NULL) {
request = (byte*)XMALLOC(requestSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
if (request == NULL) {
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
return MEMORY_ERROR;
}
@@ -210,60 +270,53 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
#ifdef WOLFSSL_SMALL_STACK
newStatus = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
ocspRequest = (OcspRequest*)XMALLOC(sizeof(OcspRequest), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
ocspResponse = (OcspResponse*)XMALLOC(sizeof(OcspResponse), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (newStatus == NULL || ocspRequest == NULL || ocspResponse == NULL) {
if (newStatus == NULL || ocspResponse == NULL) {
if (newStatus) XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ocspRequest) XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (ocspResponse) XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(request, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WOLFSSL_LEAVE("CheckCertOCSP", MEMORY_ERROR);
return MEMORY_E;
}
#endif
result = InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
ocspReqBuf, ocspReqSz);
if (result == 0) {
ocspReqSz = EncodeOcspRequest(ocspRequest);
requestSz = EncodeOcspRequest(ocspRequest, request, requestSz);
if (ocsp->cm->ocspIOCb)
result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
ocspReqBuf, ocspReqSz, &ocspRespBuf);
}
if (ocsp->cm->ocspIOCb)
ret = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
request, requestSz, &response);
if (result >= 0 && ocspRespBuf) {
if (ret >= 0 && response) {
XMEMSET(newStatus, 0, sizeof(CertStatus));
InitOcspResponse(ocspResponse, newStatus, ocspRespBuf, result);
InitOcspResponse(ocspResponse, newStatus, response, ret);
OcspResponseDecode(ocspResponse);
if (ocspResponse->responseStatus != OCSP_SUCCESSFUL)
result = OCSP_LOOKUP_FAIL;
ret = OCSP_LOOKUP_FAIL;
else {
if (CompareOcspReqResp(ocspRequest, ocspResponse) == 0) {
result = xstat2err(ocspResponse->status->status);
ret = xstat2err(ocspResponse->status->status);
if (LockMutex(&ocsp->ocspLock) != 0)
result = BAD_MUTEX_E;
ret = BAD_MUTEX_E;
else {
if (certStatus != NULL)
if (status != NULL)
/* Replace existing certificate entry with updated */
XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
XMEMCPY(status, newStatus, sizeof(CertStatus));
else {
/* Save new certificate entry */
certStatus = (CertStatus*)XMALLOC(sizeof(CertStatus),
status = (CertStatus*)XMALLOC(sizeof(CertStatus),
NULL, DYNAMIC_TYPE_OCSP_STATUS);
if (certStatus != NULL) {
XMEMCPY(certStatus, newStatus, sizeof(CertStatus));
certStatus->next = ocspe->status;
ocspe->status = certStatus;
ocspe->totalStatus++;
if (status != NULL) {
XMEMCPY(status, newStatus, sizeof(CertStatus));
status->next = entry->status;
entry->status = status;
entry->totalStatus++;
}
}
@@ -271,26 +324,22 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
}
}
else
result = OCSP_LOOKUP_FAIL;
ret = OCSP_LOOKUP_FAIL;
}
}
else
result = OCSP_LOOKUP_FAIL;
FreeOcspRequest(ocspRequest);
XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
ret = OCSP_LOOKUP_FAIL;
#ifdef WOLFSSL_SMALL_STACK
XFREE(newStatus, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ocspRequest, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(ocspResponse, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (ocspRespBuf != NULL && ocsp->cm->ocspRespFreeCb)
ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, ocspRespBuf);
if (response != NULL && ocsp->cm->ocspRespFreeCb)
ocsp->cm->ocspRespFreeCb(ocsp->cm->ocspIOCtx, response);
WOLFSSL_LEAVE("CheckCertOCSP", result);
return result;
WOLFSSL_LEAVE("CheckOcspRequest", ret);
return ret;
}

View File

@@ -804,6 +804,15 @@ int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type)
return TLSX_UseCertificateStatusRequest(&ssl->extensions, status_type);
}
int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx, byte status_type)
{
if (ctx == NULL || ctx->method->side != WOLFSSL_CLIENT_END)
return BAD_FUNC_ARG;
return TLSX_UseCertificateStatusRequest(&ctx->extensions, status_type);
}
#endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
/* Elliptic Curves */

View File

@@ -1900,7 +1900,7 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr)
{
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
FreeOcspRequest(&csr->data.ocspRequest);
FreeOcspRequest(&csr->request.ocsp);
break;
}
@@ -1959,6 +1959,8 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
byte isRequest)
{
int ret = 0;
/* shut up compiler warnings */
(void) ssl; (void) input;
@@ -1967,15 +1969,43 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
CertificateStatusRequest* csr = extension ? extension->data : NULL;
if (csr == NULL)
return BUFFER_ERROR; /* unexpected extension */
if (!csr) {
/* look at context level */
ssl->status_request = csr->status_type;
extension = TLSX_Find(ssl->ctx->extensions, TLSX_STATUS_REQUEST);
csr = extension ? extension->data : NULL;
if (!csr)
return BUFFER_ERROR; /* unexpected extension */
/* enable extension at ssl level */
ret = TLSX_UseCertificateStatusRequest(&ssl->extensions,
csr->status_type);
if (ret != SSL_SUCCESS)
return ret;
}
ssl->status_request = 1;
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
#endif
}
return ret;
}
int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert)
{
TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST);
CertificateStatusRequest* csr = extension ? extension->data : NULL;
if (csr) {
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
return InitOcspRequest(&csr->request.ocsp, cert, 0);
}
}
return 0;
}
@@ -1987,7 +2017,7 @@ void* TLSX_CSR_GetRequest(TLSX* extensions)
if (csr) {
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
return &csr->data.ocspRequest;
return &csr->request.ocsp;
break;
}
}
@@ -1995,31 +2025,42 @@ void* TLSX_CSR_GetRequest(TLSX* extensions)
return NULL;
}
int TLSX_CSR_ForceRequest(WOLFSSL* ssl)
{
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
CertificateStatusRequest* csr = extension ? extension->data : NULL;
if (csr) {
switch (csr->status_type) {
case WOLFSSL_CSR_OCSP:
if (ssl->ctx->cm->ocspEnabled)
return CheckOcspRequest(ssl->ctx->cm->ocsp,
&csr->request.ocsp);
else
return OCSP_LOOKUP_FAIL;
}
}
return 0;
}
int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
{
CertificateStatusRequest* csr = NULL;
int ret = 0;
if (!extensions)
if (!extensions || status_type != WOLFSSL_CSR_OCSP)
return BAD_FUNC_ARG;
csr = (CertificateStatusRequest*)XMALLOC(sizeof(CertificateStatusRequest),
NULL, DYNAMIC_TYPE_TLSX);
csr = (CertificateStatusRequest*)
XMALLOC(sizeof(CertificateStatusRequest), NULL, DYNAMIC_TYPE_TLSX);
if (!csr)
return MEMORY_E;
ForceZero(csr, sizeof(CertificateStatusRequest));
csr->status_type = status_type;
switch (status_type) {
case WOLFSSL_CSR_OCSP:
ForceZero(&csr->data.ocspRequest, sizeof(OcspRequest));
break;
default:
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
return BAD_FUNC_ARG;
}
if ((ret = TLSX_Push(extensions, TLSX_STATUS_REQUEST, csr)) != 0) {
XFREE(csr, NULL, DYNAMIC_TYPE_TLSX);
return ret;

View File

@@ -8839,7 +8839,7 @@ static word32 SetOcspReqExtensions(word32 extSz, byte* output,
}
int EncodeOcspRequest(OcspRequest* req)
int EncodeOcspRequest(OcspRequest* req, byte* output, word32 size)
{
byte seqArray[5][MAX_SEQ_SZ];
/* The ASN.1 of the OCSP Request is an onion of sequences */
@@ -8848,7 +8848,6 @@ int EncodeOcspRequest(OcspRequest* req)
byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
byte snArray[MAX_SN_SZ];
byte extArray[MAX_OCSP_EXT_SZ];
byte* output = req->request;
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
int i;
@@ -8865,21 +8864,9 @@ int EncodeOcspRequest(OcspRequest* req)
snSz = SetSerialNumber(req->serial, req->serialSz, snArray);
extSz = 0;
if (req->useNonce) {
WC_RNG rng;
if (wc_InitRng(&rng) != 0) {
WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
} else {
if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
else {
req->nonceSz = MAX_OCSP_NONCE_SZ;
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
if (req->nonceSz)
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
req->nonce, req->nonceSz);
}
wc_FreeRng(&rng);
}
}
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
for (i = 4; i >= 0; i--) {
@@ -8888,6 +8875,9 @@ int EncodeOcspRequest(OcspRequest* req)
if (i == 2) totalSz += extSz;
}
if (totalSz > size)
return BUFFER_E;
totalSz = 0;
for (i = 0; i < 5; i++) {
XMEMCPY(output + totalSz, seqArray[i], seqSz[i]);
@@ -8915,8 +8905,7 @@ int EncodeOcspRequest(OcspRequest* req)
}
int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
byte* dest, word32 destSz)
int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce)
{
WOLFSSL_ENTER("InitOcspRequest");
@@ -8929,17 +8918,42 @@ int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
XMEMCPY(req->issuerHash, cert->issuerHash, KEYID_SIZE);
XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
req->serial = (byte*)XMALLOC(cert->serialSz, NULL, DYNAMIC_TYPE_OCSP);
req->serial = (byte*)XMALLOC(cert->serialSz, NULL,
DYNAMIC_TYPE_OCSP_REQUEST);
if (req->serial == NULL)
return MEMORY_E;
XMEMCPY(req->serial, cert->serial, cert->serialSz);
req->serialSz = cert->serialSz;
if (cert->extAuthInfoSz != 0 && cert->extAuthInfo != NULL) {
req->url = (byte*)XMALLOC(cert->extAuthInfoSz, NULL,
DYNAMIC_TYPE_OCSP_REQUEST);
if (req->url == NULL) {
XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP);
return MEMORY_E;
}
XMEMCPY(req->url, cert->extAuthInfo, cert->extAuthInfoSz);
req->urlSz = cert->extAuthInfoSz;
}
}
req->useNonce = useNonce;
req->request = dest;
req->requestSz = destSz;
if (useNonce) {
WC_RNG rng;
if (wc_InitRng(&rng) != 0) {
WOLFSSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
} else {
if (wc_RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0)
WOLFSSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce.");
else
req->nonceSz = MAX_OCSP_NONCE_SZ;
wc_FreeRng(&rng);
}
}
return 0;
}
@@ -8948,8 +8962,13 @@ void FreeOcspRequest(OcspRequest* req)
{
WOLFSSL_ENTER("FreeOcspRequest");
if (req && req->serial)
XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP);
if (req) {
if (req->serial)
XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
if (req->url)
XFREE(req->url, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
}
}
@@ -8973,7 +8992,7 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
/* Nonces are not critical. The responder may not necessarily add
* the nonce to the response. */
if (req->useNonce && resp->nonceSz != 0) {
if (req->nonceSz && resp->nonceSz != 0) {
cmp = req->nonceSz - resp->nonceSz;
if (cmp != 0)
{

View File

@@ -140,6 +140,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 */
/* add strings to SetErrorString !!!!! */

View File

@@ -1255,7 +1255,7 @@ struct WOLFSSL_CIPHER {
};
typedef struct OCSP_Entry OCSP_Entry;
typedef struct OcspEntry OcspEntry;
#ifdef NO_SHA
#define OCSP_DIGEST_SIZE SHA256_DIGEST_SIZE
@@ -1268,12 +1268,12 @@ typedef struct OCSP_Entry OCSP_Entry;
typedef struct CertStatus CertStatus;
#endif
struct OCSP_Entry {
OCSP_Entry* next; /* next entry */
byte issuerHash[OCSP_DIGEST_SIZE]; /* issuer hash */
byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */
CertStatus* status; /* OCSP response list */
int totalStatus; /* number on list */
struct OcspEntry {
OcspEntry* next; /* next entry */
byte issuerHash[OCSP_DIGEST_SIZE]; /* issuer hash */
byte issuerKeyHash[OCSP_DIGEST_SIZE]; /* issuer public key hash */
CertStatus* status; /* OCSP response list */
int totalStatus; /* number on list */
};
@@ -1284,7 +1284,7 @@ struct OCSP_Entry {
/* wolfSSL OCSP controller */
struct WOLFSSL_OCSP {
WOLFSSL_CERT_MANAGER* cm; /* pointer back to cert manager */
OCSP_Entry* ocspList; /* OCSP response list */
OcspEntry* ocspList; /* OCSP response list */
wolfSSL_Mutex ocspLock; /* OCSP list lock */
};
@@ -1577,14 +1577,15 @@ WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions);
typedef struct {
byte status_type;
union {
OcspRequest ocspRequest;
} data;
OcspRequest ocsp;
} request;
} CertificateStatusRequest;
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
byte status_type);
WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions);
WOLFSSL_LOCAL int TLSX_CSR_InitRequest(TLSX* extensions, DecodedCert* cert);
WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions);
WOLFSSL_LOCAL int TLSX_CSR_ForceRequest(WOLFSSL* ssl);
#endif

View File

@@ -40,6 +40,8 @@ WOLFSSL_LOCAL int InitOCSP(WOLFSSL_OCSP*, WOLFSSL_CERT_MANAGER*);
WOLFSSL_LOCAL void FreeOCSP(WOLFSSL_OCSP*, int dynamic);
WOLFSSL_LOCAL int CheckCertOCSP(WOLFSSL_OCSP*, DecodedCert*);
WOLFSSL_LOCAL int CheckOcspRequest(WOLFSSL_OCSP* ocsp,
OcspRequest* ocspRequest);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -1419,6 +1419,9 @@ enum {
WOLFSSL_API int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl,
unsigned char status_type);
WOLFSSL_API int wolfSSL_CTX_UseCertificateStatusRequest(WOLFSSL_CTX* ctx,
unsigned char status_type);
#endif
#endif

View File

@@ -709,25 +709,22 @@ struct OcspResponse {
struct OcspRequest {
byte issuerHash[KEYID_SIZE];
byte issuerKeyHash[KEYID_SIZE];
byte* serial; /* copy of the serial number in source cert; OWNED */
byte* serial; /* copy of the serial number in source cert */
int serialSz;
byte* url; /* copy of the extAuthInfo in source cert */
int urlSz;
byte nonce[MAX_OCSP_NONCE_SZ];
int nonceSz;
byte useNonce;
byte* request; /* pointer to the destination ASN.1 buffer; NOT OWNED */
word32 requestSz; /* length of the destination buffer */
byte nonce[MAX_OCSP_NONCE_SZ];
int nonceSz;
};
WOLFSSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse*);
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*,
byte, byte*, word32);
WOLFSSL_LOCAL int InitOcspRequest(OcspRequest*, DecodedCert*, byte);
WOLFSSL_LOCAL void FreeOcspRequest(OcspRequest*);
WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*);
WOLFSSL_LOCAL int EncodeOcspRequest(OcspRequest*, byte*, word32);
WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*);

View File

@@ -286,7 +286,8 @@
DYNAMIC_TYPE_SIGNATURE = 45,
DYNAMIC_TYPE_HASHES = 46,
DYNAMIC_TYPE_SRP = 47,
DYNAMIC_TYPE_COOKIE_PWD = 48
DYNAMIC_TYPE_COOKIE_PWD = 48,
DYNAMIC_TYPE_OCSP_REQUEST = 49,
};
/* max error buffer string size */