Merge branch 'ocsp'

Fixes some bugs in the ocsp code, and adds a new option to skip nonces.
This commit is contained in:
John Safranek 2012-12-20 16:26:49 -08:00
commit 831c760edc
6 changed files with 62 additions and 45 deletions

View File

@ -4240,7 +4240,8 @@ static int DecodeSingleResponse(byte* source,
if (GetBasicDate(source, &idx, cs->thisDate, if (GetBasicDate(source, &idx, cs->thisDate,
&cs->thisDateFormat, size) < 0) &cs->thisDateFormat, size) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
if (!ValidateDate(cs->thisDate, cs->thisDateFormat, BEFORE)) /* Check thisDate <= now, or treat thisDate > now as a failure */
if (ValidateDate(cs->thisDate, cs->thisDateFormat, AFTER))
return ASN_BEFORE_DATE_E; return ASN_BEFORE_DATE_E;
/* The following items are optional. Only check for them if there is more /* The following items are optional. Only check for them if there is more
@ -4374,8 +4375,6 @@ static int DecodeResponseData(byte* source,
if (GetBasicDate(source, &idx, resp->producedDate, if (GetBasicDate(source, &idx, resp->producedDate,
&resp->producedDateFormat, size) < 0) &resp->producedDateFormat, size) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
if (!ValidateDate(resp->producedDate, resp->producedDateFormat, BEFORE))
return ASN_BEFORE_DATE_E;
if (DecodeSingleResponse(source, &idx, resp, size) < 0) if (DecodeSingleResponse(source, &idx, resp, size) < 0)
return ASN_PARSE_E; return ASN_PARSE_E;
@ -4635,7 +4634,6 @@ int EncodeOcspRequest(OcspRequest* req)
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->dest;
RNG rng;
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz; word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, extSz, totalSz;
int i; int i;
@ -4653,14 +4651,17 @@ int EncodeOcspRequest(OcspRequest* req)
req->serialSz = req->cert->serialSz; req->serialSz = req->cert->serialSz;
snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray); snSz = SetSerialNumber(req->cert->serial, req->cert->serialSz, snArray);
if (InitRng(&rng) != 0) { extSz = 0;
CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); if (req->useNonce) {
extSz = 0; RNG rng;
} else { if (InitRng(&rng) != 0) {
req->nonceSz = MAX_OCSP_NONCE_SZ; CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); } else {
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, req->nonceSz = MAX_OCSP_NONCE_SZ;
req->nonce, req->nonceSz); RNG_GenerateBlock(&rng, req->nonce, req->nonceSz);
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
req->nonce, req->nonceSz);
}
} }
totalSz = algoSz + issuerSz + issuerKeySz + snSz; totalSz = algoSz + issuerSz + issuerKeySz + snSz;
@ -4692,12 +4693,13 @@ int EncodeOcspRequest(OcspRequest* req)
} }
void InitOcspRequest(OcspRequest* req, DecodedCert* cert, void InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce,
byte* dest, word32 destSz) byte* dest, word32 destSz)
{ {
CYASSL_ENTER("InitOcspRequest"); CYASSL_ENTER("InitOcspRequest");
req->cert = cert; req->cert = cert;
req->useNonce = useNonce;
req->nonceSz = 0; req->nonceSz = 0;
req->issuerHash = NULL; req->issuerHash = NULL;
req->issuerKeyHash = NULL; req->issuerKeyHash = NULL;
@ -4725,18 +4727,20 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
return 1; return 1;
} }
cmp = req->nonceSz - resp->nonceSz; if (req->useNonce) {
if (cmp != 0) cmp = req->nonceSz - resp->nonceSz;
{ if (cmp != 0)
CYASSL_MSG("\tnonceSz mismatch"); {
return cmp; CYASSL_MSG("\tnonceSz mismatch");
} return cmp;
}
cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz); cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
if (cmp != 0) if (cmp != 0)
{ {
CYASSL_MSG("\tnonce mismatch"); CYASSL_MSG("\tnonce mismatch");
return cmp; return cmp;
}
} }
cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE); cmp = XMEMCMP(req->issuerHash, resp->issuerHash, SHA_DIGEST_SIZE);

View File

@ -417,6 +417,7 @@ struct OcspResponse {
struct OcspRequest { struct OcspRequest {
DecodedCert* cert; DecodedCert* cert;
byte useNonce;
byte nonce[MAX_OCSP_NONCE_SZ]; byte nonce[MAX_OCSP_NONCE_SZ];
int nonceSz; int nonceSz;
@ -433,7 +434,8 @@ struct OcspRequest {
CYASSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32); CYASSL_LOCAL void InitOcspResponse(OcspResponse*, CertStatus*, byte*, word32);
CYASSL_LOCAL int OcspResponseDecode(OcspResponse*); CYASSL_LOCAL int OcspResponseDecode(OcspResponse*);
CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*, byte*, word32); CYASSL_LOCAL void InitOcspRequest(OcspRequest*, DecodedCert*,
byte, byte*, word32);
CYASSL_LOCAL int EncodeOcspRequest(OcspRequest*); CYASSL_LOCAL int EncodeOcspRequest(OcspRequest*);
CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*); CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*);

View File

@ -775,6 +775,7 @@ struct OCSP_Entry {
struct CYASSL_OCSP { struct CYASSL_OCSP {
byte enabled; byte enabled;
byte useOverrideUrl; byte useOverrideUrl;
byte useNonce;
char overrideName[80]; char overrideName[80];
char overridePath[80]; char overridePath[80];
int overridePort; int overridePort;

View File

@ -885,6 +885,7 @@ CYASSL_API int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX*, const char*);
#define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */ #define CYASSL_OCSP_ENABLE 0x0001 /* Enable OCSP lookups */
#define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL #define CYASSL_OCSP_URL_OVERRIDE 0x0002 /* Use the override URL instead of URL
* in certificate */ * in certificate */
#define CYASSL_OCSP_NO_NONCE 0x0004 /* Disables the request nonce. */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -64,6 +64,7 @@ int CyaSSL_OCSP_Init(CYASSL_OCSP* ocsp)
{ {
if (ocsp != NULL) { if (ocsp != NULL) {
XMEMSET(ocsp, 0, sizeof(*ocsp)); XMEMSET(ocsp, 0, sizeof(*ocsp));
ocsp->useNonce = 1;
return 0; return 0;
} }
@ -454,7 +455,7 @@ static int xstat2err(int stat)
int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert) int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
{ {
byte ocspReqBuf[SCRATCH_BUFFER_SIZE]; byte* ocspReqBuf = NULL;
int ocspReqSz = SCRATCH_BUFFER_SIZE; int ocspReqSz = SCRATCH_BUFFER_SIZE;
byte* ocspRespBuf = NULL; byte* ocspRespBuf = NULL;
OcspRequest ocspRequest; OcspRequest ocspRequest;
@ -501,30 +502,37 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
} }
} }
InitOcspRequest(&ocspRequest, cert, ocspReqBuf, ocspReqSz); ocspReqBuf = (byte*)XMALLOC(ocspReqSz, NULL, DYNAMIC_TYPE_IN_BUFFER);
if (ocspReqBuf == NULL) {
CYASSL_MSG("\talloc OCSP request buffer failed");
return MEMORY_ERROR;
}
InitOcspRequest(&ocspRequest, cert, ocsp->useNonce, ocspReqBuf, ocspReqSz);
ocspReqSz = EncodeOcspRequest(&ocspRequest); ocspReqSz = EncodeOcspRequest(&ocspRequest);
result = http_ocsp_transaction(ocsp, cert, result = http_ocsp_transaction(ocsp, cert,
ocspReqBuf, ocspReqSz, &ocspRespBuf); ocspReqBuf, ocspReqSz, &ocspRespBuf);
if (result < 0) return result; if (result >= 0) {
/* If the transaction failed, return that result. */ InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result);
OcspResponseDecode(&ocspResponse);
InitOcspResponse(&ocspResponse, certStatus, ocspRespBuf, result); if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
OcspResponseDecode(&ocspResponse); CYASSL_MSG("OCSP Responder failure");
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
CYASSL_MSG("OCSP Responder failure");
result = OCSP_LOOKUP_FAIL;
} else {
if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
{
result = xstat2err(ocspResponse.status->status);
}
else
{
CYASSL_MSG("OCSP Response incorrect for Request");
result = OCSP_LOOKUP_FAIL; result = OCSP_LOOKUP_FAIL;
} else {
if (CompareOcspReqResp(&ocspRequest, &ocspResponse) == 0)
{
result = xstat2err(ocspResponse.status->status);
}
else
{
CYASSL_MSG("OCSP Response incorrect for Request");
result = OCSP_LOOKUP_FAIL;
}
} }
} }
if (ocspReqBuf != NULL) {
XFREE(ocspReqBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
}
if (ocspRespBuf != NULL) { if (ocspRespBuf != NULL) {
XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER); XFREE(ocspRespBuf, NULL, DYNAMIC_TYPE_IN_BUFFER);
} }

View File

@ -8220,6 +8220,7 @@ long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options)
if (ctx != NULL) { if (ctx != NULL) {
ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0; ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0;
ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0; ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0;
ctx->ocsp.useNonce = (options & CYASSL_OCSP_NO_NONCE) == 0;
return 1; return 1;
} }
return 0; return 0;