OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #include "plarena.h" | 5 #include "plarena.h" |
6 | 6 |
7 #include "seccomon.h" | 7 #include "seccomon.h" |
8 #include "secitem.h" | 8 #include "secitem.h" |
9 #include "secasn1.h" | 9 #include "secasn1.h" |
10 #include "secder.h" | 10 #include "secder.h" |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 if (!arena || revocationReason) { | 348 if (!arena || revocationReason) { |
349 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 349 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
350 return NULL; | 350 return NULL; |
351 } | 351 } |
352 cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime); | 352 cs = ocsp_CreateCertStatus(arena, ocspCertStatus_revoked, revocationTime); |
353 if (!cs) | 353 if (!cs) |
354 return NULL; | 354 return NULL; |
355 return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); | 355 return ocsp_CreateSingleResponse(arena, id, cs, thisUpdate, nextUpdate); |
356 } | 356 } |
357 | 357 |
| 358 /* responderCert == 0 means: |
| 359 * create a response with an invalid signature (for testing purposes) */ |
358 SECItem* | 360 SECItem* |
359 CERT_CreateEncodedOCSPSuccessResponse( | 361 CERT_CreateEncodedOCSPSuccessResponse( |
360 PLArenaPool *arena, | 362 PLArenaPool *arena, |
361 CERTCertificate *responderCert, | 363 CERTCertificate *responderCert, |
362 CERTOCSPResponderIDType responderIDType, | 364 CERTOCSPResponderIDType responderIDType, |
363 PRTime producedAt, | 365 PRTime producedAt, |
364 CERTOCSPSingleResponse **responses, | 366 CERTOCSPSingleResponse **responses, |
365 void *wincx) | 367 void *wincx) |
366 { | 368 { |
367 PLArenaPool *tmpArena; | 369 PLArenaPool *tmpArena; |
368 ocspResponseData *rd = NULL; | 370 ocspResponseData *rd = NULL; |
369 ocspResponderID *rid = NULL; | 371 ocspResponderID *rid = NULL; |
370 const SEC_ASN1Template *responderIDTemplate = NULL; | 372 const SEC_ASN1Template *responderIDTemplate = NULL; |
371 ocspBasicOCSPResponse *br = NULL; | 373 ocspBasicOCSPResponse *br = NULL; |
372 ocspResponseBytes *rb = NULL; | 374 ocspResponseBytes *rb = NULL; |
373 CERTOCSPResponse *response = NULL; | 375 CERTOCSPResponse *response = NULL; |
374 | 376 |
375 SECOidTag algID; | 377 SECOidTag algID; |
376 SECOidData *od = NULL; | 378 SECOidData *od = NULL; |
377 SECKEYPrivateKey *privKey = NULL; | 379 SECKEYPrivateKey *privKey = NULL; |
378 SECItem *result = NULL; | 380 SECItem *result = NULL; |
379 | 381 |
380 if (!arena || !responderCert || !responses) { | 382 if (!arena || !responses) { |
381 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 383 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
382 return NULL; | 384 return NULL; |
383 } | 385 } |
384 if (responderIDType != ocspResponderID_byName && | 386 if (responderIDType != ocspResponderID_byName && |
385 responderIDType != ocspResponderID_byKey) { | 387 responderIDType != ocspResponderID_byKey) { |
386 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 388 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
387 return NULL; | 389 return NULL; |
388 } | 390 } |
389 | 391 |
390 tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | 392 tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); |
(...skipping 16 matching lines...) Expand all Loading... |
407 if (!response) | 409 if (!response) |
408 goto done; | 410 goto done; |
409 | 411 |
410 rd->version.data=NULL; | 412 rd->version.data=NULL; |
411 rd->version.len=0; | 413 rd->version.len=0; |
412 rd->responseExtensions = NULL; | 414 rd->responseExtensions = NULL; |
413 rd->responses = responses; | 415 rd->responses = responses; |
414 if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) | 416 if (DER_TimeToGeneralizedTimeArena(tmpArena, &rd->producedAt, producedAt) |
415 != SECSuccess) | 417 != SECSuccess) |
416 goto done; | 418 goto done; |
417 rid->responderIDType = responderIDType; | 419 |
418 if (responderIDType == ocspResponderID_byName) { | 420 if (!responderCert) { |
419 responderIDTemplate = ocsp_ResponderIDByNameTemplate; | 421 » /* use invalid signature for testing purposes */ |
420 if (CERT_CopyName(tmpArena, &rid->responderIDValue.name, | 422 » unsigned char dummyChar = 'd'; |
421 &responderCert->subject) != SECSuccess) | 423 » SECItem dummy; |
422 goto done; | 424 |
| 425 » dummy.len = 1; |
| 426 » dummy.data = &dummyChar; |
| 427 |
| 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 » */ |
| 432 » |
| 433 » rid->responderIDType = ocspResponderID_byKey; |
| 434 » if (!ocsp_DigestValue(tmpArena, SEC_OID_SHA1, &rid->responderIDValue.key
Hash, |
| 435 » » » &dummy)) |
| 436 » goto done; |
| 437 |
| 438 » if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, |
| 439 » » » » ocsp_ResponderIDByKeyTemplate)) |
| 440 » goto done; |
| 441 |
| 442 » br->tbsResponseData = rd; |
| 443 |
| 444 » if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsRespon
seData, |
| 445 » » » » ocsp_myResponseDataTemplate)) |
| 446 » goto done; |
| 447 |
| 448 » br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*,
1); |
| 449 » if (!br->responseSignature.derCerts) |
| 450 » goto done; |
| 451 » br->responseSignature.derCerts[0] = NULL; |
| 452 |
| 453 » algID = SEC_GetSignatureAlgorithmOidTag(rsaKey, SEC_OID_SHA1); |
| 454 » if (algID == SEC_OID_UNKNOWN) |
| 455 » goto done; |
| 456 |
| 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); |
| 461 |
| 462 » /* convert len-in-bytes to len-in-bits */ |
| 463 » br->responseSignature.signature.len = br->responseSignature.signature.le
n << 3; |
423 } | 464 } |
424 else { | 465 else { |
425 responderIDTemplate = ocsp_ResponderIDByKeyTemplate; | 466 » rid->responderIDType = responderIDType; |
426 if (!CERT_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1, | 467 » if (responderIDType == ocspResponderID_byName) { |
427 &rid->responderIDValue.keyHash)) | 468 » responderIDTemplate = ocsp_ResponderIDByNameTemplate; |
428 goto done; | 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_GetSPKIDigest(tmpArena, responderCert, SEC_OID_SHA1, |
| 476 » » » » » &rid->responderIDValue.keyHash)) |
| 477 » » goto done; |
| 478 » } |
| 479 |
| 480 » if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, |
| 481 » » responderIDTemplate)) |
| 482 » goto done; |
| 483 |
| 484 » br->tbsResponseData = rd; |
| 485 |
| 486 » if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsRespon
seData, |
| 487 » » ocsp_myResponseDataTemplate)) |
| 488 » goto done; |
| 489 |
| 490 » br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*,
1); |
| 491 » if (!br->responseSignature.derCerts) |
| 492 » goto done; |
| 493 » br->responseSignature.derCerts[0] = NULL; |
| 494 |
| 495 » privKey = PK11_FindKeyByAnyCert(responderCert, wincx); |
| 496 » if (!privKey) |
| 497 » goto done; |
| 498 |
| 499 » algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1); |
| 500 » if (algID == SEC_OID_UNKNOWN) |
| 501 » goto done; |
| 502 |
| 503 » if (SEC_SignData(&br->responseSignature.signature, |
| 504 » » » br->tbsResponseDataDER.data, br->tbsResponseDataDER.
len, |
| 505 » » » privKey, algID) |
| 506 » » != SECSuccess) |
| 507 » goto done; |
| 508 |
| 509 » /* convert len-in-bytes to len-in-bits */ |
| 510 » br->responseSignature.signature.len = br->responseSignature.signature.le
n << 3; |
| 511 |
| 512 » /* br->responseSignature.signature wasn't allocated from arena, |
| 513 » * we must free it when done. */ |
429 } | 514 } |
430 | 515 |
431 if (!SEC_ASN1EncodeItem(tmpArena, &rd->derResponderID, rid, | |
432 responderIDTemplate)) | |
433 goto done; | |
434 | |
435 br->tbsResponseData = rd; | |
436 | |
437 if (!SEC_ASN1EncodeItem(tmpArena, &br->tbsResponseDataDER, br->tbsResponseDa
ta, | |
438 ocsp_myResponseDataTemplate)) | |
439 goto done; | |
440 | |
441 br->responseSignature.derCerts = PORT_ArenaNewArray(tmpArena, SECItem*, 1); | |
442 if (!br->responseSignature.derCerts) | |
443 goto done; | |
444 br->responseSignature.derCerts[0] = NULL; | |
445 | |
446 privKey = PK11_FindKeyByAnyCert(responderCert, wincx); | |
447 if (!privKey) | |
448 goto done; | |
449 | |
450 algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1); | |
451 if (algID == SEC_OID_UNKNOWN) | |
452 goto done; | |
453 | |
454 if (SEC_SignData(&br->responseSignature.signature, | |
455 br->tbsResponseDataDER.data, br->tbsResponseDataDER.len, | |
456 privKey, algID) | |
457 != SECSuccess) | |
458 goto done; | |
459 | |
460 /* convert len-in-bytes to len-in-bits */ | |
461 br->responseSignature.signature.len = br->responseSignature.signature.len <<
3; | |
462 | |
463 /* br->responseSignature.signature wasn't allocated from arena, | |
464 * we must free it when done. */ | |
465 | |
466 if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorith
m, algID, 0) | 516 if (SECOID_SetAlgorithmID(tmpArena, &br->responseSignature.signatureAlgorith
m, algID, 0) |
467 != SECSuccess) | 517 » != SECSuccess) |
468 goto done; | 518 » goto done; |
469 | 519 |
470 if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br, | 520 if (!SEC_ASN1EncodeItem(tmpArena, &rb->response, br, |
471 ocsp_EncodeBasicOCSPResponseTemplate)) | 521 ocsp_EncodeBasicOCSPResponseTemplate)) |
472 goto done; | 522 goto done; |
473 | 523 |
474 rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE; | 524 rb->responseTypeTag = SEC_OID_PKIX_OCSP_BASIC_RESPONSE; |
475 | 525 |
476 od = SECOID_FindOIDByTag(rb->responseTypeTag); | 526 od = SECOID_FindOIDByTag(rb->responseTypeTag); |
477 if (!od) | 527 if (!od) |
478 goto done; | 528 goto done; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 response.statusValue)) | 591 response.statusValue)) |
542 return NULL; | 592 return NULL; |
543 | 593 |
544 result = SEC_ASN1EncodeItem(arena, NULL, &response, | 594 result = SEC_ASN1EncodeItem(arena, NULL, &response, |
545 ocsp_OCSPErrorResponseTemplate); | 595 ocsp_OCSPErrorResponseTemplate); |
546 | 596 |
547 SECITEM_FreeItem(&response.responseStatus, PR_FALSE); | 597 SECITEM_FreeItem(&response.responseStatus, PR_FALSE); |
548 | 598 |
549 return result; | 599 return result; |
550 } | 600 } |
OLD | NEW |