diff options
Diffstat (limited to 'security/nss/lib/certhigh/ocspsig.c')
-rw-r--r-- | security/nss/lib/certhigh/ocspsig.c | 600 |
1 files changed, 0 insertions, 600 deletions
diff --git a/security/nss/lib/certhigh/ocspsig.c b/security/nss/lib/certhigh/ocspsig.c deleted file mode 100644 index 775c12411..000000000 --- a/security/nss/lib/certhigh/ocspsig.c +++ /dev/null @@ -1,600 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * 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 "plarena.h" - -#include "seccomon.h" -#include "secitem.h" -#include "secasn1.h" -#include "secder.h" -#include "cert.h" -#include "secerr.h" -#include "secoid.h" -#include "sechash.h" -#include "keyhi.h" -#include "cryptohi.h" -#include "ocsp.h" -#include "ocspti.h" -#include "ocspi.h" -#include "pk11pub.h" - - -extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[]; -extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[]; -extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[]; - -ocspCertStatus* -ocsp_CreateCertStatus(PLArenaPool *arena, - ocspCertStatusType status, - PRTime revocationTime) -{ - ocspCertStatus *cs; - - if (!arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - switch (status) { - case ocspCertStatus_good: - case ocspCertStatus_unknown: - case ocspCertStatus_revoked: - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - cs = PORT_ArenaZNew(arena, ocspCertStatus); - if (!cs) - return NULL; - cs->certStatusType = status; - switch (status) { - case ocspCertStatus_good: - cs->certStatusInfo.goodInfo = SECITEM_AllocItem(arena, NULL, 0); - if (!cs->certStatusInfo.goodInfo) - return NULL; - break; - case ocspCertStatus_unknown: - cs->certStatusInfo.unknownInfo = SECITEM_AllocItem(arena, NULL, 0); - if (!cs->certStatusInfo.unknownInfo) - return NULL; - break; - case ocspCertStatus_revoked: - cs->certStatusInfo.revokedInfo = - PORT_ArenaZNew(arena, ocspRevokedInfo); - if (!cs->certStatusInfo.revokedInfo) - return NULL; - cs->certStatusInfo.revokedInfo->revocationReason = - SECITEM_AllocItem(arena, NULL, 0); - if (!cs->certStatusInfo.revokedInfo->revocationReason) - return NULL; - if (DER_TimeToGeneralizedTimeArena(arena, - &cs->certStatusInfo.revokedInfo->revocationTime, - revocationTime) != SECSuccess) - return NULL; - break; - default: - PORT_Assert(PR_FALSE); - } - return cs; -} - -static const SEC_ASN1Template mySEC_EnumeratedTemplate[] = { - { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) } -}; - -static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = { - { SEC_ASN1_POINTER, 0, mySEC_EnumeratedTemplate } -}; - -static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = { - { SEC_ASN1_GENERALIZED_TIME, - offsetof(ocspRevokedInfo, revocationTime) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0, - offsetof(ocspRevokedInfo, revocationReason), - mySEC_PointerToEnumeratedTemplate }, - { 0 } -}; - -static const SEC_ASN1Template ocsp_PointerToEncodeRevokedInfoTemplate[] = { - { SEC_ASN1_POINTER, 0, - ocsp_EncodeRevokedInfoTemplate } -}; - -static const SEC_ASN1Template mySEC_NullTemplate[] = { - { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) } -}; - -static const SEC_ASN1Template ocsp_CertStatusTemplate[] = { - { SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType), - 0, sizeof(ocspCertStatus) }, - { SEC_ASN1_CONTEXT_SPECIFIC | 0, - 0, mySEC_NullTemplate, ocspCertStatus_good }, - { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | - SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspCertStatus, certStatusInfo.revokedInfo), - ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked }, - { SEC_ASN1_CONTEXT_SPECIFIC | 2, - 0, mySEC_NullTemplate, ocspCertStatus_unknown }, - { 0 } -}; - -static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SECAlgorithmID) }, - { SEC_ASN1_OBJECT_ID, - offsetof(SECAlgorithmID,algorithm), }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(SECAlgorithmID,parameters), }, - { 0, } -}; - -static const SEC_ASN1Template mySEC_AnyTemplate[] = { - { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) } -}; - -static const SEC_ASN1Template mySEC_SequenceOfAnyTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, mySEC_AnyTemplate } -}; - -static const SEC_ASN1Template mySEC_PointerToSequenceOfAnyTemplate[] = { - { SEC_ASN1_POINTER, 0, mySEC_SequenceOfAnyTemplate } -}; - -static const SEC_ASN1Template mySEC_IntegerTemplate[] = { - { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) } -}; - -static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = { - { SEC_ASN1_POINTER, 0, mySEC_IntegerTemplate } -}; - -static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = { - { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)} -}; - -static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = { - { SEC_ASN1_POINTER, 0, mySEC_GeneralizedTimeTemplate } -}; - -static const SEC_ASN1Template ocsp_myCertIDTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPCertID) }, - { SEC_ASN1_INLINE, - offsetof(CERTOCSPCertID, hashAlgorithm), - mySECOID_AlgorithmIDTemplate }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTOCSPCertID, issuerNameHash) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTOCSPCertID, issuerKeyHash) }, - { SEC_ASN1_INTEGER, - offsetof(CERTOCSPCertID, serialNumber) }, - { 0 } -}; - -static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTCertExtension) }, - { SEC_ASN1_OBJECT_ID, - offsetof(CERTCertExtension,id) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN, /* XXX DER_DEFAULT */ - offsetof(CERTCertExtension,critical) }, - { SEC_ASN1_OCTET_STRING, - offsetof(CERTCertExtension,value) }, - { 0, } -}; - -static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = { - { SEC_ASN1_SEQUENCE_OF, 0, myCERT_CertExtensionTemplate } -}; - -static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[] = { - { SEC_ASN1_POINTER, 0, myCERT_SequenceOfCertExtensionTemplate } -}; - -static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPSingleResponse) }, - { SEC_ASN1_POINTER, - offsetof(CERTOCSPSingleResponse, certID), - ocsp_myCertIDTemplate }, - { SEC_ASN1_ANY, - offsetof(CERTOCSPSingleResponse, derCertStatus) }, - { SEC_ASN1_GENERALIZED_TIME, - offsetof(CERTOCSPSingleResponse, thisUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(CERTOCSPSingleResponse, nextUpdate), - mySEC_PointerToGeneralizedTimeTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(CERTOCSPSingleResponse, singleExtensions), - myCERT_PointerToSequenceOfCertExtensionTemplate }, - { 0 } -}; - -static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspResponseData) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspResponseData, version), - mySEC_PointerToIntegerTemplate }, - { SEC_ASN1_ANY, - offsetof(ocspResponseData, derResponderID) }, - { SEC_ASN1_GENERALIZED_TIME, - offsetof(ocspResponseData, producedAt) }, - { SEC_ASN1_SEQUENCE_OF, - offsetof(ocspResponseData, responses), - ocsp_mySingleResponseTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, - offsetof(ocspResponseData, responseExtensions), - myCERT_PointerToSequenceOfCertExtensionTemplate }, - { 0 } -}; - - -static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ocspBasicOCSPResponse) }, - { SEC_ASN1_POINTER, - offsetof(ocspBasicOCSPResponse, tbsResponseData), - ocsp_myResponseDataTemplate }, - { SEC_ASN1_INLINE, - offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), - mySECOID_AlgorithmIDTemplate }, - { SEC_ASN1_BIT_STRING, - offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | - SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), - mySEC_PointerToSequenceOfAnyTemplate }, - { 0 } -}; - -static CERTOCSPSingleResponse* -ocsp_CreateSingleResponse(PLArenaPool *arena, - CERTOCSPCertID *id, ocspCertStatus *status, - PRTime thisUpdate, const PRTime *nextUpdate) -{ - CERTOCSPSingleResponse *sr; - - if (!arena || !id || !status) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - sr = PORT_ArenaZNew(arena, CERTOCSPSingleResponse); - if (!sr) - return NULL; - sr->arena = arena; - sr->certID = id; - sr->certStatus = status; - if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) - != SECSuccess) - return NULL; - sr->nextUpdate = NULL; - if (nextUpdate) { - sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0); - if (!sr->nextUpdate) - return NULL; - if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) - != SECSuccess) - return NULL; - } - - sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1); - if (!sr->singleExtensions) - return NULL; - - sr->singleExtensions[0] = NULL; - - if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus, - status, ocsp_CertStatusTemplate)) - return NULL; - - return sr; -} - -CERTOCSPSingleResponse* -CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, - const PRTime *nextUpdate) -{ - ocspCertStatus * cs; - if (!arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - cs = ocsp_CreateCertStatus(arena, ocspCertStatus_good, 0); - if (!cs) - return NULL; - return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); -} - -CERTOCSPSingleResponse* -CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, - const PRTime *nextUpdate) -{ - ocspCertStatus * cs; - if (!arena) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - cs = ocsp_CreateCertStatus(arena, ocspCertStatus_unknown, 0); - if (!cs) - return NULL; - return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); -} - -CERTOCSPSingleResponse* -CERT_CreateOCSPSingleResponseRevoked( - PLArenaPool *arena, - CERTOCSPCertID *id, - PRTime thisUpdate, - const PRTime *nextUpdate, - PRTime revocationTime, - const CERTCRLEntryReasonCode* revocationReason) -{ - ocspCertStatus * cs; - /* revocationReason is not yet supported, so it must be NULL. */ - if (!arena || revocationReason) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime); - if (!cs) - return NULL; - return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); -} - -/* responderCert == 0 means: - * create a response with an invalid signature (for testing purposes) */ -SECItem* -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; - - SECOidTag algID; - SECOidData *od = NULL; - SECKEYPrivateKey *privKey = NULL; - SECItem *result = NULL; - - if (!arena || !responses) { - 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) - return NULL; - - rd = PORT_ArenaZNew(tmpArena, ocspResponseData); - if (!rd) - goto done; - rid = PORT_ArenaZNew(tmpArena, ocspResponderID); - if (!rid) - goto done; - br = PORT_ArenaZNew(tmpArena, ocspBasicOCSPResponse); - if (!br) - goto done; - rb = PORT_ArenaZNew(tmpArena, ocspResponseBytes); - if (!rb) - goto done; - response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse); - if (!response) - goto done; - - rd->version.data=NULL; - rd->version.len=0; - rd->responseExtensions = NULL; - rd->responses = responses; - if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) - != SECSuccess) - goto done; - - if (!responderCert) { - /* use invalid signature for testing purposes */ - char dummyChar = 'd'; - SECItem dummy; - - dummy.len = 1; - dummy.data = &dummyChar; - - /* it's easier to produdce a keyHash out of nowhere, - * than to produce an encoded subject, - * so for our dummy response we always use byKey - */ - - rid->responderIDType = ocspResponderID_byKey; - if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash, - &dummy)) - goto done; - - if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, - ocsp_ResponderIDByKeyTemplate)) - goto done; - - br->tbsResponseData = rd; - - if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, - ocsp_myResponseDataTemplate)) - goto done; - - br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1); - if (!br->responseSignature.derCerts) - goto done; - br->responseSignature.derCerts[0] = NULL; - - algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1); - if (algID == SEC_OID_UNKNOWN) - goto done; - - /* match the regular signature code, which doesn't use the arena */ - if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1)) - goto done; - PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1); - - /* convert len-in-bytes to len-in-bits */ - br->responseSignature.signature.len = br->responseSignature.signature.len << 3; - } - else { - rid->responderIDType = responderIDType; - if (responderIDType == ocspResponderID_byName) { - responderIDTemplate = ocsp_ResponderIDByNameTemplate; - if (CERT_CopyName(tmpArena, &rid->responderIDValue.name, - &responderCert->subject) != SECSuccess) - goto done; - } - else { - responderIDTemplate = ocsp_ResponderIDByKeyTemplate; - if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1, - &rid->responderIDValue.keyHash)) - goto done; - } - - if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, - responderIDTemplate)) - goto done; - - br->tbsResponseData = rd; - - if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, - ocsp_myResponseDataTemplate)) - goto done; - - br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1); - if (!br->responseSignature.derCerts) - goto done; - br->responseSignature.derCerts[0] = NULL; - - privKey = PK11_FindKeyByAnyCert(responderCert, wincx); - if (!privKey) - goto done; - - algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1); - if (algID == SEC_OID_UNKNOWN) - goto done; - - if (SEC_SignData(&br->responseSignature.signature, - br->tbsResponseDataDER.data, br->tbsResponseDataDER.len, - privKey, algID) - != SECSuccess) - goto done; - - /* convert len-in-bytes to len-in-bits */ - br->responseSignature.signature.len = br->responseSignature.signature.len << 3; - - /* br->responseSignature.signature wasn't allocated from arena, - * we must free it when done. */ - } - - if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) - != SECSuccess) - goto done; - - if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br, - ocsp_EncodeBasicOCSPResponseTemplate)) - goto done; - - rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE; - - od = SECOID_FindOIDByTag(rb->responseTypeTag); - if (!od) - goto done; - - rb->responseType = od->oid; - rb->decodedResponse.basic = br; - - response->arena = tmpArena; - response->responseBytes = rb; - response->statusValue = ocspResponse_successful; - - if (!SEC_ASN1EncodeInteger(tmpArena, &response->responseStatus, - response->statusValue)) - goto done; - - result = SEC_ASN1EncodeItem(arena, NULL, response, ocsp_OCSPResponseTemplate); - -done: - if (privKey) - SECKEY_DestroyPrivateKey(privKey); - if (br->responseSignature.signature.data) - SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE); - PORT_FreeArena(tmpArena, PR_FALSE); - - return result; -} - -static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = { - { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(CERTOCSPResponse) }, - { SEC_ASN1_ENUMERATED, - offsetof(CERTOCSPResponse, responseStatus) }, - { 0, 0, - mySEC_NullTemplate }, - { 0 } -}; - -SECItem* -CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error) -{ - CERTOCSPResponse response; - SECItem *result = NULL; - - switch (error) { - case SEC_ERROR_OCSP_MALFORMED_REQUEST: - response.statusValue = ocspResponse_malformedRequest; - break; - case SEC_ERROR_OCSP_SERVER_ERROR: - response.statusValue = ocspResponse_internalError; - break; - case SEC_ERROR_OCSP_TRY_SERVER_LATER: - response.statusValue = ocspResponse_tryLater; - break; - case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG: - response.statusValue = ocspResponse_sigRequired; - break; - case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST: - response.statusValue = ocspResponse_unauthorized; - break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return NULL; - } - - if (!SEC_ASN1EncodeInteger(NULL, &response.responseStatus, - response.statusValue)) - return NULL; - - result = SEC_ASN1EncodeItem(arena, NULL, &response, - ocsp_OCSPErrorResponseTemplate); - - SECITEM_FreeItem(&response.responseStatus, PR_FALSE); - - return result; -} |