diff options
author | nelsonb%netscape.com <devnull@localhost> | 2003-12-06 06:41:51 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2003-12-06 06:41:51 +0000 |
commit | ab5a12f0b4b478fe51179fef6b13515eecc08e90 (patch) | |
tree | 6a3368a53e481a2d140009850fac7eb13ae39977 /security/nss/cmd/swfort | |
parent | b6c9daf28b6890a04b30759dafbfe596084ae614 (diff) | |
parent | 4a8a6c26b6278cb6359fabd743efc45e94bfc878 (diff) | |
download | nss-hg-ab5a12f0b4b478fe51179fef6b13515eecc08e90.tar.gz |
NSC_Finalize will now destroy 3 softoken free lists and one more
global pointer. Plugs some memory leaks. Bugscape bug 54301. r=wtc
Diffstat (limited to 'security/nss/cmd/swfort')
-rw-r--r-- | security/nss/cmd/swfort/Makefile | 108 | ||||
-rw-r--r-- | security/nss/cmd/swfort/instinit/Makefile | 75 | ||||
-rw-r--r-- | security/nss/cmd/swfort/instinit/instinit.c | 421 | ||||
-rw-r--r-- | security/nss/cmd/swfort/instinit/manifest.mn | 46 | ||||
-rw-r--r-- | security/nss/cmd/swfort/manifest.mn | 38 | ||||
-rw-r--r-- | security/nss/cmd/swfort/newuser/Makefile | 83 | ||||
-rw-r--r-- | security/nss/cmd/swfort/newuser/manifest.mn | 45 | ||||
-rw-r--r-- | security/nss/cmd/swfort/newuser/mktst.c | 254 | ||||
-rw-r--r-- | security/nss/cmd/swfort/newuser/newuser.c | 1132 |
9 files changed, 2202 insertions, 0 deletions
diff --git a/security/nss/cmd/swfort/Makefile b/security/nss/cmd/swfort/Makefile new file mode 100644 index 000000000..a5b4350a6 --- /dev/null +++ b/security/nss/cmd/swfort/Makefile @@ -0,0 +1,108 @@ +#! gmake +# 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. + +CORE_DEPTH = ../../.. + +include manifest.mn +include $(CORE_DEPTH)/coreconf/config.mk + +# $(NULL) + + +INCLUDES += \ + -I$(DIST)/../public/security \ + -I$(DIST)/../private/security \ + -I$(DEPTH)/security/lib/cert \ + -I$(DEPTH)/security/lib/key \ + -I$(DEPTH)/security/lib/util \ + -I./include \ + $(NULL) + + +# For the time being, sec stuff is export only +# US_FLAGS = -DEXPORT_VERSION -DUS_VERSION + +US_FLAGS = -DEXPORT_VERSION +EXPORT_FLAGS = -DEXPORT_VERSION + +BASE_LIBS = \ + $(DIST)/lib/libdbm.$(LIB_SUFFIX) \ + $(DIST)/lib/libxp.$(LIB_SUFFIX) \ + $(DIST)/lib/libnspr.$(LIB_SUFFIX) \ + $(NULL) + +# $(DIST)/lib/libpurenspr.$(LIB_SUFFIX) \ + +#There are a circular dependancies in security/lib, and we deal with it by +# double linking some libraries +SEC_LIBS = \ + $(DIST)/lib/libsecnav.$(LIB_SUFFIX) \ + $(DIST)/lib/libssl.$(LIB_SUFFIX) \ + $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \ + $(DIST)/lib/libcert.$(LIB_SUFFIX) \ + $(DIST)/lib/libkey.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \ + $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \ + $(DIST)/lib/libssl.$(LIB_SUFFIX) \ + $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \ + $(DIST)/lib/libcert.$(LIB_SUFFIX) \ + $(DIST)/lib/libkey.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \ + $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \ + $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \ + $(DIST)/lib/libhash.$(LIB_SUFFIX) \ + $(NULL) + +MYLIB = lib/$(OBJDIR)/libsectool.$(LIB_SUFFIX) + +US_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS) +EX_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS) + +REQUIRES = libxp nspr security + +CSRCS = $(EXEC_SRCS) $(BI_SRCS) + +OBJS = $(CSRCS:.c=.o) $(BI_SRCS:.c=-us.o) $(BI_SRCS:.c=-ex.o) + +PROGS = $(addprefix $(OBJDIR)/, $(EXEC_SRCS:.c=$(BIN_SUFFIX))) +US_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-us$(BIN_SUFFIX))) +EX_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-ex$(BIN_SUFFIX))) + + +NON_DIRS = $(PROGS) $(US_PROGS) $(EX_PROGS) +TARGETS = $(NON_DIRS) + +include $(CORE_DEPTH)/coreconf/rules.mk + +symbols:: + @echo "TARGETS = $(TARGETS)" diff --git a/security/nss/cmd/swfort/instinit/Makefile b/security/nss/cmd/swfort/instinit/Makefile new file mode 100644 index 000000000..f912d54cd --- /dev/null +++ b/security/nss/cmd/swfort/instinit/Makefile @@ -0,0 +1,75 @@ +#! gmake +# +# 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. +# + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include ../../platlibs.mk + + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +include ../../platrules.mk diff --git a/security/nss/cmd/swfort/instinit/instinit.c b/security/nss/cmd/swfort/instinit/instinit.c new file mode 100644 index 000000000..8b8b86c81 --- /dev/null +++ b/security/nss/cmd/swfort/instinit/instinit.c @@ -0,0 +1,421 @@ +/* + * 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" + +#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); +} + diff --git a/security/nss/cmd/swfort/instinit/manifest.mn b/security/nss/cmd/swfort/instinit/manifest.mn new file mode 100644 index 000000000..8380f4246 --- /dev/null +++ b/security/nss/cmd/swfort/instinit/manifest.mn @@ -0,0 +1,46 @@ +# +# 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. +# +CORE_DEPTH = ../../../.. + +DEFINES += -DNSPR20 + +MODULE = nss + +CSRCS = instinit.c + +REQUIRES = nspr dbm seccmd + +PROGRAM = instinit +# PROGRAM = ./$(OBJDIR)/selfserv.exe + +USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/swfort/manifest.mn b/security/nss/cmd/swfort/manifest.mn new file mode 100644 index 000000000..aaacd83e8 --- /dev/null +++ b/security/nss/cmd/swfort/manifest.mn @@ -0,0 +1,38 @@ +# +# 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. +# +CORE_DEPTH = ../../.. + +REQUIRES = nss seccmd dbm + + +DIRS = instinit newuser diff --git a/security/nss/cmd/swfort/newuser/Makefile b/security/nss/cmd/swfort/newuser/Makefile new file mode 100644 index 000000000..f0a47a0a3 --- /dev/null +++ b/security/nss/cmd/swfort/newuser/Makefile @@ -0,0 +1,83 @@ +#! gmake +# 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. +# + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +ctmp := $(shell $(MAKE) -C ../../../lib/fortcrypt --no-print-directory cilib_name) +ifeq ($(ctmp), $(patsubst /%,/,$(ctmp))) + CILIB := ../../../lib/fortcrypt/$(ctmp) +else + CILIB := $(ctmp) +endif + +EXTRA_LIBS += $(CILIB) + +include ../../platlibs.mk + + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + +include ../../platrules.mk + diff --git a/security/nss/cmd/swfort/newuser/manifest.mn b/security/nss/cmd/swfort/newuser/manifest.mn new file mode 100644 index 000000000..4554c69ef --- /dev/null +++ b/security/nss/cmd/swfort/newuser/manifest.mn @@ -0,0 +1,45 @@ +# +# 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. +# +CORE_DEPTH = ../../../.. + +DEFINES += -DNSPR20 + +MODULE = nss + +CSRCS = newuser.c mktst.c + +REQUIRES = nspr dbm seccmd + +PROGRAM = newuser + +USE_STATIC_LIBS = 1 diff --git a/security/nss/cmd/swfort/newuser/mktst.c b/security/nss/cmd/swfort/newuser/mktst.c new file mode 100644 index 000000000..6e111d3dd --- /dev/null +++ b/security/nss/cmd/swfort/newuser/mktst.c @@ -0,0 +1,254 @@ +/* + * 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 "swforti.h" +#include "maci.h" +#include "secder.h" +#include "blapi.h" + +void +printkey(char *s, unsigned char *block) { + int i; + printf("%s \n 0x",s); + for(i=0; i < 10; i++) printf("%02x",block[i]); + printf("\n"); +} + +void +printblock(char *s, unsigned char *block) { + int i; + printf("%s \n 0x",s); + for(i=0; i < 8; i++) printf("%02x",block[i]); + printf("\n 0x"); + for(i=8; i < 16; i++) printf("%02x",block[i]); + printf("\n"); +} + + +static char *leafbits="THIS IS NOT LEAF"; + +static void +encryptCertEntry(fortProtectedData *pdata,FORTSkipjackKeyPtr Ks, + unsigned char *data,int len) +{ + unsigned char *dataout; + int enc_len; + /* XXX Make length */ + pdata->dataIV.data = PORT_ZAlloc(24); + pdata->dataIV.len = 24; + PORT_Memcpy(pdata->dataIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&pdata->dataIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + enc_len = (len + (SKIPJACK_BLOCK_SIZE-1)) & ~(SKIPJACK_BLOCK_SIZE-1); + dataout = pdata->dataEncryptedWithKs.data = PORT_ZAlloc(enc_len); + pdata->dataEncryptedWithKs.len = enc_len; + fort_skipjackEncrypt(Ks,&pdata->dataIV.data[SKIPJACK_LEAF_SIZE], + enc_len, data,dataout); + if (len > 255) { + pdata->length.data = PORT_ZAlloc(2); + pdata->length.data[0] = (len >> 8) & 0xff; + pdata->length.data[1] = len & 0xff; + pdata->length.len = 2; + } else { + pdata->length.data = PORT_ZAlloc(1); + pdata->length.data[0] = len & 0xff; + pdata->length.len = 1; + } + +} + +unsigned char issuer[30] = { 0 }; + +void +makeCertSlot(fortSlotEntry *entry,int index,char *label,SECItem *cert, + FORTSkipjackKeyPtr Ks, unsigned char *xKEA, unsigned char *xDSA, + unsigned char *pubKey, int pubKeyLen, unsigned char *p, unsigned char *q, + unsigned char *g) +{ + unsigned char *key; /* private key */ + + entry->trusted.data = PORT_Alloc(1); + *entry->trusted.data = index == 0 ? 1 : 0; + entry->trusted.len = 1; + entry->certificateIndex.data = PORT_Alloc(1); + *entry->certificateIndex.data = index; + entry->certificateIndex.len = 1; + entry->certIndex = index; + encryptCertEntry(&entry->certificateLabel,Ks, + (unsigned char *)label, strlen(label)); + encryptCertEntry(&entry->certificateData,Ks, cert->data, cert->len); + if (xKEA) { + entry->exchangeKeyInformation = PORT_ZNew(fortKeyInformation); + entry->exchangeKeyInformation->keyFlags.data = PORT_ZAlloc(1); + entry->exchangeKeyInformation->keyFlags.data[0] = 1; + entry->exchangeKeyInformation->keyFlags.len = 1; + key = PORT_Alloc(24); + fort_skipjackWrap(Ks,24,xKEA,key); + entry->exchangeKeyInformation->privateKeyWrappedWithKs.data = key; + entry->exchangeKeyInformation->privateKeyWrappedWithKs.len = 24; + entry->exchangeKeyInformation->derPublicKey.data = pubKey; + entry->exchangeKeyInformation->derPublicKey.len = pubKeyLen; + entry->exchangeKeyInformation->p.data = p; + entry->exchangeKeyInformation->p.len = 128; + entry->exchangeKeyInformation->q.data = q; + entry->exchangeKeyInformation->q.len = 20; + entry->exchangeKeyInformation->g.data = g; + entry->exchangeKeyInformation->g.len = 128; + + entry->signatureKeyInformation = PORT_ZNew(fortKeyInformation); + entry->signatureKeyInformation->keyFlags.data = PORT_ZAlloc(1); + entry->signatureKeyInformation->keyFlags.data[0] = 1; + entry->signatureKeyInformation->keyFlags.len = 1; + key = PORT_Alloc(24); + fort_skipjackWrap(Ks,24,xDSA,key); + entry->signatureKeyInformation->privateKeyWrappedWithKs.data = key; + entry->signatureKeyInformation->privateKeyWrappedWithKs.len = 24; + entry->signatureKeyInformation->derPublicKey.data = pubKey; + entry->signatureKeyInformation->derPublicKey.len = pubKeyLen; + entry->signatureKeyInformation->p.data = p; + entry->signatureKeyInformation->p.len = 128; + entry->signatureKeyInformation->q.data = q; + entry->signatureKeyInformation->q.len = 20; + entry->signatureKeyInformation->g.data = g; + entry->signatureKeyInformation->g.len = 128; + } else { + entry->exchangeKeyInformation = NULL; + entry->signatureKeyInformation = NULL; + } + + return; +} + + +void +makeProtectedPhrase(FORTSWFile *file, fortProtectedPhrase *prot_phrase, + FORTSkipjackKeyPtr Ks, FORTSkipjackKeyPtr Kinit, char *phrase) +{ + SHA1Context *sha; + unsigned char hashout[SHA1_LENGTH]; + FORTSkipjackKey Kfek; + unsigned int len; + unsigned char cw[4]; + unsigned char enc_version[2]; + unsigned char *data = NULL; + int keySize; + int i,version; + char tmp_data[13]; + + if (strlen(phrase) < 12) { + PORT_Memset(tmp_data, ' ', sizeof(tmp_data)); + PORT_Memcpy(tmp_data,phrase,strlen(phrase)); + tmp_data[12] = 0; + phrase = tmp_data; + } + + /* now calculate the PBE key for fortezza */ + sha = SHA1_NewContext(); + SHA1_Begin(sha); + version = DER_GetUInteger(&file->version); + enc_version[0] = (version >> 8) & 0xff; + enc_version[1] = version & 0xff; + SHA1_Update(sha,enc_version,sizeof(enc_version)); + SHA1_Update(sha,file->derIssuer.data, file->derIssuer.len); + SHA1_Update(sha,file->serialID.data, file->serialID.len); + SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase)); + SHA1_End(sha,hashout,&len,SHA1_LENGTH); + PORT_Memcpy(Kfek,hashout,sizeof(FORTSkipjackKey)); + + keySize = sizeof(CI_KEY); + if (Kinit) keySize = SKIPJACK_BLOCK_SIZE*2; + data = PORT_ZAlloc(keySize); + prot_phrase->wrappedKValue.data = data; + prot_phrase->wrappedKValue.len = keySize; + fort_skipjackWrap(Kfek,sizeof(CI_KEY),Ks,data); + + /* first, decrypt the hashed/Encrypted Memphrase */ + data = (unsigned char *) PORT_ZAlloc(SHA1_LENGTH+sizeof(cw)); + + /* now build the hash for comparisons */ + SHA1_Begin(sha); + SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase)); + SHA1_End(sha,hashout,&len,SHA1_LENGTH); + SHA1_DestroyContext(sha,PR_TRUE); + + + /* now calcuate the checkword and compare it */ + cw[0] = cw[1] = cw[2] = cw[3] = 0; + for (i=0; i <5 ; i++) { + cw[0] = cw[0] ^ hashout[i*4]; + cw[1] = cw[1] ^ hashout[i*4+1]; + cw[2] = cw[2] ^ hashout[i*4+2]; + cw[3] = cw[3] ^ hashout[i*4+3]; + } + + PORT_Memcpy(data,hashout,len); + PORT_Memcpy(data+len,cw,sizeof(cw)); + + prot_phrase->memPhraseIV.data = PORT_ZAlloc(24); + prot_phrase->memPhraseIV.len = 24; + PORT_Memcpy(prot_phrase->memPhraseIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + prot_phrase->kValueIV.data = PORT_ZAlloc(24); + prot_phrase->kValueIV.len = 24; + PORT_Memcpy(prot_phrase->kValueIV.data,leafbits,SKIPJACK_LEAF_SIZE); + fort_GenerateRandom(&prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE], + SKIPJACK_BLOCK_SIZE); + fort_skipjackEncrypt(Ks,&prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE], + len+sizeof(cw), data,data); + + prot_phrase->hashedEncryptedMemPhrase.data = data; + prot_phrase->hashedEncryptedMemPhrase.len = len+sizeof(cw); + + if (Kinit) { + fort_skipjackEncrypt(Kinit, + &prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE], + prot_phrase->wrappedKValue.len, + prot_phrase->wrappedKValue.data, + prot_phrase->wrappedKValue.data ); + } + + return; +} + + +void +fill_in(SECItem *item,unsigned char *data, int len) +{ + item->data = PORT_Alloc(len); + PORT_Memcpy(item->data,data,len); + item->len = len; +} + diff --git a/security/nss/cmd/swfort/newuser/newuser.c b/security/nss/cmd/swfort/newuser/newuser.c new file mode 100644 index 000000000..c1b5c311b --- /dev/null +++ b/security/nss/cmd/swfort/newuser/newuser.c @@ -0,0 +1,1132 @@ +/* + * 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 <fcntl.h> +#include <sys/types.h> +#ifdef XP_UNIX +#include <unistd.h> +#endif +#include "cryptint.h" +#include "blapi.h" /* program calls low level functions directly!*/ +#include "pk11func.h" +#include "secmod.h" +/*#include "secmodi.h"*/ +#include "cert.h" +#include "key.h" +#include "nss.h" +#include "swforti.h" +#include "secutil.h" + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define MAX_PERSONALITIES 50 +typedef struct { + int index; + CI_CERT_STR label; + CERTCertificate *cert; +} certlist; + +typedef struct { + int card; + int index; + CI_CERT_STR label; + certlist valid[MAX_PERSONALITIES]; + int count; +} Cert; + + +#define EMAIL_OID_LEN 9 +#define EMAIL_OID 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 +unsigned char emailAVA[127] = { + 0x31, 6+EMAIL_OID_LEN, /* Set */ + 0x30, 4+EMAIL_OID_LEN, /* Sequence */ + 0x06, EMAIL_OID_LEN, EMAIL_OID, + 0x13, 0, /* printable String */ +}; +#define EMAIL_DATA_START 8+EMAIL_OID_LEN + +int emailOffset[] = { 1, 3, EMAIL_DATA_START-1 }; +int offsetCount = sizeof(emailOffset)/sizeof(emailOffset[0]); + +unsigned char hash[20] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e', + 'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*' }; +unsigned char sig[40] = { 'H', 'a', 's', 'h', ' ', 'F', 'a', 'i', 'l', 'e', + 'd', ' ', '*', '*', '*', '*', '*', '*', '*', '*', + '>', '>', '>', ' ', 'N', 'o', 't', ' ', 'S', 'i', + 'g', 'n', 'd', ' ', '<', '<', '<', ' ', ' ', ' ' }; + + +/*void *malloc(int); */ + +unsigned char *data_start(unsigned char *buf, int length, int *data_length) +{ + unsigned char tag; + int used_length= 0; + + tag = buf[used_length++]; + + /* blow out when we come to the end */ + if (tag == 0) { + return NULL; + } + + *data_length = buf[used_length++]; + + if (*data_length&0x80) { + int len_count = *data_length & 0x7f; + + *data_length = 0; + + while (len_count-- > 0) { + *data_length = (*data_length << 8) | buf[used_length++]; + } + } + + if (*data_length > (length-used_length) ) { + *data_length = length-used_length; + return NULL; + } + + return (buf + used_length); +} + +unsigned char * +GetAbove(unsigned char *cert,int cert_length,int *above_len) +{ + unsigned char *buf = cert; + int buf_length = cert_length; + unsigned char *tmp; + int len; + + *above_len = 0; + + /* optional serial number */ + if ((buf[0] & 0xa0) == 0xa0) { + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + } + /* serial number */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the OID */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* issuer */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the date */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + + *above_len = buf - cert; + return cert; +} + +unsigned char * +GetSubject(unsigned char *cert,int cert_length,int *subj_len) { + unsigned char *buf = cert; + int buf_length = cert_length; + unsigned char *tmp; + int len; + + *subj_len = 0; + + /* optional serial number */ + if ((buf[0] & 0xa0) == 0xa0) { + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + } + /* serial number */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the OID */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* issuer */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* skip the date */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + + return data_start(buf,buf_length,subj_len); +} + +unsigned char * +GetBelow(unsigned char *cert,int cert_length,int *below_len) { + unsigned char *subj; + int subj_len; + unsigned char *below; + + *below_len = 0; + + subj = GetSubject(cert,cert_length,&subj_len); + + below = subj + subj_len; + *below_len = cert_length - (below - cert); + return below; +} + +unsigned char * +GetSignature(unsigned char *sig,int sig_length,int *subj_len) { + unsigned char *buf = sig; + int buf_length = sig_length; + unsigned char *tmp; + int len; + + *subj_len = 0; + + /* signature oid */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + buf_length -= (tmp-buf) + len; + buf = tmp + len; + /* signature data */ + tmp = data_start(buf,buf_length,&len); + if (tmp == NULL) return NULL; + + *subj_len = len -1; + return tmp+1; +} + +int DER_Sequence(unsigned char *buf, int length) { + int next = 0; + + buf[next++] = 0x30; + if (length < 0x80) { + buf[next++] = length; + } else { + buf[next++] = 0x82; + buf[next++] = (length >> 8) & 0xff; + buf[next++] = length & 0xff; + } + return next; +} + +static +int Cert_length(unsigned char *buf, int length) { + unsigned char tag; + int used_length= 0; + int data_length; + + tag = buf[used_length++]; + + /* blow out when we come to the end */ + if (tag == 0) { + return 0; + } + + data_length = buf[used_length++]; + + if (data_length&0x80) { + int len_count = data_length & 0x7f; + + data_length = 0; + + while (len_count-- > 0) { + data_length = (data_length << 8) | buf[used_length++]; + } + } + + if (data_length > (length-used_length) ) { + return length; + } + + return (data_length + used_length); +} + +int +InitCard(int card, char *inpass) { + int cirv; + char buf[50]; + char *pass; + + cirv = CI_Open( 0 /* flags */, card); + if (cirv != CI_OK) return cirv; + + if (inpass == NULL) { + sprintf(buf,"Enter PIN for card in socket %d: ",card); + pass = SECU_GetPasswordString(NULL, buf); + + if (pass == NULL) { + CI_Close(CI_POWER_DOWN_FLAG,card); + return CI_FAIL; + } + } else pass=inpass; + + cirv = CI_CheckPIN(CI_USER_PIN,(unsigned char *)pass); + if (cirv != CI_OK) { + CI_Close(CI_POWER_DOWN_FLAG,card); + } + return cirv; +} + +int +isUser(CI_PERSON *person) { + return 1; +} + +int +isCA(CI_PERSON *person) { + return 0; +} + +int FoundCert(int card, char *name, Cert *cert) { + CI_PERSON personalities[MAX_PERSONALITIES]; + CI_PERSON *person; + int cirv; + int i; + int user_len = strlen(name); + + PORT_Memset(personalities, 0, sizeof(CI_PERSON)*MAX_PERSONALITIES); + + cirv = CI_GetPersonalityList(MAX_PERSONALITIES,personalities); + if (cirv != CI_OK) return 0; + + + cert->count = 1; + cert->valid[0].index = 0; + memcpy(cert->valid[0].label,"RRXX0000Root PAA Certificate ", + sizeof(cert->valid[0].label)); + cert->valid[0].cert = NULL; + for (i=0; i < MAX_PERSONALITIES; i++) { + person = &personalities[i]; + if ( (PORT_Memcmp(person->CertLabel,"RRXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"RTXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"LAXX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"INKS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"INKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"ONKS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"ONKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"KEAK",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3IKX",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSA1",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSAI",4) == 0) || + (PORT_Memcmp(person->CertLabel,"DSAO",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3IXS",4) == 0) || + (PORT_Memcmp(person->CertLabel,"3OXS",4) == 0) ){ + int index; + + cert->valid[cert->count].cert = NULL; + memcpy(cert->valid[cert->count].label, + person->CertLabel,sizeof(person->CertLabel)); + for (index = sizeof(person->CertLabel)-1; + cert->valid[cert->count].label[index] == ' '; index--) { + cert->valid[cert->count].label[index] = 0; + } + cert->valid[cert->count++].index = person->CertificateIndex; + } + } + for (i=0; i < MAX_PERSONALITIES; i++) { + person = &personalities[i]; + if (strncmp((char *)&person->CertLabel[8],name,user_len) == 0) { + cert->card = card; + cert->index = person->CertificateIndex; + memcpy(&cert->label,person->CertLabel,sizeof(person->CertLabel)); + return 1; + } + } + return 0; +} + +void +Terminate(char *mess, int cirv, int card1, int card2) +{ + fprintf(stderr,"FAIL: %s error %d\n",mess,cirv); + if (card1 != -1) CI_Close(CI_POWER_DOWN_FLAG,card1); + if (card2 != -1) CI_Close(CI_POWER_DOWN_FLAG,card2); + CI_Terminate(); + exit(1); +} + +void +usage(char *prog) +{ + fprintf(stderr,"usage: %s [-e email][-t transport][-u userpin][-U userpass][-s ssopin][-S ssopass][-o outfile] common_name ca_label\n",prog); + exit(1); +} + +#define CERT_SIZE 2048 + + +/* version and oid */ +unsigned char header[] = { + /* Cert OID */ + 0x02, 0x10, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13 }; + +#define KEY_START 21 +#define KMID_OFFSET 4 +#define KEA_OFFSET 15 +#define DSA_OFFSET 148 +unsigned char key[] = { + /* Sequence(Constructed): 293 bytes (0x125) */ + 0x30, 0x82, 0x01, 0x25, + /*Sequence(Constructed): 11 bytes (0xb) */ + 0x30, 0x0b, + /* ObjectId(Universal): 9 bytes (0x9) */ + 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x14, + /* BitString(Universal): 276 bytes (0x114) */ + 0x03, 0x82, 0x01, 0x14, + 0x00, 0x00, 0x01, 0xef, 0x04, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x69, 0x60, 0x70, 0x00, 0x80, 0x02, + 0x2e, 0x46, 0xb9, 0xcb, 0x22, 0x72, 0x0b, 0x1c, + 0xe6, 0x25, 0x20, 0x16, 0x86, 0x05, 0x8e, 0x2b, + 0x98, 0xd1, 0x46, 0x3d, 0x00, 0xb8, 0x69, 0xe1, + 0x1a, 0x42, 0x7d, 0x7d, 0xb5, 0xbf, 0x9f, 0x26, + 0xd3, 0x2c, 0xb1, 0x73, 0x01, 0xb6, 0xb2, 0x6f, + 0x7b, 0xa5, 0x54, 0x85, 0x60, 0x77, 0x81, 0x8a, + 0x87, 0x86, 0xe0, 0x2d, 0xbf, 0xdb, 0x28, 0xe8, + 0xfa, 0x20, 0x35, 0xb4, 0xc0, 0x94, 0x10, 0x8e, + 0x1c, 0x58, 0xaa, 0x02, 0x60, 0x97, 0xf5, 0xb3, + 0x2f, 0xf8, 0x99, 0x29, 0x28, 0x73, 0x47, 0x36, + 0xdd, 0x1d, 0x78, 0x95, 0xeb, 0xb8, 0xec, 0x45, + 0x96, 0x69, 0x6f, 0x54, 0xc8, 0x1f, 0x2d, 0x3a, + 0xd9, 0x0e, 0x8e, 0xaa, 0x59, 0x11, 0x8c, 0x3b, + 0x8d, 0xa4, 0xed, 0xf2, 0x7d, 0xdc, 0x42, 0xaa, + 0xa4, 0xd2, 0x1c, 0xb9, 0x87, 0xd0, 0xd9, 0x3d, + 0x8e, 0x89, 0xbb, 0x06, 0x54, 0xcf, 0x32, 0x00, + 0x02, 0x00, 0x00, 0x80, 0x0b, 0x80, 0x6c, 0x0f, + 0x71, 0xd1, 0xa1, 0xa9, 0x26, 0xb4, 0xf1, 0xcd, + 0x6a, 0x7a, 0x09, 0xaa, 0x58, 0x28, 0xd7, 0x35, + 0x74, 0x8e, 0x7c, 0x83, 0xcb, 0xfe, 0x00, 0x3b, + 0x62, 0x00, 0xfb, 0x90, 0x37, 0xcd, 0x93, 0xcf, + 0xf3, 0xe4, 0x6d, 0x8d, 0xdd, 0xb8, 0x53, 0xe0, + 0x5c, 0xda, 0x1a, 0x7e, 0x56, 0x03, 0x95, 0x03, + 0x2f, 0x74, 0x86, 0xb1, 0xa0, 0xbb, 0x05, 0x91, + 0xe4, 0x76, 0x83, 0xe6, 0x62, 0xf9, 0x12, 0x64, + 0x5a, 0x62, 0xd8, 0x94, 0x04, 0x1f, 0x83, 0x02, + 0x2e, 0xc5, 0xa7, 0x17, 0x46, 0x46, 0x21, 0x96, + 0xc3, 0xa9, 0x8e, 0x92, 0x18, 0xd1, 0x52, 0x08, + 0x1d, 0xff, 0x8e, 0x24, 0xdb, 0x6c, 0xd8, 0xfe, + 0x80, 0x93, 0xe1, 0xa5, 0x4a, 0x0a, 0x37, 0x24, + 0x18, 0x07, 0xbe, 0x0f, 0xaf, 0x73, 0xea, 0x50, + 0x64, 0xa1, 0xb3, 0x77, 0xe5, 0x41, 0x02, 0x82, + 0x39, 0xb9, 0xe3, 0x94 +}; + +unsigned char valitity[] = { + 0x30, 0x1e, + 0x17, 0x0d, + '2','0','0','0','0','1','0','1','0','0','0','0','Z', + 0x17, 0x0d, + '2','0','0','5','1','2','0','1','0','0','0','0','Z' +}; + + +unsigned char cnam_oid[] = { 0x06, 0x03, 0x55, 0x04, 0x03 }; + +unsigned char signature[] = { + /* the OID */ + 0x30, 0x0b, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13, + /* signature wrap */ + 0x03, 0x29, 0x00, + /* 40 byte dsa signature */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +unsigned char fortezza_oid [] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01, 0x13 +}; + +unsigned char software_ou[] = { + 0x31, 26, 0x30, 24, + 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 17, + 'S','o','f','t','w', + 'a','r','e',' ','F', + 'O','R','T','E','Z','Z','A' +}; + + +char letterarray[] = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v','w','x','y','z' }; + +char constarray[] = { + 'b','c','d','f','g','h','j','k','l','m','n', + 'p','q','r','s','t','v','w','x','y','z' }; + +char vowelarray[] = { + 'a','e','i','o','u','y' }; + +char digitarray[] = { + '0','1','2','3','4','5','6','7','8','9' }; + +unsigned long +getRandom(unsigned long max) { + unsigned short data; + unsigned long result; + + fort_GenerateRandom((unsigned char *)&data,sizeof(data)); + + result = (unsigned long)data * max; + result = result >> 16; + return result; +} + + +char getLetter(void) +{ + return letterarray[getRandom(sizeof(letterarray))]; +} +char getVowel(void) +{ + return vowelarray[getRandom(sizeof(vowelarray))]; +} +char getDigit(void) +{ + return digitarray[getRandom(sizeof(digitarray))]; +} + +char getConst(void) +{ + return constarray[getRandom(sizeof(constarray))]; +} + +char *getPinPhrase(void) +{ + char * pass = PORT_ZAlloc(5); + + pass[0] = getDigit(); + pass[1] = getDigit(); + pass[2] = getDigit(); + pass[3] = getDigit(); + + return pass; +} + +char *getPassPhrase(void) +{ + char * pass = PORT_ZAlloc(13); + + pass[0] = getConst()+'A'-'a'; + pass[1] = getVowel(); + pass[2] = getConst(); + pass[3] = getVowel(); + pass[4] = getConst(); + pass[5] = getVowel(); + pass[6] = getConst(); + pass[7] = getDigit(); + pass[8] = getDigit(); + pass[9] = getDigit(); + pass[10] = getDigit(); + pass[11] = getLetter()+'A'-'a'; + + return pass; +} + +extern void +makeCertSlot(fortSlotEntry * entry, + int index, + char * label, + SECItem * cert, + FORTSkipjackKeyPtr Ks, + unsigned char *xKEA, + unsigned char *xDSA, + unsigned char *pubKey, + int pubKeyLen, + unsigned char *p, + unsigned char *q, + unsigned char *g); + +extern void +makeProtectedPhrase(FORTSWFile * file, + fortProtectedPhrase *prot_phrase, + FORTSkipjackKeyPtr Ks, + FORTSkipjackKeyPtr Kinit, + char * phrase); + +extern void +fill_in(SECItem *item, unsigned char *data, int len); + +char *userLabel = "INKS0002 "; +int main(int argc, char **argv) +{ + char *progname = *argv++; + char *commonName = NULL; + char *caname = NULL; + char *email = NULL; + char *outname = NULL; + char *cp; + int arg_count = 0; + Cert caCert; + SECItem userCert; + int cirv,i; + int cards, start; + unsigned char *subject; + int subject_len; + int signature_len = sizeof(signature); + int newSubject_len, newCertBody_len, len; + int cname1_len, cname_len, pstring_len; + int valitity_len = sizeof(valitity); + unsigned char origCert[CERT_SIZE]; + unsigned char newSubject[CERT_SIZE]; + unsigned char newCertBody[CERT_SIZE]; + unsigned char newCert[CERT_SIZE]; + unsigned char pstring[CERT_SIZE]; + unsigned char cname1[CERT_SIZE]; + unsigned char cname[CERT_SIZE]; + CERTCertificate *myCACert = NULL; + CERTCertificate *cert; + CERTCertDBHandle *certhandle; + SECStatus rv; + unsigned char serial[16]; + SECKEYPublicKey *pubKey; + DSAPrivateKey *keaPrivKey; + DSAPrivateKey *dsaPrivKey; + CI_RANDOM randomVal; + PQGParams *params; + int pca_index = -1; + unsigned char *p,*q,*g; + FORTSkipjackKey Ks; + FORTSkipjackKey Kinit; + FORTSWFile *file; + FORTSignedSWFile *signed_file; + FORTSignedSWFile *signed_file2; + unsigned char random[20]; + unsigned char vers; + unsigned char *data; + char *transportPin=NULL; + char *ssoMemPhrase=NULL; + char *userMemPhrase=NULL; + char *ssoPin=NULL; + char *userPin=NULL; + char *pass=NULL; + SECItem *outItem; + int email_len = 0; + int emailAVA_len = 0; + + + /* put better argument parsing here */ + while ((cp = *argv++) != NULL) { + if (*cp == '-') { + while (*++cp) { + switch (*cp) { + /* verbose mode */ + case 'e': + email = *argv++; + break; + /* explicitly set the target */ + case 'o': + outname = *argv++; + break; + case 't': + /* provide password on command line */ + transportPin = *argv++; + break; + case 'u': + /* provide user password on command line */ + userPin = *argv++; + break; + case 'U': + /* provide user password on command line */ + userMemPhrase = *argv++; + break; + case 's': + /* provide user password on command line */ + ssoPin = *argv++; + break; + case 'S': + /* provide user password on command line */ + ssoMemPhrase = *argv++; + break; + case 'p': + /* provide card password on command line */ + pass = *argv++; + break; + case 'd': + transportPin="test1234567890"; + ssoMemPhrase="sso1234567890"; + userMemPhrase="user1234567890"; + ssoPin="9999"; + userPin="0000"; + break; + default: + usage(progname); + break; + } + } + } else switch (arg_count++) { + case 0: + commonName = cp; + break; + case 1: + caname = cp; + break; + default: + usage(progname); + } + } + + if (outname == NULL) outname = "swfort.sfi"; + if (caname == NULL) usage(progname); + + + + caCert.card = -1; + memset(newCert,0,CERT_SIZE); + + if (commonName == NULL) usage(progname); + + + cirv = CI_Initialize(&cards); + + start = 0; + for (i=0; i < cards; i++) { + cirv = InitCard(i+1,pass); + if (cirv == CI_OK) { + if (FoundCert(i+1,caname,&caCert)) { + break; + } + } + } + + if (caCert.card == -1) { + fprintf(stderr, + "WARNING: Couldn't find Signing CA...new cert will not be signed\n"); + } + + + /* + * initialize enough security to deal with certificates. + */ + NSS_NoDB_Init(NULL); + certhandle = CERT_GetDefaultCertDB(); + if (certhandle == NULL) { + Terminate("Couldn't build temparary Cert Database", + 1, -1, caCert.card); + exit(1); + } + + CI_GenerateRandom(random); + RNG_RandomUpdate(random,sizeof(random)); + CI_GenerateRandom(random); + RNG_RandomUpdate(random,sizeof(random)); + + + if (transportPin == NULL) transportPin = getPassPhrase(); + if (ssoMemPhrase == NULL) ssoMemPhrase = getPassPhrase(); + if (userMemPhrase == NULL) userMemPhrase = getPassPhrase(); + if (ssoPin == NULL) ssoPin = getPinPhrase(); + if (userPin == NULL) userPin = getPinPhrase(); + + + + /* now dump the certs into the temparary data base */ + for (i=0; i < caCert.count; i++) { + int trusted = 0; + SECItem derCert; + + cirv = CI_Select(caCert.card); + if (cirv != CI_OK) { + Terminate("Couldn't select on CA card",cirv, + -1, caCert.card); + } + cirv = CI_GetCertificate(caCert.valid[i].index,origCert); + if (cirv != CI_OK) { + continue; + } + derCert.data = origCert; + derCert.len = Cert_length(origCert, sizeof(origCert)); + cert = + (CERTCertificate *)CERT_NewTempCertificate(certhandle,&derCert, NULL, + PR_FALSE, PR_TRUE); + caCert.valid[i].cert = cert; + if (cert == NULL) continue; + if (caCert.valid[i].index == caCert.index) myCACert=cert; + if (caCert.valid[i].index == atoi((char *)&caCert.label[4])) + pca_index = i; + } + + if (myCACert == NULL) { + Terminate("Couldn't find CA's Certificate", 1, -1, caCert.card); + exit(1); + } + + + /* + * OK now build the user cert. + */ + /* first get the serial number and KMID */ + cirv = CI_GenerateRandom(randomVal); + memcpy(&header[2],randomVal,sizeof(serial)); + memcpy(serial,randomVal,sizeof(serial)); + memcpy(&key[KEY_START+KMID_OFFSET],randomVal+sizeof(serial),7); + /* KMID */ + + /* now generate the keys */ + pubKey = CERT_ExtractPublicKey(myCACert); + if (pubKey == NULL) { + Terminate("Couldn't extract CA's public key", + 1, -1, caCert.card); + exit(1); + } + + + switch (pubKey->keyType) { + case fortezzaKey: + params = (PQGParams *)&pubKey->u.fortezza.params; + break; + case dsaKey: + params = (PQGParams *)&pubKey->u.dsa.params; + break; + default: + Terminate("Certificate is not a fortezza or DSA Cert", + 1, -1, caCert.card); + exit(1); + } + + rv = DSA_NewKey(params,&keaPrivKey); + if (rv != SECSuccess) { + Terminate("Couldn't Generate KEA key", + PORT_GetError(), -1, caCert.card); + exit(1); + } + rv = DSA_NewKey(params,&dsaPrivKey); + if (rv != SECSuccess) { + Terminate("Couldn't Generate DSA key", + PORT_GetError(), -1, caCert.card); + exit(1); + } + + if (keaPrivKey->publicValue.len == 129) + keaPrivKey->publicValue.data++; + if (dsaPrivKey->publicValue.len == 129) + dsaPrivKey->publicValue.data++; + if (keaPrivKey->privateValue.len == 21) + keaPrivKey->privateValue.data++; + if (dsaPrivKey->privateValue.len == 21) + dsaPrivKey->privateValue.data++; + + /* save the parameters */ + p = params->prime.data; + if (params->prime.len == 129) p++; + q = params->subPrime.data; + if (params->subPrime.len == 21) q++; + g = params->base.data; + if (params->base.len == 129) g++; + + memcpy(&key[KEY_START+KEA_OFFSET], + keaPrivKey->publicValue.data, + keaPrivKey->publicValue.len); + memcpy(&key[KEY_START+DSA_OFFSET], + dsaPrivKey->publicValue.data, + dsaPrivKey->publicValue.len); + + /* build the der subject */ + subject = data_start(myCACert->derSubject.data,myCACert->derSubject.len, + &subject_len); + + /* build the new Common name AVA */ + len = DER_Sequence(pstring,strlen(commonName)); + memcpy(pstring+len,commonName,strlen(commonName)); + len += strlen(commonName); + pstring_len = len; + pstring[0] = 0x13; + + len = DER_Sequence(cname1,sizeof(cnam_oid)+pstring_len); + memcpy(cname1+len,cnam_oid,sizeof(cnam_oid)); len += sizeof(cnam_oid); + memcpy(cname1+len,pstring,pstring_len); len += pstring_len; + cname1_len = len; + + len = DER_Sequence(cname, cname1_len); + memcpy(cname+len,cname1,cname1_len); len += cname1_len; + cname_len = len; + cname[0] = 0x31; /* make it a set rather than a sequence */ + + if (email) { + email_len = strlen(email); + emailAVA_len = EMAIL_DATA_START + email_len; + } + + /* now assemble it */ + len = DER_Sequence(newSubject,subject_len + sizeof(software_ou) + + cname_len + emailAVA_len); + memcpy(newSubject+len,subject,subject_len); + + for (i=0; i < subject_len; i++) { + if (memcmp(newSubject+len+i,cnam_oid,sizeof(cnam_oid)) == 0) { + newSubject[i+len+4] = 0x0b; /* change CN to OU */ + break; + } + } + len += subject_len; + memcpy(newSubject+len,software_ou,sizeof(software_ou)); + len += sizeof(software_ou); + memcpy(newSubject+len,cname,cname_len); len += cname_len; + newSubject_len = len; + + /* + * build the email AVA + */ + if (email) { + memcpy(&emailAVA[EMAIL_DATA_START],email,email_len); + for (i=0; i < offsetCount; i++) { + emailAVA[emailOffset[i]] += email_len; + } + memcpy(newSubject+len,emailAVA,emailAVA_len); + newSubject_len += emailAVA_len; + } + + + /* + * Assemble the Cert + */ + + len = DER_Sequence(newCertBody,sizeof(header)+newSubject_len+ + valitity_len+myCACert->derSubject.len+sizeof(key)); + memcpy(newCertBody+len,header,sizeof(header));len += sizeof(header); + memcpy(newCertBody+len,myCACert->derSubject.data, + myCACert->derSubject.len);len += myCACert->derSubject.len; + memcpy(newCertBody+len,valitity,valitity_len);len += valitity_len; + memcpy(newCertBody+len,newSubject,newSubject_len); + len += newSubject_len; + memcpy(newCertBody+len,key,sizeof(key));len += sizeof(key); + newCertBody_len = len; + + + /* + * generate the hash + */ + cirv = CI_InitializeHash(); + if (cirv == CI_OK) { + int hash_left = newCertBody_len & 63; + int hash_len = newCertBody_len - hash_left; + cirv = CI_Hash(hash_len,newCertBody); + if (cirv == CI_OK) { + cirv = CI_GetHash(hash_left,newCertBody+hash_len,hash); + } + } + + /* + * now sign the hash + */ + if ((cirv == CI_OK) && (caCert.card != -1)) { + cirv = CI_Select(caCert.card); + if (cirv == CI_OK) { + cirv = CI_SetPersonality(caCert.index); + if (cirv == CI_OK) { + cirv = CI_Sign(hash,sig); + } + } + } else cirv = -1; + + if (cirv != CI_OK) { + memcpy(sig,hash,sizeof(hash)); + } + + /* + * load in new signature + */ + { + int sig_len; + unsigned char *sig_start = + GetSignature(signature,signature_len,&sig_len); + memcpy(sig_start,sig,sizeof(sig)); + } + + /* + * now do the final wrap + */ + len = DER_Sequence(newCert,newCertBody_len+signature_len); + memcpy(newCert+len,newCertBody,newCertBody_len); len += newCertBody_len; + memcpy(newCert+len, signature, signature_len); len +=signature_len; + userCert.data = newCert; + userCert.len = len; + + + /* OK, we now have our cert, let's go build our software file */ + signed_file = PORT_ZNew(FORTSignedSWFile); + file = &signed_file->file; + + signed_file->signatureWrap.signature.data = PORT_ZAlloc(40); + signed_file->signatureWrap.signature.len = 40; + signed_file->signatureWrap.signatureAlgorithm.algorithm.data = + fortezza_oid; + signed_file->signatureWrap.signatureAlgorithm.algorithm.len = + sizeof(fortezza_oid); + + vers = 1; + fill_in(&file->version,&vers,1); + file->derIssuer.data = myCACert->derSubject.data; + file->derIssuer.len = myCACert->derSubject.len; + file->serialID.data = serial; + file->serialID.len =sizeof(serial); + /* generate out Ks value */ + fort_GenerateRandom(Ks,sizeof(Ks)); + makeProtectedPhrase(file,&file->initMemPhrase,Kinit,NULL,transportPin); + makeProtectedPhrase(file,&file->ssoMemPhrase,Ks,Kinit,ssoMemPhrase); + makeProtectedPhrase(file,&file->ssoPinPhrase,Ks,Kinit,ssoPin); + makeProtectedPhrase(file,&file->userMemPhrase,Ks,Kinit,userMemPhrase); + makeProtectedPhrase(file,&file->userPinPhrase,Ks,Kinit,userPin); + file->wrappedRandomSeed.data = PORT_ZAlloc(12); + file->wrappedRandomSeed.len = 12; + cirv = fort_GenerateRandom(file->wrappedRandomSeed.data,10); + if (cirv != CI_OK) { + Terminate("Couldn't get Random Seed", + cirv, -1, caCert.card); + } + fort_skipjackWrap(Ks,12,file->wrappedRandomSeed.data, + file->wrappedRandomSeed.data); + file->slotEntries = PORT_ZAlloc(sizeof(fortSlotEntry *)*5); + /* paa */ + file->slotEntries[0] = PORT_ZNew(fortSlotEntry); + makeCertSlot(file->slotEntries[0],0, + (char *)caCert.valid[0].label, + &caCert.valid[0].cert->derCert, + Ks,NULL,NULL,NULL,0,p,q,g); + /* pca */ + file->slotEntries[1] = PORT_ZNew(fortSlotEntry); + makeCertSlot(file->slotEntries[1],1, + (char *)caCert.valid[pca_index].label, + &caCert.valid[pca_index].cert->derCert, + Ks,NULL,NULL,NULL,0,p,q,g); + /* ca */ + file->slotEntries[2] = PORT_ZNew(fortSlotEntry); + /* make sure the caCert lable points to our new pca slot location */ + caCert.label[4] = '0'; + caCert.label[5] = '0'; + caCert.label[6] = '0'; + caCert.label[7] = '1'; + makeCertSlot(file->slotEntries[2],2,(char *)caCert.label, + &myCACert->derCert,Ks,NULL,NULL,NULL,0,p,q,g); + /* user */ + file->slotEntries[3] = PORT_ZNew(fortSlotEntry); + strncpy(&userLabel[8],commonName,sizeof(CI_PERSON)-8); + makeCertSlot(file->slotEntries[3],3,userLabel,&userCert,Ks, + keaPrivKey->privateValue.data, + dsaPrivKey->privateValue.data, + key, sizeof(key), p, q, g); + file->slotEntries[4] = 0; + + /* encode the file so we can sign it */ + outItem = FORT_PutSWFile(signed_file); + + /* get the der encoded data to sign */ + signed_file2 = FORT_GetSWFile(outItem); + + /* now sign it */ + len = signed_file2->signatureWrap.data.len; + data = signed_file2->signatureWrap.data.data; + /* + * generate the hash + */ + cirv = CI_InitializeHash(); + if (cirv == CI_OK) { + int hash_left = len & 63; + int hash_len = len - hash_left; + cirv = CI_Hash(hash_len,data); + if (cirv == CI_OK) { + cirv = CI_GetHash(hash_left,data+hash_len,hash); + } + } + + /* + * now sign the hash + */ + if ((cirv == CI_OK) && (caCert.card != -1)) { + cirv = CI_Select(caCert.card); + if (cirv == CI_OK) { + cirv = CI_SetPersonality(caCert.index); + if (cirv == CI_OK) { + cirv = CI_Sign(hash,sig); + } + } + } else cirv = -1; + + if (cirv != CI_OK) { + memcpy(sig,hash,sizeof(hash)); + } + memcpy( signed_file->signatureWrap.signature.data,sig,sizeof(sig)); + signed_file->signatureWrap.signature.len = sizeof(sig)*8; + + + /* encode it for the last time */ + outItem = FORT_PutSWFile(signed_file); + + + /* + * write it out to the .sfi file + */ + { + int fd = open(outname,O_WRONLY|O_CREAT|O_BINARY,0777); + + write(fd,outItem->data,outItem->len); + close(fd); + } + CI_Close(CI_POWER_DOWN_FLAG,caCert.card); + CI_Terminate(); + + printf("Wrote %s to file %s.\n",commonName,outname); + printf("Initialization Memphrase: %s\n",transportPin); + printf("SSO Memphrase: %s\n",ssoMemPhrase); + printf("User Memphrase: %s\n",userMemPhrase); + printf("SSO pin: %s\n",ssoPin); + printf("User pin: %s\n",userPin); + + return 0; +} + |