Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
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/. */
5 /*
6 ** secutil.c - various functions used by security stuff
7 **
8 */
10 /* pkcs #7 -related functions */
13 #include "secutil.h"
14 #include "secpkcs7.h"
15 #include "secoid.h"
16 #include <sys/stat.h>
17 #include <stdarg.h>
19 #ifdef XP_UNIX
20 #include <unistd.h>
21 #endif
23 /* for SEC_TraverseNames */
24 #include "cert.h"
25 #include "prtypes.h"
26 #include "prtime.h"
28 #include "prlong.h"
29 #include "secmod.h"
30 #include "pk11func.h"
31 #include "prerror.h"
36 /*
37 ** PKCS7 Support
38 */
40 /* forward declaration */
41 int
42 sv_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *);
45 void
46 sv_PrintAsHex(FILE *out, SECItem *data, char *m)
47 {
48 unsigned i;
50 if (m) fprintf(out, "%s", m);
52 for (i = 0; i < data->len; i++) {
53 if (i < data->len - 1) {
54 fprintf(out, "%02x:", data->data[i]);
55 } else {
56 fprintf(out, "%02x\n", data->data[i]);
57 break;
58 }
59 }
60 }
62 void
63 sv_PrintInteger(FILE *out, SECItem *i, char *m)
64 {
65 int iv;
67 if (i->len > 4) {
68 sv_PrintAsHex(out, i, m);
69 } else {
70 iv = DER_GetInteger(i);
71 fprintf(out, "%s%d (0x%x)\n", m, iv, iv);
72 }
73 }
76 int
77 sv_PrintTime(FILE *out, SECItem *t, char *m)
78 {
79 PRExplodedTime printableTime;
80 PRTime time;
81 char *timeString;
82 int rv;
84 rv = DER_DecodeTimeChoice(&time, t);
85 if (rv) return rv;
87 /* Convert to local time */
88 PR_ExplodeTime(time, PR_LocalTimeParameters, &printableTime);
90 timeString = (char *)PORT_Alloc(256);
92 if ( timeString ) {
93 if (PR_FormatTime( timeString, 256, "%a %b %d %H:%M:%S %Y", &printableTime )) {
94 fprintf(out, "%s%s\n", m, timeString);
95 }
96 PORT_Free(timeString);
97 return 0;
98 }
99 return SECFailure;
100 }
102 int
103 sv_PrintValidity(FILE *out, CERTValidity *v, char *m)
104 {
105 int rv;
107 fprintf(out, "%s", m);
108 rv = sv_PrintTime(out, &v->notBefore, "notBefore=");
109 if (rv) return rv;
110 fprintf(out, "%s", m);
111 sv_PrintTime(out, &v->notAfter, "notAfter=");
112 return rv;
113 }
115 void
116 sv_PrintObjectID(FILE *out, SECItem *oid, char *m)
117 {
118 const char *name;
119 SECOidData *oiddata;
121 oiddata = SECOID_FindOID(oid);
122 if (oiddata == NULL) {
123 sv_PrintAsHex(out, oid, m);
124 return;
125 }
126 name = oiddata->desc;
128 if (m != NULL)
129 fprintf(out, "%s", m);
130 fprintf(out, "%s\n", name);
131 }
133 void
134 sv_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m)
135 {
136 sv_PrintObjectID(out, &a->algorithm, m);
138 if ((a->parameters.len != 2) ||
139 (PORT_Memcmp(a->parameters.data, "\005\000", 2) != 0)) {
140 /* Print args to algorithm */
141 sv_PrintAsHex(out, &a->parameters, "Args=");
142 }
143 }
145 void
146 sv_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m)
147 {
148 SECItem *value;
149 int i;
150 char om[100];
152 fprintf(out, "%s", m);
154 /*
155 * XXX Make this smarter; look at the type field and then decode
156 * and print the value(s) appropriately!
157 */
158 sv_PrintObjectID(out, &(attr->type), "type=");
159 if (attr->values != NULL) {
160 i = 0;
161 while ((value = attr->values[i]) != NULL) {
162 sprintf(om, "%svalue[%d]=%s", m, i++, attr->encoded ? "(encoded)" : "");
163 if (attr->encoded || attr->typeTag == NULL) {
164 sv_PrintAsHex(out, value, om);
165 } else {
166 switch (attr->typeTag->offset) {
167 default:
168 sv_PrintAsHex(out, value, om);
169 break;
170 case SEC_OID_PKCS9_CONTENT_TYPE:
171 sv_PrintObjectID(out, value, om);
172 break;
173 case SEC_OID_PKCS9_SIGNING_TIME:
174 sv_PrintTime(out, value, om);
175 break;
176 }
177 }
178 }
179 }
180 }
182 void
183 sv_PrintName(FILE *out, CERTName *name, char *msg)
184 {
185 char *str;
187 str = CERT_NameToAscii(name);
188 fprintf(out, "%s%s\n", msg, str);
189 PORT_Free(str);
190 }
193 #if 0
194 /*
195 ** secu_PrintPKCS7EncContent
196 ** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
197 */
198 void
199 secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
200 char *m, int level)
201 {
202 if (src->contentTypeTag == NULL)
203 src->contentTypeTag = SECOID_FindOID(&(src->contentType));
205 secu_Indent(out, level);
206 fprintf(out, "%s:\n", m);
207 secu_Indent(out, level + 1);
208 fprintf(out, "Content Type: %s\n",
209 (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
210 : "Unknown");
211 sv_PrintAlgorithmID(out, &(src->contentEncAlg),
212 "Content Encryption Algorithm");
213 sv_PrintAsHex(out, &(src->encContent),
214 "Encrypted Content", level+1);
215 }
217 /*
218 ** secu_PrintRecipientInfo
219 ** Prints a PKCS7RecipientInfo type
220 */
221 void
222 secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
223 int level)
224 {
225 secu_Indent(out, level); fprintf(out, "%s:\n", m);
226 sv_PrintInteger(out, &(info->version), "Version");
228 sv_PrintName(out, &(info->issuerAndSN->issuer), "Issuer");
229 sv_PrintInteger(out, &(info->issuerAndSN->serialNumber),
230 "Serial Number");
232 /* Parse and display encrypted key */
233 sv_PrintAlgorithmID(out, &(info->keyEncAlg),
234 "Key Encryption Algorithm");
235 sv_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
236 }
237 #endif
239 /*
240 ** secu_PrintSignerInfo
241 ** Prints a PKCS7SingerInfo type
242 */
243 void
244 sv_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m)
245 {
246 SEC_PKCS7Attribute *attr;
247 int iv;
249 fprintf(out, "%s", m);
250 sv_PrintInteger(out, &(info->version), "version=");
252 fprintf(out, "%s", m);
253 sv_PrintName(out, &(info->issuerAndSN->issuer), "issuerName=");
254 fprintf(out, "%s", m);
255 sv_PrintInteger(out, &(info->issuerAndSN->serialNumber),
256 "serialNumber=");
258 fprintf(out, "%s", m);
259 sv_PrintAlgorithmID(out, &(info->digestAlg), "digestAlgorithm=");
261 if (info->authAttr != NULL) {
262 char mm[120];
264 iv = 0;
265 while (info->authAttr[iv] != NULL) iv++;
266 fprintf(out, "%sauthenticatedAttributes=%d\n", m, iv);
267 iv = 0;
268 while ((attr = info->authAttr[iv]) != NULL) {
269 sprintf(mm, "%sattribute[%d].", m, iv++);
270 sv_PrintAttribute(out, attr, mm);
271 }
272 }
274 /* Parse and display signature */
275 fprintf(out, "%s", m);
276 sv_PrintAlgorithmID(out, &(info->digestEncAlg), "digestEncryptionAlgorithm=");
277 fprintf(out, "%s", m);
278 sv_PrintAsHex(out, &(info->encDigest), "encryptedDigest=");
280 if (info->unAuthAttr != NULL) {
281 char mm[120];
283 iv = 0;
284 while (info->unAuthAttr[iv] != NULL) iv++;
285 fprintf(out, "%sunauthenticatedAttributes=%d\n", m, iv);
286 iv = 0;
287 while ((attr = info->unAuthAttr[iv]) != NULL) {
288 sprintf(mm, "%sattribute[%d].", m, iv++);
289 sv_PrintAttribute(out, attr, mm);
290 }
291 }
292 }
294 void
295 sv_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
296 {
297 fprintf(out, "%s", m);
298 sv_PrintInteger(out, &pk->u.rsa.modulus, "modulus=");
299 fprintf(out, "%s", m);
300 sv_PrintInteger(out, &pk->u.rsa.publicExponent, "exponent=");
301 }
303 void
304 sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
305 {
306 fprintf(out, "%s", m);
307 sv_PrintInteger(out, &pk->u.dsa.params.prime, "prime=");
308 fprintf(out, "%s", m);
309 sv_PrintInteger(out, &pk->u.dsa.params.subPrime, "subprime=");
310 fprintf(out, "%s", m);
311 sv_PrintInteger(out, &pk->u.dsa.params.base, "base=");
312 fprintf(out, "%s", m);
313 sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue=");
314 }
316 int
317 sv_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena,
318 CERTSubjectPublicKeyInfo *i, char *msg)
319 {
320 SECKEYPublicKey *pk;
321 int rv;
322 char mm[200];
324 sprintf(mm, "%s.publicKeyAlgorithm=", msg);
325 sv_PrintAlgorithmID(out, &i->algorithm, mm);
327 pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey));
328 if (!pk) return PORT_GetError();
330 DER_ConvertBitString(&i->subjectPublicKey);
331 switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) {
332 case SEC_OID_PKCS1_RSA_ENCRYPTION:
333 rv = SEC_ASN1DecodeItem(arena, pk,
334 SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate),
335 &i->subjectPublicKey);
336 if (rv) return rv;
337 sprintf(mm, "%s.rsaPublicKey.", msg);
338 sv_PrintRSAPublicKey(out, pk, mm);
339 break;
340 case SEC_OID_ANSIX9_DSA_SIGNATURE:
341 rv = SEC_ASN1DecodeItem(arena, pk,
342 SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate),
343 &i->subjectPublicKey);
344 if (rv) return rv;
345 sprintf(mm, "%s.dsaPublicKey.", msg);
346 sv_PrintDSAPublicKey(out, pk, mm);
347 break;
348 default:
349 fprintf(out, "%s=bad SPKI algorithm type\n", msg);
350 return 0;
351 }
353 return 0;
354 }
356 SECStatus
357 sv_PrintInvalidDateExten (FILE *out, SECItem *value, char *msg)
358 {
359 SECItem decodedValue;
360 SECStatus rv;
361 PRTime invalidTime;
362 char *formattedTime = NULL;
364 decodedValue.data = NULL;
365 rv = SEC_ASN1DecodeItem (NULL, &decodedValue,
366 SEC_ASN1_GET(SEC_GeneralizedTimeTemplate),
367 value);
368 if (rv == SECSuccess) {
369 rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
370 if (rv == SECSuccess) {
371 formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y");
372 fprintf (out, "%s: %s\n", msg, formattedTime);
373 PORT_Free (formattedTime);
374 }
375 }
376 PORT_Free (decodedValue.data);
378 return (rv);
379 }
381 int
382 sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg)
383 {
384 SECOidTag oidTag;
386 if (extensions) {
388 while ( *extensions ) {
389 SECItem *tmpitem;
391 fprintf(out, "%sname=", msg);
393 tmpitem = &(*extensions)->id;
394 sv_PrintObjectID(out, tmpitem, NULL);
396 tmpitem = &(*extensions)->critical;
397 if ( tmpitem->len )
398 fprintf(out, "%scritical=%s\n", msg,
399 (tmpitem->data && tmpitem->data[0])? "True": "False");
401 oidTag = SECOID_FindOIDTag (&((*extensions)->id));
403 fprintf(out, "%s", msg);
404 tmpitem = &((*extensions)->value);
405 if (oidTag == SEC_OID_X509_INVALID_DATE)
406 sv_PrintInvalidDateExten (out, tmpitem,"invalidExt");
407 else
408 sv_PrintAsHex(out,tmpitem, "data=");
410 /*fprintf(out, "\n");*/
411 extensions++;
412 }
413 }
415 return 0;
416 }
418 /* callers of this function must make sure that the CERTSignedCrl
419 from which they are extracting the CERTCrl has been fully-decoded.
420 Otherwise it will not have the entries even though the CRL may have
421 some */
422 void
423 sv_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m)
424 {
425 CERTCrlEntry *entry;
426 int iv;
427 char om[100];
429 fprintf(out, "%s", m);
430 sv_PrintAlgorithmID(out, &(crl->signatureAlg), "signatureAlgorithm=");
431 fprintf(out, "%s", m);
432 sv_PrintName(out, &(crl->name), "name=");
433 fprintf(out, "%s", m);
434 sv_PrintTime(out, &(crl->lastUpdate), "lastUpdate=");
435 fprintf(out, "%s", m);
436 sv_PrintTime(out, &(crl->nextUpdate), "nextUpdate=");
438 if (crl->entries != NULL) {
439 iv = 0;
440 while ((entry = crl->entries[iv]) != NULL) {
441 fprintf(out, "%sentry[%d].", m, iv);
442 sv_PrintInteger(out, &(entry->serialNumber), "serialNumber=");
443 fprintf(out, "%sentry[%d].", m, iv);
444 sv_PrintTime(out, &(entry->revocationDate), "revocationDate=");
445 sprintf(om, "%sentry[%d].signedCRLEntriesExtensions.", m, iv++);
446 sv_PrintExtensions(out, entry->extensions, om);
447 }
448 }
449 sprintf(om, "%ssignedCRLEntriesExtensions.", m);
450 sv_PrintExtensions(out, crl->extensions, om);
451 }
454 int
455 sv_PrintCertificate(FILE *out, SECItem *der, char *m, int level)
456 {
457 PLArenaPool *arena = NULL;
458 CERTCertificate *c;
459 int rv;
460 int iv;
461 char mm[200];
463 /* Decode certificate */
464 c = (CERTCertificate*) PORT_ZAlloc(sizeof(CERTCertificate));
465 if (!c) return PORT_GetError();
467 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
468 if (!arena) return SEC_ERROR_NO_MEMORY;
470 rv = SEC_ASN1DecodeItem(arena, c, SEC_ASN1_GET(CERT_CertificateTemplate),
471 der);
472 if (rv) {
473 PORT_FreeArena(arena, PR_FALSE);
474 return rv;
475 }
477 /* Pretty print it out */
478 iv = DER_GetInteger(&c->version);
479 fprintf(out, "%sversion=%d (0x%x)\n", m, iv + 1, iv);
480 sprintf(mm, "%sserialNumber=", m);
481 sv_PrintInteger(out, &c->serialNumber, mm);
482 sprintf(mm, "%ssignatureAlgorithm=", m);
483 sv_PrintAlgorithmID(out, &c->signature, mm);
484 sprintf(mm, "%sissuerName=", m);
485 sv_PrintName(out, &c->issuer, mm);
486 sprintf(mm, "%svalidity.", m);
487 sv_PrintValidity(out, &c->validity, mm);
488 sprintf(mm, "%ssubject=", m);
489 sv_PrintName(out, &c->subject, mm);
490 sprintf(mm, "%ssubjectPublicKeyInfo", m);
491 rv = sv_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo, mm);
492 if (rv) {
493 PORT_FreeArena(arena, PR_FALSE);
494 return rv;
495 }
496 sprintf(mm, "%ssignedExtensions.", m);
497 sv_PrintExtensions(out, c->extensions, mm);
499 PORT_FreeArena(arena, PR_FALSE);
500 return 0;
501 }
503 int
504 sv_PrintSignedData(FILE *out, SECItem *der, char *m, SECU_PPFunc inner)
505 {
506 PLArenaPool *arena = NULL;
507 CERTSignedData *sd;
508 int rv;
510 /* Strip off the signature */
511 sd = (CERTSignedData*) PORT_ZAlloc(sizeof(CERTSignedData));
512 if (!sd) return PORT_GetError();
514 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
515 if (!arena) return SEC_ERROR_NO_MEMORY;
517 rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate),
518 der);
519 if (rv) {
520 PORT_FreeArena(arena, PR_FALSE);
521 return rv;
522 }
524 /* fprintf(out, "%s:\n", m); */
525 PORT_Strcat(m, "data.");
527 rv = (*inner)(out, &sd->data, m, 0);
528 if (rv) {
529 PORT_FreeArena(arena, PR_FALSE);
530 return rv;
531 }
533 m[PORT_Strlen(m) - 5] = 0;
534 fprintf(out, "%s", m);
535 sv_PrintAlgorithmID(out, &sd->signatureAlgorithm, "signatureAlgorithm=");
536 DER_ConvertBitString(&sd->signature);
537 fprintf(out, "%s", m);
538 sv_PrintAsHex(out, &sd->signature, "signature=");
540 PORT_FreeArena(arena, PR_FALSE);
541 return 0;
543 }
546 /*
547 ** secu_PrintPKCS7Signed
548 ** Pretty print a PKCS7 signed data type (up to version 1).
549 */
550 int
551 sv_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src)
552 {
553 SECAlgorithmID *digAlg; /* digest algorithms */
554 SECItem *aCert; /* certificate */
555 CERTSignedCrl *aCrl; /* certificate revocation list */
556 SEC_PKCS7SignerInfo *sigInfo; /* signer information */
557 int rv, iv;
558 char om[120];
560 sv_PrintInteger(out, &(src->version), "pkcs7.version=");
562 /* Parse and list digest algorithms (if any) */
563 if (src->digestAlgorithms != NULL) {
564 iv = 0;
565 while (src->digestAlgorithms[iv] != NULL)
566 iv++;
567 fprintf(out, "pkcs7.digestAlgorithmListLength=%d\n", iv);
568 iv = 0;
569 while ((digAlg = src->digestAlgorithms[iv]) != NULL) {
570 sprintf(om, "pkcs7.digestAlgorithm[%d]=", iv++);
571 sv_PrintAlgorithmID(out, digAlg, om);
572 }
573 }
575 /* Now for the content */
576 rv = sv_PrintPKCS7ContentInfo(out, &(src->contentInfo),
577 "pkcs7.contentInformation=");
578 if (rv != 0) return rv;
580 /* Parse and list certificates (if any) */
581 if (src->rawCerts != NULL) {
582 iv = 0;
583 while (src->rawCerts[iv] != NULL)
584 iv++;
585 fprintf(out, "pkcs7.certificateListLength=%d\n", iv);
587 iv = 0;
588 while ((aCert = src->rawCerts[iv]) != NULL) {
589 sprintf(om, "certificate[%d].", iv++);
590 rv = sv_PrintSignedData(out, aCert, om, sv_PrintCertificate);
591 if (rv) return rv;
592 }
593 }
595 /* Parse and list CRL's (if any) */
596 if (src->crls != NULL) {
597 iv = 0;
598 while (src->crls[iv] != NULL) iv++;
599 fprintf(out, "pkcs7.signedRevocationLists=%d\n", iv);
600 iv = 0;
601 while ((aCrl = src->crls[iv]) != NULL) {
602 sprintf(om, "signedRevocationList[%d].", iv);
603 fprintf(out, "%s", om);
604 sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
605 "signatureAlgorithm=");
606 DER_ConvertBitString(&aCrl->signatureWrap.signature);
607 fprintf(out, "%s", om);
608 sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "signature=");
609 sprintf(om, "certificateRevocationList[%d].", iv);
610 sv_PrintCRLInfo(out, &aCrl->crl, om);
611 iv++;
612 }
613 }
615 /* Parse and list signatures (if any) */
616 if (src->signerInfos != NULL) {
617 iv = 0;
618 while (src->signerInfos[iv] != NULL)
619 iv++;
620 fprintf(out, "pkcs7.signerInformationListLength=%d\n", iv);
621 iv = 0;
622 while ((sigInfo = src->signerInfos[iv]) != NULL) {
623 sprintf(om, "signerInformation[%d].", iv++);
624 sv_PrintSignerInfo(out, sigInfo, om);
625 }
626 }
628 return 0;
629 }
631 #if 0
632 /*
633 ** secu_PrintPKCS7Enveloped
634 ** Pretty print a PKCS7 enveloped data type (up to version 1).
635 */
636 void
637 secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
638 char *m, int level)
639 {
640 SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
641 int iv;
642 char om[100];
644 secu_Indent(out, level); fprintf(out, "%s:\n", m);
645 sv_PrintInteger(out, &(src->version), "Version", level + 1);
647 /* Parse and list recipients (this is not optional) */
648 if (src->recipientInfos != NULL) {
649 secu_Indent(out, level + 1);
650 fprintf(out, "Recipient Information List:\n");
651 iv = 0;
652 while ((recInfo = src->recipientInfos[iv++]) != NULL) {
653 sprintf(om, "Recipient Information (%x)", iv);
654 secu_PrintRecipientInfo(out, recInfo, om, level + 2);
655 }
656 }
658 secu_PrintPKCS7EncContent(out, &src->encContentInfo,
659 "Encrypted Content Information", level + 1);
660 }
662 /*
663 ** secu_PrintPKCS7SignedEnveloped
664 ** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
665 */
666 int
667 secu_PrintPKCS7SignedAndEnveloped(FILE *out,
668 SEC_PKCS7SignedAndEnvelopedData *src,
669 char *m, int level)
670 {
671 SECAlgorithmID *digAlg; /* pointer for digest algorithms */
672 SECItem *aCert; /* pointer for certificate */
673 CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
674 SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
675 SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
676 int rv, iv;
677 char om[100];
679 secu_Indent(out, level); fprintf(out, "%s:\n", m);
680 sv_PrintInteger(out, &(src->version), "Version", level + 1);
682 /* Parse and list recipients (this is not optional) */
683 if (src->recipientInfos != NULL) {
684 secu_Indent(out, level + 1);
685 fprintf(out, "Recipient Information List:\n");
686 iv = 0;
687 while ((recInfo = src->recipientInfos[iv++]) != NULL) {
688 sprintf(om, "Recipient Information (%x)", iv);
689 secu_PrintRecipientInfo(out, recInfo, om, level + 2);
690 }
691 }
693 /* Parse and list digest algorithms (if any) */
694 if (src->digestAlgorithms != NULL) {
695 secu_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
696 iv = 0;
697 while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
698 sprintf(om, "Digest Algorithm (%x)", iv);
699 sv_PrintAlgorithmID(out, digAlg, om);
700 }
701 }
703 secu_PrintPKCS7EncContent(out, &src->encContentInfo,
704 "Encrypted Content Information", level + 1);
706 /* Parse and list certificates (if any) */
707 if (src->rawCerts != NULL) {
708 secu_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
709 iv = 0;
710 while ((aCert = src->rawCerts[iv++]) != NULL) {
711 sprintf(om, "Certificate (%x)", iv);
712 rv = SECU_PrintSignedData(out, aCert, om, level + 2,
713 SECU_PrintCertificate);
714 if (rv)
715 return rv;
716 }
717 }
719 /* Parse and list CRL's (if any) */
720 if (src->crls != NULL) {
721 secu_Indent(out, level + 1);
722 fprintf(out, "Signed Revocation Lists:\n");
723 iv = 0;
724 while ((aCrl = src->crls[iv++]) != NULL) {
725 sprintf(om, "Signed Revocation List (%x)", iv);
726 secu_Indent(out, level + 2); fprintf(out, "%s:\n", om);
727 sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
728 "Signature Algorithm");
729 DER_ConvertBitString(&aCrl->signatureWrap.signature);
730 sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
731 level+3);
732 SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
733 level + 3);
734 }
735 }
737 /* Parse and list signatures (if any) */
738 if (src->signerInfos != NULL) {
739 secu_Indent(out, level + 1);
740 fprintf(out, "Signer Information List:\n");
741 iv = 0;
742 while ((sigInfo = src->signerInfos[iv++]) != NULL) {
743 sprintf(om, "Signer Information (%x)", iv);
744 secu_PrintSignerInfo(out, sigInfo, om, level + 2);
745 }
746 }
748 return 0;
749 }
751 /*
752 ** secu_PrintPKCS7Encrypted
753 ** Pretty print a PKCS7 encrypted data type (up to version 1).
754 */
755 void
756 secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
757 char *m, int level)
758 {
759 secu_Indent(out, level); fprintf(out, "%s:\n", m);
760 sv_PrintInteger(out, &(src->version), "Version", level + 1);
762 secu_PrintPKCS7EncContent(out, &src->encContentInfo,
763 "Encrypted Content Information", level + 1);
764 }
766 /*
767 ** secu_PrintPKCS7Digested
768 ** Pretty print a PKCS7 digested data type (up to version 1).
769 */
770 void
771 sv_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src)
772 {
773 secu_Indent(out, level); fprintf(out, "%s:\n", m);
774 sv_PrintInteger(out, &(src->version), "Version", level + 1);
776 sv_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm");
777 sv_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
778 level + 1);
779 sv_PrintAsHex(out, &src->digest, "Digest", level + 1);
780 }
782 #endif
784 /*
785 ** secu_PrintPKCS7ContentInfo
786 ** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
787 ** appropriate function
788 */
789 int
790 sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m)
791 {
792 const char *desc;
793 SECOidTag kind;
794 int rv;
796 if (src->contentTypeTag == NULL)
797 src->contentTypeTag = SECOID_FindOID(&(src->contentType));
799 if (src->contentTypeTag == NULL) {
800 desc = "Unknown";
801 kind = SEC_OID_PKCS7_DATA;
802 } else {
803 desc = src->contentTypeTag->desc;
804 kind = src->contentTypeTag->offset;
805 }
807 fprintf(out, "%s%s\n", m, desc);
809 if (src->content.data == NULL) {
810 fprintf(out, "pkcs7.data=<no content>\n");
811 return 0;
812 }
814 rv = 0;
815 switch (kind) {
816 case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
817 rv = sv_PrintPKCS7Signed(out, src->content.signedData);
818 break;
820 case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
821 fprintf(out, "pkcs7EnvelopedData=<unsupported>\n");
822 /*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/
823 break;
825 case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
826 fprintf(out, "pkcs7SignedEnvelopedData=<unsupported>\n");
827 /*rv = sv_PrintPKCS7SignedAndEnveloped(out,
828 src->content.signedAndEnvelopedData);*/
829 break;
831 case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
832 fprintf(out, "pkcs7DigestedData=<unsupported>\n");
833 /*sv_PrintPKCS7Digested(out, src->content.digestedData);*/
834 break;
836 case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
837 fprintf(out, "pkcs7EncryptedData=<unsupported>\n");
838 /*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/
839 break;
841 default:
842 fprintf(out, "pkcs7UnknownData=<unsupported>\n");
843 /*sv_PrintAsHex(out, src->content.data);*/
844 break;
845 }
847 return rv;
848 }
851 int
852 SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der)
853 {
854 SEC_PKCS7ContentInfo *cinfo;
855 int rv = -1;
857 cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
859 if (cinfo != NULL) {
860 rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo=");
861 SEC_PKCS7DestroyContentInfo(cinfo);
862 }
864 return rv;
865 }
866 /*
867 ** End of PKCS7 functions
868 */