| 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 |