/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ** secutil.c - various functions used by security stuff ** */ /* pkcs #7 -related functions */ #include "secutil.h" #include "secpkcs7.h" #include "secoid.h" #include #include #ifdef XP_UNIX #include #endif /* for SEC_TraverseNames */ #include "cert.h" #include "prtypes.h" #include "prtime.h" #include "prlong.h" #include "secmod.h" #include "pk11func.h" #include "prerror.h" /* ** PKCS7 Support */ /* forward declaration */ int sv_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *); void sv_PrintAsHex(FILE *out, SECItem *data, char *m) { unsigned i; if (m) fprintf(out, "%s", m); for (i = 0; i < data->len; i++) { if (i < data->len - 1) { fprintf(out, "%02x:", data->data[i]); } else { fprintf(out, "%02x\n", data->data[i]); break; } } } void sv_PrintInteger(FILE *out, SECItem *i, char *m) { int iv; if (i->len > 4) { sv_PrintAsHex(out, i, m); } else { iv = DER_GetInteger(i); fprintf(out, "%s%d (0x%x)\n", m, iv, iv); } } int sv_PrintTime(FILE *out, SECItem *t, char *m) { PRExplodedTime printableTime; PRTime time; char *timeString; int rv; rv = DER_DecodeTimeChoice(&time, t); if (rv) return rv; /* Convert to local time */ PR_ExplodeTime(time, PR_LocalTimeParameters, &printableTime); timeString = (char *)PORT_Alloc(256); if (timeString) { if (PR_FormatTime(timeString, 256, "%a %b %d %H:%M:%S %Y", &printableTime)) { fprintf(out, "%s%s\n", m, timeString); } PORT_Free(timeString); return 0; } return SECFailure; } int sv_PrintValidity(FILE *out, CERTValidity *v, char *m) { int rv; fprintf(out, "%s", m); rv = sv_PrintTime(out, &v->notBefore, "notBefore="); if (rv) return rv; fprintf(out, "%s", m); sv_PrintTime(out, &v->notAfter, "notAfter="); return rv; } void sv_PrintObjectID(FILE *out, SECItem *oid, char *m) { const char *name; SECOidData *oiddata; oiddata = SECOID_FindOID(oid); if (oiddata == NULL) { sv_PrintAsHex(out, oid, m); return; } name = oiddata->desc; if (m != NULL) fprintf(out, "%s", m); fprintf(out, "%s\n", name); } void sv_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m) { sv_PrintObjectID(out, &a->algorithm, m); if ((a->parameters.len != 2) || (PORT_Memcmp(a->parameters.data, "\005\000", 2) != 0)) { /* Print args to algorithm */ sv_PrintAsHex(out, &a->parameters, "Args="); } } void sv_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m) { SECItem *value; int i; char om[100]; fprintf(out, "%s", m); /* * XXX Make this smarter; look at the type field and then decode * and print the value(s) appropriately! */ sv_PrintObjectID(out, &(attr->type), "type="); if (attr->values != NULL) { i = 0; while ((value = attr->values[i]) != NULL) { snprintf(om, sizeof(om), "%svalue[%d]=%s", m, i++, attr->encoded ? "(encoded)" : ""); if (attr->encoded || attr->typeTag == NULL) { sv_PrintAsHex(out, value, om); } else { switch (attr->typeTag->offset) { default: sv_PrintAsHex(out, value, om); break; case SEC_OID_PKCS9_CONTENT_TYPE: sv_PrintObjectID(out, value, om); break; case SEC_OID_PKCS9_SIGNING_TIME: sv_PrintTime(out, value, om); break; } } } } } void sv_PrintName(FILE *out, CERTName *name, char *msg) { char *str; str = CERT_NameToAscii(name); fprintf(out, "%s%s\n", msg, str); PORT_Free(str); } #if 0 /* ** secu_PrintPKCS7EncContent ** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it) */ void secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src, char *m, int level) { if (src->contentTypeTag == NULL) src->contentTypeTag = SECOID_FindOID(&(src->contentType)); secu_Indent(out, level); fprintf(out, "%s:\n", m); secu_Indent(out, level + 1); fprintf(out, "Content Type: %s\n", (src->contentTypeTag != NULL) ? src->contentTypeTag->desc : "Unknown"); sv_PrintAlgorithmID(out, &(src->contentEncAlg), "Content Encryption Algorithm"); sv_PrintAsHex(out, &(src->encContent), "Encrypted Content", level+1); } /* ** secu_PrintRecipientInfo ** Prints a PKCS7RecipientInfo type */ void secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m, int level) { secu_Indent(out, level); fprintf(out, "%s:\n", m); sv_PrintInteger(out, &(info->version), "Version"); sv_PrintName(out, &(info->issuerAndSN->issuer), "Issuer"); sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), "Serial Number"); /* Parse and display encrypted key */ sv_PrintAlgorithmID(out, &(info->keyEncAlg), "Key Encryption Algorithm"); sv_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1); } #endif /* ** secu_PrintSignerInfo ** Prints a PKCS7SingerInfo type */ void sv_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m) { SEC_PKCS7Attribute *attr; int iv; fprintf(out, "%s", m); sv_PrintInteger(out, &(info->version), "version="); fprintf(out, "%s", m); sv_PrintName(out, &(info->issuerAndSN->issuer), "issuerName="); fprintf(out, "%s", m); sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), "serialNumber="); fprintf(out, "%s", m); sv_PrintAlgorithmID(out, &(info->digestAlg), "digestAlgorithm="); if (info->authAttr != NULL) { char mm[120]; iv = 0; while (info->authAttr[iv] != NULL) iv++; fprintf(out, "%sauthenticatedAttributes=%d\n", m, iv); iv = 0; while ((attr = info->authAttr[iv]) != NULL) { snprintf(mm, sizeof(mm), "%sattribute[%d].", m, iv++); sv_PrintAttribute(out, attr, mm); } } /* Parse and display signature */ fprintf(out, "%s", m); sv_PrintAlgorithmID(out, &(info->digestEncAlg), "digestEncryptionAlgorithm="); fprintf(out, "%s", m); sv_PrintAsHex(out, &(info->encDigest), "encryptedDigest="); if (info->unAuthAttr != NULL) { char mm[120]; iv = 0; while (info->unAuthAttr[iv] != NULL) iv++; fprintf(out, "%sunauthenticatedAttributes=%d\n", m, iv); iv = 0; while ((attr = info->unAuthAttr[iv]) != NULL) { snprintf(mm, sizeof(mm), "%sattribute[%d].", m, iv++); sv_PrintAttribute(out, attr, mm); } } } void sv_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m) { fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.rsa.modulus, "modulus="); fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.rsa.publicExponent, "exponent="); } void sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m) { fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.dsa.params.prime, "prime="); fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.dsa.params.subPrime, "subprime="); fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.dsa.params.base, "base="); fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue="); } void sv_PrintECDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m) { SECItem curve = { siBuffer, NULL, 0 }; if ((pk->u.ec.DEREncodedParams.len > 2) && (pk->u.ec.DEREncodedParams.data[0] == 0x06)) { /* strip to just the oid for the curve */ curve.len = pk->u.ec.DEREncodedParams.data[1]; curve.data = pk->u.ec.DEREncodedParams.data + 2; /* don't overflow the buffer */ curve.len = PR_MIN(curve.len, pk->u.ec.DEREncodedParams.len - 2); fprintf(out, "%s", m); sv_PrintObjectID(out, &curve, "curve="); } fprintf(out, "%s", m); sv_PrintInteger(out, &pk->u.ec.publicValue, "publicValue="); } int sv_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena, CERTSubjectPublicKeyInfo *i, char *msg) { SECKEYPublicKey pk; int rv; char mm[200]; snprintf(mm, sizeof(mm), "%s.publicKeyAlgorithm=", msg); sv_PrintAlgorithmID(out, &i->algorithm, mm); DER_ConvertBitString(&i->subjectPublicKey); switch (SECOID_FindOIDTag(&i->algorithm.algorithm)) { case SEC_OID_PKCS1_RSA_ENCRYPTION: case SEC_OID_PKCS1_RSA_PSS_SIGNATURE: rv = SEC_ASN1DecodeItem(arena, &pk, SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), &i->subjectPublicKey); if (rv) return rv; snprintf(mm, sizeof(mm), "%s.rsaPublicKey.", msg); sv_PrintRSAPublicKey(out, &pk, mm); break; case SEC_OID_ANSIX9_DSA_SIGNATURE: rv = SEC_ASN1DecodeItem(arena, &pk, SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate), &i->subjectPublicKey); if (rv) return rv; #ifdef notdef /* SECKEY_PQGParamsTemplate is not yet exported form NSS */ rv = SEC_ASN1DecodeItem(arena, &pk.u.dsa.params, SEC_ASN1_GET(SECKEY_PQGParamsTemplate), &i->algorithm.parameters); if (rv) return rv; #endif snprintf(mm, sizeof(mm), "%s.dsaPublicKey.", msg); sv_PrintDSAPublicKey(out, &pk, mm); break; case SEC_OID_ANSIX962_EC_PUBLIC_KEY: rv = SECITEM_CopyItem(arena, &pk.u.ec.DEREncodedParams, &i->algorithm.parameters); if (rv) return rv; rv = SECITEM_CopyItem(arena, &pk.u.ec.publicValue, &i->subjectPublicKey); if (rv) return rv; snprintf(mm, sizeof(mm), "%s.ecdsaPublicKey.", msg); sv_PrintECDSAPublicKey(out, &pk, mm); break; default: fprintf(out, "%s=bad SPKI algorithm type\n", msg); return 0; } return 0; } SECStatus sv_PrintInvalidDateExten(FILE *out, SECItem *value, char *msg) { SECItem decodedValue; SECStatus rv; PRTime invalidTime; char *formattedTime = NULL; decodedValue.data = NULL; rv = SEC_ASN1DecodeItem(NULL, &decodedValue, SEC_ASN1_GET(SEC_GeneralizedTimeTemplate), value); if (rv == SECSuccess) { rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue); if (rv == SECSuccess) { formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y"); fprintf(out, "%s: %s\n", msg, formattedTime); PORT_Free(formattedTime); } } PORT_Free(decodedValue.data); return (rv); } int sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg) { SECOidTag oidTag; if (extensions) { while (*extensions) { SECItem *tmpitem; fprintf(out, "%sname=", msg); tmpitem = &(*extensions)->id; sv_PrintObjectID(out, tmpitem, NULL); tmpitem = &(*extensions)->critical; if (tmpitem->len) fprintf(out, "%scritical=%s\n", msg, (tmpitem->data && tmpitem->data[0]) ? "True" : "False"); oidTag = SECOID_FindOIDTag(&((*extensions)->id)); fprintf(out, "%s", msg); tmpitem = &((*extensions)->value); if (oidTag == SEC_OID_X509_INVALID_DATE) sv_PrintInvalidDateExten(out, tmpitem, "invalidExt"); else sv_PrintAsHex(out, tmpitem, "data="); /*fprintf(out, "\n");*/ extensions++; } } return 0; } /* callers of this function must make sure that the CERTSignedCrl from which they are extracting the CERTCrl has been fully-decoded. Otherwise it will not have the entries even though the CRL may have some */ void sv_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m) { CERTCrlEntry *entry; int iv; char om[100]; fprintf(out, "%s", m); sv_PrintAlgorithmID(out, &(crl->signatureAlg), "signatureAlgorithm="); fprintf(out, "%s", m); sv_PrintName(out, &(crl->name), "name="); fprintf(out, "%s", m); sv_PrintTime(out, &(crl->lastUpdate), "lastUpdate="); fprintf(out, "%s", m); sv_PrintTime(out, &(crl->nextUpdate), "nextUpdate="); if (crl->entries != NULL) { iv = 0; while ((entry = crl->entries[iv]) != NULL) { fprintf(out, "%sentry[%d].", m, iv); sv_PrintInteger(out, &(entry->serialNumber), "serialNumber="); fprintf(out, "%sentry[%d].", m, iv); sv_PrintTime(out, &(entry->revocationDate), "revocationDate="); snprintf(om, sizeof(om), "%sentry[%d].signedCRLEntriesExtensions.", m, iv++); sv_PrintExtensions(out, entry->extensions, om); } } snprintf(om, sizeof(om), "%ssignedCRLEntriesExtensions.", m); sv_PrintExtensions(out, crl->extensions, om); } int sv_PrintCertificate(FILE *out, SECItem *der, char *m, int level) { PLArenaPool *arena = NULL; CERTCertificate *c; int rv; int iv; char mm[200]; /* Decode certificate */ c = (CERTCertificate *)PORT_ZAlloc(sizeof(CERTCertificate)); if (!c) return PORT_GetError(); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return SEC_ERROR_NO_MEMORY; rv = SEC_ASN1DecodeItem(arena, c, SEC_ASN1_GET(CERT_CertificateTemplate), der); if (rv) { PORT_FreeArena(arena, PR_FALSE); return rv; } /* Pretty print it out */ iv = DER_GetInteger(&c->version); fprintf(out, "%sversion=%d (0x%x)\n", m, iv + 1, iv); snprintf(mm, sizeof(mm), "%sserialNumber=", m); sv_PrintInteger(out, &c->serialNumber, mm); snprintf(mm, sizeof(mm), "%ssignatureAlgorithm=", m); sv_PrintAlgorithmID(out, &c->signature, mm); snprintf(mm, sizeof(mm), "%sissuerName=", m); sv_PrintName(out, &c->issuer, mm); snprintf(mm, sizeof(mm), "%svalidity.", m); sv_PrintValidity(out, &c->validity, mm); snprintf(mm, sizeof(mm), "%ssubject=", m); sv_PrintName(out, &c->subject, mm); snprintf(mm, sizeof(mm), "%ssubjectPublicKeyInfo", m); rv = sv_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo, mm); if (rv) { PORT_FreeArena(arena, PR_FALSE); return rv; } snprintf(mm, sizeof(mm), "%ssignedExtensions.", m); sv_PrintExtensions(out, c->extensions, mm); PORT_FreeArena(arena, PR_FALSE); return 0; } int sv_PrintSignedData(FILE *out, SECItem *der, char *m, SECU_PPFunc inner) { PLArenaPool *arena = NULL; CERTSignedData *sd; int rv; /* Strip off the signature */ sd = (CERTSignedData *)PORT_ZAlloc(sizeof(CERTSignedData)); if (!sd) return PORT_GetError(); arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) return SEC_ERROR_NO_MEMORY; rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate), der); if (rv) { PORT_FreeArena(arena, PR_FALSE); return rv; } /* fprintf(out, "%s:\n", m); */ PORT_Strcat(m, "data."); rv = (*inner)(out, &sd->data, m, 0); if (rv) { PORT_FreeArena(arena, PR_FALSE); return rv; } m[PORT_Strlen(m) - 5] = 0; fprintf(out, "%s", m); sv_PrintAlgorithmID(out, &sd->signatureAlgorithm, "signatureAlgorithm="); DER_ConvertBitString(&sd->signature); fprintf(out, "%s", m); sv_PrintAsHex(out, &sd->signature, "signature="); PORT_FreeArena(arena, PR_FALSE); return 0; } /* ** secu_PrintPKCS7Signed ** Pretty print a PKCS7 signed data type (up to version 1). */ int sv_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src) { SECAlgorithmID *digAlg; /* digest algorithms */ SECItem *aCert; /* certificate */ CERTSignedCrl *aCrl; /* certificate revocation list */ SEC_PKCS7SignerInfo *sigInfo; /* signer information */ int rv, iv; char om[120]; sv_PrintInteger(out, &(src->version), "pkcs7.version="); /* Parse and list digest algorithms (if any) */ if (src->digestAlgorithms != NULL) { iv = 0; while (src->digestAlgorithms[iv] != NULL) iv++; fprintf(out, "pkcs7.digestAlgorithmListLength=%d\n", iv); iv = 0; while ((digAlg = src->digestAlgorithms[iv]) != NULL) { snprintf(om, sizeof(om), "pkcs7.digestAlgorithm[%d]=", iv++); sv_PrintAlgorithmID(out, digAlg, om); } } /* Now for the content */ rv = sv_PrintPKCS7ContentInfo(out, &(src->contentInfo), "pkcs7.contentInformation="); if (rv != 0) return rv; /* Parse and list certificates (if any) */ if (src->rawCerts != NULL) { iv = 0; while (src->rawCerts[iv] != NULL) iv++; fprintf(out, "pkcs7.certificateListLength=%d\n", iv); iv = 0; while ((aCert = src->rawCerts[iv]) != NULL) { snprintf(om, sizeof(om), "certificate[%d].", iv++); rv = sv_PrintSignedData(out, aCert, om, sv_PrintCertificate); if (rv) return rv; } } /* Parse and list CRL's (if any) */ if (src->crls != NULL) { iv = 0; while (src->crls[iv] != NULL) iv++; fprintf(out, "pkcs7.signedRevocationLists=%d\n", iv); iv = 0; while ((aCrl = src->crls[iv]) != NULL) { snprintf(om, sizeof(om), "signedRevocationList[%d].", iv); fprintf(out, "%s", om); sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, "signatureAlgorithm="); DER_ConvertBitString(&aCrl->signatureWrap.signature); fprintf(out, "%s", om); sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "signature="); snprintf(om, sizeof(om), "certificateRevocationList[%d].", iv); sv_PrintCRLInfo(out, &aCrl->crl, om); iv++; } } /* Parse and list signatures (if any) */ if (src->signerInfos != NULL) { iv = 0; while (src->signerInfos[iv] != NULL) iv++; fprintf(out, "pkcs7.signerInformationListLength=%d\n", iv); iv = 0; while ((sigInfo = src->signerInfos[iv]) != NULL) { snprintf(om, sizeof(om), "signerInformation[%d].", iv++); sv_PrintSignerInfo(out, sigInfo, om); } } return 0; } #if 0 /* ** secu_PrintPKCS7Enveloped ** Pretty print a PKCS7 enveloped data type (up to version 1). */ void secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src, char *m, int level) { SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */ int iv; char om[100]; secu_Indent(out, level); fprintf(out, "%s:\n", m); sv_PrintInteger(out, &(src->version), "Version", level + 1); /* Parse and list recipients (this is not optional) */ if (src->recipientInfos != NULL) { secu_Indent(out, level + 1); fprintf(out, "Recipient Information List:\n"); iv = 0; while ((recInfo = src->recipientInfos[iv++]) != NULL) { snprintf(om, sizeof(om), "Recipient Information (%x)", iv); secu_PrintRecipientInfo(out, recInfo, om, level + 2); } } secu_PrintPKCS7EncContent(out, &src->encContentInfo, "Encrypted Content Information", level + 1); } /* ** secu_PrintPKCS7SignedEnveloped ** Pretty print a PKCS7 singed and enveloped data type (up to version 1). */ int secu_PrintPKCS7SignedAndEnveloped(FILE *out, SEC_PKCS7SignedAndEnvelopedData *src, char *m, int level) { SECAlgorithmID *digAlg; /* pointer for digest algorithms */ SECItem *aCert; /* pointer for certificate */ CERTSignedCrl *aCrl; /* pointer for certificate revocation list */ SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */ SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */ int rv, iv; char om[100]; secu_Indent(out, level); fprintf(out, "%s:\n", m); sv_PrintInteger(out, &(src->version), "Version", level + 1); /* Parse and list recipients (this is not optional) */ if (src->recipientInfos != NULL) { secu_Indent(out, level + 1); fprintf(out, "Recipient Information List:\n"); iv = 0; while ((recInfo = src->recipientInfos[iv++]) != NULL) { snprintf(om, sizeof(om), "Recipient Information (%x)", iv); secu_PrintRecipientInfo(out, recInfo, om, level + 2); } } /* Parse and list digest algorithms (if any) */ if (src->digestAlgorithms != NULL) { secu_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n"); iv = 0; while ((digAlg = src->digestAlgorithms[iv++]) != NULL) { snprintf(om, sizeof(om), "Digest Algorithm (%x)", iv); sv_PrintAlgorithmID(out, digAlg, om); } } secu_PrintPKCS7EncContent(out, &src->encContentInfo, "Encrypted Content Information", level + 1); /* Parse and list certificates (if any) */ if (src->rawCerts != NULL) { secu_Indent(out, level + 1); fprintf(out, "Certificate List:\n"); iv = 0; while ((aCert = src->rawCerts[iv++]) != NULL) { snprintf(om, sizeof(om), "Certificate (%x)", iv); rv = SECU_PrintSignedData(out, aCert, om, level + 2, SECU_PrintCertificate); if (rv) return rv; } } /* Parse and list CRL's (if any) */ if (src->crls != NULL) { secu_Indent(out, level + 1); fprintf(out, "Signed Revocation Lists:\n"); iv = 0; while ((aCrl = src->crls[iv++]) != NULL) { snprintf(om, sizeof(om), "Signed Revocation List (%x)", iv); secu_Indent(out, level + 2); fprintf(out, "%s:\n", om); sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, "Signature Algorithm"); DER_ConvertBitString(&aCrl->signatureWrap.signature); sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature", level+3); SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List", level + 3); } } /* Parse and list signatures (if any) */ if (src->signerInfos != NULL) { secu_Indent(out, level + 1); fprintf(out, "Signer Information List:\n"); iv = 0; while ((sigInfo = src->signerInfos[iv++]) != NULL) { snprintf(om, sizeof(om), "Signer Information (%x)", iv); secu_PrintSignerInfo(out, sigInfo, om, level + 2); } } return 0; } /* ** secu_PrintPKCS7Encrypted ** Pretty print a PKCS7 encrypted data type (up to version 1). */ void secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src, char *m, int level) { secu_Indent(out, level); fprintf(out, "%s:\n", m); sv_PrintInteger(out, &(src->version), "Version", level + 1); secu_PrintPKCS7EncContent(out, &src->encContentInfo, "Encrypted Content Information", level + 1); } /* ** secu_PrintPKCS7Digested ** Pretty print a PKCS7 digested data type (up to version 1). */ void sv_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src) { secu_Indent(out, level); fprintf(out, "%s:\n", m); sv_PrintInteger(out, &(src->version), "Version", level + 1); sv_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm"); sv_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information", level + 1); sv_PrintAsHex(out, &src->digest, "Digest", level + 1); } #endif /* ** secu_PrintPKCS7ContentInfo ** Takes a SEC_PKCS7ContentInfo type and sends the contents to the ** appropriate function */ int sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m) { const char *desc; SECOidTag kind; int rv; if (src->contentTypeTag == NULL) src->contentTypeTag = SECOID_FindOID(&(src->contentType)); if (src->contentTypeTag == NULL) { desc = "Unknown"; kind = SEC_OID_PKCS7_DATA; } else { desc = src->contentTypeTag->desc; kind = src->contentTypeTag->offset; } fprintf(out, "%s%s\n", m, desc); if (src->content.data == NULL) { fprintf(out, "pkcs7.data=\n"); return 0; } rv = 0; switch (kind) { case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */ rv = sv_PrintPKCS7Signed(out, src->content.signedData); break; case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */ fprintf(out, "pkcs7EnvelopedData=\n"); /*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/ break; case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */ fprintf(out, "pkcs7SignedEnvelopedData=\n"); /*rv = sv_PrintPKCS7SignedAndEnveloped(out, src->content.signedAndEnvelopedData);*/ break; case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */ fprintf(out, "pkcs7DigestedData=\n"); /*sv_PrintPKCS7Digested(out, src->content.digestedData);*/ break; case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */ fprintf(out, "pkcs7EncryptedData=\n"); /*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/ break; default: fprintf(out, "pkcs7UnknownData=\n"); /*sv_PrintAsHex(out, src->content.data);*/ break; } return rv; } int SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der) { SEC_PKCS7ContentInfo *cinfo; int rv = -1; cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (cinfo != NULL) { rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo="); SEC_PKCS7DestroyContentInfo(cinfo); } return rv; } /* ** End of PKCS7 functions */