summaryrefslogtreecommitdiff
path: root/security/nss/cmd/swfort
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/cmd/swfort')
-rw-r--r--security/nss/cmd/swfort/Makefile108
-rw-r--r--security/nss/cmd/swfort/instinit/Makefile75
-rw-r--r--security/nss/cmd/swfort/instinit/instinit.c421
-rw-r--r--security/nss/cmd/swfort/instinit/manifest.mn46
-rw-r--r--security/nss/cmd/swfort/manifest.mn38
-rw-r--r--security/nss/cmd/swfort/newuser/Makefile83
-rw-r--r--security/nss/cmd/swfort/newuser/manifest.mn45
-rw-r--r--security/nss/cmd/swfort/newuser/mktst.c254
-rw-r--r--security/nss/cmd/swfort/newuser/newuser.c1132
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;
+}
+