instinit.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:11k
- /*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
- #include <stdio.h>
- #include "prio.h"
- #include "seccomon.h"
- #include "swforti.h"
- #include "cert.h"
- #include "pk11func.h"
- #include "nss.h"
- #include "secutil.h"
- #include "cdbhdl.h"
- #define CERTDB_VALID_CA (1<<3)
- #define CERTDB_TRUSTED_CA (1<<4) /* trusted for issuing server certs */
- void secmod_GetInternalModule(SECMODModule *module);
- void sec_SetCheckKRLState(int i);
- #define STEP 16
- void
- printItem(SECItem *key) {
- int i;
- unsigned char *block;
- int len;
- for (block=key->data,len=key->len; len > 0; len -= STEP,block += STEP) {
- for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]);
- printf("n");
- }
- printf("n");
- }
- void
- dump(unsigned char *block, int len) {
- int i;
- for (; len > 0; len -= STEP,block += STEP) {
- for(i=0; i < STEP && i < len; i++) printf(" %02x ",block[i]);
- printf("n");
- }
- printf("n");
- }
- /*
- * We need to move this to security/cmd .. so we can use the password
- * prompting infrastructure.
- */
- char *GetUserInput(char * prompt)
- {
- char phrase[200];
- fprintf(stderr, "%s", prompt);
- fflush (stderr);
- fgets ((char*) phrase, sizeof(phrase), stdin);
- /* stomp on newline */
- phrase[PORT_Strlen((char*)phrase)-1] = 0;
- /* Validate password */
- return (char*) PORT_Strdup((char*)phrase);
- }
- void ClearPass(char *pass) {
- PORT_Memset(pass,0,strlen(pass));
- PORT_Free(pass);
- }
- char *
- formatDERIssuer(FORTSWFile *file,SECItem *derIssuer)
- {
- CERTName name;
- SECStatus rv;
- PORT_Memset(&name,0,sizeof(name));;
- rv = SEC_ASN1DecodeItem(file->arena,&name,CERT_NameTemplate,derIssuer);
- if (rv != SECSuccess) {
- return NULL;
- }
- return CERT_NameToAscii(&name);
- }
- #define NETSCAPE_INIT_FILE "nsswft.swf"
- char *getDefaultTarget(void)
- {
- char *fname = NULL;
- char *home = NULL;
- static char unix_home[512];
- /* first try to get it from the environment */
- fname = getenv("SW_FORTEZZA_FILE");
- if (fname != NULL) {
- return PORT_Strdup(fname);
- }
- #ifdef XP_UNIX
- home = getenv("HOME");
- if (home) {
- strncpy(unix_home,home, sizeof(unix_home)-sizeof("/.netscape/"NETSCAPE_INIT_FILE));
- strcat(unix_home,"/.netscape/"NETSCAPE_INIT_FILE);
- return unix_home;
- }
- #endif
- #ifdef XP_WIN
- home = getenv("windir");
- if (home) {
- strncpy(unix_home,home, sizeof(unix_home)-sizeof("\"NETSCAPE_INIT_FILE));
- strcat(unix_home,"\"NETSCAPE_INIT_FILE);
- return unix_home;
- }
- #endif
- return (NETSCAPE_INIT_FILE);
- }
- void
- usage(char *prog) {
- fprintf(stderr,"usage: %s [-v][-f][-t transport_pass][-u user_pass][-o output_file] source_filen",prog);
- exit(1);
- }
-
- main(int argc, char ** argv)
- {
- FORTSignedSWFile * swfile;
- int size;
- SECItem file;
- char *progname = *argv++;
- char *filename = NULL;
- char *outname = NULL;
- char *cp;
- int verbose = 0;
- int force = 0;
- CERTCertDBHandle certhandle = { 0 };
- CERTCertificate *cert;
- CERTCertTrust *trust;
- char * pass;
- SECStatus rv;
- int i;
- SECMODModule *module;
- int64 now; /* XXXX */
- char *issuer;
- char *transport_pass = NULL;
- char *user_pass = NULL;
- SECItem *outItem = NULL;
- PRFileDesc *fd;
- PRFileInfo info;
- PRStatus prv;
-
- /* put better argument parsing here */
- while ((cp = *argv++) != NULL) {
- if (*cp == '-') {
- while (*++cp) {
- switch (*cp) {
- /* verbose mode */
- case 'v':
- verbose++;
- break;
- /* explicitly set the target */
- case 'o':
- outname = *argv++;
- break;
- case 'f':
- /* skip errors in signatures without prompts */
- force++;
- break;
- case 't':
- /* provide password on command line */
- transport_pass = *argv++;
- break;
- case 'u':
- /* provide user password on command line */
- user_pass = *argv++;
- break;
- default:
- usage(progname);
- break;
- }
- }
- } else if (filename) {
- usage(progname);
- } else {
- filename = cp;
- }
- }
- if (filename == NULL) usage(progname);
- if (outname == NULL) outname = getDefaultTarget();
- now = PR_Now();
- /* read the file in */
- fd = PR_Open(filename,PR_RDONLY,0);
- if (fd == NULL) {
- fprintf(stderr,"%s: couldn't open file "%s".n",progname,filename);
- exit(1);
- }
- prv = PR_GetOpenFileInfo(fd,&info);
- if (prv != PR_SUCCESS) {
- fprintf(stderr,"%s: couldn't get info on file "%s".n",
- progname,filename);
- exit(1);
- }
- size = info.size;
- file.data = malloc(size);
- file.len = size;
- file.len = PR_Read(fd,file.data,file.len);
- if (file.len < 0) {
- fprintf(stderr,"%s: couldn't read file "%s".n",progname, filename);
- exit(1);
- }
- PR_Close(fd);
- /* Parse the file */
- swfile = FORT_GetSWFile(&file);
- if (swfile == NULL) {
- fprintf(stderr,
- "%s: File "%s" not a valid FORTEZZA initialization file.n",
- progname,filename);
- exit(1);
- }
- issuer = formatDERIssuer(&swfile->file,&swfile->file.derIssuer);
- if (issuer == NULL) {
- issuer = "<Invalid Issuer DER>";
- }
- if (verbose) {
- printf("Processing file %s ....n",filename);
- printf(" Version %dn",DER_GetInteger(&swfile->file.version));
- printf(" Issuer: %sn",issuer);
- printf(" Serial Number: ");
- for (i=0; i < (int)swfile->file.serialID.len; i++) {
- printf(" %02x",swfile->file.serialID.data[i]);
- }
- printf("n");
- }
- /* Check the Initalization phrase and save Kinit */
- if (!transport_pass) {
- pass = SECU_GetPasswordString(NULL,"Enter the Initialization Memphrase:");
- transport_pass = pass;
- }
- rv = FORT_CheckInitPhrase(swfile,transport_pass);
- if (rv != SECSuccess) {
- fprintf(stderr,
- "%s: Invalid Initialization Memphrase for file "%s".n",
- progname,filename);
- exit(1);
- }
- /* Check the user or init phrase and save Ks, use Kinit to unwrap the
- * remaining data. */
- if (!user_pass) {
- pass = SECU_GetPasswordString(NULL,"Enter the User Memphrase or the User PIN:");
- user_pass = pass;
- }
- rv = FORT_CheckUserPhrase(swfile,user_pass);
- if (rv != SECSuccess) {
- fprintf(stderr,"%s: Invalid User Memphrase or PIN for file "%s".n",
- progname,filename);
- exit(1);
- }
- NSS_NoDB_Init(NULL);
- sec_SetCheckKRLState(1);
- /* now dump the certs into the temparary data base */
- for (i=0; swfile->file.slotEntries[i]; i++) {
- int trusted = 0;
- SECItem *derCert = FORT_GetDERCert(swfile,
- swfile->file.slotEntries[i]->certIndex);
- if (derCert == NULL) {
- if (verbose) {
- printf(" Cert %02d: %s "%s" n",
- swfile->file.slotEntries[i]->certIndex,
- "untrusted", "Couldn't decrypt Cert");
- }
- continue;
- }
- cert = CERT_NewTempCertificate(&certhandle,derCert, NULL,
- PR_FALSE, PR_TRUE);
- if (cert == NULL) {
- if (verbose) {
- printf(" Cert %02d: %s "%s" n",
- swfile->file.slotEntries[i]->certIndex,
- "untrusted", "Couldn't decode Cert");
- }
- continue;
- }
- if (swfile->file.slotEntries[i]->trusted.data[0]) {
- /* Add TRUST */
- trust = PORT_ArenaAlloc(cert->arena,sizeof(CERTCertTrust));
- if (trust != NULL) {
- trust->sslFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
- trust->emailFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
- trust->objectSigningFlags = CERTDB_VALID_CA|CERTDB_TRUSTED_CA;
- cert->trust = trust;
- trusted++;
- }
- }
- if (verbose) {
- printf(" Cert %02d: %s "%s" n",
- swfile->file.slotEntries[i]->certIndex,
- trusted?" trusted ":"untrusted",
- CERT_NameToAscii(&cert->subject));
- }
- }
- fflush(stdout);
- cert = CERT_FindCertByName(&certhandle,&swfile->file.derIssuer);
- if (cert == NULL) {
- fprintf(stderr,"%s: Couldn't find signer certificate "%s".n",
- progname,issuer);
- rv = SECFailure;
- goto noverify;
- }
- rv = CERT_VerifySignedData(&swfile->signatureWrap,cert, now, NULL);
- if (rv != SECSuccess) {
- fprintf(stderr,
- "%s: Couldn't verify the signature on file "%s" with certificate "%s".n",
- progname,filename,issuer);
- goto noverify;
- }
- rv = CERT_VerifyCert(&certhandle, cert, PR_TRUE, certUsageSSLServer,
- now ,NULL,NULL);
- /* not an normal cert, see if it's a CA? */
- if (rv != SECSuccess) {
- rv = CERT_VerifyCert(&certhandle, cert, PR_TRUE, certUsageAnyCA,
- now ,NULL,NULL);
- }
- if (rv != SECSuccess) {
- fprintf(stderr,"%s: Couldn't verify the signer certificate "%s".n",
- progname,issuer);
- goto noverify;
- }
- noverify:
- if (rv != SECSuccess) {
- if (!force) {
- pass = GetUserInput(
- "Signature verify failed, continue without verification? ");
- if (!(pass && ((*pass == 'Y') || (*pass == 'y')))) {
- exit(1);
- }
- }
- }
- /* now write out the modified init file for future use */
- outItem = FORT_PutSWFile(swfile);
- if (outItem == NULL) {
- fprintf(stderr,"%s: Couldn't format target init file.n",
- progname);
- goto noverify;
- }
- if (verbose) {
- printf("writing modified file out to "%s".n",outname);
- }
- /* now write it out */
- fd = PR_Open(outname,PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,0700);
- if (fd == NULL) {
- fprintf(stderr,"%s: couldn't open file "%s".n",progname,outname);
- exit(1);
- }
- file.len = PR_Write(fd,outItem->data,outItem->len);
- if (file.len < 0) {
- fprintf(stderr,"%s: couldn't read file "%s".n",progname, filename);
- exit(1);
- }
- PR_Close(fd);
-
- exit(0);
- return (0);
- }