File: | s/lib/pkcs7/p7common.c |
Warning: | line 451, column 5 Value stored to 'rv' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | |
5 | /* |
6 | * PKCS7 implementation -- the exported parts that are used whether |
7 | * creating or decoding. |
8 | */ |
9 | |
10 | #include "p7local.h" |
11 | |
12 | #include "cert.h" |
13 | #include "secitem.h" |
14 | #include "secoid.h" |
15 | #include "pk11func.h" |
16 | |
17 | /* |
18 | * Find out (saving pointer to lookup result for future reference) |
19 | * and return the inner content type. |
20 | */ |
21 | SECOidTag |
22 | SEC_PKCS7ContentType(SEC_PKCS7ContentInfo *cinfo) |
23 | { |
24 | if (cinfo->contentTypeTag == NULL((void*)0)) |
25 | cinfo->contentTypeTag = SECOID_FindOIDSECOID_FindOID_Util(&(cinfo->contentType)); |
26 | |
27 | if (cinfo->contentTypeTag == NULL((void*)0)) |
28 | return SEC_OID_UNKNOWN; |
29 | |
30 | return cinfo->contentTypeTag->offset; |
31 | } |
32 | |
33 | /* |
34 | * Destroy a PKCS7 contentInfo and all of its sub-pieces. |
35 | */ |
36 | void |
37 | SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo) |
38 | { |
39 | SECOidTag kind; |
40 | CERTCertificate **certs; |
41 | CERTCertificateList **certlists; |
42 | SEC_PKCS7SignerInfo **signerinfos; |
43 | SEC_PKCS7RecipientInfo **recipientinfos; |
44 | |
45 | PORT_Assert(cinfo->refCount > 0)((cinfo->refCount > 0)?((void)0):PR_Assert("cinfo->refCount > 0" ,"p7common.c",45)); |
46 | if (cinfo->refCount <= 0) |
47 | return; |
48 | |
49 | cinfo->refCount--; |
50 | if (cinfo->refCount > 0) |
51 | return; |
52 | |
53 | certs = NULL((void*)0); |
54 | certlists = NULL((void*)0); |
55 | recipientinfos = NULL((void*)0); |
56 | signerinfos = NULL((void*)0); |
57 | |
58 | kind = SEC_PKCS7ContentType(cinfo); |
59 | switch (kind) { |
60 | case SEC_OID_PKCS7_ENVELOPED_DATA: { |
61 | SEC_PKCS7EnvelopedData *edp; |
62 | |
63 | edp = cinfo->content.envelopedData; |
64 | if (edp != NULL((void*)0)) { |
65 | recipientinfos = edp->recipientInfos; |
66 | } |
67 | } break; |
68 | case SEC_OID_PKCS7_SIGNED_DATA: { |
69 | SEC_PKCS7SignedData *sdp; |
70 | |
71 | sdp = cinfo->content.signedData; |
72 | if (sdp != NULL((void*)0)) { |
73 | certs = sdp->certs; |
74 | certlists = sdp->certLists; |
75 | signerinfos = sdp->signerInfos; |
76 | } |
77 | } break; |
78 | case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { |
79 | SEC_PKCS7SignedAndEnvelopedData *saedp; |
80 | |
81 | saedp = cinfo->content.signedAndEnvelopedData; |
82 | if (saedp != NULL((void*)0)) { |
83 | certs = saedp->certs; |
84 | certlists = saedp->certLists; |
85 | recipientinfos = saedp->recipientInfos; |
86 | signerinfos = saedp->signerInfos; |
87 | if (saedp->sigKey != NULL((void*)0)) |
88 | PK11_FreeSymKey(saedp->sigKey); |
89 | } |
90 | } break; |
91 | default: |
92 | /* XXX Anything else that needs to be "manually" freed/destroyed? */ |
93 | break; |
94 | } |
95 | |
96 | if (certs != NULL((void*)0)) { |
97 | CERTCertificate *cert; |
98 | |
99 | while ((cert = *certs++) != NULL((void*)0)) { |
100 | CERT_DestroyCertificate(cert); |
101 | } |
102 | } |
103 | |
104 | if (certlists != NULL((void*)0)) { |
105 | CERTCertificateList *certlist; |
106 | |
107 | while ((certlist = *certlists++) != NULL((void*)0)) { |
108 | CERT_DestroyCertificateList(certlist); |
109 | } |
110 | } |
111 | |
112 | if (recipientinfos != NULL((void*)0)) { |
113 | SEC_PKCS7RecipientInfo *ri; |
114 | |
115 | while ((ri = *recipientinfos++) != NULL((void*)0)) { |
116 | if (ri->cert != NULL((void*)0)) |
117 | CERT_DestroyCertificate(ri->cert); |
118 | } |
119 | } |
120 | |
121 | if (signerinfos != NULL((void*)0)) { |
122 | SEC_PKCS7SignerInfo *si; |
123 | |
124 | while ((si = *signerinfos++) != NULL((void*)0)) { |
125 | if (si->cert != NULL((void*)0)) |
126 | CERT_DestroyCertificate(si->cert); |
127 | if (si->certList != NULL((void*)0)) |
128 | CERT_DestroyCertificateList(si->certList); |
129 | } |
130 | } |
131 | |
132 | if (cinfo->poolp != NULL((void*)0)) { |
133 | PORT_FreeArenaPORT_FreeArena_Util(cinfo->poolp, PR_FALSE0); /* XXX clear it? */ |
134 | } |
135 | } |
136 | |
137 | /* |
138 | * Return a copy of the given contentInfo. The copy may be virtual |
139 | * or may be real -- either way, the result needs to be passed to |
140 | * SEC_PKCS7DestroyContentInfo later (as does the original). |
141 | */ |
142 | SEC_PKCS7ContentInfo * |
143 | SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo) |
144 | { |
145 | if (cinfo == NULL((void*)0)) |
146 | return NULL((void*)0); |
147 | |
148 | PORT_Assert(cinfo->refCount > 0)((cinfo->refCount > 0)?((void)0):PR_Assert("cinfo->refCount > 0" ,"p7common.c",148)); |
149 | |
150 | if (cinfo->created) { |
151 | /* |
152 | * Want to do a real copy of these; otherwise subsequent |
153 | * changes made to either copy are likely to be a surprise. |
154 | * XXX I suspect that this will not actually be called for yet, |
155 | * which is why the assert, so to notice if it is... |
156 | */ |
157 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","p7common.c",157)); |
158 | /* |
159 | * XXX Create a new pool here, and copy everything from |
160 | * within. For cert stuff, need to call the appropriate |
161 | * copy functions, etc. |
162 | */ |
163 | } |
164 | |
165 | cinfo->refCount++; |
166 | return cinfo; |
167 | } |
168 | |
169 | /* |
170 | * Return a pointer to the actual content. In the case of those types |
171 | * which are encrypted, this returns the *plain* content. |
172 | * XXX Needs revisiting if/when we handle nested encrypted types. |
173 | */ |
174 | SECItem * |
175 | SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo) |
176 | { |
177 | SECOidTag kind; |
178 | |
179 | kind = SEC_PKCS7ContentType(cinfo); |
180 | switch (kind) { |
181 | case SEC_OID_PKCS7_DATA: |
182 | return cinfo->content.data; |
183 | case SEC_OID_PKCS7_DIGESTED_DATA: { |
184 | SEC_PKCS7DigestedData *digd; |
185 | |
186 | digd = cinfo->content.digestedData; |
187 | if (digd == NULL((void*)0)) |
188 | break; |
189 | return SEC_PKCS7GetContent(&(digd->contentInfo)); |
190 | } |
191 | case SEC_OID_PKCS7_ENCRYPTED_DATA: { |
192 | SEC_PKCS7EncryptedData *encd; |
193 | |
194 | encd = cinfo->content.encryptedData; |
195 | if (encd == NULL((void*)0)) |
196 | break; |
197 | return &(encd->encContentInfo.plainContent); |
198 | } |
199 | case SEC_OID_PKCS7_ENVELOPED_DATA: { |
200 | SEC_PKCS7EnvelopedData *envd; |
201 | |
202 | envd = cinfo->content.envelopedData; |
203 | if (envd == NULL((void*)0)) |
204 | break; |
205 | return &(envd->encContentInfo.plainContent); |
206 | } |
207 | case SEC_OID_PKCS7_SIGNED_DATA: { |
208 | SEC_PKCS7SignedData *sigd; |
209 | |
210 | sigd = cinfo->content.signedData; |
211 | if (sigd == NULL((void*)0)) |
212 | break; |
213 | return SEC_PKCS7GetContent(&(sigd->contentInfo)); |
214 | } |
215 | case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { |
216 | SEC_PKCS7SignedAndEnvelopedData *saed; |
217 | |
218 | saed = cinfo->content.signedAndEnvelopedData; |
219 | if (saed == NULL((void*)0)) |
220 | break; |
221 | return &(saed->encContentInfo.plainContent); |
222 | } |
223 | default: |
224 | PORT_Assert(0)((0)?((void)0):PR_Assert("0","p7common.c",224)); |
225 | break; |
226 | } |
227 | |
228 | return NULL((void*)0); |
229 | } |
230 | |
231 | /* |
232 | * XXX Fix the placement and formatting of the |
233 | * following routines (i.e. make them consistent with the rest of |
234 | * the pkcs7 code -- I think some/many belong in other files and |
235 | * they all need a formatting/style rehaul) |
236 | */ |
237 | |
238 | /* retrieve the algorithm identifier for encrypted data. |
239 | * the identifier returned is a copy of the algorithm identifier |
240 | * in the content info and needs to be freed after being used. |
241 | * |
242 | * cinfo is the content info for which to retrieve the |
243 | * encryption algorithm. |
244 | * |
245 | * if the content info is not encrypted data or an error |
246 | * occurs NULL is returned. |
247 | */ |
248 | SECAlgorithmID * |
249 | SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo) |
250 | { |
251 | SECAlgorithmID *alg = 0; |
252 | switch (SEC_PKCS7ContentType(cinfo)) { |
253 | case SEC_OID_PKCS7_ENCRYPTED_DATA: |
254 | alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg; |
255 | break; |
256 | case SEC_OID_PKCS7_ENVELOPED_DATA: |
257 | alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg; |
258 | break; |
259 | case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: |
260 | alg = &cinfo->content.signedAndEnvelopedData |
261 | ->encContentInfo.contentEncAlg; |
262 | break; |
263 | default: |
264 | alg = 0; |
265 | break; |
266 | } |
267 | |
268 | return alg; |
269 | } |
270 | |
271 | /* set the content of the content info. For data content infos, |
272 | * the data is set. For encrytped content infos, the plainContent |
273 | * is set, and is expected to be encrypted later. |
274 | * |
275 | * cinfo is the content info where the data will be set |
276 | * |
277 | * buf is a buffer of the data to set |
278 | * |
279 | * len is the length of the data being set. |
280 | * |
281 | * in the event of an error, SECFailure is returned. SECSuccess |
282 | * indicates the content was successfully set. |
283 | */ |
284 | SECStatus |
285 | SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo, |
286 | const char *buf, |
287 | unsigned long len) |
288 | { |
289 | SECOidTag cinfo_type; |
290 | SECStatus rv; |
291 | SECItem content; |
292 | SECOidData *contentTypeTag = NULL((void*)0); |
293 | |
294 | content.type = siBuffer; |
295 | content.data = (unsigned char *)buf; |
296 | content.len = len; |
297 | |
298 | cinfo_type = SEC_PKCS7ContentType(cinfo); |
299 | |
300 | /* set inner content */ |
301 | switch (cinfo_type) { |
302 | case SEC_OID_PKCS7_SIGNED_DATA: |
303 | if (content.len > 0) { |
304 | /* we "leak" the old content here, but as it's all in the pool */ |
305 | /* it does not really matter */ |
306 | |
307 | /* create content item if necessary */ |
308 | if (cinfo->content.signedData->contentInfo.content.data == NULL((void*)0)) |
309 | cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItemSECITEM_AllocItem_Util(cinfo->poolp, NULL((void*)0), 0); |
310 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(cinfo->poolp, |
311 | cinfo->content.signedData->contentInfo.content.data, |
312 | &content); |
313 | } else { |
314 | cinfo->content.signedData->contentInfo.content.data->data = NULL((void*)0); |
315 | cinfo->content.signedData->contentInfo.content.data->len = 0; |
316 | rv = SECSuccess; |
317 | } |
318 | if (rv == SECFailure) |
319 | goto loser; |
320 | |
321 | break; |
322 | case SEC_OID_PKCS7_ENCRYPTED_DATA: |
323 | /* XXX this forces the inner content type to be "data" */ |
324 | /* do we really want to override without asking or reason? */ |
325 | contentTypeTag = SECOID_FindOIDByTagSECOID_FindOIDByTag_Util(SEC_OID_PKCS7_DATA); |
326 | if (contentTypeTag == NULL((void*)0)) |
327 | goto loser; |
328 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(cinfo->poolp, |
329 | &(cinfo->content.encryptedData->encContentInfo.contentType), |
330 | &(contentTypeTag->oid)); |
331 | if (rv == SECFailure) |
332 | goto loser; |
333 | if (content.len > 0) { |
334 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(cinfo->poolp, |
335 | &(cinfo->content.encryptedData->encContentInfo.plainContent), |
336 | &content); |
337 | } else { |
338 | cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL((void*)0); |
339 | cinfo->content.encryptedData->encContentInfo.encContent.data = NULL((void*)0); |
340 | cinfo->content.encryptedData->encContentInfo.plainContent.len = 0; |
341 | cinfo->content.encryptedData->encContentInfo.encContent.len = 0; |
342 | rv = SECSuccess; |
343 | } |
344 | if (rv == SECFailure) |
345 | goto loser; |
346 | break; |
347 | case SEC_OID_PKCS7_DATA: |
348 | cinfo->content.data = (SECItem *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(cinfo->poolp, |
349 | sizeof(SECItem)); |
350 | if (cinfo->content.data == NULL((void*)0)) |
351 | goto loser; |
352 | if (content.len > 0) { |
353 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(cinfo->poolp, |
354 | cinfo->content.data, &content); |
355 | } else { |
356 | /* handle case with NULL content */ |
357 | rv = SECSuccess; |
358 | } |
359 | if (rv == SECFailure) |
360 | goto loser; |
361 | break; |
362 | default: |
363 | goto loser; |
364 | } |
365 | |
366 | return SECSuccess; |
367 | |
368 | loser: |
369 | |
370 | return SECFailure; |
371 | } |
372 | |
373 | /* the content of an encrypted data content info is encrypted. |
374 | * it is assumed that for encrypted data, that the data has already |
375 | * been set and is in the "plainContent" field of the content info. |
376 | * |
377 | * cinfo is the content info to encrypt |
378 | * |
379 | * key is the key with which to perform the encryption. if the |
380 | * algorithm is a password based encryption algorithm, the |
381 | * key is actually a password which will be processed per |
382 | * PKCS #5. |
383 | * |
384 | * in the event of an error, SECFailure is returned. SECSuccess |
385 | * indicates a success. |
386 | */ |
387 | SECStatus |
388 | SEC_PKCS7EncryptContents(PLArenaPool *poolp, |
389 | SEC_PKCS7ContentInfo *cinfo, |
390 | SECItem *key, |
391 | void *wincx) |
392 | { |
393 | SECAlgorithmID *algid = NULL((void*)0); |
394 | SECItem *src; |
395 | SECItem *dest; |
396 | SECItem *blocked_data = NULL((void*)0); |
397 | void *mark; |
398 | void *cx; |
399 | PK11SymKey *eKey = NULL((void*)0); |
400 | PK11SlotInfo *slot = NULL((void*)0); |
401 | |
402 | CK_MECHANISM_TYPE cryptoMechType; |
403 | int bs; |
404 | SECStatus rv = SECFailure; |
405 | SECItem *c_param = NULL((void*)0); |
406 | |
407 | if ((cinfo == NULL((void*)0)) || (key == NULL((void*)0))) |
408 | return SECFailure; |
409 | |
410 | if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) |
411 | return SECFailure; |
412 | |
413 | algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); |
414 | if (algid == NULL((void*)0)) |
415 | return SECFailure; |
416 | |
417 | if (poolp == NULL((void*)0)) |
418 | poolp = cinfo->poolp; |
419 | |
420 | mark = PORT_ArenaMarkPORT_ArenaMark_Util(poolp); |
421 | |
422 | src = &cinfo->content.encryptedData->encContentInfo.plainContent; |
423 | dest = &cinfo->content.encryptedData->encContentInfo.encContent; |
424 | dest->data = (unsigned char *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(poolp, (src->len + 64)); |
425 | dest->len = (src->len + 64); |
426 | if (dest->data == NULL((void*)0)) { |
427 | rv = SECFailure; |
428 | goto loser; |
429 | } |
430 | |
431 | slot = PK11_GetInternalKeySlot(); |
432 | if (slot == NULL((void*)0)) { |
433 | rv = SECFailure; |
434 | goto loser; |
435 | } |
436 | |
437 | eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE0, wincx); |
438 | if (eKey == NULL((void*)0)) { |
439 | rv = SECFailure; |
440 | goto loser; |
441 | } |
442 | |
443 | cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); |
444 | if (cryptoMechType == CKM_INVALID_MECHANISM0xffffffffUL) { |
445 | rv = SECFailure; |
446 | goto loser; |
447 | } |
448 | |
449 | /* block according to PKCS 8 */ |
450 | bs = PK11_GetBlockSize(cryptoMechType, c_param); |
451 | rv = SECSuccess; |
Value stored to 'rv' is never read | |
452 | if (bs) { |
453 | char pad_char; |
454 | pad_char = (char)(bs - (src->len % bs)); |
455 | if (src->len % bs) { |
456 | rv = SECSuccess; |
457 | blocked_data = PK11_BlockData(src, bs); |
458 | if (blocked_data) { |
459 | PORT_Memsetmemset((blocked_data->data + blocked_data->len - (int)pad_char), |
460 | pad_char, (int)pad_char); |
461 | } else { |
462 | rv = SECFailure; |
463 | goto loser; |
464 | } |
465 | } else { |
466 | blocked_data = SECITEM_DupItemSECITEM_DupItem_Util(src); |
467 | if (blocked_data) { |
468 | blocked_data->data = (unsigned char *)PORT_ReallocPORT_Realloc_Util( |
469 | blocked_data->data, |
470 | blocked_data->len + bs); |
471 | if (blocked_data->data) { |
472 | blocked_data->len += bs; |
473 | PORT_Memsetmemset((blocked_data->data + src->len), (char)bs, bs); |
474 | } else { |
475 | rv = SECFailure; |
476 | goto loser; |
477 | } |
478 | } else { |
479 | rv = SECFailure; |
480 | goto loser; |
481 | } |
482 | } |
483 | } else { |
484 | blocked_data = SECITEM_DupItemSECITEM_DupItem_Util(src); |
485 | if (!blocked_data) { |
486 | rv = SECFailure; |
487 | goto loser; |
488 | } |
489 | } |
490 | |
491 | cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT0x00000104UL, |
492 | eKey, c_param); |
493 | if (cx == NULL((void*)0)) { |
494 | rv = SECFailure; |
495 | goto loser; |
496 | } |
497 | |
498 | rv = PK11_CipherOp((PK11Context *)cx, dest->data, (int *)(&dest->len), |
499 | (int)(src->len + 64), blocked_data->data, |
500 | (int)blocked_data->len); |
501 | PK11_DestroyContext((PK11Context *)cx, PR_TRUE1); |
502 | |
503 | loser: |
504 | /* let success fall through */ |
505 | if (blocked_data != NULL((void*)0)) |
506 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(blocked_data, PR_TRUE1); |
507 | |
508 | if (rv == SECFailure) |
509 | PORT_ArenaReleasePORT_ArenaRelease_Util(poolp, mark); |
510 | else |
511 | PORT_ArenaUnmarkPORT_ArenaUnmark_Util(poolp, mark); |
512 | |
513 | if (eKey != NULL((void*)0)) |
514 | PK11_FreeSymKey(eKey); |
515 | |
516 | if (slot != NULL((void*)0)) |
517 | PK11_FreeSlot(slot); |
518 | |
519 | if (c_param != NULL((void*)0)) |
520 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(c_param, PR_TRUE1); |
521 | |
522 | return rv; |
523 | } |
524 | |
525 | /* the content of an encrypted data content info is decrypted. |
526 | * it is assumed that for encrypted data, that the data has already |
527 | * been set and is in the "encContent" field of the content info. |
528 | * |
529 | * cinfo is the content info to decrypt |
530 | * |
531 | * key is the key with which to perform the decryption. if the |
532 | * algorithm is a password based encryption algorithm, the |
533 | * key is actually a password which will be processed per |
534 | * PKCS #5. |
535 | * |
536 | * in the event of an error, SECFailure is returned. SECSuccess |
537 | * indicates a success. |
538 | */ |
539 | SECStatus |
540 | SEC_PKCS7DecryptContents(PLArenaPool *poolp, |
541 | SEC_PKCS7ContentInfo *cinfo, |
542 | SECItem *key, |
543 | void *wincx) |
544 | { |
545 | SECAlgorithmID *algid = NULL((void*)0); |
546 | SECStatus rv = SECFailure; |
547 | SECItem *dest, *src; |
548 | void *mark; |
549 | |
550 | PK11SymKey *eKey = NULL((void*)0); |
551 | PK11SlotInfo *slot = NULL((void*)0); |
552 | CK_MECHANISM_TYPE cryptoMechType; |
553 | void *cx; |
554 | SECItem *c_param = NULL((void*)0); |
555 | int bs; |
556 | |
557 | if ((cinfo == NULL((void*)0)) || (key == NULL((void*)0))) |
558 | return SECFailure; |
559 | |
560 | if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) |
561 | return SECFailure; |
562 | |
563 | algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); |
564 | if (algid == NULL((void*)0)) |
565 | return SECFailure; |
566 | |
567 | if (poolp == NULL((void*)0)) |
568 | poolp = cinfo->poolp; |
569 | |
570 | mark = PORT_ArenaMarkPORT_ArenaMark_Util(poolp); |
571 | |
572 | src = &cinfo->content.encryptedData->encContentInfo.encContent; |
573 | dest = &cinfo->content.encryptedData->encContentInfo.plainContent; |
574 | dest->data = (unsigned char *)PORT_ArenaZAllocPORT_ArenaZAlloc_Util(poolp, (src->len + 64)); |
575 | dest->len = (src->len + 64); |
576 | if (dest->data == NULL((void*)0)) { |
577 | rv = SECFailure; |
578 | goto loser; |
579 | } |
580 | |
581 | slot = PK11_GetInternalKeySlot(); |
582 | if (slot == NULL((void*)0)) { |
583 | rv = SECFailure; |
584 | goto loser; |
585 | } |
586 | |
587 | eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE0, wincx); |
588 | if (eKey == NULL((void*)0)) { |
589 | rv = SECFailure; |
590 | goto loser; |
591 | } |
592 | |
593 | cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); |
594 | if (cryptoMechType == CKM_INVALID_MECHANISM0xffffffffUL) { |
595 | rv = SECFailure; |
596 | goto loser; |
597 | } |
598 | |
599 | cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT0x00000105UL, |
600 | eKey, c_param); |
601 | if (cx == NULL((void*)0)) { |
602 | rv = SECFailure; |
603 | goto loser; |
604 | } |
605 | |
606 | rv = PK11_CipherOp((PK11Context *)cx, dest->data, (int *)(&dest->len), |
607 | (int)(src->len + 64), src->data, (int)src->len); |
608 | PK11_DestroyContext((PK11Context *)cx, PR_TRUE1); |
609 | |
610 | bs = PK11_GetBlockSize(cryptoMechType, c_param); |
611 | if (bs) { |
612 | /* check for proper badding in block algorithms. this assumes |
613 | * RC2 cbc or a DES cbc variant. and the padding is thus defined |
614 | */ |
615 | if (((int)dest->data[dest->len - 1] <= bs) && |
616 | ((int)dest->data[dest->len - 1] > 0)) { |
617 | dest->len -= (int)dest->data[dest->len - 1]; |
618 | } else { |
619 | rv = SECFailure; |
620 | /* set an error ? */ |
621 | } |
622 | } |
623 | |
624 | loser: |
625 | /* let success fall through */ |
626 | if (rv == SECFailure) |
627 | PORT_ArenaReleasePORT_ArenaRelease_Util(poolp, mark); |
628 | else |
629 | PORT_ArenaUnmarkPORT_ArenaUnmark_Util(poolp, mark); |
630 | |
631 | if (eKey != NULL((void*)0)) |
632 | PK11_FreeSymKey(eKey); |
633 | |
634 | if (slot != NULL((void*)0)) |
635 | PK11_FreeSlot(slot); |
636 | |
637 | if (c_param != NULL((void*)0)) |
638 | SECITEM_ZfreeItemSECITEM_ZfreeItem_Util(c_param, PR_TRUE1); |
639 | |
640 | return rv; |
641 | } |
642 | |
643 | SECItem ** |
644 | SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo) |
645 | { |
646 | switch (SEC_PKCS7ContentType(cinfo)) { |
647 | case SEC_OID_PKCS7_SIGNED_DATA: |
648 | return cinfo->content.signedData->rawCerts; |
649 | break; |
650 | default: |
651 | return NULL((void*)0); |
652 | break; |
653 | } |
654 | } |
655 | |
656 | int |
657 | SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo) |
658 | { |
659 | if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA) |
660 | return cinfo->content.envelopedData->encContentInfo.keysize; |
661 | else |
662 | return 0; |
663 | } |