/security/nss/cmd/signver/pk7print.c

http://github.com/zpao/v8monkey · C · 900 lines · 646 code · 135 blank · 119 comment · 129 complexity · 5af7b4e7e1884209942efb65fecf9fe2 MD5 · raw file

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