adds comparison of OcspRequest and OcspResponse;

removes TLS Extension Status Request at context level as specific data is always needed for each session;
This commit is contained in:
Moisés Guimarães
2015-10-23 19:25:41 -03:00
parent daf3155d3c
commit 42380793c9
10 changed files with 220 additions and 168 deletions

View File

@@ -946,12 +946,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS) if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS)
err_sys("UseTruncatedHMAC failed"); err_sys("UseTruncatedHMAC failed");
#endif #endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
if (statusRequest)
if (wolfSSL_CTX_UseCertificateStatusRequest(ctx, WOLFSSL_CSR_OCSP)
!= SSL_SUCCESS)
err_sys("UseCertificateStatusRequest failed");
#endif
#ifdef HAVE_SESSION_TICKET #ifdef HAVE_SESSION_TICKET
if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS) if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS)
err_sys("UseSessionTicket failed"); err_sys("UseSessionTicket failed");
@@ -988,6 +982,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt); wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
} }
#endif #endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST
if (statusRequest)
if (wolfSSL_UseCertificateStatusRequest(ssl, WOLFSSL_CSR_OCSP)
!= SSL_SUCCESS)
err_sys("UseCertificateStatusRequest failed");
#endif
tcp_connect(&sockfd, host, port, doDTLS, ssl); tcp_connect(&sockfd, host, port, doDTLS, ssl);

View File

@@ -4447,12 +4447,28 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#if defined(HAVE_OCSP) || defined(HAVE_CRL) #if defined(HAVE_OCSP) || defined(HAVE_CRL)
if (fatal == 0) { if (fatal == 0) {
int doCrlLookup = 1; int doLookup = 1;
#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;
}
}
#endif
#ifdef HAVE_OCSP #ifdef HAVE_OCSP
if (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);
doCrlLookup = (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");
fatal = 0; fatal = 0;
@@ -4461,7 +4477,7 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#endif /* HAVE_OCSP */ #endif /* HAVE_OCSP */
#ifdef HAVE_CRL #ifdef HAVE_CRL
if (doCrlLookup && ssl->ctx->cm->crlEnabled) { if (doLookup && ssl->ctx->cm->crlEnabled) {
WOLFSSL_MSG("Doing Leaf CRL check"); WOLFSSL_MSG("Doing Leaf CRL check");
ret = CheckCertCRL(ssl->ctx->cm->crl, dCert); ret = CheckCertCRL(ssl->ctx->cm->crl, dCert);
if (ret != 0) { if (ret != 0) {
@@ -4469,14 +4485,13 @@ static int DoCertificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
fatal = 0; fatal = 0;
} }
} }
#else
(void)doCrlLookup;
#endif /* HAVE_CRL */ #endif /* HAVE_CRL */
(void)doLookup;
} }
#endif /* HAVE_OCSP || HAVE_CRL */ #endif /* HAVE_OCSP || HAVE_CRL */
#ifdef KEEP_PEER_CERT #ifdef KEEP_PEER_CERT
{ if (fatal == 0) {
/* set X509 format for peer cert even if fatal */ /* set X509 format for peer cert even if fatal */
int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert); int copyRet = CopyDecodedToX509(&ssl->peerCert, dCert);
if (copyRet == MEMORY_E) if (copyRet == MEMORY_E)
@@ -4801,6 +4816,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) #if defined(HAVE_CERTIFICATE_STATUS_REQUEST)
case WOLFSSL_CSR_OCSP: { case WOLFSSL_CSR_OCSP: {
OcspRequest* request = TLSX_CSR_GetRequest(ssl->extensions);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
CertStatus* status; CertStatus* status;
@@ -4817,12 +4833,6 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
break; break;
} }
#endif #endif
#ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2
if (ssl->status_request_v2) {
ssl->status_request_v2 = 0;
break;
}
#endif
return BUFFER_ERROR; return BUFFER_ERROR;
} while(0); } while(0);
@@ -4844,12 +4854,11 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx,
if ((ret = OcspResponseDecode(response)) == 0) { if ((ret = OcspResponseDecode(response)) == 0) {
if (response->responseStatus != OCSP_SUCCESSFUL) if (response->responseStatus != OCSP_SUCCESSFUL)
ret = FATAL_ERROR; ret = BAD_CERTIFICATE_STATUS_ERROR;
/* TODO CSR */ else if (CompareOcspReqResp(request, response) != 0)
/*else if (CompareOcspReqResp(request, response) != 0) ret = BAD_CERTIFICATE_STATUS_ERROR;
ret = FATAL_ERROR; */
else if (response->status->status != CERT_GOOD) else if (response->status->status != CERT_GOOD)
ret = FATAL_ERROR; ret = BAD_CERTIFICATE_STATUS_ERROR;
} }
*inOutIdx += status_length; *inOutIdx += status_length;
@@ -8730,6 +8739,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case UNKNOWN_ALPN_PROTOCOL_NAME_E: case UNKNOWN_ALPN_PROTOCOL_NAME_E:
return "Unrecognized protocol name Error"; return "Unrecognized protocol name Error";
case BAD_CERTIFICATE_STATUS_ERROR:
return "Bad Certificate Status Message Error";
case HANDSHAKE_SIZE_ERROR: case HANDSHAKE_SIZE_ERROR:
return "Handshake message too large Error"; return "Handshake message too large Error";

View File

@@ -227,13 +227,15 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
} }
#endif #endif
InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce, result = InitOcspRequest(ocspRequest, cert, ocsp->cm->ocspSendNonce,
ocspReqBuf, ocspReqSz); ocspReqBuf, ocspReqSz);
if (result == 0) {
ocspReqSz = EncodeOcspRequest(ocspRequest); ocspReqSz = EncodeOcspRequest(ocspRequest);
if (ocsp->cm->ocspIOCb) if (ocsp->cm->ocspIOCb)
result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz, result = ocsp->cm->ocspIOCb(ocsp->cm->ocspIOCtx, url, urlSz,
ocspReqBuf, ocspReqSz, &ocspRespBuf); ocspReqBuf, ocspReqSz, &ocspRespBuf);
}
if (result >= 0 && ocspRespBuf) { if (result >= 0 && ocspRespBuf) {
XMEMSET(newStatus, 0, sizeof(CertStatus)); XMEMSET(newStatus, 0, sizeof(CertStatus));
@@ -275,6 +277,7 @@ int CheckCertOCSP(WOLFSSL_OCSP* ocsp, DecodedCert* cert)
else else
result = OCSP_LOOKUP_FAIL; result = OCSP_LOOKUP_FAIL;
FreeOcspRequest(ocspRequest);
XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK

View File

@@ -804,15 +804,6 @@ int wolfSSL_UseCertificateStatusRequest(WOLFSSL* ssl, byte status_type)
return TLSX_UseCertificateStatusRequest(&ssl->extensions, 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 */ #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */
/* Elliptic Curves */ /* Elliptic Curves */

View File

@@ -1900,7 +1900,7 @@ static void TLSX_CSR_Free(CertificateStatusRequest* csr)
{ {
switch (csr->status_type) { switch (csr->status_type) {
case WOLFSSL_CSR_OCSP: case WOLFSSL_CSR_OCSP:
/* nothing to release for now... */ FreeOcspRequest(&csr->data.ocspRequest);
break; break;
} }
@@ -1963,14 +1963,38 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, byte* input, word16 length,
(void) ssl; (void) input; (void) ssl; (void) input;
if (!isRequest) { if (!isRequest) {
ssl->status_request = 1; #ifndef NO_WOLFSSL_CLIENT
TLSX* extension = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST);
CertificateStatusRequest* csr = extension ? extension->data : NULL;
if (csr == NULL)
return BUFFER_ERROR; /* unexpected extension */
ssl->status_request = csr->status_type;
return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */ return length ? BUFFER_ERROR : 0; /* extension_data MUST be empty. */
#endif
} }
return 0; return 0;
} }
void* TLSX_CSR_GetRequest(TLSX* extensions)
{
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 &csr->data.ocspRequest;
break;
}
}
return NULL;
}
int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type) int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
{ {
CertificateStatusRequest* csr = NULL; CertificateStatusRequest* csr = NULL;
@@ -1988,7 +2012,7 @@ int TLSX_UseCertificateStatusRequest(TLSX** extensions, byte status_type)
switch (status_type) { switch (status_type) {
case WOLFSSL_CSR_OCSP: case WOLFSSL_CSR_OCSP:
/* nothing to handle for now... */ ForceZero(&csr->data.ocspRequest, sizeof(OcspRequest));
break; break;
default: default:

View File

@@ -8848,7 +8848,7 @@ int EncodeOcspRequest(OcspRequest* req)
byte issuerKeyArray[MAX_ENCODED_DIG_SZ]; byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
byte snArray[MAX_SN_SZ]; byte snArray[MAX_SN_SZ];
byte extArray[MAX_OCSP_EXT_SZ]; byte extArray[MAX_OCSP_EXT_SZ];
byte* output = req->dest; byte* output = req->request;
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
int i; int i;
@@ -8915,21 +8915,41 @@ int EncodeOcspRequest(OcspRequest* req)
} }
void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
byte* dest, word32 destSz) byte* dest, word32 destSz)
{ {
WOLFSSL_ENTER("InitOcspRequest"); WOLFSSL_ENTER("InitOcspRequest");
if (req == NULL)
return BAD_FUNC_ARG;
ForceZero(req, sizeof(OcspRequest)); ForceZero(req, sizeof(OcspRequest));
req->cert = cert; if (cert) {
req->useNonce = useNonce; XMEMCPY(req->issuerHash, cert->issuerHash, KEYID_SIZE);
req->issuerHash = cert->issuerHash; XMEMCPY(req->issuerKeyHash, cert->issuerKeyHash, KEYID_SIZE);
req->issuerKeyHash = cert->issuerKeyHash;
req->serial = cert->serial; req->serial = (byte*)XMALLOC(cert->serialSz, NULL, DYNAMIC_TYPE_OCSP);
if (req->serial == NULL)
return MEMORY_E;
XMEMCPY(req->serial, cert->serial, cert->serialSz);
req->serialSz = cert->serialSz; req->serialSz = cert->serialSz;
req->dest = dest; }
req->destSz = destSz;
req->useNonce = useNonce;
req->request = dest;
req->requestSz = destSz;
return 0;
}
void FreeOcspRequest(OcspRequest* req)
{
WOLFSSL_ENTER("FreeOcspRequest");
if (req && req->serial)
XFREE(req->serial, NULL, DYNAMIC_TYPE_OCSP);
} }

View File

@@ -139,6 +139,7 @@ enum wolfSSL_ErrorCodes {
HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */ HANDSHAKE_SIZE_ERROR = -404, /* Handshake message too large */
UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/ UNKNOWN_ALPN_PROTOCOL_NAME_E = -405, /* Unrecognized protocol name Error*/
BAD_CERTIFICATE_STATUS_ERROR = -406, /* Bad certificate status message */
/* add strings to SetErrorString !!!!! */ /* add strings to SetErrorString !!!!! */

View File

@@ -1576,10 +1576,15 @@ WOLFSSL_LOCAL int TLSX_UseTruncatedHMAC(TLSX** extensions);
typedef struct { typedef struct {
byte status_type; byte status_type;
union {
OcspRequest ocspRequest;
} data;
} CertificateStatusRequest; } CertificateStatusRequest;
WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions, WOLFSSL_LOCAL int TLSX_UseCertificateStatusRequest(TLSX** extensions,
byte status_type); byte status_type);
WOLFSSL_LOCAL void* TLSX_CSR_GetRequest(TLSX* extensions);
#endif #endif

View File

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

View File

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