Merge branch 'ocsp'
Fixes some bugs in the ocsp code, and adds a new option to skip nonces.
This commit is contained in:
commit
831c760edc
@ -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);
|
||||||
|
@ -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*);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
44
src/ocsp.c
44
src/ocsp.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user