summaryrefslogtreecommitdiff
path: root/security/nss/cmd/swfort/instinit/instinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/swfort/instinit/instinit.c')
-rw-r--r--security/nss/cmd/swfort/instinit/instinit.c424
1 files changed, 424 insertions, 0 deletions
diff --git a/security/nss/cmd/swfort/instinit/instinit.c b/security/nss/cmd/swfort/instinit/instinit.c
new file mode 100644
index 000000000..2e65b1aac
--- /dev/null
+++ b/security/nss/cmd/swfort/instinit/instinit.c
@@ -0,0 +1,424 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include <stdio.h>
+
+#include "prio.h"
+#include "seccomon.h"
+#include "swforti.h"
+#include "cert.h"
+#include "pk11func.h"
+#include "nss.h"
+#include "secutil.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_file\n",prog);
+ exit(1);
+}
+
+int 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 = NULL;
+ CERTCertificate *cert;
+ CERTCertTrust *trust;
+ char * pass;
+ SECStatus rv;
+ int i;
+ 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 %ld\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);
+ certhandle = CERT_GetDefaultCertDB();
+
+ /* 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);
+}
+