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