forked from wolfSSL/wolfssl
adds support to WOLFSSL_CSR2_OCSP in both DoCertificateStatus() and SendCertificateStatus();
adds contingence plan for status_request_v2;
This commit is contained in:
@ -526,6 +526,10 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method)
|
||||
/* In case contexts are held in array and don't want to free actual ctx */
|
||||
void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)i;
|
||||
|
||||
XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD);
|
||||
if (ctx->suites)
|
||||
XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES);
|
||||
@ -534,22 +538,39 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
|
||||
XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_DH);
|
||||
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_DH);
|
||||
#endif
|
||||
|
||||
#ifndef NO_CERTS
|
||||
XFREE(ctx->privateKey.buffer, ctx->heap, DYNAMIC_TYPE_KEY);
|
||||
XFREE(ctx->certificate.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
|
||||
XFREE(ctx->certChain.buffer, ctx->heap, DYNAMIC_TYPE_CERT);
|
||||
wolfSSL_CertManagerFree(ctx->cm);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TLS_EXTENSIONS
|
||||
TLSX_FreeAll(ctx->extensions);
|
||||
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
if (ctx->certOcspRequest) {
|
||||
FreeOcspRequest(ctx->certOcspRequest);
|
||||
XFREE(ctx->certOcspRequest, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
if (ctx->certOcspRequest) {
|
||||
FreeOcspRequest(ctx->certOcspRequest);
|
||||
XFREE(ctx->certOcspRequest, NULL, DYNAMIC_TYPE_OCSP_REQUEST);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
for (i = 0; i < MAX_CHAIN_DEPTH; i++) {
|
||||
if (ctx->chainOcspRequest[i]) {
|
||||
FreeOcspRequest(ctx->chainOcspRequest[i]);
|
||||
XFREE(ctx->chainOcspRequest[i], NULL, DYNAMIC_TYPE_OCSP_REQUEST);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NO_WOLFSSL_SERVER */
|
||||
|
||||
#endif /* HAVE_TLS_EXTENSIONS */
|
||||
}
|
||||
|
||||
|
||||
@ -4464,14 +4485,21 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
if (fatal == 0) {
|
||||
int doLookup = 1;
|
||||
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
/* TODO CSR2 */
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
if (ssl->status_request) {
|
||||
fatal = TLSX_CSR_InitRequest(ssl->extensions, dCert);
|
||||
doLookup = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
if (ssl->status_request_v2) {
|
||||
fatal = TLSX_CSR2_InitRequests(ssl->extensions, dCert);
|
||||
doLookup = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_OCSP
|
||||
if (doLookup && ssl->ctx->cm->ocspEnabled) {
|
||||
@ -4827,7 +4855,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
|
||||
/* WOLFSSL_CSR_OCSP overlaps with WOLFSSL_CSR2_OCSP */
|
||||
case WOLFSSL_CSR2_OCSP: {
|
||||
OcspRequest* request = TLSX_CSR_GetRequest(ssl->extensions);
|
||||
OcspRequest* request;
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
CertStatus* status;
|
||||
@ -4840,12 +4868,15 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
do {
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
|
||||
if (ssl->status_request) {
|
||||
request = TLSX_CSR_GetRequest(ssl->extensions);
|
||||
ssl->status_request = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
if (ssl->status_request_v2) {
|
||||
request = TLSX_CSR2_GetRequest(ssl->extensions,
|
||||
WOLFSSL_CSR2_OCSP);
|
||||
ssl->status_request_v2 = 0;
|
||||
break;
|
||||
}
|
||||
@ -4853,6 +4884,9 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
|
||||
return BUFFER_ERROR;
|
||||
} while(0);
|
||||
|
||||
if (request == NULL)
|
||||
return BAD_CERTIFICATE_STATUS_ERROR; /* not expected */
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@ -5132,6 +5166,15 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type)
|
||||
if ((ret = TLSX_CSR_ForceRequest(ssl)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
|
||||
if (ssl->status_request_v2) {
|
||||
int ret;
|
||||
|
||||
WOLFSSL_MSG("No CertificateStatus before ServerKeyExchange");
|
||||
if ((ret = TLSX_CSR2_ForceRequest(ssl)) != 0)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
106
src/tls.c
106
src/tls.c
@ -2329,6 +2329,36 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
|
||||
if (!csr2)
|
||||
return BUFFER_ERROR; /* unexpected extension */
|
||||
|
||||
/* enable extension at ssl level */
|
||||
for (; csr2; csr2 = csr2->next) {
|
||||
ret = TLSX_UseCertificateStatusRequestV2(&ssl->extensions,
|
||||
csr2->status_type, csr2->options);
|
||||
if (ret != SSL_SUCCESS)
|
||||
return ret;
|
||||
|
||||
switch (csr2->status_type) {
|
||||
case WOLFSSL_CSR2_OCSP:
|
||||
/* followed by */
|
||||
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||
/* propagate nonce */
|
||||
if (csr2->request.ocsp.nonceSz) {
|
||||
OcspRequest* request =
|
||||
TLSX_CSR2_GetRequest(ssl->extensions,
|
||||
csr2->status_type);
|
||||
|
||||
if (request) {
|
||||
XMEMCPY(request->nonce,
|
||||
csr2->request.ocsp.nonce,
|
||||
csr2->request.ocsp.nonceSz);
|
||||
|
||||
request->nonceSz = csr2->request.ocsp.nonceSz;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ssl->status_request_v2 = 1;
|
||||
@ -2417,6 +2447,82 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, byte* input, word16 length,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert)
|
||||
{
|
||||
TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
|
||||
CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
|
||||
int ret = 0;
|
||||
|
||||
for (; csr2; csr2 = csr2->next) {
|
||||
switch (csr2->status_type) {
|
||||
case WOLFSSL_CSR2_OCSP:
|
||||
/* followed by */
|
||||
|
||||
case WOLFSSL_CSR2_OCSP_MULTI: {
|
||||
byte nonce[MAX_OCSP_NONCE_SZ];
|
||||
int nonceSz = csr2->request.ocsp.nonceSz;
|
||||
|
||||
/* preserve nonce */
|
||||
XMEMCPY(nonce, csr2->request.ocsp.nonce, nonceSz);
|
||||
|
||||
if ((ret = InitOcspRequest(&csr2->request.ocsp, cert, 0)) != 0)
|
||||
return ret;
|
||||
|
||||
/* restore nonce */
|
||||
XMEMCPY(csr2->request.ocsp.nonce, nonce, nonceSz);
|
||||
csr2->request.ocsp.nonceSz = nonceSz;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type)
|
||||
{
|
||||
TLSX* extension = TLSX_Find(extensions, TLSX_STATUS_REQUEST_V2);
|
||||
CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
|
||||
|
||||
for (; csr2; csr2 = csr2->next) {
|
||||
if (csr2->status_type == status_type) {
|
||||
switch (csr2->status_type) {
|
||||
case WOLFSSL_CSR2_OCSP:
|
||||
/* followed by */
|
||||
|
||||
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||
return &csr2->request.ocsp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int TLSX_CSR2_ForceRequest(WOLFSSL* ssl)
|
||||
{
|
||||
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST_V2);
|
||||
CertificateStatusRequestItemV2* csr2 = extension ? extension->data : NULL;
|
||||
|
||||
/* forces only the first one */
|
||||
if (csr2) {
|
||||
switch (csr2->status_type) {
|
||||
case WOLFSSL_CSR2_OCSP:
|
||||
/* followed by */
|
||||
|
||||
case WOLFSSL_CSR2_OCSP_MULTI:
|
||||
if (ssl->ctx->cm->ocspEnabled)
|
||||
return CheckOcspRequest(ssl->ctx->cm->ocsp,
|
||||
&csr2->request.ocsp, NULL);
|
||||
else
|
||||
return OCSP_LOOKUP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
|
||||
byte options)
|
||||
{
|
||||
|
@ -1589,11 +1589,11 @@ typedef struct {
|
||||
} request;
|
||||
} CertificateStatusRequest;
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
|
||||
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
|
||||
byte status_type, byte options);
|
||||
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);
|
||||
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
|
||||
|
||||
@ -1610,8 +1610,11 @@ typedef struct CSRIv2 {
|
||||
struct CSRIv2* next;
|
||||
} CertificateStatusRequestItemV2;
|
||||
|
||||
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequestV2(TLSX** extensions,
|
||||
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequestV2(TLSX** extensions,
|
||||
byte status_type, byte options);
|
||||
WOLFSSL_LOCAL int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert);
|
||||
WOLFSSL_LOCAL void* TLSX_CSR2_GetRequest(TLSX* extensions, byte status_type);
|
||||
WOLFSSL_LOCAL int TLSX_CSR2_ForceRequest(WOLFSSL* ssl);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1790,8 +1793,14 @@ struct WOLFSSL_CTX {
|
||||
#endif
|
||||
#ifdef HAVE_TLS_EXTENSIONS
|
||||
TLSX* extensions; /* RFC 6066 TLS Extensions data */
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && !defined(NO_WOLFSSL_SERVER)
|
||||
OcspRequest* certOcspRequest;
|
||||
#ifndef NO_WOLFSSL_SERVER
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|
||||
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
OcspRequest* certOcspRequest;
|
||||
#endif
|
||||
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
|
||||
OcspRequest* chainOcspRequest[MAX_CHAIN_DEPTH];
|
||||
#endif
|
||||
#endif
|
||||
#if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SEVER)
|
||||
SessionTicketEncCb ticketEncCb; /* enc/dec session ticket Cb */
|
||||
|
Reference in New Issue
Block a user