servget.c (27002B)
1 /* -*- Mode: C; tab-width: 8 -*-*/ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "cmmf.h" 7 #include "cmmfi.h" 8 #include "secitem.h" 9 #include "keyhi.h" 10 #include "secder.h" 11 12 CRMFEncryptedKeyChoice 13 CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey) 14 { 15 PORT_Assert(inEncrKey != NULL); 16 if (inEncrKey == NULL) { 17 return crmfNoEncryptedKeyChoice; 18 } 19 return inEncrKey->encKeyChoice; 20 } 21 22 CRMFEncryptedValue * 23 CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey) 24 { 25 CRMFEncryptedValue *newEncrValue = NULL; 26 SECStatus rv; 27 28 PORT_Assert(inEncrKey != NULL); 29 if (inEncrKey == NULL || 30 CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) { 31 goto loser; 32 } 33 newEncrValue = PORT_ZNew(CRMFEncryptedValue); 34 if (newEncrValue == NULL) { 35 goto loser; 36 } 37 rv = crmf_copy_encryptedvalue(NULL, &inEncrKey->value.encryptedValue, 38 newEncrValue); 39 if (rv != SECSuccess) { 40 goto loser; 41 } 42 return newEncrValue; 43 loser: 44 if (newEncrValue != NULL) { 45 CRMF_DestroyEncryptedValue(newEncrValue); 46 } 47 return NULL; 48 } 49 50 static SECItem * 51 crmf_get_encvalue_bitstring(SECItem *srcItem) 52 { 53 SECItem *newItem = NULL; 54 SECStatus rv; 55 56 if (srcItem->data == NULL) { 57 return NULL; 58 } 59 newItem = PORT_ZNew(SECItem); 60 if (newItem == NULL) { 61 goto loser; 62 } 63 rv = crmf_make_bitstring_copy(NULL, newItem, srcItem); 64 if (rv != SECSuccess) { 65 goto loser; 66 } 67 return newItem; 68 loser: 69 if (newItem != NULL) { 70 SECITEM_FreeItem(newItem, PR_TRUE); 71 } 72 return NULL; 73 } 74 75 SECItem * 76 CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue) 77 { 78 if (inEncValue == NULL) { 79 return NULL; 80 } 81 return crmf_get_encvalue_bitstring(&inEncValue->encSymmKey); 82 } 83 84 SECItem * 85 CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue) 86 { 87 if (inEncrValue == NULL || inEncrValue->encValue.data == NULL) { 88 return NULL; 89 } 90 return crmf_get_encvalue_bitstring(&inEncrValue->encValue); 91 } 92 93 static SECAlgorithmID * 94 crmf_get_encvalue_algid(SECAlgorithmID *srcAlg) 95 { 96 SECStatus rv; 97 SECAlgorithmID *newAlgID; 98 99 if (srcAlg == NULL) { 100 return NULL; 101 } 102 rv = crmf_copy_encryptedvalue_secalg(NULL, srcAlg, &newAlgID); 103 if (rv != SECSuccess) { 104 return NULL; 105 } 106 return newAlgID; 107 } 108 109 SECAlgorithmID * 110 CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue) 111 { 112 if (inEncValue == NULL) { 113 return NULL; 114 } 115 return crmf_get_encvalue_algid(inEncValue->intendedAlg); 116 } 117 118 SECAlgorithmID * 119 CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue) 120 { 121 if (inEncValue == NULL) { 122 return NULL; 123 } 124 return crmf_get_encvalue_algid(inEncValue->keyAlg); 125 } 126 127 SECAlgorithmID * 128 CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue) 129 { 130 if (inEncValue == NULL) { 131 return NULL; 132 } 133 return crmf_get_encvalue_algid(inEncValue->symmAlg); 134 } 135 136 SECItem * 137 CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue) 138 { 139 if (inEncValue == NULL || inEncValue->valueHint.data == NULL) { 140 return NULL; 141 } 142 return SECITEM_DupItem(&inEncValue->valueHint); 143 } 144 145 SECStatus 146 CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt, 147 PRBool *destVal) 148 { 149 if (inOpt == NULL || destVal == NULL || 150 CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey) { 151 return SECFailure; 152 } 153 *destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse) 154 ? PR_FALSE 155 : PR_TRUE; 156 return SECSuccess; 157 } 158 159 CRMFEncryptedKey * 160 CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts) 161 { 162 CRMFEncryptedKey *newEncrKey = NULL; 163 SECStatus rv; 164 165 PORT_Assert(inOpts != NULL); 166 if (inOpts == NULL || 167 CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey) { 168 return NULL; 169 } 170 newEncrKey = PORT_ZNew(CRMFEncryptedKey); 171 if (newEncrKey == NULL) { 172 goto loser; 173 } 174 rv = crmf_copy_encryptedkey(NULL, &inOpts->option.encryptedKey, 175 newEncrKey); 176 if (rv != SECSuccess) { 177 goto loser; 178 } 179 return newEncrKey; 180 loser: 181 if (newEncrKey != NULL) { 182 CRMF_DestroyEncryptedKey(newEncrKey); 183 } 184 return NULL; 185 } 186 187 SECItem * 188 CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions) 189 { 190 if (inOptions == NULL || 191 CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters || 192 inOptions->option.keyGenParameters.data == NULL) { 193 return NULL; 194 } 195 return SECITEM_DupItem(&inOptions->option.keyGenParameters); 196 } 197 198 CRMFPKIArchiveOptionsType 199 CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions) 200 { 201 PORT_Assert(inOptions != NULL); 202 if (inOptions == NULL) { 203 return crmfNoArchiveOptions; 204 } 205 return inOptions->archOption; 206 } 207 208 static SECStatus 209 crmf_extract_long_from_item(SECItem *intItem, long *destLong) 210 { 211 *destLong = DER_GetInteger(intItem); 212 return (*destLong == -1) ? SECFailure : SECSuccess; 213 } 214 215 SECStatus 216 CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey *inKey, 217 CRMFSubseqMessOptions *destOpt) 218 { 219 long value; 220 SECStatus rv; 221 222 PORT_Assert(inKey != NULL); 223 if (inKey == NULL || 224 inKey->messageChoice != crmfSubsequentMessage) { 225 return SECFailure; 226 } 227 rv = crmf_extract_long_from_item(&inKey->message.subsequentMessage, &value); 228 if (rv != SECSuccess) { 229 return SECFailure; 230 } 231 switch (value) { 232 case 0: 233 *destOpt = crmfEncrCert; 234 break; 235 case 1: 236 *destOpt = crmfChallengeResp; 237 break; 238 default: 239 rv = SECFailure; 240 } 241 if (rv != SECSuccess) { 242 return rv; 243 } 244 return SECSuccess; 245 } 246 247 CRMFPOPOPrivKeyChoice 248 CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inPrivKey) 249 { 250 PORT_Assert(inPrivKey != NULL); 251 if (inPrivKey != NULL) { 252 return inPrivKey->messageChoice; 253 } 254 return crmfNoMessage; 255 } 256 257 SECStatus 258 CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey, SECItem *destMAC) 259 { 260 PORT_Assert(inKey != NULL); 261 if (inKey == NULL || inKey->message.dhMAC.data == NULL) { 262 return SECFailure; 263 } 264 return crmf_make_bitstring_copy(NULL, destMAC, &inKey->message.dhMAC); 265 } 266 267 SECStatus 268 CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey *inKey, 269 SECItem *destString) 270 { 271 PORT_Assert(inKey != NULL); 272 if (inKey == NULL || 273 inKey->messageChoice != crmfThisMessage) { 274 return SECFailure; 275 } 276 277 return crmf_make_bitstring_copy(NULL, destString, 278 &inKey->message.thisMessage); 279 } 280 281 SECAlgorithmID * 282 CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey) 283 { 284 SECAlgorithmID *newAlgId = NULL; 285 SECStatus rv; 286 287 PORT_Assert(inSignKey != NULL); 288 if (inSignKey == NULL) { 289 return NULL; 290 } 291 newAlgId = PORT_ZNew(SECAlgorithmID); 292 if (newAlgId == NULL) { 293 goto loser; 294 } 295 rv = SECOID_CopyAlgorithmID(NULL, newAlgId, 296 inSignKey->algorithmIdentifier); 297 if (rv != SECSuccess) { 298 goto loser; 299 } 300 return newAlgId; 301 302 loser: 303 if (newAlgId != NULL) { 304 SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE); 305 } 306 return NULL; 307 } 308 309 SECItem * 310 CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey) 311 { 312 PORT_Assert(inSignKey != NULL); 313 if (inSignKey == NULL || inSignKey->derInput.data == NULL) { 314 return NULL; 315 } 316 return SECITEM_DupItem(&inSignKey->derInput); 317 } 318 319 SECItem * 320 CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey) 321 { 322 SECItem *newSig = NULL; 323 SECStatus rv; 324 325 PORT_Assert(inSignKey != NULL); 326 if (inSignKey == NULL) { 327 return NULL; 328 } 329 newSig = PORT_ZNew(SECItem); 330 if (newSig == NULL) { 331 goto loser; 332 } 333 rv = crmf_make_bitstring_copy(NULL, newSig, &inSignKey->signature); 334 if (rv != SECSuccess) { 335 goto loser; 336 } 337 return newSig; 338 loser: 339 if (newSig != NULL) { 340 SECITEM_FreeItem(newSig, PR_TRUE); 341 } 342 return NULL; 343 } 344 345 static SECStatus 346 crmf_copy_poposigningkey(PLArenaPool *poolp, 347 CRMFPOPOSigningKey *inPopoSignKey, 348 CRMFPOPOSigningKey *destPopoSignKey) 349 { 350 SECStatus rv; 351 352 /* We don't support use of the POPOSigningKeyInput, so we'll only 353 * store away the DER encoding. 354 */ 355 if (inPopoSignKey->derInput.data != NULL) { 356 rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput, 357 &inPopoSignKey->derInput); 358 if (rv != SECSuccess) { 359 goto loser; 360 } 361 } 362 destPopoSignKey->algorithmIdentifier = (poolp == NULL) ? PORT_ZNew(SECAlgorithmID) 363 : PORT_ArenaZNew(poolp, SECAlgorithmID); 364 365 if (destPopoSignKey->algorithmIdentifier == NULL) { 366 goto loser; 367 } 368 rv = SECOID_CopyAlgorithmID(poolp, destPopoSignKey->algorithmIdentifier, 369 inPopoSignKey->algorithmIdentifier); 370 if (rv != SECSuccess) { 371 goto loser; 372 } 373 374 rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature, 375 &inPopoSignKey->signature); 376 if (rv != SECSuccess) { 377 goto loser; 378 } 379 return SECSuccess; 380 loser: 381 if (poolp == NULL) { 382 CRMF_DestroyPOPOSigningKey(destPopoSignKey); 383 } 384 return SECFailure; 385 } 386 387 static SECStatus 388 crmf_copy_popoprivkey(PLArenaPool *poolp, 389 CRMFPOPOPrivKey *srcPrivKey, 390 CRMFPOPOPrivKey *destPrivKey) 391 { 392 SECStatus rv; 393 394 destPrivKey->messageChoice = srcPrivKey->messageChoice; 395 switch (destPrivKey->messageChoice) { 396 case crmfThisMessage: 397 case crmfDHMAC: 398 /* I've got a union, so taking the address of one, will also give 399 * me a pointer to the other (eg, message.dhMAC) 400 */ 401 rv = crmf_make_bitstring_copy(poolp, &destPrivKey->message.thisMessage, 402 &srcPrivKey->message.thisMessage); 403 break; 404 case crmfSubsequentMessage: 405 rv = SECITEM_CopyItem(poolp, &destPrivKey->message.subsequentMessage, 406 &srcPrivKey->message.subsequentMessage); 407 break; 408 default: 409 rv = SECFailure; 410 } 411 412 if (rv != SECSuccess && poolp == NULL) { 413 CRMF_DestroyPOPOPrivKey(destPrivKey); 414 } 415 return rv; 416 } 417 418 static CRMFProofOfPossession * 419 crmf_copy_pop(PLArenaPool *poolp, CRMFProofOfPossession *srcPOP) 420 { 421 CRMFProofOfPossession *newPOP; 422 SECStatus rv; 423 424 /* 425 * Proof Of Possession structures are always part of the Request 426 * message, so there will always be an arena for allocating memory. 427 */ 428 if (poolp == NULL) { 429 return NULL; 430 } 431 newPOP = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 432 if (newPOP == NULL) { 433 return NULL; 434 } 435 switch (srcPOP->popUsed) { 436 case crmfRAVerified: 437 newPOP->popChoice.raVerified.data = NULL; 438 newPOP->popChoice.raVerified.len = 0; 439 break; 440 case crmfSignature: 441 rv = crmf_copy_poposigningkey(poolp, &srcPOP->popChoice.signature, 442 &newPOP->popChoice.signature); 443 if (rv != SECSuccess) { 444 goto loser; 445 } 446 break; 447 case crmfKeyEncipherment: 448 case crmfKeyAgreement: 449 /* We've got a union, so a pointer to one, is a pointer to the 450 * other one. 451 */ 452 rv = crmf_copy_popoprivkey(poolp, &srcPOP->popChoice.keyEncipherment, 453 &newPOP->popChoice.keyEncipherment); 454 if (rv != SECSuccess) { 455 goto loser; 456 } 457 break; 458 default: 459 goto loser; 460 } 461 newPOP->popUsed = srcPOP->popUsed; 462 return newPOP; 463 464 loser: 465 return NULL; 466 } 467 468 static CRMFCertReqMsg * 469 crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg) 470 { 471 CRMFCertReqMsg *newReqMsg; 472 PLArenaPool *poolp; 473 474 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); 475 if (poolp == NULL) { 476 return NULL; 477 } 478 newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); 479 if (newReqMsg == NULL) { 480 PORT_FreeArena(poolp, PR_TRUE); 481 return NULL; 482 } 483 484 newReqMsg->poolp = poolp; 485 newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq); 486 if (newReqMsg->certReq == NULL) { 487 goto loser; 488 } 489 newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop); 490 if (newReqMsg->pop == NULL) { 491 goto loser; 492 } 493 /* None of my set/get routines operate on the regInfo field, so 494 * for now, that won't get copied over. 495 */ 496 return newReqMsg; 497 498 loser: 499 CRMF_DestroyCertReqMsg(newReqMsg); 500 return NULL; 501 } 502 503 CRMFCertReqMsg * 504 CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs, 505 int index) 506 { 507 int numMsgs; 508 509 PORT_Assert(inReqMsgs != NULL && index >= 0); 510 if (inReqMsgs == NULL) { 511 return NULL; 512 } 513 numMsgs = CRMF_CertReqMessagesGetNumMessages(inReqMsgs); 514 if (index < 0 || index >= numMsgs) { 515 return NULL; 516 } 517 return crmf_copy_cert_req_msg(inReqMsgs->messages[index]); 518 } 519 520 int 521 CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs) 522 { 523 int numMessages = 0; 524 525 PORT_Assert(inCertReqMsgs != NULL); 526 if (inCertReqMsgs == NULL) { 527 return 0; 528 } 529 while (inCertReqMsgs->messages[numMessages] != NULL) { 530 numMessages++; 531 } 532 return numMessages; 533 } 534 535 CRMFCertRequest * 536 CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg) 537 { 538 PLArenaPool *poolp = NULL; 539 CRMFCertRequest *newCertReq = NULL; 540 541 PORT_Assert(inCertReqMsg != NULL); 542 543 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); 544 if (poolp == NULL) { 545 goto loser; 546 } 547 newCertReq = crmf_copy_cert_request(poolp, inCertReqMsg->certReq); 548 if (newCertReq == NULL) { 549 goto loser; 550 } 551 newCertReq->poolp = poolp; 552 return newCertReq; 553 loser: 554 if (poolp != NULL) { 555 PORT_FreeArena(poolp, PR_FALSE); 556 } 557 return NULL; 558 } 559 560 SECStatus 561 CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg, long *destID) 562 { 563 PORT_Assert(inCertReqMsg != NULL && destID != NULL); 564 if (inCertReqMsg == NULL || inCertReqMsg->certReq == NULL) { 565 return SECFailure; 566 } 567 return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId, 568 destID); 569 } 570 571 SECStatus 572 CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg *inCertReqMsg, 573 CRMFPOPOPrivKey **destKey) 574 { 575 PORT_Assert(inCertReqMsg != NULL && destKey != NULL); 576 if (inCertReqMsg == NULL || destKey == NULL || 577 CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) { 578 return SECFailure; 579 } 580 *destKey = PORT_ZNew(CRMFPOPOPrivKey); 581 if (*destKey == NULL) { 582 return SECFailure; 583 } 584 return crmf_copy_popoprivkey(NULL, 585 &inCertReqMsg->pop->popChoice.keyAgreement, 586 *destKey); 587 } 588 589 SECStatus 590 CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg *inCertReqMsg, 591 CRMFPOPOPrivKey **destKey) 592 { 593 PORT_Assert(inCertReqMsg != NULL && destKey != NULL); 594 if (inCertReqMsg == NULL || destKey == NULL || 595 CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) { 596 return SECFailure; 597 } 598 *destKey = PORT_ZNew(CRMFPOPOPrivKey); 599 if (*destKey == NULL) { 600 return SECFailure; 601 } 602 return crmf_copy_popoprivkey(NULL, 603 &inCertReqMsg->pop->popChoice.keyEncipherment, 604 *destKey); 605 } 606 607 SECStatus 608 CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg *inCertReqMsg, 609 CRMFPOPOSigningKey **destKey) 610 { 611 CRMFProofOfPossession *pop; 612 PORT_Assert(inCertReqMsg != NULL); 613 if (inCertReqMsg == NULL) { 614 return SECFailure; 615 } 616 pop = inCertReqMsg->pop; 617 ; 618 if (pop->popUsed != crmfSignature) { 619 return SECFailure; 620 } 621 *destKey = PORT_ZNew(CRMFPOPOSigningKey); 622 if (*destKey == NULL) { 623 return SECFailure; 624 } 625 return crmf_copy_poposigningkey(NULL, &pop->popChoice.signature, *destKey); 626 } 627 628 static SECStatus 629 crmf_copy_name(CERTName *destName, CERTName *srcName) 630 { 631 PLArenaPool *poolp = NULL; 632 SECStatus rv; 633 634 if (destName->arena != NULL) { 635 poolp = destName->arena; 636 } else { 637 poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); 638 } 639 if (poolp == NULL) { 640 return SECFailure; 641 } 642 /* Need to do this so that CERT_CopyName doesn't free out 643 * the arena from underneath us. 644 */ 645 destName->arena = NULL; 646 rv = CERT_CopyName(poolp, destName, srcName); 647 destName->arena = poolp; 648 return rv; 649 } 650 651 SECStatus 652 CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq, 653 CERTName *destIssuer) 654 { 655 PORT_Assert(inCertReq != NULL); 656 if (inCertReq == NULL) { 657 return SECFailure; 658 } 659 if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuer)) { 660 return crmf_copy_name(destIssuer, 661 inCertReq->certTemplate.issuer); 662 } 663 return SECFailure; 664 } 665 666 SECStatus 667 CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq, 668 SECItem *destIssuerUID) 669 { 670 PORT_Assert(inCertReq != NULL); 671 if (inCertReq == NULL) { 672 return SECFailure; 673 } 674 if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuerUID)) { 675 return crmf_make_bitstring_copy(NULL, destIssuerUID, 676 &inCertReq->certTemplate.issuerUID); 677 } 678 return SECFailure; 679 } 680 681 SECStatus 682 CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest *inCertReq, 683 CERTSubjectPublicKeyInfo *destPublicKey) 684 { 685 PORT_Assert(inCertReq != NULL); 686 if (inCertReq == NULL) { 687 return SECFailure; 688 } 689 if (CRMF_DoesRequestHaveField(inCertReq, crmfPublicKey)) { 690 return SECKEY_CopySubjectPublicKeyInfo(NULL, destPublicKey, 691 inCertReq->certTemplate.publicKey); 692 } 693 return SECFailure; 694 } 695 696 SECStatus 697 CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq, 698 long *serialNumber) 699 { 700 PORT_Assert(inCertReq != NULL); 701 if (inCertReq == NULL) { 702 return SECFailure; 703 } 704 if (CRMF_DoesRequestHaveField(inCertReq, crmfSerialNumber)) { 705 return crmf_extract_long_from_item(&inCertReq->certTemplate.serialNumber, 706 serialNumber); 707 } 708 return SECFailure; 709 } 710 711 SECStatus 712 CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq, 713 SECAlgorithmID *destAlg) 714 { 715 PORT_Assert(inCertReq != NULL); 716 if (inCertReq == NULL) { 717 return SECFailure; 718 } 719 if (CRMF_DoesRequestHaveField(inCertReq, crmfSigningAlg)) { 720 return SECOID_CopyAlgorithmID(NULL, destAlg, 721 inCertReq->certTemplate.signingAlg); 722 } 723 return SECFailure; 724 } 725 726 SECStatus 727 CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq, 728 CERTName *destSubject) 729 { 730 PORT_Assert(inCertReq != NULL); 731 if (inCertReq == NULL) { 732 return SECFailure; 733 } 734 if (CRMF_DoesRequestHaveField(inCertReq, crmfSubject)) { 735 return crmf_copy_name(destSubject, inCertReq->certTemplate.subject); 736 } 737 return SECFailure; 738 } 739 740 SECStatus 741 CRMF_CertRequestGetCertTemplateSubjectUID(CRMFCertRequest *inCertReq, 742 SECItem *destSubjectUID) 743 { 744 PORT_Assert(inCertReq != NULL); 745 if (inCertReq == NULL) { 746 return SECFailure; 747 } 748 if (CRMF_DoesRequestHaveField(inCertReq, crmfSubjectUID)) { 749 return crmf_make_bitstring_copy(NULL, destSubjectUID, 750 &inCertReq->certTemplate.subjectUID); 751 } 752 return SECFailure; 753 } 754 755 SECStatus 756 CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq, 757 long *version) 758 { 759 PORT_Assert(inCertReq != NULL); 760 if (inCertReq == NULL) { 761 return SECFailure; 762 } 763 if (CRMF_DoesRequestHaveField(inCertReq, crmfVersion)) { 764 return crmf_extract_long_from_item(&inCertReq->certTemplate.version, 765 version); 766 } 767 return SECFailure; 768 } 769 770 static SECStatus 771 crmf_copy_validity(CRMFGetValidity *destValidity, 772 CRMFOptionalValidity *src) 773 { 774 SECStatus rv; 775 776 destValidity->notBefore = destValidity->notAfter = NULL; 777 if (src->notBefore.data != NULL) { 778 rv = crmf_create_prtime(&src->notBefore, 779 &destValidity->notBefore); 780 if (rv != SECSuccess) { 781 return rv; 782 } 783 } 784 if (src->notAfter.data != NULL) { 785 rv = crmf_create_prtime(&src->notAfter, 786 &destValidity->notAfter); 787 if (rv != SECSuccess) { 788 return rv; 789 } 790 } 791 return SECSuccess; 792 } 793 794 SECStatus 795 CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq, 796 CRMFGetValidity *destValidity) 797 { 798 PORT_Assert(inCertReq != NULL); 799 if (inCertReq == NULL) { 800 return SECFailure; 801 } 802 if (CRMF_DoesRequestHaveField(inCertReq, crmfValidity)) { 803 return crmf_copy_validity(destValidity, 804 inCertReq->certTemplate.validity); 805 } 806 return SECFailure; 807 } 808 809 CRMFControl * 810 CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index) 811 { 812 CRMFControl *newControl, *srcControl; 813 int numControls; 814 SECStatus rv; 815 816 PORT_Assert(inCertReq != NULL); 817 if (inCertReq == NULL) { 818 return NULL; 819 } 820 numControls = CRMF_CertRequestGetNumControls(inCertReq); 821 if (index >= numControls || index < 0) { 822 return NULL; 823 } 824 newControl = PORT_ZNew(CRMFControl); 825 if (newControl == NULL) { 826 return NULL; 827 } 828 srcControl = inCertReq->controls[index]; 829 newControl->tag = srcControl->tag; 830 rv = SECITEM_CopyItem(NULL, &newControl->derTag, &srcControl->derTag); 831 if (rv != SECSuccess) { 832 goto loser; 833 } 834 835 rv = SECITEM_CopyItem(NULL, &newControl->derValue, 836 &srcControl->derValue); 837 if (rv != SECSuccess) { 838 goto loser; 839 } 840 /* Copy over the PKIArchiveOptions stuff */ 841 switch (srcControl->tag) { 842 case SEC_OID_PKIX_REGCTRL_REGTOKEN: 843 case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR: 844 /* No further processing necessary for these types. */ 845 rv = SECSuccess; 846 break; 847 case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID: 848 case SEC_OID_PKIX_REGCTRL_PKIPUBINFO: 849 case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY: 850 /* These aren't supported yet, so no post-processing will 851 * be done at this time. But we don't want to fail in case 852 * we read in DER that has one of these options. 853 */ 854 rv = SECSuccess; 855 break; 856 case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS: 857 rv = crmf_copy_pkiarchiveoptions(NULL, 858 &newControl->value.archiveOptions, 859 &srcControl->value.archiveOptions); 860 break; 861 default: 862 rv = SECFailure; 863 } 864 if (rv != SECSuccess) { 865 goto loser; 866 } 867 return newControl; 868 loser: 869 CRMF_DestroyControl(newControl); 870 return NULL; 871 } 872 873 static SECItem * 874 crmf_copy_control_value(CRMFControl *inControl) 875 { 876 return SECITEM_DupItem(&inControl->derValue); 877 } 878 879 SECItem * 880 CRMF_ControlGetAuthenticatorControlValue(CRMFControl *inControl) 881 { 882 PORT_Assert(inControl != NULL); 883 if (inControl == NULL || 884 CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) { 885 return NULL; 886 } 887 return crmf_copy_control_value(inControl); 888 } 889 890 CRMFControlType 891 CRMF_ControlGetControlType(CRMFControl *inControl) 892 { 893 CRMFControlType retType; 894 895 PORT_Assert(inControl != NULL); 896 switch (inControl->tag) { 897 case SEC_OID_PKIX_REGCTRL_REGTOKEN: 898 retType = crmfRegTokenControl; 899 break; 900 case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR: 901 retType = crmfAuthenticatorControl; 902 break; 903 case SEC_OID_PKIX_REGCTRL_PKIPUBINFO: 904 retType = crmfPKIPublicationInfoControl; 905 break; 906 case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS: 907 retType = crmfPKIArchiveOptionsControl; 908 break; 909 case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID: 910 retType = crmfOldCertIDControl; 911 break; 912 case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY: 913 retType = crmfProtocolEncrKeyControl; 914 break; 915 default: 916 retType = crmfNoControl; 917 } 918 return retType; 919 } 920 921 CRMFPKIArchiveOptions * 922 CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl) 923 { 924 CRMFPKIArchiveOptions *newOpt = NULL; 925 SECStatus rv; 926 927 PORT_Assert(inControl != NULL); 928 if (inControl == NULL || 929 CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl) { 930 goto loser; 931 } 932 newOpt = PORT_ZNew(CRMFPKIArchiveOptions); 933 if (newOpt == NULL) { 934 goto loser; 935 } 936 rv = crmf_copy_pkiarchiveoptions(NULL, newOpt, 937 &inControl->value.archiveOptions); 938 if (rv != SECSuccess) { 939 goto loser; 940 } 941 942 loser: 943 if (newOpt != NULL) { 944 CRMF_DestroyPKIArchiveOptions(newOpt); 945 } 946 return NULL; 947 } 948 949 SECItem * 950 CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl) 951 { 952 PORT_Assert(inControl != NULL); 953 if (inControl == NULL || 954 CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) { 955 return NULL; 956 } 957 return crmf_copy_control_value(inControl); 958 ; 959 } 960 961 CRMFCertExtension * 962 CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq, 963 int index) 964 { 965 int numExtensions; 966 967 PORT_Assert(inCertReq != NULL); 968 numExtensions = CRMF_CertRequestGetNumberOfExtensions(inCertReq); 969 if (index >= numExtensions || index < 0) { 970 return NULL; 971 } 972 return crmf_copy_cert_extension(NULL, 973 inCertReq->certTemplate.extensions[index]); 974 }