Bug Summary

File:s/lib/pkcs7/p7common.c
Warning:line 451, column 5
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name p7common.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/pkcs7 -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/pkcs7 -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../dist/public/nss -I ../../../dist/private/nss -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c p7common.c
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 */
21SECOidTag
22SEC_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 */
36void
37SEC_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 */
142SEC_PKCS7ContentInfo *
143SEC_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 */
174SECItem *
175SEC_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 */
248SECAlgorithmID *
249SEC_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 */
284SECStatus
285SEC_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
368loser:
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 */
387SECStatus
388SEC_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
503loser:
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 */
539SECStatus
540SEC_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
624loser:
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
643SECItem **
644SEC_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
656int
657SEC_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}