Back to index

lightning-sunbird  0.9+nobinonly
pk7print.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*
00038 ** secutil.c - various functions used by security stuff
00039 **
00040 */
00041  
00042 /* pkcs #7 -related functions */
00043  
00044  
00045 #include "secutil.h"
00046 #include "secpkcs7.h"
00047 #include "secoid.h"
00048 #include <sys/stat.h>
00049 #include <stdarg.h>
00050  
00051 #ifdef XP_UNIX
00052 #include <unistd.h>
00053 #endif
00054  
00055 /* for SEC_TraverseNames */
00056 #include "cert.h"
00057 #include "prtypes.h"
00058 #include "prtime.h"
00059  
00060 #include "prlong.h"
00061 #include "secmod.h"
00062 #include "pk11func.h"
00063 #include "prerror.h"
00064  
00065 
00066 
00067 
00068 /*
00069 ** PKCS7 Support
00070 */
00071 
00072 /* forward declaration */
00073 int
00074 sv_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *);
00075 
00076 
00077 void
00078 sv_PrintAsHex(FILE *out, SECItem *data, char *m)
00079 {
00080     unsigned i;
00081 
00082     if (m) fprintf(out, m);
00083     
00084     for (i = 0; i < data->len; i++) {
00085         if (i < data->len - 1) {
00086             fprintf(out, "%02x:", data->data[i]);
00087         } else {
00088             fprintf(out, "%02x\n", data->data[i]);
00089             break;
00090         }
00091     }
00092 }
00093 
00094 void
00095 sv_PrintInteger(FILE *out, SECItem *i, char *m)
00096 {
00097     int iv;
00098 
00099     if (i->len > 4) {
00100         sv_PrintAsHex(out, i, m);
00101     } else {
00102         iv = DER_GetInteger(i);
00103         fprintf(out, "%s%d (0x%x)\n", m, iv, iv);
00104     }
00105 }
00106 
00107 
00108 int
00109 sv_PrintTime(FILE *out, SECItem *t, char *m)
00110 {
00111     PRExplodedTime printableTime; 
00112     int64 time;
00113     char *timeString;
00114     int rv;
00115 
00116     rv = DER_DecodeTimeChoice(&time, t);
00117     if (rv) return rv;
00118 
00119     /* Convert to local time */
00120     PR_ExplodeTime(time, PR_LocalTimeParameters, &printableTime);
00121 
00122     timeString = (char *)PORT_Alloc(100);
00123 
00124     if ( timeString ) {
00125         PR_FormatTime( timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime );
00126         fprintf(out, "%s%s\n", m, timeString);
00127         PORT_Free(timeString);
00128         return 0;
00129     }
00130     return SECFailure;
00131 }
00132 
00133 int
00134 sv_PrintValidity(FILE *out, CERTValidity *v, char *m)
00135 {
00136     int rv;
00137 
00138     fprintf(out, m);
00139     rv = sv_PrintTime(out, &v->notBefore, "notBefore=");
00140     if (rv) return rv;
00141     fprintf(out, m);
00142     sv_PrintTime(out, &v->notAfter, "notAfter=");
00143     return rv;
00144 }
00145 
00146 void
00147 sv_PrintObjectID(FILE *out, SECItem *oid, char *m)
00148 {
00149     const char *name;
00150     SECOidData *oiddata;
00151     
00152     oiddata = SECOID_FindOID(oid);
00153     if (oiddata == NULL) {
00154         sv_PrintAsHex(out, oid, m);
00155         return;
00156     }
00157     name = oiddata->desc;
00158 
00159     if (m != NULL)
00160         fprintf(out, "%s", m);
00161     fprintf(out, "%s\n", name);
00162 }
00163 
00164 void
00165 sv_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m)
00166 {
00167     sv_PrintObjectID(out, &a->algorithm, m);
00168 
00169     if ((a->parameters.len != 2) ||
00170         (PORT_Memcmp(a->parameters.data, "\005\000", 2) != 0)) {
00171         /* Print args to algorithm */
00172         sv_PrintAsHex(out, &a->parameters, "Args=");
00173     }
00174 }
00175 
00176 void
00177 sv_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m)
00178 {
00179     SECItem *value;
00180     int i;
00181     char om[100];
00182 
00183     fprintf(out, m);
00184 
00185     /*
00186      * XXX Make this smarter; look at the type field and then decode
00187      * and print the value(s) appropriately!
00188      */
00189     sv_PrintObjectID(out, &(attr->type), "type=");
00190     if (attr->values != NULL) {
00191         i = 0;
00192         while ((value = attr->values[i]) != NULL) {
00193             sprintf(om, "%svalue[%d]=%s", m, i++, attr->encoded ? "(encoded)" : ""); 
00194             if (attr->encoded || attr->typeTag == NULL) {
00195                 sv_PrintAsHex(out, value, om);
00196             } else {
00197                 switch (attr->typeTag->offset) {
00198                     default:
00199                         sv_PrintAsHex(out, value, om);
00200                         break;
00201                     case SEC_OID_PKCS9_CONTENT_TYPE:
00202                         sv_PrintObjectID(out, value, om);
00203                         break;
00204                     case SEC_OID_PKCS9_SIGNING_TIME:
00205                         sv_PrintTime(out, value, om);
00206                         break;
00207                 }
00208             }
00209         }
00210     }
00211 }
00212 
00213 void
00214 sv_PrintName(FILE *out, CERTName *name, char *msg)
00215 {
00216     char *str;
00217 
00218     str = CERT_NameToAscii(name);
00219     fprintf(out, "%s%s\n", msg, str);
00220     PORT_Free(str);
00221 }
00222 
00223 
00224 #if 0
00225 /*
00226 ** secu_PrintPKCS7EncContent
00227 **   Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
00228 */
00229 void
00230 secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src, 
00231                        char *m, int level)
00232 {
00233     if (src->contentTypeTag == NULL)
00234        src->contentTypeTag = SECOID_FindOID(&(src->contentType));
00235 
00236     secu_Indent(out, level);
00237     fprintf(out, "%s:\n", m);
00238     secu_Indent(out, level + 1); 
00239     fprintf(out, "Content Type: %s\n",
00240            (src->contentTypeTag != NULL) ? src->contentTypeTag->desc
00241                                      : "Unknown");
00242     sv_PrintAlgorithmID(out, &(src->contentEncAlg),
00243                        "Content Encryption Algorithm");
00244     sv_PrintAsHex(out, &(src->encContent), 
00245                   "Encrypted Content", level+1);
00246 }
00247 
00248 /*
00249 ** secu_PrintRecipientInfo
00250 **   Prints a PKCS7RecipientInfo type
00251 */
00252 void
00253 secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m, 
00254                      int level)
00255 {
00256     secu_Indent(out, level); fprintf(out, "%s:\n", m);
00257     sv_PrintInteger(out, &(info->version), "Version");  
00258 
00259     sv_PrintName(out, &(info->issuerAndSN->issuer), "Issuer");
00260     sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), 
00261                     "Serial Number");
00262 
00263     /* Parse and display encrypted key */
00264     sv_PrintAlgorithmID(out, &(info->keyEncAlg), 
00265                      "Key Encryption Algorithm");
00266     sv_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
00267 }
00268 #endif
00269 
00270 /* 
00271 ** secu_PrintSignerInfo
00272 **   Prints a PKCS7SingerInfo type
00273 */
00274 void
00275 sv_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m)
00276 {
00277     SEC_PKCS7Attribute *attr;
00278     int iv;
00279     
00280     fprintf(out, m);
00281     sv_PrintInteger(out, &(info->version), "version=");
00282 
00283     fprintf(out, m);
00284     sv_PrintName(out, &(info->issuerAndSN->issuer), "issuerName=");
00285     fprintf(out, m);
00286     sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), 
00287                         "serialNumber=");
00288   
00289     fprintf(out, m);
00290     sv_PrintAlgorithmID(out, &(info->digestAlg), "digestAlgorithm=");
00291     
00292     if (info->authAttr != NULL) {
00293         char mm[120];
00294 
00295         iv = 0;
00296         while (info->authAttr[iv] != NULL) iv++;
00297         fprintf(out, "%sauthenticatedAttributes=%d\n", m, iv);
00298         iv = 0;
00299         while ((attr = info->authAttr[iv]) != NULL) {
00300             sprintf(mm, "%sattribute[%d].", m, iv++); 
00301             sv_PrintAttribute(out, attr, mm);
00302         }
00303     }
00304     
00305     /* Parse and display signature */
00306     fprintf(out, m);
00307     sv_PrintAlgorithmID(out, &(info->digestEncAlg), "digestEncryptionAlgorithm=");
00308     fprintf(out, m);
00309     sv_PrintAsHex(out, &(info->encDigest), "encryptedDigest=");
00310     
00311     if (info->unAuthAttr != NULL) {
00312         char mm[120];
00313 
00314         iv = 0;
00315         while (info->unAuthAttr[iv] != NULL) iv++;
00316         fprintf(out, "%sunauthenticatedAttributes=%d\n", m, iv);
00317         iv = 0;
00318         while ((attr = info->unAuthAttr[iv]) != NULL) {
00319             sprintf(mm, "%sattribute[%d].", m, iv++); 
00320             sv_PrintAttribute(out, attr, mm);
00321         }
00322     }
00323 }
00324 
00325 void
00326 sv_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
00327 {
00328     fprintf(out, m);
00329     sv_PrintInteger(out, &pk->u.rsa.modulus, "modulus=");
00330     fprintf(out, m);
00331     sv_PrintInteger(out, &pk->u.rsa.publicExponent, "exponent=");
00332 }
00333 
00334 void
00335 sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
00336 {
00337     fprintf(out, m);
00338     sv_PrintInteger(out, &pk->u.dsa.params.prime, "prime=");
00339     fprintf(out, m);
00340     sv_PrintInteger(out, &pk->u.dsa.params.subPrime, "subprime=");
00341     fprintf(out, m);
00342     sv_PrintInteger(out, &pk->u.dsa.params.base, "base=");
00343     fprintf(out, m);
00344     sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue=");
00345 }
00346 
00347 int
00348 sv_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena,
00349                              CERTSubjectPublicKeyInfo *i,  char *msg)
00350 {
00351     SECKEYPublicKey *pk;
00352     int rv;
00353     char mm[200];
00354 
00355     sprintf(mm, "%s.publicKeyAlgorithm=", msg);
00356     sv_PrintAlgorithmID(out, &i->algorithm, mm);
00357 
00358     pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey));
00359     if (!pk) return PORT_GetError();
00360 
00361     DER_ConvertBitString(&i->subjectPublicKey);
00362     switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) {
00363         case SEC_OID_PKCS1_RSA_ENCRYPTION:
00364             rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_RSAPublicKeyTemplate,
00365                                     &i->subjectPublicKey);
00366             if (rv) return rv;
00367             sprintf(mm, "%s.rsaPublicKey.", msg);
00368             sv_PrintRSAPublicKey(out, pk, mm);
00369             break;
00370         case SEC_OID_ANSIX9_DSA_SIGNATURE:
00371             rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_DSAPublicKeyTemplate,
00372                                     &i->subjectPublicKey);
00373             if (rv) return rv;
00374             sprintf(mm, "%s.dsaPublicKey.", msg);
00375             sv_PrintDSAPublicKey(out, pk, mm);
00376             break;
00377         default:
00378             fprintf(out, "%s=bad SPKI algorithm type\n", msg);
00379             return 0;
00380     }
00381 
00382     return 0;
00383 }
00384 
00385 SECStatus
00386 sv_PrintInvalidDateExten  (FILE *out, SECItem *value, char *msg)
00387 {
00388     SECItem decodedValue;
00389     SECStatus rv;
00390     int64 invalidTime;
00391     char *formattedTime = NULL;
00392 
00393     decodedValue.data = NULL;
00394     rv = SEC_ASN1DecodeItem (NULL, &decodedValue, SEC_GeneralizedTimeTemplate,
00395                              value);
00396     if (rv == SECSuccess) {
00397         rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
00398         if (rv == SECSuccess) {
00399             formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y");
00400             fprintf (out, "%s: %s\n", msg, formattedTime);
00401             PORT_Free (formattedTime);
00402         }
00403     }
00404     PORT_Free (decodedValue.data);
00405 
00406     return (rv);
00407 }
00408 
00409 int
00410 sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg)
00411 {
00412     SECOidTag oidTag;
00413 
00414     if (extensions) {
00415 
00416         while ( *extensions ) {
00417             SECItem *tmpitem;
00418 
00419             fprintf(out, "%sname=", msg);
00420 
00421             tmpitem = &(*extensions)->id;
00422             sv_PrintObjectID(out, tmpitem, NULL);
00423 
00424             tmpitem = &(*extensions)->critical;
00425             if ( tmpitem->len )
00426                 fprintf(out, "%scritical=%s\n", msg,
00427                         (tmpitem->data && tmpitem->data[0])? "True": "False");
00428 
00429             oidTag = SECOID_FindOIDTag (&((*extensions)->id));
00430 
00431             fprintf(out, msg);
00432             tmpitem = &((*extensions)->value);
00433             if (oidTag == SEC_OID_X509_INVALID_DATE) 
00434                 sv_PrintInvalidDateExten (out, tmpitem,"invalidExt");
00435             else                       
00436                 sv_PrintAsHex(out,tmpitem, "data=");
00437 
00438             /*fprintf(out, "\n");*/
00439             extensions++;
00440         }
00441     }
00442 
00443     return 0;
00444 }
00445 
00446 /* callers of this function must make sure that the CERTSignedCrl
00447    from which they are extracting the CERTCrl has been fully-decoded.
00448    Otherwise it will not have the entries even though the CRL may have
00449    some */
00450 void
00451 sv_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m)
00452 {
00453     CERTCrlEntry *entry;
00454     int iv;
00455     char om[100];
00456     
00457     fprintf(out, m);
00458     sv_PrintAlgorithmID(out, &(crl->signatureAlg), "signatureAlgorithm=");
00459     fprintf(out, m);
00460     sv_PrintName(out, &(crl->name), "name=");
00461     fprintf(out, m);
00462     sv_PrintTime(out, &(crl->lastUpdate), "lastUpdate=");
00463     fprintf(out, m);
00464     sv_PrintTime(out, &(crl->nextUpdate), "nextUpdate=");
00465     
00466     if (crl->entries != NULL) {
00467         iv = 0;
00468         while ((entry = crl->entries[iv]) != NULL) {
00469             fprintf(out, "%sentry[%d].", m, iv); 
00470             sv_PrintInteger(out, &(entry->serialNumber), "serialNumber=");
00471             fprintf(out, "%sentry[%d].", m, iv); 
00472             sv_PrintTime(out, &(entry->revocationDate), "revocationDate=");
00473             sprintf(om, "%sentry[%d].signedCRLEntriesExtensions.", m, iv++); 
00474             sv_PrintExtensions(out, entry->extensions, om);
00475         }
00476     }
00477     sprintf(om, "%ssignedCRLEntriesExtensions.", m); 
00478     sv_PrintExtensions(out, crl->extensions, om);
00479 }
00480 
00481 
00482 int
00483 sv_PrintCertificate(FILE *out, SECItem *der, char *m, int level)
00484 {
00485     PRArenaPool *arena = NULL;
00486     CERTCertificate *c;
00487     int rv;
00488     int iv;
00489     char mm[200];
00490     
00491     /* Decode certificate */
00492     c = (CERTCertificate*) PORT_ZAlloc(sizeof(CERTCertificate));
00493     if (!c) return PORT_GetError();
00494 
00495     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
00496     if (!arena) return SEC_ERROR_NO_MEMORY;
00497 
00498     rv = SEC_ASN1DecodeItem(arena, c, CERT_CertificateTemplate, der);
00499     if (rv) {
00500         PORT_FreeArena(arena, PR_FALSE);
00501         return rv;
00502     }
00503 
00504     /* Pretty print it out */
00505     iv = DER_GetInteger(&c->version);
00506     fprintf(out, "%sversion=%d (0x%x)\n", m, iv + 1, iv);
00507     sprintf(mm, "%sserialNumber=", m);
00508     sv_PrintInteger(out, &c->serialNumber, mm);
00509     sprintf(mm, "%ssignatureAlgorithm=", m);
00510     sv_PrintAlgorithmID(out, &c->signature, mm);
00511     sprintf(mm, "%sissuerName=", m);
00512     sv_PrintName(out, &c->issuer, mm);
00513     sprintf(mm, "%svalidity.", m);
00514     sv_PrintValidity(out, &c->validity, mm);
00515     sprintf(mm, "%ssubject=", m);
00516     sv_PrintName(out, &c->subject, mm);
00517     sprintf(mm, "%ssubjectPublicKeyInfo", m);
00518     rv = sv_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo, mm);
00519     if (rv) {
00520         PORT_FreeArena(arena, PR_FALSE);
00521         return rv;
00522     }
00523     sprintf(mm, "%ssignedExtensions.", m);
00524     sv_PrintExtensions(out, c->extensions, mm);
00525     
00526     PORT_FreeArena(arena, PR_FALSE);
00527     return 0;
00528 }
00529 
00530 int
00531 sv_PrintSignedData(FILE *out, SECItem *der, char *m, SECU_PPFunc inner)
00532 {
00533     PRArenaPool *arena = NULL;
00534     CERTSignedData *sd;
00535     int rv;
00536 
00537     /* Strip off the signature */
00538     sd = (CERTSignedData*) PORT_ZAlloc(sizeof(CERTSignedData));
00539     if (!sd) return PORT_GetError();
00540 
00541     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
00542     if (!arena) return SEC_ERROR_NO_MEMORY;
00543 
00544     rv = SEC_ASN1DecodeItem(arena, sd, CERT_SignedDataTemplate, der);
00545     if (rv) {
00546         PORT_FreeArena(arena, PR_FALSE);
00547         return rv;
00548     }
00549 
00550 /*    fprintf(out, "%s:\n", m); */
00551     PORT_Strcat(m, "data.");
00552 
00553     rv = (*inner)(out, &sd->data, m, 0);
00554     if (rv) {
00555         PORT_FreeArena(arena, PR_FALSE);
00556         return rv;
00557     }
00558 
00559     m[PORT_Strlen(m) - 5] = 0;
00560     fprintf(out, m);
00561     sv_PrintAlgorithmID(out, &sd->signatureAlgorithm, "signatureAlgorithm=");
00562     DER_ConvertBitString(&sd->signature);
00563     fprintf(out, m);
00564     sv_PrintAsHex(out, &sd->signature, "signature=");
00565 
00566     PORT_FreeArena(arena, PR_FALSE);
00567     return 0;
00568 
00569 }
00570 
00571 
00572 /*
00573 ** secu_PrintPKCS7Signed
00574 **   Pretty print a PKCS7 signed data type (up to version 1).
00575 */
00576 int
00577 sv_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src)
00578 {
00579     SECAlgorithmID *digAlg;        /* digest algorithms */
00580     SECItem *aCert;                /* certificate */
00581     CERTSignedCrl *aCrl;           /* certificate revocation list */
00582     SEC_PKCS7SignerInfo *sigInfo;  /* signer information */
00583     int rv, iv;
00584     char om[120];
00585 
00586     sv_PrintInteger(out, &(src->version), "pkcs7.version=");
00587 
00588     /* Parse and list digest algorithms (if any) */
00589     if (src->digestAlgorithms != NULL) {
00590         iv = 0;
00591         while (src->digestAlgorithms[iv] != NULL)
00592             iv++;
00593         fprintf(out, "pkcs7.digestAlgorithmListLength=%d\n", iv);
00594         iv = 0;
00595         while ((digAlg = src->digestAlgorithms[iv]) != NULL) {
00596             sprintf(om, "pkcs7.digestAlgorithm[%d]=", iv++);
00597             sv_PrintAlgorithmID(out, digAlg, om);
00598         }
00599     }
00600 
00601     /* Now for the content */
00602     rv = sv_PrintPKCS7ContentInfo(out, &(src->contentInfo), 
00603                                                 "pkcs7.contentInformation=");
00604     if (rv != 0) return rv;
00605 
00606     /* Parse and list certificates (if any) */
00607     if (src->rawCerts != NULL) {
00608         iv = 0;
00609         while (src->rawCerts[iv] != NULL)
00610             iv++;
00611         fprintf(out, "pkcs7.certificateListLength=%d\n", iv);
00612 
00613         iv = 0;
00614         while ((aCert = src->rawCerts[iv]) != NULL) {
00615             sprintf(om, "certificate[%d].", iv++);
00616             rv = sv_PrintSignedData(out, aCert, om, sv_PrintCertificate);
00617             if (rv) return rv;
00618         }
00619     }
00620 
00621     /* Parse and list CRL's (if any) */
00622     if (src->crls != NULL) {
00623         iv = 0;
00624         while (src->crls[iv] != NULL) iv++;
00625         fprintf(out, "pkcs7.signedRevocationLists=%d\n", iv);
00626         iv = 0;
00627         while ((aCrl = src->crls[iv]) != NULL) {
00628             sprintf(om, "signedRevocationList[%d].", iv);
00629             fprintf(out, om);
00630             sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, 
00631                                 "signatureAlgorithm=");
00632             DER_ConvertBitString(&aCrl->signatureWrap.signature);
00633             fprintf(out, om);
00634             sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "signature=");
00635             sprintf(om, "certificateRevocationList[%d].", iv);
00636             sv_PrintCRLInfo(out, &aCrl->crl, om);
00637             iv++;
00638         }
00639     }
00640 
00641     /* Parse and list signatures (if any) */
00642     if (src->signerInfos != NULL) {
00643         iv = 0;
00644         while (src->signerInfos[iv] != NULL)
00645             iv++;
00646         fprintf(out, "pkcs7.signerInformationListLength=%d\n", iv);
00647         iv = 0;
00648         while ((sigInfo = src->signerInfos[iv]) != NULL) {
00649             sprintf(om, "signerInformation[%d].", iv++);
00650             sv_PrintSignerInfo(out, sigInfo, om);
00651         }
00652     }  
00653 
00654     return 0;
00655 }
00656 
00657 #if 0
00658 /*
00659 ** secu_PrintPKCS7Enveloped
00660 **  Pretty print a PKCS7 enveloped data type (up to version 1).
00661 */
00662 void
00663 secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
00664                       char *m, int level)
00665 {
00666     SEC_PKCS7RecipientInfo *recInfo;   /* pointer for signer information */
00667     int iv;
00668     char om[100];
00669 
00670     secu_Indent(out, level); fprintf(out, "%s:\n", m);
00671     sv_PrintInteger(out, &(src->version), "Version", level + 1);
00672 
00673     /* Parse and list recipients (this is not optional) */
00674     if (src->recipientInfos != NULL) {
00675        secu_Indent(out, level + 1);
00676        fprintf(out, "Recipient Information List:\n");
00677        iv = 0;
00678        while ((recInfo = src->recipientInfos[iv++]) != NULL) {
00679            sprintf(om, "Recipient Information (%x)", iv);
00680            secu_PrintRecipientInfo(out, recInfo, om, level + 2);
00681        }
00682     }  
00683 
00684     secu_PrintPKCS7EncContent(out, &src->encContentInfo, 
00685                            "Encrypted Content Information", level + 1);
00686 }
00687 
00688 /*
00689 ** secu_PrintPKCS7SignedEnveloped
00690 **   Pretty print a PKCS7 singed and enveloped data type (up to version 1).
00691 */
00692 int
00693 secu_PrintPKCS7SignedAndEnveloped(FILE *out,
00694                               SEC_PKCS7SignedAndEnvelopedData *src,
00695                               char *m, int level)
00696 {
00697     SECAlgorithmID *digAlg;  /* pointer for digest algorithms */
00698     SECItem *aCert;           /* pointer for certificate */
00699     CERTSignedCrl *aCrl;        /* pointer for certificate revocation list */
00700     SEC_PKCS7SignerInfo *sigInfo;   /* pointer for signer information */
00701     SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
00702     int rv, iv;
00703     char om[100];
00704 
00705     secu_Indent(out, level); fprintf(out, "%s:\n", m);
00706     sv_PrintInteger(out, &(src->version), "Version", level + 1);
00707 
00708     /* Parse and list recipients (this is not optional) */
00709     if (src->recipientInfos != NULL) {
00710        secu_Indent(out, level + 1);
00711        fprintf(out, "Recipient Information List:\n");
00712        iv = 0;
00713        while ((recInfo = src->recipientInfos[iv++]) != NULL) {
00714            sprintf(om, "Recipient Information (%x)", iv);
00715            secu_PrintRecipientInfo(out, recInfo, om, level + 2);
00716        }
00717     }  
00718 
00719     /* Parse and list digest algorithms (if any) */
00720     if (src->digestAlgorithms != NULL) {
00721        secu_Indent(out, level + 1);  fprintf(out, "Digest Algorithm List:\n");
00722        iv = 0;
00723        while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
00724            sprintf(om, "Digest Algorithm (%x)", iv);
00725            sv_PrintAlgorithmID(out, digAlg, om);
00726        }
00727     }
00728 
00729     secu_PrintPKCS7EncContent(out, &src->encContentInfo, 
00730                            "Encrypted Content Information", level + 1);
00731 
00732     /* Parse and list certificates (if any) */
00733     if (src->rawCerts != NULL) {
00734        secu_Indent(out, level + 1);  fprintf(out, "Certificate List:\n");
00735        iv = 0;
00736        while ((aCert = src->rawCerts[iv++]) != NULL) {
00737            sprintf(om, "Certificate (%x)", iv);
00738            rv = SECU_PrintSignedData(out, aCert, om, level + 2, 
00739                                   SECU_PrintCertificate);
00740            if (rv)
00741               return rv;
00742        }
00743     }
00744 
00745     /* Parse and list CRL's (if any) */
00746     if (src->crls != NULL) {
00747        secu_Indent(out, level + 1);  
00748        fprintf(out, "Signed Revocation Lists:\n");
00749        iv = 0;
00750        while ((aCrl = src->crls[iv++]) != NULL) {
00751            sprintf(om, "Signed Revocation List (%x)", iv);
00752            secu_Indent(out, level + 2);  fprintf(out, "%s:\n", om);
00753            sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, 
00754                               "Signature Algorithm");
00755            DER_ConvertBitString(&aCrl->signatureWrap.signature);
00756            sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
00757                          level+3);
00758            SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List", 
00759                        level + 3); 
00760        }
00761     }
00762 
00763     /* Parse and list signatures (if any) */
00764     if (src->signerInfos != NULL) {
00765        secu_Indent(out, level + 1);
00766        fprintf(out, "Signer Information List:\n");
00767        iv = 0;
00768        while ((sigInfo = src->signerInfos[iv++]) != NULL) {
00769            sprintf(om, "Signer Information (%x)", iv);
00770            secu_PrintSignerInfo(out, sigInfo, om, level + 2);
00771        }
00772     }  
00773 
00774     return 0;
00775 }
00776 
00777 /*
00778 ** secu_PrintPKCS7Encrypted
00779 **   Pretty print a PKCS7 encrypted data type (up to version 1).
00780 */
00781 void
00782 secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
00783                       char *m, int level)
00784 {
00785     secu_Indent(out, level); fprintf(out, "%s:\n", m);
00786     sv_PrintInteger(out, &(src->version), "Version", level + 1);
00787 
00788     secu_PrintPKCS7EncContent(out, &src->encContentInfo, 
00789                            "Encrypted Content Information", level + 1);
00790 }
00791 
00792 /*
00793 ** secu_PrintPKCS7Digested
00794 **   Pretty print a PKCS7 digested data type (up to version 1).
00795 */
00796 void
00797 sv_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src)
00798 {
00799     secu_Indent(out, level); fprintf(out, "%s:\n", m);
00800     sv_PrintInteger(out, &(src->version), "Version", level + 1);
00801     
00802     sv_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm");
00803     sv_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
00804                             level + 1);
00805     sv_PrintAsHex(out, &src->digest, "Digest", level + 1);  
00806 }
00807 
00808 #endif
00809 
00810 /*
00811 ** secu_PrintPKCS7ContentInfo
00812 **   Takes a SEC_PKCS7ContentInfo type and sends the contents to the 
00813 ** appropriate function
00814 */
00815 int
00816 sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m)
00817 {
00818     const char *desc;
00819     SECOidTag kind;
00820     int rv;
00821 
00822     if (src->contentTypeTag == NULL)
00823         src->contentTypeTag = SECOID_FindOID(&(src->contentType));
00824 
00825     if (src->contentTypeTag == NULL) {
00826         desc = "Unknown";
00827         kind = SEC_OID_PKCS7_DATA;
00828     } else {
00829         desc = src->contentTypeTag->desc;
00830         kind = src->contentTypeTag->offset;
00831     }
00832 
00833     fprintf(out, "%s%s\n", m, desc);
00834 
00835     if (src->content.data == NULL) {
00836         fprintf(out, "pkcs7.data=<no content>\n");
00837         return 0;
00838     }
00839 
00840     rv = 0;
00841     switch (kind) {
00842         case SEC_OID_PKCS7_SIGNED_DATA:  /* Signed Data */
00843             rv = sv_PrintPKCS7Signed(out, src->content.signedData);
00844             break;
00845 
00846         case SEC_OID_PKCS7_ENVELOPED_DATA:  /* Enveloped Data */
00847             fprintf(out, "pkcs7EnvelopedData=<unsupported>\n");
00848             /*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/
00849             break;
00850 
00851         case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:  /* Signed and Enveloped */
00852             fprintf(out, "pkcs7SignedEnvelopedData=<unsupported>\n");
00853             /*rv = sv_PrintPKCS7SignedAndEnveloped(out,
00854                                 src->content.signedAndEnvelopedData);*/
00855             break;
00856 
00857         case SEC_OID_PKCS7_DIGESTED_DATA:  /* Digested Data */
00858             fprintf(out, "pkcs7DigestedData=<unsupported>\n");
00859             /*sv_PrintPKCS7Digested(out, src->content.digestedData);*/
00860             break;
00861 
00862         case SEC_OID_PKCS7_ENCRYPTED_DATA:  /* Encrypted Data */
00863             fprintf(out, "pkcs7EncryptedData=<unsupported>\n");
00864             /*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/
00865             break;
00866 
00867         default:
00868             fprintf(out, "pkcs7UnknownData=<unsupported>\n");
00869             /*sv_PrintAsHex(out, src->content.data);*/
00870             break;
00871     }
00872 
00873     return rv;
00874 }
00875 
00876 
00877 int
00878 SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der)
00879 {
00880     SEC_PKCS7ContentInfo *cinfo;
00881     int rv = -1;
00882 
00883     cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
00884 
00885     if (cinfo != NULL) {
00886         rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo=");
00887         SEC_PKCS7DestroyContentInfo(cinfo);
00888     }
00889 
00890     return rv;
00891 }
00892 /*
00893 ** End of PKCS7 functions
00894 */