summaryrefslogtreecommitdiff
path: root/security/nss/lib/fortcrypt
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2000-03-31 20:13:40 +0000
committerrelyea%netscape.com <devnull@localhost>2000-03-31 20:13:40 +0000
commit9502869e82d4f3ce26b292263e1c626dca3a34f3 (patch)
tree4d0f8ab157505b57c13a5e2bdf979560ab751527 /security/nss/lib/fortcrypt
parent222a52dab759085f56dcb6588b69a6a937d82aa2 (diff)
downloadnss-hg-9502869e82d4f3ce26b292263e1c626dca3a34f3.tar.gz
Initial NSS Open Source checkin
Diffstat (limited to 'security/nss/lib/fortcrypt')
-rw-r--r--security/nss/lib/fortcrypt/Makefile146
-rw-r--r--security/nss/lib/fortcrypt/config.mk52
-rw-r--r--security/nss/lib/fortcrypt/cryptint.h703
-rw-r--r--security/nss/lib/fortcrypt/fmutex.c113
-rw-r--r--security/nss/lib/fortcrypt/fmutex.h57
-rw-r--r--security/nss/lib/fortcrypt/forsock.c815
-rw-r--r--security/nss/lib/fortcrypt/fortinst.htm161
-rw-r--r--security/nss/lib/fortcrypt/fortpk11.c4544
-rw-r--r--security/nss/lib/fortcrypt/fortsock.h105
-rw-r--r--security/nss/lib/fortcrypt/fpkcs11.h170
-rw-r--r--security/nss/lib/fortcrypt/fpkcs11f.h953
-rw-r--r--security/nss/lib/fortcrypt/fpkcs11i.h269
-rw-r--r--security/nss/lib/fortcrypt/fpkcs11t.h1098
-rw-r--r--security/nss/lib/fortcrypt/fpkmem.h48
-rw-r--r--security/nss/lib/fortcrypt/fpkstrs.h122
-rw-r--r--security/nss/lib/fortcrypt/genci.h145
-rw-r--r--security/nss/lib/fortcrypt/globinst.htm139
-rw-r--r--security/nss/lib/fortcrypt/handinst.htm180
-rw-r--r--security/nss/lib/fortcrypt/homeinst.htm211
-rw-r--r--security/nss/lib/fortcrypt/inst.js268
-rw-r--r--security/nss/lib/fortcrypt/inst_PPC.js134
-rw-r--r--security/nss/lib/fortcrypt/install.js134
-rw-r--r--security/nss/lib/fortcrypt/maci.c895
-rw-r--r--security/nss/lib/fortcrypt/maci.h776
-rw-r--r--security/nss/lib/fortcrypt/macinst.htm148
-rw-r--r--security/nss/lib/fortcrypt/manifest.mn50
-rw-r--r--security/nss/lib/fortcrypt/replace.c101
-rw-r--r--security/nss/lib/fortcrypt/secmodjar.html441
-rw-r--r--security/nss/lib/fortcrypt/swfort/.cvsignore1
-rw-r--r--security/nss/lib/fortcrypt/swfort/Makefile82
-rw-r--r--security/nss/lib/fortcrypt/swfort/config.mk44
-rw-r--r--security/nss/lib/fortcrypt/swfort/manifest.mn56
-rw-r--r--security/nss/lib/fortcrypt/swfort/nsmap.h86
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore15
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/Makefile164
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/config.mk52
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/inst.js189
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn73
-rwxr-xr-xsecurity/nss/lib/fortcrypt/swfort/pkcs11/pk11inst49
-rw-r--r--security/nss/lib/fortcrypt/swfort/pkcs11/stub.c344
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfalg.c506
-rw-r--r--security/nss/lib/fortcrypt/swfort/swflib.c1028
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfort.h70
-rw-r--r--security/nss/lib/fortcrypt/swfort/swforti.h176
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfortt.h56
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfortti.h153
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfparse.c538
-rw-r--r--security/nss/lib/fortcrypt/swfort/swfutl.c728
48 files changed, 17388 insertions, 0 deletions
diff --git a/security/nss/lib/fortcrypt/Makefile b/security/nss/lib/fortcrypt/Makefile
new file mode 100644
index 000000000..d7dcef59d
--- /dev/null
+++ b/security/nss/lib/fortcrypt/Makefile
@@ -0,0 +1,146 @@
+#! 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.
+#
+
+include manifest.mn
+include $(CORE_DEPTH)/coreconf/config.mk
+
+CILIB = $(OBJDIR)/cilib.$(LIB_SUFFIX)
+ORIG_CILIB = libci/$(OS_CONFIG).$(LIB_SUFFIX)
+
+ifeq ($(OS_ARCH), WINNT)
+ORIG_CILIB = libci/tssp32.lib
+endif
+
+ifeq ($(OS_TARGET), WIN16)
+ORIG_CILIB = libci/tssp.lib
+endif
+
+ifeq ($(OS_TARGET), WIN95)
+ORIG_CILIB = libci/tssp32.lib
+endif
+
+STUBLIB = $(OBJDIR)/stub.$(LIB_SUFFIX)
+
+ifeq ($(OS_TARGET), WIN16)
+W16LIBS += $(CILIB)
+else
+EXTRA_LIBS += $(CILIB)
+endif
+
+INST_JS = inst.js
+LIBCI_JAR = $(OBJDIR)/libfort.jar
+LIBCI_JAR_SRC = $(INST_JS) $(SHARED_LIBRARY)
+
+ifneq ($(OS_TARGET), WIN16)
+TARGETS : $(LIBCI_JAR)
+endif
+
+ifeq ($(OS_TARGET), WIN16)
+# note that rules.mk is not included below for WIN16
+all:
+ @echo Skipping fortcrypt directory for 16-bit windows builds
+
+all_platforms alltags clean clobber clobber_all realclean: all
+
+boot export install libs program release: all
+
+endif
+
+$(SHARED_LIBRARY): $(CILIB) $(DIRS)
+
+$(CILIB):
+ @$(MAKE_OBJDIR)
+ @if test -f $(ORIG_CILIB); then \
+ echo "Copying $(ORIG_CILIB) to $@"; \
+ cp $(ORIG_CILIB) $@; \
+ else \
+ echo "Making empty stub $@"; \
+ $(MAKE) $(STUBLIB); \
+ fi
+ @$(RANLIB) $@
+
+$(STUBLIB): $(OBJDIR)/maci.o
+ @$(MAKE_OBJDIR)
+ $(AR) $<
+ cp $@ $(CILIB)
+
+#
+# The following rules packages the shared library into a JAR,
+# ready to be signed
+#
+$(OBJDIR)/replace: replace.c
+ $(CC) -o $@ $<
+
+# ZIP options:
+# -5 means medium compression
+# -q means quiet
+# -j means do not store tree structure, all files go into one dir
+#
+$(LIBCI_JAR): $(DIRS) $(LIBCI_JAR_SRC)
+ @echo +++ building $@ from $(LIBCI_JAR_SRC)
+ @rm -f $@
+ zip -5qj $@ $(LIBCI_JAR_SRC)
+
+force:
+ (cd swfort ; gmake)
+
+
+MD_FILES += $(LIBCI_JAR)
+
+# coreconf doesn't build the AIX shared library for FORTEZZA,
+# so I'm going to override their shared library command and build the shared
+# library the way config used to.
+#
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
+EXTRA_DSO_LDOPTS = -lc
+MKSHLIB = svld $(DSO_LDOPTS)
+
+$(SHARED_LIBRARY): $(OBJS)
+ @$(MAKE_OBJDIR)
+ rm -f $@
+ $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
+ chmod +x $@
+endif
+
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.2)
+LD += -G
+endif
+
+
+ifneq ($(OS_TARGET), WIN16)
+include $(CORE_DEPTH)/coreconf/rules.mk
+endif
+
+export:: private_export
diff --git a/security/nss/lib/fortcrypt/config.mk b/security/nss/lib/fortcrypt/config.mk
new file mode 100644
index 000000000..1e8237ff2
--- /dev/null
+++ b/security/nss/lib/fortcrypt/config.mk
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+ifeq ($(OS_TARGET), WIN16)
+TARGETS = all
+else
+TARGETS = $(SHARED_LIBRARY)
+endif
+LIBRARY =
+PURE_LIBRARY =
+PROGRAM =
+
+
+ifeq ($(OS_TARGET), WIN16)
+dummy:
+ @echo $(TARGETS)
+endif
diff --git a/security/nss/lib/fortcrypt/cryptint.h b/security/nss/lib/fortcrypt/cryptint.h
new file mode 100644
index 000000000..c4de00ff2
--- /dev/null
+++ b/security/nss/lib/fortcrypt/cryptint.h
@@ -0,0 +1,703 @@
+/*
+ * 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.
+ */
+/* @(#)cryptint.h 1.26\t10 Nov 1995 */
+/*****************************************************************************
+ Definitive Fortezza header file.
+ Application Level Interface to Fortezza CI Library.
+
+ Version for CI Library 1.52
+ November 8, 1995
+
+
+ NOTICE: Fortezza Export Policy
+
+ The Fortezza Cryptologic Interface (CI) Library (both source and
+ object) and Fortezza CI Library based applications are defense
+ articles, as defined in the International Traffic In Arms
+ Regulations (ITAR), and are subject to export controls under the
+ ITAR and the Arms Export Control Act. Any export to any country
+ of (a) the Fortezza CI Library, related documentation, and
+ technical data, or (b) your cryptographic application, process,
+ or service that is the direct product of, or contains the
+ Fortezza CI Library must comply with the requirements of the ITAR.
+ If you or your customer intends to engage in such export, contact
+ the United States Department of State, Office of Defense Trade
+ Controls for specific guidance.
+
+
+ ****************************************************************************/
+#ifndef __CRYPTINT_H
+#define __CRYPTINT_H
+
+#if __cplusplus__ || __cplusplus
+extern "C"
+{
+#endif /* C++ */
+
+#ifndef PROTO_LIST
+#ifdef _K_AND_R_
+#define PROTO_LIST(list) ()
+#else
+#define PROTO_LIST(list) list
+#endif /*_K_AND_R_ */
+#endif /* PROTO_LIST */
+
+
+#ifndef RETURN_TYPE
+#if defined( _WIN32 ) || defined( __WIN32__ )
+#define RETURN_TYPE __declspec(dllimport) int
+#elif defined( _WINDOWS ) || defined( _Windows )
+#define RETURN_TYPE extern int _far _pascal
+#else
+#define RETURN_TYPE extern int
+#endif /* Windows */
+#endif /* RETURN_TYPE */
+
+/* MS Visual C++ defines _MSDOS and _WINDOWS */
+/* Borland C/C++ defines __MSDOS__ and _Windows */
+#if defined( _WIN32 ) || defined ( __WIN32__ )
+#define CI_FAR
+#elif defined( _WINDOWS ) || defined( _Windows )
+#define CI_FAR _far
+#else
+#define CI_FAR
+#endif /* MS DOS or Windows */
+
+
+/*****************************************************************************
+ Constants
+ ****************************************************************************/
+#define CI_LIB_VERSION_VAL 0x0152 /* Version 1.52 */
+
+#define CI_CERT_SIZE 2048
+#define CI_CERT_FLAGS_SIZE 16
+#define CI_CERT_NAME_SIZE 32
+#define CI_CHALLENGE_SIZE 20
+
+#define CI_G_SIZE 128
+
+#define CI_HASHVALUE_SIZE 20
+
+#define CI_IV_SIZE 24
+
+#define CI_KEY_SIZE 12
+#define CI_KS_SIZE 10
+
+#define CI_NAME_SIZE 32
+
+#define CI_PASSWORD_SIZE 24
+#define CI_PIN_SIZE 12
+#define CI_P_SIZE 128
+
+#define CI_Q_SIZE 20
+
+#define CI_R_SIZE 40
+#define CI_RANDOM_NO_SIZE 20
+#define CI_RANDOM_SEED_SIZE 8
+#define CI_RA_SIZE 128
+#define CI_RB_SIZE 128
+#define CI_REG_FLAGS_SIZE 4
+
+#define CI_S_SIZE 40
+#define CI_SAVE_DATA_SIZE 28
+#define CI_SERIAL_NUMBER_SIZE 8
+#define CI_SIGNATURE_SIZE 40
+#define CI_STATUS_FLAGS_SIZE 4
+
+#define CI_TIME_SIZE 16
+#define CI_TIMESTAMP_SIZE 16
+
+#define CI_WRAPPED_X_SIZE 24
+
+#define CI_Y_SIZE 128
+
+#define CI_X_SIZE 20
+
+
+/* Miscellaneous */
+#define CI_NULL_FLAG 0
+#define CI_POWER_DOWN_FLAG 2
+#define CI_NO_LOG_OFF_FLAG 4
+#define CI_INITIATOR_FLAG 0
+#define CI_RECIPIENT_FLAG 1
+
+#define CI_BLOCK_LOCK_FLAG 1
+#define CI_SSO_LOGGED_ON 0x40
+#define CI_USER_LOGGED_ON 0x00
+#define CI_FAST_MODE 0x10
+#define CI_SLOW_MODE 0x00
+#define CI_WORST_CASE_MODE 0x40
+#define CI_TYPICAL_CASE_MODE 0x00
+
+/* Card Public Key Algorithms Types */
+#define CI_DSA_TYPE 0xA
+#define CI_KEA_TYPE 0x5
+#define CI_DSA_KEA_TYPE 0xF
+
+/* Fortezza Pin Types */
+#define CI_SSO_PIN 0x25
+#define CI_USER_PIN 0x2A
+
+/* Crypto Types */
+#define CI_ENCRYPT_TYPE 0
+#define CI_DECRYPT_TYPE 1
+#define CI_HASH_TYPE 2
+
+/* Save and Restore Types */
+#define CI_ENCRYPT_INT_TYPE 0x00 /* Internal Encryption */
+#define CI_ENCRYPT_EXT_TYPE 0x10 /* External Encryption */
+#define CI_DECRYPT_INT_TYPE 0x01 /* Internal Decryption */
+#define CI_DECRYPT_EXT_TYPE 0x11 /* External Decryption */
+#define CI_HASH_INT_TYPE 0x02 /* Internal Hash */
+#define CI_HASH_EXT_TYPE 0x12 /* External Hash */
+#define CI_TYPE_EXT_FLAG 0x10 /* Used to differentiate */
+
+/* Configuration types */
+#define CI_SET_SPEED_TYPE 1
+#define CI_SET_TIMING_TYPE 2
+
+/* Lock States */
+#define CI_SOCKET_UNLOCKED 0
+#define CI_HOLD_LOCK 1
+#define CI_SOCKET_LOCKED 2
+
+/* Fortezza Crypto Types Modes */
+#define CI_ECB64_MODE 0
+#define CI_CBC64_MODE 1
+#define CI_OFB64_MODE 2
+#define CI_CFB64_MODE 3
+#define CI_CFB32_MODE 4
+#define CI_CFB16_MODE 5
+#define CI_CFB8_MODE 6
+
+/* Card States */
+#define CI_POWER_UP 0
+#define CI_UNINITIALIZED 1
+#define CI_INITIALIZED 2
+#define CI_SSO_INITIALIZED 3
+#define CI_LAW_INITIALIZED 4
+#define CI_USER_INITIALIZED 5
+#define CI_STANDBY 6
+#define CI_READY 7
+#define CI_ZEROIZE 8
+#define CI_INTERNAL_FAILURE (-1)
+
+/* Flags for Firmware Update. */
+#define CI_NOT_LAST_BLOCK_FLAG 0x00000000UL
+#define CI_LAST_BLOCK_FLAG 0x80000000UL
+#define CI_DESTRUCTIVE_FLAG 0x000000FFUL
+#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00UL
+
+
+/****************************************************************************
+ Fortezza Library Return Codes
+ ***************************************************************************/
+
+/* Card Responses */
+#define CI_OK 0
+#define CI_FAIL 1
+#define CI_CHECKWORD_FAIL 2
+#define CI_INV_TYPE 3
+#define CI_INV_MODE 4
+#define CI_INV_KEY_INDEX 5
+#define CI_INV_CERT_INDEX 6
+#define CI_INV_SIZE 7
+#define CI_INV_HEADER 8
+#define CI_INV_STATE 9
+#define CI_EXEC_FAIL 10
+#define CI_NO_KEY 11
+#define CI_NO_IV 12
+#define CI_NO_X 13
+
+#define CI_NO_SAVE 15
+#define CI_REG_IN_USE 16
+#define CI_INV_COMMAND 17
+#define CI_INV_POINTER 18
+#define CI_BAD_CLOCK 19
+#define CI_NO_DSA_PARMS 20
+
+/* Library Errors */
+#define CI_ERROR (-1)
+#define CI_LIB_NOT_INIT (-2)
+#define CI_CARD_NOT_READY (-3)
+#define CI_CARD_IN_USE (-4)
+#define CI_TIME_OUT (-5)
+#define CI_OUT_OF_MEMORY (-6)
+#define CI_NULL_PTR (-7)
+#define CI_BAD_SIZE (-8)
+#define CI_NO_DECRYPT (-9)
+#define CI_NO_ENCRYPT (-10)
+#define CI_NO_EXECUTE (-11)
+#define CI_BAD_PARAMETER (-12)
+#define CI_OUT_OF_RESOURCES (-13)
+
+#define CI_NO_CARD (-20)
+#define CI_NO_DRIVER (-21)
+#define CI_NO_CRDSRV (-22)
+#define CI_NO_SCTSRV (-23)
+
+#define CI_BAD_CARD (-30)
+#define CI_BAD_IOCTL (-31)
+#define CI_BAD_READ (-32)
+#define CI_BAD_SEEK (-33)
+#define CI_BAD_WRITE (-34)
+#define CI_BAD_FLUSH (-35)
+#define CI_BAD_IOSEEK (-36)
+#define CI_BAD_ADDR (-37)
+
+#define CI_INV_SOCKET_INDEX (-40)
+#define CI_SOCKET_IN_USE (-41)
+#define CI_NO_SOCKET (-42)
+#define CI_SOCKET_NOT_OPENED (-43)
+#define CI_BAD_TUPLES (-44)
+#define CI_NOT_A_CRYPTO_CARD (-45)
+
+#define CI_INVALID_FUNCTION (-50)
+#define CI_LIB_ALRDY_INIT (-51)
+#define CI_SRVR_ERROR (-52)
+
+
+/*****************************************************************************
+ Data Structures
+ ****************************************************************************/
+
+typedef unsigned char CI_CERTIFICATE[CI_CERT_SIZE];
+
+typedef unsigned char CI_CERT_FLAGS[CI_CERT_FLAGS_SIZE];
+
+typedef unsigned char CI_CERT_STR[CI_CERT_NAME_SIZE+4];
+
+typedef unsigned char CI_FAR *CI_DATA;
+
+typedef unsigned char CI_G[CI_G_SIZE];
+
+typedef unsigned char CI_HASHVALUE[CI_HASHVALUE_SIZE];
+
+typedef unsigned char CI_IV[CI_IV_SIZE];
+
+typedef unsigned char CI_KEY[CI_KEY_SIZE];
+
+typedef unsigned char CI_KS[CI_KS_SIZE];
+
+typedef unsigned char CI_P[CI_P_SIZE];
+
+typedef unsigned char CI_PASSWORD[CI_PASSWORD_SIZE + 4];
+
+typedef unsigned char CI_PIN[CI_PIN_SIZE + 4];
+
+typedef unsigned char CI_Q[CI_Q_SIZE];
+
+typedef unsigned char CI_RA[CI_RA_SIZE];
+
+typedef unsigned char CI_RB[CI_RB_SIZE];
+
+typedef unsigned char CI_RANDOM[CI_RANDOM_NO_SIZE];
+
+typedef unsigned char CI_RANDSEED[CI_RANDOM_SEED_SIZE];
+
+typedef unsigned char CI_REG_FLAGS[CI_REG_FLAGS_SIZE];
+
+typedef unsigned char CI_SIGNATURE[CI_SIGNATURE_SIZE];
+
+typedef unsigned char CI_SAVE_DATA[CI_SAVE_DATA_SIZE];
+
+typedef unsigned char CI_SERIAL_NUMBER[CI_SERIAL_NUMBER_SIZE];
+
+typedef unsigned int CI_STATE, CI_FAR *CI_STATE_PTR;
+
+typedef unsigned char CI_TIME[CI_TIME_SIZE];
+
+typedef unsigned char CI_TIMESTAMP[CI_TIMESTAMP_SIZE];
+
+typedef unsigned char CI_WRAPPED_X[CI_WRAPPED_X_SIZE];
+
+typedef unsigned char CI_Y[CI_Y_SIZE];
+
+typedef unsigned char CI_X[CI_X_SIZE];
+
+typedef struct {
+ int LibraryVersion; /* CI Library version */
+ int ManufacturerVersion; /* Card's hardware version */
+ char ManufacturerName[CI_NAME_SIZE+4]; /* Card manufacturer's name*/
+ char ProductName[CI_NAME_SIZE+4]; /* Card's product name */
+ char ProcessorType[CI_NAME_SIZE+4]; /* Card's processor type */
+ unsigned long UserRAMSize; /* Amount of User RAM in bytes */
+ unsigned long LargestBlockSize; /* Largest block of data to pass in */
+ int KeyRegisterCount; /* Number of key registers */
+ int CertificateCount; /* Maximum number of personalities (# certs-1) */
+ int CryptoCardFlag; /* A flag that if non-zero indicates that there is
+ a Crypto-Card in the socket. If this value is
+ zero then there is NOT a Crypto-Card in the
+ sockets. */
+ int ICDVersion; /* The ICD compliance level */
+ int ManufacturerSWVer; /* The Manufacturer's Software Version */
+ int DriverVersion; /* Driver Version */
+} CI_CONFIG, CI_FAR *CI_CONFIG_PTR;
+
+typedef struct {
+ int CertificateIndex; /* Index from 1 to CertificateCount */
+ CI_CERT_STR CertLabel; /* The certificate label */
+} CI_PERSON, CI_FAR *CI_PERSON_PTR;
+
+typedef struct {
+ int CurrentSocket; /* The currently selected socket */
+ int LockState; /* Lock status of the current socket */
+ CI_SERIAL_NUMBER SerialNumber; /* Serial number of the Crypto Engine chip */
+ CI_STATE CurrentState; /* State of The Card */
+ int DecryptionMode; /* Decryption mode of The Card */
+ int EncryptionMode; /* Encryption mode of The Card */
+ int CurrentPersonality; /* Index of the current personality */
+ int KeyRegisterCount; /* No. of Key Register on The Card */
+ CI_REG_FLAGS KeyRegisterFlags; /* Bit Masks indicating Key Register use */
+ int CertificateCount; /* No. of Certificates on The Card */
+ CI_CERT_FLAGS CertificateFlags; /* Bit Mask indicating certificate use */
+ unsigned char Flags[CI_STATUS_FLAGS_SIZE];
+ /* Flag[0] : bit 6 for Condition mode */
+ /* bit 4 for Clock mode */
+} CI_STATUS, CI_FAR *CI_STATUS_PTR;
+
+
+/*****************************************************************************
+ Function Call Prototypes
+ ****************************************************************************/
+
+RETURN_TYPE
+CI_ChangePIN PROTO_LIST( (
+ int PINType,
+ CI_PIN CI_FAR pOldPIN,
+ CI_PIN CI_FAR pNewPIN ) );
+
+RETURN_TYPE
+CI_CheckPIN PROTO_LIST( (
+ int PINType,
+ CI_PIN CI_FAR pPIN ) );
+
+RETURN_TYPE
+CI_Close PROTO_LIST( (
+ unsigned int Flags,
+ int SocketIndex ) );
+
+RETURN_TYPE
+CI_Decrypt PROTO_LIST( (
+ unsigned int CipherSize,
+ CI_DATA pCipher,
+ CI_DATA pPlain ) );
+
+RETURN_TYPE
+CI_DeleteCertificate PROTO_LIST( (
+ int CertificateIndex ) );
+
+RETURN_TYPE
+CI_DeleteKey PROTO_LIST( (
+ int RegisterIndex ) );
+
+RETURN_TYPE
+CI_Encrypt PROTO_LIST( (
+ unsigned int PlainSize,
+ CI_DATA pPlain,
+ CI_DATA pCipher ) );
+
+RETURN_TYPE
+CI_ExtractX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+CI_FirmwareUpdate PROTO_LIST( (
+ unsigned long Flags,
+ long Cksum,
+ unsigned int CksumLength,
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+CI_GenerateIV PROTO_LIST( (
+ CI_IV CI_FAR pIV ) );
+
+RETURN_TYPE
+CI_GenerateMEK PROTO_LIST( (
+ int RegisterIndex,
+ int Reserved ) );
+
+RETURN_TYPE
+CI_GenerateRa PROTO_LIST( (
+ CI_RA CI_FAR pRa ) );
+
+RETURN_TYPE
+CI_GenerateRandom PROTO_LIST( (
+ CI_RANDOM CI_FAR pRandom ) );
+
+RETURN_TYPE
+CI_GenerateTEK PROTO_LIST( (
+ int Flags,
+ int RegisterIndex,
+ CI_RA CI_FAR pRa,
+ CI_RB CI_FAR pRb,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+CI_GenerateX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+CI_GetCertificate PROTO_LIST( (
+ int CertificateIndex,
+ CI_CERTIFICATE CI_FAR pCertificate ) );
+
+RETURN_TYPE
+CI_GetConfiguration PROTO_LIST( (
+ CI_CONFIG_PTR pConfiguration ) );
+
+RETURN_TYPE
+CI_GetHash PROTO_LIST( (
+ unsigned int DataSize,
+ CI_DATA pData,
+ CI_HASHVALUE CI_FAR pHashValue ) );
+
+RETURN_TYPE
+CI_GetPersonalityList PROTO_LIST( (
+ int EntryCount,
+ CI_PERSON CI_FAR pPersonalityList[] ) );
+
+RETURN_TYPE
+CI_GetState PROTO_LIST( (
+ CI_STATE_PTR pState ) );
+
+RETURN_TYPE
+CI_GetStatus PROTO_LIST( (
+ CI_STATUS_PTR pStatus ) );
+
+RETURN_TYPE
+CI_GetTime PROTO_LIST( (
+ CI_TIME CI_FAR pTime ) );
+
+RETURN_TYPE
+CI_Hash PROTO_LIST( (
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+CI_Initialize PROTO_LIST( (
+ int CI_FAR *SocketCount ) );
+
+RETURN_TYPE
+CI_InitializeHash PROTO_LIST( (
+ void ) );
+
+RETURN_TYPE
+CI_InstallX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pWrappedX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+CI_LoadCertificate PROTO_LIST( (
+ int CertificateIndex,
+ CI_CERT_STR CI_FAR pCertLabel,
+ CI_CERTIFICATE CI_FAR pCertificate,
+ long Reserved ) );
+
+RETURN_TYPE
+CI_LoadDSAParameters PROTO_LIST( (
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+CI_LoadInitValues PROTO_LIST( (
+ CI_RANDSEED CI_FAR pRandSeed,
+ CI_KS CI_FAR pKs ) );
+
+RETURN_TYPE
+CI_LoadIV PROTO_LIST( (
+ CI_IV CI_FAR pIV ) );
+
+RETURN_TYPE
+CI_LoadX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ CI_X CI_FAR pX,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+CI_Lock PROTO_LIST( (
+ int Flags ) );
+
+RETURN_TYPE
+CI_Open PROTO_LIST( (
+ unsigned int Flags,
+ int SocketIndex ) );
+
+RETURN_TYPE
+CI_RelayX PROTO_LIST( (
+ CI_PASSWORD CI_FAR pOldPassword,
+ unsigned int OldYSize,
+ CI_Y CI_FAR pOldY,
+ CI_RA CI_FAR pOldRa,
+ CI_WRAPPED_X CI_FAR pOldWrappedX,
+ CI_PASSWORD CI_FAR pNewPassword,
+ unsigned int NewYSize,
+ CI_Y CI_FAR pNewY,
+ CI_RA CI_FAR pNewRa,
+ CI_WRAPPED_X CI_FAR pNewWrappedX ) );
+
+RETURN_TYPE
+CI_Reset PROTO_LIST( (
+ void ) );
+
+RETURN_TYPE
+CI_Restore PROTO_LIST( (
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) );
+
+RETURN_TYPE
+CI_Save PROTO_LIST( (
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) );
+
+RETURN_TYPE
+CI_Select PROTO_LIST( (
+ int SocketIndex ) );
+
+RETURN_TYPE
+CI_SetConfiguration PROTO_LIST( (
+ int Type,
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+CI_SetKey PROTO_LIST( (
+ int RegisterIndex ) );
+
+RETURN_TYPE
+CI_SetMode PROTO_LIST( (
+ int CryptoType,
+ int CryptoMode ) );
+
+RETURN_TYPE
+CI_SetPersonality PROTO_LIST( (
+ int CertificateIndex ) );
+
+RETURN_TYPE
+CI_SetTime PROTO_LIST( (
+ CI_TIME CI_FAR pTime ) );
+
+RETURN_TYPE
+CI_Sign PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature ) );
+
+RETURN_TYPE
+CI_Terminate PROTO_LIST( (
+ void ) );
+
+RETURN_TYPE
+CI_TimeStamp PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) );
+
+RETURN_TYPE
+CI_Unlock PROTO_LIST( (
+ void ) );
+
+RETURN_TYPE
+CI_UnwrapKey PROTO_LIST( (
+ int UnwrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) );
+
+RETURN_TYPE
+CI_VerifySignature PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_SIGNATURE CI_FAR pSignature ) );
+
+RETURN_TYPE
+CI_VerifyTimeStamp PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) );
+
+RETURN_TYPE
+CI_WrapKey PROTO_LIST( (
+ int WrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) );
+
+RETURN_TYPE
+CI_Zeroize PROTO_LIST( (
+ void ) );
+
+#if __cplusplus__ || __cplusplus
+}
+#endif /* C++ */
+
+#endif /* CRYPTINT_H */
diff --git a/security/nss/lib/fortcrypt/fmutex.c b/security/nss/lib/fortcrypt/fmutex.c
new file mode 100644
index 000000000..ad98c04b6
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fmutex.c
@@ -0,0 +1,113 @@
+/*
+ * 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 "fmutex.h"
+#include "fpkmem.h"
+#include <stdio.h>
+
+typedef struct PKMutexFunctions {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ int useMutex;
+} PKMutexFunctions;
+
+static PKMutexFunctions gMutex = {NULL, NULL, NULL, NULL, 0};
+static int gInit = 0;
+
+#define FMUTEX_CHECKS() \
+ if (gInit == 0) { \
+ return CKR_GENERAL_ERROR; \
+ } \
+ if (!gMutex.useMutex) { \
+ return CKR_GENERAL_ERROR; \
+ }
+
+CK_RV FMUTEX_Init(CK_C_INITIALIZE_ARGS_PTR pArgs) {
+ if (gInit != 0) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (pArgs && pArgs->CreateMutex && pArgs->DestroyMutex &&
+ pArgs->LockMutex && pArgs->UnlockMutex) {
+
+ gMutex.CreateMutex = pArgs->CreateMutex;
+ gMutex.DestroyMutex = pArgs->DestroyMutex;
+ gMutex.LockMutex = pArgs->LockMutex;
+ gMutex.UnlockMutex = pArgs->UnlockMutex;
+ gMutex.useMutex = 1;
+ gInit = 1;
+ } else {
+ gInit = 0;
+ return CKR_GENERAL_ERROR;
+ }
+
+ return CKR_OK;
+}
+
+
+CK_RV FMUTEX_Create(CK_VOID_PTR_PTR pMutex) {
+ CK_RV rv;
+ FMUTEX_CHECKS()
+
+ rv = gMutex.CreateMutex(pMutex);
+ return rv;
+}
+
+CK_RV FMUTEX_Destroy(CK_VOID_PTR pMutex) {
+ CK_RV rv;
+ FMUTEX_CHECKS()
+
+ rv = gMutex.DestroyMutex(pMutex);
+ return rv;
+}
+
+CK_RV FMUTEX_Lock(CK_VOID_PTR pMutex) {
+ CK_RV rv;
+ FMUTEX_CHECKS()
+
+ rv = gMutex.LockMutex(pMutex);
+ return rv;
+}
+
+CK_RV FMUTEX_Unlock(CK_VOID_PTR pMutex) {
+ CK_RV rv;
+ FMUTEX_CHECKS()
+
+ rv = gMutex.UnlockMutex(pMutex);
+ return rv;
+}
+
+int FMUTEX_MutexEnabled (void) {
+ return gMutex.useMutex;
+}
diff --git a/security/nss/lib/fortcrypt/fmutex.h b/security/nss/lib/fortcrypt/fmutex.h
new file mode 100644
index 000000000..589eea786
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fmutex.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+#ifndef _FMUTEX_H_
+#define _FMUTEX_H_ 1
+
+#include "fpkcs11t.h"
+
+/*
+ * All of these functions will return CK_RV values.
+ */
+extern CK_RV FMUTEX_Init(CK_C_INITIALIZE_ARGS_PTR pArgs);
+
+
+extern CK_RV FMUTEX_Create(CK_VOID_PTR_PTR pMutex);
+
+extern CK_RV FMUTEX_Destroy(CK_VOID_PTR pMutex);
+
+extern CK_RV FMUTEX_Lock(CK_VOID_PTR pMutex);
+
+extern CK_RV FMUTEX_Unlock(CK_VOID_PTR pMutex);
+
+/* Returns 0 if mutexes have not been enabled.
+ * Returns 1 if mutexes have been enabled.
+ */
+extern int FMUTEX_MutexEnabled(void);
+
+#endif /*_FMUTEX_H_*/
diff --git a/security/nss/lib/fortcrypt/forsock.c b/security/nss/lib/fortcrypt/forsock.c
new file mode 100644
index 000000000..39a4f0420
--- /dev/null
+++ b/security/nss/lib/fortcrypt/forsock.c
@@ -0,0 +1,815 @@
+/*
+ * 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 "fortsock.h"
+#include "fpkmem.h"
+#include "fmutex.h"
+#include <string.h>
+#include <stdlib.h>
+
+#define DEF_ENCRYPT_SIZE 0x8000
+
+static unsigned char Fortezza_mail_Rb[128] = {
+0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,1,
+};
+
+int InitSocket (FortezzaSocket *inSocket, int inSlotID) {
+ int ci_rv;
+ CK_RV mrv;
+
+ if (inSocket == NULL)
+ return SOCKET_FAILURE;
+
+ inSocket->isLoggedIn = PR_FALSE;
+ inSocket->personalitiesLoaded = PR_FALSE;
+ inSocket->isOpen = PR_FALSE;
+ inSocket->personalityList = NULL;
+ inSocket->keyRegisters = NULL;
+ inSocket->keys = NULL;
+ inSocket->numPersonalities = 0;
+ inSocket->numKeyRegisters = 0;
+ inSocket->hitCount = 0;
+
+ inSocket->slotID = inSlotID;
+ ci_rv = MACI_GetSessionID(&(inSocket->maciSession));
+ if (ci_rv != CI_OK)
+ return SOCKET_FAILURE;
+
+ ci_rv = MACI_Open (inSocket->maciSession, 0, inSlotID);
+ if (ci_rv == CI_OK) {
+ inSocket->isOpen = PR_TRUE;
+ } else {
+ MACI_Close (inSocket->maciSession, CI_NULL_FLAG, inSlotID);
+ }
+
+ if (FMUTEX_MutexEnabled()) {
+ mrv = FMUTEX_Create(&inSocket->registersLock);
+ if (mrv != CKR_OK) {
+ inSocket->registersLock = NULL;
+ }
+ } else {
+ inSocket->registersLock = NULL;
+ }
+
+ return SOCKET_SUCCESS;
+}
+
+int FreeSocket (FortezzaSocket *inSocket) {
+ if (inSocket->registersLock) {
+ FMUTEX_Destroy(inSocket->registersLock);
+ }
+ MACI_Close(inSocket->maciSession, CI_NULL_FLAG, inSocket->slotID);
+ return SOCKET_SUCCESS;
+}
+
+int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin) {
+ int ci_rv, i;
+ CI_STATUS ciStatus;
+ CI_CONFIG ciConfig;
+ FortezzaKey **oldRegisters, **newRegisters;
+ int oldCount;
+ HSESSION hs;
+
+ if (inSocket == NULL || inSocket->isLoggedIn)
+ return SOCKET_FAILURE;
+
+ hs = inSocket->maciSession;
+ ci_rv = MACI_Select (hs, inSocket->slotID);
+ if (ci_rv != CI_OK)
+ return ci_rv;
+
+ ci_rv = MACI_CheckPIN(hs, inUserType, inPin);
+
+ if (ci_rv != CI_OK) {
+ return ci_rv;
+ }
+
+ ci_rv = MACI_GetStatus(hs, &ciStatus);
+
+ if (ci_rv != CI_OK) {
+ if (ci_rv == CI_FAIL) {
+ ci_rv = CI_EXEC_FAIL;
+ }
+ return ci_rv;
+ }
+
+ ci_rv = MACI_GetConfiguration(hs, &ciConfig);
+ if (ci_rv != CI_OK) {
+ return ci_rv;
+ }
+
+ inSocket->isLoggedIn = PR_TRUE;
+ inSocket->hasLoggedIn = PR_TRUE;
+ PORT_Memcpy (inSocket->openCardSerial, ciStatus.SerialNumber,
+ sizeof (CI_SERIAL_NUMBER));
+ inSocket->openCardState = ciStatus.CurrentState;
+ inSocket->numPersonalities = ciStatus.CertificateCount;
+ inSocket->numKeyRegisters = ciConfig.KeyRegisterCount;
+ newRegisters =
+ (FortezzaKey**)PORT_Alloc (sizeof(FortezzaKey)*ciConfig.KeyRegisterCount);
+
+ FMUTEX_Lock(inSocket->registersLock);
+ oldRegisters = inSocket->keyRegisters;
+ oldCount = inSocket->numKeyRegisters;
+ inSocket->keyRegisters = newRegisters;
+ if (oldRegisters) {
+ for (i=0; i<oldCount; i++) {
+ if (oldRegisters[i]) {
+ oldRegisters[i]->keyRegister = KeyNotLoaded;
+ }
+ oldRegisters[i] = NULL;
+ }
+ PORT_Free(oldRegisters);
+ }
+
+ if (inSocket->keyRegisters == NULL) {
+ FMUTEX_Unlock(inSocket->registersLock);
+ return SOCKET_FAILURE;
+ }
+
+ for (i=0; i<ciConfig.KeyRegisterCount; i++) {
+ inSocket->keyRegisters[i] = NULL;
+ }
+ FMUTEX_Unlock(inSocket->registersLock);
+
+ return SOCKET_SUCCESS;
+}
+
+int LogoutFromSocket (FortezzaSocket *inSocket) {
+ if (inSocket == NULL)
+ return SOCKET_FAILURE;
+
+ inSocket->isLoggedIn = PR_FALSE;
+ inSocket->hasLoggedIn = PR_FALSE;
+ if (UnloadPersonalityList(inSocket) != SOCKET_SUCCESS)
+ return SOCKET_FAILURE;
+
+
+ return SOCKET_SUCCESS;
+}
+
+
+int FetchPersonalityList(FortezzaSocket *inSocket) {
+ int rv;
+
+ if (inSocket == NULL || inSocket->numPersonalities == 0) {
+ return SOCKET_FAILURE;
+ }
+
+ rv = MACI_Select (inSocket->maciSession, inSocket->slotID);
+
+ inSocket->personalityList =
+ (CI_PERSON*)PORT_Alloc (sizeof(CI_PERSON)*inSocket->numPersonalities);
+
+ if (inSocket->personalityList == NULL) {
+ return SOCKET_FAILURE;
+ }
+
+ rv = MACI_GetPersonalityList(inSocket->maciSession,
+ inSocket->numPersonalities,
+ inSocket->personalityList);
+
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+ inSocket->personalitiesLoaded = PR_TRUE;
+ return SOCKET_SUCCESS;
+}
+
+int UnloadPersonalityList(FortezzaSocket *inSocket) {
+ if (inSocket == NULL)
+ return SOCKET_FAILURE;
+
+ inSocket->personalitiesLoaded = PR_FALSE;
+ if (inSocket->personalityList) {
+ PORT_Free(inSocket->personalityList);
+ }
+ inSocket->numPersonalities = 0;
+ inSocket->personalityList = NULL;
+
+ return SOCKET_SUCCESS;
+}
+
+PRBool SocketIsLoggedIn(CI_STATE status) {
+
+ return (PRBool)((status == CI_READY) || (status == CI_STANDBY));
+}
+
+PRBool SocketStateUnchanged(FortezzaSocket* inSocket) {
+ CI_STATUS ciStatus;
+ int ciRV;
+
+ ciRV = MACI_Select (inSocket->maciSession, inSocket->slotID);
+ if (ciRV != CI_OK)
+ return PR_FALSE;
+
+ if (inSocket->hasLoggedIn && !inSocket->isLoggedIn)
+ return PR_FALSE; /* User Logged out from the socket */
+
+ /*
+ * Some vendor cards are slow. so if we think we are logged in,
+ * and the card still thinks we're logged in, we must have the same
+ * card.
+ */
+ if (inSocket->isLoggedIn) {
+ CI_STATE state;
+ ciRV = MACI_GetState(inSocket->maciSession, &state);
+ if (ciRV != CI_OK) return PR_FALSE;
+
+ return SocketIsLoggedIn(state);
+ }
+
+ ciRV = MACI_GetStatus(inSocket->maciSession, &ciStatus);
+ if(ciRV != CI_OK) {
+ return PR_FALSE;
+ }
+ if (inSocket->isLoggedIn) {
+ if (PORT_Memcmp(ciStatus.SerialNumber, inSocket->openCardSerial,
+ sizeof (CI_SERIAL_NUMBER)) != 0)
+ return PR_FALSE; /* Serial Number of card in slot has changed */
+ /* Probably means there is a new card */
+ }
+
+ if (inSocket->isLoggedIn && !SocketIsLoggedIn(ciStatus.CurrentState))
+ return PR_FALSE; /* State of card changed. */
+ /* Probably re-inserted same card */
+
+ return PR_TRUE; /* No change in the state of the socket */
+}
+
+/*
+ * can we regenerate this key on the fly?
+ */
+static PRBool
+FortezzaIsRegenerating(FortezzaKey *key) {
+ /* TEK's are the only type of key that can't be regenerated */
+ if (key->keyType != TEK) return PR_TRUE;
+ /* Client TEK's can never be regenerated */
+ if (key->keyData.tek.flags == CI_INITIATOR_FLAG) return PR_FALSE;
+ /* Only Server TEK's that use the Mail protocol can be regenerated */
+ return ((PRBool)(memcmp(key->keyData.tek.Rb,Fortezza_mail_Rb,
+ sizeof(key->keyData.tek.Rb)) == 0));
+}
+
+int GetBestKeyRegister(FortezzaSocket *inSocket) {
+ int i, candidate = -1, candidate2 = 1;
+ CK_ULONG minHitCount = 0xffffffff;
+ CK_ULONG minRegHitCount = 0xffffffff;
+ FortezzaKey **registers;
+
+ registers = inSocket->keyRegisters;
+ for (i=1; i< inSocket->numKeyRegisters; i++) {
+ if (registers[i] == NULL)
+ return i;
+ }
+
+ for (i=1; i < inSocket->numKeyRegisters; i++) {
+ if (registers[i]->hitCount < minHitCount) {
+ minHitCount = registers[i]->hitCount;
+ candidate2 = i;
+ }
+
+ if (FortezzaIsRegenerating(registers[i]) &&
+ (registers[i]->hitCount < minRegHitCount)) {
+ minRegHitCount = registers[i]->hitCount;
+ candidate = i;
+ }
+ }
+
+ if (candidate == -1)
+ candidate = candidate2;
+
+ return candidate;
+}
+
+int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle) {
+ inKey->keyHandle = inHandle;
+ return SOCKET_SUCCESS;
+}
+
+void
+RemoveKey (FortezzaKey *inKey) {
+ if (inKey != NULL && inKey->keySocket->keyRegisters != NULL) {
+ if (inKey->keyRegister != KeyNotLoaded) {
+ FortezzaKey **registers = inKey->keySocket->keyRegisters;
+ registers[inKey->keyRegister] = NULL;
+ MACI_DeleteKey(inKey->keySocket->maciSession, inKey->keyRegister);
+ }
+
+ PORT_Free(inKey);
+ }
+}
+
+FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket,
+ FortezzaKeyType inKeyType,
+ CreateTEKInfo *TEKinfo,
+ int inKeyRegister) {
+ FortezzaKey *newKey, *oldKey;
+ FortezzaKey **registers;
+ HSESSION hs = inSocket->maciSession;
+ int ciRV;
+
+ newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey));
+ if (newKey == NULL) {
+ return NULL;
+ }
+
+ newKey->keyHandle = 0;
+ newKey->keyRegister = KeyNotLoaded;
+ newKey->keyType = inKeyType;
+ newKey->keySocket = inSocket;
+ newKey->hitCount = 0;
+ newKey->id = TEKinfo ? TEKinfo->personality : 0;
+
+ if (inKeyType != Ks && inSocket->keyRegisters) {
+ registers = inSocket->keyRegisters;
+ oldKey = registers[inKeyRegister];
+ if (oldKey != NULL) {
+ oldKey->keyRegister = KeyNotLoaded;
+ }
+
+ registers[inKeyRegister] = newKey;
+ newKey->hitCount = inSocket->hitCount++;
+
+ MACI_DeleteKey (hs, inKeyRegister);
+ }
+ newKey->keyRegister = inKeyRegister;
+
+ MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
+ switch (inKeyType) {
+ case MEK:
+ ciRV = MACI_GenerateMEK (hs, inKeyRegister, 0);
+ if (ciRV != CI_OK) {
+ RemoveKey(newKey);
+ MACI_Unlock(hs);
+ return NULL;
+ }
+ MACI_WrapKey(hs, 0, inKeyRegister, newKey->keyData.mek);
+ break;
+ case TEK:
+ PORT_Memcpy (newKey->keyData.tek.Rb, TEKinfo->Rb, TEKinfo->randomLen);
+ PORT_Memcpy (newKey->keyData.tek.Ra, TEKinfo->Ra, TEKinfo->randomLen);
+ PORT_Memcpy (newKey->keyData.tek.pY, TEKinfo->pY, TEKinfo->YSize);
+ newKey->keyData.tek.ySize = TEKinfo->YSize;
+ newKey->keyData.tek.randomLen = TEKinfo->randomLen;
+ newKey->keyData.tek.registerIndex = TEKinfo->personality;
+ newKey->keyData.tek.flags = TEKinfo->flag;
+
+ ciRV = MACI_SetPersonality(hs,TEKinfo->personality);
+ if (ciRV != CI_OK) {
+ RemoveKey(newKey);
+ MACI_Unlock(hs);
+ return NULL;
+ }
+ ciRV = MACI_GenerateTEK(hs, TEKinfo->flag, inKeyRegister,
+ newKey->keyData.tek.Ra, TEKinfo->Rb,
+ TEKinfo->YSize, TEKinfo->pY);
+ if (ciRV != CI_OK) {
+ RemoveKey(newKey);
+ MACI_Unlock(hs);
+ return NULL;
+ }
+
+
+ break;
+ case Ks:
+ break;
+ default:
+ RemoveKey(newKey);
+ MACI_Unlock(hs);
+ return NULL;
+ }
+ MACI_Unlock(hs);
+ return newKey;
+}
+
+FortezzaKey *NewUnwrappedKey(int inKeyRegister, int id,
+ FortezzaSocket *inSocket) {
+ FortezzaKey *newKey;
+
+ newKey = (FortezzaKey*)PORT_Alloc (sizeof(FortezzaKey));
+ if (newKey == NULL) {
+ return NULL;
+ }
+
+ newKey->keyRegister = inKeyRegister;
+ newKey->keyType = UNWRAP;
+ newKey->keySocket = inSocket;
+ newKey->id = id;
+ newKey->hitCount = inSocket->hitCount++;
+ MACI_WrapKey(inSocket->maciSession,0 , inKeyRegister, newKey->keyData.mek);
+ inSocket->keyRegisters[inKeyRegister] = newKey;
+
+ return newKey;
+}
+
+int LoadKeyIntoRegister (FortezzaKey *inKey) {
+ int registerIndex = GetBestKeyRegister(inKey->keySocket);
+ FortezzaSocket *socket = inKey->keySocket;
+ FortezzaKey **registers = socket->keyRegisters;
+ HSESSION hs = socket->maciSession;
+ FortezzaTEK *tek = &inKey->keyData.tek;
+ FortezzaKey *oldKey;
+ int rv = CI_FAIL;
+
+ if (inKey->keyRegister != KeyNotLoaded) {
+ return inKey->keyRegister;
+ }
+
+ oldKey = registers[registerIndex];
+
+ MACI_Select(hs, socket->slotID);
+ if (oldKey) {
+ oldKey->keyRegister = KeyNotLoaded;
+ }
+ MACI_DeleteKey (hs, registerIndex);
+
+ switch (inKey->keyType) {
+ case TEK:
+ if (!FortezzaIsRegenerating(inKey)) {
+ return KeyNotLoaded;
+ }
+ if (MACI_SetPersonality(hs, tek->registerIndex) == CI_OK) {
+ rv = MACI_GenerateTEK (hs, tek->flags, registerIndex,
+ tek->Ra, tek->Rb, tek->ySize,
+ tek->pY);
+ }
+ if (rv != CI_OK)
+ return KeyNotLoaded;
+ break;
+ case MEK:
+ case UNWRAP:
+ rv = MACI_UnwrapKey (hs, 0, registerIndex, inKey->keyData.mek);
+ if (rv != CI_OK)
+ return KeyNotLoaded;
+ break;
+ default:
+ return KeyNotLoaded;
+ }
+ inKey->keyRegister = registerIndex;
+ registers[registerIndex] = inKey;
+
+ return registerIndex;
+}
+
+int InitCryptoOperation (FortezzaContext *inContext,
+ CryptoType inCryptoOperation) {
+ inContext->cryptoOperation = inCryptoOperation;
+ return SOCKET_SUCCESS;
+}
+
+int EndCryptoOperation (FortezzaContext *inContext,
+ CryptoType inCryptoOperation) {
+ if (inCryptoOperation != inContext->cryptoOperation) {
+ return SOCKET_FAILURE;
+ }
+ inContext->cryptoOperation = None;
+ return SOCKET_SUCCESS;
+}
+
+CryptoType GetCryptoOperation (FortezzaContext *inContext) {
+ return inContext->cryptoOperation;
+}
+
+void InitContext(FortezzaContext *inContext, FortezzaSocket *inSocket,
+ CK_OBJECT_HANDLE hKey) {
+ inContext->fortezzaKey = NULL;
+ inContext->fortezzaSocket = inSocket;
+ inContext->session = NULL;
+ inContext->mechanism = NO_MECHANISM;
+ inContext->userRamSize = 0;
+ inContext->cryptoOperation = None;
+ inContext->hKey = hKey;
+}
+
+extern PRBool fort11_FortezzaIsUserCert(unsigned char *label);
+
+static int
+GetValidPersonality (FortezzaSocket *inSocket) {
+ int index;
+ int i;
+ PRBool unLoadList = PR_FALSE;
+ int numPersonalities;
+
+ if (!inSocket->personalitiesLoaded) {
+ numPersonalities = inSocket->numPersonalities;
+ FetchPersonalityList (inSocket);
+ unLoadList = PR_TRUE;
+ }
+
+ for (i=0; i<inSocket->numPersonalities; i++) {
+ if (fort11_FortezzaIsUserCert(inSocket->personalityList[i].CertLabel)) {
+ index = inSocket->personalityList[i].CertificateIndex;
+ break;
+ }
+ }
+
+ if (unLoadList) {
+ UnloadPersonalityList(inSocket);
+ /* UnloadPersonality sets numPersonalities to zero,
+ * so we set it back to what it was when this function
+ * was called.
+ */
+ inSocket->numPersonalities = numPersonalities;
+ }
+ return index;
+}
+
+int RestoreState (FortezzaContext *inContext, CryptoType inType) {
+ FortezzaKey *key = inContext->fortezzaKey;
+ FortezzaSocket *socket = inContext->fortezzaSocket;
+ HSESSION hs = socket->maciSession;
+ CI_IV bogus_iv;
+ int rv, cryptoType;
+ int personality = inContext->fortezzaKey->id;
+
+ if (key == NULL)
+ return SOCKET_FAILURE;
+
+ if (personality == 0) {
+ personality = GetValidPersonality (socket);
+ }
+ rv = MACI_SetPersonality(hs, personality);
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+ /*
+ * The cards need to have some state bits set because
+ * save and restore don't necessarily save all the state.
+ * Instead of fixing the cards, they decided to change the
+ * protocol :(.
+ */
+ switch (inType) {
+ case Encrypt:
+ rv = MACI_SetKey(hs, key->keyRegister);
+ if (rv != CI_OK)
+ break;
+ rv = MACI_GenerateIV (hs, bogus_iv);
+ cryptoType = CI_ENCRYPT_EXT_TYPE;
+ break;
+ case Decrypt:
+ rv = MACI_SetKey(hs, key->keyRegister);
+ rv = MACI_LoadIV (hs, inContext->cardIV);
+ cryptoType = CI_DECRYPT_EXT_TYPE;
+ break;
+ default:
+ rv = CI_INV_POINTER;
+ break;
+ }
+
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+ rv = MACI_Restore(hs, cryptoType, inContext->cardState);
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+ return SOCKET_SUCCESS;
+}
+
+int SaveState (FortezzaContext *inContext, CI_IV inIV,
+ PK11Session *inSession, FortezzaKey *inKey,
+ int inCryptoType, CK_MECHANISM_TYPE inMechanism){
+ int ciRV;
+ FortezzaSocket *socket = inContext->fortezzaSocket;
+ HSESSION hs = socket->maciSession;
+ CI_CONFIG ciConfig;
+
+ ciRV = MACI_Select (hs, socket->slotID);
+ if (ciRV != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+ inContext->session = inSession;
+ inContext->fortezzaKey = inKey;
+ inContext->mechanism = inMechanism;
+ PORT_Memcpy (inContext->cardIV, inIV, sizeof (CI_IV));
+ ciRV = MACI_Save(hs, inCryptoType, inContext->cardState);
+ if (ciRV != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+ ciRV = MACI_GetConfiguration (hs, &ciConfig);
+ if (ciRV == CI_OK) {
+ inContext->userRamSize = ciConfig.LargestBlockSize;
+ }
+
+ if (inContext->userRamSize == 0) inContext->userRamSize = 0x4000;
+
+ return SOCKET_SUCCESS;
+}
+
+int SocketSaveState (FortezzaContext *inContext, int inCryptoType) {
+ int ciRV;
+
+ ciRV = MACI_Save (inContext->fortezzaSocket->maciSession, inCryptoType,
+ inContext->cardState);
+ if (ciRV != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+ return SOCKET_SUCCESS;
+}
+
+int DecryptData (FortezzaContext *inContext,
+ CK_BYTE_PTR inData,
+ CK_ULONG inDataLen,
+ CK_BYTE_PTR inDest,
+ CK_ULONG inDestLen) {
+ FortezzaSocket *socket = inContext->fortezzaSocket;
+ FortezzaKey *key = inContext->fortezzaKey;
+ HSESSION hs = socket->maciSession;
+ CK_ULONG defaultEncryptSize;
+ CK_ULONG left = inDataLen;
+ CK_BYTE_PTR loopin, loopout;
+ int rv = CI_OK;
+
+ MACI_Select (hs, socket->slotID);
+
+ defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE)
+ ? DEF_ENCRYPT_SIZE : inContext->userRamSize;
+
+ if (key->keyRegister == KeyNotLoaded) {
+ rv = LoadKeyIntoRegister(key);
+ if (rv == KeyNotLoaded) {
+ return SOCKET_FAILURE;
+ }
+ }
+
+ key->hitCount = socket->hitCount++;
+ loopin = inData;
+ loopout = inDest;
+ left = inDataLen;
+ rv = CI_OK;
+
+ MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
+ RestoreState (inContext, Decrypt);
+
+ while ((left > 0) && (rv == CI_OK)) {
+ CK_ULONG current = (left > defaultEncryptSize)
+ ? defaultEncryptSize : left;
+ rv = MACI_Decrypt(hs, current, loopin, loopout);
+ loopin += current;
+ loopout += current;
+ left -= current;
+ }
+
+ MACI_Unlock(hs);
+
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+
+ rv = SocketSaveState (inContext, CI_DECRYPT_EXT_TYPE);
+ if (rv != SOCKET_SUCCESS) {
+ return rv;
+ }
+
+
+ return SOCKET_SUCCESS;
+}
+
+int EncryptData (FortezzaContext *inContext,
+ CK_BYTE_PTR inData,
+ CK_ULONG inDataLen,
+ CK_BYTE_PTR inDest,
+ CK_ULONG inDestLen) {
+ FortezzaSocket *socket = inContext->fortezzaSocket;
+ FortezzaKey *key = inContext->fortezzaKey;
+ HSESSION hs = socket->maciSession;
+ CK_ULONG defaultEncryptSize;
+ CK_ULONG left = inDataLen;
+ CK_BYTE_PTR loopin, loopout;
+ int rv = CI_OK;
+
+ MACI_Select (hs, socket->slotID);
+
+ defaultEncryptSize = (inContext->userRamSize > DEF_ENCRYPT_SIZE)
+ ? DEF_ENCRYPT_SIZE : inContext->userRamSize;
+ if (key->keyRegister == KeyNotLoaded) {
+ rv = LoadKeyIntoRegister(key);
+ if (rv == KeyNotLoaded) {
+ return rv;
+ }
+ }
+
+ key->hitCount = socket->hitCount++;
+ loopin = inData;
+ loopout = inDest;
+
+ RestoreState (inContext,Encrypt);
+
+ rv = CI_OK;
+ while ((left > 0) && (rv == CI_OK)) {
+ CK_ULONG current = (left > defaultEncryptSize) ? defaultEncryptSize :
+ left;
+ rv = MACI_Encrypt(hs, current, loopin, loopout);
+ loopin += current;
+ loopout += current;
+ left -= current;
+ }
+
+ if (rv != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+ rv = SocketSaveState (inContext, CI_ENCRYPT_EXT_TYPE);
+ if (rv != SOCKET_SUCCESS) {
+ return rv;
+ }
+
+ return SOCKET_SUCCESS;
+}
+
+int WrapKey (FortezzaKey *wrappingKey, FortezzaKey *srcKey,
+ CK_BYTE_PTR pDest, CK_ULONG ulDestLen) {
+ int ciRV;
+ HSESSION hs = wrappingKey->keySocket->maciSession;
+
+ if (wrappingKey->keyRegister == KeyNotLoaded) {
+ if (LoadKeyIntoRegister(wrappingKey) == KeyNotLoaded) {
+ return SOCKET_FAILURE;
+ }
+ }
+
+ if (srcKey->id == 0) srcKey->id = wrappingKey->id;
+
+ ciRV = MACI_WrapKey (hs, wrappingKey->keyRegister,
+ srcKey->keyRegister, pDest);
+ if (ciRV != CI_OK) {
+ return SOCKET_FAILURE;
+ }
+
+ return SOCKET_SUCCESS;
+}
+
+int UnwrapKey (CK_BYTE_PTR inWrappedKey, FortezzaKey *inUnwrapKey) {
+ int newIndex;
+ int ciRV;
+ FortezzaSocket *socket = inUnwrapKey->keySocket;
+ HSESSION hs = socket->maciSession;
+ FortezzaKey *oldKey;
+
+ if (inUnwrapKey->keyRegister == KeyNotLoaded) {
+ if (LoadKeyIntoRegister(inUnwrapKey) == KeyNotLoaded) {
+ return KeyNotLoaded;
+ }
+ }
+
+ ciRV = MACI_Select(hs, socket->slotID);
+ if (ciRV != CI_OK) {
+ return KeyNotLoaded;
+ }
+
+ newIndex = GetBestKeyRegister(inUnwrapKey->keySocket);
+ oldKey = socket->keyRegisters[newIndex];
+
+ MACI_Select(hs, socket->slotID);
+ if (oldKey) {
+ oldKey->keyRegister = KeyNotLoaded;
+ socket->keyRegisters[newIndex] = NULL;
+ }
+ MACI_DeleteKey (hs, newIndex);
+ ciRV = MACI_UnwrapKey(hs,inUnwrapKey->keyRegister, newIndex, inWrappedKey);
+ if (ciRV != CI_OK) {
+ inUnwrapKey->keyRegister = KeyNotLoaded;
+ socket->keyRegisters[newIndex] = NULL;
+ return KeyNotLoaded;
+ }
+
+ return newIndex;
+}
+
diff --git a/security/nss/lib/fortcrypt/fortinst.htm b/security/nss/lib/fortcrypt/fortinst.htm
new file mode 100644
index 000000000..649012c82
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fortinst.htm
@@ -0,0 +1,161 @@
+<HTML>
+<TITLE>Generic PKCS #11 Installer</TITLE>
+<--
+ - 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.
+-->
+
+<SCRIPT>
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+pkcs11MechanismFlags = 0;
+
+
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3 // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1 // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4 // Error deleting a module
+JS_ERR_ADD_MODULE = -5 // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid
+
+var new_window;
+var has_new_window = 0;
+
+function HandleCipher(checkBox) {
+ if (checkBox.checked) {
+ pkcs11MechanismFlags |= checkBox.value;
+ } else {
+ pkcs11MechanismFlags &= ~checkBox.value;
+ }
+}
+
+function HandleSSL(checkBox) {
+ if (checkBox.checked) {
+ pkcs11CipherFlags |= checkBox.value;
+ } else {
+ pkcs11CipherFlags &= ~checkBox.value;
+ }
+}
+
+function colonize(string) {
+ len = string.length;
+ end = len -1;
+
+ if (len == 0) return string;
+
+
+ for (i=0; i < len; i++) {
+ if (string.charAt(i) == "/") {
+ if (i == 0) {
+ new_string = ":" + string.substring(1,len);
+ } else if (i == end) {
+ new_string = string.substring(0,i)+':';
+ } else {
+ new_string = string.substring(0,i)+':'+
+ string.substring(i+1,len);
+ }
+ string = new_string;
+ }
+ }
+
+ if (string.charAt(0) == ":") string = string.substring(1,len);
+ return string;
+}
+
+function DoInstall(name,module) {
+ if ((navigator.platform == "MacPPC")
+ || (navigator.platform == "Mac68K")) {
+ module = colonize(module);
+ }
+ result = pkcs11.addmodule(name, module,
+ pkcs11MechanismFlags, pkcs11CipherFlags);
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ }
+ if (has_new_window) new_window.close();
+}
+
+default_name = "Netscape FORTEZZA Module"
+
+default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll"
+document.writeln("<FORM name=instform target=_self> <H2>FORTEZZA PKCS #11 Installer version 1.5</H2>");
+document.writeln(" Module name: <Input Type=Text Name=modName value=\""+default_name+"\" size=50 required><br>");
+document.writeln(" Module Library: <Input Type=FILE required Name=module><br>");
+document.writeln("<i>Note: If you use the browse button, be sure to change the filter to show all the files (*), not just the HTML files (*.html).</i><p>");
+document.writeln("<hr>");
+document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall(");
+document.writeln( "document.instform.modName.value,document.instform.module.value) >");
+document.writeln("</FORM>");
+</SCRIPT>
diff --git a/security/nss/lib/fortcrypt/fortpk11.c b/security/nss/lib/fortcrypt/fortpk11.c
new file mode 100644
index 000000000..076db666e
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fortpk11.c
@@ -0,0 +1,4544 @@
+/*
+ * 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.
+ *
+ * This file implements PKCS 11 for FORTEZZA using MACI
+ * drivers. Except for the Mac. They only have CI libraries, so
+ * that's what we use there.
+ *
+ * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
+ *
+ * This implementations queries the MACI to figure out how
+ * many slots exist on a given system. There is an artificial boundary
+ * of 32 slots, because allocating slots dynamically caused memory
+ * problems in the client when first this module was first developed.
+ * Some how the heap was being corrupted and we couldn't find out where.
+ * Subsequent attempts to allocate dynamic memory caused no problem.
+ *
+ * In this implementation, session objects are only visible to the session
+ * that created or generated them.
+ */
+
+#include "fpkmem.h"
+#include "seccomon.h"
+#include "fpkcs11.h"
+#include "fpkcs11i.h"
+#include "cryptint.h"
+#include "pk11func.h"
+#include "fortsock.h"
+#include "fmutex.h"
+#ifdef notdef
+#include <ctype.h>
+#include <stdio.h>
+#endif
+#ifdef XP_MAC
+#ifndef __POWERPC__
+#include <A4Stuff.h>
+#endif
+/* This is not a 4.0 project, so I can't depend on
+ * 4.0 defines, so instead I depend on CodeWarrior
+ * defines. I define XP_MAC in fpkmem.h
+ */
+#if __POWERPC__
+#elif __CFM68K__
+#else
+/* These include are taken fromn npmac.cpp which are used
+ * by the plugin group to properly set-up a plug-in for
+ * dynamic loading on 68K.
+ */
+
+#include <Quickdraw.h>
+
+/*
+** The Mixed Mode procInfos defined in npupp.h assume Think C-
+** style calling conventions. These conventions are used by
+** Metrowerks with the exception of pointer return types, which
+** in Metrowerks 68K are returned in A0, instead of the standard
+** D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers,
+** Mixed Mode will return the values to a 68K plugin in D0, but
+** a 68K plugin compiled by Metrowerks will expect the result in
+** A0. The following pragma forces Metrowerks to use D0 instead.
+*/
+#ifdef __MWERKS__
+#ifndef powerc
+#pragma pointers_in_D0
+#endif
+#endif
+
+#ifdef __MWERKS__
+#ifndef powerc
+#pragma pointers_in_A0
+#endif
+#endif
+
+/* The following fix for static initializers fixes a previous
+** incompatibility with some parts of PowerPlant.
+*/
+#ifdef __MWERKS__
+#ifdef __cplusplus
+ extern "C" {
+#endif
+#ifndef powerc
+ extern void __InitCode__(void);
+#else
+ extern void __sinit(void);
+#endif
+ extern void __destroy_global_chain(void);
+#ifdef __cplusplus
+ }
+#endif /* __cplusplus */
+#endif /* __MWERKS__ */
+
+#endif
+#endif
+
+
+typedef struct {
+ unsigned char *data;
+ int len;
+} CertItem;
+
+
+/*
+ * ******************** Static data *******************************
+ */
+
+/* The next three strings must be exactly 32 characters long */
+static char *manufacturerID = "Netscape Communications Corp ";
+static char *libraryDescription = "Communicator Fortezza Crypto Svc";
+
+typedef enum {DSA_KEY, KEA_KEY, V1_KEY, INVALID_KEY } PrivKeyType;
+
+static PK11Slot fort11_slot[NUM_SLOTS];
+static FortezzaSocket fortezzaSockets[NUM_SLOTS];
+static PRBool init = PR_FALSE;
+static CK_ULONG kNumSockets = 0;
+
+#define __PASTE(x,y) x##y
+
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef CK_NEED_ARG_LIST
+#undef _CK_RV
+
+#define fort11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
+#define fort11_SlotFromSession pk11_SlotFromSession
+#define fort11_isToken pk11_isToken
+
+static CK_FUNCTION_LIST fort11_funcList = {
+ { 2, 1 },
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef CK_NEED_ARG_LIST
+#undef _CK_RV
+
+#define CK_EXTERN
+#define CK_FUNC(name) name,
+#define _CK_RV
+
+#include "fpkcs11f.h"
+
+};
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef _CK_RV
+
+
+#undef __PASTE
+#undef pk11_SlotFromSessionHandle
+#undef pk11_SlotFromID
+
+#define MAJOR_VERSION_MASK 0xFF00
+#define MINOR_VERSION_MASK 0x00FF
+
+/* Mechanisms */
+struct mechanismList {
+ CK_MECHANISM_TYPE type;
+ CK_MECHANISM_INFO domestic;
+ PRBool privkey;
+};
+
+static struct mechanismList mechanisms[] = {
+ {CKM_DSA, {512,1024,CKF_SIGN}, PR_TRUE},
+ {CKM_SKIPJACK_KEY_GEN, {92, 92, CKF_GENERATE}, PR_TRUE},
+ {CKM_SKIPJACK_CBC64, {92, 92, CKF_ENCRYPT | CKF_DECRYPT}, PR_TRUE},
+ {CKM_SKIPJACK_WRAP, {92, 92, CKF_WRAP}, PR_TRUE},
+ {CKM_KEA_KEY_DERIVE, {128, 128, CKF_DERIVE}, PR_TRUE},
+};
+static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
+
+/*************Static function prototypes********************************/
+static PRBool fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type);
+static void fort11_FreeAttribute(PK11Attribute *attribute);
+static void fort11_DestroyAttribute(PK11Attribute *attribute);
+static PK11Object* fort11_NewObject(PK11Slot *slot);
+static PK11FreeStatus fort11_FreeObject(PK11Object *object);
+static CK_RV fort11_AddAttributeType(PK11Object *object,
+ CK_ATTRIBUTE_TYPE type,
+ void *valPtr,
+ CK_ULONG length);
+static void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object);
+static PK11Attribute* fort11_FindAttribute(PK11Object *object,
+ CK_ATTRIBUTE_TYPE type);
+static PK11Attribute* fort11_NewAttribute(CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR value, CK_ULONG len);
+static void fort11_DeleteAttributeType(PK11Object *object,
+ CK_ATTRIBUTE_TYPE type);
+static void fort11_AddAttribute(PK11Object *object,
+ PK11Attribute *attribute);
+static void fort11_AddObject(PK11Session *session,
+ PK11Object *object);
+static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
+ PK11Session *session);
+static void fort11_DeleteObject(PK11Session *session,PK11Object *object);
+static CK_RV fort11_DestroyObject(PK11Object *object);
+void fort11_FreeSession(PK11Session *session);
+
+#define FIRST_SLOT_SESS_ID 0x00000100L
+#define ADD_NEXT_SESS_ID 0x00000100L
+#define SLOT_MASK 0x000000FFL
+
+#define FAILED CKR_FUNCTION_FAILED
+
+static void
+fort11_FreeFortezzaKey (void *inFortezzaKey) {
+ RemoveKey ((FortezzaKey*) inFortezzaKey);
+}
+
+static void
+fort11_DestroySlotObjects (PK11Slot *slot, PK11Session *session) {
+ PK11Object *currObject, *nextObject, *oldObject;
+ int i;
+
+ for (i=0; i<HASH_SIZE; i++) {
+ currObject = slot->tokObjects[i];
+ slot->tokObjects[i] = NULL;
+ do {
+ FMUTEX_Lock(slot->sessionLock);
+
+ if (currObject) {
+ nextObject = currObject->next;
+ FMUTEX_Lock(currObject->refLock);
+ currObject->refCount++;
+ FMUTEX_Unlock(currObject->refLock);
+ fort11_DeleteObject(session, currObject);
+ }
+ FMUTEX_Unlock(slot->sessionLock);
+ if (currObject) {
+ oldObject = currObject;
+ currObject = nextObject;
+ fort11_FreeObject(oldObject);
+ }
+ } while (currObject != NULL);
+ }
+}
+
+static void
+fort11_TokenRemoved(PK11Slot *slot, PK11Session *session) {
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+
+ LogoutFromSocket (socket);
+ slot->isLoggedIn = PR_FALSE;
+ if (session && session->notify) {
+ /*If no session pointer exists, lots of leaked memory*/
+ session->notify (session->handle, CKN_SURRENDER,
+ session->appData);
+ fort11_FreeSession(session); /* Release the reference held
+ * by the slot with the session
+ */
+ }
+
+ fort11_DestroySlotObjects(slot, session);
+ fort11_FreeSession(session); /* Release the reference held
+ * by the slot with the session
+ */
+
+ /* All keys will have been freed at this point so we can
+ * NULL out this pointer
+ */
+ socket->keys = NULL;
+
+}
+
+PRBool
+fort11_FortezzaIsUserCert(unsigned char * label) {
+
+ if ( (!PORT_Memcmp(label, "KEAK", 4)) || /* v3 user certs */
+ (!PORT_Memcmp(label, "DSA1", 4)) ||
+ (!PORT_Memcmp(label, "DSAI", 4)) ||
+ (!PORT_Memcmp(label, "DSAO", 4)) ||
+ (!PORT_Memcmp(label, "INKS", 4)) || /* v1 user certs */
+ (!PORT_Memcmp(label, "INKX", 4)) ||
+ (!PORT_Memcmp(label, "ONKS", 4)) ||
+ (!PORT_Memcmp(label, "ONKX", 4)) ||
+ (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 user certs */
+ (!PORT_Memcmp(label, "3OXS", 4)) ||
+ (!PORT_Memcmp(label, "3IKX", 4)) ) {
+
+ return PR_TRUE;
+
+ } else { return PR_FALSE; }
+
+}
+
+static PRBool
+fort11_FortezzaIsACert(unsigned char * label) {
+ if (label == NULL) return PR_FALSE;
+
+ if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */
+ (!PORT_Memcmp(label, "DSAI", 4)) ||
+ (!PORT_Memcmp(label, "DSAO", 4)) ||
+ (!PORT_Memcmp(label, "DSAX", 4)) ||
+ (!PORT_Memcmp(label, "KEAK", 4)) ||
+ (!PORT_Memcmp(label, "KEAX", 4)) ||
+ (!PORT_Memcmp(label, "CAX1", 4)) ||
+ (!PORT_Memcmp(label, "PCA1", 4)) ||
+ (!PORT_Memcmp(label, "PAA1", 4)) ||
+ (!PORT_Memcmp(label, "ICA1", 4)) ||
+
+ (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */
+ (!PORT_Memcmp(label, "3OXS", 4)) ||
+ (!PORT_Memcmp(label, "3CAX", 4)) ||
+ (!PORT_Memcmp(label, "3IKX", 4)) ||
+ (!PORT_Memcmp(label, "3PCA", 4)) ||
+ (!PORT_Memcmp(label, "3PAA", 4)) ||
+ (!PORT_Memcmp(label, "3ICA", 4)) ||
+
+ (!PORT_Memcmp(label, "INKS", 4)) || /* v1 certs */
+ (!PORT_Memcmp(label, "INKX", 4)) ||
+ (!PORT_Memcmp(label, "ONKS", 4)) ||
+ (!PORT_Memcmp(label, "ONKX", 4)) ||
+ (!PORT_Memcmp(label, "RRXX", 4)) ||
+ (!PORT_Memcmp(label, "RTXX", 4)) ||
+ (!PORT_Memcmp(label, "LAXX", 4)) ) {
+
+ return PR_TRUE;
+
+ }
+
+ return PR_FALSE;
+}
+
+static
+int fort11_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);
+}
+
+unsigned char *fort11_data_start(unsigned char *buf, int length,
+ int *data_length, PRBool includeTag) {
+ 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;
+ }
+ if (includeTag) *data_length += used_length;
+
+ return (buf + (includeTag ? 0 : used_length));
+}
+
+int
+fort11_GetCertFields(unsigned char *cert,int cert_length,CertItem *issuer,
+ CertItem *serial,CertItem *subject)
+{
+ unsigned char *buf;
+ int buf_length;
+ unsigned char *date;
+ int datelen;
+
+ /* get past the signature wrap */
+ buf = fort11_data_start(cert,cert_length,&buf_length,PR_FALSE);
+ if (buf == NULL) return FAILED;
+ /* get into the raw cert data */
+ buf = fort11_data_start(buf,buf_length,&buf_length,PR_FALSE);
+ if (buf == NULL) return FAILED;
+ /* skip past any optional version number */
+ if ((buf[0] & 0xa0) == 0xa0) {
+ date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
+ if (date == NULL) return FAILED;
+ buf_length -= (date-buf) + datelen;
+ buf = date + datelen;
+ }
+ /* serial number */
+ serial->data = fort11_data_start(buf,buf_length,&serial->len,PR_FALSE);
+ if (serial->data == NULL) return FAILED;
+ buf_length -= (serial->data-buf) + serial->len;
+ buf = serial->data + serial->len;
+ /* skip the OID */
+ date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
+ if (date == NULL) return FAILED;
+ buf_length -= (date-buf) + datelen;
+ buf = date + datelen;
+ /* issuer */
+ issuer->data = fort11_data_start(buf,buf_length,&issuer->len,PR_TRUE);
+ if (issuer->data == NULL) return FAILED;
+ buf_length -= (issuer->data-buf) + issuer->len;
+ buf = issuer->data + issuer->len;
+ /* skip the date */
+ date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
+ if (date == NULL) return FAILED;
+ buf_length -= (date-buf) + datelen;
+ buf = date + datelen;
+ /*subject */
+ subject->data=fort11_data_start(buf,buf_length,&subject->len,PR_TRUE);
+ if (subject->data == NULL) return FAILED;
+ buf_length -= (subject->data-buf) + subject->len;
+ buf = subject->data +subject->len;
+ /*subject */
+ return CKR_OK;
+}
+
+/* quick tohex function to get rid of scanf */
+static
+int fort11_tohex(char *s) {
+ int val = 0;
+
+ for(;*s;s++) {
+ if ((*s >= '0') && (*s <= '9')) {
+ val = (val << 4) + (*s - '0');
+ continue;
+ } else if ((*s >= 'a') && (*s <= 'f')) {
+ val = (val << 4) + (*s - 'a') + 10;
+ continue;
+ } else if ((*s >= 'A') && (*s <= 'F')) {
+ val = (val << 4) + (*s - 'A') + 10;
+ continue;
+ }
+ break;
+ }
+ return val;
+}
+
+/* only should be called for V3 KEA cert labels. */
+
+static int
+fort11_GetSibling(CI_CERT_STR label) {
+
+ int value = 0;
+ char s[3];
+
+ label +=4;
+
+ strcpy(s,"00");
+ memcpy(s, label, 2);
+ value = fort11_tohex(s);
+
+ /* sibling of 255 means no sibling */
+ if (value == 255) {
+ value = -1;
+ }
+
+ return value;
+}
+
+
+static PrivKeyType
+fort11_GetKeyType(CI_CERT_STR label) {
+ if (label == NULL) return INVALID_KEY;
+
+ if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */
+ (!PORT_Memcmp(label, "DSAI", 4)) ||
+ (!PORT_Memcmp(label, "DSAO", 4)) ||
+ (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */
+ (!PORT_Memcmp(label, "3OXS", 4)) ) {
+
+ return DSA_KEY;
+ }
+
+
+ if ( (!PORT_Memcmp(label, "KEAK", 4)) ||
+ (!PORT_Memcmp(label, "3IKX", 4)) ) {
+ return KEA_KEY;
+ }
+
+ if ( (!PORT_Memcmp(label, "INKS", 4)) || /* V1 Certs*/
+ (!PORT_Memcmp(label, "INKX", 4)) ||
+ (!PORT_Memcmp(label, "ONKS", 4)) ||
+ (!PORT_Memcmp(label, "ONKX", 4)) ||
+ (!PORT_Memcmp(label, "RRXX", 4)) ||
+ (!PORT_Memcmp(label, "RTXX", 4)) ||
+ (!PORT_Memcmp(label, "LAXX", 4)) ) {
+
+ return V1_KEY;
+ }
+
+ return INVALID_KEY;
+}
+
+static CK_RV
+fort11_ConvertToDSAKey(PK11Object *privateKey, PK11Slot *slot) {
+ CK_KEY_TYPE key_type = CKK_DSA;
+ CK_BBOOL cktrue = TRUE;
+ CK_BBOOL ckfalse = FALSE;
+ CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
+ CK_CHAR label[] = "A DSA Private Key";
+
+
+ /* Fill in the common Default values */
+ if (fort11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_CLASS, &privClass,
+ sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &key_type,
+ sizeof(CK_KEY_TYPE)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType (privateKey, CKA_TOKEN, &cktrue,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType (privateKey, CKA_LABEL, label,
+ PORT_Strlen((char*)label)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_SENSITIVE, &cktrue,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_SIGN, &cktrue,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &cktrue,
+ sizeof(cktrue)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_DECRYPT, &ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_SIGN_RECOVER, &ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_UNWRAP, &ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_EXTRACTABLE, &ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_ALWAYS_SENSITIVE, &cktrue,
+ sizeof(cktrue)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_NEVER_EXTRACTABLE, &cktrue,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_PRIME, NULL, 0) != CKR_OK){
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_SUBPRIME, NULL, 0) != CKR_OK){
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_BASE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_VALUE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &cktrue,
+ sizeof(cktrue)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_MODIFIABLE,&ckfalse,
+ sizeof(ckfalse)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ FMUTEX_Lock(slot->objectLock);
+ privateKey->handle = slot->tokenIDCount++;
+ privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+ privateKey->objclass = privClass;
+ privateKey->slot = slot;
+ privateKey->inDB = PR_TRUE;
+
+
+ return CKR_OK;
+}
+
+static int
+fort11_LoadRootPAAKey(PK11Slot *slot, PK11Session *session) {
+ CK_OBJECT_CLASS theClass = CKO_SECRET_KEY;
+ int id = 0;
+ CK_BBOOL True = TRUE;
+ CK_BBOOL False = FALSE;
+ CK_CHAR label[] = "Trusted Root PAA Key";
+ PK11Object *rootKey;
+ FortezzaKey *newKey;
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+
+ /*Don't know the key type. Does is matter?*/
+
+ rootKey = fort11_NewObject(slot);
+
+ if (rootKey == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_CLASS, &theClass,
+ sizeof(theClass)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_TOKEN, &True,
+ sizeof(True)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_LABEL, label,
+ sizeof(label)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_PRIVATE, &True,
+ sizeof (True)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey,CKA_MODIFIABLE, &False,
+ sizeof(False)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_ID, &id,
+ sizeof(int)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_DERIVE, &True,
+ sizeof(True)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_AddAttributeType(rootKey, CKA_SENSITIVE, &True,
+ sizeof(True)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ FMUTEX_Lock(slot->objectLock);
+ rootKey->handle = slot->tokenIDCount++;
+ rootKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+
+ rootKey->objclass = theClass;
+ rootKey->slot = slot;
+ rootKey->inDB = PR_TRUE;
+
+ newKey = NewFortezzaKey(socket, Ks, NULL, 0);
+ if (newKey == NULL) {
+ fort11_FreeObject(rootKey);
+ return CKR_HOST_MEMORY;
+ }
+
+ rootKey->objectInfo = (void*)newKey;
+ rootKey->infoFree = fort11_FreeFortezzaKey;
+ fort11_AddObject(session, rootKey);
+
+ return CKR_OK;
+}
+
+static CK_RV
+fort11_ConvertToKEAKey (PK11Object *privateKey, PK11Slot *slot) {
+ CK_OBJECT_CLASS theClass = CKO_PRIVATE_KEY;
+ CK_KEY_TYPE keyType = CKK_KEA;
+ CK_CHAR label[] = "A KEA private key Object";
+ CK_BBOOL True = TRUE;
+ CK_BBOOL False = FALSE;
+
+ if (fort11_AddAttributeType(privateKey, CKA_CLASS, &theClass,
+ sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &keyType,
+ sizeof (CK_KEY_TYPE)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_TOKEN, &True,
+ sizeof(CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType (privateKey, CKA_LABEL, label,
+ PORT_Strlen((char*)label)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType (privateKey, CKA_SENSITIVE,
+ &True, sizeof(CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType (privateKey, CKA_DERIVE,
+ &True, sizeof(CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &True,
+ sizeof(True)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_START_DATE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_END_DATE, NULL, 0) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &False,
+ sizeof(False)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ FMUTEX_Lock(slot->objectLock);
+ privateKey->handle = slot->tokenIDCount++;
+ privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+ privateKey->objclass = theClass;
+ privateKey->slot = slot;
+ privateKey->inDB = PR_TRUE;
+
+ return CKR_OK;
+}
+
+static CK_RV
+fort11_ConvertToV1Key (PK11Object* privateKey, PK11Slot *slot) {
+ CK_RV rv;
+ CK_BBOOL True = TRUE;
+
+ rv = fort11_ConvertToDSAKey(privateKey, slot);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+
+ if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &True,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ return CKR_OK;
+}
+
+static CK_RV
+fort11_NewPrivateKey(PK11Object *privKeyObject, PK11Slot *slot,CI_PERSON currPerson) {
+ PrivKeyType keyType = fort11_GetKeyType(currPerson.CertLabel);
+ CK_RV rv;
+
+ switch (keyType) {
+ case DSA_KEY:
+ rv = fort11_ConvertToDSAKey(privKeyObject, slot);
+ break;
+ case KEA_KEY:
+ rv = fort11_ConvertToKEAKey(privKeyObject, slot);
+ break;
+ case V1_KEY:
+ rv = fort11_ConvertToV1Key(privKeyObject, slot);
+ break;
+ default:
+ rv = CKR_GENERAL_ERROR;
+ break;
+ }
+ return rv;
+}
+
+
+PRBool
+fort11_LoadCertObjectForSearch(CI_PERSON currPerson, PK11Slot *slot,
+ PK11Session *session, CI_PERSON *pers_array) {
+ PK11Object *certObject, *privKeyObject;
+ PK11Attribute *attribute, *newAttribute;
+ int ci_rv;
+ CI_CERTIFICATE cert;
+ CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
+ CK_CERTIFICATE_TYPE certType = CKC_X_509;
+ CK_BBOOL cktrue = TRUE;
+ CK_BBOOL ckfalse = FALSE;
+ CertItem issuer, serial, subject;
+ int certSize;
+ char nickname[50];
+ char *cursor;
+ PrivKeyType priv_key;
+ int sibling;
+
+
+ certObject = fort11_NewObject(slot);
+ if (certObject == NULL)
+ return PR_FALSE;
+
+ ci_rv = MACI_GetCertificate (fortezzaSockets[slot->slotID-1].maciSession,
+ currPerson.CertificateIndex, cert);
+ if (ci_rv != CI_OK){
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+
+ ci_rv = fort11_GetCertFields(cert,CI_CERT_SIZE,&issuer,&serial,&subject);
+
+ if (ci_rv != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+
+ if (fort11_AddAttributeType(certObject, CKA_CLASS, &certClass,
+ sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
+ fort11_FreeObject (certObject);
+ return PR_FALSE;
+ }
+ if (fort11_AddAttributeType(certObject, CKA_TOKEN, &cktrue,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ if (fort11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse,
+ sizeof (CK_BBOOL)) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+
+
+ /* check if the label represents a KEA key. if so, the
+ nickname should be made the same as the corresponding DSA
+ sibling cert. */
+
+ priv_key = fort11_GetKeyType(currPerson.CertLabel);
+
+ if (priv_key == KEA_KEY) {
+ sibling = fort11_GetSibling(currPerson.CertLabel);
+
+ /* check for failure of fort11_GetSibling. also check that
+ the sibling is not zero. */
+
+ if (sibling > 0) {
+ /* assign the KEA cert label to be the same as the
+ sibling DSA label */
+
+ sprintf (nickname, "%s", &pers_array[sibling-1].CertLabel[8] );
+ } else {
+ sprintf (nickname, "%s", &currPerson.CertLabel[8]);
+ }
+ } else {
+ sprintf (nickname, "%s", &currPerson.CertLabel[8]);
+ }
+
+ cursor = nickname+PORT_Strlen(nickname)-1;
+ while ((*cursor) == ' ') {
+ cursor--;
+ }
+ cursor[1] = '\0';
+ if (fort11_AddAttributeType(certObject, CKA_LABEL, nickname,
+ PORT_Strlen(nickname)) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+
+
+
+ if (fort11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType,
+ sizeof(CK_CERTIFICATE_TYPE)) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ certSize = fort11_cert_length(cert,CI_CERT_SIZE);
+ if (fort11_AddAttributeType (certObject, CKA_VALUE, cert, certSize)
+ != CI_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ if (fort11_AddAttributeType(certObject, CKA_ISSUER, issuer.data,
+ issuer.len) != CKR_OK) {
+ fort11_FreeObject (certObject);
+ return PR_FALSE;
+ }
+ if (fort11_AddAttributeType(certObject, CKA_SUBJECT, subject.data,
+ subject.len) != CKR_OK) {
+ fort11_FreeObject (certObject);
+ return PR_FALSE;
+ }
+ if (fort11_AddAttributeType(certObject, CKA_SERIAL_NUMBER,
+ serial.data, serial.len) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ /*Change this to a byte array later*/
+ if (fort11_AddAttributeType(certObject, CKA_ID,
+ &currPerson.CertificateIndex,
+ sizeof(int)) != CKR_OK) {
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ certObject->objectInfo = NULL;
+ certObject->infoFree = NULL;
+
+ certObject->objclass = certClass;
+ certObject->slot = slot;
+ certObject->inDB = PR_TRUE;
+
+ FMUTEX_Lock(slot->objectLock);
+
+ certObject->handle = slot->tokenIDCount++;
+ certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
+
+ FMUTEX_Unlock(slot->objectLock);
+
+ if (fort11_FortezzaIsUserCert (currPerson.CertLabel)) {
+ privKeyObject = fort11_NewObject(slot);
+ if (fort11_NewPrivateKey(privKeyObject, slot, currPerson) != CKR_OK) {
+ fort11_FreeObject(privKeyObject);
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ if(fort11_AddAttributeType(privKeyObject,CKA_ID,
+ &currPerson.CertificateIndex,
+ sizeof(int)) != CKR_OK) {
+ fort11_FreeObject(privKeyObject);
+ fort11_FreeObject(certObject);
+ return PR_FALSE;
+ }
+ attribute = fort11_FindAttribute(certObject,CKA_SUBJECT);
+ newAttribute=
+ fort11_NewAttribute(pk11_attr_expand(&attribute->attrib));
+ fort11_FreeAttribute(attribute);
+ if (newAttribute != NULL) {
+ fort11_DeleteAttributeType(privKeyObject,
+ CKA_SUBJECT);
+ fort11_AddAttribute(privKeyObject,
+ newAttribute);
+ }
+ fort11_AddObject (session, privKeyObject);
+ }
+
+
+ fort11_AddObject (session, certObject);
+
+
+ return PR_TRUE;
+}
+
+#define TRUSTED_PAA "00000000Trusted Root PAA"
+
+static int
+fort11_BuildCertObjects(FortezzaSocket *currSocket, PK11Slot *slot,
+ PK11Session *session) {
+
+ int i;
+ CI_PERSON rootPAA;
+
+ PORT_Memcpy (rootPAA.CertLabel, TRUSTED_PAA, 1+PORT_Strlen (TRUSTED_PAA));
+ rootPAA.CertificateIndex = 0;
+
+ if (!fort11_LoadCertObjectForSearch(rootPAA, slot, session,
+ currSocket->personalityList)) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ if (fort11_LoadRootPAAKey(slot, session) != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ for (i=0 ; i < currSocket->numPersonalities; i++) {
+ if (fort11_FortezzaIsACert (currSocket->personalityList[i].CertLabel)){
+ if (!fort11_LoadCertObjectForSearch(currSocket->personalityList[i],
+ slot, session,
+ currSocket->personalityList)){
+ return CKR_GENERAL_ERROR;
+ }
+ }
+ }
+
+ return CKR_OK;
+}
+
+PK11Slot*
+fort11_SlotFromSessionHandle(CK_SESSION_HANDLE inHandle) {
+ CK_SESSION_HANDLE whichSlot = inHandle & SLOT_MASK;
+
+ if (whichSlot >= kNumSockets) return NULL_PTR;
+
+ return &fort11_slot[whichSlot];
+}
+
+PK11Slot*
+fort11_SlotFromID (CK_SLOT_ID inSlotID) {
+ if (inSlotID == 0 || inSlotID > kNumSockets)
+ return NULL;
+
+ return &fort11_slot[inSlotID-1];
+}
+
+CK_ULONG fort11_firstSessionID (int inSlotNum) {
+ return (CK_ULONG)(inSlotNum);
+}
+
+/*
+ * Utility to convert passed in PIN to a CI_PIN
+ */
+void fort11_convertToCIPin (CI_PIN ciPin,CK_CHAR_PTR pPin, CK_ULONG ulLen) {
+ unsigned long i;
+
+ for (i=0; i<ulLen; i++) {
+ ciPin[i] = pPin[i];
+ }
+ ciPin[ulLen] = '\0';
+}
+
+
+/*
+ * return true if object has attribute
+ */
+static PRBool
+fort11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
+ PK11Attribute *attribute;
+
+ FMUTEX_Lock(object->attributeLock);
+ pk11queue_find(attribute,type,object->head,HASH_SIZE);
+ FMUTEX_Unlock(object->attributeLock);
+
+ return (PRBool)(attribute != NULL);
+}
+
+/*
+ * create a new attribute with type, value, and length. Space is allocated
+ * to hold value.
+ */
+static PK11Attribute *
+fort11_NewAttribute(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len) {
+ PK11Attribute *attribute;
+ CK_RV mrv;
+
+ attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
+ if (attribute == NULL) return NULL;
+
+ attribute->attrib.type = type;
+ if (value) {
+ attribute->attrib.pValue = (CK_VOID_PTR)PORT_Alloc(len);
+ if (attribute->attrib.pValue == NULL) {
+ PORT_Free(attribute);
+ return NULL;
+ }
+ PORT_Memcpy(attribute->attrib.pValue,value,len);
+ attribute->attrib.ulValueLen = len;
+ } else {
+ attribute->attrib.pValue = NULL;
+ attribute->attrib.ulValueLen = 0;
+ }
+ attribute->handle = type;
+ attribute->next = attribute->prev = NULL;
+ attribute->refCount = 1;
+ if (FMUTEX_MutexEnabled()) {
+ mrv = FMUTEX_Create (&attribute->refLock);
+ if (mrv != CKR_OK) {
+ if (attribute->attrib.pValue) PORT_Free(attribute->attrib.pValue);
+ PORT_Free(attribute);
+ return NULL;
+ }
+ } else {
+ attribute->refLock = NULL;
+ }
+
+ return attribute;
+}
+
+/*
+ * add an attribute to an object
+ */
+static
+void fort11_AddAttribute(PK11Object *object,PK11Attribute *attribute) {
+ FMUTEX_Lock (object->attributeLock);
+ pk11queue_add(attribute,attribute->handle,object->head,HASH_SIZE);
+ FMUTEX_Unlock(object->attributeLock);
+}
+
+static CK_RV
+fort11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
+ CK_ULONG length) {
+ PK11Attribute *attribute;
+ attribute = fort11_NewAttribute(type,valPtr,length);
+ if (attribute == NULL) { return CKR_HOST_MEMORY; }
+ fort11_AddAttribute(object,attribute);
+ return CKR_OK;
+}
+
+
+
+/* Make sure a given attribute exists. If it doesn't, initialize it to
+ * value and len
+ */
+static CK_RV
+fort11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,
+ unsigned int len) {
+ if ( !fort11_hasAttribute(object, type)) {
+ return fort11_AddAttributeType(object,type,value,len);
+ }
+ return CKR_OK;
+}
+
+/*
+ * look up and attribute structure from a type and Object structure.
+ * The returned attribute is referenced and needs to be freed when
+ * it is no longer needed.
+ */
+static PK11Attribute *
+fort11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
+ PK11Attribute *attribute;
+
+ FMUTEX_Lock(object->attributeLock);
+ pk11queue_find(attribute,type,object->head,HASH_SIZE);
+ if (attribute) {
+ /* atomic increment would be nice here */
+ FMUTEX_Lock(attribute->refLock);
+ attribute->refCount++;
+ FMUTEX_Unlock(attribute->refLock);
+ }
+ FMUTEX_Unlock(object->attributeLock);
+
+ return(attribute);
+}
+
+/*
+ * this is only valid for CK_BBOOL type attributes. Return the state
+ * of that attribute.
+ */
+static PRBool
+fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
+ PK11Attribute *attribute;
+ PRBool tok = PR_FALSE;
+
+ attribute=fort11_FindAttribute(object,type);
+ if (attribute == NULL) { return PR_FALSE; }
+ tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
+ fort11_FreeAttribute(attribute);
+
+ return tok;
+}
+
+/*
+ * add an object to a slot and session queue
+ */
+static
+void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object) {
+ FMUTEX_Lock(slot->objectLock);
+ pk11queue_add(object,object->handle,slot->tokObjects,HASH_SIZE);
+ FMUTEX_Unlock(slot->objectLock);
+}
+
+static
+void fort11_AddObject(PK11Session *session, PK11Object *object) {
+ PK11Slot *slot = fort11_SlotFromSession(session);
+
+ if (!fort11_isToken(object->handle)) {
+ FMUTEX_Lock(session->objectLock);
+ pk11queue_add(&object->sessionList,0,session->objects,0);
+ FMUTEX_Unlock(session->objectLock);
+ }
+ fort11_AddSlotObject(slot,object);
+}
+
+/*
+ * free all the data associated with an object. Object reference count must
+ * be 'zero'.
+ */
+static CK_RV
+fort11_DestroyObject(PK11Object *object) {
+ int i;
+ CK_RV crv = CKR_OK;
+/* PORT_Assert(object->refCount == 0);*/
+
+ if (object->label) PORT_Free(object->label);
+
+ /* clean out the attributes */
+ /* since no one is referencing us, it's safe to walk the chain
+ * without a lock */
+ for (i=0; i < HASH_SIZE; i++) {
+ PK11Attribute *ap,*next;
+ for (ap = object->head[i]; ap != NULL; ap = next) {
+ next = ap->next;
+ /* paranoia */
+ ap->next = ap->prev = NULL;
+ fort11_FreeAttribute(ap);
+ }
+ object->head[i] = NULL;
+ }
+ FMUTEX_Destroy(object->attributeLock);
+ FMUTEX_Destroy(object->refLock);
+ if (object->objectInfo) {
+ (*object->infoFree)(object->objectInfo);
+ }
+ PORT_Free(object);
+ return crv;
+}
+
+
+/*
+ * release a reference to an attribute structure
+ */
+static void
+fort11_FreeAttribute(PK11Attribute *attribute) {
+ PRBool destroy = PR_FALSE;
+
+ FMUTEX_Lock(attribute->refLock);
+ if (attribute->refCount == 1) destroy = PR_TRUE;
+ attribute->refCount--;
+ FMUTEX_Unlock(attribute->refLock);
+
+ if (destroy) fort11_DestroyAttribute(attribute);
+}
+
+
+/*
+ * release a reference to an object handle
+ */
+static PK11FreeStatus
+fort11_FreeObject(PK11Object *object) {
+ PRBool destroy = PR_FALSE;
+ CK_RV crv;
+
+ FMUTEX_Lock(object->refLock);
+ if (object->refCount == 1) destroy = PR_TRUE;
+ object->refCount--;
+ FMUTEX_Unlock(object->refLock);
+
+ if (destroy) {
+ crv = fort11_DestroyObject(object);
+ if (crv != CKR_OK) {
+ return PK11_DestroyFailure;
+ }
+ return PK11_Destroyed;
+ }
+ return PK11_Busy;
+}
+
+static void
+fort11_update_state(PK11Slot *slot,PK11Session *session) {
+ if (slot->isLoggedIn) {
+ if (slot->ssoLoggedIn) {
+ session->info.state = CKS_RW_SO_FUNCTIONS;
+ } else if (session->info.flags & CKF_RW_SESSION) {
+ session->info.state = CKS_RW_USER_FUNCTIONS;
+ } else {
+ session->info.state = CKS_RO_USER_FUNCTIONS;
+ }
+ } else {
+ if (session->info.flags & CKF_RW_SESSION) {
+ session->info.state = CKS_RW_PUBLIC_SESSION;
+ } else {
+ session->info.state = CKS_RO_PUBLIC_SESSION;
+ }
+ }
+}
+
+/* update the state of all the sessions on a slot */
+static void
+fort11_update_all_states(PK11Slot *slot) {
+ int i;
+ PK11Session *session;
+
+ for (i=0; i < SESSION_HASH_SIZE; i++) {
+ FMUTEX_Lock(slot->sessionLock);
+ for (session = slot->head[i]; session; session = session->next) {
+ fort11_update_state(slot,session);
+ }
+ FMUTEX_Unlock(slot->sessionLock);
+ }
+}
+
+
+/*
+ * Create a new object
+ */
+static PK11Object *
+fort11_NewObject(PK11Slot *slot) {
+ PK11Object *object;
+ CK_RV mrv;
+ int i;
+
+ object = (PK11Object*)PORT_Alloc(sizeof(PK11Object));
+ if (object == NULL) return NULL;
+
+ object->handle = 0;
+ object->next = object->prev = NULL;
+ object->sessionList.next = NULL;
+ object->sessionList.prev = NULL;
+ object->sessionList.parent = object;
+ object->inDB = PR_FALSE;
+ object->label = NULL;
+ object->refCount = 1;
+ object->session = NULL;
+ object->slot = slot;
+ object->objclass = 0xffff;
+ if (FMUTEX_MutexEnabled()) {
+ mrv = FMUTEX_Create(&object->refLock);
+ if (mrv != CKR_OK) {
+ PORT_Free(object);
+ return NULL;
+ }
+ mrv = FMUTEX_Create(&object->attributeLock);
+ if (mrv != CKR_OK) {
+ FMUTEX_Destroy(object->refLock);
+ PORT_Free(object);
+ return NULL;
+ }
+ } else {
+ object->attributeLock = NULL;
+ object->refLock = NULL;
+ }
+ for (i=0; i < HASH_SIZE; i++) {
+ object->head[i] = NULL;
+ }
+ object->objectInfo = NULL;
+ object->infoFree = NULL;
+ return object;
+}
+
+/*
+ * look up and object structure from a handle. OBJECT_Handles only make
+ * sense in terms of a given session. make a reference to that object
+ * structure returned.
+ */
+static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
+ PK11Session *session) {
+ PK11Object **head;
+ void *lock;
+ PK11Slot *slot = fort11_SlotFromSession(session);
+ PK11Object *object;
+
+ /*
+ * Token objects are stored in the slot. Session objects are stored
+ * with the session.
+ */
+ head = slot->tokObjects;
+ lock = slot->objectLock;
+
+ FMUTEX_Lock(lock);
+ pk11queue_find(object,handle,head,HASH_SIZE);
+ if (object) {
+ FMUTEX_Lock(object->refLock);
+ object->refCount++;
+ FMUTEX_Unlock(object->refLock);
+ }
+ FMUTEX_Unlock(lock);
+
+ return(object);
+}
+
+/*
+ * add an object to a slot andsession queue
+ */
+static
+void fort11_DeleteObject(PK11Session *session, PK11Object *object) {
+ PK11Slot *slot;
+
+ if (session == NULL)
+ return;
+ slot = fort11_SlotFromSession(session);
+ if (!fort11_isToken(object->handle)) {
+ FMUTEX_Lock(session->objectLock);
+ pk11queue_delete(&object->sessionList,0,session->objects,0);
+ FMUTEX_Unlock(session->objectLock);
+ }
+ FMUTEX_Lock(slot->objectLock);
+ pk11queue_delete(object,object->handle,slot->tokObjects,HASH_SIZE);
+ FMUTEX_Unlock(slot->objectLock);
+ fort11_FreeObject(object);
+}
+
+
+
+/*
+ * ******************** Search Utilities *******************************
+ */
+
+/* add an object to a search list */
+CK_RV
+fort11_AddToList(PK11ObjectListElement **list,PK11Object *object) {
+ PK11ObjectListElement *newelem =
+ (PK11ObjectListElement *)PORT_Alloc(sizeof(PK11ObjectListElement));
+
+ if (newelem == NULL) return CKR_HOST_MEMORY;
+
+ newelem->next = *list;
+ newelem->object = object;
+ FMUTEX_Lock(object->refLock);
+ object->refCount++;
+ FMUTEX_Unlock(object->refLock);
+
+ *list = newelem;
+ return CKR_OK;
+}
+
+
+/*
+ * free a single list element. Return the Next object in the list.
+ */
+PK11ObjectListElement *
+fort11_FreeObjectListElement(PK11ObjectListElement *objectList) {
+ PK11ObjectListElement *ol = objectList->next;
+
+ fort11_FreeObject(objectList->object);
+ PORT_Free(objectList);
+ return ol;
+}
+
+/* free an entire object list */
+void
+fort11_FreeObjectList(PK11ObjectListElement *objectList) {
+ PK11ObjectListElement *ol;
+
+ for (ol= objectList; ol != NULL; ol = fort11_FreeObjectListElement(ol)) {}
+}
+
+/*
+ * free a search structure
+ */
+void
+fort11_FreeSearch(PK11SearchResults *search) {
+ if (search->handles) {
+ PORT_Free(search->handles);
+ }
+ PORT_Free(search);
+}
+
+
+/*
+ * Free up all the memory associated with an attribute. Reference count
+ * must be zero to call this.
+ */
+static void
+fort11_DestroyAttribute(PK11Attribute *attribute) {
+ /*PORT_Assert(attribute->refCount == 0);*/
+ FMUTEX_Destroy(attribute->refLock);
+ if (attribute->attrib.pValue) {
+ /* clear out the data in the attribute value... it may have been
+ * sensitive data */
+ PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
+ PORT_Free(attribute->attrib.pValue);
+ }
+ PORT_Free(attribute);
+}
+
+/*
+ * delete an attribute from an object
+ */
+static void
+fort11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute) {
+ FMUTEX_Lock(object->attributeLock);
+ if (attribute->next || attribute->prev) {
+ pk11queue_delete(attribute,attribute->handle,
+ object->head,HASH_SIZE);
+ }
+ FMUTEX_Unlock(object->attributeLock);
+ fort11_FreeAttribute(attribute);
+}
+
+/*
+ * decode when a particular attribute may be modified
+ * PK11_NEVER: This attribute must be set at object creation time and
+ * can never be modified.
+ * PK11_ONCOPY: This attribute may be modified only when you copy the
+ * object.
+ * PK11_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
+ * FALSE to TRUE.
+ * PK11_ALWAYS: This attribute can always be modified.
+ * Some attributes vary their modification type based on the class of the
+ * object.
+ */
+PK11ModifyType
+fort11_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) {
+ /* if we don't know about it, user user defined, always allow modify */
+ PK11ModifyType mtype = PK11_ALWAYS;
+
+ switch(type) {
+ /* NEVER */
+ case CKA_CLASS:
+ case CKA_CERTIFICATE_TYPE:
+ case CKA_KEY_TYPE:
+ case CKA_MODULUS:
+ case CKA_MODULUS_BITS:
+ case CKA_PUBLIC_EXPONENT:
+ case CKA_PRIVATE_EXPONENT:
+ case CKA_PRIME:
+ case CKA_SUBPRIME:
+ case CKA_BASE:
+ case CKA_PRIME_1:
+ case CKA_PRIME_2:
+ case CKA_EXPONENT_1:
+ case CKA_EXPONENT_2:
+ case CKA_COEFFICIENT:
+ case CKA_VALUE_LEN:
+ mtype = PK11_NEVER;
+ break;
+
+ /* ONCOPY */
+ case CKA_TOKEN:
+ case CKA_PRIVATE:
+ mtype = PK11_ONCOPY;
+ break;
+
+ /* SENSITIVE */
+ case CKA_SENSITIVE:
+ mtype = PK11_SENSITIVE;
+ break;
+
+ /* ALWAYS */
+ case CKA_LABEL:
+ case CKA_APPLICATION:
+ case CKA_ID:
+ case CKA_SERIAL_NUMBER:
+ case CKA_START_DATE:
+ case CKA_END_DATE:
+ case CKA_DERIVE:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_VERIFY:
+ case CKA_SIGN_RECOVER:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ mtype = PK11_ALWAYS;
+ break;
+
+ /* DEPENDS ON CLASS */
+ case CKA_VALUE:
+ mtype = (inClass == CKO_DATA) ? PK11_ALWAYS : PK11_NEVER;
+ break;
+
+ case CKA_SUBJECT:
+ mtype = (inClass == CKO_CERTIFICATE) ? PK11_NEVER : PK11_ALWAYS;
+ break;
+ default:
+ break;
+ }
+ return mtype;
+}
+
+/* decode if a particular attribute is sensitive (cannot be read
+ * back to the user of if the object is set to SENSITIVE) */
+PRBool
+fort11_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) {
+ switch(type) {
+ /* ALWAYS */
+ case CKA_PRIVATE_EXPONENT:
+ case CKA_PRIME_1:
+ case CKA_PRIME_2:
+ case CKA_EXPONENT_1:
+ case CKA_EXPONENT_2:
+ case CKA_COEFFICIENT:
+ return PR_TRUE;
+
+ /* DEPENDS ON CLASS */
+ case CKA_VALUE:
+ /* PRIVATE and SECRET KEYS have SENSITIVE values */
+ return (PRBool)((inClass == CKO_PRIVATE_KEY) ||
+ (inClass == CKO_SECRET_KEY));
+
+ default:
+ break;
+ }
+ return PR_FALSE;
+}
+
+static void
+fort11_DeleteAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
+ PK11Attribute *attribute;
+ attribute = fort11_FindAttribute(object, type);
+ if (attribute == NULL) return ;
+ fort11_DeleteAttribute(object,attribute);
+}
+
+
+/*
+ * create a new nession. NOTE: The session handle is not set, and the
+ * session is not added to the slot's session queue.
+ */
+static PK11Session *
+fort11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
+ CK_VOID_PTR pApplication,
+ CK_FLAGS flags) {
+ PK11Session *session;
+ PK11Slot *slot = &fort11_slot[slotID-1];
+ CK_RV mrv;
+
+ if (slot == NULL) return NULL;
+
+ session = (PK11Session*)PORT_Alloc(sizeof(PK11Session));
+ if (session == NULL) return NULL;
+
+ session->next = session->prev = NULL;
+ session->refCount = 1;
+ session->context = NULL;
+ session->search = NULL;
+ session->objectIDCount = 1;
+ session->fortezzaContext.fortezzaKey = NULL;
+ session->fortezzaContext.fortezzaSocket = NULL;
+
+ if (FMUTEX_MutexEnabled()) {
+ mrv = FMUTEX_Create(&session->refLock);
+ if (mrv != CKR_OK) {
+ PORT_Free(session);
+ return NULL;
+ }
+ mrv = FMUTEX_Create(&session->objectLock);
+ if (mrv != CKR_OK) {
+ FMUTEX_Destroy(session->refLock);
+ PORT_Free(session);
+ return NULL;
+ }
+ } else {
+ session->refLock = NULL;
+ session->objectLock = NULL;
+ }
+
+ session->objects[0] = NULL;
+
+ session->slot = slot;
+ session->notify = notify;
+ session->appData = pApplication;
+ session->info.flags = flags;
+ session->info.slotID = slotID;
+ fort11_update_state(slot,session);
+ return session;
+}
+
+
+/*
+ * look up a session structure from a session handle
+ * generate a reference to it.
+ */
+PK11Session *
+fort11_SessionFromHandle(CK_SESSION_HANDLE handle, PRBool isCloseSession) {
+ PK11Slot *slot = fort11_SlotFromSessionHandle(handle);
+ PK11Session *session;
+
+ if (!isCloseSession &&
+ !SocketStateUnchanged(&fortezzaSockets[slot->slotID-1]))
+ return NULL;
+
+ FMUTEX_Lock(slot->sessionLock);
+ pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE);
+ if (session) session->refCount++;
+ FMUTEX_Unlock(slot->sessionLock);
+
+ return (session);
+}
+
+/* free all the data associated with a session. */
+static void
+fort11_DestroySession(PK11Session *session)
+{
+ PK11ObjectList *op,*next;
+/* PORT_Assert(session->refCount == 0);*/
+
+ /* clean out the attributes */
+ FMUTEX_Lock(session->objectLock);
+ for (op = session->objects[0]; op != NULL; op = next) {
+ next = op->next;
+ /* paranoia */
+ op->next = op->prev = NULL;
+ fort11_DeleteObject(session,op->parent);
+ }
+ FMUTEX_Unlock(session->objectLock);
+
+ FMUTEX_Destroy(session->objectLock);
+ FMUTEX_Destroy(session->refLock);
+
+ if (session->search) {
+ fort11_FreeSearch(session->search);
+ }
+
+ pk11queue_delete(session, session->handle, session->slot->head,
+ SESSION_HASH_SIZE);
+
+ PORT_Free(session);
+}
+
+
+/*
+ * release a reference to a session handle
+ */
+void
+fort11_FreeSession(PK11Session *session) {
+ PRBool destroy = PR_FALSE;
+ PK11Slot *slot = NULL;
+
+ if (!session) return; /*Quick fix to elminate crash*/
+ /*Fix in later version */
+
+ if (FMUTEX_MutexEnabled()) {
+ slot = fort11_SlotFromSession(session);
+ FMUTEX_Lock(slot->sessionLock);
+ }
+ if (session->refCount == 1) destroy = PR_TRUE;
+ session->refCount--;
+ if (FMUTEX_MutexEnabled()) {
+ FMUTEX_Unlock(slot->sessionLock);
+ }
+
+ if (destroy) {
+ fort11_DestroySession(session);
+ }
+}
+
+
+/* return true if the object matches the template */
+PRBool
+fort11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count) {
+ int i;
+
+ for (i=0; i < count; i++) {
+ PK11Attribute *attribute =
+ fort11_FindAttribute(object,theTemplate[i].type);
+ if (attribute == NULL) {
+ return PR_FALSE;
+ }
+ if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
+ if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue,
+ theTemplate[i].ulValueLen) == 0) {
+ fort11_FreeAttribute(attribute);
+ continue;
+ }
+ }
+ fort11_FreeAttribute(attribute);
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+/* search through all the objects in the queue and return the template matches
+ * in the object list.
+ */
+CK_RV
+fort11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
+ void *lock, CK_ATTRIBUTE_PTR theTemplate, int count) {
+ int i;
+ PK11Object *object;
+ CK_RV rv;
+
+ for(i=0; i < HASH_SIZE; i++) {
+ /* We need to hold the lock to copy a consistant version of
+ * the linked list. */
+ FMUTEX_Lock(lock);
+ for (object = head[i]; object != NULL; object= object->next) {
+ if (fort11_objectMatch(object,theTemplate,count)) {
+ rv = fort11_AddToList(objectList,object);
+ if (rv != CKR_OK) {
+ return rv;
+ }
+ }
+ }
+ FMUTEX_Unlock(lock);
+ }
+ return CKR_OK;
+}
+
+static PRBool
+fort11_NotAllFuncsNULL (CK_C_INITIALIZE_ARGS_PTR pArgs) {
+ return (PRBool)(pArgs && pArgs->CreateMutex && pArgs->DestroyMutex &&
+ pArgs->LockMutex && pArgs->UnlockMutex);
+}
+
+static PRBool
+fort11_InArgCheck(CK_C_INITIALIZE_ARGS_PTR pArgs) {
+ PRBool rv;
+ /* The only check for now, is to make sure that all of the
+ * function pointers are either all NULL or all Non-NULL.
+ * We also need to make sure the pReserved field in pArgs is
+ * set to NULL.
+ */
+ if (pArgs == NULL) {
+ return PR_TRUE; /* If the argument is NULL, no
+ * inconsistencies can exist.
+ */
+ }
+
+ if (pArgs->pReserved != NULL) {
+ return PR_FALSE;
+ }
+
+ if (pArgs->CreateMutex != NULL) {
+ rv = (PRBool) (pArgs->DestroyMutex != NULL &&
+ pArgs->LockMutex != NULL &&
+ pArgs->UnlockMutex != NULL);
+ } else { /*pArgs->CreateMutex == NULL*/
+ rv = (PRBool) (pArgs->DestroyMutex == NULL &&
+ pArgs->LockMutex == NULL &&
+ pArgs->UnlockMutex == NULL);
+ }
+ return rv;
+}
+
+
+
+/**********************************************************************
+ *
+ * Start of PKCS 11 functions
+ *
+ **********************************************************************/
+
+
+/**********************************************************************
+ *
+ * In order to get this to work on 68K, we have to do some special tricks,
+ * First trick is that we need to make the module a Code Resource, and
+ * all Code Resources on 68K have to have a main function. So we
+ * define main to be a wrapper for C_GetFunctionList which will be the
+ * first funnction called by any software that uses the PKCS11 module.
+ *
+ * The second trick is that whenever you access a global variable from
+ * the Code Resource, it does funny things to the stack on 68K, so we
+ * need to call some macros that handle the stack for us. First thing
+ * you do is call EnterCodeResource() first thing in a function that
+ * accesses a global, right before you leave that function, you call
+ * ExitCodeResource. This will take care of stack management.
+ *
+ * Third trick is to call __InitCode__() when we first enter the module
+ * so that all of the global variables get initialized properly.
+ *
+ **********************************************************************/
+
+#if defined(XP_MAC) && !defined(__POWERPC__)
+
+#define FORT11_RETURN(exp) {ExitCodeResource(); return (exp);}
+#define FORT11_ENTER() EnterCodeResource();
+
+#else /*XP_MAC*/
+
+#define FORT11_RETURN(exp) return (exp);
+#define FORT11_ENTER()
+
+#endif /*XP_MAC*/
+
+#define CARD_OK(rv) if ((rv) != CI_OK) FORT11_RETURN (CKR_DEVICE_ERROR);
+#define SLOT_OK(slot) if ((slot) > kNumSockets) FORT11_RETURN (CKR_SLOT_ID_INVALID);
+
+#ifdef XP_MAC
+/* This is not a 4.0 project, so I can't depend on
+ * 4.0 defines, so instead I depend on CodeWarrior
+ * defines.
+ */
+#if __POWERPC__
+#elif __CFM68K__
+#else
+/* To get this to work on 68K, we need to have
+ * the symbol main. So we just make it a wrapper for C_GetFunctionList.
+ */
+PR_PUBLIC_API(CK_RV) main(CK_FUNCTION_LIST_PTR *pFunctionList) {
+ FORT11_ENTER()
+ CK_RV rv;
+
+ __InitCode__();
+
+ rv = C_GetFunctionList(pFunctionList);
+ FORT11_RETURN (rv);
+}
+#endif
+
+#endif /*XP_MAC*/
+
+/* Return the function list */
+PR_PUBLIC_API(CK_RV) C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
+ /* No need to do a FORT11_RETURN as this function will never be directly
+ * called in the case where we need to do stack management.
+ * The main function will call this after taking care of stack stuff.
+ */
+ *pFunctionList = &fort11_funcList;
+ return CKR_OK;
+}
+
+
+/* C_Initialize initializes the Cryptoki library. */
+PR_PUBLIC_API(CK_RV) C_Initialize(CK_VOID_PTR pReserved) {
+ FORT11_ENTER()
+ int i,j, tempNumSockets;
+ int rv = 1;
+ CK_C_INITIALIZE_ARGS_PTR pArgs = (CK_C_INITIALIZE_ARGS_PTR)pReserved;
+ CK_RV mrv;
+
+ /* intialize all the slots */
+ if (!init) {
+ init = PR_TRUE;
+
+ /* need to initialize locks before MACI_Initialize is called in
+ * software fortezza. */
+ if (pArgs) {
+ if (!fort11_InArgCheck(pArgs)) {
+ FORT11_RETURN (CKR_ARGUMENTS_BAD);
+ }
+ if (pArgs->flags & CKF_OS_LOCKING_OK){
+ if (!fort11_NotAllFuncsNULL(pArgs)) {
+ FORT11_RETURN (CKR_CANT_LOCK);
+ }
+ }
+ if (fort11_NotAllFuncsNULL(pArgs)) {
+ mrv = FMUTEX_Init(pArgs);
+ if (mrv != CKR_OK) {
+ return CKR_GENERAL_ERROR;
+ }
+ }
+ }
+ rv = MACI_Initialize (&tempNumSockets);
+ kNumSockets = (CK_ULONG)tempNumSockets;
+
+ CARD_OK (rv);
+ for (i=0; i < (int) kNumSockets; i++) {
+ if (FMUTEX_MutexEnabled()) {
+ mrv = FMUTEX_Create(&fort11_slot[i].sessionLock);
+ if (mrv != CKR_OK) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+ mrv = FMUTEX_Create(&fort11_slot[i].objectLock);
+ if (mrv != CKR_OK) {
+ FMUTEX_Destroy(fort11_slot[i].sessionLock);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+ } else {
+ fort11_slot[i].sessionLock = NULL;
+ fort11_slot[i].objectLock = NULL;
+ }
+ for(j=0; j < SESSION_HASH_SIZE; j++) {
+ fort11_slot[i].head[j] = NULL;
+ }
+ for(j=0; j < HASH_SIZE; j++) {
+ fort11_slot[i].tokObjects[j] = NULL;
+ }
+ fort11_slot[i].password = NULL;
+ fort11_slot[i].hasTokens = PR_FALSE;
+ fort11_slot[i].sessionIDCount = fort11_firstSessionID (i);
+ fort11_slot[i].sessionCount = 0;
+ fort11_slot[i].rwSessionCount = 0;
+ fort11_slot[i].tokenIDCount = 1;
+ fort11_slot[i].needLogin = PR_TRUE;
+ fort11_slot[i].isLoggedIn = PR_FALSE;
+ fort11_slot[i].ssoLoggedIn = PR_FALSE;
+ fort11_slot[i].DB_loaded = PR_FALSE;
+ fort11_slot[i].slotID= i+1;
+ InitSocket(&fortezzaSockets[i], i+1);
+ }
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+/*C_Finalize indicates that an application is done with the Cryptoki library.*/
+PR_PUBLIC_API(CK_RV) C_Finalize (CK_VOID_PTR pReserved) {
+ FORT11_ENTER()
+ int i;
+
+ for (i=0; i< (int) kNumSockets; i++) {
+ FreeSocket(&fortezzaSockets[i]);
+ }
+ MACI_Terminate(fortezzaSockets[0].maciSession);
+ init = PR_FALSE;
+ FORT11_RETURN (CKR_OK);
+}
+
+
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+PR_PUBLIC_API(CK_RV) C_GetInfo(CK_INFO_PTR pInfo) {
+ FORT11_ENTER()
+ pInfo->cryptokiVersion = fort11_funcList.version;
+ PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
+ pInfo->libraryVersion.major = 1;
+ pInfo->libraryVersion.minor = 7;
+ PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
+ pInfo->flags = 0;
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_GetSlotList obtains a list of slots in the system. */
+PR_PUBLIC_API(CK_RV) C_GetSlotList(CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList,
+ CK_ULONG_PTR pulCount) {
+ FORT11_ENTER()
+ int i;
+
+ if (pSlotList != NULL) {
+ if (*pulCount >= kNumSockets) {
+ for (i=0; i < (int) kNumSockets; i++) {
+ pSlotList[i] = i+1;
+ }
+ } else {
+ FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
+ }
+ } else {
+ *pulCount = kNumSockets;
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_GetSlotInfo obtains information about a particular slot in the system. */
+PR_PUBLIC_API(CK_RV) C_GetSlotInfo(CK_SLOT_ID slotID,
+ CK_SLOT_INFO_PTR pInfo) {
+ FORT11_ENTER()
+ int rv;
+ CI_CONFIG ciConfig;
+ CI_STATE ciState;
+ HSESSION maciSession;
+ char slotDescription[65];
+ FortezzaSocket *socket;
+
+
+ SLOT_OK(slotID);
+
+ socket = &fortezzaSockets[slotID-1];
+ if (!socket->isOpen) {
+ InitSocket(socket, slotID);
+ }
+ maciSession = socket->maciSession;
+
+ rv = MACI_Select(maciSession, slotID);
+
+ CARD_OK (rv)
+
+ rv = MACI_GetConfiguration (maciSession, &ciConfig);
+
+
+ pInfo->firmwareVersion.major = 0;
+ pInfo->firmwareVersion.minor = 0;
+#ifdef SWFORT
+ PORT_Memcpy (pInfo->manufacturerID,"Netscape Communications Corp ",32);
+ PORT_Memcpy (slotDescription,"Netscape Software Slot # ",32);
+#define _local_BASE 24
+#else
+ PORT_Memcpy (pInfo->manufacturerID,"LITRONIC ",32);
+ PORT_Memcpy (slotDescription,"Litronic MACI Slot # ",32);
+#define _local_BASE 20
+#endif
+ slotDescription[_local_BASE] = (char )((slotID < 10) ? slotID :
+ slotID/10) + '0';
+ if (slotID >= 10) slotDescription[_local_BASE+1] =
+ (char)(slotID % 10) + '0';
+ PORT_Memcpy (&slotDescription[32]," ",32);
+ PORT_Memcpy (pInfo->slotDescription, slotDescription , 64);
+ if (rv == CI_OK) {
+ pInfo->hardwareVersion.major =
+ (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8;
+ pInfo->hardwareVersion.minor =
+ ciConfig.ManufacturerVersion & MINOR_VERSION_MASK;
+ pInfo->flags = CKF_TOKEN_PRESENT;
+ } else {
+ pInfo->hardwareVersion.major = 0;
+ pInfo->hardwareVersion.minor = 0;
+ pInfo->flags = 0;
+ }
+#ifdef SWFORT
+ /* do we need to make it a removable device as well?? */
+ pInfo->flags |= CKF_REMOVABLE_DEVICE;
+#else
+ pInfo->flags |= (CKF_REMOVABLE_DEVICE | CKF_HW_SLOT);
+#endif
+
+ rv = MACI_GetState(maciSession, &ciState);
+
+ if (rv == CI_OK) {
+ switch (ciState) {
+ case CI_ZEROIZE:
+ case CI_INTERNAL_FAILURE:
+ pInfo->flags &= (~CKF_TOKEN_PRESENT);
+ default:
+ break;
+ }
+ } else {
+ pInfo->flags &= (~CKF_TOKEN_PRESENT);
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+#define CKF_THREAD_SAFE 0x8000
+
+/* C_GetTokenInfo obtains information about a particular token
+ in the system. */
+PR_PUBLIC_API(CK_RV) C_GetTokenInfo(CK_SLOT_ID slotID,
+ CK_TOKEN_INFO_PTR pInfo) {
+ FORT11_ENTER()
+ CI_STATUS cardStatus;
+ CI_CONFIG ciConfig;
+ PK11Slot *slot;
+ int rv, i;
+ char tmp[33];
+ FortezzaSocket *socket;
+
+ SLOT_OK (slotID);
+
+ slot = &fort11_slot[slotID-1];
+
+ socket = &fortezzaSockets[slotID-1];
+ if (!socket->isOpen) {
+ InitSocket(socket, slotID);
+ }
+
+ rv = MACI_Select (socket->maciSession, slotID);
+ rv = MACI_GetStatus (socket->maciSession, &cardStatus);
+ if (rv != CI_OK) {
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+#ifdef SWFORT
+ sprintf (tmp, "Software FORTEZZA Slot #%d", slotID);
+#else
+ sprintf (tmp, "FORTEZZA Slot #%d", slotID);
+#endif
+
+ PORT_Memcpy (pInfo->label, tmp, PORT_Strlen(tmp)+1);
+
+ for (i=0; i<8; i++) {
+ int serNum;
+
+ serNum = (int)cardStatus.SerialNumber[i];
+ sprintf ((char*)&pInfo->serialNumber[2*i], "%.2x", serNum);
+ }
+
+ rv = MACI_GetTime (fortezzaSockets[slotID-1].maciSession, pInfo->utcTime);
+ if (rv == CI_OK) {
+ pInfo->flags = CKF_CLOCK_ON_TOKEN;
+ } else {
+ switch (rv) {
+ case CI_LIB_NOT_INIT:
+ case CI_INV_POINTER:
+ case CI_NO_CARD:
+ case CI_NO_SOCKET:
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ default:
+ pInfo->flags = 0;
+ break;
+ }
+ }
+
+ rv = MACI_GetConfiguration (fortezzaSockets[slotID-1].maciSession,
+ &ciConfig);
+
+ if (rv == CI_OK) {
+ PORT_Memcpy(pInfo->manufacturerID,ciConfig.ManufacturerName,
+ PORT_Strlen(ciConfig.ManufacturerName));
+ for (i=PORT_Strlen(ciConfig.ManufacturerName); i<32; i++) {
+ pInfo->manufacturerID[i] = ' ';
+ }
+ PORT_Memcpy(pInfo->model,ciConfig.ProcessorType,16);
+ }
+ pInfo->ulMaxPinLen = CI_PIN_SIZE;
+ pInfo->ulMinPinLen = 0;
+ pInfo->ulTotalPublicMemory = 0;
+ pInfo->ulFreePublicMemory = 0;
+ pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED| CKF_USER_PIN_INITIALIZED |
+ CKF_THREAD_SAFE | CKF_WRITE_PROTECTED;
+
+ pInfo->ulMaxSessionCount = 0;
+ pInfo->ulSessionCount = slot->sessionCount;
+ pInfo->ulMaxRwSessionCount = 0;
+ pInfo->ulRwSessionCount = slot->rwSessionCount;
+
+ if (rv == CI_OK) {
+ pInfo->firmwareVersion.major =
+ (ciConfig.ManufacturerSWVer & MAJOR_VERSION_MASK) >> 8;
+ pInfo->firmwareVersion.minor =
+ ciConfig.ManufacturerSWVer & MINOR_VERSION_MASK;
+ pInfo->hardwareVersion.major =
+ (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8;
+ pInfo->hardwareVersion.minor =
+ ciConfig.ManufacturerVersion & MINOR_VERSION_MASK;
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+
+
+/* C_GetMechanismList obtains a list of mechanism types supported by a
+ token. */
+PR_PUBLIC_API(CK_RV) C_GetMechanismList(CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE_PTR pMechanismList,
+ CK_ULONG_PTR pulCount) {
+ FORT11_ENTER()
+ CK_RV rv = CKR_OK;
+ int i;
+
+ SLOT_OK (slotID);
+
+ if (pMechanismList == NULL) {
+ *pulCount = mechanismCount;
+ } else {
+ if (*pulCount >= mechanismCount) {
+ *pulCount = mechanismCount;
+ for (i=0; i< (int)mechanismCount; i++) {
+ pMechanismList[i] = mechanisms[i].type;
+ }
+ } else {
+ rv = CKR_BUFFER_TOO_SMALL;
+ }
+ }
+ FORT11_RETURN (rv);
+}
+
+
+/* C_GetMechanismInfo obtains information about a particular mechanism
+ * possibly supported by a token. */
+PR_PUBLIC_API(CK_RV) C_GetMechanismInfo(CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR pInfo) {
+ int i;
+ FORT11_ENTER()
+ SLOT_OK (slotID);
+
+ for (i=0; i< (int)mechanismCount; i++) {
+ if (type == mechanisms[i].type) {
+ PORT_Memcpy (pInfo, &mechanisms[i].domestic, sizeof (CK_MECHANISM_INFO));
+ FORT11_RETURN (CKR_OK);
+ }
+ }
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+}
+
+
+/* C_InitToken initializes a token. */
+PR_PUBLIC_API(CK_RV) C_InitToken(CK_SLOT_ID slotID,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen,
+ CK_CHAR_PTR pLabel) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+PR_PUBLIC_API(CK_RV) C_InitPIN(CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_SetPIN modifies the PIN of user that is currently logged in. */
+/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
+PR_PUBLIC_API(CK_RV) C_SetPIN(CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pOldPin,
+ CK_ULONG ulOldLen,
+ CK_CHAR_PTR pNewPin,
+ CK_ULONG ulNewLen) {
+ FORT11_ENTER()
+#ifndef SWFORT
+ CI_PIN ciOldPin, ciNewPin;
+#endif
+ PK11Session *session;
+ PK11Slot *slot;
+ int rv;
+
+ session = fort11_SessionFromHandle (hSession, PR_FALSE);
+
+ slot = fort11_SlotFromSession (session);
+ SLOT_OK(slot->slotID)
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ rv = MACI_Select (fortezzaSockets[slot->slotID-1].maciSession, slot->slotID);
+ CARD_OK (rv)
+
+ if (slot->needLogin && session->info.state != CKS_RW_USER_FUNCTIONS) {
+ fort11_FreeSession (session);
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+ }
+
+ fort11_FreeSession (session);
+
+ if (ulNewLen > CI_PIN_SIZE || ulOldLen > CI_PIN_SIZE)
+ FORT11_RETURN (CKR_PIN_LEN_RANGE);
+
+#ifndef SWFORT
+ fort11_convertToCIPin (ciOldPin,pOldPin, ulOldLen);
+ fort11_convertToCIPin (ciNewPin,pNewPin, ulNewLen);
+
+ rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession,
+ CI_USER_PIN, ciOldPin, ciNewPin);
+#else
+ rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession,
+ CI_USER_PIN, pOldPin, pNewPin);
+#endif
+
+ if (rv != CI_OK) {
+ switch (rv) {
+ case CI_FAIL:
+ FORT11_RETURN (CKR_PIN_INCORRECT);
+ default:
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_OpenSession opens a session between an application and a token. */
+PR_PUBLIC_API(CK_RV) C_OpenSession(CK_SLOT_ID slotID,
+ CK_FLAGS flags,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_SESSION_HANDLE_PTR phSession) {
+ FORT11_ENTER()
+ PK11Slot *slot;
+ CK_SESSION_HANDLE sessionID;
+ PK11Session *session;
+ FortezzaSocket *socket;
+
+ SLOT_OK (slotID)
+ slot = &fort11_slot[slotID-1];
+ socket = &fortezzaSockets[slotID-1];
+
+ if (!socket->isOpen) {
+ if (InitSocket(socket, slotID) != SOCKET_SUCCESS) {
+ FORT11_RETURN (CKR_TOKEN_NOT_PRESENT);
+ }
+ }
+
+ session = fort11_NewSession (slotID, Notify, pApplication,
+ flags | CKF_SERIAL_SESSION);
+
+ if (session == NULL) FORT11_RETURN (CKR_HOST_MEMORY);
+
+ FMUTEX_Lock(slot->sessionLock);
+
+ slot->sessionIDCount += ADD_NEXT_SESS_ID;
+ sessionID = slot->sessionIDCount;
+ fort11_update_state (slot, session);
+ pk11queue_add (session, sessionID, slot->head, SESSION_HASH_SIZE);
+ slot->sessionCount++;
+ if (session->info.flags & CKF_RW_SESSION) {
+ slot->rwSessionCount++;
+ }
+ session->handle = sessionID;
+ session->info.ulDeviceError = 0;
+
+ FMUTEX_Unlock(slot->sessionLock);
+
+ *phSession = sessionID;
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_CloseSession closes a session between an application and a token. */
+PR_PUBLIC_API(CK_RV) C_CloseSession(CK_SESSION_HANDLE hSession) {
+ FORT11_ENTER()
+ PK11Slot *slot;
+ PK11Session *session;
+
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ slot = fort11_SlotFromSessionHandle (hSession);
+
+ if (session == NULL) {
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ FMUTEX_Lock(slot->sessionLock);
+ if (session->next || session->prev) {
+ session->refCount--;
+ if (session->info.flags & CKF_RW_SESSION) {
+ slot->rwSessionCount--;
+ }
+ if (slot->sessionCount == 0) {
+ slot->isLoggedIn = PR_FALSE;
+ slot->password = NULL;
+ }
+ }
+
+ FMUTEX_Unlock(slot->sessionLock);
+
+ fort11_FreeSession (session);
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+PR_PUBLIC_API(CK_RV) C_CloseAllSessions (CK_SLOT_ID slotID) {
+ FORT11_ENTER()
+ PK11Slot *slot;
+ PK11Session *session;
+ int i;
+
+
+ slot = fort11_SlotFromID(slotID);
+ if (slot == NULL) FORT11_RETURN (CKR_SLOT_ID_INVALID);
+
+ /* first log out the card */
+ FMUTEX_Lock(slot->sessionLock);
+ slot->isLoggedIn = PR_FALSE;
+ slot->password = NULL;
+ FMUTEX_Unlock(slot->sessionLock);
+
+ /* now close all the current sessions */
+ /* NOTE: If you try to open new sessions before C_CloseAllSessions
+ * completes, some of those new sessions may or may not be closed by
+ * C_CloseAllSessions... but any session running when this code starts
+ * will guarrenteed be close, and no session will be partially closed */
+ for (i=0; i < SESSION_HASH_SIZE; i++) {
+ do {
+ FMUTEX_Lock(slot->sessionLock);
+ session = slot->head[i];
+ /* hand deque */
+ /* this duplicates much of C_close session functionality, but because
+ * we know that we are freeing all the sessions, we and do some
+ * more efficient processing */
+ if (session) {
+ slot->head[i] = session->next;
+ if (session->next) session->next->prev = NULL;
+ session->next = session->prev = NULL;
+ slot->sessionCount--;
+ if (session->info.flags & CKF_RW_SESSION) {
+ slot->rwSessionCount--;
+ }
+ }
+ FMUTEX_Unlock(slot->sessionLock);
+ if (session) fort11_FreeSession(session);
+ } while (session != NULL);
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_GetSessionInfo obtains information about the session. */
+PR_PUBLIC_API(CK_RV) C_GetSessionInfo(CK_SESSION_HANDLE hSession,
+ CK_SESSION_INFO_PTR pInfo) {
+ FORT11_ENTER()
+ PK11Session *session;
+ PK11Slot *slot;
+ CI_STATE cardState;
+ FortezzaSocket *socket;
+ int ciRV;
+
+ session = fort11_SessionFromHandle (hSession, PR_FALSE);
+ slot = fort11_SlotFromSessionHandle(hSession);
+ socket = &fortezzaSockets[slot->slotID-1];
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+ PORT_Memcpy (pInfo, &session->info, sizeof (CK_SESSION_INFO));
+ fort11_FreeSession(session);
+
+ ciRV = MACI_Select(socket->maciSession, slot->slotID);
+ CARD_OK(ciRV)
+
+ ciRV = MACI_GetState(socket->maciSession, &cardState);
+ CARD_OK(ciRV)
+
+ if (socket->isLoggedIn) {
+ switch (cardState) {
+ case CI_POWER_UP:
+ case CI_UNINITIALIZED:
+ case CI_INITIALIZED:
+ case CI_SSO_INITIALIZED:
+ case CI_LAW_INITIALIZED:
+ case CI_USER_INITIALIZED:
+ pInfo->state = CKS_RO_PUBLIC_SESSION;
+ break;
+ case CI_STANDBY:
+ case CI_READY:
+ pInfo->state = CKS_RO_USER_FUNCTIONS;
+ break;
+ default:
+ pInfo->state = CKS_RO_PUBLIC_SESSION;
+ break;
+ }
+ } else {
+ pInfo->state = CKS_RO_PUBLIC_SESSION;
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_Login logs a user into a token. */
+PR_PUBLIC_API(CK_RV) C_Login(CK_SESSION_HANDLE hSession,
+ CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen) {
+ FORT11_ENTER()
+ PK11Slot *slot;
+ PK11Session *session;
+#ifndef SWFORT
+ CI_PIN ciPin;
+#endif
+ int rv, ciUserType;
+
+ slot = fort11_SlotFromSessionHandle (hSession);
+ session = fort11_SessionFromHandle(hSession, PR_FALSE);
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ fort11_FreeSession(session);
+
+ if (slot->isLoggedIn) FORT11_RETURN (CKR_USER_ALREADY_LOGGED_IN);
+ slot->ssoLoggedIn = PR_FALSE;
+
+#ifndef SWFORT
+ if (ulPinLen > CI_PIN_SIZE) FORT11_RETURN (CKR_PIN_LEN_RANGE);
+
+ fort11_convertToCIPin (ciPin, pPin, ulPinLen);
+#endif
+ switch (userType) {
+ case CKU_SO:
+ ciUserType = CI_SSO_PIN;
+ break;
+ case CKU_USER:
+ ciUserType = CI_USER_PIN;
+ break;
+ default:
+ FORT11_RETURN (CKR_USER_TYPE_INVALID);
+ }
+
+#ifndef SWFORT
+ rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, ciPin);
+#else
+ rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, pPin);
+#endif
+
+ switch (rv) {
+ case SOCKET_SUCCESS:
+ break;
+ case CI_FAIL:
+ FORT11_RETURN (CKR_PIN_INCORRECT);
+ default:
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ FMUTEX_Lock(slot->sessionLock);
+ slot->isLoggedIn = PR_TRUE;
+ if (userType == CKU_SO) {
+ slot->ssoLoggedIn = PR_TRUE;
+ }
+ FMUTEX_Unlock(slot->sessionLock);
+
+ fort11_update_all_states(slot);
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_Logout logs a user out from a token. */
+PR_PUBLIC_API(CK_RV) C_Logout(CK_SESSION_HANDLE hSession) {
+ FORT11_ENTER()
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (!slot->isLoggedIn)
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+
+ FMUTEX_Lock(slot->sessionLock);
+
+ slot->isLoggedIn = PR_FALSE;
+ slot->ssoLoggedIn = PR_FALSE;
+ slot->password = NULL;
+ LogoutFromSocket (&fortezzaSockets[slot->slotID-1]);
+
+ FMUTEX_Unlock(slot->sessionLock);
+
+ fort11_update_all_states(slot);
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_CreateObject creates a new object. */
+PR_PUBLIC_API(CK_RV) C_CreateObject(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_CopyObject copies an object, creating a new object for the copy. */
+PR_PUBLIC_API(CK_RV) C_CopyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phNewObject) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_DestroyObject destroys an object. */
+PR_PUBLIC_API(CK_RV) C_DestroyObject(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject) {
+ FORT11_ENTER()
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Session *session;
+ PK11Object *object;
+ PK11FreeStatus status;
+
+ /*
+ * This whole block just makes sure we really can destroy the
+ * requested object.
+ */
+ session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ object = fort11_ObjectFromHandle(hObject,session);
+ if (object == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
+ }
+
+ /* don't destroy a private object if we aren't logged in */
+ if ((!slot->isLoggedIn) && (slot->needLogin) &&
+ (fort11_isTrue(object,CKA_PRIVATE))) {
+ fort11_FreeSession(session);
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+ }
+
+ /* don't destroy a token object if we aren't in a rw session */
+
+ if (((session->info.flags & CKF_RW_SESSION) == 0) &&
+ (fort11_isTrue(object,CKA_TOKEN))) {
+ fort11_FreeSession(session);
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_SESSION_READ_ONLY);
+ }
+
+ /* ACTUALLY WE NEED TO DEAL WITH TOKEN OBJECTS AS WELL */
+ FMUTEX_Lock(session->objectLock);
+ fort11_DeleteObject(session,object);
+ FMUTEX_Unlock(session->objectLock);
+
+ fort11_FreeSession(session);
+
+ /*
+ * get some indication if the object is destroyed. Note: this is not
+ * 100%. Someone may have an object reference outstanding (though that
+ * should not be the case by here. Also now that the object is "half"
+ * destroyed. Our internal representation is destroyed, but it is still
+ * in the data base.
+ */
+ status = fort11_FreeObject(object);
+
+ FORT11_RETURN ((status != PK11_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR);
+}
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+PR_PUBLIC_API(CK_RV) C_GetObjectSize(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ULONG_PTR pulSize) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ *pulSize = 0;
+ return CKR_OK;
+}
+
+
+/* C_GetAttributeValue obtains the value of one or more object attributes. */
+PR_PUBLIC_API(CK_RV) C_GetAttributeValue(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount) {
+ FORT11_ENTER()
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Session *session;
+ PK11Object *object;
+ PK11Attribute *attribute;
+ PRBool sensitive;
+ int i;
+
+ /*
+ * make sure we're allowed
+ */
+ session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ object = fort11_ObjectFromHandle(hObject,session);
+ fort11_FreeSession(session);
+ if (object == NULL) {
+ FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
+ }
+
+ /* don't read a private object if we aren't logged in */
+ if ((!slot->isLoggedIn) && (slot->needLogin) &&
+ (fort11_isTrue(object,CKA_PRIVATE))) {
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+ }
+
+ sensitive = fort11_isTrue(object,CKA_SENSITIVE);
+ for (i=0; i < (int)ulCount; i++) {
+ /* Make sure that this attribute is retrievable */
+ if (sensitive && fort11_isSensitive(pTemplate[i].type,object->objclass)) {
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_ATTRIBUTE_SENSITIVE);
+ }
+ attribute = fort11_FindAttribute(object,pTemplate[i].type);
+ if (attribute == NULL) {
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_ATTRIBUTE_TYPE_INVALID);
+ }
+ if (pTemplate[i].pValue != NULL) {
+ PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue,
+ attribute->attrib.ulValueLen);
+ }
+ pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
+ fort11_FreeAttribute(attribute);
+ }
+
+ fort11_FreeObject(object);
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_SetAttributeValue modifies the value of one or more object attributes */
+PR_PUBLIC_API(CK_RV) C_SetAttributeValue (CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/* C_FindObjectsInit initializes a search for token and session objects
+ * that match a template. */
+PR_PUBLIC_API(CK_RV) C_FindObjectsInit(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount) {
+ FORT11_ENTER()
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Session *session;
+ PK11ObjectListElement *objectList = NULL;
+ PK11ObjectListElement *olp;
+ PK11SearchResults *search, *freeSearch;
+ FortezzaSocket *currSocket;
+ int rv, count, i;
+
+ if (slot == NULL) {
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+
+ if ((!slot->isLoggedIn) && (slot->needLogin))
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+
+ session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+ currSocket = &fortezzaSockets[slot->slotID-1];
+ if (currSocket->personalityList == NULL) {
+ rv = FetchPersonalityList(currSocket);
+ if (rv != SOCKET_SUCCESS) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ rv = fort11_BuildCertObjects(currSocket, slot, session);
+
+ if (rv != CKR_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (rv);
+ }
+
+
+ }
+ rv = fort11_searchObjectList(&objectList, slot->tokObjects,
+ slot->objectLock, pTemplate, ulCount);
+ if (rv != CKR_OK) {
+ fort11_FreeObjectList(objectList);
+ fort11_FreeSession(session);
+ FORT11_RETURN (rv);
+ }
+
+ /*copy list to session*/
+
+ count = 0;
+ for(olp = objectList; olp != NULL; olp = olp->next) {
+ count++;
+ }
+
+ search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
+ if (search != NULL) {
+ search->handles = (CK_OBJECT_HANDLE *)
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
+ if (search->handles != NULL) {
+ for (i=0; i < count; i++) {
+ search->handles[i] = objectList->object->handle;
+ objectList = fort11_FreeObjectListElement(objectList);
+ }
+ } else {
+ PORT_Free(search);
+ search = NULL;
+ }
+ }
+ if (search == NULL) {
+ fort11_FreeObjectList(objectList);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ /* store the search info */
+ search->index = 0;
+ search->size = count;
+ if ((freeSearch = session->search) != NULL) {
+ session->search = NULL;
+ fort11_FreeSearch(freeSearch);
+ }
+ session->search = search;
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_FindObjects continues a search for token and session objects
+ * that match a template, obtaining additional object handles. */
+PR_PUBLIC_API(CK_RV) C_FindObjects(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE_PTR phObject,
+ CK_ULONG ulMaxObjectCount,
+ CK_ULONG_PTR pulObjectCount) {
+ FORT11_ENTER()
+ PK11Session *session;
+ PK11SearchResults *search;
+ PK11Slot *slot;
+ int transfer;
+ unsigned long left;
+
+ *pulObjectCount = 0;
+ session = fort11_SessionFromHandle(hSession,PR_FALSE);
+ slot = fort11_SlotFromSessionHandle(hSession);
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+ if (session->search == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+ search = session->search;
+ left = session->search->size - session->search->index;
+ transfer = (ulMaxObjectCount > left) ? left : ulMaxObjectCount;
+ PORT_Memcpy(phObject,&search->handles[search->index],
+ transfer*sizeof(CK_OBJECT_HANDLE_PTR));
+ search->index += transfer;
+ if (search->index == search->size) {
+ session->search = NULL;
+ fort11_FreeSearch(search);
+ }
+ fort11_FreeSession(session);
+ *pulObjectCount = transfer;
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_FindObjectsFinal finishes a search for token and session objects. */
+PR_PUBLIC_API(CK_RV) C_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
+ FORT11_ENTER()
+ PK11Session *session;
+ PK11SearchResults *search;
+ PK11Slot *slot;
+
+ session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ slot = fort11_SlotFromSessionHandle(hSession);
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+ search = session->search;
+ session->search = NULL;
+ if (search == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+ fort11_FreeSearch(search);
+
+ /* UnloadPersonalityList(&fortezzaSockets[session->slot->slotID-1]); */
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_EncryptInit initializes an encryption operation. */
+PR_PUBLIC_API(CK_RV) C_EncryptInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Object *keyObject;
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ HSESSION hs = socket->maciSession;
+ FortezzaKey *fortezzaKey;
+ CI_IV fortezzaIV;
+ int ciRV, registerIndex;
+
+
+ if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
+ if (session) {
+ fort11_FreeSession(session);
+ }
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ keyObject = fort11_ObjectFromHandle (hKey, session);
+
+ if (keyObject == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ ciRV = MACI_Select (hs, slot->slotID);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_SetMode(hs, CI_ENCRYPT_TYPE, CI_CBC64_MODE);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ /*Load the correct key into a key register*/
+ fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
+ fort11_FreeObject (keyObject);
+ if (fortezzaKey == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ if (fortezzaKey->keyRegister == KeyNotLoaded) {
+ registerIndex = LoadKeyIntoRegister (fortezzaKey);
+ } else {
+ registerIndex = fortezzaKey->keyRegister;
+ }
+
+ if (registerIndex == KeyNotLoaded) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_SetKey (hs,registerIndex);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_GenerateIV(hs, fortezzaIV);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ context = &session->fortezzaContext;
+ InitContext(context, socket, hKey);
+ ciRV = SaveState(context, fortezzaIV, session, fortezzaKey,
+ CI_ENCRYPT_EXT_TYPE, pMechanism->mechanism);
+ if (ciRV != SOCKET_SUCCESS) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ if (pMechanism->pParameter != NULL &&
+ pMechanism->ulParameterLen >= sizeof(CI_IV)) {
+ PORT_Memcpy (pMechanism->pParameter, fortezzaIV, sizeof(CI_IV));
+ }
+
+ InitCryptoOperation(context, Encrypt);
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_Encrypt encrypts single-part data. */
+PR_PUBLIC_API(CK_RV) C_Encrypt (CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG_PTR pulEncryptedDataLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ HSESSION hs;
+ CK_RV rv;
+
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession , PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+ if (GetCryptoOperation(context) != Encrypt) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
+ }
+
+ *pulEncryptedDataLen = ulDataLen;
+ if (pEncryptedData == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ hs = socket->maciSession;
+ FMUTEX_Lock(socket->registersLock);
+ MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
+ rv = EncryptData (context, pData, ulDataLen,
+ pEncryptedData, *pulEncryptedDataLen);
+ MACI_Unlock(hs);
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (rv != SOCKET_SUCCESS) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ EndCryptoOperation(context, Encrypt);
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_EncryptUpdate continues a multiple-part encryption operation. */
+PR_PUBLIC_API(CK_RV) C_EncryptUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ int rv;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+
+ if (GetCryptoOperation(context) != Encrypt) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
+ }
+
+ if (pEncryptedPart == NULL) {
+ *pulEncryptedPartLen = ulPartLen;
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ if (*pulEncryptedPartLen < ulPartLen) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
+ }
+
+ *pulEncryptedPartLen = ulPartLen;
+
+ FMUTEX_Lock(socket->registersLock);
+ MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
+ rv = EncryptData(context,pPart, ulPartLen, pEncryptedPart,
+ *pulEncryptedPartLen);
+ MACI_Unlock(socket->maciSession);
+ FMUTEX_Unlock(socket->registersLock);
+
+ fort11_FreeSession(session);
+ if (rv != SOCKET_SUCCESS) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_EncryptFinal finishes a multiple-part encryption operation. */
+PR_PUBLIC_API(CK_RV) C_EncryptFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastEncryptedPart,
+ CK_ULONG_PTR pulLastEncryptedPartLen){
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaContext *context;
+ int rv;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+
+ rv = EndCryptoOperation(context, Encrypt);
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+/* C_DecryptInit initializes a decryption operation. */
+PR_PUBLIC_API(CK_RV) C_DecryptInit( CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Object *keyObject;
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ HSESSION hs = socket->maciSession;
+ FortezzaKey *fortezzaKey;
+ CI_IV fortezzaIV;
+ int ciRV, registerIndex;
+
+ if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
+ if (session) fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ keyObject = fort11_ObjectFromHandle (hKey, session);
+
+ if (keyObject == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
+ fort11_FreeObject(keyObject);
+
+ if (fortezzaKey == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ ciRV = MACI_Select (hs, slot->slotID);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_SetMode(hs, CI_DECRYPT_TYPE, CI_CBC64_MODE);
+ if (ciRV != CI_OK) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ FMUTEX_Lock(socket->registersLock);
+ if (fortezzaKey->keyRegister == KeyNotLoaded) {
+ registerIndex = LoadKeyIntoRegister(fortezzaKey);
+ } else {
+ registerIndex = fortezzaKey->keyRegister;
+ }
+
+ if (registerIndex == KeyNotLoaded) {
+ FMUTEX_Unlock(socket->registersLock);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ if (pMechanism->pParameter == NULL ||
+ pMechanism->ulParameterLen < sizeof (CI_IV)) {
+ FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
+ }
+
+ PORT_Memcpy (fortezzaIV, pMechanism->pParameter, sizeof(CI_IV));
+
+ ciRV = MACI_SetKey (hs, registerIndex);
+ if (ciRV != CI_OK) {
+ FMUTEX_Unlock(socket->registersLock);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_LoadIV (hs, fortezzaIV);
+ if (ciRV != CI_OK) {
+ FMUTEX_Unlock(socket->registersLock);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ context = &session->fortezzaContext;
+ InitContext(context, socket, hKey);
+ ciRV = SaveState (context, fortezzaIV, session, fortezzaKey,
+ CI_DECRYPT_EXT_TYPE, pMechanism->mechanism);
+
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (ciRV != SOCKET_SUCCESS) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ InitCryptoOperation (context, Decrypt);
+ fort11_FreeSession (session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+PR_PUBLIC_API(CK_RV) C_Decrypt(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ HSESSION hs;
+ CK_RV rv;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+
+ if (GetCryptoOperation(context) != Decrypt) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
+ }
+
+ *pulDataLen = ulEncryptedDataLen;
+ if (pData == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ hs = socket->maciSession;
+ FMUTEX_Lock(socket->registersLock);
+ MACI_Lock(hs, CI_NULL_FLAG);
+ rv = DecryptData (context, pEncryptedData, ulEncryptedDataLen,
+ pData, *pulDataLen);
+ MACI_Unlock(hs);
+ FMUTEX_Unlock(socket->registersLock);
+ if (rv != SOCKET_SUCCESS) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ EndCryptoOperation (context, Decrypt);
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_DecryptUpdate continues a multiple-part decryption operation. */
+PR_PUBLIC_API(CK_RV) C_DecryptUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ HSESSION hs;
+ int rv;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession (session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+ hs = socket->maciSession;
+
+ if (GetCryptoOperation(context) != Decrypt) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
+ }
+
+ if (pPart == NULL) {
+ *pulPartLen = ulEncryptedPartLen;
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ *pulPartLen = ulEncryptedPartLen;
+
+ FMUTEX_Lock(socket->registersLock);
+ MACI_Lock (hs, CI_NULL_FLAG);
+ rv = DecryptData (context, pEncryptedPart, ulEncryptedPartLen, pPart,
+ *pulPartLen);
+ MACI_Unlock(hs);
+ FMUTEX_Unlock(socket->registersLock);
+
+ fort11_FreeSession(session);
+
+ if (rv != SOCKET_SUCCESS) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_DecryptFinal finishes a multiple-part decryption operation. */
+PR_PUBLIC_API(CK_RV) C_DecryptFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR pulLastPartLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaContext *context;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+ EndCryptoOperation (context, Decrypt);
+
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/*
+ ************** Crypto Functions: Digest (HASH) ************************
+ */
+
+/* C_DigestInit initializes a message-digesting operation. */
+PR_PUBLIC_API(CK_RV) C_DigestInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_Digest digests data in a single part. */
+PR_PUBLIC_API(CK_RV) C_Digest(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting operation. */
+PR_PUBLIC_API(CK_RV) C_DigestUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting operation. */
+PR_PUBLIC_API(CK_RV) C_DigestFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/*
+ ************** Crypto Functions: Sign ************************
+ */
+
+/* C_SignInit initializes a signature (private key encryption) operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+PR_PUBLIC_API(CK_RV) C_SignInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Object *keyObject;
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ FortezzaContext *context;
+ PK11Attribute *idAttribute;
+ int personalityIndex;
+ HSESSION hs = socket->maciSession;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (pMechanism->mechanism != CKM_DSA) {
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ keyObject = fort11_ObjectFromHandle (hKey, session);
+
+ if (keyObject == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ context = &session->fortezzaContext;
+ InitContext(context, socket, hKey);
+ InitCryptoOperation (context, Sign);
+ fort11_FreeSession(session);
+
+ idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
+ fort11_FreeObject(keyObject);
+
+ if (idAttribute == NULL) {
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ personalityIndex = *(int*)(idAttribute->attrib.pValue);
+ fort11_FreeAttribute(idAttribute);
+
+ MACI_Select (hs, slot->slotID);
+ if (MACI_SetPersonality (hs,personalityIndex) != CI_OK) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_Sign signs (encrypts with private key) data in a single part,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+PR_PUBLIC_API(CK_RV) C_Sign(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen) {
+
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaContext *context;
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ HSESSION hs = socket->maciSession;
+ PK11Object *keyObject;
+ PK11Attribute *idAttribute;
+ int ciRV, personalityIndex;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+
+ context = &session->fortezzaContext;
+ if (GetCryptoOperation(context) != Sign) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
+ }
+
+ if (pSignature == NULL) {
+ *pulSignatureLen = 40;
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ if (ulDataLen > 20) {
+ FORT11_RETURN (CKR_DATA_LEN_RANGE);
+ }
+
+ if (*pulSignatureLen < 40) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
+ }
+ *pulSignatureLen = 40;
+
+ keyObject = fort11_ObjectFromHandle(context->hKey, session);
+ if (keyObject == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN(CKR_GENERAL_ERROR);
+ }
+
+ idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
+ fort11_FreeObject(keyObject);
+
+ personalityIndex = *(int*)(idAttribute->attrib.pValue);
+ fort11_FreeAttribute(idAttribute);
+
+ MACI_Select(hs, slot->slotID);
+
+ MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
+ ciRV = MACI_SetPersonality(hs, personalityIndex);
+ if (ciRV != CI_OK) {
+ MACI_Unlock(hs);
+ fort11_FreeSession(session);
+ FORT11_RETURN(CKR_DEVICE_ERROR);
+ }
+
+ ciRV = MACI_Sign (hs, pData, pSignature);
+ if (ciRV != CI_OK) {
+ MACI_Unlock(hs);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ MACI_Unlock(hs);
+ EndCryptoOperation (context, Sign);
+ fort11_FreeSession(session);
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+PR_PUBLIC_API(CK_RV) C_SignUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * FORT11_RETURNing the signature. */
+PR_PUBLIC_API(CK_RV) C_SignFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/*
+ ************** Crypto Functions: Sign Recover ************************
+ */
+/* C_SignRecoverInit initializes a signature operation,
+ * where the (digest) data can be recovered from the signature.
+ * E.g. encryption with the user's private key */
+PR_PUBLIC_API(CK_RV) C_SignRecoverInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_SignRecover signs data in a single operation
+ * where the (digest) data can be recovered from the signature.
+ * E.g. encryption with the user's private key */
+PR_PUBLIC_API(CK_RV) C_SignRecover(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/*
+ ************** Crypto Functions: verify ************************
+ */
+
+/* C_VerifyInit initializes a verification operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature (e.g. DSA) */
+PR_PUBLIC_API(CK_RV) C_VerifyInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+PR_PUBLIC_API(CK_RV) C_Verify(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_VerifyUpdate continues a multiple-part verification operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+PR_PUBLIC_API(CK_RV) C_VerifyUpdate( CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_VerifyFinal finishes a multiple-part verification operation,
+ * checking the signature. */
+PR_PUBLIC_API(CK_RV) C_VerifyFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/*
+ ************** Crypto Functions: Verify Recover ************************
+ */
+
+/* C_VerifyRecoverInit initializes a signature verification operation,
+ * where the data is recovered from the signature.
+ * E.g. Decryption with the user's public key */
+PR_PUBLIC_API(CK_RV) C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey) {
+ /* For functions that don't access globals, we don't have to worry about the
+ * stack.
+ */
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_VerifyRecover verifies a signature in a single-part operation,
+ * where the data is recovered from the signature.
+ * E.g. Decryption with the user's public key */
+PR_PUBLIC_API(CK_RV) C_VerifyRecover(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/*
+ **************************** Key Functions: ************************
+ */
+
+#define MAX_KEY_LEN 256
+/* C_GenerateKey generates a secret key, creating a new key object. */
+PR_PUBLIC_API(CK_RV) C_GenerateKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ PK11Object *key;
+ FortezzaKey *newKey;
+ int i, keyRegister;
+ CK_ULONG key_length = 0;
+ CK_RV crv = CKR_OK;
+ CK_OBJECT_CLASS secretKey = CKO_SECRET_KEY;
+ CK_BBOOL False = FALSE;
+ CK_BBOOL cktrue = TRUE;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+ if (pMechanism->mechanism != CKM_SKIPJACK_KEY_GEN) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ key = fort11_NewObject(slot);
+
+ if (key == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_HOST_MEMORY);
+ }
+
+ for (i=0; i < (int) ulCount; i++) {
+ if (pTemplate[i].type == CKA_VALUE_LEN) {
+ key_length = *(CK_ULONG *)pTemplate[i].pValue;
+ continue;
+ }
+ crv = fort11_AddAttributeType (key, pk11_attr_expand (&pTemplate[i]));
+ if (crv != CKR_OK)
+ break;
+ }
+
+ if (crv != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (crv);
+ }
+
+ /* make sure we don't have any class, key_type, or value fields */
+ fort11_DeleteAttributeType(key,CKA_CLASS);
+ fort11_DeleteAttributeType(key,CKA_KEY_TYPE);
+ fort11_DeleteAttributeType(key,CKA_VALUE);
+
+ if (MAX_KEY_LEN < key_length) {
+ crv = CKR_TEMPLATE_INCONSISTENT;
+ }
+
+ if (crv != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (crv);
+ }
+
+ if (fort11_AddAttributeType(key, CKA_CLASS,&secretKey,
+ sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ if (fort11_AddAttributeType(key, CKA_TOKEN, &False,
+ sizeof(CK_BBOOL)) != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ if (fort11_isTrue(key,CKA_SENSITIVE)) {
+ fort11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,
+ sizeof(CK_BBOOL));
+ }
+ if (!fort11_isTrue(key,CKA_EXTRACTABLE)) {
+ fort11_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,
+ sizeof(CK_BBOOL));
+ }
+
+ FMUTEX_Lock(socket->registersLock);
+
+ keyRegister = GetBestKeyRegister(socket);
+ newKey = NewFortezzaKey(socket, MEK, NULL, keyRegister);
+
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (newKey == NULL) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_HOST_MEMORY);
+ }
+
+ key->objectInfo = (void*)newKey;
+ key->infoFree = fort11_FreeFortezzaKey;
+
+ FMUTEX_Lock(slot->objectLock);
+ key->handle = slot->tokenIDCount++;
+ key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+
+ key->objclass = secretKey;
+ key->slot = slot;
+ key->inDB = PR_TRUE;
+
+ fort11_AddObject(session, key);
+ fort11_FreeSession(session);
+ SetFortezzaKeyHandle(newKey, key->handle);
+ *phKey = key->handle;
+
+ FORT11_RETURN (CKR_OK);
+
+}
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+PR_PUBLIC_API(CK_RV) C_GenerateKeyPair
+ (CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPrivateKey,
+ CK_OBJECT_HANDLE_PTR phPublicKey) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+PR_PUBLIC_API(CK_RV) C_WrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hWrappingKey,
+ CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG_PTR pulWrappedKeyLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ PK11Object *wrapKey;
+ PK11Object *srcKey;
+ FortezzaKey *wrapFortKey;
+ FortezzaKey *srcFortKey;
+ int rv;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (!socket->isLoggedIn) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+ }
+
+ if (pMechanism->mechanism != CKM_SKIPJACK_WRAP) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ wrapKey = fort11_ObjectFromHandle (hWrappingKey, session);
+ if ((wrapKey == NULL) || (wrapKey->objectInfo == NULL)) {
+ if (wrapKey)
+ fort11_FreeObject(wrapKey);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ srcKey = fort11_ObjectFromHandle (hKey, session);
+ fort11_FreeSession(session);
+ if ((srcKey == NULL) || (srcKey->objectInfo == NULL)) {
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ wrapFortKey = (FortezzaKey*)wrapKey->objectInfo;
+ fort11_FreeObject(wrapKey);
+
+ srcFortKey = (FortezzaKey*)srcKey->objectInfo;
+ fort11_FreeObject(srcKey);
+
+ FMUTEX_Lock(socket->registersLock);
+ if (wrapFortKey->keyRegister == KeyNotLoaded) {
+ if (LoadKeyIntoRegister(wrapFortKey) == KeyNotLoaded) {
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ }
+
+ if (srcFortKey->keyRegister == KeyNotLoaded) {
+ if (LoadKeyIntoRegister(srcFortKey) == KeyNotLoaded) {
+ FMUTEX_Unlock(socket->registersLock);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ }
+
+ MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
+ rv = WrapKey (wrapFortKey, srcFortKey, pWrappedKey, *pulWrappedKeyLen);
+ MACI_Unlock(socket->maciSession);
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (rv != SOCKET_SUCCESS) {
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
+PR_PUBLIC_API(CK_RV) C_UnwrapKey(CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hUnwrappingKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ PK11Object *wrapKey;
+ PK11Object *newKey;
+ FortezzaKey *fortKey;
+ FortezzaKey *unwrapFort;
+ CK_ULONG key_length;
+ int i, newKeyRegister;
+ CK_RV crv = CKR_OK;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (pMechanism->mechanism != CKM_SKIPJACK_WRAP){
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ if (!socket->isLoggedIn) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
+ }
+
+ wrapKey = fort11_ObjectFromHandle(hUnwrappingKey, session);
+ if (wrapKey == NULL || wrapKey->objectInfo == NULL) {
+ if (wrapKey)
+ fort11_FreeObject(wrapKey);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_UNWRAPPING_KEY_HANDLE_INVALID);
+ }
+
+ fortKey = (FortezzaKey*)wrapKey->objectInfo;
+ fort11_FreeObject(wrapKey);
+
+ newKey = fort11_NewObject(slot);
+ if (newKey == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_HOST_MEMORY);
+ }
+
+ for (i=0; i< (int)ulAttributeCount; i++) {
+ if (pTemplate[i].type == CKA_VALUE_LEN) {
+ key_length = *(CK_ULONG*)pTemplate[i].pValue;
+ continue;
+ }
+ crv=fort11_AddAttributeType(newKey,fort11_attr_expand(&pTemplate[i]));
+ if (crv != CKR_OK) {
+ break;
+ }
+ }
+
+ if (crv != CKR_OK) {
+ fort11_FreeSession(session);
+ fort11_FreeObject(newKey);
+ FORT11_RETURN (crv);
+ }
+
+ /* make sure we don't have any class, key_type, or value fields */
+ if (!fort11_hasAttribute(newKey,CKA_CLASS)) {
+ fort11_FreeObject(newKey);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
+ }
+ if (!fort11_hasAttribute(newKey,CKA_KEY_TYPE)) {
+ fort11_FreeObject(newKey);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
+ }
+
+ FMUTEX_Lock(socket->registersLock);
+ newKeyRegister = UnwrapKey (pWrappedKey, fortKey);
+ if (newKeyRegister == KeyNotLoaded) {
+ /*Couldn't Unwrap the key*/
+ fort11_FreeObject(newKey);
+ fort11_FreeSession(session);
+ FMUTEX_Unlock(socket->registersLock);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ unwrapFort = NewUnwrappedKey(newKeyRegister, fortKey->id, socket);
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (unwrapFort == NULL) {
+ fort11_FreeObject(newKey);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_HOST_MEMORY);
+ }
+ newKey->objectInfo = unwrapFort;
+ newKey->infoFree = fort11_FreeFortezzaKey;
+
+ FMUTEX_Lock(slot->objectLock);
+ newKey->handle = slot->tokenIDCount++;
+ newKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+ newKey->objclass = CKO_SECRET_KEY;
+ newKey->slot = slot;
+ newKey->inDB = PR_TRUE;
+
+ fort11_AddObject (session, newKey);
+ fort11_FreeSession(session);
+
+ SetFortezzaKeyHandle(unwrapFort, newKey->handle);
+ *phKey = newKey->handle;
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key object. */
+PR_PUBLIC_API(CK_RV) C_DeriveKey( CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hBaseKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
+ PK11Object *key, *sourceKey;
+ CK_ULONG i;
+ CK_ULONG key_length = 0;
+ CK_RV crv = 0;
+ CK_KEY_TYPE keyType = CKK_SKIPJACK;
+ CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
+ CK_BBOOL ckTrue = TRUE;
+ CK_BBOOL ckFalse = FALSE;
+ int ciRV;
+ int personality;
+ PK11Attribute *att;
+
+ CK_KEA_DERIVE_PARAMS_PTR params;
+ FortezzaKey *derivedKey;
+ CreateTEKInfo tekInfo;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (pMechanism->mechanism != CKM_KEA_KEY_DERIVE) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_INVALID);
+ }
+
+ key = fort11_NewObject (slot);
+
+ if (key == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_HOST_MEMORY);
+ }
+
+ for (i = 0; i < ulAttributeCount; i++) {
+ crv = fort11_AddAttributeType (key, fort11_attr_expand(&pTemplate[i]));
+ if (crv != CKR_OK) {
+ break;
+ }
+ if (pTemplate[i].type == CKA_KEY_TYPE) {
+ keyType = *(CK_KEY_TYPE*)pTemplate[i].pValue;
+ } else if (pTemplate[i].type == CKA_VALUE_LEN) {
+ key_length = *(CK_ULONG*)pTemplate[i].pValue;
+ }
+ }
+
+ if (crv != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (crv);
+ }
+
+ if (key_length == 0) {
+ key_length = 12;
+ }
+
+ classType = CKO_SECRET_KEY;
+ crv = fort11_forceAttribute (key, CKA_CLASS, &classType,
+ sizeof(classType));
+ if (crv != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (crv);
+ }
+ crv = fort11_forceAttribute (key, CKA_SENSITIVE, &ckTrue,
+ sizeof(CK_BBOOL));
+ if (crv != CKR_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (crv);
+ }
+ crv = fort11_forceAttribute (key, CKA_EXTRACTABLE, &ckFalse,
+ sizeof(CK_BBOOL));
+ if (crv != CKR_OK) {
+ fort11_FreeSession(session);
+ fort11_FreeObject(key);
+ FORT11_RETURN (crv);
+ }
+
+ sourceKey = fort11_ObjectFromHandle (hBaseKey, session);
+
+ if (sourceKey == NULL) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+
+ att = fort11_FindAttribute(sourceKey,CKA_ID);
+ fort11_FreeObject(sourceKey);
+ if (att == NULL) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_TYPE_INCONSISTENT);
+ }
+ personality = *(int *) att->attrib.pValue;
+ fort11_FreeAttribute(att);
+
+ params = (CK_KEA_DERIVE_PARAMS_PTR)pMechanism->pParameter;
+
+ if (params == NULL) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
+ }
+
+ ciRV = MACI_SetPersonality(socket->maciSession,personality);
+ if (ciRV != CI_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ /*
+ * If we're sending, generate our own RA.
+ */
+ if (params->isSender) {
+ ciRV = MACI_GenerateRa(socket->maciSession,params->pRandomA);
+ if (ciRV != CI_OK) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ }
+ PORT_Memcpy (tekInfo.Ra, params->pRandomA, params->ulRandomLen);
+ PORT_Memcpy (tekInfo.Rb, params->pRandomB, params->ulRandomLen);
+ tekInfo.randomLen = params->ulRandomLen;
+ tekInfo.personality = personality;
+ tekInfo.flag = (params->isSender) ? CI_INITIATOR_FLAG : CI_RECIPIENT_FLAG;
+
+ PORT_Memcpy (tekInfo.pY, params->pPublicData, params->ulPublicDataLen);
+ tekInfo.YSize = params->ulPublicDataLen;
+
+ FMUTEX_Lock(socket->registersLock);
+ derivedKey = NewFortezzaKey(socket, TEK, &tekInfo,
+ GetBestKeyRegister(socket));
+ FMUTEX_Unlock(socket->registersLock);
+
+ if (derivedKey == NULL) {
+ fort11_FreeObject(key);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_GENERAL_ERROR);
+ }
+
+ key->objectInfo = derivedKey;
+ key->infoFree = fort11_FreeFortezzaKey;
+
+ FMUTEX_Lock(slot->objectLock);
+ key->handle = slot->tokenIDCount++;
+ key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ FMUTEX_Unlock(slot->objectLock);
+ key->objclass = classType;
+ key->slot = slot;
+ key->inDB = PR_TRUE;
+
+ fort11_AddObject (session, key);
+ fort11_FreeSession(session);
+
+ SetFortezzaKeyHandle(derivedKey, key->handle);
+ *phKey = key->handle;
+
+ FORT11_RETURN (CKR_OK);
+}
+
+/*
+ **************************** Random Functions: ************************
+ */
+
+/* C_SeedRandom mixes additional seed material into the token's random number
+ * generator. */
+PR_PUBLIC_API(CK_RV) C_SeedRandom(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSeed,
+ CK_ULONG ulSeedLen) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_GenerateRandom generates random data. */
+PR_PUBLIC_API(CK_RV) C_GenerateRandom(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pRandomData,
+ CK_ULONG ulRandomLen) {
+ FORT11_ENTER()
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
+ CI_RANDOM randomNum;
+ CK_ULONG randomSize = sizeof (CI_RANDOM);
+ int ciRV;
+ CK_ULONG bytesCopied = 0, bytesToCopy;
+ CK_ULONG bufferSize = 0, bytesRemaining;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle (hSession, PR_TRUE);
+ fort11_TokenRemoved(slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ fort11_FreeSession(session);
+ ciRV = MACI_Select(fortezzaSockets[slot->slotID-1].maciSession,
+ slot->slotID);
+ if (ciRV != CI_OK) {
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ while (bytesCopied < ulRandomLen) {
+ bytesRemaining = ulRandomLen - bytesCopied;
+ if (bufferSize < bytesRemaining) {
+ ciRV =
+ MACI_GenerateRandom(fortezzaSockets[slot->slotID-1].maciSession,
+ randomNum);
+ if (ciRV != CI_OK)
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ bufferSize = randomSize;
+ }
+ bytesToCopy = (bytesRemaining > randomSize) ? randomSize :
+ bytesRemaining;
+
+ PORT_Memcpy (&pRandomData[bytesCopied],
+ &randomNum[randomSize-bufferSize], bytesToCopy);
+
+ bytesCopied += bytesToCopy;
+ bufferSize -= bytesToCopy;
+ }
+
+ FORT11_RETURN (CKR_OK);
+}
+
+
+/* C_GetFunctionStatus obtains an updated status of a function running
+ * in parallel with an application. */
+PR_PUBLIC_API(CK_RV) C_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_CancelFunction cancels a function running in parallel */
+PR_PUBLIC_API(CK_RV) C_CancelFunction(CK_SESSION_HANDLE hSession) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/* C_GetOperationState saves the state of the cryptographic
+ *operation in a session. */
+PR_PUBLIC_API(CK_RV) C_GetOperationState(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG_PTR pulOperationStateLen) {
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaContext *context;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (pOperationState == NULL) {
+ *pulOperationStateLen = sizeof (FortezzaContext);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_OK);
+ }
+
+ if (*pulOperationStateLen < sizeof (FortezzaContext)) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
+ }
+
+ context = &session->fortezzaContext;
+ fort11_FreeSession(session);
+ PORT_Memcpy (pOperationState, context, sizeof(FortezzaContext));
+ ((FortezzaContext *)pOperationState)->session = NULL;
+ ((FortezzaContext *)pOperationState)->fortezzaKey = NULL;
+ *pulOperationStateLen = sizeof(FortezzaContext);
+ FORT11_RETURN (CKR_OK);
+}
+
+
+
+/* C_SetOperationState restores the state of the cryptographic operation in a session. */
+PR_PUBLIC_API(CK_RV) C_SetOperationState(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG ulOperationStateLen,
+ CK_OBJECT_HANDLE hEncryptionKey,
+ CK_OBJECT_HANDLE hAuthenticationKey){
+ FORT11_ENTER()
+ PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
+ PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
+ FortezzaContext *context;
+ FortezzaContext passedInCxt;
+ PK11Object *keyObject;
+ FortezzaKey *fortKey;
+
+ if (session == NULL) {
+ session = fort11_SessionFromHandle(hSession, PR_TRUE);
+ fort11_TokenRemoved (slot, session);
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
+ }
+
+ if (ulOperationStateLen != sizeof(FortezzaContext)) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SAVED_STATE_INVALID);
+ }
+
+ PORT_Memcpy(&passedInCxt, pOperationState, sizeof(FortezzaContext));
+ if (passedInCxt.fortezzaSocket->slotID != slot->slotID) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SAVED_STATE_INVALID);
+ }
+ passedInCxt.session = NULL;
+ passedInCxt.fortezzaKey = NULL;
+
+ if (hEncryptionKey != 0) {
+ keyObject = fort11_ObjectFromHandle(hEncryptionKey, session);
+ if (keyObject == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
+ }
+ fortKey = (FortezzaKey*)keyObject->objectInfo;
+ fort11_FreeObject(keyObject);
+ if (fortKey == NULL) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_SAVED_STATE_INVALID);
+ }
+ if (fortKey->keyRegister == KeyNotLoaded) {
+ if (LoadKeyIntoRegister (fortKey) == KeyNotLoaded) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+ }
+ passedInCxt.fortezzaKey = fortKey;
+
+ }
+ if (hAuthenticationKey != 0) {
+ fort11_FreeSession(session);
+ FORT11_RETURN (CKR_DEVICE_ERROR);
+ }
+
+ passedInCxt.session = session;
+ context = &session->fortezzaContext;
+ fort11_FreeSession (session);
+ PORT_Memcpy (context, &passedInCxt, sizeof(passedInCxt));
+
+ FORT11_RETURN (CKR_OK);
+}
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting and
+ encryption operation. */
+PR_PUBLIC_API(CK_RV) C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen){
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and digesting
+ operation. */
+PR_PUBLIC_API(CK_RV) C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen){
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and encryption
+ operation. */
+PR_PUBLIC_API(CK_RV) C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen){
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and verify
+ operation. */
+PR_PUBLIC_API(CK_RV) C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen){
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+/* C_DigestKey continues a multi-part message-digesting operation,
+ * by digesting the value of a secret key as part of the data already digested.
+ */
+PR_PUBLIC_API(CK_RV) C_DigestKey(CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hKey) {
+ return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+PR_PUBLIC_API(CK_RV) C_WaitForSlotEvent(CK_FLAGS flags,
+ CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pRserved) {
+ return CKR_FUNCTION_FAILED;
+}
+
diff --git a/security/nss/lib/fortcrypt/fortsock.h b/security/nss/lib/fortcrypt/fortsock.h
new file mode 100644
index 000000000..f74fc80b8
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fortsock.h
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+#ifndef FORSOCK_H_
+#define FORSOCK_H_
+
+#include "seccomon.h"
+#include "fpkcs11.h"
+#include "fpkcs11i.h"
+#include "fpkstrs.h"
+
+
+#ifndef prtypes_h___
+typedef enum { PR_FALSE, PR_TRUE }PRBool;
+#endif
+
+
+#define SOCKET_SUCCESS 0
+#define SOCKET_FAILURE 1
+
+#define KeyNotLoaded -1
+#define NoCryptoType -1
+#define NoCryptoMode -1
+#define NO_MECHANISM 0xFFFFFFFFL
+
+
+/*Get the Fortezza context in here*/
+
+int InitSocket (FortezzaSocket *inSocket, int inSlotID);
+int FreeSocket (FortezzaSocket *inSocket);
+
+int FetchPersonalityList (FortezzaSocket *inSocket);
+int UnloadPersonalityList(FortezzaSocket *inSocket);
+
+int LoginToSocket (FortezzaSocket *inSocket, int inUserType, CI_PIN inPin);
+
+int LogoutFromSocket (FortezzaSocket *inSocket);
+
+PRBool SocketStateUnchanged(FortezzaSocket* inSocket);
+
+int GetBestKeyRegister(FortezzaSocket *inSocket);
+
+FortezzaKey *NewFortezzaKey(FortezzaSocket *inSocket,
+ FortezzaKeyType inKeyType,
+ CreateTEKInfo *TEKinfo,
+ int inKeyRegister);
+FortezzaKey *NewUnwrappedKey(int inKeyRegister, int i,
+ FortezzaSocket *inSocket);
+
+int LoadKeyIntoRegister (FortezzaKey *inKey);
+int SetFortezzaKeyHandle (FortezzaKey *inKey, CK_OBJECT_HANDLE inHandle);
+void RemoveKey (FortezzaKey *inKey);
+
+void InitContext(FortezzaContext *inContext, FortezzaSocket *inSocket,
+ CK_OBJECT_HANDLE hKey);
+int InitCryptoOperation (FortezzaContext *inContext,
+ CryptoType inCryptoOperation);
+int EndCryptoOperation (FortezzaContext *inContext,
+ CryptoType inCryptoOperation);
+CryptoType GetCryptoOperation (FortezzaContext *inContext);
+int EncryptData (FortezzaContext *inContext, CK_BYTE_PTR inData,
+ CK_ULONG inDataLen, CK_BYTE_PTR inDest,
+ CK_ULONG inDestLen);
+int DecryptData (FortezzaContext *inContext, CK_BYTE_PTR inData,
+ CK_ULONG inDataLen, CK_BYTE_PTR inDest,
+ CK_ULONG inDestLen);
+
+int SaveState (FortezzaContext *inContext, CI_IV inIV,
+ PK11Session *inSession, FortezzaKey *inKey,
+ int inCryptoType, CK_MECHANISM_TYPE inMechanism);
+
+int WrapKey (FortezzaKey *wrappingKey, FortezzaKey *srcKey,
+ CK_BYTE_PTR pDest, CK_ULONG ulDestLen);
+int UnwrapKey (CK_BYTE_PTR inWrappedKey, FortezzaKey *inKey);
+
+#endif /*SOCKET_H_*/
diff --git a/security/nss/lib/fortcrypt/fpkcs11.h b/security/nss/lib/fortcrypt/fpkcs11.h
new file mode 100644
index 000000000..09f3dfe29
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkcs11.h
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
+ * is granted provided that it is identified as "RSA Security In.c Public-Key
+ * Cryptography Standards (PKCS)" in all material mentioning or referencing
+ * this document.
+ */
+/* Define API */
+#ifndef _FPKCS11_H_
+#define _FPKCS11_H_ 1
+
+#include "seccomon.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* All the various pkcs11 types and #define'd values are in the file */
+/* pkcs11t.h. CK_PTR should be defined there, too; it's the recipe for */
+/* making pointers. */
+#include "fpkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+/* ================================================================= */
+/* Define the "extern" form of all the entry points */
+
+#define CK_EXTERN extern
+#define CK_FUNC(name) CK_ENTRY name
+#define CK_NEED_ARG_LIST 1
+#define _CK_RV PR_PUBLIC_API(CK_RV)
+
+/* pkcs11f.h has all the information about the PKCS #11 functions. */
+#include "fpkcs11f.h"
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef CK_NEED_ARG_LIST
+#undef _CK_RV
+
+/* ================================================================= */
+/* Define the typedef form of all the entry points. */
+/* That is, for each Cryptoki function C_XXX, define a type CK_C_XXX */
+/* which is a pointer to that kind of function. */
+
+#define CK_EXTERN typedef
+#define CK_FUNC(name) CK_ENTRY (CK_PTR __PASTE(CK_,name))
+#define CK_NEED_ARG_LIST 1
+#define _CK_RV CK_RV
+
+#include "fpkcs11f.h"
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef CK_NEED_ARG_LIST
+#undef _CK_RV
+
+/* =================================================================
+ * Define structed vector of entry points.
+ * The CK_FUNCTION_LIST contains a CK_VERSION indicating the PKCS #11
+ * version, and then a whole slew of function pointers to the routines
+ * in the library. This type was declared, but not defined, in
+ * pkcs11t.h. */
+
+
+/* These data types are platform/implementation dependent. */
+#if defined(XP_WIN)
+#if defined(_WIN32)
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win32 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(push, cryptoki, 1)
+#else /* win16 */
+#if defined(__WATCOMC__)
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win16 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(push, 1)
+#else /* not Watcom 16-bit */
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win16 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(1)
+#endif
+#endif
+#else /* not windows */
+#define CK_ENTRY
+#define CK_PTR * /* definition for UNIX */
+#define NULL_PTR 0 /* NULL pointer */
+#endif
+
+
+#define CK_EXTERN
+#define CK_FUNC(name) __PASTE(CK_,name) name;
+#define _CK_RV
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* PKCS #11 version */
+
+/* Pile all the function pointers into it. */
+#include "fpkcs11f.h"
+
+};
+
+#undef CK_FUNC
+#undef CK_EXTERN
+#undef _CK_RV
+
+
+#if defined(XP_WIN)
+#if defined(_WIN32)
+#pragma pack(pop, cryptoki)
+#else /* win16 */
+#if defined(__WATCOMC__)
+#pragma pack(pop)
+#else /* not Watcom 16-bit */
+#pragma pack()
+#endif
+#endif
+#endif
+
+
+#undef __PASTE
+/* ================================================================= */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/security/nss/lib/fortcrypt/fpkcs11f.h b/security/nss/lib/fortcrypt/fpkcs11f.h
new file mode 100644
index 000000000..6fa7e755d
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkcs11f.h
@@ -0,0 +1,953 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
+ * is granted provided that it is identified as "RSA Security In.c Public-Key
+ * Cryptography Standards (PKCS)" in all material mentioning or referencing
+ * this document.
+ */
+/* This function contains pretty much everything about all */
+/* the PKCS #11 function prototypes. */
+
+/* General-purpose */
+
+/* C_Initialize initializes the PKCS #11 library. */
+CK_EXTERN _CK_RV CK_FUNC(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the PKCS #11
+ * library. */
+CK_EXTERN _CK_RV CK_FUNC(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about PKCS #11. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives the information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives ptr to function
+list */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with token present */
+ CK_SLOT_ID_PTR pSlotList, /* receives the array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives the number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in the
+system. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token in the
+ * system. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types supported by
+ * a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* receives mech. types array
+*/
+ CK_ULONG_PTR pulCount /* receives number of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular mechanism
+ * possibly supported by a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism information */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_EXTERN _CK_RV CK_FUNC(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of user that is currently logged in. */
+CK_EXTERN _CK_RV CK_FUNC(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* defined in CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* pointer passed to callback */
+ CK_NOTIFY Notify, /* notification callback function
+*/
+ CK_SESSION_HANDLE_PTR phSession /* receives new session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a token.
+*/
+CK_EXTERN _CK_RV CK_FUNC(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session information */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pOperationState, /* location receiving state */
+ CK_ULONG_PTR pulOperationStateLen /* location receiving state
+length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic operation
+ * in a session. */
+CK_EXTERN _CK_RV CK_FUNC(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pOperationState, /* the location holding the
+state */
+ CK_ULONG ulOperationStateLen, /* location holding state
+length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* handle of en/decryption key
+*/
+ CK_OBJECT_HANDLE hAuthenticationKey /* handle of sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_EXTERN _CK_RV CK_FUNC(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_EXTERN _CK_RV CK_FUNC(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* receives new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the copy. */
+CK_EXTERN _CK_RV CK_FUNC(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_EXTERN _CK_RV CK_FUNC(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+attributes. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+attributes */
+CK_EXTERN _CK_RV CK_FUNC(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session objects
+ * that match a template. */
+CK_EXTERN _CK_RV CK_FUNC(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attributes in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session objects
+ * that match a template, obtaining additional object handles. */
+CK_EXTERN _CK_RV CK_FUNC(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* receives object handle array
+*/
+ CK_ULONG ulMaxObjectCount, /* max handles to be returned
+*/
+ CK_ULONG_PTR pulObjectCount /* actual number returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session objects.
+*/
+CK_EXTERN _CK_RV CK_FUNC(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_EXTERN _CK_RV CK_FUNC(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext data */
+ CK_BYTE_PTR pEncryptedData, /* receives encrypted data */
+ CK_ULONG_PTR pulEncryptedDataLen /* receives encrypted byte
+count */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* bytes of plaintext data */
+ CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
+ CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte count
+*/
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* receives encrypted last
+part */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* receives byte count */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_EXTERN _CK_RV CK_FUNC(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pEncryptedData, /* input encrypted data */
+ CK_ULONG ulEncryptedDataLen, /* count of bytes of input */
+ CK_BYTE_PTR pData, /* receives decrypted output */
+ CK_ULONG_PTR pulDataLen /* receives decrypted byte count
+*/
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* count of bytes of input */
+ CK_BYTE_PTR pPart, /* receives decrypted output */
+ CK_ULONG_PTR pulPartLen /* receives decrypted byte
+count */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* receives decrypted output */
+ CK_ULONG_PTR pulLastPartLen /* receives decrypted byte count */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_EXTERN _CK_RV CK_FUNC(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to be digested */
+ CK_BYTE_PTR pDigest, /* receives the message digest */
+ CK_ULONG_PTR pulDigestLen /* receives byte length of digest */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting operation.
+*/
+CK_EXTERN _CK_RV CK_FUNC(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting operation, by
+ * digesting the value of a secret key as part of the data already
+digested.
+ */
+CK_EXTERN _CK_RV CK_FUNC(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* handle of secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting operation.
+*/
+CK_EXTERN _CK_RV CK_FUNC(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* receives the message digest */
+ CK_ULONG_PTR pulDigestLen /* receives byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+CK_EXTERN _CK_RV CK_FUNC(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single part,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+CK_EXTERN _CK_RV CK_FUNC(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data (digest) to be signed
+*/
+ CK_ULONG ulDataLen, /* count of bytes to be signed */
+ CK_BYTE_PTR pSignature, /* receives the signature */
+ CK_ULONG_PTR pulSignatureLen /* receives byte count of signature
+*/
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+CK_EXTERN _CK_RV CK_FUNC(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data (digest) to be signed */
+ CK_ULONG ulPartLen /* count of bytes to be signed */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_EXTERN _CK_RV CK_FUNC(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* receives the signature */
+ CK_ULONG_PTR pulSignatureLen /* receives byte count of signature
+*/
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation,
+ * where the (digest) data can be recovered from the signature.
+ * E.g. encryption with the user's private key */
+CK_EXTERN _CK_RV CK_FUNC(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation
+ * where the (digest) data can be recovered from the signature.
+ * E.g. encryption with the user's private key */
+CK_EXTERN _CK_RV CK_FUNC(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data (digest) to be signed
+*/
+ CK_ULONG ulDataLen, /* count of bytes to be signed */
+ CK_BYTE_PTR pSignature, /* receives the signature */
+ CK_ULONG_PTR pulSignatureLen /* receives byte count of signature
+*/
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature (e.g. DSA) */
+CK_EXTERN _CK_RV CK_FUNC(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+CK_EXTERN _CK_RV CK_FUNC(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* plaintext data (digest) to
+compare */
+ CK_ULONG ulDataLen, /* length of data (digest) in bytes
+*/
+ CK_BYTE_PTR pSignature, /* the signature to be verified */
+ CK_ULONG ulSignatureLen /* count of bytes of signature */
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification operation,
+ * where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature */
+CK_EXTERN _CK_RV CK_FUNC(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* plaintext data (digest) to compare */
+ CK_ULONG ulPartLen /* length of data (digest) in bytes */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification operation,
+ * checking the signature. */
+CK_EXTERN _CK_RV CK_FUNC(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* the signature to be verified */
+ CK_ULONG ulSignatureLen /* count of bytes of signature */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification operation,
+ * where the data is recovered from the signature.
+ * E.g. Decryption with the user's public key */
+CK_EXTERN _CK_RV CK_FUNC(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part operation,
+ * where the data is recovered from the signature.
+ * E.g. Decryption with the user's public key */
+CK_EXTERN _CK_RV CK_FUNC(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* the signature to be verified */
+ CK_ULONG ulSignatureLen, /* count of bytes of signature */
+ CK_BYTE_PTR pData, /* receives decrypted data (digest)
+*/
+ CK_ULONG_PTR pulDataLen /* receives byte count of data */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting and
+encryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* bytes of plaintext data */
+ CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
+ CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte
+count */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* count of bytes of input */
+ CK_BYTE_PTR pPart, /* receives decrypted output */
+ CK_ULONG_PTR pulPartLen /* receives decrypted byte
+count */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* bytes of plaintext data */
+ CK_BYTE_PTR pEncryptedPart, /* receives encrypted data */
+ CK_ULONG_PTR pulEncryptedPartLen /* receives encrypted byte
+count */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_EXTERN _CK_RV CK_FUNC(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* input encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* count of byes of input */
+ CK_BYTE_PTR pPart, /* receives decrypted output */
+ CK_ULONG_PTR pulPartLen /* receives decrypted byte
+count */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key object. */
+CK_EXTERN _CK_RV CK_FUNC(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the key generation mechanism */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
+ CK_ULONG ulCount, /* number of attributes in template
+*/
+ CK_OBJECT_HANDLE_PTR phKey /* receives handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_EXTERN _CK_RV CK_FUNC(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's
+handle */
+ CK_MECHANISM_PTR pMechanism, /* the key gen.
+mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* pub. attr.
+template */
+ CK_ULONG ulPublicKeyAttributeCount, /* # of pub. attrs.
+*/
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* priv. attr.
+template */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # of priv. attrs.
+*/
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. key
+handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets priv. key
+handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_EXTERN _CK_RV CK_FUNC(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* handle of the wrapping key */
+ CK_OBJECT_HANDLE hKey, /* handle of the key to be wrapped
+*/
+ CK_BYTE_PTR pWrappedKey, /* receives the wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* receives byte size of wrapped
+key */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key
+object. */
+CK_EXTERN _CK_RV CK_FUNC(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the unwrapping mechanism */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* handle of the unwrapping
+key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* bytes length of wrapped key
+*/
+ CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
+ CK_ULONG ulAttributeCount, /* # of attributes in template
+*/
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of recovered
+key */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key object.
+*/
+CK_EXTERN _CK_RV CK_FUNC(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the key derivation
+mechanism */
+ CK_OBJECT_HANDLE hBaseKey, /* handle of the base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for the new key */
+ CK_ULONG ulAttributeCount, /* # of attributes in template
+*/
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of derived key
+*/
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's random
+number
+ * generator. */
+CK_EXTERN _CK_RV CK_FUNC(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* count of bytes of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_EXTERN _CK_RV CK_FUNC(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* number of bytes to be generated */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus obtains an updated status of a function running
+ * in parallel with an application. */
+CK_EXTERN _CK_RV CK_FUNC(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction cancels a function running in parallel. */
+CK_EXTERN _CK_RV CK_FUNC(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Functions added in for PKCS #11 Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_EXTERN _CK_RV CK_FUNC(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
diff --git a/security/nss/lib/fortcrypt/fpkcs11i.h b/security/nss/lib/fortcrypt/fpkcs11i.h
new file mode 100644
index 000000000..9359bb8d6
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkcs11i.h
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+/*
+ * Internal data structures used by pkcs11.c
+ */
+#ifndef _FPKCS11I_H_
+#define _FPKCS11I_H_ 1
+
+#include "fpkstrs.h"
+#ifdef SWFORT
+#ifndef RETURN_TYPE
+#define RETURN_TYPE int
+#endif
+#endif
+#include "genci.h"
+
+typedef struct PK11AttributeStr PK11Attribute;
+typedef struct PK11ObjectListStr PK11ObjectList;
+typedef struct PK11ObjectListElementStr PK11ObjectListElement;
+typedef struct PK11ObjectStr PK11Object;
+typedef struct PK11SessionStr PK11Session;
+typedef struct PK11SlotStr PK11Slot;
+typedef struct PK11SessionContextStr PK11SessionContext;
+typedef struct PK11SearchResultsStr PK11SearchResults;
+
+typedef void (*PK11Destroy)(void *, PRBool);
+typedef SECStatus (*PK11Cipher)(void *,void *,unsigned int *,unsigned int,
+ void *, unsigned int);
+typedef SECStatus (*PK11Verify)(void *,void *,unsigned int,void *,unsigned int);
+typedef void (*PK11Hash)(void *,void *,unsigned int);
+typedef void (*PK11End)(void *,void *,unsigned int *,unsigned int);
+typedef void (*PK11Free)(void *);
+
+#define HASH_SIZE 32
+#define SESSION_HASH_SIZE 64
+
+/* Value to tell if an attribute is modifiable or not.
+ * NEVER: attribute is only set on creation.
+ * ONCOPY: attribute is set on creation and can only be changed on copy.
+ * SENSITIVE: attribute can only be changed to TRUE.
+ * ALWAYS: attribute can always be changed.
+ */
+typedef enum {
+ PK11_NEVER = 0,
+ PK11_ONCOPY = 1,
+ PK11_SENSITIVE = 2,
+ PK11_ALWAYS = 3
+} PK11ModifyType;
+
+/*
+ * Free Status Enum... tell us more information when we think we're
+ * deleting an object.
+ */
+typedef enum {
+ PK11_DestroyFailure,
+ PK11_Destroyed,
+ PK11_Busy
+} PK11FreeStatus;
+
+/*
+ * attribute values of an object.
+ */
+struct PK11AttributeStr {
+ PK11Attribute *next;
+ PK11Attribute *prev;
+ int refCount;
+ void *refLock;
+ /*must be called handle to make pk11queue_find work */
+ CK_ATTRIBUTE_TYPE handle;
+ CK_ATTRIBUTE attrib;
+};
+
+struct PK11ObjectListStr {
+ PK11ObjectList *next;
+ PK11ObjectList *prev;
+ PK11Object *parent;
+};
+
+/*
+ * PKCS 11 crypto object structure
+ */
+struct PK11ObjectStr {
+ PK11Object *next;
+ PK11Object *prev;
+ PK11ObjectList sessionList;
+ CK_OBJECT_HANDLE handle;
+ int refCount;
+ void *refLock;
+ void *attributeLock;
+ PK11Session *session;
+ PK11Slot *slot;
+ CK_OBJECT_CLASS objclass;
+ void *objectInfo;
+ PK11Free infoFree;
+ char *label;
+ PRBool inDB;
+ PK11Attribute *head[HASH_SIZE];
+};
+
+/*
+ * struct to deal with a temparary list of objects
+ */
+struct PK11ObjectListElementStr {
+ PK11ObjectListElement *next;
+ PK11Object *object;
+};
+
+/*
+ * Area to hold Search results
+ */
+struct PK11SearchResultsStr {
+ CK_OBJECT_HANDLE *handles;
+ int size;
+ int index;
+};
+
+
+/*
+ * the universal crypto/hash/sign/verify context structure
+ */
+typedef enum {
+ PK11_ENCRYPT,
+ PK11_DECRYPT,
+ PK11_HASH,
+ PK11_SIGN,
+ PK11_SIGN_RECOVER,
+ PK11_VERIFY,
+ PK11_VERIFY_RECOVER
+} PK11ContextType;
+
+
+struct PK11SessionContextStr {
+ PK11ContextType type;
+ PRBool multi; /* is multipart */
+ void *cipherInfo;
+ unsigned int cipherInfoLen;
+ CK_MECHANISM_TYPE currentMech;
+ PK11Cipher update;
+ PK11Hash hashUpdate;
+ PK11End end;
+ PK11Destroy destroy;
+ PK11Verify verify;
+ unsigned int maxLen;
+};
+
+/*
+ * Sessions (have objects)
+ */
+struct PK11SessionStr {
+ PK11Session *next;
+ PK11Session *prev;
+ CK_SESSION_HANDLE handle;
+ int refCount;
+ void *refLock;
+ void *objectLock;
+ int objectIDCount;
+ CK_SESSION_INFO info;
+ CK_NOTIFY notify;
+ CK_VOID_PTR appData;
+ PK11Slot *slot;
+ PK11SearchResults *search;
+ PK11SessionContext *context;
+ PK11ObjectList *objects[1];
+ FortezzaContext fortezzaContext;
+};
+
+/*
+ * slots (have sessions and objects)
+ */
+struct PK11SlotStr {
+ CK_SLOT_ID slotID;
+ void *sessionLock;
+ void *objectLock;
+ SECItem *password;
+ PRBool hasTokens;
+ PRBool isLoggedIn;
+ PRBool ssoLoggedIn;
+ PRBool needLogin;
+ PRBool DB_loaded;
+ int sessionIDCount;
+ int sessionCount;
+ int rwSessionCount;
+ int tokenIDCount;
+ PK11Object *tokObjects[HASH_SIZE];
+ PK11Session *head[SESSION_HASH_SIZE];
+};
+
+/*
+ * session handle modifiers
+ */
+#define PK11_PRIVATE_KEY_FLAG 0x80000000L
+
+/*
+ * object handle modifiers
+ */
+#define PK11_TOKEN_MASK 0x80000000L
+#define PK11_TOKEN_MAGIC 0x80000000L
+#define PK11_TOKEN_TYPE_MASK 0x70000000L
+#define PK11_TOKEN_TYPE_CERT 0x00000000L
+#define PK11_TOKEN_TYPE_PRIV 0x10000000L
+
+/* how big a password/pin we can deal with */
+#define PK11_MAX_PIN 255
+
+/* slot helper macros */
+#define pk11_SlotFromSessionHandle(handle) (((handle) & PK11_PRIVATE_KEY_FLAG)\
+ ? &pk11_slot[1] : &pk11_slot[0])
+#define PK11_TOSLOT1(handle) handle &= ~PK11_PRIVATE_KEY_FLAG
+#define PK11_TOSLOT2(handle) handle |= PK11_PRIVATE_KEY_FLAG
+#define pk11_SlotFromSession(sp) ((sp)->slot)
+#define pk11_SlotFromID(id) ((id) == NETSCAPE_SLOT_ID ? \
+ &pk11_slot[0] : (((id) == PRIVATE_KEY_SLOT_ID) ? &pk11_slot[1] : NULL))
+#define pk11_isToken(id) (((id) & PK11_TOKEN_MASK) == PK11_TOKEN_MAGIC)
+
+/* queueing helper macros */
+#define pk11_hash(value,size) ((value) & (size-1))/*size must be a power of 2*/
+#define pk11queue_add(element,id,head,hash_size) \
+ { int tmp = pk11_hash(id,hash_size); \
+ (element)->next = (head)[tmp]; \
+ (element)->prev = NULL; \
+ if ((head)[tmp]) (head)[tmp]->prev = (element); \
+ (head)[tmp] = (element); }
+#define pk11queue_find(element,id,head,hash_size) \
+ for( (element) = (head)[pk11_hash(id,hash_size)]; (element) != NULL; \
+ (element) = (element)->next) { \
+ if ((element)->handle == (id)) { break; } }
+#define pk11queue_delete(element,id,head,hash_size) \
+ if ((element)->next) (element)->next->prev = (element)->prev; \
+ if ((element)->prev) (element)->prev->next = (element)->next; \
+ else (head)[pk11_hash(id,hash_size)] = ((element)->next); \
+ (element)->next = NULL; \
+ (element)->prev = NULL; \
+
+/* expand an attribute & secitem structures out */
+#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
+#define pk11_item_expand(ip) (ip)->data,(ip)->len
+
+#endif
+
diff --git a/security/nss/lib/fortcrypt/fpkcs11t.h b/security/nss/lib/fortcrypt/fpkcs11t.h
new file mode 100644
index 000000000..f3c6b0470
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkcs11t.h
@@ -0,0 +1,1098 @@
+/*
+ * 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.
+ */
+/*
+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
+ * is granted provided that it is identified as "RSA Security In.c Public-Key
+ * Cryptography Standards (PKCS)" in all material mentioning or referencing
+ * this document.
+ */
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int CK_LONG;
+
+/* at least 32 bits, each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0
+
+/* these data types are platform/implementation dependent. */
+#if defined(XP_WIN)
+#if defined(_WIN32)
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win32 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(push, cryptoki, 1)
+#else /* win16 */
+#if defined(__WATCOMC__)
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win16 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(push, 1)
+#else /* not Watcom 16-bit */
+#define CK_ENTRY
+#define CK_PTR * /* definition for Win16 */
+#define NULL_PTR 0 /* NULL pointer */
+#pragma pack(1)
+#endif
+#endif
+#else /* not windows */
+#define CK_ENTRY
+#define CK_PTR * /* definition for UNIX */
+#define NULL_PTR 0 /* NULL pointer */
+#endif
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR; /* Pointer to a CK_BYTE */
+typedef CK_CHAR CK_PTR CK_CHAR_PTR; /* Pointer to a CK_CHAR */
+typedef CK_ULONG CK_PTR CK_ULONG_PTR; /* Pointer to a CK_ULONG */
+typedef void CK_PTR CK_VOID_PTR; /* Pointer to a void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; /* Pointer to a CK_VOID_PTR */
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of the version number */
+ CK_BYTE minor; /* hundredths portion of the version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR; /* points to a CK_VERSION */
+
+
+typedef struct CK_INFO {
+ CK_VERSION cryptokiVersion; /* PKCS #11 interface version number */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR; /* points to a CK_INFO structure */
+
+
+/* CK_NOTIFICATION enumerates the types of notifications
+ * that PKCS #11 provides to an application. */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0
+
+
+typedef CK_ULONG CK_SLOT_ID;
+
+/* CK_SLOT_ID_PTR points to a CK_SLOT_ID. */
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot. */
+typedef struct CK_SLOT_INFO {
+ CK_CHAR slotDescription[64]; /* blank padded */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ /* hardwareVersion and firmwareVersion are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bits flags that provide capabilities of the slot.
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is present in the slot */
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* reader supports removable devices*/
+#define CKF_HW_SLOT 0x00000004 /* a hardware slot, not a "soft token"*/
+
+/* CK_SLOT_INFO_PTR points to a CK_SLOT_INFO. */
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token. */
+typedef struct CK_TOKEN_INFO {
+ CK_CHAR label[32]; /* blank padded */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+ * changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sessions currently open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sessions currently open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+
+ /* hardwareVersion, firmwareVersion, and time are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Table 7-2, Token Information Flags
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001 /* has random number generator */
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is write-protected */
+#define CKF_LOGIN_REQUIRED 0x00000004 /* a user must be logged in */
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's PIN is initialized */
+
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, then that means */
+/* that *every* time the state of cryptographic operations of a session is */
+/* successfully saved, all keys needed to continue those operations are */
+/* stored in the state. */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 /* key always saved in saved sessions */
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, then that means that */
+/* the token has some sort of clock. The time on that clock is returned in */
+/* the token info structure. */
+#define CKF_CLOCK_ON_TOKEN 0x00000040 /* token has a clock */
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is true, that means */
+/* that there is some way for the user to login without sending a PIN through */
+/* the PKCS #11 library itself. */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 /* token has protected path */
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, that
+ * means that a single session with the token can perform dual
+ * simultaneous cryptographic operations (digest and encrypt;
+ * decrypt and digest; sign and encrypt; and decrypt and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 /* dual crypto operations */
+
+/* CK_TOKEN_INFO_PTR points to a CK_TOKEN_INFO. */
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a PKCS #11-assigned value that identifies a session. */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+/* CK_SESSION_HANDLE_PTR points to a CK_SESSION_HANDLE. */
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of PKCS #11 users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for v2.0 */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0
+/* Normal user */
+#define CKU_USER 1
+
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for v2.0 */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0
+#define CKS_RO_USER_FUNCTIONS 1
+#define CKS_RW_PUBLIC_SESSION 2
+#define CKS_RW_SO_FUNCTIONS 3
+#define CKS_RW_USER_FUNCTIONS 4
+
+
+/* CK_SESSION_INFO provides information about a session. */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table. */
+/* Table 7-3, Session Information Flags */
+/* Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002 /* session is read/write; not R/O */
+#define CKF_SERIAL_SESSION 0x00000004 /* session doesn't support parallel */
+
+/* CK_SESSION_INFO_PTR points to a CK_SESSION_INFO. */
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an object. */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+/* CK_OBJECT_HANDLE_PTR points to a CK_OBJECT_HANDLE. */
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or types)
+ * of objects that PKCS #11 recognizes. It is defined as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_VENDOR_DEFINED 0x80000000L
+
+/* CK_OBJECT_CLASS_PTR points to a CK_OBJECT_CLASS structure. */
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+
+/* CK_KEY_TYPE is a value that identifies a key type. */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000
+#define CKK_DSA 0x00000001
+#define CKK_DH 0x00000002
+
+/* CKK_ECDSA, and CKK_KEA are new for v2.0 */
+#define CKK_ECDSA 0x00000003
+#define CKK_KEA 0x00000005
+
+#define CKK_GENERIC_SECRET 0x00000010
+#define CKK_RC2 0x00000011
+#define CKK_RC4 0x00000012
+#define CKK_DES 0x00000013
+#define CKK_DES2 0x00000014
+#define CKK_DES3 0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST 0x00000016
+#define CKK_CAST3 0x00000017
+#define CKK_CAST5 0x00000018
+#define CKK_RC5 0x00000019
+#define CKK_IDEA 0x0000001A
+#define CKK_SKIPJACK 0x0000001B
+#define CKK_BATON 0x0000001C
+#define CKK_JUNIPER 0x0000001D
+#define CKK_CDMF 0x0000001E
+
+#define CKK_VENDOR_DEFINED 0x80000000L
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate type. */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+#define CKC_X_509 0x00000000
+#define CKC_VENDOR_DEFINED 0x80000000L
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute type. */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000
+#define CKA_TOKEN 0x00000001
+#define CKA_PRIVATE 0x00000002
+#define CKA_LABEL 0x00000003
+#define CKA_APPLICATION 0x00000010
+#define CKA_VALUE 0x00000011
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+#define CKA_KEY_TYPE 0x00000100
+#define CKA_SUBJECT 0x00000101
+#define CKA_ID 0x00000102
+#define CKA_SENSITIVE 0x00000103
+#define CKA_ENCRYPT 0x00000104
+#define CKA_DECRYPT 0x00000105
+#define CKA_WRAP 0x00000106
+#define CKA_UNWRAP 0x00000107
+#define CKA_SIGN 0x00000108
+#define CKA_SIGN_RECOVER 0x00000109
+#define CKA_VERIFY 0x0000010A
+#define CKA_VERIFY_RECOVER 0x0000010B
+#define CKA_DERIVE 0x0000010C
+#define CKA_START_DATE 0x00000110
+#define CKA_END_DATE 0x00000111
+#define CKA_MODULUS 0x00000120
+#define CKA_MODULUS_BITS 0x00000121
+#define CKA_PUBLIC_EXPONENT 0x00000122
+#define CKA_PRIVATE_EXPONENT 0x00000123
+#define CKA_PRIME_1 0x00000124
+#define CKA_PRIME_2 0x00000125
+#define CKA_EXPONENT_1 0x00000126
+#define CKA_EXPONENT_2 0x00000127
+#define CKA_COEFFICIENT 0x00000128
+#define CKA_PRIME 0x00000130
+#define CKA_SUBPRIME 0x00000131
+#define CKA_BASE 0x00000132
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, CKA_ALWAYS_SENSITIVE, */
+/* and CKA_MODIFIABLE are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+#define CKA_MODIFIABLE 0x00000170
+
+#define CKA_VENDOR_DEFINED 0x80000000L
+
+/* CK_ATTRIBUTE is a structure that includes the type, length and value
+ * of an attribute. */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+
+ /* ulValueLen was changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+/* CK_ATTRIBUTE_PTR points to a CK_ATTRIBUTE. */
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date. */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism type. */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
+#define CKM_RSA_PKCS 0x00000001
+#define CKM_RSA_9796 0x00000002
+#define CKM_RSA_X_509 0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS are */
+/* new for v2.0. They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS 0x00000004
+#define CKM_MD5_RSA_PKCS 0x00000005
+#define CKM_SHA1_RSA_PKCS 0x00000006
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+#define CKM_RC2_KEY_GEN 0x00000100
+#define CKM_RC2_ECB 0x00000101
+#define CKM_RC2_CBC 0x00000102
+#define CKM_RC2_MAC 0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new to v2.0 */
+#define CKM_RC2_MAC_GENERAL 0x00000104
+#define CKM_RC2_CBC_PAD 0x00000105
+
+#define CKM_RC4_KEY_GEN 0x00000110
+#define CKM_RC4 0x00000111
+#define CKM_DES_KEY_GEN 0x00000120
+#define CKM_DES_ECB 0x00000121
+#define CKM_DES_CBC 0x00000122
+#define CKM_DES_MAC 0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new to v2.0 */
+#define CKM_DES_MAC_GENERAL 0x00000124
+#define CKM_DES_CBC_PAD 0x00000125
+
+#define CKM_DES2_KEY_GEN 0x00000130
+#define CKM_DES3_KEY_GEN 0x00000131
+#define CKM_DES3_ECB 0x00000132
+#define CKM_DES3_CBC 0x00000133
+#define CKM_DES3_MAC 0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, */
+/* CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, CKM_CDMF_MAC_GENERAL, */
+/* and CKM_CDMF_CBC_PAD are new to v2.0 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#define CKM_CDMF_KEY_GEN 0x00000140
+#define CKM_CDMF_ECB 0x00000141
+#define CKM_CDMF_CBC 0x00000142
+#define CKM_CDMF_MAC 0x00000143
+#define CKM_CDMF_MAC_GENERAL 0x00000144
+#define CKM_CDMF_CBC_PAD 0x00000145
+
+#define CKM_MD2 0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new to v2.0 */
+#define CKM_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
+
+#define CKM_MD5 0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new to v2.0 */
+#define CKM_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
+
+#define CKM_SHA_1 0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new to v2.0 */
+#define CKM_SHA_1_HMAC 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+
+/* All the following mechanisms are new to v2.0 */
+#define CKM_CAST_KEY_GEN 0x00000300
+#define CKM_CAST_ECB 0x00000301
+#define CKM_CAST_CBC 0x00000302
+#define CKM_CAST_MAC 0x00000303
+#define CKM_CAST_MAC_GENERAL 0x00000304
+#define CKM_CAST_CBC_PAD 0x00000305
+#define CKM_CAST3_KEY_GEN 0x00000310
+#define CKM_CAST3_ECB 0x00000311
+#define CKM_CAST3_CBC 0x00000312
+#define CKM_CAST3_MAC 0x00000313
+#define CKM_CAST3_MAC_GENERAL 0x00000314
+#define CKM_CAST3_CBC_PAD 0x00000315
+#define CKM_CAST5_KEY_GEN 0x00000320
+#define CKM_CAST5_ECB 0x00000321
+#define CKM_CAST5_CBC 0x00000322
+#define CKM_CAST5_MAC 0x00000323
+#define CKM_CAST5_MAC_GENERAL 0x00000324
+#define CKM_CAST5_CBC_PAD 0x00000325
+#define CKM_RC5_KEY_GEN 0x00000330
+#define CKM_RC5_ECB 0x00000331
+#define CKM_RC5_CBC 0x00000332
+#define CKM_RC5_MAC 0x00000333
+#define CKM_RC5_MAC_GENERAL 0x00000334
+#define CKM_RC5_CBC_PAD 0x00000335
+#define CKM_IDEA_KEY_GEN 0x00000340
+#define CKM_IDEA_ECB 0x00000341
+#define CKM_IDEA_CBC 0x00000342
+#define CKM_IDEA_MAC 0x00000343
+#define CKM_IDEA_MAC_GENERAL 0x00000344
+#define CKM_IDEA_CBC_PAD 0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
+#define CKM_XOR_BASE_AND_DATA 0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+#define CKM_SSL3_MD5_MAC 0x00000380
+#define CKM_SSL3_SHA1_MAC 0x00000381
+#define CKM_MD5_KEY_DERIVATION 0x00000390
+#define CKM_MD2_KEY_DERIVATION 0x00000391
+#define CKM_SHA1_KEY_DERIVATION 0x00000392
+#define CKM_PBE_MD2_DES_CBC 0x000003A0
+#define CKM_PBE_MD5_DES_CBC 0x000003A1
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
+#define CKM_PBE_SHA1_RC4_128 0x000003A6
+#define CKM_PBE_SHA1_RC4_40 0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN 0x00001000
+#define CKM_SKIPJACK_ECB64 0x00001001
+#define CKM_SKIPJACK_CBC64 0x00001002
+#define CKM_SKIPJACK_OFB64 0x00001003
+#define CKM_SKIPJACK_CFB64 0x00001004
+#define CKM_SKIPJACK_CFB32 0x00001005
+#define CKM_SKIPJACK_CFB16 0x00001006
+#define CKM_SKIPJACK_CFB8 0x00001007
+#define CKM_SKIPJACK_WRAP 0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
+#define CKM_SKIPJACK_RELAYX 0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
+#define CKM_KEA_KEY_DERIVE 0x00001011
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
+#define CKM_BATON_KEY_GEN 0x00001030
+#define CKM_BATON_ECB128 0x00001031
+#define CKM_BATON_ECB96 0x00001032
+#define CKM_BATON_CBC128 0x00001033
+#define CKM_BATON_COUNTER 0x00001034
+#define CKM_BATON_SHUFFLE 0x00001035
+#define CKM_BATON_WRAP 0x00001036
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+#define CKM_JUNIPER_KEY_GEN 0x00001060
+#define CKM_JUNIPER_ECB128 0x00001061
+#define CKM_JUNIPER_CBC128 0x00001062
+#define CKM_JUNIPER_COUNTER 0x00001063
+#define CKM_JUNIPER_SHUFFLE 0x00001064
+#define CKM_JUNIPER_WRAP 0x00001065
+#define CKM_FASTHASH 0x00001070
+
+#define CKM_VENDOR_DEFINED 0x80000000L
+
+
+/* CK_MECHANISM_TYPE_PTR points to a CK_MECHANISM_TYPE structure. */
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular mechanism. */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+/* CK_MECHANISM_PTR points to a CK_MECHANISM structure. */
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular mechanism. */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows.
+ * Table 7-4, Mechanism Information FLags
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001 /* performed by HW device; not SW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, CKG_SIGN_RECOVER, */
+/* CKF_VERIFY, CKF_VERIFY_RECOVER, CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, */
+/* CKF_UNWRAP, and CKF_DERIVE are new for v2.0 */
+#define CKF_ENCRYPT 0x00000100 /* can be used with C_EncryptInit */
+#define CKF_DECRYPT 0x00000200 /* can be used with C_DecryptInit */
+#define CKF_DIGEST 0x00000400 /* can be used with C_DigestInit */
+#define CKF_SIGN 0x00000800 /* can be used with C_SignInit */
+#define CKF_SIGN_RECOVER 0x00001000 /* can use with C_SignRecoverInit */
+#define CKF_VERIFY 0x00002000 /* can be used with C_VerifyInit */
+#define CKF_VERIFY_RECOVER 0x00004000 /* can use w/ C_VerifyRecoverInit */
+#define CKF_GENERATE 0x00008000L /* can be used with C_GenerateKey */
+#define CKF_GENERATE_KEY_PAIR 0x00010000L /* can use with C_GenerateKeyPair */
+#define CKF_WRAP 0x00020000L /* can be used with C_WrapKey */
+#define CKF_UNWRAP 0x00040000L /* can be used with C_UnwrapKey */
+#define CKF_DERIVE 0x00080000L /* can be used with C_DeriveKey */
+
+#define CKF_EXTENSION 0x80000000L /* Must be FALSE for this version */
+
+/* CK_MECHANISM_INFO_PTR points to a CK_MECHANISM_INFO structure. */
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a PKCS #11 function. */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000
+#define CKR_CANCEL 0x00000001
+#define CKR_HOST_MEMORY 0x00000002
+#define CKR_SLOT_ID_INVALID 0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR 0x00000005
+#define CKR_FUNCTION_FAILED 0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD 0x00000007
+#define CKR_NO_EVENT 0x00000008
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
+#define CKR_CANT_LOCK 0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
+#define CKR_DATA_INVALID 0x00000020
+#define CKR_DATA_LEN_RANGE 0x00000021
+#define CKR_DEVICE_ERROR 0x00000030
+#define CKR_DEVICE_MEMORY 0x00000031
+#define CKR_DEVICE_REMOVED 0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
+#define CKR_FUNCTION_CANCELED 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE 0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are
+ * new for v2.0 */
+#define CKR_KEY_NOT_NEEDED 0x00000064
+#define CKR_KEY_CHANGED 0x00000065
+#define CKR_KEY_NEEDED 0x00000066
+#define CKR_KEY_INDIGESTIBLE 0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+
+#define CKR_MECHANISM_INVALID 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
+#define CKR_OPERATION_ACTIVE 0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
+#define CKR_PIN_INCORRECT 0x000000A0
+#define CKR_PIN_INVALID 0x000000A1
+#define CKR_PIN_LEN_RANGE 0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED 0x000000A3
+#define CKR_PIN_LOCKED 0x000000A4
+
+#define CKR_SESSION_CLOSED 0x000000B0
+#define CKR_SESSION_COUNT 0x000000B1
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
+#define CKR_SESSION_READ_ONLY 0x000000B5
+#define CKR_SESSION_EXISTS 0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and CKR_SESSION_READ_WRITE_SO_EXISTS
+ * are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
+
+#define CKR_SIGNATURE_INVALID 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
+#define CKR_USER_NOT_LOGGED_IN 0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
+#define CKR_USER_TYPE_INVALID 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
+#define CKR_USER_TOO_MANY_TYPES 0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG 0x00000121
+#define CKR_INSERTION_CALLBACK_SET 0x00000140
+#define CKR_INSERTION_CALLBACK_NOT_SUPPORTED 0x00000141
+#define CKR_BUFFER_TOO_SMALL 0x00000150
+#define CKR_SAVED_STATE_INVALID 0x00000160
+#define CKR_INFORMATION_SENSITIVE 0x00000170
+#define CKR_STATE_UNSAVEABLE 0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
+#define CKR_MUTEX_BAD 0x000001A0
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+
+#define CKR_VENDOR_DEFINED 0x80000000L
+
+
+/* CK_NOTIFY is an application callback that processes events. */
+typedef CK_RV (CK_ENTRY CK_PTR CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* same as passed to C_OpenSession. */
+);
+
+/* CK_FUNCTION_LIST is going to be a structure holding a PKCS #11 spec */
+/* version and pointers of appropriate types to all the PKCS #11 functions. */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+/* CK_CREATEMUTEX is an application callback for creating a mutex */
+typedef CK_RV CK_ENTRY (CK_PTR CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive pointer to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a mutex */
+typedef CK_RV CK_ENTRY (CK_PTR CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_RV CK_ENTRY (CK_PTR CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a mutex */
+typedef CK_RV CK_ENTRY (CK_PTR CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to C_Initialize
+*/
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 /* library may not
+ * spawn its own
+ * threads */
+#define CKF_OS_LOCKING_OK 0x00000002 /* library can use
+ * native operating
+ * system thread
+ * synchronization */
+
+/* CK_C_INITIALIZE_ARGS_PTR is a pointer to a CK_C_INITIALIZE_ARGS */
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the CKM_KEA_DERIVE
+ * mechanism. */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+/* CK_KEA_DERIVE_PARAMS_PTR points to a CK_KEA_DERIVE_PARAMS. */
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and CKM_RC2_MAC */
+/* mechanisms. An instance of CK_RC2_PARAMS just holds the effective keysize. */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+
+/* CK_RC2_PARAMS_PTR points to a CK_RC2_PARAMS. */
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC mechanism. */
+typedef struct CK_RC2_CBC_PARAMS {
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+/* CK_RC2_CBC_PARAMS_PTR points to a CK_RC2_CBC_PARAMS. */
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the */
+/* CKM_RC2_MAC_GENERAL mechanism. */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and CKM_RC5_MAC */
+/* mechanisms. */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+/* CK_RC5_PARAMS_PTR points to a CK_RC5_PARAMS. */
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC mechanism. */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+/* CK_RC5_CBC_PARAMS_PTR points to a CK_RC5_CBC_PARAMS. */
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the */
+/* CKM_RC5_MAC_GENERAL mechanism. */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block ciphers' */
+/* MAC_GENERAL mechanisms. Its value is the length of the MAC. */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS_PTR points to a
+ * CK_SKIPJACK_PRIVATE_WRAP_PARAMS */
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+/* CK_SKIPJACK_RELAYX_PARAMS_PTR points to a CK_SKIPJACK_RELAYX_PARAMS
+*/
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+typedef struct CK_PBE_PARAMS {
+ CK_CHAR_PTR pInitVector;
+ CK_CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_CHAR_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the */
+/* CKM_KEY_WRAP_SET_OAEP mechanism. */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS_PTR points to a CK_KEY_WRAP_SET_OAEP_PARAMS. */
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+/* CK_BATON_PARAMS provides the parameters to the CKM_BATON_ECB128, */
+/* CKM_BATON_ECB96, CKM_BATON_CBC128, CKM_BATON_COUNTER, and */
+/* CKM_BATON_SHUFFLE mechanisms. */
+/* CK_BATON_PARAMS is new for v2.0 */
+typedef struct CK_BATON_PARAMS {
+ CK_BYTE iv[24];
+} CK_BATON_PARAMS;
+
+/* CK_BATON_PARAMS_PTR points to a CK_BATON_PARAMS. */
+typedef CK_BATON_PARAMS CK_PTR CK_BATON_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+/* The CK_DERIVATION_STRING_DATA is used for bunches of Deriviation
+ * Mechanisms. */
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+/* The CK_EXTRACT_PARAMS is used for the CKM_EXTRACT_KEY_FROM_KEY mechanism. */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+/* CK_EXTRACT_PARAMS_PTR points to a CK_EXTRACT_PARAMS. */
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+
+/* Do not attempt to use these. They are only used by NETSCAPE's internal
+ * PKCS #11 interface. Most of these are place holders for other mechanism
+ * and will change in the future.
+ */
+#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
+#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
+#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
+#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
+#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
+
+/* define used to pass in the database key for DSA private keys */
+#define CKA_NETSCAPE_DB 0xD5A0DB00L
+#define CKA_NETSCAPE_TRUST 0x80000001L
+
+#if defined(XP_WIN)
+#if defined(_WIN32)
+#pragma pack(pop, cryptoki)
+#else /* win16 */
+#if defined(__WATCOMC__)
+#pragma pack(pop)
+#else /* not Watcom 16-bit */
+#pragma pack()
+#endif
+#endif
+#endif
+
+#endif
diff --git a/security/nss/lib/fortcrypt/fpkmem.h b/security/nss/lib/fortcrypt/fpkmem.h
new file mode 100644
index 000000000..f0530dbcb
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkmem.h
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+#ifndef _FPKMEM_H_
+#define _FPKMEM_H_
+
+#define PORT_Free free
+#define PORT_Alloc malloc
+
+#define PORT_Memcmp memcmp
+#define PORT_Memcpy memcpy
+
+#define NUM_SLOTS 32
+
+#if !defined (XP_UNIX) && !defined (_WINDOWS)
+#define XP_MAC 1 /*Make sure we get this define in for Mac builds*/
+#endif
+
+#endif /*_FPKMEM_H_*/
diff --git a/security/nss/lib/fortcrypt/fpkstrs.h b/security/nss/lib/fortcrypt/fpkstrs.h
new file mode 100644
index 000000000..144ea1ee7
--- /dev/null
+++ b/security/nss/lib/fortcrypt/fpkstrs.h
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+#ifndef _context_h_
+#define _context_h_
+
+#ifdef SWFORT
+#ifndef RETURN_TYPE
+#define RETURN_TYPE int
+#endif
+#endif
+#include "cryptint.h"
+#include "genci.h"
+#include "maci.h"
+
+typedef enum {NOKEY, TEK, MEK, UNWRAP, Ks} FortezzaKeyType;
+typedef enum {Encrypt, Decrypt, Sign, None} CryptoType;
+
+typedef struct FortezzaKeyStr *FortezzaKeyPtr;
+typedef struct FortezzaSocketStr *FortezzaSocketPtr;
+typedef struct FortezzaKeyStr FortezzaKey;
+typedef unsigned char FortezzaMEK[12];
+
+
+typedef struct CreateTEKInfoStr {
+ CI_RA Ra;
+ CI_RB Rb;
+ unsigned long randomLen;
+ int personality;
+ int flag; /*Either CI_INITIATOR_FLAG or CI_RECIPIENT_FLAG*/
+ CI_Y pY;
+ unsigned int YSize;
+} CreateTEKInfo;
+
+typedef struct FortezzaTEKStr {
+ CI_RA Ra; /*All the parameters necessary to create a TEK */
+ CI_RB Rb;
+ unsigned long randomLen;
+ CI_Y pY;
+ int flags;
+ int registerIndex;
+ unsigned int ySize;
+} FortezzaTEK;
+
+struct FortezzaKeyStr {
+ FortezzaKeyPtr next, prev;
+ CK_OBJECT_HANDLE keyHandle;
+ int keyRegister;
+ FortezzaKeyType keyType;
+ FortezzaSocketPtr keySocket;
+ unsigned long id;
+ unsigned long hitCount;
+ union {
+ FortezzaTEK tek;
+ FortezzaMEK mek;
+ } keyData;
+};
+
+typedef struct FortezzaSocketStr {
+ PRBool isOpen;
+ PRBool isLoggedIn;
+ PRBool hasLoggedIn;
+ PRBool personalitiesLoaded;
+ unsigned long slotID;
+ unsigned long hitCount;
+ HSESSION maciSession;
+ CI_SERIAL_NUMBER openCardSerial;
+ CI_STATE openCardState;
+ CI_PERSON *personalityList;
+ int numPersonalities;
+ int numKeyRegisters;
+ FortezzaKey **keyRegisters; /*Array of pointers to keys in registers*/
+ FortezzaKey *keys; /*Linked list of all the keys*/
+ void *registersLock;
+} FortezzaSocket;
+
+typedef struct PK11SessionStr *PK11SessionPtr;
+
+typedef struct FortezzaConstextStr {
+ FortezzaKey *fortezzaKey;
+ FortezzaSocket *fortezzaSocket;
+ PK11SessionPtr session;
+ CryptoType cryptoOperation;
+ CK_MECHANISM_TYPE mechanism;
+ CI_SAVE_DATA cardState;
+ CI_IV cardIV;
+ unsigned long userRamSize;
+ CK_OBJECT_HANDLE hKey;
+} FortezzaContext;
+
+
+
+#endif /*_context_h_*/
diff --git a/security/nss/lib/fortcrypt/genci.h b/security/nss/lib/fortcrypt/genci.h
new file mode 100644
index 000000000..7868e1853
--- /dev/null
+++ b/security/nss/lib/fortcrypt/genci.h
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+/*
+ * the following header file switches between MACI and CI based on
+ * compile options. That lest the rest of the source code operate
+ * without change, even if it only suports CI_ calls, not MACI_ calls
+ */
+#ifndef _GENCI_H_
+#define _GENCI_H_ 1
+#include "seccomon.h"
+
+#if defined (XP_UNIX) || defined (XP_WIN32)
+
+/*
+ * On unix, NT, and Windows '95 we use full maci
+ */
+#include "maci.h"
+
+#define MACI_SEL(x)
+
+/*
+ * for sec-for.c
+ */
+#define CI_Initialize MACI_Initialize
+#define CI_Terminate() { HSESSION hs;\
+ MACI_GetSessionID(&hs);\
+ MACI_Terminate(hs); }
+
+#else
+
+/*
+ * On Mac we use the original CI_LIB
+ */
+#include "cryptint.h"
+
+/*
+ * MACI specific values not defined for CI lib
+ */
+#define MACI_SESSION_EXCEEDED (-53)
+
+#ifndef HSESSION_DEFINE
+typedef unsigned int HSESSION;
+#define HSESSION_DEFINE
+#endif
+
+/*
+ * Map MACI_ calls to CI_ calls. NOTE: this assumes the proper CI_Select
+ * calls are issued in the CI_ case
+ */
+#define MACI_ChangePIN(s,pin,old,new) CI_ChangePIN(pin,old,new)
+#define MACI_CheckPIN(s,type,pin) CI_CheckPIN(type,pin)
+#define MACI_Close(s,flag,socket) CI_Close(flag,socket)
+#define MACI_Decrypt(s,size,in,out) CI_Decrypt(size,in,out)
+#define MACI_DeleteCertificate(s,cert) CI_DeleteCertificate(cert)
+#define MACI_DeleteKey(s,index) CI_DeleteKey(index)
+#define MACI_Encrypt(s,size,in,out) CI_Encrypt(size,in,out)
+#define MACI_ExtractX(s,cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) \
+ CI_ExtractX(cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g)
+#define MACI_FirmwareUpdate(s,flags,Cksum,len,size,data) \
+ CI_FirmwareUpdate(flags,Cksum,len,size,data)
+#define MACI_GenerateIV(s,iv) CI_GenerateIV(iv)
+#define MACI_GenerateMEK(s,index,res) CI_GenerateMEK(index,res)
+#define MACI_GenerateRa(s,Ra) CI_GenerateRa(Ra)
+#define MACI_GenerateRandom(s,ran) CI_GenerateRandom(ran)
+#define MACI_GenerateTEK(s,flag,index,Ra,Rb,size,Y) \
+ CI_GenerateTEK(flag,index,Ra,Rb,size,Y)
+#define MACI_GenerateX(s,cert,type,pgSize,qSize,p,q,g,ySize,y) \
+ CI_GenerateX(cert,type,pgSize,qSize,p,q,g,ySize,y)
+#define MACI_GetCertificate(s,cert,val) CI_GetCertificate(cert,val)
+#define MACI_GetConfiguration(s,config) CI_GetConfiguration(config)
+#define MACI_GetHash(s,size,data,val) CI_GetHash(size,data,val)
+#define MACI_GetPersonalityList(s,cnt,list) CI_GetPersonalityList(cnt,list)
+#define MACI_GetSessionID(s) CI_OK
+#define MACI_GetState(s,state) CI_GetState(state)
+#define MACI_GetStatus(s,status) CI_GetStatus(status)
+#define MACI_GetTime(s,time) CI_GetTime(time)
+#define MACI_Hash(s,size,data) CI_Hash(size,data)
+#define MACI_Initialize(count) CI_Initialize(count)
+#define MACI_InitializeHash(s) CI_InitializeHash()
+#define MACI_InstallX(s,cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g) \
+ CI_InstallX(cert,type,pass,ySize,y,x,Ra,pgSize,qSize,p,q,g)
+#define MACI_LoadCertificate(s,cert,label,data,res) \
+ CI_LoadCertificate(cert,label,data,res)
+#define MACI_LoadDSAParameters(s,pgSize,qSize,p,q,g) \
+ CI_LoadDSAParameters(pgSize,qSize,p,q,g)
+#define MACI_LoadInitValues(s,seed,Ks) CI_LoadInitValues(seed,Ks)
+#define MACI_LoadIV(s,iv) CI_LoadIV(iv)
+#define MACI_LoadX(s,cert,type,pgSize,qSize,p,q,g,x,ySize,y) \
+ CI_LoadX(cert,type,pgSize,qSize,p,q,g,x,ySize,y)
+#define MACI_Lock(s,flags) CI_Lock(flags)
+#define MACI_Open(s,flags,index) CI_Open(flags,index)
+#define MACI_RelayX(s,oPass,oSize,oY,oRa,oX,nPass,nSize,nY,nRa,nX) \
+ CI_RelayX(oPass,oSize,oY,oRa,oX,nPass,nSize,nY,nRa,nX)
+#define MACI_Reset(s) CI_Reset()
+#define MACI_Restore(s,type,data) CI_Restore(type,data)
+#define MACI_Save(s,type,data) CI_Save(type,data)
+#define MACI_Select(s,socket) CI_Select(socket)
+#define MACI_SetConfiguration(s,typ,sz,d) CI_SetConfiguration(typ,sz,d)
+#define MACI_SetKey(s,key) CI_SetKey(key)
+#define MACI_SetMode(s,type,mode) CI_SetMode(type,mode)
+#define MACI_SetPersonality(s,index) CI_SetPersonality(index)
+#define MACI_SetTime(s,time) CI_SetTime(time)
+#define MACI_Sign(s,hash,sig) CI_Sign(hash,sig)
+#define MACI_Terminate(s) CI_Terminate()
+#define MACI_TimeStamp(s,val,sig,time) CI_TimeStamp(val,sig,time)
+#define MACI_Unlock(s) CI_Unlock()
+#define MACI_UnwrapKey(s,targ,wrap,key) CI_UnwrapKey(targ,wrap,key)
+#define MACI_VerifySignature(s,h,siz,y,sig) CI_VerifySignature(h,siz,y,sig)
+#define MACI_VerifyTimeStamp(s,hash,sig,tim) CI_VerityTimeStap(hash,sig,tim)
+#define MACI_WrapKey(s,src,wrap,key) CI_WrapKey(src,wrap,key)
+#define MACI_Zeroize(s) CI_Zeroize()
+
+#define MACI_SEL(x) CI_Select(x)
+#endif /* ! XP_UNIX */
+#endif /* _GENCI_H_ */
diff --git a/security/nss/lib/fortcrypt/globinst.htm b/security/nss/lib/fortcrypt/globinst.htm
new file mode 100644
index 000000000..cd0a194d4
--- /dev/null
+++ b/security/nss/lib/fortcrypt/globinst.htm
@@ -0,0 +1,139 @@
+<HTML>
+<--
+ - 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.
+-->
+<SCRIPT>
+
+
+// ---------------------- Configuration variables ----------------
+var pkcs11jar="fortpk11.jar";
+//var pkcs11base="file://d|/dogbert/ns/dist/";
+pkcs11base="";
+
+var comm_platforms = pk_init_array (
+ "Win32", "Win16", "Mac68k", "MacPPC",
+ "AIX4.1", "HP-UXA.09", "HP-UXB.10",
+ "SunOS4.1.3_U1", "SunOS5.4", "SunOS5.5.1" );
+var directories = pk_init_array (
+ "win32", "win16", "none", "macppc",
+ "aix", "hpux", "hpux",
+ "sunos", "sol24",
+ "sol251" );
+
+function mapPlatform(InPlat)
+{
+ for (i=0; i < comm_platforms.length; i++) {
+ if (InPlat == comm_platforms[i]) {
+ return directories[i];
+ }
+ }
+ return InPlat;
+}
+
+
+function pk_init_array()
+{
+ var numArgs = pk_init_array.arguments.length;
+ var a = new Array(numArgs);
+
+ for (var i = 0; i < numArgs; i++) {
+ a[i] = pk_init_array.arguments[i];
+ }
+ return a;
+}
+
+function getPlatform() {
+ return navigator.platform;
+// var string = navigator.appVersion;
+// start = string.indexOf("(",0);
+// if (start == -1) {
+// return "unknown";
+// }
+// end = string.indexOf(";",start);
+// if (end == -1) {
+// end = string.indexOf(")",start);
+// }
+// if (end == -1) {
+// end = string.length;
+// }
+// platform = string.substring(start+1,end);
+// return platform;
+}
+
+function getURLPath() {
+ var string = window.location.href;
+ end = string.lastIndexOf("/");
+ if (end == -1) {
+ end = string.length-1;
+ }
+ return string.substring(0,end+1);
+}
+
+
+
+plat=getPlatform();
+platDir = mapPlatform(plat);
+if (pkcs11base == "") pkcs11base=getURLPath();
+
+if (plat == "MacPPC") {
+ pkcs11jar= "macinst.htm"
+}
+
+function DoInstall(url) {
+ window.location.href = url;
+}
+
+function DoCancel() {
+ // set window.location.href to your home page if you wish
+ //alert('Cancel Installation?');
+ history.back();
+}
+
+// ------ Change the following for your own Message --------
+document.write("<CENTER><H1>Netscape Fortezza PKCS #11 Module Installer</H1>");
+document.write("</CENTER>");
+document.write("<Table><TR><TD>");
+document.write("<DD><p><IMG SRC=about:logo WIDTH=90 Height=77 NAME=LITRONIC></TD>");
+document.write("<TD VAlign=Center><i> Netscape Fortezza PKCS #11 Modules require Litronic's MACI drivers to be installed on your platform.");
+document.write(" If you haven't already installed theLitronic MACI drivers, please to do so now.</I>");
+document.write("</TD></TR></Table>");
+// ----- end of generic message section --------
+document.write("<p>Netscape has detected you are installing on <b>"+plat+"</b>.<br>");
+document.write("Installing: <b>"+pkcs11base+platDir+"/"+pkcs11jar+"</b><br>");
+document.write("<FORM>");
+document.write("<CENTER><Table><TR><TD><Input Type=Button name=install value='Install Now' onclick=DoInstall("+ "\"" +pkcs11base+platDir+"/"+pkcs11jar+"\""+")>");
+document.write("</TD><TD><Input type=Button name=cancel value=Cancel Onclick=DoCancel()>");
+document.write("</TD></TR></Table></CENTER>");
+document.write("</FORM>");
+document.close();
+</SCRIPT>
+</HTML>
diff --git a/security/nss/lib/fortcrypt/handinst.htm b/security/nss/lib/fortcrypt/handinst.htm
new file mode 100644
index 000000000..f816432e1
--- /dev/null
+++ b/security/nss/lib/fortcrypt/handinst.htm
@@ -0,0 +1,180 @@
+<HTML>
+<TITLE>Generic PKCS #11 Installer</TITLE>
+<--
+ - 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.
+-->
+<SCRIPT>
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG;
+
+
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3 // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1 // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4 // Error deleting a module
+JS_ERR_ADD_MODULE = -5 // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid
+
+var new_window;
+var has_new_window = 0;
+
+function HandleCipher(checkBox) {
+ if (checkBox.checked) {
+ pkcs11MechanismFlags |= checkBox.value;
+ } else {
+ pkcs11MechanismFlags &= ~checkBox.value;
+ }
+}
+
+function HandleSSL(checkBox) {
+ if (checkBox.checked) {
+ pkcs11CipherFlags |= checkBox.value;
+ } else {
+ pkcs11CipherFlags &= ~checkBox.value;
+ }
+}
+
+function colonize(string) {
+ len = string.length;
+ end = len -1;
+
+ if (len == 0) return string;
+
+
+ for (i=0; i < len; i++) {
+ if (string.charAt(i) == "/") {
+ if (i == 0) {
+ new_string = ":" + string.substring(1,len);
+ } else if (i == end) {
+ new_string = string.substring(0,i)+':';
+ } else {
+ new_string = string.substring(0,i)+':'+
+ string.substring(i+1,len);
+ }
+ string = new_string;
+ }
+ }
+
+ if (string.charAt(0) == ":") string = string.substring(1,len);
+ return string;
+}
+
+function DoInstall(name,module) {
+ if ((navigator.platform == "MacPPC")
+ || (navigator.platform == "Mac68K")) {
+ module = colonize(module);
+ }
+ result = pkcs11.addmodule(name, module,
+ pkcs11MechanismFlags, pkcs11CipherFlags);
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ }
+ if (has_new_window) new_window.close();
+}
+
+default_name = "Netscape FORTEZZA Module"
+
+default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll"
+document.writeln("<FORM name=instform target=_self> <H2>PKCS #11 Installer</H2>");
+document.writeln(" Module name: <Input Type=Text Name=modName value=\""+default_name+"\" size=50 required><br>");
+document.writeln(" Module Library: <Input Type=FILE required Name=module><p>");
+document.writeln("<hr><TABLE><TR><TD>");
+document.writeln("<Input type=Checkbox name=RSA value="+PKCS11_MECH_RSA_FLAG+" onclick=HandleCipher(document.instform.RSA)> RSA<br>");
+document.writeln("<Input type=Checkbox name=DSA value="+PKCS11_MECH_DSA_FLAG+" onclick=HandleCipher(document.instform.DSA)> DSA<br>");
+document.writeln("<Input type=Checkbox name=RC2 value="+PKCS11_MECH_RC2_FLAG+" onclick=HandleCipher(document.instform.RC2)> RC2<br>");
+document.writeln("<Input type=Checkbox name=RC4 value="+PKCS11_MECH_RC4_FLAG+" onclick=HandleCipher(document.instform.RC4)> RC4<br>");
+document.writeln("</TD><TD>");
+document.writeln("<Input type=Checkbox name=DES value="+PKCS11_MECH_DES_FLAG+" onclick=HandleCipher(document.instform.DES)> DES<br>");
+document.writeln("<Input type=Checkbox name=DH value="+PKCS11_MECH_DH_FLAG+" onclick=HandleCipher(document.instform.DH)> DH<br>");
+document.writeln("<Input type=Checkbox name=SKIPJACK value="+PKCS11_MECH_SKIPJACK_FLAG+" onclick=HandleCipher(document.instform.SKIPJACK)> SKIPJACK<br>");
+document.writeln("<Input type=Checkbox name=RC5 value="+PKCS11_MECH_RC5_FLAG+" onclick=HandleCipher(document.instform.RC5)> RC5<br>");
+document.writeln("</TD><TD>");
+document.writeln("<Input type=Checkbox name=SHA1 value="+PKCS11_MECH_SHA1_FLAG+" onclick=HandleCipher(document.instform.SHA1)> SHA1<br>");
+document.writeln("<Input type=Checkbox name=MD5 value="+PKCS11_MECH_MD5_FLAG+" onclick=HandleCipher(document.instform.MD5)> MD5<br>");
+document.writeln("<Input type=Checkbox name=MD2 value="+PKCS11_MECH_MD2_FLAG+" onclick=HandleCipher(document.instform.MD2)> MD2<br>");
+document.writeln("</TD><TD>");
+document.writeln("<Input type=Checkbox name=Random value="+PKCS11_MECH_RANDOM_FLAG+" CHECKED onclick=HandleCipher(document.instform.Random)> Random Number Generation<br>");
+document.writeln("<Input type=Checkbox name=readCert value="+PKCS11_PUB_READABLE_CERT_FLAG+" onclick=HandleCipher(document.instform.ReadCert)> Public Readable Certificates<br>");
+document.writeln("<Input type=Checkbox name=Disable value="+PKCS11_DISABLE_FLAG+" onclick=HandleCipher(document.instform.Disable)> Disable<br>");
+document.writeln("</TD></TR></TABLE>");
+document.writeln("<hr>");
+document.writeln("<Input type=Checkbox name=fortssl value="+ PKCS11_CIPHER_FORTEZZA_FLAG +" checked onclick=HandleSSL(document.instform.fortssl)> Enable FORTEZZA menus<br>");
+document.writeln("<hr>");
+document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall(");
+document.writeln( "document.instform.modName.value,document.instform.module.value) >");
+document.writeln("</FORM>");
+</SCRIPT>
diff --git a/security/nss/lib/fortcrypt/homeinst.htm b/security/nss/lib/fortcrypt/homeinst.htm
new file mode 100644
index 000000000..a0583fbc7
--- /dev/null
+++ b/security/nss/lib/fortcrypt/homeinst.htm
@@ -0,0 +1,211 @@
+<HTML>
+<--
+ - 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.
+-->
+<SCRIPT>
+
+
+// ---------------------- Configuration variables ----------------
+var pkcs11jar="bin/fortWIN32.jar";
+var pkcs11base="ftp://sweetlou/products/client/dogbert/new";
+//pkcs11base="";
+win_file = "libfort.jar"
+unix = "libfort-v404b9."
+mac_file = "macinst.htm"
+
+
+var winDates = pk_init_array (
+ "oct_02a_404", "oct_01a_404" );
+
+var unixDates = pk_init_array (
+ "current", "Oct_02", "Oct_O1");
+
+
+var comm_platforms = pk_init_array (
+ "Win32", "Win16", "Mac68k", "MacPPC",
+ "AIX4.1", "HP-UXA.09", "HP-UXB.10",
+ "SunOS4.1.3_U1", "SunOS5.4", "SunOS5.5.1",
+ "BSD_3861.1","BSD_3862.1", "FreeBSD2", "IRIX5.3", "IRIX6.2",
+ "LinuxELF1.2","LinusELF2.0","NCR4.0","NEC4.2","OSF1V3","SCOOS5.0",
+ "SINIX-N5.42","SunOS5.4_i86pc","UNIXWARE2.1",
+ "OS23.0","OS24.0");
+var isSupport = pk_init_array ( 1, 1, 0, 1,
+ 1, 1, 1,
+ 1, 1, 1, 1,
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,
+ 0, 0 );
+var directories = pk_init_array (
+ "32bit/fortezza", "16bit/fortezza", "", "404-fortezza-items",
+ "aix4", "hpux", "hpux10",
+ "sunos4", "sol24", "sol251",
+ // not really supported
+ "bsdi", "bsdi2", "freebsd", "irix53", "irix62",
+ "linux12","linux20","ncr","nec","osf132","sco",
+ "sinix","solx86","unixware",
+ "" ,"" );
+var files = pk_init_array (
+ win_file, win_file, mac_file, mac_file,
+ unix+"rs6000-ibm-aix4.jar",unix+"hppa1.1-hp-hpux9.jar",
+ unix+"hppa1.1-hp-hpux10.jar",
+ unix+"sparc-sun-sunos4.1.3_U1.jar",unix+"sparc-sun-solaris2.4.jar",
+ unix+"sparc-sun-solaris2.5.1.jar",
+ unix+"x86-bsdi-bsd.jar",unix+"x86-bsdi-bsd2.jar",
+ unix+"x86-unknown-freebsd.jar",
+ unix+"mips-sgi-irix5.3.jar",unix+"mips-sgi-irix6.2.jar",
+ unix+"x86-unknown-linix1.2.jar",unix+"x86-unknown-linix2.0.jar",
+ unix+"x86-ncr-sysv5.jar",unix+"mips-nec-uxv4.2.jar",
+ unix+"alpha-dec-osf3.2.jar",unix+"x86-sco-opensv5.0.2",
+ unix+"mips-sni-reliantunix.jar",unix+"x86-sun-solaris2.4.jar",
+ unix+"x86-sco-unixware2.1.jar",
+ win_file, win_file );
+
+function isSupported(InPlat)
+{
+ for (i=0; i < comm_platforms.length; i++) {
+ if (InPlat == comm_platforms[i]) {
+ return isSupport[i];
+ }
+ }
+ return 0;
+}
+
+function mapPlatform(InPlat)
+{
+ for (i=0; i < comm_platforms.length; i++) {
+ if (InPlat == comm_platforms[i]) {
+ return directories[i];
+ }
+ }
+ return InPlat;
+}
+
+function mapFile(InPlat)
+{
+ for (i=0; i < comm_platforms.length; i++) {
+ if (InPlat == comm_platforms[i]) {
+ return files[i];
+ }
+ }
+ return unix+"unknown-unknown-unknown.jar";
+}
+
+function mapDate(platform) {
+ if ((platform == "MacPPC") || (platform == "Mac68K")) {
+ return "";
+ } else if ((platform == "Win32") || (platform == "Win16")) {
+ return "/oct_2a_404";
+ } else if ((platform == "OS23.0") || (platform == "OS24.0")) {
+ return "";
+ }
+ return "/current/signed";
+}
+function mapBaseDir(platform) {
+ if ((platform == "MacPPC") || (platform == "Mac68K")) {
+ return "mac";
+ } else if ((platform == "Win32") || (platform == "Win16")) {
+ return "windows"
+ } else if ((platform == "OS23.0") || (platform == "OS24.0")) {
+ return "os2";
+ }
+ return "unix/Fortezza";
+}
+
+function pk_init_array()
+{
+ var numArgs = pk_init_array.arguments.length;
+ var a = new Array(numArgs);
+
+ for (var i = 0; i < numArgs; i++) {
+ a[i] = pk_init_array.arguments[i];
+ }
+ return a;
+}
+
+function getPlatform() {
+ return navigator.platform;
+}
+
+function getURLPath() {
+ var string = window.location.href;
+ end = string.lastIndexOf("/");
+ if (end == -1) {
+ end = string.length-1;
+ }
+ return string.substring(0,end+1);
+}
+
+
+
+plat=getPlatform();
+platDir = mapPlatform(plat);
+platFile = mapFile(plat);
+platBase = mapBaseDir(plat);
+platDate = mapDate(plat);
+if (pkcs11base == "") pkcs11base=getURLPath();
+pkcs11loc=pkcs11base+"/"+platBase+"/"+platDir + platDate + "/" + platFile;
+
+
+
+function DoInstall(url) {
+ window.location.href = url;
+}
+
+function DoCancel() {
+ // set window.location.href to your home page if you wish
+ //alert('Cancel Installation?');
+ history.back();
+}
+
+// ------ Change the following for your own Message --------
+document.write("<CENTER><H1>Netscape Fortezza PKCS #11 Module Installer</H1>");
+document.write("</CENTER>");
+document.write("<Table><TR><TD>");
+document.write("<DD><p><IMG SRC=litronic.gif WIDTH=110 Height=63 NAME=LITRONIC></TD>");
+document.write("<TD VAlign=Center><i> Netscape Fortezza PKCS #11 Modules require Litronic's MACI drivers to be installed on your platform.");
+document.write(" If you haven't already installed theLitronic MACI drivers, please to do so now.</I>");
+document.write("</TD></TR></Table>");
+// ----- end of generic message section --------
+document.write("<p>Netscape has detected you are installing on <b>"+plat+"</b>.<br>");
+if (!isSupported(plat)) {
+ document.write("<b>This platform is currently not suppported for FORTEZZA</b><br>");
+}
+document.write("Installing: <b>"+pkcs11loc+"</b><br>");
+document.write("<FORM>");
+document.write("<CENTER><Table><TR><TD><Input Type=Button name=install value='Install Now' onclick=DoInstall("+ "\"" +pkcs11loc+"\""+")>");
+document.write("</TD><TD><Input type=Button name=cancel value=Cancel Onclick=DoCancel()>");
+document.write("</TD></TR></Table></CENTER>");
+document.write("</FORM>");
+document.close();
+</SCRIPT>
+</HTML>
diff --git a/security/nss/lib/fortcrypt/inst.js b/security/nss/lib/fortcrypt/inst.js
new file mode 100644
index 000000000..2c2b1ab64
--- /dev/null
+++ b/security/nss/lib/fortcrypt/inst.js
@@ -0,0 +1,268 @@
+//
+// 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.
+//
+////////////////////////////////////////////////////////////////////////////////////////
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+var pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG;
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+var pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3; // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2; // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1; // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1; // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2; // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3; // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4; // Error deleting a module
+JS_ERR_ADD_MODULE = -5; // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6; // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7; // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8; // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9; // The SSL, S/MIME cipher flags are invalid
+JS_ERR_ADD_MODULE_DULICATE =-10; // Module with the same name already installed
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Find out which library is to be installed depending on the platform
+
+// pathname seperator is platform specific
+var sep = "/";
+var vendor = "netscape";
+var moduleName = "not_supported";
+var plat = navigator.platform;
+
+var dir = "pkcs11/" + vendor + "/" + plat + "/";
+if (plat == "Win16") {
+ dir = "pkcs11/";
+}
+
+bAbort = false;
+if (plat == "Win32") {
+ moduleName = "fort32.dll";
+ sep = "\\";
+} else if (plat == "Win16") {
+ moduleName = "FORT16.DLL";
+ sep = "\\";
+} else if (plat == "MacPPC") {
+ moduleName = "FortPK11Lib";
+ sep = ":";
+} else if (plat == "AIX4.1") {
+ moduleName = "libfort_shr.a";
+} else if (plat == "SunOS4.1.3_U1") {
+ moduleName = "libfort.so.1.0";
+} else if ((plat == "SunOS5.4") || (plat == "SunOS5.5.1")){
+ moduleName = "libfort.so";
+} else if ((plat == "HP-UXA.09") || (plat == "HP-UXB.10")){
+ moduleName = "libfort.sl";
+} else if (plat == "IRIX6.2"){
+ // The module only works on 6.3, but Communicator returns 6.2 even when
+ // running 6.3. So in order to prevent the user from thinking
+ // the module actually works on 6.2, we will force the name to
+ // say 6.3 instead of 6.2. In the even the user tries to install
+ // on 6.2, the user will see 6.3 instead. If they don't get it that
+ // it's not going to work at this point in time, then the entire install
+ // process wil just fail miserably, and that is OK.
+ plat = "IRIX6.3";
+ moduleName = "libfort.so";
+} else {
+ window.alert("Sorry, platform "+plat+" is not supported.");
+ bAbort = true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Installation Begins...
+if (!bAbort) {
+if (confirm("This script will install a security module. \nIt may over-write older files having the same name. \nDo you want to continue?")) {
+ // Step 1. Create a version object and a software update object
+ vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);
+ su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module");
+ // "Fortezza ... Module" is the logical name of the bundle
+
+ ////////////////////////////////////////
+ // Step 2. Start the install process
+ bAbort = false;
+ err = su.StartInstall("NSfortezza", // NSfortezza is the component folder (logical)
+ vi,
+ netscape.softupdate.SoftwareUpdate.FULL_INSTALL);
+
+ bAbort = (err!=0);
+
+ if (err == 0) {
+ ////////////////////////////////////////
+ // Step 3. Find out the physical location of the Program dir
+ Folder = su.GetFolder("Program");
+
+ ////////////////////////////////////////
+ // Step 4. Install the files. Unpack them and list where they go
+
+ err = su.AddSubcomponent("FortezzaLibrary_"+plat, //component name (logical)
+ vi, // version info
+ moduleName, // source file in JAR (physical)
+ Folder, // target folder (physical)
+ dir + moduleName, // target path & filename (physical)
+ true); // forces update
+ if (err != 0) {
+ if (err == -200) {
+ errmsg = "Bad Package Name.";
+ } else if (err == -201) {
+ errmsg = "Unexpected error.";
+ } else if (err == -203) {
+ errmsg = "Installation script was signed by more than one certificate.";
+ } else if (err == -204) {
+ errmsg = "Installation script was not signed."
+ } else if (err == -205) {
+ errmsg = "The file to be installed is not signed."
+ } else if (err == -206) {
+ errmsg = "The file to be installed is not present, or it was signed with a different certificate than the one used to sign the install script.";
+ } else if (err == -207) {
+ errmsg = "JAR archive has not been opened."
+ } else if (err == -208) {
+ errmsg = "Bad arguments to AddSubcomponent( )."
+ } else if (err == -209) {
+ errmsg = "Illegal relative path( )."
+ } else if (err == -210) {
+ errmsg = "User cancelled installation."
+ } else if (err == -211) {
+ errmsg = "A problem occurred with the StartInstall( )."
+ } else {
+ errmsg = "Unknown error";
+ }
+ window.alert("Error adding sub-component: "+"("+err+")"+errmsg);
+ //window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName);
+ bAbort = true;
+ }
+ }
+
+ ////////////////////////////////////////
+ // Step 5. Unless there was a problem, move files to final location
+ // and update the Client Version Registry
+ if (bAbort) {
+ su.AbortInstall();
+ } else {
+ err = su.FinalizeInstall();
+
+ if (err != 0) {
+
+ if (err == -900) {
+ errmsg = "Restart the computer, and install again.";
+ } else if (err == -201) {
+ errmsg = "Unexpected error.";
+ } else if (err == -202) {
+ errmsg = "Access denied. Make sure you have the permissions to write to the disk.";
+ } else if (err == -203) {
+ errmsg = "Installation script was signed by more than one certificate.";
+ } else if (err == -204) {
+ errmsg = "Installation script was not signed."
+ } else if (err == -205) {
+ errmsg = "The file to be installed is not signed."
+ } else if (err == -206) {
+ errmsg = "The file to be installed is not present, or it was signed with a different certificate than the one used to sign the install script."
+ } else if (err == -207) {
+ errmsg = "JAR archive has not been opened."
+ } else if (err == -208) {
+ errmsg = "Bad arguments to AddSubcomponent( )."
+ } else if (err == -209) {
+ errmsg = "Illegal relative path( )."
+ } else if (err == -210) {
+ errmsg = "User cancelled installation."
+ } else if (err == -211) {
+ errmsg = "A problem occurred with the StartInstall( )."
+ } else {
+ errmsg = "\nIf you have FORTEZZA module already installed, try deleting it first.";
+ }
+ window.alert("Error Finalizing Install: "+"("+err+")"+errmsg);
+ //window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName);
+
+ } else {
+
+ // Platform specific full path
+ if (plat=="Win16") {
+ fullpath = Folder + "pkcs11" + sep + moduleName;
+ } else {
+ fullpath = Folder + "pkcs11" + sep + vendor + sep + plat + sep + moduleName;
+ }
+
+ ////////////////////////////////////////
+ // Step 6: Call pkcs11.addmodule() to register the newly downloaded module
+ moduleCommonName = "Netscape FORTEZZA Module " + plat;
+ result = pkcs11.addmodule(moduleCommonName,
+ fullpath,
+ pkcs11MechanismFlags,
+ pkcs11CipherFlags);
+ if (result == -10) {
+ window.alert("New module was copied to destination, \nbut setup failed because a module "
+ +"with the same name has been installed. \nTry deleting the module "
+ + moduleCommonName +" first.")
+ } else if (result < 0) {
+ window.alert("New module was copied to destination, but setup failed. Error code: " + result);
+ }
+ }
+ }
+}
+}
diff --git a/security/nss/lib/fortcrypt/inst_PPC.js b/security/nss/lib/fortcrypt/inst_PPC.js
new file mode 100644
index 000000000..490910fff
--- /dev/null
+++ b/security/nss/lib/fortcrypt/inst_PPC.js
@@ -0,0 +1,134 @@
+//
+// 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.
+//
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG;
+
+
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3 // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1 // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4 // Error deleting a module
+JS_ERR_ADD_MODULE = -5 // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid
+
+
+if (confirm("This script will install and configure a security module, do you want to continue?")) {
+ // Step 1. Create a version object and a software update object
+ vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);
+ su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module");
+ // "Fortezza ... Module" is the logical name of the bundle
+
+ // Step 2. Start the install process
+ bAbort = false;
+ err = su.StartInstall("NSfortezza", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL);
+ // nsfortezza is the component folder (logical)
+ bAbort = bAbort || (err !=0);
+
+ if (err == 0) {
+
+ // Step 3. Find out the physical location of the Program dir
+ Folder = su.GetFolder("Program");
+
+ // Step 4. Install the files. Unpack them and list where they go
+ err = su.AddSubcomponent("FortezzaCardDLL", //component name (logical)
+ vi, // version info
+ "FortPK11Lib", // source file in JAR (physical)
+ Folder, // target folder (physical)
+ "FortPK11Lib", // target path & filename (physical)
+ this.force); // forces update
+ bAbort = bAbort || (err !=0);
+ }
+
+ // Step 5. Unless there was a problem, move files to final location
+ // and update the Client Version Registry
+ if (bAbort) {
+ window.alert("Installation Aborted");
+ su.AbortInstall();
+ } else {
+ err = su.FinalizeInstall();
+ window.alert("Files have been installed.\nContinue to setup the newly isntalled module...");
+ // Add Module
+ compFolder = su.GetComponentFolder("NSfortezza/FortezzaCardDLL") + "/FortPK11Lib";
+ result = pkcs11.addmodule("Netscape FORTEZZA Module", compFolder, pkcs11MechanismFlags, pkcs11CipherFlags);
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ } else {
+ window.alert("New module setup completed.");
+ }
+ }
+}
diff --git a/security/nss/lib/fortcrypt/install.js b/security/nss/lib/fortcrypt/install.js
new file mode 100644
index 000000000..e823e213b
--- /dev/null
+++ b/security/nss/lib/fortcrypt/install.js
@@ -0,0 +1,134 @@
+//
+// 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.
+//
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG;
+
+
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3 // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1 // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4 // Error deleting a module
+JS_ERR_ADD_MODULE = -5 // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid
+
+
+if (confirm("This script will install and configure a security module, do you want to continue?")) {
+ // Step 1. Create a version object and a software update object
+ vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);
+ su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module");
+ // "Fortezza ... Module" is the logical name of the bundle
+
+ // Step 2. Start the install process
+ bAbort = false;
+ err = su.StartInstall("NSfortezza", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL);
+ // nsfortezza is the component folder (logical)
+ bAbort = bAbort || (err !=0);
+
+ if (err == 0) {
+
+ // Step 3. Find out the physical location of the Program dir
+ Folder = su.GetFolder("Program");
+
+ // Step 4. Install the files. Unpack them and list where they go
+ err = su.AddSubcomponent("FortezzaCardDLL", //component name (logical)
+ vi, // version info
+ "DUMMY_DLL", // source file in JAR (physical)
+ Folder, // target folder (physical)
+ "DUMMY_DLL", // target path & filename (physical)
+ this.force); // forces update
+ bAbort = bAbort || (err !=0);
+ }
+
+ // Step 5. Unless there was a problem, move files to final location
+ // and update the Client Version Registry
+ if (bAbort) {
+ window.alert("Installation Aborted");
+ su.AbortInstall();
+ } else {
+ err = su.FinalizeInstall();
+ window.alert("Files have been installed.\nContinue to setup the newly isntalled module...");
+ // Add Module
+ compFolder = su.GetComponentFolder("NSfortezza/FortezzaCardDLL") + "/DUMMY_DLL";
+ result = pkcs11.addmodule("Netscape FORTEZZA Module", compFolder, pkcs11MechanismFlags, pkcs11CipherFlags);
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ } else {
+ window.alert("New module setup completed.");
+ }
+ }
+}
diff --git a/security/nss/lib/fortcrypt/maci.c b/security/nss/lib/fortcrypt/maci.c
new file mode 100644
index 000000000..09a117f5f
--- /dev/null
+++ b/security/nss/lib/fortcrypt/maci.c
@@ -0,0 +1,895 @@
+/*
+ * 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 "maci.h"
+
+RETURN_TYPE
+MACI_ChangePIN PROTO_LIST( (
+ HSESSION hSession,
+ int PINType,
+ CI_PIN CI_FAR pOldPIN,
+ CI_PIN CI_FAR pNewPIN ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_CheckPIN PROTO_LIST( (
+ HSESSION hSession,
+ int PINType,
+ CI_PIN CI_FAR pPIN ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Close PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int Flags,
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Decrypt PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int CipherSize,
+ CI_DATA pCipher,
+ CI_DATA pPlain ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_DeleteCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_DeleteKey PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Encrypt PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int PlainSize,
+ CI_DATA pPlain,
+ CI_DATA pCipher ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_ExtractX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_FirmwareUpdate PROTO_LIST( (
+ HSESSION hSession,
+ unsigned long Flags,
+ long Cksum,
+ unsigned int CksumLength,
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateIV PROTO_LIST( (
+ HSESSION hSession,
+ CI_IV CI_FAR pIV ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateMEK PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex,
+ int Reserved ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateRa PROTO_LIST( (
+ HSESSION hSession,
+ CI_RA CI_FAR pRa ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateRandom PROTO_LIST( (
+ HSESSION hSession,
+ CI_RANDOM CI_FAR pRandom ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateTEK PROTO_LIST( (
+ HSESSION hSession,
+ int Flags,
+ int RegisterIndex,
+ CI_RA CI_FAR pRa,
+ CI_RB CI_FAR pRb,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GenerateX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ CI_CERTIFICATE CI_FAR pCertificate ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetConfiguration PROTO_LIST( (
+ HSESSION hSession,
+ CI_CONFIG_PTR pConfiguration ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetHash PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int DataSize,
+ CI_DATA pData,
+ CI_HASHVALUE CI_FAR pHashValue ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetPersonalityList PROTO_LIST( (
+ HSESSION hSession,
+ int EntryCount,
+ CI_PERSON CI_FAR pPersonalityList[] ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetSessionID PROTO_LIST( (
+ HSESSION *hSession ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetState PROTO_LIST( (
+ HSESSION hSession,
+ CI_STATE_PTR pState ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetStatus PROTO_LIST( (
+ HSESSION hSession,
+ CI_STATUS_PTR pStatus ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_GetTime PROTO_LIST( (
+ HSESSION hSession,
+ CI_TIME CI_FAR pTime ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Hash PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Initialize PROTO_LIST( (
+ int CI_FAR *SocketCount ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_InitializeHash PROTO_LIST( (
+ HSESSION hSession ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_InstallX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pWrappedX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_LoadCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ CI_CERT_STR CI_FAR pCertLabel,
+ CI_CERTIFICATE CI_FAR pCertificate,
+ long Reserved ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_LoadDSAParameters PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_LoadInitValues PROTO_LIST( (
+ HSESSION hSession,
+ CI_RANDSEED CI_FAR pRandSeed,
+ CI_KS CI_FAR pKs ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_LoadIV PROTO_LIST( (
+ HSESSION hSession,
+ CI_IV CI_FAR pIV ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_LoadX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ CI_X CI_FAR pX,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Lock PROTO_LIST( (
+ HSESSION hSession,
+ int Flags ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Open PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int Flags,
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_RelayX PROTO_LIST( (
+ HSESSION hSession,
+ CI_PASSWORD CI_FAR pOldPassword,
+ unsigned int OldYSize,
+ CI_Y CI_FAR pOldY,
+ CI_RA CI_FAR pOldRa,
+ CI_WRAPPED_X CI_FAR pOldWrappedX,
+ CI_PASSWORD CI_FAR pNewPassword,
+ unsigned int NewYSize,
+ CI_Y CI_FAR pNewY,
+ CI_RA CI_FAR pNewRa,
+ CI_WRAPPED_X CI_FAR pNewWrappedX ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Reset PROTO_LIST( (
+ HSESSION hSession ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Restore PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Save PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Select PROTO_LIST( (
+ HSESSION hSession,
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_SetConfiguration PROTO_LIST( (
+ HSESSION hSession,
+ int Type,
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_SetKey PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_SetMode PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ int CryptoMode ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_SetPersonality PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_SetTime PROTO_LIST( (
+ HSESSION hSession,
+ CI_TIME CI_FAR pTime ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Sign PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Terminate PROTO_LIST( (
+ HSESSION hSession ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_TimeStamp PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Unlock PROTO_LIST( (
+ HSESSION hSession) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_UnwrapKey PROTO_LIST( (
+ HSESSION hSession,
+ int UnwrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_VerifySignature PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_SIGNATURE CI_FAR pSignature ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_VerifyTimeStamp PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_WrapKey PROTO_LIST( (
+ HSESSION hSession,
+ int WrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+MACI_Zeroize PROTO_LIST( (
+ HSESSION hSession ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_ChangePIN PROTO_LIST( (
+ int PINType,
+ CI_PIN CI_FAR pOldPIN,
+ CI_PIN CI_FAR pNewPIN ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_CheckPIN PROTO_LIST( (
+ int PINType,
+ CI_PIN CI_FAR pPIN ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Close PROTO_LIST( (
+ unsigned int Flags,
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Decrypt PROTO_LIST( (
+ unsigned int CipherSize,
+ CI_DATA pCipher,
+ CI_DATA pPlain ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_DeleteCertificate PROTO_LIST( (
+ int CertificateIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_DeleteKey PROTO_LIST( (
+ int RegisterIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Encrypt PROTO_LIST( (
+ unsigned int PlainSize,
+ CI_DATA pPlain,
+ CI_DATA pCipher ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_ExtractX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_FirmwareUpdate PROTO_LIST( (
+ unsigned long Flags,
+ long Cksum,
+ unsigned int CksumLength,
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateIV PROTO_LIST( (
+ CI_IV CI_FAR pIV ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateMEK PROTO_LIST( (
+ int RegisterIndex,
+ int Reserved ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateRa PROTO_LIST( (
+ CI_RA CI_FAR pRa ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateRandom PROTO_LIST( (
+ CI_RANDOM CI_FAR pRandom ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateTEK PROTO_LIST( (
+ int Flags,
+ int RegisterIndex,
+ CI_RA CI_FAR pRa,
+ CI_RB CI_FAR pRb,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GenerateX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetCertificate PROTO_LIST( (
+ int CertificateIndex,
+ CI_CERTIFICATE CI_FAR pCertificate ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetConfiguration PROTO_LIST( (
+ CI_CONFIG_PTR pConfiguration ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetHash PROTO_LIST( (
+ unsigned int DataSize,
+ CI_DATA pData,
+ CI_HASHVALUE CI_FAR pHashValue ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetPersonalityList PROTO_LIST( (
+ int EntryCount,
+ CI_PERSON CI_FAR pPersonalityList[] ) ) {
+ return CI_ERROR;
+}
+
+
+RETURN_TYPE
+CI_GetState PROTO_LIST( (
+ CI_STATE_PTR pState ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetStatus PROTO_LIST( (
+ CI_STATUS_PTR pStatus ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_GetTime PROTO_LIST( (
+ CI_TIME CI_FAR pTime ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Hash PROTO_LIST( (
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Initialize PROTO_LIST( (
+ int CI_FAR *SocketCount ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_InitializeHash PROTO_LIST( () ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_InstallX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pWrappedX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_LoadCertificate PROTO_LIST( (
+ int CertificateIndex,
+ CI_CERT_STR CI_FAR pCertLabel,
+ CI_CERTIFICATE CI_FAR pCertificate,
+ long Reserved ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_LoadDSAParameters PROTO_LIST( (
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_LoadInitValues PROTO_LIST( (
+ CI_RANDSEED CI_FAR pRandSeed,
+ CI_KS CI_FAR pKs ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_LoadIV PROTO_LIST( (
+ CI_IV CI_FAR pIV ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_LoadX PROTO_LIST( (
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ CI_X CI_FAR pX,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Lock PROTO_LIST( (
+ int Flags ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Open PROTO_LIST( (
+ unsigned int Flags,
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_RelayX PROTO_LIST( (
+ CI_PASSWORD CI_FAR pOldPassword,
+ unsigned int OldYSize,
+ CI_Y CI_FAR pOldY,
+ CI_RA CI_FAR pOldRa,
+ CI_WRAPPED_X CI_FAR pOldWrappedX,
+ CI_PASSWORD CI_FAR pNewPassword,
+ unsigned int NewYSize,
+ CI_Y CI_FAR pNewY,
+ CI_RA CI_FAR pNewRa,
+ CI_WRAPPED_X CI_FAR pNewWrappedX ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Reset PROTO_LIST( ( ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Restore PROTO_LIST( (
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Save PROTO_LIST( (
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Select PROTO_LIST( (
+ int SocketIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_SetConfiguration PROTO_LIST( (
+ int Type,
+ unsigned int DataSize,
+ CI_DATA pData ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_SetKey PROTO_LIST( (
+ int RegisterIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_SetMode PROTO_LIST( (
+ int CryptoType,
+ int CryptoMode ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_SetPersonality PROTO_LIST( (
+ int CertificateIndex ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_SetTime PROTO_LIST( (
+ CI_TIME CI_FAR pTime ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Sign PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Terminate PROTO_LIST( ( ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_TimeStamp PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_Unlock PROTO_LIST( () ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_UnwrapKey PROTO_LIST( (
+ int UnwrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_VerifySignature PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_SIGNATURE CI_FAR pSignature ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_VerifyTimeStamp PROTO_LIST( (
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) ) {
+ return CI_ERROR;
+}
+
+RETURN_TYPE
+CI_WrapKey PROTO_LIST( (
+ int WrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) ) {
+ return CI_ERROR;
+}
+
diff --git a/security/nss/lib/fortcrypt/maci.h b/security/nss/lib/fortcrypt/maci.h
new file mode 100644
index 000000000..eb38ff81c
--- /dev/null
+++ b/security/nss/lib/fortcrypt/maci.h
@@ -0,0 +1,776 @@
+/*
+ * 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.
+ */
+/* @(#)maci.h 1.27\t05 Jan 1996 */
+/*****************************************************************************
+ Definitive Fortezza header file.
+ Application Level Interface to Fortezza MACI Library.
+
+ Version for CI Library 1.52
+ January 5, 1996
+
+
+ NOTICE: Fortezza Export Policy
+
+ The Fortezza Cryptologic Interface (CI) Library (both source and
+ object) and Fortezza CI Library based applications are defense
+ articles, as defined in the International Traffic In Arms
+ Regulations (ITAR), and are subject to export controls under the
+ ITAR and the Arms Export Control Act. Any export to any country
+ of (a) the Fortezza CI Library, related documentation, and
+ technical data, or (b) your cryptographic application, process,
+ or service that is the direct product of, or contains the
+ Fortezza CI Library must comply with the requirements of the ITAR.
+ If you or your customer intends to engage in such export, contact
+ the United States Department of State, Office of Defense Trade
+ Controls for specific guidance.
+
+
+ ****************************************************************************/
+#ifndef __MACI_H
+#define __MACI_H
+
+#if __cplusplus__ || __cplusplus
+extern "C"
+{
+#endif /* C++ */
+
+
+#ifndef __CRYPTINT_H
+
+#ifndef PROTO_LIST
+#ifdef _K_AND_R_
+#define PROTO_LIST(list) ()
+#else
+#define PROTO_LIST(list) list
+#endif /*_K_AND_R_ */
+#endif /* PROTO_LIST */
+
+
+#ifndef RETURN_TYPE
+#if defined( _WIN32 ) || defined( __WIN32__ )
+#define RETURN_TYPE extern _declspec( dllimport ) int _cdecl
+#elif defined( _WINDOWS ) || defined( _Windows )
+#define RETURN_TYPE extern int _far _pascal
+#else
+#define RETURN_TYPE extern int
+#endif /* Windows */
+#endif /* RETURN_TYPE */
+
+/* MS Visual C++ defines _MSDOS and _WINDOWS */
+/* Borland C/C++ defines __MSDOS__ and _Windows */
+#if (defined( _WINDOWS ) || defined( _Windows )) && \
+ !(defined( _WIN32 ) || defined( __WIN32__ ))
+#define CI_FAR _far
+#else
+#define CI_FAR
+#endif /* MS DOS or Windows */
+
+
+/*****************************************************************************
+ Constants
+ ****************************************************************************/
+#define CI_LIB_VERSION_VAL 0x0152 /* Version 1.52 */
+
+#define CI_CERT_SIZE 2048
+#define CI_CERT_FLAGS_SIZE 16
+#define CI_CERT_NAME_SIZE 32
+#define CI_CHALLENGE_SIZE 20
+
+#define CI_G_SIZE 128
+
+#define CI_HASHVALUE_SIZE 20
+
+#define CI_IV_SIZE 24
+
+#define CI_KEY_SIZE 12
+#define CI_KS_SIZE 10
+
+#define CI_NAME_SIZE 32
+
+#define CI_PASSWORD_SIZE 24
+#define CI_PIN_SIZE 12
+#define CI_P_SIZE 128
+
+#define CI_Q_SIZE 20
+
+#define CI_R_SIZE 40
+#define CI_RANDOM_NO_SIZE 20
+#define CI_RANDOM_SEED_SIZE 8
+#define CI_RA_SIZE 128
+#define CI_RB_SIZE 128
+#define CI_REG_FLAGS_SIZE 4
+
+#define CI_S_SIZE 40
+#define CI_SAVE_DATA_SIZE 28
+#define CI_SERIAL_NUMBER_SIZE 8
+#define CI_SIGNATURE_SIZE 40
+#define CI_STATUS_FLAGS_SIZE 4
+
+#define CI_TIME_SIZE 16
+#define CI_TIMESTAMP_SIZE 16
+
+#define CI_WRAPPED_X_SIZE 24
+
+#define CI_Y_SIZE 128
+
+#define CI_X_SIZE 20
+
+
+/* Miscellaneous */
+#define CI_NULL_FLAG 0
+#define CI_POWER_DOWN_FLAG 2
+#define CI_NO_LOG_OFF_FLAG 4
+#define CI_INITIATOR_FLAG 0
+#define CI_RECIPIENT_FLAG 1
+
+#define CI_BLOCK_LOCK_FLAG 1
+#define CI_SSO_LOGGED_ON 0x40
+#define CI_USER_LOGGED_ON 0x00
+#define CI_FAST_MODE 0x10
+#define CI_SLOW_MODE 0x00
+#define CI_WORST_CASE_MODE 0x40
+#define CI_TYPICAL_CASE_MODE 0x00
+
+/* Card Public Key Algorithms Types */
+#define CI_DSA_TYPE 0xA
+#define CI_KEA_TYPE 0x5
+#define CI_DSA_KEA_TYPE 0xF
+
+/* Fortezza Pin Types */
+#define CI_SSO_PIN 0x25
+#define CI_USER_PIN 0x2A
+
+/* Crypto Types */
+#define CI_ENCRYPT_TYPE 0
+#define CI_DECRYPT_TYPE 1
+#define CI_HASH_TYPE 2
+
+/* Save and Restore Types */
+#define CI_ENCRYPT_INT_TYPE 0x00 /* Internal Encryption */
+#define CI_ENCRYPT_EXT_TYPE 0x10 /* External Encryption */
+#define CI_DECRYPT_INT_TYPE 0x01 /* Internal Decryption */
+#define CI_DECRYPT_EXT_TYPE 0x11 /* External Decryption */
+#define CI_HASH_INT_TYPE 0x02 /* Internal Hash */
+#define CI_HASH_EXT_TYPE 0x12 /* External Hash */
+#define CI_TYPE_EXT_FLAG 0x10 /* Used to differentiate */
+
+/* Configuration types */
+#define CI_SET_SPEED_TYPE 1
+#define CI_SET_TIMING_TYPE 2
+
+/* Lock States */
+#define CI_SOCKET_UNLOCKED 0
+#define CI_HOLD_LOCK 1
+#define CI_SOCKET_LOCKED 2
+
+/* Fortezza Crypto Types Modes */
+#define CI_ECB64_MODE 0
+#define CI_CBC64_MODE 1
+#define CI_OFB64_MODE 2
+#define CI_CFB64_MODE 3
+#define CI_CFB32_MODE 4
+#define CI_CFB16_MODE 5
+#define CI_CFB8_MODE 6
+
+/* Card States */
+#define CI_POWER_UP 0
+#define CI_UNINITIALIZED 1
+#define CI_INITIALIZED 2
+#define CI_SSO_INITIALIZED 3
+#define CI_LAW_INITIALIZED 4
+#define CI_USER_INITIALIZED 5
+#define CI_STANDBY 6
+#define CI_READY 7
+#define CI_ZEROIZE 8
+#define CI_INTERNAL_FAILURE (-1)
+
+/* Flags for Firmware Update. */
+#if !defined( _K_AND_R_ )
+
+#define CI_NOT_LAST_BLOCK_FLAG 0x00000000UL
+#define CI_LAST_BLOCK_FLAG 0x80000000UL
+#define CI_DESTRUCTIVE_FLAG 0x000000FFUL
+#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00UL
+
+#else
+
+#define CI_NOT_LAST_BLOCK_FLAG 0x00000000L
+#define CI_LAST_BLOCK_FLAG 0x80000000L
+#define CI_DESTRUCTIVE_FLAG 0x000000FFL
+#define CI_NONDESTRUCTIVE_FLAG 0x0000FF00L
+
+#endif /* _K_AND_R_ */
+
+/****************************************************************************
+ Fortezza Library Return Codes
+ ***************************************************************************/
+
+/* Card Responses */
+#define CI_OK 0
+#define CI_FAIL 1
+#define CI_CHECKWORD_FAIL 2
+#define CI_INV_TYPE 3
+#define CI_INV_MODE 4
+#define CI_INV_KEY_INDEX 5
+#define CI_INV_CERT_INDEX 6
+#define CI_INV_SIZE 7
+#define CI_INV_HEADER 8
+#define CI_INV_STATE 9
+#define CI_EXEC_FAIL 10
+#define CI_NO_KEY 11
+#define CI_NO_IV 12
+#define CI_NO_X 13
+
+#define CI_NO_SAVE 15
+#define CI_REG_IN_USE 16
+#define CI_INV_COMMAND 17
+#define CI_INV_POINTER 18
+#define CI_BAD_CLOCK 19
+#define CI_NO_DSA_PARMS 20
+
+/* Library Errors */
+#define CI_ERROR (-1)
+#define CI_LIB_NOT_INIT (-2)
+#define CI_CARD_NOT_READY (-3)
+#define CI_CARD_IN_USE (-4)
+#define CI_TIME_OUT (-5)
+#define CI_OUT_OF_MEMORY (-6)
+#define CI_NULL_PTR (-7)
+#define CI_BAD_SIZE (-8)
+#define CI_NO_DECRYPT (-9)
+#define CI_NO_ENCRYPT (-10)
+#define CI_NO_EXECUTE (-11)
+#define CI_BAD_PARAMETER (-12)
+#define CI_OUT_OF_RESOURCES (-13)
+
+#define CI_NO_CARD (-20)
+#define CI_NO_DRIVER (-21)
+#define CI_NO_CRDSRV (-22)
+#define CI_NO_SCTSRV (-23)
+
+#define CI_BAD_CARD (-30)
+#define CI_BAD_IOCTL (-31)
+#define CI_BAD_READ (-32)
+#define CI_BAD_SEEK (-33)
+#define CI_BAD_WRITE (-34)
+#define CI_BAD_FLUSH (-35)
+#define CI_BAD_IOSEEK (-36)
+#define CI_BAD_ADDR (-37)
+
+#define CI_INV_SOCKET_INDEX (-40)
+#define CI_SOCKET_IN_USE (-41)
+#define CI_NO_SOCKET (-42)
+#define CI_SOCKET_NOT_OPENED (-43)
+#define CI_BAD_TUPLES (-44)
+#define CI_NOT_A_CRYPTO_CARD (-45)
+
+#define CI_INVALID_FUNCTION (-50)
+#define CI_LIB_ALRDY_INIT (-51)
+#define CI_SRVR_ERROR (-52)
+#define MACI_SESSION_EXCEEDED (-53)
+
+
+/*****************************************************************************
+ Data Structures
+ ****************************************************************************/
+
+
+typedef unsigned char CI_CERTIFICATE[CI_CERT_SIZE];
+
+typedef unsigned char CI_CERT_FLAGS[CI_CERT_FLAGS_SIZE];
+
+typedef unsigned char CI_CERT_STR[CI_CERT_NAME_SIZE+4];
+
+typedef unsigned char CI_FAR *CI_DATA;
+
+typedef unsigned char CI_G[CI_G_SIZE];
+
+typedef unsigned char CI_HASHVALUE[CI_HASHVALUE_SIZE];
+
+typedef unsigned char CI_IV[CI_IV_SIZE];
+
+typedef unsigned char CI_KEY[CI_KEY_SIZE];
+
+typedef unsigned char CI_KS[CI_KS_SIZE];
+
+typedef unsigned char CI_P[CI_P_SIZE];
+
+typedef unsigned char CI_PASSWORD[CI_PASSWORD_SIZE + 4];
+
+typedef unsigned char CI_PIN[CI_PIN_SIZE + 4];
+
+typedef unsigned char CI_Q[CI_Q_SIZE];
+
+typedef unsigned char CI_RA[CI_RA_SIZE];
+
+typedef unsigned char CI_RB[CI_RB_SIZE];
+
+typedef unsigned char CI_RANDOM[CI_RANDOM_NO_SIZE];
+
+typedef unsigned char CI_RANDSEED[CI_RANDOM_SEED_SIZE];
+
+typedef unsigned char CI_REG_FLAGS[CI_REG_FLAGS_SIZE];
+
+typedef unsigned char CI_SIGNATURE[CI_SIGNATURE_SIZE];
+
+typedef unsigned char CI_SAVE_DATA[CI_SAVE_DATA_SIZE];
+
+typedef unsigned char CI_SERIAL_NUMBER[CI_SERIAL_NUMBER_SIZE];
+
+typedef unsigned int CI_STATE, CI_FAR *CI_STATE_PTR;
+
+typedef unsigned char CI_TIME[CI_TIME_SIZE];
+
+typedef unsigned char CI_TIMESTAMP[CI_TIMESTAMP_SIZE];
+
+typedef unsigned char CI_WRAPPED_X[CI_WRAPPED_X_SIZE];
+
+typedef unsigned char CI_Y[CI_Y_SIZE];
+
+typedef unsigned char CI_X[CI_X_SIZE];
+
+typedef struct {
+ int LibraryVersion; /* CI Library version */
+ int ManufacturerVersion; /* Card's hardware version */
+ char ManufacturerName[CI_NAME_SIZE+4]; /* Card manufacturer's name*/
+ char ProductName[CI_NAME_SIZE+4]; /* Card's product name */
+ char ProcessorType[CI_NAME_SIZE+4]; /* Card's processor type */
+ unsigned long UserRAMSize; /* Amount of User RAM in bytes */
+ unsigned long LargestBlockSize; /* Largest block of data to pass in */
+ int KeyRegisterCount; /* Number of key registers */
+ int CertificateCount; /* Maximum number of personalities (# certs-1) */
+ int CryptoCardFlag; /* A flag that if non-zero indicates that there is
+ a Crypto-Card in the socket. If this value is
+ zero then there is NOT a Crypto-Card in the
+ sockets. */
+ int ICDVersion; /* The ICD compliance level */
+ int ManufacturerSWVer; /* The Manufacturer's Software Version */
+ int DriverVersion; /* Driver Version */
+} CI_CONFIG, CI_FAR *CI_CONFIG_PTR;
+
+typedef struct {
+ int CertificateIndex; /* Index from 1 to CertificateCount */
+ CI_CERT_STR CertLabel; /* The certificate label */
+} CI_PERSON, CI_FAR *CI_PERSON_PTR;
+
+typedef struct {
+ int CurrentSocket; /* The currently selected socket */
+ int LockState; /* Lock status of the current socket */
+ CI_SERIAL_NUMBER SerialNumber; /* Serial number of the Crypto Engine chip */
+ CI_STATE CurrentState; /* State of The Card */
+ int DecryptionMode; /* Decryption mode of The Card */
+ int EncryptionMode; /* Encryption mode of The Card */
+ int CurrentPersonality; /* Index of the current personality */
+ int KeyRegisterCount; /* No. of Key Register on The Card */
+ CI_REG_FLAGS KeyRegisterFlags; /* Bit Masks indicating Key Register use */
+ int CertificateCount; /* No. of Certificates on The Card */
+ CI_CERT_FLAGS CertificateFlags; /* Bit Mask indicating certificate use */
+ unsigned char Flags[CI_STATUS_FLAGS_SIZE];
+ /* Flag[0] : bit 6 for Condition mode */
+ /* bit 4 for Clock mode */
+} CI_STATUS, CI_FAR *CI_STATUS_PTR;
+
+#endif
+
+/* Session constants */
+#ifndef HSESSION_DEFINE
+typedef unsigned int HSESSION;
+#define HSESSION_DEFINE
+#endif
+#define MAXSESSION 100
+
+/*****************************************************************************
+ Function Call Prototypes
+ ****************************************************************************/
+
+RETURN_TYPE
+MACI_ChangePIN PROTO_LIST( (
+ HSESSION hSession,
+ int PINType,
+ CI_PIN CI_FAR pOldPIN,
+ CI_PIN CI_FAR pNewPIN ) );
+
+RETURN_TYPE
+MACI_CheckPIN PROTO_LIST( (
+ HSESSION hSession,
+ int PINType,
+ CI_PIN CI_FAR pPIN ) );
+
+RETURN_TYPE
+MACI_Close PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int Flags,
+ int SocketIndex ) );
+
+RETURN_TYPE
+MACI_Decrypt PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int CipherSize,
+ CI_DATA pCipher,
+ CI_DATA pPlain ) );
+
+RETURN_TYPE
+MACI_DeleteCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex ) );
+
+RETURN_TYPE
+MACI_DeleteKey PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex ) );
+
+RETURN_TYPE
+MACI_Encrypt PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int PlainSize,
+ CI_DATA pPlain,
+ CI_DATA pCipher ) );
+
+RETURN_TYPE
+MACI_ExtractX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+MACI_FirmwareUpdate PROTO_LIST( (
+ HSESSION hSession,
+ unsigned long Flags,
+ long Cksum,
+ unsigned int CksumLength,
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+MACI_GenerateIV PROTO_LIST( (
+ HSESSION hSession,
+ CI_IV CI_FAR pIV ) );
+
+RETURN_TYPE
+MACI_GenerateMEK PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex,
+ int Reserved ) );
+
+RETURN_TYPE
+MACI_GenerateRa PROTO_LIST( (
+ HSESSION hSession,
+ CI_RA CI_FAR pRa ) );
+
+RETURN_TYPE
+MACI_GenerateRandom PROTO_LIST( (
+ HSESSION hSession,
+ CI_RANDOM CI_FAR pRandom ) );
+
+RETURN_TYPE
+MACI_GenerateTEK PROTO_LIST( (
+ HSESSION hSession,
+ int Flags,
+ int RegisterIndex,
+ CI_RA CI_FAR pRa,
+ CI_RB CI_FAR pRb,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+MACI_GenerateX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+MACI_GetCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ CI_CERTIFICATE CI_FAR pCertificate ) );
+
+RETURN_TYPE
+MACI_GetConfiguration PROTO_LIST( (
+ HSESSION hSession,
+ CI_CONFIG_PTR pConfiguration ) );
+
+RETURN_TYPE
+MACI_GetHash PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int DataSize,
+ CI_DATA pData,
+ CI_HASHVALUE CI_FAR pHashValue ) );
+
+RETURN_TYPE
+MACI_GetPersonalityList PROTO_LIST( (
+ HSESSION hSession,
+ int EntryCount,
+ CI_PERSON CI_FAR pPersonalityList[] ) );
+
+RETURN_TYPE
+MACI_GetSessionID PROTO_LIST( (
+ HSESSION *hSession ) );
+
+RETURN_TYPE
+MACI_GetState PROTO_LIST( (
+ HSESSION hSession,
+ CI_STATE_PTR pState ) );
+
+RETURN_TYPE
+MACI_GetStatus PROTO_LIST( (
+ HSESSION hSession,
+ CI_STATUS_PTR pStatus ) );
+
+RETURN_TYPE
+MACI_GetTime PROTO_LIST( (
+ HSESSION hSession,
+ CI_TIME CI_FAR pTime ) );
+
+RETURN_TYPE
+MACI_Hash PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+MACI_Initialize PROTO_LIST( (
+ int CI_FAR *SocketCount ) );
+
+RETURN_TYPE
+MACI_InitializeHash PROTO_LIST( (
+ HSESSION hSession ) );
+
+RETURN_TYPE
+MACI_InstallX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ CI_PASSWORD CI_FAR pPassword,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_WRAPPED_X CI_FAR pWrappedX,
+ CI_RA CI_FAR pRa,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+MACI_LoadCertificate PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ CI_CERT_STR CI_FAR pCertLabel,
+ CI_CERTIFICATE CI_FAR pCertificate,
+ long Reserved ) );
+
+RETURN_TYPE
+MACI_LoadDSAParameters PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG ) );
+
+RETURN_TYPE
+MACI_LoadInitValues PROTO_LIST( (
+ HSESSION hSession,
+ CI_RANDSEED CI_FAR pRandSeed,
+ CI_KS CI_FAR pKs ) );
+
+RETURN_TYPE
+MACI_LoadIV PROTO_LIST( (
+ HSESSION hSession,
+ CI_IV CI_FAR pIV ) );
+
+RETURN_TYPE
+MACI_LoadX PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex,
+ int AlgorithmType,
+ unsigned int PandGSize,
+ unsigned int QSize,
+ CI_P CI_FAR pP,
+ CI_Q CI_FAR pQ,
+ CI_G CI_FAR pG,
+ CI_X CI_FAR pX,
+ unsigned int YSize,
+ CI_Y CI_FAR pY ) );
+
+RETURN_TYPE
+MACI_Lock PROTO_LIST( (
+ HSESSION hSession,
+ int Flags ) );
+
+RETURN_TYPE
+MACI_Open PROTO_LIST( (
+ HSESSION hSession,
+ unsigned int Flags,
+ int SocketIndex ) );
+
+RETURN_TYPE
+MACI_RelayX PROTO_LIST( (
+ HSESSION hSession,
+ CI_PASSWORD CI_FAR pOldPassword,
+ unsigned int OldYSize,
+ CI_Y CI_FAR pOldY,
+ CI_RA CI_FAR pOldRa,
+ CI_WRAPPED_X CI_FAR pOldWrappedX,
+ CI_PASSWORD CI_FAR pNewPassword,
+ unsigned int NewYSize,
+ CI_Y CI_FAR pNewY,
+ CI_RA CI_FAR pNewRa,
+ CI_WRAPPED_X CI_FAR pNewWrappedX ) );
+
+RETURN_TYPE
+MACI_Reset PROTO_LIST( (
+ HSESSION hSession ) );
+
+RETURN_TYPE
+MACI_Restore PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) );
+
+RETURN_TYPE
+MACI_Save PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ CI_SAVE_DATA CI_FAR pData ) );
+
+RETURN_TYPE
+MACI_Select PROTO_LIST( (
+ HSESSION hSession,
+ int SocketIndex ) );
+
+RETURN_TYPE
+MACI_SetConfiguration PROTO_LIST( (
+ HSESSION hSession,
+ int Type,
+ unsigned int DataSize,
+ CI_DATA pData ) );
+
+RETURN_TYPE
+MACI_SetKey PROTO_LIST( (
+ HSESSION hSession,
+ int RegisterIndex ) );
+
+RETURN_TYPE
+MACI_SetMode PROTO_LIST( (
+ HSESSION hSession,
+ int CryptoType,
+ int CryptoMode ) );
+
+RETURN_TYPE
+MACI_SetPersonality PROTO_LIST( (
+ HSESSION hSession,
+ int CertificateIndex ) );
+
+RETURN_TYPE
+MACI_SetTime PROTO_LIST( (
+ HSESSION hSession,
+ CI_TIME CI_FAR pTime ) );
+
+RETURN_TYPE
+MACI_Sign PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature ) );
+
+RETURN_TYPE
+MACI_Terminate PROTO_LIST( (
+ HSESSION hSession ) );
+
+RETURN_TYPE
+MACI_TimeStamp PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) );
+
+RETURN_TYPE
+MACI_Unlock PROTO_LIST( (
+ HSESSION hSession) );
+
+RETURN_TYPE
+MACI_UnwrapKey PROTO_LIST( (
+ HSESSION hSession,
+ int UnwrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) );
+
+RETURN_TYPE
+MACI_VerifySignature PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ unsigned int YSize,
+ CI_Y CI_FAR pY,
+ CI_SIGNATURE CI_FAR pSignature ) );
+
+RETURN_TYPE
+MACI_VerifyTimeStamp PROTO_LIST( (
+ HSESSION hSession,
+ CI_HASHVALUE CI_FAR pHashValue,
+ CI_SIGNATURE CI_FAR pSignature,
+ CI_TIMESTAMP CI_FAR pTimeStamp ) );
+
+RETURN_TYPE
+MACI_WrapKey PROTO_LIST( (
+ HSESSION hSession,
+ int WrapIndex,
+ int KeyIndex,
+ CI_KEY CI_FAR pKey ) );
+
+RETURN_TYPE
+MACI_Zeroize PROTO_LIST( (
+ HSESSION hSession ) );
+
+#if __cplusplus__ || __cplusplus
+}
+#endif /* C++ */
+
+#endif /* CRYPTINT_H */
+
diff --git a/security/nss/lib/fortcrypt/macinst.htm b/security/nss/lib/fortcrypt/macinst.htm
new file mode 100644
index 000000000..cf3988157
--- /dev/null
+++ b/security/nss/lib/fortcrypt/macinst.htm
@@ -0,0 +1,148 @@
+<HTML>
+<--
+ - 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.
+-->
+<TITLE>MAC Installer</TITLE>
+
+<SCRIPT>
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+pkcs11MechanismFlags = PKCS11_MECH_RANDOM_FLAG;
+
+
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3 // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2 // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1 // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1 // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2 // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4 // Error deleting a module
+JS_ERR_ADD_MODULE = -5 // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6 // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7 // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8 // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME cipher flags are invalid
+
+var new_window;
+var has_new_window = 0;
+
+function colonize(string) {
+ len = string.length;
+ end = len -1;
+
+ if (len == 0) return string;
+
+
+ for (i=0; i < len; i++) {
+ if (string.charAt(i) == "/") {
+ if (i == 0) {
+ new_string = ":" + string.substring(1,len);
+ } else if (i == end) {
+ new_string = string.substring(0,i)+':';
+ } else {
+ new_string = string.substring(0,i)+':'+
+ string.substring(i+1,len);
+ }
+ string = new_string;
+ }
+ }
+
+ if (string.charAt(0) == ":") string = string.substring(1,len);
+ return string;
+}
+
+function DoInstall(module) {
+ module = colonize(module);
+ result = pkcs11.addmodule("Netscape FORTEZZA Module", module, pkcs11MechanismFlags, pkcs11CipherFlags);
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ }
+ if (has_new_window) new_window.close();
+}
+
+function DoUnpack(name) {
+ new_window = open(name,"unpacking","toolbar=no,location=no,status=yes,scrollbar=no,width=50,height=50");
+ has_new_window = 1;
+}
+
+filename=navigator.platform+".hqx"
+
+default_module = "D:/dogbert/ns/dist/WIN32_D.OBJ/bin/fort32.dll"
+document.writeln("<FORM name=instform target=_self> <H2>Mac Fortezza Installer</H2>");
+document.writeln("<I>You must first unpack the <b>"+filename+"</b> file.");
+document.writeln(" Do that by clicking on button below.</i><p>");
+document.writeln("<Input type=button value=Unpack name=unpack onclick=DoUnpack(\""+filename+"\"); ><p>");
+document.writeln("<I>Then move <b>FortPK11Lib</b> to an appropriate directory ");
+document.writeln(" enter that directory below, then click the Install button.</i><p>");
+document.writeln(" Module Name: <Input Type=FILE Name=module><p>");
+document.write("<Input type=submit Name=Install Value=Install onclick=DoInstall(");
+document.writeln( "document.instform.module.value) >");
+document.writeln("</FORM>");
+</SCRIPT>
diff --git a/security/nss/lib/fortcrypt/manifest.mn b/security/nss/lib/fortcrypt/manifest.mn
new file mode 100644
index 000000000..6dc9019c4
--- /dev/null
+++ b/security/nss/lib/fortcrypt/manifest.mn
@@ -0,0 +1,50 @@
+#
+# 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 = ../../..
+
+MODULE = security
+LIBRARY_NAME = fort
+#LIBRARY_VERSION = 32
+
+DIRS = swfort
+
+CSRCS = forsock.c \
+ fortpk11.c \
+ fmutex.c \
+ $(NULL)
+
+EXPORTS =
+PRIVATE_EXPORTS = maci.h cryptint.h
+
+REQUIRES = security dbm
+
diff --git a/security/nss/lib/fortcrypt/replace.c b/security/nss/lib/fortcrypt/replace.c
new file mode 100644
index 000000000..b4c5edd18
--- /dev/null
+++ b/security/nss/lib/fortcrypt/replace.c
@@ -0,0 +1,101 @@
+/*
+ * 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 <string.h>
+
+int main(int argc, char* argv[]) {
+ FILE *templ;
+ FILE *target;
+ unsigned char buffer[81];
+ unsigned char *find, *replace;
+ int matchcount = 0;
+ int ch;
+ int len;
+
+ buffer[0] = '\0';
+
+ if (argc != 5) {
+ fprintf(stderr, "usuage: replace template.js searchstring replacestring target.js \n");
+ return 1;
+ }
+
+ templ = fopen(argv[1], "r");
+ if (!templ) {
+ fprintf(stderr, "Cannot open template script %s\n", argv[1]);
+ return 2;
+ }
+
+ find = (unsigned char*) argv[2];
+ replace = (unsigned char*) argv[3];
+
+ target = fopen(argv[4], "w");
+ if (!target) {
+ fclose(templ);
+ fprintf(stderr, "Cannot write to target script %s\n", argv[4]);
+ return 3;
+ }
+
+ for (len = 0; find[len]!='\0'; len++);
+
+ if (len > 80) {
+ fprintf(stderr, "length of searchstring exceeds 80 chars");
+ return 4;
+ }
+
+ /* get a char from templ */
+ while ((int)(ch=fgetc(templ)) != EOF) {
+ if ((unsigned char)ch == find[matchcount]) {
+ /* if it matches find[matchcount],
+ * then store one more char in buffer,
+ * increase match count, and checks if
+ * the whole word has been found */
+ buffer[matchcount] = (unsigned char) ch;
+ buffer[++matchcount] = '\0';
+
+ if (matchcount == len) {
+ matchcount = 0;
+ fprintf(target, "%s", replace);
+ }
+ } else {
+ /* reset matchcount, flush buffer */
+ if (matchcount > 0) {
+ fprintf(target, "%s", buffer);
+ matchcount = 0;
+ }
+ fputc(ch, target);
+ }
+ }
+ fclose(templ);
+ fclose(target);
+ return 0;
+}
diff --git a/security/nss/lib/fortcrypt/secmodjar.html b/security/nss/lib/fortcrypt/secmodjar.html
new file mode 100644
index 000000000..f093a5965
--- /dev/null
+++ b/security/nss/lib/fortcrypt/secmodjar.html
@@ -0,0 +1,441 @@
+<HTML>
+<--
+ - 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.
+-->
+<HEAD>
+ <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+ <META NAME="Author" CONTENT="Hoi-Sheung Wilson So">
+ <META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (WinNT; I) [Netscape]">
+ <TITLE>How to Package Your Security Module for use with SmartUpdate</TITLE>
+</HEAD>
+<BODY>
+<FONT SIZE=+2>Using
+JAR Installation Manager Technology to Install Your PKCS11 Security Module</FONT>
+
+<P>Table of contents
+<BR><A HREF="#intro">I. Introduction</A>
+<BR><A HREF="#procedure">II. How to Create a Security Module JAR</A>
+<BR><A HREF="#samplescript">III. Sample Installer Script</A>
+<BR><A HREF="#reference">IV. Programmers' Reference</A>
+<BR><A HREF="#copyright">VI. Copyright Notice</A>
+<BR><A NAME="intro"></A><FONT SIZE=+1>I. Introduction</FONT>
+<BR>This docuemnt describes how to prepare your security module so that
+users can download it from the Internet, verify its integrity, and install
+by only pointing and clicking mouses.&nbsp; The packaged module is a signed
+JAR archive. This JAR archive contains a dynamically-linked library which
+implements the Security Module and a pice of installer script (.js) that
+registers and configures the newly installed module.&nbsp; SmartUpdate
+allows users to download JAR archinve that has been signed digitally by
+the software vendor.&nbsp; SmartUpdate then decompresses the JAR file,
+verify the signature and validity of the files packaged into the archive.&nbsp;
+If the signature is valid, SmartUpdate will run the installer script found
+in the archive.&nbsp; The installer script will instruct SmartUpdate to
+move the downloaded security module library to a specified location.&nbsp;
+Next, the script will register the module with Navigator, and configure
+it.
+
+<P>This document does not describe how SmartUpdate works.&nbsp; For more
+information about SmartUpdate, check out <A HREF="http://developer.netscape.com/library/documentation/communicator/jarman/index.htm">JAR
+Installation Manager</A>.
+
+<P><A NAME="procedure"></A><FONT SIZE=+1>II. How to Create a Security Module
+JAR</FONT>
+<OL>
+<LI>
+Obtain a copy of PKCS#11: Cryptographic Token Interface Standard Version
+2.00, published by <A HREF="http://www.rsa.com">RSA Laboratories</A>, Redwood
+City, California.</LI>
+
+<LI>
+Implement a PKCS#11 library according to PKCS#11 standards.</LI>
+
+<LI>
+Write a installer script that will register the module with Navigator.</LI>
+
+<LI>
+Use either JAR Packager or command line tool to package the library and
+the script in a signed JAR archive.</LI>
+
+<LI>
+Publish the JAR file on the web, and notify users to install/upgrade their
+library.</LI>
+</OL>
+<A NAME="samplescript"></A><FONT SIZE=+1>III. Sample Installer Script</FONT>
+
+<P>Functions of the following installer script:
+<BR>1. Start SmartUpdate and declares the version and the name of the module
+to be installed.
+<BR>2. Extract a library called DUMMY_DLL from the JAR archive and install
+it under the Netscape Program folder.
+<BR>3. Register the installed module by calling pkcs11.addmodule( ) method
+with information about the capabilities of the module.
+<BR>4. Check to see if pkcs11.addmodule( ) has been successful, and display
+appropriate messages.
+
+<P><TT>// Crypto Mechanism Flags</TT>
+<BR><TT>PKCS11_MECH_RSA_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;0;</TT>
+<BR><TT>PKCS11_MECH_DSA_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;1;</TT>
+<BR><TT>PKCS11_MECH_RC2_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;2;</TT>
+<BR><TT>PKCS11_MECH_RC4_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;3;</TT>
+<BR><TT>PKCS11_MECH_DES_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;4;</TT>
+<BR><TT>PKCS11_MECH_DH_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;5; //Diffie-Hellman</TT>
+<BR><TT>PKCS11_MECH_SKIPJACK_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;
+0x1&lt;&lt;6; //SKIPJACK algorithm as in Fortezza cards</TT>
+<BR><TT>PKCS11_MECH_RC5_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;7;</TT>
+<BR><TT>PKCS11_MECH_SHA1_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;8;</TT>
+<BR><TT>PKCS11_MECH_MD5_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;9;</TT>
+<BR><TT>PKCS11_MECH_MD2_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;10;</TT>
+<BR><TT>PKCS11_MECH_RANDOM_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;27; //Random number generator</TT>
+<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG&nbsp; =&nbsp; 0x1&lt;&lt;28; //Stored
+certs can be read off the token w/o logging in</TT>
+<BR><TT>PKCS11_DISABLE_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;30; //tell Navigator to disable this slot by default</TT>
+
+<P><TT>// Important:</TT>
+<BR><TT>// 0x1&lt;&lt;11, 0x1&lt;&lt;12, ... , 0x1&lt;&lt;26, and 0x1&lt;&lt;31
+are reserved</TT>
+<BR><TT>// for internal use in Navigator.</TT>
+<BR><TT>// Therefore, these bits should always be set to 0; otherwise,</TT>
+<BR><TT>// Navigator might exhibit unpredictable behavior.</TT>
+
+<P><TT>// These flags indicate which mechanisms should be turned on by</TT>
+<BR><TT>pkcs11MechanismFlags = PKCS11_MECH_DSA_FLAG | PKCS11_MECH_SKIPJACK_FLAG
+| PKCS11_MECH_RANDOM_FLAG;</TT>
+<BR><TT>&nbsp;</TT>
+
+<P><TT>// Ciphers that support SSL or S/MIME</TT>
+<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG&nbsp;&nbsp;&nbsp; = 0x1&lt;&lt;0;</TT>
+
+<P><TT>// Important:</TT>
+<BR><TT>// 0x1&lt;&lt;11, 0x1&lt;&lt;12, ... , 0x1&lt;&lt;26, 0x1&lt;&lt;29,
+and 0x1&lt;&lt;31 are reserved</TT>
+<BR><TT>// for internal use in Navigator.</TT>
+<BR><TT>// Therefore, these bits should ALWAYS be set to 0; otherwise,</TT>
+<BR><TT>// Navigator might exhibit unpredictable behavior.</TT>
+
+<P><TT>// These flags indicate which SSL ciphers are supported</TT>
+<BR><TT>pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;</TT>
+<BR><TT>&nbsp;</TT>
+
+<P><TT>// Return values of pkcs11.addmodule() &amp; pkcs11.delmodule()</TT>
+<BR><TT>// success codes</TT>
+<BR><TT>JS_OK_ADD_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 3 // Successfully added a module</TT>
+<BR><TT>JS_OK_DEL_EXTERNAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 2 // Successfully deleted ext. module</TT>
+<BR><TT>JS_OK_DEL_INTERNAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 1 // Successfully deleted int. module</TT>
+
+<P><TT>// failure codes</TT>
+<BR><TT>JS_ERR_OTHER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -1 // Other errors than the followings</TT>
+<BR><TT>JS_ERR_USER_CANCEL_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -2 // User abort an action</TT>
+<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect
+# of arguments</TT>
+<BR><TT>JS_ERR_DEL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -4 // Error deleting a module</TT>
+<BR><TT>JS_ERR_ADD_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -5 // Error adding a module</TT>
+<BR><TT>JS_ERR_BAD_MODULE_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -6 // The module name is invalid</TT>
+<BR><TT>JS_ERR_BAD_DLL_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -7 // The DLL name is bad</TT>
+<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -8 // The mechanism flags are invalid</TT>
+<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS&nbsp;&nbsp; = -9 // The SSL, S/MIME
+cipher flags are invalid</TT>
+<BR>&nbsp;
+
+<P><TT>if (confirm("This script will install and configure a security module,
+do you want to continue?")) {</TT>
+<BR><TT>&nbsp;// Step 1. Create a version object and a software update
+object</TT>
+<BR><TT>&nbsp;vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);</TT>
+<BR><TT>&nbsp;su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza
+Card PKCS#11 Module");</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// "Fortezza ... Module" is the logical name of the bundle</TT>
+
+<P><TT>&nbsp;// Step 2. Start the install process</TT>
+<BR><TT>&nbsp;bAbort = false;</TT>
+<BR><TT>&nbsp;err = su.StartInstall("litronic", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL);</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+// litronic is the component folder (logical)</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bAbort = bAbort || (err
+!=0);</TT>
+
+<P><TT>&nbsp;if (err == 0) {</TT>
+
+<P><TT>&nbsp;&nbsp;&nbsp; // Step 3. Find out the physical location of
+the Program dir</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; Folder = su.GetFolder("Program");</TT>
+
+<P><TT>&nbsp;&nbsp;&nbsp; // Step 4. Install the files. Unpack them and
+list where they go</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; err = su.AddSubcomponent("FortezzaCardDLL",
+//component name (logical)</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+vi, // version info</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+"DUMMY_DLL", // source file in JAR (physical)</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Folder, // target folder (physical)</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+"DUMMY_DLL", // target path &amp; filename (physical)</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+this.force); // forces update</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; bAbort = bAbort || (err !=0);</TT>
+<BR><TT>&nbsp;}</TT>
+
+<P><TT>&nbsp;// Step 5. Unless there was a problem, move files to final
+location</TT>
+<BR><TT>&nbsp;// and update the Client Version Registry</TT>
+<BR><TT>&nbsp;if (bAbort) {</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; window.alert("Installation Aborted");</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; su.AbortInstall();</TT>
+<BR><TT>&nbsp;} else {</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; err = su.FinalizeInstall();</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; window.alert("Files have been installed.\nContinue
+to setup the newly isntalled module...");</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; // Add Module</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; compFolder = su.GetComponentFolder("litronic/FortezzaCardDLL")
++ "/DUMMY_DLL";</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp; result = pkcs11.addmodule("Fortezza", compFolder,
+pkcs11MechanismFlags, pkcs11CipherFlags);</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if
+( result &lt; 0) {</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+window.alert("New module setup failed.&nbsp; Error code: " + result);</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
+else {</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+window.alert("New module setup completed.");</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</TT>
+<BR><TT>&nbsp;}</TT>
+<BR><TT>}</TT>
+
+<P><A NAME="reference"></A><FONT SIZE=+1>IV. Appendix A: Programmers' Refernce</FONT>
+<UL>
+<LI>
+<A HREF="#delmodule">pkcs11.addmodule( )</A></LI>
+
+<LI>
+<A HREF="#delmodule">pkcs11.delmodule( )</A></LI>
+</UL>
+
+<HR ALIGN=LEFT WIDTH="70%">
+<BR><A NAME="addmodule"></A>Name
+<BR><TT>addmodule</TT>
+<BR>Adds a PKCS#11 security module to the security module database, and
+notifies Communicator which cryptographic mechanisms should be turned on
+by default, and which SSL or S/MIME ciphers are supported.&nbsp; For security
+reasons, it will pop up a dialog box to ask the user to confirm this action.&nbsp;
+It might pop up other dialog boxes if necessary.
+
+<P>Method of
+<BR><TT>pkcs11</TT>
+
+<P>Syntax
+<BR><TT>int pkcs11.addmodule( string ModuleName,</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+string LibraryFullPath,</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+int CryptoMechanismFlags,</TT>
+<BR><TT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+int CipherFlags);</TT>
+<BR>&nbsp;
+<BR>Parameters
+<TABLE BORDER WIDTH="90%" >
+<TR>
+<TD><TT>ModuleName</TT></TD>
+
+<TD>Name of the module</TD>
+</TR>
+
+<TR>
+<TD><TT>LibraryFullPath</TT></TD>
+
+<TD>The filename of the library prepended with its full path</TD>
+</TR>
+
+<TR>
+<TD><TT>CryptoMechanismFlags</TT></TD>
+
+<TD>A bit vector indicating all cryptographic mechanisms should be turned
+on by default&nbsp; (See below)</TD>
+</TR>
+
+<TR>
+<TD><TT>CipherFlags</TT></TD>
+
+<TD>A bit vector indicating all SSL or S/MIME cipher functions supported
+by the module (Seel below)</TD>
+</TR>
+</TABLE>
+Cryptographic Mechanism Flags
+<BR><TT>PKCS11_MECH_RSA_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;0;</TT>
+<BR><TT>PKCS11_MECH_DSA_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;1;</TT>
+<BR><TT>PKCS11_MECH_RC2_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;2;</TT>
+<BR><TT>PKCS11_MECH_RC4_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;3;</TT>
+<BR><TT>PKCS11_MECH_DES_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;4;</TT>
+<BR><TT>PKCS11_MECH_DH_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;5; //Diffie-Hellman</TT>
+<BR><TT>PKCS11_MECH_SKIPJACK_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;
+0x1&lt;&lt;6; //SKIPJACK algorithm as in Fortezza cards</TT>
+<BR><TT>PKCS11_MECH_RC5_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;7;</TT>
+<BR><TT>PKCS11_MECH_SHA1_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;8;</TT>
+<BR><TT>PKCS11_MECH_MD5_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;9;</TT>
+<BR><TT>PKCS11_MECH_MD2_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;10;</TT>
+<BR><TT>PKCS11_MECH_RANDOM_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;27; //Random number generator</TT>
+<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG&nbsp; =&nbsp; 0x1&lt;&lt;28; //Stored
+certs can be read off the token w/o logging in</TT>
+<BR><TT>PKCS11_DISABLE_FLAG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+=&nbsp; 0x1&lt;&lt;30; //tell Navigator to disable this slot by default</TT>
+
+<P>Supported SSL or S/MIME Ciphers
+<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG&nbsp;&nbsp;&nbsp; = 0x1&lt;&lt;0;</TT>
+
+<P>Important for CryptoMechanismFlags:
+<BR><TT>0x1&lt;&lt;11</TT>, <TT>0x1&lt;&lt;12</TT>, ... , <TT>0x1&lt;&lt;26</TT>,
+<TT>0x1&lt;&lt;29, </TT>and <TT>0x1&lt;&lt;31</TT> are reserved for internal
+use in Navigator.
+<BR>Therefore, these bits should always be set to 0; otherwise, Navigator
+might exhibit unpredictable behavior.
+
+<P>Important for CipherFlags:
+<BR><TT>0x1&lt;&lt;1</TT>, <TT>0x1&lt;&lt;2</TT>, ... , <TT>0x1&lt;&lt;31</TT>
+are reserved for internal use in Navigator.
+<BR>Therefore, these bits should ALWAYS be set to 0; otherwise, Navigator
+might exhibit unpredictable behavior.
+
+<P>Example of CryptoMechanismFlags and CipherFlags:
+<BR><TT>pkcs11MechanismFlags = PKCS11_MECH_DSA_FLAG | PKCS11_MECH_SKIPJACK_FLAG
+| PKCS11_MECH_RANDOM_FLAG;</TT>
+<BR><TT>pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;</TT>
+<BR><TT>&nbsp;</TT>
+<BR>Return Values:
+<BR><TT>// Return values of pkcs11.addmod()</TT>
+<BR><TT>// success codes</TT>
+<BR><TT>JS_OK_ADD_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 3 // Successfully added a module</TT>
+
+<P><TT>// failure codes</TT>
+<BR><TT>JS_ERR_OTHER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -1 // Other errors than the followings</TT>
+<BR><TT>JS_ERR_USER_CANCEL_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -2 // User abort an action</TT>
+<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect
+# of arguments</TT>
+<BR><TT>JS_ERR_ADD_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -5 // Error adding a module</TT>
+<BR><TT>JS_ERR_BAD_MODULE_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -6 // The module name is invalid</TT>
+<BR><TT>JS_ERR_BAD_DLL_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -7 // The DLL name is bad</TT>
+<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -8 // The mechanism flags are invalid</TT>
+<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS&nbsp;&nbsp; = -9 // The SSL, S/MIME
+cipher flags are invalid</TT>
+<BR>&nbsp;
+<HR ALIGN=LEFT WIDTH="70%">
+<BR><A NAME="delmodule"></A>Name
+<BR><TT>delmodule</TT>
+<BR>Deletes a PKCS#11 security module from the module database, but does
+not physically remove the file.&nbsp; For security reasons, it will pop
+up a dialog box to ask the user to confirm this action.&nbsp; It might
+pop up other dialog boxes if necessary.
+
+<P>Method of
+<BR><TT>pkcs11</TT>
+
+<P>Syntax
+<BR><TT>int pkcs11.delmodule( string ModuleName);</TT>
+<BR>&nbsp;
+<BR>Parameters
+<TABLE BORDER WIDTH="90%" >
+<TR>
+<TD><TT>ModuleName</TT></TD>
+
+<TD>Name of the module</TD>
+</TR>
+</TABLE>
+<TT>&nbsp;</TT>
+<BR>Return Values:
+<BR><TT>// Return values of pkcs11.addmod() &amp; pkcs11.delmod()</TT>
+<BR><TT>// success codes</TT>
+<BR><TT>JS_OK_DEL_EXTERNAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 2 // Successfully deleted ext. module</TT>
+<BR><TT>JS_OK_DEL_INTERNAL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= 1 // Successfully deleted int. module</TT>
+
+<P><TT>// failure codes</TT>
+<BR><TT>JS_ERR_OTHER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -1 // Other errors than the followings</TT>
+<BR><TT>JS_ERR_USER_CANCEL_ACTION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -2 // User abort an action</TT>
+<BR><TT>JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3 // Calling a method w/ incorrect
+# of arguments</TT>
+<BR><TT>JS_ERR_DEL_MODULE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -4 // Error deleting a module</TT>
+<BR><TT>JS_ERR_BAD_MODULE_NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+= -6 // The module name is invalid</TT>
+
+<P><A NAME="copyright"></A><FONT SIZE=+1>VI. Copyright Notice</FONT>
+<BR>&nbsp;
+
+<P><FONT SIZE=+4>XXX Don't know what to put here!!!</FONT>
+
+<P>Last modified 9/26/97
+</BODY>
+</HTML>
diff --git a/security/nss/lib/fortcrypt/swfort/.cvsignore b/security/nss/lib/fortcrypt/swfort/.cvsignore
new file mode 100644
index 000000000..46d9697ae
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/.cvsignore
@@ -0,0 +1 @@
+nslib.c
diff --git a/security/nss/lib/fortcrypt/swfort/Makefile b/security/nss/lib/fortcrypt/swfort/Makefile
new file mode 100644
index 000000000..80b91c768
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/Makefile
@@ -0,0 +1,82 @@
+#! 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 config.mk
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
+
+nslib.c:: swflib.c nsmap.h
+ rm -f nslib.c
+ cat nsmap.h swflib.c > nslib.c
+
+export:: private_export
+
+
diff --git a/security/nss/lib/fortcrypt/swfort/config.mk b/security/nss/lib/fortcrypt/swfort/config.mk
new file mode 100644
index 000000000..a73a1086e
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/config.mk
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+TARGETS = $(LIBRARY)
+SHARED_LIBRARY =
+IMPORT_LIBRARY =
+PURE_LIBRARY =
+PROGRAM =
+
diff --git a/security/nss/lib/fortcrypt/swfort/manifest.mn b/security/nss/lib/fortcrypt/swfort/manifest.mn
new file mode 100644
index 000000000..5445af13b
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/manifest.mn
@@ -0,0 +1,56 @@
+#
+# 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 = ../../../..
+
+MODULE = security
+LIBRARY_NAME = swfci
+#LIBRARY_VERSION = 12
+
+CSRCS = swfalg.c \
+ swfparse.c \
+ swflib.c \
+ nslib.c \
+ swfutl.c \
+ $(NULL)
+
+DIRS = pkcs11
+
+
+EXPORTS = swfort.h swfortt.h
+PRIVATE_EXPORTS = swforti.h swfortti.h
+
+REQUIRES = security dbm nspr
+
+GARBAGE = nslib.c
+
+
diff --git a/security/nss/lib/fortcrypt/swfort/nsmap.h b/security/nss/lib/fortcrypt/swfort/nsmap.h
new file mode 100644
index 000000000..b5e1c2cda
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/nsmap.h
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+#define MACI_ChangePIN NSCI_ChangePIN
+#define MACI_CheckPIN NSCI_CheckPIN
+#define MACI_Close NSCI_Close
+#define MACI_Decrypt NSCI_Decrypt
+#define MACI_DeleteCertificate NSCI_DeleteCertificate
+#define MACI_DeleteKey NSCI_DeleteKey
+#define MACI_Encrypt NSCI_Encrypt
+#define MACI_ExtractX NSCI_ExtractX
+#define MACI_FirmwareUpdate NSCI_FirmwareUpdate
+#define MACI_GenerateIV NSCI_GenerateIV
+#define MACI_GenerateMEK NSCI_GenerateMEK
+#define MACI_GenerateRa NSCI_GenerateRa
+#define MACI_GenerateRandom NSCI_GenerateRandom
+#define MACI_GenerateTEK NSCI_GenerateTEK
+#define MACI_GenerateX NSCI_GenerateX
+#define MACI_GetCertificate NSCI_GetCertificate
+#define MACI_GetConfiguration NSCI_GetConfiguration
+#define MACI_GetHash NSCI_GetHash
+#define MACI_GetPersonalityList NSCI_GetPersonalityList
+#define MACI_GetSessionID NSCI_GetSessionID
+#define MACI_GetState NSCI_GetState
+#define MACI_GetStatus NSCI_GetStatus
+#define MACI_GetTime NSCI_GetTime
+#define MACI_Hash NSCI_Hash
+#define MACI_Initialize NSCI_Initialize
+#define MACI_InitializeHash NSCI_InitializeHash
+#define MACI_InstallX NSCI_InstallX
+#define MACI_LoadCertificate NSCI_LoadCertificate
+#define MACI_LoadDSAParameters NSCI_LoadDSAParameters
+#define MACI_LoadInitValues NSCI_LoadInitValues
+#define MACI_LoadIV NSCI_LoadIV
+#define MACI_LoadX NSCI_LoadX
+#define MACI_Lock NSCI_Lock
+#define MACI_Open NSCI_Open
+#define MACI_RelayX NSCI_RelayX
+#define MACI_Reset NSCI_Reset
+#define MACI_Restore NSCI_Restore
+#define MACI_Save NSCI_Save
+#define MACI_Select NSCI_Select
+#define MACI_SetConfiguration NSCI_SetConfiguration
+#define MACI_SetKey NSCI_SetKey
+#define MACI_SetMode NSCI_SetMode
+#define MACI_SetPersonality NSCI_SetPersonality
+#define MACI_SetTime NSCI_SetTime
+#define MACI_Sign NSCI_Sign
+#define MACI_Terminate NSCI_Terminate
+#define MACI_TimeStamp NSCI_TimeStamp
+#define MACI_Unlock NSCI_Unlock
+#define MACI_UnwrapKey NSCI_UnwrapKey
+#define MACI_VerifySignature NSCI_VerifySignature
+#define MACI_VerifyTimeStamp NSCI_VerityTimeStap
+#define MACI_WrapKey NSCI_WrapKey
+#define MACI_Zeroize NSCI_Zeroize
+
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore b/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore
new file mode 100644
index 000000000..6532d294d
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/.cvsignore
@@ -0,0 +1,15 @@
+forsock.c
+cryptint.h
+fmutex.h
+fortsock.h
+fpkcs11.h
+fpkcs11f.h
+fpkcs11i.h
+fpkcs11t.h
+fpkmem.h
+fpkstrs.h
+genci.h
+maci.h
+fortpk11.c
+fmutex.c
+
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile
new file mode 100644
index 000000000..afb11cf6f
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile
@@ -0,0 +1,164 @@
+#! 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.
+#
+
+include manifest.mn
+include $(CORE_DEPTH)/coreconf/config.mk
+
+
+#SWCILIB = ../$(OBJDIR)/$(LIB_PREFIX)swfci.$(LIB_SUFFIX)
+# can't do this in manifest.mn because OS_ARCH isn't defined there.
+ifeq ($(OS_ARCH), WINNT)
+
+# $(DIST)/lib/dbm.lib
+# $(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib
+EXTRA_LIBS = \
+ $(DIST)/lib/swfci.lib \
+ $(DIST)/lib/softoken.lib \
+ $(DIST)/lib/freebl.lib \
+ $(DIST)/lib/crypto.lib \
+ $(DIST)/lib/secutil.lib \
+ $(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4_s.lib \
+ $(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4_s.lib \
+ wsock32.lib \
+ winmm.lib \
+ $(NULL)
+else
+
+# $(DIST)/lib/libdbm.a
+# $(DIST)/lib/libnspr3.a
+# OSF 1 linker is very agressive. It includes the entire archive,
+# not just the .o's that we need from that archive.
+#
+ifneq ($(OS_ARCH), OSF1)
+EXTRA_LIBS += \
+ $(DIST)/lib/libswfci.a \
+ $(DIST)/lib/libsoftoken.a \
+ $(DIST)/lib/libfreebl.a \
+ $(DIST)/lib/libcrypto.a \
+ $(DIST)/lib/libsecutil.a \
+ $(DIST)/lib/libplc4.a \
+ $(DIST)/lib/libplds4.a \
+ $(NULL)
+endif
+endif
+
+#ifeq ($(OS_TARGET), WIN16)
+#W16LIBS += $(SWCILIB)
+#else
+#OBJS += $(SWCILIB)
+#endif
+
+INST_JS = inst.js
+LIBCI_JAR = $(OBJDIR)/lib$(LIBRARY_NAME).jar
+LIBCI_JAR_SRC = $(INST_JS) pk11inst $(SHARED_LIBRARY)
+
+ifneq ($(OS_TARGET), WIN16)
+TARGETS : $(LIBCI_JAR)
+endif
+
+ifeq ($(OS_TARGET), WIN16)
+# note that rules.mk is not included below for WIN16
+all:
+ @echo Skipping fortcrypt directory for 16-bit windows builds
+
+all_platforms alltags clean clobber clobber_all realclean: all
+
+boot export install libs program release: all
+
+endif
+
+#$(SHARED_LIBRARY): $(SWCILIB)
+
+forsock.c: ../../forsock.c $(CP_INCLUDES)
+ cp ../../forsock.c $(CP_INCLUDES) .
+
+fortpk11.c: ../../fortpk11.c
+ cp ../../fortpk11.c .
+
+fmutex.c: ../../fmutex.c
+ cp ../../fmutex.c .
+
+
+#
+# The following rules packages the shared library into a JAR,
+# ready to be signed
+#
+$(OBJDIR)/replace: replace.c
+ $(CC) -o $@ $<
+
+# ZIP options:
+# -5 means medium compression
+# -q means quiet
+# -j means do not store tree structure, all files go into one dir
+#
+$(LIBCI_JAR): $(LIBCI_JAR_SRC)
+ @echo +++ building $@ from $(LIBCI_JAR_SRC)
+ @rm -f $@
+ zip -5qj $@ $(LIBCI_JAR_SRC)
+
+$(LIBSWCI_JAR): $(LIBSWCI_JAR_SRC)
+ @echo +++ building $@ from $(LIBSWCI_JAR_SRC)
+ @rm -f $@
+ zip -5qj $@ $(LIBSWCI_JAR_SRC)
+
+
+MD_FILES += $(LIBCI_JAR) $(LIBSWCI_JAR)
+
+# coreconf doesn't build the AIX shared library for FORTEZZA,
+# so I'm going to override their shared library command and build the shared
+# library the way config used to.
+#
+
+
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
+DSO_LDOPTS = -bM:SRE -bh:4 -bnoentry
+EXTRA_DSO_LDOPTS = -lc
+MKSHLIB = xlC $(DSO_LDOPTS)
+
+$(SHARED_LIBRARY): $(OBJS)
+ @$(MAKE_OBJDIR)
+ rm -f $@
+ $(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS)
+ chmod +x $@
+
+endif
+
+ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.2)
+LD += -G
+endif
+
+ifneq ($(OS_TARGET), WIN16)
+include $(CORE_DEPTH)/coreconf/rules.mk
+endif
+
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk b/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk
new file mode 100644
index 000000000..9b1a488d2
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+#
+# Override TARGETS variable so that only static libraries
+# are specifed as dependencies within rules.mk.
+#
+
+ifeq ($(OS_TARGET), WIN16)
+TARGETS = all
+else
+TARGETS = $(SHARED_LIBRARY) $(SHARED_SW_LIBRARY) $(LIBCI_JAR) $(LIBCI_SW_JAR)
+endif
+LIBRARY =
+PURE_LIBRARY =
+PROGRAM =
+
+
+ifeq ($(OS_TARGET), WIN16)
+dummy:
+ @echo $(TARGETS)
+endif
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js b/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js
new file mode 100644
index 000000000..2f7574717
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/inst.js
@@ -0,0 +1,189 @@
+//
+// 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.
+//
+////////////////////////////////////////////////////////////////////////////////////////
+// Crypto Mechanism Flags
+PKCS11_MECH_RSA_FLAG = 0x1<<0;
+PKCS11_MECH_DSA_FLAG = 0x1<<1;
+PKCS11_MECH_RC2_FLAG = 0x1<<2;
+PKCS11_MECH_RC4_FLAG = 0x1<<3;
+PKCS11_MECH_DES_FLAG = 0x1<<4;
+PKCS11_MECH_DH_FLAG = 0x1<<5; //Diffie-Hellman
+PKCS11_MECH_SKIPJACK_FLAG = 0x1<<6; //SKIPJACK algorithm as in Fortezza cards
+PKCS11_MECH_RC5_FLAG = 0x1<<7;
+PKCS11_MECH_SHA1_FLAG = 0x1<<8;
+PKCS11_MECH_MD5_FLAG = 0x1<<9;
+PKCS11_MECH_MD2_FLAG = 0x1<<10;
+PKCS11_MECH_RANDOM_FLAG = 0x1<<27; //Random number generator
+PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored certs can be read off the token w/o logging in
+PKCS11_DISABLE_FLAG = 0x1<<30; //tell Navigator to disable this slot by default
+
+// Important:
+// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, and 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should always be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which mechanisms should be turned on by
+var pkcs11MechanismFlags = 0;
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Ciphers that support SSL or S/MIME
+PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;
+
+// Important:
+// 0x1<<1, 0x1<<2, ... , 0x1<<31 are reserved
+// for internal use in Navigator.
+// Therefore, these bits should ALWAYS be set to 0; otherwise,
+// Navigator might exhibit unpredictable behavior.
+
+// These flags indicate which SSL ciphers are supported
+var pkcs11CipherFlags = PKCS11_CIPHER_FORTEZZA_FLAG;
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Return values of pkcs11.addmodule() & pkcs11.delmodule()
+// success codes
+JS_OK_ADD_MODULE = 3; // Successfully added a module
+JS_OK_DEL_EXTERNAL_MODULE = 2; // Successfully deleted ext. module
+JS_OK_DEL_INTERNAL_MODULE = 1; // Successfully deleted int. module
+
+// failure codes
+JS_ERR_OTHER = -1; // Other errors than the followings
+JS_ERR_USER_CANCEL_ACTION = -2; // User abort an action
+JS_ERR_INCORRECT_NUM_OF_ARGUMENTS= -3; // Calling a method w/ incorrect # of arguments
+JS_ERR_DEL_MODULE = -4; // Error deleting a module
+JS_ERR_ADD_MODULE = -5; // Error adding a module
+JS_ERR_BAD_MODULE_NAME = -6; // The module name is invalid
+JS_ERR_BAD_DLL_NAME = -7; // The DLL name is bad
+JS_ERR_BAD_MECHANISM_FLAGS = -8; // The mechanism flags are invalid
+JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9; // The SSL, S/MIME cipher flags are invalid
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Find out which library is to be installed depending on the platform
+
+// pathname seperator is platform specific
+var sep = "/";
+var vendor = "netscape";
+var moduleName = "not_supported";
+
+// platform-independent relative path
+var dir = "pkcs11/" + vendor + "/";
+
+var plat = navigator.platform;
+
+bAbort = false;
+progName = "instinit";
+if (plat == "Win32") {
+ moduleName = "swft32.dll";
+ // progName = "instinit.exe";
+ sep = "\\";
+} else if (plat == "AIX4.1") {
+ moduleName = "libswft.so";
+} else if (plat == "SunOS4.1.3_U1") {
+ moduleName = "libswft.so.1.0";
+} else if ((plat == "SunOS5.4") || (plat == "SunOS5.5.1")){
+ moduleName = "libswft.so";
+} else if ((plat == "HP-UXA.09") || (plat == "HP-UXB.10")){
+ moduleName = "libswft.sl";
+} else {
+ window.alert("Sorry, platform "+plat+" is not supported.");
+ bAbort = true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Installation Begins...
+if (!bAbort) {
+if (confirm("This script will install and configure a security module, do you want to continue?")) {
+ // Step 1. Create a version object and a software update object
+ vi = new netscape.softupdate.VersionInfo(1, 5, 0, 0);
+ su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza Card PKCS#11 Module");
+ // "Fortezza ... Module" is the logical name of the bundle
+
+ ////////////////////////////////////////
+ // Step 2. Start the install process
+ bAbort = false;
+ err = su.StartInstall("NSfortezza", // NSfortezza is the component folder (logical)
+ vi,
+ netscape.softupdate.SoftwareUpdate.FULL_INSTALL);
+
+ bAbort = bAbort || (err !=0);
+
+ if (err == 0) {
+ ////////////////////////////////////////
+ // Step 3. Find out the physical location of the Program dir
+ Folder = su.GetFolder("Program");
+
+ ////////////////////////////////////////
+ // Step 4. Install the files. Unpack them and list where they go
+ err = su.AddSubcomponent("FortezzaLibrary", //component name (logical)
+ vi, // version info
+ moduleName, // source file in JAR (physical)
+ Folder, // target folder (physical)
+ dir + moduleName, // target path & filename (physical)
+ this.force); // forces update
+ bAbort = bAbort || (err !=0);
+ if (err != 0) window.alert("Add sub err= "+ err);
+ }
+
+ if (err == 0) {
+ /// Try installing the init program
+ err = su.AddSubcomponent("FortezzaInitProg", vi, progName, Folder, progName, this.force);
+ // don't fail because it didn't install, may just not be part of the package
+}
+
+ ////////////////////////////////////////
+ // Step 5. Unless there was a problem, move files to final location
+ // and update the Client Version Registry
+ if (bAbort) {
+ window.alert("Aborting, Folder="+Folder+" module="+dir+moduleName);
+ su.AbortInstall();
+ } else {
+ err = su.FinalizeInstall();
+ // Platform specific full path
+ fullpath = Folder + "pkcs11" + sep + vendor + sep + moduleName;
+
+ ////////////////////////////////////////
+ // Step 6: Call pkcs11.addmodule() to register the newly downloaded module
+ result = pkcs11.addmodule("Netscape Software FORTEZZA Module",
+ fullpath,
+ pkcs11MechanismFlags,
+ pkcs11CipherFlags);
+
+ if ( result < 0) {
+ window.alert("New module setup failed. Error code: " + result);
+ } else {
+ window.alert("New module setup completed.");
+ }
+ }
+}
+}
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn b/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn
new file mode 100644
index 000000000..eca9b5ab3
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn
@@ -0,0 +1,73 @@
+#
+# 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 = ../../../../..
+
+MODULE = security
+LIBRARY_NAME = swft
+#LIBRARY_VERSION = 32
+
+COPIED_CSRCS = forsock.c \
+ fortpk11.c \
+ fmutex.c \
+ $(NULL)
+
+CSRCS = \
+ $(COPIED_CSRCS) \
+ stub.c \
+ $(NULL)
+
+EXPORTS =
+
+REQUIRES = security dbm
+
+CP_INCLUDES = \
+ ../../cryptint.h \
+ ../../fmutex.h \
+ ../../fortsock.h \
+ ../../fpkcs11.h \
+ ../../fpkcs11f.h \
+ ../../fpkcs11i.h \
+ ../../fpkcs11t.h \
+ ../../fpkmem.h \
+ ../../fpkstrs.h \
+ ../../genci.h \
+ ../../maci.h \
+ $(NULL)
+
+CFLAGS += -DSWFORT
+
+GARBAGE = $(COPIED_CSRCS) cryptint.h fmutex.h fortsock.h fpkcs11.h \
+ fpkcs11f.h fpkcs11i.h fpkcs11t.h fpkmem.h fpkstrs.h genci.h maci.h
+
+
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst b/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst
new file mode 100755
index 000000000..31d73eb4a
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/pk11inst
@@ -0,0 +1,49 @@
+ForwardCompatible { HPUX:10:hppa1.1 Solaris:5.5.1:sparc AIX:4.1:rs6000 }
+ Platforms {
+ WINNT::x86 {
+ ModuleName { "Netscape Software FORTEZZA Module" }
+ ModuleFile { %root%/pkcs11/netscape/swft32.dll }
+ DefaultMechanismFlags{0x0000}
+ DefaultCipherFlags{0x0001}
+ Files {
+ swft32.dll {
+ RelativePath { %root%/pkcs11/netscape/swft32.dll }
+ }
+ }
+ WIN95::x86 {
+ EquivalentPlatform {WINNT::x86}
+ }
+ Solaris:5.5.1:sparc {
+ ModuleName { "Netscape Software FORTEZZA Module" }
+ ModuleFile { %root%/pkcs11/netscape/libswft.so }
+ DefaultMechanismFlags{0x0000}
+ DefaultCipherFlags{0x0001}
+ Files {
+ libswft.so {
+ RelativePath { %root%/pkcs11/netscape/libswft.so }
+ }
+ }
+ }
+ AIX:4.1:rs6000 {
+ ModuleName { "Netscape Software FORTEZZA Module" }
+ ModuleFile { %root%/pkcs11/netscape/libswft.so }
+ DefaultMechanismFlags{0x0000}
+ DefaultCipherFlags{0x0001}
+ Files {
+ libswft.so {
+ RelativePath { %root%/pkcs11/netscape/libswft.so }
+ }
+ }
+ }
+ HPUX:10:hppa1.1 {
+ ModuleName { "Netscape Software FORTEZZA Module" }
+ ModuleFile { %root%/pkcs11/netscape/libswft.sl }
+ DefaultMechanismFlags{0x0000}
+ DefaultCipherFlags{0x0001}
+ Files {
+ libswft.so {
+ RelativePath { %root%/pkcs11/netscape/libswft.sl }
+ }
+ }
+ }
+ }
diff --git a/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c
new file mode 100644
index 000000000..917eff386
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+/*
+ * secport.c - portability interfaces for security libraries
+ *
+ * This file abstracts out libc functionality that libsec depends on
+ *
+ * NOTE - These are not public interfaces. These stubs are to allow the
+ * SW FORTEZZA to link with some low level security functions without dragging
+ * in NSPR.
+ *
+ * $Id$
+ */
+
+#include "seccomon.h"
+#include "prmem.h"
+#include "prerror.h"
+#include "plarena.h"
+#include "secerr.h"
+#include "prmon.h"
+#include "prbit.h"
+
+unsigned long port_allocFailures;
+
+/* locations for registering Unicode conversion functions.
+ * Is this the appropriate location? or should they be
+ * moved to client/server specific locations?
+ */
+PORTCharConversionFunc ucs4Utf8ConvertFunc;
+PORTCharConversionFunc ucs2Utf8ConvertFunc;
+PORTCharConversionWSwapFunc ucs2AsciiConvertFunc;
+
+void *
+PORT_Alloc(size_t bytes)
+{
+ void *rv;
+
+ /* Always allocate a non-zero amount of bytes */
+ rv = (void *)malloc(bytes ? bytes : 1);
+ if (!rv) {
+ ++port_allocFailures;
+ }
+ return rv;
+}
+
+void *
+PORT_Realloc(void *oldptr, size_t bytes)
+{
+ void *rv;
+
+ rv = (void *)realloc(oldptr, bytes);
+ if (!rv) {
+ ++port_allocFailures;
+ }
+ return rv;
+}
+
+void *
+PORT_ZAlloc(size_t bytes)
+{
+ void *rv;
+
+ /* Always allocate a non-zero amount of bytes */
+ rv = (void *)calloc(1, bytes ? bytes : 1);
+ if (!rv) {
+ ++port_allocFailures;
+ }
+ return rv;
+}
+
+void
+PORT_Free(void *ptr)
+{
+ if (ptr) {
+ free(ptr);
+ }
+}
+
+void
+PORT_ZFree(void *ptr, size_t len)
+{
+ if (ptr) {
+ memset(ptr, 0, len);
+ free(ptr);
+ }
+}
+
+void
+PORT_SetError(int value)
+{
+ return;
+}
+
+int
+PORT_GetError(void)
+{
+ return(1);
+}
+
+/********************* Arena code follows *****************************/
+
+
+PLArenaPool *
+PORT_NewArena(unsigned long chunksize)
+{
+ PLArenaPool *arena;
+
+ arena = (PLArenaPool*)PORT_ZAlloc(sizeof(PLArenaPool));
+ if ( arena != NULL ) {
+ PR_InitArenaPool(arena, "security", chunksize, sizeof(double));
+ }
+ return(arena);
+}
+
+void *
+PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
+{
+ void *p;
+
+ PL_ARENA_ALLOCATE(p, arena, size);
+ if (p == NULL) {
+ ++port_allocFailures;
+ }
+
+ return(p);
+}
+
+void *
+PORT_ArenaZAlloc(PLArenaPool *arena, size_t size)
+{
+ void *p;
+
+ PL_ARENA_ALLOCATE(p, arena, size);
+ if (p == NULL) {
+ ++port_allocFailures;
+ } else {
+ PORT_Memset(p, 0, size);
+ }
+
+ return(p);
+}
+
+/* need to zeroize!! */
+void
+PORT_FreeArena(PLArenaPool *arena, PRBool zero)
+{
+ PR_FinishArenaPool(arena);
+ PORT_Free(arena);
+}
+
+void *
+PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize)
+{
+ PORT_Assert(newsize >= oldsize);
+
+ PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) );
+
+ return(ptr);
+}
+
+void *
+PORT_ArenaMark(PLArenaPool *arena)
+{
+ void * result;
+
+ result = PL_ARENA_MARK(arena);
+ return result;
+}
+
+void
+PORT_ArenaRelease(PLArenaPool *arena, void *mark)
+{
+ PL_ARENA_RELEASE(arena, mark);
+}
+
+void
+PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
+{
+ /* do nothing */
+}
+
+char *
+PORT_ArenaStrdup(PLArenaPool *arena,char *str) {
+ int len = PORT_Strlen(str)+1;
+ char *newstr;
+
+ newstr = (char*)PORT_ArenaAlloc(arena,len);
+ if (newstr) {
+ PORT_Memcpy(newstr,str,len);
+ }
+ return newstr;
+}
+
+PR_IMPLEMENT(void)
+PR_Assert(const char *expr, const char *file, int line) {
+ return;
+}
+
+PR_IMPLEMENT(void *)
+PR_Alloc(PRUint32 bytes) { return malloc(bytes); }
+
+PR_IMPLEMENT(void *)
+PR_Malloc(PRUint32 bytes) { return malloc(bytes); }
+
+PR_IMPLEMENT(void *)
+PR_Calloc(PRUint32 blocks, PRUint32 bytes) { return calloc(blocks,bytes); }
+
+PR_IMPLEMENT(void)
+PR_Free(void *ptr) { free(ptr); }
+
+
+/* Old template; want to expunge it eventually. */
+#include "secasn1.h"
+#include "secoid.h"
+
+const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SECAlgorithmID) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(SECAlgorithmID,algorithm), },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
+ offsetof(SECAlgorithmID,parameters), },
+ { 0, }
+};
+
+/* now make the RNG happy */ /* This is not atomic! */
+PR_IMPLEMENT(PRInt32) PR_AtomicIncrement(PRInt32 *val) { return ++(*val); }
+/* This is not atomic! */
+PR_IMPLEMENT(PRInt32) PR_AtomicDecrement(PRInt32 *val) { return --(*val); }
+
+PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) { return PR_SUCCESS; }
+
+#include "prlock.h"
+#include "fmutex.h"
+PR_IMPLEMENT(PRLock *)
+PR_NewLock(void) {
+ PRLock *lock = NULL;
+
+ FMUTEX_Create(&lock);
+
+ /* if we don't have a lock, FMUTEX can deal with things */
+ if (lock == NULL) lock=(PRLock *) 1;
+ return lock;
+}
+
+PR_IMPLEMENT(void)
+PR_DestroyLock(PRLock *lock) {
+ FMUTEX_Destroy(lock);
+}
+
+PR_IMPLEMENT(void)
+PR_Lock(PRLock *lock) {
+ FMUTEX_Lock(lock);
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_Unlock(PRLock *lock) {
+ FMUTEX_Unlock(lock);
+ return PR_SUCCESS;
+}
+
+/* this implementation is here to satisfy the PRMonitor use in plarena.c.
+** It appears that it doesn't need re-entrant locks. It could have used
+** PRLock instead of PRMonitor. So, this implementation just uses
+** PRLock for a PRMonitor.
+*/
+PR_IMPLEMENT(PRMonitor*)
+PR_NewMonitor(void)
+{
+ return (PRMonitor *) PR_NewLock();
+}
+
+
+PR_IMPLEMENT(void)
+PR_EnterMonitor(PRMonitor *mon)
+{
+ PR_Lock( (PRLock *)mon );
+}
+
+PR_IMPLEMENT(PRStatus)
+PR_ExitMonitor(PRMonitor *mon)
+{
+ return PR_Unlock( (PRLock *)mon );
+}
+
+#include "prinit.h"
+
+/* This is NOT threadsafe. It is merely a pseudo-functional stub.
+*/
+PR_IMPLEMENT(PRStatus) PR_CallOnce(
+ PRCallOnceType *once,
+ PRCallOnceFN func)
+{
+ /* This is not really atomic! */
+ if (1 == PR_AtomicIncrement(&once->initialized)) {
+ once->status = (*func)();
+ } else {
+ /* Should wait to be sure that func has finished before returning. */
+ }
+ return once->status;
+}
+
+
+/*
+** Compute the log of the least power of 2 greater than or equal to n
+*/
+PRIntn PR_CeilingLog2(PRUint32 i) {
+ PRIntn log2;
+ PR_CEILING_LOG2(log2,i);
+ return log2;
+}
+
+/********************** end of arena functions ***********************/
+
diff --git a/security/nss/lib/fortcrypt/swfort/swfalg.c b/security/nss/lib/fortcrypt/swfort/swfalg.c
new file mode 100644
index 000000000..6f8ab9f6c
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfalg.c
@@ -0,0 +1,506 @@
+/*
+ * 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.
+ */
+/*
+ * Software implementation of FORTEZZA skipjack primatives
+ */
+#include "maci.h"
+#include "seccomon.h"
+#include "swforti.h"
+
+/*
+ * Xor the IV into the plaintext buffer either just before encryption, or
+ * just after decryption.
+ */
+static void
+fort_XorIV(unsigned char *obuffer, unsigned char *buffer, unsigned char *iv) {
+ int i;
+#ifdef USE_INT32
+ if ((buffer & 0x3) == 0) && ((iv & 0x3) == 0)) {
+ int32 *ibuffer = (int32 *)buffer;
+ int32 *iobuffer = (int32 *)obuffer;
+ int32 *iiv = (int32 *)iv;
+
+ iobuffer[0] = ibuffer[0] ^ iiv[0];
+ iobuffer[1] = ibuffer[1] ^ iiv[1];
+ return;
+ }
+#endif
+
+ for (i=0; i < SKIPJACK_BLOCK_SIZE; i++) {
+ obuffer[i] = buffer[i] ^ iv[i];
+ }
+}
+
+
+/* the F-table for Skipjack */
+unsigned char F[256] = {
+ 0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4,
+ 0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9,
+ 0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e,
+ 0x52, 0x95, 0xd9, 0x1e, 0x4e, 0x38, 0x44, 0x28,
+ 0x0a, 0xdf, 0x02, 0xa0, 0x17, 0xf1, 0x60, 0x68,
+ 0x12, 0xb7, 0x7a, 0xc3, 0xe9, 0xfa, 0x3d, 0x53,
+ 0x96, 0x84, 0x6b, 0xba, 0xf2, 0x63, 0x9a, 0x19,
+ 0x7c, 0xae, 0xe5, 0xf5, 0xf7, 0x16, 0x6a, 0xa2,
+ 0x39, 0xb6, 0x7b, 0x0f, 0xc1, 0x93, 0x81, 0x1b,
+ 0xee, 0xb4, 0x1a, 0xea, 0xd0, 0x91, 0x2f, 0xb8,
+ 0x55, 0xb9, 0xda, 0x85, 0x3f, 0x41, 0xbf, 0xe0,
+ 0x5a, 0x58, 0x80, 0x5f, 0x66, 0x0b, 0xd8, 0x90,
+ 0x35, 0xd5, 0xc0, 0xa7, 0x33, 0x06, 0x65, 0x69,
+ 0x45, 0x00, 0x94, 0x56, 0x6d, 0x98, 0x9b, 0x76,
+ 0x97, 0xfc, 0xb2, 0xc2, 0xb0, 0xfe, 0xdb, 0x20,
+ 0xe1, 0xeb, 0xd6, 0xe4, 0xdd, 0x47, 0x4a, 0x1d,
+ 0x42, 0xed, 0x9e, 0x6e, 0x49, 0x3c, 0xcd, 0x43,
+ 0x27, 0xd2, 0x07, 0xd4, 0xde, 0xc7, 0x67, 0x18,
+ 0x89, 0xcb, 0x30, 0x1f, 0x8d, 0xc6, 0x8f, 0xaa,
+ 0xc8, 0x74, 0xdc, 0xc9, 0x5d, 0x5c, 0x31, 0xa4,
+ 0x70, 0x88, 0x61, 0x2c, 0x9f, 0x0d, 0x2b, 0x87,
+ 0x50, 0x82, 0x54, 0x64, 0x26, 0x7d, 0x03, 0x40,
+ 0x34, 0x4b, 0x1c, 0x73, 0xd1, 0xc4, 0xfd, 0x3b,
+ 0xcc, 0xfb, 0x7f, 0xab, 0xe6, 0x3e, 0x5b, 0xa5,
+ 0xad, 0x04, 0x23, 0x9c, 0x14, 0x51, 0x22, 0xf0,
+ 0x29, 0x79, 0x71, 0x7e, 0xff, 0x8c, 0x0e, 0xe2,
+ 0x0c, 0xef, 0xbc, 0x72, 0x75, 0x6f, 0x37, 0xa1,
+ 0xec, 0xd3, 0x8e, 0x62, 0x8b, 0x86, 0x10, 0xe8,
+ 0x08, 0x77, 0x11, 0xbe, 0x92, 0x4f, 0x24, 0xc5,
+ 0x32, 0x36, 0x9d, 0xcf, 0xf3, 0xa6, 0xbb, 0xac,
+ 0x5e, 0x6c, 0xa9, 0x13, 0x57, 0x25, 0xb5, 0xe3,
+ 0xbd, 0xa8, 0x3a, 0x01, 0x05, 0x59, 0x2a, 0x46
+};
+
+typedef unsigned char fort_keysched[32*4];
+
+/* do the key schedule work once for efficency */
+static void
+fort_skipKeySchedule(FORTSkipjackKeyPtr key,fort_keysched keysched)
+{
+ unsigned char *keyptr = key;
+ unsigned char *first = keyptr +sizeof(FORTSkipjackKey)-1;
+ int i;
+
+ keyptr = first;
+
+ for (i=0; i < (32*4); i++) {
+ keysched[i] = *keyptr--;
+ if (keyptr < key) keyptr = first;
+ }
+ return;
+}
+
+static void
+fort_clearShedule(fort_keysched keysched)
+{
+ PORT_Memset(keysched, 0, sizeof(keysched));
+}
+
+
+static unsigned int
+G(fort_keysched cv, int k, unsigned int wordIn)
+{
+ unsigned char g1, g2, g3, g4, g5, g6;
+
+ g1 = (unsigned char) (wordIn >> 8) & 0xff;
+ g2 = (unsigned char) wordIn & 0xff;
+
+ g3 = F[g2^cv[4*k]]^g1;
+ g4 = F[g3^cv[4*k+1]]^g2;
+ g5 = F[g4^cv[4*k+2]]^g3;
+ g6 = F[g5^cv[4*k+3]]^g4;
+
+ return ((g5<<8)+g6);
+}
+
+static unsigned int
+G1(fort_keysched cv, int k, unsigned int wordIn)
+{
+ unsigned char g1, g2, g3, g4, g5, g6;
+
+ g5 = (unsigned char) (wordIn >> 8) & 0xff;
+ g6 = (unsigned char) wordIn & 0xff;
+
+ g4 = F[g5^cv[4*k+3]]^g6;
+ g3 = F[g4^cv[4*k+2]]^g5;
+ g2 = F[g3^cv[4*k+1]]^g4;
+ g1 = F[g2^cv[4*k]]^g3;
+
+ return ((g1<<8)+g2);
+}
+
+static void
+ruleA(fort_keysched cv,int round,unsigned int *w)
+{
+ unsigned int w4;
+ int i;
+
+ for(i=0; i<8; i++) {
+ int k = round*16+i;
+ int counter = k+1;
+
+ w4 = w[4];
+ w[4] = w[3];
+ w[3] = w[2];
+ w[2] = G(cv,k,w[1]);
+ w[1] = G(cv,k,w[1]) ^ w4 ^ counter;
+ }
+ return;
+}
+
+static void
+ruleB(fort_keysched cv,int round,unsigned int *w)
+{
+ unsigned int w4;
+ int i;
+
+ for(i=0; i<8; i++) {
+ int k = round*16+i+8;
+ int counter = k+1;
+
+ w4 = w[4];
+ w[4] = w[3];
+ w[3] = w[1] ^ w[2] ^ counter;
+ w[2] = G(cv,k,w[1]);
+ w[1] = w4;
+ }
+ return;
+}
+
+static void
+ruleA1(fort_keysched cv,int round,unsigned int *w)
+{
+ unsigned int w4;
+ int i;
+
+ for(i=7; i>=0; i--) {
+ int k = round*16+i;
+ int counter = k+1;
+
+ w4 = w[4];
+ w[4] = w[1] ^ w[2] ^ counter;
+ w[1] = G1(cv,k,w[2]);
+ w[2] = w[3];
+ w[3] = w4;
+ }
+ return;
+}
+
+static void
+ruleB1(fort_keysched cv,int round,unsigned int *w)
+{
+ unsigned int w4;
+ int i;
+
+ for(i=7; i>=0; i--) {
+ int k = round*16+i+8;
+ int counter = k+1;
+
+ w4 = w[4];
+ w[4] = w[1];
+ w[1] = G1(cv,k,w[2]);
+ w[2] = G1(cv,k,w[2]) ^ w[3] ^ counter;
+ w[3] = w4;
+ }
+ return;
+}
+
+
+static void
+fort_doskipD(fort_keysched cv,unsigned char *cipherIn,
+ unsigned char *plainOut) {
+ unsigned int w[5]; /* ignore w[0] so the code matches the doc */
+
+ /* initial byte swap */
+ w[1]=(cipherIn[7]<<8)+cipherIn[6];
+ w[2]=(cipherIn[5]<<8)+cipherIn[4];
+ w[3]=(cipherIn[3]<<8)+cipherIn[2];
+ w[4]=(cipherIn[1]<<8)+cipherIn[0];
+
+ ruleB1(cv,1,w);
+ ruleA1(cv,1,w);
+ ruleB1(cv,0,w);
+ ruleA1(cv,0,w);
+
+ /* final byte swap */
+ plainOut[0] = w[4] & 0xff;
+ plainOut[1] = (w[4] >> 8) & 0xff;
+ plainOut[2] = w[3] & 0xff;
+ plainOut[3] = (w[3] >> 8) & 0xff;
+ plainOut[4] = w[2] & 0xff;
+ plainOut[5] = (w[2] >> 8) & 0xff;
+ plainOut[6] = w[1] & 0xff;
+ plainOut[7] = (w[1] >> 8) & 0xff;
+ return;
+}
+
+static void
+fort_doskipE(fort_keysched cv,unsigned char *cipherIn,
+ unsigned char *plainOut) {
+ unsigned int w[5]; /* ignore w[0] so the code matches the doc */
+
+ /* initial byte swap */
+ w[1]=(cipherIn[7]<<8)+cipherIn[6];
+ w[2]=(cipherIn[5]<<8)+cipherIn[4];
+ w[3]=(cipherIn[3]<<8)+cipherIn[2];
+ w[4]=(cipherIn[1]<<8)+cipherIn[0];
+
+ ruleA(cv,0,w);
+ ruleB(cv,0,w);
+ ruleA(cv,1,w);
+ ruleB(cv,1,w);
+
+ /* final byte swap */
+ plainOut[0] = w[4] & 0xff;
+ plainOut[1] = (w[4] >> 8) & 0xff;
+ plainOut[2] = w[3] & 0xff;
+ plainOut[3] = (w[3] >> 8) & 0xff;
+ plainOut[4] = w[2] & 0xff;
+ plainOut[5] = (w[2] >> 8) & 0xff;
+ plainOut[6] = w[1] & 0xff;
+ plainOut[7] = (w[1] >> 8) & 0xff;
+ return;
+}
+
+/* Checksums are calculated by encrypted a fixed string with the key, then
+ * taking 16 bytes of the result from the block */
+static int
+fort_CalcKeyChecksum(FORTSkipjackKeyPtr key, unsigned char *sum) {
+ unsigned char ckdata[8] = {
+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
+ unsigned char ckres[8];
+ fort_keysched keysched;
+
+
+ fort_skipKeySchedule(key,keysched);
+
+ fort_doskipE(keysched,ckdata,ckres);
+ fort_clearShedule(keysched);
+ PORT_Memcpy(sum,&ckres[1],2);
+ return CI_OK;
+}
+
+/* These function actually implements skipjack CBC Decrypt */
+int
+fort_skipjackDecrypt(FORTSkipjackKeyPtr key, unsigned char *iv,
+ unsigned long size, unsigned char *cipherIn,
+ unsigned char *plainOut) {
+ unsigned char ivdata1[SKIPJACK_BLOCK_SIZE];
+ unsigned char ivdata2[SKIPJACK_BLOCK_SIZE];
+ unsigned char *lastiv, *nextiv, *tmpiv;
+ fort_keysched keysched;
+
+ /* do the key schedule work once for efficency */
+ fort_skipKeySchedule(key,keysched);
+
+ /* As we decrypt, we need to save the last block so that we can
+ * Xor it out of decrypted text to get the real plain text. We actually
+ * have to save it because cipherIn and plainOut may point to the same
+ * buffer. */
+ lastiv =ivdata1;
+ nextiv = ivdata2;
+ PORT_Memcpy(lastiv,iv,SKIPJACK_BLOCK_SIZE);
+ while (size >= SKIPJACK_BLOCK_SIZE) {
+ /* save the IV for the next block */
+ PORT_Memcpy(nextiv,cipherIn,SKIPJACK_BLOCK_SIZE);
+ fort_doskipD(keysched,cipherIn,plainOut);
+ /* xor out the last IV */
+ fort_XorIV(plainOut,plainOut,lastiv);
+
+ /* swap the IV buffers */
+ tmpiv = lastiv;
+ lastiv = nextiv;
+ nextiv =tmpiv;
+
+ /* increment the loop pointers... be sure to get the input, output,
+ * and size (decrement) each fortdoskipD operates on an entire block*/
+ cipherIn += SKIPJACK_BLOCK_SIZE;
+ plainOut += SKIPJACK_BLOCK_SIZE;
+ size -= SKIPJACK_BLOCK_SIZE;
+ }
+ fort_clearShedule(keysched); /* don't leave the key lying around the stack*/
+ if (size != 0) return CI_INV_SIZE;
+ return CI_OK;
+}
+
+/* These function actually implements skipjack CBC Encrypt */
+int
+fort_skipjackEncrypt(FORTSkipjackKeyPtr key, unsigned char *iv,
+ unsigned long size, unsigned char *plainIn,
+ unsigned char *cipherOut) {
+ unsigned char *tmpiv;
+ fort_keysched keysched;
+ unsigned char plain[SKIPJACK_BLOCK_SIZE];
+
+ fort_skipKeySchedule(key,keysched);
+ tmpiv = iv;
+ while (size >= SKIPJACK_BLOCK_SIZE) {
+ /* We Xor into a temp buffer because we don't want to modify plainIn,
+ * doing so may make the caller very unhappy:). */
+ fort_XorIV(plain,plainIn,tmpiv);
+ fort_doskipE(keysched,plain,cipherOut);
+ tmpiv = cipherOut;
+ cipherOut += SKIPJACK_BLOCK_SIZE;
+ plainIn += SKIPJACK_BLOCK_SIZE;
+ size -= SKIPJACK_BLOCK_SIZE;
+ }
+ fort_clearShedule(keysched); /* don't leave the key lying around the stack*/
+ if (size != 0) return CI_INV_SIZE;
+ return CI_OK;
+}
+
+
+
+/*
+ * unwrap is used for key generation and mixing
+ */
+int
+fort_skipjackUnwrap(FORTSkipjackKeyPtr key,unsigned long len,
+ unsigned char *cipherIn, unsigned char *plainOut) {
+ unsigned char low[10];
+ fort_keysched keysched;
+ int i,ret;
+
+ /* unwrap can only unwrap 80 bit symetric keys and 160 private keys
+ * sometimes these values have checksums. When they do, we should verify
+ * those checksums. */
+ switch (len) {
+ case 20: /* private key */
+ case 24: /* private key with checksum */
+ ret = fort_skipjackUnwrap(key,len/2,cipherIn,plainOut);
+ if (ret != CI_OK) return ret;
+ ret = fort_skipjackUnwrap(key,len/2,&cipherIn[len/2],low);
+
+ /* unmunge the low word */
+ for (i=0; i < 10; i++) {
+ low[i] = low[i] ^ plainOut[i];
+ }
+
+ /* the unwrap will fail above because the checkword is on
+ * low, not low ^ high.
+ */
+ if (ret == CI_CHECKWORD_FAIL) {
+ unsigned char checksum[2];
+
+ ret = fort_CalcKeyChecksum(low,checksum);
+ if (ret != CI_OK) return ret;
+ if (PORT_Memcmp(checksum,&cipherIn[len-2],2) != 0) {
+ return CI_CHECKWORD_FAIL;
+ }
+ }
+ if (ret != CI_OK) return ret;
+
+ /* re-order the low word */
+ PORT_Memcpy(&plainOut[10],&low[8],2);
+ PORT_Memcpy(&plainOut[12],&low[0],8);
+ return CI_OK;
+ case 10: /* 80 bit skipjack key */
+ case 12: /* 80 bit skipjack key with checksum */
+ fort_skipKeySchedule(key,keysched);
+ fort_doskipD(keysched,cipherIn,plainOut);
+ plainOut[8] = cipherIn[8] ^ plainOut[0];
+ plainOut[9] = cipherIn[9] ^ plainOut[1];
+ fort_doskipD(keysched,plainOut,plainOut);
+ fort_clearShedule(keysched);
+ /* if we have a checkum, verify it */
+ if (len == 12) {
+ unsigned char checksum[2];
+
+ ret = fort_CalcKeyChecksum(plainOut,checksum);
+ if (ret != CI_OK) return ret;
+ if (PORT_Memcmp(checksum,&cipherIn[10],2) != 0) {
+ return CI_CHECKWORD_FAIL;
+ }
+ }
+ return CI_OK;
+ default:
+ break;
+ }
+ return CI_INV_SIZE;
+}
+
+/*
+ * unwrap is used for key generation and mixing
+ */
+int
+fort_skipjackWrap(FORTSkipjackKeyPtr key,unsigned long len,
+ unsigned char *plainIn, unsigned char *cipherOut) {
+ unsigned char low[10];
+ unsigned char checksum[2];
+ fort_keysched keysched;
+ int i,ret;
+
+
+ /* NOTE: length refers to the target in the case of wrap */
+ /* Wrap can only Wrap 80 bit symetric keys and 160 private keys
+ * sometimes these values have checksums. When they do, we should verify
+ * those checksums. */
+ switch (len) {
+ case 20: /* private key */
+ case 24: /* private key with checksum */
+ /* re-order the low word */
+ PORT_Memcpy(&low[8],&plainIn[10],2);
+ PORT_Memcpy(&low[0],&plainIn[12],8);
+ if (len == 24) {
+ ret = fort_CalcKeyChecksum(low,checksum);
+ if (ret != CI_OK) return ret;
+ }
+ /* munge the low word */
+ for (i=0; i < 10; i++) {
+ low[i] = low[i] ^ plainIn[i];
+ }
+ ret = fort_skipjackWrap(key,len/2,plainIn,cipherOut);
+ ret = fort_skipjackWrap(key,len/2,low,&cipherOut[len/2]);
+ if (len == 24) {
+ PORT_Memcpy(&cipherOut[len - 2], checksum, sizeof(checksum));
+ }
+
+ return CI_OK;
+ case 10: /* 80 bit skipjack key */
+ case 12: /* 80 bit skipjack key with checksum */
+
+ fort_skipKeySchedule(key,keysched);
+ fort_doskipE(keysched,plainIn,cipherOut);
+ cipherOut[8] = plainIn[8] ^ cipherOut[0];
+ cipherOut[9] = plainIn[9] ^ cipherOut[1];
+ fort_doskipE(keysched,cipherOut,cipherOut);
+ fort_clearShedule(keysched);
+ /* if we need a checkum, get it */
+ if (len == 12) {
+ ret = fort_CalcKeyChecksum(plainIn,&cipherOut[10]);
+ if (ret != CI_OK) return ret;
+ }
+ return CI_OK;
+ default:
+ break;
+ }
+ return CI_INV_SIZE;
+}
+
diff --git a/security/nss/lib/fortcrypt/swfort/swflib.c b/security/nss/lib/fortcrypt/swfort/swflib.c
new file mode 100644
index 000000000..cc4647006
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swflib.c
@@ -0,0 +1,1028 @@
+/*
+ * 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.
+ */
+/*
+ * implement the MACI calls as Software Fortezza Calls.
+ * only do the ones Nescape Needs. This provides a single software slot,
+ * with 100 key registers, and 50 backup Ra private registers. Since we only
+ * create one session per slot, this implementation only uses one session.
+ * One future enhancement may be to try to improve on this for better threading
+ * support.
+ */
+
+#include "prtypes.h"
+#include "prio.h"
+
+#include "swforti.h"
+#include "keytlow.h"
+/* #include "dh.h" */
+#include "blapi.h"
+#include "maci.h"
+/* #include "dsa.h" */
+/* #include "hasht.h" */
+#include "secitem.h"
+#include "secrng.h"
+#include "keylow.h"
+#include "secder.h"
+
+#ifdef XP_UNIX
+#include <unistd.h>
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+
+/* currently we only support one software token. In the future we can use the
+ * session to determin which of many possible tokens we are talking about.
+ * all the calls which need tokens take a pointer to the software token as a
+ * target.
+ */
+static FORTSWToken *swtoken = NULL;
+
+#define SOCKET_ID 1
+
+
+/* can't change the pin on SW fortezza for now */
+int
+MACI_ChangePIN(HSESSION session, int PINType, CI_PIN CI_FAR pOldPIN,
+ CI_PIN CI_FAR pNewPin)
+{
+ return CI_INV_STATE;
+}
+
+
+/*
+ * Check pin checks the pin, then logs the user in or out depending on if
+ * the pin succedes. The General implementation would support both SSO and
+ * User mode our's only needs User mode. Pins are checked by whether or not
+ * they can produce our valid Ks for this 'card'.
+ */
+int
+MACI_CheckPIN(HSESSION session, int PINType, CI_PIN CI_FAR pin)
+{
+ FORTSkipjackKeyPtr Ks;
+ FORTSWFile *config_file = NULL;
+ FORTSkipjackKey seed;
+ unsigned char pinArea[13];
+ unsigned char *padPin = NULL;
+
+ /* This SW module can only log in as USER */
+ if (PINType != CI_USER_PIN) return CI_INV_TYPE;
+
+ if (swtoken == NULL) return CI_NO_CARD;
+ /* we can't check a pin if we haven't been initialized yet */
+ if (swtoken->config_file == NULL) return CI_NO_CARD;
+ config_file = swtoken->config_file;
+
+ /* Make sure the pin value meets minimum lengths */
+ if (PORT_Strlen((char *)pin) < 12) {
+ PORT_Memset(pinArea, ' ', sizeof(pinArea));
+ PORT_Memcpy(pinArea,pin,PORT_Strlen((char *)pin));
+ pinArea[12] = 0;
+ padPin = pinArea;
+ }
+
+ /* get the Ks by unwrapping it from the memphrase with the pbe generated
+ * from the pin */
+ Ks = fort_CalculateKMemPhrase(config_file,
+ &config_file->fortezzaPhrase, (char *)pin, NULL);
+
+ if (Ks == 0) {
+ Ks = fort_CalculateKMemPhrase(config_file,
+ &config_file->fortezzaPhrase, (char *)padPin, NULL);
+ if (Ks == 0) {
+ PORT_Memset(pinArea, 0, sizeof(pinArea));
+ fort_Logout(swtoken);
+ return CI_FAIL;
+ }
+ }
+
+ /* use Ks and hash to verify that pin is correct */
+ if (! fort_CheckMemPhrase(config_file, &config_file->fortezzaPhrase,
+ (char *)pin, Ks) ) {
+ if ((padPin == NULL) ||
+ ! fort_CheckMemPhrase(config_file, &config_file->fortezzaPhrase,
+ (char *)padPin, Ks) ) {
+ PORT_Memset(pinArea, 0, sizeof(pinArea));
+ fort_Logout(swtoken);
+ return CI_FAIL;
+ }
+ }
+
+ PORT_Memset(pinArea, 0, sizeof(pinArea));
+
+
+ /* OK, add the random Seed value into the random number generator */
+ fort_skipjackUnwrap(Ks,config_file->wrappedRandomSeed.len,
+ config_file->wrappedRandomSeed.data,seed);
+ RNG_RandomUpdate(seed,sizeof(seed));
+
+ /* it is, go ahead and log in */
+ swtoken->login = PR_TRUE;
+ /* Ks is always stored in keyReg[0] when we log in */
+ PORT_Memcpy(swtoken->keyReg[0].data, Ks, sizeof (FORTSkipjackKey));
+ swtoken->keyReg[0].present = PR_TRUE;
+ PORT_Memset(Ks, 0, sizeof(FORTSkipjackKey));
+ PORT_Free(Ks);
+
+
+ return CI_OK;
+}
+
+/*
+ * close an open socket. Power_Down flag is set when we want to reset the
+ * cards complete state.
+ */
+int
+MACI_Close(HSESSION session, unsigned int flags, int socket)
+{
+ if (socket != SOCKET_ID) return CI_BAD_CARD;
+ if (swtoken == NULL) return CI_BAD_CARD;
+
+ if (flags == CI_POWER_DOWN_FLAG) {
+ fort_Logout(swtoken);
+ }
+ return CI_OK;
+}
+
+/*
+ * Decrypt keeps track of it's own IV.
+ */
+int
+MACI_Decrypt(HSESSION session, unsigned int size, CI_DATA cipherIn,
+ CI_DATA plainOut)
+{
+ int ret;
+ unsigned char IV[SKIPJACK_BLOCK_SIZE];
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret;
+
+ /*fort_AddNoise();*/
+
+ /* save the IV, before we potentially trash the new one when we decrypt.
+ * (it's permissible to decrypt into the cipher text buffer by passing the
+ * same buffers for both cipherIn and plainOut.
+ */
+ PORT_Memcpy(IV,swtoken->IV, sizeof(IV));
+ fort_UpdateIV(cipherIn,size,swtoken->IV);
+ return fort_skipjackDecrypt(swtoken->keyReg[swtoken->key].data,
+ IV,size,cipherIn,plainOut);
+}
+
+/*
+ * Clear a key from one of the key registers (indicated by index).
+ * return an error if no key exists.
+ */
+int
+MACI_DeleteKey(HSESSION session, int index)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+
+ /* can't delete Ks */
+ if (index == 0) return CI_INV_KEY_INDEX;
+
+ if ((ret = fort_KeyOK(swtoken,index,PR_TRUE)) != CI_OK) return ret;
+ fort_ClearKey(&swtoken->keyReg[index]);
+ return CI_OK;
+}
+
+
+/*
+ * encrypt some blocks of data and update the IV.
+ */
+int
+MACI_Encrypt(HSESSION session, unsigned int size, CI_DATA plainIn,
+ CI_DATA cipherOut)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret;
+
+ /*fort_AddNoise();*/
+
+ ret = fort_skipjackEncrypt(swtoken->keyReg[swtoken->key].data,
+ swtoken->IV,size,plainIn,cipherOut);
+ fort_UpdateIV(cipherOut,size,swtoken->IV);
+
+ return ret;
+
+}
+
+/*
+ * create a new IV and encode it.
+ */
+
+static char *leafbits="THIS IS NOT LEAF";
+
+int
+MACI_GenerateIV(HSESSION Session, CI_IV CI_FAR pIV)
+{
+ int ret;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,swtoken->key,PR_TRUE)) != CI_OK) return ret;
+
+ ret = fort_GenerateRandom(swtoken->IV,SKIPJACK_BLOCK_SIZE);
+ if (ret != CI_OK) return ret;
+
+ PORT_Memcpy(pIV,leafbits,SKIPJACK_LEAF_SIZE);
+ PORT_Memcpy(&pIV[SKIPJACK_LEAF_SIZE],swtoken->IV,SKIPJACK_BLOCK_SIZE);
+
+ return CI_OK;
+}
+
+
+/*
+ * create a new Key
+ */
+int
+MACI_GenerateMEK(HSESSION session, int index, int reserved)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,index,PR_FALSE)) != CI_OK) return ret;
+
+ ret = fort_GenerateRandom(swtoken->keyReg[index].data,
+ sizeof (swtoken->keyReg[index].data));
+ if (ret == CI_OK) swtoken->keyReg[index].present = PR_TRUE;
+
+ return ret;
+}
+
+/*
+ * build a new Ra/ra pair for a KEA exchange.
+ */
+int
+MACI_GenerateRa(HSESSION session, CI_RA CI_FAR pRa)
+{
+ int ret;
+ int counter;
+ int RaLen,raLen;
+ DSAPrivateKey *privKey = NULL;
+ PQGParams params;
+ SECStatus rv;
+ int crv = CI_EXEC_FAIL;
+ fortSlotEntry *certEntry = NULL;
+ unsigned char *unsignedRa = NULL;
+ unsigned char *unsignedra = NULL;
+ fortKeyInformation *key_info = NULL;
+
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ /* make sure the personality is set */
+ if (swtoken->certIndex == 0) return CI_INV_STATE;
+
+ /* pick next Ra circular buffer */
+ counter = swtoken->nextRa;
+ swtoken->nextRa++;
+ if (swtoken->nextRa >= MAX_RA_SLOTS) swtoken->nextRa = 0;
+
+ /* now get the params for diffie -helman key gen */
+ certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex);
+ if (certEntry == NULL) return CI_INV_CERT_INDEX;
+ if (certEntry->exchangeKeyInformation) {
+ key_info = certEntry->exchangeKeyInformation;
+ } else {
+ key_info = certEntry->signatureKeyInformation;
+ }
+ if (key_info == NULL) return CI_NO_X;
+
+ /* Generate Diffie Helman key Pair -- but we use DSA key gen to do it */
+ rv = SECITEM_CopyItem(NULL,&params.prime,&key_info->p);
+ if (rv != SECSuccess) return CI_EXEC_FAIL;
+ rv = SECITEM_CopyItem(NULL,&params.subPrime,&key_info->q);
+ if (rv != SECSuccess) return CI_EXEC_FAIL;
+ rv = SECITEM_CopyItem(NULL,&params.base,&key_info->g);
+ if (rv != SECSuccess) return CI_EXEC_FAIL;
+
+ /* KEA uses DSA like key generation with short DSA keys that have to
+ * maintain a relationship to q */
+ rv = DSA_NewKey(&params, &privKey);
+ SECITEM_FreeItem(&params.prime,PR_FALSE);
+ SECITEM_FreeItem(&params.subPrime,PR_FALSE);
+ SECITEM_FreeItem(&params.base,PR_FALSE);
+ if (rv != SECSuccess) return CI_EXEC_FAIL;
+
+ /* save private key, public key, and param in Ra Circular buffer */
+ unsignedRa = privKey->publicValue.data;
+ RaLen = privKey->publicValue.len;
+ while ((unsignedRa[0] == 0) && (RaLen > CI_RA_SIZE)) {
+ unsignedRa++;
+ RaLen--;
+ }
+ if (RaLen > CI_RA_SIZE) goto loser;
+
+ unsignedra = privKey->privateValue.data;
+ raLen = privKey->privateValue.len;
+ while ((unsignedra[0] == 0) && (raLen > sizeof(fortRaPrivate))) {
+ unsignedra++;
+ raLen--;
+ }
+
+ if (raLen > sizeof(fortRaPrivate)) goto loser;
+
+ PORT_Memset(swtoken->RaValues[counter].private, 0, sizeof(fortRaPrivate));
+ PORT_Memcpy(
+ &swtoken->RaValues[counter].private[sizeof(fortRaPrivate) - raLen],
+ unsignedra, raLen);
+ PORT_Memset(pRa, 0, CI_RA_SIZE);
+ PORT_Memcpy(&pRa[CI_RA_SIZE-RaLen], unsignedRa, RaLen);
+ PORT_Memcpy(swtoken->RaValues[counter].public, pRa, CI_RA_SIZE);
+ crv = CI_OK;
+
+loser:
+ PORT_FreeArena(privKey->params.arena, PR_TRUE);
+
+ return crv;
+}
+
+
+/*
+ * return some random data.
+ */
+int
+MACI_GenerateRandom(HSESSION session, CI_RANDOM CI_FAR random)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret;
+ return fort_GenerateRandom(random,sizeof (CI_RANDOM));
+}
+
+
+static CI_RA Remail = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
+};
+
+/*
+ * build a new Token exchange key using KEA.
+ */
+int
+MACI_GenerateTEK(HSESSION hSession, int flags, int target,
+ CI_RA CI_FAR Ra, CI_RA CI_FAR Rb, unsigned int YSize, CI_Y CI_FAR pY )
+{
+ SECKEYLowPrivateKey *key = NULL;
+ fortSlotEntry * certEntry;
+ unsigned char * w = NULL;
+ SECItem *q;
+ SECStatus rv;
+ int ret,i;
+ PRBool email = PR_TRUE;
+ SECItem R; /* public */
+ SECItem Y; /* public */
+ SECItem r; /* private */
+ SECItem x; /* private */
+ SECItem wItem; /* derived secret */
+ fortRaPrivatePtr ra;
+ FORTSkipjackKey cover_key;
+
+ unsigned char pad[10] = { 0x72, 0xf1, 0xa8, 0x7e, 0x92,
+ 0x82, 0x41, 0x98, 0xab, 0x0b };
+
+ /* verify that everything is ok with the token, keys and certs */
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ /* make sure the personality is set */
+ if (swtoken->certIndex == 0) return CI_INV_STATE;
+ if ((ret = fort_KeyOK(swtoken,target,PR_FALSE)) != CI_OK) return ret;
+
+ /* get the cert from the entry, then look up the key from that cert */
+ certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex);
+ if (certEntry == NULL) return CI_INV_CERT_INDEX;
+ key = fort_GetPrivKey(swtoken,dhKey,certEntry);
+ if (key == NULL) return CI_NO_X;
+
+ if (certEntry->exchangeKeyInformation) {
+ q = &certEntry->exchangeKeyInformation->q;
+ } else {
+ q = &certEntry->signatureKeyInformation->q;
+ }
+
+ email = (PORT_Memcmp(Rb,Remail,sizeof(Rb)) == 0) ? PR_TRUE: PR_FALSE;
+
+
+ /* load the common elements */
+ Y.data = pY;
+ Y.len = YSize;
+ x.data = key->u.dh.privateValue.data;
+ x.len = key->u.dh.privateValue.len;
+
+ /* now initialize the rest of the values */
+ if (flags == CI_INITIATOR_FLAG) {
+ if (email) {
+ R.data = Y.data;
+ R.len = Y.len;
+ } else {
+ R.data = Rb;
+ R.len = sizeof(CI_RA);
+ }
+ ra = fort_LookupPrivR(swtoken,Ra);
+ if (ra == NULL) {
+ ret = CI_EXEC_FAIL;
+ goto loser;
+ }
+ r.data = ra;
+ r.len = sizeof(fortRaPrivate);
+ } else {
+ R.data = Ra;
+ R.len = sizeof(CI_RA);
+ if (email) {
+ r.data = x.data;
+ r.len = x.len;
+ } else {
+ ra = fort_LookupPrivR(swtoken,Rb);
+ if (ra == NULL) {
+ ret = CI_EXEC_FAIL;
+ goto loser;
+ }
+ r.data = ra;
+ r.len = sizeof(fortRaPrivate);
+ }
+ }
+
+
+ if (!KEA_Verify(&Y,&key->u.dh.prime,q)) {
+ ret = CI_EXEC_FAIL;
+ goto loser;
+ }
+ if (!KEA_Verify(&R,&key->u.dh.prime,q)) {
+ ret = CI_EXEC_FAIL;
+ goto loser;
+ }
+
+ /* calculate the base key */
+ rv = KEA_Derive(&key->u.dh.prime, &Y, &R, &r, &x, &wItem);
+ if (rv != SECSuccess) {
+ ret = CI_EXEC_FAIL;
+ goto loser;
+ }
+
+ w = wItem.data;
+ /* use the skipjack wrapping function to 'mix' the key up */
+ for (i=0; i < sizeof(FORTSkipjackKey); i++)
+ cover_key[i] = pad[i] ^ w[i];
+
+ ret = fort_skipjackWrap(cover_key,sizeof(FORTSkipjackKey),
+ &w[sizeof(FORTSkipjackKey)],swtoken->keyReg[target].data);
+ if (ret != CI_OK) goto loser;
+
+ swtoken->keyReg[target].present = PR_TRUE;
+
+ ret = CI_OK;
+loser:
+ if (w) PORT_Free(w);
+ if (key) SECKEY_LowDestroyPrivateKey(key);
+
+ return ret;
+}
+
+
+/*
+ * return the bytes of a certificate.
+ */
+int
+MACI_GetCertificate(HSESSION hSession, int certIndex,
+ CI_CERTIFICATE CI_FAR cert)
+{
+ int len;
+ int ret;
+ fortSlotEntry *certEntry = NULL;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+
+ certEntry = fort_GetCertEntry(swtoken->config_file,certIndex);
+ if (certEntry == NULL) return CI_INV_CERT_INDEX;
+
+ len = certEntry->certificateData.dataEncryptedWithKs.len;
+ PORT_Memset(cert,0,sizeof(CI_CERTIFICATE));
+ PORT_Memcpy(cert, certEntry->certificateData.dataEncryptedWithKs.data,len);
+
+ /* Ks is always stored in keyReg[0] when we log in */
+ return fort_skipjackDecrypt(swtoken->keyReg[0].data,
+ &certEntry->certificateData.dataIV.data[SKIPJACK_LEAF_SIZE],
+ len,cert,cert);
+}
+
+
+/*
+ * return out sofware configuration bytes. Those field not used by the PKCS #11
+ * module may not be filled in exactly.
+ */
+#define NETSCAPE "Netscape Communications Corp "
+#define PRODUCT "Netscape Software FORTEZZA Lib "
+#define SOFTWARE "Software FORTEZZA Implementation"
+
+int
+MACI_GetConfiguration(HSESSION hSession, CI_CONFIG_PTR config)
+{
+ config->LibraryVersion = 0x0100;
+ config->ManufacturerVersion = 0x0100;
+ PORT_Memcpy(config->ManufacturerName,NETSCAPE,sizeof(NETSCAPE));
+ PORT_Memcpy(config->ProductName,PRODUCT,sizeof(PRODUCT));
+ PORT_Memcpy(config->ProcessorType,SOFTWARE,sizeof(SOFTWARE));
+ config->UserRAMSize = 0;
+ config->LargestBlockSize = 0x10000;
+ config->KeyRegisterCount = KEY_REGISTERS;
+ config->CertificateCount =
+ swtoken ? fort_GetCertCount(swtoken->config_file): 0;
+ config->CryptoCardFlag = 0;
+ config->ICDVersion = 0;
+ config->ManufacturerSWVer = 0x0100;
+ config->DriverVersion = 0x0100;
+ return CI_OK;
+}
+
+/*
+ * return a list of all the personalities (up to the value 'EntryCount')
+ */
+int
+MACI_GetPersonalityList(HSESSION hSession, int EntryCount,
+ CI_PERSON CI_FAR personList[])
+{
+ int count;
+ int i,ret;
+ FORTSWFile *config_file = NULL;
+ unsigned char tmp[32];
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ config_file = swtoken->config_file;
+
+ /* search for the index */
+ count= fort_GetCertCount(config_file);
+
+ /* don't return more than the user asked for */
+ if (count > EntryCount) count = EntryCount;
+ for (i=0; i < count ;i ++) {
+ int len, dataLen;
+ personList[i].CertificateIndex =
+ config_file->slotEntries[i]->certIndex;
+ len = config_file->slotEntries[i]->certificateLabel.
+ dataEncryptedWithKs.len;
+ if (len > sizeof(tmp)) len = sizeof(tmp);
+ PORT_Memset(personList[i].CertLabel, ' ',
+ sizeof(personList[i].CertLabel));
+ PORT_Memcpy(tmp,
+ config_file->slotEntries[i]->
+ certificateLabel.dataEncryptedWithKs.data,
+ len);
+ /* Ks is always stored in keyReg[0] when we log in */
+ ret = fort_skipjackDecrypt(swtoken->keyReg[0].data,
+ &config_file->slotEntries[i]->
+ certificateLabel.dataIV.data[SKIPJACK_LEAF_SIZE],len,
+ tmp,tmp);
+ if (ret != CI_OK) return ret;
+ dataLen = DER_GetInteger(&config_file->slotEntries[i]->
+ certificateLabel.length);
+ if (dataLen > sizeof(tmp)) dataLen = sizeof(tmp);
+ PORT_Memcpy(personList[i].CertLabel, tmp, dataLen);
+ personList[i].CertLabel[32] = 0;
+ personList[i].CertLabel[33] = 0;
+ personList[i].CertLabel[34] = 0;
+ personList[i].CertLabel[35] = 0;
+ }
+ return CI_OK;
+}
+
+
+/*
+ * get a new session ID. This function is only to make the interface happy,
+ * the PKCS #11 module only uses one session per token.
+ */
+int
+MACI_GetSessionID(HSESSION *session)
+{
+ *session = 1;
+ return CI_OK;
+}
+
+/*
+ * return the current card state.
+ */
+int
+MACI_GetState(HSESSION hSession, CI_STATE_PTR state)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret;
+ *state = fort_GetState(swtoken);
+ return CI_OK;
+}
+
+/*
+ * return the status. NOTE that KeyRegisterFlags and CertificateFlags are never
+ * really used by the PKCS #11 module, so they are not implemented.
+ */
+int
+MACI_GetStatus(HSESSION hSession, CI_STATUS_PTR status)
+{
+ int ret;
+ FORTSWFile *config_file = NULL;
+
+ if ((ret = fort_CardExists(swtoken,PR_FALSE)) != CI_OK) return ret;
+ config_file = swtoken->config_file;
+ status->CurrentSocket = 1;
+ status->LockState = swtoken->lock;
+ PORT_Memcpy(status->SerialNumber,
+ config_file->serialID.data, config_file->serialID.len);
+ status->CurrentState = fort_GetState(swtoken);
+ status->DecryptionMode = CI_CBC64_MODE;
+ status->EncryptionMode = CI_CBC64_MODE;
+ status->CurrentPersonality = swtoken->certIndex;
+ status->KeyRegisterCount = KEY_REGISTERS;
+ /* our code doesn't use KeyRegisters, which is good, because there's not
+ * enough of them .... */
+ PORT_Memset(status->KeyRegisterFlags,0,sizeof(status->KeyRegisterFlags));
+ status->CertificateCount = fort_GetCertCount(config_file);
+ PORT_Memset(status->CertificateFlags,0,sizeof(status->CertificateFlags));
+ PORT_Memset(status->Flags,0,sizeof(status->Flags));
+
+ return CI_OK;
+}
+
+/*
+ * add the time call because the PKCS #11 module calls it, but always pretend
+ * the clock is bad, so it never uses the returned time.
+ */
+int
+MACI_GetTime(HSESSION hSession, CI_TIME CI_FAR time)
+{
+ return CI_BAD_CLOCK;
+}
+
+
+/* This function is copied from NSPR so that the PKCS #11 module can be
+ * independent of NSPR */
+PRInt32 local_getFileInfo(const char *fn, PRFileInfo *info);
+
+/*
+ * initialize the SW module, and return the number of slots we support (1).
+ */
+int
+MACI_Initialize(int CI_FAR *count)
+{
+ char *filename = NULL;
+ SECItem file;
+ FORTSignedSWFile *decode_file = NULL;
+ PRFileInfo info;
+ /*PRFileDesc *fd = NULL;*/
+ int fd = -1;
+ PRStatus err;
+ int ret = CI_OK;
+ int fcount;
+
+ file.data = NULL;
+ file.len = 0;
+
+ *count = 1;
+
+ /* allocate swtoken structure */
+ swtoken = PORT_ZNew(FORTSWToken);
+ if (swtoken == NULL) return CI_OUT_OF_MEMORY;
+
+ filename = (char *)fort_LookupFORTEZZAInitFile();
+ if (filename == NULL) {
+ ret = CI_BAD_READ;
+ goto failed;
+ }
+
+ fd = open(filename,O_RDONLY|O_BINARY,0);
+ if (fd < 0) {
+ ret = CI_BAD_READ;
+ goto failed;
+ }
+
+ err = local_getFileInfo(filename,&info);
+ if ((err != 0) || (info.size == 0)) {
+ ret = CI_BAD_READ;
+ goto failed;
+ }
+
+ file.data = PORT_ZAlloc(info.size);
+ if (file.data == NULL) {
+ ret = CI_OUT_OF_MEMORY;
+ goto failed;
+ }
+
+ fcount = read(fd,file.data,info.size);
+ close(fd); fd = -1;
+ if (fcount != (int)info.size) {
+ ret = CI_BAD_READ;
+ goto failed;
+ }
+
+ file.len = fcount;
+
+ decode_file = FORT_GetSWFile(&file);
+ if (decode_file == NULL) {
+ ret = CI_BAD_READ;
+ goto failed;
+ }
+ swtoken->config_file = &decode_file->file;
+
+ RNG_SystemInfoForRNG();
+ RNG_FileForRNG(filename);
+
+
+failed:
+ if (filename) PORT_Free(filename);
+ if (fd != -1) close(fd);
+ if (file.data) PORT_Free(file.data);
+ if (ret != CI_OK) {
+ if (decode_file) FORT_DestroySignedSWFile(decode_file);
+ if (swtoken) PORT_Free(swtoken);
+ swtoken = NULL;
+ }
+
+ return CI_OK;
+}
+
+/*
+ * load an IV from an external source. We technically should check it with the
+ * key we received.
+ */
+int
+MACI_LoadIV(HSESSION session, CI_IV CI_FAR iv)
+{
+ int ret;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ PORT_Memcpy(swtoken->IV,&iv[SKIPJACK_LEAF_SIZE],SKIPJACK_BLOCK_SIZE);
+ return CI_OK;
+}
+
+/* implement token lock (should call PR_Monitor here) */
+int
+MACI_Lock(HSESSION session, int flags)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ swtoken->lock = 1;
+
+ return CI_OK;
+}
+
+/* open a token. For software there isn't much to do that hasn't already been
+ * done by initialize. */
+int
+MACI_Open(HSESSION session, unsigned int flags, int socket)
+{
+ if (socket != SOCKET_ID) return CI_NO_CARD;
+ if (swtoken == NULL) return CI_NO_CARD;
+ return CI_OK;
+}
+
+/*
+ * Reset logs out the token...
+ */
+int
+MACI_Reset(HSESSION session)
+{
+ if (swtoken) fort_Logout(swtoken);
+ return CI_OK;
+}
+
+/*
+ * restore and encrypt/decrypt state. NOTE: there is no error checking in this
+ * or the save function.
+ */
+int
+MACI_Restore(HSESSION session, int type, CI_SAVE_DATA CI_FAR data)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ PORT_Memcpy(swtoken->IV,data, sizeof (swtoken->IV));
+ return CI_OK;
+}
+
+/*
+ * save and encrypt/decrypt state. NOTE: there is no error checking in this
+ * or the restore function.
+ */
+int
+MACI_Save(HSESSION session, int type,CI_SAVE_DATA CI_FAR data)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ PORT_Memcpy(data,swtoken->IV, sizeof (swtoken->IV));
+ return CI_OK;
+}
+
+/*
+ * picks a token to operate against. In our case there can be only one.
+ */
+int
+MACI_Select(HSESSION session, int socket)
+{
+ if (socket == SOCKET_ID) return CKR_OK;
+ return CI_NO_CARD;
+}
+
+/*
+ * set a register as the key to use for encrypt/decrypt operations.
+ */
+int
+MACI_SetKey(HSESSION session, int index)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,index,PR_TRUE)) != CI_OK) return ret;
+
+ swtoken->key = index;
+ return CI_OK;
+}
+
+/*
+ * only CBC64 is supported. Keep setmode for compatibility */
+int
+MACI_SetMode(HSESSION session, int type, int mode)
+{
+ if (mode != CI_CBC64_MODE) return CI_INV_MODE;
+ return CI_OK;
+}
+
+/* set the personality to use for sign/verify */
+int
+MACI_SetPersonality(HSESSION session, int cert)
+{
+ int ret;
+ fortSlotEntry *certEntry = NULL;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+
+ certEntry = fort_GetCertEntry(swtoken->config_file,cert);
+ if ((certEntry == NULL) ||
+ ((certEntry->exchangeKeyInformation == NULL) &&
+ (certEntry->signatureKeyInformation == NULL)) )
+ return CI_INV_CERT_INDEX;
+ swtoken->certIndex = cert;
+ return CI_OK;
+}
+
+
+/* DSA sign some data */
+int
+MACI_Sign(HSESSION session, CI_HASHVALUE CI_FAR hash, CI_SIGNATURE CI_FAR sig)
+{
+ SECKEYLowPrivateKey *key = NULL;
+ fortSlotEntry * certEntry = NULL;
+ int ret = CI_OK;
+ SECStatus rv;
+ SECItem signItem;
+ SECItem hashItem;
+ unsigned char random[DSA_SUBPRIME_LEN];
+
+ /* standard checks */
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ /* make sure the personality is set */
+ if (swtoken->certIndex == 0) return CI_INV_STATE;
+
+ /* get the current personality */
+ certEntry = fort_GetCertEntry(swtoken->config_file,swtoken->certIndex);
+ if (certEntry == NULL) return CI_INV_CERT_INDEX;
+
+ /* extract the private key from the personality */
+ ret = CI_OK;
+ key = fort_GetPrivKey(swtoken,dsaKey,certEntry);
+ if (key == NULL) {
+ ret = CI_NO_X;
+ goto loser;
+ }
+
+ /* create a random value for the signature */
+ ret = fort_GenerateRandom(random, sizeof(random));
+ if (ret != CI_OK) goto loser;
+
+ /* Sign with that private key */
+ signItem.data = sig;
+ signItem.len = DSA_SIGNATURE_LEN;
+
+ hashItem.data = hash;
+ hashItem.len = SHA1_LENGTH;
+
+ rv = DSA_SignDigestWithSeed(&key->u.dsa, &signItem, &hashItem, random);
+ if (rv != SECSuccess) {
+ ret = CI_EXEC_FAIL;
+ }
+
+ /* clean up */
+loser:
+ if (key != NULL) SECKEY_LowDestroyPrivateKey(key);
+
+ return ret;
+}
+
+/*
+ * clean up after ourselves.
+ */
+int
+MACI_Terminate(HSESSION session)
+{
+ if (swtoken == NULL) return CI_OUT_OF_MEMORY;
+
+ /* clear all the keys */
+ fort_Logout(swtoken);
+
+ FORT_DestroySWFile(swtoken->config_file);
+ PORT_Free(swtoken);
+ swtoken = NULL;
+ return CI_OK;
+}
+
+
+
+/* implement token unlock (should call PR_Monitor here) */
+int
+MACI_Unlock(HSESSION session)
+{
+ int ret;
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ swtoken->lock = 0;
+ return CI_OK;
+}
+
+/*
+ * unwrap a key into our software token. NOTE: this function does not
+ * verify that the wrapping key is Ks or a TEK. This is because our higher
+ * level software doesn't try to wrap MEKs with MEKs. If this API was exposed
+ * generically, then we would have to worry about things like this.
+ */
+int
+MACI_UnwrapKey(HSESSION session, int wrapKey, int target,
+ CI_KEY CI_FAR keyData)
+{
+ int ret = CI_OK;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,target,PR_FALSE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret;
+ ret = fort_skipjackUnwrap(swtoken->keyReg[wrapKey].data,
+ sizeof(CI_KEY), keyData, swtoken->keyReg[target].data);
+ if (ret != CI_OK) goto loser;
+
+ swtoken->keyReg[target].present = PR_TRUE;
+
+loser:
+ return ret;
+}
+
+/*
+ * Wrap a key out of our software token. NOTE: this function does not
+ * verify that the wrapping key is Ks or a TEK, or that the source key is
+ * a MEK. This is because our higher level software doesn't try to wrap MEKs
+ * with MEKs, or wrap out TEKS and Ks. If this API was exposed
+ * generically, then we would have to worry about things like this.
+ */
+int
+MACI_WrapKey(HSESSION session, int wrapKey, int source, CI_KEY CI_FAR keyData)
+{
+ int ret;
+
+ if ((ret = fort_CardExists(swtoken,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,source,PR_TRUE)) != CI_OK) return ret;
+ if ((ret = fort_KeyOK(swtoken,wrapKey,PR_TRUE)) != CI_OK) return ret;
+ ret = fort_skipjackWrap(swtoken->keyReg[wrapKey].data,
+ sizeof(CI_KEY), swtoken->keyReg[source].data,keyData);
+
+ return ret;
+}
+
diff --git a/security/nss/lib/fortcrypt/swfort/swfort.h b/security/nss/lib/fortcrypt/swfort/swfort.h
new file mode 100644
index 000000000..d0cefb098
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfort.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+/*
+ * Software implementation of FORTEZZA skipjack primatives
+ */
+#ifndef _SWFORT_H_
+#define _SWFORT_H_
+
+#include "seccomon.h"
+#include "swfortt.h"
+/*#include "genci.h"*/
+
+
+SEC_BEGIN_PROTOS
+
+FORTSignedSWFile *
+FORT_GetSWFile(SECItem *initBits);
+
+SECStatus
+FORT_CheckInitPhrase(FORTSignedSWFile *sw_init_file, char *initMemPhrase);
+
+SECStatus
+FORT_CheckUserPhrase(FORTSignedSWFile *sw_init_file, char *userMemPhrase);
+
+void
+FORT_DestroySWFile(FORTSWFile *file);
+
+void
+FORT_DestroySignedSWFile(FORTSignedSWFile *swfile);
+
+SECItem *
+FORT_GetDERCert(FORTSignedSWFile *swfile, int index);
+
+SECItem *
+FORT_PutSWFile(FORTSignedSWFile *sw_init_file);
+
+
+SEC_END_PROTOS
+
+#endif
diff --git a/security/nss/lib/fortcrypt/swfort/swforti.h b/security/nss/lib/fortcrypt/swfort/swforti.h
new file mode 100644
index 000000000..c2156e2fc
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swforti.h
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+/*
+ * Software implementation of FORTEZZA Skipjack primatives and helper functions.
+ */
+#ifndef _SWFORTI_H_
+#define _SWFORTI_H_
+
+#ifndef RETURN_TYPE
+#define RETURN_TYPE int
+#endif
+
+#include "seccomon.h"
+#include "swfort.h"
+#include "swfortti.h"
+#include "maci.h"
+
+
+SEC_BEGIN_PROTOS
+/*
+ * Check to see if the index is ok, and that key is appropriately present or
+ * absent.
+ */
+int fort_KeyOK(FORTSWToken *token, int index, PRBool isPresent);
+
+/*
+ * clear out a key register
+ */
+void fort_ClearKey(FORTKeySlot *key);
+
+/*
+ * clear out an Ra register
+ */
+void fort_ClearRaSlot(FORTRaRegisters *ra);
+
+/*
+ * provide a helper function to do all the loggin out functions.
+ * NOTE: Logging in only happens in MACI_CheckPIN
+ */
+void fort_Logout(FORTSWToken *token);
+
+/*
+ * update the new IV value based on the current cipherText (should be the last
+ * block of the cipher text).
+ */
+int fort_UpdateIV(unsigned char *cipherText, unsigned int size,unsigned char *IV);
+
+
+/*
+ * verify that we have a card initialized, and if necessary, logged in.
+ */
+int fort_CardExists(FORTSWToken *token,PRBool needLogin);
+
+/*
+ * walk down the cert slot entries, counting them.
+ * return that count.
+ */
+int fort_GetCertCount(FORTSWFile *file);
+
+/*
+ * copy an unsigned SECItem to a signed SecItem. (if the high bit is on,
+ * pad with a leading 0.
+ */
+SECStatus fort_CopyUnsigned(PRArenaPool *arena, SECItem *to, const SECItem *from);
+
+/*
+ * NOTE: these keys do not have the public values, and cannot be used to
+ * extract the public key from the private key. Since we never do this in
+ * this code, and this function is private, we're reasonably safe (as long as
+ * any of your callees do not try to extract the public value as well).
+ * Also -- the token must be logged in before this function is called.
+ */
+SECKEYLowPrivateKey * fort_GetPrivKey(FORTSWToken *token,KeyType keyType,fortSlotEntry *certEntry);
+
+/*
+ * find a particulare certificate entry from the config
+ * file.
+ */
+fortSlotEntry * fort_GetCertEntry(FORTSWFile *file,int index);
+
+/*
+ * use the token to termine it's CI_State.
+ */
+CI_STATE fort_GetState(FORTSWToken *token);
+
+/*
+ * find the private ra value for a given public Ra value.
+ */
+fortRaPrivatePtr fort_LookupPrivR(FORTSWToken *token,CI_RA Ra);
+
+/*
+ * go add more noise to the random number generator
+ */
+void fort_AddNoise(void);
+
+/*
+ * Get a random number
+ */
+int fort_GenerateRandom(unsigned char *buf, int bytes);
+
+
+/*
+ * We're deep in the bottom of MACI and PKCS #11... We need to
+ * find our fortezza key file. This function lets us search manual paths to
+ * find our key file.
+ */
+char *fort_FindFileInPath(char *path, char *fn);
+
+
+char *fort_LookupFORTEZZAInitFile(void);
+
+
+FORTSkipjackKeyPtr fort_CalculateKMemPhrase(FORTSWFile *file,
+ fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey);
+
+
+PRBool fort_CheckMemPhrase(FORTSWFile *file,
+ fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey);
+
+
+/* These function actually implements skipjack CBC64 Decrypt */
+int fort_skipjackDecrypt(FORTSkipjackKeyPtr key, unsigned char *iv,
+ unsigned long size, unsigned char *cipherIn,
+ unsigned char *plainOut);
+
+/* These function actually implements skipjack CBC64 Encrypt */
+int fort_skipjackEncrypt(FORTSkipjackKeyPtr key, unsigned char *iv,
+ unsigned long size, unsigned char *plainIn,
+ unsigned char *cipherOut);
+
+/*
+ * unwrap is used for key generation and mixing
+ */
+int fort_skipjackUnwrap(FORTSkipjackKeyPtr key,unsigned long len,
+ unsigned char *cipherIn, unsigned char *plainOut);
+
+/*
+ * unwrap is used for key generation and mixing
+ */
+int
+fort_skipjackWrap(FORTSkipjackKeyPtr key,unsigned long len,
+ unsigned char *plainIn, unsigned char *cipherOut);
+
+SEC_END_PROTOS
+
+#endif
diff --git a/security/nss/lib/fortcrypt/swfort/swfortt.h b/security/nss/lib/fortcrypt/swfort/swfortt.h
new file mode 100644
index 000000000..a5ee7b2b5
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfortt.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+/*
+ * All the data structures for Software fortezza are internal only.
+ * The external API for Software fortezza is MACI (which is only used by
+ * the PKCS #11 module.
+ */
+
+#ifndef _SWFORTT_H_
+#define _SWFORTT_H_
+
+/* structure typedefs */
+typedef struct FORTKeySlotStr FORTKeySlot;
+typedef struct FORTRaRegistersStr FORTRaRegisters;
+typedef struct FORTSWTokenStr FORTSWToken;
+
+/* Der parsing typedefs */
+typedef struct fortKeyInformationStr fortKeyInformation;
+typedef struct fortProtectedDataStr fortProtectedData;
+typedef struct fortSlotEntryStr fortSlotEntry;
+typedef struct fortProtectedPhraseStr fortProtectedPhrase;
+typedef struct FORTSWFileStr FORTSWFile;
+typedef struct FORTSignedSWFileStr FORTSignedSWFile;
+
+
+#endif
diff --git a/security/nss/lib/fortcrypt/swfort/swfortti.h b/security/nss/lib/fortcrypt/swfort/swfortti.h
new file mode 100644
index 000000000..2e6df4250
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfortti.h
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+/*
+ * All the data structures for Software fortezza are internal only.
+ * The external API for Software fortezza is MACI (which is only used by
+ * the PKCS #11 module.
+ */
+
+#ifndef _SWFORTTI_H_
+#define _SWFORTTI_H_
+
+#include "maci.h"
+#include "seccomon.h"
+#include "mcom_db.h" /* really should be included by certt.h */
+#include "certt.h"
+#include "keyt.h"
+#include "swfortt.h"
+
+/* the following parameters are tunable. The bigger the key registers are,
+ * the less likely the PKCS #11 module will thrash. */
+#define KEY_REGISTERS 100
+#define MAX_RA_SLOTS 20
+
+/* SKIPJACK algorithm constants */
+#define SKIPJACK_KEY_SIZE 10
+#define SKIPJACK_BLOCK_SIZE 8
+#define SKIPJACK_LEAF_SIZE 16
+
+/* private typedefs */
+typedef unsigned char FORTSkipjackKey[SKIPJACK_KEY_SIZE];
+typedef unsigned char *FORTSkipjackKeyPtr;
+typedef unsigned char fortRaPrivate[20];
+typedef unsigned char *fortRaPrivatePtr;
+
+/* save a public/private key pair */
+struct FORTRaRegistersStr {
+ CI_RA public;
+ fortRaPrivate private;
+};
+
+/* FORTEZZA Key Register */
+struct FORTKeySlotStr {
+ FORTSkipjackKey data;
+ PRBool present;
+};
+
+/* structure to hole private key information */
+struct fortKeyInformationStr {
+ SECItem keyFlags;
+ SECItem privateKeyWrappedWithKs;
+ SECItem derPublicKey;
+ SECItem p;
+ SECItem g;
+ SECItem q;
+};
+
+/* struture to hole Ks wrapped data */
+struct fortProtectedDataStr {
+ SECItem length;
+ SECItem dataIV;
+ SECItem dataEncryptedWithKs;
+};
+
+/* This structure represents a fortezza personality */
+struct fortSlotEntryStr {
+ SECItem trusted;
+ SECItem certificateIndex;
+ int certIndex;
+ fortProtectedData certificateLabel;
+ fortProtectedData certificateData;
+ fortKeyInformation *exchangeKeyInformation;
+ fortKeyInformation *signatureKeyInformation;
+};
+
+/* this structure represents a K value wrapped by a protected pin */
+struct fortProtectedPhraseStr {
+ SECItem kValueIV;
+ SECItem wrappedKValue;
+ SECItem memPhraseIV;
+ SECItem hashedEncryptedMemPhrase;
+};
+
+
+/* This structure represents all the relevant data stored in a der encoded
+ * fortezza slot file. */
+struct FORTSWFileStr {
+ PRArenaPool *arena;
+ SECItem version;
+ SECItem derIssuer;
+ SECItem serialID;
+ fortProtectedPhrase initMemPhrase;
+#define fortezzaPhrase initMemPhrase
+ fortProtectedPhrase ssoMemPhrase;
+ fortProtectedPhrase userMemPhrase;
+ fortProtectedPhrase ssoPinPhrase;
+ fortProtectedPhrase userPinPhrase;
+ SECItem wrappedRandomSeed;
+ fortSlotEntry **slotEntries;
+};
+
+/* This data structed represents a signed data structure */
+struct FORTSignedSWFileStr {
+ FORTSWFile file;
+ CERTSignedData signatureWrap;
+ FORTSkipjackKeyPtr Kinit;
+ FORTSkipjackKeyPtr Ks;
+};
+
+
+/* collect all the data that makes up a token */
+struct FORTSWTokenStr {
+ PRBool login; /* has this token been logged in? */
+ int lock; /* the current lock state */
+ int certIndex; /* index of the current personality */
+ int key; /* currently selected key */
+ int nextRa; /* where the next Ra/ra pair will go */
+ FORTSWFile *config_file; /* parsed Fortezza Config file */
+ unsigned char IV[SKIPJACK_BLOCK_SIZE];
+ FORTKeySlot keyReg[KEY_REGISTERS]; /* sw fortezza key slots */
+ FORTRaRegisters RaValues[MAX_RA_SLOTS]; /* Ra/ra values */
+};
+
+#endif
diff --git a/security/nss/lib/fortcrypt/swfort/swfparse.c b/security/nss/lib/fortcrypt/swfort/swfparse.c
new file mode 100644
index 000000000..e7ad6ffb6
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfparse.c
@@ -0,0 +1,538 @@
+/*
+ * 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.
+ */
+/*
+ * The following program decodes the FORTEZZA Init File, and stores the result
+ * into the fortezza directory.
+ */
+#include "secasn1.h"
+#include "swforti.h"
+#include "blapi.h"
+#include "secoid.h"
+#include "secitem.h"
+#include "secder.h"
+
+
+/*
+ * templates for parsing the FORTEZZA Init File. These were taken from DER
+ * definitions on SWF Initialization File Format Version 1.0 pp1-3.
+ */
+
+/* Key info structure... There are up to two of these per slot entry */
+static const SEC_ASN1Template fortKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(fortKeyInformation) },
+ { SEC_ASN1_INTEGER,
+ offsetof(fortKeyInformation,keyFlags) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortKeyInformation,privateKeyWrappedWithKs) },
+ { SEC_ASN1_ANY ,
+ offsetof(fortKeyInformation, derPublicKey) },
+ { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,p) },
+ { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,g) },
+ { SEC_ASN1_OCTET_STRING, offsetof(fortKeyInformation,q) },
+ { 0 }
+};
+
+/* This is data that has been wrapped by Ks */
+static const SEC_ASN1Template fortProtDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(fortProtectedData) },
+ { SEC_ASN1_INTEGER,
+ offsetof(fortProtectedData,length) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedData,dataIV) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedData,dataEncryptedWithKs) },
+ { 0 }
+};
+
+/* DER to describe each Certificate Slot ... there are an arbitrary number */
+static const SEC_ASN1Template fortSlotEntryTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(fortSlotEntry) },
+ { SEC_ASN1_BOOLEAN,
+ offsetof(fortSlotEntry,trusted) },
+ { SEC_ASN1_INTEGER,
+ offsetof(fortSlotEntry,certificateIndex) },
+ { SEC_ASN1_INLINE,
+ offsetof(fortSlotEntry,certificateLabel), fortProtDataTemplate },
+ { SEC_ASN1_INLINE,
+ offsetof(fortSlotEntry,certificateData), fortProtDataTemplate },
+ { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_CONSTRUCTED | 0,
+ offsetof(fortSlotEntry, exchangeKeyInformation),
+ fortKeyInfoTemplate },
+ { SEC_ASN1_POINTER | SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_CONSTRUCTED | 1,
+ offsetof(fortSlotEntry, signatureKeyInformation),
+ fortKeyInfoTemplate },
+ { 0 }
+};
+
+/* This data is used to check MemPhrases, and to generate Ks
+ * each file has two mem phrases, one for SSO, one for User */
+static const SEC_ASN1Template fortProtectedMemPhrase[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(fortProtectedPhrase) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,kValueIV) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,wrappedKValue) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,memPhraseIV) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,hashedEncryptedMemPhrase) },
+ { 0 }
+};
+
+/* This data is used to check the Mem Init Phrases, and to generate Kinit
+ * each file has one mem init phrase, which is used only in transport of
+ * this file */
+static const SEC_ASN1Template fortMemInitPhrase[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(fortProtectedPhrase) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,wrappedKValue) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,memPhraseIV) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(fortProtectedPhrase,hashedEncryptedMemPhrase) },
+ { 0 }
+};
+
+static const SEC_ASN1Template fortSlotEntriesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, fortSlotEntryTemplate }
+};
+
+/* This is the complete file with all it's data, but has not been signed
+ * yet. */
+static const SEC_ASN1Template fortSwFortezzaInitFileToSign[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(FORTSWFile) },
+ { SEC_ASN1_INTEGER,
+ offsetof(FORTSWFile,version) },
+ { SEC_ASN1_ANY,
+ offsetof(FORTSWFile,derIssuer) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(FORTSWFile,serialID) },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSWFile,initMemPhrase), fortMemInitPhrase },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSWFile,ssoMemPhrase), fortProtectedMemPhrase },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSWFile,userMemPhrase), fortProtectedMemPhrase },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSWFile,ssoPinPhrase), fortProtectedMemPhrase },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSWFile,userPinPhrase), fortProtectedMemPhrase },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(FORTSWFile,wrappedRandomSeed) },
+ { SEC_ASN1_SEQUENCE_OF, offsetof(FORTSWFile,slotEntries),
+ fortSlotEntryTemplate },
+ /* optional extentions to ignore here... */
+ { 0 }
+};
+
+/* The complete, signed init file */
+static const SEC_ASN1Template fortSwFortezzaInitFile[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(FORTSignedSWFile) },
+ { SEC_ASN1_SAVE,
+ offsetof(FORTSignedSWFile,signatureWrap.data) },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSignedSWFile,file),
+ fortSwFortezzaInitFileToSign },
+ { SEC_ASN1_INLINE,
+ offsetof(FORTSignedSWFile,signatureWrap.signatureAlgorithm),
+ SECOID_AlgorithmIDTemplate },
+ { SEC_ASN1_BIT_STRING,
+ offsetof(FORTSignedSWFile,signatureWrap.signature) },
+ { 0 }
+};
+
+FORTSkipjackKeyPtr
+fort_CalculateKMemPhrase(FORTSWFile *file,
+ fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey)
+{
+ unsigned char *data = NULL;
+ unsigned char hashout[SHA1_LENGTH];
+ int data_len = prot_phrase->wrappedKValue.len;
+ int ret;
+ unsigned int len;
+ unsigned int version;
+ unsigned char enc_version[2];
+ FORTSkipjackKeyPtr Kout = NULL;
+ FORTSkipjackKey Kfek;
+ SHA1Context *sha;
+
+ data = (unsigned char *) PORT_ZAlloc(data_len);
+ if (data == NULL) goto fail;
+
+ PORT_Memcpy(data,prot_phrase->wrappedKValue.data,data_len);
+
+ /* if it's a real protected mem phrase, it's been wrapped by kinit, which
+ * was passed to us. */
+ if (wrapKey) {
+ fort_skipjackDecrypt(wrapKey,
+ &prot_phrase->kValueIV.data[SKIPJACK_LEAF_SIZE],data_len,
+ data,data);
+ data_len = sizeof(CI_KEY);
+ }
+
+ /* now calculate the PBE key for fortezza */
+ sha = SHA1_NewContext();
+ if (sha == NULL) goto fail;
+ 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);
+ SHA1_DestroyContext(sha, PR_TRUE);
+ PORT_Memcpy(Kfek,hashout,sizeof(FORTSkipjackKey));
+
+ /* now use that key to unwrap */
+ Kout = (FORTSkipjackKeyPtr) PORT_Alloc(sizeof(FORTSkipjackKey));
+ ret = fort_skipjackUnwrap(Kfek,data_len,data,Kout);
+ if (ret != CI_OK) {
+ PORT_Free(Kout);
+ Kout = NULL;
+ }
+
+fail:
+ PORT_Memset(&Kfek, 0, sizeof(FORTSkipjackKey));
+ if (data) PORT_ZFree(data,data_len);
+ return Kout;
+}
+
+
+PRBool
+fort_CheckMemPhrase(FORTSWFile *file,
+ fortProtectedPhrase * prot_phrase, char *phrase, FORTSkipjackKeyPtr wrapKey)
+{
+ unsigned char *data = NULL;
+ unsigned char hashout[SHA1_LENGTH];
+ int data_len = prot_phrase->hashedEncryptedMemPhrase.len;
+ unsigned int len;
+ SHA1Context *sha;
+ PRBool pinOK = PR_FALSE;
+ unsigned char cw[4];
+ int i;
+
+
+ /* first, decrypt the hashed/Encrypted Memphrase */
+ data = (unsigned char *) PORT_ZAlloc(data_len);
+ if (data == NULL) goto failed;
+
+ PORT_Memcpy(data,prot_phrase->hashedEncryptedMemPhrase.data,data_len);
+ fort_skipjackDecrypt(wrapKey,
+ &prot_phrase->memPhraseIV.data[SKIPJACK_LEAF_SIZE],data_len,
+ data,data);
+
+ /* now build the hash for comparisons */
+ sha = SHA1_NewContext();
+ if (sha == NULL) goto failed;
+ SHA1_Begin(sha);
+ SHA1_Update(sha,(unsigned char *)phrase,strlen(phrase));
+ SHA1_End(sha,hashout,&len,SHA1_LENGTH);
+ SHA1_DestroyContext(sha, PR_TRUE);
+
+ /* hashes don't match... must not be the right pass mem */
+ if (PORT_Memcmp(data,hashout,len) != 0) goto failed;
+
+ /* 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];
+ }
+
+ /* checkword doesn't match, must not be the right pass mem */
+ if (PORT_Memcmp(data+len,cw,4) != 0) goto failed;
+
+ /* pased all our test, its OK */
+ pinOK = PR_TRUE;
+
+failed:
+ PORT_Free(data);
+
+ return pinOK;
+}
+
+/*
+ * walk through the list of memphrases. This function allows us to use a
+ * for loop to walk down them.
+ */
+fortProtectedPhrase *
+fort_getNextPhrase( FORTSWFile *file, fortProtectedPhrase *last)
+{
+ if (last == &file->userMemPhrase) {
+ return &file->userPinPhrase;
+ }
+ /* we can add more test here if we want to support SSO mode someday. */
+
+ return NULL;
+}
+
+/*
+ * decode the DER file data into our nice data structures, including turning
+ * cert indexes into integers.
+ */
+FORTSignedSWFile *
+FORT_GetSWFile(SECItem *initBits)
+{
+ FORTSignedSWFile *sw_init_file;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ int i, count;
+
+ /* get the local arena... be sure to free this at the end */
+
+ /* get the local arena... be sure to free this at the end */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) goto fail;
+
+ sw_init_file = (FORTSignedSWFile *)
+ PORT_ArenaZAlloc(arena,sizeof(FORTSignedSWFile));
+ if (sw_init_file == NULL) goto fail;
+
+ /* ANS1 decode the complete init file */
+ rv = SEC_ASN1DecodeItem(arena,sw_init_file,fortSwFortezzaInitFile,initBits);
+ if (rv != SECSuccess) {
+ goto fail;
+ }
+
+ /* count the certs */
+ count = 0;
+ while (sw_init_file->file.slotEntries[count]) count++;
+
+ for (i=0; i < count; i++) {
+ /* update the cert Index Pointers */
+ sw_init_file->file.slotEntries[i]->certIndex =
+ DER_GetInteger(&sw_init_file->
+ file.slotEntries[i]->certificateIndex );
+ }
+
+ /* now start checking the mem phrases and pins, as well as calculating the
+ * file's 'K' values. First we start with K(init). */
+ sw_init_file->file.arena = arena;
+
+ return sw_init_file;
+ /* OK now that we've read in the init file, and now have Kinit, Ks, and the
+ * appropriate Pin Phrase, we need to build our database file. */
+
+fail:
+ if (arena) PORT_FreeArena(arena,PR_TRUE);
+ return NULL;
+}
+
+/*
+ * Check the init memphrases and the user mem phrases. Remove all the init
+ * memphrase wrappings. Save the Kinit and Ks values for use.
+ */
+SECStatus
+FORT_CheckInitPhrase(FORTSignedSWFile *sw_init_file, char *initMemPhrase)
+{
+ SECStatus rv = SECFailure;
+
+ sw_init_file->Kinit = fort_CalculateKMemPhrase(&sw_init_file->file,
+ &sw_init_file->file.initMemPhrase, initMemPhrase, NULL);
+ if (sw_init_file->Kinit == NULL) goto fail;
+
+ /* now check the init Mem phrase */
+ if (!fort_CheckMemPhrase(&sw_init_file->file,
+ &sw_init_file->file.initMemPhrase,
+ initMemPhrase, sw_init_file->Kinit)) {
+ goto fail;
+ }
+ rv = SECSuccess;
+
+fail:
+ return rv;
+}
+
+ /* now check user user mem phrase and calculate Ks */
+SECStatus
+FORT_CheckUserPhrase(FORTSignedSWFile *sw_init_file, char *userMemPhrase)
+{
+ SECStatus rv = SECFailure;
+ char tmp_data[13];
+ char *padMemPhrase = NULL;
+ fortProtectedPhrase *phrase_store;
+
+ if (strlen(userMemPhrase) < 12) {
+ PORT_Memset(tmp_data, ' ', sizeof(tmp_data));
+ PORT_Memcpy(tmp_data,userMemPhrase,strlen(userMemPhrase));
+ tmp_data[12] = 0;
+ padMemPhrase = tmp_data;
+ }
+
+ for (phrase_store = &sw_init_file->file.userMemPhrase; phrase_store;
+ phrase_store = fort_getNextPhrase(&sw_init_file->file,phrase_store)) {
+ sw_init_file->Ks = fort_CalculateKMemPhrase(&sw_init_file->file,
+ phrase_store, userMemPhrase, sw_init_file->Kinit);
+
+ if ((sw_init_file->Ks == NULL) && (padMemPhrase != NULL)) {
+ sw_init_file->Ks = fort_CalculateKMemPhrase(&sw_init_file->file,
+ phrase_store, padMemPhrase, sw_init_file->Kinit);
+ userMemPhrase = padMemPhrase;
+ }
+ if (sw_init_file->Ks == NULL) {
+ continue;
+ }
+
+ /* now check the User Mem phrase */
+ if (fort_CheckMemPhrase(&sw_init_file->file, phrase_store,
+ userMemPhrase, sw_init_file->Ks)) {
+ break;
+ }
+ PORT_Free(sw_init_file->Ks);
+ sw_init_file->Ks = NULL;
+ }
+
+
+ if (phrase_store == NULL) goto fail;
+
+ /* strip the Kinit wrapping */
+ fort_skipjackDecrypt(sw_init_file->Kinit,
+ &phrase_store->kValueIV.data[SKIPJACK_LEAF_SIZE],
+ phrase_store->wrappedKValue.len, phrase_store->wrappedKValue.data,
+ phrase_store->wrappedKValue.data);
+ phrase_store->wrappedKValue.len = 12;
+
+ PORT_Memset(phrase_store->kValueIV.data,0,phrase_store->kValueIV.len);
+
+ sw_init_file->file.initMemPhrase = *phrase_store;
+ sw_init_file->file.ssoMemPhrase = *phrase_store;
+ sw_init_file->file.ssoPinPhrase = *phrase_store;
+ sw_init_file->file.userMemPhrase = *phrase_store;
+ sw_init_file->file.userPinPhrase = *phrase_store;
+
+
+ rv = SECSuccess;
+
+fail:
+ /* don't keep the pin around */
+ PORT_Memset(tmp_data, 0, sizeof(tmp_data));
+ return rv;
+}
+
+void
+FORT_DestroySWFile(FORTSWFile *file)
+{
+ PORT_FreeArena(file->arena,PR_FALSE);
+}
+
+void
+FORT_DestroySignedSWFile(FORTSignedSWFile *swfile)
+{
+ FORT_DestroySWFile(&swfile->file);
+}
+
+
+SECItem *
+FORT_GetDERCert(FORTSignedSWFile *swfile,int index)
+{
+ SECItem *newItem = NULL;
+ unsigned char *cert = NULL;
+ int len,ret;
+ fortSlotEntry *certEntry = NULL;
+
+
+ newItem = PORT_ZNew(SECItem);
+ if (newItem == NULL) return NULL;
+
+ certEntry = fort_GetCertEntry(&swfile->file,index);
+ if (certEntry == NULL) {
+ PORT_Free(newItem);
+ return NULL;
+ }
+
+ newItem->len = len = certEntry->certificateData.dataEncryptedWithKs.len;
+ newItem->data = cert = PORT_ZAlloc(len);
+ if (cert == NULL) {
+ PORT_Free(newItem);
+ return NULL;
+ }
+ newItem->len = DER_GetUInteger(&certEntry->certificateData.length);
+
+
+ PORT_Memcpy(cert, certEntry->certificateData.dataEncryptedWithKs.data,len);
+
+ /* Ks is always stored in keyReg[0] when we log in */
+ ret = fort_skipjackDecrypt(swfile->Ks,
+ &certEntry->certificateData.dataIV.data[SKIPJACK_LEAF_SIZE],
+ len,cert,cert);
+ if (ret != CI_OK) {
+ SECITEM_FreeItem(newItem,PR_TRUE);
+ return NULL;
+ }
+ return newItem;
+}
+
+/*
+ * decode the DER file data into our nice data structures, including turning
+ * cert indexes into integers.
+ */
+SECItem *
+FORT_PutSWFile(FORTSignedSWFile *sw_init_file)
+{
+ SECItem *outBits, *tmpBits;
+ PRArenaPool *arena = NULL;
+
+
+ /* get the local arena... be sure to free this at the end */
+ /* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); */
+ /* if (arena == NULL) goto fail; */
+
+ /*outBits = (SECItem *) PORT_ArenaZAlloc(arena,sizeof(SECItem)); */
+ outBits = PORT_ZNew(SECItem);
+ if (outBits == NULL) goto fail;
+
+ /* ANS1 encode the complete init file */
+ tmpBits = SEC_ASN1EncodeItem(NULL,outBits,sw_init_file,fortSwFortezzaInitFile);
+ if (tmpBits == NULL) {
+ goto fail;
+ }
+
+ return outBits;
+
+fail:
+ if (outBits) SECITEM_FreeItem(outBits,PR_TRUE);
+ return NULL;
+}
diff --git a/security/nss/lib/fortcrypt/swfort/swfutl.c b/security/nss/lib/fortcrypt/swfort/swfutl.c
new file mode 100644
index 000000000..740444c3a
--- /dev/null
+++ b/security/nss/lib/fortcrypt/swfort/swfutl.c
@@ -0,0 +1,728 @@
+/*
+ * 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.
+ */
+/*
+ * This File includes utility functions used by cilib. and swfparse.c
+ */
+
+#include "prtypes.h"
+#include "prsystem.h"
+#include "prio.h"
+
+#include "swforti.h"
+#include "keyt.h"
+/* #include "dh.h" */
+#include "maci.h"
+#include "secport.h"
+#include "secrng.h"
+
+#ifdef XP_WIN
+#include <windows.h>
+#include <winsock.h>
+#include <direct.h>
+#endif
+
+/* no platform seem to agree on where this function is defined */
+static char *local_index(char *source, char target) {
+ while ((*source != target) && (*source != 0)) {
+ *source++;
+ }
+ return (*source != 0) ? source : NULL;
+}
+
+/*
+ * Check to see if the index is ok, and that key is appropriately present or
+ * absent.
+ */
+int
+fort_KeyOK(FORTSWToken *token, int index, PRBool isPresent)
+{
+ if (index < 0) return CI_INV_KEY_INDEX;
+ if (index >= KEY_REGISTERS) return CI_INV_KEY_INDEX;
+
+ return (token->keyReg[index].present == isPresent) ? CI_OK :
+ (isPresent ? CI_NO_KEY : CI_REG_IN_USE);
+}
+
+/*
+ * clear out a key register
+ */
+void
+fort_ClearKey(FORTKeySlot *key)
+{
+ key->present = PR_FALSE;
+ PORT_Memset(key->data, 0, sizeof (key->data));
+ return;
+}
+
+/*
+ * clear out an Ra register
+ */
+void
+fort_ClearRaSlot(FORTRaRegisters *ra)
+{
+ PORT_Memset(ra->public, 0, sizeof(ra->public));
+ PORT_Memset(ra->private, 0, sizeof(ra->private));
+ return;
+}
+
+/*
+ * provide a helper function to do all the loggin out functions.
+ * NOTE: Logining in only happens in MACI_CheckPIN
+ */
+void
+fort_Logout(FORTSWToken *token)
+{
+ int i;
+
+ /* ditch all the stored keys */
+ for (i=0; i < KEY_REGISTERS; i++) {
+ fort_ClearKey(&token->keyReg[i]);
+ }
+ for (i=0; i < MAX_RA_SLOTS; i++) {
+ fort_ClearRaSlot(&token->RaValues[i]);
+ }
+
+ /* mark as logged out */
+ token->login = PR_FALSE;
+ token->certIndex = 0;
+ token->key = 0;
+ return;
+}
+
+/*
+ * update the new IV value based on the current cipherText (should be the last
+ * block of the cipher text).
+ */
+int
+fort_UpdateIV(unsigned char *cipherText, unsigned int size,unsigned char *IV)
+{
+ if (size == 0) return CI_INV_SIZE;
+ if ((size & (SKIPJACK_BLOCK_SIZE-1)) != 0) return CI_INV_SIZE;
+ size -= SKIPJACK_BLOCK_SIZE;
+ PORT_Memcpy(IV,&cipherText[size],SKIPJACK_BLOCK_SIZE);
+ return CI_OK;
+}
+
+
+/*
+ * verify that we have a card initialized, and if necessary, logged in.
+ */
+int
+fort_CardExists(FORTSWToken *token,PRBool needLogin)
+{
+ if (token == NULL ) return CI_LIB_NOT_INIT;
+ if (token->config_file == NULL) return CI_NO_CARD;
+ if (needLogin && !token->login) return CI_INV_STATE;
+ return CI_OK;
+}
+
+/*
+ * walk down the cert slot entries, counting them.
+ * return that count.
+ */
+int
+fort_GetCertCount(FORTSWFile *file)
+{
+ int i;
+
+ if (file->slotEntries == NULL) return 0;
+
+ for (i=0; file->slotEntries[i]; i++)
+ /* no body */ ;
+
+ return i;
+}
+
+/*
+ * copy an unsigned SECItem to a signed SecItem. (if the high bit is on,
+ * pad with a leading 0.
+ */
+SECStatus
+fort_CopyUnsigned(PRArenaPool *arena, SECItem *to, const SECItem *from)
+{
+ int offset = 0;
+
+ if (from->data && from->len) {
+ if (from->data[0] & 0x80) offset = 1;
+ if ( arena ) {
+ to->data = (unsigned char*) PORT_ArenaZAlloc(arena,
+ from->len+offset);
+ } else {
+ to->data = (unsigned char*) PORT_ZAlloc(from->len+offset);
+ }
+
+ if (!to->data) {
+ return SECFailure;
+ }
+ PORT_Memcpy(to->data+offset, from->data, from->len);
+ to->len = from->len+offset;
+ } else {
+ to->data = 0;
+ to->len = 0;
+ }
+ return SECSuccess;
+}
+
+/*
+ * NOTE: these keys do not have the public values, and cannot be used to
+ * extract the public key from the private key. Since we never do this in
+ * this code, and this function is static, we're reasonably safe (as long as
+ * any of your callees do not try to extract the public value as well).
+ * Also -- the token must be logged in before this function is called.
+ */
+SECKEYLowPrivateKey *
+fort_GetPrivKey(FORTSWToken *token,KeyType keyType,fortSlotEntry *certEntry)
+{
+ SECKEYLowPrivateKey *returnKey = NULL;
+ SECStatus rv = SECFailure;
+ PRArenaPool *poolp;
+ fortKeyInformation *keyInfo;
+ unsigned char *keyData;
+ int len, ret;
+
+
+ /* select the right keyinfo */
+ switch (keyType) {
+ case dsaKey:
+ keyInfo = certEntry->signatureKeyInformation;
+ if (keyInfo == NULL) keyInfo = certEntry->exchangeKeyInformation;
+ break;
+ case dhKey:
+ keyInfo = certEntry->exchangeKeyInformation;
+ if (keyInfo == NULL) keyInfo = certEntry->signatureKeyInformation;
+ break;
+ }
+
+ /* if we don't have any key information, blow out of here */
+ if (keyInfo == NULL) return NULL;
+
+ poolp = PORT_NewArena(2048);
+ if(!poolp) {
+ return NULL;
+ }
+
+ returnKey = (SECKEYLowPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(SECKEYLowPrivateKey));
+ if(!returnKey) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ returnKey->keyType = keyType;
+ returnKey->arena = poolp;
+
+ /*
+ * decrypt the private key
+ */
+ len = keyInfo->privateKeyWrappedWithKs.len;
+ keyData = PORT_ArenaZAlloc(poolp,len);
+ if (keyData == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ /* keys must be 160 bits (20 bytes) if that's not the case the Unwrap will
+ * fail.. */
+ ret = fort_skipjackUnwrap(token->keyReg[0].data, len,
+ keyInfo->privateKeyWrappedWithKs.data, keyData);
+ if (ret != CI_OK) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ switch(keyType) {
+ case dsaKey:
+ returnKey->u.dsa.privateValue.data = keyData;
+ returnKey->u.dsa.privateValue.len = 20;
+ returnKey->u.dsa.params.arena = poolp;
+ rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.prime),
+ &(keyInfo->p));
+ if(rv != SECSuccess) break;
+ rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.subPrime),
+ &(keyInfo->q));
+ if(rv != SECSuccess) break;
+ rv = fort_CopyUnsigned(poolp, &(returnKey->u.dsa.params.base),
+ &(keyInfo->g));
+ if(rv != SECSuccess) break;
+ break;
+ case dhKey:
+ returnKey->u.dh.arena = poolp;
+ returnKey->u.dh.privateValue.data = keyData;
+ returnKey->u.dh.privateValue.len = 20;
+ rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.prime),
+ &(keyInfo->p));
+ if(rv != SECSuccess) break;
+ rv = fort_CopyUnsigned(poolp, &(returnKey->u.dh.base),
+ &(keyInfo->g));
+ if(rv != SECSuccess) break;
+ rv = SECSuccess;
+ break;
+ default:
+ rv = SECFailure;
+ }
+
+loser:
+
+ if(rv != SECSuccess) {
+ PORT_FreeArena(poolp, PR_TRUE);
+ returnKey = NULL;
+ }
+
+ return returnKey;
+}
+
+
+
+/*
+ * find a particulare certificate entry from the config
+ * file.
+ */
+fortSlotEntry *
+fort_GetCertEntry(FORTSWFile *file,int index)
+{
+ /* search for the index */
+ int i,count= fort_GetCertCount(file);
+
+ /* make sure the given index exists & has key material */
+ for (i=0; i < count ;i ++) {
+ if (file->slotEntries[i]->certIndex == index) {
+ return file->slotEntries[i];
+ }
+ }
+ return NULL;
+}
+
+/*
+ * use the token to determine it's CI_State.
+ */
+CI_STATE
+fort_GetState(FORTSWToken *token)
+{
+ /* no file? then the token has not been initialized */
+ if (!token->config_file) {
+ return CI_UNINITIALIZED;
+ }
+ /* we're initialized, are we logged in (CI_USER_INITIALIZED is not logged
+ * in) */
+ if (!token->login) {
+ return CI_USER_INITIALIZED;
+ }
+ /* We're logged in, do we have a personality set */
+ if (token->certIndex) {
+ return CI_READY;
+ }
+ /* We're logged in, with no personality set */
+ return CI_STANDBY;
+}
+
+/*
+ * find the private ra value for a given public Ra value.
+ */
+fortRaPrivatePtr
+fort_LookupPrivR(FORTSWToken *token,CI_RA Ra)
+{
+ int i;
+
+ /* probably a more efficient way of doing this would be to search first
+ * several entries before nextRa (or search backwards from next Ra)
+ */
+ for (i=0; i < MAX_RA_SLOTS; i++) {
+ if (PORT_Memcmp(token->RaValues[i].public,Ra,CI_RA_SIZE) == 0) {
+ return token->RaValues[i].private;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * go add more noise to the random number generator
+ */
+void
+fort_AddNoise(void)
+{
+ unsigned char seed[20];
+
+ /* note: GetNoise doesn't always get 20 bytes, but adding more
+ * random data from the stack doesn't subtract entropy from the
+ * Random number generator, so just send it all.
+ */
+ RNG_GetNoise(seed,sizeof(seed));
+ RNG_RandomUpdate(seed,sizeof(seed));
+}
+
+/*
+ * Get a random number
+ */
+int
+fort_GenerateRandom(unsigned char *buf, int bytes)
+{
+ SECStatus rv;
+
+ fort_AddNoise();
+ rv = RNG_GenerateGlobalRandomBytes(buf,bytes);
+ if (rv != SECSuccess) return CI_EXEC_FAIL;
+ return CI_OK;
+}
+
+/*
+ * NOTE: that MAC is missing below.
+ */
+#ifdef XP_UNIX
+#define NS_PATH_SEP ':'
+#define NS_DIR_SEP '/'
+#define NS_DEFAULT_PATH ".:/bin/netscape:/etc/netscape/:/etc"
+PRInt32
+local_getFileInfo(const char *fn, PRFileInfo *info)
+{
+ PRInt32 rv;
+ struct stat sb;
+
+ rv = stat(fn, &sb);
+ if (rv < 0)
+ return -1;
+ else if (NULL != info)
+ {
+ if (S_IFREG & sb.st_mode)
+ info->type = PR_FILE_FILE;
+ else if (S_IFDIR & sb.st_mode)
+ info->type = PR_FILE_DIRECTORY;
+ else
+ info->type = PR_FILE_OTHER;
+
+#if defined(OSF1)
+ if (0x7fffffffLL < sb.st_size)
+ {
+ return -1;
+ }
+#endif /* defined(OSF1) */
+ info->size = sb.st_size;
+
+ }
+ return rv;
+}
+#endif
+#ifdef XP_WIN
+#define NS_PATH_SEP ';'
+#define NS_DIR_SEP '\\'
+#define NS_DEFAULT_PATH ".;c:\\program files\\netscape\\communicator\\program\\pkcs11\\netscape;c:\\netscape\\communicator\\program\\pkcs11\\netscape;c:\\windows\\system"
+
+
+/*
+ * Since we're a pkcs #11 module, we may get
+ * loaded into lots of different binaries, each with different or no versions
+ * of NSPR running... so we copy the one function we need.
+ */
+
+#define _PR_IS_SLASH(ch) ((ch) == '/' || (ch) == '\\')
+
+/*
+ * IsRootDirectory --
+ *
+ * Return PR_TRUE if the pathname 'fn' is a valid root directory,
+ * else return PR_FALSE. The char buffer pointed to by 'fn' must
+ * be writable. During the execution of this function, the contents
+ * of the buffer pointed to by 'fn' may be modified, but on return
+ * the original contents will be restored. 'buflen' is the size of
+ * the buffer pointed to by 'fn'.
+ *
+ * Root directories come in three formats:
+ * 1. / or \, meaning the root directory of the current drive.
+ * 2. C:/ or C:\, where C is a drive letter.
+ * 3. \\<server name>\<share point name>\ or
+ * \\<server name>\<share point name>, meaning the root directory
+ * of a UNC (Universal Naming Convention) name.
+ */
+
+static PRBool
+IsRootDirectory(char *fn, size_t buflen)
+{
+ char *p;
+ PRBool slashAdded = PR_FALSE;
+ PRBool rv = PR_FALSE;
+
+ if (_PR_IS_SLASH(fn[0]) && fn[1] == '\0') {
+ return PR_TRUE;
+ }
+
+ if (isalpha(fn[0]) && fn[1] == ':' && _PR_IS_SLASH(fn[2])
+ && fn[3] == '\0') {
+ rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+ return rv;
+ }
+
+ /* The UNC root directory */
+
+ if (_PR_IS_SLASH(fn[0]) && _PR_IS_SLASH(fn[1])) {
+ /* The 'server' part should have at least one character. */
+ p = &fn[2];
+ if (*p == '\0' || _PR_IS_SLASH(*p)) {
+ return PR_FALSE;
+ }
+
+ /* look for the next slash */
+ do {
+ p++;
+ } while (*p != '\0' && !_PR_IS_SLASH(*p));
+ if (*p == '\0') {
+ return PR_FALSE;
+ }
+
+ /* The 'share' part should have at least one character. */
+ p++;
+ if (*p == '\0' || _PR_IS_SLASH(*p)) {
+ return PR_FALSE;
+ }
+
+ /* look for the final slash */
+ do {
+ p++;
+ } while (*p != '\0' && !_PR_IS_SLASH(*p));
+ if (_PR_IS_SLASH(*p) && p[1] != '\0') {
+ return PR_FALSE;
+ }
+ if (*p == '\0') {
+ /*
+ * GetDriveType() doesn't work correctly if the
+ * path is of the form \\server\share, so we add
+ * a final slash temporarily.
+ */
+ if ((p + 1) < (fn + buflen)) {
+ *p++ = '\\';
+ *p = '\0';
+ slashAdded = PR_TRUE;
+ } else {
+ return PR_FALSE; /* name too long */
+ }
+ }
+ rv = GetDriveType(fn) > 1 ? PR_TRUE : PR_FALSE;
+ /* restore the 'fn' buffer */
+ if (slashAdded) {
+ *--p = '\0';
+ }
+ }
+ return rv;
+}
+
+PRInt32
+local_getFileInfo(const char *fn, PRFileInfo *info)
+{
+ HANDLE hFindFile;
+ WIN32_FIND_DATA findFileData;
+ char pathbuf[MAX_PATH + 1];
+
+ if (NULL == fn || '\0' == *fn) {
+ return -1;
+ }
+
+ /*
+ * FindFirstFile() expands wildcard characters. So
+ * we make sure the pathname contains no wildcard.
+ */
+ if (NULL != strpbrk(fn, "?*")) {
+ return -1;
+ }
+
+ hFindFile = FindFirstFile(fn, &findFileData);
+ if (INVALID_HANDLE_VALUE == hFindFile) {
+ DWORD len;
+ char *filePart;
+
+ /*
+ * FindFirstFile() does not work correctly on root directories.
+ * It also doesn't work correctly on a pathname that ends in a
+ * slash. So we first check to see if the pathname specifies a
+ * root directory. If not, and if the pathname ends in a slash,
+ * we remove the final slash and try again.
+ */
+
+ /*
+ * If the pathname does not contain ., \, and /, it cannot be
+ * a root directory or a pathname that ends in a slash.
+ */
+ if (NULL == strpbrk(fn, ".\\/")) {
+ return -1;
+ }
+ len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
+ &filePart);
+ if (len > sizeof(pathbuf)) {
+ return -1;
+ }
+ if (IsRootDirectory(pathbuf, sizeof(pathbuf))) {
+ info->type = PR_FILE_DIRECTORY;
+ info->size = 0;
+ /*
+ * These timestamps don't make sense for root directories.
+ */
+ info->modifyTime = 0;
+ info->creationTime = 0;
+ return 0;
+ }
+ if (!((pathbuf[len - 1] == '/') || (pathbuf[len-1] == '\\'))) {
+ return -1;
+ } else {
+ pathbuf[len - 1] = '\0';
+ hFindFile = FindFirstFile(pathbuf, &findFileData);
+ if (INVALID_HANDLE_VALUE == hFindFile) {
+ return -1;
+ }
+ }
+ }
+
+ FindClose(hFindFile);
+
+ if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ info->type = PR_FILE_DIRECTORY;
+ } else {
+ info->type = PR_FILE_FILE;
+ }
+
+ info->size = findFileData.nFileSizeLow;
+
+ return 0;
+}
+
+#endif
+#ifdef XP_MAC
+#error Need to write fort_FindFileInPath for Mac
+#define NS_PATH_SEP ','
+#define NS_DIR_SEP ':'
+#define NS_DEFAULT_PATH ",System Folder,System Folder:Netscape f:pkcs11:netscape"
+#endif
+
+#define NETSCAPE_INIT_FILE "nsswft.swf"
+
+/*
+ * OK, We're deep in the bottom of MACI and PKCS #11... We need to
+ * find our fortezza key file. We have no clue of where the our binary lives
+ * or where our key file lives. This function lets us search manual paths
+ * to find our key file.
+ */
+char *fort_FindFileInPath(char *path, char *fn)
+{
+ char *next;
+ char *holdData;
+ char *ret = NULL;
+ int len = 0;
+ int fn_len = PORT_Strlen(fn)+1; /* include the NULL */
+ PRFileInfo info;
+ char dirSep = NS_DIR_SEP;
+
+ holdData = PORT_Alloc(strlen(path)+1+fn_len);
+
+ while ((next = local_index(path,NS_PATH_SEP)) != NULL) {
+ len = next - path;
+
+ PORT_Memcpy(holdData,path,len);
+ if ((len != 0) && (holdData[len-1] != dirSep)) {
+ PORT_Memcpy(&holdData[len],&dirSep,1);
+ len++;
+ }
+ PORT_Memcpy(&holdData[len],fn,fn_len);
+
+ if ((local_getFileInfo(holdData,&info) == 0) &&
+ (info.type == PR_FILE_FILE) && (info.size != 0)) {
+ ret = PORT_Strdup(holdData);
+ PORT_Free(holdData);
+ return ret;
+ }
+ path = next+1;
+ }
+
+ len = strlen(path);
+ PORT_Memcpy(holdData,path,len);
+ if ((len != 0) && (holdData[len-1] != dirSep)) {
+ PORT_Memcpy(&holdData[len],&dirSep,1);
+ len++;
+ }
+ PORT_Memcpy(&holdData[len],fn,fn_len);
+
+ if ((local_getFileInfo(holdData,&info) == 0) &&
+ (info.type == PR_FILE_FILE) && (info.size != 0)) {
+ ret = PORT_Strdup(holdData);
+ }
+ PORT_Free(holdData);
+ return ret;
+}
+
+static char *path_table[] = {
+ "PATH","LD_LIBRARY_PATH","LIBPATH"
+};
+
+static int path_table_size = sizeof(path_table)/sizeof(path_table[0]);
+
+char *fort_LookupFORTEZZAInitFile(void)
+{
+ char *fname = NULL;
+ char *home = NULL;
+#ifdef XP_UNIX
+ char unix_home[512];
+#endif
+ int i;
+
+ /* 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"));
+ strcat(unix_home,"/.netscape");
+ fname = fort_FindFileInPath(unix_home,NETSCAPE_INIT_FILE);
+ if (fname) return fname;
+ }
+#endif
+#ifdef XP_WIN
+ home = getenv("windir");
+ if (home) {
+ fname = fort_FindFileInPath(home,NETSCAPE_INIT_FILE);
+ if (fname) return fname;
+ }
+#endif
+
+ fname = fort_FindFileInPath(NS_DEFAULT_PATH,NETSCAPE_INIT_FILE);
+ if (fname) return fname;
+
+ /* now search the system paths */
+ for (i=0; i < path_table_size; i++) {
+ char *path = getenv(path_table[i]);
+
+ if (path != NULL) {
+ fname = fort_FindFileInPath(path,NETSCAPE_INIT_FILE);
+ if (fname) return fname;
+ }
+ }
+
+
+ return NULL;
+}