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

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. ** certutil.c
  35. **
  36. ** utility for managing certificates and the cert database
  37. **
  38. */
  39. /* test only */
  40. #include "nspr.h"
  41. #include "plgetopt.h"
  42. #include "secutil.h"
  43. #include "cert.h"
  44. #include "certdb.h"
  45. #include "cdbhdl.h"
  46. #define SEC_CERT_DB_EXISTS 0
  47. #define SEC_CREATE_CERT_DB 1
  48. static char *progName;
  49. static CERTCertDBHandle
  50. *OpenCertDB(int createNew)
  51.   /* NOTE: This routine has been modified to allow the libsec/pcertdb.c  routines to automatically
  52.   ** find and convert the old cert database into the new v3.0 format (cert db version 5).
  53.   */
  54. {
  55.     CERTCertDBHandle *certHandle;
  56.     SECStatus         rv;
  57.     /* Allocate a handle to fill with CERT_OpenCertDB below */
  58.     certHandle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));
  59.     if (!certHandle) {
  60. SECU_PrintError(progName, "unable to get database handle");
  61. return NULL;
  62.     }
  63.     rv = CERT_OpenCertDB(certHandle, PR_FALSE, SECU_CertDBNameCallback, NULL);
  64.     if (rv) {
  65. SECU_PrintError(progName, "could not open certificate database");
  66. if (certHandle) free (certHandle);  /* we don't want to leave anything behind... */
  67. return NULL;
  68.     }
  69.     return certHandle;
  70. }
  71. static CERTSignedCrl *FindCRL
  72.    (CERTCertDBHandle *certHandle, char *name, int type)
  73. {
  74.     CERTSignedCrl *crl = NULL;    
  75.     CERTCertificate *cert = NULL;
  76.     cert = CERT_FindCertByNickname(certHandle, name);
  77.     if (!cert) {
  78. SECU_PrintError(progName, "could not find certificate named %s", name);
  79. return ((CERTSignedCrl *)NULL);
  80.     }
  81.     crl = SEC_FindCrlByKey(certHandle, &cert->derSubject, type);
  82.     if (crl ==NULL) 
  83. SECU_PrintError
  84. (progName, "could not find %s's CRL", name);
  85.     CERT_DestroyCertificate (cert);
  86.     return (crl);
  87. }
  88. static void DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
  89. {
  90.     CERTCertificate *cert = NULL;
  91.     CERTSignedCrl *crl = NULL;
  92.     crl = FindCRL (certHandle, nickName, crlType);
  93.     if (crl) {
  94. SECU_PrintCRLInfo (stdout, &crl->crl, "CRL Info:n", 0);
  95. CERT_DestroyCrl (crl);
  96.     }
  97. }
  98. static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType)
  99. {
  100.     CERTCrlHeadNode *crlList = NULL;
  101.     CERTCrlNode *crlNode = NULL;
  102.     CERTName *name = NULL;
  103.     PRArenaPool *arena = NULL;
  104.     SECStatus rv;
  105.     void *mark;
  106.     do {
  107. arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
  108. if (arena == NULL) {
  109.     fprintf(stderr, "%s: fail to allocate memoryn", progName);
  110.     break;
  111. }
  112. name = PORT_ArenaZAlloc (arena, sizeof(*name));
  113. if (name == NULL) {
  114.     fprintf(stderr, "%s: fail to allocate memoryn", progName);
  115.     break;
  116. }
  117. name->arena = arena;
  118.     
  119. rv = SEC_LookupCrls (certHandle, &crlList, crlType);
  120. if (rv != SECSuccess) {
  121.     fprintf(stderr, "%s: fail to look up CRLs (%s)n", progName,
  122.     SECU_Strerror(PORT_GetError()));
  123.     break;
  124. }
  125. /* just in case */
  126. if (!crlList)
  127.     break;
  128. crlNode  = crlList->first;
  129.         fprintf (stdout, "n");
  130. fprintf (stdout, "n%-40s %-5snn", "CRL names", "CRL Type");
  131. while (crlNode) {
  132.     mark = PORT_ArenaMark (arena);      
  133.     rv = SEC_ASN1DecodeItem
  134.    (arena, name, CERT_NameTemplate, &(crlNode->crl->crl.derName));
  135.     if (!name){
  136. fprintf(stderr, "%s: fail to get the CRL issuer namen", progName,
  137. SECU_Strerror(PORT_GetError()));
  138. break;
  139.     }
  140.     fprintf (stdout, "n%-40s %-5sn", CERT_NameToAscii(name), "CRL");
  141.     crlNode = crlNode->next;
  142.     PORT_ArenaRelease (arena, mark);
  143.     } while (0);
  144.     if (crlList)
  145. PORT_FreeArena (crlList->arena, PR_FALSE);
  146.     PORT_FreeArena (arena, PR_FALSE);
  147. }
  148. static void ListCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
  149. {
  150.     if (nickName == NULL)
  151. ListCRLNames (certHandle, crlType);
  152.     else
  153. DisplayCRL (certHandle, nickName, crlType);
  154. }
  155. static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type)
  156. {
  157.     CERTSignedCrl *crl = NULL;    
  158.     SECStatus rv = SECFailure;
  159.     crl = FindCRL (certHandle, name, type);
  160.     if (!crl) {
  161. SECU_PrintError
  162. (progName, "could not find the issuer %s's CRL", name);
  163. return SECFailure;
  164.     }
  165.     rv = SEC_DeletePermCRL (crl);
  166.     if (rv != SECSuccess) {
  167. SECU_PrintError
  168. (progName, "fail to delete the issuer %s's CRL from the perm dbase (reason: %s)",
  169.  name, SECU_Strerror(PORT_GetError()));
  170. return SECFailure;
  171.     }
  172.     rv = SEC_DeleteTempCrl (crl);
  173.     if (rv != SECSuccess) {
  174. SECU_PrintError
  175. (progName, "fail to delete the issuer %s's CRL from the temp dbase (reason: %s)",
  176.  name, SECU_Strerror(PORT_GetError()));
  177. return SECFailure;
  178.     }
  179.     return (rv);
  180. }
  181. SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, 
  182.                      PRFileDesc *inFile)
  183. {
  184.     CERTCertificate *cert = NULL;
  185.     CERTSignedCrl *crl = NULL;
  186.     SECItem crlDER;
  187.     int rv;
  188.     crlDER.data = NULL;
  189.     /* Read in the entire file specified with the -f argument */
  190. rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
  191.     if (rv != SECSuccess) {
  192. SECU_PrintError(progName, "unable to read input file");
  193. return (SECFailure);
  194.     }
  195.     
  196.     crl = CERT_ImportCRL (certHandle, &crlDER, url, type, NULL);
  197.     if (!crl) {
  198. const char *errString;
  199. errString = SECU_Strerror(PORT_GetError());
  200. if (PORT_Strlen (errString) == 0)
  201.     SECU_PrintError
  202.     (progName, "CRL is not import (error: input CRL is not up to date.)");
  203. else    
  204.     SECU_PrintError
  205.     (progName, "unable to import CRL");
  206.     }
  207.     PORT_Free (crlDER.data);
  208.     CERT_DestroyCrl (crl);
  209.     return (rv);
  210. }
  211.     
  212. static void Usage(char *progName)
  213. {
  214.     fprintf(stderr,
  215.     "Usage:  %s -L [-n nickname[ [-d keydir] [-t crlType]n"
  216.     "        %s -D -n nickname [-d keydir]n"
  217.     "        %s -I -i crl -t crlType [-u url] [-d keydir]n",
  218.     progName, progName, progName);
  219.     fprintf (stderr, "%-15s List CRLn", "-L");
  220.     fprintf(stderr, "%-20s Specify the nickname of the CA certificaten",
  221.     "-n nickname");
  222.     fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)n",
  223.     "-d keydir");
  224.    
  225.     fprintf (stderr, "%-15s Delete a CRL from the cert dbasen", "-D");    
  226.     fprintf(stderr, "%-20s Specify the nickname for the CA certificaten",
  227.     "-n nickname");
  228.     fprintf(stderr, "%-20s Specify the crl type.n", "-t crlType");
  229.     fprintf (stderr, "%-15s Import a CRL to the cert dbasen", "-I");    
  230.     fprintf(stderr, "%-20s Specify the file which contains the CRL to importn",
  231.     "-i crl");
  232.     fprintf(stderr, "%-20s Specify the url.n", "-u url");
  233.     fprintf(stderr, "%-20s Specify the crl type.n", "-t crlType");
  234.     fprintf(stderr, "%-20s CRL Types (default is SEC_CRL_TYPE):n", " ");
  235.     fprintf(stderr, "%-20s t 0 - SEC_KRL_TYPEn", " ");
  236.     fprintf(stderr, "%-20s t 1 - SEC_CRL_TYPEn", " ");        
  237.     exit(-1);
  238. }
  239. int main(int argc, char **argv)
  240. {
  241.     SECItem privKeyDER;
  242.     CERTCertDBHandle *certHandle;
  243.     FILE *certFile;
  244.     PRFileDesc *inFile;
  245.     int listCRL;
  246.     int importCRL;
  247.     int opt;
  248.     int deleteCRL;
  249.     int rv;
  250.     char *nickName;
  251.     char *progName;
  252.     char *url;
  253.     int crlType;
  254.     PLOptState *optstate;
  255.     PLOptStatus status;
  256.     progName = strrchr(argv[0], '/');
  257.     progName = progName ? progName+1 : argv[0];
  258.     rv = 0;
  259.     deleteCRL = importCRL = listCRL = 0;
  260.     certFile = NULL;
  261.     inFile = NULL;
  262.     nickName = url = NULL;
  263.     privKeyDER.data = NULL;
  264.     certHandle = NULL;
  265.     crlType = SEC_CRL_TYPE;
  266.     /*
  267.      * Parse command line arguments
  268.      */
  269.     optstate = PL_CreateOptState(argc, argv, "IALd:i:Dn:Ct:u:");
  270.     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
  271. switch (optstate->option) {
  272.   case '?':
  273.     Usage(progName);
  274.     break;
  275.   case 'C':
  276.       listCRL = 1;
  277.       break;
  278.   case 'D':
  279.       deleteCRL = 1;
  280.       break;
  281.   case 'I':
  282.       importCRL = 1;
  283.       break;
  284.            
  285.   case 'L':
  286.       listCRL = 1;
  287.       break;
  288.            
  289.   case 'd':
  290.     SECU_ConfigDirectory(optstate->value);
  291.     break;
  292.   case 'i':
  293.     inFile = PR_Open(optstate->value, PR_RDONLY, 0);
  294.     if (!inFile) {
  295. fprintf(stderr, "%s: unable to open "%s" for readingn",
  296. progName, optstate->value);
  297. return -1;
  298.     }
  299.     break;
  300.     
  301.   case 'n':
  302.     nickName = strdup(optstate->value);
  303.     break;
  304.     
  305.   case 'u':
  306.     url = strdup(optstate->value);
  307.     break;
  308.   case 't': {
  309.     char *type;
  310.     
  311.     type = strdup(optstate->value);
  312.     crlType = atoi (type);
  313.     if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
  314. fprintf(stderr, "%s: invalid crl typen", progName);
  315. return -1;
  316.     }
  317.     break;
  318.           }
  319. }
  320.     }
  321.     if (deleteCRL && !nickName) Usage (progName);
  322.     if (!(listCRL || deleteCRL || importCRL)) Usage (progName);
  323.     if (importCRL && !inFile) Usage (progName);
  324.     
  325.     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
  326.     SECU_PKCS11Init(PR_FALSE);
  327.     SEC_Init();
  328.     certHandle = OpenCertDB(SEC_CREATE_CERT_DB);
  329.     if (certHandle == NULL) {
  330. SECU_PrintError(progName, "unable to open the cert db");     
  331. return (-1);
  332.     }
  333.     /* Read in the private key info */
  334.     if (deleteCRL) 
  335. DeleteCRL (certHandle, nickName, crlType);
  336.     else if (listCRL)
  337. ListCRL (certHandle, nickName, crlType);
  338.     else if (importCRL) 
  339. rv = ImportCRL (certHandle, url, crlType, inFile);
  340.     
  341.     return (rv);
  342. }