summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralexei.volkov.bugs%sun.com <devnull@localhost>2007-01-25 00:36:29 +0000
committeralexei.volkov.bugs%sun.com <devnull@localhost>2007-01-25 00:36:29 +0000
commit823c35d27972cf59c5c8e2d3b1dbfbb218a9aec0 (patch)
treef54fe6ee4b8ffa415b279608fda72cc69b33bf6f
parent51e92bf733282b0777aa9f6cdaf6a3ba56fea090 (diff)
downloadnss-hg-823c35d27972cf59c5c8e2d3b1dbfbb218a9aec0.tar.gz
Bug 342461: verify signature on an OCSP response without intermediate decoding and encoding. r=nelson, sr=wtc
-rw-r--r--security/nss/lib/certhigh/ocsp.c42
-rw-r--r--security/nss/lib/certhigh/ocspti.h1
2 files changed, 26 insertions, 17 deletions
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 183f9b902..481b9523a 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -353,6 +353,8 @@ const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = {
static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(ocspBasicOCSPResponse) },
+ { SEC_ASN1_ANY | SEC_ASN1_SAVE,
+ offsetof(ocspBasicOCSPResponse, tbsResponseDataDER) },
{ SEC_ASN1_POINTER,
offsetof(ocspBasicOCSPResponse, tbsResponseData),
ocsp_ResponseDataTemplate },
@@ -1571,9 +1573,19 @@ loser:
* is only used internally. When this interface is officially exported,
* each assertion below will need to be followed-up with setting an error
* and returning (null).
+ *
+ * FUNCTION: ocsp_GetResponseData
+ * Returns ocspResponseData structure and a pointer to tbs response
+ * data DER from a valid ocsp response.
+ * INPUTS:
+ * CERTOCSPResponse *response
+ * structure of a valid ocsp response
+ * RETURN:
+ * decoded OCSP response data and a pointer(tbsResponseDataDER) to its
+ * undecoded data DER.
*/
static ocspResponseData *
-ocsp_GetResponseData(CERTOCSPResponse *response)
+ocsp_GetResponseData(CERTOCSPResponse *response, SECItem **tbsResponseDataDER)
{
ocspBasicOCSPResponse *basic;
ocspResponseData *responseData;
@@ -1591,6 +1603,13 @@ ocsp_GetResponseData(CERTOCSPResponse *response)
responseData = basic->tbsResponseData;
PORT_Assert(responseData != NULL);
+ if (tbsResponseDataDER) {
+ *tbsResponseDataDER = &basic->tbsResponseDataDER;
+
+ PORT_Assert((*tbsResponseDataDER)->data != NULL);
+ PORT_Assert((*tbsResponseDataDER)->len != 0);
+ }
+
return responseData;
}
@@ -2541,15 +2560,13 @@ ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID);
* verifying the signer's cert, or low-level problems (no memory, etc.)
*/
static SECStatus
-ocsp_CheckSignature(ocspSignature *signature, void *tbs,
- const SEC_ASN1Template *encodeTemplate,
+ocsp_CheckSignature(ocspSignature *signature, SECItem *encodedTBS,
CERTCertDBHandle *handle, SECCertUsage certUsage,
int64 checkTime, PRBool lookupByName, void *certIndex,
void *pwArg, CERTCertificate **pSignerCert,
CERTCertificate *issuer)
{
SECItem rawSignature;
- SECItem *encodedTBS = NULL;
CERTCertificate *responder = NULL;
CERTCertificate *signerCert = NULL;
SECKEYPublicKey *signerKey = NULL;
@@ -2662,13 +2679,6 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
goto finish;
/*
- * Prepare the data to be verified; it needs to be DER encoded first.
- */
- encodedTBS = SEC_ASN1EncodeItem(NULL, NULL, tbs, encodeTemplate);
- if (encodedTBS == NULL)
- goto finish;
-
- /*
* We copy the signature data *pointer* and length, so that we can
* modify the length without damaging the original copy. This is a
* simple copy, not a dup, so no destroy/free is necessary.
@@ -2706,9 +2716,6 @@ finish:
}
}
- if (encodedTBS != NULL)
- SECITEM_FreeItem(encodedTBS, PR_TRUE);
-
if (signerKey != NULL)
SECKEY_DestroyPublicKey(signerKey);
@@ -2756,12 +2763,13 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertificate *issuer)
{
ocspResponseData *tbsData; /* this is what is signed */
+ SECItem *tbsResponseDataDER;
PRBool byName;
void *certIndex;
int64 producedAt;
SECStatus rv;
- tbsData = ocsp_GetResponseData(response);
+ tbsData = ocsp_GetResponseData(response, &tbsResponseDataDER);
PORT_Assert(tbsData->responderID != NULL);
switch (tbsData->responderID->responderIDType) {
@@ -2791,7 +2799,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
return rv;
return ocsp_CheckSignature(ocsp_GetResponseSignature(response),
- tbsData, ocsp_ResponseDataTemplate,
+ tbsResponseDataDER,
handle, certUsageStatusResponder, producedAt,
byName, certIndex, pwArg, pSignerCert, issuer);
}
@@ -3621,7 +3629,7 @@ CERT_GetOCSPStatusForCertID(CERTCertDBHandle *handle,
/*
* The ResponseData part is the real guts of the response.
*/
- responseData = ocsp_GetResponseData(response);
+ responseData = ocsp_GetResponseData(response, NULL);
if (responseData == NULL) {
rv = SECFailure;
goto loser;
diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h
index 7148c140a..11b87c64b 100644
--- a/security/nss/lib/certhigh/ocspti.h
+++ b/security/nss/lib/certhigh/ocspti.h
@@ -279,6 +279,7 @@ struct ocspResponseBytesStr {
* the C data structure here and in some shared code to operate on them.
*/
struct ocspBasicOCSPResponseStr {
+ SECItem tbsResponseDataDER;
ocspResponseData *tbsResponseData; /* "tbs" == To Be Signed */
ocspSignature responseSignature;
};