1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/signver/pk7print.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,868 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 +** secutil.c - various functions used by security stuff 1.10 +** 1.11 +*/ 1.12 + 1.13 +/* pkcs #7 -related functions */ 1.14 + 1.15 + 1.16 +#include "secutil.h" 1.17 +#include "secpkcs7.h" 1.18 +#include "secoid.h" 1.19 +#include <sys/stat.h> 1.20 +#include <stdarg.h> 1.21 + 1.22 +#ifdef XP_UNIX 1.23 +#include <unistd.h> 1.24 +#endif 1.25 + 1.26 +/* for SEC_TraverseNames */ 1.27 +#include "cert.h" 1.28 +#include "prtypes.h" 1.29 +#include "prtime.h" 1.30 + 1.31 +#include "prlong.h" 1.32 +#include "secmod.h" 1.33 +#include "pk11func.h" 1.34 +#include "prerror.h" 1.35 + 1.36 + 1.37 + 1.38 + 1.39 +/* 1.40 +** PKCS7 Support 1.41 +*/ 1.42 + 1.43 +/* forward declaration */ 1.44 +int 1.45 +sv_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *); 1.46 + 1.47 + 1.48 +void 1.49 +sv_PrintAsHex(FILE *out, SECItem *data, char *m) 1.50 +{ 1.51 + unsigned i; 1.52 + 1.53 + if (m) fprintf(out, "%s", m); 1.54 + 1.55 + for (i = 0; i < data->len; i++) { 1.56 + if (i < data->len - 1) { 1.57 + fprintf(out, "%02x:", data->data[i]); 1.58 + } else { 1.59 + fprintf(out, "%02x\n", data->data[i]); 1.60 + break; 1.61 + } 1.62 + } 1.63 +} 1.64 + 1.65 +void 1.66 +sv_PrintInteger(FILE *out, SECItem *i, char *m) 1.67 +{ 1.68 + int iv; 1.69 + 1.70 + if (i->len > 4) { 1.71 + sv_PrintAsHex(out, i, m); 1.72 + } else { 1.73 + iv = DER_GetInteger(i); 1.74 + fprintf(out, "%s%d (0x%x)\n", m, iv, iv); 1.75 + } 1.76 +} 1.77 + 1.78 + 1.79 +int 1.80 +sv_PrintTime(FILE *out, SECItem *t, char *m) 1.81 +{ 1.82 + PRExplodedTime printableTime; 1.83 + PRTime time; 1.84 + char *timeString; 1.85 + int rv; 1.86 + 1.87 + rv = DER_DecodeTimeChoice(&time, t); 1.88 + if (rv) return rv; 1.89 + 1.90 + /* Convert to local time */ 1.91 + PR_ExplodeTime(time, PR_LocalTimeParameters, &printableTime); 1.92 + 1.93 + timeString = (char *)PORT_Alloc(256); 1.94 + 1.95 + if ( timeString ) { 1.96 + if (PR_FormatTime( timeString, 256, "%a %b %d %H:%M:%S %Y", &printableTime )) { 1.97 + fprintf(out, "%s%s\n", m, timeString); 1.98 + } 1.99 + PORT_Free(timeString); 1.100 + return 0; 1.101 + } 1.102 + return SECFailure; 1.103 +} 1.104 + 1.105 +int 1.106 +sv_PrintValidity(FILE *out, CERTValidity *v, char *m) 1.107 +{ 1.108 + int rv; 1.109 + 1.110 + fprintf(out, "%s", m); 1.111 + rv = sv_PrintTime(out, &v->notBefore, "notBefore="); 1.112 + if (rv) return rv; 1.113 + fprintf(out, "%s", m); 1.114 + sv_PrintTime(out, &v->notAfter, "notAfter="); 1.115 + return rv; 1.116 +} 1.117 + 1.118 +void 1.119 +sv_PrintObjectID(FILE *out, SECItem *oid, char *m) 1.120 +{ 1.121 + const char *name; 1.122 + SECOidData *oiddata; 1.123 + 1.124 + oiddata = SECOID_FindOID(oid); 1.125 + if (oiddata == NULL) { 1.126 + sv_PrintAsHex(out, oid, m); 1.127 + return; 1.128 + } 1.129 + name = oiddata->desc; 1.130 + 1.131 + if (m != NULL) 1.132 + fprintf(out, "%s", m); 1.133 + fprintf(out, "%s\n", name); 1.134 +} 1.135 + 1.136 +void 1.137 +sv_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m) 1.138 +{ 1.139 + sv_PrintObjectID(out, &a->algorithm, m); 1.140 + 1.141 + if ((a->parameters.len != 2) || 1.142 + (PORT_Memcmp(a->parameters.data, "\005\000", 2) != 0)) { 1.143 + /* Print args to algorithm */ 1.144 + sv_PrintAsHex(out, &a->parameters, "Args="); 1.145 + } 1.146 +} 1.147 + 1.148 +void 1.149 +sv_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m) 1.150 +{ 1.151 + SECItem *value; 1.152 + int i; 1.153 + char om[100]; 1.154 + 1.155 + fprintf(out, "%s", m); 1.156 + 1.157 + /* 1.158 + * XXX Make this smarter; look at the type field and then decode 1.159 + * and print the value(s) appropriately! 1.160 + */ 1.161 + sv_PrintObjectID(out, &(attr->type), "type="); 1.162 + if (attr->values != NULL) { 1.163 + i = 0; 1.164 + while ((value = attr->values[i]) != NULL) { 1.165 + sprintf(om, "%svalue[%d]=%s", m, i++, attr->encoded ? "(encoded)" : ""); 1.166 + if (attr->encoded || attr->typeTag == NULL) { 1.167 + sv_PrintAsHex(out, value, om); 1.168 + } else { 1.169 + switch (attr->typeTag->offset) { 1.170 + default: 1.171 + sv_PrintAsHex(out, value, om); 1.172 + break; 1.173 + case SEC_OID_PKCS9_CONTENT_TYPE: 1.174 + sv_PrintObjectID(out, value, om); 1.175 + break; 1.176 + case SEC_OID_PKCS9_SIGNING_TIME: 1.177 + sv_PrintTime(out, value, om); 1.178 + break; 1.179 + } 1.180 + } 1.181 + } 1.182 + } 1.183 +} 1.184 + 1.185 +void 1.186 +sv_PrintName(FILE *out, CERTName *name, char *msg) 1.187 +{ 1.188 + char *str; 1.189 + 1.190 + str = CERT_NameToAscii(name); 1.191 + fprintf(out, "%s%s\n", msg, str); 1.192 + PORT_Free(str); 1.193 +} 1.194 + 1.195 + 1.196 +#if 0 1.197 +/* 1.198 +** secu_PrintPKCS7EncContent 1.199 +** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it) 1.200 +*/ 1.201 +void 1.202 +secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src, 1.203 + char *m, int level) 1.204 +{ 1.205 + if (src->contentTypeTag == NULL) 1.206 + src->contentTypeTag = SECOID_FindOID(&(src->contentType)); 1.207 + 1.208 + secu_Indent(out, level); 1.209 + fprintf(out, "%s:\n", m); 1.210 + secu_Indent(out, level + 1); 1.211 + fprintf(out, "Content Type: %s\n", 1.212 + (src->contentTypeTag != NULL) ? src->contentTypeTag->desc 1.213 + : "Unknown"); 1.214 + sv_PrintAlgorithmID(out, &(src->contentEncAlg), 1.215 + "Content Encryption Algorithm"); 1.216 + sv_PrintAsHex(out, &(src->encContent), 1.217 + "Encrypted Content", level+1); 1.218 +} 1.219 + 1.220 +/* 1.221 +** secu_PrintRecipientInfo 1.222 +** Prints a PKCS7RecipientInfo type 1.223 +*/ 1.224 +void 1.225 +secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m, 1.226 + int level) 1.227 +{ 1.228 + secu_Indent(out, level); fprintf(out, "%s:\n", m); 1.229 + sv_PrintInteger(out, &(info->version), "Version"); 1.230 + 1.231 + sv_PrintName(out, &(info->issuerAndSN->issuer), "Issuer"); 1.232 + sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), 1.233 + "Serial Number"); 1.234 + 1.235 + /* Parse and display encrypted key */ 1.236 + sv_PrintAlgorithmID(out, &(info->keyEncAlg), 1.237 + "Key Encryption Algorithm"); 1.238 + sv_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1); 1.239 +} 1.240 +#endif 1.241 + 1.242 +/* 1.243 +** secu_PrintSignerInfo 1.244 +** Prints a PKCS7SingerInfo type 1.245 +*/ 1.246 +void 1.247 +sv_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m) 1.248 +{ 1.249 + SEC_PKCS7Attribute *attr; 1.250 + int iv; 1.251 + 1.252 + fprintf(out, "%s", m); 1.253 + sv_PrintInteger(out, &(info->version), "version="); 1.254 + 1.255 + fprintf(out, "%s", m); 1.256 + sv_PrintName(out, &(info->issuerAndSN->issuer), "issuerName="); 1.257 + fprintf(out, "%s", m); 1.258 + sv_PrintInteger(out, &(info->issuerAndSN->serialNumber), 1.259 + "serialNumber="); 1.260 + 1.261 + fprintf(out, "%s", m); 1.262 + sv_PrintAlgorithmID(out, &(info->digestAlg), "digestAlgorithm="); 1.263 + 1.264 + if (info->authAttr != NULL) { 1.265 + char mm[120]; 1.266 + 1.267 + iv = 0; 1.268 + while (info->authAttr[iv] != NULL) iv++; 1.269 + fprintf(out, "%sauthenticatedAttributes=%d\n", m, iv); 1.270 + iv = 0; 1.271 + while ((attr = info->authAttr[iv]) != NULL) { 1.272 + sprintf(mm, "%sattribute[%d].", m, iv++); 1.273 + sv_PrintAttribute(out, attr, mm); 1.274 + } 1.275 + } 1.276 + 1.277 + /* Parse and display signature */ 1.278 + fprintf(out, "%s", m); 1.279 + sv_PrintAlgorithmID(out, &(info->digestEncAlg), "digestEncryptionAlgorithm="); 1.280 + fprintf(out, "%s", m); 1.281 + sv_PrintAsHex(out, &(info->encDigest), "encryptedDigest="); 1.282 + 1.283 + if (info->unAuthAttr != NULL) { 1.284 + char mm[120]; 1.285 + 1.286 + iv = 0; 1.287 + while (info->unAuthAttr[iv] != NULL) iv++; 1.288 + fprintf(out, "%sunauthenticatedAttributes=%d\n", m, iv); 1.289 + iv = 0; 1.290 + while ((attr = info->unAuthAttr[iv]) != NULL) { 1.291 + sprintf(mm, "%sattribute[%d].", m, iv++); 1.292 + sv_PrintAttribute(out, attr, mm); 1.293 + } 1.294 + } 1.295 +} 1.296 + 1.297 +void 1.298 +sv_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m) 1.299 +{ 1.300 + fprintf(out, "%s", m); 1.301 + sv_PrintInteger(out, &pk->u.rsa.modulus, "modulus="); 1.302 + fprintf(out, "%s", m); 1.303 + sv_PrintInteger(out, &pk->u.rsa.publicExponent, "exponent="); 1.304 +} 1.305 + 1.306 +void 1.307 +sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m) 1.308 +{ 1.309 + fprintf(out, "%s", m); 1.310 + sv_PrintInteger(out, &pk->u.dsa.params.prime, "prime="); 1.311 + fprintf(out, "%s", m); 1.312 + sv_PrintInteger(out, &pk->u.dsa.params.subPrime, "subprime="); 1.313 + fprintf(out, "%s", m); 1.314 + sv_PrintInteger(out, &pk->u.dsa.params.base, "base="); 1.315 + fprintf(out, "%s", m); 1.316 + sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue="); 1.317 +} 1.318 + 1.319 +int 1.320 +sv_PrintSubjectPublicKeyInfo(FILE *out, PLArenaPool *arena, 1.321 + CERTSubjectPublicKeyInfo *i, char *msg) 1.322 +{ 1.323 + SECKEYPublicKey *pk; 1.324 + int rv; 1.325 + char mm[200]; 1.326 + 1.327 + sprintf(mm, "%s.publicKeyAlgorithm=", msg); 1.328 + sv_PrintAlgorithmID(out, &i->algorithm, mm); 1.329 + 1.330 + pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey)); 1.331 + if (!pk) return PORT_GetError(); 1.332 + 1.333 + DER_ConvertBitString(&i->subjectPublicKey); 1.334 + switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) { 1.335 + case SEC_OID_PKCS1_RSA_ENCRYPTION: 1.336 + rv = SEC_ASN1DecodeItem(arena, pk, 1.337 + SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), 1.338 + &i->subjectPublicKey); 1.339 + if (rv) return rv; 1.340 + sprintf(mm, "%s.rsaPublicKey.", msg); 1.341 + sv_PrintRSAPublicKey(out, pk, mm); 1.342 + break; 1.343 + case SEC_OID_ANSIX9_DSA_SIGNATURE: 1.344 + rv = SEC_ASN1DecodeItem(arena, pk, 1.345 + SEC_ASN1_GET(SECKEY_DSAPublicKeyTemplate), 1.346 + &i->subjectPublicKey); 1.347 + if (rv) return rv; 1.348 + sprintf(mm, "%s.dsaPublicKey.", msg); 1.349 + sv_PrintDSAPublicKey(out, pk, mm); 1.350 + break; 1.351 + default: 1.352 + fprintf(out, "%s=bad SPKI algorithm type\n", msg); 1.353 + return 0; 1.354 + } 1.355 + 1.356 + return 0; 1.357 +} 1.358 + 1.359 +SECStatus 1.360 +sv_PrintInvalidDateExten (FILE *out, SECItem *value, char *msg) 1.361 +{ 1.362 + SECItem decodedValue; 1.363 + SECStatus rv; 1.364 + PRTime invalidTime; 1.365 + char *formattedTime = NULL; 1.366 + 1.367 + decodedValue.data = NULL; 1.368 + rv = SEC_ASN1DecodeItem (NULL, &decodedValue, 1.369 + SEC_ASN1_GET(SEC_GeneralizedTimeTemplate), 1.370 + value); 1.371 + if (rv == SECSuccess) { 1.372 + rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue); 1.373 + if (rv == SECSuccess) { 1.374 + formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y"); 1.375 + fprintf (out, "%s: %s\n", msg, formattedTime); 1.376 + PORT_Free (formattedTime); 1.377 + } 1.378 + } 1.379 + PORT_Free (decodedValue.data); 1.380 + 1.381 + return (rv); 1.382 +} 1.383 + 1.384 +int 1.385 +sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg) 1.386 +{ 1.387 + SECOidTag oidTag; 1.388 + 1.389 + if (extensions) { 1.390 + 1.391 + while ( *extensions ) { 1.392 + SECItem *tmpitem; 1.393 + 1.394 + fprintf(out, "%sname=", msg); 1.395 + 1.396 + tmpitem = &(*extensions)->id; 1.397 + sv_PrintObjectID(out, tmpitem, NULL); 1.398 + 1.399 + tmpitem = &(*extensions)->critical; 1.400 + if ( tmpitem->len ) 1.401 + fprintf(out, "%scritical=%s\n", msg, 1.402 + (tmpitem->data && tmpitem->data[0])? "True": "False"); 1.403 + 1.404 + oidTag = SECOID_FindOIDTag (&((*extensions)->id)); 1.405 + 1.406 + fprintf(out, "%s", msg); 1.407 + tmpitem = &((*extensions)->value); 1.408 + if (oidTag == SEC_OID_X509_INVALID_DATE) 1.409 + sv_PrintInvalidDateExten (out, tmpitem,"invalidExt"); 1.410 + else 1.411 + sv_PrintAsHex(out,tmpitem, "data="); 1.412 + 1.413 + /*fprintf(out, "\n");*/ 1.414 + extensions++; 1.415 + } 1.416 + } 1.417 + 1.418 + return 0; 1.419 +} 1.420 + 1.421 +/* callers of this function must make sure that the CERTSignedCrl 1.422 + from which they are extracting the CERTCrl has been fully-decoded. 1.423 + Otherwise it will not have the entries even though the CRL may have 1.424 + some */ 1.425 +void 1.426 +sv_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m) 1.427 +{ 1.428 + CERTCrlEntry *entry; 1.429 + int iv; 1.430 + char om[100]; 1.431 + 1.432 + fprintf(out, "%s", m); 1.433 + sv_PrintAlgorithmID(out, &(crl->signatureAlg), "signatureAlgorithm="); 1.434 + fprintf(out, "%s", m); 1.435 + sv_PrintName(out, &(crl->name), "name="); 1.436 + fprintf(out, "%s", m); 1.437 + sv_PrintTime(out, &(crl->lastUpdate), "lastUpdate="); 1.438 + fprintf(out, "%s", m); 1.439 + sv_PrintTime(out, &(crl->nextUpdate), "nextUpdate="); 1.440 + 1.441 + if (crl->entries != NULL) { 1.442 + iv = 0; 1.443 + while ((entry = crl->entries[iv]) != NULL) { 1.444 + fprintf(out, "%sentry[%d].", m, iv); 1.445 + sv_PrintInteger(out, &(entry->serialNumber), "serialNumber="); 1.446 + fprintf(out, "%sentry[%d].", m, iv); 1.447 + sv_PrintTime(out, &(entry->revocationDate), "revocationDate="); 1.448 + sprintf(om, "%sentry[%d].signedCRLEntriesExtensions.", m, iv++); 1.449 + sv_PrintExtensions(out, entry->extensions, om); 1.450 + } 1.451 + } 1.452 + sprintf(om, "%ssignedCRLEntriesExtensions.", m); 1.453 + sv_PrintExtensions(out, crl->extensions, om); 1.454 +} 1.455 + 1.456 + 1.457 +int 1.458 +sv_PrintCertificate(FILE *out, SECItem *der, char *m, int level) 1.459 +{ 1.460 + PLArenaPool *arena = NULL; 1.461 + CERTCertificate *c; 1.462 + int rv; 1.463 + int iv; 1.464 + char mm[200]; 1.465 + 1.466 + /* Decode certificate */ 1.467 + c = (CERTCertificate*) PORT_ZAlloc(sizeof(CERTCertificate)); 1.468 + if (!c) return PORT_GetError(); 1.469 + 1.470 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1.471 + if (!arena) return SEC_ERROR_NO_MEMORY; 1.472 + 1.473 + rv = SEC_ASN1DecodeItem(arena, c, SEC_ASN1_GET(CERT_CertificateTemplate), 1.474 + der); 1.475 + if (rv) { 1.476 + PORT_FreeArena(arena, PR_FALSE); 1.477 + return rv; 1.478 + } 1.479 + 1.480 + /* Pretty print it out */ 1.481 + iv = DER_GetInteger(&c->version); 1.482 + fprintf(out, "%sversion=%d (0x%x)\n", m, iv + 1, iv); 1.483 + sprintf(mm, "%sserialNumber=", m); 1.484 + sv_PrintInteger(out, &c->serialNumber, mm); 1.485 + sprintf(mm, "%ssignatureAlgorithm=", m); 1.486 + sv_PrintAlgorithmID(out, &c->signature, mm); 1.487 + sprintf(mm, "%sissuerName=", m); 1.488 + sv_PrintName(out, &c->issuer, mm); 1.489 + sprintf(mm, "%svalidity.", m); 1.490 + sv_PrintValidity(out, &c->validity, mm); 1.491 + sprintf(mm, "%ssubject=", m); 1.492 + sv_PrintName(out, &c->subject, mm); 1.493 + sprintf(mm, "%ssubjectPublicKeyInfo", m); 1.494 + rv = sv_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo, mm); 1.495 + if (rv) { 1.496 + PORT_FreeArena(arena, PR_FALSE); 1.497 + return rv; 1.498 + } 1.499 + sprintf(mm, "%ssignedExtensions.", m); 1.500 + sv_PrintExtensions(out, c->extensions, mm); 1.501 + 1.502 + PORT_FreeArena(arena, PR_FALSE); 1.503 + return 0; 1.504 +} 1.505 + 1.506 +int 1.507 +sv_PrintSignedData(FILE *out, SECItem *der, char *m, SECU_PPFunc inner) 1.508 +{ 1.509 + PLArenaPool *arena = NULL; 1.510 + CERTSignedData *sd; 1.511 + int rv; 1.512 + 1.513 + /* Strip off the signature */ 1.514 + sd = (CERTSignedData*) PORT_ZAlloc(sizeof(CERTSignedData)); 1.515 + if (!sd) return PORT_GetError(); 1.516 + 1.517 + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 1.518 + if (!arena) return SEC_ERROR_NO_MEMORY; 1.519 + 1.520 + rv = SEC_ASN1DecodeItem(arena, sd, SEC_ASN1_GET(CERT_SignedDataTemplate), 1.521 + der); 1.522 + if (rv) { 1.523 + PORT_FreeArena(arena, PR_FALSE); 1.524 + return rv; 1.525 + } 1.526 + 1.527 +/* fprintf(out, "%s:\n", m); */ 1.528 + PORT_Strcat(m, "data."); 1.529 + 1.530 + rv = (*inner)(out, &sd->data, m, 0); 1.531 + if (rv) { 1.532 + PORT_FreeArena(arena, PR_FALSE); 1.533 + return rv; 1.534 + } 1.535 + 1.536 + m[PORT_Strlen(m) - 5] = 0; 1.537 + fprintf(out, "%s", m); 1.538 + sv_PrintAlgorithmID(out, &sd->signatureAlgorithm, "signatureAlgorithm="); 1.539 + DER_ConvertBitString(&sd->signature); 1.540 + fprintf(out, "%s", m); 1.541 + sv_PrintAsHex(out, &sd->signature, "signature="); 1.542 + 1.543 + PORT_FreeArena(arena, PR_FALSE); 1.544 + return 0; 1.545 + 1.546 +} 1.547 + 1.548 + 1.549 +/* 1.550 +** secu_PrintPKCS7Signed 1.551 +** Pretty print a PKCS7 signed data type (up to version 1). 1.552 +*/ 1.553 +int 1.554 +sv_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src) 1.555 +{ 1.556 + SECAlgorithmID *digAlg; /* digest algorithms */ 1.557 + SECItem *aCert; /* certificate */ 1.558 + CERTSignedCrl *aCrl; /* certificate revocation list */ 1.559 + SEC_PKCS7SignerInfo *sigInfo; /* signer information */ 1.560 + int rv, iv; 1.561 + char om[120]; 1.562 + 1.563 + sv_PrintInteger(out, &(src->version), "pkcs7.version="); 1.564 + 1.565 + /* Parse and list digest algorithms (if any) */ 1.566 + if (src->digestAlgorithms != NULL) { 1.567 + iv = 0; 1.568 + while (src->digestAlgorithms[iv] != NULL) 1.569 + iv++; 1.570 + fprintf(out, "pkcs7.digestAlgorithmListLength=%d\n", iv); 1.571 + iv = 0; 1.572 + while ((digAlg = src->digestAlgorithms[iv]) != NULL) { 1.573 + sprintf(om, "pkcs7.digestAlgorithm[%d]=", iv++); 1.574 + sv_PrintAlgorithmID(out, digAlg, om); 1.575 + } 1.576 + } 1.577 + 1.578 + /* Now for the content */ 1.579 + rv = sv_PrintPKCS7ContentInfo(out, &(src->contentInfo), 1.580 + "pkcs7.contentInformation="); 1.581 + if (rv != 0) return rv; 1.582 + 1.583 + /* Parse and list certificates (if any) */ 1.584 + if (src->rawCerts != NULL) { 1.585 + iv = 0; 1.586 + while (src->rawCerts[iv] != NULL) 1.587 + iv++; 1.588 + fprintf(out, "pkcs7.certificateListLength=%d\n", iv); 1.589 + 1.590 + iv = 0; 1.591 + while ((aCert = src->rawCerts[iv]) != NULL) { 1.592 + sprintf(om, "certificate[%d].", iv++); 1.593 + rv = sv_PrintSignedData(out, aCert, om, sv_PrintCertificate); 1.594 + if (rv) return rv; 1.595 + } 1.596 + } 1.597 + 1.598 + /* Parse and list CRL's (if any) */ 1.599 + if (src->crls != NULL) { 1.600 + iv = 0; 1.601 + while (src->crls[iv] != NULL) iv++; 1.602 + fprintf(out, "pkcs7.signedRevocationLists=%d\n", iv); 1.603 + iv = 0; 1.604 + while ((aCrl = src->crls[iv]) != NULL) { 1.605 + sprintf(om, "signedRevocationList[%d].", iv); 1.606 + fprintf(out, "%s", om); 1.607 + sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, 1.608 + "signatureAlgorithm="); 1.609 + DER_ConvertBitString(&aCrl->signatureWrap.signature); 1.610 + fprintf(out, "%s", om); 1.611 + sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "signature="); 1.612 + sprintf(om, "certificateRevocationList[%d].", iv); 1.613 + sv_PrintCRLInfo(out, &aCrl->crl, om); 1.614 + iv++; 1.615 + } 1.616 + } 1.617 + 1.618 + /* Parse and list signatures (if any) */ 1.619 + if (src->signerInfos != NULL) { 1.620 + iv = 0; 1.621 + while (src->signerInfos[iv] != NULL) 1.622 + iv++; 1.623 + fprintf(out, "pkcs7.signerInformationListLength=%d\n", iv); 1.624 + iv = 0; 1.625 + while ((sigInfo = src->signerInfos[iv]) != NULL) { 1.626 + sprintf(om, "signerInformation[%d].", iv++); 1.627 + sv_PrintSignerInfo(out, sigInfo, om); 1.628 + } 1.629 + } 1.630 + 1.631 + return 0; 1.632 +} 1.633 + 1.634 +#if 0 1.635 +/* 1.636 +** secu_PrintPKCS7Enveloped 1.637 +** Pretty print a PKCS7 enveloped data type (up to version 1). 1.638 +*/ 1.639 +void 1.640 +secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src, 1.641 + char *m, int level) 1.642 +{ 1.643 + SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */ 1.644 + int iv; 1.645 + char om[100]; 1.646 + 1.647 + secu_Indent(out, level); fprintf(out, "%s:\n", m); 1.648 + sv_PrintInteger(out, &(src->version), "Version", level + 1); 1.649 + 1.650 + /* Parse and list recipients (this is not optional) */ 1.651 + if (src->recipientInfos != NULL) { 1.652 + secu_Indent(out, level + 1); 1.653 + fprintf(out, "Recipient Information List:\n"); 1.654 + iv = 0; 1.655 + while ((recInfo = src->recipientInfos[iv++]) != NULL) { 1.656 + sprintf(om, "Recipient Information (%x)", iv); 1.657 + secu_PrintRecipientInfo(out, recInfo, om, level + 2); 1.658 + } 1.659 + } 1.660 + 1.661 + secu_PrintPKCS7EncContent(out, &src->encContentInfo, 1.662 + "Encrypted Content Information", level + 1); 1.663 +} 1.664 + 1.665 +/* 1.666 +** secu_PrintPKCS7SignedEnveloped 1.667 +** Pretty print a PKCS7 singed and enveloped data type (up to version 1). 1.668 +*/ 1.669 +int 1.670 +secu_PrintPKCS7SignedAndEnveloped(FILE *out, 1.671 + SEC_PKCS7SignedAndEnvelopedData *src, 1.672 + char *m, int level) 1.673 +{ 1.674 + SECAlgorithmID *digAlg; /* pointer for digest algorithms */ 1.675 + SECItem *aCert; /* pointer for certificate */ 1.676 + CERTSignedCrl *aCrl; /* pointer for certificate revocation list */ 1.677 + SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */ 1.678 + SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */ 1.679 + int rv, iv; 1.680 + char om[100]; 1.681 + 1.682 + secu_Indent(out, level); fprintf(out, "%s:\n", m); 1.683 + sv_PrintInteger(out, &(src->version), "Version", level + 1); 1.684 + 1.685 + /* Parse and list recipients (this is not optional) */ 1.686 + if (src->recipientInfos != NULL) { 1.687 + secu_Indent(out, level + 1); 1.688 + fprintf(out, "Recipient Information List:\n"); 1.689 + iv = 0; 1.690 + while ((recInfo = src->recipientInfos[iv++]) != NULL) { 1.691 + sprintf(om, "Recipient Information (%x)", iv); 1.692 + secu_PrintRecipientInfo(out, recInfo, om, level + 2); 1.693 + } 1.694 + } 1.695 + 1.696 + /* Parse and list digest algorithms (if any) */ 1.697 + if (src->digestAlgorithms != NULL) { 1.698 + secu_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n"); 1.699 + iv = 0; 1.700 + while ((digAlg = src->digestAlgorithms[iv++]) != NULL) { 1.701 + sprintf(om, "Digest Algorithm (%x)", iv); 1.702 + sv_PrintAlgorithmID(out, digAlg, om); 1.703 + } 1.704 + } 1.705 + 1.706 + secu_PrintPKCS7EncContent(out, &src->encContentInfo, 1.707 + "Encrypted Content Information", level + 1); 1.708 + 1.709 + /* Parse and list certificates (if any) */ 1.710 + if (src->rawCerts != NULL) { 1.711 + secu_Indent(out, level + 1); fprintf(out, "Certificate List:\n"); 1.712 + iv = 0; 1.713 + while ((aCert = src->rawCerts[iv++]) != NULL) { 1.714 + sprintf(om, "Certificate (%x)", iv); 1.715 + rv = SECU_PrintSignedData(out, aCert, om, level + 2, 1.716 + SECU_PrintCertificate); 1.717 + if (rv) 1.718 + return rv; 1.719 + } 1.720 + } 1.721 + 1.722 + /* Parse and list CRL's (if any) */ 1.723 + if (src->crls != NULL) { 1.724 + secu_Indent(out, level + 1); 1.725 + fprintf(out, "Signed Revocation Lists:\n"); 1.726 + iv = 0; 1.727 + while ((aCrl = src->crls[iv++]) != NULL) { 1.728 + sprintf(om, "Signed Revocation List (%x)", iv); 1.729 + secu_Indent(out, level + 2); fprintf(out, "%s:\n", om); 1.730 + sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm, 1.731 + "Signature Algorithm"); 1.732 + DER_ConvertBitString(&aCrl->signatureWrap.signature); 1.733 + sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature", 1.734 + level+3); 1.735 + SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List", 1.736 + level + 3); 1.737 + } 1.738 + } 1.739 + 1.740 + /* Parse and list signatures (if any) */ 1.741 + if (src->signerInfos != NULL) { 1.742 + secu_Indent(out, level + 1); 1.743 + fprintf(out, "Signer Information List:\n"); 1.744 + iv = 0; 1.745 + while ((sigInfo = src->signerInfos[iv++]) != NULL) { 1.746 + sprintf(om, "Signer Information (%x)", iv); 1.747 + secu_PrintSignerInfo(out, sigInfo, om, level + 2); 1.748 + } 1.749 + } 1.750 + 1.751 + return 0; 1.752 +} 1.753 + 1.754 +/* 1.755 +** secu_PrintPKCS7Encrypted 1.756 +** Pretty print a PKCS7 encrypted data type (up to version 1). 1.757 +*/ 1.758 +void 1.759 +secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src, 1.760 + char *m, int level) 1.761 +{ 1.762 + secu_Indent(out, level); fprintf(out, "%s:\n", m); 1.763 + sv_PrintInteger(out, &(src->version), "Version", level + 1); 1.764 + 1.765 + secu_PrintPKCS7EncContent(out, &src->encContentInfo, 1.766 + "Encrypted Content Information", level + 1); 1.767 +} 1.768 + 1.769 +/* 1.770 +** secu_PrintPKCS7Digested 1.771 +** Pretty print a PKCS7 digested data type (up to version 1). 1.772 +*/ 1.773 +void 1.774 +sv_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src) 1.775 +{ 1.776 + secu_Indent(out, level); fprintf(out, "%s:\n", m); 1.777 + sv_PrintInteger(out, &(src->version), "Version", level + 1); 1.778 + 1.779 + sv_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm"); 1.780 + sv_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information", 1.781 + level + 1); 1.782 + sv_PrintAsHex(out, &src->digest, "Digest", level + 1); 1.783 +} 1.784 + 1.785 +#endif 1.786 + 1.787 +/* 1.788 +** secu_PrintPKCS7ContentInfo 1.789 +** Takes a SEC_PKCS7ContentInfo type and sends the contents to the 1.790 +** appropriate function 1.791 +*/ 1.792 +int 1.793 +sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m) 1.794 +{ 1.795 + const char *desc; 1.796 + SECOidTag kind; 1.797 + int rv; 1.798 + 1.799 + if (src->contentTypeTag == NULL) 1.800 + src->contentTypeTag = SECOID_FindOID(&(src->contentType)); 1.801 + 1.802 + if (src->contentTypeTag == NULL) { 1.803 + desc = "Unknown"; 1.804 + kind = SEC_OID_PKCS7_DATA; 1.805 + } else { 1.806 + desc = src->contentTypeTag->desc; 1.807 + kind = src->contentTypeTag->offset; 1.808 + } 1.809 + 1.810 + fprintf(out, "%s%s\n", m, desc); 1.811 + 1.812 + if (src->content.data == NULL) { 1.813 + fprintf(out, "pkcs7.data=<no content>\n"); 1.814 + return 0; 1.815 + } 1.816 + 1.817 + rv = 0; 1.818 + switch (kind) { 1.819 + case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */ 1.820 + rv = sv_PrintPKCS7Signed(out, src->content.signedData); 1.821 + break; 1.822 + 1.823 + case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */ 1.824 + fprintf(out, "pkcs7EnvelopedData=<unsupported>\n"); 1.825 + /*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/ 1.826 + break; 1.827 + 1.828 + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */ 1.829 + fprintf(out, "pkcs7SignedEnvelopedData=<unsupported>\n"); 1.830 + /*rv = sv_PrintPKCS7SignedAndEnveloped(out, 1.831 + src->content.signedAndEnvelopedData);*/ 1.832 + break; 1.833 + 1.834 + case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */ 1.835 + fprintf(out, "pkcs7DigestedData=<unsupported>\n"); 1.836 + /*sv_PrintPKCS7Digested(out, src->content.digestedData);*/ 1.837 + break; 1.838 + 1.839 + case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */ 1.840 + fprintf(out, "pkcs7EncryptedData=<unsupported>\n"); 1.841 + /*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/ 1.842 + break; 1.843 + 1.844 + default: 1.845 + fprintf(out, "pkcs7UnknownData=<unsupported>\n"); 1.846 + /*sv_PrintAsHex(out, src->content.data);*/ 1.847 + break; 1.848 + } 1.849 + 1.850 + return rv; 1.851 +} 1.852 + 1.853 + 1.854 +int 1.855 +SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der) 1.856 +{ 1.857 + SEC_PKCS7ContentInfo *cinfo; 1.858 + int rv = -1; 1.859 + 1.860 + cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 1.861 + 1.862 + if (cinfo != NULL) { 1.863 + rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo="); 1.864 + SEC_PKCS7DestroyContentInfo(cinfo); 1.865 + } 1.866 + 1.867 + return rv; 1.868 +} 1.869 +/* 1.870 +** End of PKCS7 functions 1.871 +*/