security/nss/lib/certhigh/ocspsig.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "plarena.h"
     7 #include "seccomon.h"
     8 #include "secitem.h"
     9 #include "secasn1.h"
    10 #include "secder.h"
    11 #include "cert.h"
    12 #include "secerr.h"
    13 #include "secoid.h"
    14 #include "sechash.h"
    15 #include "keyhi.h"
    16 #include "cryptohi.h"
    17 #include "ocsp.h"
    18 #include "ocspti.h"
    19 #include "ocspi.h"
    20 #include "pk11pub.h"
    23 extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[];
    24 extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[];
    25 extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[];
    27 ocspCertStatus*
    28 ocsp_CreateCertStatus(PLArenaPool *arena,
    29                       ocspCertStatusType status,
    30                       PRTime revocationTime)
    31 {
    32     ocspCertStatus *cs;
    34     if (!arena) {
    35         PORT_SetError(SEC_ERROR_INVALID_ARGS);
    36         return NULL;
    37     }
    39     switch (status) {
    40         case ocspCertStatus_good:
    41         case ocspCertStatus_unknown:
    42         case ocspCertStatus_revoked:
    43             break;
    44         default:
    45             PORT_SetError(SEC_ERROR_INVALID_ARGS);
    46             return NULL;
    47     }
    49     cs = PORT_ArenaZNew(arena, ocspCertStatus);
    50     if (!cs)
    51         return NULL;
    52     cs->certStatusType = status;
    53     switch (status) {
    54         case ocspCertStatus_good:
    55             cs->certStatusInfo.goodInfo = SECITEM_AllocItem(arena, NULL, 0);
    56             if (!cs->certStatusInfo.goodInfo)
    57                 return NULL;
    58             break;
    59         case ocspCertStatus_unknown:
    60             cs->certStatusInfo.unknownInfo = SECITEM_AllocItem(arena, NULL, 0);
    61             if (!cs->certStatusInfo.unknownInfo)
    62                 return NULL;
    63             break;
    64         case ocspCertStatus_revoked:
    65             cs->certStatusInfo.revokedInfo =
    66                 PORT_ArenaZNew(arena, ocspRevokedInfo);
    67             if (!cs->certStatusInfo.revokedInfo)
    68                 return NULL;
    69             cs->certStatusInfo.revokedInfo->revocationReason =
    70                 SECITEM_AllocItem(arena, NULL, 0);
    71             if (!cs->certStatusInfo.revokedInfo->revocationReason)
    72                 return NULL;
    73             if (DER_TimeToGeneralizedTimeArena(arena,
    74                     &cs->certStatusInfo.revokedInfo->revocationTime,
    75                     revocationTime) != SECSuccess)
    76                 return NULL;
    77             break;
    78         default:
    79             PORT_Assert(PR_FALSE);
    80     }
    81     return cs;
    82 }
    84 static const SEC_ASN1Template mySEC_EnumeratedTemplate[] = {
    85     { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) }
    86 };
    88 static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = {
    89     { SEC_ASN1_POINTER, 0, mySEC_EnumeratedTemplate }
    90 };
    92 static const SEC_ASN1Template ocsp_EncodeRevokedInfoTemplate[] = {
    93     { SEC_ASN1_GENERALIZED_TIME,
    94         offsetof(ocspRevokedInfo, revocationTime) },
    95     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
    96       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC| 0,
    97         offsetof(ocspRevokedInfo, revocationReason),
    98         mySEC_PointerToEnumeratedTemplate },
    99     { 0 }
   100 };
   102 static const SEC_ASN1Template ocsp_PointerToEncodeRevokedInfoTemplate[] = {
   103     { SEC_ASN1_POINTER, 0,
   104       ocsp_EncodeRevokedInfoTemplate }
   105 };
   107 static const SEC_ASN1Template mySEC_NullTemplate[] = {
   108     { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) }
   109 };
   111 static const SEC_ASN1Template ocsp_CertStatusTemplate[] = {
   112     { SEC_ASN1_CHOICE, offsetof(ocspCertStatus, certStatusType),
   113         0, sizeof(ocspCertStatus) },
   114     { SEC_ASN1_CONTEXT_SPECIFIC | 0,
   115         0, mySEC_NullTemplate, ocspCertStatus_good },
   116     { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
   117       SEC_ASN1_CONTEXT_SPECIFIC | 1,
   118         offsetof(ocspCertStatus, certStatusInfo.revokedInfo),
   119         ocsp_PointerToEncodeRevokedInfoTemplate, ocspCertStatus_revoked },
   120     { SEC_ASN1_CONTEXT_SPECIFIC | 2,
   121         0, mySEC_NullTemplate, ocspCertStatus_unknown },
   122     { 0 }
   123 };
   125 static const SEC_ASN1Template mySECOID_AlgorithmIDTemplate[] = {
   126     { SEC_ASN1_SEQUENCE,
   127           0, NULL, sizeof(SECAlgorithmID) },
   128     { SEC_ASN1_OBJECT_ID,
   129           offsetof(SECAlgorithmID,algorithm), },
   130     { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
   131           offsetof(SECAlgorithmID,parameters), },
   132     { 0, }
   133 };
   135 static const SEC_ASN1Template mySEC_AnyTemplate[] = {
   136     { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
   137 };
   139 static const SEC_ASN1Template mySEC_SequenceOfAnyTemplate[] = {
   140     { SEC_ASN1_SEQUENCE_OF, 0, mySEC_AnyTemplate }
   141 };
   143 static const SEC_ASN1Template mySEC_PointerToSequenceOfAnyTemplate[] = {
   144     { SEC_ASN1_POINTER, 0, mySEC_SequenceOfAnyTemplate }
   145 };
   147 static const SEC_ASN1Template mySEC_IntegerTemplate[] = {
   148     { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) }
   149 };
   151 static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = {
   152     { SEC_ASN1_POINTER, 0, mySEC_IntegerTemplate }
   153 };
   155 static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = {
   156     { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem)}
   157 };
   159 static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = {
   160     { SEC_ASN1_POINTER, 0, mySEC_GeneralizedTimeTemplate }
   161 };
   163 static const SEC_ASN1Template ocsp_myCertIDTemplate[] = {
   164     { SEC_ASN1_SEQUENCE,
   165         0, NULL, sizeof(CERTOCSPCertID) },
   166     { SEC_ASN1_INLINE,
   167         offsetof(CERTOCSPCertID, hashAlgorithm),
   168         mySECOID_AlgorithmIDTemplate },
   169     { SEC_ASN1_OCTET_STRING,
   170         offsetof(CERTOCSPCertID, issuerNameHash) },
   171     { SEC_ASN1_OCTET_STRING,
   172         offsetof(CERTOCSPCertID, issuerKeyHash) },
   173     { SEC_ASN1_INTEGER,
   174         offsetof(CERTOCSPCertID, serialNumber) },
   175     { 0 }
   176 };
   178 static const SEC_ASN1Template myCERT_CertExtensionTemplate[] = {
   179     { SEC_ASN1_SEQUENCE,
   180           0, NULL, sizeof(CERTCertExtension) },
   181     { SEC_ASN1_OBJECT_ID,
   182           offsetof(CERTCertExtension,id) },
   183     { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,             /* XXX DER_DEFAULT */
   184           offsetof(CERTCertExtension,critical) },
   185     { SEC_ASN1_OCTET_STRING,
   186           offsetof(CERTCertExtension,value) },
   187     { 0, }
   188 };
   190 static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = {
   191     { SEC_ASN1_SEQUENCE_OF, 0, myCERT_CertExtensionTemplate }
   192 };
   194 static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[] = {
   195     { SEC_ASN1_POINTER, 0, myCERT_SequenceOfCertExtensionTemplate }
   196 };
   198 static const SEC_ASN1Template ocsp_mySingleResponseTemplate[] = {
   199     { SEC_ASN1_SEQUENCE,
   200         0, NULL, sizeof(CERTOCSPSingleResponse) },
   201     { SEC_ASN1_POINTER,
   202         offsetof(CERTOCSPSingleResponse, certID),
   203         ocsp_myCertIDTemplate },
   204     { SEC_ASN1_ANY,
   205         offsetof(CERTOCSPSingleResponse, derCertStatus) },
   206     { SEC_ASN1_GENERALIZED_TIME,
   207         offsetof(CERTOCSPSingleResponse, thisUpdate) },
   208     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
   209       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
   210         offsetof(CERTOCSPSingleResponse, nextUpdate),
   211         mySEC_PointerToGeneralizedTimeTemplate },
   212     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
   213       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
   214         offsetof(CERTOCSPSingleResponse, singleExtensions),
   215         myCERT_PointerToSequenceOfCertExtensionTemplate },
   216     { 0 }
   217 };
   219 static const SEC_ASN1Template ocsp_myResponseDataTemplate[] = {
   220     { SEC_ASN1_SEQUENCE,
   221         0, NULL, sizeof(ocspResponseData) },
   222     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |           /* XXX DER_DEFAULT */
   223       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
   224         offsetof(ocspResponseData, version),
   225         mySEC_PointerToIntegerTemplate },
   226     { SEC_ASN1_ANY,
   227         offsetof(ocspResponseData, derResponderID) },
   228     { SEC_ASN1_GENERALIZED_TIME,
   229         offsetof(ocspResponseData, producedAt) },
   230     { SEC_ASN1_SEQUENCE_OF,
   231         offsetof(ocspResponseData, responses),
   232         ocsp_mySingleResponseTemplate },
   233     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
   234       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
   235         offsetof(ocspResponseData, responseExtensions),
   236         myCERT_PointerToSequenceOfCertExtensionTemplate },
   237     { 0 }
   238 };
   241 static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = {
   242     { SEC_ASN1_SEQUENCE,
   243         0, NULL, sizeof(ocspBasicOCSPResponse) },
   244     { SEC_ASN1_POINTER,
   245         offsetof(ocspBasicOCSPResponse, tbsResponseData),
   246         ocsp_myResponseDataTemplate },
   247     { SEC_ASN1_INLINE,
   248         offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm),
   249         mySECOID_AlgorithmIDTemplate },
   250     { SEC_ASN1_BIT_STRING,
   251         offsetof(ocspBasicOCSPResponse, responseSignature.signature) },
   252     { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT |
   253       SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
   254         offsetof(ocspBasicOCSPResponse, responseSignature.derCerts),
   255         mySEC_PointerToSequenceOfAnyTemplate },
   256     { 0 }
   257 };
   259 static CERTOCSPSingleResponse*
   260 ocsp_CreateSingleResponse(PLArenaPool *arena,
   261                           CERTOCSPCertID *id, ocspCertStatus *status,
   262                           PRTime thisUpdate, const PRTime *nextUpdate)
   263 {
   264     CERTOCSPSingleResponse *sr;
   266     if (!arena || !id || !status) {
   267         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   268         return NULL;
   269     }
   271     sr = PORT_ArenaZNew(arena, CERTOCSPSingleResponse);
   272     if (!sr)
   273         return NULL;
   274     sr->arena = arena;
   275     sr->certID = id;
   276     sr->certStatus = status;
   277     if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate)
   278              != SECSuccess)
   279         return NULL;
   280     sr->nextUpdate = NULL;
   281     if (nextUpdate) {
   282         sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0);
   283         if (!sr->nextUpdate)
   284             return NULL;
   285         if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate)
   286              != SECSuccess)
   287             return NULL;
   288     }
   290     sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension*, 1);
   291     if (!sr->singleExtensions)
   292         return NULL;
   294     sr->singleExtensions[0] = NULL;
   296     if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus,
   297                             status, ocsp_CertStatusTemplate))
   298         return NULL;
   300     return sr;
   301 }
   303 CERTOCSPSingleResponse*
   304 CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena,
   305                                   CERTOCSPCertID *id,
   306                                   PRTime thisUpdate,
   307                                   const PRTime *nextUpdate)
   308 {
   309     ocspCertStatus * cs;
   310     if (!arena) {
   311         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   312         return NULL;
   313     }
   314     cs = ocsp_CreateCertStatus(arena, ocspCertStatus_good, 0);
   315     if (!cs)
   316         return NULL;
   317     return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
   318 }
   320 CERTOCSPSingleResponse*
   321 CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena,
   322                                      CERTOCSPCertID *id,
   323                                      PRTime thisUpdate,
   324                                      const PRTime *nextUpdate)
   325 {
   326     ocspCertStatus * cs;
   327     if (!arena) {
   328         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   329         return NULL;
   330     }
   331     cs = ocsp_CreateCertStatus(arena, ocspCertStatus_unknown, 0);
   332     if (!cs)
   333         return NULL;
   334     return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
   335 }
   337 CERTOCSPSingleResponse*
   338 CERT_CreateOCSPSingleResponseRevoked(
   339     PLArenaPool *arena,
   340     CERTOCSPCertID *id,
   341     PRTime thisUpdate,
   342     const PRTime *nextUpdate,
   343     PRTime revocationTime,
   344     const CERTCRLEntryReasonCode* revocationReason)
   345 {
   346     ocspCertStatus * cs;
   347     /* revocationReason is not yet supported, so it must be NULL. */
   348     if (!arena || revocationReason) {
   349         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   350         return NULL;
   351     }
   352     cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime);
   353     if (!cs)
   354         return NULL;
   355     return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate);
   356 }
   358 /* responderCert == 0 means:
   359  * create a response with an invalid signature (for testing purposes) */
   360 SECItem*
   361 CERT_CreateEncodedOCSPSuccessResponse(
   362     PLArenaPool *arena,
   363     CERTCertificate *responderCert,
   364     CERTOCSPResponderIDType responderIDType,
   365     PRTime producedAt,
   366     CERTOCSPSingleResponse **responses,
   367     void *wincx)
   368 {
   369     PLArenaPool *tmpArena;
   370     ocspResponseData *rd = NULL;
   371     ocspResponderID *rid = NULL;
   372     const SEC_ASN1Template *responderIDTemplate = NULL;
   373     ocspBasicOCSPResponse *br = NULL;
   374     ocspResponseBytes *rb = NULL;
   375     CERTOCSPResponse *response = NULL;
   377     SECOidTag algID;
   378     SECOidData *od = NULL;
   379     SECKEYPrivateKey *privKey = NULL;
   380     SECItem *result = NULL;
   382     if (!arena || !responses) {
   383         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   384         return NULL;
   385     }
   386     if (responderIDType != ocspResponderID_byName &&
   387         responderIDType != ocspResponderID_byKey) {
   388         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   389         return NULL;
   390     }
   392     tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
   393     if (!tmpArena)
   394         return NULL;
   396     rd = PORT_ArenaZNew(tmpArena, ocspResponseData);
   397     if (!rd)
   398         goto done;
   399     rid = PORT_ArenaZNew(tmpArena, ocspResponderID);
   400     if (!rid)
   401         goto done;
   402     br = PORT_ArenaZNew(tmpArena, ocspBasicOCSPResponse);
   403     if (!br)
   404         goto done;
   405     rb = PORT_ArenaZNew(tmpArena, ocspResponseBytes);
   406     if (!rb)
   407         goto done;
   408     response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse);
   409     if (!response)
   410         goto done;
   412     rd->version.data=NULL;
   413     rd->version.len=0;
   414     rd->responseExtensions = NULL;
   415     rd->responses = responses;
   416     if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt)
   417             != SECSuccess)
   418         goto done;
   420     if (!responderCert) {
   421 	/* use invalid signature for testing purposes */
   422 	unsigned char dummyChar = 'd';
   423 	SECItem dummy;
   425 	dummy.len = 1;
   426 	dummy.data = &dummyChar;
   428 	/* it's easier to produdce a keyHash out of nowhere,
   429 	 * than to produce an encoded subject,
   430 	 * so for our dummy response we always use byKey
   431 	 */
   433 	rid->responderIDType = ocspResponderID_byKey;
   434 	if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash,
   435 			      &dummy))
   436 	    goto done;
   438 	if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
   439 				ocsp_ResponderIDByKeyTemplate))
   440 	    goto done;
   442 	br->tbsResponseData = rd;
   444 	if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
   445 				ocsp_myResponseDataTemplate))
   446 	    goto done;
   448 	br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
   449 	if (!br->responseSignature.derCerts)
   450 	    goto done;
   451 	br->responseSignature.derCerts[0] = NULL;
   453 	algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1);
   454 	if (algID == SEC_OID_UNKNOWN)
   455 	    goto done;
   457 	/* match the regular signature code, which doesn't use the arena */
   458 	if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1))
   459 	    goto done;
   460 	PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1);
   462 	/* convert len-in-bytes to len-in-bits */
   463 	br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
   464     }
   465     else {
   466 	rid->responderIDType = responderIDType;
   467 	if (responderIDType == ocspResponderID_byName) {
   468 	    responderIDTemplate = ocsp_ResponderIDByNameTemplate;
   469 	    if (CERT_CopyName(tmpArena, &rid->responderIDValue.name,
   470 			    &responderCert->subject) != SECSuccess)
   471 		goto done;
   472 	}
   473 	else {
   474 	    responderIDTemplate = ocsp_ResponderIDByKeyTemplate;
   475 	    if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert,
   476 				SEC_OID_SHA1, &rid->responderIDValue.keyHash))
   477 		goto done;
   478 	}
   480 	if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid,
   481 		responderIDTemplate))
   482 	    goto done;
   484 	br->tbsResponseData = rd;
   486 	if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData,
   487 		ocsp_myResponseDataTemplate))
   488 	    goto done;
   490 	br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1);
   491 	if (!br->responseSignature.derCerts)
   492 	    goto done;
   493 	br->responseSignature.derCerts[0] = NULL;
   495 	privKey = PK11_FindKeyByAnyCert(responderCert, wincx);
   496 	if (!privKey)
   497 	    goto done;
   499 	algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
   500 	if (algID == SEC_OID_UNKNOWN)
   501 	    goto done;
   503 	if (SEC_SignData(&br->responseSignature.signature,
   504 			    br->tbsResponseDataDER.data, br->tbsResponseDataDER.len,
   505 			    privKey, algID)
   506 		!= SECSuccess)
   507 	    goto done;
   509 	/* convert len-in-bytes to len-in-bits */
   510 	br->responseSignature.signature.len = br->responseSignature.signature.len << 3;
   512 	/* br->responseSignature.signature wasn't allocated from arena,
   513 	* we must free it when done. */
   514     }
   516     if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0)
   517 	    != SECSuccess)
   518 	goto done;
   520     if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br,
   521                             ocsp_EncodeBasicOCSPResponseTemplate))
   522         goto done;
   524     rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE;
   526     od = SECOID_FindOIDByTag(rb->responseTypeTag);
   527     if (!od)
   528         goto done;
   530     rb->responseType = od->oid;
   531     rb->decodedResponse.basic = br;
   533     response->arena = tmpArena;
   534     response->responseBytes = rb;
   535     response->statusValue = ocspResponse_successful;
   537     if (!SEC_ASN1EncodeInteger(tmpArena, &response->responseStatus,
   538                                response->statusValue))
   539         goto done;
   541     result = SEC_ASN1EncodeItem(arena, NULL, response, ocsp_OCSPResponseTemplate);
   543 done:
   544     if (privKey)
   545         SECKEY_DestroyPrivateKey(privKey);
   546     if (br->responseSignature.signature.data)
   547         SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE);
   548     PORT_FreeArena(tmpArena, PR_FALSE);
   550     return result;
   551 }
   553 static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = {
   554     { SEC_ASN1_SEQUENCE,
   555         0, NULL, sizeof(CERTOCSPResponse) },
   556     { SEC_ASN1_ENUMERATED,
   557         offsetof(CERTOCSPResponse, responseStatus) },
   558     { 0, 0,
   559         mySEC_NullTemplate },
   560     { 0 }
   561 };
   563 SECItem*
   564 CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error)
   565 {
   566     CERTOCSPResponse response;
   567     SECItem *result = NULL;
   569     switch (error) {
   570         case SEC_ERROR_OCSP_MALFORMED_REQUEST:
   571             response.statusValue = ocspResponse_malformedRequest;
   572             break;
   573         case SEC_ERROR_OCSP_SERVER_ERROR:
   574             response.statusValue = ocspResponse_internalError;
   575             break;
   576         case SEC_ERROR_OCSP_TRY_SERVER_LATER:
   577             response.statusValue = ocspResponse_tryLater;
   578             break;
   579         case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG:
   580             response.statusValue = ocspResponse_sigRequired;
   581             break;
   582         case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST:
   583             response.statusValue = ocspResponse_unauthorized;
   584             break;
   585         default:
   586             PORT_SetError(SEC_ERROR_INVALID_ARGS);
   587             return NULL;
   588     }
   590     if (!SEC_ASN1EncodeInteger(NULL, &response.responseStatus,
   591                                response.statusValue))
   592         return NULL;
   594     result = SEC_ASN1EncodeItem(arena, NULL, &response,
   595                                 ocsp_OCSPErrorResponseTemplate);
   597     SECITEM_FreeItem(&response.responseStatus, PR_FALSE);
   599     return result;
   600 }

mercurial