diff options
-rw-r--r-- | security/nss/cmd/ocspresp/ocspresp.c | 29 | ||||
-rw-r--r-- | security/nss/lib/certhigh/ocsp.c | 8 | ||||
-rw-r--r-- | security/nss/lib/certhigh/ocsp.h | 73 | ||||
-rw-r--r-- | security/nss/lib/certhigh/ocspsig.c | 80 | ||||
-rw-r--r-- | security/nss/lib/certhigh/ocspt.h | 20 | ||||
-rw-r--r-- | security/nss/lib/certhigh/ocspti.h | 26 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.def | 10 |
7 files changed, 143 insertions, 103 deletions
diff --git a/security/nss/cmd/ocspresp/ocspresp.c b/security/nss/cmd/ocspresp/ocspresp.c index bda42c2cc..22c66bb88 100644 --- a/security/nss/cmd/ocspresp/ocspresp.c +++ b/security/nss/cmd/ocspresp/ocspresp.c @@ -36,8 +36,7 @@ getCaAndSubjectCert(CERTCertDBHandle *certHandle, } static SECItem * -encode(PRArenaPool *arena, CERTOCSPCertID *cid, - CERTCertificate *ca, CERTCertificate *cert) +encode(PRArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) { SECItem *response; PRTime now = PR_Now(); @@ -50,7 +49,7 @@ encode(PRArenaPool *arena, CERTOCSPCertID *cid, nextUpdate = now + 10 * PR_USEC_PER_SEC; /* in the future */ - sr = OCSP_CreateSingleResponseGood(arena, cid, now, &nextUpdate); + sr = CERT_CreateOCSPSingleResponseGood(arena, cid, now, &nextUpdate); /* meaning of value 2: one entry + one end marker */ responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2); @@ -60,15 +59,14 @@ encode(PRArenaPool *arena, CERTOCSPCertID *cid, responses[0] = sr; responses[1] = NULL; - response = OCSP_CreateSuccessResponseEncodedBasicV1( - arena, ca, PR_TRUE, now, responses, &pwdata); + response = CERT_CreateEncodedOCSPSuccessResponse( + arena, ca, ocspResponderID_byName, now, responses, &pwdata); return response; } static SECItem * -encodeRevoked(PRArenaPool *arena, CERTOCSPCertID *cid, - CERTCertificate *ca, CERTCertificate *cert) +encodeRevoked(PRArenaPool *arena, CERTOCSPCertID *cid, CERTCertificate *ca) { SECItem *response; PRTime now = PR_Now(); @@ -81,8 +79,8 @@ encodeRevoked(PRArenaPool *arena, CERTOCSPCertID *cid, revocationTime = now - 10 * PR_USEC_PER_SEC; /* in the past */ - sr = OCSP_CreateSingleResponseRevoked(arena, cid, now, NULL, - revocationTime); + sr = CERT_CreateOCSPSingleResponseRevoked(arena, cid, now, NULL, + revocationTime, NULL); /* meaning of value 2: one entry + one end marker */ responses = PORT_ArenaNewArray(arena, CERTOCSPSingleResponse*, 2); @@ -92,13 +90,13 @@ encodeRevoked(PRArenaPool *arena, CERTOCSPCertID *cid, responses[0] = sr; responses[1] = NULL; - response = OCSP_CreateSuccessResponseEncodedBasicV1( - arena, ca, PR_TRUE, now, responses, &pwdata); + response = CERT_CreateEncodedOCSPSuccessResponse( + arena, ca, ocspResponderID_byName, now, responses, &pwdata); return response; } -int Usage() +int Usage(void) { PRFileDesc *pr_stderr = PR_STDERR; PR_fprintf (pr_stderr, "ocspresp runs an internal selftest for OCSP response creation"); @@ -180,7 +178,7 @@ main(int argc, char **argv) cid = CERT_CreateOCSPCertID(cert, now); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - encoded = encode(arena, cid, caCert, cert); + encoded = encode(arena, cid, caCert); PORT_Assert(encoded); decoded = CERT_DecodeOCSPResponse(encoded); statusDecoded = CERT_GetOCSPResponseStatus(decoded); @@ -194,7 +192,7 @@ main(int argc, char **argv) PORT_Assert(statusDecoded == SECSuccess); CERT_DestroyCertificate(obtainedSignerCert); - encodedRev = encodeRevoked(arena, cid, caCert, cert); + encodedRev = encodeRevoked(arena, cid, caCert); PORT_Assert(encodedRev); decodedRev = CERT_DecodeOCSPResponse(encodedRev); statusDecodedRev = CERT_GetOCSPResponseStatus(decodedRev); @@ -209,7 +207,8 @@ main(int argc, char **argv) PORT_Assert(PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE); CERT_DestroyCertificate(obtainedSignerCert); - encodedFail = OCSP_CreateFailureResponse(arena, SEC_ERROR_OCSP_TRY_SERVER_LATER); + encodedFail = CERT_CreateEncodedOCSPErrorResponse( + arena, SEC_ERROR_OCSP_TRY_SERVER_LATER); PORT_Assert(encodedFail); decodedFail = CERT_DecodeOCSPResponse(encodedFail); statusDecodedFail = CERT_GetOCSPResponseStatus(decodedFail); diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 9f23168ec..cc4d3e125 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -2226,7 +2226,7 @@ CERT_DestroyOCSPRequest(CERTOCSPRequest *request) * given type, return the associated template for that choice. */ static const SEC_ASN1Template * -ocsp_ResponderIDTemplateByType(ocspResponderIDType responderIDType) +ocsp_ResponderIDTemplateByType(CERTOCSPResponderIDType responderIDType) { const SEC_ASN1Template *responderIDTemplate; @@ -2371,10 +2371,10 @@ loser: * Helper function for decoding a responderID -- turn the actual DER tag * into our local translation. */ -static ocspResponderIDType +static CERTOCSPResponderIDType ocsp_ResponderIDTypeByTag(int derTag) { - ocspResponderIDType responderIDType; + CERTOCSPResponderIDType responderIDType; switch (derTag) { case 1: @@ -2401,7 +2401,7 @@ ocsp_DecodeBasicOCSPResponse(PRArenaPool *arena, SECItem *src) ocspBasicOCSPResponse *basicResponse; ocspResponseData *responseData; ocspResponderID *responderID; - ocspResponderIDType responderIDType; + CERTOCSPResponderIDType responderIDType; const SEC_ASN1Template *responderIDTemplate; int derTag; SECStatus rv; diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h index 78231fc35..1493d83f4 100644 --- a/security/nss/lib/certhigh/ocsp.h +++ b/security/nss/lib/certhigh/ocsp.h @@ -18,7 +18,6 @@ #include "keyt.h" #include "certt.h" #include "ocspt.h" -#include "prerror.h" /************************************************************************/ @@ -636,31 +635,69 @@ CERT_DestroyOCSPCertID(CERTOCSPCertID* certID); extern CERTOCSPSingleResponse* -OCSP_CreateSingleResponseGood(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate); +CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate); extern CERTOCSPSingleResponse* -OCSP_CreateSingleResponseUnknown(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate); +CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate); extern CERTOCSPSingleResponse* -OCSP_CreateSingleResponseRevoked(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate, - PRTime revocationTime); +CERT_CreateOCSPSingleResponseRevoked( + PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate, + PRTime revocationTime, + const CERTCRLEntryReasonCode* revocationReason); extern SECItem* -OCSP_CreateSuccessResponseEncodedBasicV1(PLArenaPool *arena, - CERTCertificate *responderCert, - PRBool idByName, /* false: by key */ - PRTime producedAt, - CERTOCSPSingleResponse **responses, - void *wincx); +CERT_CreateEncodedOCSPSuccessResponse( + PLArenaPool *arena, + CERTCertificate *responderCert, + CERTOCSPResponderIDType responderIDType, + PRTime producedAt, + CERTOCSPSingleResponse **responses, + void *wincx); +/* + * FUNCTION: CERT_CreateEncodedOCSPErrorResponse + * Creates an encoded OCSP response with an error response status. + * INPUTS: + * PLArenaPool *arena + * The return value is allocated from here. + * If a NULL is passed in, allocation is done from the heap instead. + * int error + * An NSS error code indicating an error response status. The error + * code is mapped to an OCSP response status as follows: + * SEC_ERROR_OCSP_MALFORMED_REQUEST -> malformedRequest + * SEC_ERROR_OCSP_SERVER_ERROR -> internalError + * SEC_ERROR_OCSP_TRY_SERVER_LATER -> tryLater + * SEC_ERROR_OCSP_REQUEST_NEEDS_SIG -> sigRequired + * SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST -> unauthorized + * where the OCSP response status is an enumerated type defined in + * RFC 2560: + * OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + * RETURN: + * Returns a pointer to the SECItem holding the response. + * On error, returns null with error set describing the reason: + * SEC_ERROR_INVALID_ARGS + * Other errors are low-level problems (no memory, bad database, etc.). + */ extern SECItem* -OCSP_CreateFailureResponse(PLArenaPool *arena, PRErrorCode reason); +CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error); /************************************************************************/ SEC_END_PROTOS diff --git a/security/nss/lib/certhigh/ocspsig.c b/security/nss/lib/certhigh/ocspsig.c index 262161a0f..99298ffa4 100644 --- a/security/nss/lib/certhigh/ocspsig.c +++ b/security/nss/lib/certhigh/ocspsig.c @@ -2,33 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "prerror.h" -#include "prprf.h" #include "plarena.h" -#include "prnetdb.h" #include "seccomon.h" #include "secitem.h" -#include "secoidt.h" #include "secasn1.h" #include "secder.h" #include "cert.h" -#include "xconst.h" #include "secerr.h" #include "secoid.h" -#include "hasht.h" #include "sechash.h" -#include "secasn1.h" #include "keyhi.h" #include "cryptohi.h" #include "ocsp.h" #include "ocspti.h" #include "ocspi.h" -#include "genname.h" -#include "certxutl.h" -#include "pk11func.h" /* for PK11_HashBuf */ -#include <stdarg.h> -#include <plhash.h> +#include "pk11pub.h" extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[]; @@ -270,7 +259,7 @@ static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = { static CERTOCSPSingleResponse* ocsp_CreateSingleResponse(PLArenaPool *arena, CERTOCSPCertID *id, ocspCertStatus *status, - PRTime thisUpdate, PRTime *nextUpdate) + PRTime thisUpdate, const PRTime *nextUpdate) { CERTOCSPSingleResponse *sr; @@ -312,9 +301,10 @@ ocsp_CreateSingleResponse(PLArenaPool *arena, } CERTOCSPSingleResponse* -OCSP_CreateSingleResponseGood(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate) +CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate) { ocspCertStatus * cs; if (!arena) { @@ -328,9 +318,10 @@ OCSP_CreateSingleResponseGood(PLArenaPool *arena, } CERTOCSPSingleResponse* -OCSP_CreateSingleResponseUnknown(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate) +CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate) { ocspCertStatus * cs; if (!arena) { @@ -344,13 +335,17 @@ OCSP_CreateSingleResponseUnknown(PLArenaPool *arena, } CERTOCSPSingleResponse* -OCSP_CreateSingleResponseRevoked(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, PRTime *nextUpdate, - PRTime revocationTime) +CERT_CreateOCSPSingleResponseRevoked( + PLArenaPool *arena, + CERTOCSPCertID *id, + PRTime thisUpdate, + const PRTime *nextUpdate, + PRTime revocationTime, + const CERTCRLEntryReasonCode* revocationReason) { ocspCertStatus * cs; - if (!arena) { + /* revocationReason is not yet supported, so it must be NULL. */ + if (!arena || revocationReason) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -361,16 +356,18 @@ OCSP_CreateSingleResponseRevoked(PLArenaPool *arena, } SECItem* -OCSP_CreateSuccessResponseEncodedBasicV1(PLArenaPool *arena, - CERTCertificate *responderCert, - PRBool idByName, /* false: by key */ - PRTime producedAt, - CERTOCSPSingleResponse **responses, - void *wincx) +CERT_CreateEncodedOCSPSuccessResponse( + PLArenaPool *arena, + CERTCertificate *responderCert, + CERTOCSPResponderIDType responderIDType, + PRTime producedAt, + CERTOCSPSingleResponse **responses, + void *wincx) { PLArenaPool *tmpArena; ocspResponseData *rd = NULL; ocspResponderID *rid = NULL; + const SEC_ASN1Template *responderIDTemplate = NULL; ocspBasicOCSPResponse *br = NULL; ocspResponseBytes *rb = NULL; CERTOCSPResponse *response = NULL; @@ -384,6 +381,11 @@ OCSP_CreateSuccessResponseEncodedBasicV1(PLArenaPool *arena, PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } + if (responderIDType != ocspResponderID_byName && + responderIDType != ocspResponderID_byKey) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!tmpArena) @@ -412,21 +414,22 @@ OCSP_CreateSuccessResponseEncodedBasicV1(PLArenaPool *arena, if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) != SECSuccess) goto done; - if (idByName) { - rid->responderIDType = ocspResponderID_byName; + rid->responderIDType = responderIDType; + if (responderIDType == ocspResponderID_byName) { + responderIDTemplate = ocsp_ResponderIDByNameTemplate; if (CERT_CopyName(tmpArena, &rid->responderIDValue.name, &responderCert->subject) != SECSuccess) goto done; } else { - rid->responderIDType = ocspResponderID_byKey; + responderIDTemplate = ocsp_ResponderIDByKeyTemplate; if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1, &rid->responderIDValue.keyHash)) goto done; } if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, - idByName ? ocsp_ResponderIDByNameTemplate : ocsp_ResponderIDByKeyTemplate)) + responderIDTemplate)) goto done; br->tbsResponseData = rd; @@ -497,7 +500,7 @@ done: return result; } -static const SEC_ASN1Template ocsp_OCSPFailureResponseTemplate[] = { +static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTOCSPResponse) }, { SEC_ASN1_ENUMERATED, @@ -508,12 +511,12 @@ static const SEC_ASN1Template ocsp_OCSPFailureResponseTemplate[] = { }; SECItem* -OCSP_CreateFailureResponse(PLArenaPool *arena, PRErrorCode reason) +CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error) { CERTOCSPResponse response; SECItem *result = NULL; - switch (reason) { + switch (error) { case SEC_ERROR_OCSP_MALFORMED_REQUEST: response.statusValue = ocspResponse_malformedRequest; break; @@ -538,7 +541,8 @@ OCSP_CreateFailureResponse(PLArenaPool *arena, PRErrorCode reason) response.statusValue)) return NULL; - result = SEC_ASN1EncodeItem(arena, NULL, &response, ocsp_OCSPFailureResponseTemplate); + result = SEC_ASN1EncodeItem(arena, NULL, &response, + ocsp_OCSPErrorResponseTemplate); SECITEM_FreeItem(&response.responseStatus, PR_FALSE); diff --git a/security/nss/lib/certhigh/ocspt.h b/security/nss/lib/certhigh/ocspt.h index 58da13a85..7992861c8 100644 --- a/security/nss/lib/certhigh/ocspt.h +++ b/security/nss/lib/certhigh/ocspt.h @@ -280,4 +280,24 @@ typedef enum { ocspMode_FailureIsNotAVerificationFailure = 1 } SEC_OcspFailureMode; +/* + * A ResponderID identifies the responder -- or more correctly, the + * signer of the response. The ASN.1 definition of a ResponderID is: + * + * ResponderID ::= CHOICE { + * byName [1] EXPLICIT Name, + * byKey [2] EXPLICIT KeyHash } + * + * Because it is CHOICE, the type of identification used and the + * identification itself are actually encoded together. To represent + * this same information internally, we explicitly define a type and + * save it, along with the value, into a data structure. + */ + +typedef enum { + ocspResponderID_other = -1, /* unknown kind of responderID */ + ocspResponderID_byName = 1, + ocspResponderID_byKey = 2 +} CERTOCSPResponderIDType; + #endif /* _OCSPT_H_ */ diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h index c629a98fd..2d7a96709 100644 --- a/security/nss/lib/certhigh/ocspti.h +++ b/security/nss/lib/certhigh/ocspti.h @@ -189,14 +189,14 @@ struct CERTOCSPCertIDStr { * } */ typedef enum { + ocspResponse_other = -1, /* unknown/unrecognized value */ ocspResponse_successful = 0, ocspResponse_malformedRequest = 1, ocspResponse_internalError = 2, ocspResponse_tryLater = 3, ocspResponse_unused = 4, ocspResponse_sigRequired = 5, - ocspResponse_unauthorized = 6, - ocspResponse_other /* unknown/unrecognized value */ + ocspResponse_unauthorized = 6 } ocspResponseStatus; /* @@ -266,28 +266,8 @@ struct ocspResponseDataStr { CERTCertExtension **responseExtensions; }; -/* - * A ResponderID identifies the responder -- or more correctly, the - * signer of the response. The ASN.1 definition of a ResponderID is: - * - * ResponderID ::= CHOICE { - * byName [1] EXPLICIT Name, - * byKey [2] EXPLICIT KeyHash } - * - * Because it is CHOICE, the type of identification used and the - * identification itself are actually encoded together. To represent - * this same information internally, we explicitly define a type and - * save it, along with the value, into a data structure. - */ - -typedef enum { - ocspResponderID_byName, - ocspResponderID_byKey, - ocspResponderID_other /* unknown kind of responderID */ -} ocspResponderIDType; - struct ocspResponderIDStr { - ocspResponderIDType responderIDType;/* local; not part of encoding */ + CERTOCSPResponderIDType responderIDType;/* local; not part of encoding */ union { CERTName name; /* when ocspResponderID_byName */ SECItem keyHash; /* when ocspResponderID_byKey */ diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index aabf022ec..aecd92870 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -1013,11 +1013,11 @@ PK11_PQG_ParamGenV2; ;+}; ;+NSS_3.14.1 { # NSS 3.14.1 release ;+ global: -OCSP_CreateFailureResponse; -OCSP_CreateSingleResponseGood; -OCSP_CreateSingleResponseUnknown; -OCSP_CreateSingleResponseRevoked; -OCSP_CreateSuccessResponseEncodedBasicV1; +CERT_CreateEncodedOCSPErrorResponse; +CERT_CreateEncodedOCSPSuccessResponse; +CERT_CreateOCSPSingleResponseGood; +CERT_CreateOCSPSingleResponseUnknown; +CERT_CreateOCSPSingleResponseRevoked; ;+ local: ;+ *; ;+}; |