p7content.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:8k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. /*
  34.  * p7content -- A command to display pkcs7 content.
  35.  *
  36.  * $Id: p7content.c,v 1.1 2000/03/31 20:12:19 relyea%netscape.com Exp $
  37.  */
  38. #include "nspr.h"
  39. #include "secutil.h"
  40. #include "plgetopt.h"
  41. #include "secpkcs7.h"
  42. #include "cert.h"
  43. #include "certdb.h"
  44. #include "cdbhdl.h"
  45. #if defined(XP_UNIX)
  46. #include <unistd.h>
  47. #endif
  48. #include <stdio.h>
  49. #include <string.h>
  50. #if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4))
  51. extern int fwrite(char *, size_t, size_t, FILE*);
  52. extern int fprintf(FILE *, char *, ...);
  53. #endif
  54. extern void SEC_Init(void); /* XXX */
  55. static void
  56. Usage(char *progName)
  57. {
  58.     fprintf(stderr,
  59.     "Usage:  %s [-d dbdir] [-i input] [-o output]n",
  60.     progName);
  61.     fprintf(stderr,
  62.     "%-20s Key/Cert database directory (default is ~/.netscape)n",
  63.     "-d dbdir");
  64.     fprintf(stderr, "%-20s Define an input file to use (default is stdin)n",
  65.     "-i input");
  66.     fprintf(stderr, "%-20s Define an output file to use (default is stdout)n",
  67.     "-o output");
  68.     exit(-1);
  69. }
  70. static SECKEYKeyDBHandle *
  71. OpenKeyDB(char *progName)
  72. {
  73.     SECKEYKeyDBHandle *keyHandle;
  74.     keyHandle = SECU_OpenKeyDB(PR_FALSE);
  75.     if (keyHandle == NULL) {
  76.         SECU_PrintError(progName, "could not open key database");
  77. return NULL;
  78.     }
  79.     return(keyHandle);
  80. }
  81. static CERTCertDBHandle certHandleStatic; /* avoid having to allocate */
  82. static CERTCertDBHandle *
  83. OpenCertDB(char *progName)
  84. {
  85.     CERTCertDBHandle *certHandle;
  86.     SECStatus rv;
  87.     certHandle = &certHandleStatic;
  88.     rv = CERT_OpenCertDB(certHandle, PR_FALSE, SECU_CertDBNameCallback, NULL);
  89.     if (rv != SECSuccess) {
  90.         SECU_PrintError(progName, "could not open cert database");
  91. return NULL;
  92.     }
  93.     return certHandle;
  94. }
  95. static PRBool saw_content;
  96. static void
  97. PrintBytes(void *arg, const char *buf, unsigned long len)
  98. {
  99.     FILE *out;
  100.     out = arg; 
  101.     fwrite (buf, len, 1, out);
  102.     saw_content = PR_TRUE;
  103. }
  104. /*
  105.  * XXX Someday we may want to do real policy stuff here.  This allows
  106.  * anything to be decrypted, which is okay for a test program but does
  107.  * not set an example of how a real client with a real policy would
  108.  * need to do it.
  109.  */
  110. static PRBool
  111. decryption_allowed(SECAlgorithmID *algid, PK11SymKey *key)
  112. {
  113.     return PR_TRUE;
  114. }
  115. int
  116. DecodeAndPrintFile(FILE *out, PRFileDesc *in, char *progName)
  117. {
  118.     SECItem derdata;
  119.     SEC_PKCS7ContentInfo *cinfo;
  120.     SEC_PKCS7DecoderContext *dcx;
  121. if (SECU_ReadDERFromFile(&derdata, in, PR_FALSE)) {
  122.         SECU_PrintError(progName, "error converting der");
  123. return -1;
  124.     }
  125.     fprintf(out,
  126.     "Content printed between bars (newline added before second bar):");
  127.     fprintf(out, "n---------------------------------------------n");
  128.     saw_content = PR_FALSE;
  129.     dcx = SEC_PKCS7DecoderStart(PrintBytes, out, SECU_GetPassword, NULL,
  130. NULL, NULL, decryption_allowed);
  131.     if (dcx != NULL) {
  132. #if 0 /* Test that decoder works when data is really streaming in. */
  133. {
  134.     unsigned long i;
  135.     for (i = 0; i < derdata.len; i++)
  136. SEC_PKCS7DecoderUpdate(dcx, derdata.data + i, 1);
  137. }
  138. #else
  139. SEC_PKCS7DecoderUpdate(dcx, derdata.data, derdata.len);
  140. #endif
  141. cinfo = SEC_PKCS7DecoderFinish(dcx);
  142.     }
  143.     fprintf(out, "n---------------------------------------------n");
  144.     if (cinfo == NULL)
  145. return -1;
  146.     fprintf(out, "Content was%s encrypted.n",
  147.     SEC_PKCS7ContentIsEncrypted(cinfo) ? "" : " not");
  148.     if (SEC_PKCS7ContentIsSigned(cinfo)) {
  149. char *signer_cname, *signer_ename;
  150. SECItem *signing_time;
  151. if (saw_content) {
  152.     fprintf(out, "Signature is ");
  153.     PORT_SetError(0);
  154.     if (SEC_PKCS7VerifySignature(cinfo, certUsageEmailSigner, PR_FALSE))
  155. fprintf(out, "valid.n");
  156.     else
  157. fprintf(out, "invalid (Reason: %s).n",
  158. SECU_Strerror(PORT_GetError()));
  159. } else {
  160.     fprintf(out,
  161.     "Content is detached; signature cannot be verified.n");
  162. }
  163. signer_cname = SEC_PKCS7GetSignerCommonName(cinfo);
  164. if (signer_cname != NULL) {
  165.     fprintf(out, "The signer's common name is %sn", signer_cname);
  166.     PORT_Free(signer_cname);
  167. } else {
  168.     fprintf(out, "No signer common name.n");
  169. }
  170. signer_ename = SEC_PKCS7GetSignerEmailAddress(cinfo);
  171. if (signer_ename != NULL) {
  172.     fprintf(out, "The signer's email address is %sn", signer_ename);
  173.     PORT_Free(signer_ename);
  174. } else {
  175.     fprintf(out, "No signer email address.n");
  176. }
  177. signing_time = SEC_PKCS7GetSigningTime(cinfo);
  178. if (signing_time != NULL) {
  179.     SECU_PrintUTCTime(out, signing_time, "Signing time", 0);
  180. } else {
  181.     fprintf(out, "No signing time included.n");
  182. }
  183.     } else {
  184. fprintf(out, "Content was not signed.n");
  185.     }
  186.     fprintf(out, "There were%s certs or crls included.n",
  187.     SEC_PKCS7ContainsCertsOrCrls(cinfo) ? "" : " no");
  188.     SEC_PKCS7DestroyContentInfo(cinfo);
  189.     return 0;
  190. }
  191. /*
  192.  * Print the contents of a PKCS7 message, indicating signatures, etc.
  193.  */
  194. int
  195. main(int argc, char **argv)
  196. {
  197.     char *progName;
  198.     FILE *outFile;
  199.     PRFileDesc *inFile;
  200.     SECKEYKeyDBHandle *keyHandle;
  201.     CERTCertDBHandle *certHandle;
  202.     PLOptState *optstate;
  203.     PLOptStatus status;
  204.     progName = strrchr(argv[0], '/');
  205.     progName = progName ? progName+1 : argv[0];
  206.     inFile = NULL;
  207.     outFile = NULL;
  208.     /*
  209.      * Parse command line arguments
  210.      */
  211.     optstate = PL_CreateOptState(argc, argv, "d:i:o:");
  212.     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
  213. switch (optstate->option) {
  214.   case 'd':
  215.     SECU_ConfigDirectory(optstate->value);
  216.     break;
  217.   case 'i':
  218.     inFile = PR_Open(optstate->value, PR_RDONLY, 0);
  219.     if (!inFile) {
  220. fprintf(stderr, "%s: unable to open "%s" for readingn",
  221. progName, optstate->value);
  222. return -1;
  223.     }
  224.     break;
  225.   case 'o':
  226.     outFile = fopen(optstate->value, "w");
  227.     if (!outFile) {
  228. fprintf(stderr, "%s: unable to open "%s" for writingn",
  229. progName, optstate->value);
  230. return -1;
  231.     }
  232.     break;
  233.   default:
  234.     Usage(progName);
  235.     break;
  236. }
  237.     }
  238.     if (status == PL_OPT_BAD)
  239. Usage(progName);
  240.     if (!inFile) inFile = PR_STDIN;
  241.     if (!outFile) outFile = stdout;
  242.     /* Call the initialization routines */
  243.     PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
  244.     SECU_PKCS11Init(PR_FALSE);
  245.     SEC_Init();
  246.     /* open key database */
  247.     keyHandle = OpenKeyDB(progName);
  248.     if (keyHandle == NULL) {
  249. return -1;
  250.     }
  251.     SECKEY_SetDefaultKeyDB(keyHandle);
  252.     /* open cert database */
  253.     certHandle = OpenCertDB(progName);
  254.     if (certHandle == NULL) {
  255. return -1;
  256.     }
  257.     CERT_SetDefaultCertDB(certHandle);
  258.     if (DecodeAndPrintFile(outFile, inFile, progName)) {
  259. SECU_PrintError(progName, "problem decoding data");
  260. return -1;
  261.     }
  262.     return 0;
  263. }