ocspsig.c (19840B)
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/. */ 4 5 #include "plarena.h" 6 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" 21 22 extern const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[]; 23 extern const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[]; 24 extern const SEC_ASN1Template ocsp_OCSPResponseTemplate[]; 25 26 ocspCertStatus * 27 ocsp_CreateCertStatus(PLArenaPool *arena, 28 ocspCertStatusType status, 29 PRTime revocationTime) 30 { 31 ocspCertStatus *cs; 32 33 if (!arena) { 34 PORT_SetError(SEC_ERROR_INVALID_ARGS); 35 return NULL; 36 } 37 38 switch (status) { 39 case ocspCertStatus_good: 40 case ocspCertStatus_unknown: 41 case ocspCertStatus_revoked: 42 break; 43 default: 44 PORT_SetError(SEC_ERROR_INVALID_ARGS); 45 return NULL; 46 } 47 48 cs = PORT_ArenaZNew(arena, ocspCertStatus); 49 if (!cs) 50 return NULL; 51 cs->certStatusType = status; 52 switch (status) { 53 case ocspCertStatus_good: 54 cs->certStatusInfo.goodInfo = SECITEM_AllocItem(arena, NULL, 0); 55 if (!cs->certStatusInfo.goodInfo) 56 return NULL; 57 break; 58 case ocspCertStatus_unknown: 59 cs->certStatusInfo.unknownInfo = SECITEM_AllocItem(arena, NULL, 0); 60 if (!cs->certStatusInfo.unknownInfo) 61 return NULL; 62 break; 63 case ocspCertStatus_revoked: 64 cs->certStatusInfo.revokedInfo = 65 PORT_ArenaZNew(arena, ocspRevokedInfo); 66 if (!cs->certStatusInfo.revokedInfo) 67 return NULL; 68 cs->certStatusInfo.revokedInfo->revocationReason = 69 SECITEM_AllocItem(arena, NULL, 0); 70 if (!cs->certStatusInfo.revokedInfo->revocationReason) 71 return NULL; 72 if (DER_TimeToGeneralizedTimeArena(arena, 73 &cs->certStatusInfo.revokedInfo->revocationTime, 74 revocationTime) != 75 SECSuccess) 76 return NULL; 77 break; 78 default: 79 PORT_Assert(PR_FALSE); 80 } 81 return cs; 82 } 83 84 static const SEC_ASN1Template mySEC_EnumeratedTemplate[] = { 85 { SEC_ASN1_ENUMERATED, 0, NULL, sizeof(SECItem) } 86 }; 87 88 static const SEC_ASN1Template mySEC_PointerToEnumeratedTemplate[] = { 89 { SEC_ASN1_POINTER, 0, mySEC_EnumeratedTemplate } 90 }; 91 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 }; 101 102 static const SEC_ASN1Template ocsp_PointerToEncodeRevokedInfoTemplate[] = { 103 { SEC_ASN1_POINTER, 0, 104 ocsp_EncodeRevokedInfoTemplate } 105 }; 106 107 static const SEC_ASN1Template mySEC_NullTemplate[] = { 108 { SEC_ASN1_NULL, 0, NULL, sizeof(SECItem) } 109 }; 110 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 }; 124 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 }; 134 135 static const SEC_ASN1Template mySEC_AnyTemplate[] = { 136 { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) } 137 }; 138 139 static const SEC_ASN1Template mySEC_SequenceOfAnyTemplate[] = { 140 { SEC_ASN1_SEQUENCE_OF, 0, mySEC_AnyTemplate } 141 }; 142 143 static const SEC_ASN1Template mySEC_PointerToSequenceOfAnyTemplate[] = { 144 { SEC_ASN1_POINTER, 0, mySEC_SequenceOfAnyTemplate } 145 }; 146 147 static const SEC_ASN1Template mySEC_IntegerTemplate[] = { 148 { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) } 149 }; 150 151 static const SEC_ASN1Template mySEC_PointerToIntegerTemplate[] = { 152 { SEC_ASN1_POINTER, 0, mySEC_IntegerTemplate } 153 }; 154 155 static const SEC_ASN1Template mySEC_GeneralizedTimeTemplate[] = { 156 { SEC_ASN1_GENERALIZED_TIME | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) } 157 }; 158 159 static const SEC_ASN1Template mySEC_PointerToGeneralizedTimeTemplate[] = { 160 { SEC_ASN1_POINTER, 0, mySEC_GeneralizedTimeTemplate } 161 }; 162 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 }; 177 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 }; 189 190 static const SEC_ASN1Template myCERT_SequenceOfCertExtensionTemplate[] = { 191 { SEC_ASN1_SEQUENCE_OF, 0, myCERT_CertExtensionTemplate } 192 }; 193 194 static const SEC_ASN1Template myCERT_PointerToSequenceOfCertExtensionTemplate[] = { 195 { SEC_ASN1_POINTER, 0, myCERT_SequenceOfCertExtensionTemplate } 196 }; 197 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 }; 218 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 }; 239 240 static const SEC_ASN1Template ocsp_EncodeBasicOCSPResponseTemplate[] = { 241 { SEC_ASN1_SEQUENCE, 242 0, NULL, sizeof(ocspBasicOCSPResponse) }, 243 { SEC_ASN1_POINTER, 244 offsetof(ocspBasicOCSPResponse, tbsResponseData), 245 ocsp_myResponseDataTemplate }, 246 { SEC_ASN1_INLINE, 247 offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), 248 mySECOID_AlgorithmIDTemplate }, 249 { SEC_ASN1_BIT_STRING, 250 offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, 251 { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | 252 SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, 253 offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), 254 mySEC_PointerToSequenceOfAnyTemplate }, 255 { 0 } 256 }; 257 258 static CERTOCSPSingleResponse * 259 ocsp_CreateSingleResponse(PLArenaPool *arena, 260 CERTOCSPCertID *id, ocspCertStatus *status, 261 PRTime thisUpdate, const PRTime *nextUpdate) 262 { 263 CERTOCSPSingleResponse *sr; 264 265 if (!arena || !id || !status) { 266 PORT_SetError(SEC_ERROR_INVALID_ARGS); 267 return NULL; 268 } 269 270 sr = PORT_ArenaZNew(arena, CERTOCSPSingleResponse); 271 if (!sr) 272 return NULL; 273 sr->arena = arena; 274 sr->certID = id; 275 sr->certStatus = status; 276 if (DER_TimeToGeneralizedTimeArena(arena, &sr->thisUpdate, thisUpdate) != 277 SECSuccess) 278 return NULL; 279 sr->nextUpdate = NULL; 280 if (nextUpdate) { 281 sr->nextUpdate = SECITEM_AllocItem(arena, NULL, 0); 282 if (!sr->nextUpdate) 283 return NULL; 284 if (DER_TimeToGeneralizedTimeArena(arena, sr->nextUpdate, *nextUpdate) != 285 SECSuccess) 286 return NULL; 287 } 288 289 sr->singleExtensions = PORT_ArenaNewArray(arena, CERTCertExtension *, 1); 290 if (!sr->singleExtensions) 291 return NULL; 292 293 sr->singleExtensions[0] = NULL; 294 295 if (!SEC_ASN1EncodeItem(arena, &sr->derCertStatus, 296 status, ocsp_CertStatusTemplate)) 297 return NULL; 298 299 return sr; 300 } 301 302 CERTOCSPSingleResponse * 303 CERT_CreateOCSPSingleResponseGood(PLArenaPool *arena, 304 CERTOCSPCertID *id, 305 PRTime thisUpdate, 306 const PRTime *nextUpdate) 307 { 308 ocspCertStatus *cs; 309 if (!arena) { 310 PORT_SetError(SEC_ERROR_INVALID_ARGS); 311 return NULL; 312 } 313 cs = ocsp_CreateCertStatus(arena, ocspCertStatus_good, 0); 314 if (!cs) 315 return NULL; 316 return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); 317 } 318 319 CERTOCSPSingleResponse * 320 CERT_CreateOCSPSingleResponseUnknown(PLArenaPool *arena, 321 CERTOCSPCertID *id, 322 PRTime thisUpdate, 323 const PRTime *nextUpdate) 324 { 325 ocspCertStatus *cs; 326 if (!arena) { 327 PORT_SetError(SEC_ERROR_INVALID_ARGS); 328 return NULL; 329 } 330 cs = ocsp_CreateCertStatus(arena, ocspCertStatus_unknown, 0); 331 if (!cs) 332 return NULL; 333 return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); 334 } 335 336 CERTOCSPSingleResponse * 337 CERT_CreateOCSPSingleResponseRevoked( 338 PLArenaPool *arena, 339 CERTOCSPCertID *id, 340 PRTime thisUpdate, 341 const PRTime *nextUpdate, 342 PRTime revocationTime, 343 const CERTCRLEntryReasonCode *revocationReason) 344 { 345 ocspCertStatus *cs; 346 /* revocationReason is not yet supported, so it must be NULL. */ 347 if (!arena || revocationReason) { 348 PORT_SetError(SEC_ERROR_INVALID_ARGS); 349 return NULL; 350 } 351 cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime); 352 if (!cs) 353 return NULL; 354 return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); 355 } 356 357 /* responderCert == 0 means: 358 * create a response with an invalid signature (for testing purposes) */ 359 SECItem * 360 CERT_CreateEncodedOCSPSuccessResponse( 361 PLArenaPool *arena, 362 CERTCertificate *responderCert, 363 CERTOCSPResponderIDType responderIDType, 364 PRTime producedAt, 365 CERTOCSPSingleResponse **responses, 366 void *wincx) 367 { 368 PLArenaPool *tmpArena; 369 ocspResponseData *rd = NULL; 370 ocspResponderID *rid = NULL; 371 const SEC_ASN1Template *responderIDTemplate = NULL; 372 ocspBasicOCSPResponse *br = NULL; 373 ocspResponseBytes *rb = NULL; 374 CERTOCSPResponse *response = NULL; 375 376 SECOidTag algID; 377 SECOidData *od = NULL; 378 SECKEYPrivateKey *privKey = NULL; 379 SECItem *result = NULL; 380 381 if (!arena || !responses) { 382 PORT_SetError(SEC_ERROR_INVALID_ARGS); 383 return NULL; 384 } 385 if (responderIDType != ocspResponderID_byName && 386 responderIDType != ocspResponderID_byKey) { 387 PORT_SetError(SEC_ERROR_INVALID_ARGS); 388 return NULL; 389 } 390 391 tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 392 if (!tmpArena) 393 return NULL; 394 395 rd = PORT_ArenaZNew(tmpArena, ocspResponseData); 396 if (!rd) 397 goto done; 398 rid = PORT_ArenaZNew(tmpArena, ocspResponderID); 399 if (!rid) 400 goto done; 401 br = PORT_ArenaZNew(tmpArena, ocspBasicOCSPResponse); 402 if (!br) 403 goto done; 404 rb = PORT_ArenaZNew(tmpArena, ocspResponseBytes); 405 if (!rb) 406 goto done; 407 response = PORT_ArenaZNew(tmpArena, CERTOCSPResponse); 408 if (!response) 409 goto done; 410 411 rd->version.data = NULL; 412 rd->version.len = 0; 413 rd->responseExtensions = NULL; 414 rd->responses = responses; 415 if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) != 416 SECSuccess) 417 goto done; 418 419 if (!responderCert) { 420 /* use invalid signature for testing purposes */ 421 unsigned char dummyChar = 'd'; 422 SECItem dummy; 423 424 dummy.len = 1; 425 dummy.data = &dummyChar; 426 427 /* it's easier to produdce a keyHash out of nowhere, 428 * than to produce an encoded subject, 429 * so for our dummy response we always use byKey 430 */ 431 432 rid->responderIDType = ocspResponderID_byKey; 433 if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.keyHash, 434 &dummy)) 435 goto done; 436 437 if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, 438 ocsp_ResponderIDByKeyTemplate)) 439 goto done; 440 441 br->tbsResponseData = rd; 442 443 if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, 444 ocsp_myResponseDataTemplate)) 445 goto done; 446 447 br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1); 448 if (!br->responseSignature.derCerts) 449 goto done; 450 br->responseSignature.derCerts[0] = NULL; 451 452 algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1); 453 if (algID == SEC_OID_UNKNOWN) 454 goto done; 455 456 /* match the regular signature code, which doesn't use the arena */ 457 if (!SECITEM_AllocItem(NULL, &br->responseSignature.signature, 1)) 458 goto done; 459 PORT_Memcpy(br->responseSignature.signature.data, &dummyChar, 1); 460 461 /* convert len-in-bytes to len-in-bits */ 462 br->responseSignature.signature.len = br->responseSignature.signature.len << 3; 463 } else { 464 rid->responderIDType = responderIDType; 465 if (responderIDType == ocspResponderID_byName) { 466 responderIDTemplate = ocsp_ResponderIDByNameTemplate; 467 if (CERT_CopyName(tmpArena, &rid->responderIDValue.name, 468 &responderCert->subject) != SECSuccess) 469 goto done; 470 } else { 471 responderIDTemplate = ocsp_ResponderIDByKeyTemplate; 472 if (!CERT_GetSubjectPublicKeyDigest(tmpArena, responderCert, 473 SEC_OID_SHA1, &rid->responderIDValue.keyHash)) 474 goto done; 475 } 476 477 if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, 478 responderIDTemplate)) 479 goto done; 480 481 br->tbsResponseData = rd; 482 483 if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseData, 484 ocsp_myResponseDataTemplate)) 485 goto done; 486 487 br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem *, 1); 488 if (!br->responseSignature.derCerts) 489 goto done; 490 br->responseSignature.derCerts[0] = NULL; 491 492 privKey = PK11_FindKeyByAnyCert(responderCert, wincx); 493 if (!privKey) 494 goto done; 495 496 algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1); 497 if (algID == SEC_OID_UNKNOWN) 498 goto done; 499 500 if (SEC_SignData(&br->responseSignature.signature, 501 br->tbsResponseDataDER.data, br->tbsResponseDataDER.len, 502 privKey, algID) != 503 SECSuccess) 504 goto done; 505 506 /* convert len-in-bytes to len-in-bits */ 507 br->responseSignature.signature.len = br->responseSignature.signature.len << 3; 508 509 /* br->responseSignature.signature wasn't allocated from arena, 510 * we must free it when done. */ 511 } 512 513 if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorithm, algID, 0) != 514 SECSuccess) 515 goto done; 516 517 if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br, 518 ocsp_EncodeBasicOCSPResponseTemplate)) 519 goto done; 520 521 rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE; 522 523 od = SECOID_FindOIDByTag(rb->responseTypeTag); 524 if (!od) 525 goto done; 526 527 rb->responseType = od->oid; 528 rb->decodedResponse.basic = br; 529 530 response->arena = tmpArena; 531 response->responseBytes = rb; 532 response->statusValue = ocspResponse_successful; 533 534 if (!SEC_ASN1EncodeInteger(tmpArena, &response->responseStatus, 535 response->statusValue)) 536 goto done; 537 538 result = SEC_ASN1EncodeItem(arena, NULL, response, ocsp_OCSPResponseTemplate); 539 540 done: 541 if (privKey) 542 SECKEY_DestroyPrivateKey(privKey); 543 if (br && br->responseSignature.signature.data) 544 SECITEM_FreeItem(&br->responseSignature.signature, PR_FALSE); 545 PORT_FreeArena(tmpArena, PR_FALSE); 546 547 return result; 548 } 549 550 static const SEC_ASN1Template ocsp_OCSPErrorResponseTemplate[] = { 551 { SEC_ASN1_SEQUENCE, 552 0, NULL, sizeof(CERTOCSPResponse) }, 553 { SEC_ASN1_ENUMERATED, 554 offsetof(CERTOCSPResponse, responseStatus) }, 555 { 0, 0, 556 mySEC_NullTemplate }, 557 { 0 } 558 }; 559 560 SECItem * 561 CERT_CreateEncodedOCSPErrorResponse(PLArenaPool *arena, int error) 562 { 563 CERTOCSPResponse response; 564 SECItem *result = NULL; 565 566 switch (error) { 567 case SEC_ERROR_OCSP_MALFORMED_REQUEST: 568 response.statusValue = ocspResponse_malformedRequest; 569 break; 570 case SEC_ERROR_OCSP_SERVER_ERROR: 571 response.statusValue = ocspResponse_internalError; 572 break; 573 case SEC_ERROR_OCSP_TRY_SERVER_LATER: 574 response.statusValue = ocspResponse_tryLater; 575 break; 576 case SEC_ERROR_OCSP_REQUEST_NEEDS_SIG: 577 response.statusValue = ocspResponse_sigRequired; 578 break; 579 case SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST: 580 response.statusValue = ocspResponse_unauthorized; 581 break; 582 default: 583 PORT_SetError(SEC_ERROR_INVALID_ARGS); 584 return NULL; 585 } 586 587 if (!SEC_ASN1EncodeInteger(NULL, &response.responseStatus, 588 response.statusValue)) 589 return NULL; 590 591 result = SEC_ASN1EncodeItem(arena, NULL, &response, 592 ocsp_OCSPErrorResponseTemplate); 593 594 SECITEM_FreeItem(&response.responseStatus, PR_FALSE); 595 596 return result; 597 }