|
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 "crmf.h" |
|
8 #include "crmfi.h" |
|
9 #include "secasn1.h" |
|
10 #include "keyhi.h" |
|
11 #include "cryptohi.h" |
|
12 |
|
13 #define CRMF_DEFAULT_ALLOC_SIZE 1024 |
|
14 |
|
15 SECStatus |
|
16 crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg, |
|
17 SECItem *derDest) |
|
18 { |
|
19 derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE); |
|
20 if (derDest->data == NULL) { |
|
21 return SECFailure; |
|
22 } |
|
23 derDest->len = 0; |
|
24 encoderArg->allocatedLen = CRMF_DEFAULT_ALLOC_SIZE; |
|
25 encoderArg->buffer = derDest; |
|
26 return SECSuccess; |
|
27 |
|
28 } |
|
29 |
|
30 /* Caller should release or unmark the pool, instead of doing it here. |
|
31 ** But there are NO callers of this function at present... |
|
32 */ |
|
33 SECStatus |
|
34 CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg) |
|
35 { |
|
36 SECItem *dummy; |
|
37 CRMFProofOfPossession *pop; |
|
38 PLArenaPool *poolp; |
|
39 void *mark; |
|
40 |
|
41 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); |
|
42 poolp = inCertReqMsg->poolp; |
|
43 mark = PORT_ArenaMark(poolp); |
|
44 if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) { |
|
45 return SECFailure; |
|
46 } |
|
47 pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); |
|
48 if (pop == NULL) { |
|
49 goto loser; |
|
50 } |
|
51 pop->popUsed = crmfRAVerified; |
|
52 pop->popChoice.raVerified.data = NULL; |
|
53 pop->popChoice.raVerified.len = 0; |
|
54 inCertReqMsg->pop = pop; |
|
55 dummy = SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP), |
|
56 &(pop->popChoice.raVerified), |
|
57 CRMFRAVerifiedTemplate); |
|
58 return SECSuccess; |
|
59 loser: |
|
60 PORT_ArenaRelease(poolp, mark); |
|
61 return SECFailure; |
|
62 } |
|
63 |
|
64 static SECOidTag |
|
65 crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey) |
|
66 { |
|
67 /* maintain backward compatibility with older |
|
68 * implementations */ |
|
69 if (inPubKey->keyType == rsaKey) { |
|
70 return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; |
|
71 } |
|
72 return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN); |
|
73 } |
|
74 |
|
75 static SECAlgorithmID* |
|
76 crmf_create_poposignkey_algid(PLArenaPool *poolp, |
|
77 SECKEYPublicKey *inPubKey) |
|
78 { |
|
79 SECAlgorithmID *algID; |
|
80 SECOidTag tag; |
|
81 SECStatus rv; |
|
82 void *mark; |
|
83 |
|
84 mark = PORT_ArenaMark(poolp); |
|
85 algID = PORT_ArenaZNew(poolp, SECAlgorithmID); |
|
86 if (algID == NULL) { |
|
87 goto loser; |
|
88 } |
|
89 tag = crmf_get_key_sign_tag(inPubKey); |
|
90 if (tag == SEC_OID_UNKNOWN) { |
|
91 goto loser; |
|
92 } |
|
93 rv = SECOID_SetAlgorithmID(poolp, algID, tag, NULL); |
|
94 if (rv != SECSuccess) { |
|
95 goto loser; |
|
96 } |
|
97 PORT_ArenaUnmark(poolp, mark); |
|
98 return algID; |
|
99 loser: |
|
100 PORT_ArenaRelease(poolp, mark); |
|
101 return NULL; |
|
102 } |
|
103 |
|
104 static CRMFPOPOSigningKeyInput* |
|
105 crmf_create_poposigningkeyinput(PLArenaPool *poolp, CERTCertificate *inCert, |
|
106 CRMFMACPasswordCallback fn, void *arg) |
|
107 { |
|
108 /* PSM isn't going to do this, so we'll fail here for now.*/ |
|
109 return NULL; |
|
110 } |
|
111 |
|
112 void |
|
113 crmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len, |
|
114 int depth, SEC_ASN1EncodingPart data_kind) |
|
115 { |
|
116 struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg; |
|
117 unsigned char *cursor; |
|
118 |
|
119 if (encoderArg->buffer->len + len > encoderArg->allocatedLen) { |
|
120 int newSize = encoderArg->buffer->len+CRMF_DEFAULT_ALLOC_SIZE; |
|
121 void *dummy = PORT_Realloc(encoderArg->buffer->data, newSize); |
|
122 if (dummy == NULL) { |
|
123 /* I really want to return an error code here */ |
|
124 PORT_Assert(0); |
|
125 return; |
|
126 } |
|
127 encoderArg->buffer->data = dummy; |
|
128 encoderArg->allocatedLen = newSize; |
|
129 } |
|
130 cursor = &(encoderArg->buffer->data[encoderArg->buffer->len]); |
|
131 PORT_Memcpy (cursor, buf, len); |
|
132 encoderArg->buffer->len += len; |
|
133 } |
|
134 |
|
135 static SECStatus |
|
136 crmf_encode_certreq(CRMFCertRequest *inCertReq, SECItem *derDest) |
|
137 { |
|
138 struct crmfEncoderArg encoderArg; |
|
139 SECStatus rv; |
|
140 |
|
141 rv = crmf_init_encoder_callback_arg (&encoderArg, derDest); |
|
142 if (rv != SECSuccess) { |
|
143 return SECFailure; |
|
144 } |
|
145 return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate, |
|
146 crmf_generic_encoder_callback, &encoderArg); |
|
147 } |
|
148 |
|
149 static SECStatus |
|
150 crmf_sign_certreq(PLArenaPool *poolp, |
|
151 CRMFPOPOSigningKey *crmfSignKey, |
|
152 CRMFCertRequest *certReq, |
|
153 SECKEYPrivateKey *inKey, |
|
154 SECAlgorithmID *inAlgId) |
|
155 { |
|
156 SECItem derCertReq = { siBuffer, NULL, 0 }; |
|
157 SECItem certReqSig = { siBuffer, NULL, 0 }; |
|
158 SECStatus rv = SECSuccess; |
|
159 |
|
160 rv = crmf_encode_certreq(certReq, &derCertReq); |
|
161 if (rv != SECSuccess) { |
|
162 goto loser; |
|
163 } |
|
164 rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len, |
|
165 inKey,SECOID_GetAlgorithmTag(inAlgId)); |
|
166 if (rv != SECSuccess) { |
|
167 goto loser; |
|
168 } |
|
169 |
|
170 /* Now make it a part of the POPOSigningKey */ |
|
171 rv = SECITEM_CopyItem(poolp, &(crmfSignKey->signature), &certReqSig); |
|
172 /* Convert this length to number of bits */ |
|
173 crmfSignKey->signature.len <<= 3; |
|
174 |
|
175 loser: |
|
176 if (derCertReq.data != NULL) { |
|
177 PORT_Free(derCertReq.data); |
|
178 } |
|
179 if (certReqSig.data != NULL) { |
|
180 PORT_Free(certReqSig.data); |
|
181 } |
|
182 return rv; |
|
183 } |
|
184 |
|
185 static SECStatus |
|
186 crmf_create_poposignkey(PLArenaPool *poolp, |
|
187 CRMFCertReqMsg *inCertReqMsg, |
|
188 CRMFPOPOSigningKeyInput *signKeyInput, |
|
189 SECKEYPrivateKey *inPrivKey, |
|
190 SECAlgorithmID *inAlgID, |
|
191 CRMFPOPOSigningKey *signKey) |
|
192 { |
|
193 CRMFCertRequest *certReq; |
|
194 void *mark; |
|
195 PRBool useSignKeyInput; |
|
196 SECStatus rv; |
|
197 |
|
198 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL); |
|
199 mark = PORT_ArenaMark(poolp); |
|
200 if (signKey == NULL) { |
|
201 goto loser; |
|
202 } |
|
203 certReq = inCertReqMsg->certReq; |
|
204 useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq,crmfSubject) && |
|
205 CRMF_DoesRequestHaveField(certReq,crmfPublicKey)); |
|
206 |
|
207 if (useSignKeyInput) { |
|
208 goto loser; |
|
209 } else { |
|
210 rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID); |
|
211 if (rv != SECSuccess) { |
|
212 goto loser; |
|
213 } |
|
214 } |
|
215 PORT_ArenaUnmark(poolp,mark); |
|
216 return SECSuccess; |
|
217 loser: |
|
218 PORT_ArenaRelease(poolp,mark); |
|
219 return SECFailure; |
|
220 } |
|
221 |
|
222 SECStatus |
|
223 CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, |
|
224 SECKEYPrivateKey *inPrivKey, |
|
225 SECKEYPublicKey *inPubKey, |
|
226 CERTCertificate *inCertForInput, |
|
227 CRMFMACPasswordCallback fn, |
|
228 void *arg) |
|
229 { |
|
230 SECAlgorithmID *algID; |
|
231 PLArenaPool *poolp; |
|
232 SECItem derTemp = {siBuffer, NULL, 0}; |
|
233 void *mark; |
|
234 SECStatus rv; |
|
235 CRMFPOPOSigningKeyInput *signKeyInput = NULL; |
|
236 CRMFCertRequest *certReq; |
|
237 CRMFProofOfPossession *pop; |
|
238 struct crmfEncoderArg encoderArg; |
|
239 |
|
240 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL && |
|
241 inCertReqMsg->pop == NULL); |
|
242 certReq = inCertReqMsg->certReq; |
|
243 if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice || |
|
244 !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) { |
|
245 return SECFailure; |
|
246 } |
|
247 poolp = inCertReqMsg->poolp; |
|
248 mark = PORT_ArenaMark(poolp); |
|
249 algID = crmf_create_poposignkey_algid(poolp, inPubKey); |
|
250 |
|
251 if(!CRMF_DoesRequestHaveField(certReq,crmfSubject)) { |
|
252 signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput, |
|
253 fn, arg); |
|
254 if (signKeyInput == NULL) { |
|
255 goto loser; |
|
256 } |
|
257 } |
|
258 |
|
259 pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); |
|
260 if (pop == NULL) { |
|
261 goto loser; |
|
262 } |
|
263 |
|
264 rv = crmf_create_poposignkey(poolp, inCertReqMsg, |
|
265 signKeyInput, inPrivKey, algID, |
|
266 &(pop->popChoice.signature)); |
|
267 if (rv != SECSuccess) { |
|
268 goto loser; |
|
269 } |
|
270 |
|
271 pop->popUsed = crmfSignature; |
|
272 pop->popChoice.signature.algorithmIdentifier = algID; |
|
273 inCertReqMsg->pop = pop; |
|
274 |
|
275 rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp); |
|
276 if (rv != SECSuccess) { |
|
277 goto loser; |
|
278 } |
|
279 rv = SEC_ASN1Encode(&pop->popChoice.signature, |
|
280 CRMFPOPOSigningKeyTemplate, |
|
281 crmf_generic_encoder_callback, &encoderArg); |
|
282 if (rv != SECSuccess) { |
|
283 goto loser; |
|
284 } |
|
285 rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp); |
|
286 if (rv != SECSuccess) { |
|
287 goto loser; |
|
288 } |
|
289 PORT_Free (derTemp.data); |
|
290 PORT_ArenaUnmark(poolp,mark); |
|
291 return SECSuccess; |
|
292 |
|
293 loser: |
|
294 PORT_ArenaRelease(poolp,mark); |
|
295 if (derTemp.data != NULL) { |
|
296 PORT_Free(derTemp.data); |
|
297 } |
|
298 return SECFailure; |
|
299 } |
|
300 |
|
301 static const SEC_ASN1Template* |
|
302 crmf_get_popoprivkey_subtemplate(CRMFPOPOPrivKey *inPrivKey) |
|
303 { |
|
304 const SEC_ASN1Template *retTemplate = NULL; |
|
305 |
|
306 switch (inPrivKey->messageChoice) { |
|
307 case crmfThisMessage: |
|
308 retTemplate = CRMFThisMessageTemplate; |
|
309 break; |
|
310 case crmfSubsequentMessage: |
|
311 retTemplate = CRMFSubsequentMessageTemplate; |
|
312 break; |
|
313 case crmfDHMAC: |
|
314 retTemplate = CRMFDHMACTemplate; |
|
315 break; |
|
316 default: |
|
317 retTemplate = NULL; |
|
318 } |
|
319 return retTemplate; |
|
320 } |
|
321 |
|
322 static SECStatus |
|
323 crmf_encode_popoprivkey(PLArenaPool *poolp, |
|
324 CRMFCertReqMsg *inCertReqMsg, |
|
325 CRMFPOPOPrivKey *popoPrivKey, |
|
326 const SEC_ASN1Template *privKeyTemplate) |
|
327 { |
|
328 struct crmfEncoderArg encoderArg; |
|
329 SECItem derTemp = { siBuffer, NULL, 0 }; |
|
330 SECStatus rv; |
|
331 void *mark; |
|
332 const SEC_ASN1Template *subDerTemplate; |
|
333 |
|
334 mark = PORT_ArenaMark(poolp); |
|
335 rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp); |
|
336 if (rv != SECSuccess) { |
|
337 goto loser; |
|
338 } |
|
339 subDerTemplate = crmf_get_popoprivkey_subtemplate(popoPrivKey); |
|
340 /* We've got a union, so a pointer to one item is a pointer to |
|
341 * all the items in the union. |
|
342 */ |
|
343 rv = SEC_ASN1Encode(&popoPrivKey->message.thisMessage, |
|
344 subDerTemplate, |
|
345 crmf_generic_encoder_callback, &encoderArg); |
|
346 if (rv != SECSuccess) { |
|
347 goto loser; |
|
348 } |
|
349 if (encoderArg.allocatedLen > derTemp.len+2) { |
|
350 void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2); |
|
351 if (dummy == NULL) { |
|
352 goto loser; |
|
353 } |
|
354 derTemp.data = dummy; |
|
355 } |
|
356 PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len); |
|
357 /* I couldn't figure out how to get the ASN1 encoder to implicitly |
|
358 * tag an implicitly tagged der blob. So I'm putting in the outter- |
|
359 * most tag myself. -javi |
|
360 */ |
|
361 derTemp.data[0] = (unsigned char)privKeyTemplate->kind; |
|
362 derTemp.data[1] = (unsigned char)derTemp.len; |
|
363 derTemp.len += 2; |
|
364 rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp); |
|
365 if (rv != SECSuccess) { |
|
366 goto loser; |
|
367 } |
|
368 PORT_Free(derTemp.data); |
|
369 PORT_ArenaUnmark(poolp, mark); |
|
370 return SECSuccess; |
|
371 loser: |
|
372 PORT_ArenaRelease(poolp, mark); |
|
373 if (derTemp.data) { |
|
374 PORT_Free(derTemp.data); |
|
375 } |
|
376 return SECFailure; |
|
377 } |
|
378 |
|
379 static const SEC_ASN1Template* |
|
380 crmf_get_template_for_privkey(CRMFPOPChoice inChoice) |
|
381 { |
|
382 switch (inChoice) { |
|
383 case crmfKeyAgreement: |
|
384 return CRMFPOPOKeyAgreementTemplate; |
|
385 case crmfKeyEncipherment: |
|
386 return CRMFPOPOKeyEnciphermentTemplate; |
|
387 default: |
|
388 break; |
|
389 } |
|
390 return NULL; |
|
391 } |
|
392 |
|
393 static SECStatus |
|
394 crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, |
|
395 CRMFPOPChoice inChoice) |
|
396 { |
|
397 PLArenaPool *poolp; |
|
398 void *mark; |
|
399 CRMFPOPOPrivKey *popoPrivKey; |
|
400 CRMFProofOfPossession *pop; |
|
401 SECStatus rv; |
|
402 |
|
403 PORT_Assert(inCertReqMsg != NULL && encPrivKey != NULL); |
|
404 poolp = inCertReqMsg->poolp; |
|
405 mark = PORT_ArenaMark(poolp); |
|
406 pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); |
|
407 if (pop == NULL) { |
|
408 goto loser; |
|
409 } |
|
410 pop->popUsed = inChoice; |
|
411 /* popChoice is a union, so getting a pointer to one |
|
412 * field gives me a pointer to the other fields as |
|
413 * well. This in essence points to both |
|
414 * pop->popChoice.keyEncipherment and |
|
415 * pop->popChoice.keyAgreement |
|
416 */ |
|
417 popoPrivKey = &pop->popChoice.keyEncipherment; |
|
418 |
|
419 rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.thisMessage), |
|
420 encPrivKey); |
|
421 if (rv != SECSuccess) { |
|
422 goto loser; |
|
423 } |
|
424 popoPrivKey->message.thisMessage.len <<= 3; |
|
425 popoPrivKey->messageChoice = crmfThisMessage; |
|
426 inCertReqMsg->pop = pop; |
|
427 rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, |
|
428 crmf_get_template_for_privkey(inChoice)); |
|
429 if (rv != SECSuccess) { |
|
430 goto loser; |
|
431 } |
|
432 PORT_ArenaUnmark(poolp, mark); |
|
433 return SECSuccess; |
|
434 |
|
435 loser: |
|
436 PORT_ArenaRelease(poolp, mark); |
|
437 return SECFailure; |
|
438 } |
|
439 |
|
440 static SECStatus |
|
441 crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, |
|
442 CRMFPOPChoice inChoice) |
|
443 { |
|
444 PLArenaPool *poolp; |
|
445 void *mark; |
|
446 CRMFPOPOPrivKey *popoPrivKey; |
|
447 CRMFProofOfPossession *pop; |
|
448 SECStatus rv; |
|
449 |
|
450 PORT_Assert(inCertReqMsg != NULL && dhmac != NULL); |
|
451 poolp = inCertReqMsg->poolp; |
|
452 mark = PORT_ArenaMark(poolp); |
|
453 pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); |
|
454 if (pop == NULL) { |
|
455 goto loser; |
|
456 } |
|
457 pop->popUsed = inChoice; |
|
458 popoPrivKey = &pop->popChoice.keyAgreement; |
|
459 |
|
460 rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC), |
|
461 dhmac); |
|
462 if (rv != SECSuccess) { |
|
463 goto loser; |
|
464 } |
|
465 popoPrivKey->message.dhMAC.len <<= 3; |
|
466 popoPrivKey->messageChoice = crmfDHMAC; |
|
467 inCertReqMsg->pop = pop; |
|
468 rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, |
|
469 crmf_get_template_for_privkey(inChoice)); |
|
470 if (rv != SECSuccess) { |
|
471 goto loser; |
|
472 } |
|
473 PORT_ArenaUnmark(poolp, mark); |
|
474 return SECSuccess; |
|
475 |
|
476 loser: |
|
477 PORT_ArenaRelease(poolp, mark); |
|
478 return SECFailure; |
|
479 } |
|
480 |
|
481 static SECStatus |
|
482 crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg, |
|
483 CRMFSubseqMessOptions subsequentMessage, |
|
484 CRMFPOPChoice inChoice) |
|
485 { |
|
486 void *mark; |
|
487 PLArenaPool *poolp; |
|
488 CRMFProofOfPossession *pop; |
|
489 CRMFPOPOPrivKey *popoPrivKey; |
|
490 SECStatus rv; |
|
491 const SEC_ASN1Template *privKeyTemplate; |
|
492 |
|
493 if (subsequentMessage == crmfNoSubseqMess) { |
|
494 return SECFailure; |
|
495 } |
|
496 poolp = inCertReqMsg->poolp; |
|
497 mark = PORT_ArenaMark(poolp); |
|
498 pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); |
|
499 if (pop == NULL) { |
|
500 goto loser; |
|
501 } |
|
502 |
|
503 pop->popUsed = inChoice; |
|
504 /* |
|
505 * We have a union, so a pointer to one member of the union |
|
506 * is also a member to another member of that same union. |
|
507 */ |
|
508 popoPrivKey = &pop->popChoice.keyEncipherment; |
|
509 |
|
510 switch (subsequentMessage) { |
|
511 case crmfEncrCert: |
|
512 rv = crmf_encode_integer(poolp, |
|
513 &(popoPrivKey->message.subsequentMessage), |
|
514 0); |
|
515 break; |
|
516 case crmfChallengeResp: |
|
517 rv = crmf_encode_integer(poolp, |
|
518 &(popoPrivKey->message.subsequentMessage), |
|
519 1); |
|
520 break; |
|
521 default: |
|
522 goto loser; |
|
523 } |
|
524 if (rv != SECSuccess) { |
|
525 goto loser; |
|
526 } |
|
527 popoPrivKey->messageChoice = crmfSubsequentMessage; |
|
528 privKeyTemplate = crmf_get_template_for_privkey(inChoice); |
|
529 inCertReqMsg->pop = pop; |
|
530 rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, |
|
531 privKeyTemplate); |
|
532 |
|
533 if (rv != SECSuccess) { |
|
534 goto loser; |
|
535 } |
|
536 PORT_ArenaUnmark(poolp, mark); |
|
537 return SECSuccess; |
|
538 loser: |
|
539 PORT_ArenaRelease(poolp, mark); |
|
540 return SECFailure; |
|
541 } |
|
542 |
|
543 SECStatus |
|
544 CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg, |
|
545 CRMFPOPOPrivKeyChoice inKeyChoice, |
|
546 CRMFSubseqMessOptions subseqMess, |
|
547 SECItem *encPrivKey) |
|
548 { |
|
549 SECStatus rv; |
|
550 |
|
551 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); |
|
552 if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) { |
|
553 return SECFailure; |
|
554 } |
|
555 switch (inKeyChoice) { |
|
556 case crmfThisMessage: |
|
557 rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey, |
|
558 crmfKeyEncipherment); |
|
559 break; |
|
560 case crmfSubsequentMessage: |
|
561 rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, |
|
562 crmfKeyEncipherment); |
|
563 break; |
|
564 case crmfDHMAC: |
|
565 default: |
|
566 rv = SECFailure; |
|
567 } |
|
568 return rv; |
|
569 } |
|
570 |
|
571 SECStatus |
|
572 CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, |
|
573 CRMFPOPOPrivKeyChoice inKeyChoice, |
|
574 CRMFSubseqMessOptions subseqMess, |
|
575 SECItem *encPrivKey) |
|
576 { |
|
577 SECStatus rv; |
|
578 |
|
579 PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); |
|
580 switch (inKeyChoice) { |
|
581 case crmfThisMessage: |
|
582 rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey, |
|
583 crmfKeyAgreement); |
|
584 break; |
|
585 case crmfSubsequentMessage: |
|
586 rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, |
|
587 crmfKeyAgreement); |
|
588 break; |
|
589 case crmfDHMAC: |
|
590 /* In this case encPrivKey should be the calculated dhMac |
|
591 * as specified in RFC 2511 */ |
|
592 rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey, |
|
593 crmfKeyAgreement); |
|
594 break; |
|
595 default: |
|
596 rv = SECFailure; |
|
597 } |
|
598 return rv; |
|
599 } |
|
600 |