security/nss/cmd/signver/pk7print.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial