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