instinit.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 423 行

C
423
字号
/* * 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 16voidprintItem(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");}voiddump(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);}voidusage(char *prog) {   fprintf(stderr,"usage: %s [-v][-f][-t transport_pass][-u user_pass][-o output_file] source_file\n",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 %d\n",DER_GetInteger(&swfile->file.version));	printf("  Issuer: %s\n",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);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?