diff options
author | nelsonb%netscape.com <devnull@localhost> | 2003-12-06 06:41:51 +0000 |
---|---|---|
committer | nelsonb%netscape.com <devnull@localhost> | 2003-12-06 06:41:51 +0000 |
commit | ab5a12f0b4b478fe51179fef6b13515eecc08e90 (patch) | |
tree | 6a3368a53e481a2d140009850fac7eb13ae39977 /security/nss/lib/fortcrypt | |
parent | b6c9daf28b6890a04b30759dafbfe596084ae614 (diff) | |
parent | 4a8a6c26b6278cb6359fabd743efc45e94bfc878 (diff) | |
download | nss-hg-ab5a12f0b4b478fe51179fef6b13515eecc08e90.tar.gz |
NSC_Finalize will now destroy 3 softoken free lists and one more
global pointer. Plugs some memory leaks. Bugscape bug 54301. r=wtc
Diffstat (limited to 'security/nss/lib/fortcrypt')
47 files changed, 17492 insertions, 0 deletions
diff --git a/security/nss/lib/fortcrypt/Makefile b/security/nss/lib/fortcrypt/Makefile new file mode 100644 index 000000000..b3913b3a0 --- /dev/null +++ b/security/nss/lib/fortcrypt/Makefile @@ -0,0 +1,176 @@ +#! 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 +include config.mk + +CILIB = $(OBJDIR)/cilib.$(LIB_SUFFIX) +ORIG_CILIB = libci/$(OS_TARGET)$(OS_RELEASE).$(LIB_SUFFIX) + +ifeq (,$(filter-out WINNT WINCE,$(OS_TARGET))) # omits WIN16 WIN95 +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 + +ifeq (,$(filter-out WIN%,$(OS_TARGET))) +STUBDLL = $(OBJDIR)/stub.$(DLL_SUFFIX) +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_name: + @echo $(CILIB) + +$(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$(OBJ_SUFFIX) + @$(MAKE_OBJDIR) +ifeq (,$(filter-out WIN%,$(OS_TARGET))) + $(MAKE) $(STUBDLL) +else + $(AR) $< +endif + cp $@ $(CILIB) + +ifeq (,$(filter-out WIN%,$(OS_TARGET))) +$(STUBDLL): $(OBJDIR)/maci.o +ifdef NS_USE_GCC + $(LINK_DLL) -Wl,--out-implib,$(STUBLIB) $(OBJDIR)/maci.o $(OS_LIBS) +else + $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJDIR)/maci.o $(OS_LIBS)) +endif + +$(OBJDIR)/maci.o: maci.c +ifdef NS_USE_GCC + $(CC) -o $@ -c $(CFLAGS) $< +else + $(CC) -Fo$@ -c $(CFLAGS) $< +endif +endif + +# +# 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 ; $(MAKE)) + + +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_TARGET)$(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_TARGET)$(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..d54a9dfc0 --- /dev/null +++ b/security/nss/lib/fortcrypt/config.mk @@ -0,0 +1,43 @@ +# +# 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 shared libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(SHARED_LIBRARY) +LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + 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..eb4d5ef87 --- /dev/null +++ b/security/nss/lib/fortcrypt/forsock.c @@ -0,0 +1,816 @@ +/* + * 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 = -1; /* return an invalid personalidyt if one isn't found */ + int i; + PRBool unLoadList = PR_FALSE; + int numPersonalities = 0; + + 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 = -1; + 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; + } + /*PORT_Assert(cryptoType != -1); */ + + 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..e28fd7909 --- /dev/null +++ b/security/nss/lib/fortcrypt/fortpk11.c @@ -0,0 +1,4553 @@ +/* + * 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 + +/* sigh */ +#ifndef EOF +/* stdio was not included */ +extern int sprintf(char *out, char *fmt, ...); +#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 = NULL, *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", (int) slotID); +#else + sprintf (tmp, "FORTEZZA Slot #%d", (int) 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..5097828c6 --- /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) && !defined (XP_OS2) && !defined (XP_BEOS) +#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..6a44cd7a7 --- /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) || defined (XP_OS2) || defined (XP_BEOS) + +/* + * On unix, NT, Windows '95, and OS/2 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..a1b38ec87 --- /dev/null +++ b/security/nss/lib/fortcrypt/maci.c @@ -0,0 +1,901 @@ +/* + * 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 "seccomon.h" + +#if defined( _WIN32 ) || defined( __WIN32__ ) +#define RETURN_TYPE extern __declspec( dllexport ) int _cdecl +#endif /* Windows */ +#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..cab61ace8 --- /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..04057bcba --- /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 = nss +LIBRARY_NAME = fort +#LIBRARY_VERSION = 32 + +DIRS = swfort + +CSRCS = forsock.c \ + fortpk11.c \ + fmutex.c \ + $(NULL) + +EXPORTS = +PRIVATE_EXPORTS = maci.h cryptint.h + +REQUIRES = 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. 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. SmartUpdate +allows users to download JAR archinve that has been signed digitally by +the software vendor. SmartUpdate then decompresses the JAR file, +verify the signature and validity of the files packaged into the archive. +If the signature is valid, SmartUpdate will run the installer script found +in the archive. The installer script will instruct SmartUpdate to +move the downloaded security module library to a specified location. +Next, the script will register the module with Navigator, and configure +it. + +<P>This document does not describe how SmartUpdate works. 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 += 0x1<<0;</TT> +<BR><TT>PKCS11_MECH_DSA_FLAG += 0x1<<1;</TT> +<BR><TT>PKCS11_MECH_RC2_FLAG += 0x1<<2;</TT> +<BR><TT>PKCS11_MECH_RC4_FLAG += 0x1<<3;</TT> +<BR><TT>PKCS11_MECH_DES_FLAG += 0x1<<4;</TT> +<BR><TT>PKCS11_MECH_DH_FLAG += 0x1<<5; //Diffie-Hellman</TT> +<BR><TT>PKCS11_MECH_SKIPJACK_FLAG = +0x1<<6; //SKIPJACK algorithm as in Fortezza cards</TT> +<BR><TT>PKCS11_MECH_RC5_FLAG += 0x1<<7;</TT> +<BR><TT>PKCS11_MECH_SHA1_FLAG += 0x1<<8;</TT> +<BR><TT>PKCS11_MECH_MD5_FLAG += 0x1<<9;</TT> +<BR><TT>PKCS11_MECH_MD2_FLAG += 0x1<<10;</TT> +<BR><TT>PKCS11_MECH_RANDOM_FLAG += 0x1<<27; //Random number generator</TT> +<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored +certs can be read off the token w/o logging in</TT> +<BR><TT>PKCS11_DISABLE_FLAG += 0x1<<30; //tell Navigator to disable this slot by default</TT> + +<P><TT>// Important:</TT> +<BR><TT>// 0x1<<11, 0x1<<12, ... , 0x1<<26, and 0x1<<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> </TT> + +<P><TT>// Ciphers that support SSL or S/MIME</TT> +<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;</TT> + +<P><TT>// Important:</TT> +<BR><TT>// 0x1<<11, 0x1<<12, ... , 0x1<<26, 0x1<<29, +and 0x1<<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> </TT> + +<P><TT>// Return values of pkcs11.addmodule() & pkcs11.delmodule()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_ADD_MODULE += 3 // Successfully added a module</TT> +<BR><TT>JS_OK_DEL_EXTERNAL_MODULE += 2 // Successfully deleted ext. module</TT> +<BR><TT>JS_OK_DEL_INTERNAL_MODULE += 1 // Successfully deleted int. module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -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 += -4 // Error deleting a module</TT> +<BR><TT>JS_ERR_ADD_MODULE += -5 // Error adding a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> +<BR><TT>JS_ERR_BAD_DLL_NAME += -7 // The DLL name is bad</TT> +<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS += -8 // The mechanism flags are invalid</TT> +<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME +cipher flags are invalid</TT> +<BR> + +<P><TT>if (confirm("This script will install and configure a security module, +do you want to continue?")) {</TT> +<BR><TT> // Step 1. Create a version object and a software update +object</TT> +<BR><TT> vi = new netscape.softupdate.VersionInfo(1, 6, 0, 0);</TT> +<BR><TT> su = new netscape.softupdate.SoftwareUpdate(this, "Fortezza +Card PKCS#11 Module");</TT> +<BR><TT> +// "Fortezza ... Module" is the logical name of the bundle</TT> + +<P><TT> // Step 2. Start the install process</TT> +<BR><TT> bAbort = false;</TT> +<BR><TT> err = su.StartInstall("litronic", vi, netscape.softupdate.SoftwareUpdate.FULL_INSTALL);</TT> +<BR><TT> +// litronic is the component folder (logical)</TT> +<BR><TT> bAbort = bAbort || (err +!=0);</TT> + +<P><TT> if (err == 0) {</TT> + +<P><TT> // Step 3. Find out the physical location of +the Program dir</TT> +<BR><TT> Folder = su.GetFolder("Program");</TT> + +<P><TT> // Step 4. Install the files. Unpack them and +list where they go</TT> +<BR><TT> err = su.AddSubcomponent("FortezzaCardDLL", +//component name (logical)</TT> +<BR><TT> +vi, // version info</TT> +<BR><TT> +"DUMMY_DLL", // source file in JAR (physical)</TT> +<BR><TT> +Folder, // target folder (physical)</TT> +<BR><TT> +"DUMMY_DLL", // target path & filename (physical)</TT> +<BR><TT> +this.force); // forces update</TT> +<BR><TT> bAbort = bAbort || (err !=0);</TT> +<BR><TT> }</TT> + +<P><TT> // Step 5. Unless there was a problem, move files to final +location</TT> +<BR><TT> // and update the Client Version Registry</TT> +<BR><TT> if (bAbort) {</TT> +<BR><TT> window.alert("Installation Aborted");</TT> +<BR><TT> su.AbortInstall();</TT> +<BR><TT> } else {</TT> +<BR><TT> err = su.FinalizeInstall();</TT> +<BR><TT> window.alert("Files have been installed.\nContinue +to setup the newly isntalled module...");</TT> +<BR><TT> // Add Module</TT> +<BR><TT> compFolder = su.GetComponentFolder("litronic/FortezzaCardDLL") ++ "/DUMMY_DLL";</TT> +<BR><TT> result = pkcs11.addmodule("Fortezza", compFolder, +pkcs11MechanismFlags, pkcs11CipherFlags);</TT> +<BR><TT> if +( result < 0) {</TT> +<BR><TT> +window.alert("New module setup failed. Error code: " + result);</TT> +<BR><TT> } +else {</TT> +<BR><TT> +window.alert("New module setup completed.");</TT> +<BR><TT> }</TT> +<BR><TT> }</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. For security +reasons, it will pop up a dialog box to ask the user to confirm this action. +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> +string LibraryFullPath,</TT> +<BR><TT> +int CryptoMechanismFlags,</TT> +<BR><TT> +int CipherFlags);</TT> +<BR> +<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 (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 += 0x1<<0;</TT> +<BR><TT>PKCS11_MECH_DSA_FLAG += 0x1<<1;</TT> +<BR><TT>PKCS11_MECH_RC2_FLAG += 0x1<<2;</TT> +<BR><TT>PKCS11_MECH_RC4_FLAG += 0x1<<3;</TT> +<BR><TT>PKCS11_MECH_DES_FLAG += 0x1<<4;</TT> +<BR><TT>PKCS11_MECH_DH_FLAG += 0x1<<5; //Diffie-Hellman</TT> +<BR><TT>PKCS11_MECH_SKIPJACK_FLAG = +0x1<<6; //SKIPJACK algorithm as in Fortezza cards</TT> +<BR><TT>PKCS11_MECH_RC5_FLAG += 0x1<<7;</TT> +<BR><TT>PKCS11_MECH_SHA1_FLAG += 0x1<<8;</TT> +<BR><TT>PKCS11_MECH_MD5_FLAG += 0x1<<9;</TT> +<BR><TT>PKCS11_MECH_MD2_FLAG += 0x1<<10;</TT> +<BR><TT>PKCS11_MECH_RANDOM_FLAG += 0x1<<27; //Random number generator</TT> +<BR><TT>PKCS11_PUB_READABLE_CERT_FLAG = 0x1<<28; //Stored +certs can be read off the token w/o logging in</TT> +<BR><TT>PKCS11_DISABLE_FLAG += 0x1<<30; //tell Navigator to disable this slot by default</TT> + +<P>Supported SSL or S/MIME Ciphers +<BR><TT>PKCS11_CIPHER_FORTEZZA_FLAG = 0x1<<0;</TT> + +<P>Important for CryptoMechanismFlags: +<BR><TT>0x1<<11</TT>, <TT>0x1<<12</TT>, ... , <TT>0x1<<26</TT>, +<TT>0x1<<29, </TT>and <TT>0x1<<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<<1</TT>, <TT>0x1<<2</TT>, ... , <TT>0x1<<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> </TT> +<BR>Return Values: +<BR><TT>// Return values of pkcs11.addmod()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_ADD_MODULE += 3 // Successfully added a module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -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 += -5 // Error adding a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> +<BR><TT>JS_ERR_BAD_DLL_NAME += -7 // The DLL name is bad</TT> +<BR><TT>JS_ERR_BAD_MECHANISM_FLAGS += -8 // The mechanism flags are invalid</TT> +<BR><TT>JS_ERR_BAD_CIPHER_ENABLE_FLAGS = -9 // The SSL, S/MIME +cipher flags are invalid</TT> +<BR> +<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. For security reasons, it will pop +up a dialog box to ask the user to confirm this action. 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> +<BR>Parameters +<TABLE BORDER WIDTH="90%" > +<TR> +<TD><TT>ModuleName</TT></TD> + +<TD>Name of the module</TD> +</TR> +</TABLE> +<TT> </TT> +<BR>Return Values: +<BR><TT>// Return values of pkcs11.addmod() & pkcs11.delmod()</TT> +<BR><TT>// success codes</TT> +<BR><TT>JS_OK_DEL_EXTERNAL_MODULE += 2 // Successfully deleted ext. module</TT> +<BR><TT>JS_OK_DEL_INTERNAL_MODULE += 1 // Successfully deleted int. module</TT> + +<P><TT>// failure codes</TT> +<BR><TT>JS_ERR_OTHER += -1 // Other errors than the followings</TT> +<BR><TT>JS_ERR_USER_CANCEL_ACTION += -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 += -4 // Error deleting a module</TT> +<BR><TT>JS_ERR_BAD_MODULE_NAME += -6 // The module name is invalid</TT> + +<P><A NAME="copyright"></A><FONT SIZE=+1>VI. Copyright Notice</FONT> +<BR> + +<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/Makefile b/security/nss/lib/fortcrypt/swfort/Makefile new file mode 100644 index 000000000..9c5e39de2 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/Makefile @@ -0,0 +1,83 @@ +#! gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1994-2000 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License Version 2 or later (the +# "GPL"), in which case the provisions of the GPL are applicable +# instead of those above. If you wish to allow use of your +# version of this file only under the terms of the GPL and not to +# allow others to use your version of this file under the MPL, +# indicate your decision by deleting the provisions above and +# replace them with the notice and other provisions required by +# the GPL. If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +####################################################################### +# (1) Include initial platform-independent assignments (MANDATORY). # +####################################################################### + +include manifest.mn + +####################################################################### +# (2) Include "global" configuration information. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/config.mk + +####################################################################### +# (3) Include "component" configuration information. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (4) Include "local" platform-dependent assignments (OPTIONAL). # +####################################################################### + +include config.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +$(OBJDIR)/nslib.c: nsmap.h swflib.c + @$(MAKE_OBJDIR) + rm -f $@ + cat $+ > $@ + +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..0a00dc61e --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/config.mk @@ -0,0 +1,43 @@ +# +# 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 = +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..597d86c3c --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/manifest.mn @@ -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. +# +CORE_DEPTH = ../../../.. + +MODULE = nss +LIBRARY_NAME = swfci +#LIBRARY_VERSION = 12 + +BUILT_CSRCS = nslib.c \ + $(NULL) + +CSRCS = swfalg.c \ + swfparse.c \ + swflib.c \ + swfutl.c \ + $(NULL) +DIRS = pkcs11 + +EXPORTS = swfort.h swfortt.h +PRIVATE_EXPORTS = swforti.h swfortti.h + +REQUIRES = dbm nspr 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..44e50063b --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/Makefile @@ -0,0 +1,175 @@ +#! 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 +include config.mk + +CRYPTO_LIB = $(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) +#SWCILI = ../$(OBJDIR)/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) + +# can't do this in manifest.mn because OS_TARGET isn't defined there. +ifeq (,$(filter-out WIN%,$(OS_TARGET))) + +ifdef MOZILLA_SECURITY_BUILD +CRYPTO_LIB = $(DIST)/lib/crypto.lib +endif +ifdef MOZILLA_BSAFE_BUILD +CRYPTO_LIB += $(DIST)/lib/bsafe$(BSAFEVER).lib +CRYPTO_LIB += $(DIST)/lib/freebl.lib +endif + +# Link with the real NSPR DLLs for MinGW because the NSPR stubs in +# stub.c can't resolve the references to the _imp__PR_XXX symbols. +# This is merely an expedient hack and not the right solution. +ifdef NS_USE_GCC +EXTRA_LIBS = \ + $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \ + $(CRYPTO_LIB) \ + $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \ + -L$(DIST)/lib \ + -lplc4 \ + -lplds4 \ + -lnspr4 \ + -lws2_32 \ + -lwinmm \ + $(NULL) +else # ! NS_USE_GCC +EXTRA_LIBS = \ + $(DIST)/lib/swfci.lib \ + $(DIST)/lib/softokn.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) +endif # NS_USE_GCC + +else + +ifdef MOZILLA_SECURITY_BUILD +CRYPTO_LIB = $(DIST)/lib/$(LIB_PREFIX)crypto.$(LIB_SUFFIX) +endif +ifdef MOZILLA_BSAFE_BUILD +CRYPTO_LIB += $(DIST)/lib/$(LIB_PREFIX)bsafe.$(LIB_SUFFIX) +CRYPTO_LIB += $(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) +endif + +EXTRA_LIBS += \ + $(DIST)/lib/$(LIB_PREFIX)swfci.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)softokn.$(LIB_SUFFIX) \ + $(CRYPTO_LIB) \ + $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) \ + $(DIST)/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX) \ + $(NULL) + +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) + +# +# 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_TARGET)$(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_TARGET)$(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..960774691 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/config.mk @@ -0,0 +1,43 @@ +# +# 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 shared libraries +# are specifed as dependencies within rules.mk. +# + +TARGETS = $(SHARED_LIBRARY) $(SHARED_SW_LIBRARY) $(LIBCI_JAR) $(LIBCI_SW_JAR) +LIBRARY = +IMPORT_LIBRARY = +PROGRAM = + 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..fce80320a --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/manifest.mn @@ -0,0 +1,63 @@ +# +# 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 = nss +LIBRARY_NAME = swft +#LIBRARY_VERSION = 32 + +COPIED_CSRCS = forsock.c \ + fortpk11.c \ + fmutex.c \ + $(NULL) + +CSRCS = \ + $(COPIED_CSRCS) \ + stub.c \ + $(NULL) + +vpath %.c ../../ +INCLUDES = -I../.. + +EXPORTS = + +REQUIRES = dbm + + +DEFINES = -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..12ce3cd27 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/pkcs11/stub.c @@ -0,0 +1,377 @@ +/* + * 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); + } +} + +char * +PORT_Strdup(const char *str) +{ + size_t len = PORT_Strlen(str)+1; + char *newstr; + + newstr = (char *)PORT_Alloc(len); + if (newstr) { + PORT_Memcpy(newstr, str, len); + } + return newstr; +} + +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,const 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; +} + +/* + * Do not use NSPR stubs for MinGW because they can't resolve references + * to the _imp__PR_XXX symbols. This is merely an expedient hack and not + * the right solution. + */ +#if !(defined(WIN32) && defined(__GNUC__)) +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); } + +PR_IMPLEMENT(void) +PR_SetError(PRErrorCode errorCode, PRInt32 oserr) { return; } + +PR_IMPLEMENT(void) +PR_SetErrorText(PRIntn textLength, const char *text) { return; } +#endif /* ! (WIN32 && GCC) */ + + +/* 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, } +}; + +/* + * Do not use NSPR stubs for MinGW because they can't resolve references + * to the _imp__PR_XXX symbols. This is merely an expedient hack and not + * the right solution. + */ +#if !(defined(WIN32) && defined(__GNUC__)) +/* 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 "nssilock.h" +#include "fmutex.h" +PR_IMPLEMENT(PRLock *) +PR_NewLock(void) { + PRLock *lock = NULL; + + FMUTEX_Create((void **)&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; +} +#endif /* ! (WIN32 && GCC) */ + +/********************** 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..c41a878fb --- /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" + +#if defined(XP_UNIX) || defined(XP_BEOS) +#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,¶ms.prime,&key_info->p); + if (rv != SECSuccess) return CI_EXEC_FAIL; + rv = SECITEM_CopyItem(NULL,¶ms.subPrime,&key_info->q); + if (rv != SECSuccess) return CI_EXEC_FAIL; + rv = SECITEM_CopyItem(NULL,¶ms.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(¶ms, &privKey); + SECITEM_FreeItem(¶ms.prime,PR_FALSE); + SECITEM_FreeItem(¶ms.subPrime,PR_FALSE); + SECITEM_FreeItem(¶ms.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 ) +{ + FORTEZZAPrivateKey *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,fortezzaDHKey,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) fort_DestroyPrivateKey(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) +{ + FORTEZZAPrivateKey *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,fortezzaDSAKey,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) fort_DestroyPrivateKey(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..bcc07ee62 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swforti.h @@ -0,0 +1,177 @@ +/* + * 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); + +/* + * return the private key based on the token and entry. + */ +FORTEZZAPrivateKey *fort_GetPrivKey(FORTSWToken *token,FORTEZZAKeyType keyType,fortSlotEntry *certEntry); + +/* + * Free the key acquired above. + */ +void fort_DestroyPrivateKey(FORTEZZAPrivateKey *key); + +/* + * 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..0fd2d0e34 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfortti.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. + */ +/* + * 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 "blapit.h" +#include "swfortt.h" + + +typedef enum { + fortezzaDSAKey = 0, + fortezzaDHKey = 1 +} FORTEZZAKeyType; + +/* +** Low Level private key object +** This is only used by the raw Crypto engines (crypto), keydb (keydb), +** and PKCS #11. Everyone else uses the high level key structure. +*/ +struct FORTEZZAPrivateKeyStr { + PLArenaPool *arena; + FORTEZZAKeyType keyType; + union { + DSAPrivateKey dsa; + DHPrivateKey dh; + } u; +}; +typedef struct FORTEZZAPrivateKeyStr FORTEZZAPrivateKey; + + +/* 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..30672c73d --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfparse.c @@ -0,0 +1,539 @@ +/* + * 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; + SECItem newInitBits; + + /* 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; + + /* copy the DER into the arena, since Quick DER returns data that points + into the DER input, which may get freed by the caller */ + rv = SECITEM_CopyItem(arena, &newInitBits, initBits); + if ( rv != SECSuccess ) { + goto fail; + } + + /* ANS1 decode the complete init file */ + rv = SEC_QuickDERDecodeItem(arena,sw_init_file,fortSwFortezzaInitFile,&newInitBits); + 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; + + 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..eee677f65 --- /dev/null +++ b/security/nss/lib/fortcrypt/swfort/swfutl.c @@ -0,0 +1,750 @@ +/* + * 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_OS2 +#include <sys/stat.h> +#endif + +#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. + */ +FORTEZZAPrivateKey * +fort_GetPrivKey(FORTSWToken *token,FORTEZZAKeyType keyType, + fortSlotEntry *certEntry) +{ + FORTEZZAPrivateKey *returnKey = NULL; + SECStatus rv = SECFailure; + PRArenaPool *poolp; + fortKeyInformation *keyInfo = NULL; + unsigned char *keyData; + int len, ret; + + + /* select the right keyinfo */ + switch (keyType) { + case fortezzaDSAKey: + keyInfo = certEntry->signatureKeyInformation; + if (keyInfo == NULL) keyInfo = certEntry->exchangeKeyInformation; + break; + case fortezzaDHKey: + 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 = (FORTEZZAPrivateKey*)PORT_ArenaZAlloc(poolp, sizeof(FORTEZZAPrivateKey)); + 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; +} + + +void +fort_DestroyPrivateKey(FORTEZZAPrivateKey *key) +{ + if (key && key->arena) { + PORT_FreeArena(key->arena, PR_TRUE); + } +} + +/* + * 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. + */ +#if defined (XP_UNIX) || defined (XP_OS2) || defined (XP_BEOS) +#if defined (XP_UNIX) || defined (XP_BEOS) +#define NS_PATH_SEP ':' +#define NS_DIR_SEP '/' +#define NS_DEFAULT_PATH ".:/bin/netscape:/etc/netscape/:/etc" +#endif + +#ifdef XP_OS2 /* for OS/2 */ +#define NS_PATH_SEP ';' +#define NS_DIR_SEP '\\' +#define NS_DEFAULT_PATH ".:\\bin\\netscape:\\etc\\netscape\\:\\etc" +#endif + +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 /* UNIX, OS/2, and BEOS */ + +#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 /* XP_WIN */ + +#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; +} |