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