summaryrefslogtreecommitdiff
path: root/security/nss/cmd
diff options
context:
space:
mode:
authorcvs2hg <devnull@localhost>2008-01-31 22:25:55 +0000
committercvs2hg <devnull@localhost>2008-01-31 22:25:55 +0000
commit413fd8e28a7195f4e849e4bd5356cdc75ca429ea (patch)
treec1559eb16782fa2b5adfdb74f260ce7e15f39830 /security/nss/cmd
parentefc6ec73fd3a32a186e55ad5da2cb9e383c8676e (diff)
downloadnss-hg-413fd8e28a7195f4e849e4bd5356cdc75ca429ea.tar.gz
fixup commit for branch 'GECKO181_20080702_RELBRANCH'
Diffstat (limited to 'security/nss/cmd')
-rw-r--r--security/nss/cmd/Makefile133
-rw-r--r--security/nss/cmd/SSLsample/NSPRerrs.h136
-rw-r--r--security/nss/cmd/SSLsample/SECerrs.h444
-rw-r--r--security/nss/cmd/SSLsample/SSLerrs.h369
-rw-r--r--security/nss/cmd/SSLsample/client.mn4
-rw-r--r--security/nss/cmd/SSLsample/server.mn4
-rw-r--r--security/nss/cmd/addbuiltin/addbuiltin.c6
-rw-r--r--security/nss/cmd/bltest/blapitest.c9
-rw-r--r--security/nss/cmd/certutil/certutil.c99
-rw-r--r--security/nss/cmd/crlutil/crlgen.c63
-rw-r--r--security/nss/cmd/crlutil/crlutil.c97
-rw-r--r--security/nss/cmd/dbck/Makefile2
-rw-r--r--security/nss/cmd/dbck/dbck.c1118
-rw-r--r--security/nss/cmd/dbck/dbrecover.c702
-rw-r--r--security/nss/cmd/dbck/manifest.mn1
-rw-r--r--security/nss/cmd/dbtest/Makefile10
-rwxr-xr-xsecurity/nss/cmd/fipstest/Makefile7
-rwxr-xr-xsecurity/nss/cmd/fipstest/dsa.sh34
-rw-r--r--security/nss/cmd/fipstest/ecdsa.sh29
-rw-r--r--security/nss/cmd/fipstest/fipstest.c4851
-rwxr-xr-xsecurity/nss/cmd/fipstest/hmac.sh20
-rw-r--r--security/nss/cmd/fipstest/rng.sh29
-rw-r--r--security/nss/cmd/fipstest/rsa.sh20
-rw-r--r--security/nss/cmd/fipstest/sha.sh46
-rw-r--r--security/nss/cmd/fipstest/tdea.sh87
-rw-r--r--security/nss/cmd/lib/SECerrs.h19
-rw-r--r--security/nss/cmd/lib/SSLerrs.h18
-rw-r--r--security/nss/cmd/lib/manifest.mn3
-rw-r--r--security/nss/cmd/lib/secpwd.c2
-rw-r--r--security/nss/cmd/lib/secutil.c63
-rw-r--r--security/nss/cmd/lib/secutil.h2
-rw-r--r--security/nss/cmd/manifest.mn1
-rw-r--r--security/nss/cmd/modutil/modutil.c3
-rw-r--r--security/nss/cmd/modutil/pk11.c21
-rw-r--r--security/nss/cmd/modutil/specification.html2
-rw-r--r--security/nss/cmd/ocspclnt/ocspclnt.c7
-rwxr-xr-xsecurity/nss/cmd/pk11mode/Makefile93
-rw-r--r--security/nss/cmd/pk11mode/manifest.mn48
-rw-r--r--security/nss/cmd/pk11mode/pk11mode.c5345
-rw-r--r--security/nss/cmd/pk11util/pk11util.c16
-rw-r--r--security/nss/cmd/pk12util/pk12util.c324
-rw-r--r--security/nss/cmd/platlibs.mk59
-rw-r--r--security/nss/cmd/pp/pp.c1
-rw-r--r--security/nss/cmd/rsaperf/Makefile10
-rw-r--r--security/nss/cmd/selfserv/selfserv.c265
-rw-r--r--security/nss/cmd/shlibsign/Makefile10
-rw-r--r--security/nss/cmd/shlibsign/mangle/mangle.c36
-rw-r--r--security/nss/cmd/shlibsign/sign.sh2
-rw-r--r--security/nss/cmd/signtool/util.c2
-rw-r--r--security/nss/cmd/ssltap/ssltap.c366
-rw-r--r--security/nss/cmd/strsclnt/strsclnt.c268
-rw-r--r--security/nss/cmd/tstclnt/Makefile10
-rw-r--r--security/nss/cmd/tstclnt/tstclnt.c232
-rw-r--r--security/nss/cmd/vfychain/Makefile8
-rw-r--r--security/nss/cmd/vfyserv/Makefile10
-rw-r--r--security/nss/cmd/vfyserv/vfyserv.c149
-rw-r--r--security/nss/cmd/vfyserv/vfyutil.c52
-rw-r--r--security/nss/cmd/zlib/zutil.h3
58 files changed, 11653 insertions, 4117 deletions
diff --git a/security/nss/cmd/Makefile b/security/nss/cmd/Makefile
index 5369d8904..a8d18fd67 100644
--- a/security/nss/cmd/Makefile
+++ b/security/nss/cmd/Makefile
@@ -46,145 +46,12 @@ ifndef USE_SYSTEM_ZLIB
ZLIB_SRCDIR = zlib # Add the zlib directory to DIRS.
endif
-# These sources were once in this directory, but now are gone.
-MISSING_SOURCES = \
- addcert.c \
- berparse.c \
- cert.c \
- key.c \
- key_rand.c \
- keygen.c \
- sec_fe.c \
- sec_read.c \
- secarb.c \
- secutil.c \
- $(NULL)
-
-# we don't build these any more, but the sources are still here
-OBSOLETE = \
- berdec.c \
- berdump.c \
- cypher.c \
- dumpcert.c \
- listcerts.c \
- mkdongle.c \
- p12exprt.c \
- p12imprt.c \
- rc4.c \
- sign.c \
- unwrap.c \
- vector.c \
- verify.c \
- wrap.c \
- $(NULL)
-
-# the base files for the executables
-# hey -- keep these alphabetical, please
-EXEC_SRCS = \
- $(NULL)
-
-# files that generate two separate objects and executables
-# BI_SRCS = \
-# keyutil.c \
-# p7env.c \
-# tstclnt.c \
-# $(NULL)
-
-# -I$(CORE_DEPTH)/security/lib/cert \
-# -I$(CORE_DEPTH)/security/lib/key \
-# -I$(CORE_DEPTH)/security/lib/util \
-
INCLUDES += \
-I$(DIST)/../public/security \
-I./include \
$(NULL)
-TBD_DIRS = rsh rshd rdist ssld
-
-# For the time being, sec stuff is export only
-# US_FLAGS = -DEXPORT_VERSION -DUS_VERSION
-
-US_FLAGS = -DEXPORT_VERSION
-EXPORT_FLAGS = -DEXPORT_VERSION
-
-BASE_LIBS = \
- $(DIST)/lib/libdbm.$(LIB_SUFFIX) \
- $(DIST)/lib/libxp.$(LIB_SUFFIX) \
- $(DIST)/lib/libnspr.$(LIB_SUFFIX) \
- $(NULL)
-
-# $(DIST)/lib/libpurenspr.$(LIB_SUFFIX) \
-
-#There is a circular dependancy in security/lib, and here is a gross fix
-SEC_LIBS = \
- $(DIST)/lib/libsecnav.$(LIB_SUFFIX) \
- $(DIST)/lib/libssl.$(LIB_SUFFIX) \
- $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \
- $(DIST)/lib/libcert.$(LIB_SUFFIX) \
- $(DIST)/lib/libkey.$(LIB_SUFFIX) \
- $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \
- $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \
- $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
- $(DIST)/lib/libssl.$(LIB_SUFFIX) \
- $(DIST)/lib/libpkcs7.$(LIB_SUFFIX) \
- $(DIST)/lib/libcert.$(LIB_SUFFIX) \
- $(DIST)/lib/libkey.$(LIB_SUFFIX) \
- $(DIST)/lib/libsecmod.$(LIB_SUFFIX) \
- $(DIST)/lib/libcrypto.$(LIB_SUFFIX) \
- $(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
- $(DIST)/lib/libhash.$(LIB_SUFFIX) \
- $(NULL)
-
-MYLIB = lib/$(OBJDIR)/libsectool.$(LIB_SUFFIX)
-
-US_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS)
-EX_LIBS = $(MYLIB) $(SEC_LIBS) $(BASE_LIBS) $(MYLIB) $(BASE_LIBS)
-
-REQUIRES = libxp nspr security
-
-CSRCS = $(EXEC_SRCS) $(BI_SRCS)
-
-OBJS = $(CSRCS:.c=.o) $(BI_SRCS:.c=-us.o) $(BI_SRCS:.c=-ex.o)
-
-PROGS = $(addprefix $(OBJDIR)/, $(EXEC_SRCS:.c=$(BIN_SUFFIX)))
-US_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-us$(BIN_SUFFIX)))
-EX_PROGS = $(addprefix $(OBJDIR)/, $(BI_SRCS:.c=-ex$(BIN_SUFFIX)))
-
-
-NON_DIRS = $(PROGS) $(US_PROGS) $(EX_PROGS)
-TARGETS = $(NON_DIRS)
-
include $(CORE_DEPTH)/coreconf/rules.mk
-
-ifneq ($(OS_TARGET),OS2)
-$(OBJDIR)/%-us.o: %.c
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $(US_FLAGS) -c $*.c
-
-$(OBJDIR)/%-ex.o: %.c
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $(EXPORT_FLAGS) -c $*.c
-
-$(OBJDIR)/%.o: %.c
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $(EXPORT_FLAGS) -c $*.c
-
-$(US_PROGS):$(OBJDIR)/%-us: $(OBJDIR)/%-us.o $(US_LIBS)
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $(OBJDIR)/$*-us.o $(LDFLAGS) $(US_LIBS) $(OS_LIBS)
-
-$(EX_PROGS):$(OBJDIR)/%-ex: $(OBJDIR)/%-ex.o $(EX_LIBS)
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $(OBJDIR)/$*-ex.o $(LDFLAGS) $(EX_LIBS) $(OS_LIBS)
-
-$(PROGS):$(OBJDIR)/%: $(OBJDIR)/%.o $(EX_LIBS)
- @$(MAKE_OBJDIR)
- $(CCF) -o $@ $@.o $(LDFLAGS) $(EX_LIBS) $(OS_LIBS)
-
-#install:: $(TARGETS)
-# $(INSTALL) $(TARGETS) $(DIST)/bin
-endif
-
symbols::
@echo "TARGETS = $(TARGETS)"
diff --git a/security/nss/cmd/SSLsample/NSPRerrs.h b/security/nss/cmd/SSLsample/NSPRerrs.h
deleted file mode 100644
index 8a6a49f63..000000000
--- a/security/nss/cmd/SSLsample/NSPRerrs.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* General NSPR 2.0 errors */
-/* Caller must #include "prerror.h" */
-
-ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." )
-ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." )
-ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." )
-ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." )
-ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." )
-ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." )
-ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." )
-ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." )
-ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." )
-ER2( PR_IO_ERROR, "I/O function error." )
-ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." )
-ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." )
-ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." )
-ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." )
-ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." )
-ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." )
-ER2( PR_IS_CONNECTED_ERROR, "Already connected." )
-ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." )
-ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." )
-ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." )
-ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." )
-ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." )
-ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." )
-ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." )
-ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." )
-ER2( PR_FIND_SYMBOL_ERROR,
-"Symbol not found in any of the loaded dynamic libraries." )
-ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." )
-ER2( PR_DIRECTORY_LOOKUP_ERROR,
-"A directory lookup on a network address has failed." )
-ER2( PR_TPD_RANGE_ERROR,
-"Attempt to access a TPD key that is out of range." )
-ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." )
-ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." )
-ER2( PR_NOT_SOCKET_ERROR,
-"Network operation attempted on non-network file descriptor." )
-ER2( PR_NOT_TCP_SOCKET_ERROR,
-"TCP-specific function attempted on a non-TCP file descriptor." )
-ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." )
-ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." )
-ER2( PR_OPERATION_NOT_SUPPORTED_ERROR,
-"The requested operation is not supported by the platform." )
-ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR,
-"The host operating system does not support the protocol requested." )
-ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." )
-ER2( PR_BUFFER_OVERFLOW_ERROR,
-"The value requested is too large to be stored in the data buffer provided." )
-ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." )
-ER2( PR_RANGE_ERROR, "Unused." )
-ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." )
-ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." )
-ER2( PR_FILE_TOO_BIG_ERROR,
-"Write would result in file larger than the system allows." )
-ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." )
-ER2( PR_PIPE_ERROR, "Unused." )
-ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." )
-ER2( PR_IS_DIRECTORY_ERROR,
-"Cannot perform a normal file operation on a directory." )
-ER2( PR_LOOP_ERROR, "Symbolic link loop." )
-ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." )
-ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." )
-ER2( PR_NOT_DIRECTORY_ERROR,
-"Cannot perform directory operation on a normal file." )
-ER2( PR_READ_ONLY_FILESYSTEM_ERROR,
-"Cannot write to a read-only file system." )
-ER2( PR_DIRECTORY_NOT_EMPTY_ERROR,
-"Cannot delete a directory that is not empty." )
-ER2( PR_FILESYSTEM_MOUNTED_ERROR,
-"Cannot delete or rename a file object while the file system is busy." )
-ER2( PR_NOT_SAME_DEVICE_ERROR,
-"Cannot rename a file to a file system on another device." )
-ER2( PR_DIRECTORY_CORRUPTED_ERROR,
-"The directory object in the file system is corrupted." )
-ER2( PR_FILE_EXISTS_ERROR,
-"Cannot create or rename a filename that already exists." )
-ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR,
-"Directory is full. No additional filenames may be added." )
-ER2( PR_INVALID_DEVICE_STATE_ERROR,
-"The required device was in an invalid state." )
-ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." )
-ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." )
-ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." )
-ER2( PR_FILE_SEEK_ERROR, "Seek error." )
-ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." )
-ER2( PR_IN_PROGRESS_ERROR,
-"Operation is still in progress (probably a non-blocking connect)." )
-ER2( PR_ALREADY_INITIATED_ERROR,
-"Operation has already been initiated (probably a non-blocking connect)." )
-
-#ifdef PR_GROUP_EMPTY_ERROR
-ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." )
-#endif
-
-#ifdef PR_INVALID_STATE_ERROR
-ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." )
-#endif
-
-ER2( PR_MAX_ERROR, "Placeholder for the end of the list" )
diff --git a/security/nss/cmd/SSLsample/SECerrs.h b/security/nss/cmd/SSLsample/SECerrs.h
deleted file mode 100644
index 90f7a2e9f..000000000
--- a/security/nss/cmd/SSLsample/SECerrs.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* General security error codes */
-/* Caller must #include "secerr.h" */
-
-ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0,
-"An I/O error occurred during security authorization.")
-
-ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1,
-"security library failure.")
-
-ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2,
-"security library: received bad data.")
-
-ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3,
-"security library: output length error.")
-
-ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4,
-"security library has experienced an input length error.")
-
-ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5,
-"security library: invalid arguments.")
-
-ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6,
-"security library: invalid algorithm.")
-
-ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7,
-"security library: invalid AVA.")
-
-ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8,
-"Improperly formatted time string.")
-
-ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9,
-"security library: improperly formatted DER-encoded message.")
-
-ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10,
-"Peer's certificate has an invalid signature.")
-
-ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11,
-"Peer's Certificate has expired.")
-
-ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12,
-"Peer's Certificate has been revoked.")
-
-ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13,
-"Peer's Certificate issuer is not recognized.")
-
-ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14,
-"Peer's public key is invalid.")
-
-ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15,
-"The security password entered is incorrect.")
-
-ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16,
-"New password entered incorrectly. Please try again.")
-
-ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17,
-"security library: no nodelock.")
-
-ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18,
-"security library: bad database.")
-
-ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19,
-"security library: memory allocation failure.")
-
-ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20,
-"Peer's certificate issuer has been marked as not trusted by the user.")
-
-ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21,
-"Peer's certificate has been marked as not trusted by the user.")
-
-ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22),
-"Certificate already exists in your database.")
-
-ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23),
-"Downloaded certificate's name duplicates one already in your database.")
-
-ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24),
-"Error adding certificate to database.")
-
-ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25),
-"Error refiling the key for this certificate.")
-
-ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26),
-"The private key for this certificate cannot be found in key database")
-
-ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27),
-"This certificate is valid.")
-
-ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28),
-"This certificate is not valid.")
-
-ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29),
-"Cert Library: No Response")
-
-ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
-"The certificate issuer's certificate has expired. Check your system date and time.")
-
-ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
-"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
-
-ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
-"The CRL for the certificate's issuer has an invalid signature.")
-
-ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33),
-"New CRL has an invalid format.")
-
-ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34),
-"Certificate extension value is invalid.")
-
-ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35),
-"Certificate extension not found.")
-
-ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36),
-"Issuer certificate is invalid.")
-
-ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37),
-"Certificate path length constraint is invalid.")
-
-ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38),
-"Certificate usages field is invalid.")
-
-ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39),
-"**Internal ONLY module**")
-
-ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40),
-"The key does not support the requested operation.")
-
-ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41),
-"Certificate contains unknown critical extension.")
-
-ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42),
-"New CRL is not later than the current one.")
-
-ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43),
-"Not encrypted or signed: you do not yet have an email certificate.")
-
-ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44),
-"Not encrypted: you do not have certificates for each of the recipients.")
-
-ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45),
-"Cannot decrypt: you are not a recipient, or matching certificate and \
-private key not found.")
-
-ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46),
-"Cannot decrypt: key encryption algorithm does not match your certificate.")
-
-ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47),
-"Signature verification failed: no signer found, too many signers found, \
-or improper or corrupted data.")
-
-ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48),
-"Unsupported or unknown key algorithm.")
-
-ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49),
-"Cannot decrypt: encrypted using a disallowed algorithm or key size.")
-
-
-/* Fortezza Alerts */
-ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50),
-"Fortezza card has not been properly initialized. \
-Please remove it and return it to your issuer.")
-
-ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51),
-"No Fortezza cards Found")
-
-ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52),
-"No Fortezza card selected")
-
-ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53),
-"Please select a personality to get more info on")
-
-ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54),
-"Personality not found")
-
-ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55),
-"No more information on that Personality")
-
-ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56),
-"Invalid Pin")
-
-ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57),
-"Couldn't initialize Fortezza personalities.")
-/* end fortezza alerts. */
-
-ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58),
-"No KRL for this site's certificate has been found.")
-
-ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59),
-"The KRL for this site's certificate has expired.")
-
-ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60),
-"The KRL for this site's certificate has an invalid signature.")
-
-ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61),
-"The key for this site's certificate has been revoked.")
-
-ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62),
-"New KRL has an invalid format.")
-
-ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63),
-"security library: need random data.")
-
-ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64),
-"security library: no security module can perform the requested operation.")
-
-ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65),
-"The security card or token does not exist, needs to be initialized, or has been removed.")
-
-ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66),
-"security library: read-only database.")
-
-ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67),
-"No slot or token was selected.")
-
-ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68),
-"A certificate with the same nickname already exists.")
-
-ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69),
-"A key with the same nickname already exists.")
-
-ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70),
-"error while creating safe object")
-
-ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71),
-"error while creating baggage object")
-
-ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72),
-"Couldn't remove the principal")
-
-ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73),
-"Couldn't delete the privilege")
-
-ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74),
-"This principal doesn't have a certificate")
-
-ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75),
-"Required algorithm is not allowed.")
-
-ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76),
-"Error attempting to export certificates.")
-
-ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77),
-"Error attempting to import certificates.")
-
-ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78),
-"Unable to import. Decoding error. File not valid.")
-
-ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79),
-"Unable to import. Invalid MAC. Incorrect password or corrupt file.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80),
-"Unable to import. MAC algorithm not supported.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81),
-"Unable to import. Only password integrity and privacy modes supported.")
-
-ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82),
-"Unable to import. File structure is corrupt.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83),
-"Unable to import. Encryption algorithm not supported.")
-
-ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84),
-"Unable to import. File version not supported.")
-
-ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85),
-"Unable to import. Incorrect privacy password.")
-
-ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86),
-"Unable to import. Same nickname already exists in database.")
-
-ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87),
-"The user pressed cancel.")
-
-ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88),
-"Not imported, already in database.")
-
-ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89),
-"Message not sent.")
-
-ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90),
-"Certificate key usage inadequate for attempted operation.")
-
-ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91),
-"Certificate type not approved for application.")
-
-ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92),
-"Address in signing certificate does not match address in message headers.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93),
-"Unable to import. Error attempting to import private key.")
-
-ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94),
-"Unable to import. Error attempting to import certificate chain.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95),
-"Unable to export. Unable to locate certificate or key by nickname.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96),
-"Unable to export. Private Key could not be located and exported.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97),
-"Unable to export. Unable to write the export file.")
-
-ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98),
-"Unable to import. Unable to read the import file.")
-
-ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99),
-"Unable to export. Key database corrupt or deleted.")
-
-ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100),
-"Unable to generate public/private key pair.")
-
-ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101),
-"Password entered is invalid. Please pick a different one.")
-
-ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102),
-"Old password entered incorrectly. Please try again.")
-
-ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103),
-"Certificate nickname already in use.")
-
-ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104),
-"Peer FORTEZZA chain has a non-FORTEZZA Certificate.")
-
-/* ER3(SEC_ERROR_UNKNOWN, (SEC_ERROR_BASE + 105), */
-
-ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106),
-"Invalid module name.")
-
-ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107),
-"Invalid module path/filename")
-
-ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108),
-"Unable to add module")
-
-ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109),
-"Unable to delete module")
-
-ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110),
-"New KRL is not later than the current one.")
-
-ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111),
-"New CKL has different issuer than current CKL. Delete current CKL.")
-
-ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112),
-"The Certifying Authority for this certificate is not permitted to issue a \
-certificate with this name.")
-
-ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113),
-"The key revocation list for this certificate is not yet valid.")
-
-ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114),
-"The certificate revocation list for this certificate is not yet valid.")
-
-ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115),
-"The requested certificate could not be found.")
-
-ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116),
-"The signer's certificate could not be found.")
-
-ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117),
-"The location for the certificate status server has invalid format.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118),
-"The OCSP response cannot be fully decoded; it is of an unknown type.")
-
-ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119),
-"The OCSP server returned unexpected/invalid HTTP data.")
-
-ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120),
-"The OCSP server found the request to be corrupted or improperly formed.")
-
-ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121),
-"The OCSP server experienced an internal error.")
-
-ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122),
-"The OCSP server suggests trying again later.")
-
-ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123),
-"The OCSP server requires a signature on this request.")
-
-ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124),
-"The OCSP server has refused this request as unauthorized.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125),
-"The OCSP server returned an unrecognizable status.")
-
-ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126),
-"The OCSP server has no status for the certificate.")
-
-ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127),
-"You must enable OCSP before performing this operation.")
-
-ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128),
-"You must set the OCSP default responder before performing this operation.")
-
-ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129),
-"The response from the OCSP server was corrupted or improperly formed.")
-
-ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130),
-"The signer of the OCSP response is not authorized to give status for \
-this certificate.")
-
-ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131),
-"The OCSP response is not yet valid (contains a date in the future).")
-
-ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132),
-"The OCSP response contains out-of-date information.")
diff --git a/security/nss/cmd/SSLsample/SSLerrs.h b/security/nss/cmd/SSLsample/SSLerrs.h
deleted file mode 100644
index f502c523e..000000000
--- a/security/nss/cmd/SSLsample/SSLerrs.h
+++ /dev/null
@@ -1,369 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1994-2000
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* SSL-specific security error codes */
-/* caller must include "sslerr.h" */
-
-ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0,
-"Unable to communicate securely. Peer does not support high-grade encryption.")
-
-ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1,
-"Unable to communicate securely. Peer requires high-grade encryption which is not supported.")
-
-ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2,
-"Cannot communicate securely with peer: no common encryption algorithm(s).")
-
-ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3,
-"Unable to find the certificate or key necessary for authentication.")
-
-ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4,
-"Unable to communicate securely with peer: peers's certificate was rejected.")
-
-/* unused (SSL_ERROR_BASE + 5),*/
-
-ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6,
-"The server has encountered bad data from the client.")
-
-ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7,
-"The client has encountered bad data from the server.")
-
-ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8,
-"Unsupported certificate type.")
-
-ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9,
-"Peer using unsupported version of security protocol.")
-
-/* unused (SSL_ERROR_BASE + 10),*/
-
-ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11,
-"Client authentication failed: private key in key database does not match public key in certificate database.")
-
-ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12,
-"Unable to communicate securely with peer: requested domain name does not match the server's certificate.")
-
-/* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13),
- defined in sslerr.h
-*/
-
-ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14),
-"Peer only supports SSL version 2, which is locally disabled.")
-
-
-ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15),
-"SSL received a record with an incorrect Message Authentication Code.")
-
-ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16),
-"SSL peer reports incorrect Message Authentication Code.")
-
-ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17),
-"SSL peer cannot verify your certificate.")
-
-ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18),
-"SSL peer rejected your certificate as revoked.")
-
-ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19),
-"SSL peer rejected your certificate as expired.")
-
-ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20),
-"Cannot connect: SSL is disabled.")
-
-ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21),
-"Cannot connect: SSL peer is in another FORTEZZA domain.")
-
-
-ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22),
-"An unknown SSL cipher suite has been requested.")
-
-ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23),
-"No cipher suites are present and enabled in this program.")
-
-ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24),
-"SSL received a record with bad block padding.")
-
-ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25),
-"SSL received a record that exceeded the maximum permissible length.")
-
-ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26),
-"SSL attempted to send a record that exceeded the maximum permissible length.")
-
-/*
- * Received a malformed (too long or short or invalid content) SSL handshake.
- */
-ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27),
-"SSL received a malformed Hello Request handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28),
-"SSL received a malformed Client Hello handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29),
-"SSL received a malformed Server Hello handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30),
-"SSL received a malformed Certificate handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31),
-"SSL received a malformed Server Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32),
-"SSL received a malformed Certificate Request handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33),
-"SSL received a malformed Server Hello Done handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34),
-"SSL received a malformed Certificate Verify handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35),
-"SSL received a malformed Client Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36),
-"SSL received a malformed Finished handshake message.")
-
-/*
- * Received a malformed (too long or short) SSL record.
- */
-ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37),
-"SSL received a malformed Change Cipher Spec record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38),
-"SSL received a malformed Alert record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39),
-"SSL received a malformed Handshake record.")
-
-ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40),
-"SSL received a malformed Application Data record.")
-
-/*
- * Received an SSL handshake that was inappropriate for the state we're in.
- * E.g. Server received message from server, or wrong state in state machine.
- */
-ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41),
-"SSL received an unexpected Hello Request handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42),
-"SSL received an unexpected Client Hello handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43),
-"SSL received an unexpected Server Hello handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44),
-"SSL received an unexpected Certificate handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45),
-"SSL received an unexpected Server Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46),
-"SSL received an unexpected Certificate Request handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47),
-"SSL received an unexpected Server Hello Done handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
-"SSL received an unexpected Certificate Verify handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
-"SSL received an unexpected Cllient Key Exchange handshake message.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
-"SSL received an unexpected Finished handshake message.")
-
-/*
- * Received an SSL record that was inappropriate for the state we're in.
- */
-ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51),
-"SSL received an unexpected Change Cipher Spec record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52),
-"SSL received an unexpected Alert record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53),
-"SSL received an unexpected Handshake record.")
-
-ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54),
-"SSL received an unexpected Application Data record.")
-
-/*
- * Received record/message with unknown discriminant.
- */
-ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55),
-"SSL received a record with an unknown content type.")
-
-ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56),
-"SSL received a handshake message with an unknown message type.")
-
-ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57),
-"SSL received an alert record with an unknown alert description.")
-
-/*
- * Received an alert reporting what we did wrong. (more alerts above)
- */
-ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58),
-"SSL peer has closed this connection.")
-
-ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
-"SSL peer was not expecting a handshake message it received.")
-
-ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
-"SSL peer was unable to succesfully decompress an SSL record it received.")
-
-ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
-"SSL peer was unable to negotiate an acceptable set of security parameters.")
-
-ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62),
-"SSL peer rejected a handshake message for unacceptable content.")
-
-ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63),
-"SSL peer does not support certificates of the type it received.")
-
-ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64),
-"SSL peer had some unspecified issue with the certificate it received.")
-
-
-ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65),
-"SSL experienced a failure of its random number generator.")
-
-ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66),
-"Unable to digitally sign data required to verify your certificate.")
-
-ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67),
-"SSL was unable to extract the public key from the peer's certificate.")
-
-ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68),
-"Unspecified failure while processing SSL Server Key Exchange handshake.")
-
-ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69),
-"Unspecified failure while processing SSL Client Key Exchange handshake.")
-
-ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70),
-"Bulk data encryption algorithm failed in selected cipher suite.")
-
-ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71),
-"Bulk data decryption algorithm failed in selected cipher suite.")
-
-ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72),
-"Attempt to write encrypted data to underlying socket failed.")
-
-ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73),
-"MD5 digest function failed.")
-
-ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74),
-"SHA-1 digest function failed.")
-
-ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75),
-"MAC computation failed.")
-
-ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76),
-"Failure to create Symmetric Key context.")
-
-ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77),
-"Failure to unwrap the Symmetric key in Client Key Exchange message.")
-
-ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78),
-"SSL Server attempted to use domestic-grade public key with export cipher suite.")
-
-ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79),
-"PKCS11 code failed to translate an IV into a param.")
-
-ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80),
-"Failed to initialize the selected cipher suite.")
-
-ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81),
-"Client failed to generate session keys for SSL session.")
-
-ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82),
-"Server has no key for the attempted key exchange algorithm.")
-
-ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83),
-"PKCS#11 token was inserted or removed while operation was in progress.")
-
-ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84),
-"No PKCS#11 token could be found to do a required operation.")
-
-ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85),
-"Cannot communicate securely with peer: no common compression algorithm(s).")
-
-ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86),
-"Cannot initiate another SSL handshake until current handshake is complete.")
-
-ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87),
-"Received incorrect handshakes hash values from peer.")
-
-ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88),
-"The certificate provided cannot be used with the selected key exchange algorithm.")
-
-ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89),
-"No certificate authority is trusted for SSL client authentication.")
-
-ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90),
-"Client's SSL session ID not found in server's session cache.")
-
-ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91),
-"Peer was unable to decrypt an SSL record it received.")
-
-ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92),
-"Peer received an SSL record that was longer than is permitted.")
-
-ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93),
-"Peer does not recognize and trust the CA that issued your certificate.")
-
-ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94),
-"Peer received a valid certificate, but access was denied.")
-
-ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95),
-"Peer could not decode an SSL handshake message.")
-
-ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96),
-"Peer reports failure of signature verification or key exchange.")
-
-ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97),
-"Peer reports negotiation not in compliance with export regulations.")
-
-ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98),
-"Peer reports incompatible or unsupported protocol version.")
-
-ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99),
-"Server requires ciphers more secure than those supported by client.")
-
-ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100),
-"Peer reports it experienced an internal error.")
-
-ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101),
-"Peer user canceled handshake.")
-
-ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
-"Peer does not permit renegotiation of SSL security parameters.")
-
diff --git a/security/nss/cmd/SSLsample/client.mn b/security/nss/cmd/SSLsample/client.mn
index 4ede63e2d..064b7750f 100644
--- a/security/nss/cmd/SSLsample/client.mn
+++ b/security/nss/cmd/SSLsample/client.mn
@@ -46,9 +46,5 @@ CSRCS = client.c \
PROGRAM = client
-REQUIRES = dbm
-
IMPORTS = nss/lib/nss
-DEFINES = -DNSPR20
-
diff --git a/security/nss/cmd/SSLsample/server.mn b/security/nss/cmd/SSLsample/server.mn
index 50ec860c7..2c29b587b 100644
--- a/security/nss/cmd/SSLsample/server.mn
+++ b/security/nss/cmd/SSLsample/server.mn
@@ -46,7 +46,3 @@ CSRCS = server.c \
PROGRAM = server
-REQUIRES = dbm
-
-DEFINES = -DNSPR20
-
diff --git a/security/nss/cmd/addbuiltin/addbuiltin.c b/security/nss/cmd/addbuiltin/addbuiltin.c
index 94de6f490..8bb99547c 100644
--- a/security/nss/cmd/addbuiltin/addbuiltin.c
+++ b/security/nss/cmd/addbuiltin/addbuiltin.c
@@ -75,11 +75,13 @@ char *getTrustString(unsigned int trust)
} else {
if (trust & CERTDB_TRUSTED_CA) {
return "CKT_NETSCAPE_TRUSTED_DELEGATOR";
+ } else if (trust & CERTDB_VALID_CA) {
+ return "CKT_NETSCAPE_VALID_DELEGATOR";
} else {
- return "CKT_NETSCAPE_VALID";
+ return "CKT_NETSCAPE_TRUST_UNKNOWN";
}
}
- return "CKT_NETSCAPE_VALID"; /* not reached */
+ return "CKT_NETSCAPE_TRUST_UNKNOWN"; /* not reached */
}
static const SEC_ASN1Template serialTemplate[] = {
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c
index 72182a127..0f3fe8e48 100644
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -184,7 +184,7 @@ static void Usage()
PRINTUSAGE("", "", " sect233r1, nistb233, sect239k1, sect283k1, nistk283,");
PRINTUSAGE("", "", " sect283r1, nistb283, sect409k1, nistk409, sect409r1,");
PRINTUSAGE("", "", " nistb409, sect571k1, nistk571, sect571r1, nistb571,");
- PRINTUSAGE("", "", " secp169k1, secp160r1, secp160r2, secp192k1, secp192r1,");
+ PRINTUSAGE("", "", " secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,");
PRINTUSAGE("", "", " nistp192, secp224k1, secp224r1, nistp224, secp256k1,");
PRINTUSAGE("", "", " secp256r1, nistp256, secp384r1, nistp384, secp521r1,");
PRINTUSAGE("", "", " nistp521, prime192v1, prime192v2, prime192v3,");
@@ -2499,9 +2499,12 @@ print_td:
case bltestECDSA:
if (td)
fprintf(stdout, "%12s", "ec_curve");
- else
+ else {
+ ECCurveName curveName = info->params.ecdsa.eckey->ecParams.name;
fprintf(stdout, "%12s",
- ecCurve_map[info->params.ecdsa.eckey->ecParams.name]->text);
+ ecCurve_map[curveName]? ecCurve_map[curveName]->text:
+ "Unsupported curve");
+ }
break;
#endif
case bltestMD2:
diff --git a/security/nss/cmd/certutil/certutil.c b/security/nss/cmd/certutil/certutil.c
index d9a82bfd9..609ef823b 100644
--- a/security/nss/cmd/certutil/certutil.c
+++ b/security/nss/cmd/certutil/certutil.c
@@ -70,7 +70,8 @@
#include "nss.h"
#define MIN_KEY_BITS 512
-#define MAX_KEY_BITS 2048
+/* MAX_KEY_BITS should agree with MAX_RSA_MODULUS in freebl */
+#define MAX_KEY_BITS 8192
#define DEFAULT_KEY_BITS 1024
#define GEN_BREAK(e) rv=e; break;
@@ -762,6 +763,9 @@ ValidateCert(CERTCertDBHandle *handle, char *name, char *date,
}
switch (*certUsage) {
+ case 'O':
+ usage = certificateUsageStatusResponder;
+ break;
case 'C':
usage = certificateUsageSSLClient;
break;
@@ -993,6 +997,7 @@ Usage(char *progName)
FPS "Usage: %s -T [-d certdir] [-P dbprefix] [-h token-name] [-f pwfile]\n", progName);
FPS "\t%s -A -n cert-name -t trustargs [-d certdir] [-P dbprefix] [-a] [-i input]\n",
progName);
+ FPS "\t%s -B -i batch-file\n", progName);
FPS "\t%s -C [-c issuer-name | -x] -i cert-request-file -o cert-file\n"
"\t\t [-m serial-number] [-w warp-months] [-v months-valid]\n"
"\t\t [-f pwfile] [-d certdir] [-P dbprefix] [-1] [-2] [-3] [-4] [-5]\n"
@@ -1041,6 +1046,9 @@ static void LongUsage(char *progName)
FPS "%-15s Add a certificate to the database (create if needed)\n",
"-A");
+ FPS "%-20s\n", " All options under -E apply");
+ FPS "%-15s Run a series of certutil commands from a batch file\n", "-B");
+ FPS "%-20s Specify the batch file\n", " -i batch-file");
FPS "%-15s Add an Email certificate to the database (create if needed)\n",
"-E");
FPS "%-20s Specify the nickname of the certificate to add\n",
@@ -1133,23 +1141,26 @@ static void LongUsage(char *progName)
#ifdef NSS_ENABLE_ECC
FPS "%-20s Elliptic curve name (ec only)\n",
" -q curve-name");
- FPS "%-20s One of sect163k1, nistk163, sect163r1, sect163r2,\n", "");
+ FPS "%-20s One of nistp256, nistp384, nistp521\n", "");
+#ifdef NSS_ECC_MORE_THAN_SUITE_B
+ FPS "%-20s sect163k1, nistk163, sect163r1, sect163r2,\n", "");
FPS "%-20s nistb163, sect193r1, sect193r2, sect233k1, nistk233,\n", "");
FPS "%-20s sect233r1, nistb233, sect239k1, sect283k1, nistk283,\n", "");
FPS "%-20s sect283r1, nistb283, sect409k1, nistk409, sect409r1,\n", "");
FPS "%-20s nistb409, sect571k1, nistk571, sect571r1, nistb571,\n", "");
- FPS "%-20s secp169k1, secp160r1, secp160r2, secp192k1, secp192r1,\n", "");
+ FPS "%-20s secp160k1, secp160r1, secp160r2, secp192k1, secp192r1,\n", "");
FPS "%-20s nistp192, secp224k1, secp224r1, nistp224, secp256k1,\n", "");
- FPS "%-20s secp256r1, nistp256, secp384r1, nistp384, secp521r1,\n", "");
- FPS "%-20s nistp521, prime192v1, prime192v2, prime192v3, \n", "");
+ FPS "%-20s secp256r1, secp384r1, secp521r1,\n", "");
+ FPS "%-20s prime192v1, prime192v2, prime192v3, \n", "");
FPS "%-20s prime239v1, prime239v2, prime239v3, c2pnb163v1, \n", "");
FPS "%-20s c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1, \n", "");
- FPS "%-20s c2tnb191v2, c2tnb191v3, c2onb191v4, c2onb191v5, \n", "");
+ FPS "%-20s c2tnb191v2, c2tnb191v3, \n", "");
FPS "%-20s c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, \n", "");
- FPS "%-20s c2onb239v4, c2onb239v5, c2pnb272w1, c2pnb304w1, \n", "");
+ FPS "%-20s c2pnb272w1, c2pnb304w1, \n", "");
FPS "%-20s c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, \n", "");
FPS "%-20s secp112r2, secp128r1, secp128r2, sect113r1, sect113r2\n", "");
FPS "%-20s sect131r1, sect131r2\n", "");
+#endif /* NSS_ECC_MORE_THAN_SUITE_B */
#endif
FPS "%-20s Key database directory (default is ~/.netscape)\n",
" -d keydir");
@@ -1292,6 +1303,8 @@ static void LongUsage(char *progName)
" -p phone");
FPS "%-20s Output the cert request in ASCII (RFC1113); default is binary\n",
" -a");
+ FPS "%-20s \n",
+ " See -S for available extension options");
FPS "\n");
FPS "%-15s Validate a certificate\n",
@@ -1307,6 +1320,7 @@ static void LongUsage(char *progName)
FPS "%-25s V \t SSL Server\n", "");
FPS "%-25s S \t Email signer\n", "");
FPS "%-25s R \t Email Recipient\n", "");
+ FPS "%-25s O \t OCSP status responder\n", "");
FPS "%-20s Cert database directory (default is ~/.netscape)\n",
" -d certdir");
FPS "%-20s Cert & Key database prefix\n",
@@ -1390,7 +1404,7 @@ MakeV1Cert( CERTCertDBHandle * handle,
PRBool selfsign,
unsigned int serialNumber,
int warpmonths,
- int validitylength)
+ int validityMonths)
{
CERTCertificate *issuerCert = NULL;
CERTValidity *validity;
@@ -1414,19 +1428,19 @@ MakeV1Cert( CERTCertDBHandle * handle,
now = PR_ImplodeTime (&printableTime);
PR_ExplodeTime (now, PR_GMTParameters, &printableTime);
}
- printableTime.tm_month += validitylength;
- printableTime.tm_month += 3;
+ printableTime.tm_month += validityMonths;
after = PR_ImplodeTime (&printableTime);
/* note that the time is now in micro-second unit */
validity = CERT_CreateValidity (now, after);
-
- cert = CERT_CreateCertificate(serialNumber,
+ if (validity) {
+ cert = CERT_CreateCertificate(serialNumber,
(selfsign ? &req->subject
: &issuerCert->subject),
validity, req);
- CERT_DestroyValidity(validity);
+ CERT_DestroyValidity(validity);
+ }
if ( issuerCert ) {
CERT_DestroyCertificate (issuerCert);
}
@@ -1561,7 +1575,7 @@ AddOidToSequence(CERTOidSequence *os, SECOidTag oidTag)
return SECSuccess;
}
-SEC_ASN1_MKSUB(SEC_ObjectIDTemplate);
+SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
const SEC_ASN1Template CERT_OidSeqTemplate[] = {
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_XTRN,
@@ -2189,7 +2203,7 @@ CreateCert(
SECOidTag hashAlgTag,
unsigned int serialNumber,
int warpmonths,
- int validitylength,
+ int validityMonths,
const char *emailAddrs,
const char *dnsNames,
PRBool ascii,
@@ -2224,7 +2238,7 @@ CreateCert(
}
subjectCert = MakeV1Cert (handle, certReq, issuerNickName, selfsign,
- serialNumber, warpmonths, validitylength);
+ serialNumber, warpmonths, validityMonths);
if (subjectCert == NULL) {
GEN_BREAK (SECFailure)
}
@@ -2302,7 +2316,8 @@ enum {
cmd_ListModules,
cmd_CheckCertValidity,
cmd_ChangePassword,
- cmd_Version
+ cmd_Version,
+ cmd_Batch
};
/* Certutil options */
@@ -2344,8 +2359,7 @@ enum {
opt_RW,
opt_Exponent,
opt_NoiseFile,
- opt_Hash,
- opt_Batch
+ opt_Hash
};
static int
@@ -2367,11 +2381,12 @@ certutil_main(int argc, char **argv, PRBool initialize)
int publicExponent = 0x010001;
unsigned int serialNumber = 0;
int warpmonths = 0;
- int validitylength = 0;
+ int validityMonths = 3;
int commandsEntered = 0;
char commandToRun = '\0';
secuPWData pwdata = { PW_NONE, 0 };
PRBool readOnly = PR_FALSE;
+ PRBool initialized = PR_FALSE;
SECKEYPrivateKey *privkey = NULL;
SECKEYPublicKey *pubkey = NULL;
@@ -2401,7 +2416,8 @@ secuCommandFlag certutil_commands[] =
{ /* cmd_ListModules */ 'U', PR_FALSE, 0, PR_FALSE },
{ /* cmd_CheckCertValidity */ 'V', PR_FALSE, 0, PR_FALSE },
{ /* cmd_ChangePassword */ 'W', PR_FALSE, 0, PR_FALSE },
- { /* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE }
+ { /* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE },
+ { /* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE }
};
secuCommandFlag certutil_options[] =
@@ -2443,8 +2459,7 @@ secuCommandFlag certutil_options[] =
{ /* opt_RW */ 'X', PR_FALSE, 0, PR_FALSE },
{ /* opt_Exponent */ 'y', PR_TRUE, 0, PR_FALSE },
{ /* opt_NoiseFile */ 'z', PR_TRUE, 0, PR_FALSE },
- { /* opt_Hash */ 'Z', PR_TRUE, 0, PR_FALSE },
- { /* opt_Batch */ 'B', PR_TRUE, 0, PR_FALSE }
+ { /* opt_Hash */ 'Z', PR_TRUE, 0, PR_FALSE }
};
@@ -2576,8 +2591,8 @@ secuCommandFlag certutil_options[] =
/* -v validity period */
if (certutil.options[opt_Validity].activated) {
- validitylength = PORT_Atoi(certutil.options[opt_Validity].arg);
- if (validitylength < 0) {
+ validityMonths = PORT_Atoi(certutil.options[opt_Validity].arg);
+ if (validityMonths < 0) {
PR_fprintf(PR_STDERR, "%s -v: incorrect validity period: \"%s\"\n",
progName, certutil.options[opt_Validity].arg);
return 255;
@@ -2801,6 +2816,7 @@ secuCommandFlag certutil_options[] =
rv = SECFailure;
goto shutdown;
}
+ initialized = PR_TRUE;
SECU_RegisterDynamicOids();
}
certHandle = CERT_GetDefaultCertDB();
@@ -2813,6 +2829,21 @@ secuCommandFlag certutil_options[] =
slot = PK11_GetInternalKeySlot();
else if (slotname != NULL)
slot = PK11_FindSlotByName(slotname);
+
+ if ( !slot && (certutil.commands[cmd_NewDBs].activated ||
+ certutil.commands[cmd_ModifyCertTrust].activated ||
+ certutil.commands[cmd_ChangePassword].activated ||
+ certutil.commands[cmd_TokenReset].activated ||
+ certutil.commands[cmd_CreateAndAddCert].activated ||
+ certutil.commands[cmd_AddCert].activated ||
+ certutil.commands[cmd_AddEmailCert].activated)) {
+
+ SECU_PrintError(progName, "could not find the slot %s",slotname);
+ rv = SECFailure;
+ goto shutdown;
+ }
+
+
/* If creating new database, initialize the password. */
if (certutil.commands[cmd_NewDBs].activated) {
@@ -2994,7 +3025,7 @@ secuCommandFlag certutil_options[] =
rv = CreateCert(certHandle,
certutil.options[opt_IssuerName].arg,
inFile, outFile, privkey, &pwdata, hashAlgTag,
- serialNumber, warpmonths, validitylength,
+ serialNumber, warpmonths, validityMonths,
certutil.options[opt_ExtendedEmailAddrs].arg,
certutil.options[opt_ExtendedDNSNames].arg,
certutil.options[opt_ASCIIForIO].activated,
@@ -3074,13 +3105,21 @@ shutdown:
* - each line in the batch file is limited to 512 characters
*/
- if ((SECSuccess == rv) && certutil.options[opt_Batch].activated) {
- FILE* batchFile = fopen(certutil.options[opt_Batch].arg, "r");
+ if ((SECSuccess == rv) && certutil.commands[cmd_Batch].activated) {
+ FILE* batchFile = NULL;
char nextcommand[512];
+ if (!certutil.options[opt_InputFile].activated ||
+ !certutil.options[opt_InputFile].arg) {
+ PR_fprintf(PR_STDERR,
+ "%s: no batch input file specified.\n",
+ progName);
+ return 255;
+ }
+ batchFile = fopen(certutil.options[opt_InputFile].arg, "r");
if (!batchFile) {
PR_fprintf(PR_STDERR,
"%s: unable to open \"%s\" for reading (%ld, %ld).\n",
- progName, certutil.options[opt_Batch].arg,
+ progName, certutil.options[opt_InputFile].arg,
PR_GetError(), PR_GetOSError());
return 255;
}
@@ -3144,7 +3183,7 @@ shutdown:
fclose(batchFile);
}
- if ((initialize == PR_TRUE) && NSS_Shutdown() != SECSuccess) {
+ if ((initialized == PR_TRUE) && NSS_Shutdown() != SECSuccess) {
exit(1);
}
diff --git a/security/nss/cmd/crlutil/crlgen.c b/security/nss/cmd/crlutil/crlgen.c
index 15e542cac..e0d525e3b 100644
--- a/security/nss/cmd/crlutil/crlgen.c
+++ b/security/nss/cmd/crlutil/crlgen.c
@@ -1,35 +1,38 @@
-/*
- * The contents of this file are subject to the Maxilla 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.
- *
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
* The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
* Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of 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.
- */
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
/*
** crlgen.c
diff --git a/security/nss/cmd/crlutil/crlutil.c b/security/nss/cmd/crlutil/crlutil.c
index ab066c33a..9d164a4c8 100644
--- a/security/nss/cmd/crlutil/crlutil.c
+++ b/security/nss/cmd/crlutil/crlutil.c
@@ -62,19 +62,47 @@ static CERTSignedCrl *FindCRL
{
CERTSignedCrl *crl = NULL;
CERTCertificate *cert = NULL;
+ SECItem derName;
+ derName.data = NULL;
+ derName.len = 0;
- cert = CERT_FindCertByNickname(certHandle, name);
+ cert = CERT_FindCertByNicknameOrEmailAddr(certHandle, name);
if (!cert) {
- SECU_PrintError(progName, "could not find certificate named %s", name);
- return ((CERTSignedCrl *)NULL);
+ CERTName *certName = NULL;
+ PRArenaPool *arena = NULL;
+
+ certName = CERT_AsciiToName(name);
+ if (certName) {
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena) {
+ SECItem *nameItem =
+ SEC_ASN1EncodeItem (arena, NULL, (void *)certName,
+ SEC_ASN1_GET(CERT_NameTemplate));
+ if (nameItem) {
+ SECITEM_CopyItem(NULL, &derName, nameItem);
+ }
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ CERT_DestroyName(certName);
+ }
+
+ if (!derName.len || !derName.data) {
+ SECU_PrintError(progName, "could not find certificate named '%s'", name);
+ return ((CERTSignedCrl *)NULL);
+ }
+ } else {
+ SECITEM_CopyItem(NULL, &derName, &cert->derSubject);
+ CERT_DestroyCertificate (cert);
}
-
- crl = SEC_FindCrlByName(certHandle, &cert->derSubject, type);
+
+ crl = SEC_FindCrlByName(certHandle, &derName, type);
if (crl ==NULL)
SECU_PrintError
(progName, "could not find %s's CRL", name);
- CERT_DestroyCertificate (cert);
+ if (derName.data) {
+ SECITEM_FreeItem(&derName, PR_FALSE);
+ }
return (crl);
}
@@ -128,16 +156,39 @@ static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool dele
fprintf (stdout, "\n");
fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
while (crlNode) {
- char* asciiname = NULL;
- name = &crlNode->crl->crl.name;
- if (!name){
- fprintf(stderr, "%s: fail to get the CRL issuer name (%s)\n", progName,
- SECU_Strerror(PORT_GetError()));
- break;
+ char* asciiname = NULL;
+ CERTCertificate *cert = NULL;
+ if (crlNode->crl && &crlNode->crl->crl.derName) {
+ cert = CERT_FindCertByName(certHandle,
+ &crlNode->crl->crl.derName);
+ if (!cert) {
+ SECU_PrintError(progName, "could not find signing "
+ "certificate in database");
+ }
}
-
- asciiname = CERT_NameToAscii(name);
- fprintf (stdout, "\n%-40s %-5s\n", asciiname, "CRL");
+ if (cert) {
+ char* certName = NULL;
+ if (cert->nickname && PORT_Strlen(cert->nickname) > 0) {
+ certName = cert->nickname;
+ } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr) > 0) {
+ certName = cert->emailAddr;
+ }
+ if (certName) {
+ asciiname = PORT_Strdup(certName);
+ }
+ CERT_DestroyCertificate(cert);
+ }
+
+ if (!asciiname) {
+ name = &crlNode->crl->crl.name;
+ if (!name){
+ SECU_PrintError(progName, "fail to get the CRL "
+ "issuer name");
+ continue;
+ }
+ asciiname = CERT_NameToAscii(name);
+ }
+ fprintf (stdout, "%-40s %-5s\n", asciiname, "CRL");
if (asciiname) {
PORT_Free(asciiname);
}
@@ -300,7 +351,7 @@ FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl,
}
static CERTSignedCrl*
-DuplicateModCrl(PRArenaPool *arena, CERTCertDBHandle *certHandle,
+CreateModifiedCRLCopy(PRArenaPool *arena, CERTCertDBHandle *certHandle,
CERTCertificate **cert, char *certNickName,
PRFileDesc *inFile, PRInt32 decodeOptions,
PRInt32 importOptions)
@@ -314,7 +365,7 @@ DuplicateModCrl(PRArenaPool *arena, CERTCertDBHandle *certHandle,
PORT_Assert(arena != NULL && certHandle != NULL &&
certNickName != NULL);
if (!arena || !certHandle || !certNickName) {
- SECU_PrintError(progName, "DuplicateModCrl: invalid args\n");
+ SECU_PrintError(progName, "CreateModifiedCRLCopy: invalid args\n");
return NULL;
}
@@ -378,7 +429,15 @@ DuplicateModCrl(PRArenaPool *arena, CERTCertDBHandle *certHandle,
goto loser;
}
- signCrl->arena = arena;
+ /* Make sure the update time is current. It can be modified later
+ * by "update <time>" command from crl generation script */
+ rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now());
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "fail to encode current time\n");
+ goto loser;
+ }
+
+ signCrl->arena = arena;
loser:
SECITEM_FreeItem(&crlDER, PR_FALSE);
@@ -624,7 +683,7 @@ GenerateCRL (CERTCertDBHandle *certHandle, char *certNickName,
}
if (modifyFlag == PR_TRUE) {
- signCrl = DuplicateModCrl(arena, certHandle, &cert, certNickName,
+ signCrl = CreateModifiedCRLCopy(arena, certHandle, &cert, certNickName,
inFile, decodeOptions, importOptions);
if (signCrl == NULL) {
goto loser;
diff --git a/security/nss/cmd/dbck/Makefile b/security/nss/cmd/dbck/Makefile
index 834e1d62f..b9915d5e2 100644
--- a/security/nss/cmd/dbck/Makefile
+++ b/security/nss/cmd/dbck/Makefile
@@ -68,7 +68,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
-
+INCLUDES += -I ../../lib/softoken
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
diff --git a/security/nss/cmd/dbck/dbck.c b/security/nss/cmd/dbck/dbck.c
index 2ff736268..a1bba5b0e 100644
--- a/security/nss/cmd/dbck/dbck.c
+++ b/security/nss/cmd/dbck/dbck.c
@@ -51,6 +51,8 @@
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"
+#include "pcert.h"
+#include "nss.h"
static char *progName;
@@ -59,6 +61,46 @@ static void *WrongEntry;
static void *NoNickname;
static void *NoSMime;
+typedef enum {
+/* 0*/ NoSubjectForCert = 0,
+/* 1*/ SubjectHasNoKeyForCert,
+/* 2*/ NoNicknameOrSMimeForSubject,
+/* 3*/ WrongNicknameForSubject,
+/* 4*/ NoNicknameEntry,
+/* 5*/ WrongSMimeForSubject,
+/* 6*/ NoSMimeEntry,
+/* 7*/ NoSubjectForNickname,
+/* 8*/ NoSubjectForSMime,
+/* 9*/ NicknameAndSMimeEntries,
+ NUM_ERROR_TYPES
+} dbErrorType;
+
+static char *dbErrorString[NUM_ERROR_TYPES] = {
+/* 0*/ "<CERT ENTRY>\nDid not find a subject entry for this certificate.",
+/* 1*/ "<SUBJECT ENTRY>\nSubject has certKey which is not in db.",
+/* 2*/ "<SUBJECT ENTRY>\nSubject does not have a nickname or email address.",
+/* 3*/ "<SUBJECT ENTRY>\nUsing this subject's nickname, found a nickname entry for a different subject.",
+/* 4*/ "<SUBJECT ENTRY>\nDid not find a nickname entry for this subject.",
+/* 5*/ "<SUBJECT ENTRY>\nUsing this subject's email, found an S/MIME entry for a different subject.",
+/* 6*/ "<SUBJECT ENTRY>\nDid not find an S/MIME entry for this subject.",
+/* 7*/ "<NICKNAME ENTRY>\nDid not find a subject entry for this nickname.",
+/* 8*/ "<S/MIME ENTRY>\nDid not find a subject entry for this S/MIME profile.",
+};
+
+static char *errResult[NUM_ERROR_TYPES] = {
+ "Certificate entries that had no subject entry.",
+ "Subject entries with no corresponding Certificate entries.",
+ "Subject entries that had no nickname or S/MIME entries.",
+ "Redundant nicknames (subjects with the same nickname).",
+ "Subject entries that had no nickname entry.",
+ "Redundant email addresses (subjects with the same email address).",
+ "Subject entries that had no S/MIME entry.",
+ "Nickname entries that had no subject entry.",
+ "S/MIME entries that had no subject entry.",
+ "Subject entries with BOTH nickname and S/MIME entries."
+};
+
+
enum {
GOBOTH = 0,
GORIGHT,
@@ -71,9 +113,16 @@ typedef struct
PRBool dograph;
PRFileDesc *out;
PRFileDesc *graphfile;
- int dbErrors[10];
+ int dbErrors[NUM_ERROR_TYPES];
} dbDebugInfo;
+struct certDBEntryListNodeStr {
+ PRCList link;
+ certDBEntry entry;
+ void *appData;
+};
+typedef struct certDBEntryListNodeStr certDBEntryListNode;
+
/*
* A list node for a cert db entry. The index is a unique identifier
* to use for creating generic maps of a db. This struct handles
@@ -113,10 +162,12 @@ typedef struct
int numSubjects;
int numNicknames;
int numSMime;
+ int numRevocation;
certDBEntryListNode certs; /* pointer to head of cert list */
certDBEntryListNode subjects; /* pointer to head of subject list */
certDBEntryListNode nicknames; /* pointer to head of nickname list */
certDBEntryListNode smime; /* pointer to head of smime list */
+ certDBEntryListNode revocation; /* pointer to head of revocation list */
} certDBArray;
/* Cast list to the base element, a certDBEntryListNode. */
@@ -128,10 +179,12 @@ Usage(char *progName)
{
#define FPS fprintf(stderr,
FPS "Type %s -H for more detailed descriptions\n", progName);
- FPS "Usage: %s -D [-d certdir] [-i dbname] [-m] [-v [-f dumpfile]]\n",
+ FPS "Usage: %s -D [-d certdir] [-m] [-v [-f dumpfile]]\n",
progName);
- FPS " %s -R -o newdbname [-d certdir] [-i dbname] [-aprsx] [-v [-f dumpfile]]\n",
+#ifdef DORECOVER
+ FPS " %s -R -o newdbname [-d certdir] [-aprsx] [-v [-f dumpfile]]\n",
progName);
+#endif
exit(-1);
}
@@ -144,18 +197,13 @@ LongUsage(char *progName)
"-D");
FPS "%-15s Cert database directory (default is ~/.netscape)\n",
" -d certdir");
- FPS "%-15s Input cert database name (default is cert7.db)\n",
- " -i dbname");
- FPS "%-15s Mail a graph of the database to certdb@netscape.com.\n",
+ FPS "%-15s Put database graph in ./mailfile (default is stdout).\n",
" -m");
- FPS "%-15s This will produce an index graph of your cert db and send\n",
- "");
- FPS "%-15s it to Netscape for analysis. Personal info will be removed.\n",
- "");
- FPS "%-15s Verbose mode. Dumps the entire contents of your cert7.db.\n",
+ FPS "%-15s Verbose mode. Dumps the entire contents of your cert8.db.\n",
" -v");
- FPS "%-15s File to dump verbose output into.\n",
+ FPS "%-15s File to dump verbose output into. (default is stdout)\n",
" -f dumpfile");
+#ifdef DORECOVER
FPS "%-15s Repair the database. The program will look for broken\n",
"-R");
FPS "%-15s dependencies between subject entries and certificates,\n",
@@ -166,12 +214,10 @@ LongUsage(char *progName)
"");
FPS "%-15s removed, any missing entries will be created.\n",
"");
- FPS "%-15s File to store new database in (default is new_cert7.db)\n",
+ FPS "%-15s File to store new database in (default is new_cert8.db)\n",
" -o newdbname");
FPS "%-15s Cert database directory (default is ~/.netscape)\n",
" -d certdir");
- FPS "%-15s Input cert database name (default is cert7.db)\n",
- " -i dbname");
FPS "%-15s Prompt before removing any certificates.\n",
" -p");
FPS "%-15s Keep all possible certificates. Only remove certificates\n",
@@ -195,6 +241,7 @@ LongUsage(char *progName)
FPS "%-15s File to dump verbose output into.\n",
" -f dumpfile");
FPS "\n");
+#endif
exit(-1);
#undef FPS
}
@@ -208,7 +255,7 @@ LongUsage(char *progName)
void
printHexString(PRFileDesc *out, SECItem *hexval)
{
- int i;
+ unsigned int i;
for (i = 0; i < hexval->len; i++) {
if (i != hexval->len - 1) {
PR_fprintf(out, "%02x:", hexval->data[i]);
@@ -219,30 +266,6 @@ printHexString(PRFileDesc *out, SECItem *hexval)
PR_fprintf(out, "\n");
}
-typedef enum {
-/* 0*/ NoSubjectForCert = 0,
-/* 1*/ SubjectHasNoKeyForCert,
-/* 2*/ NoNicknameOrSMimeForSubject,
-/* 3*/ WrongNicknameForSubject,
-/* 4*/ NoNicknameEntry,
-/* 5*/ WrongSMimeForSubject,
-/* 6*/ NoSMimeEntry,
-/* 7*/ NoSubjectForNickname,
-/* 8*/ NoSubjectForSMime,
-/* 9*/ NicknameAndSMimeEntry
-} dbErrorType;
-
-static char *dbErrorString[] = {
-/* 0*/ "<CERT ENTRY>\nDid not find a subject entry for this certificate.",
-/* 1*/ "<SUBJECT ENTRY>\nSubject has certKey which is not in db.",
-/* 2*/ "<SUBJECT ENTRY>\nSubject does not have a nickname or email address.",
-/* 3*/ "<SUBJECT ENTRY>\nUsing this subject's nickname, found a nickname entry for a different subject.",
-/* 4*/ "<SUBJECT ENTRY>\nDid not find a nickname entry for this subject.",
-/* 5*/ "<SUBJECT ENTRY>\nUsing this subject's email, found an S/MIME entry for a different subject.",
-/* 6*/ "<SUBJECT ENTRY>\nDid not find an S/MIME entry for this subject.",
-/* 7*/ "<NICKNAME ENTRY>\nDid not find a subject entry for this nickname.",
-/* 8*/ "<S/MIME ENTRY>\nDid not find a subject entry for this S/MIME profile.",
-};
SECStatus
dumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile)
@@ -285,13 +308,20 @@ dumpCertificate(CERTCertificate *cert, int num, PRFileDesc *outfile)
SECStatus
dumpCertEntry(certDBEntryCert *entry, int num, PRFileDesc *outfile)
{
+#if 0
+ NSSLOWCERTCertificate *cert;
+ /* should we check for existing duplicates? */
+ cert = nsslowcert_DecodeDERCertificate(&entry->cert.derCert,
+ entry->cert.nickname);
+#else
CERTCertificate *cert;
cert = CERT_DecodeDERCertificate(&entry->derCert, PR_FALSE, NULL);
+#endif
if (!cert) {
fprintf(stderr, "Failed to decode certificate.\n");
return SECFailure;
}
- cert->trust = &entry->trust;
+ cert->trust = (CERTCertTrust *)&entry->trust;
dumpCertificate(cert, num, outfile);
CERT_DestroyCertificate(cert);
return SECSuccess;
@@ -300,16 +330,23 @@ dumpCertEntry(certDBEntryCert *entry, int num, PRFileDesc *outfile)
SECStatus
dumpSubjectEntry(certDBEntrySubject *entry, int num, PRFileDesc *outfile)
{
- char *subjectName;
- subjectName = CERT_DerNameToAscii(&entry->derSubject);
+ char *subjectName = CERT_DerNameToAscii(&entry->derSubject);
+
PR_fprintf(outfile, "Subject: %3d\n", num);
PR_fprintf(outfile, "------------\n");
PR_fprintf(outfile, "## %s\n", subjectName);
if (entry->nickname)
PR_fprintf(outfile, "## Subject nickname: %s\n", entry->nickname);
- if (entry->emailAddr && entry->emailAddr[0])
- PR_fprintf(outfile, "## Subject email address: %s\n",
- entry->emailAddr);
+ if (entry->emailAddrs) {
+ unsigned int n;
+ for (n = 0; n < entry->nemailAddrs && entry->emailAddrs[n]; ++n) {
+ char * emailAddr = entry->emailAddrs[n];
+ if (emailAddr[0]) {
+ PR_fprintf(outfile, "## Subject email address: %s\n",
+ emailAddr);
+ }
+ }
+ }
PR_fprintf(outfile, "## This subject has %d cert(s).\n", entry->ncerts);
PR_fprintf(outfile, "\n");
PORT_Free(subjectName);
@@ -331,10 +368,18 @@ dumpSMimeEntry(certDBEntrySMime *entry, int num, PRFileDesc *outfile)
PR_fprintf(outfile, "S/MIME Profile: %3d\n", num);
PR_fprintf(outfile, "-------------------\n");
PR_fprintf(outfile, "## \"%s\"\n", entry->emailAddr);
+#ifdef OLDWAY
PR_fprintf(outfile, "## OPTIONS: ");
printHexString(outfile, &entry->smimeOptions);
PR_fprintf(outfile, "## TIMESTAMP: ");
printHexString(outfile, &entry->optionsDate);
+#else
+ SECU_PrintAny(stdout, &entry->smimeOptions, "## OPTIONS ", 0);
+ fflush(stdout);
+ if (entry->optionsDate.len && entry->optionsDate.data)
+ PR_fprintf(outfile, "## TIMESTAMP: %.*s\n",
+ entry->optionsDate.len, entry->optionsDate.data);
+#endif
PR_fprintf(outfile, "\n");
return SECSuccess;
}
@@ -351,7 +396,6 @@ mapCertEntries(certDBArray *dbArray)
SECItem derSubject;
SECItem certKey;
PRCList *cElem, *sElem;
- int i;
/* Arena for decoded entries */
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -377,6 +421,7 @@ mapCertEntries(certDBArray *dbArray)
subjNode = LISTNODE_CAST(sElem);
subjectEntry = (certDBEntrySubject *)&subjNode->entry;
if (SECITEM_ItemsAreEqual(&derSubject, &subjectEntry->derSubject)) {
+ unsigned int i;
/* Found matching subject name, create link. */
map->pSubject = subjNode;
/* Make sure subject entry has cert's key. */
@@ -400,12 +445,9 @@ SECStatus
mapSubjectEntries(certDBArray *dbArray)
{
certDBEntrySubject *subjectEntry;
- certDBEntryNickname *nicknameEntry;
- certDBEntrySMime *smimeEntry;
- certDBEntryListNode *subjNode, *nickNode, *smimeNode;
+ certDBEntryListNode *subjNode;
certDBSubjectEntryMap *subjMap;
- certDBEntryMap *nickMap, *smimeMap;
- PRCList *sElem, *nElem, *mElem;
+ PRCList *sElem;
for (sElem = PR_LIST_HEAD(&dbArray->subjects.link);
sElem != &dbArray->subjects.link; sElem = PR_NEXT_LINK(sElem)) {
@@ -420,57 +462,73 @@ mapSubjectEntries(certDBArray *dbArray)
subjMap->pCerts = PORT_ArenaAlloc(subjMap->arena,
subjectEntry->ncerts*sizeof(int));
subjMap->numCerts = subjectEntry->ncerts;
+ subjMap->pNickname = NoNickname;
+ subjMap->pSMime = NoSMime;
+
if (subjectEntry->nickname) {
/* Subject should have a nickname entry, so create a link. */
+ PRCList *nElem;
for (nElem = PR_LIST_HEAD(&dbArray->nicknames.link);
nElem != &dbArray->nicknames.link;
nElem = PR_NEXT_LINK(nElem)) {
+ certDBEntryListNode *nickNode;
+ certDBEntryNickname *nicknameEntry;
/* Look for subject's nickname in nickname entries. */
nickNode = LISTNODE_CAST(nElem);
nicknameEntry = (certDBEntryNickname *)&nickNode->entry;
- nickMap = (certDBEntryMap *)nickNode->appData;
if (PL_strcmp(subjectEntry->nickname,
nicknameEntry->nickname) == 0) {
/* Found a nickname entry for subject's nickname. */
if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
&nicknameEntry->subjectName)) {
+ certDBEntryMap *nickMap;
+ nickMap = (certDBEntryMap *)nickNode->appData;
/* Nickname and subject match. */
subjMap->pNickname = nickNode;
nickMap->pSubject = subjNode;
- } else {
+ } else if (subjMap->pNickname == NoNickname) {
/* Nickname entry found is for diff. subject. */
subjMap->pNickname = WrongEntry;
}
}
}
- } else {
- subjMap->pNickname = NoNickname;
- }
- if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
- /* Subject should have an smime entry, so create a link. */
- for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
- mElem != &dbArray->smime.link; mElem = PR_NEXT_LINK(mElem)) {
- /* Look for subject's email in S/MIME entries. */
- smimeNode = LISTNODE_CAST(mElem);
- smimeEntry = (certDBEntrySMime *)&smimeNode->entry;
- smimeMap = (certDBEntryMap *)smimeNode->appData;
- if (PL_strcmp(subjectEntry->emailAddr,
- smimeEntry->emailAddr) == 0) {
- /* Found a S/MIME entry for subject's email. */
- if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
- &smimeEntry->subjectName)) {
- /* S/MIME entry and subject match. */
- subjMap->pSMime = smimeNode;
- smimeMap->pSubject = subjNode;
- } else {
- /* S/MIME entry found is for diff. subject. */
- subjMap->pSMime = WrongEntry;
- }
- }
- }
- } else {
- subjMap->pSMime = NoSMime;
}
+ if (subjectEntry->emailAddrs) {
+ unsigned int n;
+ for (n = 0; n < subjectEntry->nemailAddrs &&
+ subjectEntry->emailAddrs[n]; ++n) {
+ char * emailAddr = subjectEntry->emailAddrs[n];
+ if (emailAddr[0]) {
+ PRCList *mElem;
+ /* Subject should have an smime entry, so create a link. */
+ for (mElem = PR_LIST_HEAD(&dbArray->smime.link);
+ mElem != &dbArray->smime.link;
+ mElem = PR_NEXT_LINK(mElem)) {
+ certDBEntryListNode *smimeNode;
+ certDBEntrySMime *smimeEntry;
+ /* Look for subject's email in S/MIME entries. */
+ smimeNode = LISTNODE_CAST(mElem);
+ smimeEntry = (certDBEntrySMime *)&smimeNode->entry;
+ if (PL_strcmp(emailAddr,
+ smimeEntry->emailAddr) == 0) {
+ /* Found a S/MIME entry for subject's email. */
+ if (SECITEM_ItemsAreEqual(
+ &subjectEntry->derSubject,
+ &smimeEntry->subjectName)) {
+ certDBEntryMap *smimeMap;
+ /* S/MIME entry and subject match. */
+ subjMap->pSMime = smimeNode;
+ smimeMap = (certDBEntryMap *)smimeNode->appData;
+ smimeMap->pSubject = subjNode;
+ } else if (subjMap->pSMime == NoSMime) {
+ /* S/MIME entry found is for diff. subject. */
+ subjMap->pSMime = WrongEntry;
+ }
+ }
+ } /* end for */
+ } /* endif (emailAddr[0]) */
+ } /* end for */
+ } /* endif (subjectEntry->emailAddrs) */
}
return SECSuccess;
}
@@ -535,6 +593,7 @@ print_smime_graph(dbDebugInfo *info, certDBEntryMap *smimeMap, int direction)
smimeMap->index, certDBEntryTypeSMimeProfile);
} else {
printnode(info, "<---- S/MIME %5d ", smimeMap->index);
+ info->dbErrors[NoSubjectForSMime]++;
}
} else {
printnode(info, "S/MIME %5d ", smimeMap->index);
@@ -559,6 +618,7 @@ print_nickname_graph(dbDebugInfo *info, certDBEntryMap *nickMap, int direction)
nickMap->index, certDBEntryTypeNickname);
} else {
printnode(info, "<---- Nickname %5d ", nickMap->index);
+ info->dbErrors[NoSubjectForNickname]++;
}
} else {
printnode(info, "Nickname %5d ", nickMap->index);
@@ -603,6 +663,8 @@ print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
map = (certDBEntryMap *)node->appData;
/* going left here stops. */
print_cert_graph(info, map, GOLEFT);
+ } else {
+ info->dbErrors[SubjectHasNoKeyForCert]++;
}
/* Now it is safe to output the subject id. */
if (direction == GOLEFT)
@@ -632,6 +694,10 @@ print_subject_graph(dbDebugInfo *info, certDBSubjectEntryMap *subjMap,
}
if (!subjMap->pNickname && !subjMap->pSMime) {
printnode(info, "******************* ", -1);
+ info->dbErrors[NoNicknameOrSMimeForSubject]++;
+ }
+ if (subjMap->pNickname && subjMap->pSMime) {
+ info->dbErrors[NicknameAndSMimeEntries]++;
}
}
if (direction != GORIGHT) { /* going right has only one cert */
@@ -672,6 +738,8 @@ print_cert_graph(dbDebugInfo *info, certDBEntryMap *certMap, int direction)
if (map_handle_is_ok(info, (void *)subjNode, 0)) {
subjMap = (certDBSubjectEntryMap *)subjNode->appData;
print_subject_graph(info, subjMap, GORIGHT, -1, -1);
+ } else {
+ info->dbErrors[NoSubjectForCert]++;
}
}
@@ -774,6 +842,7 @@ verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
/* List subjects */
for (elem = PR_LIST_HEAD(&dbArray->subjects.link);
elem != &dbArray->subjects.link; elem = PR_NEXT_LINK(elem)) {
+ int refs = 0;
node = LISTNODE_CAST(elem);
subjectEntry = (certDBEntrySubject *)&node->entry;
smap = (certDBSubjectEntryMap *)node->appData;
@@ -789,6 +858,7 @@ verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
}
}
if (subjectEntry->nickname) {
+ ++refs;
/* walk each subject handle to it's nickname entry */
if (map_handle_is_ok(info, smap->pNickname, -1)) {
ref = ((certDBEntryMap *)smap->pNickname->appData)->index;
@@ -797,7 +867,11 @@ verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
PR_fprintf(info->out, "-->(MISSING NICKNAME ENTRY)\n");
}
}
- if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
+ if (subjectEntry->nemailAddrs &&
+ subjectEntry->emailAddrs &&
+ subjectEntry->emailAddrs[0] &&
+ subjectEntry->emailAddrs[0][0]) {
+ ++refs;
/* walk each subject handle to it's smime entry */
if (map_handle_is_ok(info, smap->pSMime, -1)) {
ref = ((certDBEntryMap *)smap->pSMime->appData)->index;
@@ -806,6 +880,9 @@ verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
PR_fprintf(info->out, "-->(MISSING S/MIME ENTRY)\n");
}
}
+ if (!refs) {
+ PR_fprintf(info->out, "-->(NO NICKNAME+S/MIME ENTRY)\n");
+ }
PR_fprintf(info->out, "\n\n");
}
for (elem = PR_LIST_HEAD(&dbArray->nicknames.link);
@@ -836,20 +913,43 @@ verboseOutput(certDBArray *dbArray, dbDebugInfo *info)
PR_fprintf(info->out, "\n\n");
}
-char *errResult[] = {
- "Certificate entries that had no subject entry.",
- "Certificate entries that had no key in their subject entry.",
- "Subject entries that had no nickname or email address.",
- "Redundant nicknames (subjects with the same nickname).",
- "Subject entries that had no nickname entry.",
- "Redundant email addresses (subjects with the same email address).",
- "Subject entries that had no S/MIME entry.",
- "Nickname entries that had no subject entry.",
- "S/MIME entries that had no subject entry.",
-};
+
+/* A callback function, intended to be called from nsslowcert_TraverseDBEntries
+ * Builds a PRCList of DB entries of the specified type.
+ */
+SECStatus
+SEC_GetCertDBEntryList(SECItem *dbdata, SECItem *dbkey,
+ certDBEntryType entryType, void *pdata)
+{
+ certDBEntry * entry;
+ certDBEntryListNode * node;
+ PRCList * list = (PRCList *)pdata;
+
+ if (!dbdata || !dbkey || !pdata || !dbdata->data || !dbkey->data) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ entry = nsslowcert_DecodeAnyDBEntry(dbdata, dbkey, entryType, NULL);
+ if (!entry) {
+ return SECSuccess; /* skip it */
+ }
+ node = PORT_ArenaZNew(entry->common.arena, certDBEntryListNode);
+ if (!node) {
+ /* DestroyDBEntry(entry); */
+ PLArenaPool *arena = entry->common.arena;
+ PORT_Memset(&entry->common, 0, sizeof entry->common);
+ PORT_FreeArena(arena, PR_FALSE);
+ return SECFailure;
+ }
+ node->entry = *entry; /* crude but effective. */
+ PR_INIT_CLIST(&node->link);
+ PR_INSERT_BEFORE(&node->link, list);
+ return SECSuccess;
+}
+
int
-fillDBEntryArray(CERTCertDBHandle *handle, certDBEntryType type,
+fillDBEntryArray(NSSLOWCERTCertDBHandle *handle, certDBEntryType type,
certDBEntryListNode *list)
{
PRCList *elem;
@@ -858,20 +958,21 @@ fillDBEntryArray(CERTCertDBHandle *handle, certDBEntryType type,
certDBSubjectEntryMap *smnode;
PRArenaPool *arena;
int count = 0;
+
/* Initialize a dummy entry in the list. The list head will be the
* next element, so this element is skipped by for loops.
*/
PR_INIT_CLIST((PRCList *)list);
/* Collect all of the cert db entries for this type into a list. */
- SEC_TraverseDBEntries(handle, type, SEC_GetCertDBEntryList,
- (PRCList *)list);
+ nsslowcert_TraverseDBEntries(handle, type, SEC_GetCertDBEntryList, list);
+
for (elem = PR_LIST_HEAD(&list->link);
elem != &list->link; elem = PR_NEXT_LINK(elem)) {
/* Iterate over the entries and ... */
node = (certDBEntryListNode *)elem;
if (type != certDBEntryTypeSubject) {
arena = PORT_NewArena(sizeof(*mnode));
- mnode = (certDBEntryMap *)PORT_ArenaZAlloc(arena, sizeof(*mnode));
+ mnode = PORT_ArenaZNew(arena, certDBEntryMap);
mnode->arena = arena;
/* ... assign a unique index number to each node, and ... */
mnode->index = count;
@@ -880,8 +981,7 @@ fillDBEntryArray(CERTCertDBHandle *handle, certDBEntryType type,
} else {
/* allocate some room for the cert pointers also */
arena = PORT_NewArena(sizeof(*smnode) + 20*sizeof(void *));
- smnode = (certDBSubjectEntryMap *)
- PORT_ArenaZAlloc(arena, sizeof(*smnode));
+ smnode = PORT_ArenaZNew(arena, certDBSubjectEntryMap);
smnode->arena = arena;
smnode->index = count;
node->appData = (void *)smnode;
@@ -910,10 +1010,11 @@ freeDBEntryList(PRCList *list)
}
void
-DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
+DBCK_DebugDB(NSSLOWCERTCertDBHandle *handle, PRFileDesc *out,
+ PRFileDesc *mailfile)
{
int i, nCertsFound, nSubjFound, nErr;
- int nCerts, nSubjects, nSubjCerts, nNicknames, nSMime;
+ int nCerts, nSubjects, nSubjCerts, nNicknames, nSMime, nRevocation;
PRCList *elem;
char c;
dbDebugInfo info;
@@ -921,20 +1022,22 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
PORT_Memset(&dbArray, 0, sizeof(dbArray));
PORT_Memset(&info, 0, sizeof(info));
- info.verbose = (out == NULL) ? PR_FALSE : PR_TRUE ;
- info.dograph = (mailfile == NULL) ? PR_FALSE : PR_TRUE ;
- info.out = (out) ? out : PR_STDOUT;
- info.graphfile = mailfile;
+ info.verbose = (PRBool)(out != NULL);
+ info.dograph = info.verbose;
+ info.out = (out) ? out : PR_STDOUT;
+ info.graphfile = mailfile ? mailfile : PR_STDOUT;
/* Fill the array structure with cert/subject/nickname/smime entries. */
- dbArray.numCerts = fillDBEntryArray(handle, certDBEntryTypeCert,
- &dbArray.certs);
- dbArray.numSubjects = fillDBEntryArray(handle, certDBEntryTypeSubject,
- &dbArray.subjects);
+ dbArray.numCerts = fillDBEntryArray(handle, certDBEntryTypeCert,
+ &dbArray.certs);
+ dbArray.numSubjects = fillDBEntryArray(handle, certDBEntryTypeSubject,
+ &dbArray.subjects);
dbArray.numNicknames = fillDBEntryArray(handle, certDBEntryTypeNickname,
&dbArray.nicknames);
- dbArray.numSMime = fillDBEntryArray(handle, certDBEntryTypeSMimeProfile,
- &dbArray.smime);
+ dbArray.numSMime = fillDBEntryArray(handle, certDBEntryTypeSMimeProfile,
+ &dbArray.smime);
+ dbArray.numRevocation= fillDBEntryArray(handle, certDBEntryTypeRevocation,
+ &dbArray.revocation);
/* Compute the map between the database entries. */
mapSubjectEntries(&dbArray);
@@ -942,10 +1045,11 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
computeDBGraph(&dbArray, &info);
/* Store the totals for later reference. */
- nCerts = dbArray.numCerts;
- nSubjects = dbArray.numSubjects;
+ nCerts = dbArray.numCerts;
+ nSubjects = dbArray.numSubjects;
nNicknames = dbArray.numNicknames;
- nSMime = dbArray.numSMime;
+ nSMime = dbArray.numSMime;
+ nRevocation= dbArray.numRevocation;
nSubjCerts = 0;
for (elem = PR_LIST_HEAD(&dbArray.subjects.link);
elem != &dbArray.subjects.link; elem = PR_NEXT_LINK(elem)) {
@@ -963,6 +1067,7 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
freeDBEntryList(&dbArray.subjects.link);
freeDBEntryList(&dbArray.nicknames.link);
freeDBEntryList(&dbArray.smime.link);
+ freeDBEntryList(&dbArray.revocation.link);
PR_fprintf(info.out, "\n");
PR_fprintf(info.out, "Database statistics:\n");
@@ -976,10 +1081,12 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
nNicknames);
PR_fprintf(info.out, "N4: Found %4d S/MIME entries.\n",
nSMime);
+ PR_fprintf(info.out, "N5: Found %4d CRL entries.\n",
+ nRevocation);
PR_fprintf(info.out, "\n");
nErr = 0;
- for (i=0; i<sizeof(errResult)/sizeof(char*); i++) {
+ for (i=0; i < NUM_ERROR_TYPES; i++) {
PR_fprintf(info.out, "E%d: Found %4d %s\n",
i, info.dbErrors[i], errResult[i]);
nErr += info.dbErrors[i];
@@ -998,11 +1105,16 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
info.dbErrors[NoSubjectForCert],
info.dbErrors[SubjectHasNoKeyForCert]);
PR_fprintf(info.out, "\nSubjects:\n");
- PR_fprintf(info.out, "N1 == N3 + N4 + E%d + E%d + E%d + E%d + E%d - E%d - E%d\n",
- NoNicknameOrSMimeForSubject, WrongNicknameForSubject,
- NoNicknameEntry, WrongSMimeForSubject, NoSMimeEntry,
- NoSubjectForNickname, NoSubjectForSMime);
- PR_fprintf(info.out, " - #(subjects with both nickname and S/MIME entries)\n");
+ PR_fprintf(info.out,
+ "N1 == N3 + N4 + E%d + E%d + E%d + E%d + E%d - E%d - E%d - E%d\n",
+ NoNicknameOrSMimeForSubject,
+ WrongNicknameForSubject,
+ NoNicknameEntry,
+ WrongSMimeForSubject,
+ NoSMimeEntry,
+ NoSubjectForNickname,
+ NoSubjectForSMime,
+ NicknameAndSMimeEntries);
nSubjFound = nNicknames + nSMime +
info.dbErrors[NoNicknameOrSMimeForSubject] +
info.dbErrors[WrongNicknameForSubject] +
@@ -1011,9 +1123,10 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
info.dbErrors[NoSMimeEntry] -
info.dbErrors[NoSubjectForNickname] -
info.dbErrors[NoSubjectForSMime] -
- info.dbErrors[NicknameAndSMimeEntry];
+ info.dbErrors[NicknameAndSMimeEntries];
c = (nSubjFound == nSubjects) ? '=' : '!';
- PR_fprintf(info.out, "%d %c= %d + %d + %d + %d + %d + %d + %d - %d - %d - %d\n",
+ PR_fprintf(info.out,
+ "%2d %c= %2d + %2d + %2d + %2d + %2d + %2d + %2d - %2d - %2d - %2d\n",
nSubjects, c, nNicknames, nSMime,
info.dbErrors[NoNicknameOrSMimeForSubject],
info.dbErrors[WrongNicknameForSubject],
@@ -1022,676 +1135,12 @@ DBCK_DebugDB(CERTCertDBHandle *handle, PRFileDesc *out, PRFileDesc *mailfile)
info.dbErrors[NoSMimeEntry],
info.dbErrors[NoSubjectForNickname],
info.dbErrors[NoSubjectForSMime],
- info.dbErrors[NicknameAndSMimeEntry]);
+ info.dbErrors[NicknameAndSMimeEntries]);
PR_fprintf(info.out, "\n");
}
#ifdef DORECOVER
-enum {
- dbInvalidCert = 0,
- dbNoSMimeProfile,
- dbOlderCert,
- dbBadCertificate,
- dbCertNotWrittenToDB
-};
-
-typedef struct dbRestoreInfoStr
-{
- CERTCertDBHandle *handle;
- PRBool verbose;
- PRFileDesc *out;
- int nCerts;
- int nOldCerts;
- int dbErrors[5];
- PRBool removeType[3];
- PRBool promptUser[3];
-} dbRestoreInfo;
-
-char *
-IsEmailCert(CERTCertificate *cert)
-{
- char *email, *tmp1, *tmp2;
- PRBool isCA;
- int len;
-
- if (!cert->subjectName) {
- return NULL;
- }
-
- tmp1 = PORT_Strstr(cert->subjectName, "E=");
- tmp2 = PORT_Strstr(cert->subjectName, "MAIL=");
- /* XXX Nelson has cert for KTrilli which does not have either
- * of above but is email cert (has cert->emailAddr).
- */
- if (!tmp1 && !tmp2 && !(cert->emailAddr && cert->emailAddr[0])) {
- return NULL;
- }
-
- /* Server or CA cert, not personal email. */
- isCA = CERT_IsCACert(cert, NULL);
- if (isCA)
- return NULL;
-
- /* XXX CERT_IsCACert advertises checking the key usage ext.,
- but doesn't appear to. */
- /* Check the key usage extension. */
- if (cert->keyUsagePresent) {
- /* Must at least be able to sign or encrypt (not neccesarily
- * both if it is one of a dual cert).
- */
- if (!((cert->rawKeyUsage & KU_DIGITAL_SIGNATURE) ||
- (cert->rawKeyUsage & KU_KEY_ENCIPHERMENT)))
- return NULL;
-
- /* CA cert, not personal email. */
- if (cert->rawKeyUsage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN))
- return NULL;
- }
-
- if (cert->emailAddr && cert->emailAddr[0]) {
- email = PORT_Strdup(cert->emailAddr);
- } else {
- if (tmp1)
- tmp1 += 2; /* "E=" */
- else
- tmp1 = tmp2 + 5; /* "MAIL=" */
- len = strcspn(tmp1, ", ");
- email = (char*)PORT_Alloc(len+1);
- PORT_Strncpy(email, tmp1, len);
- email[len] = '\0';
- }
-
- return email;
-}
-
-SECStatus
-deleteit(CERTCertificate *cert, void *arg)
-{
- return SEC_DeletePermCertificate(cert);
-}
-
-/* Different than DeleteCertificate - has the added bonus of removing
- * all certs with the same DN.
- */
-SECStatus
-deleteAllEntriesForCert(CERTCertDBHandle *handle, CERTCertificate *cert,
- PRFileDesc *outfile)
-{
-#if 0
- certDBEntrySubject *subjectEntry;
- certDBEntryNickname *nicknameEntry;
- certDBEntrySMime *smimeEntry;
- int i;
-#endif
-
- if (outfile) {
- PR_fprintf(outfile, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n");
- PR_fprintf(outfile, "Deleting redundant certificate:\n");
- dumpCertificate(cert, -1, outfile);
- }
-
- CERT_TraverseCertsForSubject(handle, cert->subjectList, deleteit, NULL);
-#if 0
- CERT_LockDB(handle);
- subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
- /* It had better be there, or created a bad db. */
- PORT_Assert(subjectEntry);
- for (i=0; i<subjectEntry->ncerts; i++) {
- DeleteDBCertEntry(handle, &subjectEntry->certKeys[i]);
- }
- DeleteDBSubjectEntry(handle, &cert->derSubject);
- if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
- smimeEntry = ReadDBSMimeEntry(handle, subjectEntry->emailAddr);
- if (smimeEntry) {
- if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
- &smimeEntry->subjectName))
- /* Only delete it if it's for this subject! */
- DeleteDBSMimeEntry(handle, subjectEntry->emailAddr);
- SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
- }
- }
- if (subjectEntry->nickname) {
- nicknameEntry = ReadDBNicknameEntry(handle, subjectEntry->nickname);
- if (nicknameEntry) {
- if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
- &nicknameEntry->subjectName))
- /* Only delete it if it's for this subject! */
- DeleteDBNicknameEntry(handle, subjectEntry->nickname);
- SEC_DestroyDBEntry((certDBEntry*)nicknameEntry);
- }
- }
- SEC_DestroyDBEntry((certDBEntry*)subjectEntry);
- CERT_UnlockDB(handle);
-#endif
- return SECSuccess;
-}
-
-void
-getCertsToDelete(char *numlist, int len, int *certNums, int nCerts)
-{
- int j, num;
- char *numstr, *numend, *end;
-
- numstr = numlist;
- end = numstr + len - 1;
- while (numstr != end) {
- numend = strpbrk(numstr, ", \n");
- *numend = '\0';
- if (PORT_Strlen(numstr) == 0)
- return;
- num = PORT_Atoi(numstr);
- if (numstr == numlist)
- certNums[0] = num;
- for (j=1; j<nCerts+1; j++) {
- if (num == certNums[j]) {
- certNums[j] = -1;
- break;
- }
- }
- if (numend == end)
- break;
- numstr = strpbrk(numend+1, "0123456789");
- }
-}
-
-PRBool
-userSaysDeleteCert(CERTCertificate **certs, int nCerts,
- int errtype, dbRestoreInfo *info, int *certNums)
-{
- char response[32];
- int32 nb;
- int i;
- /* User wants to remove cert without prompting. */
- if (info->promptUser[errtype] == PR_FALSE)
- return (info->removeType[errtype]);
- switch (errtype) {
- case dbInvalidCert:
- PR_fprintf(PR_STDOUT, "******** Expired ********\n");
- PR_fprintf(PR_STDOUT, "Cert has expired.\n\n");
- dumpCertificate(certs[0], -1, PR_STDOUT);
- PR_fprintf(PR_STDOUT,
- "Keep it? (y/n - this one, Y/N - all expired certs) [n] ");
- break;
- case dbNoSMimeProfile:
- PR_fprintf(PR_STDOUT, "******** No Profile ********\n");
- PR_fprintf(PR_STDOUT, "S/MIME cert has no profile.\n\n");
- dumpCertificate(certs[0], -1, PR_STDOUT);
- PR_fprintf(PR_STDOUT,
- "Keep it? (y/n - this one, Y/N - all S/MIME w/o profile) [n] ");
- break;
- case dbOlderCert:
- PR_fprintf(PR_STDOUT, "******* Redundant nickname/email *******\n\n");
- PR_fprintf(PR_STDOUT, "These certs have the same nickname/email:\n");
- for (i=0; i<nCerts; i++)
- dumpCertificate(certs[i], i, PR_STDOUT);
- PR_fprintf(PR_STDOUT,
- "Enter the certs you would like to keep from those listed above.\n");
- PR_fprintf(PR_STDOUT,
- "Use a comma-separated list of the cert numbers (ex. 0, 8, 12).\n");
- PR_fprintf(PR_STDOUT,
- "The first cert in the list will be the primary cert\n");
- PR_fprintf(PR_STDOUT,
- " accessed by the nickname/email handle.\n");
- PR_fprintf(PR_STDOUT,
- "List cert numbers to keep here, or hit enter\n");
- PR_fprintf(PR_STDOUT,
- " to always keep only the newest cert: ");
- break;
- default:
- }
- nb = PR_Read(PR_STDIN, response, sizeof(response));
- PR_fprintf(PR_STDOUT, "\n\n");
- if (errtype == dbOlderCert) {
- if (!isdigit(response[0])) {
- info->promptUser[errtype] = PR_FALSE;
- info->removeType[errtype] = PR_TRUE;
- return PR_TRUE;
- }
- getCertsToDelete(response, nb, certNums, nCerts);
- return PR_TRUE;
- }
- /* User doesn't want to be prompted for this type anymore. */
- if (response[0] == 'Y') {
- info->promptUser[errtype] = PR_FALSE;
- info->removeType[errtype] = PR_FALSE;
- return PR_FALSE;
- } else if (response[0] == 'N') {
- info->promptUser[errtype] = PR_FALSE;
- info->removeType[errtype] = PR_TRUE;
- return PR_TRUE;
- }
- return (response[0] != 'y') ? PR_TRUE : PR_FALSE;
-}
-
-SECStatus
-addCertToDB(certDBEntryCert *certEntry, dbRestoreInfo *info,
- CERTCertDBHandle *oldhandle)
-{
- SECStatus rv = SECSuccess;
- PRBool allowOverride;
- PRBool userCert;
- SECCertTimeValidity validity;
- CERTCertificate *oldCert = NULL;
- CERTCertificate *dbCert = NULL;
- CERTCertificate *newCert = NULL;
- CERTCertTrust *trust;
- certDBEntrySMime *smimeEntry = NULL;
- char *email = NULL;
- char *nickname = NULL;
- int nCertsForSubject = 1;
-
- oldCert = CERT_DecodeDERCertificate(&certEntry->derCert, PR_FALSE,
- certEntry->nickname);
- if (!oldCert) {
- info->dbErrors[dbBadCertificate]++;
- SEC_DestroyDBEntry((certDBEntry*)certEntry);
- return SECSuccess;
- }
-
- oldCert->dbEntry = certEntry;
- oldCert->trust = &certEntry->trust;
- oldCert->dbhandle = oldhandle;
-
- trust = oldCert->trust;
-
- info->nOldCerts++;
-
- if (info->verbose)
- PR_fprintf(info->out, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");
-
- if (oldCert->nickname)
- nickname = PORT_Strdup(oldCert->nickname);
-
- /* Always keep user certs. Skip ahead. */
- /* XXX if someone sends themselves a signed message, it is possible
- for their cert to be imported as an "other" cert, not a user cert.
- this mucks with smime entries... */
- userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
- (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
- (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
- if (userCert)
- goto createcert;
-
- /* If user chooses so, ignore expired certificates. */
- allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) ||
- (oldCert->keyUsage == certUsageSSLServerWithStepUp));
- validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride);
- /* If cert expired and user wants to delete it, ignore it. */
- if ((validity != secCertTimeValid) &&
- userSaysDeleteCert(&oldCert, 1, dbInvalidCert, info, 0)) {
- info->dbErrors[dbInvalidCert]++;
- if (info->verbose) {
- PR_fprintf(info->out, "Deleting expired certificate:\n");
- dumpCertificate(oldCert, -1, info->out);
- }
- goto cleanup;
- }
-
- /* New database will already have default certs, don't attempt
- to overwrite them. */
- dbCert = CERT_FindCertByDERCert(info->handle, &oldCert->derCert);
- if (dbCert) {
- info->nCerts++;
- if (info->verbose) {
- PR_fprintf(info->out, "Added certificate to database:\n");
- dumpCertificate(oldCert, -1, info->out);
- }
- goto cleanup;
- }
-
- /* Determine if cert is S/MIME and get its email if so. */
- email = IsEmailCert(oldCert);
-
- /*
- XXX Just create empty profiles?
- if (email) {
- SECItem *profile = CERT_FindSMimeProfile(oldCert);
- if (!profile &&
- userSaysDeleteCert(&oldCert, 1, dbNoSMimeProfile, info, 0)) {
- info->dbErrors[dbNoSMimeProfile]++;
- if (info->verbose) {
- PR_fprintf(info->out,
- "Deleted cert missing S/MIME profile.\n");
- dumpCertificate(oldCert, -1, info->out);
- }
- goto cleanup;
- } else {
- SECITEM_FreeItem(profile);
- }
- }
- */
-
-createcert:
-
- /* Sometimes happens... */
- if (!nickname && userCert)
- nickname = PORT_Strdup(oldCert->subjectName);
-
- /* Create a new certificate, copy of the old one. */
- newCert = CERT_NewTempCertificate(info->handle, &oldCert->derCert,
- nickname, PR_FALSE, PR_TRUE);
- if (!newCert) {
- PR_fprintf(PR_STDERR, "Unable to create new certificate.\n");
- dumpCertificate(oldCert, -1, PR_STDERR);
- info->dbErrors[dbBadCertificate]++;
- goto cleanup;
- }
-
- /* Add the cert to the new database. */
- rv = CERT_AddTempCertToPerm(newCert, nickname, oldCert->trust);
- if (rv) {
- PR_fprintf(PR_STDERR, "Failed to write temp cert to perm database.\n");
- dumpCertificate(oldCert, -1, PR_STDERR);
- info->dbErrors[dbCertNotWrittenToDB]++;
- goto cleanup;
- }
-
- if (info->verbose) {
- PR_fprintf(info->out, "Added certificate to database:\n");
- dumpCertificate(oldCert, -1, info->out);
- }
-
- /* If the cert is an S/MIME cert, and the first with it's subject,
- * modify the subject entry to include the email address,
- * CERT_AddTempCertToPerm does not do email addresses and S/MIME entries.
- */
- if (smimeEntry) { /*&& !userCert && nCertsForSubject == 1) { */
-#if 0
- UpdateSubjectWithEmailAddr(newCert, email);
-#endif
- SECItem emailProfile, profileTime;
- rv = CERT_FindFullSMimeProfile(oldCert, &emailProfile, &profileTime);
- /* calls UpdateSubjectWithEmailAddr */
- if (rv == SECSuccess)
- rv = CERT_SaveSMimeProfile(newCert, &emailProfile, &profileTime);
- }
-
- info->nCerts++;
-
-cleanup:
-
- if (nickname)
- PORT_Free(nickname);
- if (email)
- PORT_Free(email);
- if (oldCert)
- CERT_DestroyCertificate(oldCert);
- if (dbCert)
- CERT_DestroyCertificate(dbCert);
- if (newCert)
- CERT_DestroyCertificate(newCert);
- if (smimeEntry)
- SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
- return SECSuccess;
-}
-
-#if 0
-SECStatus
-copyDBEntry(SECItem *data, SECItem *key, certDBEntryType type, void *pdata)
-{
- SECStatus rv;
- CERTCertDBHandle *newdb = (CERTCertDBHandle *)pdata;
- certDBEntryCommon common;
- SECItem dbkey;
-
- common.type = type;
- common.version = CERT_DB_FILE_VERSION;
- common.flags = data->data[2];
- common.arena = NULL;
-
- dbkey.len = key->len + SEC_DB_KEY_HEADER_LEN;
- dbkey.data = (unsigned char *)PORT_Alloc(dbkey.len*sizeof(unsigned char));
- PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], key->data, key->len);
- dbkey.data[0] = type;
-
- rv = WriteDBEntry(newdb, &common, &dbkey, data);
-
- PORT_Free(dbkey.data);
- return rv;
-}
-#endif
-
-int
-certIsOlder(CERTCertificate **cert1, CERTCertificate** cert2)
-{
- return !CERT_IsNewer(*cert1, *cert2);
-}
-
-int
-findNewestSubjectForEmail(CERTCertDBHandle *handle, int subjectNum,
- certDBArray *dbArray, dbRestoreInfo *info,
- int *subjectWithSMime, int *smimeForSubject)
-{
- int newestSubject;
- int subjectsForEmail[50];
- int i, j, ns, sNum;
- certDBEntryListNode *subjects = &dbArray->subjects;
- certDBEntryListNode *smime = &dbArray->smime;
- certDBEntrySubject *subjectEntry1, *subjectEntry2;
- certDBEntrySMime *smimeEntry;
- CERTCertificate **certs;
- CERTCertificate *cert;
- CERTCertTrust *trust;
- PRBool userCert;
- int *certNums;
-
- ns = 0;
- subjectEntry1 = (certDBEntrySubject*)&subjects.entries[subjectNum];
- subjectsForEmail[ns++] = subjectNum;
-
- *subjectWithSMime = -1;
- *smimeForSubject = -1;
- newestSubject = subjectNum;
-
- cert = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
- if (cert) {
- trust = cert->trust;
- userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
- (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
- (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
- CERT_DestroyCertificate(cert);
- }
-
- /*
- * XXX Should we make sure that subjectEntry1->emailAddr is not
- * a null pointer or an empty string before going into the next
- * two for loops, which pass it to PORT_Strcmp?
- */
-
- /* Loop over the remaining subjects. */
- for (i=subjectNum+1; i<subjects.numEntries; i++) {
- subjectEntry2 = (certDBEntrySubject*)&subjects.entries[i];
- if (!subjectEntry2)
- continue;
- if (subjectEntry2->emailAddr && subjectEntry2->emailAddr[0] &&
- PORT_Strcmp(subjectEntry1->emailAddr,
- subjectEntry2->emailAddr) == 0) {
- /* Found a subject using the same email address. */
- subjectsForEmail[ns++] = i;
- }
- }
-
- /* Find the S/MIME entry for this email address. */
- for (i=0; i<smime.numEntries; i++) {
- smimeEntry = (certDBEntrySMime*)&smime.entries[i];
- if (smimeEntry->common.arena == NULL)
- continue;
- if (smimeEntry->emailAddr && smimeEntry->emailAddr[0] &&
- PORT_Strcmp(subjectEntry1->emailAddr, smimeEntry->emailAddr) == 0) {
- /* Find which of the subjects uses this S/MIME entry. */
- for (j=0; j<ns && *subjectWithSMime < 0; j++) {
- sNum = subjectsForEmail[j];
- subjectEntry2 = (certDBEntrySubject*)&subjects.entries[sNum];
- if (SECITEM_ItemsAreEqual(&smimeEntry->subjectName,
- &subjectEntry2->derSubject)) {
- /* Found the subject corresponding to the S/MIME entry. */
- *subjectWithSMime = sNum;
- *smimeForSubject = i;
- }
- }
- SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
- PORT_Memset(smimeEntry, 0, sizeof(certDBEntry));
- break;
- }
- }
-
- if (ns <= 1)
- return subjectNum;
-
- if (userCert)
- return *subjectWithSMime;
-
- /* Now find which of the subjects has the newest cert. */
- certs = (CERTCertificate**)PORT_Alloc(ns*sizeof(CERTCertificate*));
- certNums = (int*)PORT_Alloc((ns+1)*sizeof(int));
- certNums[0] = 0;
- for (i=0; i<ns; i++) {
- sNum = subjectsForEmail[i];
- subjectEntry1 = (certDBEntrySubject*)&subjects.entries[sNum];
- certs[i] = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
- certNums[i+1] = i;
- }
- /* Sort the array by validity. */
- qsort(certs, ns, sizeof(CERTCertificate*),
- (int (*)(const void *, const void *))certIsOlder);
- newestSubject = -1;
- for (i=0; i<ns; i++) {
- sNum = subjectsForEmail[i];
- subjectEntry1 = (certDBEntrySubject*)&subjects.entries[sNum];
- if (SECITEM_ItemsAreEqual(&subjectEntry1->derSubject,
- &certs[0]->derSubject))
- newestSubject = sNum;
- else
- SEC_DestroyDBEntry((certDBEntry*)subjectEntry1);
- }
- if (info && userSaysDeleteCert(certs, ns, dbOlderCert, info, certNums)) {
- for (i=1; i<ns+1; i++) {
- if (certNums[i] >= 0 && certNums[i] != certNums[0]) {
- deleteAllEntriesForCert(handle, certs[certNums[i]], info->out);
- info->dbErrors[dbOlderCert]++;
- }
- }
- }
- CERT_DestroyCertArray(certs, ns);
- return newestSubject;
-}
-
-CERTCertDBHandle *
-DBCK_ReconstructDBFromCerts(CERTCertDBHandle *oldhandle, char *newdbname,
- PRFileDesc *outfile, PRBool removeExpired,
- PRBool requireProfile, PRBool singleEntry,
- PRBool promptUser)
-{
- SECStatus rv;
- dbRestoreInfo info;
- certDBEntryContentVersion *oldContentVersion;
- certDBArray dbArray;
- int i;
-
- PORT_Memset(&dbArray, 0, sizeof(dbArray));
- PORT_Memset(&info, 0, sizeof(info));
- info.verbose = (outfile) ? PR_TRUE : PR_FALSE;
- info.out = (outfile) ? outfile : PR_STDOUT;
- info.removeType[dbInvalidCert] = removeExpired;
- info.removeType[dbNoSMimeProfile] = requireProfile;
- info.removeType[dbOlderCert] = singleEntry;
- info.promptUser[dbInvalidCert] = promptUser;
- info.promptUser[dbNoSMimeProfile] = promptUser;
- info.promptUser[dbOlderCert] = promptUser;
-
- /* Allocate a handle to fill with CERT_OpenCertDB below. */
- info.handle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));
- if (!info.handle) {
- fprintf(stderr, "unable to get database handle");
- return NULL;
- }
-
- /* Create a certdb with the most recent set of roots. */
- rv = CERT_OpenCertDBFilename(info.handle, newdbname, PR_FALSE);
-
- if (rv) {
- fprintf(stderr, "could not open certificate database");
- goto loser;
- }
-
- /* Create certificate, subject, nickname, and email records.
- * mcom_db seems to have a sequential access bug. Though reads and writes
- * should be allowed during traversal, they seem to screw up the sequence.
- * So, stuff all the cert entries into an array, and loop over the array
- * doing read/writes in the db.
- */
- fillDBEntryArray(oldhandle, certDBEntryTypeCert, &dbArray.certs);
- for (elem = PR_LIST_HEAD(&dbArray->certs.link);
- elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
- node = LISTNODE_CAST(elem);
- addCertToDB((certDBEntryCert*)&node->entry, &info, oldhandle);
- /* entries get destroyed in addCertToDB */
- }
-#if 0
- rv = SEC_TraverseDBEntries(oldhandle, certDBEntryTypeSMimeProfile,
- copyDBEntry, info.handle);
-#endif
-
- /* Fix up the pointers between (nickname|S/MIME) --> (subject).
- * Create S/MIME entries for S/MIME certs.
- * Have the S/MIME entry point to the last-expiring cert using
- * an email address.
- */
-#if 0
- CERT_RedoHandlesForSubjects(info.handle, singleEntry, &info);
-#endif
-
- freeDBEntryList(&dbArray.certs.link);
-
- /* Copy over the version record. */
- /* XXX Already exists - and _must_ be correct... */
- /*
- versionEntry = ReadDBVersionEntry(oldhandle);
- rv = WriteDBVersionEntry(info.handle, versionEntry);
- */
-
- /* Copy over the content version record. */
- /* XXX Can probably get useful info from old content version?
- * Was this db created before/after this tool? etc.
- */
-#if 0
- oldContentVersion = ReadDBContentVersionEntry(oldhandle);
- CERT_SetDBContentVersion(oldContentVersion->contentVersion, info.handle);
-#endif
-
-#if 0
- /* Copy over the CRL & KRL records. */
- rv = SEC_TraverseDBEntries(oldhandle, certDBEntryTypeRevocation,
- copyDBEntry, info.handle);
- /* XXX Only one KRL, just do db->get? */
- rv = SEC_TraverseDBEntries(oldhandle, certDBEntryTypeKeyRevocation,
- copyDBEntry, info.handle);
-#endif
-
- PR_fprintf(info.out, "Database had %d certificates.\n", info.nOldCerts);
-
- PR_fprintf(info.out, "Reconstructed %d certificates.\n", info.nCerts);
- PR_fprintf(info.out, "(ax) Rejected %d expired certificates.\n",
- info.dbErrors[dbInvalidCert]);
- PR_fprintf(info.out, "(as) Rejected %d S/MIME certificates missing a profile.\n",
- info.dbErrors[dbNoSMimeProfile]);
- PR_fprintf(info.out, "(ar) Rejected %d certificates for which a newer certificate was found.\n",
- info.dbErrors[dbOlderCert]);
- PR_fprintf(info.out, " Rejected %d corrupt certificates.\n",
- info.dbErrors[dbBadCertificate]);
- PR_fprintf(info.out, " Rejected %d certificates which did not write to the DB.\n",
- info.dbErrors[dbCertNotWrittenToDB]);
-
- if (rv)
- goto loser;
-
- return info.handle;
-
-loser:
- if (info.handle)
- PORT_Free(info.handle);
- return NULL;
-}
+#include "dbrecover.c"
#endif /* DORECOVER */
enum {
@@ -1736,12 +1185,51 @@ static secuCommandFlag dbck_options[] =
{ /* opt_KeepExpired, */ 'x', PR_FALSE, 0, PR_FALSE }
};
+#define CERT_DB_FMT "%s/cert%s.db"
+
+static char *
+dbck_certdb_name_cb(void *arg, int dbVersion)
+{
+ const char *configdir = (const char *)arg;
+ const char *dbver;
+ char *smpname = NULL;
+ char *dbname = NULL;
+
+ switch (dbVersion) {
+ case 8:
+ dbver = "8";
+ break;
+ case 7:
+ dbver = "7";
+ break;
+ case 6:
+ dbver = "6";
+ break;
+ case 5:
+ dbver = "5";
+ break;
+ case 4:
+ default:
+ dbver = "";
+ break;
+ }
+
+ /* make sure we return something allocated with PORT_ so we have properly
+ * matched frees at the end */
+ smpname = PR_smprintf(CERT_DB_FMT, configdir, dbver);
+ if (smpname) {
+ dbname = PORT_Strdup(smpname);
+ PR_smprintf_free(smpname);
+ }
+ return dbname;
+}
+
+
int
main(int argc, char **argv)
{
- CERTCertDBHandle *certHandle;
+ NSSLOWCERTCertDBHandle *certHandle;
- PRFileInfo fileInfo;
PRFileDesc *mailfile = NULL;
PRFileDesc *dumpfile = NULL;
@@ -1750,10 +1238,9 @@ main(int argc, char **argv)
char * newdbname = 0;
PRBool removeExpired, requireProfile, singleEntry;
-
- SECStatus rv;
-
+ SECStatus rv;
secuCommand dbck;
+
dbck.numCommands = sizeof(dbck_commands) / sizeof(secuCommandFlag);
dbck.numOptions = sizeof(dbck_options) / sizeof(secuCommandFlag);
dbck.commands = dbck_commands;
@@ -1772,7 +1259,7 @@ main(int argc, char **argv)
if (!dbck.commands[cmd_Debug].activated &&
!dbck.commands[cmd_Recover].activated) {
- PR_fprintf(PR_STDERR, "Please specify -D or -R.\n");
+ PR_fprintf(PR_STDERR, "Please specify -H, -D or -R.\n");
Usage(progName);
}
@@ -1788,7 +1275,7 @@ main(int argc, char **argv)
if (dbck.options[opt_OutputDB].activated) {
newdbname = PL_strdup(dbck.options[opt_OutputDB].arg);
} else {
- newdbname = PL_strdup("new_cert7.db");
+ newdbname = PL_strdup("new_cert8.db");
}
/* Create a generic graph of the database. */
@@ -1805,10 +1292,12 @@ main(int argc, char **argv)
if (dbck.options[opt_Dumpfile].activated) {
dumpfile = PR_Open(dbck.options[opt_Dumpfile].arg,
PR_RDWR | PR_CREATE_FILE, 00660);
- }
- if (!dumpfile) {
- fprintf(stderr, "Unable to create dumpfile.\n");
- return -1;
+ if (!dumpfile) {
+ fprintf(stderr, "Unable to create dumpfile.\n");
+ return -1;
+ }
+ } else {
+ dumpfile = PR_STDOUT;
}
}
@@ -1817,18 +1306,26 @@ main(int argc, char **argv)
SECU_ConfigDirectory(dbck.options[opt_CertDir].arg);
}
+ pathname = SECU_ConfigDirectory(NULL);
+
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
- SEC_Init();
+ rv = NSS_NoDB_Init(pathname);
+ if (rv != SECSuccess) {
+ fprintf(stderr, "NSS_NoDB_Init failed\n");
+ return -1;
+ }
- certHandle = (CERTCertDBHandle *)PORT_ZAlloc(sizeof(CERTCertDBHandle));
+ certHandle = PORT_ZNew(NSSLOWCERTCertDBHandle);
if (!certHandle) {
SECU_PrintError(progName, "unable to get database handle");
return -1;
}
+ certHandle->ref = 1;
+#ifdef NOTYET
/* Open the possibly corrupt database. */
if (dbck.options[opt_InputDB].activated) {
- pathname = SECU_ConfigDirectory(NULL);
+ PRFileInfo fileInfo;
fullname = PR_smprintf("%s/%s", pathname,
dbck.options[opt_InputDB].arg);
if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
@@ -1836,15 +1333,24 @@ main(int argc, char **argv)
return -1;
}
rv = CERT_OpenCertDBFilename(certHandle, fullname, PR_TRUE);
- } else {
+ } else
+#endif
+ {
/* Use the default. */
+#ifdef NOTYET
fullname = SECU_CertDBNameCallback(NULL, CERT_DB_FILE_VERSION);
if (PR_GetFileInfo(fullname, &fileInfo) != PR_SUCCESS) {
fprintf(stderr, "Unable to read file \"%s\".\n", fullname);
return -1;
}
- rv = CERT_OpenCertDB(certHandle, PR_TRUE,
- SECU_CertDBNameCallback, NULL);
+#endif
+ rv = nsslowcert_OpenCertDB(certHandle,
+ PR_TRUE, /* readOnly */
+ NULL, /* rdb appName */
+ "", /* rdb prefix */
+ dbck_certdb_name_cb, /* namecb */
+ pathname, /* configDir */
+ PR_FALSE); /* volatile */
}
if (rv) {
@@ -1872,7 +1378,7 @@ main(int argc, char **argv)
if (dumpfile)
PR_Close(dumpfile);
if (certHandle) {
- CERT_ClosePermCertDB(certHandle);
+ nsslowcert_ClosePermCertDB(certHandle);
PORT_Free(certHandle);
}
return -1;
diff --git a/security/nss/cmd/dbck/dbrecover.c b/security/nss/cmd/dbck/dbrecover.c
new file mode 100644
index 000000000..db65d0e5c
--- /dev/null
+++ b/security/nss/cmd/dbck/dbrecover.c
@@ -0,0 +1,702 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+enum {
+ dbInvalidCert = 0,
+ dbNoSMimeProfile,
+ dbOlderCert,
+ dbBadCertificate,
+ dbCertNotWrittenToDB
+};
+
+typedef struct dbRestoreInfoStr
+{
+ NSSLOWCERTCertDBHandle *handle;
+ PRBool verbose;
+ PRFileDesc *out;
+ int nCerts;
+ int nOldCerts;
+ int dbErrors[5];
+ PRBool removeType[3];
+ PRBool promptUser[3];
+} dbRestoreInfo;
+
+char *
+IsEmailCert(CERTCertificate *cert)
+{
+ char *email, *tmp1, *tmp2;
+ PRBool isCA;
+ int len;
+
+ if (!cert->subjectName) {
+ return NULL;
+ }
+
+ tmp1 = PORT_Strstr(cert->subjectName, "E=");
+ tmp2 = PORT_Strstr(cert->subjectName, "MAIL=");
+ /* XXX Nelson has cert for KTrilli which does not have either
+ * of above but is email cert (has cert->emailAddr).
+ */
+ if (!tmp1 && !tmp2 && !(cert->emailAddr && cert->emailAddr[0])) {
+ return NULL;
+ }
+
+ /* Server or CA cert, not personal email. */
+ isCA = CERT_IsCACert(cert, NULL);
+ if (isCA)
+ return NULL;
+
+ /* XXX CERT_IsCACert advertises checking the key usage ext.,
+ but doesn't appear to. */
+ /* Check the key usage extension. */
+ if (cert->keyUsagePresent) {
+ /* Must at least be able to sign or encrypt (not neccesarily
+ * both if it is one of a dual cert).
+ */
+ if (!((cert->rawKeyUsage & KU_DIGITAL_SIGNATURE) ||
+ (cert->rawKeyUsage & KU_KEY_ENCIPHERMENT)))
+ return NULL;
+
+ /* CA cert, not personal email. */
+ if (cert->rawKeyUsage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN))
+ return NULL;
+ }
+
+ if (cert->emailAddr && cert->emailAddr[0]) {
+ email = PORT_Strdup(cert->emailAddr);
+ } else {
+ if (tmp1)
+ tmp1 += 2; /* "E=" */
+ else
+ tmp1 = tmp2 + 5; /* "MAIL=" */
+ len = strcspn(tmp1, ", ");
+ email = (char*)PORT_Alloc(len+1);
+ PORT_Strncpy(email, tmp1, len);
+ email[len] = '\0';
+ }
+
+ return email;
+}
+
+SECStatus
+deleteit(CERTCertificate *cert, void *arg)
+{
+ return SEC_DeletePermCertificate(cert);
+}
+
+/* Different than DeleteCertificate - has the added bonus of removing
+ * all certs with the same DN.
+ */
+SECStatus
+deleteAllEntriesForCert(NSSLOWCERTCertDBHandle *handle, CERTCertificate *cert,
+ PRFileDesc *outfile)
+{
+#if 0
+ certDBEntrySubject *subjectEntry;
+ certDBEntryNickname *nicknameEntry;
+ certDBEntrySMime *smimeEntry;
+ int i;
+#endif
+
+ if (outfile) {
+ PR_fprintf(outfile, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n\n");
+ PR_fprintf(outfile, "Deleting redundant certificate:\n");
+ dumpCertificate(cert, -1, outfile);
+ }
+
+ CERT_TraverseCertsForSubject(handle, cert->subjectList, deleteit, NULL);
+#if 0
+ CERT_LockDB(handle);
+ subjectEntry = ReadDBSubjectEntry(handle, &cert->derSubject);
+ /* It had better be there, or created a bad db. */
+ PORT_Assert(subjectEntry);
+ for (i=0; i<subjectEntry->ncerts; i++) {
+ DeleteDBCertEntry(handle, &subjectEntry->certKeys[i]);
+ }
+ DeleteDBSubjectEntry(handle, &cert->derSubject);
+ if (subjectEntry->emailAddr && subjectEntry->emailAddr[0]) {
+ smimeEntry = ReadDBSMimeEntry(handle, subjectEntry->emailAddr);
+ if (smimeEntry) {
+ if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
+ &smimeEntry->subjectName))
+ /* Only delete it if it's for this subject! */
+ DeleteDBSMimeEntry(handle, subjectEntry->emailAddr);
+ SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
+ }
+ }
+ if (subjectEntry->nickname) {
+ nicknameEntry = ReadDBNicknameEntry(handle, subjectEntry->nickname);
+ if (nicknameEntry) {
+ if (SECITEM_ItemsAreEqual(&subjectEntry->derSubject,
+ &nicknameEntry->subjectName))
+ /* Only delete it if it's for this subject! */
+ DeleteDBNicknameEntry(handle, subjectEntry->nickname);
+ SEC_DestroyDBEntry((certDBEntry*)nicknameEntry);
+ }
+ }
+ SEC_DestroyDBEntry((certDBEntry*)subjectEntry);
+ CERT_UnlockDB(handle);
+#endif
+ return SECSuccess;
+}
+
+void
+getCertsToDelete(char *numlist, int len, int *certNums, int nCerts)
+{
+ int j, num;
+ char *numstr, *numend, *end;
+
+ numstr = numlist;
+ end = numstr + len - 1;
+ while (numstr != end) {
+ numend = strpbrk(numstr, ", \n");
+ *numend = '\0';
+ if (PORT_Strlen(numstr) == 0)
+ return;
+ num = PORT_Atoi(numstr);
+ if (numstr == numlist)
+ certNums[0] = num;
+ for (j=1; j<nCerts+1; j++) {
+ if (num == certNums[j]) {
+ certNums[j] = -1;
+ break;
+ }
+ }
+ if (numend == end)
+ break;
+ numstr = strpbrk(numend+1, "0123456789");
+ }
+}
+
+PRBool
+userSaysDeleteCert(CERTCertificate **certs, int nCerts,
+ int errtype, dbRestoreInfo *info, int *certNums)
+{
+ char response[32];
+ int32 nb;
+ int i;
+ /* User wants to remove cert without prompting. */
+ if (info->promptUser[errtype] == PR_FALSE)
+ return (info->removeType[errtype]);
+ switch (errtype) {
+ case dbInvalidCert:
+ PR_fprintf(PR_STDOUT, "******** Expired ********\n");
+ PR_fprintf(PR_STDOUT, "Cert has expired.\n\n");
+ dumpCertificate(certs[0], -1, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Keep it? (y/n - this one, Y/N - all expired certs) [n] ");
+ break;
+ case dbNoSMimeProfile:
+ PR_fprintf(PR_STDOUT, "******** No Profile ********\n");
+ PR_fprintf(PR_STDOUT, "S/MIME cert has no profile.\n\n");
+ dumpCertificate(certs[0], -1, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Keep it? (y/n - this one, Y/N - all S/MIME w/o profile) [n] ");
+ break;
+ case dbOlderCert:
+ PR_fprintf(PR_STDOUT, "******* Redundant nickname/email *******\n\n");
+ PR_fprintf(PR_STDOUT, "These certs have the same nickname/email:\n");
+ for (i=0; i<nCerts; i++)
+ dumpCertificate(certs[i], i, PR_STDOUT);
+ PR_fprintf(PR_STDOUT,
+ "Enter the certs you would like to keep from those listed above.\n");
+ PR_fprintf(PR_STDOUT,
+ "Use a comma-separated list of the cert numbers (ex. 0, 8, 12).\n");
+ PR_fprintf(PR_STDOUT,
+ "The first cert in the list will be the primary cert\n");
+ PR_fprintf(PR_STDOUT,
+ " accessed by the nickname/email handle.\n");
+ PR_fprintf(PR_STDOUT,
+ "List cert numbers to keep here, or hit enter\n");
+ PR_fprintf(PR_STDOUT,
+ " to always keep only the newest cert: ");
+ break;
+ default:
+ }
+ nb = PR_Read(PR_STDIN, response, sizeof(response));
+ PR_fprintf(PR_STDOUT, "\n\n");
+ if (errtype == dbOlderCert) {
+ if (!isdigit(response[0])) {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_TRUE;
+ return PR_TRUE;
+ }
+ getCertsToDelete(response, nb, certNums, nCerts);
+ return PR_TRUE;
+ }
+ /* User doesn't want to be prompted for this type anymore. */
+ if (response[0] == 'Y') {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_FALSE;
+ return PR_FALSE;
+ } else if (response[0] == 'N') {
+ info->promptUser[errtype] = PR_FALSE;
+ info->removeType[errtype] = PR_TRUE;
+ return PR_TRUE;
+ }
+ return (response[0] != 'y') ? PR_TRUE : PR_FALSE;
+}
+
+SECStatus
+addCertToDB(certDBEntryCert *certEntry, dbRestoreInfo *info,
+ NSSLOWCERTCertDBHandle *oldhandle)
+{
+ SECStatus rv = SECSuccess;
+ PRBool allowOverride;
+ PRBool userCert;
+ SECCertTimeValidity validity;
+ CERTCertificate *oldCert = NULL;
+ CERTCertificate *dbCert = NULL;
+ CERTCertificate *newCert = NULL;
+ CERTCertTrust *trust;
+ certDBEntrySMime *smimeEntry = NULL;
+ char *email = NULL;
+ char *nickname = NULL;
+ int nCertsForSubject = 1;
+
+ oldCert = CERT_DecodeDERCertificate(&certEntry->derCert, PR_FALSE,
+ certEntry->nickname);
+ if (!oldCert) {
+ info->dbErrors[dbBadCertificate]++;
+ SEC_DestroyDBEntry((certDBEntry*)certEntry);
+ return SECSuccess;
+ }
+
+ oldCert->dbEntry = certEntry;
+ oldCert->trust = &certEntry->trust;
+ oldCert->dbhandle = oldhandle;
+
+ trust = oldCert->trust;
+
+ info->nOldCerts++;
+
+ if (info->verbose)
+ PR_fprintf(info->out, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n");
+
+ if (oldCert->nickname)
+ nickname = PORT_Strdup(oldCert->nickname);
+
+ /* Always keep user certs. Skip ahead. */
+ /* XXX if someone sends themselves a signed message, it is possible
+ for their cert to be imported as an "other" cert, not a user cert.
+ this mucks with smime entries... */
+ userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
+ if (userCert)
+ goto createcert;
+
+ /* If user chooses so, ignore expired certificates. */
+ allowOverride = (PRBool)((oldCert->keyUsage == certUsageSSLServer) ||
+ (oldCert->keyUsage == certUsageSSLServerWithStepUp));
+ validity = CERT_CheckCertValidTimes(oldCert, PR_Now(), allowOverride);
+ /* If cert expired and user wants to delete it, ignore it. */
+ if ((validity != secCertTimeValid) &&
+ userSaysDeleteCert(&oldCert, 1, dbInvalidCert, info, 0)) {
+ info->dbErrors[dbInvalidCert]++;
+ if (info->verbose) {
+ PR_fprintf(info->out, "Deleting expired certificate:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ }
+
+ /* New database will already have default certs, don't attempt
+ to overwrite them. */
+ dbCert = CERT_FindCertByDERCert(info->handle, &oldCert->derCert);
+ if (dbCert) {
+ info->nCerts++;
+ if (info->verbose) {
+ PR_fprintf(info->out, "Added certificate to database:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ }
+
+ /* Determine if cert is S/MIME and get its email if so. */
+ email = IsEmailCert(oldCert);
+
+ /*
+ XXX Just create empty profiles?
+ if (email) {
+ SECItem *profile = CERT_FindSMimeProfile(oldCert);
+ if (!profile &&
+ userSaysDeleteCert(&oldCert, 1, dbNoSMimeProfile, info, 0)) {
+ info->dbErrors[dbNoSMimeProfile]++;
+ if (info->verbose) {
+ PR_fprintf(info->out,
+ "Deleted cert missing S/MIME profile.\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+ goto cleanup;
+ } else {
+ SECITEM_FreeItem(profile);
+ }
+ }
+ */
+
+createcert:
+
+ /* Sometimes happens... */
+ if (!nickname && userCert)
+ nickname = PORT_Strdup(oldCert->subjectName);
+
+ /* Create a new certificate, copy of the old one. */
+ newCert = CERT_NewTempCertificate(info->handle, &oldCert->derCert,
+ nickname, PR_FALSE, PR_TRUE);
+ if (!newCert) {
+ PR_fprintf(PR_STDERR, "Unable to create new certificate.\n");
+ dumpCertificate(oldCert, -1, PR_STDERR);
+ info->dbErrors[dbBadCertificate]++;
+ goto cleanup;
+ }
+
+ /* Add the cert to the new database. */
+ rv = CERT_AddTempCertToPerm(newCert, nickname, oldCert->trust);
+ if (rv) {
+ PR_fprintf(PR_STDERR, "Failed to write temp cert to perm database.\n");
+ dumpCertificate(oldCert, -1, PR_STDERR);
+ info->dbErrors[dbCertNotWrittenToDB]++;
+ goto cleanup;
+ }
+
+ if (info->verbose) {
+ PR_fprintf(info->out, "Added certificate to database:\n");
+ dumpCertificate(oldCert, -1, info->out);
+ }
+
+ /* If the cert is an S/MIME cert, and the first with it's subject,
+ * modify the subject entry to include the email address,
+ * CERT_AddTempCertToPerm does not do email addresses and S/MIME entries.
+ */
+ if (smimeEntry) { /*&& !userCert && nCertsForSubject == 1) { */
+#if 0
+ UpdateSubjectWithEmailAddr(newCert, email);
+#endif
+ SECItem emailProfile, profileTime;
+ rv = CERT_FindFullSMimeProfile(oldCert, &emailProfile, &profileTime);
+ /* calls UpdateSubjectWithEmailAddr */
+ if (rv == SECSuccess)
+ rv = CERT_SaveSMimeProfile(newCert, &emailProfile, &profileTime);
+ }
+
+ info->nCerts++;
+
+cleanup:
+
+ if (nickname)
+ PORT_Free(nickname);
+ if (email)
+ PORT_Free(email);
+ if (oldCert)
+ CERT_DestroyCertificate(oldCert);
+ if (dbCert)
+ CERT_DestroyCertificate(dbCert);
+ if (newCert)
+ CERT_DestroyCertificate(newCert);
+ if (smimeEntry)
+ SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
+ return SECSuccess;
+}
+
+#if 0
+SECStatus
+copyDBEntry(SECItem *data, SECItem *key, certDBEntryType type, void *pdata)
+{
+ SECStatus rv;
+ NSSLOWCERTCertDBHandle *newdb = (NSSLOWCERTCertDBHandle *)pdata;
+ certDBEntryCommon common;
+ SECItem dbkey;
+
+ common.type = type;
+ common.version = CERT_DB_FILE_VERSION;
+ common.flags = data->data[2];
+ common.arena = NULL;
+
+ dbkey.len = key->len + SEC_DB_KEY_HEADER_LEN;
+ dbkey.data = (unsigned char *)PORT_Alloc(dbkey.len*sizeof(unsigned char));
+ PORT_Memcpy(&dbkey.data[SEC_DB_KEY_HEADER_LEN], key->data, key->len);
+ dbkey.data[0] = type;
+
+ rv = WriteDBEntry(newdb, &common, &dbkey, data);
+
+ PORT_Free(dbkey.data);
+ return rv;
+}
+#endif
+
+int
+certIsOlder(CERTCertificate **cert1, CERTCertificate** cert2)
+{
+ return !CERT_IsNewer(*cert1, *cert2);
+}
+
+int
+findNewestSubjectForEmail(NSSLOWCERTCertDBHandle *handle, int subjectNum,
+ certDBArray *dbArray, dbRestoreInfo *info,
+ int *subjectWithSMime, int *smimeForSubject)
+{
+ int newestSubject;
+ int subjectsForEmail[50];
+ int i, j, ns, sNum;
+ certDBEntryListNode *subjects = &dbArray->subjects;
+ certDBEntryListNode *smime = &dbArray->smime;
+ certDBEntrySubject *subjectEntry1, *subjectEntry2;
+ certDBEntrySMime *smimeEntry;
+ CERTCertificate **certs;
+ CERTCertificate *cert;
+ CERTCertTrust *trust;
+ PRBool userCert;
+ int *certNums;
+
+ ns = 0;
+ subjectEntry1 = (certDBEntrySubject*)&subjects.entries[subjectNum];
+ subjectsForEmail[ns++] = subjectNum;
+
+ *subjectWithSMime = -1;
+ *smimeForSubject = -1;
+ newestSubject = subjectNum;
+
+ cert = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
+ if (cert) {
+ trust = cert->trust;
+ userCert = (SEC_GET_TRUST_FLAGS(trust, trustSSL) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustEmail) & CERTDB_USER) ||
+ (SEC_GET_TRUST_FLAGS(trust, trustObjectSigning) & CERTDB_USER);
+ CERT_DestroyCertificate(cert);
+ }
+
+ /*
+ * XXX Should we make sure that subjectEntry1->emailAddr is not
+ * a null pointer or an empty string before going into the next
+ * two for loops, which pass it to PORT_Strcmp?
+ */
+
+ /* Loop over the remaining subjects. */
+ for (i=subjectNum+1; i<subjects.numEntries; i++) {
+ subjectEntry2 = (certDBEntrySubject*)&subjects.entries[i];
+ if (!subjectEntry2)
+ continue;
+ if (subjectEntry2->emailAddr && subjectEntry2->emailAddr[0] &&
+ PORT_Strcmp(subjectEntry1->emailAddr,
+ subjectEntry2->emailAddr) == 0) {
+ /* Found a subject using the same email address. */
+ subjectsForEmail[ns++] = i;
+ }
+ }
+
+ /* Find the S/MIME entry for this email address. */
+ for (i=0; i<smime.numEntries; i++) {
+ smimeEntry = (certDBEntrySMime*)&smime.entries[i];
+ if (smimeEntry->common.arena == NULL)
+ continue;
+ if (smimeEntry->emailAddr && smimeEntry->emailAddr[0] &&
+ PORT_Strcmp(subjectEntry1->emailAddr, smimeEntry->emailAddr) == 0) {
+ /* Find which of the subjects uses this S/MIME entry. */
+ for (j=0; j<ns && *subjectWithSMime < 0; j++) {
+ sNum = subjectsForEmail[j];
+ subjectEntry2 = (certDBEntrySubject*)&subjects.entries[sNum];
+ if (SECITEM_ItemsAreEqual(&smimeEntry->subjectName,
+ &subjectEntry2->derSubject)) {
+ /* Found the subject corresponding to the S/MIME entry. */
+ *subjectWithSMime = sNum;
+ *smimeForSubject = i;
+ }
+ }
+ SEC_DestroyDBEntry((certDBEntry*)smimeEntry);
+ PORT_Memset(smimeEntry, 0, sizeof(certDBEntry));
+ break;
+ }
+ }
+
+ if (ns <= 1)
+ return subjectNum;
+
+ if (userCert)
+ return *subjectWithSMime;
+
+ /* Now find which of the subjects has the newest cert. */
+ certs = (CERTCertificate**)PORT_Alloc(ns*sizeof(CERTCertificate*));
+ certNums = (int*)PORT_Alloc((ns+1)*sizeof(int));
+ certNums[0] = 0;
+ for (i=0; i<ns; i++) {
+ sNum = subjectsForEmail[i];
+ subjectEntry1 = (certDBEntrySubject*)&subjects.entries[sNum];
+ certs[i] = CERT_FindCertByKey(handle, &subjectEntry1->certKeys[0]);
+ certNums[i+1] = i;
+ }
+ /* Sort the array by validity. */
+ qsort(certs, ns, sizeof(CERTCertificate*),
+ (int (*)(const void *, const void *))certIsOlder);
+ newestSubject = -1;
+ for (i=0; i<ns; i++) {
+ sNum = subjectsForEmail[i];
+ subjectEntry1 = (certDBEntrySubject*)&subjects.entries[sNum];
+ if (SECITEM_ItemsAreEqual(&subjectEntry1->derSubject,
+ &certs[0]->derSubject))
+ newestSubject = sNum;
+ else
+ SEC_DestroyDBEntry((certDBEntry*)subjectEntry1);
+ }
+ if (info && userSaysDeleteCert(certs, ns, dbOlderCert, info, certNums)) {
+ for (i=1; i<ns+1; i++) {
+ if (certNums[i] >= 0 && certNums[i] != certNums[0]) {
+ deleteAllEntriesForCert(handle, certs[certNums[i]], info->out);
+ info->dbErrors[dbOlderCert]++;
+ }
+ }
+ }
+ CERT_DestroyCertArray(certs, ns);
+ return newestSubject;
+}
+
+NSSLOWCERTCertDBHandle *
+DBCK_ReconstructDBFromCerts(NSSLOWCERTCertDBHandle *oldhandle, char *newdbname,
+ PRFileDesc *outfile, PRBool removeExpired,
+ PRBool requireProfile, PRBool singleEntry,
+ PRBool promptUser)
+{
+ SECStatus rv;
+ dbRestoreInfo info;
+ certDBEntryContentVersion *oldContentVersion;
+ certDBArray dbArray;
+ int i;
+
+ PORT_Memset(&dbArray, 0, sizeof(dbArray));
+ PORT_Memset(&info, 0, sizeof(info));
+ info.verbose = (outfile) ? PR_TRUE : PR_FALSE;
+ info.out = (outfile) ? outfile : PR_STDOUT;
+ info.removeType[dbInvalidCert] = removeExpired;
+ info.removeType[dbNoSMimeProfile] = requireProfile;
+ info.removeType[dbOlderCert] = singleEntry;
+ info.promptUser[dbInvalidCert] = promptUser;
+ info.promptUser[dbNoSMimeProfile] = promptUser;
+ info.promptUser[dbOlderCert] = promptUser;
+
+ /* Allocate a handle to fill with CERT_OpenCertDB below. */
+ info.handle = PORT_ZNew(NSSLOWCERTCertDBHandle);
+ if (!info.handle) {
+ fprintf(stderr, "unable to get database handle");
+ return NULL;
+ }
+
+ /* Create a certdb with the most recent set of roots. */
+ rv = CERT_OpenCertDBFilename(info.handle, newdbname, PR_FALSE);
+
+ if (rv) {
+ fprintf(stderr, "could not open certificate database");
+ goto loser;
+ }
+
+ /* Create certificate, subject, nickname, and email records.
+ * mcom_db seems to have a sequential access bug. Though reads and writes
+ * should be allowed during traversal, they seem to screw up the sequence.
+ * So, stuff all the cert entries into an array, and loop over the array
+ * doing read/writes in the db.
+ */
+ fillDBEntryArray(oldhandle, certDBEntryTypeCert, &dbArray.certs);
+ for (elem = PR_LIST_HEAD(&dbArray->certs.link);
+ elem != &dbArray->certs.link; elem = PR_NEXT_LINK(elem)) {
+ node = LISTNODE_CAST(elem);
+ addCertToDB((certDBEntryCert*)&node->entry, &info, oldhandle);
+ /* entries get destroyed in addCertToDB */
+ }
+#if 0
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeSMimeProfile,
+ copyDBEntry, info.handle);
+#endif
+
+ /* Fix up the pointers between (nickname|S/MIME) --> (subject).
+ * Create S/MIME entries for S/MIME certs.
+ * Have the S/MIME entry point to the last-expiring cert using
+ * an email address.
+ */
+#if 0
+ CERT_RedoHandlesForSubjects(info.handle, singleEntry, &info);
+#endif
+
+ freeDBEntryList(&dbArray.certs.link);
+
+ /* Copy over the version record. */
+ /* XXX Already exists - and _must_ be correct... */
+ /*
+ versionEntry = ReadDBVersionEntry(oldhandle);
+ rv = WriteDBVersionEntry(info.handle, versionEntry);
+ */
+
+ /* Copy over the content version record. */
+ /* XXX Can probably get useful info from old content version?
+ * Was this db created before/after this tool? etc.
+ */
+#if 0
+ oldContentVersion = ReadDBContentVersionEntry(oldhandle);
+ CERT_SetDBContentVersion(oldContentVersion->contentVersion, info.handle);
+#endif
+
+#if 0
+ /* Copy over the CRL & KRL records. */
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeRevocation,
+ copyDBEntry, info.handle);
+ /* XXX Only one KRL, just do db->get? */
+ rv = nsslowcert_TraverseDBEntries(oldhandle, certDBEntryTypeKeyRevocation,
+ copyDBEntry, info.handle);
+#endif
+
+ PR_fprintf(info.out, "Database had %d certificates.\n", info.nOldCerts);
+
+ PR_fprintf(info.out, "Reconstructed %d certificates.\n", info.nCerts);
+ PR_fprintf(info.out, "(ax) Rejected %d expired certificates.\n",
+ info.dbErrors[dbInvalidCert]);
+ PR_fprintf(info.out, "(as) Rejected %d S/MIME certificates missing a profile.\n",
+ info.dbErrors[dbNoSMimeProfile]);
+ PR_fprintf(info.out, "(ar) Rejected %d certificates for which a newer certificate was found.\n",
+ info.dbErrors[dbOlderCert]);
+ PR_fprintf(info.out, " Rejected %d corrupt certificates.\n",
+ info.dbErrors[dbBadCertificate]);
+ PR_fprintf(info.out, " Rejected %d certificates which did not write to the DB.\n",
+ info.dbErrors[dbCertNotWrittenToDB]);
+
+ if (rv)
+ goto loser;
+
+ return info.handle;
+
+loser:
+ if (info.handle)
+ PORT_Free(info.handle);
+ return NULL;
+}
+
diff --git a/security/nss/cmd/dbck/manifest.mn b/security/nss/cmd/dbck/manifest.mn
index 79327c08e..c2405be5f 100644
--- a/security/nss/cmd/dbck/manifest.mn
+++ b/security/nss/cmd/dbck/manifest.mn
@@ -51,3 +51,4 @@ CSRCS = \
REQUIRES = dbm seccmd
PROGRAM = dbck
+USE_STATIC_LIBS = 1
diff --git a/security/nss/cmd/dbtest/Makefile b/security/nss/cmd/dbtest/Makefile
index ea25b8125..4a59c046f 100644
--- a/security/nss/cmd/dbtest/Makefile
+++ b/security/nss/cmd/dbtest/Makefile
@@ -62,16 +62,6 @@ ifdef XP_OS2_VACPP
CFLAGS += -I../modutil
endif
-ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) # omits WINCE
-ifndef BUILD_OPT
-ifndef NS_USE_GCC
-LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
-endif
-OS_CFLAGS += -D_CONSOLE
-endif
-endif
-
-
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/cmd/fipstest/Makefile b/security/nss/cmd/fipstest/Makefile
index 60f791f6c..3b8ea808a 100755
--- a/security/nss/cmd/fipstest/Makefile
+++ b/security/nss/cmd/fipstest/Makefile
@@ -62,10 +62,9 @@ include $(CORE_DEPTH)/coreconf/config.mk
include ../platlibs.mk
-#EXTRA_SHARED_LIBS += \
-# -L/usr/lib \
-# -lposix4 \
-# $(NULL)
+ifdef NSS_ENABLE_ECC
+DEFINES += -DNSS_ENABLE_ECC
+endif
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
diff --git a/security/nss/cmd/fipstest/dsa.sh b/security/nss/cmd/fipstest/dsa.sh
new file mode 100755
index 000000000..50dd20d4a
--- /dev/null
+++ b/security/nss/cmd/fipstest/dsa.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST DSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+request=KeyPair.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa keypair $request > $response
+
+request=PQGGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa pqggen $request > $response
+
+request=PQGVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa pqgver $request > $response
+
+request=SigGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa siggen $request > $response
+
+request=SigVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest dsa sigver $request > $response
diff --git a/security/nss/cmd/fipstest/ecdsa.sh b/security/nss/cmd/fipstest/ecdsa.sh
new file mode 100644
index 000000000..306c8650f
--- /dev/null
+++ b/security/nss/cmd/fipstest/ecdsa.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST ECDSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+request=KeyPair.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa keypair $request > $response
+
+request=PKV.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa pkv $request > $response
+
+request=SigGen.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa siggen $request > $response
+
+request=SigVer.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest ecdsa sigver $request > $response
diff --git a/security/nss/cmd/fipstest/fipstest.c b/security/nss/cmd/fipstest/fipstest.c
index bea7f2e72..b683cd8ee 100644
--- a/security/nss/cmd/fipstest/fipstest.c
+++ b/security/nss/cmd/fipstest/fipstest.c
@@ -41,298 +41,39 @@
#include "secitem.h"
#include "blapi.h"
#include "nss.h"
+#include "secerr.h"
+#include "secder.h"
+#include "secdig.h"
+#include "keythi.h"
+#include "ec.h"
+#include "hasht.h"
+#include "lowkeyi.h"
+#include "softoken.h"
+#include "pqgutil.h"
+
#if 0
#include "../../lib/freebl/mpi/mpi.h"
#endif
-static const unsigned char
-table3[32][8] = {
- { 0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31 },
- { 0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
- { 0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20 },
- { 0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20 },
- { 0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01 },
- { 0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01 },
- { 0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01 },
- { 0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01 },
- { 0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01 },
- { 0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40 },
- { 0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40 },
- { 0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01 },
- { 0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01 },
- { 0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01 },
- { 0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20 },
- { 0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01 },
- { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01 },
- { 0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01 },
- { 0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01 },
- { 0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01 },
- { 0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01 },
- { 0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01 },
- { 0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01 },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02 },
- { 0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04 },
- { 0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01 },
- { 0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01 }
-};
-
-static const unsigned char
-table4_key[19][8] = {
- { 0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57 },
- { 0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e },
- { 0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86 },
- { 0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e },
- { 0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6 },
- { 0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce },
- { 0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6 },
- { 0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe },
- { 0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16 },
- { 0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f },
- { 0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46 },
- { 0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e },
- { 0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76 },
- { 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07 },
- { 0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f },
- { 0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7 },
- { 0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf },
- { 0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6 },
- { 0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef }
-};
-
-static const unsigned char
-table4_inp[19][8] = {
- { 0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42 },
- { 0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda },
- { 0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72 },
- { 0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a },
- { 0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2 },
- { 0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a },
- { 0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2 },
- { 0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a },
- { 0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02 },
- { 0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a },
- { 0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32 },
- { 0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca },
- { 0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62 },
- { 0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2 },
- { 0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa },
- { 0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92 },
- { 0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a },
- { 0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2 },
- { 0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a }
-};
+#ifdef NSS_ENABLE_ECC
+extern SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams);
+extern SECStatus
+EC_CopyParams(PRArenaPool *arena, ECParams *dstParams,
+ const ECParams *srcParams);
+#endif
-static const unsigned char
-des_ecb_enc_sample_key[8] = { 0x97, 0xae, 0x43, 0x08, 0xb6, 0xa8, 0x7a, 0x08 };
-static const unsigned char
-des_ecb_enc_sample_inp[8] = { 0xcf, 0xcd, 0x91, 0xf1, 0xb3, 0x40, 0xc9, 0x91 };
-
-static const unsigned char
-des_ecb_dec_sample_key[8] = { 0x0b, 0x8c, 0x38, 0xef, 0x52, 0x01, 0xda, 0x13 };
-static const unsigned char
-des_ecb_dec_sample_inp[8] = { 0x58, 0x0b, 0x39, 0x57, 0x3d, 0x9b, 0x8d, 0xdf };
-
-static const unsigned char
-des_cbc_enc_sample_key[8] = { 0x58, 0x62, 0xd3, 0xf8, 0x04, 0xe9, 0xb3, 0x98 };
-static const unsigned char
-des_cbc_enc_sample_iv[8] = { 0xac, 0xcf, 0x45, 0x4c, 0x1a, 0x28, 0x68, 0xcf };
-static const unsigned char
-des_cbc_enc_sample_inp[8] = { 0xf1, 0x55, 0x47, 0x63, 0x76, 0x0e, 0x43, 0xa9 };
-
-static const unsigned char
-des_cbc_dec_sample_key[8] = { 0x64, 0x6d, 0x02, 0x75, 0xe9, 0x34, 0xe6, 0x7a };
-static const unsigned char
-des_cbc_dec_sample_iv[8] = { 0xb4, 0x32, 0xa3, 0x8c, 0xd5, 0xe3, 0x20, 0x1a };
-static const unsigned char
-des_cbc_dec_sample_inp[8] = { 0x5a, 0xfe, 0xe8, 0xf2, 0xf6, 0x63, 0x4f, 0xb6 };
-
-static const unsigned char
-tdea_ecb_enc_sample_key[24] = {
- 0x0b, 0x62, 0x7f, 0x67, 0xea, 0xda, 0x0b, 0x34,
- 0x08, 0x07, 0x3b, 0xc8, 0x8c, 0x23, 0x1a, 0xb6,
- 0x75, 0x0b, 0x9e, 0x57, 0x83, 0xf4, 0xe6, 0xa4 };
-static const unsigned char
-tdea_ecb_enc_sample_inp[8] = { 0x44, 0x15, 0x7a, 0xb0, 0x0a, 0x78, 0x6d, 0xbf };
-
-static const unsigned char
-tdea_ecb_dec_sample_key[24] = {
- 0x91, 0xe5, 0x07, 0xba, 0x01, 0x01, 0xb6, 0xdc,
- 0x0e, 0x51, 0xf1, 0xd0, 0x25, 0xc2, 0xc2, 0x1c,
- 0x1f, 0x54, 0x2f, 0xa1, 0xf8, 0xce, 0xda, 0x89 };
-static const unsigned char
-tdea_ecb_dec_sample_inp[8] = { 0x66, 0xe8, 0x72, 0x0d, 0x42, 0x85, 0x4b, 0xba };
-
-static const unsigned char
-tdea_cbc_enc_sample_key[24] = {
- 0xd5, 0xe5, 0x61, 0x61, 0xb0, 0xc4, 0xa4, 0x25,
- 0x45, 0x1a, 0x15, 0x67, 0xa4, 0x89, 0x6b, 0xc4,
- 0x3b, 0x54, 0x1a, 0x4c, 0x1a, 0xb5, 0x49, 0x0d };
-static const unsigned char
-tdea_cbc_enc_sample_iv[8] = { 0x5a, 0xb2, 0xa7, 0x3e, 0xc4, 0x3c, 0xe7, 0x1e };
-static const unsigned char
-tdea_cbc_enc_sample_inp[8] = { 0x9e, 0x76, 0x87, 0x7c, 0x54, 0x14, 0xab, 0x50 };
-
-static const unsigned char
-tdea_cbc_dec_sample_key[24] = {
- 0xf8, 0x25, 0xcd, 0x02, 0xc7, 0x76, 0xe6, 0xce,
- 0x9e, 0x16, 0xe6, 0x40, 0x7f, 0xcd, 0x01, 0x80,
- 0x5b, 0x38, 0xc4, 0xe0, 0xb5, 0x6e, 0x94, 0x61 };
-static const unsigned char
-tdea_cbc_dec_sample_iv[8] = { 0x74, 0x3e, 0xdc, 0xc2, 0xc6, 0xc4, 0x18, 0xe3 };
-static const unsigned char
-tdea_cbc_dec_sample_inp[8] = { 0xbe, 0x47, 0xd1, 0x77, 0xa5, 0xe8, 0x29, 0xfb };
-
-
-static const unsigned char
-des_ecb_enc_key[8] = { 0x49, 0x45, 0xd9, 0x3d, 0x83, 0xcd, 0x61, 0x9b };
-static const unsigned char
-des_ecb_enc_inp[8] = { 0x81, 0xf2, 0x12, 0x0d, 0x99, 0x04, 0x5d, 0x16 };
-
-static const unsigned char
-des_ecb_dec_key[8] = { 0x7a, 0x6b, 0x61, 0x76, 0xc8, 0x85, 0x43, 0x31 };
-static const unsigned char
-des_ecb_dec_inp[8] = { 0xef, 0xe4, 0x6e, 0x4f, 0x4f, 0xc3, 0x28, 0xcc };
-
-static const unsigned char
-des_cbc_enc_key[8] = { 0xc8, 0x5e, 0xfd, 0xa7, 0xa7, 0xc2, 0xc4, 0x0d };
-static const unsigned char
-des_cbc_enc_iv[8] = { 0x4c, 0xb9, 0xcf, 0x46, 0xff, 0x7a, 0x3d, 0xff };
-static const unsigned char
-des_cbc_enc_inp[8] = { 0x80, 0x1b, 0x24, 0x9b, 0x24, 0x0e, 0xa5, 0x96 };
-
-static const unsigned char
-des_cbc_dec_key[8] = { 0x2c, 0x3d, 0xa1, 0x67, 0x4c, 0xfb, 0x85, 0x23 };
-static const unsigned char
-des_cbc_dec_iv[8] = { 0x7a, 0x0a, 0xc2, 0x15, 0x1d, 0x22, 0x98, 0x3a };
-static const unsigned char
-des_cbc_dec_inp[8] = { 0x2d, 0x5d, 0x02, 0x04, 0x98, 0x5d, 0x5e, 0x28 };
-
-static const unsigned char
-tdea1_ecb_enc_key[24] = {
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4,
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4,
- 0x89, 0xcd, 0xd3, 0xf1, 0x01, 0xc1, 0x1a, 0xf4 };
-
-static const unsigned char
-tdea1_ecb_enc_inp[8] = { 0xe5, 0x8c, 0x48, 0xf0, 0x91, 0x4e, 0xeb, 0x87 };
-
-static const unsigned char
-tdea1_ecb_dec_key[24] = {
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37,
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37,
- 0xbf, 0x86, 0x94, 0xe0, 0x83, 0x46, 0x70, 0x37 };
-
-static const unsigned char
-tdea1_ecb_dec_inp[8] = { 0x35, 0x7a, 0x6c, 0x05, 0xe0, 0x8c, 0x3d, 0xb7 };
-
-static const unsigned char
-tdea1_cbc_enc_key[24] = {
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94,
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94,
- 0x46, 0xf1, 0x6d, 0xbf, 0xe3, 0xd5, 0xd3, 0x94 };
-
-
-static const unsigned char
-tdea1_cbc_enc_iv[8] = { 0xf7, 0x3e, 0x14, 0x05, 0x88, 0xeb, 0x2e, 0x96 };
-static const unsigned char
-tdea1_cbc_enc_inp[8] = { 0x18, 0x1b, 0xdf, 0x18, 0x10, 0xb2, 0xe0, 0x05 };
-
-static const unsigned char
-tdea1_cbc_dec_key[24] = {
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c,
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c,
- 0x83, 0xd0, 0x54, 0xa2, 0x92, 0xe9, 0x6e, 0x7c };
-
-
-static const unsigned char
-tdea1_cbc_dec_iv[8] = { 0xb9, 0x65, 0x4a, 0x94, 0xba, 0x6a, 0x66, 0xf9 };
-static const unsigned char
-tdea1_cbc_dec_inp[8] = { 0xce, 0xb8, 0x30, 0x95, 0xac, 0x82, 0xdf, 0x9b };
-
-static const unsigned char
-tdea2_ecb_enc_key[24] = {
- 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda,
- 0x16, 0x3e, 0xb5, 0xfe, 0xcd, 0x52, 0x20, 0x01,
- 0x79, 0x98, 0x4a, 0xe9, 0x23, 0xad, 0x10, 0xda };
-static const unsigned char
-tdea2_ecb_enc_inp[8] = { 0x99, 0xd2, 0xca, 0xe8, 0xa7, 0x90, 0x13, 0xc2 };
-
-static const unsigned char
-tdea2_ecb_dec_key[24] = {
- 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3,
- 0xab, 0x29, 0xe3, 0x10, 0xa2, 0x10, 0x04, 0x58,
- 0x98, 0xcd, 0x29, 0x52, 0x85, 0x91, 0x75, 0xe3 };
-
-static const unsigned char
-tdea2_ecb_dec_inp[8] = { 0xc0, 0x35, 0x24, 0x1f, 0xc9, 0x29, 0x5c, 0x7a };
-
-static const unsigned char
-tdea2_cbc_enc_key[24] = {
- 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c,
- 0xf8, 0x46, 0xa8, 0xce, 0xe6, 0xb3, 0x08, 0x02,
- 0xba, 0x5d, 0x70, 0xf8, 0x08, 0x13, 0xb0, 0x4c };
-
-
-static const unsigned char
-tdea2_cbc_enc_iv[8] = { 0xe8, 0x39, 0xd7, 0x3a, 0x8d, 0x8c, 0x59, 0x8a };
-static const unsigned char
-tdea2_cbc_enc_inp[8] = { 0x6e, 0x85, 0x0a, 0x4c, 0x86, 0x86, 0x70, 0x23 };
-
-static const unsigned char
-tdea2_cbc_dec_key[24] = {
- 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e,
- 0x46, 0x32, 0x19, 0x9b, 0xea, 0x1c, 0x19, 0xad,
- 0x25, 0xf8, 0x9e, 0x7a, 0xef, 0x26, 0xb5, 0x9e };
-
-
-static const unsigned char
-tdea2_cbc_dec_iv[8] = { 0x48, 0x07, 0x6f, 0xf9, 0x05, 0x14, 0xc1, 0xdc };
-static const unsigned char
-tdea2_cbc_dec_inp[8] = { 0x9e, 0xf4, 0x10, 0x55, 0xe8, 0x7e, 0x7e, 0x25 };
-
-static const unsigned char
-tdea3_ecb_enc_key[24] = {
- 0x6d, 0x37, 0x16, 0x31, 0x6e, 0x02, 0x83, 0xb6,
- 0xf7, 0x16, 0xa2, 0x64, 0x57, 0x8c, 0xae, 0x34,
- 0xd0, 0xce, 0x38, 0xb6, 0x31, 0x5e, 0xae, 0x1a };
-static const unsigned char
-tdea3_ecb_enc_inp[8] = { 0x28, 0x8a, 0x45, 0x22, 0x53, 0x95, 0xba, 0x3c };
-
-static const unsigned char
-tdea3_ecb_dec_key[24] = {
- 0xb0, 0x75, 0x92, 0x2c, 0xfd, 0x67, 0x8a, 0x26,
- 0xc8, 0xba, 0xad, 0x68, 0xb6, 0xba, 0x92, 0x49,
- 0xe3, 0x2c, 0xec, 0x83, 0x34, 0xe6, 0xda, 0x98 };
-static const unsigned char
-tdea3_ecb_dec_inp[8] = { 0x03, 0xcc, 0xe6, 0x65, 0xf6, 0xc5, 0xc3, 0xba };
-
-static const unsigned char
-tdea3_cbc_enc_key[24] = {
- 0x01, 0x32, 0x73, 0xe9, 0xcb, 0x8a, 0x89, 0x80,
- 0x02, 0x7a, 0xc1, 0x5d, 0xf4, 0xd5, 0x6b, 0x76,
- 0x2f, 0xef, 0xfd, 0x58, 0x57, 0x1a, 0xce, 0x29 };
-static const unsigned char
-tdea3_cbc_enc_iv[8] = { 0x93, 0x98, 0x7c, 0x66, 0x98, 0x21, 0x5b, 0x9e };
-static const unsigned char
-tdea3_cbc_enc_inp[8] = { 0x16, 0x54, 0x09, 0xd2, 0x2c, 0xad, 0x6d, 0x99 };
-
-static const unsigned char
-tdea3_cbc_dec_key[24] = {
- 0x57, 0x70, 0x3b, 0x4f, 0xae, 0xe6, 0x9d, 0x0e,
- 0x4c, 0x3b, 0x23, 0xcd, 0x54, 0x20, 0xbc, 0x58,
- 0x3b, 0x8a, 0x4a, 0xf1, 0x73, 0xf8, 0xf8, 0x38 };
-static const unsigned char
-tdea3_cbc_dec_iv[8] = { 0x5f, 0x62, 0xe4, 0xea, 0xa7, 0xb2, 0xb5, 0x70 };
-static const unsigned char
-tdea3_cbc_dec_inp[8] = { 0x44, 0xb3, 0xe6, 0x3b, 0x1f, 0xbb, 0x43, 0x02 };
+#define ENCRYPT 1
+#define DECRYPT 0
+#define BYTE unsigned char
+#define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001
+#define RSA_MAX_TEST_MODULUS_BITS 4096
+#define RSA_MAX_TEST_MODULUS_BYTES RSA_MAX_TEST_MODULUS_BITS/8
+#define RSA_MAX_TEST_EXPONENT_BYTES 8
+#define PQG_TEST_SEED_BYTES 20
SECStatus
-hex_from_2char(unsigned char *c2, unsigned char *byteval)
+hex_from_2char(const char *c2, unsigned char *byteval)
{
int i;
unsigned char offset;
@@ -355,7 +96,7 @@ hex_from_2char(unsigned char *c2, unsigned char *byteval)
}
SECStatus
-char2_from_hex(unsigned char byteval, unsigned char *c2, char a)
+char2_from_hex(unsigned char byteval, char *c2, char a)
{
int i;
unsigned char offset;
@@ -381,463 +122,778 @@ to_hex_str(char *str, const unsigned char *buf, unsigned int len)
}
void
-to_hex_str_cap(char *str, unsigned char *buf, unsigned int len)
+to_hex_str_cap(char *str, const unsigned char *buf, unsigned int len)
{
unsigned int i;
for (i=0; i<len; i++) {
char2_from_hex(buf[i], &str[2*i], 'A');
}
+ str[2*len] = '\0';
}
-void
-des_var_pt_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+/*
+ * Convert a string of hex digits (str) to an array (buf) of len bytes.
+ * Return PR_TRUE if the hex string can fit in the byte array. Return
+ * PR_FALSE if the hex string is empty or is too long.
+ */
+PRBool
+from_hex_str(unsigned char *buf, unsigned int len, const char *str)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char in[8];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(in, 0, sizeof in);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- in[mbnum] = mod_byte;
- for (i=1; i<=64; i++) {
- cx1 = DES_CreateContext(key, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(key, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, key, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, key+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, key+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, key, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- if (encrypt) {
- to_hex_str(instr, in, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- if (mod_byte > 0x01) {
- mod_byte >>= 1;
- } else {
- in[mbnum] = 0x00;
- mod_byte = 0x80;
- mbnum++;
+ unsigned int nxdigit; /* number of hex digits in str */
+ unsigned int i; /* index into buf */
+ unsigned int j; /* index into str */
+
+ /* count the hex digits */
+ nxdigit = 0;
+ for (nxdigit = 0; isxdigit(str[nxdigit]); nxdigit++) {
+ /* empty body */
+ }
+ if (nxdigit == 0) {
+ return PR_FALSE;
+ }
+ if (nxdigit > 2*len) {
+ /*
+ * The input hex string is too long, but we allow it if the
+ * extra digits are leading 0's.
+ */
+ for (j = 0; j < nxdigit-2*len; j++) {
+ if (str[j] != '0') {
+ return PR_FALSE;
+ }
}
- in[mbnum] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
+ /* skip leading 0's */
+ str += nxdigit-2*len;
+ nxdigit = 2*len;
+ }
+ for (i=0, j=0; i< len; i++) {
+ if (2*i < 2*len-nxdigit) {
+ /* Handle a short input as if we padded it with leading 0's. */
+ if (2*i+1 < 2*len-nxdigit) {
+ buf[i] = 0;
+ } else {
+ char tmp[2];
+ tmp[0] = '0';
+ tmp[1] = str[j];
+ hex_from_2char(tmp, &buf[i]);
+ j++;
+ }
+ } else {
+ hex_from_2char(&str[j], &buf[i]);
+ j += 2;
}
}
+ return PR_TRUE;
}
-void
-des_inv_perm_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+SECStatus
+tdea_encrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char in[8];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(in, 0, sizeof in);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- in[mbnum] = mod_byte;
- for (i=1; i<=64; i++) {
- if (encrypt) {
- cx1 = DES_CreateContext(key, iv, mode, PR_TRUE);
- cx2 = DES_CreateContext(key, iv, mode, PR_TRUE);
- } else {
- cx1 = DES_CreateContext(key, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, key, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, key+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, key+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, key, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- if (encrypt) {
- unsigned char inv[8];
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- DES_Encrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- DES_Decrypt(cx1, out, &olen, 8, in, 8);
- to_hex_str(instr, in, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- if (mod_byte > 0x01) {
- mod_byte >>= 1;
- } else {
- in[mbnum] = 0x00;
- mod_byte = 0x80;
- mbnum++;
- }
- in[mbnum] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
- }
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, output, outputlen, maxoutputlen, input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by decrypting the ciphertext and
+ * compare the output with the input plaintext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
}
+ return rv;
}
-void
-des_var_key_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+SECStatus
+tdea_decrypt_buf(
+ int mode,
+ const unsigned char *key,
+ const unsigned char *iv,
+ unsigned char *output, unsigned int *outputlen, unsigned int maxoutputlen,
+ const unsigned char *input, unsigned int inputlen)
{
- int i;
- unsigned int olen, mbnum = 0;
- unsigned char mod_byte = 0x80;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 1, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- keyin[mbnum] = mod_byte;
- keyin[mbnum+8] = mod_byte;
- keyin[mbnum+16] = mod_byte;
- for (i=1; i<=56; i++) {
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- DES_Encrypt(cx1, out, &olen, 8, inp, 8);
- if (encrypt) {
- to_hex_str(instr, inp, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- if (mod_byte > 0x02) {
- mod_byte >>= 1;
- } else {
- keyin[mbnum] = 0x01;
- keyin[mbnum+8] = 0x01;
- keyin[mbnum+16] = 0x01;
- mod_byte = 0x80;
- mbnum++;
- }
- keyin[mbnum] = mod_byte;
- keyin[mbnum+8] = mod_byte;
- keyin[mbnum+16] = mod_byte;
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
- }
+ SECStatus rv = SECFailure;
+ DESContext *cx;
+ unsigned char doublecheck[8*20]; /* 1 to 20 blocks */
+ unsigned int doublechecklen = 0;
+
+ cx = DES_CreateContext(key, iv, mode, PR_FALSE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Decrypt(cx, output, outputlen, maxoutputlen,
+ input, inputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (*outputlen != inputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+
+ /*
+ * Doublecheck our result by encrypting the plaintext and
+ * compare the output with the input ciphertext.
+ */
+ cx = DES_CreateContext(key, iv, mode, PR_TRUE);
+ if (cx == NULL) {
+ goto loser;
+ }
+ rv = DES_Encrypt(cx, doublecheck, &doublechecklen, sizeof doublecheck,
+ output, *outputlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (doublechecklen != *outputlen) {
+ goto loser;
+ }
+ DES_DestroyContext(cx, PR_TRUE);
+ cx = NULL;
+ if (memcmp(doublecheck, input, inputlen) != 0) {
+ goto loser;
+ }
+ rv = SECSuccess;
+
+loser:
+ if (cx != NULL) {
+ DES_DestroyContext(cx, PR_TRUE);
}
+ return rv;
}
+/*
+ * Perform the TDEA Known Answer Test (KAT) or Multi-block Message
+ * Test (MMT) in ECB or CBC mode. The KAT (there are five types)
+ * and MMT have the same structure: given the key and IV (CBC mode
+ * only), encrypt the given plaintext or decrypt the given ciphertext.
+ * So we can handle them the same way.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-des_perm_op_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+tdea_kat_mmt(char *reqfn)
{
- int i;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 0, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- for (i=0; i<32; i++) {
- memcpy(keyin, table3[i], 8);
- memcpy(keyin+8, table3[i], 8);
- memcpy(keyin+16, table3[i], 8);
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- DES_Encrypt(cx1, out, &olen, 8, inp, 8);
- if (encrypt) {
- to_hex_str(instr, inp, 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
- }
+ char buf[180]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "CIPHERTEXT = <180 hex digits>\n".
+ */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ int i, j;
+ int mode; /* NSS_DES_EDE3 (ECB) or NSS_DES_EDE3_CBC */
+ int crypt = DECRYPT; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char iv[8]; /* for all modes except ECB */
+ unsigned char plaintext[8*20]; /* 1 to 20 blocks */
+ unsigned int plaintextlen;
+ unsigned char ciphertext[8*20]; /* 1 to 20 blocks */
+ unsigned int ciphertextlen;
+ SECStatus rv;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = buf[i];
+ fputs(buf, resp);
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* mode defaults to ECB, if dataset has IV mode will be set CBC */
+ mode = NSS_DES_EDE3;
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(iv, 0, sizeof iv);
+ memset(plaintext, 0, sizeof plaintext);
+ plaintextlen = 0;
+ memset(ciphertext, 0, sizeof ciphertext);
+ ciphertextlen = 0;
+ fputs(buf, resp);
+ continue;
+ }
+ if (numKeys == 0) {
+ if (strncmp(buf, "KEYs", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ key[j+8] = key[j];
+ key[j+16] = key[j];
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ } else {
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=8; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=16; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ mode = NSS_DES_EDE3_CBC;
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ fputs(buf, resp);
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+ plaintextlen = j;
+ rv = tdea_encrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ ciphertext, &ciphertextlen, sizeof ciphertext,
+ plaintext, plaintextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("CIPHERTEXT = ", resp);
+ to_hex_str(buf, ciphertext, ciphertextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+ ciphertextlen = j;
+
+ rv = tdea_decrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ plaintext, &plaintextlen, sizeof plaintext,
+ ciphertext, ciphertextlen);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ fputs(buf, resp);
+ fputs("PLAINTEXT = ", resp);
+ to_hex_str(buf, plaintext, plaintextlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
}
+
+loser:
+ fclose(req);
}
-void
-des_sub_tbl_kat(int mode, PRBool encrypt, unsigned int len,
- unsigned char *key, unsigned char *iv,
- unsigned char *inp)
+/*
+* Set the parity bit for the given byte
+*/
+BYTE odd_parity( BYTE in)
{
- int i;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char out[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL, *cx2 = NULL;
- memset(keyin, 0, sizeof keyin);
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- for (i=0; i<19; i++) {
- memcpy(keyin, table4_key[i], 8);
- memcpy(keyin+8, table4_key[i], 8);
- memcpy(keyin+16, table4_key[i], 8);
- cx1 = DES_CreateContext(keyin, iv, mode, PR_TRUE);
- if (!encrypt) {
- cx2 = DES_CreateContext(keyin, iv, mode, PR_FALSE);
- }
- if (len > 8) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, iv, 8);
- printf("IV=%s%c", ivstr, tchar);
- }
- DES_Encrypt(cx1, out, &olen, 8, table4_inp[i], 8);
- if (encrypt) {
- to_hex_str(instr, table4_inp[i], 8);
- to_hex_str(outstr, out, 8);
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- unsigned char inv[8];
- DES_Decrypt(cx2, inv, &olen, 8, out, 8);
- to_hex_str(instr, out, 8);
- to_hex_str(outstr, inv, 8);
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- DES_DestroyContext(cx1, PR_TRUE);
- if (cx2) {
- DES_DestroyContext(cx2, PR_TRUE);
- }
- }
+ BYTE out = in;
+ in ^= in >> 4;
+ in ^= in >> 2;
+ in ^= in >> 1;
+ return (BYTE)(out ^ !(in & 1));
}
-unsigned char make_odd_parity(unsigned char b)
+/*
+ * Generate Keys [i+1] from Key[i], PT/CT[j-2], PT/CT[j-1], and PT/CT[j]
+ * for TDEA Monte Carlo Test (MCT) in ECB and CBC modes.
+ */
+void
+tdea_mct_next_keys(unsigned char *key,
+ const unsigned char *text_2, const unsigned char *text_1,
+ const unsigned char *text, unsigned int numKeys)
{
- int i;
- int sum = 0;
- for (i=1; i<8; i++) {
- sum += (b & (1 << i)) ? 1 : 0;
+ int k;
+
+ /* key1[i+1] = key1[i] xor PT/CT[j] */
+ for (k=0; k<8; k++) {
+ key[k] ^= text[k];
+ }
+ /* key2 */
+ if (numKeys == 2 || numKeys == 3) {
+ /* key2 independent */
+ for (k=8; k<16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j-1] */
+ key[k] ^= text_1[k-8];
+ }
+ } else {
+ /* key2 == key 1 */
+ for (k=8; k<16; k++) {
+ /* key2[i+1] = KEY2[i] xor PT/CT[j] */
+ key[k] = key[k-8];
+ }
}
- if (sum & 0x01) {
- return (b & 0xfe);
+ /* key3 */
+ if (numKeys == 1 || numKeys == 2) {
+ /* key3 == key 1 */
+ for (k=16; k<24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j] */
+ key[k] = key[k-16];
+ }
} else {
- return (b | 0x01);
+ /* key3 independent */
+ for (k=16; k<24; k++) {
+ /* key3[i+1] = KEY3[i] xor PT/CT[j-2] */
+ key[k] ^= text_2[k-16];
+ }
+ }
+ /* set the parity bits */
+ for (k=0; k<24; k++) {
+ key[k] = odd_parity(key[k]);
+ }
+}
+
+/*
+ * Perform the Monte Carlo Test
+ *
+ * mode = NSS_DES_EDE3 or NSS_DES_EDE3_CBC
+ * crypt = ENCRYPT || DECRYPT
+ * inputtext = plaintext or Cyphertext depending on the value of crypt
+ * inputlength is expected to be size 8 bytes
+ * iv = needs to be set for NSS_DES_EDE3_CBC mode
+ * resp = is the output response file.
+ */
+ void
+tdea_mct_test(int mode, unsigned char* key, unsigned int numKeys,
+ unsigned int crypt, unsigned char* inputtext,
+ unsigned int inputlength, unsigned char* iv, FILE *resp) {
+
+ int i, j;
+ unsigned char outputtext_1[8]; /* PT/CT[j-1] */
+ unsigned char outputtext_2[8]; /* PT/CT[j-2] */
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ unsigned int outputlen;
+ unsigned char outputtext[8];
+
+
+ SECStatus rv;
+
+ if (mode == NSS_DES_EDE3 && iv != NULL) {
+ printf("IV must be NULL for NSS_DES_EDE3 mode");
+ goto loser;
+ } else if (mode == NSS_DES_EDE3_CBC && iv == NULL) {
+ printf("IV must not be NULL for NSS_DES_EDE3_CBC mode");
+ goto loser;
+ }
+
+ /* loop 400 times */
+ for (i=0; i<400; i++) {
+ /* if i == 0 CV[0] = IV not necessary */
+ /* record the count and key values and plainText */
+ sprintf(buf, "COUNT = %d\n", i);
+ fputs(buf, resp);
+ /* Output KEY1[i] */
+ fputs("KEY1 = ", resp);
+ to_hex_str(buf, key, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY2[i] */
+ fputs("KEY2 = ", resp);
+ to_hex_str(buf, &key[8], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ /* Output KEY3[i] */
+ fputs("KEY3 = ", resp);
+ to_hex_str(buf, &key[16], 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* Output CV[i] */
+ fputs("IV = ", resp);
+ to_hex_str(buf, iv, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+ if (crypt == ENCRYPT) {
+ /* Output PT[0] */
+ fputs("PLAINTEXT = ", resp);
+ } else {
+ /* Output CT[0] */
+ fputs("CIPHERTEXT = ", resp);
+ }
+
+ to_hex_str(buf, inputtext, inputlength);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* loop 10,000 times */
+ for (j=0; j<10000; j++) {
+
+ outputlen = 0;
+ if (crypt == ENCRYPT) {
+ /* inputtext == ciphertext outputtext == plaintext*/
+ rv = tdea_encrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ } else {
+ /* inputtext == plaintext outputtext == ciphertext */
+ rv = tdea_decrypt_buf(mode, key,
+ (mode == NSS_DES_EDE3) ? NULL : iv,
+ outputtext, &outputlen, 8,
+ inputtext, 8);
+ }
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (outputlen != inputlength) {
+ goto loser;
+ }
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ if (crypt == ENCRYPT) {
+ if (j == 0) {
+ /*P[j+1] = CV[0] */
+ memcpy(inputtext, iv, 8);
+ } else {
+ /* p[j+1] = C[j-1] */
+ memcpy(inputtext, outputtext_1, 8);
+ }
+ /* CV[j+1] = C[j] */
+ memcpy(iv, outputtext, 8);
+ if (j != 9999) {
+ /* save C[j-1] */
+ memcpy(outputtext_1, outputtext, 8);
+ }
+ } else { /* DECRYPT */
+ /* CV[j+1] = C[j] */
+ memcpy(iv, inputtext, 8);
+ /* C[j+1] = P[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ } else {
+ /* ECB mode PT/CT[j+1] = CT/PT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+
+ /* Save PT/CT[j-2] and PT/CT[j-1] */
+ if (j==9997) memcpy(outputtext_2, outputtext, 8);
+ if (j==9998) memcpy(outputtext_1, outputtext, 8);
+ /* done at the end of the for(j) loop */
+ }
+
+
+ if (crypt == ENCRYPT) {
+ /* Output CT[j] */
+ fputs("CIPHERTEXT = ", resp);
+ } else {
+ /* Output PT[j] */
+ fputs("PLAINTEXT = ", resp);
+ }
+ to_hex_str(buf, outputtext, 8);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* Key[i+1] = Key[i] xor ... outputtext_2 == PT/CT[j-2]
+ * outputtext_1 == PT/CT[j-1] outputtext == PT/CT[j]
+ */
+ tdea_mct_next_keys(key, outputtext_2,
+ outputtext_1, outputtext, numKeys);
+
+ if (mode == NSS_DES_EDE3_CBC) {
+ /* taken care of in the j=9999 iteration */
+ if (crypt == ENCRYPT) {
+ /* P[i] = C[j-1] */
+ /* CV[i] = C[j] */
+ } else {
+ /* taken care of in the j=9999 iteration */
+ /* CV[i] = C[j] */
+ /* C[i] = P[j] */
+ }
+ } else {
+ /* ECB PT/CT[i] = PT/CT[j] */
+ memcpy(inputtext, outputtext, 8);
+ }
+ /* done at the end of the for(i) loop */
+ fputc('\n', resp);
}
+
+loser:
+ return;
}
+/*
+ * Perform the TDEA Monte Carlo Test (MCT) in ECB/CBC modes.
+ * by gathering the input from the request file, and then
+ * calling tdea_mct_test.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-des_modes(int mode, PRBool encrypt, unsigned int len,
- const unsigned char *key, const unsigned char *iv,
- const unsigned char *inp, int keymode)
+tdea_mct(int mode, char *reqfn)
{
int i, j;
- unsigned int olen;
- unsigned char keyin[24];
- unsigned char in[8];
- unsigned char cv[8];
- unsigned char cv0[8];
- unsigned char in0[8];
- unsigned char out[8];
- unsigned char cj9998[8], cj9997[8];
- char keystr[17], ivstr[17], instr[17], outstr[17];
- char *ptty = (len == 8) ? "PT" : "PLAINTEXT";
- char *ctty = (len == 8) ? "CT" : "CIPHERTEXT";
- char tchar = (len == 8) ? '\t' : '\n';
- DESContext *cx1 = NULL;
- memset(keystr, 0, sizeof keystr);
- memset(ivstr, 0, sizeof ivstr);
- memset(instr, 0, sizeof instr);
- memset(outstr, 0, sizeof outstr);
- memcpy(in, inp, 8);
- if (iv) memcpy(cv, iv, 8);
- memcpy(keyin, key, len);
- for (i=0; i<400; i++) {
- if (iv) memcpy(cv0, cv, 8);
- memcpy(in0, in, 8);
- for (j=0; j<10000; j++) {
- if (encrypt) {
- cx1 = DES_CreateContext(keyin, cv, mode, PR_TRUE);
- DES_Encrypt(cx1, out, &olen, 8, in, 8);
- } else {
- cx1 = DES_CreateContext(keyin, cv, mode, PR_FALSE);
- DES_Decrypt(cx1, out, &olen, 8, in, 8);
- }
- if (j==9997) memcpy(cj9997, out, 8);
- if (j==9998) memcpy(cj9998, out, 8);
- if (iv) {
- if (encrypt) {
- memcpy(in, cv, 8);
- memcpy(cv, out, 8);
- } else {
- memcpy(cv, in, 8);
- memcpy(in, out, 8);
- }
- } else {
- memcpy(in, out, 8);
- }
- DES_DestroyContext(cx1, PR_TRUE);
- }
- if (keymode > 0) {
- printf("COUNT = %d\n", i);
- to_hex_str(keystr, keyin, 8);
- printf("KEY1=%s\n", keystr);
- to_hex_str(keystr, keyin+8, 8);
- printf("KEY2=%s\n", keystr);
- to_hex_str(keystr, keyin+16, 8);
- printf("KEY3=%s\n", keystr);
- } else {
- to_hex_str(keystr, keyin, 8);
- printf("%ld\tKEY=%s\t", i, keystr);
- }
- if (iv) {
- to_hex_str(ivstr, cv0, 8);
- printf("CV=%s%c", ivstr, tchar);
- }
- to_hex_str(instr, in0, 8);
- to_hex_str(outstr, out, 8);
- if (encrypt) {
- printf("%s=%s%c%s=%s\n\n", ptty, instr, tchar, ctty, outstr);
- } else {
- printf("%s=%s%c%s=%s\n\n", ctty, instr, tchar, ptty, outstr);
- }
- for (j=0; j<8; j++) {
- keyin[j] ^= out[j];
- keyin[j] = make_odd_parity(keyin[j]);
- if (keymode == 0) continue;
- if (keymode > 1) {
- keyin[j+8] ^= cj9998[j];
- keyin[j+8] = make_odd_parity(keyin[j+8]);
- } else {
- keyin[j+8] = keyin[j];
- }
- if (keymode > 2) {
- keyin[j+16] ^= cj9997[j];
- keyin[j+16] = make_odd_parity(keyin[j+16]);
- } else {
- keyin[j+16] = keyin[j];
- }
- }
+ char buf[80]; /* holds one line from the input REQUEST file. */
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ unsigned int crypt = 0; /* 1 means encrypt, 0 means decrypt */
+ unsigned char key[24]; /* TDEA 3 key bundle */
+ unsigned int numKeys = 0;
+ unsigned char plaintext[8]; /* PT[j] */
+ unsigned char ciphertext[8]; /* CT[j] */
+ unsigned char iv[8];
+
+ /* zeroize the variables for the test with this data set */
+ memset(key, 0, sizeof key);
+ memset(plaintext, 0, sizeof plaintext);
+ memset(ciphertext, 0, sizeof ciphertext);
+ memset(iv, 0, sizeof iv);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [ENCRYPT] or [DECRYPT] */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "ENCRYPT", 7) == 0) {
+ crypt = ENCRYPT;
+ } else {
+ crypt = DECRYPT;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ /* NumKeys */
+ if (strncmp(&buf[0], "NumKeys", 7) == 0) {
+ i = 7;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ numKeys = atoi(&buf[i]);
+ continue;
+ }
+ /* KEY1 = ... */
+ if (strncmp(buf, "KEY1", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY2 = ... */
+ if (strncmp(buf, "KEY2", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=8; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+ /* KEY3 = ... */
+ if (strncmp(buf, "KEY3", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=16; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ continue;
+ }
+
+ /* IV = ... */
+ if (strncmp(buf, "IV", 2) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof iv; i+=2,j++) {
+ hex_from_2char(&buf[i], &iv[j]);
+ }
+ continue;
+ }
+
+ /* PLAINTEXT = ... */
+ if (strncmp(buf, "PLAINTEXT", 9) == 0) {
+
+ /* sanity check */
+ if (crypt != ENCRYPT) {
+ goto loser;
+ }
+ /* PT[0] = PT */
+ i = 9;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof plaintext; i+=2,j++) {
+ hex_from_2char(&buf[i], &plaintext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode==NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, plaintext, sizeof plaintext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, plaintext, sizeof plaintext, iv, resp);
+ }
+ continue;
+ }
+ /* CIPHERTEXT = ... */
+ if (strncmp(buf, "CIPHERTEXT", 10) == 0) {
+ /* sanity check */
+ if (crypt != DECRYPT) {
+ goto loser;
+ }
+ /* CT[0] = CT */
+ i = 10;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &ciphertext[j]);
+ }
+
+ /* do the Monte Carlo test */
+ if (mode==NSS_DES_EDE3) {
+ tdea_mct_test(NSS_DES_EDE3, key, numKeys, crypt, ciphertext, sizeof ciphertext, NULL, resp);
+ } else {
+ tdea_mct_test(NSS_DES_EDE3_CBC, key, numKeys, crypt, ciphertext, sizeof ciphertext, iv, resp);
+ }
+ continue;
+ }
}
+
+loser:
+ fclose(req);
}
+
SECStatus
aes_encrypt_buf(
int mode,
@@ -1797,152 +1853,6 @@ void write_compact_string(FILE *out, unsigned char *hash, unsigned int len)
fseek(out, 0, SEEK_END);
}
-void do_shs_type3(FILE *out, unsigned char *M, unsigned int len)
-{
- int i, j, a;
- unsigned char zero[30];
- unsigned char iword[4];
- unsigned int l = len;
- char hashstr[41];
- SHA1Context *cx;
- memset(zero, 0, sizeof zero);
- for (j=0; j<100; j++) {
- cx = SHA1_NewContext();
- for (i=1; i<=50000; i++) {
- SHA1_Begin(cx);
- SHA1_Update(cx, M, l);
- a = j/4 + 3;
- SHA1_Update(cx, zero, a);
- iword[3] = (char)i;
- iword[2] = (char)(i >> 8);
- iword[1] = (char)(i >> 16);
- iword[0] = (char)(i >> 24);
- SHA1_Update(cx, iword, 4);
- SHA1_End(cx, M, &l, 20);
- }
- SHA1_DestroyContext(cx, PR_TRUE);
- to_hex_str_cap(hashstr, M, l);
- hashstr[40] = '\0';
- fprintf(out, "%s ^", hashstr);
- if (j<99) fprintf(out, "\n");
- }
-}
-
-void
-shs_test(char *reqfn)
-{
- char buf[80];
- FILE *shareq, *sharesp;
- char readbuf[64];
- int i, nr;
- int newline, skip, r_z, r_b, r_n, r, b, z, n, reading;
- unsigned char hash[20];
- char hashstr[41];
- unsigned char input[13000];
- int next_bit = 0;
- int shs_type = 0;
- shareq = fopen(reqfn, "r");
- sharesp = stdout;
- newline = 1;
- reading = skip = r_z = r_b = r_n = z = r = n = 0;
- while ((nr = fread(buf, 1, sizeof buf, shareq)) > 0) {
- for (i=0; i<nr; i++) {
- if (newline) {
- if (buf[i] == '#' || buf[i] == 'D' || buf[i] == '<') {
- skip = 1;
- } else if (buf[i] == 'H') {
- skip = 0;
- shs_type++;
- fprintf(sharesp, "H>SHS Type %d Hashes<H", shs_type);
- } else if (isdigit(buf[i])) {
- r_z = 1;
- readbuf[r++] = buf[i];
- }
- newline = (buf[i] == '\n') ? 1 : 0;
- } else {
- if (buf[i] == '\n' && !r_n) {
- skip = r_z = r_n = 0;
- newline = 1;
- } else if (r_z) {
- if (buf[i] == ' ') {
- r_z = 0;
- readbuf[r] = '\0';
- z = atoi(readbuf);
- r_b = 1;
- r = 0;
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- } else if (r_b) {
- if (buf[i] == ' ') {
- r_b = 0;
- readbuf[r] = '\0';
- b = atoi(readbuf);
- r_n = 1;
- r = 0;
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- } else if (r_n) {
- if (buf[i] == ' ') {
- readbuf[r++] = '\0';
- n = atoi(readbuf);
- if (b == 0) {
- next_bit += n;
- b = 1;
- } else {
- int next_byte = next_bit / 8;
- int shift = next_bit % 8;
- unsigned char m = 0xff;
- if (n < 8 - shift) {
- m <<= (8 - n);
- m >>= shift;
- input[next_byte] |= m;
- next_bit += n;
- } else {
- m >>= shift;
- input[next_byte++] |= m;
- next_bit += 8 - shift;
- n -= (8 - shift);
- while (n > 8) {
- m = 0xff;
- input[next_byte++] |= m;
- next_bit += 8;
- n -= 8;
- }
- if (n > 0) {
- m = 0xff << (8 - n);
- input[next_byte] |= m;
- next_bit += n;
- }
- }
- b = 0;
- }
- r = 0;
- } else if (buf[i] == '^') {
- r_n = 0;
- if (shs_type < 3) {
- SHA1_HashBuf(hash, input, next_bit/8);
- to_hex_str_cap(hashstr, hash, sizeof hash);
- hashstr[40] = '\0';
- fprintf(sharesp, "%s ^", hashstr);
- memset(input, 0, sizeof input);
- next_bit = 0;
- } else {
- do_shs_type3(sharesp, input, next_bit/8);
- }
- } else if (isdigit(buf[i])) {
- readbuf[r++] = buf[i];
- }
- }
- }
- if (skip || newline) {
- fprintf(sharesp, "%c", buf[i]);
- }
- }
- }
-}
-
int get_next_line(FILE *req, char *key, char *val, FILE *rsp)
{
int ignore = 0;
@@ -1972,644 +1882,2615 @@ int get_next_line(FILE *req, char *key, char *val, FILE *rsp)
return (c == EOF) ? -1 : ignore;
}
+#ifdef NSS_ENABLE_ECC
+typedef struct curveNameTagPairStr {
+ char *curveName;
+ SECOidTag curveOidTag;
+} CurveNameTagPair;
+
+#define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP192R1
+/* #define DEFAULT_CURVE_OID_TAG SEC_OID_SECG_EC_SECP160R1 */
+
+static CurveNameTagPair nameTagPair[] =
+{
+ { "sect163k1", SEC_OID_SECG_EC_SECT163K1},
+ { "nistk163", SEC_OID_SECG_EC_SECT163K1},
+ { "sect163r1", SEC_OID_SECG_EC_SECT163R1},
+ { "sect163r2", SEC_OID_SECG_EC_SECT163R2},
+ { "nistb163", SEC_OID_SECG_EC_SECT163R2},
+ { "sect193r1", SEC_OID_SECG_EC_SECT193R1},
+ { "sect193r2", SEC_OID_SECG_EC_SECT193R2},
+ { "sect233k1", SEC_OID_SECG_EC_SECT233K1},
+ { "nistk233", SEC_OID_SECG_EC_SECT233K1},
+ { "sect233r1", SEC_OID_SECG_EC_SECT233R1},
+ { "nistb233", SEC_OID_SECG_EC_SECT233R1},
+ { "sect239k1", SEC_OID_SECG_EC_SECT239K1},
+ { "sect283k1", SEC_OID_SECG_EC_SECT283K1},
+ { "nistk283", SEC_OID_SECG_EC_SECT283K1},
+ { "sect283r1", SEC_OID_SECG_EC_SECT283R1},
+ { "nistb283", SEC_OID_SECG_EC_SECT283R1},
+ { "sect409k1", SEC_OID_SECG_EC_SECT409K1},
+ { "nistk409", SEC_OID_SECG_EC_SECT409K1},
+ { "sect409r1", SEC_OID_SECG_EC_SECT409R1},
+ { "nistb409", SEC_OID_SECG_EC_SECT409R1},
+ { "sect571k1", SEC_OID_SECG_EC_SECT571K1},
+ { "nistk571", SEC_OID_SECG_EC_SECT571K1},
+ { "sect571r1", SEC_OID_SECG_EC_SECT571R1},
+ { "nistb571", SEC_OID_SECG_EC_SECT571R1},
+ { "secp160k1", SEC_OID_SECG_EC_SECP160K1},
+ { "secp160r1", SEC_OID_SECG_EC_SECP160R1},
+ { "secp160r2", SEC_OID_SECG_EC_SECP160R2},
+ { "secp192k1", SEC_OID_SECG_EC_SECP192K1},
+ { "secp192r1", SEC_OID_SECG_EC_SECP192R1},
+ { "nistp192", SEC_OID_SECG_EC_SECP192R1},
+ { "secp224k1", SEC_OID_SECG_EC_SECP224K1},
+ { "secp224r1", SEC_OID_SECG_EC_SECP224R1},
+ { "nistp224", SEC_OID_SECG_EC_SECP224R1},
+ { "secp256k1", SEC_OID_SECG_EC_SECP256K1},
+ { "secp256r1", SEC_OID_SECG_EC_SECP256R1},
+ { "nistp256", SEC_OID_SECG_EC_SECP256R1},
+ { "secp384r1", SEC_OID_SECG_EC_SECP384R1},
+ { "nistp384", SEC_OID_SECG_EC_SECP384R1},
+ { "secp521r1", SEC_OID_SECG_EC_SECP521R1},
+ { "nistp521", SEC_OID_SECG_EC_SECP521R1},
+
+ { "prime192v1", SEC_OID_ANSIX962_EC_PRIME192V1 },
+ { "prime192v2", SEC_OID_ANSIX962_EC_PRIME192V2 },
+ { "prime192v3", SEC_OID_ANSIX962_EC_PRIME192V3 },
+ { "prime239v1", SEC_OID_ANSIX962_EC_PRIME239V1 },
+ { "prime239v2", SEC_OID_ANSIX962_EC_PRIME239V2 },
+ { "prime239v3", SEC_OID_ANSIX962_EC_PRIME239V3 },
+
+ { "c2pnb163v1", SEC_OID_ANSIX962_EC_C2PNB163V1 },
+ { "c2pnb163v2", SEC_OID_ANSIX962_EC_C2PNB163V2 },
+ { "c2pnb163v3", SEC_OID_ANSIX962_EC_C2PNB163V3 },
+ { "c2pnb176v1", SEC_OID_ANSIX962_EC_C2PNB176V1 },
+ { "c2tnb191v1", SEC_OID_ANSIX962_EC_C2TNB191V1 },
+ { "c2tnb191v2", SEC_OID_ANSIX962_EC_C2TNB191V2 },
+ { "c2tnb191v3", SEC_OID_ANSIX962_EC_C2TNB191V3 },
+ { "c2onb191v4", SEC_OID_ANSIX962_EC_C2ONB191V4 },
+ { "c2onb191v5", SEC_OID_ANSIX962_EC_C2ONB191V5 },
+ { "c2pnb208w1", SEC_OID_ANSIX962_EC_C2PNB208W1 },
+ { "c2tnb239v1", SEC_OID_ANSIX962_EC_C2TNB239V1 },
+ { "c2tnb239v2", SEC_OID_ANSIX962_EC_C2TNB239V2 },
+ { "c2tnb239v3", SEC_OID_ANSIX962_EC_C2TNB239V3 },
+ { "c2onb239v4", SEC_OID_ANSIX962_EC_C2ONB239V4 },
+ { "c2onb239v5", SEC_OID_ANSIX962_EC_C2ONB239V5 },
+ { "c2pnb272w1", SEC_OID_ANSIX962_EC_C2PNB272W1 },
+ { "c2pnb304w1", SEC_OID_ANSIX962_EC_C2PNB304W1 },
+ { "c2tnb359v1", SEC_OID_ANSIX962_EC_C2TNB359V1 },
+ { "c2pnb368w1", SEC_OID_ANSIX962_EC_C2PNB368W1 },
+ { "c2tnb431r1", SEC_OID_ANSIX962_EC_C2TNB431R1 },
+
+ { "secp112r1", SEC_OID_SECG_EC_SECP112R1},
+ { "secp112r2", SEC_OID_SECG_EC_SECP112R2},
+ { "secp128r1", SEC_OID_SECG_EC_SECP128R1},
+ { "secp128r2", SEC_OID_SECG_EC_SECP128R2},
+
+ { "sect113r1", SEC_OID_SECG_EC_SECT113R1},
+ { "sect113r2", SEC_OID_SECG_EC_SECT113R2},
+ { "sect131r1", SEC_OID_SECG_EC_SECT131R1},
+ { "sect131r2", SEC_OID_SECG_EC_SECT131R2},
+};
+
+static SECKEYECParams *
+getECParams(const char *curve)
+{
+ SECKEYECParams *ecparams;
+ SECOidData *oidData = NULL;
+ SECOidTag curveOidTag = SEC_OID_UNKNOWN; /* default */
+ int i, numCurves;
+
+ if (curve != NULL) {
+ numCurves = sizeof(nameTagPair)/sizeof(CurveNameTagPair);
+ for (i = 0; ((i < numCurves) && (curveOidTag == SEC_OID_UNKNOWN));
+ i++) {
+ if (PL_strcmp(curve, nameTagPair[i].curveName) == 0)
+ curveOidTag = nameTagPair[i].curveOidTag;
+ }
+ }
+
+ /* Return NULL if curve name is not recognized */
+ if ((curveOidTag == SEC_OID_UNKNOWN) ||
+ (oidData = SECOID_FindOIDByTag(curveOidTag)) == NULL) {
+ fprintf(stderr, "Unrecognized elliptic curve %s\n", curve);
+ return NULL;
+ }
+
+ ecparams = SECITEM_AllocItem(NULL, NULL, (2 + oidData->oid.len));
+
+ /*
+ * ecparams->data needs to contain the ASN encoding of an object ID (OID)
+ * representing the named curve. The actual OID is in
+ * oidData->oid.data so we simply prepend 0x06 and OID length
+ */
+ ecparams->data[0] = SEC_ASN1_OBJECT_ID;
+ ecparams->data[1] = oidData->oid.len;
+ memcpy(ecparams->data + 2, oidData->oid.data, oidData->oid.len);
+
+ return ecparams;
+}
+
+/*
+ * Perform the ECDSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
void
-dss_test(char *reqdir, char *rspdir)
+ecdsa_keypair_test(char *reqfn)
{
- char filename[128];
- char key[24], val[1024];
- FILE *req, *rsp;
- unsigned int mod;
- SECItem digest = { 0 }, sig = { 0 };
- DSAPublicKey pubkey = { 0 };
- DSAPrivateKey privkey = { 0 };
- PQGParams params;
- PQGVerify verify;
- unsigned int i;
- int j, rv;
- goto do_pqggen;
-#if 0
- /* primality test */
-do_prime:
- sprintf(filename, "%s/prime.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/prime.rsp", rspdir);
- rsp = fopen(filename, "w");
- while ((rv = get_next_line(req, key, val, rsp)) >= 0) {
- if (rv == 0) {
- if (strcmp(key, "mod") == 0) {
- mod = atoi(val);
- fprintf(rsp, "[mod=%d]\n", mod);
- } else if (strcmp(key, "Prime") == 0) {
- unsigned char octets[128];
- mp_int mp;
- fprintf(rsp, "Prime= %s\n", val);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, octets + i);
+ char buf[256]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams;
+ int N;
+ int i;
+ unsigned int len;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* N = x */
+ if (buf[0] == 'N') {
+ if (sscanf(buf, "N = %d", &N) != 1) {
+ goto loser;
+ }
+ for (i = 0; i < N; i++) {
+ ECPrivateKey *ecpriv;
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
}
- mp_init(&mp);
- mp_read_unsigned_octets(&mp, octets, i);
- if (mpp_pprime(&mp, 50) == MP_YES) {
- fprintf(rsp, "result= P\n");
- } else {
- fprintf(rsp, "result= F\n");
+ fputs("d = ", ecdsaresp);
+ to_hex_str(buf, ecpriv->privateValue.data,
+ ecpriv->privateValue.len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+ != SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len%2 == 0) {
+ goto loser;
}
+ len = (len-1)/2;
+ if (ecpriv->publicValue.data[0]
+ != EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputc('\n', ecdsaresp);
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
}
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ continue;
}
}
- fclose(req);
- fclose(rsp);
-#endif
-do_pqggen:
- /* PQG Gen */
- sprintf(filename, "%s/pqg.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/pqg.rsp", rspdir);
- rsp = fopen(filename, "w");
- while ((rv = get_next_line(req, key, val, rsp)) >= 0) {
- if (rv == 0) {
- if (strcmp(key, "mod") == 0) {
- mod = atoi(val);
- fprintf(rsp, "[mod=%d]\n", mod);
- } else if (strcmp(key, "N") == 0) {
- char str[264];
- unsigned int jj;
- int N = atoi(val);
- for (i=0; i<N; i++) {
- PQGParams *pqg;
- PQGVerify *vfy;
- PQG_ParamGenSeedLen(PQG_PBITS_TO_INDEX(mod), 20, &pqg, &vfy);
-#if 0
- if (!(vfy->seed.data[0] & 0x80)) {
- to_hex_str(str, vfy->seed.data, vfy->seed.len);
- fprintf(stderr, "rejected %s\n", str);
- --i;
- continue;
- }
-#endif
- to_hex_str(str, pqg->prime.data, pqg->prime.len);
- fprintf(rsp, "P= %s\n", str);
- to_hex_str(str, pqg->subPrime.data, pqg->subPrime.len);
- fprintf(rsp, "Q= %s\n", str);
- to_hex_str(str, pqg->base.data, pqg->base.len);
- fprintf(rsp, "G= %s\n", str);
- to_hex_str(str, vfy->seed.data, vfy->seed.len);
- fprintf(rsp, "Seed= %s\n", str);
- to_hex_str(str, vfy->h.data, vfy->h.len);
- fprintf(rsp, "H= ");
- for (jj=vfy->h.len; jj<pqg->prime.len; jj++) {
- fprintf(rsp, "00");
- }
- fprintf(rsp, "%s\n", str);
- fprintf(rsp, "c= %d\n", vfy->counter);
- }
+loser:
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Public Key Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_pkv_test(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Qx = <144 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ SECItem pubkey;
+ unsigned int i;
+ unsigned int len;
+ PRBool keyvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ pubkey.data = NULL;
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ len = (ecparams->fieldID.size + 7) >> 3;
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ pubkey.data = NULL;
+ }
+ SECITEM_AllocItem(NULL, &pubkey, 2*len+1);
+ if (pubkey.data == NULL) {
+ goto loser;
+ }
+ pubkey.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1], len, &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&pubkey.data[1+len], len, &buf[i]);
+ if (!keyvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ continue;
}
+ if (EC_ValidatePublicKey(ecparams, &pubkey) == SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ fputs("Result = F\n", ecdsaresp);
+ } else {
+ goto loser;
+ }
+ continue;
}
}
- fclose(req);
- fclose(rsp);
- return;
-do_pqgver:
- /* PQG Verification */
- sprintf(filename, "%s/verpqg.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/verpqg.rsp", rspdir);
- rsp = fopen(filename, "w");
- memset(&params, 0, sizeof(params));
- memset(&verify, 0, sizeof(verify));
- while ((rv = get_next_line(req, key, val, rsp)) >= 0) {
- if (rv == 0) {
- if (strcmp(key, "mod") == 0) {
- mod = atoi(val);
- fprintf(rsp, "[mod=%d]\n", mod);
- } else if (strcmp(key, "P") == 0) {
- if (params.prime.data) {
- SECITEM_ZfreeItem(&params.prime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &params.prime, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, params.prime.data + i);
- }
- fprintf(rsp, "P= %s\n", val);
- } else if (strcmp(key, "Q") == 0) {
- if (params.subPrime.data) {
- SECITEM_ZfreeItem(&params.subPrime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &params.subPrime,strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, params.subPrime.data + i);
- }
- fprintf(rsp, "Q= %s\n", val);
- } else if (strcmp(key, "G") == 0) {
- if (params.base.data) {
- SECITEM_ZfreeItem(&params.base, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &params.base, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, params.base.data + i);
- }
- fprintf(rsp, "G= %s\n", val);
- } else if (strcmp(key, "Seed") == 0) {
- if (verify.seed.data) {
- SECITEM_ZfreeItem(&verify.seed, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &verify.seed, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, verify.seed.data + i);
- }
- fprintf(rsp, "Seed= %s\n", val);
- } else if (strcmp(key, "H") == 0) {
- if (verify.h.data) {
- SECITEM_ZfreeItem(&verify.h, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &verify.h, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, verify.h.data + i);
- }
- fprintf(rsp, "H= %s\n", val);
- } else if (strcmp(key, "c") == 0) {
- SECStatus pqgrv, result;
- verify.counter = atoi(val);
- fprintf(rsp, "c= %d\n", verify.counter);
- pqgrv = PQG_VerifyParams(&params, &verify, &result);
- if (result == SECSuccess) {
- fprintf(rsp, "result= P\n");
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ }
+ if (pubkey.data != NULL) {
+ PORT_Free(pubkey.data);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_siggen_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECParams *ecparams = NULL;
+ int i, j;
+ unsigned int len;
+ unsigned char msg[512]; /* message to be signed (<= 128 bytes) */
+ unsigned int msglen;
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[2*MAX_ECKEY_LEN];
+ SECItem signature, digest;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ ecparams = NULL;
+ }
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ ECPrivateKey *ecpriv;
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ if (EC_NewKey(ecparams, &ecpriv) != SECSuccess) {
+ goto loser;
+ }
+ if (EC_ValidatePublicKey(ecparams, &ecpriv->publicValue)
+ != SECSuccess) {
+ goto loser;
+ }
+ len = ecpriv->publicValue.len;
+ if (len%2 == 0) {
+ goto loser;
+ }
+ len = (len-1)/2;
+ if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) {
+ goto loser;
+ }
+ fputs("Qx = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("Qy = ", ecdsaresp);
+ to_hex_str(buf, &ecpriv->publicValue.data[1+len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+ if (ECDSA_SignDigest(ecpriv, &signature, &digest) != SECSuccess) {
+ goto loser;
+ }
+ len = signature.len;
+ if (len%2 != 0) {
+ goto loser;
+ }
+ len = len/2;
+ fputs("R = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[0], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+ fputs("S = ", ecdsaresp);
+ to_hex_str(buf, &signature.data[len], len);
+ fputs(buf, ecdsaresp);
+ fputc('\n', ecdsaresp);
+
+ PORT_FreeArena(ecpriv->ecParams.arena, PR_TRUE);
+ continue;
+ }
+ }
+loser:
+ if (ecparams != NULL) {
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ }
+ fclose(ecdsareq);
+}
+
+/*
+ * Perform the ECDSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+ecdsa_sigver_test(char *reqfn)
+{
+ char buf[1024]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "Msg = <256 hex digits>\n".
+ */
+ FILE *ecdsareq; /* input stream from the REQUEST file */
+ FILE *ecdsaresp; /* output stream to the RESPONSE file */
+ char curve[16]; /* "nistxddd" */
+ ECPublicKey ecpub;
+ unsigned int i, j;
+ unsigned int flen; /* length in bytes of the field size */
+ unsigned int olen; /* length in bytes of the base point order */
+ unsigned char msg[512]; /* message that was signed (<= 128 bytes) */
+ unsigned int msglen;
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[2*MAX_ECKEY_LEN];
+ SECItem signature, digest;
+ PRBool keyvalid = PR_TRUE;
+ PRBool sigvalid = PR_TRUE;
+
+ ecdsareq = fopen(reqfn, "r");
+ ecdsaresp = stdout;
+ ecpub.ecParams.arena = NULL;
+ strcpy(curve, "nist");
+ while (fgets(buf, sizeof buf, ecdsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* [X-ddd] */
+ if (buf[0] == '[') {
+ const char *src;
+ char *dst;
+ SECKEYECParams *encodedparams;
+ ECParams *ecparams;
+
+ src = &buf[1];
+ dst = &curve[4];
+ *dst++ = tolower(*src);
+ src += 2; /* skip the hyphen */
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst++ = *src++;
+ *dst = '\0';
+ encodedparams = getECParams(curve);
+ if (encodedparams == NULL) {
+ goto loser;
+ }
+ if (EC_DecodeParams(encodedparams, &ecparams) != SECSuccess) {
+ goto loser;
+ }
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ if (ecpub.ecParams.arena != NULL) {
+ PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+ }
+ ecpub.ecParams.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (ecpub.ecParams.arena == NULL) {
+ goto loser;
+ }
+ if (EC_CopyParams(ecpub.ecParams.arena, &ecpub.ecParams, ecparams)
+ != SECSuccess) {
+ goto loser;
+ }
+ PORT_FreeArena(ecparams->arena, PR_FALSE);
+ flen = (ecpub.ecParams.fieldID.size + 7) >> 3;
+ olen = ecpub.ecParams.order.len;
+ if (2*olen > sizeof sig) {
+ goto loser;
+ }
+ ecpub.publicValue.type = siBuffer;
+ ecpub.publicValue.data = NULL;
+ ecpub.publicValue.len = 0;
+ SECITEM_AllocItem(ecpub.ecParams.arena,
+ &ecpub.publicValue, 2*flen+1);
+ if (ecpub.publicValue.data == NULL) {
+ goto loser;
+ }
+ ecpub.publicValue.data[0] = EC_POINT_FORM_UNCOMPRESSED;
+ fputs(buf, ecdsaresp);
+ continue;
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ msglen = j;
+ if (SHA1_HashBuf(sha1, msg, msglen) != SECSuccess) {
+ goto loser;
+ }
+ fputs(buf, ecdsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+
+ continue;
+ }
+ /* Qx = ... */
+ if (strncmp(buf, "Qx", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1], flen,
+ &buf[i]);
+ continue;
+ }
+ /* Qy = ... */
+ if (strncmp(buf, "Qy", 2) == 0) {
+ fputs(buf, ecdsaresp);
+ if (!keyvalid) {
+ continue;
+ }
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&ecpub.publicValue.data[1+flen], flen,
+ &buf[i]);
+ if (!keyvalid) {
+ continue;
+ }
+ if (EC_ValidatePublicKey(&ecpub.ecParams, &ecpub.publicValue)
+ != SECSuccess) {
+ if (PORT_GetError() == SEC_ERROR_BAD_KEY) {
+ keyvalid = PR_FALSE;
} else {
- fprintf(rsp, "result= F\n");
+ goto loser;
}
}
+ continue;
}
- }
- fclose(req);
- fclose(rsp);
- return;
-do_keygen:
- /* Key Gen */
- sprintf(filename, "%s/xy.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/xy.rsp", rspdir);
- rsp = fopen(filename, "w");
- while ((rv = get_next_line(req, key, val, rsp)) >= 0);
- for (j=0; j<=8; j++) {
- char str[264];
- PQGParams *pqg;
- PQGVerify *vfy;
- fprintf(rsp, "[mod=%d]\n", 512 + j*64);
- PQG_ParamGen(j, &pqg, &vfy);
- to_hex_str(str, pqg->prime.data, pqg->prime.len);
- fprintf(rsp, "P= %s\n", str);
- to_hex_str(str, pqg->subPrime.data, pqg->subPrime.len);
- fprintf(rsp, "Q= %s\n", str);
- to_hex_str(str, pqg->base.data, pqg->base.len);
- fprintf(rsp, "G= %s\n", str);
- for (i=0; i<10; i++) {
- DSAPrivateKey *dsakey;
- DSA_NewKey(pqg, &dsakey);
- to_hex_str(str, dsakey->privateValue.data,dsakey->privateValue.len);
- fprintf(rsp, "X= %s\n", str);
- to_hex_str(str, dsakey->publicValue.data, dsakey->publicValue.len);
- fprintf(rsp, "Y= %s\n", str);
- PORT_FreeArena(dsakey->params.arena, PR_TRUE);
- dsakey = NULL;
+ /* R = ... */
+ if (buf[0] == 'R') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ sigvalid = from_hex_str(sig, olen, &buf[i]);
+ continue;
+ }
+ /* S = ... */
+ if (buf[0] == 'S') {
+ fputs(buf, ecdsaresp);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (sigvalid) {
+ sigvalid = from_hex_str(&sig[olen], olen, &buf[i]);
+ }
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = 2*olen;
+
+ if (!keyvalid || !sigvalid) {
+ fputs("Result = F\n", ecdsaresp);
+ } else if (ECDSA_VerifyDigest(&ecpub, &signature, &digest)
+ == SECSuccess) {
+ fputs("Result = P\n", ecdsaresp);
+ } else {
+ fputs("Result = F\n", ecdsaresp);
+ }
+ continue;
}
}
- fclose(req);
- fclose(rsp);
- return;
-do_siggen:
- /* Signature Gen */
- sprintf(filename, "%s/gensig.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/gensig.rsp", rspdir);
- rsp = fopen(filename, "w");
- while ((rv = get_next_line(req, key, val, rsp)) >= 0) {
- if (rv == 0) {
- if (strcmp(key, "mod") == 0) {
- mod = atoi(val);
- fprintf(rsp, "[mod=%d]\n", mod);
- } else if (strcmp(key, "P") == 0) {
- if (privkey.params.prime.data) {
- SECITEM_ZfreeItem(&privkey.params.prime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &privkey.params.prime, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, privkey.params.prime.data + i);
- }
- fprintf(rsp, "P= %s\n", val);
- } else if (strcmp(key, "Q") == 0) {
- if (privkey.params.subPrime.data) {
- SECITEM_ZfreeItem(&privkey.params.subPrime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &privkey.params.subPrime,strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, privkey.params.subPrime.data + i);
- }
- fprintf(rsp, "Q= %s\n", val);
- } else if (strcmp(key, "G") == 0) {
- if (privkey.params.base.data) {
- SECITEM_ZfreeItem(&privkey.params.base, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &privkey.params.base, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, privkey.params.base.data + i);
- }
- fprintf(rsp, "G= %s\n", val);
- } else if (strcmp(key, "X") == 0) {
- if (privkey.privateValue.data) {
- SECITEM_ZfreeItem(&privkey.privateValue, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &privkey.privateValue, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, privkey.privateValue.data + i);
- }
- fprintf(rsp, "X= %s\n", val);
- } else if (strcmp(key, "Msg") == 0) {
- char msg[512];
- char str[81];
- if (digest.data) {
- SECITEM_ZfreeItem(&digest, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &digest, 20);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, msg + i);
- }
- msg[i] = '\0';
- /*SHA1_Hash(digest.data, msg);*/
- SHA1_HashBuf(digest.data, msg, i);
- fprintf(rsp, "Msg= %s\n", val);
- if (sig.data) {
- SECITEM_ZfreeItem(&sig, PR_FALSE);
+loser:
+ if (ecpub.ecParams.arena != NULL) {
+ PORT_FreeArena(ecpub.ecParams.arena, PR_FALSE);
+ }
+ fclose(ecdsareq);
+}
+#endif /* NSS_ENABLE_ECC */
+
+/*
+ * Perform the RNG Variable Seed Test (VST) for the RNG algorithm
+ * "DSA - Generation of X", used both as specified and as a generic
+ * purpose RNG. The presence of "Q = ..." in the REQUEST file
+ * indicates we are using the algorithm as specified.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rng_vst(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "XSeed = <128 hex digits>\n".
+ */
+ FILE *rngreq; /* input stream from the REQUEST file */
+ FILE *rngresp; /* output stream to the RESPONSE file */
+ unsigned int i, j;
+ unsigned char Q[DSA_SUBPRIME_LEN];
+ PRBool hasQ = PR_FALSE;
+ unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
+ unsigned char XKey[512/8];
+ unsigned char XSeed[512/8];
+ unsigned char GENX[2*SHA1_LENGTH];
+ unsigned char DSAX[DSA_SUBPRIME_LEN];
+ SECStatus rv;
+
+ rngreq = fopen(reqfn, "r");
+ rngresp = stdout;
+ while (fgets(buf, sizeof buf, rngreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* [Xchange - SHA1] */
+ if (buf[0] == '[') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof Q; i+=2,j++) {
+ hex_from_2char(&buf[i], &Q[j]);
+ }
+ fputs(buf, rngresp);
+ hasQ = PR_TRUE;
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ b = 0;
+ memset(XKey, 0, sizeof XKey);
+ memset(XSeed, 0, sizeof XSeed);
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* b = ... */
+ if (buf[0] == 'b') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ b = atoi(&buf[i]);
+ if (b < 160 || b > 512 || b%8 != 0) {
+ goto loser;
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XKey = ... */
+ if (strncmp(buf, "XKey", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<b/8; i+=2,j++) {
+ hex_from_2char(&buf[i], &XKey[j]);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XSeed = ... */
+ if (strncmp(buf, "XSeed", 5) == 0) {
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<b/8; i+=2,j++) {
+ hex_from_2char(&buf[i], &XSeed[j]);
+ }
+ fputs(buf, rngresp);
+
+ rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ fputs("X = ", rngresp);
+ if (hasQ) {
+ rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+ if (rv != SECSuccess) {
+ goto loser;
}
- SECITEM_AllocItem(NULL, &sig, 40);
- rv = DSA_SignDigest(&privkey, &sig, &digest);
- to_hex_str(str, sig.data, sig.len);
- fprintf(rsp, "Sig= %s\n", str);
+ to_hex_str(buf, DSAX, sizeof DSAX);
+ } else {
+ to_hex_str(buf, GENX, sizeof GENX);
}
+ fputs(buf, rngresp);
+ fputc('\n', rngresp);
+ continue;
}
}
- fclose(req);
- fclose(rsp);
-do_sigver:
- /* Signature Verification */
- sprintf(filename, "%s/versig.req", reqdir);
- req = fopen(filename, "r");
- sprintf(filename, "%s/versig.rsp", rspdir);
- rsp = fopen(filename, "w");
- while ((rv = get_next_line(req, key, val, rsp)) >= 0) {
- if (rv == 0) {
- if (strcmp(key, "mod") == 0) {
- mod = atoi(val);
- fprintf(rsp, "[mod=%d]\n", mod);
- } else if (strcmp(key, "P") == 0) {
- if (pubkey.params.prime.data) {
- SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &pubkey.params.prime, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, pubkey.params.prime.data + i);
- }
- fprintf(rsp, "P= %s\n", val);
- } else if (strcmp(key, "Q") == 0) {
- if (pubkey.params.subPrime.data) {
- SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &pubkey.params.subPrime, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, pubkey.params.subPrime.data + i);
- }
- fprintf(rsp, "Q= %s\n", val);
- } else if (strcmp(key, "G") == 0) {
- if (pubkey.params.base.data) {
- SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &pubkey.params.base, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, pubkey.params.base.data + i);
- }
- fprintf(rsp, "G= %s\n", val);
- } else if (strcmp(key, "Y") == 0) {
- if (pubkey.publicValue.data) {
- SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &pubkey.publicValue, strlen(val)/2);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, pubkey.publicValue.data + i);
- }
- fprintf(rsp, "Y= %s\n", val);
- } else if (strcmp(key, "Msg") == 0) {
- char msg[512];
- if (digest.data) {
- SECITEM_ZfreeItem(&digest, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &digest, 20);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, msg + i);
- }
- msg[i] = '\0';
- SHA1_HashBuf(digest.data, msg, i);
- /*SHA1_Hash(digest.data, msg);*/
- fprintf(rsp, "Msg= %s\n", val);
- } else if (strcmp(key, "Sig") == 0) {
- SECStatus rv;
- if (sig.data) {
- SECITEM_ZfreeItem(&sig, PR_FALSE);
- }
- SECITEM_AllocItem(NULL, &sig, 40);
- for (i=0; i<strlen(val) / 2; i++) {
- hex_from_2char(val + 2*i, sig.data + i);
+loser:
+ fclose(rngreq);
+}
+
+/*
+ * Perform the RNG Monte Carlo Test (MCT) for the RNG algorithm
+ * "DSA - Generation of X", used both as specified and as a generic
+ * purpose RNG. The presence of "Q = ..." in the REQUEST file
+ * indicates we are using the algorithm as specified.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rng_mct(char *reqfn)
+{
+ char buf[256]; /* holds one line from the input REQUEST file.
+ * needs to be large enough to hold the longest
+ * line "XSeed = <128 hex digits>\n".
+ */
+ FILE *rngreq; /* input stream from the REQUEST file */
+ FILE *rngresp; /* output stream to the RESPONSE file */
+ unsigned int i, j;
+ unsigned char Q[DSA_SUBPRIME_LEN];
+ PRBool hasQ = PR_FALSE;
+ unsigned int b; /* 160 <= b <= 512, b is a multiple of 8 */
+ unsigned char XKey[512/8];
+ unsigned char XSeed[512/8];
+ unsigned char GENX[2*SHA1_LENGTH];
+ unsigned char DSAX[DSA_SUBPRIME_LEN];
+ SECStatus rv;
+
+ rngreq = fopen(reqfn, "r");
+ rngresp = stdout;
+ while (fgets(buf, sizeof buf, rngreq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* [Xchange - SHA1] */
+ if (buf[0] == '[') {
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof Q; i+=2,j++) {
+ hex_from_2char(&buf[i], &Q[j]);
+ }
+ fputs(buf, rngresp);
+ hasQ = PR_TRUE;
+ continue;
+ }
+ /* "COUNT = x" begins a new data set */
+ if (strncmp(buf, "COUNT", 5) == 0) {
+ /* zeroize the variables for the test with this data set */
+ b = 0;
+ memset(XKey, 0, sizeof XKey);
+ memset(XSeed, 0, sizeof XSeed);
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* b = ... */
+ if (buf[0] == 'b') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ b = atoi(&buf[i]);
+ if (b < 160 || b > 512 || b%8 != 0) {
+ goto loser;
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XKey = ... */
+ if (strncmp(buf, "XKey", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<b/8; i+=2,j++) {
+ hex_from_2char(&buf[i], &XKey[j]);
+ }
+ fputs(buf, rngresp);
+ continue;
+ }
+ /* XSeed = ... */
+ if (strncmp(buf, "XSeed", 5) == 0) {
+ unsigned int k;
+ i = 5;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<b/8; i+=2,j++) {
+ hex_from_2char(&buf[i], &XSeed[j]);
+ }
+ fputs(buf, rngresp);
+
+ for (k = 0; k < 10000; k++) {
+ rv = FIPS186Change_GenerateX(XKey, XSeed, GENX);
+ if (rv != SECSuccess) {
+ goto loser;
}
- rv = DSA_VerifyDigest(&pubkey, &sig, &digest);
- fprintf(rsp, "Sig= %s\n", val);
- if (rv == SECSuccess) {
- fprintf(rsp, "result= P\n");
- } else {
- fprintf(rsp, "result= F\n");
+ }
+ fputs("X = ", rngresp);
+ if (hasQ) {
+ rv = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX);
+ if (rv != SECSuccess) {
+ goto loser;
}
+ to_hex_str(buf, DSAX, sizeof DSAX);
+ } else {
+ to_hex_str(buf, GENX, sizeof GENX);
}
+ fputs(buf, rngresp);
+ fputc('\n', rngresp);
+ continue;
}
}
+loser:
+ fclose(rngreq);
+}
+
+/*
+ * Calculate the SHA Message Digest
+ *
+ * MD = Message digest
+ * MDLen = length of Message Digest and SHA_Type
+ * msg = message to digest
+ * msgLen = length of message to digest
+ */
+SECStatus sha_calcMD(unsigned char *MD, unsigned int MDLen, unsigned char *msg, unsigned int msgLen)
+{
+ SECStatus sha_status = SECFailure;
+
+ if (MDLen == SHA1_LENGTH) {
+ sha_status = SHA1_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA256_LENGTH) {
+ sha_status = SHA256_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA384_LENGTH) {
+ sha_status = SHA384_HashBuf(MD, msg, msgLen);
+ } else if (MDLen == SHA512_LENGTH) {
+ sha_status = SHA512_HashBuf(MD, msg, msgLen);
+ }
+
+ return sha_status;
+}
+
+/*
+ * Perform the SHA Monte Carlo Test
+ *
+ * MDLen = length of Message Digest and SHA_Type
+ * seed = input seed value
+ * resp = is the output response file.
+ */
+SECStatus sha_mct_test(unsigned int MDLen, unsigned char *seed, FILE *resp)
+{
+ int i, j;
+ unsigned int msgLen = MDLen*3;
+ unsigned char MD_i3[HASH_LENGTH_MAX]; /* MD[i-3] */
+ unsigned char MD_i2[HASH_LENGTH_MAX]; /* MD[i-2] */
+ unsigned char MD_i1[HASH_LENGTH_MAX]; /* MD[i-1] */
+ unsigned char MD_i[HASH_LENGTH_MAX]; /* MD[i] */
+ unsigned char msg[HASH_LENGTH_MAX*3];
+ char buf[HASH_LENGTH_MAX*2 + 1]; /* MAX buf MD_i as a hex string */
+
+ for (j=0; j<100; j++) {
+ /* MD_0 = MD_1 = MD_2 = seed */
+ memcpy(MD_i3, seed, MDLen);
+ memcpy(MD_i2, seed, MDLen);
+ memcpy(MD_i1, seed, MDLen);
+
+ for (i=3; i < 1003; i++) {
+ /* Mi = MD[i-3] || MD [i-2] || MD [i-1] */
+ memcpy(msg, MD_i3, MDLen);
+ memcpy(&msg[MDLen], MD_i2, MDLen);
+ memcpy(&msg[MDLen*2], MD_i1,MDLen);
+
+ /* MDi = SHA(Msg) */
+ if (sha_calcMD(MD_i, MDLen,
+ msg, msgLen) != SECSuccess) {
+ return SECFailure;
+ }
+
+ /* save MD[i-3] MD[i-2] MD[i-1] */
+ memcpy(MD_i3, MD_i2, MDLen);
+ memcpy(MD_i2, MD_i1, MDLen);
+ memcpy(MD_i1, MD_i, MDLen);
+
+ }
+
+ /* seed = MD_i */
+ memcpy(seed, MD_i, MDLen);
+
+ sprintf(buf, "COUNT = %d\n", j);
+ fputs(buf, resp);
+
+ /* output MD_i */
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD_i, MDLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * Perform the SHA Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void sha_test(char *reqfn)
+{
+ unsigned int i, j;
+ unsigned int MDlen; /* the length of the Message Digest in Bytes */
+ unsigned int msgLen; /* the length of the input Message in Bytes */
+ unsigned char *msg = NULL; /* holds the message to digest.*/
+ size_t bufSize = 25608; /*MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned char seed[HASH_LENGTH_MAX]; /* max size of seed 64 bytes */
+ unsigned char MD[HASH_LENGTH_MAX]; /* message digest */
+
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+
+ /* zeroize the variables for the test with this data set */
+ memset(seed, 0, sizeof seed);
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the Message Digest and sha_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ MDlen = atoi(&buf[i]);
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Len = Length of the Input Message Length ... */
+ if (strncmp(buf, "Len", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ if (msg) {
+ PORT_ZFree(msg,msgLen);
+ msg = NULL;
+ }
+ msgLen = atoi(&buf[i]); /* in bits */
+ msgLen = msgLen/8; /* convert to bytes */
+ fputs(buf, resp);
+ msg = PORT_ZAlloc(msgLen);
+ if (msg == NULL && msgLen != 0) {
+ goto loser;
+ }
+ continue;
+ }
+ /* MSG = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< msgLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the Message Digest */
+ memset(MD, 0, sizeof MD);
+ if (sha_calcMD(MD, MDlen,
+ msg, msgLen) != SECSuccess) {
+ goto loser;
+ }
+
+ fputs("MD = ", resp);
+ to_hex_str(buf, MD, MDlen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ continue;
+ }
+ /* Seed = ... */
+ if (strncmp(buf, "Seed", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j<sizeof seed; i+=2,j++) {
+ hex_from_2char(&buf[i], &seed[j]);
+ }
+
+ fputs(buf, resp);
+ fputc('\n', resp);
+
+ /* do the Monte Carlo test */
+ if (sha_mct_test(MDlen, seed, resp) != SECSuccess) {
+ goto loser;
+ }
+
+ continue;
+ }
+ }
+loser:
fclose(req);
- fclose(rsp);
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
}
-void do_random()
+/****************************************************/
+/* HMAC SHA-X calc */
+/* hmac_computed - the computed HMAC */
+/* hmac_length - the length of the computed HMAC */
+/* secret_key - secret key to HMAC */
+/* secret_key_length - length of secret key, */
+/* message - message to HMAC */
+/* message_length - length ofthe message */
+/****************************************************/
+static SECStatus
+hmac_calc(unsigned char *hmac_computed,
+ const unsigned int hmac_length,
+ const unsigned char *secret_key,
+ const unsigned int secret_key_length,
+ const unsigned char *message,
+ const unsigned int message_length,
+ const HASH_HashType hashAlg )
{
- int i, j, k = 0;
- unsigned char buf[500];
- for (i=0; i<5; i++) {
- RNG_GenerateGlobalRandomBytes(buf, sizeof buf);
- for (j=0; j<sizeof buf / 2; j++) {
- printf("0x%02x%02x", buf[2*j], buf[2*j+1]);
- if (++k % 8 == 0) printf("\n"); else printf(" ");
- }
+ SECStatus hmac_status = SECFailure;
+ HMACContext *cx = NULL;
+ SECHashObject *hashObj = NULL;
+ unsigned int bytes_hashed = 0;
+
+ hashObj = (SECHashObject *) HASH_GetRawHashObject(hashAlg);
+
+ if (!hashObj)
+ return( SECFailure );
+
+ cx = HMAC_Create(hashObj, secret_key,
+ secret_key_length,
+ PR_TRUE); /* PR_TRUE for in FIPS mode */
+
+ if (cx == NULL)
+ return( SECFailure );
+
+ HMAC_Begin(cx);
+ HMAC_Update(cx, message, message_length);
+ hmac_status = HMAC_Finish(cx, hmac_computed, &bytes_hashed,
+ hmac_length);
+
+ HMAC_Destroy(cx, PR_TRUE);
+
+ return( hmac_status );
+}
+
+/*
+ * Perform the HMAC Tests.
+ *
+ * reqfn is the pathname of the input REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void hmac_test(char *reqfn)
+{
+ unsigned int i, j;
+ size_t bufSize = 288; /* MAX buffer size */
+ char *buf = NULL; /* holds one line from the input REQUEST file.*/
+ unsigned int keyLen; /* Key Length */
+ unsigned char key[140]; /* key MAX size = 140 */
+ unsigned int msgLen = 128; /* the length of the input */
+ /* Message is always 128 Bytes */
+ unsigned char *msg = NULL; /* holds the message to digest.*/
+ unsigned int HMACLen; /* the length of the HMAC Bytes */
+ unsigned char HMAC[HASH_LENGTH_MAX]; /* computed HMAC */
+ HASH_HashType hash_alg; /* HMAC type */
+
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+
+ buf = PORT_ZAlloc(bufSize);
+ if (buf == NULL) {
+ goto loser;
+ }
+ msg = PORT_ZAlloc(msgLen);
+ memset(msg, 0, msgLen);
+ if (msg == NULL) {
+ goto loser;
+ }
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ while (fgets(buf, bufSize, req) != NULL) {
+
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, resp);
+ continue;
+ }
+ /* [L = Length of the MAC and HASH_type */
+ if (buf[0] == '[') {
+ if (strncmp(&buf[1], "L ", 1) == 0) {
+ i = 2;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* HMACLen will get reused for Tlen */
+ HMACLen = atoi(&buf[i]);
+ /* set the HASH algorithm for HMAC */
+ if (HMACLen == SHA1_LENGTH) {
+ hash_alg = HASH_AlgSHA1;
+ } else if (HMACLen == SHA256_LENGTH) {
+ hash_alg = HASH_AlgSHA256;
+ } else if (HMACLen == SHA384_LENGTH) {
+ hash_alg = HASH_AlgSHA384;
+ } else if (HMACLen == SHA512_LENGTH) {
+ hash_alg = HASH_AlgSHA512;
+ } else {
+ goto loser;
+ }
+ fputs(buf, resp);
+ continue;
+ }
+ }
+ /* Count = test iteration number*/
+ if (strncmp(buf, "Count ", 5) == 0) {
+ /* count can just be put into resp file */
+ fputs(buf, resp);
+ /* zeroize the variables for the test with this data set */
+ keyLen = 0;
+ HMACLen = 0;
+ memset(key, 0, sizeof key);
+ memset(msg, 0, sizeof msg);
+ memset(HMAC, 0, sizeof HMAC);
+ continue;
+ }
+ /* KLen = Length of the Input Secret Key ... */
+ if (strncmp(buf, "Klen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* key = the secret key for the key to MAC */
+ if (strncmp(buf, "Key", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< keyLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &key[j]);
+ }
+ fputs(buf, resp);
+ }
+ /* TLen = Length of the calculated HMAC */
+ if (strncmp(buf, "Tlen", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ HMACLen = atoi(&buf[i]); /* in bytes */
+ fputs(buf, resp);
+ continue;
+ }
+ /* MSG = to HMAC always 128 bytes for these tests */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< msgLen; i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ fputs(buf, resp);
+ /* calculate the HMAC and output */
+ if (hmac_calc(HMAC, HMACLen, key, keyLen,
+ msg, msgLen, hash_alg) != SECSuccess) {
+ goto loser;
+ }
+ fputs("MAC = ", resp);
+ to_hex_str(buf, HMAC, HMACLen);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ continue;
+ }
+ }
+loser:
+ fclose(req);
+ if (buf) {
+ PORT_ZFree(buf, bufSize);
+ }
+ if (msg) {
+ PORT_ZFree(msg, msgLen);
+ }
+}
+
+/*
+ * Perform the DSA Key Pair Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_keypair_test(char *reqfn)
+{
+ char buf[260]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 257 to hold (128 public key (x2 for HEX) + 1'\n'
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int N; /* number of time to generate key pair */
+ int modulus;
+ int i;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ int keySizeIndex; /* index for valid key sizes */
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+ if(pqg!=NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if(vfy!=NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ /*****************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
+ * that points to a valid key size.
+ */
+ keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
+ if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+
+ /* Generate the parameters P, Q, and G */
+ if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+
+ /* output P, Q, and G */
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n\n", buf);
+ continue;
+ }
+ /* N = ...*/
+ if (buf[0] == 'N') {
+
+ if (sscanf(buf, "N = %d", &N) != 1) {
+ goto loser;
+ }
+ /* Generate a DSA key, and output the key pair for N times */
+ for (i = 0; i < N; i++) {
+ DSAPrivateKey *dsakey = NULL;
+ if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA key");
+ goto loser;
+ }
+ to_hex_str(buf, dsakey->privateValue.data,
+ dsakey->privateValue.len);
+ fprintf(dsaresp, "X = %s\n", buf);
+ to_hex_str(buf, dsakey->publicValue.data,
+ dsakey->publicValue.len);
+ fprintf(dsaresp, "Y = %s\n\n", buf);
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+ continue;
+ }
+
+ }
+loser:
+ fclose(dsareq);
+}
+
+/*
+ * Perform the DSA Domain Parameter Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_pqgver_test(char *reqfn)
+{
+ char buf[263]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 260 to hold (128 public key (x2 for HEX) + P = ...
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int modulus;
+ unsigned int i, j;
+ PQGParams pqg;
+ PQGVerify vfy;
+ unsigned int pghSize; /* size for p, g, and h */
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ memset(&pqg, 0, sizeof(pqg));
+ memset(&vfy, 0, sizeof(vfy));
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+
+ if (pqg.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
+ }
+ if (pqg.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
+ }
+ if (pqg.base.data) { /* G */
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
+ }
+ if (vfy.seed.data) { /* seed */
+ SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
+ }
+ if (vfy.h.data) { /* H */
+ SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
+ }
+
+ fputs(buf, dsaresp);
+
+ /*calculate the size of p, g, and h then allocate items */
+ pghSize = modulus/8;
+ SECITEM_AllocItem(NULL, &pqg.prime, pghSize);
+ SECITEM_AllocItem(NULL, &pqg.base, pghSize);
+ SECITEM_AllocItem(NULL, &vfy.h, pghSize);
+ pqg.prime.len = pqg.base.len = vfy.h.len = pghSize;
+ /* seed and q are always 20 bytes */
+ SECITEM_AllocItem(NULL, &vfy.seed, 20);
+ SECITEM_AllocItem(NULL, &pqg.subPrime, 20);
+ vfy.seed.len = pqg.subPrime.len = 20;
+ vfy.counter = 0;
+
+ continue;
+ }
+ /* P = ... */
+ if (buf[0] == 'P') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< pqg.prime.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pqg.prime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< pqg.subPrime.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pqg.subPrime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* G = ... */
+ if (buf[0] == 'G') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< pqg.base.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pqg.base.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Seed = ... */
+ if (strncmp(buf, "Seed", 4) == 0) {
+ i = 4;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< vfy.seed.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &vfy.seed.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* c = ... */
+ if (buf[0] == 'c') {
+
+ if (sscanf(buf, "c = %u", &vfy.counter) != 1) {
+ goto loser;
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* H = ... */
+ if (buf[0] == 'H') {
+ SECStatus rv, result = SECFailure;
+
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< vfy.h.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &vfy.h.data[j]);
+ }
+ fputs(buf, dsaresp);
+
+ /* Verify the Parameters */
+ rv = PQG_VerifyParams(&pqg, &vfy, &result);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (result == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pqg.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pqg.prime, PR_FALSE);
+ }
+ if (pqg.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pqg.subPrime, PR_FALSE);
+ }
+ if (pqg.base.data) { /* G */
+ SECITEM_ZfreeItem(&pqg.base, PR_FALSE);
+ }
+ if (vfy.seed.data) { /* seed */
+ SECITEM_ZfreeItem(&vfy.seed, PR_FALSE);
+ }
+ if (vfy.h.data) { /* H */
+ SECITEM_ZfreeItem(&vfy.h, PR_FALSE);
+ }
+
+}
+
+/*
+ * Perform the DSA Public Key Validation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_pqggen_test(char *reqfn)
+{
+ char buf[263]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 263 to hold seed = (128 public key (x2 for HEX)
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int N; /* number of times to generate parameters */
+ int modulus;
+ int i;
+ unsigned int j;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ unsigned int keySizeIndex;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = ... ] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ /****************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
+ * that points to a valid key size.
+ */
+ keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
+ if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+
+ continue;
+ }
+ /* N = ... */
+ if (buf[0] == 'N') {
+
+ if (sscanf(buf, "N = %d", &N) != 1) {
+ goto loser;
+ }
+ for (i = 0; i < N; i++) {
+ if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy) != SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n", buf);
+ to_hex_str(buf, vfy->seed.data, vfy->seed.len);
+ fprintf(dsaresp, "Seed = %s\n", buf);
+ fprintf(dsaresp, "c = %d\n", vfy->counter);
+ to_hex_str(buf, vfy->h.data, vfy->h.len);
+ fputs("H = ", dsaresp);
+ for (j=vfy->h.len; j<pqg->prime.len; j++) {
+ fprintf(dsaresp, "00");
+ }
+ fprintf(dsaresp, "%s\n", buf);
+ fputc('\n', dsaresp);
+ if(pqg!=NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if(vfy!=NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ }
+
+ continue;
+ }
+
+ }
+loser:
+ fclose(dsareq);
+ if(pqg!=NULL) {
+ PQG_DestroyParams(pqg);
+ }
+ if(vfy!=NULL) {
+ PQG_DestroyVerify(vfy);
+ }
+}
+
+/*
+ * Perform the DSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_siggen_test(char *reqfn)
+{
+ char buf[263]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * max for Msg = ....
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int modulus;
+ int i, j;
+ PQGParams *pqg = NULL;
+ PQGVerify *vfy = NULL;
+ DSAPrivateKey *dsakey = NULL;
+ int keySizeIndex; /* index for valid key sizes */
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[DSA_SIGNATURE_LEN];
+ SECItem digest, signature;
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+ if(pqg!=NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if(vfy!=NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ if (dsakey != NULL) {
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+
+ /****************************************************************
+ * PQG_ParamGenSeedLen doesn't take a key size, it takes an index
+ * that points to a valid key size.
+ */
+ keySizeIndex = PQG_PBITS_TO_INDEX(modulus);
+ if(keySizeIndex == -1 || modulus<512 || modulus>1024) {
+ fprintf(dsaresp,
+ "DSA key size must be a multiple of 64 between 512 "
+ "and 1024, inclusive");
+ goto loser;
+ }
+
+ /* Generate PQG and output PQG */
+ if (PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
+ &pqg, &vfy) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate PQG parameters");
+ goto loser;
+ }
+ to_hex_str(buf, pqg->prime.data, pqg->prime.len);
+ fprintf(dsaresp, "P = %s\n", buf);
+ to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
+ fprintf(dsaresp, "Q = %s\n", buf);
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n", buf);
+
+ /* create DSA Key */
+ if (DSA_NewKey(pqg, &dsakey) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA key");
+ goto loser;
+ }
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+ unsigned int len = 0;
+
+ memset(sha1, 0, sizeof sha1);
+ memset(sig, 0, sizeof sig);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ if (SHA1_HashBuf(sha1, msg, j) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate SHA1 digest");
+ goto loser;
+ }
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+
+ if (DSA_SignDigest(dsakey, &signature, &digest) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate DSA signature");
+ goto loser;
+ }
+ len = signature.len;
+ if (len%2 != 0) {
+ goto loser;
+ }
+ len = len/2;
+
+ /* output the orginal Msg, and generated Y, R, and S */
+ fputs(buf, dsaresp);
+ fputc('\n', dsaresp);
+ to_hex_str(buf, dsakey->publicValue.data,
+ dsakey->publicValue.len);
+ fprintf(dsaresp, "Y = %s\n", buf);
+ to_hex_str(buf, &signature.data[0], len);
+ fprintf(dsaresp, "R = %s\n", buf);
+ to_hex_str(buf, &signature.data[len], len);
+ fprintf(dsaresp, "S = %s\n", buf);
+ continue;
+ }
+
+ }
+loser:
+ fclose(dsareq);
+ if(pqg != NULL) {
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ }
+ if(vfy != NULL) {
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
+ }
+ if (dsaKey) {
+ PORT_FreeArena(dsakey->params.arena, PR_TRUE);
+ dsakey = NULL;
+ }
+}
+
+ /*
+ * Perform the DSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+dsa_sigver_test(char *reqfn)
+{
+ char buf[263]; /* holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * max for Msg = ....
+ */
+ FILE *dsareq; /* input stream from the REQUEST file */
+ FILE *dsaresp; /* output stream to the RESPONSE file */
+ int modulus;
+ unsigned int i, j;
+ SECItem digest, signature;
+ DSAPublicKey pubkey;
+ unsigned int pgySize; /* size for p, g, and y */
+ unsigned char sha1[20]; /* SHA-1 hash (160 bits) */
+ unsigned char sig[DSA_SIGNATURE_LEN];
+
+ dsareq = fopen(reqfn, "r");
+ dsaresp = stdout;
+ memset(&pubkey, 0, sizeof(pubkey));
+
+ while (fgets(buf, sizeof buf, dsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* [Mod = x] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+
+ if (pubkey.params.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
+ }
+ if (pubkey.params.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
+ }
+ if (pubkey.params.base.data) { /* G */
+ SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
+ }
+ if (pubkey.publicValue.data) { /* Y */
+ SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
+ }
+ fputs(buf, dsaresp);
+
+ /* calculate the size of p, g, and y then allocate items */
+ pgySize = modulus/8;
+ SECITEM_AllocItem(NULL, &pubkey.params.prime, pgySize);
+ SECITEM_AllocItem(NULL, &pubkey.params.base, pgySize);
+ SECITEM_AllocItem(NULL, &pubkey.publicValue, pgySize);
+ pubkey.params.prime.len = pubkey.params.base.len = pgySize;
+ pubkey.publicValue.len = pgySize;
+
+ /* q always 20 bytes */
+ SECITEM_AllocItem(NULL, &pubkey.params.subPrime, 20);
+ pubkey.params.subPrime.len = 20;
+
+ continue;
+ }
+ /* P = ... */
+ if (buf[0] == 'P') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.prime.data, 0, pubkey.params.prime.len);
+ for (j=0; j< pubkey.params.prime.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pubkey.params.prime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Q = ... */
+ if (buf[0] == 'Q') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.subPrime.data, 0, pubkey.params.subPrime.len);
+ for (j=0; j< pubkey.params.subPrime.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pubkey.params.subPrime.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* G = ... */
+ if (buf[0] == 'G') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.params.base.data, 0, pubkey.params.base.len);
+ for (j=0; j< pubkey.params.base.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pubkey.params.base.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+ memset(sha1, 0, sizeof sha1);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+ if (SHA1_HashBuf(sha1, msg, j) != SECSuccess) {
+ fprintf(dsaresp, "ERROR: Unable to generate SHA1 digest");
+ goto loser;
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* Y = ... */
+ if (buf[0] == 'Y') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ memset(pubkey.publicValue.data, 0, pubkey.params.subPrime.len);
+ for (j=0; j< pubkey.publicValue.len; i+=2,j++) {
+ hex_from_2char(&buf[i], &pubkey.publicValue.data[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* R = ... */
+ if (buf[0] == 'R') {
+ memset(sig, 0, sizeof sig);
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; j< DSA_SUBPRIME_LEN; i+=2,j++) {
+ hex_from_2char(&buf[i], &sig[j]);
+ }
+
+ fputs(buf, dsaresp);
+ continue;
+ }
+
+ /* S = ... */
+ if (buf[0] == 'S') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=DSA_SUBPRIME_LEN; j< DSA_SIGNATURE_LEN; i+=2,j++) {
+ hex_from_2char(&buf[i], &sig[j]);
+ }
+ fputs(buf, dsaresp);
+
+ digest.type = siBuffer;
+ digest.data = sha1;
+ digest.len = sizeof sha1;
+ signature.type = siBuffer;
+ signature.data = sig;
+ signature.len = sizeof sig;
+
+ if (DSA_VerifyDigest(&pubkey, &signature, &digest) == SECSuccess) {
+ fprintf(dsaresp, "Result = P\n");
+ } else {
+ fprintf(dsaresp, "Result = F\n");
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(dsareq);
+ if (pubkey.params.prime.data) { /* P */
+ SECITEM_ZfreeItem(&pubkey.params.prime, PR_FALSE);
+ }
+ if (pubkey.params.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&pubkey.params.subPrime, PR_FALSE);
+ }
+ if (pubkey.params.base.data) { /* G */
+ SECITEM_ZfreeItem(&pubkey.params.base, PR_FALSE);
+ }
+ if (pubkey.publicValue.data) { /* Y */
+ SECITEM_ZfreeItem(&pubkey.publicValue, PR_FALSE);
+ }
+}
+
+/*
+ * Perform the RSA Signature Generation Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_siggen_test(char *reqfn)
+{
+ char buf[2*RSA_MAX_TEST_MODULUS_BYTES+1];
+ /* buf holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * 2x for HEX output + 1 for \n
+ */
+ FILE *rsareq; /* input stream from the REQUEST file */
+ FILE *rsaresp; /* output stream to the RESPONSE file */
+ int i, j;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* length of SHA */
+ HASH_HashType shaAlg = HASH_AlgNULL; /* type of SHA Alg */
+ SECOidTag shaOid = SEC_OID_UNKNOWN;
+ int modulus; /* the Modulus size */
+ int publicExponent = DEFAULT_RSA_PUBLIC_EXPONENT;
+ SECItem pe = {0, 0, 0 };
+ unsigned char pubEx[4];
+ int peCount = 0;
+
+ RSAPrivateKey *rsaBlapiPrivKey = NULL; /* holds RSA private and
+ * public keys */
+ RSAPublicKey *rsaBlapiPublicKey = NULL; /* hold RSA public key */
+
+ rsareq = fopen(reqfn, "r");
+ rsaresp = stdout;
+
+ /* calculate the exponent */
+ for (i=0; i < 4; i++) {
+ if (peCount || (publicExponent &
+ ((unsigned long)0xff000000L >> (i*8)))) {
+ pubEx[peCount] =
+ (unsigned char)((publicExponent >> (3-i)*8) & 0xff);
+ peCount++;
+ }
+ }
+ pe.len = peCount;
+ pe.data = &pubEx[0];
+ pe.type = siBuffer;
+
+ while (fgets(buf, sizeof buf, rsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* [mod = ...] */
+ if (buf[0] == '[') {
+
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+ if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
+ fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+
+ if (rsaBlapiPrivKey != NULL) {
+ PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
+ rsaBlapiPrivKey = NULL;
+ rsaBlapiPublicKey = NULL;
+ }
+
+ rsaBlapiPrivKey = RSA_NewKey(modulus, &pe);
+ if (rsaBlapiPrivKey == NULL) {
+ fprintf(rsaresp, "Error unable to create RSA key\n");
+ goto loser;
+ }
+
+ to_hex_str(buf, rsaBlapiPrivKey->modulus.data,
+ rsaBlapiPrivKey->modulus.len);
+ fprintf(rsaresp, "\nn = %s\n\n", buf);
+ to_hex_str(buf, rsaBlapiPrivKey->publicExponent.data,
+ rsaBlapiPrivKey->publicExponent.len);
+ fprintf(rsaresp, "e = %s\n", buf);
+ /* convert private key to public key. Memory
+ * is freed with private key's arena */
+ rsaBlapiPublicKey = (RSAPublicKey *)PORT_ArenaAlloc(
+ rsaBlapiPrivKey->arena,
+ sizeof(RSAPublicKey));
+
+ rsaBlapiPublicKey->modulus.len = rsaBlapiPrivKey->modulus.len;
+ rsaBlapiPublicKey->modulus.data = rsaBlapiPrivKey->modulus.data;
+ rsaBlapiPublicKey->publicExponent.len =
+ rsaBlapiPrivKey->publicExponent.len;
+ rsaBlapiPublicKey->publicExponent.data =
+ rsaBlapiPrivKey->publicExponent.data;
+ continue;
+ }
+
+ /* SHAAlg = ... */
+ if (strncmp(buf, "SHAAlg", 6) == 0) {
+ i = 6;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* set the SHA Algorithm */
+ if (strncmp(&buf[i], "SHA1", 4) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(&buf[i], "SHA384", 6)== 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+
+ }
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+
+ unsigned char msg[128]; /* MAX msg 128 */
+ unsigned int rsa_bytes_signed;
+ unsigned char rsa_computed_signature[RSA_MAX_TEST_MODULUS_BYTES];
+ SECStatus rv = SECFailure;
+ NSSLOWKEYPublicKey * rsa_public_key;
+ NSSLOWKEYPrivateKey * rsa_private_key;
+ NSSLOWKEYPrivateKey low_RSA_private_key = { NULL,
+ NSSLOWKEYRSAKey, };
+ NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
+ NSSLOWKEYRSAKey, };
+
+ low_RSA_private_key.u.rsa = *rsaBlapiPrivKey;
+ low_RSA_public_key.u.rsa = *rsaBlapiPublicKey;
+
+ rsa_private_key = &low_RSA_private_key;
+ rsa_public_key = &low_RSA_public_key;
+
+ memset(sha, 0, sizeof sha);
+ memset(msg, 0, sizeof msg);
+ rsa_bytes_signed = 0;
+ memset(rsa_computed_signature, 0, sizeof rsa_computed_signature);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ for (j=0; isxdigit(buf[i]) && j < sizeof(msg); i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+
+ if (shaAlg == HASH_AlgSHA1) {
+ if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA1");
+ goto loser;
+ }
+ shaLength = SHA1_LENGTH;
+ shaOid = SEC_OID_SHA1;
+ } else if (shaAlg == HASH_AlgSHA256) {
+ if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA256");
+ goto loser;
+ }
+ shaLength = SHA256_LENGTH;
+ shaOid = SEC_OID_SHA256;
+ } else if (shaAlg == HASH_AlgSHA384) {
+ if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA384");
+ goto loser;
+ }
+ shaLength = SHA384_LENGTH;
+ shaOid = SEC_OID_SHA384;
+ } else if (shaAlg == HASH_AlgSHA512) {
+ if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA512");
+ goto loser;
+ }
+ shaLength = SHA512_LENGTH;
+ shaOid = SEC_OID_SHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+ goto loser;
+ }
+
+ /* Perform RSA signature with the RSA private key. */
+ rv = RSA_HashSign( shaOid,
+ rsa_private_key,
+ rsa_computed_signature,
+ &rsa_bytes_signed,
+ nsslowkey_PrivateModulusLen(rsa_private_key),
+ sha,
+ shaLength);
+
+ if( rv != SECSuccess ) {
+ fprintf(rsaresp, "ERROR: RSA_HashSign failed");
+ goto loser;
+ }
+
+ /* Output the signature */
+ fputs(buf, rsaresp);
+ to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
+ fprintf(rsaresp, "S = %s\n", buf);
+
+ /* Perform RSA verification with the RSA public key. */
+ rv = RSA_HashCheckSign( shaOid,
+ rsa_public_key,
+ rsa_computed_signature,
+ rsa_bytes_signed,
+ sha,
+ shaLength);
+ if( rv != SECSuccess ) {
+ fprintf(rsaresp, "ERROR: RSA_HashCheckSign failed");
+ goto loser;
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(rsareq);
+
+ if (rsaBlapiPrivKey != NULL) {
+ /* frees private and public key */
+ PORT_FreeArena(rsaBlapiPrivKey->arena, PR_TRUE);
+ rsaBlapiPrivKey = NULL;
+ rsaBlapiPublicKey = NULL;
+ }
+
+}
+/*
+ * Perform the RSA Signature Verification Test.
+ *
+ * reqfn is the pathname of the REQUEST file.
+ *
+ * The output RESPONSE file is written to stdout.
+ */
+void
+rsa_sigver_test(char *reqfn)
+{
+ char buf[2*RSA_MAX_TEST_MODULUS_BYTES+7];
+ /* buf holds one line from the input REQUEST file
+ * or to the output RESPONSE file.
+ * s = 2x for HEX output + 1 for \n
+ */
+ FILE *rsareq; /* input stream from the REQUEST file */
+ FILE *rsaresp; /* output stream to the RESPONSE file */
+ int i, j;
+ unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */
+ unsigned int shaLength = 0; /* actual length of the digest */
+ HASH_HashType shaAlg = HASH_AlgNULL;
+ SECOidTag shaOid = SEC_OID_UNKNOWN;
+ int modulus = 0; /* the Modulus size */
+ unsigned char signature[513]; /* largest signature size + '\n' */
+ unsigned int signatureLength = 0; /* actual length of the signature */
+ PRBool keyvalid = PR_TRUE;
+
+ RSAPublicKey rsaBlapiPublicKey; /* hold RSA public key */
+
+ rsareq = fopen(reqfn, "r");
+ rsaresp = stdout;
+ memset(&rsaBlapiPublicKey, 0, sizeof(RSAPublicKey));
+
+ while (fgets(buf, sizeof buf, rsareq) != NULL) {
+ /* a comment or blank line */
+ if (buf[0] == '#' || buf[0] == '\n') {
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* [Mod = ...] */
+ if (buf[0] == '[') {
+ unsigned int flen; /* length in bytes of the field size */
+
+ if (rsaBlapiPublicKey.modulus.data) { /* n */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
+ }
+ if (sscanf(buf, "[mod = %d]", &modulus) != 1) {
+ goto loser;
+ }
+
+ if (modulus > RSA_MAX_TEST_MODULUS_BITS) {
+ fprintf(rsaresp,"ERROR: modulus greater than test maximum\n");
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+
+ signatureLength = flen = modulus/8;
+
+ SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.modulus, flen);
+ if (rsaBlapiPublicKey.modulus.data == NULL) {
+ goto loser;
+ }
+ continue;
+ }
+
+ /* n = ... modulus */
+ if (buf[0] == 'n') {
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ keyvalid = from_hex_str(&rsaBlapiPublicKey.modulus.data[0],
+ rsaBlapiPublicKey.modulus.len,
+ &buf[i]);
+
+ if (!keyvalid) {
+ fprintf(rsaresp, "ERROR: rsa_sigver n not valid.\n");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* SHAAlg = ... */
+ if (strncmp(buf, "SHAAlg", 6) == 0) {
+ i = 6;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* set the SHA Algorithm */
+ if (strncmp(&buf[i], "SHA1", 4) == 0) {
+ shaAlg = HASH_AlgSHA1;
+ } else if (strncmp(&buf[i], "SHA256", 6) == 0) {
+ shaAlg = HASH_AlgSHA256;
+ } else if (strncmp(&buf[i], "SHA384", 6) == 0) {
+ shaAlg = HASH_AlgSHA384;
+ } else if (strncmp(&buf[i], "SHA512", 6) == 0) {
+ shaAlg = HASH_AlgSHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: Unable to find SHAAlg type");
+ goto loser;
+ }
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* e = ... public Key */
+ if (buf[0] == 'e') {
+ unsigned char data[RSA_MAX_TEST_EXPONENT_BYTES];
+ unsigned char t;
+
+ memset(data, 0, sizeof data);
+
+ if (rsaBlapiPublicKey.publicExponent.data) { /* e */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
+ }
+
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+ /* skip leading zero's */
+ while (isxdigit(buf[i])) {
+ hex_from_2char(&buf[i], &t);
+ if (t == 0) {
+ i+=2;
+ } else break;
+ }
+
+ /* get the exponent */
+ for (j=0; isxdigit(buf[i]) && j < sizeof data; i+=2,j++) {
+ hex_from_2char(&buf[i], &data[j]);
+ }
+
+ if (j == 0) { j = 1; } /* to handle 1 byte length exponents */
+
+ SECITEM_AllocItem(NULL, &rsaBlapiPublicKey.publicExponent, j);
+ if (rsaBlapiPublicKey.publicExponent.data == NULL) {
+ goto loser;
+ }
+
+ for (i=0; i < j; i++) {
+ rsaBlapiPublicKey.publicExponent.data[i] = data[i];
+ }
+
+ fputs(buf, rsaresp);
+ continue;
+ }
+
+ /* Msg = ... */
+ if (strncmp(buf, "Msg", 3) == 0) {
+ unsigned char msg[128]; /* MAX msg 128 */
+
+ memset(sha, 0, sizeof sha);
+ memset(msg, 0, sizeof msg);
+
+ i = 3;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ for (j=0; isxdigit(buf[i]) && j < sizeof msg; i+=2,j++) {
+ hex_from_2char(&buf[i], &msg[j]);
+ }
+
+ if (shaAlg == HASH_AlgSHA1) {
+ if (SHA1_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA1");
+ goto loser;
+ }
+ shaLength = SHA1_LENGTH;
+ shaOid = SEC_OID_SHA1;
+ } else if (shaAlg == HASH_AlgSHA256) {
+ if (SHA256_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA256");
+ goto loser;
+ }
+ shaLength = SHA256_LENGTH;
+ shaOid = SEC_OID_SHA256;
+ } else if (shaAlg == HASH_AlgSHA384) {
+ if (SHA384_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA384");
+ goto loser;
+ }
+ shaLength = SHA384_LENGTH;
+ shaOid = SEC_OID_SHA384;
+ } else if (shaAlg == HASH_AlgSHA512) {
+ if (SHA512_HashBuf(sha, msg, j) != SECSuccess) {
+ fprintf(rsaresp, "ERROR: Unable to generate SHA512");
+ goto loser;
+ }
+ shaLength = SHA512_LENGTH;
+ shaOid = SEC_OID_SHA512;
+ } else {
+ fprintf(rsaresp, "ERROR: SHAAlg not defined.");
+ goto loser;
+ }
+
+ fputs(buf, rsaresp);
+ continue;
+
+ }
+
+ /* S = ... */
+ if (buf[0] == 'S') {
+ SECStatus rv = SECFailure;
+ NSSLOWKEYPublicKey * rsa_public_key;
+ NSSLOWKEYPublicKey low_RSA_public_key = { NULL,
+ NSSLOWKEYRSAKey, };
+
+ /* convert to a low RSA public key */
+ low_RSA_public_key.u.rsa = rsaBlapiPublicKey;
+ rsa_public_key = &low_RSA_public_key;
+
+ memset(signature, 0, sizeof(signature));
+ i = 1;
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ for (j=0; isxdigit(buf[i]) && j < sizeof signature; i+=2,j++) {
+ hex_from_2char(&buf[i], &signature[j]);
+ }
+
+ signatureLength = j;
+ fputs(buf, rsaresp);
+
+ /* Perform RSA verification with the RSA public key. */
+ rv = RSA_HashCheckSign( shaOid,
+ rsa_public_key,
+ signature,
+ signatureLength,
+ sha,
+ shaLength);
+ if( rv == SECSuccess ) {
+ fputs("Result = P\n", rsaresp);
+ } else {
+ fputs("Result = F\n", rsaresp);
+ }
+ continue;
+ }
+ }
+loser:
+ fclose(rsareq);
+ if (rsaBlapiPublicKey.modulus.data) { /* n */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.modulus, PR_FALSE);
+ }
+ if (rsaBlapiPublicKey.publicExponent.data) { /* e */
+ SECITEM_ZfreeItem(&rsaBlapiPublicKey.publicExponent, PR_FALSE);
}
}
int main(int argc, char **argv)
{
- unsigned char key[24];
- unsigned char inp[24];
- unsigned char iv[8];
if (argc < 2) exit (-1);
NSS_NoDB_Init(NULL);
- memset(inp, 0, sizeof inp);
- /*************/
- /* DES */
- /*************/
- /**** ECB ****/
- /* encrypt */
- if ( strcmp(argv[1], "des_5_1_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES, PR_TRUE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES, PR_TRUE, 8, key, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- des_perm_op_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES, PR_TRUE, 8, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_1_6") == 0) {
- printf("Modes Test for the Encryption Process\n\n");
- des_modes(NSS_DES, PR_TRUE, 8, des_ecb_enc_key,
- NULL, des_ecb_enc_inp, 0);
- /* decrypt */
- } else if (strcmp(argv[1], "des_5_1_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES, PR_FALSE, 8, key, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES, PR_FALSE, 8, key, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- des_perm_op_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, inp);
- } else if (strcmp(argv[1], "des_5_1_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- des_sub_tbl_kat(NSS_DES, PR_FALSE, 8, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "des_5_1_2_6") == 0) {
- printf("Modes Test for the Decryption Process\n\n");
- des_modes(NSS_DES, PR_FALSE, 8, des_ecb_dec_key,
- NULL, des_ecb_dec_inp, 0);
- /**** CBC ****/
- /* encrypt */
- } else if (strcmp(argv[1], "des_5_2_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_CBC, PR_TRUE, 8, key, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_CBC, PR_TRUE, 8, NULL, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_1_6") == 0) {
- printf("Modes Test for the Encryption Process\n\n");
- des_modes(NSS_DES_CBC, PR_TRUE, 8, des_cbc_enc_key,
- des_cbc_enc_iv, des_cbc_enc_inp, 0);
- /* decrypt */
- } else if (strcmp(argv[1], "des_5_2_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_CBC, PR_FALSE, 8, key, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, inp);
- } else if (strcmp(argv[1], "des_5_2_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_CBC, PR_FALSE, 8, NULL, iv, NULL);
- } else if (strcmp(argv[1], "des_5_2_2_6") == 0) {
- printf("Modes Test for the Decryption Process\n\n");
- des_modes(NSS_DES_CBC, PR_FALSE, 8, des_cbc_dec_key,
- des_cbc_dec_iv, des_cbc_dec_inp, 0);
/*************/
/* TDEA */
/*************/
- /**** ECB ****/
- /* encrypt */
- } else if (strcmp(argv[1], "tdea_5_1_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES_EDE3, PR_TRUE, 24, key, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- des_perm_op_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_1_5") == 0) {
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3, PR_TRUE, 24, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_3") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee1\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea1_ecb_enc_key,
- NULL, tdea1_ecb_enc_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_2") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee2\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea2_ecb_enc_key,
- NULL, tdea2_ecb_enc_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_1_1_6_1") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datecbmontee3\n\n");
- des_modes(NSS_DES_EDE3, PR_TRUE, 24, tdea3_ecb_enc_key,
- NULL, tdea3_ecb_enc_inp, 3);
- /* decrypt */
- } else if (strcmp(argv[1], "tdea_5_1_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_pt_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_inv_perm_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- des_var_key_kat(NSS_DES_EDE3, PR_FALSE, 24, key, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- des_perm_op_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, inp);
- } else if (strcmp(argv[1], "tdea_5_1_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3, PR_FALSE, 24, NULL, NULL, NULL);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_3") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted1\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea1_ecb_dec_key,
- NULL, tdea1_ecb_dec_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_2") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted2\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea2_ecb_dec_key,
- NULL, tdea2_ecb_dec_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_1_2_6_1") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datecbmonted3\n\n");
- des_modes(NSS_DES_EDE3, PR_FALSE, 24, tdea3_ecb_dec_key,
- NULL, tdea3_ecb_dec_inp, 3);
- /**** CBC ****/
- /* encrypt */
- } else if (strcmp(argv[1], "tdea_5_2_1_1") == 0) {
- printf("Variable Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_2") == 0) {
- printf("Inverse Plaintext Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_3") == 0) {
- printf("Variable Key Known Answer Test - Encryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, key, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_1_4") == 0) {
- printf("Permutation Operation Known Answer Test - Encryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_1_5") == 0) {
- memset(iv, 0, sizeof iv);
- printf("Substitution Table Known Answer Test - Encryption\n\n");
- des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_TRUE, 24, NULL, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_3") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee1\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea1_cbc_enc_key,
- tdea1_cbc_enc_iv, tdea1_cbc_enc_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_2") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee2\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea2_cbc_enc_key,
- tdea2_cbc_enc_iv, tdea2_cbc_enc_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_2_1_6_1") == 0) {
- printf("Modes Test for the Encryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmontee3\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_TRUE, 24, tdea3_cbc_enc_key,
- tdea3_cbc_enc_iv, tdea3_cbc_enc_inp, 3);
- /* decrypt */
- } else if (strcmp(argv[1], "tdea_5_2_2_1") == 0) {
- printf("Variable Ciphertext Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_pt_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_2") == 0) {
- printf("Inverse Permutation Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_inv_perm_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_3") == 0) {
- printf("Variable Key Known Answer Test - Decryption\n\n");
- memset(key, 1, sizeof key);
- memset(iv, 0, sizeof iv);
- des_var_key_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, key, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_2_4") == 0) {
- printf("Permutation Operation Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_perm_op_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, inp);
- } else if (strcmp(argv[1], "tdea_5_2_2_5") == 0) {
- printf("Substitution Table Known Answer Test - Decryption\n\n");
- memset(iv, 0, sizeof iv);
- des_sub_tbl_kat(NSS_DES_EDE3_CBC, PR_FALSE, 24, NULL, iv, NULL);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_3") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted1\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea1_cbc_dec_key,
- tdea1_cbc_dec_iv, tdea1_cbc_dec_inp, 1);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_2") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted2\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea2_cbc_dec_key,
- tdea2_cbc_dec_iv, tdea2_cbc_dec_inp, 2);
- } else if (strcmp(argv[1], "tdea_5_2_2_6_1") == 0) {
- printf("Modes Test for the Decryption Process\n");
- printf("DATA FILE UTILIZED: datcbcmonted3\n\n");
- des_modes(NSS_DES_EDE3_CBC, PR_FALSE, 24, tdea3_cbc_dec_key,
- tdea3_cbc_dec_iv, tdea3_cbc_dec_inp, 3);
+ if (strcmp(argv[1], "tdea") == 0) {
+ /* argv[2]=kat|mmt|mct argv[3]=ecb|cbc argv[4]=<test name>.req */
+ if (strcmp(argv[2], "kat") == 0) {
+ /* Known Answer Test (KAT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mmt") == 0) {
+ /* Multi-block Message Test (MMT) */
+ tdea_kat_mmt(argv[4]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test (MCT) */
+ if (strcmp(argv[3], "ecb") == 0) {
+ /* ECB mode */
+ tdea_mct(NSS_DES_EDE3, argv[4]);
+ } else if (strcmp(argv[3], "cbc") == 0) {
+ /* CBC mode */
+ tdea_mct(NSS_DES_EDE3_CBC, argv[4]);
+ }
+ }
/*************/
/* AES */
/*************/
@@ -2632,20 +4513,82 @@ int main(int argc, char **argv)
}
}
/*************/
- /* SHS */
+ /* SHA */
+ /*************/
+ } else if (strcmp(argv[1], "sha") == 0) {
+ sha_test(argv[2]);
+ /*************/
+ /* RSA */
/*************/
- } else if (strcmp(argv[1], "shs") == 0) {
- shs_test(argv[2]);
+ } else if (strcmp(argv[1], "rsa") == 0) {
+ /* argv[2]=siggen|sigver */
+ /* argv[3]=<test name>.req */
+ if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ rsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ rsa_sigver_test(argv[3]);
+ }
/*************/
- /* DSS */
+ /* HMAC */
/*************/
- } else if (strcmp(argv[1], "dss") == 0) {
- dss_test(argv[2], argv[3]);
+ } else if (strcmp(argv[1], "hmac") == 0) {
+ hmac_test(argv[2]);
+ /*************/
+ /* DSA */
+ /*************/
+ } else if (strcmp(argv[1], "dsa") == 0) {
+ /* argv[2]=keypair|pqggen|pqgver|siggen|sigver */
+ /* argv[3]=<test name>.req */
+ if (strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ dsa_keypair_test(argv[3]);
+ } else if (strcmp(argv[2], "pqggen") == 0) {
+ /* Domain Parameter Generation Test */
+ dsa_pqggen_test(argv[3]);
+ } else if (strcmp(argv[2], "pqgver") == 0) {
+ /* Domain Parameter Validation Test */
+ dsa_pqgver_test(argv[3]);
+ } else if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ dsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ dsa_sigver_test(argv[3]);
+ }
+#ifdef NSS_ENABLE_ECC
+ /*************/
+ /* ECDSA */
+ /*************/
+ } else if (strcmp(argv[1], "ecdsa") == 0) {
+ /* argv[2]=keypair|pkv|siggen|sigver argv[3]=<test name>.req */
+ if ( strcmp(argv[2], "keypair") == 0) {
+ /* Key Pair Generation Test */
+ ecdsa_keypair_test(argv[3]);
+ } else if (strcmp(argv[2], "pkv") == 0) {
+ /* Public Key Validation Test */
+ ecdsa_pkv_test(argv[3]);
+ } else if (strcmp(argv[2], "siggen") == 0) {
+ /* Signature Generation Test */
+ ecdsa_siggen_test(argv[3]);
+ } else if (strcmp(argv[2], "sigver") == 0) {
+ /* Signature Verification Test */
+ ecdsa_sigver_test(argv[3]);
+ }
+#endif /* NSS_ENABLE_ECC */
/*************/
/* RNG */
/*************/
} else if (strcmp(argv[1], "rng") == 0) {
- do_random();
+ /* argv[2]=vst|mct argv[3]=<test name>.req */
+ if ( strcmp(argv[2], "vst") == 0) {
+ /* Variable Seed Test */
+ rng_vst(argv[3]);
+ } else if (strcmp(argv[2], "mct") == 0) {
+ /* Monte Carlo Test */
+ rng_mct(argv[3]);
+ }
}
return 0;
}
diff --git a/security/nss/cmd/fipstest/hmac.sh b/security/nss/cmd/fipstest/hmac.sh
new file mode 100755
index 000000000..ace988c7f
--- /dev/null
+++ b/security/nss/cmd/fipstest/hmac.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+hmac_requests="
+HMAC.req
+"
+
+for request in $hmac_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest hmac $request > $response
+done
+
diff --git a/security/nss/cmd/fipstest/rng.sh b/security/nss/cmd/fipstest/rng.sh
new file mode 100644
index 000000000..4b62a998d
--- /dev/null
+++ b/security/nss/cmd/fipstest/rng.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+vst_requests="
+FIPS186_VST.req
+FIPS186_VSTGEN.req
+"
+mct_requests="
+FIPS186_MCT.req
+FIPS186_MCTGEN.req
+"
+
+for request in $vst_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest rng vst $request > $response
+done
+for request in $mct_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest rng mct $request > $response
+done
diff --git a/security/nss/cmd/fipstest/rsa.sh b/security/nss/cmd/fipstest/rsa.sh
new file mode 100644
index 000000000..4b68a58bc
--- /dev/null
+++ b/security/nss/cmd/fipstest/rsa.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST RSA Validation System
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+
+request=SigGen15.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest rsa siggen $request > $response
+
+request=SigVer15.req
+response=`echo $request | sed -e "s/req/rsp/"`
+echo $request $response
+fipstest rsa sigver $request > $response
diff --git a/security/nss/cmd/fipstest/sha.sh b/security/nss/cmd/fipstest/sha.sh
new file mode 100644
index 000000000..685a41b00
--- /dev/null
+++ b/security/nss/cmd/fipstest/sha.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+sha_ShortMsg_requests="
+SHA1ShortMsg.req
+SHA256ShortMsg.req
+SHA384ShortMsg.req
+SHA512ShortMsg.req
+"
+
+sha_LongMsg_requests="
+SHA1LongMsg.req
+SHA256LongMsg.req
+SHA384LongMsg.req
+SHA512LongMsg.req
+"
+
+sha_Monte_requests="
+SHA1Monte.req
+SHA256Monte.req
+SHA384Monte.req
+SHA512Monte.req
+"
+for request in $sha_ShortMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+for request in $sha_LongMsg_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+for request in $sha_Monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest sha $request > $response
+done
+
diff --git a/security/nss/cmd/fipstest/tdea.sh b/security/nss/cmd/fipstest/tdea.sh
new file mode 100644
index 000000000..505478039
--- /dev/null
+++ b/security/nss/cmd/fipstest/tdea.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+#
+# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+
+#CBC_Known_Answer_tests
+#Initial Permutation KAT
+#Permutation Operation KAT
+#Subsitution Table KAT
+#Variable Key KAT
+#Variable PlainText KAT
+cbc_kat_requests="
+TCBCinvperm.req
+TCBCpermop.req
+TCBCsubtab.req
+TCBCvarkey.req
+TCBCvartext.req
+"
+
+#CBC Monte Carlo KATs
+cbc_monte_requests="
+TCBCMonte1.req
+TCBCMonte2.req
+TCBCMonte3.req
+"
+#Multi-block Message KATs
+cbc_mmt_requests="
+TCBCMMT1.req
+TCBCMMT2.req
+TCBCMMT3.req
+"
+
+ecb_kat_requests="
+TECBinvperm.req
+TECBpermop.req
+TECBsubtab.req
+TECBvarkey.req
+TECBvartext.req
+"
+
+ecb_monte_requests="
+TECBMonte1.req
+TECBMonte2.req
+TECBMonte3.req
+"
+
+ecb_mmt_requests="
+TECBMMT1.req
+TECBMMT2.req
+TECBMMT3.req
+"
+
+for request in $ecb_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt ecb $request > $response
+done
+for request in $ecb_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat ecb $request > $response
+done
+for request in $ecb_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct ecb $request > $response
+done
+for request in $cbc_mmt_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mmt cbc $request > $response
+done
+for request in $cbc_kat_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea kat cbc $request > $response
+done
+for request in $cbc_monte_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest tdea mct cbc $request > $response
+done
diff --git a/security/nss/cmd/lib/SECerrs.h b/security/nss/cmd/lib/SECerrs.h
index bd97dd791..2d5e7fe71 100644
--- a/security/nss/cmd/lib/SECerrs.h
+++ b/security/nss/cmd/lib/SECerrs.h
@@ -131,7 +131,7 @@ ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30),
"The certificate issuer's certificate has expired. Check your system date and time.")
ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31),
-"The CRL for the certificate's issuer has expired. Update it or check your system data and time.")
+"The CRL for the certificate's issuer has expired. Update it or check your system date and time.")
ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32),
"The CRL for the certificate's issuer has an invalid signature.")
@@ -476,7 +476,7 @@ ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142),
"Unsupported elliptic curve point form.")
ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143),
-"Unrecognized Object IDentifier.")
+"Unrecognized Object Identifier.")
ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144),
"Invalid OCSP signing certificate in OCSP response.")
@@ -504,3 +504,18 @@ ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151),
ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152),
"No new slot event is available at this time.")
+
+ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153),
+"CRL already exists.")
+
+ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154),
+"NSS is not initialized.")
+
+ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155),
+"The operation failed because the PKCS#11 token is not logged in.")
+
+ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156),
+"Configured OCSP responder's certificate is invalid.")
+
+ER3(SEC_ERROR_OCSP_BAD_SIGNATURE, (SEC_ERROR_BASE + 157),
+"OCSP response has an invalid signature.")
diff --git a/security/nss/cmd/lib/SSLerrs.h b/security/nss/cmd/lib/SSLerrs.h
index 62ce99f03..376ee8399 100644
--- a/security/nss/cmd/lib/SSLerrs.h
+++ b/security/nss/cmd/lib/SSLerrs.h
@@ -196,7 +196,7 @@ ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48),
"SSL received an unexpected Certificate Verify handshake message.")
ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49),
-"SSL received an unexpected Cllient Key Exchange handshake message.")
+"SSL received an unexpected Client Key Exchange handshake message.")
ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50),
"SSL received an unexpected Finished handshake message.")
@@ -238,7 +238,7 @@ ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59),
"SSL peer was not expecting a handshake message it received.")
ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60),
-"SSL peer was unable to succesfully decompress an SSL record it received.")
+"SSL peer was unable to successfully decompress an SSL record it received.")
ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61),
"SSL peer was unable to negotiate an acceptable set of security parameters.")
@@ -370,3 +370,17 @@ ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102),
ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103),
"SSL server cache not configured and not disabled for this socket.")
+ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104),
+"SSL peer does not support requested TLS hello extension.")
+
+ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105),
+"SSL peer could not obtain your certificate from the supplied URL.")
+
+ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106),
+"SSL peer has no certificate for the requested DNS name.")
+
+ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107),
+"SSL peer was unable to get an OCSP response for its certificate.")
+
+ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108),
+"SSL peer reported bad certificate hash value.")
diff --git a/security/nss/cmd/lib/manifest.mn b/security/nss/cmd/lib/manifest.mn
index 18086156b..d9829c977 100644
--- a/security/nss/cmd/lib/manifest.mn
+++ b/security/nss/cmd/lib/manifest.mn
@@ -44,6 +44,9 @@ MODULE = nss
DEFINES = -DNSPR20
PRIVATE_EXPORTS = secutil.h \
+ NSPRerrs.h \
+ SECerrs.h \
+ SSLerrs.h \
$(NULL)
CSRCS = secutil.c \
diff --git a/security/nss/cmd/lib/secpwd.c b/security/nss/cmd/lib/secpwd.c
index f1189e1c9..4d54d1ccf 100644
--- a/security/nss/cmd/lib/secpwd.c
+++ b/security/nss/cmd/lib/secpwd.c
@@ -96,7 +96,7 @@ char *SEC_GetPassword(FILE *input, FILE *output, char *prompt,
int infd = fileno(input);
int isTTY = isatty(infd);
#endif
- char phrase[200];
+ char phrase[200] = {'\0'}; /* ensure EOF doesn't return junk */
for (;;) {
/* Prompt for password */
diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c
index 1f41e938d..069f81f30 100644
--- a/security/nss/cmd/lib/secutil.c
+++ b/security/nss/cmd/lib/secutil.c
@@ -3012,25 +3012,6 @@ loser:
}
-
-SECItem *
-SECU_GetPBEPassword(void *arg)
-{
- char *p = NULL;
- SECItem *pwitem = NULL;
-
- p = SECU_GetPasswordString(arg,"Password: ");
-
- /* NOTE: This function is obviously unfinished. */
-
- if ( pwitem == NULL ) {
- fprintf(stderr, "Error hashing password\n");
- return NULL;
- }
-
- return pwitem;
-}
-
SECStatus
SECU_ParseCommandLine(int argc, char **argv, char *progName, secuCommand *cmd)
{
@@ -3614,10 +3595,8 @@ CERTCertificate *
SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
CERTAuthKeyID* authorityKeyID, PRTime validTime)
{
- CERTCertListNode *node;
- CERTCertificate * issuerCert = NULL, *cert = NULL;
+ CERTCertificate *issuerCert = NULL;
CERTCertList *certList = NULL;
- SECStatus rv = SECFailure;
if (!subject) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@@ -3627,32 +3606,24 @@ SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
certList =
CERT_CreateSubjectCertList(NULL, dbhandle, subject,
validTime, PR_TRUE);
- if (!certList) {
- goto loser;
- }
-
- node = CERT_LIST_HEAD(certList);
+ if (certList) {
+ CERTCertListNode *node = CERT_LIST_HEAD(certList);
- /* XXX and authoritykeyid in the future */
- while ( ! CERT_LIST_END(node, certList) ) {
- cert = node->cert;
- if (CERT_CheckCertUsage(cert, KU_CRL_SIGN) != SECSuccess ||
- !cert->trust) {
- continue;
- }
- /* select the first (newest) user cert */
- if (CERT_IsUserCert(cert)) {
- rv = SECSuccess;
- goto success;
+ /* XXX and authoritykeyid in the future */
+ while ( ! CERT_LIST_END(node, certList) ) {
+ CERTCertificate *cert = node->cert;
+ /* check cert CERTCertTrust data is allocated, check cert
+ usage extension, check that cert has pkey in db. Select
+ the first (newest) user cert */
+ if (cert->trust &&
+ CERT_CheckCertUsage(cert, KU_CRL_SIGN) == SECSuccess &&
+ CERT_IsUserCert(cert)) {
+
+ issuerCert = CERT_DupCertificate(cert);
+ break;
+ }
+ node = CERT_LIST_NEXT(node);
}
- }
-
- success:
- if (rv == SECSuccess) {
- issuerCert = CERT_DupCertificate(cert);
- }
- loser:
- if (certList) {
CERT_DestroyCertList(certList);
}
return(issuerCert);
diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h
index e8fc37550..4cede1cce 100644
--- a/security/nss/cmd/lib/secutil.h
+++ b/security/nss/cmd/lib/secutil.h
@@ -289,8 +289,6 @@ extern void SECU_PrintName(FILE *out, CERTName *name, char *msg, int level);
extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
#endif
-extern SECItem *SECU_GetPBEPassword(void *arg);
-
extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
extern SECStatus DER_PrettyPrint(FILE *out, SECItem *it, PRBool raw);
diff --git a/security/nss/cmd/manifest.mn b/security/nss/cmd/manifest.mn
index 0428314a4..332919454 100644
--- a/security/nss/cmd/manifest.mn
+++ b/security/nss/cmd/manifest.mn
@@ -63,6 +63,7 @@ DIRS = lib \
p7sign \
p7verify \
pk12util \
+ pk11mode \
pp \
rsaperf \
sdrtest \
diff --git a/security/nss/cmd/modutil/modutil.c b/security/nss/cmd/modutil/modutil.c
index d277fea05..b74935730 100644
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -749,7 +749,8 @@ usage()
"---------------------------------------------------------------------------\n"
"\n"
"Mechanism lists are colon-separated. The following mechanisms are recognized:\n"
-"RSA, DSA, RC2, RC4, RC5, DES, DH, SHA1, MD5, MD2, SSL, TLS, RANDOM, FRIENDLY\n"
+"RSA, DSA, DH, RC2, RC4, RC5, AES, DES, MD2, MD5, SHA1, SHA256, SHA512,\n"
+"SSL, TLS, RANDOM, and FRIENDLY\n"
"\n"
"Cipher lists are colon-separated. The following ciphers are recognized:\n"
"\n"
diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c
index 365301440..196af2575 100644
--- a/security/nss/cmd/modutil/pk11.c
+++ b/security/nss/cmd/modutil/pk11.c
@@ -141,11 +141,11 @@ ChkFipsMode(char *arg)
*/
typedef struct {
- char *name;
- unsigned long mask;
+ const char *name;
+ const unsigned long mask;
} MaskString;
-static MaskString mechanismStrings[] = {
+static const MaskString mechanismStrings[] = {
{"RSA", PUBLIC_MECH_RSA_FLAG},
{"DSA", PUBLIC_MECH_DSA_FLAG},
{"RC2", PUBLIC_MECH_RC2_FLAG},
@@ -159,16 +159,19 @@ static MaskString mechanismStrings[] = {
{"MD2", PUBLIC_MECH_MD2_FLAG},
{"SSL", PUBLIC_MECH_SSL_FLAG},
{"TLS", PUBLIC_MECH_TLS_FLAG},
+ {"AES", PUBLIC_MECH_AES_FLAG},
+ {"SHA256", PUBLIC_MECH_SHA256_FLAG},
+ {"SHA512", PUBLIC_MECH_SHA512_FLAG},
{"RANDOM", PUBLIC_MECH_RANDOM_FLAG},
{"FRIENDLY", PUBLIC_MECH_FRIENDLY_FLAG}
};
-static int numMechanismStrings =
+static const int numMechanismStrings =
sizeof(mechanismStrings) / sizeof(mechanismStrings[0]);
-static MaskString cipherStrings[] = {
+static const MaskString cipherStrings[] = {
{"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
};
-static int numCipherStrings =
+static const int numCipherStrings =
sizeof(cipherStrings) / sizeof(cipherStrings[0]);
/* Maximum length of a colon-separated list of all the strings in an
@@ -186,7 +189,7 @@ static int numCipherStrings =
* elements is the number of elements in array.
*/
static unsigned long
-getFlagsFromString(char *string, MaskString array[], int elements)
+getFlagsFromString(char *string, const MaskString array[], int elements)
{
unsigned long ret = 0;
short i = 0;
@@ -239,7 +242,7 @@ getFlagsFromString(char *string, MaskString array[], int elements)
* if you need it permanently or you want to change it.
*/
static char *
-getStringFromFlags(unsigned long flags, MaskString array[], int elements)
+getStringFromFlags(unsigned long flags, const MaskString array[], int elements)
{
static char buf[MAX_STRING_LIST_LEN];
int i;
@@ -739,7 +742,7 @@ loser:
PORT_Free(newpw);
}
if(newpw2) {
- memset(newpw2, 0, strlen(newpw));
+ memset(newpw2, 0, strlen(newpw2));
PORT_Free(newpw2);
}
return ret;
diff --git a/security/nss/cmd/modutil/specification.html b/security/nss/cmd/modutil/specification.html
index 9ab09627d..b64fe80c7 100644
--- a/security/nss/cmd/modutil/specification.html
+++ b/security/nss/cmd/modutil/specification.html
@@ -54,7 +54,7 @@
(<a href="#changepw">-changepw</a>)
<li>Create databases (secmod[ule].db, key3.db, cert7.db) from scratch.
(<a href="#create">-create</a>)
-<li>Switch to and from FIPS-140-1 compliant mode.
+<li>Switch to and from FIPS-140 compliant mode.
(<a href="#fips">-fips</a>)
<li>Delete a PKCS #11 module. (<a href="#delete">-delete</a>)
<li>List installed PKCS #11 modules. (<a href="#list">-list</a>)
diff --git a/security/nss/cmd/ocspclnt/ocspclnt.c b/security/nss/cmd/ocspclnt/ocspclnt.c
index 0b0ccaccc..ddb82d702 100644
--- a/security/nss/cmd/ocspclnt/ocspclnt.c
+++ b/security/nss/cmd/ocspclnt/ocspclnt.c
@@ -1050,6 +1050,8 @@ main (int argc, char **argv)
}
}
+ PL_DestroyOptState(optstate);
+
if ((crequest + dresponse + prequest + presponse + ccert + vcert) != 1) {
PR_fprintf (PR_STDERR, "%s: must specify exactly one command\n\n",
program_name);
@@ -1212,11 +1214,12 @@ nssdone:
}
if (handle != NULL) {
- (void) CERT_DisableOCSPChecking (handle);
+ CERT_DisableOCSPDefaultResponder(handle);
+ CERT_DisableOCSPChecking (handle);
}
if (NSS_Shutdown () != SECSuccess) {
- exit(1);
+ retval = 1;
}
prdone:
diff --git a/security/nss/cmd/pk11mode/Makefile b/security/nss/cmd/pk11mode/Makefile
new file mode 100755
index 000000000..9e2708a76
--- /dev/null
+++ b/security/nss/cmd/pk11mode/Makefile
@@ -0,0 +1,93 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#######################################################################
+# (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). #
+#######################################################################
+
+ifeq ($(OS_ARCH), WINNT)
+
+EXTRA_LIBS += \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.$(LIB_SUFFIX) \
+ $(NULL)
+
+else
+
+EXTRA_SHARED_LIBS += \
+ -L$(NSPR_LIB_DIR) \
+ -lplc4 \
+ -lplds4 \
+ -lnspr4 \
+ $(NULL)
+
+endif
+
+#######################################################################
+# (5) Execute "global" rules. (OPTIONAL) #
+#######################################################################
+
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+#######################################################################
+# (6) Execute "component" rules. (OPTIONAL) #
+#######################################################################
+
+
+
+#######################################################################
+# (7) Execute "local" rules. (OPTIONAL). #
+#######################################################################
+
diff --git a/security/nss/cmd/pk11mode/manifest.mn b/security/nss/cmd/pk11mode/manifest.mn
new file mode 100644
index 000000000..6c84958b6
--- /dev/null
+++ b/security/nss/cmd/pk11mode/manifest.mn
@@ -0,0 +1,48 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1994-2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+CORE_DEPTH = ../../..
+
+MODULE = nss
+
+EXPORTS =
+
+CSRCS = pk11mode.c
+
+PROGRAM = pk11mode
+
+REQUIRES =
diff --git a/security/nss/cmd/pk11mode/pk11mode.c b/security/nss/cmd/pk11mode/pk11mode.c
new file mode 100644
index 000000000..6220abaa4
--- /dev/null
+++ b/security/nss/cmd/pk11mode/pk11mode.c
@@ -0,0 +1,5345 @@
+/*
+ * pk11mode.c - Test FIPS or NONFIPS Modes for the NSS PKCS11 api.
+ * The goal of this program is to test every function
+ * entry point of the PKCS11 api at least once.
+ * To test in FIPS mode: pk11mode
+ * To test in NONFIPS mode: pk11mode nonFIPS
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#define LIB_NAME "softokn3.dll"
+#endif
+#include "prlink.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+
+#include "pkcs11.h"
+
+
+#define NUM_ELEM(array) (sizeof(array)/sizeof(array[0]))
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+struct tuple_str {
+ CK_RV errNum;
+ const char * errString;
+};
+
+
+typedef struct tuple_str tuple_str;
+
+static const tuple_str errStrings[] = {
+{CKR_OK , "CKR_OK "},
+{CKR_CANCEL , "CKR_CANCEL "},
+{CKR_HOST_MEMORY , "CKR_HOST_MEMORY "},
+{CKR_SLOT_ID_INVALID , "CKR_SLOT_ID_INVALID "},
+{CKR_GENERAL_ERROR , "CKR_GENERAL_ERROR "},
+{CKR_FUNCTION_FAILED , "CKR_FUNCTION_FAILED "},
+{CKR_ARGUMENTS_BAD , "CKR_ARGUMENTS_BAD "},
+{CKR_NO_EVENT , "CKR_NO_EVENT "},
+{CKR_NEED_TO_CREATE_THREADS , "CKR_NEED_TO_CREATE_THREADS "},
+{CKR_CANT_LOCK , "CKR_CANT_LOCK "},
+{CKR_ATTRIBUTE_READ_ONLY , "CKR_ATTRIBUTE_READ_ONLY "},
+{CKR_ATTRIBUTE_SENSITIVE , "CKR_ATTRIBUTE_SENSITIVE "},
+{CKR_ATTRIBUTE_TYPE_INVALID , "CKR_ATTRIBUTE_TYPE_INVALID "},
+{CKR_ATTRIBUTE_VALUE_INVALID , "CKR_ATTRIBUTE_VALUE_INVALID "},
+{CKR_DATA_INVALID , "CKR_DATA_INVALID "},
+{CKR_DATA_LEN_RANGE , "CKR_DATA_LEN_RANGE "},
+{CKR_DEVICE_ERROR , "CKR_DEVICE_ERROR "},
+{CKR_DEVICE_MEMORY , "CKR_DEVICE_MEMORY "},
+{CKR_DEVICE_REMOVED , "CKR_DEVICE_REMOVED "},
+{CKR_ENCRYPTED_DATA_INVALID , "CKR_ENCRYPTED_DATA_INVALID "},
+{CKR_ENCRYPTED_DATA_LEN_RANGE , "CKR_ENCRYPTED_DATA_LEN_RANGE "},
+{CKR_FUNCTION_CANCELED , "CKR_FUNCTION_CANCELED "},
+{CKR_FUNCTION_NOT_PARALLEL , "CKR_FUNCTION_NOT_PARALLEL "},
+{CKR_FUNCTION_NOT_SUPPORTED , "CKR_FUNCTION_NOT_SUPPORTED "},
+{CKR_KEY_HANDLE_INVALID , "CKR_KEY_HANDLE_INVALID "},
+{CKR_KEY_SIZE_RANGE , "CKR_KEY_SIZE_RANGE "},
+{CKR_KEY_TYPE_INCONSISTENT , "CKR_KEY_TYPE_INCONSISTENT "},
+{CKR_KEY_NOT_NEEDED , "CKR_KEY_NOT_NEEDED "},
+{CKR_KEY_CHANGED , "CKR_KEY_CHANGED "},
+{CKR_KEY_NEEDED , "CKR_KEY_NEEDED "},
+{CKR_KEY_INDIGESTIBLE , "CKR_KEY_INDIGESTIBLE "},
+{CKR_KEY_FUNCTION_NOT_PERMITTED , "CKR_KEY_FUNCTION_NOT_PERMITTED "},
+{CKR_KEY_NOT_WRAPPABLE , "CKR_KEY_NOT_WRAPPABLE "},
+{CKR_KEY_UNEXTRACTABLE , "CKR_KEY_UNEXTRACTABLE "},
+{CKR_MECHANISM_INVALID , "CKR_MECHANISM_INVALID "},
+{CKR_MECHANISM_PARAM_INVALID , "CKR_MECHANISM_PARAM_INVALID "},
+{CKR_OBJECT_HANDLE_INVALID , "CKR_OBJECT_HANDLE_INVALID "},
+{CKR_OPERATION_ACTIVE , "CKR_OPERATION_ACTIVE "},
+{CKR_OPERATION_NOT_INITIALIZED , "CKR_OPERATION_NOT_INITIALIZED "},
+{CKR_PIN_INCORRECT , "CKR_PIN_INCORRECT "},
+{CKR_PIN_INVALID , "CKR_PIN_INVALID "},
+{CKR_PIN_LEN_RANGE , "CKR_PIN_LEN_RANGE "},
+{CKR_PIN_EXPIRED , "CKR_PIN_EXPIRED "},
+{CKR_PIN_LOCKED , "CKR_PIN_LOCKED "},
+{CKR_SESSION_CLOSED , "CKR_SESSION_CLOSED "},
+{CKR_SESSION_COUNT , "CKR_SESSION_COUNT "},
+{CKR_SESSION_HANDLE_INVALID , "CKR_SESSION_HANDLE_INVALID "},
+{CKR_SESSION_PARALLEL_NOT_SUPPORTED , "CKR_SESSION_PARALLEL_NOT_SUPPORTED "},
+{CKR_SESSION_READ_ONLY , "CKR_SESSION_READ_ONLY "},
+{CKR_SESSION_EXISTS , "CKR_SESSION_EXISTS "},
+{CKR_SESSION_READ_ONLY_EXISTS , "CKR_SESSION_READ_ONLY_EXISTS "},
+{CKR_SESSION_READ_WRITE_SO_EXISTS , "CKR_SESSION_READ_WRITE_SO_EXISTS "},
+{CKR_SIGNATURE_INVALID , "CKR_SIGNATURE_INVALID "},
+{CKR_SIGNATURE_LEN_RANGE , "CKR_SIGNATURE_LEN_RANGE "},
+{CKR_TEMPLATE_INCOMPLETE , "CKR_TEMPLATE_INCOMPLETE "},
+{CKR_TEMPLATE_INCONSISTENT , "CKR_TEMPLATE_INCONSISTENT "},
+{CKR_TOKEN_NOT_PRESENT , "CKR_TOKEN_NOT_PRESENT "},
+{CKR_TOKEN_NOT_RECOGNIZED , "CKR_TOKEN_NOT_RECOGNIZED "},
+{CKR_TOKEN_WRITE_PROTECTED , "CKR_TOKEN_WRITE_PROTECTED "},
+{CKR_UNWRAPPING_KEY_HANDLE_INVALID , "CKR_UNWRAPPING_KEY_HANDLE_INVALID "},
+{CKR_UNWRAPPING_KEY_SIZE_RANGE , "CKR_UNWRAPPING_KEY_SIZE_RANGE "},
+{CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"},
+{CKR_USER_ALREADY_LOGGED_IN , "CKR_USER_ALREADY_LOGGED_IN "},
+{CKR_USER_NOT_LOGGED_IN , "CKR_USER_NOT_LOGGED_IN "},
+{CKR_USER_PIN_NOT_INITIALIZED , "CKR_USER_PIN_NOT_INITIALIZED "},
+{CKR_USER_TYPE_INVALID , "CKR_USER_TYPE_INVALID "},
+{CKR_USER_ANOTHER_ALREADY_LOGGED_IN , "CKR_USER_ANOTHER_ALREADY_LOGGED_IN "},
+{CKR_USER_TOO_MANY_TYPES , "CKR_USER_TOO_MANY_TYPES "},
+{CKR_WRAPPED_KEY_INVALID , "CKR_WRAPPED_KEY_INVALID "},
+{CKR_WRAPPED_KEY_LEN_RANGE , "CKR_WRAPPED_KEY_LEN_RANGE "},
+{CKR_WRAPPING_KEY_HANDLE_INVALID , "CKR_WRAPPING_KEY_HANDLE_INVALID "},
+{CKR_WRAPPING_KEY_SIZE_RANGE , "CKR_WRAPPING_KEY_SIZE_RANGE "},
+{CKR_WRAPPING_KEY_TYPE_INCONSISTENT , "CKR_WRAPPING_KEY_TYPE_INCONSISTENT "},
+{CKR_RANDOM_SEED_NOT_SUPPORTED , "CKR_RANDOM_SEED_NOT_SUPPORTED "},
+{CKR_RANDOM_NO_RNG , "CKR_RANDOM_NO_RNG "},
+{CKR_DOMAIN_PARAMS_INVALID , "CKR_DOMAIN_PARAMS_INVALID "},
+{CKR_BUFFER_TOO_SMALL , "CKR_BUFFER_TOO_SMALL "},
+{CKR_SAVED_STATE_INVALID , "CKR_SAVED_STATE_INVALID "},
+{CKR_INFORMATION_SENSITIVE , "CKR_INFORMATION_SENSITIVE "},
+{CKR_STATE_UNSAVEABLE , "CKR_STATE_UNSAVEABLE "},
+{CKR_CRYPTOKI_NOT_INITIALIZED , "CKR_CRYPTOKI_NOT_INITIALIZED "},
+{CKR_CRYPTOKI_ALREADY_INITIALIZED , "CKR_CRYPTOKI_ALREADY_INITIALIZED "},
+{CKR_MUTEX_BAD , "CKR_MUTEX_BAD "},
+{CKR_MUTEX_NOT_LOCKED , "CKR_MUTEX_NOT_LOCKED "},
+{CKR_FUNCTION_REJECTED , "CKR_FUNCTION_REJECTED "},
+{CKR_VENDOR_DEFINED , "CKR_VENDOR_DEFINED "},
+{0xCE534351 , "CKR_NETSCAPE_CERTDB_FAILED "},
+{0xCE534352 , "CKR_NETSCAPE_KEYDB_FAILED "}
+};
+
+static const CK_ULONG numStrings = sizeof(errStrings) / sizeof(tuple_str);
+
+/* Returns constant error string for "CRV".
+ * Returns "unknown error" if errNum is unknown.
+ */
+const char *
+PKM_CK_RVtoStr(CK_RV errNum) {
+ CK_ULONG low = 1;
+ CK_ULONG high = numStrings - 1;
+ CK_ULONG i;
+ CK_RV num;
+ static int initDone;
+
+ /* make sure table is in ascending order.
+ * binary search depends on it.
+ */
+ if (!initDone) {
+ CK_RV lastNum = CKR_OK;
+ for (i = low; i <= high; ++i) {
+ num = errStrings[i].errNum;
+ if (num <= lastNum) {
+ fprintf(stderr,
+"sequence error in error strings at item %d\n"
+"error %d (%s)\n"
+"should come after \n"
+"error %d (%s)\n",
+ (int) i, (int) lastNum, errStrings[i-1].errString,
+ (int) num, errStrings[i].errString);
+ }
+ lastNum = num;
+ }
+ initDone = 1;
+ }
+
+ /* Do binary search of table. */
+ while (low + 1 < high) {
+ i = (low + high) / 2;
+ num = errStrings[i].errNum;
+ if (errNum == num)
+ return errStrings[i].errString;
+ if (errNum < num)
+ high = i;
+ else
+ low = i;
+ }
+ if (errNum == errStrings[low].errNum)
+ return errStrings[low].errString;
+ if (errNum == errStrings[high].errNum)
+ return errStrings[high].errString;
+ return "unknown error";
+}
+
+#include "pkcs11p.h"
+
+typedef struct CK_C_INITIALIZE_ARGS_NSS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ /* The official PKCS #11 spec does not have a 'LibraryParameters' field, but
+ * a reserved field. NSS needs a way to pass instance-specific information
+ * to the library (like where to find its config files, etc). This
+ * information is usually provided by the installer and passed uninterpreted
+ * by NSS to the library, though NSS does know the specifics of the softoken
+ * version of this parameter. Most compliant PKCS#11 modules expect this
+ * parameter to be NULL, and will return CKR_ARGUMENTS_BAD from
+ * C_Initialize if Library parameters is supplied. */
+ CK_CHAR_PTR *LibraryParameters;
+ /* This field is only present if the LibraryParameters is not NULL. It must
+ * be NULL in all cases */
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS_NSS;
+
+#include "pkcs11u.h"
+
+static CK_ATTRIBUTE_TYPE all_known_attribute_types[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_PRIVATE,
+ CKA_LABEL,
+ CKA_APPLICATION,
+ CKA_VALUE,
+ CKA_CERTIFICATE_TYPE,
+ CKA_ISSUER,
+ CKA_SERIAL_NUMBER,
+ CKA_KEY_TYPE,
+ CKA_SUBJECT,
+ CKA_ID,
+ CKA_SENSITIVE,
+ CKA_ENCRYPT,
+ CKA_DECRYPT,
+ CKA_WRAP,
+ CKA_UNWRAP,
+ CKA_SIGN,
+ CKA_SIGN_RECOVER,
+ CKA_VERIFY,
+ CKA_VERIFY_RECOVER,
+ CKA_DERIVE,
+ CKA_START_DATE,
+ CKA_END_DATE,
+ CKA_MODULUS,
+ CKA_MODULUS_BITS,
+ CKA_PUBLIC_EXPONENT,
+ CKA_PRIVATE_EXPONENT,
+ CKA_PRIME_1,
+ CKA_PRIME_2,
+ CKA_EXPONENT_1,
+ CKA_EXPONENT_2,
+ CKA_COEFFICIENT,
+ CKA_PRIME,
+ CKA_SUBPRIME,
+ CKA_BASE,
+ CKA_VALUE_BITS,
+ CKA_VALUE_LEN,
+ CKA_EXTRACTABLE,
+ CKA_LOCAL,
+ CKA_NEVER_EXTRACTABLE,
+ CKA_ALWAYS_SENSITIVE,
+ CKA_MODIFIABLE,
+#ifdef CKA_NETSCAPE
+ CKA_NETSCAPE_URL,
+ CKA_NETSCAPE_EMAIL,
+ CKA_NETSCAPE_SMIME_INFO,
+ CKA_NETSCAPE_SMIME_TIMESTAMP,
+ CKA_NETSCAPE_PKCS8_SALT,
+ CKA_NETSCAPE_PASSWORD_CHECK,
+ CKA_NETSCAPE_EXPIRES,
+#endif /* CKA_NETSCAPE */
+#ifdef CKA_TRUST
+ CKA_TRUST_DIGITAL_SIGNATURE,
+ CKA_TRUST_NON_REPUDIATION,
+ CKA_TRUST_KEY_ENCIPHERMENT,
+ CKA_TRUST_DATA_ENCIPHERMENT,
+ CKA_TRUST_KEY_AGREEMENT,
+ CKA_TRUST_KEY_CERT_SIGN,
+ CKA_TRUST_CRL_SIGN,
+ CKA_TRUST_SERVER_AUTH,
+ CKA_TRUST_CLIENT_AUTH,
+ CKA_TRUST_CODE_SIGNING,
+ CKA_TRUST_EMAIL_PROTECTION,
+ CKA_TRUST_IPSEC_END_SYSTEM,
+ CKA_TRUST_IPSEC_TUNNEL,
+ CKA_TRUST_IPSEC_USER,
+ CKA_TRUST_TIME_STAMPING,
+#endif /* CKA_TRUST */
+};
+
+static int number_of_all_known_attribute_types =
+(sizeof(all_known_attribute_types)/sizeof(all_known_attribute_types[0]));
+
+#define MAX_SIG_SZ 128
+#define MAX_CIPHER_SZ 128
+#define MAX_DATA_SZ 64
+#define MAX_DIGEST_SZ 64
+#define HMAC_MAX_LENGTH 64
+#define FIPSMODE 0
+#define NONFIPSMODE 1
+#define HYBRIDMODE 2
+#define NOMODE 3
+int MODE = FIPSMODE;
+
+CK_BBOOL true = CK_TRUE;
+CK_BBOOL false = CK_FALSE;
+static const CK_BYTE PLAINTEXT[] = {"Firefox Rules!"};
+static const CK_BYTE PLAINTEXT_PAD[] =
+ {"Firefox and thunderbird rule the world!"};
+CK_ULONG NUMTESTS = 0;
+
+static const char * slotFlagName[] = {
+ "CKF_TOKEN_PRESENT",
+ "CKF_REMOVABLE_DEVICE",
+ "CKF_HW_SLOT",
+ "unknown token flag 0x00000008",
+ "unknown token flag 0x00000010",
+ "unknown token flag 0x00000020",
+ "unknown token flag 0x00000040",
+ "unknown token flag 0x00000080",
+ "unknown token flag 0x00000100",
+ "unknown token flag 0x00000200",
+ "unknown token flag 0x00000400",
+ "unknown token flag 0x00000800",
+ "unknown token flag 0x00001000",
+ "unknown token flag 0x00002000",
+ "unknown token flag 0x00004000",
+ "unknown token flag 0x00008000"
+ "unknown token flag 0x00010000",
+ "unknown token flag 0x00020000",
+ "unknown token flag 0x00040000",
+ "unknown token flag 0x00080000",
+ "unknown token flag 0x00100000",
+ "unknown token flag 0x00200000",
+ "unknown token flag 0x00400000",
+ "unknown token flag 0x00800000"
+ "unknown token flag 0x01000000",
+ "unknown token flag 0x02000000",
+ "unknown token flag 0x04000000",
+ "unknown token flag 0x08000000",
+ "unknown token flag 0x10000000",
+ "unknown token flag 0x20000000",
+ "unknown token flag 0x40000000",
+ "unknown token flag 0x80000000"
+};
+
+static const char * tokenFlagName[] = {
+ "CKF_PKM_RNG",
+ "CKF_WRITE_PROTECTED",
+ "CKF_LOGIN_REQUIRED",
+ "CKF_USER_PIN_INITIALIZED",
+ "unknown token flag 0x00000010",
+ "CKF_RESTORE_KEY_NOT_NEEDED",
+ "CKF_CLOCK_ON_TOKEN",
+ "unknown token flag 0x00000080",
+ "CKF_PROTECTED_AUTHENTICATION_PATH",
+ "CKF_DUAL_CRYPTO_OPERATIONS",
+ "CKF_TOKEN_INITIALIZED",
+ "CKF_SECONDARY_AUTHENTICATION",
+ "unknown token flag 0x00001000",
+ "unknown token flag 0x00002000",
+ "unknown token flag 0x00004000",
+ "unknown token flag 0x00008000",
+ "CKF_USER_PIN_COUNT_LOW",
+ "CKF_USER_PIN_FINAL_TRY",
+ "CKF_USER_PIN_LOCKED",
+ "CKF_USER_PIN_TO_BE_CHANGED",
+ "CKF_SO_PIN_COUNT_LOW",
+ "CKF_SO_PIN_FINAL_TRY",
+ "CKF_SO_PIN_LOCKED",
+ "CKF_SO_PIN_TO_BE_CHANGED",
+ "unknown token flag 0x01000000",
+ "unknown token flag 0x02000000",
+ "unknown token flag 0x04000000",
+ "unknown token flag 0x08000000",
+ "unknown token flag 0x10000000",
+ "unknown token flag 0x20000000",
+ "unknown token flag 0x40000000",
+ "unknown token flag 0x80000000"
+};
+
+static const unsigned char TLSClientRandom[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0d, 0x90, 0xbb, 0x5e, 0xc6, 0xe1, 0x3f, 0x71,
+ 0x0a, 0xa2, 0x70, 0x5a, 0x4f, 0xbc, 0x3f, 0x0d
+};
+static const unsigned char TLSServerRandom[] = {
+ 0x00, 0x00, 0x1d, 0x4a, 0x7a, 0x0a, 0xa5, 0x01,
+ 0x8e, 0x79, 0x72, 0xde, 0x9e, 0x2f, 0x8a, 0x0d,
+ 0xed, 0xb2, 0x5d, 0xf1, 0x14, 0xc2, 0xc6, 0x66,
+ 0x95, 0x86, 0xb0, 0x0d, 0x87, 0x2a, 0x2a, 0xc9
+};
+
+typedef enum {
+ CORRECT,
+ BOGUS_CLIENT_RANDOM,
+ BOGUS_CLIENT_RANDOM_LEN,
+ BOGUS_SERVER_RANDOM,
+ BOGUS_SERVER_RANDOM_LEN
+} enum_random_t;
+
+void
+dumpToHash64(const unsigned char *buf, unsigned int bufLen)
+{
+ unsigned int i;
+ for (i = 0; i < bufLen; i += 8) {
+ if (i % 32 == 0)
+ printf("\n");
+ printf(" 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,",
+ buf[i ], buf[i+1], buf[i+2], buf[i+3],
+ buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
+ }
+ printf("\n");
+}
+
+
+#ifdef _WIN32
+HMODULE hModule;
+#else
+PRLibrary *lib;
+#endif
+
+/*
+* All api that belongs to pk11mode.c layer start with the prefix PKM_
+*/
+void PKM_LogIt(const char *fmt, ...);
+void PKM_Error(const char *fmt, ...);
+CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_ULONG slotID);
+CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID);
+CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID *pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID);
+CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList,
+ CK_ULONG slotID);
+CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID *pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
+ CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID *pSlotList,
+ CK_ULONG slotID, CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_C_INITIALIZE_ARGS_NSS *initArgs);
+CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_MultiObjectManagement(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID *pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
+ CK_ATTRIBUTE_PTR expected_attrs,
+ CK_ULONG expected_attrs_count);
+CK_RV PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession, CK_MECHANISM_TYPE mechType,
+ CK_FLAGS flags, CK_BBOOL check_sizes,
+ CK_ULONG minkeysize, CK_ULONG maxkeysize);
+CK_RV PKM_TLSKeyAndMacDerive(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_MECHANISM_TYPE mechType, enum_random_t rnd);
+CK_RV PKM_TLSMasterKeyDerive(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_MECHANISM_TYPE mechType,
+ enum_random_t rnd);
+CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID *pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen);
+CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hRwSession,
+ CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
+ CK_MECHANISM *sigMech, CK_OBJECT_HANDLE secretKey,
+ CK_MECHANISM *cryptMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen);
+CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
+ CK_OBJECT_HANDLE hSecKeyDigest,
+ CK_MECHANISM *digestMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen);
+CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hRwSession,
+ CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
+ CK_MECHANISM *signMech, const CK_BYTE * pData,
+ CK_ULONG dataLen);
+CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
+ const CK_BYTE * pData, CK_ULONG dataLen);
+CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen);
+CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hRwSession,
+ CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
+ const CK_BYTE * pData, CK_ULONG pDataLen);
+CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hPublicKey,
+ CK_OBJECT_HANDLE hPrivateKey,
+ CK_MECHANISM *wrapMechanism,
+ CK_OBJECT_HANDLE hSecretKey,
+ CK_ATTRIBUTE *sKeyTemplate,
+ CK_ULONG skeyTempSize);
+CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
+ CK_MECHANISM *signMech, const CK_BYTE * pData,
+ CK_ULONG pDataLen);
+void PKM_Help();
+void PKM_CheckPath(char *string);
+char *PKM_FilePasswd(char *pwFile);
+static PRBool verbose = PR_FALSE;
+
+int main(int argc, char **argv)
+{
+ CK_C_GetFunctionList pC_GetFunctionList;
+ CK_FUNCTION_LIST_PTR pFunctionList;
+ CK_RV crv = CKR_OK;
+ CK_C_INITIALIZE_ARGS_NSS initArgs;
+ CK_SLOT_ID *pSlotList = NULL;
+ CK_TOKEN_INFO tokenInfo;
+ CK_ULONG slotID = 0; /* slotID == 0 for FIPSMODE */
+
+ CK_UTF8CHAR *pwd = NULL;
+ CK_ULONG pwdLen = 0;
+ char *moduleSpec = NULL;
+ char *configDir = NULL;
+ char *dbPrefix = NULL;
+ char *disableUnload = NULL;
+
+ PLOptStatus os;
+ PLOptState *opt = PL_CreateOptState(argc, argv, "nvhf:d:p:");
+ while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
+ {
+ if (PL_OPT_BAD == os) continue;
+ switch (opt->option)
+ {
+ case 'n': /* non fips mode */
+ MODE = NONFIPSMODE;
+ slotID = 1;
+ break;
+ case 'f': /* password file */
+ pwd = (CK_UTF8CHAR *) PKM_FilePasswd((char *)opt->value);
+ if (!pwd) PKM_Help();
+ break;
+ case 'd': /* opt_CertDir */
+ if (!opt->value) PKM_Help();
+ configDir = strdup(opt->value);
+ PKM_CheckPath(configDir);
+ break;
+ case 'p': /* opt_DBPrefix */
+ if (!opt->value) PKM_Help();
+ dbPrefix = strdup(opt->value);
+ break;
+ case 'v':
+ verbose = PR_TRUE;
+ break;
+ case 'h': /* help message */
+ default:
+ PKM_Help();
+ break;
+ }
+ }
+ PL_DestroyOptState(opt);
+
+ if (!pwd) {
+ pwd = (CK_UTF8CHAR *)strdup("1Mozilla");
+ }
+ pwdLen = strlen((const char*)pwd);
+ if (!configDir) {
+ configDir = strdup(".");
+ }
+ if (!dbPrefix) {
+ dbPrefix = strdup("");
+ }
+
+#ifdef _WIN32
+ hModule = LoadLibrary(LIB_NAME);
+ if (hModule == NULL) {
+ PKM_Error( "cannot load %s\n", LIB_NAME);
+ goto cleanup;
+ }
+ if (MODE == FIPSMODE) {
+ /* FIPS mode == FC_GetFunctionList */
+ pC_GetFunctionList = (CK_C_GetFunctionList)
+ GetProcAddress(hModule, "FC_GetFunctionList");
+ } else {
+ /* NON FIPS mode == C_GetFunctionList */
+ pC_GetFunctionList = (CK_C_GetFunctionList)
+ GetProcAddress(hModule, "C_GetFunctionList");
+ }
+ if (pC_GetFunctionList == NULL) {
+ PKM_Error( "cannot load %s\n", LIB_NAME);
+ goto cleanup;
+ }
+#else
+ {
+ char *libname = NULL;
+ /* Get the platform-dependent library name of the NSS cryptographic module */
+ libname = PR_GetLibraryName(NULL, "softokn3");
+ assert(libname != NULL);
+ lib = PR_LoadLibrary(libname);
+ assert(lib != NULL);
+ PR_FreeLibraryName(libname);
+ }
+ if (MODE == FIPSMODE) {
+ pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
+ "FC_GetFunctionList");
+ assert(pC_GetFunctionList != NULL);
+ slotID = 0;
+ } else {
+ pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
+ "C_GetFunctionList");
+ assert(pC_GetFunctionList != NULL);
+ slotID = 1;
+ }
+#endif
+
+ if (MODE == FIPSMODE) {
+ printf("Loaded FC_GetFunctionList for FIPS MODE; slotID %d \n",
+ (int) slotID);
+ } else {
+ printf("loaded C_GetFunctionList for NON FIPS MODE; slotID %d \n",
+ (int) slotID);
+ }
+
+ crv = (*pC_GetFunctionList)(&pFunctionList);
+ assert(crv == CKR_OK);
+
+ initArgs.CreateMutex = NULL;
+ initArgs.DestroyMutex = NULL;
+ initArgs.LockMutex = NULL;
+ initArgs.UnlockMutex = NULL;
+ initArgs.flags = CKF_OS_LOCKING_OK;
+ moduleSpec = PR_smprintf("configdir='%s' certPrefix='%s' "
+ "keyPrefix='%s' secmod='secmod.db' flags= ",
+ configDir, dbPrefix, dbPrefix);
+ initArgs.LibraryParameters = (CK_CHAR_PTR *) moduleSpec;
+ initArgs.pReserved = NULL;
+
+ /*DebugBreak();*/
+ /* FIPSMODE invokes FC_Initialize as pFunctionList->C_Initialize */
+ /* NSS cryptographic module library initialization for the FIPS */
+ /* Approved mode when FC_Initialize is envoked will perfom */
+ /* software integrity test, and power-up self-tests before */
+ /* FC_Initialize returns */
+ crv = pFunctionList->C_Initialize(&initArgs);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Initialize succeeded\n");
+ } else {
+ PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_ShowInfo(pFunctionList, slotID);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_ShowInfo succeeded\n");
+ } else {
+ PKM_Error( "PKM_ShowInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ pSlotList = PKM_GetSlotList(pFunctionList, slotID);
+ if (pSlotList == NULL) {
+ PKM_Error( "PKM_GetSlotList failed with \n");
+ goto cleanup;
+ }
+ crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetTokenInfo succeeded\n\n");
+ } else {
+ PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) {
+ PKM_LogIt("Initing PW for DB\n");
+ crv = PKM_InitPWforDB(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_InitPWforDB succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_InitPWforDB failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ } else {
+ PKM_LogIt("using existing DB\n");
+ }
+
+ /* general mechanism by token */
+ crv = PKM_Mechanism(pFunctionList, pSlotList, slotID);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Mechanism succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_Mechanism failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ /* RNG example without Login */
+ crv = PKM_RNG(pFunctionList, pSlotList, slotID);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_RNG succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_RNG failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SessionLogin succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_SessionLogin failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ /*
+ * PKM_KeyTest creates RSA,DSA public keys
+ * and AES, DES3 secret keys.
+ * then does digest, hmac, encrypt/decrypt, signing operations.
+ */
+ crv = PKM_KeyTests(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_KeyTests succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_KeyTest failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd,
+ pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SecretKey succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_SecretKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ crv = PKM_PublicKey(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_PublicKey succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_PublicKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_OperationalState(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_OperationalState succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_OperationalState failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_MultiObjectManagement succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_MultiObjectManagement failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_LegacyFunctions succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_LegacyFunctions failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen,
+ CKM_TLS_KEY_AND_MAC_DERIVE, CORRECT);
+
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_TLSKeyAndMacDerive succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_TLSKeyAndMacDerive failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen,
+ CKM_TLS_MASTER_KEY_DERIVE,
+ CORRECT);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen,
+ CKM_TLS_MASTER_KEY_DERIVE_DH,
+ CORRECT);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_TLSMasterKeyDerive succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_TLSMasterKeyDerive failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID,
+ pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_FindAllObjects succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_FindAllObjects failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+ crv = pFunctionList->C_Finalize(NULL);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Finalize succeeded\n");
+ } else {
+ PKM_Error( "C_Finalize failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ if (pSlotList) free(pSlotList);
+
+ /* demostrate how an application can be in Hybrid mode */
+ /* PKM_HybridMode shows how to switch between NONFIPS */
+ /* mode to FIPS mode */
+
+ PKM_LogIt("Testing Hybrid mode \n");
+ crv = PKM_HybridMode(pwd, pwdLen, &initArgs);
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_HybridMode succeeded\n");
+ } else {
+ PKM_Error( "PKM_HybridMode failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ goto cleanup;
+ }
+
+ printf("**** Total number of TESTS ran in %s is %d. ****\n",
+ ((MODE == FIPSMODE) ? "FIPS MODE" : "NON FIPS MODE"), (int) NUMTESTS);
+ printf("**** ALL TESTS PASSED ****\n");
+ PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n");
+
+cleanup:
+
+ if (pwd) {
+ free(pwd);
+ }
+ if (configDir) {
+ free(configDir);
+ }
+ if (dbPrefix) {
+ free(dbPrefix);
+ }
+ if (moduleSpec) {
+ free(moduleSpec);
+ }
+
+#ifdef _WIN32
+ FreeLibrary(hModule);
+#else
+ disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
+ if (!disableUnload) {
+ PR_UnloadLibrary(lib);
+ }
+#endif
+
+ return crv;
+}
+
+/*
+* PKM_KeyTests
+*
+*
+*/
+
+CK_RV PKM_KeyTests(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_SESSION_HANDLE hRwSession;
+
+ CK_RV crv = CKR_OK;
+
+/*** DSA Key ***/
+ CK_MECHANISM dsaParamGenMech;
+ CK_ULONG primeBits = 1024;
+ CK_ATTRIBUTE dsaParamGenTemplate[1];
+ CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
+ CK_BYTE DSA_P[128];
+ CK_BYTE DSA_Q[20];
+ CK_BYTE DSA_G[128];
+ CK_MECHANISM dsaKeyPairGenMech;
+ CK_ATTRIBUTE dsaPubKeyTemplate[5];
+ CK_ATTRIBUTE dsaPrivKeyTemplate[5];
+ CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
+
+/**** RSA Key ***/
+ CK_KEY_TYPE rsatype = CKK_RSA;
+ CK_MECHANISM rsaKeyPairGenMech;
+ CK_BYTE subject[] = {"RSA Private Key"};
+ CK_ULONG modulusBits = 1024;
+ CK_BYTE publicExponent[] = {0x01, 0x00, 0x01};
+ CK_BYTE id[] = {"RSA123"};
+ CK_ATTRIBUTE rsaPubKeyTemplate[9];
+ CK_ATTRIBUTE rsaPrivKeyTemplate[11];
+ CK_OBJECT_HANDLE hRSApubKey = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE hRSAprivKey = CK_INVALID_HANDLE;
+
+ /*** AES Key ***/
+ CK_MECHANISM sAESKeyMech = {
+ CKM_AES_KEY_GEN, NULL, 0
+ };
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE keyAESType = CKK_AES;
+ CK_UTF8CHAR AESlabel[] = "An AES secret key object";
+ CK_ULONG AESvalueLen = 32;
+ CK_ATTRIBUTE sAESKeyTemplate[9];
+ CK_OBJECT_HANDLE hAESSecKey;
+
+/*** DES3 Key ***/
+ CK_KEY_TYPE keyDES3Type = CKK_DES3;
+ CK_UTF8CHAR DES3label[] = "An Triple DES secret key object";
+ CK_ULONG DES3valueLen = 56;
+ CK_MECHANISM sDES3KeyGenMechanism = {
+ CKM_DES3_KEY_GEN, NULL, 0
+ };
+ CK_ATTRIBUTE sDES3KeyTemplate[9];
+ CK_OBJECT_HANDLE hDES3SecKey;
+
+ CK_MECHANISM dsaWithSha1Mech = {
+ CKM_DSA_SHA1, NULL, 0
+ };
+
+ CK_BYTE IV[16];
+ CK_MECHANISM mech_DES3_CBC;
+ CK_MECHANISM mech_DES3_CBC_PAD;
+ CK_MECHANISM mech_AES_CBC_PAD;
+ CK_MECHANISM mech_AES_CBC;
+ struct mech_str {
+ CK_ULONG mechanism;
+ const char *mechanismStr;
+ };
+
+ typedef struct mech_str mech_str;
+
+ mech_str digestMechs[] = {
+ {CKM_SHA_1, "CKM_SHA_1 "},
+ {CKM_SHA256, "CKM_SHA256"},
+ {CKM_SHA384, "CKM_SHA384"},
+ {CKM_SHA512, "CKM_SHA512"}
+ };
+ mech_str hmacMechs[] = {
+ {CKM_SHA_1_HMAC, "CKM_SHA_1_HMAC"},
+ {CKM_SHA256_HMAC, "CKM_SHA256_HMAC"},
+ {CKM_SHA384_HMAC, "CKM_SHA384_HMAC"},
+ {CKM_SHA512_HMAC, "CKM_SHA512_HMAC"}
+ };
+ mech_str sigRSAMechs[] = {
+ {CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS"},
+ {CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS"},
+ {CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS"},
+ {CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS"}
+ };
+
+ CK_ULONG digestMechsSZ = NUM_ELEM(digestMechs);
+ CK_ULONG sigRSAMechsSZ = NUM_ELEM(sigRSAMechs);
+ CK_ULONG hmacMechsSZ = NUM_ELEM(hmacMechs);
+ CK_MECHANISM mech;
+
+ unsigned int i;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* DSA key init */
+ dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN;
+ dsaParamGenMech.pParameter = NULL_PTR;
+ dsaParamGenMech.ulParameterLen = 0;
+ dsaParamGenTemplate[0].type = CKA_PRIME_BITS;
+ dsaParamGenTemplate[0].pValue = &primeBits;
+ dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
+ dsaPubKeyTemplate[0].type = CKA_PRIME;
+ dsaPubKeyTemplate[0].pValue = DSA_P;
+ dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
+ dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
+ dsaPubKeyTemplate[1].pValue = DSA_Q;
+ dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
+ dsaPubKeyTemplate[2].type = CKA_BASE;
+ dsaPubKeyTemplate[2].pValue = DSA_G;
+ dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
+ dsaPubKeyTemplate[3].type = CKA_TOKEN;
+ dsaPubKeyTemplate[3].pValue = &true;
+ dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
+ dsaPubKeyTemplate[4].type = CKA_VERIFY;
+ dsaPubKeyTemplate[4].pValue = &true;
+ dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
+ dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
+ dsaKeyPairGenMech.pParameter = NULL_PTR;
+ dsaKeyPairGenMech.ulParameterLen = 0;
+ dsaPrivKeyTemplate[0].type = CKA_TOKEN;
+ dsaPrivKeyTemplate[0].pValue = &true;
+ dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
+ dsaPrivKeyTemplate[1].pValue = &true;
+ dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
+ dsaPrivKeyTemplate[2].pValue = &true;
+ dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[3].type = CKA_SIGN,
+ dsaPrivKeyTemplate[3].pValue = &true;
+ dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
+ dsaPrivKeyTemplate[4].pValue = &true;
+ dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
+
+ /* RSA key init */
+ rsaKeyPairGenMech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
+ rsaKeyPairGenMech.pParameter = NULL_PTR;
+ rsaKeyPairGenMech.ulParameterLen = 0;
+
+ rsaPubKeyTemplate[0].type = CKA_KEY_TYPE;
+ rsaPubKeyTemplate[0].pValue = &rsatype;
+ rsaPubKeyTemplate[0].ulValueLen = sizeof(rsatype);
+ rsaPubKeyTemplate[1].type = CKA_PRIVATE;
+ rsaPubKeyTemplate[1].pValue = &true;
+ rsaPubKeyTemplate[1].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[2].type = CKA_ENCRYPT;
+ rsaPubKeyTemplate[2].pValue = &true;
+ rsaPubKeyTemplate[2].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[3].type = CKA_DECRYPT;
+ rsaPubKeyTemplate[3].pValue = &true;
+ rsaPubKeyTemplate[3].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[4].type = CKA_VERIFY;
+ rsaPubKeyTemplate[4].pValue = &true;
+ rsaPubKeyTemplate[4].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[5].type = CKA_SIGN;
+ rsaPubKeyTemplate[5].pValue = &true;
+ rsaPubKeyTemplate[5].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[6].type = CKA_WRAP;
+ rsaPubKeyTemplate[6].pValue = &true;
+ rsaPubKeyTemplate[6].ulValueLen = sizeof(true);
+ rsaPubKeyTemplate[7].type = CKA_MODULUS_BITS;
+ rsaPubKeyTemplate[7].pValue = &modulusBits;
+ rsaPubKeyTemplate[7].ulValueLen = sizeof(modulusBits);
+ rsaPubKeyTemplate[8].type = CKA_PUBLIC_EXPONENT;
+ rsaPubKeyTemplate[8].pValue = publicExponent;
+ rsaPubKeyTemplate[8].ulValueLen = sizeof (publicExponent);
+
+ rsaPrivKeyTemplate[0].type = CKA_KEY_TYPE;
+ rsaPrivKeyTemplate[0].pValue = &rsatype;
+ rsaPrivKeyTemplate[0].ulValueLen = sizeof(rsatype);
+ rsaPrivKeyTemplate[1].type = CKA_TOKEN;
+ rsaPrivKeyTemplate[1].pValue = &true;
+ rsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[2].type = CKA_PRIVATE;
+ rsaPrivKeyTemplate[2].pValue = &true;
+ rsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[3].type = CKA_SUBJECT;
+ rsaPrivKeyTemplate[3].pValue = subject;
+ rsaPrivKeyTemplate[3].ulValueLen = sizeof(subject);
+ rsaPrivKeyTemplate[4].type = CKA_ID;
+ rsaPrivKeyTemplate[4].pValue = id;
+ rsaPrivKeyTemplate[4].ulValueLen = sizeof(id);
+ rsaPrivKeyTemplate[5].type = CKA_SENSITIVE;
+ rsaPrivKeyTemplate[5].pValue = &true;
+ rsaPrivKeyTemplate[5].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[6].type = CKA_ENCRYPT;
+ rsaPrivKeyTemplate[6].pValue = &true;
+ rsaPrivKeyTemplate[6].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[7].type = CKA_DECRYPT;
+ rsaPrivKeyTemplate[7].pValue = &true;
+ rsaPrivKeyTemplate[7].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[8].type = CKA_VERIFY;
+ rsaPrivKeyTemplate[8].pValue = &true;
+ rsaPrivKeyTemplate[8].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[9].type = CKA_SIGN;
+ rsaPrivKeyTemplate[9].pValue = &true;
+ rsaPrivKeyTemplate[9].ulValueLen = sizeof(true);
+ rsaPrivKeyTemplate[10].type = CKA_UNWRAP;
+ rsaPrivKeyTemplate[10].pValue = &true;
+ rsaPrivKeyTemplate[10].ulValueLen = sizeof(true);
+
+ /* AES key template */
+ sAESKeyTemplate[0].type = CKA_CLASS;
+ sAESKeyTemplate[0].pValue = &class;
+ sAESKeyTemplate[0].ulValueLen = sizeof(class);
+ sAESKeyTemplate[1].type = CKA_KEY_TYPE;
+ sAESKeyTemplate[1].pValue = &keyAESType;
+ sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
+ sAESKeyTemplate[2].type = CKA_LABEL;
+ sAESKeyTemplate[2].pValue = AESlabel;
+ sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
+ sAESKeyTemplate[3].type = CKA_ENCRYPT;
+ sAESKeyTemplate[3].pValue = &true;
+ sAESKeyTemplate[3].ulValueLen = sizeof(true);
+ sAESKeyTemplate[4].type = CKA_DECRYPT;
+ sAESKeyTemplate[4].pValue = &true;
+ sAESKeyTemplate[4].ulValueLen = sizeof(true);
+ sAESKeyTemplate[5].type = CKA_SIGN;
+ sAESKeyTemplate[5].pValue = &true;
+ sAESKeyTemplate[5].ulValueLen = sizeof (true);
+ sAESKeyTemplate[6].type = CKA_VERIFY;
+ sAESKeyTemplate[6].pValue = &true;
+ sAESKeyTemplate[6].ulValueLen = sizeof(true);
+ sAESKeyTemplate[7].type = CKA_UNWRAP;
+ sAESKeyTemplate[7].pValue = &true;
+ sAESKeyTemplate[7].ulValueLen = sizeof(true);
+ sAESKeyTemplate[8].type = CKA_VALUE_LEN;
+ sAESKeyTemplate[8].pValue = &AESvalueLen;
+ sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
+
+ /* DES3 key template */
+ sDES3KeyTemplate[0].type = CKA_CLASS;
+ sDES3KeyTemplate[0].pValue = &class;
+ sDES3KeyTemplate[0].ulValueLen = sizeof(class);
+ sDES3KeyTemplate[1].type = CKA_KEY_TYPE;
+ sDES3KeyTemplate[1].pValue = &keyDES3Type;
+ sDES3KeyTemplate[1].ulValueLen = sizeof(keyDES3Type);
+ sDES3KeyTemplate[2].type = CKA_LABEL;
+ sDES3KeyTemplate[2].pValue = DES3label;
+ sDES3KeyTemplate[2].ulValueLen = sizeof(DES3label)-1;
+ sDES3KeyTemplate[3].type = CKA_ENCRYPT;
+ sDES3KeyTemplate[3].pValue = &true;
+ sDES3KeyTemplate[3].ulValueLen = sizeof(true);
+ sDES3KeyTemplate[4].type = CKA_DECRYPT;
+ sDES3KeyTemplate[4].pValue = &true;
+ sDES3KeyTemplate[4].ulValueLen = sizeof(true);
+ sDES3KeyTemplate[5].type = CKA_UNWRAP;
+ sDES3KeyTemplate[5].pValue = &true;
+ sDES3KeyTemplate[5].ulValueLen = sizeof(true);
+ sDES3KeyTemplate[6].type = CKA_SIGN,
+ sDES3KeyTemplate[6].pValue = &true;
+ sDES3KeyTemplate[6].ulValueLen = sizeof (true);
+ sDES3KeyTemplate[7].type = CKA_VERIFY;
+ sDES3KeyTemplate[7].pValue = &true;
+ sDES3KeyTemplate[7].ulValueLen = sizeof(true);
+ sDES3KeyTemplate[8].type = CKA_VALUE_LEN;
+ sDES3KeyTemplate[8].pValue = &DES3valueLen;
+ sDES3KeyTemplate[8].ulValueLen = sizeof(DES3valueLen);
+
+ /* mech init */
+ memset(IV, 0x01, sizeof(IV));
+ mech_DES3_CBC.mechanism = CKM_DES3_CBC;
+ mech_DES3_CBC.pParameter = IV;
+ mech_DES3_CBC.ulParameterLen = sizeof(IV);
+ mech_DES3_CBC_PAD.mechanism = CKM_DES3_CBC_PAD;
+ mech_DES3_CBC_PAD.pParameter = IV;
+ mech_DES3_CBC_PAD.ulParameterLen = sizeof(IV);
+ mech_AES_CBC.mechanism = CKM_AES_CBC;
+ mech_AES_CBC.pParameter = IV;
+ mech_AES_CBC.ulParameterLen = sizeof(IV);
+ mech_AES_CBC_PAD.mechanism = CKM_AES_CBC_PAD;
+ mech_AES_CBC_PAD.pParameter = IV;
+ mech_AES_CBC_PAD.ulParameterLen = sizeof(IV);
+
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID],
+ CKF_RW_SESSION | CKF_SERIAL_SESSION,
+ NULL, NULL, &hRwSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Opening a read/write session succeeded\n");
+ } else {
+ PKM_Error( "Opening a read/write session failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (MODE == FIPSMODE) {
+ crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate),
+ &hAESSecKey);
+ if (crv == CKR_OK) {
+ PKM_Error("C_GenerateKey succeeded when not logged in.\n");
+ return CKR_GENERAL_ERROR;
+ } else {
+ PKM_LogIt("C_GenerateKey returned as EXPECTED with 0x%08X, %-26s\n"
+ "since not logged in\n", crv, PKM_CK_RVtoStr(crv));
+ }
+ crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
+ rsaPubKeyTemplate,
+ NUM_ELEM(rsaPubKeyTemplate),
+ rsaPrivKeyTemplate,
+ NUM_ELEM(rsaPrivKeyTemplate),
+ &hRSApubKey, &hRSAprivKey);
+ if (crv == CKR_OK) {
+ PKM_Error("C_GenerateKeyPair succeeded when not logged in.\n");
+ return CKR_GENERAL_ERROR;
+ } else {
+ PKM_LogIt("C_GenerateKeyPair returned as EXPECTED with 0x%08X, "
+ "%-26s\n since not logged in\n", crv,
+ PKM_CK_RVtoStr(crv));
+ }
+ }
+
+ crv = pFunctionList->C_Login(hRwSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error("C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate an AES key ... \n");
+ /* generate an AES Secret Key */
+ crv = pFunctionList->C_GenerateKey(hRwSession, &sAESKeyMech,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate),
+ &hAESSecKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey AES succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate an 3DES key ...\n");
+ /* generate an 3DES Secret Key */
+ crv = pFunctionList->C_GenerateKey(hRwSession, &sDES3KeyGenMechanism,
+ sDES3KeyTemplate,
+ NUM_ELEM(sDES3KeyTemplate),
+ &hDES3SecKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey DES3 succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate DSA PQG domain parameters ... \n");
+ /* Generate DSA domain parameters PQG */
+ crv = pFunctionList->C_GenerateKey(hRwSession, &dsaParamGenMech,
+ dsaParamGenTemplate,
+ 1,
+ &hDsaParams);
+ if (crv == CKR_OK) {
+ PKM_LogIt("DSA domain parameter generation succeeded\n");
+ } else {
+ PKM_Error( "DSA domain parameter generation failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_GetAttributeValue(hRwSession, hDsaParams,
+ dsaPubKeyTemplate, 3);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Getting DSA domain parameters succeeded\n");
+ } else {
+ PKM_Error( "Getting DSA domain parameters failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DestroyObject(hRwSession, hDsaParams);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Destroying DSA domain parameters succeeded\n");
+ } else {
+ PKM_Error( "Destroying DSA domain parameters failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate a DSA key pair ... \n");
+ /* Generate a persistent DSA key pair */
+ crv = pFunctionList->C_GenerateKeyPair(hRwSession, &dsaKeyPairGenMech,
+ dsaPubKeyTemplate,
+ NUM_ELEM(dsaPubKeyTemplate),
+ dsaPrivKeyTemplate,
+ NUM_ELEM(dsaPrivKeyTemplate),
+ &hDSApubKey, &hDSAprivKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("DSA key pair generation succeeded\n");
+ } else {
+ PKM_Error( "DSA key pair generation failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate a RSA key pair ... \n");
+ /*** GEN RSA Key ***/
+ crv = pFunctionList->C_GenerateKeyPair(hRwSession, &rsaKeyPairGenMech,
+ rsaPubKeyTemplate,
+ NUM_ELEM(rsaPubKeyTemplate),
+ rsaPrivKeyTemplate,
+ NUM_ELEM(rsaPrivKeyTemplate),
+ &hRSApubKey, &hRSAprivKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKeyPair created an RSA key pair. \n");
+ } else {
+ PKM_Error("C_GenerateKeyPair failed to create an RSA key pair.\n"
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("**** Generation of keys completed ***** \n");
+
+ mech.mechanism = CKM_RSA_PKCS;
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ crv = PKM_wrapUnwrap(pFunctionList,
+ hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hAESSecKey,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate));
+
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap AES key "
+ "succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap AES key failed "
+ "with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = PKM_wrapUnwrap(pFunctionList,
+ hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hDES3SecKey,
+ sDES3KeyTemplate,
+ NUM_ELEM(sDES3KeyTemplate));
+
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
+ "succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_wrapUnwrap using RSA keypair to wrap DES3 key "
+ "failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
+ hAESSecKey, &mech_AES_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SecKeyCrypt succeeded \n\n");
+ } else {
+ PKM_Error( "PKM_SecKeyCrypt failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
+ hAESSecKey, &mech_AES_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SecKeyCrypt AES succeeded \n\n");
+ } else {
+ PKM_Error( "PKM_SecKeyCrypt failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
+ hDES3SecKey, &mech_DES3_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n");
+ } else {
+ PKM_Error( "PKM_SecKeyCrypt DES3 failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = PKM_SecKeyCrypt(pFunctionList, hRwSession,
+ hDES3SecKey, &mech_DES3_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_SecKeyCrypt DES3 succeeded \n\n");
+ } else {
+ PKM_Error( "PKM_SecKeyCrypt DES3 failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ mech.mechanism = CKM_RSA_PKCS;
+ crv = PKM_RecoverFunctions(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_RecoverFunctions for CKM_RSA_PKCS succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_RecoverFunctions failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ mech.pParameter = NULL;
+ mech.ulParameterLen = 0;
+
+ for (i=0; i < sigRSAMechsSZ; i++) {
+
+ mech.mechanism = sigRSAMechs[i].mechanism;
+
+ crv = PKM_PubKeySign(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_PubKeySign succeeded for %-10s\n\n",
+ sigRSAMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_PubKeySign failed for %-10s "
+ "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hAESSecKey, &mech_AES_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
+ "for %-10s\n\n",
+ sigRSAMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_DualFuncSign with AES secret key failed "
+ "for %-10s "
+ "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hDES3SecKey, &mech_DES3_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
+ "for %-10s\n\n",
+ sigRSAMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_DualFuncSign with DES3 secret key failed "
+ "for %-10s "
+ "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hAESSecKey, &mech_AES_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD "
+ "succeeded for %-10s\n\n",
+ sigRSAMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD "
+ "failed for %-10s "
+ "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hRSApubKey, hRSAprivKey,
+ &mech,
+ hDES3SecKey, &mech_DES3_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD "
+ "succeeded for %-10s\n\n",
+ sigRSAMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD "
+ "failed for %-10s "
+ "with 0x%08X, %-26s\n", sigRSAMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ } /* end of RSA for loop */
+
+ crv = PKM_PubKeySign(pFunctionList, hRwSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_PubKeySign for DSAwithSHA1 succeeded \n\n");
+ } else {
+ PKM_Error( "PKM_PubKeySign failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech,
+ hAESSecKey, &mech_AES_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with AES secret key succeeded "
+ "for DSAWithSHA1\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncSign with AES secret key failed "
+ "for DSAWithSHA1 with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech,
+ hDES3SecKey, &mech_DES3_CBC,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with DES3 secret key succeeded "
+ "for DSAWithSHA1\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncSign with DES3 secret key failed "
+ "for DSAWithSHA1 with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech,
+ hAESSecKey, &mech_AES_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with AES secret key CBC_PAD succeeded "
+ "for DSAWithSHA1\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncSign with AES secret key CBC_PAD failed "
+ "for DSAWithSHA1 with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncSign(pFunctionList, hRwSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech,
+ hDES3SecKey, &mech_DES3_CBC_PAD,
+ PLAINTEXT_PAD, sizeof(PLAINTEXT_PAD));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncSign with DES3 secret key CBC_PAD succeeded "
+ "for DSAWithSHA1\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncSign with DES3 secret key CBC_PAD failed "
+ "for DSAWithSHA1 with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ for (i=0; i < digestMechsSZ; i++) {
+ mech.mechanism = digestMechs[i].mechanism;
+ crv = PKM_Digest(pFunctionList, hRwSession,
+ &mech, hAESSecKey,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Digest with AES secret key succeeded for %-10s\n\n",
+ digestMechs[i].mechanismStr);
+ } else {
+ PKM_Error( "PKM_Digest with AES secret key failed for "
+ "%-10s with 0x%08X, %-26s\n",
+ digestMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
+ hAESSecKey, &mech_AES_CBC,
+ 0,&mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncDigest with AES secret key succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncDigest with AES secret key "
+ "failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ }
+
+ crv = PKM_Digest(pFunctionList, hRwSession,
+ &mech, hDES3SecKey,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Digest with DES3 secret key succeeded for %-10s\n\n",
+ digestMechs[i].mechanismStr);
+ } else {
+ PKM_Error( "PKM_Digest with DES3 secret key failed for "
+ "%-10s with 0x%08X, %-26s\n",
+ digestMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_DualFuncDigest(pFunctionList, hRwSession,
+ hDES3SecKey, &mech_DES3_CBC,
+ 0,&mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_DualFuncDigest DES3 secret key succeeded\n\n");
+ } else {
+ PKM_Error( "PKM_DualFuncDigest DES3 secret key "
+ "failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ }
+
+ crv = PKM_Digest(pFunctionList, hRwSession,
+ &mech, 0,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Digest with no secret key succeeded for %-10s\n\n",
+ digestMechs[i].mechanismStr );
+ } else {
+ PKM_Error( "PKM_Digest with no secret key failed for %-10s "
+ "with 0x%08X, %-26s\n", digestMechs[i].mechanismStr, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ } /* end of digest loop */
+
+ for (i=0; i < hmacMechsSZ; i++) {
+ mech.mechanism = hmacMechs[i].mechanism;
+ crv = PKM_Hmac(pFunctionList, hRwSession,
+ hAESSecKey, &mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Hmac with AES secret key succeeded for %-10s\n\n",
+ hmacMechs[i].mechanismStr);
+ } else {
+ PKM_Error( "PKM_Hmac with AES secret key failed for %-10s "
+ "with 0x%08X, %-26s\n",
+ hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if ((MODE == FIPSMODE) && (mech.mechanism == CKM_SHA512_HMAC)) break;
+ crv = PKM_Hmac(pFunctionList, hRwSession,
+ hDES3SecKey, &mech,
+ PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_Hmac with DES3 secret key succeeded for %-10s\n\n",
+ hmacMechs[i].mechanismStr);
+ } else {
+ PKM_Error( "PKM_Hmac with DES3 secret key failed for %-10s "
+ "with 0x%08X, %-26s\n",
+ hmacMechs[i].mechanismStr, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ } /* end of hmac loop */
+
+ crv = pFunctionList->C_Logout(hRwSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CloseSession(hRwSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+
+}
+
+void PKM_LogIt(const char *fmt, ...) {
+ va_list args;
+
+ if (verbose) {
+ va_start (args, fmt);
+ if (MODE == FIPSMODE) {
+ printf("FIPS MODE: ");
+ } else if (MODE == NONFIPSMODE) {
+ printf("NON FIPS MODE: ");
+ } else if (MODE == HYBRIDMODE) {
+ printf("Hybrid MODE: ");
+ } else printf ("NO MODE: ");
+ vprintf(fmt, args);
+ va_end(args);
+ }
+}
+
+void PKM_Error(const char *fmt, ...) {
+ va_list args;
+ va_start (args, fmt);
+
+ if (MODE == FIPSMODE) {
+ fprintf(stderr, "\nFIPS MODE PKM_Error: ");
+ } else if (MODE == NONFIPSMODE) {
+ fprintf(stderr, "NON FIPS MODE PKM_Error: ");
+ } else if (MODE == HYBRIDMODE) {
+ fprintf(stderr, "Hybrid MODE PKM_Error: ");
+ } else fprintf(stderr, "NOMODE PKM_Error: ");
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+CK_SLOT_ID *PKM_GetSlotList(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_ULONG slotID) {
+ CK_RV crv = CKR_OK;
+ CK_SLOT_ID *pSlotList = NULL;
+ CK_ULONG slotCount;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* Get slot list */
+ crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
+ NULL, &slotCount);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return NULL;
+ }
+ PKM_LogIt("C_GetSlotList reported there are %lu slots\n", slotCount);
+ pSlotList = (CK_SLOT_ID *)malloc(slotCount * sizeof(CK_SLOT_ID));
+ if (!pSlotList) {
+ PKM_Error( "failed to allocate slot list\n");
+ return NULL;
+ }
+ crv = pFunctionList->C_GetSlotList(CK_FALSE /* all slots */,
+ pSlotList, &slotCount);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetSlotList failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ if (pSlotList) free(pSlotList);
+ return NULL;
+ }
+ return pSlotList;
+}
+
+CK_RV PKM_InitPWforDB(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_RV crv = CKR_OK;
+ CK_SESSION_HANDLE hSession;
+ static const CK_UTF8CHAR testPin[] = {"0Mozilla"};
+ static const CK_UTF8CHAR weakPin[] = {"mozilla"};
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID],
+ CKF_RW_SESSION | CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
+
+ crv = pFunctionList->C_Login(hSession, CKU_SO, NULL, 0);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if (MODE == FIPSMODE) {
+ crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) weakPin,
+ sizeof(weakPin));
+ if (crv == CKR_OK) {
+ PKM_Error( "C_InitPIN with a weak password succeeded\n");
+ return crv;
+ } else {
+ PKM_LogIt("C_InitPIN with a weak password failed with "
+ "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ }
+ }
+ crv = pFunctionList->C_InitPIN(hSession, (CK_UTF8CHAR *) testPin,
+ sizeof(testPin));
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_InitPIN succeeded\n");
+ } else {
+ PKM_Error( "C_InitPIN failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID],
+ CKF_RW_SESSION | CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("CKU_USER 0x%08X \n", CKU_USER);
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, (CK_UTF8CHAR *) testPin,
+ strlen((const char *)testPin));
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Login failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if (MODE == FIPSMODE) {
+ crv = pFunctionList->C_SetPIN(
+ hSession, (CK_UTF8CHAR *) testPin,
+ strlen((const char *)testPin),
+ (CK_UTF8CHAR *) weakPin,
+ strlen((const char *)weakPin));
+ if (crv == CKR_OK) {
+ PKM_Error( "C_SetPIN with a weak password succeeded\n");
+ return crv;
+ } else {
+ PKM_LogIt("C_SetPIN with a weak password returned with "
+ "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ }
+ }
+ crv = pFunctionList->C_SetPIN(
+ hSession, (CK_UTF8CHAR *) testPin,
+ strlen((const char *)testPin),
+ pwd, pwdLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CSetPin failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ return crv;
+}
+
+CK_RV PKM_ShowInfo(CK_FUNCTION_LIST_PTR pFunctionList, CK_ULONG slotID) {
+ CK_RV crv = CKR_OK;
+ CK_INFO info;
+ CK_SLOT_ID *pSlotList = NULL;
+ unsigned i;
+
+ CK_SLOT_INFO slotInfo;
+ CK_TOKEN_INFO tokenInfo;
+ CK_FLAGS bitflag;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+
+ crv = pFunctionList->C_GetInfo(&info);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetInfo succeeded\n");
+ } else {
+ PKM_Error( "C_GetInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("General information about the PKCS #11 library:\n");
+ PKM_LogIt(" PKCS #11 version: %d.%d\n",
+ (int)info.cryptokiVersion.major,
+ (int)info.cryptokiVersion.minor);
+ PKM_LogIt(" manufacturer ID: %.32s\n", info.manufacturerID);
+ PKM_LogIt(" flags: 0x%08lX\n", info.flags);
+ PKM_LogIt(" library description: %.32s\n", info.libraryDescription);
+ PKM_LogIt(" library version: %d.%d\n",
+ (int)info.libraryVersion.major, (int)info.libraryVersion.minor);
+ PKM_LogIt("\n");
+
+ /* Get slot list */
+ pSlotList = PKM_GetSlotList(pFunctionList, slotID);
+ if (pSlotList == NULL) {
+ PKM_Error( "PKM_GetSlotList failed with \n");
+ return crv;
+ }
+ crv = pFunctionList->C_GetSlotInfo(pSlotList[slotID], &slotInfo);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetSlotInfo succeeded\n");
+ } else {
+ PKM_Error( "C_GetSlotInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("Information about slot %lu:\n", pSlotList[slotID]);
+ PKM_LogIt(" slot description: %.64s\n", slotInfo.slotDescription);
+ PKM_LogIt(" slot manufacturer ID: %.32s\n", slotInfo.manufacturerID);
+ PKM_LogIt(" flags: 0x%08lX\n", slotInfo.flags);
+ bitflag = 1;
+ for (i = 0; i < sizeof(slotFlagName)/sizeof(slotFlagName[0]); i++) {
+ if (slotInfo.flags & bitflag) {
+ PKM_LogIt(" %s\n", slotFlagName[i]);
+ }
+ bitflag <<= 1;
+ }
+ PKM_LogIt(" slot's hardware version number: %d.%d\n",
+ (int)slotInfo.hardwareVersion.major,
+ (int)slotInfo.hardwareVersion.minor);
+ PKM_LogIt(" slot's firmware version number: %d.%d\n",
+ (int)slotInfo.firmwareVersion.major,
+ (int)slotInfo.firmwareVersion.minor);
+ PKM_LogIt("\n");
+
+ crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tokenInfo);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetTokenInfo succeeded\n");
+ } else {
+ PKM_Error( "C_GetTokenInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("Information about the token in slot %lu:\n",
+ pSlotList[slotID]);
+ PKM_LogIt(" label: %.32s\n", tokenInfo.label);
+ PKM_LogIt(" device manufacturer ID: %.32s\n",
+ tokenInfo.manufacturerID);
+ PKM_LogIt(" device model: %.16s\n", tokenInfo.model);
+ PKM_LogIt(" device serial number: %.16s\n", tokenInfo.serialNumber);
+ PKM_LogIt(" flags: 0x%08lX\n", tokenInfo.flags);
+ bitflag = 1;
+ for (i = 0; i < sizeof(tokenFlagName)/sizeof(tokenFlagName[0]); i++) {
+ if (tokenInfo.flags & bitflag) {
+ PKM_LogIt(" %s\n", tokenFlagName[i]);
+ }
+ bitflag <<= 1;
+ }
+ PKM_LogIt(" maximum session count: %lu\n",
+ tokenInfo.ulMaxSessionCount);
+ PKM_LogIt(" session count: %lu\n", tokenInfo.ulSessionCount);
+ PKM_LogIt(" maximum read/write session count: %lu\n",
+ tokenInfo.ulMaxRwSessionCount);
+ PKM_LogIt(" read/write session count: %lu\n",
+ tokenInfo.ulRwSessionCount);
+ PKM_LogIt(" maximum PIN length: %lu\n", tokenInfo.ulMaxPinLen);
+ PKM_LogIt(" minimum PIN length: %lu\n", tokenInfo.ulMinPinLen);
+ PKM_LogIt(" total public memory: %lu\n",
+ tokenInfo.ulTotalPublicMemory);
+ PKM_LogIt(" free public memory: %lu\n",
+ tokenInfo.ulFreePublicMemory);
+ PKM_LogIt(" total private memory: %lu\n",
+ tokenInfo.ulTotalPrivateMemory);
+ PKM_LogIt(" free private memory: %lu\n",
+ tokenInfo.ulFreePrivateMemory);
+ PKM_LogIt(" hardware version number: %d.%d\n",
+ (int)tokenInfo.hardwareVersion.major,
+ (int)tokenInfo.hardwareVersion.minor);
+ PKM_LogIt(" firmware version number: %d.%d\n",
+ (int)tokenInfo.firmwareVersion.major,
+ (int)tokenInfo.firmwareVersion.minor);
+ if (tokenInfo.flags & CKF_CLOCK_ON_TOKEN) {
+ PKM_LogIt(" current time: %.16s\n", tokenInfo.utcTime);
+ }
+ PKM_LogIt("PKM_ShowInfo done \n\n");
+ if (pSlotList) free(pSlotList);
+ return crv;
+}
+
+/* PKM_HybridMode */
+/* The NSS cryptographic module has two modes of operation: FIPS Approved */
+/* mode and NONFIPS Approved mode. The two modes of operation are */
+/* independent of each other -- they have their own copies of data */
+/* structures and they are even allowed to be active at the same time. */
+/* The module is FIPS 140-2 compliant only when the NONFIPS mode */
+/* is inactive. */
+/* PKM_HybridMode demostrates how an application can switch between the */
+/* two modes: FIPS Approved mode and NONFIPS mode. */
+CK_RV PKM_HybridMode(CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_C_INITIALIZE_ARGS_NSS *initArgs) {
+
+ CK_C_GetFunctionList pC_GetFunctionList; /* NONFIPSMode */
+ CK_FUNCTION_LIST_PTR pC_FunctionList;
+ CK_SLOT_ID *pC_SlotList = NULL;
+ CK_ULONG slotID_C = 1;
+ CK_C_GetFunctionList pFC_GetFunctionList; /* FIPSMode */
+ CK_FUNCTION_LIST_PTR pFC_FunctionList;
+ CK_SLOT_ID *pFC_SlotList = NULL;
+ CK_ULONG slotID_FC = 0;
+ CK_RV crv = CKR_OK;
+ CK_SESSION_HANDLE hSession;
+ int origMode = MODE; /* remember the orginal MODE value */
+
+ NUMTESTS++; /* increment NUMTESTS */
+ MODE = NONFIPSMODE;
+#ifdef _WIN32
+ /* NON FIPS mode == C_GetFunctionList */
+ pC_GetFunctionList = (CK_C_GetFunctionList)
+ GetProcAddress(hModule, "C_GetFunctionList");
+ if (pC_GetFunctionList == NULL) {
+ PKM_Error( "cannot load %s\n", LIB_NAME);
+ return crv;
+ }
+#else
+ pC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
+ "C_GetFunctionList");
+ assert(pC_GetFunctionList != NULL);
+#endif
+ PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n",
+ slotID_C);
+ crv = (*pC_GetFunctionList)(&pC_FunctionList);
+ assert(crv == CKR_OK);
+
+ /* invoke C_Initialize as pC_FunctionList->C_Initialize */
+ crv = pC_FunctionList->C_Initialize(initArgs);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Initialize succeeded\n");
+ } else {
+ PKM_Error( "C_Initialize failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ pC_SlotList = PKM_GetSlotList(pC_FunctionList, slotID_C);
+ if (pC_SlotList == NULL) {
+ PKM_Error( "PKM_GetSlotList failed with \n");
+ return crv;
+ }
+ crv = pC_FunctionList->C_OpenSession(pC_SlotList[slotID_C],
+ CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("NONFIPS C_OpenSession succeeded\n");
+ } else {
+ PKM_Error( "C_OpenSession failed for NONFIPS token "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("able to login in NONFIPS token\n");
+ } else {
+ PKM_Error( "Unable to login in to NONFIPS token "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pC_FunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_ShowInfo(pC_FunctionList, slotID_C);
+ MODE = HYBRIDMODE;
+
+ /* Now load the FIPS token */
+ /* FIPS mode == FC_GetFunctionList */
+ pFC_GetFunctionList = NULL;
+#ifdef _WIN32
+ pFC_GetFunctionList = (CK_C_GetFunctionList)
+ GetProcAddress(hModule, "FC_GetFunctionList");
+#else
+ pFC_GetFunctionList = (CK_C_GetFunctionList) PR_FindFunctionSymbol(lib,
+ "FC_GetFunctionList");
+ assert(pFC_GetFunctionList != NULL);
+#endif
+
+ PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n",
+ slotID_FC);
+ PKM_LogIt("pFC_FunctionList->C_Foo == pFC_FunctionList->FC_Foo\n");
+ if (pFC_GetFunctionList == NULL) {
+ PKM_Error( "unable to load pFC_GetFunctionList\n");
+ return crv;
+ }
+
+ crv = (*pFC_GetFunctionList)(&pFC_FunctionList);
+ assert(crv == CKR_OK);
+
+ /* invoke FC_Initialize as pFunctionList->C_Initialize */
+ crv = pFC_FunctionList->C_Initialize(initArgs);
+ if (crv == CKR_OK) {
+ PKM_LogIt("FC_Initialize succeeded\n");
+ } else {
+ PKM_Error( "FC_Initialize failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_ShowInfo(pFC_FunctionList, slotID_FC);
+
+ pFC_SlotList = PKM_GetSlotList(pFC_FunctionList, slotID_FC);
+ if (pFC_SlotList == NULL) {
+ PKM_Error( "PKM_GetSlotList failed with \n");
+ return crv;
+ }
+
+ crv = pC_FunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv != CKR_OK) {
+ PKM_LogIt("NONFIPS token cannot log in when FIPS token is loaded\n");
+ } else {
+ PKM_Error("Able to login in to NONFIPS token\n");
+ return crv;
+ }
+ crv = pC_FunctionList->C_CloseSession(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("NONFIPS pC_CloseSession succeeded\n");
+ } else {
+ PKM_Error( "pC_CloseSession failed for NONFIPS token "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("The module is FIPS 140-2 compliant\n"
+ "only when the NONFIPS Approved mode is inactive by \n"
+ "calling C_Finalize on the NONFIPS token.\n");
+
+
+ /* to go in FIPSMODE you must Finalize the NONFIPS mode pointer */
+ crv = pC_FunctionList->C_Finalize(NULL);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Finalize of NONFIPS Token succeeded\n");
+ MODE = FIPSMODE;
+ } else {
+ PKM_Error( "C_Finalize of NONFIPS Token failed with "
+ "0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("*** In FIPS mode! ***\n");
+
+ /* could do some operations in FIPS MODE */
+
+ crv = pFC_FunctionList->C_Finalize(NULL);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Exiting FIPSMODE by caling FC_Finalize.\n");
+ MODE = NOMODE;
+ } else {
+ PKM_Error( "FC_Finalize failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (pC_SlotList) free(pC_SlotList);
+ if (pFC_SlotList) free(pFC_SlotList);
+
+ MODE = origMode; /* set the mode back to the orginal Mode value */
+ PKM_LogIt("PKM_HybridMode test Completed\n\n");
+ return crv;
+}
+
+CK_RV PKM_Mechanism(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID) {
+
+ CK_RV crv = CKR_OK;
+ CK_MECHANISM_TYPE *pMechanismList;
+ CK_ULONG mechanismCount;
+ CK_ULONG i;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* Get the mechanism list */
+ crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
+ NULL, &mechanismCount);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("C_GetMechanismList reported there are %lu mechanisms\n",
+ mechanismCount);
+ pMechanismList = (CK_MECHANISM_TYPE *)
+ malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE));
+ if (!pMechanismList) {
+ PKM_Error( "failed to allocate mechanism list\n");
+ return crv;
+ }
+ crv = pFunctionList->C_GetMechanismList(pSlotList[slotID],
+ pMechanismList, &mechanismCount);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetMechanismList failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt("C_GetMechanismList returned the mechanism types:\n");
+ if (verbose) {
+ for (i = 0; i < mechanismCount; i++) {
+ printf(" 0x%08lX", pMechanismList[i]);
+ if ((i != 0) && ((i % 4) == 0 )) printf("\n");
+ }
+ printf("\n");
+ }
+
+ for ( i = 0; i < mechanismCount; i++ ) {
+ CK_MECHANISM_INFO minfo;
+
+ memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
+ crv = pFunctionList->C_GetMechanismInfo(pSlotList[slotID],
+ pMechanismList[i], &minfo);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_GetMechanismInfo(%lu, %lu) returned 0x%08X, %-26s\n",
+ pSlotList[slotID], pMechanismList[i], crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " [%lu]: CK_MECHANISM_TYPE = %lu\n", (i+1),
+ pMechanismList[i]);
+ PKM_LogIt( " ulMinKeySize = %lu\n", minfo.ulMinKeySize);
+ PKM_LogIt( " ulMaxKeySize = %lu\n", minfo.ulMaxKeySize);
+ PKM_LogIt( " flags = 0x%08x\n", minfo.flags);
+ PKM_LogIt( " -> HW = %s\n", minfo.flags & CKF_HW ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> SIGN = %s\n", minfo.flags & CKF_SIGN ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> SIGN_RECOVER = %s\n", minfo.flags &
+ CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
+ PKM_LogIt( " -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> VERIFY_RECOVER = %s\n",
+ minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
+ PKM_LogIt( " -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> GENERATE_KEY_PAIR = %s\n",
+ minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
+ PKM_LogIt( " -> WRAP = %s\n", minfo.flags & CKF_WRAP ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ?
+ "TRUE" : "FALSE");
+ PKM_LogIt( " -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ?
+ "TRUE" : "FALSE");
+
+ PKM_LogIt( "\n");
+ }
+
+
+ return crv;
+
+}
+
+CK_RV PKM_RNG(CK_FUNCTION_LIST_PTR pFunctionList, CK_SLOT_ID * pSlotList,
+ CK_ULONG slotID) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+ CK_BYTE randomData[16];
+ CK_BYTE seed[] = {0x01, 0x03, 0x35, 0x55, 0xFF};
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_GenerateRandom(hSession,
+ randomData, sizeof randomData);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateRandom without login succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateRandom without login failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_SeedRandom(hSession, seed, sizeof(seed));
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SeedRandom without login succeeded\n");
+ } else {
+ PKM_Error( "C_SeedRandom without login failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_GenerateRandom(hSession,
+ randomData, sizeof randomData);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateRandom without login succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateRandom without login failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+
+}
+
+CK_RV PKM_SessionLogin(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID *pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error("C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *)
+ "netscape", 8);
+ if (crv == CKR_OK) {
+ PKM_Error("C_Login with wrong password succeeded\n");
+ return CKR_FUNCTION_FAILED;
+ } else {
+ PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
+ "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
+ }
+ crv = pFunctionList->C_Login(hSession, CKU_USER, (unsigned char *)
+ "red hat", 7);
+ if (crv == CKR_OK) {
+ PKM_Error("C_Login with wrong password succeeded\n");
+ return CKR_FUNCTION_FAILED;
+ } else {
+ PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
+ "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
+ }
+ crv = pFunctionList->C_Login(hSession, CKU_USER,
+ (unsigned char *) "sun", 3);
+ if (crv == CKR_OK) {
+ PKM_Error("C_Login with wrong password succeeded\n");
+ return CKR_FUNCTION_FAILED;
+ } else {
+ PKM_LogIt("As expected C_Login with wrong password returned 0x%08X, "
+ "%-26s.\n ", crv, PKM_CK_RVtoStr(crv));
+ }
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error("C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+
+}
+
+/*
+* PKM_LegacyFunctions
+*
+* Legacyfunctions exist only for backwards compatibility.
+* C_GetFunctionStatus and C_CancelFunction functions were
+* meant for managing parallel execution of cryptographic functions.
+*
+* C_GetFunctionStatus is a legacy function which should simply return
+* the value CKR_FUNCTION_NOT_PARALLEL.
+*
+* C_CancelFunction is a legacy function which should simply return the
+* value CKR_FUNCTION_NOT_PARALLEL.
+*
+*/
+CK_RV PKM_LegacyFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_GetFunctionStatus(hSession);
+ if (crv == CKR_FUNCTION_NOT_PARALLEL) {
+ PKM_LogIt("C_GetFunctionStatus correctly"
+ "returned CKR_FUNCTION_NOT_PARALLEL \n");
+ } else {
+ PKM_Error( "C_GetFunctionStatus failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CancelFunction(hSession);
+ if (crv == CKR_FUNCTION_NOT_PARALLEL) {
+ PKM_LogIt("C_CancelFunction correctly "
+ "returned CKR_FUNCTION_NOT_PARALLEL \n");
+ } else {
+ PKM_Error( "C_CancelFunction failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+
+}
+
+/*
+* PKM_DualFuncDigest - demostrates the Dual-function
+* cryptograpic functions:
+*
+* C_DigestEncryptUpdate - multi-part Digest and Encrypt
+* C_DecryptDigestUpdate - multi-part Decrypt and Digest
+*
+*
+*/
+
+CK_RV PKM_DualFuncDigest(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hSecKey, CK_MECHANISM *cryptMech,
+ CK_OBJECT_HANDLE hSecKeyDigest,
+ CK_MECHANISM *digestMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen) {
+ CK_RV crv = CKR_OK;
+ CK_BYTE eDigest[MAX_DIGEST_SZ];
+ CK_BYTE dDigest[MAX_DIGEST_SZ];
+ CK_ULONG ulDigestLen;
+ CK_BYTE ciphertext[MAX_CIPHER_SZ];
+ CK_ULONG ciphertextLen, lastLen;
+ CK_BYTE plaintext[MAX_DATA_SZ];
+ CK_ULONG plaintextLen;
+ unsigned int i;
+
+ memset(eDigest, 0, sizeof(eDigest));
+ memset(dDigest, 0, sizeof(dDigest));
+ memset(ciphertext, 0, sizeof(ciphertext));
+ memset(plaintext, 0, sizeof(plaintext));
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /*
+ * First init the Digest and Ecrypt operations
+ */
+ crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSecKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DigestInit(hSession, digestMech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ ciphertextLen = sizeof(ciphertext);
+ crv = pFunctionList->C_DigestEncryptUpdate(hSession, (CK_BYTE * ) pData,
+ pDataLen,
+ ciphertext, &ciphertextLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestEncryptUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ ulDigestLen = sizeof(eDigest);
+ crv = pFunctionList->C_DigestFinal(hSession, eDigest, &ulDigestLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ /* get the last piece of ciphertext (length should be 0 */
+ lastLen = sizeof(ciphertext) - ciphertextLen;
+ crv = pFunctionList->C_EncryptFinal(hSession,
+ (CK_BYTE * )&ciphertext[ciphertextLen],
+ &lastLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ ciphertextLen = ciphertextLen + lastLen;
+ if (verbose) {
+ printf("ciphertext = ");
+ for (i = 0; i < ciphertextLen; i++) {
+ printf("%02x", (unsigned)ciphertext[i]);
+ }
+ printf("\n");
+ printf("eDigest = ");
+ for (i = 0; i < ulDigestLen; i++) {
+ printf("%02x", (unsigned)eDigest[i]);
+ }
+ printf("\n");
+ }
+
+ /* Decrypt the text */
+ crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSecKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DigestInit(hSession, digestMech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ plaintextLen = sizeof(plaintext);
+ crv = pFunctionList->C_DecryptDigestUpdate(hSession, ciphertext,
+ ciphertextLen,
+ plaintext,
+ &plaintextLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptDigestUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ lastLen = sizeof(plaintext) - plaintextLen;
+
+ crv = pFunctionList->C_DecryptFinal(hSession,
+ (CK_BYTE * )&plaintext[plaintextLen],
+ &lastLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ plaintextLen = plaintextLen + lastLen;
+
+ ulDigestLen = sizeof(dDigest);
+ crv = pFunctionList->C_DigestFinal(hSession, dDigest, &ulDigestLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (plaintextLen != pDataLen) {
+ PKM_Error( "plaintextLen is %lu\n", plaintextLen);
+ return crv;
+ }
+
+ if (verbose) {
+ printf("plaintext = ");
+ for (i = 0; i < plaintextLen; i++) {
+ printf("%02x", (unsigned)plaintext[i]);
+ }
+ printf("\n");
+ printf("dDigest = ");
+ for (i = 0; i < ulDigestLen; i++) {
+ printf("%02x", (unsigned)dDigest[i]);
+ }
+ printf("\n");
+ }
+
+ if (memcmp(eDigest, dDigest, ulDigestLen) == 0) {
+ PKM_LogIt("Encrypted Digest equals Decrypted Digest\n");
+ } else {
+ PKM_Error( "Digests don't match\n");
+ }
+
+ if ((plaintextLen == pDataLen) &&
+ (memcmp(plaintext, pData, pDataLen)) == 0) {
+ PKM_LogIt("DualFuncDigest decrypt test case passed\n");
+ } else {
+ PKM_Error( "DualFuncDigest derypt test case failed\n");
+ }
+
+ return crv;
+
+}
+
+/*
+* PKM_SecKeyCrypt - Symmetric key encrypt/decyprt
+*
+*/
+
+CK_RV PKM_SecKeyCrypt(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hSymKey, CK_MECHANISM *cryptMech,
+ const CK_BYTE * pData, CK_ULONG dataLen) {
+ CK_RV crv = CKR_OK;
+
+ CK_BYTE cipher1[MAX_CIPHER_SZ];
+ CK_BYTE cipher2[MAX_CIPHER_SZ];
+ CK_BYTE data1[MAX_DATA_SZ];
+ CK_BYTE data2[MAX_DATA_SZ];
+ CK_ULONG cipher1Len =0, cipher2Len =0, lastLen =0;
+ CK_ULONG data1Len =0, data2Len =0;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ memset(cipher1, 0, sizeof(cipher1));
+ memset(cipher2, 0, sizeof(cipher2));
+ memset(data1, 0, sizeof(data1));
+ memset(data2, 0, sizeof(data2));
+
+ /* C_Encrypt */
+ crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ cipher1Len = sizeof(cipher1);
+ crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE * ) pData, dataLen,
+ cipher1, &cipher1Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* C_EncryptUpdate */
+ crv = pFunctionList->C_EncryptInit(hSession, cryptMech, hSymKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ cipher2Len = sizeof(cipher2);
+ crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE * ) pData,
+ dataLen,
+ cipher2, &cipher2Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ lastLen = sizeof(cipher2) - cipher2Len;
+
+ crv = pFunctionList->C_EncryptFinal(hSession,
+ (CK_BYTE * )&cipher2[cipher2Len],
+ &lastLen);
+ cipher2Len = cipher2Len + lastLen;
+
+ if ( (cipher1Len == cipher2Len) &&
+ (memcmp(cipher1, cipher2, sizeof(cipher1Len)) == 0) ) {
+ PKM_LogIt("encrypt test case passed\n");
+ } else {
+ PKM_Error( "encrypt test case failed\n");
+ return CKR_GENERAL_ERROR;
+ }
+
+ /* C_Decrypt */
+ crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ data1Len = sizeof(data1);
+ crv = pFunctionList->C_Decrypt(hSession, cipher1, cipher1Len,
+ data1, &data1Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ /* now use C_DecryptUpdate the text */
+ crv = pFunctionList->C_DecryptInit(hSession, cryptMech, hSymKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ data2Len = sizeof(data2);
+ crv = pFunctionList->C_DecryptUpdate(hSession, cipher2,
+ cipher2Len,
+ data2, &data2Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ lastLen = sizeof(data2) - data2Len;
+ crv = pFunctionList->C_DecryptFinal(hSession,
+ (CK_BYTE * )&data2[data2Len],
+ &lastLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ data2Len = data2Len + lastLen;
+
+
+ /* Comparison of Decrypt data */
+
+ if ( (data1Len == data2Len) && (dataLen == data1Len) &&
+ (memcmp(data1, pData, dataLen) == 0) &&
+ (memcmp(data2, pData, dataLen) == 0) ) {
+ PKM_LogIt("decrypt test case passed\n");
+ } else {
+ PKM_Error( "derypt test case failed\n");
+ }
+
+ return crv;
+
+}
+
+
+CK_RV PKM_SecretKey(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+ CK_MECHANISM sAESKeyMech = {
+ CKM_AES_KEY_GEN, NULL, 0
+ };
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE keyAESType = CKK_AES;
+ CK_UTF8CHAR AESlabel[] = "An AES secret key object";
+ CK_ULONG AESvalueLen = 16;
+ CK_ATTRIBUTE sAESKeyTemplate[9];
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
+
+ CK_BYTE KEY[16];
+ CK_BYTE IV[16];
+ static const CK_BYTE CIPHERTEXT[] = {
+ 0x7e,0x6a,0x3f,0x3b,0x39,0x3c,0xf2,0x4b,
+ 0xce,0xcc,0x23,0x6d,0x80,0xfd,0xe0,0xff
+ };
+ CK_BYTE ciphertext[64];
+ CK_BYTE ciphertext2[64];
+ CK_ULONG ciphertextLen, ciphertext2Len, lastLen;
+ CK_BYTE plaintext[32];
+ CK_BYTE plaintext2[32];
+ CK_ULONG plaintextLen, plaintext2Len;
+ CK_BYTE wrappedKey[16];
+ CK_ULONG wrappedKeyLen;
+ CK_MECHANISM aesEcbMech = {
+ CKM_AES_ECB, NULL, 0
+ };
+ CK_OBJECT_HANDLE hTestKey;
+ CK_MECHANISM mech_AES_CBC;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ memset(ciphertext, 0, sizeof(ciphertext));
+ memset(ciphertext2, 0, sizeof(ciphertext2));
+ memset(IV, 0x00, sizeof(IV));
+ memset(KEY, 0x00, sizeof(KEY));
+
+ mech_AES_CBC.mechanism = CKM_AES_CBC;
+ mech_AES_CBC.pParameter = IV;
+ mech_AES_CBC.ulParameterLen = sizeof(IV);
+
+ /* AES key template */
+ sAESKeyTemplate[0].type = CKA_CLASS;
+ sAESKeyTemplate[0].pValue = &class;
+ sAESKeyTemplate[0].ulValueLen = sizeof(class);
+ sAESKeyTemplate[1].type = CKA_KEY_TYPE;
+ sAESKeyTemplate[1].pValue = &keyAESType;
+ sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
+ sAESKeyTemplate[2].type = CKA_LABEL;
+ sAESKeyTemplate[2].pValue = AESlabel;
+ sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
+ sAESKeyTemplate[3].type = CKA_ENCRYPT;
+ sAESKeyTemplate[3].pValue = &true;
+ sAESKeyTemplate[3].ulValueLen = sizeof(true);
+ sAESKeyTemplate[4].type = CKA_DECRYPT;
+ sAESKeyTemplate[4].pValue = &true;
+ sAESKeyTemplate[4].ulValueLen = sizeof(true);
+ sAESKeyTemplate[5].type = CKA_SIGN;
+ sAESKeyTemplate[5].pValue = &true;
+ sAESKeyTemplate[5].ulValueLen = sizeof (true);
+ sAESKeyTemplate[6].type = CKA_VERIFY;
+ sAESKeyTemplate[6].pValue = &true;
+ sAESKeyTemplate[6].ulValueLen = sizeof(true);
+ sAESKeyTemplate[7].type = CKA_UNWRAP;
+ sAESKeyTemplate[7].pValue = &true;
+ sAESKeyTemplate[7].ulValueLen = sizeof(true);
+ sAESKeyTemplate[8].type = CKA_VALUE_LEN;
+ sAESKeyTemplate[8].pValue = &AESvalueLen;
+ sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate an AES key ... \n");
+ /* generate an AES Secret Key */
+ crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate),
+ &hKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey AES succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_EncryptInit(hSession, &aesEcbMech, hKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ wrappedKeyLen = sizeof(wrappedKey);
+ crv = pFunctionList->C_Encrypt(hSession, KEY, sizeof(KEY),
+ wrappedKey, &wrappedKeyLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if (wrappedKeyLen != sizeof(wrappedKey)) {
+ PKM_Error( "wrappedKeyLen is %lu\n", wrappedKeyLen);
+ return crv;
+ }
+ /* Import an encrypted key */
+ crv = pFunctionList->C_UnwrapKey(hSession, &aesEcbMech, hKey,
+ wrappedKey, wrappedKeyLen,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate),
+ &hTestKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_UnwraPKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ /* AES Encrypt the text */
+ crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ ciphertextLen = sizeof(ciphertext);
+ crv = pFunctionList->C_Encrypt(hSession, (CK_BYTE *) PLAINTEXT,
+ sizeof(PLAINTEXT),
+ ciphertext, &ciphertextLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Encrypt failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ( (ciphertextLen == sizeof(CIPHERTEXT)) &&
+ (memcmp(ciphertext, CIPHERTEXT, ciphertextLen) == 0)) {
+ PKM_LogIt("AES CBCVarKey128 encrypt test case 1 passed\n");
+ } else {
+ PKM_Error( "AES CBCVarKey128 encrypt test case 1 failed\n");
+ return crv;
+ }
+
+ /* now use EncryptUpdate the text */
+ crv = pFunctionList->C_EncryptInit(hSession, &mech_AES_CBC, hTestKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ ciphertext2Len = sizeof(ciphertext2);
+ crv = pFunctionList->C_EncryptUpdate (hSession, (CK_BYTE *) PLAINTEXT,
+ sizeof(PLAINTEXT),
+ ciphertext2, &ciphertext2Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ lastLen = sizeof(ciphertext2) - ciphertext2Len;
+
+ crv = pFunctionList->C_EncryptFinal(hSession,
+ (CK_BYTE * )&ciphertext2[ciphertext2Len],
+ &lastLen);
+ ciphertext2Len = ciphertext2Len + lastLen;
+
+ if ( (ciphertextLen == ciphertext2Len) &&
+ (memcmp(ciphertext, ciphertext2, sizeof(CIPHERTEXT)) == 0) &&
+ (memcmp(ciphertext2, CIPHERTEXT, sizeof(CIPHERTEXT)) == 0)) {
+ PKM_LogIt("AES CBCVarKey128 encrypt test case 2 passed\n");
+ } else {
+ PKM_Error( "AES CBCVarKey128 encrypt test case 2 failed\n");
+ return CKR_GENERAL_ERROR;
+ }
+
+ /* AES CBC Decrypt the text */
+ crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ plaintextLen = sizeof(plaintext);
+ crv = pFunctionList->C_Decrypt(hSession, ciphertext, ciphertextLen,
+ plaintext, &plaintextLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if ((plaintextLen == sizeof(PLAINTEXT))
+ && (memcmp(plaintext, PLAINTEXT, plaintextLen) == 0)) {
+ PKM_LogIt("AES CBCVarKey128 decrypt test case 1 passed\n");
+ } else {
+ PKM_Error( "AES CBCVarKey128 derypt test case 1 failed\n");
+ }
+ /* now use DecryptUpdate the text */
+ crv = pFunctionList->C_DecryptInit(hSession, &mech_AES_CBC, hTestKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ plaintext2Len = sizeof(plaintext2);
+ crv = pFunctionList->C_DecryptUpdate(hSession, ciphertext2,
+ ciphertext2Len,
+ plaintext2, &plaintext2Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ lastLen = sizeof(plaintext2) - plaintext2Len;
+ crv = pFunctionList->C_DecryptFinal(hSession,
+ (CK_BYTE * )&plaintext2[plaintext2Len],
+ &lastLen);
+ plaintext2Len = plaintext2Len + lastLen;
+
+ if ( (plaintextLen == plaintext2Len) &&
+ (memcmp(plaintext, plaintext2, plaintext2Len) == 0) &&
+ (memcmp(plaintext2, PLAINTEXT, sizeof(PLAINTEXT)) == 0)) {
+ PKM_LogIt("AES CBCVarKey128 decrypt test case 2 passed\n");
+ } else {
+ PKM_Error( "AES CBCVarKey128 decrypt test case 2 failed\n");
+ return CKR_GENERAL_ERROR;
+ }
+
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ return crv;
+
+}
+
+CK_RV PKM_PubKeySign(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hRwSession,
+ CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
+ CK_MECHANISM *signMech, const CK_BYTE * pData,
+ CK_ULONG pDataLen) {
+ CK_RV crv = CKR_OK;
+ CK_BYTE sig[MAX_SIG_SZ];
+ CK_ULONG sigLen = 0 ;
+
+ NUMTESTS++; /* increment NUMTESTS */
+ memset(sig, 0, sizeof(sig));
+
+ /* C_Sign */
+ crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ sigLen = sizeof(sig);
+ crv = pFunctionList->C_Sign(hRwSession, (CK_BYTE * ) pData, pDataLen,
+ sig, &sigLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* C_Verify the signature */
+ crv = pFunctionList->C_VerifyInit(hRwSession, signMech, hPubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Verify(hRwSession, (CK_BYTE * ) pData, pDataLen,
+ sig, sigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Verify succeeded\n");
+ } else {
+ PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Check that the mechanism is Multi-part */
+ if (signMech->mechanism == CKM_DSA ||
+ signMech->mechanism == CKM_RSA_PKCS) {
+ return crv;
+ }
+
+ memset(sig, 0, sizeof(sig));
+ /* SignUpdate */
+ crv = pFunctionList->C_SignInit(hRwSession, signMech, hPrivKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08lX %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_SignUpdate(hRwSession, (CK_BYTE * ) pData, pDataLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08lX %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ sigLen = sizeof(sig);
+ crv = pFunctionList->C_SignFinal(hRwSession, sig, &sigLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* C_VerifyUpdate the signature */
+ crv = pFunctionList->C_VerifyInit(hRwSession, signMech,
+ hPubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hRwSession, (CK_BYTE * ) pData,
+ pDataLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyFinal(hRwSession, sig, sigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyFinal succeeded\n");
+ } else {
+ PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ return crv;
+
+}
+
+
+
+CK_RV PKM_PublicKey(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList,
+ CK_ULONG slotID, CK_UTF8CHAR_PTR pwd,
+ CK_ULONG pwdLen){
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+
+/*** DSA Key ***/
+ CK_MECHANISM dsaParamGenMech;
+ CK_ULONG primeBits = 1024;
+ CK_ATTRIBUTE dsaParamGenTemplate[1];
+ CK_OBJECT_HANDLE hDsaParams = CK_INVALID_HANDLE;
+ CK_BYTE DSA_P[128];
+ CK_BYTE DSA_Q[20];
+ CK_BYTE DSA_G[128];
+ CK_MECHANISM dsaKeyPairGenMech;
+ CK_ATTRIBUTE dsaPubKeyTemplate[5];
+ CK_ATTRIBUTE dsaPrivKeyTemplate[5];
+ CK_OBJECT_HANDLE hDSApubKey = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE hDSAprivKey = CK_INVALID_HANDLE;
+
+ /* From SHA1ShortMsg.req, Len = 136 */
+ CK_BYTE MSG[] = {
+ 0xba, 0x33, 0x95, 0xfb,
+ 0x5a, 0xfa, 0x8e, 0x6a,
+ 0x43, 0xdf, 0x41, 0x6b,
+ 0x32, 0x7b, 0x74, 0xfa,
+ 0x44
+ };
+ CK_BYTE MD[] = {
+ 0xf7, 0x5d, 0x92, 0xa4,
+ 0xbb, 0x4d, 0xec, 0xc3,
+ 0x7c, 0x5c, 0x72, 0xfa,
+ 0x04, 0x75, 0x71, 0x0a,
+ 0x06, 0x75, 0x8c, 0x1d
+ };
+
+ CK_BYTE sha1Digest[20];
+ CK_ULONG sha1DigestLen;
+ CK_BYTE dsaSig[40];
+ CK_ULONG dsaSigLen;
+ CK_MECHANISM sha1Mech = {
+ CKM_SHA_1, NULL, 0
+ };
+ CK_MECHANISM dsaMech = {
+ CKM_DSA, NULL, 0
+ };
+ CK_MECHANISM dsaWithSha1Mech = {
+ CKM_DSA_SHA1, NULL, 0
+ };
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* DSA key init */
+ dsaParamGenMech.mechanism = CKM_DSA_PARAMETER_GEN;
+ dsaParamGenMech.pParameter = NULL_PTR;
+ dsaParamGenMech.ulParameterLen = 0;
+ dsaParamGenTemplate[0].type = CKA_PRIME_BITS;
+ dsaParamGenTemplate[0].pValue = &primeBits;
+ dsaParamGenTemplate[0].ulValueLen = sizeof(primeBits);
+ dsaPubKeyTemplate[0].type = CKA_PRIME;
+ dsaPubKeyTemplate[0].pValue = DSA_P;
+ dsaPubKeyTemplate[0].ulValueLen = sizeof(DSA_P);
+ dsaPubKeyTemplate[1].type = CKA_SUBPRIME;
+ dsaPubKeyTemplate[1].pValue = DSA_Q;
+ dsaPubKeyTemplate[1].ulValueLen = sizeof(DSA_Q);
+ dsaPubKeyTemplate[2].type = CKA_BASE;
+ dsaPubKeyTemplate[2].pValue = DSA_G;
+ dsaPubKeyTemplate[2].ulValueLen = sizeof(DSA_G);
+ dsaPubKeyTemplate[3].type = CKA_TOKEN;
+ dsaPubKeyTemplate[3].pValue = &true;
+ dsaPubKeyTemplate[3].ulValueLen = sizeof(true);
+ dsaPubKeyTemplate[4].type = CKA_VERIFY;
+ dsaPubKeyTemplate[4].pValue = &true;
+ dsaPubKeyTemplate[4].ulValueLen = sizeof(true);
+ dsaKeyPairGenMech.mechanism = CKM_DSA_KEY_PAIR_GEN;
+ dsaKeyPairGenMech.pParameter = NULL_PTR;
+ dsaKeyPairGenMech.ulParameterLen = 0;
+ dsaPrivKeyTemplate[0].type = CKA_TOKEN;
+ dsaPrivKeyTemplate[0].pValue = &true;
+ dsaPrivKeyTemplate[0].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[1].type = CKA_PRIVATE;
+ dsaPrivKeyTemplate[1].pValue = &true;
+ dsaPrivKeyTemplate[1].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[2].type = CKA_SENSITIVE;
+ dsaPrivKeyTemplate[2].pValue = &true;
+ dsaPrivKeyTemplate[2].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[3].type = CKA_SIGN,
+ dsaPrivKeyTemplate[3].pValue = &true;
+ dsaPrivKeyTemplate[3].ulValueLen = sizeof(true);
+ dsaPrivKeyTemplate[4].type = CKA_EXTRACTABLE;
+ dsaPrivKeyTemplate[4].pValue = &true;
+ dsaPrivKeyTemplate[4].ulValueLen = sizeof(true);
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID],
+ CKF_RW_SESSION | CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate DSA PQG domain parameters ... \n");
+ /* Generate DSA domain parameters PQG */
+ crv = pFunctionList->C_GenerateKey(hSession, &dsaParamGenMech,
+ dsaParamGenTemplate,
+ 1,
+ &hDsaParams);
+ if (crv == CKR_OK) {
+ PKM_LogIt("DSA domain parameter generation succeeded\n");
+ } else {
+ PKM_Error( "DSA domain parameter generation failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_GetAttributeValue(hSession, hDsaParams,
+ dsaPubKeyTemplate, 3);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Getting DSA domain parameters succeeded\n");
+ } else {
+ PKM_Error( "Getting DSA domain parameters failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DestroyObject(hSession, hDsaParams);
+ if (crv == CKR_OK) {
+ PKM_LogIt("Destroying DSA domain parameters succeeded\n");
+ } else {
+ PKM_Error( "Destroying DSA domain parameters failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate a DSA key pair ... \n");
+ /* Generate a persistent DSA key pair */
+ crv = pFunctionList->C_GenerateKeyPair(hSession, &dsaKeyPairGenMech,
+ dsaPubKeyTemplate,
+ NUM_ELEM(dsaPubKeyTemplate),
+ dsaPrivKeyTemplate,
+ NUM_ELEM(dsaPrivKeyTemplate),
+ &hDSApubKey, &hDSAprivKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("DSA key pair generation succeeded\n");
+ } else {
+ PKM_Error( "DSA key pair generation failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Compute SHA-1 digest */
+ crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ sha1DigestLen = sizeof(sha1Digest);
+ crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
+ sha1Digest, &sha1DigestLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if (sha1DigestLen != sizeof(sha1Digest)) {
+ PKM_Error( "sha1DigestLen is %lu\n", sha1DigestLen);
+ return crv;
+ }
+
+ if (memcmp(sha1Digest, MD, sizeof(MD)) == 0) {
+ PKM_LogIt("SHA-1 SHA1ShortMsg test case Len = 136 passed\n");
+ } else {
+ PKM_Error( "SHA-1 SHA1ShortMsg test case Len = 136 failed\n");
+ }
+
+ crv = PKM_PubKeySign(pFunctionList, hSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaMech, sha1Digest, sizeof(sha1Digest));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_PubKeySign CKM_DSA succeeded \n");
+ } else {
+ PKM_Error( "PKM_PubKeySign failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = PKM_PubKeySign(pFunctionList, hSession,
+ hDSApubKey, hDSAprivKey,
+ &dsaWithSha1Mech, PLAINTEXT, sizeof(PLAINTEXT));
+ if (crv == CKR_OK) {
+ PKM_LogIt("PKM_PubKeySign CKM_DSA_SHA1 succeeded \n");
+ } else {
+ PKM_Error( "PKM_PubKeySign failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Sign with DSA */
+ crv = pFunctionList->C_SignInit(hSession, &dsaMech, hDSAprivKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ dsaSigLen = sizeof(dsaSig);
+ crv = pFunctionList->C_Sign(hSession, sha1Digest, sha1DigestLen,
+ dsaSig, &dsaSigLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Verify the DSA signature */
+ crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
+ dsaSig, dsaSigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Verify succeeded\n");
+ } else {
+ PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Verify the signature in a different way */
+ crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
+ hDSApubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyFinal succeeded\n");
+ } else {
+ PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Verify the signature in a different way */
+ crv = pFunctionList->C_VerifyInit(hSession, &dsaWithSha1Mech,
+ hDSApubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hSession, MSG, 1);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hSession, MSG+1, sizeof(MSG)-1);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyFinal(hSession, dsaSig, dsaSigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyFinal of multi update succeeded.\n");
+ } else {
+ PKM_Error("C_VerifyFinal of multi update failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ /* Now modify the data */
+ MSG[0] += 1;
+ /* Compute SHA-1 digest */
+ crv = pFunctionList->C_DigestInit(hSession, &sha1Mech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ sha1DigestLen = sizeof(sha1Digest);
+ crv = pFunctionList->C_Digest(hSession, MSG, sizeof(MSG),
+ sha1Digest, &sha1DigestLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Digest failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyInit(hSession, &dsaMech, hDSApubKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Verify(hSession, sha1Digest, sha1DigestLen,
+ dsaSig, dsaSigLen);
+ if (crv != CKR_SIGNATURE_INVALID) {
+ PKM_Error( "C_Verify of modified data succeeded\n");
+ return crv;
+ } else {
+ PKM_LogIt("C_Verify of modified data returned as EXPECTED "
+ " with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ }
+
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+
+}
+
+CK_RV PKM_Hmac(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE sKey, CK_MECHANISM *hmacMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen) {
+
+ CK_RV crv = CKR_OK;
+
+ CK_BYTE hmac1[HMAC_MAX_LENGTH];
+ CK_ULONG hmac1Len = 0;
+ CK_BYTE hmac2[HMAC_MAX_LENGTH];
+ CK_ULONG hmac2Len = 0;
+
+ memset(hmac1, 0, sizeof(hmac1));
+ memset(hmac2, 0, sizeof(hmac2));
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignInit succeeded\n");
+ } else {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ hmac1Len = sizeof(hmac1);
+ crv = pFunctionList->C_Sign(hSession, (CK_BYTE * )pData,
+ pDataLen,
+ (CK_BYTE * )hmac1, &hmac1Len);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Sign succeeded\n");
+ } else {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_SignInit(hSession, hmacMech, sKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignInit succeeded\n");
+ } else {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_SignUpdate(hSession, (CK_BYTE * )pData,
+ pDataLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignUpdate succeeded\n");
+ } else {
+ PKM_Error( "C_SignUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ hmac2Len = sizeof(hmac2);
+ crv = pFunctionList->C_SignFinal(hSession, (CK_BYTE * )hmac2, &hmac2Len);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignFinal succeeded\n");
+ } else {
+ PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ((hmac1Len == hmac2Len) && (memcmp(hmac1, hmac2, hmac1Len) == 0) ) {
+ PKM_LogIt("hmacs are equal!\n");
+ } else {
+ PKM_Error("hmacs are not equal!\n");
+ }
+ crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Verify(hSession, (CK_BYTE * )pData,
+ pDataLen,
+ (CK_BYTE * ) hmac2, hmac2Len);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Verify of hmac succeeded\n");
+ } else {
+ PKM_Error( "C_Verify failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyInit(hSession, hmacMech, sKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyUpdate(hSession, (CK_BYTE * )pData,
+ pDataLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyUpdate of hmac succeeded\n");
+ } else {
+ PKM_Error( "C_VerifyUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyFinal(hSession, (CK_BYTE * ) hmac1,
+ hmac1Len);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyFinal of hmac succeeded\n");
+ } else {
+ PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ return crv;
+}
+
+CK_RV PKM_FindAllObjects(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_RV crv = CKR_OK;
+
+ CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
+ CK_SESSION_INFO sinfo;
+ CK_ATTRIBUTE_PTR pTemplate;
+ CK_ULONG tnObjects = 0;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &h);
+ if ( CKR_OK != crv ) {
+ PKM_Error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
+ "returned 0x%08X, %-26s\n", pSlotList[slotID], crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Opened a session: handle = 0x%08x\n", h);
+
+ (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
+ crv = pFunctionList->C_GetSessionInfo(h, &sinfo);
+ if ( CKR_OK != crv ) {
+ PKM_LogIt( "C_GetSessionInfo(%lu, ) returned 0x%08X, %-26s\n", h, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " SESSION INFO:\n");
+ PKM_LogIt( " slotID = %lu\n", sinfo.slotID);
+ PKM_LogIt( " state = %lu\n", sinfo.state);
+ PKM_LogIt( " flags = 0x%08x\n", sinfo.flags);
+#ifdef CKF_EXCLUSIVE_SESSION
+ PKM_LogIt( " -> EXCLUSIVE SESSION = %s\n", sinfo.flags &
+ CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
+#endif /* CKF_EXCLUSIVE_SESSION */
+ PKM_LogIt( " -> RW SESSION = %s\n", sinfo.flags &
+ CKF_RW_SESSION ? "TRUE" : "FALSE");
+ PKM_LogIt( " -> SERIAL SESSION = %s\n", sinfo.flags &
+ CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
+#ifdef CKF_INSERTION_CALLBACK
+ PKM_LogIt( " -> INSERTION CALLBACK = %s\n", sinfo.flags &
+ CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
+#endif /* CKF_INSERTION_CALLBACK */
+ PKM_LogIt( " ulDeviceError = %lu\n", sinfo.ulDeviceError);
+ PKM_LogIt( "\n");
+
+ crv = pFunctionList->C_FindObjectsInit(h, NULL, 0);
+ if ( CKR_OK != crv ) {
+ PKM_LogIt( "C_FindObjectsInit(%lu, NULL, 0) returned "
+ "0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ pTemplate = (CK_ATTRIBUTE_PTR)calloc(number_of_all_known_attribute_types,
+ sizeof(CK_ATTRIBUTE));
+ if ( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
+ PKM_Error( "[memory allocation of %lu bytes failed]\n",
+ number_of_all_known_attribute_types *
+ sizeof(CK_ATTRIBUTE));
+ return crv;
+ }
+
+ PKM_LogIt( " All objects:\n");
+
+ while (1) {
+ CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
+ CK_ULONG nObjects = 0;
+ CK_ULONG k;
+ CK_ULONG nAttributes = 0;
+ CK_ATTRIBUTE_PTR pT2;
+ CK_ULONG l;
+
+ crv = pFunctionList->C_FindObjects(h, &o, 1, &nObjects);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjects(%lu, , 1, ) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ( 0 == nObjects ) {
+ PKM_LogIt( "\n");
+ break;
+ }
+
+ tnObjects++;
+
+ PKM_LogIt( " OBJECT HANDLE %lu:\n", o);
+
+ for ( k = 0; k < (CK_ULONG)number_of_all_known_attribute_types; k++ ) {
+ pTemplate[k].type = all_known_attribute_types[k];
+ pTemplate[k].pValue = (CK_VOID_PTR) NULL;
+ pTemplate[k].ulValueLen = 0;
+ }
+
+ crv = pFunctionList->C_GetAttributeValue(h, o, pTemplate,
+ number_of_all_known_attribute_types);
+ switch ( crv ) {
+ case CKR_OK:
+ case CKR_ATTRIBUTE_SENSITIVE:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_BUFFER_TOO_SMALL:
+ break;
+ default:
+ PKM_Error( "C_GetAtributeValue(%lu, %lu, {all attribute types},"
+ "%lu) returned 0x%08X, %-26s\n",
+ h, o, number_of_all_known_attribute_types, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types; k++) {
+ if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
+ nAttributes++;
+ }
+ }
+
+ if ( 1 ) {
+ PKM_LogIt( " %lu attributes:\n", nAttributes);
+ for ( k = 0; k < (CK_ULONG) number_of_all_known_attribute_types;
+ k++ ) {
+ if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
+ PKM_LogIt( " 0x%08x (len = %lu)\n",
+ pTemplate[k].type,
+ pTemplate[k].ulValueLen);
+ }
+ }
+ PKM_LogIt( "\n");
+ }
+
+ pT2 = (CK_ATTRIBUTE_PTR)calloc(nAttributes, sizeof(CK_ATTRIBUTE));
+ if ( (CK_ATTRIBUTE_PTR)NULL == pT2 ) {
+ PKM_Error( "[memory allocation of %lu bytes failed]\n",
+ nAttributes * sizeof(CK_ATTRIBUTE));
+ return crv;
+ }
+
+ for ( l = 0, k = 0; k < (CK_ULONG) number_of_all_known_attribute_types;
+ k++ ) {
+ if ( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
+ pT2[l].type = pTemplate[k].type;
+ pT2[l].ulValueLen = pTemplate[k].ulValueLen;
+ pT2[l].pValue = (CK_VOID_PTR)malloc(pT2[l].ulValueLen);
+ if ( (CK_VOID_PTR)NULL == pT2[l].pValue ) {
+ PKM_Error( "[memory allocation of %lu bytes failed]\n",
+ pT2[l].ulValueLen);
+ return crv;
+ }
+ l++;
+ }
+ }
+
+ assert( l == nAttributes );
+
+ crv = pFunctionList->C_GetAttributeValue(h, o, pT2, nAttributes);
+ switch ( crv ) {
+ case CKR_OK:
+ case CKR_ATTRIBUTE_SENSITIVE:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_BUFFER_TOO_SMALL:
+ break;
+ default:
+ PKM_Error( "C_GetAtributeValue(%lu, %lu, {existant attribute"
+ " types}, %lu) returned 0x%08X, %-26s\n",
+ h, o, nAttributes, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ for ( l = 0; l < nAttributes; l++ ) {
+ PKM_LogIt( " type = 0x%08x, len = %ld", pT2[l].type,
+ (CK_LONG)pT2[l].ulValueLen);
+ if ( -1 == (CK_LONG)pT2[l].ulValueLen ) {
+ ;
+ } else {
+ CK_ULONG m;
+
+ if ( pT2[l].ulValueLen <= 8 ) {
+ PKM_LogIt( ", value = ");
+ } else {
+ PKM_LogIt( ", value = \n ");
+ }
+
+ for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
+ PKM_LogIt( "%02x", (CK_ULONG)(0xff &
+ ((CK_CHAR_PTR)pT2[l].pValue)[m]));
+ }
+
+ PKM_LogIt( " ");
+
+ for ( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
+ CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
+ if ( (c < 0x20) || (c >= 0x7f) ) {
+ c = '.';
+ }
+ PKM_LogIt( "%c", c);
+ }
+ }
+
+ PKM_LogIt( "\n");
+ }
+
+ PKM_LogIt( "\n");
+
+ for ( l = 0; l < nAttributes; l++ ) {
+ free(pT2[l].pValue);
+ }
+ free(pT2);
+ } /* while(1) */
+
+ crv = pFunctionList->C_FindObjectsFinal(h);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " (%lu objects total)\n", tnObjects);
+
+ crv = pFunctionList->C_CloseSession(h);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CloseSession(%lu) returned 0x%08X, %-26s\n", h, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+}
+/* session to create, find, and delete a couple session objects */
+CK_RV PKM_MultiObjectManagement (CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+
+ CK_RV crv = CKR_OK;
+
+ CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
+ CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;
+ CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
+ CK_OBJECT_CLASS cko_data = CKO_DATA;
+ char *key = "TEST PROGRAM";
+ CK_ULONG key_len = 0;
+ CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0;
+ CK_OBJECT_HANDLE hTwoIn = (CK_OBJECT_HANDLE)0;
+ CK_OBJECT_HANDLE hThreeIn = (CK_OBJECT_HANDLE)0;
+ CK_OBJECT_HANDLE hDeltaIn = (CK_OBJECT_HANDLE)0;
+ CK_OBJECT_HANDLE found[10];
+ CK_ULONG nFound;
+ CK_ULONG hDeltaLen, hThreeLen = 0;
+
+ CK_TOKEN_INFO tinfo;
+
+ NUMTESTS++; /* increment NUMTESTS */
+ key_len = sizeof(key);
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID],
+ CKF_SERIAL_SESSION, NULL, NULL, &h);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
+ "returned 0x%08X, %-26s\n", pSlotList[slotID], crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Login(h, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
+ crv = pFunctionList->C_GetTokenInfo(pSlotList[slotID], &tinfo);
+ if ( CKR_OK != crv ) {
+ PKM_Error("C_GetTokenInfo(%lu, ) returned 0x%08X, %-26s\n",
+ pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ PKM_LogIt( " Opened a session: handle = 0x%08x\n", h);
+
+ one[0].type = CKA_CLASS;
+ one[0].pValue = &cko_data;
+ one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
+ one[1].type = CKA_TOKEN;
+ one[1].pValue = &false;
+ one[1].ulValueLen = sizeof(CK_BBOOL);
+ one[2].type = CKA_PRIVATE;
+ one[2].pValue = &false;
+ one[2].ulValueLen = sizeof(CK_BBOOL);
+ one[3].type = CKA_MODIFIABLE;
+ one[3].pValue = &true;
+ one[3].ulValueLen = sizeof(CK_BBOOL);
+ one[4].type = CKA_LABEL;
+ one[4].pValue = "Test data object one";
+ one[4].ulValueLen = strlen(one[4].pValue);
+ one[5].type = CKA_APPLICATION;
+ one[5].pValue = key;
+ one[5].ulValueLen = key_len;
+ one[6].type = CKA_VALUE;
+ one[6].pValue = "Object one";
+ one[6].ulValueLen = strlen(one[6].pValue);
+
+ two[0].type = CKA_CLASS;
+ two[0].pValue = &cko_data;
+ two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
+ two[1].type = CKA_TOKEN;
+ two[1].pValue = &false;
+ two[1].ulValueLen = sizeof(CK_BBOOL);
+ two[2].type = CKA_PRIVATE;
+ two[2].pValue = &false;
+ two[2].ulValueLen = sizeof(CK_BBOOL);
+ two[3].type = CKA_MODIFIABLE;
+ two[3].pValue = &true;
+ two[3].ulValueLen = sizeof(CK_BBOOL);
+ two[4].type = CKA_LABEL;
+ two[4].pValue = "Test data object two";
+ two[4].ulValueLen = strlen(two[4].pValue);
+ two[5].type = CKA_APPLICATION;
+ two[5].pValue = key;
+ two[5].ulValueLen = key_len;
+ two[6].type = CKA_VALUE;
+ two[6].pValue = "Object two";
+ two[6].ulValueLen = strlen(two[6].pValue);
+
+ three[0].type = CKA_CLASS;
+ three[0].pValue = &cko_data;
+ three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
+ three[1].type = CKA_TOKEN;
+ three[1].pValue = &false;
+ three[1].ulValueLen = sizeof(CK_BBOOL);
+ three[2].type = CKA_PRIVATE;
+ three[2].pValue = &false;
+ three[2].ulValueLen = sizeof(CK_BBOOL);
+ three[3].type = CKA_MODIFIABLE;
+ three[3].pValue = &true;
+ three[3].ulValueLen = sizeof(CK_BBOOL);
+ three[4].type = CKA_LABEL;
+ three[4].pValue = "Test data object three";
+ three[4].ulValueLen = strlen(three[4].pValue);
+ three[5].type = CKA_APPLICATION;
+ three[5].pValue = key;
+ three[5].ulValueLen = key_len;
+ three[6].type = CKA_VALUE;
+ three[6].pValue = "Object three";
+ three[6].ulValueLen = strlen(three[6].pValue);
+
+ crv = pFunctionList->C_CreateObject(h, one, 7, &hOneIn);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CreateObject(%lu, one, 7, ) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Created object one: handle = %lu\n", hOneIn);
+
+ crv = pFunctionList->C_CreateObject(h, two, 7, &hTwoIn);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CreateObject(%lu, two, 7, ) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Created object two: handle = %lu\n", hTwoIn);
+
+ crv = pFunctionList->C_CreateObject(h, three, 7, &hThreeIn);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_GetObjectSize(h, hThreeIn, &hThreeLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetObjectSize succeeded\n");
+ } else {
+ PKM_Error("C_GetObjectSize failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Created object three: handle = %lu\n", hThreeIn);
+
+ delta[0].type = CKA_VALUE;
+ delta[0].pValue = "Copied object";
+ delta[0].ulValueLen = strlen(delta[0].pValue);
+
+ crv = pFunctionList->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CopyObject(%lu, %lu, delta, 1, ) returned "
+ "0x%08X, %-26s\n",
+ h, hThreeIn, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_GetObjectSize(h, hDeltaIn, &hDeltaLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GetObjectSize succeeded\n");
+ } else {
+ PKM_Error("C_GetObjectSize failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (hThreeLen == hDeltaLen) {
+ PKM_LogIt("Copied object size same as orginal\n");
+ } else {
+ PKM_Error("Copied object different from original\n");
+ return CKR_DEVICE_ERROR;
+ }
+
+ PKM_LogIt( " Copied object three: new handle = %lu\n", hDeltaIn);
+
+ mask[0].type = CKA_APPLICATION;
+ mask[0].pValue = key;
+ mask[0].ulValueLen = key_len;
+
+ crv = pFunctionList->C_FindObjectsInit(h, mask, 1);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ (void)memset(&found, 0, sizeof(found));
+ nFound = 0;
+ crv = pFunctionList->C_FindObjects(h, found, 10, &nFound);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ( 4 != nFound ) {
+ PKM_Error( "Found %lu objects, not 4.\n", nFound);
+ return crv;
+ }
+
+ PKM_LogIt( " Found 4 objects: %lu, %lu, %lu, %lu\n",
+ found[0], found[1], found[2], found[3]);
+
+ crv = pFunctionList->C_FindObjectsFinal(h);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n",
+ h, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_DestroyObject(h, hThreeIn);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_DestroyObject(%lu, %lu) returned 0x%08X, %-26s\n", h,
+ hThreeIn, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Destroyed object three (handle = %lu)\n", hThreeIn);
+
+ delta[0].type = CKA_APPLICATION;
+ delta[0].pValue = "Changed application";
+ delta[0].ulValueLen = strlen(delta[0].pValue);
+
+ crv = pFunctionList->C_SetAttributeValue(h, hTwoIn, delta, 1);
+ if ( CKR_OK != crv ) {
+ PKM_Error("C_SetAttributeValue(%lu, %lu, delta, 1) returned "
+ "0x%08X, %-26s\n",
+ h, hTwoIn, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( " Changed object two (handle = %lu).\n", hTwoIn);
+
+ /* Can another session find these session objects? */
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &h2);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_OpenSession(%lu, CKF_SERIAL_SESSION, , )"
+ " returned 0x%08X, %-26s\n", pSlotList[slotID], crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ PKM_LogIt( " Opened a second session: handle = 0x%08x\n", h2);
+
+ /* mask is still the same */
+
+ crv = pFunctionList->C_FindObjectsInit(h2, mask, 1);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjectsInit(%lu, mask, 1) returned 0x%08X, %-26s\n",
+ h2, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ (void)memset(&found, 0, sizeof(found));
+ nFound = 0;
+ crv = pFunctionList->C_FindObjects(h2, found, 10, &nFound);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjects(%lu,, 10, ) returned 0x%08X, %-26s\n",
+ h2, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ( 2 != nFound ) {
+ PKM_Error( "Found %lu objects, not 2.\n", nFound);
+ return crv;
+ }
+
+ PKM_LogIt( " Found 2 objects: %lu, %lu\n",
+ found[0], found[1]);
+
+ crv = pFunctionList->C_FindObjectsFinal(h2);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_FindObjectsFinal(%lu) returned 0x%08X, %-26s\n", h2, crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Logout(h);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseAllSessions(pSlotList[slotID]);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CloseAllSessions(%lu) returned 0x%08X, %-26s\n",
+ pSlotList[slotID], crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt( "\n");
+ return crv;
+}
+
+CK_RV PKM_OperationalState(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv = CKR_OK;
+ CK_MECHANISM sAESKeyMech = {
+ CKM_AES_KEY_GEN, NULL, 0
+ };
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE keyAESType = CKK_AES;
+ CK_UTF8CHAR AESlabel[] = "An AES secret key object";
+ CK_ULONG AESvalueLen = 16;
+ CK_ATTRIBUTE sAESKeyTemplate[9];
+ CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE;
+ CK_BYTE_PTR pstate = NULL;
+ CK_ULONG statelen, digestlen, plainlen, plainlen_1, plainlen_2, slen;
+
+ static const CK_UTF8CHAR *plaintext = (CK_UTF8CHAR *)"Firefox rules.";
+ static const CK_UTF8CHAR *plaintext_1 = (CK_UTF8CHAR *)"Thunderbird rules.";
+ static const CK_UTF8CHAR *plaintext_2 = (CK_UTF8CHAR *)
+ "Firefox and Thunderbird.";
+
+ char digest[MAX_DIGEST_SZ], digest_1[MAX_DIGEST_SZ];
+ char sign[MAX_SIG_SZ];
+ CK_MECHANISM signmech;
+ CK_MECHANISM digestmech;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+
+ /* AES key template */
+ sAESKeyTemplate[0].type = CKA_CLASS;
+ sAESKeyTemplate[0].pValue = &class;
+ sAESKeyTemplate[0].ulValueLen = sizeof(class);
+ sAESKeyTemplate[1].type = CKA_KEY_TYPE;
+ sAESKeyTemplate[1].pValue = &keyAESType;
+ sAESKeyTemplate[1].ulValueLen = sizeof(keyAESType);
+ sAESKeyTemplate[2].type = CKA_LABEL;
+ sAESKeyTemplate[2].pValue = AESlabel;
+ sAESKeyTemplate[2].ulValueLen = sizeof(AESlabel)-1;
+ sAESKeyTemplate[3].type = CKA_ENCRYPT;
+ sAESKeyTemplate[3].pValue = &true;
+ sAESKeyTemplate[3].ulValueLen = sizeof(true);
+ sAESKeyTemplate[4].type = CKA_DECRYPT;
+ sAESKeyTemplate[4].pValue = &true;
+ sAESKeyTemplate[4].ulValueLen = sizeof(true);
+ sAESKeyTemplate[5].type = CKA_SIGN;
+ sAESKeyTemplate[5].pValue = &true;
+ sAESKeyTemplate[5].ulValueLen = sizeof (true);
+ sAESKeyTemplate[6].type = CKA_VERIFY;
+ sAESKeyTemplate[6].pValue = &true;
+ sAESKeyTemplate[6].ulValueLen = sizeof(true);
+ sAESKeyTemplate[7].type = CKA_UNWRAP;
+ sAESKeyTemplate[7].pValue = &true;
+ sAESKeyTemplate[7].ulValueLen = sizeof(true);
+ sAESKeyTemplate[8].type = CKA_VALUE_LEN;
+ sAESKeyTemplate[8].pValue = &AESvalueLen;
+ sAESKeyTemplate[8].ulValueLen = sizeof(AESvalueLen);
+
+ signmech.mechanism = CKM_SHA_1_HMAC;
+ signmech.pParameter = NULL;
+ signmech.ulParameterLen = 0;
+ digestmech.mechanism = CKM_SHA256;
+ digestmech.pParameter = NULL;
+ digestmech.ulParameterLen = 0;
+
+
+ plainlen = strlen((char *)plaintext);
+ plainlen_1 = strlen((char *)plaintext_1);
+ plainlen_2 = strlen((char *)plaintext_2);
+ digestlen = MAX_DIGEST_SZ;
+
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ PKM_LogIt("Generate an AES key ...\n");
+ /* generate an AES Secret Key */
+ crv = pFunctionList->C_GenerateKey(hSession, &sAESKeyMech,
+ sAESKeyTemplate,
+ NUM_ELEM(sAESKeyTemplate),
+ &sKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey AES succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey AES failed with 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_SignInit(hSession, &signmech, sKey);
+ if (crv != CKR_OK) {
+ PKM_Error("C_SignInit failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ slen = sizeof(sign);
+ crv = pFunctionList->C_Sign(hSession, (CK_BYTE_PTR)plaintext, plainlen,
+ (CK_BYTE_PTR)sign, &slen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_Sign failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_DestroyObject(hSession, sKey);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DestroyObject failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ digestlen = MAX_DIGEST_SZ;
+ crv = pFunctionList->C_DigestInit(hSession, &digestmech);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext,
+ plainlen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_GetOperationState(hSession, NULL, &statelen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ pstate = (CK_BYTE_PTR) malloc(statelen * sizeof (CK_BYTE_PTR));
+ crv = pFunctionList->C_GetOperationState(hSession, pstate, &statelen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_GetOperationState failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_1,
+ plainlen_1);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE_PTR)plaintext_2,
+ plainlen_2);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestUpdate failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /*
+ * This will override/negate the above 2 digest_update
+ * operations
+ */
+ crv = pFunctionList->C_SetOperationState(hSession, pstate, statelen,
+ 0, 0);
+ if (crv != CKR_OK) {
+ PKM_Error("C_SetOperationState failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_DigestFinal(hSession, (CK_BYTE_PTR)digest,
+ &digestlen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestFinal failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ digestlen = MAX_DIGEST_SZ;
+ crv = pFunctionList->C_DigestInit(hSession, &digestmech);
+ if (crv != CKR_OK) {
+ PKM_Error("C_DigestInit failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Digest(hSession, (CK_BYTE_PTR)plaintext, plainlen,
+ (CK_BYTE_PTR)digest_1, &digestlen);
+ if (crv != CKR_OK) {
+ PKM_Error("C_Digest failed returned 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ if (memcmp(digest, digest_1, digestlen) == 0) {
+ PKM_LogIt("Digest and digest_1 are equal!\n");
+ } else {
+ PKM_Error("Digest and digest_1 are not equal!\n");
+ }
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if ( CKR_OK != crv ) {
+ PKM_Error( "C_CloseSession(%lu) returned 0x%08X, %-26s\n",
+ hSession, crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+}
+
+
+/*
+* Recover Functions
+*/
+CK_RV PKM_RecoverFunctions(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hPubKey, CK_OBJECT_HANDLE hPrivKey,
+ CK_MECHANISM *signMech, const CK_BYTE * pData,
+ CK_ULONG pDataLen) {
+ CK_RV crv = CKR_OK;
+ CK_BYTE sig[MAX_SIG_SZ];
+ CK_ULONG sigLen = MAX_SIG_SZ;
+ CK_BYTE recover[MAX_SIG_SZ];
+ CK_ULONG recoverLen = MAX_SIG_SZ;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* initializes a signature operation,
+ * where the data can be recovered from the signature
+ */
+ crv = pFunctionList->C_SignRecoverInit(hSession, signMech,
+ hPrivKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignRecoverInit succeeded. \n");
+ } else {
+ PKM_Error("C_SignRecoverInit failed.\n"
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* signs single-part data,
+ * where the data can be recovered from the signature
+ */
+ crv = pFunctionList->C_SignRecover(hSession, (CK_BYTE * )pData,
+ pDataLen,
+ (CK_BYTE * )sig, &sigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_SignRecover succeeded. \n");
+ } else {
+ PKM_Error("C_SignRecoverInit failed to create an RSA key pair.\n"
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /*
+ * initializes a verification operation
+ *where the data is recovered from the signature
+ */
+ crv = pFunctionList->C_VerifyRecoverInit(hSession, signMech,
+ hPubKey);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyRecoverInit succeeded. \n");
+ } else {
+ PKM_Error("C_VerifyRecoverInit failed.\n"
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /*
+ * verifies a signature on single-part data,
+ * where the data is recovered from the signature
+ */
+ crv = pFunctionList->C_VerifyRecover(hSession, (CK_BYTE * )sig,
+ sigLen,
+ (CK_BYTE * )recover, &recoverLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyRecover succeeded. \n");
+ } else {
+ PKM_Error("C_VerifyRecover failed.\n"
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if ((recoverLen == pDataLen)
+ && (memcmp(recover, pData, pDataLen) == 0)) {
+ PKM_LogIt("VerifyRecover test case passed\n");
+ } else {
+ PKM_Error( "VerifyRecover test case failed\n");
+ }
+
+ return crv;
+}
+/*
+* wrapUnwrap
+* wrap the secretkey with the public key.
+* unwrap the secretkey with the private key.
+*/
+CK_RV PKM_wrapUnwrap(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hPublicKey,
+ CK_OBJECT_HANDLE hPrivateKey,
+ CK_MECHANISM *wrapMechanism,
+ CK_OBJECT_HANDLE hSecretKey,
+ CK_ATTRIBUTE *sKeyTemplate,
+ CK_ULONG skeyTempSize) {
+ CK_RV crv = CKR_OK;
+ CK_OBJECT_HANDLE hSecretKeyUnwrapped = CK_INVALID_HANDLE;
+ CK_BYTE wrappedKey[128];
+ CK_ULONG ulWrappedKeyLen = 0;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ ulWrappedKeyLen = sizeof(wrappedKey);
+ crv = pFunctionList->C_WrapKey(
+ hSession, wrapMechanism,
+ hPublicKey, hSecretKey,
+ wrappedKey, &ulWrappedKeyLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_WrapKey succeeded\n");
+ } else {
+ PKM_Error( "C_WrapKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_UnwrapKey(
+ hSession, wrapMechanism, hPrivateKey,
+ wrappedKey, ulWrappedKeyLen, sKeyTemplate,
+ skeyTempSize,
+ &hSecretKeyUnwrapped);
+ if ((crv == CKR_OK) && (hSecretKeyUnwrapped != CK_INVALID_HANDLE)) {
+ PKM_LogIt("C_UnwrapKey succeeded\n");
+ } else {
+ PKM_Error( "C_UnwrapKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ return crv;
+}
+
+/*
+ * Tests if the object's attributes match the expected_attrs
+ */
+CK_RV
+PKM_AttributeCheck(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE obj,
+ CK_ATTRIBUTE_PTR expected_attrs,
+ CK_ULONG expected_attrs_count)
+{
+ CK_RV crv;
+ CK_ATTRIBUTE_PTR tmp_attrs;
+ unsigned int i;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* First duplicate the themplate */
+ tmp_attrs = malloc(expected_attrs_count * sizeof (CK_ATTRIBUTE));
+
+ if (tmp_attrs == NULL) {
+ PKM_Error("Internal test memory failure\n");
+ return (CKR_HOST_MEMORY);
+ }
+
+ for (i = 0; i < expected_attrs_count; i++) {
+ tmp_attrs[i].type = expected_attrs[i].type;
+ tmp_attrs[i].ulValueLen = expected_attrs[i].ulValueLen;
+
+ /* Don't give away the expected one. just zeros */
+ tmp_attrs[i].pValue = calloc(expected_attrs[i].ulValueLen, 1);
+
+ if (tmp_attrs[i].pValue == NULL) {
+ unsigned int j;
+ for (j = 0; j < i; j++)
+ free(tmp_attrs[j].pValue);
+
+ free(tmp_attrs);
+ printf("Internal test memory failure\n");
+ return (CKR_HOST_MEMORY);
+ }
+ }
+
+ /* then get the attributes from the object */
+ crv = pFunctionList->C_GetAttributeValue(hSession, obj, tmp_attrs,
+ expected_attrs_count);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetAttributeValue failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ crv = CKR_FUNCTION_FAILED;
+ goto out;
+ }
+
+ /* Finally compare with the expected ones */
+ for (i = 0; i < expected_attrs_count; i++) {
+
+ if (memcmp(tmp_attrs[i].pValue, expected_attrs[i].pValue,
+ expected_attrs[i].ulValueLen) != 0) {
+ PKM_LogIt("comparing attribute type 0x%x with expected 0x%x\n",
+ tmp_attrs[i].type, expected_attrs[i].type);
+ PKM_LogIt("comparing attribute type value 0x%x with expected 0x%x\n",
+ tmp_attrs[i].pValue, expected_attrs[i].pValue);
+ /* don't report error at this time */
+ }
+ }
+
+ out:
+ for (i = 0; i < expected_attrs_count; i++)
+ free(tmp_attrs[i].pValue);
+ free(tmp_attrs);
+ return (crv);
+}
+
+/*
+ * Check the validity of a mech
+ */
+CK_RV
+PKM_MechCheck(CK_FUNCTION_LIST_PTR pFunctionList, CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_TYPE mechType, CK_FLAGS flags,
+ CK_BBOOL check_sizes, CK_ULONG minkeysize, CK_ULONG maxkeysize)
+{
+ CK_SESSION_INFO sess_info;
+ CK_MECHANISM_INFO mech_info;
+ CK_RV crv;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ if ((crv = pFunctionList->C_GetSessionInfo(hSession, &sess_info))
+ != CKR_OK) {
+ PKM_Error( "C_GetSessionInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return (CKR_FUNCTION_FAILED);
+ }
+
+ crv = pFunctionList->C_GetMechanismInfo(0, mechType,
+ &mech_info);
+
+
+ crv = pFunctionList->C_GetMechanismInfo(sess_info.slotID, mechType,
+ &mech_info);
+
+ if (crv != CKR_OK) {
+ PKM_Error( "C_GetMechanismInfo failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return (CKR_FUNCTION_FAILED);
+ }
+
+ if ((mech_info.flags & flags) == 0) {
+ PKM_Error("0x%x flag missing from mech\n", flags);
+ return (CKR_MECHANISM_INVALID);
+ }
+ if (!check_sizes)
+ return (CKR_OK);
+
+ if (mech_info.ulMinKeySize != minkeysize) {
+ PKM_Error("Bad MinKeySize %d expected %d\n", mech_info.ulMinKeySize,
+ minkeysize);
+ return (CKR_MECHANISM_INVALID);
+ }
+ if (mech_info.ulMaxKeySize != maxkeysize) {
+ PKM_Error("Bad MaxKeySize %d expected %d\n", mech_info.ulMaxKeySize,
+ maxkeysize);
+ return (CKR_MECHANISM_INVALID);
+ }
+ return (CKR_OK);
+}
+
+
+
+
+
+/*
+ * Can be called with a non-null premaster_key_len for the
+ * *_DH mechanisms. In that case, no checking for the matching of
+ * the expected results is done.
+ * The rnd argument tells which correct/bogus randomInfo to use.
+ */
+CK_RV
+PKM_TLSMasterKeyDerive( CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_MECHANISM_TYPE mechType,
+ enum_random_t rnd) {
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv;
+ CK_MECHANISM mk_mech;
+ CK_VERSION expected_version, version;
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE type = CKK_GENERIC_SECRET;
+ CK_BBOOL derive_bool = true;
+ CK_ATTRIBUTE attrs[4];
+ CK_ULONG attrs_count = 4;
+ CK_OBJECT_HANDLE pmk_obj = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE;
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS mkd_params;
+ CK_MECHANISM skmd_mech;
+
+ CK_BBOOL isDH = false;
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ attrs[0].type = CKA_CLASS;
+ attrs[0].pValue = &class;
+ attrs[0].ulValueLen = sizeof (class);
+ attrs[1].type = CKA_KEY_TYPE;
+ attrs[1].pValue = &type;
+ attrs[1].ulValueLen = sizeof (type);
+ attrs[2].type = CKA_DERIVE;
+ attrs[2].pValue = &derive_bool;
+ attrs[2].ulValueLen = sizeof (derive_bool);
+ attrs[3].type = CKA_VALUE;
+ attrs[3].pValue = NULL;
+ attrs[3].ulValueLen = 0;
+
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Before all, check if the mechanism is supported correctly */
+ if (MODE == FIPSMODE) {
+ crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE, false,
+ 0, 0);
+ if (crv != CKR_OK) {
+ PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return (crv);
+ }
+ }
+
+ mk_mech.mechanism = mechType;
+ mk_mech.pParameter = &mkd_params;
+ mk_mech.ulParameterLen = sizeof (mkd_params);
+
+ switch (mechType) {
+ case CKM_TLS_MASTER_KEY_DERIVE_DH:
+ isDH = true;
+ /* FALLTHRU */
+ case CKM_TLS_MASTER_KEY_DERIVE:
+ attrs[3].pValue = NULL;
+ attrs[3].ulValueLen = 0;
+ expected_version.major = 3;
+ expected_version.minor = 1;
+
+ mkd_params.RandomInfo.pClientRandom = (unsigned char * ) TLSClientRandom;
+ mkd_params.RandomInfo.ulClientRandomLen =
+ sizeof (TLSClientRandom);
+ mkd_params.RandomInfo.pServerRandom = (unsigned char * ) TLSServerRandom;
+ mkd_params.RandomInfo.ulServerRandomLen =
+ sizeof (TLSServerRandom);
+ break;
+ }
+ mkd_params.pVersion = (!isDH) ? &version : NULL;
+
+ /* First create the pre-master secret key */
+
+ skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
+ skmd_mech.pParameter = &mkd_params;
+ skmd_mech.ulParameterLen = sizeof (mkd_params);
+
+
+ crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
+ attrs,
+ attrs_count,
+ &pmk_obj);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+
+ }
+ /* Test the bad cases */
+ switch (rnd) {
+ case CORRECT:
+ goto correct;
+
+ case BOGUS_CLIENT_RANDOM:
+ mkd_params.RandomInfo.pClientRandom = NULL;
+ break;
+
+ case BOGUS_CLIENT_RANDOM_LEN:
+ mkd_params.RandomInfo.ulClientRandomLen = 0;
+ break;
+
+ case BOGUS_SERVER_RANDOM:
+ mkd_params.RandomInfo.pServerRandom = NULL;
+ break;
+
+ case BOGUS_SERVER_RANDOM_LEN:
+ mkd_params.RandomInfo.ulServerRandomLen = 0;
+ break;
+ }
+ crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
+ &mk_obj);
+ if (crv != CKR_MECHANISM_PARAM_INVALID) {
+ PKM_LogIt( "C_DeriveKey returned as EXPECTED with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ } else {
+ PKM_Error( "C_DeriveKey did not fail with bad data \n" );
+ }
+ goto out;
+
+
+ correct:
+ /* Now derive the master secret key */
+ crv = pFunctionList->C_DeriveKey(hSession, &mk_mech, pmk_obj, NULL, 0,
+ &mk_obj);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_DeriveKey succeeded\n");
+ } else {
+ PKM_Error( "C_DeriveKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+
+ }
+
+ out:
+ if (pmk_obj != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, pmk_obj);
+ if (mk_obj != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
+ crv = pFunctionList->C_Logout(hSession);
+
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ return (crv);
+}
+
+
+CK_RV
+PKM_TLSKeyAndMacDerive( CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SLOT_ID * pSlotList, CK_ULONG slotID,
+ CK_UTF8CHAR_PTR pwd, CK_ULONG pwdLen,
+ CK_MECHANISM_TYPE mechType, enum_random_t rnd)
+{
+ CK_SESSION_HANDLE hSession;
+ CK_RV crv;
+ CK_MECHANISM kmd_mech;
+ CK_MECHANISM skmd_mech;
+ CK_OBJECT_CLASS class = CKO_SECRET_KEY;
+ CK_KEY_TYPE type = CKK_GENERIC_SECRET;
+ CK_BBOOL derive_bool = true;
+ CK_BBOOL sign_bool = true, verify_bool = true;
+ CK_BBOOL encrypt_bool = true, decrypt_bool = true;
+ CK_ULONG value_len;
+
+ /*
+ * We arrange this template so that:
+ * . Attributes 0-6 are good for a MAC key comparison template.
+ * . Attributes 2-5 are good for the master key creation template.
+ * . Attributes 3-8 are good for a cipher key comparison template.
+ */
+ CK_ATTRIBUTE attrs[9];
+
+ CK_OBJECT_HANDLE mk_obj = CK_INVALID_HANDLE;
+ CK_SSL3_KEY_MAT_PARAMS km_params;
+ CK_SSL3_KEY_MAT_OUT kmo;
+ CK_BYTE IVClient[8];
+ CK_BYTE IVServer[8];
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ attrs[0].type = CKA_SIGN;
+ attrs[0].pValue = &sign_bool;
+ attrs[0].ulValueLen = sizeof (sign_bool);
+ attrs[1].type = CKA_VERIFY;
+ attrs[1].pValue = &verify_bool;
+ attrs[1].ulValueLen = sizeof (verify_bool);
+ attrs[2].type = CKA_KEY_TYPE;
+ attrs[2].pValue = &type;
+ attrs[2].ulValueLen = sizeof (type);
+ attrs[3].type = CKA_CLASS;
+ attrs[3].pValue = &class;
+ attrs[3].ulValueLen = sizeof (class);
+ attrs[4].type = CKA_DERIVE;
+ attrs[4].pValue = &derive_bool;
+ attrs[4].ulValueLen = sizeof (derive_bool);
+ attrs[5].type = CKA_VALUE;
+ attrs[5].pValue = NULL;
+ attrs[5].ulValueLen = 0;
+ attrs[6].type = CKA_VALUE_LEN;
+ attrs[6].pValue = &value_len;
+ attrs[6].ulValueLen = sizeof (value_len);
+ attrs[7].type = CKA_ENCRYPT;
+ attrs[7].pValue = &encrypt_bool;
+ attrs[7].ulValueLen = sizeof (encrypt_bool);
+ attrs[8].type = CKA_DECRYPT;
+ attrs[8].pValue = &decrypt_bool;
+ attrs[8].ulValueLen = sizeof (decrypt_bool);
+
+ crv = pFunctionList->C_OpenSession(pSlotList[slotID], CKF_SERIAL_SESSION,
+ NULL, NULL, &hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_OpenSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_Login(hSession, CKU_USER, pwd, pwdLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Login with correct password succeeded\n");
+ } else {
+ PKM_Error( "C_Login with correct password failed "
+ "with 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ /* Before all, check if the mechanism is supported correctly */
+ if (MODE == FIPSMODE) {
+ crv = PKM_MechCheck(pFunctionList, hSession, mechType, CKF_DERIVE,
+ CK_TRUE, 48, 48);
+
+ if (crv != CKR_OK) {
+ PKM_Error( "PKM_MechCheck failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return (crv);
+ }
+ }
+ kmd_mech.mechanism = mechType;
+ kmd_mech.pParameter = &km_params;
+ kmd_mech.ulParameterLen = sizeof (km_params);
+
+ km_params.ulMacSizeInBits = 128; /* an MD5 based MAC */
+ km_params.ulKeySizeInBits = 192; /* 3DES key size */
+ km_params.ulIVSizeInBits = 64; /* 3DES block size */
+ km_params.pReturnedKeyMaterial = &kmo;
+ km_params.bIsExport = false;
+ kmo.hClientMacSecret = CK_INVALID_HANDLE;
+ kmo.hServerMacSecret = CK_INVALID_HANDLE;
+ kmo.hClientKey = CK_INVALID_HANDLE;
+ kmo.hServerKey = CK_INVALID_HANDLE;
+ kmo.pIVClient = IVClient;
+ kmo.pIVServer = IVServer;
+
+ skmd_mech.mechanism = CKM_SSL3_PRE_MASTER_KEY_GEN;
+ skmd_mech.pParameter = &km_params;
+ skmd_mech.ulParameterLen = sizeof (km_params);
+
+
+ crv = pFunctionList->C_GenerateKey(hSession, &skmd_mech,
+ &attrs[2],
+ 4,
+ &mk_obj);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_GenerateKey succeeded\n");
+ } else {
+ PKM_Error( "C_GenerateKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ attrs[5].pValue = NULL;
+ attrs[5].ulValueLen = 0;
+
+ km_params.RandomInfo.pClientRandom = (unsigned char *) TLSClientRandom;
+ km_params.RandomInfo.ulClientRandomLen =
+ sizeof (TLSClientRandom);
+ km_params.RandomInfo.pServerRandom = (unsigned char *) TLSServerRandom;
+ km_params.RandomInfo.ulServerRandomLen =
+ sizeof (TLSServerRandom);
+
+ /* Test the bad cases */
+ switch (rnd) {
+ case CORRECT:
+ goto correct;
+
+ case BOGUS_CLIENT_RANDOM:
+ km_params.RandomInfo.pClientRandom = NULL;
+ break;
+
+ case BOGUS_CLIENT_RANDOM_LEN:
+ km_params.RandomInfo.ulClientRandomLen = 0;
+ break;
+
+ case BOGUS_SERVER_RANDOM:
+ km_params.RandomInfo.pServerRandom = NULL;
+ break;
+
+ case BOGUS_SERVER_RANDOM_LEN:
+ km_params.RandomInfo.ulServerRandomLen = 0;
+ break;
+ }
+ crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
+ NULL);
+ if (crv != CKR_MECHANISM_PARAM_INVALID) {
+ PKM_Error( "key materials derivation returned unexpected "
+ "error 0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv));
+ (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
+ return (CKR_FUNCTION_FAILED);
+
+ }
+ return (CKR_OK);
+
+ correct:
+ /*
+ * Then use the master key and the client 'n server random data to
+ * derive the key materials
+ */
+ crv = pFunctionList->C_DeriveKey(hSession, &kmd_mech, mk_obj, NULL, 0,
+ NULL);
+ if (crv != CKR_OK) {
+ PKM_Error( "Cannot derive the key materials, crv 0x%08X, %-26s\n",
+ crv, PKM_CK_RVtoStr(crv));
+ (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
+ return (crv);
+ }
+
+ if (mk_obj != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, mk_obj);
+ if (kmo.hClientMacSecret != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientMacSecret);
+ if (kmo.hServerMacSecret != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerMacSecret);
+ if (kmo.hClientKey != CK_INVALID_HANDLE);
+ (void) pFunctionList->C_DestroyObject(hSession, kmo.hClientKey);
+ if (kmo.hServerKey != CK_INVALID_HANDLE)
+ (void) pFunctionList->C_DestroyObject(hSession, kmo.hServerKey);
+ crv = pFunctionList->C_Logout(hSession);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_Logout succeeded\n");
+ } else {
+ PKM_Error( "C_Logout failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_CloseSession(hSession);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_CloseSession failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ return (crv);
+}
+
+
+
+CK_RV PKM_DualFuncSign(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hRwSession,
+ CK_OBJECT_HANDLE publicKey, CK_OBJECT_HANDLE privateKey,
+ CK_MECHANISM *sigMech,
+ CK_OBJECT_HANDLE secretKey, CK_MECHANISM *cryptMech,
+ const CK_BYTE * pData, CK_ULONG pDataLen) {
+
+ CK_RV crv = CKR_OK;
+ CK_BYTE encryptedData[MAX_CIPHER_SZ];
+ CK_ULONG ulEncryptedDataLen = 0;
+ CK_ULONG ulLastUpdateSize = 0 ;
+ CK_BYTE sig[MAX_SIG_SZ];
+ CK_ULONG ulSigLen = 0;
+ CK_BYTE data[MAX_DATA_SZ];
+ CK_ULONG ulDataLen = 0;
+
+ memset(encryptedData, 0, sizeof(encryptedData));
+ memset(sig, 0, sizeof(sig));
+ memset(data, 0, sizeof(data));
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ /* Check that the mechanism is Multi-part */
+ if (sigMech->mechanism == CKM_DSA || sigMech->mechanism == CKM_RSA_PKCS) {
+ PKM_Error( "PKM_DualFuncSign must be called with a Multi-part "
+ "operation mechanism\n");
+ return CKR_DEVICE_ERROR;
+ }
+
+ /* Sign and Encrypt */
+ if (privateKey == 0 && publicKey == 0) {
+ crv = pFunctionList->C_SignInit(hRwSession, sigMech, secretKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ } else {
+ crv = pFunctionList->C_SignInit(hRwSession, sigMech, privateKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ }
+ crv = pFunctionList->C_EncryptInit(hRwSession, cryptMech, secretKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ ulEncryptedDataLen = sizeof(encryptedData);
+ crv = pFunctionList->C_SignEncryptUpdate(hRwSession, (CK_BYTE * ) pData,
+ pDataLen,
+ encryptedData,
+ &ulEncryptedDataLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ ulLastUpdateSize = sizeof(encryptedData) - ulEncryptedDataLen;
+ crv = pFunctionList->C_EncryptFinal(hRwSession,
+ (CK_BYTE * )&encryptedData[ulEncryptedDataLen], &ulLastUpdateSize);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_EncryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ ulEncryptedDataLen = ulEncryptedDataLen + ulLastUpdateSize;
+ ulSigLen = sizeof(sig);
+ crv = pFunctionList->C_SignFinal(hRwSession, sig, &ulSigLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Decrypt and Verify */
+
+ crv = pFunctionList->C_DecryptInit(hRwSession, cryptMech, secretKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ crv = pFunctionList->C_VerifyInit(hRwSession, sigMech,
+ publicKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_VerifyInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ ulDataLen = sizeof(data);
+ crv = pFunctionList->C_DecryptVerifyUpdate(hRwSession,
+ encryptedData,
+ ulEncryptedDataLen,
+ data, &ulDataLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptVerifyUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ ulLastUpdateSize = sizeof(data) - ulDataLen;
+ /* Get last little piece of plaintext. Should have length 0 */
+ crv = pFunctionList->C_DecryptFinal(hRwSession, &data[ulDataLen],
+ &ulLastUpdateSize);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (ulLastUpdateSize != 0) {
+ crv = pFunctionList->C_VerifyUpdate(hRwSession, &data[ulDataLen],
+ ulLastUpdateSize);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DecryptFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ }
+ ulDataLen = ulDataLen + ulLastUpdateSize;
+
+ /* input for the verify operation is the decrypted data */
+ crv = pFunctionList->C_VerifyFinal(hRwSession, sig, ulSigLen);
+ if (crv == CKR_OK) {
+ PKM_LogIt("C_VerifyFinal succeeded\n");
+ } else {
+ PKM_Error( "C_VerifyFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* Comparison of Decrypted data with inputed data */
+ if ( (ulDataLen == pDataLen) &&
+ (memcmp(data, pData, pDataLen) == 0) ) {
+ PKM_LogIt("PKM_DualFuncSign decrypt test case passed\n");
+ } else {
+ PKM_Error( "PKM_DualFuncSign derypt test case failed\n");
+ }
+
+ return crv;
+
+}
+
+CK_RV PKM_Digest(CK_FUNCTION_LIST_PTR pFunctionList,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM *digestMech, CK_OBJECT_HANDLE hSecretKey,
+ const CK_BYTE * pData, CK_ULONG pDataLen) {
+ CK_RV crv = CKR_OK;
+ CK_BYTE digest1[MAX_DIGEST_SZ];
+ CK_ULONG digest1Len = 0 ;
+ CK_BYTE digest2[MAX_DIGEST_SZ];
+ CK_ULONG digest2Len = 0;
+
+ /* Tested with CKM_SHA_1, CKM_SHA256, CKM_SHA384, CKM_SHA512 */
+
+ memset(digest1, 0, sizeof(digest1));
+ memset(digest2, 0, sizeof(digest2));
+
+ NUMTESTS++; /* increment NUMTESTS */
+
+ crv = pFunctionList->C_DigestInit(hSession, digestMech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_SignInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ digest1Len = sizeof(digest1);
+ crv = pFunctionList->C_Digest(hSession, (CK_BYTE * ) pData, pDataLen,
+ digest1, &digest1Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_Sign failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+
+ crv = pFunctionList->C_DigestInit(hSession, digestMech);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestInit failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ crv = pFunctionList->C_DigestUpdate(hSession, (CK_BYTE * ) pData, pDataLen);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestUpdate failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ /* C_DigestKey continues a multiple-part message-digesting operation by*/
+ /* digesting the value of a secret key. (only used with C_DigestUpdate)*/
+ if (hSecretKey != 0) {
+ crv = pFunctionList->C_DigestKey(hSession, hSecretKey);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestKey failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+ }
+
+ digest2Len = sizeof(digest2);
+ crv = pFunctionList->C_DigestFinal(hSession, digest2, &digest2Len);
+ if (crv != CKR_OK) {
+ PKM_Error( "C_DigestFinal failed with 0x%08X, %-26s\n", crv,
+ PKM_CK_RVtoStr(crv));
+ return crv;
+ }
+
+ if (hSecretKey == 0){
+ /* did not digest a secret key so digests should equal */
+ if ( (digest1Len == digest2Len)
+ && (memcmp(digest1, digest2, digest1Len) == 0) ) {
+ PKM_LogIt("Single and Multiple-part message digest "
+ "operations succesful\n");
+ } else {
+ PKM_Error("Single and Multiple-part message digest "
+ "operations failed\n");
+ }
+ } else {
+ if (digest1Len == digest2Len) {
+ PKM_LogIt("PKM_Digest Single and Multiple-part message digest "
+ "operations succesful\n");
+ } else {
+ PKM_Error("PKM_Digest Single and Multiple-part message digest "
+ "operations failed\n");
+ }
+
+ }
+
+ return crv;
+
+}
+
+char * PKM_FilePasswd(char *pwFile)
+{
+ unsigned char phrase[200];
+ PRFileDesc *fd;
+ PRInt32 nb;
+ int i;
+
+ if (!pwFile)
+ return 0;
+
+ fd = PR_Open(pwFile, PR_RDONLY, 0);
+ if (!fd) {
+ fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
+ return NULL;
+ }
+
+ nb = PR_Read(fd, phrase, sizeof(phrase));
+
+ PR_Close(fd);
+ /* handle the Windows EOL case */
+ i = 0;
+ while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb) i++;
+ phrase[i] = '\0';
+ if (nb == 0) {
+ fprintf(stderr,"password file contains no data\n");
+ return NULL;
+ }
+ return (char*) strdup((char*)phrase);
+}
+
+void PKM_Help()
+{
+ PRFileDesc *debug_out = PR_GetSpecialFD(PR_StandardError);
+ PR_fprintf(debug_out, "pk11mode test program usage:\n");
+ PR_fprintf(debug_out, "\t-f <file> Password File : echo pw > file \n");
+ PR_fprintf(debug_out, "\t-n Non Fips Mode \n");
+ PR_fprintf(debug_out, "\t-d <path> Database path location)\n");
+ PR_fprintf(debug_out, "\t-p <prefix> DataBase prefix)\n");
+ PR_fprintf(debug_out, "\t-h this help message\n");
+ exit(1);
+}
+
+void PKM_CheckPath(char *string)
+{
+ char *src;
+ char *dest;
+
+ /*
+ * windows support convert any back slashes to
+ * forward slashes.
+ */
+ for (src=string, dest=string; *src; src++,dest++) {
+ if (*src == '\\') {
+ *dest = '/';
+ }
+ }
+ dest--;
+ /* if the last char is a / set it to 0 */
+ if (*dest == '/')
+ *dest = 0;
+
+}
diff --git a/security/nss/cmd/pk11util/pk11util.c b/security/nss/cmd/pk11util/pk11util.c
index 3c8a1894f..4929ad1e3 100644
--- a/security/nss/cmd/pk11util/pk11util.c
+++ b/security/nss/cmd/pk11util/pk11util.c
@@ -56,6 +56,7 @@
#include "prtime.h"
#include "prlong.h"
#include "prinrval.h"
+#include "prenv.h"
#include "pkcs11.h"
@@ -1427,15 +1428,18 @@ putOutput(Value **ptr)
CK_RV
unloadModule(Module *module)
{
-
- if (module->library) {
+ char *disableUnload = NULL;
+
+ disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
+
+ if (module->library && !disableUnload) {
PR_UnloadLibrary(module->library);
- }
+ }
- module->library = NULL;
- module->functionList = NULL;
+ module->library = NULL;
+ module->functionList = NULL;
- return CKR_OK;
+ return CKR_OK;
}
CK_RV
diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c
index 1d15f1663..22342591c 100644
--- a/security/nss/cmd/pk12util/pk12util.c
+++ b/security/nss/cmd/pk12util/pk12util.c
@@ -282,23 +282,33 @@ P12U_UnicodeConversion(PRArenaPool *arena, SECItem *dest, SECItem *src,
SECItem *
P12U_GetP12FilePassword(PRBool confirmPw, secuPWData *p12FilePw)
{
- char *p0 = NULL, *p1 = NULL;
+ char *p0 = NULL;
SECItem *pwItem = NULL;
if (p12FilePw == NULL || p12FilePw->source == PW_NONE) {
+ char *p1 = NULL;
+ int rc;
for (;;) {
p0 = SECU_GetPasswordString(NULL,
"Enter password for PKCS12 file: ");
- if (!confirmPw)
+ if (!confirmPw || p0 == NULL)
break;
p1 = SECU_GetPasswordString(NULL, "Re-enter password: ");
- if (PL_strcmp(p0, p1) == 0)
+ if (p1 == NULL) {
+ PORT_ZFree(p0, PL_strlen(p0));
+ p0 = NULL;
break;
+ }
+ rc = PL_strcmp(p0, p1);
+ PORT_ZFree(p1, PL_strlen(p1));
+ if (rc == 0)
+ break;
+ PORT_ZFree(p0, PL_strlen(p0));
}
} else if (p12FilePw->source == PW_FROMFILE) {
p0 = SECU_FilePasswd(NULL, PR_FALSE, p12FilePw->data);
} else { /* Plaintext */
- p0 = p12FilePw->data;
+ p0 = PORT_Strdup(p12FilePw->data);
}
if (p0 == NULL) {
@@ -307,11 +317,7 @@ P12U_GetP12FilePassword(PRBool confirmPw, secuPWData *p12FilePw)
pwItem = SECITEM_AllocItem(NULL, NULL, PL_strlen(p0) + 1);
memcpy(pwItem->data, p0, pwItem->len);
- PORT_Memset(p0, 0, PL_strlen(p0));
- PORT_Free(p0);
-
- PORT_Memset(p1, 0, PL_strlen(p1));
- PORT_Free(p1);
+ PORT_ZFree(p0, PL_strlen(p0));
return pwItem;
}
@@ -344,106 +350,156 @@ P12U_InitSlot(PK11SlotInfo *slot, secuPWData *slotPw)
return SECSuccess;
}
-/*
- * given a filename for pkcs12 file, imports certs and keys
- *
- * Change: altitude
- * I've changed this function so that it takes the keydb and pkcs12 file
- * passwords from files. The "pwdKeyDB" and "pwdP12File"
- * variables have been added for this purpose.
+/* This routine takes care of getting the PKCS12 file password, then reading and
+ * verifying the file. It returns the decoder context and a filled in password.
+ * (The password is needed by P12U_ImportPKCS12Object() to import the private
+ * key.)
*/
-PRIntn
-P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
- secuPWData *slotPw, secuPWData *p12FilePw)
+SEC_PKCS12DecoderContext *
+p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
+ secuPWData *slotPw, secuPWData *p12FilePw)
{
- p12uContext *p12cxt = NULL;
SEC_PKCS12DecoderContext *p12dcx = NULL;
- SECItem *pwitem = NULL, uniPwitem = { 0 };
+ p12uContext *p12cxt = NULL;
+ SECItem *pwitem = NULL;
SECItem p12file = { 0 };
SECStatus rv = SECFailure;
PRBool swapUnicode = PR_FALSE;
+ PRBool trypw;
int error;
-
+
#ifdef IS_LITTLE_ENDIAN
swapUnicode = PR_TRUE;
#endif
- rv = P12U_InitSlot(slot, slotPw);
- if (rv != SECSuccess) {
- SECU_PrintError(progName, "Failed to authenticate to \"%s\"",
- PK11_GetSlotName(slot));
- pk12uErrno = PK12UERR_PK11GETSLOT;
- goto loser;
- }
-
p12cxt = p12u_InitContext(PR_TRUE, in_file);
if(!p12cxt) {
SECU_PrintError(progName,"File Open failed: %s", in_file);
pk12uErrno = PK12UERR_INIT_FILE;
- goto loser;
+ return NULL;
}
/* get the password */
pwitem = P12U_GetP12FilePassword(PR_FALSE, p12FilePw);
if (!pwitem) {
pk12uErrno = PK12UERR_USER_CANCELLED;
- goto loser;
+ goto done;
}
- if(P12U_UnicodeConversion(NULL, &uniPwitem, pwitem, PR_TRUE,
- swapUnicode) != SECSuccess) {
+ if(P12U_UnicodeConversion(NULL, uniPwp, pwitem, PR_TRUE,
+ swapUnicode) != SECSuccess) {
SECU_PrintError(progName,"Unicode conversion failed");
pk12uErrno = PK12UERR_UNICODECONV;
- goto loser;
+ goto done;
}
-
- /* init the decoder context */
- p12dcx = SEC_PKCS12DecoderStart(&uniPwitem, slot, slotPw,
- NULL, NULL, NULL, NULL, NULL);
- if(!p12dcx) {
- SECU_PrintError(progName,"PKCS12 decoder start failed");
- pk12uErrno = PK12UERR_PK12DECODESTART;
- goto loser;
+ rv = SECU_FileToItem(&p12file, p12cxt->file);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName,"Failed to read from import file");
+ goto done;
}
- /* decode the item */
- rv = SECU_FileToItem(&p12file, p12cxt->file);
+ do {
+ trypw = PR_FALSE; /* normally we do this once */
+ rv = SECFailure;
+ /* init the decoder context */
+ p12dcx = SEC_PKCS12DecoderStart(uniPwp, slot, slotPw,
+ NULL, NULL, NULL, NULL, NULL);
+ if(!p12dcx) {
+ SECU_PrintError(progName,"PKCS12 decoder start failed");
+ pk12uErrno = PK12UERR_PK12DECODESTART;
+ break;
+ }
+
+ /* decode the item */
+ rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len);
+
+ if(rv != SECSuccess) {
+ error = PR_GetError();
+ if(error == SEC_ERROR_DECRYPTION_DISALLOWED) {
+ PR_SetError(error, 0);
+ break;
+ }
+ SECU_PrintError(progName,"PKCS12 decoding failed");
+ pk12uErrno = PK12UERR_DECODE;
+ }
+
+ /* does the blob authenticate properly? */
+ rv = SEC_PKCS12DecoderVerify(p12dcx);
+ if (rv != SECSuccess) {
+ if(uniPwp->len == 2) {
+ /* this is a null PW, try once more with a zero-length PW
+ instead of a null string */
+ SEC_PKCS12DecoderFinish(p12dcx);
+ uniPwp->len = 0;
+ trypw = PR_TRUE;
+ }
+ else {
+ SECU_PrintError(progName,"PKCS12 decode not verified");
+ pk12uErrno = PK12UERR_DECODEVERIFY;
+ break;
+ }
+ }
+ } while (trypw == PR_TRUE);
+ /* rv has been set at this point */
+
+
+done:
if (rv != SECSuccess) {
- SECU_PrintError(progName,"Failed to read from import file");
- goto loser;
+ if (p12dcx != NULL) {
+ SEC_PKCS12DecoderFinish(p12dcx);
+ p12dcx = NULL;
+ }
+ if (uniPwp->data) {
+ SECITEM_ZfreeItem(uniPwp, PR_FALSE);
+ uniPwp->data = NULL;
+ }
}
- rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len);
+ PR_Close(p12cxt->file);
+ p12cxt->file = NULL;
+ /* PK11_FreeSlot(slot); */
+ p12u_DestroyContext(&p12cxt, PR_FALSE);
- if(rv != SECSuccess) {
- error = PR_GetError();
- if(error == SEC_ERROR_DECRYPTION_DISALLOWED) {
- PR_SetError(error, 0);
- goto loser;
- }
-#ifdef EXTRA
- /* unable to import as a new blob, it might be an old one */
- if(p12u_TryToImportOldPDU(p12cxt, pwitem, slot, import_arg->nickCb,
- import_arg->proto_win) != SECSuccess) {
- goto loser;
- }
- goto tried_pdu_import;
-#endif /* EXTRA */
- SECU_PrintError(progName,"PKCS12 decoding failed");
- pk12uErrno = PK12UERR_DECODE;
+ if (pwitem) {
+ SECITEM_ZfreeItem(pwitem, PR_TRUE);
}
+ return p12dcx;
+}
- rv = SECFailure;
+/*
+ * given a filename for pkcs12 file, imports certs and keys
+ *
+ * Change: altitude
+ * I've changed this function so that it takes the keydb and pkcs12 file
+ * passwords from files. The "pwdKeyDB" and "pwdP12File"
+ * variables have been added for this purpose.
+ */
+PRIntn
+P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
+ secuPWData *slotPw, secuPWData *p12FilePw)
+{
+ SEC_PKCS12DecoderContext *p12dcx = NULL;
+ SECItem uniPwitem = { 0 };
+ SECStatus rv = SECFailure;
+ int error;
- /* does the blob authenticate properly? */
- if(SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) {
- SECU_PrintError(progName,"PKCS12 decode not verified");
- pk12uErrno = PK12UERR_DECODEVERIFY;
- goto loser;
+ rv = P12U_InitSlot(slot, slotPw);
+ if (rv != SECSuccess) {
+ SECU_PrintError(progName, "Failed to authenticate to \"%s\"",
+ PK11_GetSlotName(slot));
+ pk12uErrno = PK12UERR_PK11GETSLOT;
+ return rv;
}
+ rv = SECFailure;
+ p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
+
+ if(p12dcx == NULL) {
+ goto loser;
+ }
+
/* make sure the bags are okey dokey -- nicknames correct, etc. */
- if (SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback)
- != SECSuccess) {
+ rv = SEC_PKCS12DecoderValidateBags(p12dcx, P12U_NicknameCollisionCallback);
+ if (rv != SECSuccess) {
if (PORT_GetError() == SEC_ERROR_PKCS12_DUPLICATE_DATA) {
pk12uErrno = PK12UERR_CERTALREADYEXISTS;
} else {
@@ -454,49 +510,25 @@ P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
}
/* stuff 'em in */
- if(SEC_PKCS12DecoderImportBags(p12dcx) != SECSuccess) {
+ rv = SEC_PKCS12DecoderImportBags(p12dcx);
+ if (rv != SECSuccess) {
SECU_PrintError(progName,"PKCS12 decode import bags failed");
pk12uErrno = PK12UERR_DECODEIMPTBAGS;
goto loser;
}
-#if 0
- /* important - to add the password hash into the key database */
- rv = PK11_CheckUserPassword(slot, pw_string);
- if( rv != SECSuccess ) {
- SECU_PrintError(progName,"Failed to CheckUserPassword");
- exit(-1);
- }
-#endif
-
- PR_Close(p12cxt->file);
- p12cxt->file = NULL;
- /* PK11_FreeSlot(slot); */
-
fprintf(stdout, "%s: PKCS12 IMPORT SUCCESSFUL\n", progName);
rv = SECSuccess;
loser:
- if (rv != SECSuccess) {
- /* pk12u_report_failure */
- } else {
- /* pk12u_report_success ? */
- }
-
if (p12dcx) {
SEC_PKCS12DecoderFinish(p12dcx);
}
- p12u_DestroyContext(&p12cxt, PR_FALSE);
-
+
if (uniPwitem.data) {
SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
}
-
- if (pwitem) {
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
- }
-
-
+
return rv;
}
@@ -545,6 +577,7 @@ p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
}
}
+
void
P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot,
secuPWData *slotPw, secuPWData *p12FilePw)
@@ -678,12 +711,6 @@ loser:
certlist = NULL;
}
- if (slotPw)
- PR_Free(slotPw->data);
-
- if (p12FilePw)
- PR_Free(p12FilePw->data);
-
p12u_DestroyContext(&p12cxt, PR_TRUE);
if(pwitem) {
SECITEM_ZfreeItem(pwitem, PR_TRUE);
@@ -697,78 +724,22 @@ PRIntn
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
secuPWData *slotPw, secuPWData *p12FilePw)
{
- p12uContext *p12cxt = NULL;
SEC_PKCS12DecoderContext *p12dcx = NULL;
- SECItem *pwitem = NULL, uniPwitem = { 0 };
- SECItem p12file = { 0 };
+ SECItem uniPwitem = { 0 };
SECStatus rv = SECFailure;
- PRBool swapUnicode = PR_FALSE;
const SEC_PKCS12DecoderItem *dip;
-
int error;
-#ifdef IS_LITTLE_ENDIAN
- swapUnicode = PR_TRUE;
-#endif
-
- p12cxt = p12u_InitContext(PR_TRUE, in_file);
- if(!p12cxt) {
- SECU_PrintError(progName,"File Open failed: %s", in_file);
- pk12uErrno = PK12UERR_INIT_FILE;
- goto loser;
- }
-
- /* get the password */
- pwitem = P12U_GetP12FilePassword(PR_FALSE, p12FilePw);
- if (!pwitem) {
- pk12uErrno = PK12UERR_USER_CANCELLED;
- goto loser;
- }
-
- if(P12U_UnicodeConversion(NULL, &uniPwitem, pwitem, PR_TRUE,
- swapUnicode) != SECSuccess) {
- SECU_PrintError(progName,"Unicode conversion failed");
- pk12uErrno = PK12UERR_UNICODECONV;
- goto loser;
- }
-
- /* init the decoder context */
- p12dcx = SEC_PKCS12DecoderStart(&uniPwitem, slot, slotPw,
- NULL, NULL, NULL, NULL, NULL);
- if(!p12dcx) {
- SECU_PrintError(progName,"PKCS12 decoder start failed");
- pk12uErrno = PK12UERR_PK12DECODESTART;
- goto loser;
- }
-
- /* read the item */
- rv = SECU_FileToItem(&p12file, p12cxt->file);
- PR_Close(p12cxt->file);
- p12cxt->file = NULL;
-
- if (rv != SECSuccess) {
- SECU_PrintError(progName,"Failed to read from import file");
- goto loser;
- }
-
- rv = SEC_PKCS12DecoderUpdate(p12dcx, p12file.data, p12file.len);
- if(rv != SECSuccess) {
- error = PR_GetError();
- if(error == SEC_ERROR_DECRYPTION_DISALLOWED) {
- PR_SetError(error, 0);
- goto loser;
- }
- SECU_PrintError(progName,"PKCS12 decoding failed");
- pk12uErrno = PK12UERR_DECODE;
- }
-
- /* does the blob authenticate properly? */
- if(SEC_PKCS12DecoderVerify(p12dcx) != SECSuccess) {
+ p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw,
+ p12FilePw);
+ /* did the blob authenticate properly? */
+ if(p12dcx == NULL) {
SECU_PrintError(progName,"PKCS12 decode not verified");
pk12uErrno = PK12UERR_DECODEVERIFY;
- rv = SECFailure;
+ goto loser;
}
- else if (SEC_PKCS12DecoderIterateInit(p12dcx) != SECSuccess) {
+ rv = SEC_PKCS12DecoderIterateInit(p12dcx);
+ if(rv != SECSuccess) {
SECU_PrintError(progName,"PKCS12 decode iterate bags failed");
pk12uErrno = PK12UERR_DECODEIMPTBAGS;
rv = SECFailure;
@@ -813,16 +784,11 @@ loser:
if (p12dcx) {
SEC_PKCS12DecoderFinish(p12dcx);
}
- p12u_DestroyContext(&p12cxt, PR_FALSE);
-
+
if (uniPwitem.data) {
SECITEM_ZfreeItem(&uniPwitem, PR_FALSE);
}
-
- if (pwitem) {
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
- }
-
+
return rv;
}
@@ -999,6 +965,10 @@ main(int argc, char **argv)
}
done:
+ if (slotPw.data != NULL)
+ PORT_ZFree(slotPw.data, PL_strlen(slotPw.data));
+ if (p12FilePw.data != NULL)
+ PORT_ZFree(p12FilePw.data, PL_strlen(p12FilePw.data));
if (slot) PK11_FreeSlot(slot);
if (NSS_Shutdown() != SECSuccess) {
pk12uErrno = 1;
diff --git a/security/nss/cmd/platlibs.mk b/security/nss/cmd/platlibs.mk
index 57872e48b..be588f440 100644
--- a/security/nss/cmd/platlibs.mk
+++ b/security/nss/cmd/platlibs.mk
@@ -35,6 +35,43 @@
#
# ***** END LICENSE BLOCK *****
+# set RPATH-type linker instructions here so they can be used in the shared
+# version and in the mixed (static nss libs/shared NSPR libs) version.
+
+ifeq ($(OS_ARCH), SunOS)
+ifeq ($(BUILD_SUN_PKG), 1)
+ifeq ($(USE_64), 1)
+EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
+else
+EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps'
+endif
+else
+EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib'
+endif
+endif
+
+ifeq ($(OS_ARCH), Linux)
+ifeq ($(USE_64), 1)
+EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:$$ORIGIN/../lib'
+else
+EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib'
+endif
+endif
+
+ifeq ($(OS_ARCH), HP-UX)
+ifeq ($(OS_TEST), ia64)
+EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib'
+else
+# pa-risc
+ifeq ($(USE_64), 1)
+EXTRA_SHARED_LIBS += \
+-Wl,+b,'$$ORIGIN/../../lib/pa20_64:$$ORIGIN/../../lib/64:$$ORIGIN/../lib'
+else
+EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib'
+endif
+endif
+endif
+
ifdef USE_STATIC_LIBS
@@ -136,6 +173,10 @@ EXTRA_SHARED_LIBS += \
-lnspr4 \
$(NULL)
endif
+
+ifeq ($(OS_TARGET), SunOS)
+OS_LIBS += -lbsm
+endif
endif
else # USE_STATIC_LIBS
@@ -184,24 +225,6 @@ endif
endif
endif
-ifeq ($(OS_ARCH), SunOS)
-ifeq ($(BUILD_SUN_PKG), 1)
-ifeq ($(USE_64), 1)
-EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
-else
-EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps'
-endif
-else
-EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib'
-endif
-endif
-
-ifeq ($(OS_ARCH), HP-UX)
-ifeq ($(OS_TEST), ia64)
-EXTRA_SHARED_LIBS += -Wl,+b,'$$ORIGIN/../lib'
-endif
-endif
-
ifeq ($(OS_ARCH), Darwin)
EXTRA_SHARED_LIBS += -dylib_file @executable_path/libsoftokn3.dylib:$(DIST)/lib/libsoftokn3.dylib
endif
diff --git a/security/nss/cmd/pp/pp.c b/security/nss/cmd/pp/pp.c
index 14e3f26af..4aa449790 100644
--- a/security/nss/cmd/pp/pp.c
+++ b/security/nss/cmd/pp/pp.c
@@ -169,6 +169,7 @@ int main(int argc, char **argv)
} else {
fprintf(stderr, "%s: don't know how to print out '%s' files\n",
progName, typeTag);
+ SECU_PrintAny(outFile, &data, "File contains", 0);
return -1;
}
diff --git a/security/nss/cmd/rsaperf/Makefile b/security/nss/cmd/rsaperf/Makefile
index e256ff037..7df60581b 100644
--- a/security/nss/cmd/rsaperf/Makefile
+++ b/security/nss/cmd/rsaperf/Makefile
@@ -57,16 +57,6 @@ include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
include ../platlibs.mk
-ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) #omits WINCE
-ifndef BUILD_OPT
-ifndef NS_USE_GCC
-LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
-endif
-OS_CFLAGS += -D_CONSOLE
-endif
-endif
-
-
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/cmd/selfserv/selfserv.c b/security/nss/cmd/selfserv/selfserv.c
index f4a3e6525..49a8e1bd8 100644
--- a/security/nss/cmd/selfserv/selfserv.c
+++ b/security/nss/cmd/selfserv/selfserv.c
@@ -58,6 +58,7 @@
#include <Process.h> /* for getpid() */
#endif
+#include <signal.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
@@ -107,28 +108,6 @@ const int ssl2CipherSuites[] = {
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
-#ifdef NSS_ENABLE_ECC
- /* NOTE: Since no new SSL2 ciphersuites are being
- * invented, and we've run out of lowercase letters
- * for SSL3 ciphers, we use letters G and beyond
- * for new SSL3 ciphers. A -1 indicates the cipher
- * is not currently implemented.
- */
- TLS_ECDH_ECDSA_WITH_NULL_SHA, /* G */
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* H */
- TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, /* I */
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* J */
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* K */
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* L */
- TLS_ECDH_RSA_WITH_NULL_SHA, /* M */
- TLS_ECDH_RSA_WITH_RC4_128_SHA, /* N */
- TLS_ECDH_RSA_WITH_DES_CBC_SHA, /* O */
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* P */
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* Q */
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* R */
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* S */
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* T */
-#endif /* NSS_ENABLE_ECC */
0
};
@@ -211,6 +190,7 @@ Usage(const char *progName)
"-S means disable SSL v2\n"
"-3 means disable SSL v3\n"
"-B bypasses the PKCS11 layer for SSL encryption and MACing\n"
+"-q checks for bypassability\n"
"-D means disable Nagle delays in TCP\n"
"-E means disable export ciphersuites and SSL step down key gen\n"
"-T means disable TLS\n"
@@ -230,31 +210,15 @@ Usage(const char *progName)
"-N means do NOT use the server session cache. Incompatible with -M.\n"
"-t threads -- specify the number of threads to use for connections.\n"
"-i pid_file file to write the process id of selfserve\n"
-"-c ciphers Letter(s) chosen from the following list\n"
"-l means use local threads instead of global threads\n"
"-C SSLCacheEntries sets the maximum number of entries in the SSL session cache\n"
+"-c ciphers Letter(s) chosen from the following list\n"
"A SSL2 RC4 128 WITH MD5\n"
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
"C SSL2 RC2 128 CBC WITH MD5\n"
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
-#ifdef NSS_ENABLE_ECC
-"G TLS ECDH ECDSA WITH NULL SHA\n"
-"H TLS ECDH ECDSA WITH RC4 128 SHA\n"
-"I TLS ECDH ECDSA WITH DES CBC SHA\n"
-"J TLS ECDH ECDSA WITH 3DES EDE CBC SHA\n"
-"K TLS ECDH ECDSA WITH AES 128 CBC SHA\n"
-"L TLS ECDH ECDSA WITH AES 256 CBC SHA\n"
-"M TLS ECDH RSA WITH NULL SHA\n"
-"N TLS ECDH RSA WITH RC4 128 SHA\n"
-"O TLS ECDH RSA WITH DES CBC SHA\n"
-"P TLS ECDH RSA WITH 3DES EDE CBC SHA\n"
-"Q TLS ECDH RSA WITH AES 128 CBC SHA\n"
-"R TLS ECDH RSA WITH AES 256 CBC SHA\n"
-"S TLS ECDHE ECDSA WITH AES 128 CBC SHA\n"
-"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
-#endif /* NSS_ENABLE_ECC */
"\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
@@ -270,6 +234,8 @@ Usage(const char *progName)
"v SSL3 RSA WITH AES 128 CBC SHA\n"
"y SSL3 RSA WITH AES 256 CBC SHA\n"
"z SSL3 RSA WITH NULL SHA\n"
+"\n"
+":WXYZ Use cipher with hex code { 0xWX , 0xYZ } in TLS\n"
,progName);
}
@@ -635,6 +601,8 @@ terminateWorkerThreads(void)
while (threadCount > 0) {
PZ_WaitCondVar(threadCountChangeCv, PR_INTERVAL_NO_TIMEOUT);
}
+ /* The worker threads empty the jobQ before they terminate. */
+ PORT_Assert(PR_CLIST_IS_EMPTY(&jobQ));
PZ_Unlock(qLock);
DESTROY_CONDVAR(jobQNotEmptyCv);
@@ -692,6 +660,7 @@ PRBool hasSidCache = PR_FALSE;
PRBool disableStepDown = PR_FALSE;
PRBool bypassPKCS11 = PR_FALSE;
PRBool disableLocking = PR_FALSE;
+PRBool testbypass = PR_FALSE;
static const char stopCmd[] = { "GET /stop " };
static const char getCmd[] = { "GET " };
@@ -705,6 +674,17 @@ static const char outHeader[] = {
};
static const char crlCacheErr[] = { "CRL ReCache Error: " };
+PRUint16 cipherlist[100];
+int nciphers;
+
+void
+savecipher(int c)
+{
+ if (nciphers < sizeof cipherlist / sizeof (cipherlist[0]))
+ cipherlist[nciphers++] = (PRUint16)c;
+}
+
+
#ifdef FULL_DUPLEX_CAPABLE
struct lockedVarsStr {
@@ -859,11 +839,8 @@ handle_fdx_connection(
cleanup:
if (ssl_sock) {
PR_Close(ssl_sock);
- } else
- {
- if (tcp_sock) {
- PR_Close(tcp_sock);
- }
+ } else if (tcp_sock) {
+ PR_Close(tcp_sock);
}
VLOG(("selfserv: handle_fdx_connection: exiting"));
@@ -918,6 +895,12 @@ reload_crl(PRFileDesc *crlFile)
return rv;
}
+void stop_server()
+{
+ stopping = 1;
+ PR_Interrupt(acceptorThread);
+ PZ_TraceFlush();
+}
int
handle_connection(
@@ -1206,6 +1189,8 @@ handle_connection(
cleanup:
if (ssl_sock) {
PR_Close(ssl_sock);
+ } else if (tcp_sock) {
+ PR_Close(tcp_sock);
}
if (local_file_fd)
PR_Close(local_file_fd);
@@ -1213,15 +1198,23 @@ cleanup:
/* do a nice shutdown if asked. */
if (!strncmp(buf, stopCmd, sizeof stopCmd - 1)) {
- stopping = 1;
VLOG(("selfserv: handle_connection: stop command"));
- PR_Interrupt(acceptorThread);
- PZ_TraceFlush();
+ stop_server();
}
VLOG(("selfserv: handle_connection: exiting"));
return SECSuccess; /* success */
}
+#ifdef XP_UNIX
+
+void sigusr1_handler(int sig)
+{
+ VLOG(("selfserv: sigusr1_handler: stop server"));
+ stop_server();
+}
+
+#endif
+
SECStatus
do_accepts(
PRFileDesc *listen_sock,
@@ -1231,11 +1224,24 @@ do_accepts(
{
PRNetAddr addr;
PRErrorCode perr;
+#ifdef XP_UNIX
+ struct sigaction act;
+#endif
VLOG(("selfserv: do_accepts: starting"));
PR_SetThreadPriority( PR_GetCurrentThread(), PR_PRIORITY_HIGH);
acceptorThread = PR_GetCurrentThread();
+#ifdef XP_UNIX
+ /* set up the signal handler */
+ act.sa_handler = sigusr1_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ if (sigaction(SIGUSR1, &act, NULL)) {
+ fprintf(stderr, "Error installing signal handler.\n");
+ exit(1);
+ }
+#endif
while (!stopping) {
PRFileDesc *tcp_sock;
PRCList *myLink;
@@ -1331,6 +1337,21 @@ getBoundListenSocket(unsigned short port)
errExit("PR_SetSocketOption(PR_SockOpt_Reuseaddr)");
}
+#ifndef WIN95
+ /* Set PR_SockOpt_Linger because it helps prevent a server bind issue
+ * after clean shutdown . See bug 331413 .
+ * Don't do it in the WIN95 build configuration because clean shutdown is
+ * not implemented, and PR_SockOpt_Linger causes a hang in ssl.sh .
+ * See bug 332348 */
+ opt.option=PR_SockOpt_Linger;
+ opt.value.linger.polarity = PR_TRUE;
+ opt.value.linger.linger = PR_SecondsToInterval(1);
+ prStatus = PR_SetSocketOption(listen_sock, &opt);
+ if (prStatus < 0) {
+ errExit("PR_SetSocketOption(PR_SockOpt_Linger)");
+ }
+#endif
+
prStatus = PR_Bind(listen_sock, &addr);
if (prStatus < 0) {
errExit("PR_Bind");
@@ -1619,6 +1640,21 @@ WaitForDebugger(void)
}
#endif
+#define HEXCHAR_TO_INT(c, i) \
+ if (((c) >= '0') && ((c) <= '9')) { \
+ i = (c) - '0'; \
+ } else if (((c) >= 'a') && ((c) <= 'f')) { \
+ i = (c) - 'a' + 10; \
+ } else if (((c) >= 'A') && ((c) <= 'F')) { \
+ i = (c) - 'A' + 10; \
+ } else if ((c) == '\0') { \
+ fprintf(stderr, "Invalid length of cipher string (-c :WXYZ).\n"); \
+ exit(9); \
+ } else { \
+ fprintf(stderr, "Non-hex char in cipher string (-c :WXYZ).\n"); \
+ exit(9); \
+ }
+
int
main(int argc, char **argv)
{
@@ -1650,7 +1686,9 @@ main(int argc, char **argv)
PLOptStatus status;
PRThread *loggerThread;
PRBool debugCache = PR_FALSE; /* bug 90518 */
- char* certPrefix = "";
+ char emptyString[] = { "" };
+ char* certPrefix = emptyString;
+ PRUint32 protos = 0;
tmp = strrchr(argv[0], '/');
@@ -1664,7 +1702,7 @@ main(int argc, char **argv)
** numbers, then capital letters, then lower case, alphabetical.
*/
optstate = PL_CreateOptState(argc, argv,
- "2:3BC:DEL:M:NP:RSTbc:d:e:f:hi:lmn:op:rst:vw:xy");
+ "2:3BC:DEL:M:NP:RSTbc:d:e:f:hi:lmn:op:qrst:vw:xy");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
++optionsFound;
switch(optstate->option) {
@@ -1705,15 +1743,15 @@ main(int argc, char **argv)
case 'b': bindOnly = PR_TRUE; break;
- case 'c': cipherString = strdup(optstate->value); break;
+ case 'c': cipherString = PORT_Strdup(optstate->value); break;
case 'd': dir = optstate->value; break;
#ifdef NSS_ENABLE_ECC
- case 'e': ecNickName = strdup(optstate->value); break;
+ case 'e': ecNickName = PORT_Strdup(optstate->value); break;
#endif /* NSS_ENABLE_ECC */
- case 'f': fNickName = strdup(optstate->value); break;
+ case 'f': fNickName = PORT_Strdup(optstate->value); break;
case 'h': Usage(progName); exit(0); break;
@@ -1723,14 +1761,16 @@ main(int argc, char **argv)
case 'm': useModelSocket = PR_TRUE; break;
- case 'n': nickName = strdup(optstate->value); break;
+ case 'n': nickName = PORT_Strdup(optstate->value); break;
- case 'P': certPrefix = strdup(optstate->value); break;
+ case 'P': certPrefix = PORT_Strdup(optstate->value); break;
case 'o': MakeCertOK = 1; break;
case 'p': port = PORT_Atoi(optstate->value); break;
+ case 'q': testbypass = PR_TRUE; break;
+
case 'r': ++requestCert; break;
case 's': disableLocking = PR_TRUE; break;
@@ -1743,7 +1783,7 @@ main(int argc, char **argv)
case 'v': verbose++; break;
- case 'w': passwd = strdup(optstate->value); break;
+ case 'w': passwd = PORT_Strdup(optstate->value); break;
case 'x': useExportPolicy = PR_TRUE; break;
@@ -1783,7 +1823,11 @@ main(int argc, char **argv)
exit(0);
}
- if ((nickName == NULL) && (fNickName == NULL)) {
+ if ((nickName == NULL) && (fNickName == NULL)
+#ifdef NSS_ENABLE_ECC
+ && (ecNickName == NULL)
+#endif
+ ) {
fprintf(stderr, "Required arg '-n' (rsa nickname) not supplied.\n");
fprintf(stderr, "Run '%s -h' for usage information.\n", progName);
exit(6);
@@ -1898,32 +1942,71 @@ main(int argc, char **argv)
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
if (cipherString) {
+ char *cstringSaved = cipherString;
int ndx;
/* disable all the ciphers, then enable the ones we want. */
disableAllSSLCiphers();
while (0 != (ndx = *cipherString++)) {
- const int *cptr;
int cipher;
- if (! isalpha(ndx)) {
- fprintf(stderr,
- "Non-alphabetic char in cipher string (-c arg).\n");
- exit(9);
+ if (ndx == ':') {
+ int ctmp;
+
+ cipher = 0;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 12);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 8);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 4);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= ctmp;
+ cipherString++;
+ } else {
+ const int *cptr;
+
+ if (! isalpha(ndx)) {
+ fprintf(stderr,
+ "Non-alphabetic char in cipher string (-c arg).\n");
+ exit(9);
+ }
+ cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
+ /* do nothing */;
}
- cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
- for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
- /* do nothing */;
if (cipher > 0) {
SECStatus status;
status = SSL_CipherPrefSetDefault(cipher, SSL_ALLOWED);
if (status != SECSuccess)
SECU_PrintError(progName, "SSL_CipherPrefSet()");
+ } else {
+ fprintf(stderr,
+ "Invalid cipher specification (-c arg).\n");
+ exit(9);
}
}
+ PORT_Free(cstringSaved);
}
+ if (testbypass) {
+ const PRUint16 *cipherSuites = SSL_ImplementedCiphers;
+ int i = SSL_NumImplementedCiphers;
+ PRBool enabled;
+
+ for (i=0; i < SSL_NumImplementedCiphers; i++, cipherSuites++) {
+ if (SSL_CipherPrefGetDefault(*cipherSuites, &enabled) == SECSuccess
+ && enabled)
+ savecipher(*cipherSuites);
+ }
+ protos = (disableTLS ? 0 : SSL_CBP_TLS1_0) +
+ (disableSSL3 ? 0 : SSL_CBP_SSL3);
+ }
+
if (nickName) {
cert[kt_rsa] = PK11_FindCertFromNickname(nickName, passwd);
if (cert[kt_rsa] == NULL) {
@@ -1936,6 +2019,16 @@ main(int argc, char **argv)
nickName);
exit(11);
}
+ if (testbypass) {
+ PRBool bypassOK;
+ if (SSL_CanBypass(cert[kt_rsa], privKey[kt_rsa], protos, cipherlist,
+ nciphers, &bypassOK, passwd) != SECSuccess) {
+ SECU_PrintError(progName, "Bypass test failed %s\n", nickName);
+ exit(14);
+ }
+ fprintf(stderr, "selfserv: %s can%s bypass\n", nickName,
+ bypassOK ? "" : "not");
+ }
}
if (fNickName) {
cert[kt_fortezza] = PK11_FindCertFromNickname(fNickName, NULL);
@@ -1947,17 +2040,35 @@ main(int argc, char **argv)
}
#ifdef NSS_ENABLE_ECC
if (ecNickName) {
- cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, NULL);
+ cert[kt_ecdh] = PK11_FindCertFromNickname(ecNickName, passwd);
if (cert[kt_ecdh] == NULL) {
fprintf(stderr, "selfserv: Can't find certificate %s\n",
ecNickName);
exit(13);
}
- privKey[kt_ecdh] = PK11_FindKeyByAnyCert(cert[kt_ecdh], NULL);
+ privKey[kt_ecdh] = PK11_FindKeyByAnyCert(cert[kt_ecdh], passwd);
+ if (privKey[kt_ecdh] == NULL) {
+ fprintf(stderr, "selfserv: Can't find Private Key for cert %s\n",
+ ecNickName);
+ exit(11);
+ }
+ if (testbypass) {
+ PRBool bypassOK;
+ if (SSL_CanBypass(cert[kt_ecdh], privKey[kt_ecdh], protos, cipherlist,
+ nciphers, &bypassOK, passwd) != SECSuccess) {
+ SECU_PrintError(progName, "Bypass test failed %s\n", ecNickName);
+ exit(15);
+ }
+ fprintf(stderr, "selfserv: %s can%s bypass\n", ecNickName,
+ bypassOK ? "" : "not");
+ }
}
#endif /* NSS_ENABLE_ECC */
- /* allocate the array of thread slots, and launch the worker threads. */
+ if (testbypass)
+ goto cleanup;
+
+/* allocate the array of thread slots, and launch the worker threads. */
rv = launch_threads(&jobLoop, 0, 0, requestCert, useLocalThreads);
if (rv == SECSuccess && logStats) {
@@ -1977,6 +2088,7 @@ main(int argc, char **argv)
VLOG(("selfserv: server_thread: exiting"));
+cleanup:
{
int i;
for (i=0; i<kt_kea_size; i++) {
@@ -1993,8 +2105,23 @@ main(int argc, char **argv)
nss_DumpCertificateCacheInfo();
}
- free(nickName);
- free(passwd);
+ if (nickName) {
+ PORT_Free(nickName);
+ }
+ if (passwd) {
+ PORT_Free(passwd);
+ }
+ if (certPrefix && certPrefix != emptyString) {
+ PORT_Free(certPrefix);
+ }
+ if (fNickName) {
+ PORT_Free(fNickName);
+ }
+ #ifdef NSS_ENABLE_ECC
+ if (ecNickName) {
+ PORT_Free(ecNickName);
+ }
+ #endif
if (hasSidCache) {
SSL_ShutdownServerSessionIDCache();
diff --git a/security/nss/cmd/shlibsign/Makefile b/security/nss/cmd/shlibsign/Makefile
index e6c47da24..6c6ad27e1 100644
--- a/security/nss/cmd/shlibsign/Makefile
+++ b/security/nss/cmd/shlibsign/Makefile
@@ -86,11 +86,17 @@ include $(CORE_DEPTH)/coreconf/rules.mk
include ../platrules.mk
+SRCDIR = $(call core_abspath,.)
+
%.chk: %.$(DLL_SUFFIX)
ifeq ($(OS_TARGET), OS2)
- cmd.exe /c sign.cmd $(DIST) $(OBJDIR) $(OS_TARGET) $(NSPR_LIB_DIR) $<
+ cd $(OBJDIR) ; cmd.exe /c $(SRCDIR)/sign.cmd $(DIST) \
+ $(call core_abspath,$(OBJDIR)) $(OS_TARGET) \
+ $(call core_abspath,$(NSPR_LIB_DIR)) $(call core_abspath,$<)
else
- sh ./sign.sh $(DIST) $(OBJDIR) $(OS_TARGET) $(NSPR_LIB_DIR) $<
+ cd $(OBJDIR) ; sh $(SRCDIR)/sign.sh $(call core_abspath,$(DIST)) \
+ $(call core_abspath,$(OBJDIR)) $(OS_TARGET) \
+ $(call core_abspath,$(NSPR_LIB_DIR)) $(call core_abspath,$<)
endif
libs install :: $(CHECKLOC)
diff --git a/security/nss/cmd/shlibsign/mangle/mangle.c b/security/nss/cmd/shlibsign/mangle/mangle.c
index 649c0ab8b..30b1daca3 100644
--- a/security/nss/cmd/shlibsign/mangle/mangle.c
+++ b/security/nss/cmd/shlibsign/mangle/mangle.c
@@ -65,17 +65,17 @@ main (int argc, char **argv)
/* parameter set variables */
const char *libFile = NULL;
- int offset = -1;
int bitOffset = -1;
/* return values */
int retval = 2; /* 0 - test succeeded.
* 1 - illegal args
* 2 - function failed */
- PRFileDesc *fd;
+ PRFileDesc *fd = NULL;
int bytesRead;
int bytesWritten;
- int pos;
+ PROffset32 offset = -1;
+ PROffset32 pos;
programName = PL_strrchr(argv[0], '/');
programName = programName ? (programName + 1) : argv[0];
@@ -112,11 +112,6 @@ main (int argc, char **argv)
return 1;
}
- if (offset < 0) {
- usage(programName);
- return 1;
- }
-
/* open the target signature file */
fd = PR_OpenFile(libFile,PR_RDWR,0666);
if (fd == NULL ) {
@@ -125,10 +120,21 @@ main (int argc, char **argv)
goto loser;
}
+ if (offset < 0) { /* convert to positive offset */
+ pos = PR_Seek(fd, offset, PR_SEEK_END);
+ if (pos == -1) {
+ PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n",
+ libFile, offset);
+ goto loser;
+ }
+ offset = pos;
+ }
+
/* read the byte */
pos = PR_Seek(fd, offset, PR_SEEK_SET);
if (pos != offset) {
- PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n", libFile, offset);
+ PR_fprintf(pr_stderr,"Seek for read on %s (to %d) failed\n",
+ libFile, offset);
goto loser;
}
bytesRead = PR_Read(fd, &cbuf, 1);
@@ -141,13 +147,14 @@ main (int argc, char **argv)
offset, offset, (unsigned char)cbuf, (unsigned char)cbuf);
/* change it */
cbuf ^= 1 << bitOffset;
- PR_fprintf(pr_stderr,"%02x (%d)\n", (
- unsigned char)cbuf, (unsigned char)cbuf);
+ PR_fprintf(pr_stderr,"%02x (%d)\n",
+ (unsigned char)cbuf, (unsigned char)cbuf);
/* write it back out */
pos = PR_Seek(fd, offset, PR_SEEK_SET);
if (pos != offset) {
- PR_fprintf(pr_stderr,"Seek for write on %s (to %d) failed\n", libFile, offset);
+ PR_fprintf(pr_stderr,"Seek for write on %s (to %d) failed\n",
+ libFile, offset);
goto loser;
}
bytesWritten = PR_Write(fd, &cbuf, 1);
@@ -156,12 +163,11 @@ main (int argc, char **argv)
goto loser;
}
- PR_Close(fd);
retval = 0;
-
loser:
-
+ if (fd)
+ PR_Close(fd);
PR_Cleanup ();
return retval;
}
diff --git a/security/nss/cmd/shlibsign/sign.sh b/security/nss/cmd/shlibsign/sign.sh
index 97c582a79..764012d7b 100644
--- a/security/nss/cmd/shlibsign/sign.sh
+++ b/security/nss/cmd/shlibsign/sign.sh
@@ -50,6 +50,8 @@ OpenVMS)
export DYLD_LIBRARY_PATH
LIBRARY_PATH=${1}/lib:${4}:$LIBRARY_PATH
export LIBRARY_PATH
+ ADDON_PATH=${1}/lib:${4}:$ADDON_PATH
+ export ADDON_PATH
echo ${2}/shlibsign -v -i ${5}
${2}/shlibsign -v -i ${5}
;;
diff --git a/security/nss/cmd/signtool/util.c b/security/nss/cmd/signtool/util.c
index 32d4e8724..552fca599 100644
--- a/security/nss/cmd/signtool/util.c
+++ b/security/nss/cmd/signtool/util.c
@@ -823,6 +823,8 @@ InitCrypto(char *cert_dir, PRBool readOnly)
if (password) {
PK11_SetPasswordFunc(pk11_password_hardcode);
+ } else {
+ PK11_SetPasswordFunc(SECU_GetModulePassword);
}
/* Must login to FIPS before you do anything else */
diff --git a/security/nss/cmd/ssltap/ssltap.c b/security/nss/cmd/ssltap/ssltap.c
index 9352d063b..8c0b911ae 100644
--- a/security/nss/cmd/ssltap/ssltap.c
+++ b/security/nss/cmd/ssltap/ssltap.c
@@ -62,6 +62,8 @@
#include <time.h>
#include "plgetopt.h"
+#include "nss.h"
+#include "cert.h"
#define VERSIONSTRING "$Revision$ ($Date$) $Author$"
@@ -144,6 +146,8 @@ int looparound=0;
int fancy=0;
int isV2Session=0;
+#define PR_FPUTS(x) PR_fprintf(PR_STDOUT, x )
+
#define GET_SHORT(x) ((PRUint16)(((PRUint16)((PRUint8*)x)[0]) << 8) + ((PRUint16)((PRUint8*)x)[1]))
#define GET_24(x) ((PRUint32) ( \
(((PRUint32)((PRUint8*)x)[0]) << 16) \
@@ -405,10 +409,36 @@ const char * V2CipherString(int cs_int) {
case 0x00009A: cs_str = "TLS/DHE-RSA/SEED-CBC/SHA"; break;
case 0x00009B: cs_str = "TLS/DH-ANON/SEED-CBC/SHA"; break;
+ case 0x00C001: cs_str = "TLS/ECDH-ECDSA/NULL/SHA"; break;
+ case 0x00C002: cs_str = "TLS/ECDH-ECDSA/RC4-128/SHA"; break;
+ case 0x00C003: cs_str = "TLS/ECDH-ECDSA/3DES-EDE-CBC/SHA"; break;
+ case 0x00C004: cs_str = "TLS/ECDH-ECDSA/AES128-CBC/SHA"; break;
+ case 0x00C005: cs_str = "TLS/ECDH-ECDSA/AES256-CBC/SHA"; break;
+ case 0x00C006: cs_str = "TLS/ECDHE-ECDSA/NULL/SHA"; break;
+ case 0x00C007: cs_str = "TLS/ECDHE-ECDSA/RC4-128/SHA"; break;
+ case 0x00C008: cs_str = "TLS/ECDHE-ECDSA/3DES-EDE-CBC/SHA";break;
+ case 0x00C009: cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA"; break;
+ case 0x00C00A: cs_str = "TLS/ECDHE-ECDSA/AES256-CBC/SHA"; break;
+ case 0x00C00B: cs_str = "TLS/ECDH-RSA/NULL/SHA"; break;
+ case 0x00C00C: cs_str = "TLS/ECDH-RSA/RC4-128/SHA"; break;
+ case 0x00C00D: cs_str = "TLS/ECDH-RSA/3DES-EDE-CBC/SHA"; break;
+ case 0x00C00E: cs_str = "TLS/ECDH-RSA/AES128-CBC/SHA"; break;
+ case 0x00C00F: cs_str = "TLS/ECDH-RSA/AES256-CBC/SHA"; break;
+ case 0x00C010: cs_str = "TLS/ECDHE-RSA/NULL/SHA"; break;
+ case 0x00C011: cs_str = "TLS/ECDHE-RSA/RC4-128/SHA"; break;
+ case 0x00C012: cs_str = "TLS/ECDHE-RSA/3DES-EDE-CBC/SHA"; break;
+ case 0x00C013: cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA"; break;
+ case 0x00C014: cs_str = "TLS/ECDHE-RSA/AES256-CBC/SHA"; break;
+ case 0x00C015: cs_str = "TLS/ECDH-anon/NULL/SHA"; break;
+ case 0x00C016: cs_str = "TLS/ECDH-anon/RC4-128/SHA"; break;
+ case 0x00C017: cs_str = "TLS/ECDH-anon/3DES-EDE-CBC/SHA"; break;
+ case 0x00C018: cs_str = "TLS/ECDH-anon/AES128-CBC/SHA"; break;
+ case 0x00C019: cs_str = "TLS/ECDH-anon/AES256-CBC/SHA"; break;
+
case 0x00feff: cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA"; break;
case 0x00fefe: cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA"; break;
- case 0x00ffe1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
- case 0x00ffe0: cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA"; break;
+ case 0x00ffe1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
+ case 0x00ffe0: cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA";break;
/* the string literal is broken up to avoid trigraphs */
default: cs_str = "????" "/????????" "/?????????" "/???"; break;
@@ -417,6 +447,25 @@ const char * V2CipherString(int cs_int) {
return cs_str;
}
+const char * helloExtensionNameString(int ex_num) {
+ const char *ex_name = NULL;
+ static char buf[10];
+
+ switch (ex_num) {
+ case 0: ex_name = "server_name"; break;
+ case 1: ex_name = "max_fragment_length"; break;
+ case 2: ex_name = "client_certificate_url"; break;
+ case 3: ex_name = "trusted_ca_keys"; break;
+ case 4: ex_name = "truncated_hmac"; break;
+ case 5: ex_name = "status_request"; break;
+ case 10: ex_name = "elliptic_curves"; break;
+ case 11: ex_name = "ec_point_formats"; break;
+ default: sprintf(buf, "%d", ex_num); ex_name = (const char *)buf; break;
+ }
+
+ return ex_name;
+}
+
void partial_packet(int thispacket, int size, int needed)
{
PR_fprintf(PR_STDOUT,"(%u bytes", thispacket);
@@ -617,7 +666,37 @@ eosh:
-
+unsigned int print_hello_extension(unsigned char * hsdata,
+ unsigned int length,
+ unsigned int pos)
+{
+ /* pretty print extensions, if any */
+ if (pos < length) {
+ int exListLen = GET_SHORT((hsdata+pos)); pos += 2;
+ PR_fprintf(PR_STDOUT,
+ " extensions[%d] = {\n", exListLen);
+ while (exListLen > 0 && pos < length) {
+ int exLen;
+ int exType = GET_SHORT((hsdata+pos)); pos += 2;
+ exLen = GET_SHORT((hsdata+pos)); pos += 2;
+ /* dump the extension */
+ PR_fprintf(PR_STDOUT,
+ " extension type %s, length [%d]",
+ helloExtensionNameString(exType), exLen);
+ if (exLen > 0) {
+ PR_fprintf(PR_STDOUT, " = {\n");
+ print_hex(exLen, hsdata + pos);
+ PR_fprintf(PR_STDOUT, " }\n");
+ } else {
+ PR_fprintf(PR_STDOUT, "\n");
+ }
+ pos += exLen;
+ exListLen -= 2 + exLen;
+ }
+ PR_fprintf(PR_STDOUT," }\n");
+ }
+ return pos;
+}
void print_ssl3_handshake(unsigned char *tbuf,
@@ -639,82 +718,101 @@ void print_ssl3_handshake(unsigned char *tbuf,
PR_fprintf(PR_STDOUT," type = %d (",sslh.type);
switch(sslh.type) {
- case 0: PR_fprintf(PR_STDOUT,"hello_request)\n"); break;
- case 1: PR_fprintf(PR_STDOUT,"client_hello)\n"); break;
- case 2: PR_fprintf(PR_STDOUT,"server_hello)\n"); break;
- case 11: PR_fprintf(PR_STDOUT,"certificate)\n"); break;
- case 12: PR_fprintf(PR_STDOUT,"server_key_exchange)\n"); break;
- case 13: PR_fprintf(PR_STDOUT,"certificate_request)\n"); break;
- case 14: PR_fprintf(PR_STDOUT,"server_hello_done)\n"); break;
- case 15: PR_fprintf(PR_STDOUT,"certificate_verify)\n"); break;
- case 16: PR_fprintf(PR_STDOUT,"client_key_exchange)\n"); break;
- case 20: PR_fprintf(PR_STDOUT,"finished)\n"); break;
- default: PR_fprintf(PR_STDOUT,"unknown)\n");
+ case 0: PR_FPUTS("hello_request)\n" ); break;
+ case 1: PR_FPUTS("client_hello)\n" ); break;
+ case 2: PR_FPUTS("server_hello)\n" ); break;
+ case 11: PR_FPUTS("certificate)\n" ); break;
+ case 12: PR_FPUTS("server_key_exchange)\n" ); break;
+ case 13: PR_FPUTS("certificate_request)\n" ); break;
+ case 14: PR_FPUTS("server_hello_done)\n" ); break;
+ case 15: PR_FPUTS("certificate_verify)\n" ); break;
+ case 16: PR_FPUTS("client_key_exchange)\n" ); break;
+ case 20: PR_FPUTS("finished)\n" ); break;
+ default: PR_FPUTS("unknown)\n" ); break;
}
PR_fprintf(PR_STDOUT," length = %d (0x%06x)\n",sslh.length,sslh.length);
switch (sslh.type) {
+ case 0: /* hello_request */ /* not much to show here. */ break;
+
case 1: /* client hello */
switch (sr->ver_maj) {
- case 2: /* ssl version 2 */
- PR_fprintf(PR_STDOUT," ClientHelloV2 {...}\n");
- break;
case 3: /* ssl version 3 */
{
- int sidlength,pos,csuitelength,w;
+ unsigned int pos;
+ int w;
+
PR_fprintf(PR_STDOUT," ClientHelloV3 {\n");
PR_fprintf(PR_STDOUT," client_version = {%d, %d}\n",
(PRUint8)hsdata[0],(PRUint8)hsdata[1]);
PR_fprintf(PR_STDOUT," random = {...}\n");
if (sslhexparse) print_hex(32,&hsdata[2]);
- PR_fprintf(PR_STDOUT," session ID = {\n");
- sidlength = (int)hsdata[2+32];
- PR_fprintf(PR_STDOUT," length = %d\n",sidlength);
- PR_fprintf(PR_STDOUT," contents = {..}\n");
- if (sslhexparse) print_hex(sidlength,&hsdata[2+32+1]);
- PR_fprintf(PR_STDOUT," }\n");
- pos = 2+32+1+sidlength;
- csuitelength = GET_SHORT((hsdata+pos));
- PR_fprintf(PR_STDOUT," cipher_suites[%d] = { \n",
- csuitelength/2);
- if (csuitelength%1) {
- PR_fprintf(PR_STDOUT,
- "*error in protocol - csuitelength shouldn't be odd*\n");
+
+ /* pretty print Session ID */
+ {
+ int sidlength = (int)hsdata[2+32];
+ PR_fprintf(PR_STDOUT," session ID = {\n");
+ PR_fprintf(PR_STDOUT," length = %d\n",sidlength);
+ PR_fprintf(PR_STDOUT," contents = {..}\n");
+ if (sslhexparse) print_hex(sidlength,&hsdata[2+32+1]);
+ PR_fprintf(PR_STDOUT," }\n");
+ pos = 2+32+1+sidlength;
}
- for (w=0; w<csuitelength; w+=2) {
- const char *cs_str=NULL;
- PRUint32 cs_int=0;
- cs_int = GET_SHORT((hsdata+pos+2+w));
- cs_str = V2CipherString(cs_int);
+ /* pretty print cipher suites */
+ {
+ int csuitelength = GET_SHORT((hsdata+pos));
+ PR_fprintf(PR_STDOUT," cipher_suites[%d] = { \n",
+ csuitelength/2);
+ if (csuitelength % 2) {
+ PR_fprintf(PR_STDOUT,
+ "*error in protocol - csuitelength shouldn't be odd*\n");
+ }
+ for (w=0; w<csuitelength; w+=2) {
+ const char *cs_str=NULL;
+ PRUint32 cs_int=0;
+ cs_int = GET_SHORT((hsdata+pos+2+w));
+ cs_str = V2CipherString(cs_int);
+ PR_fprintf(PR_STDOUT,
+ " (0x%04x) %s\n", cs_int, cs_str);
+ }
+ pos += 2 + csuitelength;
+ PR_fprintf(PR_STDOUT," }\n");
+ }
- PR_fprintf(PR_STDOUT,
- " (0x%04x) %s\n", cs_int, cs_str);
+ /* pretty print compression methods */
+ {
+ int complength = hsdata[pos];
+ PR_fprintf(PR_STDOUT," compression[%d] = {",
+ complength);
+ for (w=0; w < complength; w++) {
+ PR_fprintf(PR_STDOUT, " %02x", hsdata[pos+1+w]);
+ }
+ pos += 1 + complength;
+ PR_fprintf(PR_STDOUT," }\n");
}
- /* for (w=0;w<csuitelength;w+=2) {
- PR_fprintf(PR_STDOUT,"0x%04x ",GET_SHORT((hsdata+pos+2+w)));
- } */
+ /* pretty print extensions, if any */
+ pos = print_hello_extension(hsdata, sslh.length, pos);
- PR_fprintf(PR_STDOUT,"\n }\n");
PR_fprintf(PR_STDOUT," }\n");
-
-
-
} /* end of ssl version 3 */
break;
default:
- PR_fprintf(PR_STDOUT," ClientHelloUndefinedVersion{}\n");
+ PR_fprintf(PR_STDOUT," UNDEFINED VERSION %d.%d {...}\n",
+ sr->ver_maj, sr->ver_min );
+ if (sslhexparse) print_hex(sslh.length, hsdata);
+ break;
} /* end of switch sr->ver_maj */
break;
case 2: /* server hello */
{
- int sidlength, pos;
- const char *cs_str=NULL;
- PRUint32 cs_int=0;
+ unsigned int sidlength, pos;
+
PR_fprintf(PR_STDOUT," ServerHello {\n");
+
PR_fprintf(PR_STDOUT," server_version = {%d, %d}\n",
(PRUint8)hsdata[0],(PRUint8)hsdata[1]);
PR_fprintf(PR_STDOUT," random = {...}\n");
@@ -726,16 +824,25 @@ void print_ssl3_handshake(unsigned char *tbuf,
if (sslhexparse) print_hex(sidlength,&hsdata[2+32+1]);
PR_fprintf(PR_STDOUT," }\n");
pos = 2+32+1+sidlength;
- cs_int = GET_SHORT((hsdata+pos));
- cs_str = V2CipherString(cs_int);
- PR_fprintf(PR_STDOUT," cipher_suite = (0x%04x) %s\n",
- cs_int, cs_str);
+
+ /* pretty print chosen cipher suite */
+ {
+ PRUint32 cs_int = GET_SHORT((hsdata+pos));
+ const char *cs_str = V2CipherString(cs_int);
+ PR_fprintf(PR_STDOUT," cipher_suite = (0x%04x) %s\n",
+ cs_int, cs_str);
+ pos += 2;
+ }
+ PR_fprintf(PR_STDOUT, " compression method = %02x\n",
+ hsdata[pos++]);
+
+ /* pretty print extensions, if any */
+ pos = print_hello_extension(hsdata, sslh.length, pos);
+
PR_fprintf(PR_STDOUT," }\n");
}
break;
-
-
case 11: /* certificate */
{
PRFileDesc *cfd;
@@ -782,14 +889,73 @@ void print_ssl3_handshake(unsigned char *tbuf,
}
break;
+ case 12: /* server_key_exchange */
+ if (sslhexparse) print_hex(sslh.length, hsdata);
+ break;
+
case 13: /* certificate request */
- if (sslhexparse) {
+ {
+ unsigned int pos = 0;
+ int w, reqLength;
+
PR_fprintf(PR_STDOUT," CertificateRequest {\n");
- print_hex(sslh.length, hsdata);
+
+ /* pretty print requested certificate types */
+ reqLength = hsdata[pos];
+ PR_fprintf(PR_STDOUT," certificate types[%d] = {",
+ reqLength);
+ for (w=0; w < reqLength; w++) {
+ PR_fprintf(PR_STDOUT, " %02x", hsdata[pos+1+w]);
+ }
+ pos += 1 + reqLength;
+ PR_fprintf(PR_STDOUT," }\n");
+
+ /* pretty print CA names, if any */
+ if (pos < sslh.length) {
+ int exListLen = GET_SHORT((hsdata+pos)); pos += 2;
+ PR_fprintf(PR_STDOUT,
+ " certificate_authorities[%d] = {\n",
+ exListLen);
+ while (exListLen > 0 && pos < sslh.length) {
+ char * ca_name;
+ SECItem it;
+ int dnLen = GET_SHORT((hsdata+pos)); pos += 2;
+
+ /* dump the CA name */
+ it.type = siBuffer;
+ it.data = hsdata + pos;
+ it.len = dnLen;
+ ca_name = CERT_DerNameToAscii(&it);
+ if (ca_name) {
+ PR_fprintf(PR_STDOUT," %s\n", ca_name);
+ PORT_Free(ca_name);
+ } else {
+ PR_fprintf(PR_STDOUT,
+ " distinguished name [%d]", dnLen);
+ if (dnLen > 0 && sslhexparse) {
+ PR_fprintf(PR_STDOUT, " = {\n");
+ print_hex(dnLen, hsdata + pos);
+ PR_fprintf(PR_STDOUT, " }\n");
+ } else {
+ PR_fprintf(PR_STDOUT, "\n");
+ }
+ }
+ pos += dnLen;
+ exListLen -= 2 + dnLen;
+ }
+ PR_fprintf(PR_STDOUT," }\n");
+ }
+
PR_fprintf(PR_STDOUT," }\n");
}
break;
+ case 14: /* server_hello_done */ /* not much to show here. */ break;
+
+ case 15: /* certificate_verify */
+ if (sslhexparse) print_hex(sslh.length, hsdata);
+ break;
+
case 16: /* client key exchange */
{
PR_fprintf(PR_STDOUT," ClientKeyExchange {\n");
@@ -798,6 +964,18 @@ void print_ssl3_handshake(unsigned char *tbuf,
}
break;
+ case 20: /* finished */
+ if (sslhexparse) print_hex(sslh.length, hsdata);
+ break;
+
+ default:
+ {
+ PR_fprintf(PR_STDOUT," UNKNOWN MESSAGE TYPE %d [%d] {\n",
+ sslh.type, sslh.length);
+ if (sslhexparse) print_hex(sslh.length, hsdata);
+ PR_fprintf(PR_STDOUT," }\n");
+
+ }
} /* end of switch sslh.type */
offset += sslh.length + 4; /* +4 because of length (3 bytes) and type (1 byte) */
} /* while */
@@ -1011,31 +1189,37 @@ void print_ssl(DataBufferList *s, int length, unsigned char *buffer)
}
switch(tbuf[1]) {
- case 0: PR_fprintf(PR_STDOUT, "close notify\n"); break;
- case 10: PR_fprintf(PR_STDOUT, "unexpected message\n"); break;
- case 20: PR_fprintf(PR_STDOUT, "bad record mac\n"); break;
- case 21: PR_fprintf(PR_STDOUT, "decryption failed\n"); break;
- case 22: PR_fprintf(PR_STDOUT, "record overflow\n"); break;
- case 30: PR_fprintf(PR_STDOUT, "decompression failure\n"); break;
- case 40: PR_fprintf(PR_STDOUT, "handshake failure\n"); break;
- case 41: PR_fprintf(PR_STDOUT, "no certificate\n"); break;
- case 42: PR_fprintf(PR_STDOUT, "bad certificate\n"); break;
- case 43: PR_fprintf(PR_STDOUT, "unsupported certificate\n"); break;
- case 44: PR_fprintf(PR_STDOUT, "certificate revoked\n"); break;
- case 45: PR_fprintf(PR_STDOUT, "certificate expired\n"); break;
- case 46: PR_fprintf(PR_STDOUT, "certificate unknown\n"); break;
- case 47: PR_fprintf(PR_STDOUT, "illegal parameter\n"); break;
- case 48: PR_fprintf(PR_STDOUT, "unknown CA\n"); break;
- case 49: PR_fprintf(PR_STDOUT, "access denied\n"); break;
- case 50: PR_fprintf(PR_STDOUT, "decode error\n"); break;
- case 51: PR_fprintf(PR_STDOUT, "decrypt error\n"); break;
- case 60: PR_fprintf(PR_STDOUT, "export restriction\n"); break;
- case 70: PR_fprintf(PR_STDOUT, "protocol version\n"); break;
- case 71: PR_fprintf(PR_STDOUT, "insufficient security\n"); break;
- case 80: PR_fprintf(PR_STDOUT, "internal error\n"); break;
- case 90: PR_fprintf(PR_STDOUT, "user canceled\n"); break;
- case 100: PR_fprintf(PR_STDOUT, "no renegotiation\n"); break;
- default: PR_fprintf(PR_STDOUT, "unknown error %d\n", tbuf[1]); break;
+ case 0: PR_FPUTS("close_notify\n" ); break;
+ case 10: PR_FPUTS("unexpected_message\n" ); break;
+ case 20: PR_FPUTS("bad_record_mac\n" ); break;
+ case 21: PR_FPUTS("decryption_failed\n" ); break;
+ case 22: PR_FPUTS("record_overflow\n" ); break;
+ case 30: PR_FPUTS("decompression_failure\n" ); break;
+ case 40: PR_FPUTS("handshake_failure\n" ); break;
+ case 41: PR_FPUTS("no_certificate\n" ); break;
+ case 42: PR_FPUTS("bad_certificate\n" ); break;
+ case 43: PR_FPUTS("unsupported_certificate\n" ); break;
+ case 44: PR_FPUTS("certificate_revoked\n" ); break;
+ case 45: PR_FPUTS("certificate_expired\n" ); break;
+ case 46: PR_FPUTS("certificate_unknown\n" ); break;
+ case 47: PR_FPUTS("illegal_parameter\n" ); break;
+ case 48: PR_FPUTS("unknown_ca\n" ); break;
+ case 49: PR_FPUTS("access_denied\n" ); break;
+ case 50: PR_FPUTS("decode_error\n" ); break;
+ case 51: PR_FPUTS("decrypt_error\n" ); break;
+ case 60: PR_FPUTS("export_restriction\n" ); break;
+ case 70: PR_FPUTS("protocol_version\n" ); break;
+ case 71: PR_FPUTS("insufficient_security\n" ); break;
+ case 80: PR_FPUTS("internal_error\n" ); break;
+ case 90: PR_FPUTS("user_canceled\n" ); break;
+ case 100: PR_FPUTS("no_renegotiation\n" ); break;
+ case 110: PR_FPUTS("unsupported_extension\n" ); break;
+ case 111: PR_FPUTS("certificate_unobtainable\n" ); break;
+ case 112: PR_FPUTS("unrecognized_name\n" ); break;
+ case 113: PR_FPUTS("bad_certificate_status_response\n" ); break;
+ case 114: PR_FPUTS("bad_certificate_hash_value\n" ); break;
+
+ default: PR_fprintf(PR_STDOUT, "unknown alert %d\n", tbuf[1]); break;
}
if (sslhexparse) print_hex(alloclen,tbuf);
@@ -1059,8 +1243,8 @@ void print_ssl(DataBufferList *s, int length, unsigned char *buffer)
void print_hex(int amt, unsigned char *buf) {
int i,j,k;
- char *string = (char*)PR_Malloc(5000);
char t[20];
+ static char string[5000];
for(i=0;i<amt;i++) {
@@ -1075,11 +1259,10 @@ void print_hex(int amt, unsigned char *buf) {
PR_fprintf(PR_STDOUT," ");
}
- t[0] = buf[i];
+ j = buf[i];
+
+ t[0] = (j >= 0x20 && j < 0x80) ? j : '.';
- if (!isprint(t[0])) {
- t[0] = '.';
- }
if (fancy) {
switch (t[0]) {
case '<':
@@ -1107,7 +1290,6 @@ void print_hex(int amt, unsigned char *buf) {
for (k=0;k<(16-j);k++) PR_fprintf(PR_STDOUT," ");
PR_fprintf(PR_STDOUT," |%s\n",string);
}
- PR_Free(string);
}
void Usage(void) {
@@ -1150,6 +1332,7 @@ int main(int argc, char *argv[])
int c_count=0;
PLOptState *optstate;
PLOptStatus status;
+ SECStatus rv;
optstate = PL_CreateOptState(argc,argv,"fvxhslp:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
@@ -1232,6 +1415,12 @@ int main(int argc, char *argv[])
exit(0);
}
+ rv = NSS_NoDB_Init("");
+ if (rv != SECSuccess) {
+ PR_fprintf(PR_STDERR,
+ "NSS_NoDB_Init() failed with error %d\n",PR_GetError());
+ exit(5);
+ }
s_rend = PR_NewTCPSocket();
if (!s_rend) {
@@ -1416,5 +1605,6 @@ int main(int argc, char *argv[])
get_time_string() );
} while (looparound); /* accept connection and process it. */
PR_Close(s_rend);
+ NSS_Shutdown();
return 0;
}
diff --git a/security/nss/cmd/strsclnt/strsclnt.c b/security/nss/cmd/strsclnt/strsclnt.c
index d0c91d551..d40d1dfe7 100644
--- a/security/nss/cmd/strsclnt/strsclnt.c
+++ b/security/nss/cmd/strsclnt/strsclnt.c
@@ -86,27 +86,6 @@ int ssl2CipherSuites[] = {
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
-#ifdef NSS_ENABLE_ECC
- /* NOTE: Since no new SSL2 ciphersuites are being
- * invented, and we've run out of lowercase letters
- * for SSL3 ciphers, we use letters G and beyond
- * for new SSL3 ciphers.
- */
- TLS_ECDH_ECDSA_WITH_NULL_SHA, /* G */
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* H */
- TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, /* I */
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* J */
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* K */
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* L */
- TLS_ECDH_RSA_WITH_NULL_SHA, /* M */
- TLS_ECDH_RSA_WITH_RC4_128_SHA, /* N */
- TLS_ECDH_RSA_WITH_DES_CBC_SHA, /* O */
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* P */
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* Q */
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* R */
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* S */
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* T */
-#endif /* NSS_ENABLE_ECC */
0
};
@@ -136,6 +115,7 @@ int ssl3CipherSuites[] = {
TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* w */
TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* x */
TLS_RSA_WITH_AES_256_CBC_SHA, /* y */
+ SSL_RSA_WITH_NULL_SHA, /* z */
0
};
@@ -147,7 +127,7 @@ int ssl3CipherSuites[] = {
static const char *cipherString;
-static int certsTested;
+static PRInt32 certsTested;
static int MakeCertOK;
static int NoReuse;
static int fullhs = NO_FULLHS_PERCENTAGE; /* percentage of full handshakes to
@@ -165,20 +145,25 @@ static PRLock * threadLock; /* protects the global variables below */
static PRTime lastConnectFailure;
static PRTime lastConnectSuccess;
static PRTime lastThrottleUp;
-static int remaining_connections; /* number of connections left */
+static PRInt32 remaining_connections; /* number of connections left */
static int active_threads = 8; /* number of threads currently trying to
** connect */
-static int numUsed;
+static PRInt32 numUsed;
/* end of variables protected by threadLock */
static SSL3Statistics * ssl3stats;
static int failed_already = 0;
+static PRBool disableSSL2 = PR_FALSE;
static PRBool disableSSL3 = PR_FALSE;
static PRBool disableTLS = PR_FALSE;
static PRBool bypassPKCS11 = PR_FALSE;
static PRBool disableLocking = PR_FALSE;
+static PRBool ignoreErrors = PR_FALSE;
+PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
+
+char * progName;
char * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg)
{
@@ -203,7 +188,7 @@ Usage(const char *progName)
{
fprintf(stderr,
"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
- " [-3BDNTovqs] [-2 filename] [-P fullhandshakespercentage | -N]\n"
+ " [-23BDNTovqs] [-f filename] [-N | -P percentage]\n"
" [-w dbpasswd] [-C cipher(s)] [-t threads] hostname\n"
" where -v means verbose\n"
" -o flag is interpreted as follows:\n"
@@ -214,6 +199,7 @@ Usage(const char *progName)
" -s means disable SSL socket locking\n"
" -N means no session reuse\n"
" -P means do a specified percentage of full handshakes (0-100)\n"
+ " -2 means disable SSL2\n"
" -3 means disable SSL3\n"
" -T means disable TLS\n"
" -U means enable throttling up threads\n"
@@ -293,7 +279,7 @@ mySSLAuthCertificate(void *arg, PRFileDesc *fd, PRBool checkSig,
/* invoke the "default" AuthCert handler. */
rv = SSL_AuthCertificate(arg, fd, checkSig, isServer);
- ++certsTested;
+ PR_AtomicIncrement(&certsTested);
if (rv == SECSuccess) {
fputs("strsclnt: -- SSL: Server Certificate Validated.\n", stderr);
}
@@ -403,7 +389,7 @@ void
thread_wrapper(void * arg)
{
perThread * slot = (perThread *)arg;
- PRBool die = PR_FALSE;
+ PRBool done = PR_FALSE;
do {
PRBool doop = PR_FALSE;
@@ -415,7 +401,7 @@ thread_wrapper(void * arg)
/* this thread isn't supposed to be running */
if (!ThrottleUp) {
/* we'll never need this thread again, so abort it */
- die = PR_TRUE;
+ done = PR_TRUE;
} else if (remaining_connections > 0) {
/* we may still need this thread, so just sleep for 1s */
dosleep = PR_TRUE;
@@ -438,14 +424,14 @@ thread_wrapper(void * arg)
}
} else {
/* no more connections left, we are done */
- die = PR_TRUE;
+ done = PR_TRUE;
}
} else {
/* this thread should run */
- if (--remaining_connections >= 0) {
+ if (--remaining_connections >= 0) { /* protected by threadLock */
doop = PR_TRUE;
} else {
- die = PR_TRUE;
+ done = PR_TRUE;
}
}
PR_Unlock(threadLock);
@@ -457,7 +443,7 @@ thread_wrapper(void * arg)
if (dosleep) {
PR_Sleep(PR_SecondsToInterval(1));
}
- } while (!die);
+ } while (!done && (!failed_already || ignoreErrors));
}
SECStatus
@@ -467,8 +453,8 @@ launch_thread(
void * b,
int tid)
{
+ PRUint32 i;
perThread * slot;
- int i;
PR_Lock(threadLock);
@@ -478,7 +464,8 @@ launch_thread(
return SECFailure;
}
- slot = &threads[numUsed++];
+ i = numUsed++;
+ slot = &threads[i];
slot->a = a;
slot->b = b;
slot->tid = tid;
@@ -506,7 +493,6 @@ launch_thread(
int
reap_threads(void)
{
- perThread * slot;
int i;
for (i = 0; i < MAX_THREADS; ++i) {
@@ -615,12 +601,13 @@ do_writes(
while (sent < bigBuf.len) {
- count = PR_Write(ssl_sock, bigBuf.data + sent, bigBuf.len - sent);
+ count = PR_Send(ssl_sock, bigBuf.data + sent, bigBuf.len - sent,
+ 0, maxInterval);
if (count < 0) {
- errWarn("PR_Write bigBuf");
+ errWarn("PR_Send bigBuf");
break;
}
- FPRINTF(stderr, "strsclnt: PR_Write wrote %d bytes from bigBuf\n",
+ FPRINTF(stderr, "strsclnt: PR_Send wrote %d bytes from bigBuf\n",
count );
sent += count;
}
@@ -659,9 +646,9 @@ handle_fdx_connection( PRFileDesc * ssl_sock, int connection)
/* do reads here. */
PRInt32 count;
- count = PR_Read(ssl_sock, buf, RD_BUF_SIZE);
+ count = PR_Recv(ssl_sock, buf, RD_BUF_SIZE, 0, maxInterval);
if (count < 0) {
- errWarn("PR_Read");
+ errWarn("PR_Recv");
break;
}
countRead += count;
@@ -706,9 +693,9 @@ handle_connection( PRFileDesc *ssl_sock, int tid)
/* compose the http request here. */
- rv = PR_Write(ssl_sock, request, strlen(request));
+ rv = PR_Send(ssl_sock, request, strlen(request), 0, maxInterval);
if (rv <= 0) {
- errWarn("PR_Write");
+ errWarn("PR_Send");
PR_Free(buf);
buf = 0;
failed_already = 1;
@@ -718,12 +705,13 @@ handle_connection( PRFileDesc *ssl_sock, int tid)
/* read until EOF */
while (1) {
- rv = PR_Read(ssl_sock, buf, RD_BUF_SIZE);
+ rv = PR_Recv(ssl_sock, buf, RD_BUF_SIZE, 0, maxInterval);
if (rv == 0) {
break; /* EOF */
}
if (rv < 0) {
- errWarn("PR_Read");
+ errWarn("PR_Recv");
+ failed_already = 1;
break;
}
@@ -780,9 +768,9 @@ do_connects(
retry:
- tcp_sock = PR_NewTCPSocket();
+ tcp_sock = PR_OpenTCPSocket(addr->raw.family);
if (tcp_sock == NULL) {
- errExit("PR_NewTCPSocket");
+ errExit("PR_OpenTCPSocket");
}
opt.option = PR_SockOpt_Nonblocking;
@@ -841,7 +829,7 @@ retry:
goto done;
} else {
if (ThrottleUp) {
- PRTime now;
+ PRTime now = PR_Now();
PR_Lock(threadLock);
lastConnectSuccess = PR_MAX(now, lastConnectSuccess);
PR_Unlock(threadLock);
@@ -910,32 +898,6 @@ done:
return SECSuccess;
}
-/* Returns IP address for hostname as PRUint32 in Host Byte Order.
-** Since the value returned is an integer (not a string of bytes),
-** it is inherently in Host Byte Order.
-*/
-PRUint32
-getIPAddress(const char * hostName)
-{
- const unsigned char *p;
- PRStatus prStatus;
- PRUint32 rv;
- PRHostEnt prHostEnt;
- char scratch[PR_NETDB_BUF_SIZE];
-
- prStatus = PR_GetHostByName(hostName, scratch, sizeof scratch, &prHostEnt);
- if (prStatus != PR_SUCCESS)
- errExit("PR_GetHostByName");
-
-#undef h_addr
-#define h_addr h_addr_list[0] /* address, for backward compatibility */
-
- p = (const unsigned char *)(prHostEnt.h_addr); /* in Network Byte order */
- FPRINTF(stderr, "strsclnt: %s -> %d.%d.%d.%d\n", hostName,
- p[0], p[1], p[2], p[3]);
- rv = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
- return rv;
-}
typedef struct {
PRLock* lock;
@@ -1108,6 +1070,19 @@ StressClient_GetClientAuthData(void * arg,
}
}
+int
+hexchar_to_int(int c)
+{
+ if (((c) >= '0') && ((c) <= '9'))
+ return (c) - '0';
+ if (((c) >= 'a') && ((c) <= 'f'))
+ return (c) - 'a' + 10;
+ if (((c) >= 'A') && ((c) <= 'F'))
+ return (c) - 'A' + 10;
+ failed_already = 1;
+ return -1;
+}
+
void
client_main(
unsigned short port,
@@ -1118,15 +1093,34 @@ client_main(
PRFileDesc *model_sock = NULL;
int i;
int rv;
- PRUint32 ipAddress; /* in host byte order */
+ PRStatus status;
PRNetAddr addr;
- /* Assemble NetAddr struct for connections. */
- ipAddress = getIPAddress(hostName);
-
- addr.inet.family = PR_AF_INET;
- addr.inet.port = PR_htons(port);
- addr.inet.ip = PR_htonl(ipAddress);
+ status = PR_StringToNetAddr(hostName, &addr);
+ if (status == PR_SUCCESS) {
+ addr.inet.port = PR_htons(port);
+ } else {
+ /* Lookup host */
+ PRAddrInfo *addrInfo;
+ void *enumPtr = NULL;
+
+ addrInfo = PR_GetAddrInfoByName(hostName, PR_AF_UNSPEC,
+ PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME);
+ if (!addrInfo) {
+ SECU_PrintError(progName, "error looking up host");
+ return;
+ }
+ do {
+ enumPtr = PR_EnumerateAddrInfo(enumPtr, addrInfo, port, &addr);
+ } while (enumPtr != NULL &&
+ addr.raw.family != PR_AF_INET &&
+ addr.raw.family != PR_AF_INET6);
+ PR_FreeAddrInfo(addrInfo);
+ if (enumPtr == NULL) {
+ SECU_PrintError(progName, "error looking up host address");
+ return;
+ }
+ }
/* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
NSS_SetDomesticPolicy();
@@ -1138,33 +1132,56 @@ client_main(
/* disable all the ciphers, then enable the ones we want. */
disableAllSSLCiphers();
- while (0 != (ndx = *cipherString++)) {
- int *cptr;
- int cipher;
-
- if (! isalpha(ndx))
- Usage("strsclnt");
- cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
- for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
- /* do nothing */;
- if (cipher > 0) {
- SECStatus rv;
- rv = SSL_CipherPrefSetDefault(cipher, PR_TRUE);
- if (rv != SECSuccess) {
- fprintf(stderr,
- "strsclnt: SSL_CipherPrefSetDefault failed with value 0x%04x\n",
- cipher);
- exit(1);
+ while (0 != (ndx = *cipherString)) {
+ const char * startCipher = cipherString++;
+ int cipher = 0;
+ SECStatus rv;
+
+ if (ndx == ':') {
+ cipher = hexchar_to_int(*cipherString++);
+ cipher <<= 4;
+ cipher |= hexchar_to_int(*cipherString++);
+ cipher <<= 4;
+ cipher |= hexchar_to_int(*cipherString++);
+ cipher <<= 4;
+ cipher |= hexchar_to_int(*cipherString++);
+ if (cipher <= 0) {
+ fprintf(stderr, "strsclnt: Invalid cipher value: %-5.5s\n",
+ startCipher);
+ failed_already = 1;
+ return;
}
- }
+ } else {
+ if (isalpha(ndx)) {
+ const int *cptr;
+
+ cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
+ /* do nothing */;
+ }
+ if (cipher <= 0) {
+ fprintf(stderr, "strsclnt: Invalid cipher letter: %c\n",
+ *startCipher);
+ failed_already = 1;
+ return;
+ }
+ }
+ rv = SSL_CipherPrefSetDefault(cipher, PR_TRUE);
+ if (rv != SECSuccess) {
+ fprintf(stderr,
+ "strsclnt: SSL_CipherPrefSetDefault(0x%04x) failed\n",
+ cipher);
+ failed_already = 1;
+ return;
+ }
}
}
/* configure model SSL socket. */
- model_sock = PR_NewTCPSocket();
+ model_sock = PR_OpenTCPSocket(addr.raw.family);
if (model_sock == NULL) {
- errExit("PR_NewTCPSocket on model socket");
+ errExit("PR_OpenTCPSocket for model socket");
}
model_sock = SSL_ImportFD(NULL, model_sock);
@@ -1179,6 +1196,12 @@ client_main(
errExit("SSL_OptionSet SSL_SECURITY");
}
+ /* disabling SSL2 compatible hellos also disables SSL2 */
+ rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);
+ if (rv != SECSuccess) {
+ errExit("error enabling SSLv2 compatible hellos ");
+ }
+
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL3, !disableSSL3);
if (rv != SECSuccess) {
errExit("error enabling SSLv3 ");
@@ -1302,7 +1325,6 @@ main(int argc, char **argv)
const char * fileName = NULL;
char * hostName = NULL;
char * nickName = NULL;
- char * progName = NULL;
char * tmp = NULL;
char * passwd = NULL;
int connections = 1;
@@ -1323,11 +1345,11 @@ main(int argc, char **argv)
progName = progName ? progName + 1 : tmp;
- optstate = PL_CreateOptState(argc, argv, "2:3BC:DNP:TUc:d:n:op:qst:vw:");
+ optstate = PL_CreateOptState(argc, argv, "23BC:DNP:TUc:d:f:in:op:qst:vw:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch(optstate->option) {
- case '2': fileName = optstate->value; break;
+ case '2': disableSSL2 = PR_TRUE; break;
case '3': disableSSL3 = PR_TRUE; break;
@@ -1349,6 +1371,10 @@ main(int argc, char **argv)
case 'd': dir = optstate->value; break;
+ case 'f': fileName = optstate->value; break;
+
+ case 'i': ignoreErrors = PR_TRUE; break;
+
case 'n': nickName = PL_strdup(optstate->value); break;
case 'o': MakeCertOK++; break;
@@ -1383,6 +1409,8 @@ main(int argc, char **argv)
}
}
+ PL_DestroyOptState(optstate);
+
if (!hostName || status == PL_OPT_BAD)
Usage(progName);
@@ -1402,6 +1430,14 @@ main(int argc, char **argv)
PK11_SetPasswordFunc(SECU_GetModulePassword);
}
+ tmp = PR_GetEnv("NSS_DEBUG_TIMEOUT");
+ if (tmp && tmp[0]) {
+ int sec = PORT_Atoi(tmp);
+ if (sec > 0) {
+ maxInterval = PR_SecondsToInterval(sec);
+ }
+ }
+
/* Call the libsec initialization routines */
rv = NSS_Initialize(dir, "", "", SECMOD_DB, NSS_INIT_READONLY);
if (rv != SECSuccess) {
@@ -1439,13 +1475,24 @@ main(int argc, char **argv)
if (Cert_And_Key.key) {
SECKEY_DestroyPrivateKey(Cert_And_Key.key);
}
+
PR_DestroyLock(Cert_And_Key.lock);
+ if (Cert_And_Key.password) {
+ PL_strfree(Cert_And_Key.password);
+ }
+ if (Cert_And_Key.nickname) {
+ PL_strfree(Cert_And_Key.nickname);
+ }
+
+ PL_strfree(hostName);
+
/* some final stats. */
if (ssl3stats->hsh_sid_cache_hits + ssl3stats->hsh_sid_cache_misses +
ssl3stats->hsh_sid_cache_not_ok == 0) {
/* presumably we were testing SSL2. */
- printf("strsclnt: %d server certificates tested.\n", certsTested);
+ printf("strsclnt: SSL2 - %d server certificates tested.\n",
+ certsTested);
} else {
printf(
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n",
@@ -1458,13 +1505,22 @@ main(int argc, char **argv)
exitVal = (ssl3stats->hsh_sid_cache_misses > 1) ||
(ssl3stats->hsh_sid_cache_not_ok != 0) ||
(certsTested > 1);
- else
- exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
+ else {
+ printf("strsclnt: NoReuse - %d server certificates tested.\n",
+ certsTested);
+ if (ssl3stats->hsh_sid_cache_hits + ssl3stats->hsh_sid_cache_misses +
+ ssl3stats->hsh_sid_cache_not_ok > 0) {
+ exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
(certsTested != connections);
+ } else { /* ssl2 connections */
+ exitVal = (certsTested != connections);
+ }
+ }
exitVal = ( exitVal || failed_already );
SSL_ClearSessionCache();
if (NSS_Shutdown() != SECSuccess) {
+ printf("strsclnt: NSS_Shutdown() failed.\n");
exit(1);
}
diff --git a/security/nss/cmd/tstclnt/Makefile b/security/nss/cmd/tstclnt/Makefile
index 7814da158..297114522 100644
--- a/security/nss/cmd/tstclnt/Makefile
+++ b/security/nss/cmd/tstclnt/Makefile
@@ -58,16 +58,6 @@ include $(CORE_DEPTH)/coreconf/config.mk
include ../platlibs.mk
-ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) # omits WINCE
-ifndef BUILD_OPT
-ifndef NS_USE_GCC
-LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
-endif
-OS_CFLAGS += -D_CONSOLE
-endif
-endif
-
-
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/cmd/tstclnt/tstclnt.c b/security/nss/cmd/tstclnt/tstclnt.c
index f4e337a48..5db624722 100644
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -20,6 +20,7 @@
*
* Contributor(s):
* Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -64,6 +65,7 @@
#include "sslproto.h"
#include "pk11func.h"
#include "plgetopt.h"
+#include "plstr.h"
#if defined(WIN32)
#include <fcntl.h>
@@ -76,6 +78,8 @@
#define MAX_WAIT_FOR_SERVER 600
#define WAIT_INTERVAL 100
+PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
+
int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
@@ -83,27 +87,6 @@ int ssl2CipherSuites[] = {
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
-#ifdef NSS_ENABLE_ECC
- /* NOTE: Since no new SSL2 ciphersuites are being
- * invented, and we've run out of lowercase letters
- * for SSL3 ciphers, we use letters G and beyond
- * for new SSL3 ciphers.
- */
- TLS_ECDH_ECDSA_WITH_NULL_SHA, /* G */
- TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* H */
- TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, /* I */
- TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* J */
- TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* K */
- TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* L */
- TLS_ECDH_RSA_WITH_NULL_SHA, /* M */
- TLS_ECDH_RSA_WITH_RC4_128_SHA, /* N */
- TLS_ECDH_RSA_WITH_DES_CBC_SHA, /* O */
- TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* P */
- TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* Q */
- TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* R */
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* S */
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* T */
-#endif /* NSS_ENABLE_ECC */
0
};
@@ -228,6 +211,7 @@ static void Usage(const char *progName)
fprintf(stderr, "%-20s Disable SSL v2.\n", "-2");
fprintf(stderr, "%-20s Disable SSL v3.\n", "-3");
fprintf(stderr, "%-20s Disable TLS (SSL v3.1).\n", "-T");
+ fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S");
fprintf(stderr, "%-20s Client speaks first. \n", "-f");
fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
@@ -243,22 +227,6 @@ static void Usage(const char *progName)
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
-#ifdef NSS_ENABLE_ECC
-"G TLS ECDH ECDSA WITH NULL SHA\n"
-"H TLS ECDH ECDSA WITH RC4 128 SHA\n"
-"I TLS ECDH ECDSA WITH DES CBC SHA\n"
-"J TLS ECDH ECDSA WITH 3DES EDE CBC SHA\n"
-"K TLS ECDH ECDSA WITH AES 128 CBC SHA\n"
-"L TLS ECDH ECDSA WITH AES 256 CBC SHA\n"
-"M TLS ECDH RSA WITH NULL SHA\n"
-"N TLS ECDH RSA WITH RC4 128 SHA\n"
-"O TLS ECDH RSA WITH DES CBC SHA\n"
-"P TLS ECDH RSA WITH 3DES EDE CBC SHA\n"
-"Q TLS ECDH RSA WITH AES 128 CBC SHA\n"
-"R TLS ECDH RSA WITH AES 256 CBC SHA\n"
-"S TLS ECDHE ECDSA WITH AES 128 CBC SHA\n"
-"T TLS ECDHE RSA WITH AES 128 CBC SHA\n"
-#endif /* NSS_ENABLE_ECC */
"\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
@@ -283,6 +251,8 @@ static void Usage(const char *progName)
"x SSL3 DHE RSA WITH AES 256 CBC SHA\n"
"y SSL3 RSA WITH AES 256 CBC SHA\n"
"z SSL3 RSA WITH NULL SHA\n"
+"\n"
+":WXYZ Use cipher with hex code { 0xWX , 0xYZ } in TLS\n"
);
exit(1);
}
@@ -408,7 +378,7 @@ thread_main(void * arg)
rc = PR_Read(std_in, buf, sizeof buf);
if (rc <= 0)
break;
- wc = PR_Write(ps, buf, rc);
+ wc = PR_Send(ps, buf, rc, 0, maxInterval);
} while (wc == rc);
PR_Close(ps);
}
@@ -429,9 +399,97 @@ printHostNameAndAddr(const char * host, const PRNetAddr * addr)
}
}
+/*
+ * Prints output according to skipProtoHeader flag. If skipProtoHeader
+ * is not set, prints without any changes, otherwise looking
+ * for \n\r\n(empty line sequence: HTTP header separator) and
+ * prints everything after it.
+ */
+static void
+separateReqHeader(const PRFileDesc* outFd, const char* buf, const int nb,
+ PRBool *wrStarted, int *ptrnMatched) {
+
+ /* it is sufficient to look for only "\n\r\n". Hopping that
+ * HTTP response format satisfies the standard */
+ char *ptrnStr = "\n\r\n";
+ char *resPtr;
+
+ if (nb == 0) {
+ return;
+ }
+
+ if (*ptrnMatched > 0) {
+ /* Get here only if previous separateReqHeader call found
+ * only a fragment of "\n\r\n" in previous buffer. */
+ PORT_Assert(*ptrnMatched < 3);
+
+ /* the size of fragment of "\n\r\n" what we want to find in this
+ * buffer is equal to *ptrnMatched */
+ if (*ptrnMatched <= nb) {
+ /* move the pointer to the beginning of the fragment */
+ int strSize = *ptrnMatched;
+ char *tmpPtrn = ptrnStr + (3 - strSize);
+ if (PL_strncmp(buf, tmpPtrn, strSize) == 0) {
+ /* print the rest of the buffer(without the fragment) */
+ PR_Write((void*)outFd, buf + strSize, nb - strSize);
+ *wrStarted = PR_TRUE;
+ return;
+ }
+ } else {
+ /* we are here only when nb == 1 && *ptrnMatched == 2 */
+ if (*buf == '\r') {
+ *ptrnMatched = 1;
+ } else {
+ *ptrnMatched = 0;
+ }
+ return;
+ }
+ }
+ resPtr = PL_strnstr(buf, ptrnStr, nb);
+ if (resPtr != NULL) {
+ /* if "\n\r\n" was found in the buffer, calculate offset
+ * and print the rest of the buffer */
+ int newBn = nb - (resPtr - buf + 3); /* 3 is the length of "\n\r\n" */
+
+ PR_Write((void*)outFd, resPtr + 3, newBn);
+ *wrStarted = PR_TRUE;
+ return;
+ } else {
+ /* try to find a fragment of "\n\r\n" at the end of the buffer.
+ * if found, set *ptrnMatched to the number of chars left to find
+ * in the next buffer.*/
+ int i;
+ for(i = 1 ;i < 3;i++) {
+ char *bufPrt;
+ int strSize = 3 - i;
+
+ if (strSize > nb) {
+ continue;
+ }
+ bufPrt = (char*)(buf + nb - strSize);
+
+ if (PL_strncmp(bufPrt, ptrnStr, strSize) == 0) {
+ *ptrnMatched = i;
+ return;
+ }
+ }
+ }
+}
+
#define SSOCK_FD 0
#define STDIN_FD 1
+#define HEXCHAR_TO_INT(c, i) \
+ if (((c) >= '0') && ((c) <= '9')) { \
+ i = (c) - '0'; \
+ } else if (((c) >= 'a') && ((c) <= 'f')) { \
+ i = (c) - 'a' + 10; \
+ } else if (((c) >= 'A') && ((c) <= 'F')) { \
+ i = (c) - 'A' + 10; \
+ } else { \
+ Usage(progName); \
+ }
+
int main(int argc, char **argv)
{
PRFileDesc * s;
@@ -442,6 +500,7 @@ int main(int argc, char **argv)
char * certDir = NULL;
char * nickname = NULL;
char * cipherString = NULL;
+ char * tmp;
int multiplier = 0;
SECStatus rv;
PRStatus status;
@@ -456,12 +515,15 @@ int main(int argc, char **argv)
int useExportPolicy = 0;
PRSocketOptionData opt;
PRNetAddr addr;
- PRHostEnt hp;
PRPollDesc pollset[2];
PRBool useCommandLinePassword = PR_FALSE;
PRBool pingServerFirst = PR_FALSE;
PRBool clientSpeaksFirst = PR_FALSE;
+ PRBool wrStarted = PR_FALSE;
+ PRBool skipProtoHeader = PR_FALSE;
+ int headerSeparatorPtrnId = 0;
int error = 0;
+ PRUint16 portno;
PLOptState *optstate;
PLOptStatus optstatus;
PRStatus prStatus;
@@ -471,7 +533,15 @@ int main(int argc, char **argv)
progName = strrchr(argv[0], '\\');
progName = progName ? progName+1 : argv[0];
- optstate = PL_CreateOptState(argc, argv, "23BTfc:h:p:d:m:n:oqsvw:x");
+ tmp = PR_GetEnv("NSS_DEBUG_TIMEOUT");
+ if (tmp && tmp[0]) {
+ int sec = PORT_Atoi(tmp);
+ if (sec > 0) {
+ maxInterval = PR_SecondsToInterval(sec);
+ }
+ }
+
+ optstate = PL_CreateOptState(argc, argv, "23BTSfc:h:p:d:m:n:oqsvw:x");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@@ -485,6 +555,8 @@ int main(int argc, char **argv)
case 'T': disableTLS = 1; break;
+ case 'S': skipProtoHeader = PR_TRUE; break;
+
case 'c': cipherString = strdup(optstate->value); break;
case 'h': host = strdup(optstate->value); break;
@@ -526,6 +598,7 @@ int main(int argc, char **argv)
Usage(progName);
if (!host || !port) Usage(progName);
+ portno = (PRUint16)atoi(port);
if (!certDir) {
certDir = SECU_DefaultSSLDir(); /* Look in $SSL_DIR */
@@ -568,37 +641,37 @@ int main(int argc, char **argv)
status = PR_StringToNetAddr(host, &addr);
if (status == PR_SUCCESS) {
- int portno = atoi(port);
- addr.inet.port = PR_htons((PRUint16)portno);
+ addr.inet.port = PR_htons(portno);
} else {
/* Lookup host */
- char buf[PR_NETDB_BUF_SIZE];
- status = PR_GetIPNodeByName(host, PR_AF_INET6, PR_AI_DEFAULT,
- buf, sizeof buf, &hp);
- if (status != PR_SUCCESS) {
+ PRAddrInfo *addrInfo;
+ void *enumPtr = NULL;
+
+ addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC,
+ PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME);
+ if (!addrInfo) {
SECU_PrintError(progName, "error looking up host");
return 1;
}
- if (PR_EnumerateHostEnt(0, &hp, (PRUint16)atoi(port), &addr) == -1) {
+ do {
+ enumPtr = PR_EnumerateAddrInfo(enumPtr, addrInfo, portno, &addr);
+ } while (enumPtr != NULL &&
+ addr.raw.family != PR_AF_INET &&
+ addr.raw.family != PR_AF_INET6);
+ PR_FreeAddrInfo(addrInfo);
+ if (enumPtr == NULL) {
SECU_PrintError(progName, "error looking up host address");
return 1;
}
}
- if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
- /* convert to IPv4. */
- addr.inet.family = PR_AF_INET;
- memcpy(&addr.inet.ip, &addr.ipv6.ip.pr_s6_addr[12], 4);
- memset(&addr.inet.pad[0], 0, sizeof addr.inet.pad);
- }
-
printHostNameAndAddr(host, &addr);
if (pingServerFirst) {
int iter = 0;
PRErrorCode err;
do {
- s = PR_NewTCPSocket();
+ s = PR_OpenTCPSocket(addr.raw.family);
if (s == NULL) {
SECU_PrintError(progName, "Failed to create a TCP socket");
}
@@ -636,7 +709,7 @@ int main(int argc, char **argv)
}
/* Create socket */
- s = PR_NewTCPSocket();
+ s = PR_OpenTCPSocket(addr.raw.family);
if (s == NULL) {
SECU_PrintError(progName, "error creating socket");
return 1;
@@ -670,19 +743,40 @@ int main(int argc, char **argv)
int ndx;
while (0 != (ndx = *cipherString++)) {
- int *cptr;
int cipher;
- if (! isalpha(ndx))
- Usage(progName);
- cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
- for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
- /* do nothing */;
+ if (ndx == ':') {
+ int ctmp;
+
+ cipher = 0;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 12);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 8);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 4);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= ctmp;
+ cipherString++;
+ } else {
+ const int *cptr;
+
+ if (! isalpha(ndx))
+ Usage(progName);
+ cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
+ /* do nothing */;
+ }
if (cipher > 0) {
SECStatus status;
status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);
if (status != SECSuccess)
SECU_PrintError(progName, "SSL_CipherPrefSet()");
+ } else {
+ Usage(progName);
}
}
}
@@ -788,7 +882,8 @@ int main(int argc, char **argv)
}
pollset[SSOCK_FD].fd = s;
- pollset[SSOCK_FD].in_flags = clientSpeaksFirst ? 0 : PR_POLL_READ;
+ pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT |
+ (clientSpeaksFirst ? 0 : PR_POLL_READ);
pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput);
pollset[STDIN_FD].in_flags = PR_POLL_READ;
npds = 2;
@@ -877,7 +972,7 @@ int main(int argc, char **argv)
FPRINTF(stderr, "%s: Writing %d bytes to server\n",
progName, nb);
do {
- PRInt32 cc = PR_Write(s, bufp, nb);
+ PRInt32 cc = PR_Send(s, bufp, nb, 0, maxInterval);
if (cc < 0) {
PRErrorCode err = PR_GetError();
if (err != PR_WOULD_BLOCK_ERROR) {
@@ -918,7 +1013,7 @@ int main(int argc, char **argv)
#endif
) {
/* Read from socket and write to stdout */
- nb = PR_Read(pollset[SSOCK_FD].fd, buf, sizeof(buf));
+ nb = PR_Recv(pollset[SSOCK_FD].fd, buf, sizeof buf, 0, maxInterval);
FPRINTF(stderr, "%s: Read from server %d bytes\n", progName, nb);
if (nb < 0) {
if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {
@@ -930,7 +1025,12 @@ int main(int argc, char **argv)
/* EOF from socket... stop polling socket for read */
pollset[SSOCK_FD].in_flags = 0;
} else {
- PR_Write(std_out, buf, nb);
+ if (skipProtoHeader != PR_TRUE || wrStarted == PR_TRUE) {
+ PR_Write(std_out, buf, nb);
+ } else {
+ separateReqHeader(std_out, buf, nb, &wrStarted,
+ &headerSeparatorPtrnId);
+ }
if (verbose)
fputs("\n\n", stderr);
}
diff --git a/security/nss/cmd/vfychain/Makefile b/security/nss/cmd/vfychain/Makefile
index 7cfeaac2a..297114522 100644
--- a/security/nss/cmd/vfychain/Makefile
+++ b/security/nss/cmd/vfychain/Makefile
@@ -58,14 +58,6 @@ include $(CORE_DEPTH)/coreconf/config.mk
include ../platlibs.mk
-ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) # omits WINCE
-ifndef BUILD_OPT
-LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
-OS_CFLAGS += -D_CONSOLE
-endif
-endif
-
-
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/cmd/vfyserv/Makefile b/security/nss/cmd/vfyserv/Makefile
index 7814da158..297114522 100644
--- a/security/nss/cmd/vfyserv/Makefile
+++ b/security/nss/cmd/vfyserv/Makefile
@@ -58,16 +58,6 @@ include $(CORE_DEPTH)/coreconf/config.mk
include ../platlibs.mk
-ifeq (,$(filter-out WINNT WIN95 WIN16,$(OS_TARGET))) # omits WINCE
-ifndef BUILD_OPT
-ifndef NS_USE_GCC
-LDFLAGS += /subsystem:console /profile /debug /machine:I386 /incremental:no
-endif
-OS_CFLAGS += -D_CONSOLE
-endif
-endif
-
-
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
#######################################################################
diff --git a/security/nss/cmd/vfyserv/vfyserv.c b/security/nss/cmd/vfyserv/vfyserv.c
index 4c31e4c70..257d04005 100644
--- a/security/nss/cmd/vfyserv/vfyserv.c
+++ b/security/nss/cmd/vfyserv/vfyserv.c
@@ -19,6 +19,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
+ * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -67,6 +68,7 @@
#include "prnetdb.h"
#include "nss.h"
#include "secutil.h"
+#include "ocsp.h"
#include "vfyserv.h"
@@ -80,13 +82,48 @@ char *certNickname = NULL;
char *hostName = NULL;
char *password = NULL;
unsigned short port = 0;
+PRBool dumpChain;
static void
Usage(const char *progName)
{
- fprintf(stderr,
- "Usage: %s [-p port] [-c connections] [-C cipher(s)] hostname\n",
- progName);
+ PRFileDesc *pr_stderr;
+
+ pr_stderr = PR_STDERR;
+
+ PR_fprintf(pr_stderr, "Usage:\n"
+ " %s [-c ] [-o] [-p port] [-d dbdir] [-w password]\n"
+ " \t\t[-C cipher(s)] [-l <url> -t <nickname> ] hostname",
+ progName);
+ PR_fprintf (pr_stderr, "\nWhere:\n");
+ PR_fprintf (pr_stderr,
+ " %-13s dump server cert chain into files\n",
+ "-c");
+ PR_fprintf (pr_stderr,
+ " %-13s perform server cert OCSP check\n",
+ "-o");
+ PR_fprintf (pr_stderr,
+ " %-13s server port to be used\n",
+ "-p");
+ PR_fprintf (pr_stderr,
+ " %-13s use security databases in \"dbdir\"\n",
+ "-d dbdir");
+ PR_fprintf (pr_stderr,
+ " %-13s key database password\n",
+ "-w password");
+ PR_fprintf (pr_stderr,
+ " %-13s communication cipher list\n",
+ "-C cipher(s)");
+ PR_fprintf (pr_stderr,
+ " %-13s OCSP responder location. This location is used to\n"
+ " %-13s check status of a server certificate. If not \n"
+ " %-13s specified, location will be taken from the AIA\n"
+ " %-13s server certificate extension.\n",
+ "-l url", "", "", "");
+ PR_fprintf (pr_stderr,
+ " %-13s OCSP Trusted Responder Cert nickname\n\n",
+ "-t nickname");
+
exit(1);
}
@@ -334,10 +371,10 @@ client_main(unsigned short port,
PRInt32 rv;
PRNetAddr addr;
PRHostEnt hostEntry;
- char buffer[256];
+ char buffer[PR_NETDB_BUF_SIZE];
/* Setup network connection. */
- prStatus = PR_GetHostByName(hostName, buffer, 256, &hostEntry);
+ prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry);
if (prStatus != PR_SUCCESS) {
exitErr("PR_GetHostByName");
}
@@ -368,6 +405,17 @@ client_main(unsigned short port,
destroy_thread_data(&threadMGR);
}
+#define HEXCHAR_TO_INT(c, i) \
+ if (((c) >= '0') && ((c) <= '9')) { \
+ i = (c) - '0'; \
+ } else if (((c) >= 'a') && ((c) <= 'f')) { \
+ i = (c) - 'a' + 10; \
+ } else if (((c) >= 'A') && ((c) <= 'F')) { \
+ i = (c) - 'A' + 10; \
+ } else { \
+ Usage(progName); \
+ }
+
int
main(int argc, char **argv)
{
@@ -375,9 +423,12 @@ main(int argc, char **argv)
char * progName = NULL;
int connections = 1;
char * cipherString = NULL;
+ char * respUrl = NULL;
+ char * respCertName = NULL;
SECStatus secStatus;
PLOptState * optstate;
PLOptStatus status;
+ PRBool doOcspCheck = PR_FALSE;
/* Call the NSPR initialization routines */
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
@@ -385,14 +436,17 @@ main(int argc, char **argv)
progName = PORT_Strdup(argv[0]);
hostName = NULL;
- optstate = PL_CreateOptState(argc, argv, "C:c:d:n:p:w:");
+ optstate = PL_CreateOptState(argc, argv, "C:cd:l:n:p:ot:w:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch(optstate->option) {
case 'C' : cipherString = PL_strdup(optstate->value); break;
- case 'c' : connections = PORT_Atoi(optstate->value); break;
+ case 'c' : dumpChain = PR_TRUE; break;
case 'd' : certDir = PL_strdup(optstate->value); break;
+ case 'l' : respUrl = PL_strdup(optstate->value); break;
case 'p' : port = PORT_Atoi(optstate->value); break;
- case 'w' : password = PL_strdup(optstate->value); break;
+ case 'o' : doOcspCheck = PR_TRUE; break;
+ case 't' : respCertName = PL_strdup(optstate->value); break;
+ case 'w' : password = PL_strdup(optstate->value); break;
case '\0': hostName = PL_strdup(optstate->value); break;
default : Usage(progName);
}
@@ -405,6 +459,14 @@ main(int argc, char **argv)
if (port == 0 || hostName == NULL)
Usage(progName);
+ if (doOcspCheck &&
+ ((respCertName != NULL && respUrl == NULL) ||
+ (respUrl != NULL && respCertName == NULL))) {
+ SECU_PrintError (progName, "options -l <url> and -t "
+ "<responder> must be used together");
+ Usage(progName);
+ }
+
/* Set our password function callback. */
PK11_SetPasswordFunc(myPasswd);
@@ -423,6 +485,38 @@ main(int argc, char **argv)
}
SECU_RegisterDynamicOids();
+ if (doOcspCheck == PR_TRUE) {
+ SECStatus rv;
+ CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
+ if (handle == NULL) {
+ SECU_PrintError (progName, "problem getting certdb handle");
+ goto cleanup;
+ }
+
+ rv = CERT_EnableOCSPChecking (handle);
+ if (rv != SECSuccess) {
+ SECU_PrintError (progName, "error enabling OCSP checking");
+ goto cleanup;
+ }
+
+ if (respUrl != NULL) {
+ rv = CERT_SetOCSPDefaultResponder (handle, respUrl,
+ respCertName);
+ if (rv != SECSuccess) {
+ SECU_PrintError (progName,
+ "error setting default responder");
+ goto cleanup;
+ }
+
+ rv = CERT_EnableOCSPDefaultResponder (handle);
+ if (rv != SECSuccess) {
+ SECU_PrintError (progName,
+ "error enabling default responder");
+ goto cleanup;
+ }
+ }
+ }
+
/* All cipher suites except RSA_NULL_MD5 are enabled by
* Domestic Policy. */
NSS_SetDomesticPolicy();
@@ -436,22 +530,49 @@ main(int argc, char **argv)
disableAllSSLCiphers();
while (0 != (ndx = *cipherString++)) {
- int *cptr;
int cipher;
- if (! isalpha(ndx))
- Usage(progName);
- cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
- for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
- /* do nothing */;
+ if (ndx == ':') {
+ int ctmp;
+
+ cipher = 0;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 12);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 8);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= (ctmp << 4);
+ cipherString++;
+ HEXCHAR_TO_INT(*cipherString, ctmp)
+ cipher |= ctmp;
+ cipherString++;
+ } else {
+ const int *cptr;
+ if (! isalpha(ndx))
+ Usage(progName);
+ cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
+ for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
+ /* do nothing */;
+ }
if (cipher > 0) {
SSL_CipherPrefSetDefault(cipher, PR_TRUE);
+ } else {
+ Usage(progName);
}
}
}
client_main(port, connections, hostName);
+cleanup:
+ if (doOcspCheck) {
+ CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
+ CERT_DisableOCSPDefaultResponder(handle);
+ CERT_DisableOCSPChecking (handle);
+ }
+
if (NSS_Shutdown() != SECSuccess) {
exit(1);
}
diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c
index 4741a22ad..9db64c01f 100644
--- a/security/nss/cmd/vfyserv/vfyutil.c
+++ b/security/nss/cmd/vfyserv/vfyutil.c
@@ -40,6 +40,10 @@
#include "nspr.h"
#include "secutil.h"
+
+extern PRBool dumpChain;
+extern void dumpCertChain(CERTCertificate *, SECCertUsage);
+
/* Declare SSL cipher suites. */
int ssl2CipherSuites[] = {
@@ -136,6 +140,10 @@ myAuthCertificate(void *arg, PRFileDesc *socket,
cert = SSL_PeerCertificate(socket);
pinArg = SSL_RevealPinArg(socket);
+
+ if (dumpChain == PR_TRUE) {
+ dumpCertChain(cert, certUsage);
+ }
secStatus = CERT_VerifyCertificateNow((CERTCertDBHandle *)arg,
cert,
@@ -291,10 +299,10 @@ myGetClientAuthData(void *arg,
break;
}
secStatus = SECFailure;
- break;
}
- CERT_FreeNicknames(names);
+ CERT_DestroyCertificate(cert);
} /* for loop */
+ CERT_FreeNicknames(names);
}
}
@@ -616,3 +624,43 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
return rv;
}
+
+/*
+ * Dump cert chain in to cert.* files. This function is will
+ * create collisions while dumping cert chains if called from
+ * multiple treads. But it should not be a problem since we
+ * consider vfyserv to be single threaded(see bug 353477).
+ */
+
+void
+dumpCertChain(CERTCertificate *cert, SECCertUsage usage)
+{
+ CERTCertificateList *certList;
+ int count = 0;
+
+ certList = CERT_CertChainFromCert(cert, usage, PR_TRUE);
+ if (certList == NULL) {
+ errWarn("CERT_CertChainFromCert");
+ return;
+ }
+
+ for(count = 0; count < (unsigned int)certList->len; count++) {
+ char certFileName[16];
+ PRFileDesc *cfd;
+
+ PR_snprintf(certFileName, sizeof certFileName, "cert.%03d",
+ count);
+ cfd = PR_Open(certFileName, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE,
+ 0664);
+ if (!cfd) {
+ PR_fprintf(PR_STDOUT,
+ "Error: couldn't save cert der in file '%s'\n",
+ certFileName);
+ } else {
+ PR_Write(cfd, certList->certs[count].data, certList->certs[count].len);
+ PR_Close(cfd);
+ PR_fprintf(PR_STDOUT, "Cert file %s was created.\n", certFileName);
+ }
+ }
+ CERT_DestroyCertificateList(certList);
+}
diff --git a/security/nss/cmd/zlib/zutil.h b/security/nss/cmd/zlib/zutil.h
index b7d5eff81..fe7a9a7c1 100644
--- a/security/nss/cmd/zlib/zutil.h
+++ b/security/nss/cmd/zlib/zutil.h
@@ -175,7 +175,8 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
/* functions */
-#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) || \
+ (defined(_MSC_VER) && _MSC_VER >= 1500)
# ifndef HAVE_VSNPRINTF
# define HAVE_VSNPRINTF
# endif