adds support to WOLFSSL_CSR2_OCSP in both DoCertificateStatus() and SendCertificateStatus();

adds contingence plan for status_request_v2;
This commit is contained in:
Moisés Guimarães
2015-11-24 00:47:27 -03:00
parent f9d6464793
commit 1fbaf089ae
3 changed files with 174 additions and 16 deletions

View File

@ -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
View File

@ -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)
{

View File

@ -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 */