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

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. #include <stdio.h>
  34. #include "prio.h"
  35. #include "seccomon.h"
  36. #include "swforti.h"
  37. #include "cert.h"
  38. #include "pk11func.h"
  39. #include "nss.h"
  40. #include "secutil.h"
  41. #include "cdbhdl.h"
  42. #define CERTDB_VALID_CA        (1<<3)
  43. #define CERTDB_TRUSTED_CA      (1<<4) /* trusted for issuing server certs */
  44. void secmod_GetInternalModule(SECMODModule *module);
  45. void sec_SetCheckKRLState(int i);
  46. #define STEP 16
  47. void
  48. printItem(SECItem *key) {
  49.  int i;
  50.  unsigned char *block;
  51.  int len;
  52.  for (block=key->data,len=key->len; len > 0; len -= STEP,block += STEP) {
  53.      for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]);
  54.      printf("n");
  55.  }
  56.  printf("n");
  57. }
  58. void
  59. dump(unsigned char *block, int len) {
  60.  int i;
  61.  for (; len > 0; len -= STEP,block += STEP) {
  62.      for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]);
  63.      printf("n");
  64.  }
  65.  printf("n");
  66. }
  67. /*
  68.  * We need to move this to security/cmd .. so we can use the password
  69.  * prompting infrastructure.
  70.  */
  71. char *GetUserInput(char * prompt) 
  72. {
  73.     char phrase[200];
  74.     fprintf(stderr, "%s", prompt);
  75.             fflush (stderr);
  76. fgets ((char*) phrase, sizeof(phrase), stdin);
  77. /* stomp on newline */
  78. phrase[PORT_Strlen((char*)phrase)-1] = 0;
  79. /* Validate password */
  80. return (char*) PORT_Strdup((char*)phrase);
  81. }
  82. void ClearPass(char *pass) {
  83.     PORT_Memset(pass,0,strlen(pass));
  84.     PORT_Free(pass);
  85. }
  86. char *
  87. formatDERIssuer(FORTSWFile *file,SECItem *derIssuer)
  88. {
  89.     CERTName name;
  90.     SECStatus rv;
  91.     PORT_Memset(&name,0,sizeof(name));;
  92.     rv = SEC_ASN1DecodeItem(file->arena,&name,CERT_NameTemplate,derIssuer);
  93.     if (rv != SECSuccess) {
  94. return NULL;
  95.     }
  96.     return CERT_NameToAscii(&name);
  97. }
  98. #define NETSCAPE_INIT_FILE "nsswft.swf"
  99. char *getDefaultTarget(void)
  100. {
  101.     char *fname = NULL;
  102.     char *home = NULL;
  103.     static char unix_home[512];
  104.     /* first try to get it from the environment */
  105.     fname = getenv("SW_FORTEZZA_FILE");
  106.     if (fname != NULL) {
  107. return PORT_Strdup(fname);
  108.     }
  109. #ifdef XP_UNIX
  110.     home = getenv("HOME");
  111.     if (home) {
  112. strncpy(unix_home,home, sizeof(unix_home)-sizeof("/.netscape/"NETSCAPE_INIT_FILE));
  113. strcat(unix_home,"/.netscape/"NETSCAPE_INIT_FILE);
  114. return unix_home;
  115.     }
  116. #endif
  117. #ifdef XP_WIN
  118.     home = getenv("windir");
  119.     if (home) {
  120. strncpy(unix_home,home, sizeof(unix_home)-sizeof("\"NETSCAPE_INIT_FILE));
  121. strcat(unix_home,"\"NETSCAPE_INIT_FILE);
  122. return unix_home;
  123.     }
  124. #endif
  125.     return (NETSCAPE_INIT_FILE);
  126. }
  127. void
  128. usage(char *prog) {
  129.    fprintf(stderr,"usage: %s [-v][-f][-t transport_pass][-u user_pass][-o output_file] source_filen",prog);
  130.    exit(1);
  131. }
  132. main(int argc, char ** argv)
  133. {
  134.     FORTSignedSWFile * swfile;
  135.     int size;
  136.     SECItem file;
  137.     char *progname = *argv++;
  138.     char *filename = NULL;
  139.     char *outname = NULL;
  140.     char *cp;
  141.     int verbose = 0;
  142.     int force = 0;
  143.     CERTCertDBHandle certhandle = { 0 };
  144.     CERTCertificate *cert;
  145.     CERTCertTrust *trust;
  146.     char * pass;
  147.     SECStatus rv;
  148.     int i;
  149.     SECMODModule *module;
  150.     int64 now; /* XXXX */
  151.     char *issuer;
  152.     char *transport_pass = NULL;
  153.     char *user_pass = NULL;
  154.     SECItem *outItem = NULL;
  155.     PRFileDesc *fd;
  156.     PRFileInfo info;
  157.     PRStatus prv;
  158.    
  159.     /* put better argument parsing here */
  160.     while ((cp = *argv++) != NULL) {
  161. if (*cp == '-') {
  162.     while (*++cp) {
  163. switch (*cp) {
  164. /* verbose mode */
  165. case 'v':
  166.     verbose++;
  167.     break;
  168. /* explicitly set the target */
  169. case 'o':
  170.     outname = *argv++;
  171.     break;
  172. case 'f':
  173. /* skip errors in signatures without prompts */
  174.     force++;
  175.     break;
  176. case 't':
  177. /* provide password on command line */
  178.     transport_pass = *argv++;
  179.     break;
  180. case 'u':
  181. /* provide user password on command line */
  182.     user_pass = *argv++;
  183.     break;
  184. default:
  185.     usage(progname);
  186.     break;
  187. }
  188.     }
  189. } else if (filename) {
  190.     usage(progname);
  191. } else {
  192.     filename = cp;
  193. }
  194.     }
  195.     if (filename == NULL) usage(progname);
  196.     if (outname == NULL) outname = getDefaultTarget();
  197.     now = PR_Now();
  198.     /* read the file in */ 
  199.     fd = PR_Open(filename,PR_RDONLY,0);
  200.     if (fd == NULL) { 
  201. fprintf(stderr,"%s: couldn't open file "%s".n",progname,filename); 
  202. exit(1);
  203.     }
  204.     prv = PR_GetOpenFileInfo(fd,&info);
  205.     if (prv != PR_SUCCESS) {
  206. fprintf(stderr,"%s: couldn't get info on file "%s".n",
  207. progname,filename); 
  208. exit(1);
  209.     }
  210.     size = info.size;
  211.     file.data = malloc(size);
  212.     file.len = size;
  213.     file.len = PR_Read(fd,file.data,file.len);
  214.     if (file.len < 0) { 
  215. fprintf(stderr,"%s: couldn't read file "%s".n",progname, filename); 
  216. exit(1);
  217.     }
  218.     PR_Close(fd);
  219.     /* Parse the file */
  220.     swfile = FORT_GetSWFile(&file);
  221.     if (swfile == NULL) {
  222. fprintf(stderr,
  223.    "%s: File "%s" not a valid FORTEZZA initialization file.n",
  224. progname,filename);
  225. exit(1);
  226.     }
  227.     issuer = formatDERIssuer(&swfile->file,&swfile->file.derIssuer);
  228.     if (issuer == NULL) {
  229. issuer = "<Invalid Issuer DER>";
  230.     }
  231.     if (verbose) {
  232. printf("Processing file %s ....n",filename);
  233. printf("  Version %dn",DER_GetInteger(&swfile->file.version));
  234. printf("  Issuer: %sn",issuer);
  235. printf("  Serial Number: ");
  236. for (i=0; i < (int)swfile->file.serialID.len; i++) {
  237.     printf(" %02x",swfile->file.serialID.data[i]);
  238. }
  239. printf("n");
  240.     }
  241.     /* Check the Initalization phrase and save Kinit */
  242.     if (!transport_pass) {
  243.      pass = SECU_GetPasswordString(NULL,"Enter the Initialization Memphrase:");
  244. transport_pass = pass;
  245.     }
  246.     rv = FORT_CheckInitPhrase(swfile,transport_pass);
  247.     if (rv != SECSuccess) {
  248. fprintf(stderr,
  249. "%s: Invalid Initialization Memphrase for file "%s".n",
  250. progname,filename);
  251. exit(1);
  252.     }
  253.     /* Check the user or init phrase and save Ks, use Kinit to unwrap the
  254.      * remaining data. */
  255.     if (!user_pass) {
  256.      pass = SECU_GetPasswordString(NULL,"Enter the User Memphrase or the User PIN:");
  257. user_pass = pass;
  258.     }
  259.     rv = FORT_CheckUserPhrase(swfile,user_pass);
  260.     if (rv != SECSuccess) {
  261. fprintf(stderr,"%s: Invalid User Memphrase or PIN for file "%s".n",
  262. progname,filename);
  263. exit(1);
  264.     }
  265.     NSS_NoDB_Init(NULL);
  266.     sec_SetCheckKRLState(1);
  267.     /* now dump the certs into the temparary data base */
  268.     for (i=0; swfile->file.slotEntries[i]; i++) {
  269. int trusted = 0;
  270.      SECItem *derCert = FORT_GetDERCert(swfile,
  271. swfile->file.slotEntries[i]->certIndex);
  272. if (derCert == NULL) {
  273.     if (verbose) {
  274.        printf(" Cert %02d: %s "%s" n",
  275. swfile->file.slotEntries[i]->certIndex,
  276. "untrusted", "Couldn't decrypt Cert");
  277.     }
  278.     continue;
  279. }
  280. cert = CERT_NewTempCertificate(&certhandle,derCert, NULL, 
  281. PR_FALSE, PR_TRUE);
  282. if (cert == NULL) {
  283.     if (verbose) {
  284.        printf(" Cert %02d: %s "%s" n",
  285. swfile->file.slotEntries[i]->certIndex,
  286. "untrusted", "Couldn't decode Cert");
  287.     }
  288.     continue;
  289. }
  290. if (swfile->file.slotEntries[i]->trusted.data[0]) {
  291.     /* Add TRUST */
  292.     trust = PORT_ArenaAlloc(cert->arena,sizeof(CERTCertTrust));
  293.     if (trust != NULL) {
  294.         trust->sslFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
  295.         trust->emailFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
  296.         trust->objectSigningFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
  297.         cert->trust = trust;
  298. trusted++;
  299.     }
  300. }
  301. if (verbose) {
  302.     printf(" Cert %02d: %s "%s" n",
  303. swfile->file.slotEntries[i]->certIndex,
  304. trusted?" trusted ":"untrusted",
  305. CERT_NameToAscii(&cert->subject));
  306. }
  307.     }
  308.     fflush(stdout);
  309.     cert = CERT_FindCertByName(&certhandle,&swfile->file.derIssuer);
  310.     if (cert == NULL) {
  311. fprintf(stderr,"%s: Couldn't find signer certificate "%s".n",
  312. progname,issuer);
  313. rv = SECFailure;
  314. goto noverify;
  315.     }
  316.     rv = CERT_VerifySignedData(&swfile->signatureWrap,cert, now, NULL);
  317.     if (rv != SECSuccess) {
  318. fprintf(stderr,
  319.   "%s: Couldn't verify the signature on file "%s" with certificate "%s".n",
  320. progname,filename,issuer);
  321. goto noverify;
  322.     }
  323.     rv = CERT_VerifyCert(&certhandle, cert, PR_TRUE, certUsageSSLServer,
  324. now ,NULL,NULL);
  325.     /* not an normal cert, see if it's a CA? */
  326.     if (rv != SECSuccess) {
  327. rv = CERT_VerifyCert(&certhandle, cert, PR_TRUE, certUsageAnyCA,
  328. now ,NULL,NULL);
  329.     }
  330.     if (rv != SECSuccess) {
  331. fprintf(stderr,"%s: Couldn't verify the signer certificate "%s".n",
  332. progname,issuer);
  333. goto noverify;
  334.     }
  335. noverify:
  336.     if (rv != SECSuccess) {
  337. if (!force) {
  338.     pass = GetUserInput(
  339.        "Signature verify failed, continue without verification? ");
  340.     if (!(pass && ((*pass == 'Y') || (*pass == 'y')))) {
  341. exit(1);
  342.             }
  343. }
  344.     }
  345.     /* now write out the modified init file for future use */
  346.     outItem = FORT_PutSWFile(swfile);
  347.     if (outItem == NULL) {
  348. fprintf(stderr,"%s: Couldn't format target init file.n",
  349. progname);
  350. goto noverify;
  351.     }
  352.     if (verbose) {
  353. printf("writing modified file out to "%s".n",outname);
  354.     }
  355.     /* now write it out */
  356.     fd = PR_Open(outname,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0700);
  357.     if (fd == NULL) { 
  358. fprintf(stderr,"%s: couldn't open file "%s".n",progname,outname); 
  359. exit(1);
  360.     }
  361.     file.len = PR_Write(fd,outItem->data,outItem->len);
  362.     if (file.len < 0) { 
  363. fprintf(stderr,"%s: couldn't read file "%s".n",progname, filename); 
  364. exit(1);
  365.     }
  366.     PR_Close(fd);
  367.     
  368.     exit(0);
  369.     return (0);
  370. }