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
CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey * inEncrKey)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 *
CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey * inEncrKey)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 *
crmf_get_encvalue_bitstring(SECItem * srcItem)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 *
CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue * inEncValue)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 *
CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue * inEncrValue)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 *
crmf_get_encvalue_algid(SECAlgorithmID * srcAlg)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 *
CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue * inEncValue)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 *
CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue * inEncValue)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 *
CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue * inEncValue)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 *
CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue * inEncValue)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
CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions * inOpt,PRBool * destVal)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 *
CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions * inOpts)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 *
CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions * inOptions)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
CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions * inOptions)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
crmf_extract_long_from_item(SECItem * intItem,long * destLong)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
CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey * inKey,CRMFSubseqMessOptions * destOpt)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
CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey * inPrivKey)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
CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey * inKey,SECItem * destMAC)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
CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey * inKey,SECItem * destString)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 *
CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey * inSignKey)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 *
CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey * inSignKey)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 *
CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey * inSignKey)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
crmf_copy_poposigningkey(PLArenaPool * poolp,CRMFPOPOSigningKey * inPopoSignKey,CRMFPOPOSigningKey * destPopoSignKey)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
crmf_copy_popoprivkey(PLArenaPool * poolp,CRMFPOPOPrivKey * srcPrivKey,CRMFPOPOPrivKey * destPrivKey)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 *
crmf_copy_pop(PLArenaPool * poolp,CRMFProofOfPossession * srcPOP)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 *
crmf_copy_cert_req_msg(CRMFCertReqMsg * srcReqMsg)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 *
CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages * inReqMsgs,int index)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
CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages * inCertReqMsgs)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 *
CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg * inCertReqMsg)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
CRMF_CertReqMsgGetID(CRMFCertReqMsg * inCertReqMsg,long * destID)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
CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg * inCertReqMsg,CRMFPOPOPrivKey ** destKey)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
CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg * inCertReqMsg,CRMFPOPOPrivKey ** destKey)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
CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg * inCertReqMsg,CRMFPOPOSigningKey ** destKey)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
crmf_copy_name(CERTName * destName,CERTName * srcName)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
CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest * inCertReq,CERTName * destIssuer)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
CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest * inCertReq,SECItem * destIssuerUID)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
CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest * inCertReq,CERTSubjectPublicKeyInfo * destPublicKey)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
CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest * inCertReq,long * serialNumber)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
CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest * inCertReq,SECAlgorithmID * destAlg)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
CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest * inCertReq,CERTName * destSubject)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
CRMF_CertRequestGetCertTemplateSubjectUID(CRMFCertRequest * inCertReq,SECItem * destSubjectUID)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
CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest * inCertReq,long * version)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
crmf_copy_validity(CRMFGetValidity * destValidity,CRMFOptionalValidity * src)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
CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest * inCertReq,CRMFGetValidity * destValidity)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 *
CRMF_CertRequestGetControlAtIndex(CRMFCertRequest * inCertReq,int index)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 *
crmf_copy_control_value(CRMFControl * inControl)874 crmf_copy_control_value(CRMFControl *inControl)
875 {
876 return SECITEM_DupItem(&inControl->derValue);
877 }
878
879 SECItem *
CRMF_ControlGetAuthenticatorControlValue(CRMFControl * inControl)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
CRMF_ControlGetControlType(CRMFControl * inControl)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 *
CRMF_ControlGetPKIArchiveOptions(CRMFControl * inControl)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 *
CRMF_ControlGetRegTokenControlValue(CRMFControl * inControl)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 *
CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest * inCertReq,int index)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 }
975