diff options
Diffstat (limited to 'security')
300 files changed, 26887 insertions, 13931 deletions
diff --git a/security/coreconf/Darwin.mk b/security/coreconf/Darwin.mk index 83f568bf3..fcb0a9ccb 100644 --- a/security/coreconf/Darwin.mk +++ b/security/coreconf/Darwin.mk @@ -43,12 +43,16 @@ CC = cc CCC = c++ RANLIB = ranlib -ifeq (86,$(findstring 86,$(OS_TEST))) +ifndef CPU_ARCH +# When cross-compiling, CPU_ARCH should already be defined as the target +# architecture, set to powerpc or i386. +CPU_ARCH := $(shell uname -p) +endif + +ifeq (,$(filter-out i%86,$(CPU_ARCH))) OS_REL_CFLAGS = -Di386 -CPU_ARCH = i386 else OS_REL_CFLAGS = -Dppc -CPU_ARCH = ppc endif ifneq (,$(MACOS_SDK_DIR)) @@ -65,7 +69,7 @@ ifneq (,$(MACOS_SDK_DIR)) endif DARWIN_SDK_CFLAGS = -nostdinc -isystem $(MACOS_SDK_DIR)/usr/include/gcc/darwin/$(GCC_VERSION) -isystem $(MACOS_SDK_DIR)/usr/include $(DARWIN_SDK_FRAMEWORKS) DARWIN_SDK_LDFLAGS = -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin/$(GCC_VERSION_FULL) -L$(MACOS_SDK_DIR)/usr/lib - DARWIN_SDK_DSOFLAGS = $(DARWIN_SDK_LDFLAGS) $(DARWIN_SDK_FRAMEWORKS) + DARWIN_SDK_SHLIBFLAGS = $(DARWIN_SDK_LDFLAGS) $(DARWIN_SDK_FRAMEWORKS) NEXT_ROOT = $(MACOS_SDK_DIR) export NEXT_ROOT else @@ -75,12 +79,12 @@ ifneq (,$(MACOS_SDK_DIR)) # gcc > 4.0.0 passes -syslibroot to ld based on -isysroot. # Don't add -isysroot to DARWIN_SDK_LDFLAGS, because the programs # that are linked with those flags also get DARWIN_SDK_CFLAGS. - DARWIN_SDK_DSOFLAGS = -isysroot $(MACOS_SDK_DIR) + DARWIN_SDK_SHLIBFLAGS = -isysroot $(MACOS_SDK_DIR) else # gcc 4.0.0 doesn't pass -syslibroot to ld, it needs to be # explicit. DARWIN_SDK_LDFLAGS = -Wl,-syslibroot,$(MACOS_SDK_DIR) - DARWIN_SDK_DSOFLAGS = $(DARWIN_SDK_LDFLAGS) + DARWIN_SDK_SHLIBFLAGS = $(DARWIN_SDK_LDFLAGS) endif endif @@ -107,9 +111,9 @@ ARCH = darwin DSO_CFLAGS = -fPIC # May override this with -bundle to create a loadable module. -DSO_LDOPTS = -dynamiclib -compatibility_version 1 -current_version 1 -install_name @executable_path/$(notdir $@) -headerpad_max_install_names $(DARWIN_SDK_DSOFLAGS) +DSO_LDOPTS = -dynamiclib -compatibility_version 1 -current_version 1 -install_name @executable_path/$(notdir $@) -headerpad_max_install_names -MKSHLIB = $(CC) -arch $(CPU_ARCH) $(DSO_LDOPTS) +MKSHLIB = $(CC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS) DLL_SUFFIX = dylib PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,_,' > $@ diff --git a/security/coreconf/FreeBSD.mk b/security/coreconf/FreeBSD.mk index a18739962..e0ac591dc 100644 --- a/security/coreconf/FreeBSD.mk +++ b/security/coreconf/FreeBSD.mk @@ -75,10 +75,10 @@ endif MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE -# Add LD options to restrict exported symbols to those in the map file + MKSHLIB += -Wl,--version-script,$(MAPFILE) endif -# Change PROCESS to put the mapfile in the correct format for this platform -PROCESS_MAP_FILE = cp $< $@ +PROCESS_MAP_FILE = grep -v ';-' $< | \ + sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ G++INCLUDES = -I/usr/include/g++ diff --git a/security/coreconf/Linux.mk b/security/coreconf/Linux.mk index 3a7b25fe8..d87c4ce82 100644 --- a/security/coreconf/Linux.mk +++ b/security/coreconf/Linux.mk @@ -165,7 +165,7 @@ endif ARCH = linux DSO_CFLAGS = -fPIC -DSO_LDOPTS = -shared $(ARCHFLAG) -z defs +DSO_LDOPTS = -shared $(ARCHFLAG) DSO_LDFLAGS = LDFLAGS += $(ARCHFLAG) diff --git a/security/coreconf/Linux2.6.mk b/security/coreconf/Linux2.6.mk index 86bffef75..d51f5a952 100644 --- a/security/coreconf/Linux2.6.mk +++ b/security/coreconf/Linux2.6.mk @@ -37,6 +37,8 @@ include $(CORE_DEPTH)/coreconf/Linux.mk +DSO_LDOPTS += -Wl,-z,defs + OS_REL_CFLAGS += -DLINUX2_1 MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) diff --git a/security/coreconf/OS2.mk b/security/coreconf/OS2.mk index 575fd8b55..507ebd1ae 100644 --- a/security/coreconf/OS2.mk +++ b/security/coreconf/OS2.mk @@ -78,7 +78,11 @@ FILTER = emxexp -o # GCC for OS/2 currently predefines these, but we don't want them DEFINES += -Uunix -U__unix -U__unix__ -DEFINES += -DTCPV40HDRS +DEFINES += -DXP_OS2_EMX -DTCPV40HDRS + +ifeq ($(MOZ_OS2_HIGH_MEMORY),1) +HIGHMEM_LDFLAG = -Zhigh-mem +endif ifndef NO_SHARED_LIB WRAP_MALLOC_LIB = @@ -89,7 +93,7 @@ MKSHLIB = $(CXX) $(CXXFLAGS) $(DSO_LDOPTS) -o $@ MKCSHLIB = $(CC) $(CFLAGS) $(DSO_LDOPTS) -o $@ MKSHLIB_FORCE_ALL = MKSHLIB_UNFORCE_ALL = -DSO_LDOPTS = -Zomf -Zdll -Zmap +DSO_LDOPTS = -Zomf -Zdll -Zmap $(HIGHMEM_LDFLAG) SHLIB_LDSTARTFILE = SHLIB_LDENDFILE = ifdef MAPFILE @@ -112,16 +116,16 @@ OS_CFLAGS = -Wall -W -Wno-unused -Wpointer-arith -Wcast-align -Zomf -DD ifdef BUILD_OPT OPTIMIZER = -O2 -s DEFINES += -UDEBUG -U_DEBUG -DNDEBUG -DLLFLAGS = -DLL -OUT:$@ -MAP:$(@:.dll=.map) -EXEFLAGS = -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE +DLLFLAGS = -DLL -OUT:$@ -MAP:$(@:.dll=.map) $(HIGHMEM_LDFLAG) +EXEFLAGS = -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE $(HIGHMEM_LDFLAG) OBJDIR_TAG = _OPT else #OPTIMIZER = -O+ -Oi DEFINES += -DDEBUG -D_DEBUG -DDEBUGPRINTS #HCT Need += to avoid overidding manifest.mn -DLLFLAGS = -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map) -EXEFLAGS = -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE +DLLFLAGS = -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map) $(HIGHMEM_LDFLAG) +EXEFLAGS = -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE $(HIGHMEM_LDFLAG) OBJDIR_TAG = _DBG -LDFLAGS = -DEBUG +LDFLAGS = -DEBUG $(HIGHMEM_LDFLAG) endif # BUILD_OPT else # XP_OS2_VACPP @@ -240,8 +244,6 @@ else endif endif -DEFINES += -DXP_OS2 - define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi endef diff --git a/security/coreconf/SunOS5.11.mk b/security/coreconf/SunOS5.11.mk new file mode 100644 index 000000000..5bcf4e897 --- /dev/null +++ b/security/coreconf/SunOS5.11.mk @@ -0,0 +1,46 @@ +# +# ***** 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 ***** + +SOL_CFLAGS += -D_SVID_GETTOD + +include $(CORE_DEPTH)/coreconf/SunOS5.mk + +ifeq ($(OS_RELEASE),5.11) + OS_DEFINES += -DSOLARIS2_11 +endif + +OS_LIBS += -lthread -lnsl -lsocket -lposix4 -ldl -lc diff --git a/security/coreconf/SunOS5.11_i86pc.mk b/security/coreconf/SunOS5.11_i86pc.mk new file mode 100644 index 000000000..1237f90aa --- /dev/null +++ b/security/coreconf/SunOS5.11_i86pc.mk @@ -0,0 +1,53 @@ +# +# ***** 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 ***** + +SOL_CFLAGS = -D_SVID_GETTOD + +include $(CORE_DEPTH)/coreconf/SunOS5.mk + +ifeq ($(USE_64),1) + CPU_ARCH = x86_64 +else + CPU_ARCH = x86 + OS_DEFINES += -Di386 +endif + +ifeq ($(OS_RELEASE),5.11_i86pc) + OS_DEFINES += -DSOLARIS2_11 +endif + +OS_LIBS += -lthread -lnsl -lsocket -lposix4 -ldl -lc diff --git a/security/coreconf/WIN32.mk b/security/coreconf/WIN32.mk index 423105414..9320c10e2 100644 --- a/security/coreconf/WIN32.mk +++ b/security/coreconf/WIN32.mk @@ -61,6 +61,7 @@ else RANLIB = echo BSDECHO = echo RC = rc.exe + MT = mt.exe endif ifdef BUILD_TREE @@ -89,7 +90,10 @@ endif DLL_SUFFIX = dll ifdef NS_USE_GCC - OS_CFLAGS += -mno-cygwin -mms-bitfields + # The -mnop-fun-dllimport flag allows us to avoid a drawback of + # the dllimport attribute that a pointer to a function marked as + # dllimport cannot be used as as a constant address. + OS_CFLAGS += -mno-cygwin -mms-bitfields -mnop-fun-dllimport _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY) DLLFLAGS += -mno-cygwin -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB)) ifdef BUILD_OPT @@ -126,6 +130,7 @@ else # !NS_USE_GCC endif ifneq (,$(MOZ_PROFILE)$(MOZ_DEBUG_SYMBOLS)) DLLFLAGS += -DEBUG -OPT:REF + LDFLAGS += -DEBUG -OPT:REF endif else # @@ -145,9 +150,14 @@ else # !NS_USE_GCC USERNAME := $(subst -,_,$(USERNAME)) DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME) DLLFLAGS += -DEBUG -OUT:"$@" + LDFLAGS += -DEBUG +ifndef MOZ_DEBUG_SYMBOLS + LDFLAGS += -PDB:NONE +endif # Purify requires /FIXED:NO when linking EXEs. - LDFLAGS += -DEBUG -PDB:NONE /FIXED:NO + LDFLAGS += /FIXED:NO endif +# DEFINES += -D_CRT_SECURE_NO_WARNINGS endif # NS_USE_GCC DEFINES += -DWIN32 diff --git a/security/coreconf/config.mk b/security/coreconf/config.mk index dbbfd759b..248acb68e 100644 --- a/security/coreconf/config.mk +++ b/security/coreconf/config.mk @@ -170,3 +170,14 @@ endif -include $(MKDEPENDENCIES) +####################################################################### +# [16.0] Global environ ment defines +####################################################################### + +ifdef NSS_ENABLE_ECC +DEFINES += -DNSS_ENABLE_ECC +endif + +ifdef NSS_ECC_MORE_THAN_SUITE_B +DEFINES += -DNSS_ECC_MORE_THAN_SUITE_B +endif diff --git a/security/coreconf/jdk.mk b/security/coreconf/jdk.mk index 2bc7336e1..98bc188ae 100644 --- a/security/coreconf/jdk.mk +++ b/security/coreconf/jdk.mk @@ -184,6 +184,31 @@ ifeq ($(OS_ARCH), Linux) JDK_JIT_OPT = endif +# set [Mac OS X] platforms +ifeq ($(OS_ARCH), Darwin) + JAVA_CLASSES = $(JAVA_HOME)/../Classes/classes.jar + + ifeq ($(JRE_HOME),) + JRE_HOME = $(JAVA_HOME) + JRE_CLASSES = $(JAVA_CLASSES) + else + ifeq ($(JRE_CLASSES),) + JRE_CLASSES = $(JRE_HOME)/../Classes/classes.jar + endif + endif + + PATH_SEPARATOR = : + + # (2) specify "header" information + JAVA_ARCH = darwin + + INCLUDES += -I$(JAVA_HOME)/include + INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) + + # no JIT option available on this platform + JDK_JIT_OPT = +endif + # set [IBM AIX] platforms ifeq ($(OS_ARCH), AIX) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar diff --git a/security/coreconf/location.mk b/security/coreconf/location.mk index 2b3be6451..11c02f712 100644 --- a/security/coreconf/location.mk +++ b/security/coreconf/location.mk @@ -75,4 +75,12 @@ ifndef NSPR_LIB_DIR NSPR_LIB_DIR = $(DIST)/lib endif +ifdef NSS_INCLUDE_DIR + INCLUDES += -I$(NSS_INCLUDE_DIR) +endif + +ifndef NSS_LIB_DIR + NSS_LIB_DIR = $(DIST)/lib +endif + MK_LOCATION = included diff --git a/security/coreconf/rules.mk b/security/coreconf/rules.mk index 0d0aaee1a..212e13262 100644 --- a/security/coreconf/rules.mk +++ b/security/coreconf/rules.mk @@ -114,12 +114,22 @@ ifdef LIBRARY endif ifdef SHARED_LIBRARY $(INSTALL) -m 775 $(SHARED_LIBRARY) $(SOURCE_LIB_DIR) +ifdef MOZ_DEBUG_SYMBOLS +ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) + $(INSTALL) -m 644 $(SHARED_LIBRARY:$(DLL_SUFFIX)=pdb) $(SOURCE_LIB_DIR) +endif +endif endif ifdef IMPORT_LIBRARY $(INSTALL) -m 775 $(IMPORT_LIBRARY) $(SOURCE_LIB_DIR) endif ifdef PROGRAM $(INSTALL) -m 775 $(PROGRAM) $(SOURCE_BIN_DIR) +ifdef MOZ_DEBUG_SYMBOLS +ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) + $(INSTALL) -m 644 $(PROGRAM:$(PROG_SUFFIX)=.pdb) $(SOURCE_BIN_DIR) +endif +endif endif ifdef PROGRAMS $(INSTALL) -m 775 $(PROGRAMS) $(SOURCE_BIN_DIR) @@ -275,6 +285,12 @@ $(PROGRAM): $(OBJS) $(EXTRA_LIBS) @$(MAKE_OBJDIR) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $(subst /,\\,$(OBJS)) -Fe$@ -link $(LDFLAGS) $(subst /,\\,$(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool else ifdef XP_OS2_VACPP $(MKPROG) -Fe$@ $(CFLAGS) $(OBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) @@ -329,6 +345,12 @@ ifdef NS_USE_GCC $(LINK_DLL) $(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES) else $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES)) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool endif else ifdef XP_OS2_VACPP @@ -367,6 +389,12 @@ $(OBJDIR)/$(PROG_PREFIX)%$(PROG_SUFFIX): $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $< -Fe$@ -link \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) +ifdef MT + if test -f $@.manifest; then \ + $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ + rm -f $@.manifest; \ + fi +endif # MSVC with manifest tool else $(MKPROG) -o $@ $(CFLAGS) $< \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) @@ -380,10 +408,12 @@ WCCFLAGS3 := $(subst -D,-d,$(WCCFLAGS2)) # debuggers under Windows & OS/2 to find source files automatically ifeq (,$(filter-out OS2 AIX,$(OS_TARGET))) +# OS/2 and AIX NEED_ABSOLUTE_PATH := 1 PWD := $(shell pwd) -endif +else +# Windows ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) NEED_ABSOLUTE_PATH := 1 PWD := $(shell pwd) @@ -392,21 +422,22 @@ ifndef USE_MSYS PWD := $(subst \,/,$(shell cygpath -w $(PWD))) endif endif -endif -ifdef NEED_ABSOLUTE_PATH -abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1))) else -abspath = $(1) +# everything else +PWD := $(shell pwd) +endif endif +core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1))) + $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c @$(MAKE_OBJDIR) ifdef USE_NT_C_SYNTAX - $(CC) -Fo$@ -c $(CFLAGS) $(call abspath,$<) + $(CC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH - $(CC) -o $@ -c $(CFLAGS) $(call abspath,$<) + $(CC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CC) -o $@ -c $(CFLAGS) $< endif @@ -414,10 +445,10 @@ endif $(PROG_PREFIX)%$(OBJ_SUFFIX): %.c ifdef USE_NT_C_SYNTAX - $(CC) -Fo$@ -c $(CFLAGS) $(call abspath,$<) + $(CC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH - $(CC) -o $@ -c $(CFLAGS) $(call abspath,$<) + $(CC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CC) -o $@ -c $(CFLAGS) $< endif @@ -446,10 +477,10 @@ $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S $(OBJDIR)/$(PROG_PREFIX)%: %.cpp @$(MAKE_OBJDIR) ifdef USE_NT_C_SYNTAX - $(CCC) -Fo$@ -c $(CFLAGS) $(call abspath,$<) + $(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH - $(CCC) -o $@ -c $(CFLAGS) $(call abspath,$<) + $(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CCC) -o $@ -c $(CFLAGS) $< endif @@ -470,10 +501,10 @@ ifdef STRICT_CPLUSPLUS_SUFFIX rm -f $(OBJDIR)/t_$*.cc else ifdef USE_NT_C_SYNTAX - $(CCC) -Fo$@ -c $(CFLAGS) $(call abspath,$<) + $(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH - $(CCC) -o $@ -c $(CFLAGS) $(call abspath,$<) + $(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CCC) -o $@ -c $(CFLAGS) $< endif @@ -870,8 +901,7 @@ endif ifneq (,$(filter-out OpenVMS OS2 WIN%,$(OS_TARGET))) # Can't use sed because of its 4000-char line length limit, so resort to perl -.DEFAULT: - @perl -e ' \ +PERL_DEPENDENCIES_PROGRAM = \ open(MD, "< $(DEPENDENCIES)"); \ while (<MD>) { \ if (m@ \.*/*$< @) { \ @@ -898,7 +928,10 @@ ifneq (,$(filter-out OpenVMS OS2 WIN%,$(OS_TARGET))) } elsif ("$<" ne "$(DEPENDENCIES)") { \ print "$(MAKE): *** No rule to make target $<. Stop.\n"; \ exit(1); \ - }' + } + +.DEFAULT: + @perl -e '$(PERL_DEPENDENCIES_PROGRAM)' endif ############################################################################# diff --git a/security/dbm/config/config.mk b/security/dbm/config/config.mk deleted file mode 100644 index 753364931..000000000 --- a/security/dbm/config/config.mk +++ /dev/null @@ -1,67 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -# -# These macros are defined by mozilla's configure script. -# We define them manually here. -# - -DEFINES += -DSTDC_HEADERS -DHAVE_STRERROR - -# -# Most platforms have snprintf, so it's simpler to list the exceptions. -# -HAVE_SNPRINTF = 1 -# -# OSF1 V4.0D doesn't have snprintf but V5.0A does. -# -ifeq ($(OS_TARGET)$(OS_RELEASE),OSF1V4.0D) -HAVE_SNPRINTF = -endif -ifdef HAVE_SNPRINTF -DEFINES += -DHAVE_SNPRINTF -endif - -ifeq (,$(filter-out IRIX Linux,$(OS_TARGET))) -DEFINES += -DHAVE_SYS_CDEFS_H -endif - -ifeq (,$(filter-out DGUX NCR ReliantUNIX SCO_SV SCOOS UNIXWARE,$(OS_TARGET))) -DEFINES += -DHAVE_SYS_BYTEORDER_H -endif - -# -# None of the platforms that we are interested in need to -# define HAVE_MEMORY_H. -# diff --git a/security/dbm/include/Makefile b/security/dbm/include/Makefile deleted file mode 100644 index ba4dd8ddf..000000000 --- a/security/dbm/include/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -####################################################################### -# (1) Include initial platform-independent assignments (MANDATORY). # -####################################################################### - -include manifest.mn - -####################################################################### -# (2) Include "global" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/config.mk - -####################################################################### -# (3) Include "component" configuration information. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (4) Include "local" platform-dependent assignments (OPTIONAL). # -####################################################################### - - - -####################################################################### -# (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/dbm/include/manifest.mn b/security/dbm/include/manifest.mn deleted file mode 100644 index 886fedd98..000000000 --- a/security/dbm/include/manifest.mn +++ /dev/null @@ -1,57 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/include - -MODULE = dbm - -EXPORTS = nsres.h \ - cdefs.h \ - mcom_db.h \ - ncompat.h \ - winfile.h \ - $(NULL) - -PRIVATE_EXPORTS = hsearch.h \ - page.h \ - extern.h \ - ndbm.h \ - queue.h \ - hash.h \ - mpool.h \ - search.h \ - $(NULL) - diff --git a/security/dbm/manifest.mn b/security/dbm/manifest.mn deleted file mode 100644 index d4065f761..000000000 --- a/security/dbm/manifest.mn +++ /dev/null @@ -1,45 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = .. - -MODULE = dbm - -IMPORTS = nspr20/v4.4.1 - -RELEASE = dbm - -DIRS = include \ - src \ - $(NULL) diff --git a/security/dbm/src/Makefile b/security/dbm/src/Makefile deleted file mode 100644 index 8fce98394..000000000 --- a/security/dbm/src/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -####################################################################### -# (1) Include initial platform-independent assignments (MANDATORY). # -####################################################################### - -include manifest.mn - -####################################################################### -# (2) Include "global" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/config.mk - -####################################################################### -# (3) Include "component" configuration information. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/dbm/config/config.mk - -####################################################################### -# (4) Include "local" platform-dependent assignments (OPTIONAL). # -####################################################################### - -include config.mk - -####################################################################### -# (5) Execute "global" rules. (OPTIONAL) # -####################################################################### - -include $(CORE_DEPTH)/coreconf/rules.mk - -####################################################################### -# (6) Execute "component" rules. (OPTIONAL) # -####################################################################### - - - -####################################################################### -# (7) Execute "local" rules. (OPTIONAL). # -####################################################################### - - - diff --git a/security/dbm/src/config.mk b/security/dbm/src/config.mk deleted file mode 100644 index 370fd75d6..000000000 --- a/security/dbm/src/config.mk +++ /dev/null @@ -1,63 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -DEFINES += -DMEMMOVE -D__DBINTERFACE_PRIVATE $(SECURITY_FLAG) - -INCLUDES += -I$(CORE_DEPTH)/../dbm/include - -# -# Currently, override TARGETS variable so that only static libraries -# are specifed as dependencies within rules.mk. -# - -TARGETS = $(LIBRARY) -SHARED_LIBRARY = -IMPORT_LIBRARY = -PURE_LIBRARY = -PROGRAM = - -ifdef SHARED_LIBRARY - ifeq (,$(filter-out WINNT WIN95 WINCE,$(OS_TARGET))) # list omits WIN16 - DLLBASE=/BASE:0x30000000 - RES=$(OBJDIR)/dbm.res - RESNAME=../include/dbm.rc - endif - ifeq ($(DLL_SUFFIX),dll) - DEFINES += -D_DLL - endif -endif - -ifeq ($(OS_TARGET),AIX) - OS_LIBS += -lc_r -endif diff --git a/security/dbm/src/dirent.c b/security/dbm/src/dirent.c deleted file mode 100644 index 001a48c5c..000000000 --- a/security/dbm/src/dirent.c +++ /dev/null @@ -1,348 +0,0 @@ -#ifdef OS2 - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#include <dirent.h> -#include <errno.h> - -/*#ifndef __EMX__ -#include <libx.h> -#endif */ - -#define INCL_DOSFILEMGR -#define INCL_DOSERRORS -#include <os2.h> - -#if OS2 >= 2 -# define FFBUF FILEFINDBUF3 -# define Word ULONG - /* - * LS20 recommends a request count of 100, but according to the - * APAR text it does not lead to missing files, just to funny - * numbers of returned entries. - * - * LS30 HPFS386 requires a count greater than 2, or some files - * are missing (those starting with a character less that '.'). - * - * Novell looses entries which overflow the buffer. In previous - * versions of dirent2, this could have lead to missing files - * when the average length of 100 directory entries was 40 bytes - * or more (quite unlikely for files on a Novell server). - * - * Conclusion: Make sure that the entries all fit into the buffer - * and that the buffer is large enough for more than 2 entries - * (each entry is at most 300 bytes long). And ignore the LS20 - * effect. - */ -# define Count 25 -# define BufSz (25 * (sizeof(FILEFINDBUF3)+1)) -#else -# define FFBUF FILEFINDBUF -# define Word USHORT -# define BufSz 1024 -# define Count 3 -#endif - -#if defined(__IBMC__) || defined(__IBMCPP__) - #define error(rc) _doserrno = rc, errno = EOS2ERR -#elif defined(MICROSOFT) - #define error(rc) _doserrno = rc, errno = 255 -#else - #define error(rc) errno = 255 -#endif - -struct _dirdescr { - HDIR handle; /* DosFindFirst handle */ - char fstype; /* filesystem type */ - Word count; /* valid entries in <ffbuf> */ - long number; /* absolute number of next entry */ - int index; /* relative number of next entry */ - FFBUF * next; /* pointer to next entry */ - char name[MAXPATHLEN+3]; /* directory name */ - unsigned attrmask; /* attribute mask for seekdir */ - struct dirent entry; /* buffer for directory entry */ - BYTE ffbuf[BufSz]; -}; - -/* - * Return first char of filesystem type, or 0 if unknown. - */ -static char -getFSType(const char *path) -{ - static char cache[1+26]; - char drive[3], info[512]; - Word unit, infolen; - char r; - - if (isalpha(path[0]) && path[1] == ':') { - unit = toupper(path[0]) - '@'; - path += 2; - } else { - ULONG driveMap; -#if OS2 >= 2 - if (DosQueryCurrentDisk(&unit, &driveMap)) -#else - if (DosQCurDisk(&unit, &driveMap)) -#endif - return 0; - } - - if ((path[0] == '\\' || path[0] == '/') - && (path[1] == '\\' || path[1] == '/')) - return 0; - - if (cache [unit]) - return cache [unit]; - - drive[0] = '@' + unit; - drive[1] = ':'; - drive[2] = '\0'; - infolen = sizeof info; -#if OS2 >= 2 - if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen)) - return 0; - if (infolen >= sizeof(FSQBUFFER2)) { - FSQBUFFER2 *p = (FSQBUFFER2 *)info; - r = p->szFSDName[p->cbName]; - } else -#else - if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0)) - return 0; - if (infolen >= 9) { - char *p = info + sizeof(USHORT); - p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT); - r = *p; - } else -#endif - r = 0; - return cache [unit] = r; -} - -char * -abs_path(const char *name, char *buffer, int len) -{ - char buf[4]; - if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') { - buf[0] = name[0]; - buf[1] = name[1]; - buf[2] = '.'; - buf[3] = '\0'; - name = buf; - } -#if OS2 >= 2 - if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len)) -#else - if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L)) -#endif - return NULL; - return buffer; -} - -DIR * -openxdir(const char *path, unsigned att_mask) -{ - DIR *dir; - char name[MAXPATHLEN+3]; - Word rc; - - dir = malloc(sizeof(DIR)); - if (dir == NULL) { - errno = ENOMEM; - return NULL; - } - - strncpy(name, path, MAXPATHLEN); - name[MAXPATHLEN] = '\0'; - switch (name[strlen(name)-1]) { - default: - strcat(name, "\\"); - case '\\': - case '/': - case ':': - ; - } - strcat(name, "."); - if (!abs_path(name, dir->name, MAXPATHLEN+1)) - strcpy(dir->name, name); - if (dir->name[strlen(dir->name)-1] == '\\') - strcat(dir->name, "*"); - else - strcat(dir->name, "\\*"); - - dir->fstype = getFSType(dir->name); - dir->attrmask = att_mask | A_DIR; - - dir->handle = HDIR_CREATE; - dir->count = 100; -#if OS2 >= 2 - rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask, - dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD); -#else - rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask, - (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0); -#endif - switch (rc) { - default: - free(dir); - error(rc); - return NULL; - case NO_ERROR: - case ERROR_NO_MORE_FILES: - ; - } - - dir->number = 0; - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - - return (DIR *)dir; -} - -DIR * -opendir(const char *pathname) -{ - return openxdir(pathname, 0); -} - -struct dirent * -readdir(DIR *dir) -{ - static int dummy_ino = 2; - - if (dir->index == dir->count) { - Word rc; - dir->count = 100; -#if OS2 >= 2 - rc = DosFindNext(dir->handle, dir->ffbuf, - sizeof dir->ffbuf, &dir->count); -#else - rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf, - sizeof dir->ffbuf, &dir->count); -#endif - if (rc) { - error(rc); - return NULL; - } - - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - } - - if (dir->index == dir->count) - return NULL; - - memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName); - dir->entry.d_name[dir->next->cchName] = '\0'; - dir->entry.d_ino = dummy_ino++; - dir->entry.d_reclen = dir->next->cchName; - dir->entry.d_namlen = dir->next->cchName; - dir->entry.d_size = dir->next->cbFile; - dir->entry.d_attribute = dir->next->attrFile; - dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite; - dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite; - - switch (dir->fstype) { - case 'F': /* FAT */ - case 'C': /* CDFS */ - if (dir->next->attrFile & FILE_DIRECTORY) - strupr(dir->entry.d_name); - else - strlwr(dir->entry.d_name); - } - -#if OS2 >= 2 - dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset); -#else - dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1); -#endif - ++dir->number; - ++dir->index; - - return &dir->entry; -} - -long -telldir(DIR *dir) -{ - return dir->number; -} - -void -seekdir(DIR *dir, long off) -{ - if (dir->number > off) { - char name[MAXPATHLEN+2]; - Word rc; - - DosFindClose(dir->handle); - - strcpy(name, dir->name); - strcat(name, "*"); - - dir->handle = HDIR_CREATE; - dir->count = 32767; -#if OS2 >= 2 - rc = DosFindFirst(name, &dir->handle, dir->attrmask, - dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD); -#else - rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask, - (PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0); -#endif - switch (rc) { - default: - error(rc); - return; - case NO_ERROR: - case ERROR_NO_MORE_FILES: - ; - } - - dir->number = 0; - dir->index = 0; - dir->next = (FFBUF *)dir->ffbuf; - } - - while (dir->number < off && readdir(dir)) - ; -} - -void -closedir(DIR *dir) -{ - DosFindClose(dir->handle); - free(dir); -} - -/*****************************************************************************/ - -#ifdef TEST - -main(int argc, char **argv) -{ - int i; - DIR *dir; - struct dirent *ep; - - for (i = 1; i < argc; ++i) { - dir = opendir(argv[i]); - if (!dir) - continue; - while (ep = readdir(dir)) - if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1])) - printf("%s%s\n", argv[i], ep->d_name); - else - printf("%s/%s\n", argv[i], ep->d_name); - closedir(dir); - } - - return 0; -} - -#endif - -#endif /* OS2 */ - diff --git a/security/dbm/src/dirent.h b/security/dbm/src/dirent.h deleted file mode 100644 index 07a6c0ac8..000000000 --- a/security/dbm/src/dirent.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef __DIRENT_H__ -#define __DIRENT_H__ -/* - * @(#)msd_dir.h 1.4 87/11/06 Public Domain. - * - * A public domain implementation of BSD directory routines for - * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), - * August 1897 - * - * Extended by Peter Lim (lim@mullian.oz) to overcome some MS DOS quirks - * and returns 2 more pieces of information - file size & attribute. - * Plus a little reshuffling of some #define's positions December 1987 - * - * Some modifications by Martin Junius 02-14-89 - * - * AK900712 - * AK910410 abs_path - make absolute path - * - */ - -#ifdef __EMX__ -#include <sys/param.h> -#else -#if defined(__IBMC__) || defined(__IBMCPP__) || defined(XP_W32_MSVC) -#include <stdio.h> -#ifdef MAXPATHLEN - #undef MAXPATHLEN -#endif -#define MAXPATHLEN (FILENAME_MAX*4) -#define MAXNAMLEN FILENAME_MAX - -#else -#include <param.h> -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* attribute stuff */ -#ifndef A_RONLY -# define A_RONLY 0x01 -# define A_HIDDEN 0x02 -# define A_SYSTEM 0x04 -# define A_LABEL 0x08 -# define A_DIR 0x10 -# define A_ARCHIVE 0x20 -#endif - -struct dirent { -#if defined(OS2) || defined(WIN32) /* use the layout of EMX to avoid trouble */ - int d_ino; /* Dummy */ - int d_reclen; /* Dummy, same as d_namlen */ - int d_namlen; /* length of name */ - char d_name[MAXNAMLEN + 1]; - unsigned long d_size; - unsigned short d_attribute; /* attributes (see above) */ - unsigned short d_time; /* modification time */ - unsigned short d_date; /* modification date */ -#else - char d_name[MAXNAMLEN + 1]; /* garentee null termination */ - char d_attribute; /* .. extension .. */ - unsigned long d_size; /* .. extension .. */ -#endif -}; - -typedef struct _dirdescr DIR; -/* the structs do not have to be defined here */ - -extern DIR *opendir(const char *); -extern DIR *openxdir(const char *, unsigned); -extern struct dirent *readdir(DIR *); -extern void seekdir(DIR *, long); -extern long telldir(DIR *); -extern void closedir(DIR *); -#define rewinddir(dirp) seekdir(dirp, 0L) - -extern char * abs_path(const char *name, char *buffer, int len); - -#ifndef S_IFMT -#define S_IFMT ( S_IFDIR | S_IFREG ) -#endif - -#ifndef S_ISDIR -#define S_ISDIR( m ) (((m) & S_IFMT) == S_IFDIR) -#endif - -#ifndef S_ISREG -#define S_ISREG( m ) (((m) & S_IFMT) == S_IFREG) -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/security/dbm/src/manifest.mn b/security/dbm/src/manifest.mn deleted file mode 100644 index 80f2abfd0..000000000 --- a/security/dbm/src/manifest.mn +++ /dev/null @@ -1,61 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# - -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/src - -MODULE = dbm - -# -# memmove.c, snprintf.c, and strerror.c are not in CSRCS because -# the Standard C Library has memmove and strerror and DBM is not -# using snprintf. -# - -CSRCS = db.c \ - h_bigkey.c \ - h_func.c \ - h_log2.c \ - h_page.c \ - hash.c \ - hash_buf.c \ - hsearch.c \ - mktemp.c \ - ndbm.c \ - nsres.c \ - dirent.c \ - $(NULL) - -LIBRARY_NAME = dbm diff --git a/security/dbm/tests/Makefile b/security/dbm/tests/Makefile deleted file mode 100644 index fe132e19c..000000000 --- a/security/dbm/tests/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -#! gmake -# -# The contents of this file are subject to the Mozilla Public -# License Version 1.1 (the "License"); you may not use this file -# except in compliance with the License. You may obtain a copy of -# the License at http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS -# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -# implied. See the License for the specific language governing -# rights and limitations under the License. -# -# The Original Code is the Netscape security libraries. -# -# The Initial Developer of the Original Code is Netscape -# Communications Corporation. Portions created by Netscape are -# Copyright (C) 1994-2000 Netscape Communications Corporation. All -# Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the -# terms of the GNU General Public License Version 2 or later (the -# "GPL"), in which case the provisions of the GPL are applicable -# instead of those above. If you wish to allow use of your -# version of this file only under the terms of the GPL and not to -# allow others to use your version of this file under the MPL, -# indicate your decision by deleting the provisions above and -# replace them with the notice and other provisions required by -# the GPL. If you do not delete the provisions above, a recipient -# may use your version of this file under either the MPL or the -# GPL. -# -DEPTH = ../.. -CORE_DEPTH = ../.. - -VPATH = $(CORE_DEPTH)/../dbm/tests - -MODULE = dbm - -CSRCS = lots.c - -PROGRAM = lots - -include $(DEPTH)/coreconf/config.mk - -include $(DEPTH)/dbm/config/config.mk - -ifeq (,$(filter-out WIN%,$(OS_TARGET))) -LIBDBM = ../src/$(PLATFORM)/dbm$(STATIC_LIB_SUFFIX) -else -LIBDBM = ../src/$(PLATFORM)/libdbm$(STATIC_LIB_SUFFIX) -endif - -INCLUDES += -I$(CORE_DEPTH)/../dbm/include - -LDFLAGS = $(LDOPTS) $(LIBDBM) - -include $(DEPTH)/coreconf/rules.mk - -lots.pure: lots - purify $(CC) -o lots.pure $(CFLAGS) $(OBJS) $(MYLIBS) - -crash: crash.o $(MYLIBS) - $(CC) -o crash $(CFLAGS) $^ - -crash.pure: crash.o $(MYLIBS) - purify $(CC) -o crash.pure $(CFLAGS) $^ - diff --git a/security/nss/Makefile b/security/nss/Makefile index b6e9e64b4..37e912ef1 100644 --- a/security/nss/Makefile +++ b/security/nss/Makefile @@ -80,9 +80,14 @@ include $(CORE_DEPTH)/coreconf/rules.mk nss_build_all: build_coreconf build_nspr build_dbm all +nss_clean_all: clobber_coreconf clobber_nspr clobber_dbm clobber + build_coreconf: cd $(CORE_DEPTH)/coreconf ; $(MAKE) +clobber_coreconf: + cd $(CORE_DEPTH)/coreconf ; $(MAKE) clobber + NSPR_CONFIG_STATUS = $(CORE_DEPTH)/../nsprpub/$(OBJDIR_NAME)/config.status NSPR_CONFIGURE = $(CORE_DEPTH)/../nsprpub/configure @@ -138,10 +143,14 @@ $(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE) build_nspr: $(NSPR_CONFIG_STATUS) cd $(CORE_DEPTH)/../nsprpub/$(OBJDIR_NAME) ; $(MAKE) +clobber_nspr: $(NSPR_CONFIG_STATUS) + cd $(CORE_DEPTH)/../nsprpub/$(OBJDIR_NAME) ; $(MAKE) clobber + build_dbm: cd $(CORE_DEPTH)/dbm ; $(MAKE) export libs - +clobber_dbm: + cd $(CORE_DEPTH)/dbm ; $(MAKE) clobber moz_import:: ifeq (,$(filter-out WIN%,$(OS_TARGET))) 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/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..0367ab32f 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,8 @@ static void LongUsage(char *progName) FPS "%-15s Add a certificate to the database (create if needed)\n", "-A"); + 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", @@ -1138,7 +1145,7 @@ static void LongUsage(char *progName) 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", ""); @@ -1307,6 +1314,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 +1398,7 @@ MakeV1Cert( CERTCertDBHandle * handle, PRBool selfsign, unsigned int serialNumber, int warpmonths, - int validitylength) + int validityMonths) { CERTCertificate *issuerCert = NULL; CERTValidity *validity; @@ -1414,8 +1422,7 @@ 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 */ @@ -1561,7 +1568,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 +2196,7 @@ CreateCert( SECOidTag hashAlgTag, unsigned int serialNumber, int warpmonths, - int validitylength, + int validityMonths, const char *emailAddrs, const char *dnsNames, PRBool ascii, @@ -2224,7 +2231,7 @@ CreateCert( } subjectCert = MakeV1Cert (handle, certReq, issuerNickName, selfsign, - serialNumber, warpmonths, validitylength); + serialNumber, warpmonths, validityMonths); if (subjectCert == NULL) { GEN_BREAK (SECFailure) } @@ -2302,7 +2309,8 @@ enum { cmd_ListModules, cmd_CheckCertValidity, cmd_ChangePassword, - cmd_Version + cmd_Version, + cmd_Batch }; /* Certutil options */ @@ -2344,8 +2352,7 @@ enum { opt_RW, opt_Exponent, opt_NoiseFile, - opt_Hash, - opt_Batch + opt_Hash }; static int @@ -2367,11 +2374,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 +2409,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 +2452,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 +2584,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 +2809,7 @@ secuCommandFlag certutil_options[] = rv = SECFailure; goto shutdown; } + initialized = PR_TRUE; SECU_RegisterDynamicOids(); } certHandle = CERT_GetDefaultCertDB(); @@ -2994,7 +3003,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 +3083,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 +3161,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(¶ms, 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(¶ms.prime, PR_FALSE); - } - SECITEM_AllocItem(NULL, ¶ms.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(¶ms.subPrime, PR_FALSE); - } - SECITEM_AllocItem(NULL, ¶ms.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(¶ms.base, PR_FALSE); - } - SECITEM_AllocItem(NULL, ¶ms.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(¶ms, &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..8d2908ab1 100644 --- a/security/nss/cmd/lib/SECerrs.h +++ b/security/nss/cmd/lib/SECerrs.h @@ -504,3 +504,13 @@ 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.") + diff --git a/security/nss/cmd/lib/SSLerrs.h b/security/nss/cmd/lib/SSLerrs.h index 62ce99f03..85c8c9def 100644 --- a/security/nss/cmd/lib/SSLerrs.h +++ b/security/nss/cmd/lib/SSLerrs.h @@ -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/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/dbm/Makefile b/security/nss/cmd/pk11mode/Makefile index 34cd6d899..9e2708a76 100644..100755 --- a/security/dbm/Makefile +++ b/security/nss/cmd/pk11mode/Makefile @@ -1,36 +1,38 @@ -#! gmake +# ***** 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 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 ***** ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # @@ -54,7 +56,24 @@ include $(CORE_DEPTH)/coreconf/config.mk # (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) # @@ -72,9 +91,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### -coreconf_hack: - cd ../coreconf; gmake - gmake import - -RelEng_bld: coreconf_hack - gmake 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..6dcc08c6a --- /dev/null +++ b/security/nss/cmd/pk11mode/pk11mode.c @@ -0,0 +1,5198 @@ +/* + * 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" +#else +#include "prlink.h" +#endif + +#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"; +} + + +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; + +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_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); + +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_UTF8CHAR pwd[] ="1Mozilla"; + CK_TOKEN_INFO tokenInfo; + CK_ULONG slotID; + + slotID = 0; + if (argc == 2) { + if (strcmp(argv[1], "FIPS") == 0) { + MODE = FIPSMODE; + } else { + MODE = NONFIPSMODE; + slotID = 1; + } + } else MODE = FIPSMODE; + +#ifdef _WIN32 + hModule = LoadLibrary(LIB_NAME); + if (hModule == NULL) { + PKM_Error( "cannot load %s\n", LIB_NAME); + exit(1); + } + if (MODE == FIPSMODE) { + /* FIPS mode == FC_GetFunctionList */ + pC_GetFunctionList = (CK_C_GetFunctionList) + GetProcAddress(hModule, "FC_GetFunctionList"); + PKM_LogIt("loading FC_GetFunctionList for FIPS Mode; slotID %d \n", + slotID); + PKM_LogIt("pFunctionList->C_Foo == pFunctionList->FC_Foo\n"); + + } else { + /* NON FIPS mode == C_GetFunctionList */ + pC_GetFunctionList = (CK_C_GetFunctionList) + GetProcAddress(hModule, "C_GetFunctionList"); + PKM_LogIt("loading C_GetFunctionList for Non FIPS Mode; slotID %d \n", + slotID); + } + if (pC_GetFunctionList == NULL) { + PKM_Error( "cannot load %s\n", LIB_NAME); + exit(1); + } +#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 + + 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; + initArgs.LibraryParameters = (CK_CHAR_PTR *) + "configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db' flags= "; + 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)); + exit(1); + } + 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)); + exit(1); + } + pSlotList = PKM_GetSlotList(pFunctionList, slotID); + if (pSlotList == NULL) { + PKM_Error( "PKM_GetSlotList failed with \n"); + exit(1); + } + 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)); + exit(1); + } + + if (!(tokenInfo.flags & CKF_USER_PIN_INITIALIZED)) { + PKM_LogIt("Initing PW for DB\n"); + PKM_InitPWforDB(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + } 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)); + exit(1); + } + /* 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)); + exit(1); + } + + crv = PKM_SessionLogin(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + + /* + * 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, sizeof(pwd)); + 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)); + exit(1); + } + + crv = PKM_SecretKey(pFunctionList, pSlotList, slotID, pwd, sizeof(pwd)); + 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)); + exit(1); + } + + crv = PKM_PublicKey(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + crv = PKM_OperationalState(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + crv = PKM_MultiObjectManagement(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + crv = PKM_LegacyFunctions(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + crv = PKM_TLSKeyAndMacDerive(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd), + 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)); + exit(1); + } + crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd),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)); + exit(1); + } + crv = PKM_TLSMasterKeyDerive(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd),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)); + exit(1); + } + crv = PKM_FindAllObjects(pFunctionList, pSlotList, slotID, + pwd, sizeof(pwd)); + 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)); + exit(1); + } + 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)); + exit(1); + } + + 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, sizeof(pwd)); + 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)); + exit(1); + } + + PKM_LogIt("**** ALL TESTS PASSED ****\n"); + PKM_LogIt("**** Total number of TESTS %d. ****\n", NUMTESTS); + PKM_LogIt("unloading NSS PKCS # 11 softoken and exiting\n"); + +#ifdef _WIN32 + FreeLibrary(hModule); +#else + PR_UnloadLibrary(lib); +#endif + + return 0; +} + +/* +* 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 failed 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 failed 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)); + exit(1); + } + + 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; + 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, "FIPS 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); + exit(1); +} +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, + sizeof(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, + sizeof(testPin), + (CK_UTF8CHAR *) weakPin, + sizeof(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 failed with " + "0x%08X, %-26s\n", crv, PKM_CK_RVtoStr(crv)); + } + } + crv = pFunctionList->C_SetPIN( + hSession, (CK_UTF8CHAR *) testPin, + sizeof(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_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_C_INITIALIZE_ARGS_NSS initArgs; + CK_SESSION_HANDLE hSession; + + 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); + + initArgs.CreateMutex = NULL; + initArgs.DestroyMutex = NULL; + initArgs.LockMutex = NULL; + initArgs.UnlockMutex = NULL; + initArgs.flags = CKF_OS_LOCKING_OK; + initArgs.LibraryParameters = (CK_CHAR_PTR *) + "configdir='.' certPrefix='' keyPrefix='' secmod='secmod.db' flags= "; + initArgs.pReserved = NULL; + + /* 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); + + 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"); + 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 crv; + } else { + PKM_LogIt("C_Login with wrong password failed with 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 crv; + } else { + PKM_LogIt("C_Login with wrong password failed with 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 crv; + + } else { + PKM_LogIt("C_Login with wrong password failed with 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; + + 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; + } + 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 + }; + 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); + + 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; + } + for (i = 0; i < sha1DigestLen; i++) { + printf("%02x", (unsigned)sha1Digest[i]); + } + printf("\n"); + 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 failed 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 failed 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; + +} + diff --git a/security/nss/cmd/pk12util/pk12util.c b/security/nss/cmd/pk12util/pk12util.c index 1d15f1663..ade93d1c0 100644 --- a/security/nss/cmd/pk12util/pk12util.c +++ b/security/nss/cmd/pk12util/pk12util.c @@ -344,106 +344,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 +504,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 +571,7 @@ p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len) } } + void P12U_ExportPKCS12Object(char *nn, char *outfile, PK11SlotInfo *inSlot, secuPWData *slotPw, secuPWData *p12FilePw) @@ -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; } 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..9817e9818 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 }; @@ -230,31 +209,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 +233,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 +600,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); @@ -859,11 +826,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 +882,12 @@ reload_crl(PRFileDesc *crlFile) return rv; } +void stop_server() +{ + stopping = 1; + PR_Interrupt(acceptorThread); + PZ_TraceFlush(); +} int handle_connection( @@ -1206,6 +1176,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 +1185,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 +1211,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 +1324,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 +1627,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) { @@ -1783,7 +1806,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); @@ -1904,22 +1931,45 @@ main(int argc, char **argv) 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); } } } 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/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/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..5b456d817 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 }; @@ -147,7 +126,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 +144,23 @@ 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 * ownPasswd( PK11SlotInfo *slot, PRBool retry, void *arg) { @@ -203,7 +185,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 +196,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 +276,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 +386,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 +398,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 +421,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 +440,7 @@ thread_wrapper(void * arg) if (dosleep) { PR_Sleep(PR_SecondsToInterval(1)); } - } while (!die); + } while (!done && (!failed_already || ignoreErrors)); } SECStatus @@ -467,8 +450,8 @@ launch_thread( void * b, int tid) { + PRUint32 i; perThread * slot; - int i; PR_Lock(threadLock); @@ -478,7 +461,8 @@ launch_thread( return SECFailure; } - slot = &threads[numUsed++]; + i = numUsed++; + slot = &threads[i]; slot->a = a; slot->b = b; slot->tid = tid; @@ -506,7 +490,6 @@ launch_thread( int reap_threads(void) { - perThread * slot; int i; for (i = 0; i < MAX_THREADS; ++i) { @@ -615,12 +598,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 +643,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 +690,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 +702,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; } @@ -841,7 +826,7 @@ retry: goto done; } else { if (ThrottleUp) { - PRTime now; + PRTime now = PR_Now(); PR_Lock(threadLock); lastConnectSuccess = PR_MAX(now, lastConnectSuccess); PR_Unlock(threadLock); @@ -1108,6 +1093,17 @@ StressClient_GetClientAuthData(void * arg, } } +#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("strsclnt"); \ + } + void client_main( unsigned short port, @@ -1139,14 +1135,33 @@ client_main( 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 (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("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); @@ -1156,6 +1171,8 @@ client_main( cipher); exit(1); } + } else { + Usage("strsclnt"); } } } @@ -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 "); @@ -1323,11 +1346,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 +1372,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; @@ -1402,6 +1429,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) { @@ -1445,7 +1480,8 @@ main(int argc, char **argv) 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 +1494,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..5fabe7da7 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 @@ -76,6 +77,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 +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 }; @@ -243,22 +225,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 +249,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 +376,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); } @@ -432,6 +400,17 @@ printHostNameAndAddr(const char * host, const PRNetAddr * addr) #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 +421,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; @@ -471,6 +451,14 @@ int main(int argc, char **argv) progName = strrchr(argv[0], '\\'); progName = progName ? progName+1 : argv[0]; + 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, "23BTfc:h:p:d:m:n:oqsvw:x"); while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { @@ -670,19 +658,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 +797,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 +887,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 +928,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) { 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..b55db11c5 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 @@ -85,7 +86,8 @@ static void Usage(const char *progName) { fprintf(stderr, - "Usage: %s [-p port] [-c connections] [-C cipher(s)] hostname\n", +"Usage: %s [-p port] [-c connections] [-d dbdir] [-w password]\n" +"\t\t[-C cipher(s)] hostname\n", progName); exit(1); } @@ -368,6 +370,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) { @@ -436,16 +449,36 @@ 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); } } } diff --git a/security/nss/cmd/vfyserv/vfyutil.c b/security/nss/cmd/vfyserv/vfyutil.c index 4741a22ad..038f0194a 100644 --- a/security/nss/cmd/vfyserv/vfyutil.c +++ b/security/nss/cmd/vfyserv/vfyutil.c @@ -291,10 +291,10 @@ myGetClientAuthData(void *arg, break; } secStatus = SECFailure; - break; } - CERT_FreeNicknames(names); + CERT_DestroyCertificate(cert); } /* for loop */ + CERT_FreeNicknames(names); } } diff --git a/security/nss/lib/base/arena.c b/security/nss/lib/base/arena.c index 61fb07147..18238ee91 100644 --- a/security/nss/lib/base/arena.c +++ b/security/nss/lib/base/arena.c @@ -520,12 +520,12 @@ nssArena_Destroy } #endif /* NSSDEBUG */ - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return PR_FAILURE; } + PR_Lock(arena->lock); #ifdef DEBUG if( PR_SUCCESS != arena_remove_pointer(arena) ) { @@ -585,12 +585,12 @@ nssArena_Mark } #endif /* NSSDEBUG */ - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return (nssArenaMark *)NULL; } + PR_Lock(arena->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL == arena->marking_thread ) { @@ -668,12 +668,12 @@ nss_arena_unmark_release return PR_FAILURE; } - PR_Lock(arena->lock); if( (PRLock *)NULL == arena->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return PR_FAILURE; } + PR_Lock(arena->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL != arena->marking_thread ) { @@ -908,12 +908,12 @@ nss_ZAlloc } #endif /* NSSDEBUG */ - PR_Lock(arenaOpt->lock); if( (PRLock *)NULL == arenaOpt->lock ) { /* Just got destroyed */ nss_SetError(NSS_ERROR_INVALID_ARENA); return (void *)NULL; } + PR_Lock(arenaOpt->lock); #ifdef ARENA_THREADMARK if( (PRThread *)NULL != arenaOpt->marking_thread ) { diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 9c5c22f31..f710db899 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -864,8 +864,7 @@ CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER, } if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) { - PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); - goto loser; + cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE; } /* generate and save the database key for the cert */ diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index 8567ebbe4..b50ad6e5c 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -301,7 +301,13 @@ struct CERTCertificateStr { * XXX - these should be moved into some sort of application specific * data structure. They are only used by the browser right now. */ - struct SECSocketNode *authsocketlist; + union { + void* apointer; /* was struct SECSocketNode* authsocketlist */ + struct { + unsigned int hasUnsupportedCriticalExt :1; + /* add any new option bits needed here */ + } bits; + } options; int series; /* was int authsocketcount; record the series of the pkcs11ID */ /* This is PKCS #11 stuff. */ diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index 7cd308c0a..0c8bcc505 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -463,13 +463,21 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, SECStatus rv; OpaqueCRLFields* extended = NULL; const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate; + PRInt32 testOptions = options; - if (!derSignedCrl || - ( (options & CRL_DECODE_ADOPT_HEAP_DER) && /* adopting DER requires - not copying it */ - (!(options & CRL_DECODE_DONT_COPY_DER)) - ) - ) { + PORT_Assert(derSignedCrl); + if (!derSignedCrl) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } + + /* Adopting DER requires not copying it. Code that sets ADOPT flag + * but doesn't set DONT_COPY probably doesn't know What it is doing. + * That condition is a programming error in the caller. + */ + testOptions &= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER); + PORT_Assert(testOptions != CRL_DECODE_ADOPT_HEAP_DER); + if (testOptions == CRL_DECODE_ADOPT_HEAP_DER) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -570,9 +578,13 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl, loser: if (options & CRL_DECODE_KEEP_BAD_CRL) { - extended->decodingError = PR_TRUE; - crl->referenceCount = 1; - return(crl); + if (extended) { + extended->decodingError = PR_TRUE; + } + if (crl) { + crl->referenceCount = 1; + return(crl); + } } if ((narena == NULL) && arena ) { @@ -597,8 +609,9 @@ CERT_DecodeDERCrl(PRArenaPool *narena, SECItem *derSignedCrl, int type) * caching stuff used by certificates....? * return values : * - * SECSuccess means we got a valid DER CRL (passed in "decoded"), or no CRL at - * all + * SECSuccess means we got a valid decodable DER CRL, or no CRL at all. + * Caller may distinguish those cases by the value returned in "decoded". + * When DER CRL is not found, error code will be SEC_ERROR_CRL_NOT_FOUND. * * SECFailure means we got a fatal error - most likely, we found a CRL, * and it failed decoding, or there was an out of memory error. Do NOT ignore @@ -616,7 +629,6 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, SECItem *derCrl = NULL; CK_OBJECT_HANDLE crlHandle = 0; char *url = NULL; - int nsserror; PORT_Assert(decoded); if (!decoded) { @@ -624,15 +636,12 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, return SECFailure; } - /* XXX it would be really useful to be able to fetch the CRL directly into - an arena. This would avoid a copy later on in the decode step */ - PORT_SetError(0); derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey, type, &url); if (derCrl == NULL) { /* if we had a problem other than the CRL just didn't exist, return * a failure to the upper level */ - nsserror = PORT_GetError(); - if ((nsserror != 0) && (nsserror != SEC_ERROR_CRL_NOT_FOUND)) { + int nsserror = PORT_GetError(); + if (nsserror != SEC_ERROR_CRL_NOT_FOUND) { rv = SECFailure; } goto loser; @@ -640,15 +649,16 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, PORT_Assert(crlHandle != CK_INVALID_HANDLE); /* PK11_FindCrlByName obtained a slot reference. */ - if (!(decodeoptions & CRL_DECODE_DONT_COPY_DER) ) { - /* force adoption of the DER from the heap - this will cause it to be - automatically freed when SEC_DestroyCrl is invoked */ - decodeoptions |= CRL_DECODE_ADOPT_HEAP_DER; - } + /* derCRL is a fresh HEAP copy made for us by PK11_FindCrlByName. + Force adoption of the DER CRL from the heap - this will cause it + to be automatically freed when SEC_DestroyCrl is invoked */ + decodeoptions |= (CRL_DECODE_ADOPT_HEAP_DER | CRL_DECODE_DONT_COPY_DER); + crl = CERT_DecodeDERCrlWithFlags(NULL, derCrl, type, decodeoptions); if (crl) { crl->slot = slot; slot = NULL; /* adopt it */ + derCrl = NULL; /* adopted by the crl struct */ crl->pkcs11ID = crlHandle; if (url) { crl->url = PORT_ArenaStrdup(crl->arena,url); @@ -667,10 +677,7 @@ SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type, loser: if (derCrl) { - /* destroy the DER if it was copied to the CRL */ - if (crl && (!(decodeoptions & CRL_DECODE_DONT_COPY_DER)) ) { - SECITEM_FreeItem(derCrl, PR_TRUE); - } + SECITEM_FreeItem(derCrl, PR_TRUE); } *decoded = crl; @@ -678,7 +685,6 @@ loser: return rv; } -SECStatus SEC_DestroyCrl(CERTSignedCrl *crl); CERTSignedCrl * crl_storeCRL (PK11SlotInfo *slot,char *url, @@ -687,15 +693,15 @@ crl_storeCRL (PK11SlotInfo *slot,char *url, CERTSignedCrl *oldCrl = NULL, *crl = NULL; PRBool deleteOldCrl = PR_FALSE; CK_OBJECT_HANDLE crlHandle = CK_INVALID_HANDLE; + SECStatus rv; PORT_Assert(newCrl); PORT_Assert(derCrl); /* we can't use the cache here because we must look in the same token */ - SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, + rv = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type, &oldCrl, CRL_DECODE_SKIP_ENTRIES); - /* if there is an old crl on the token, make sure the one we are installing is newer. If not, exit out, otherwise delete the old crl. @@ -2127,7 +2133,6 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer, } *returned = NULL; cache = PORT_ZAlloc(sizeof(CRLDPCache)); - PORT_Assert(cache); if (!cache) { return SECFailure; @@ -2139,6 +2144,7 @@ static SECStatus DPCache_Create(CRLDPCache** returned, CERTCertificate* issuer, #endif if (!cache->lock) { + PORT_Free(cache); return SECFailure; } if (issuer) @@ -2776,25 +2782,29 @@ SECStatus CERT_UncacheCRL(CERTCertDBHandle* dbhandle, SECItem* olddercrl) } if (PR_TRUE == dupe) { - DPCache_RemoveCRL(cache, i); /* got a match */ - cache->mustchoose = PR_TRUE; - removed = PR_TRUE; + rv = DPCache_RemoveCRL(cache, i); /* got a match */ + if (SECSuccess == rv) { + cache->mustchoose = PR_TRUE; + removed = PR_TRUE; + } break; } } DPCache_UnlockWrite(); + + if (SECSuccess != CachedCrl_Destroy(returned) ) { + rv = SECFailure; + } } ReleaseDPCache(cache, writeLocked); - - if (PR_TRUE != removed) - { - rv = SECFailure; - } } - SEC_DestroyCrl(oldcrl); /* need to do this because object is refcounted */ - if (PR_TRUE != removed) + if (SECSuccess != SEC_DestroyCrl(oldcrl) ) { + /* need to do this because object is refcounted */ + rv = SECFailure; + } + if (SECSuccess == rv && PR_TRUE != removed) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 18e35b299..4f820463f 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -155,6 +155,9 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, NSSCryptoContext *context; nssCryptokiObject *permInstance; NSSCertificate *c = STAN_GetNSSCertificate(cert); + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + context = c->object.cryptoContext; if (!context) { PORT_SetError(SEC_ERROR_ADDING_CERT); @@ -170,9 +173,10 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); } /* Delete the temp instance */ - nssCertificateStore_Lock(context->certStore); + nssCertificateStore_Lock(context->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(context->certStore, c); - nssCertificateStore_Unlock(context->certStore); + nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); c->object.cryptoContext = NULL; /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); @@ -225,7 +229,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, PRStatus nssrv; NSSCertificate *c; CERTCertificate *cc; - NSSCertificate *tempCert; + NSSCertificate *tempCert = NULL; nssPKIObject *pkio; NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); @@ -256,7 +260,7 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, return cc; } } - pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC); + pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); if (!pkio) { return NULL; } @@ -307,33 +311,26 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } - /* this function cannot detect if the cert exists as a temp cert now, but - * didn't when CERT_NewTemp was first called. - */ - nssrv = NSSCryptoContext_ImportCertificate(gCC, c); - if (nssrv != PR_SUCCESS) { + + tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); + if (!tempCert) { goto loser; } - /* so find the entry in the temp store */ - tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC, - &c->issuer, - &c->serial); - /* destroy the copy */ + /* destroy our copy */ NSSCertificate_Destroy(c); - if (tempCert) { - /* and use the "official" entry */ - c = tempCert; - cc = STAN_GetCERTCertificateOrRelease(c); - if (!cc) { - return NULL; - } - } else { + /* and use the stored entry */ + c = tempCert; + cc = STAN_GetCERTCertificateOrRelease(c); + if (!cc) { + /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ return NULL; } + cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; return cc; loser: + /* Perhaps this should be nssCertificate_Destroy(c) */ nssPKIObject_Destroy(&c->object); return NULL; } @@ -811,23 +808,10 @@ certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, emailProfile->data); } else if (profileTime && emailProfile) { PRStatus nssrv; - NSSDER subject; NSSItem profTime, profData; - NSSItem *pprofTime, *pprofData; - NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); - if (profileTime) { - NSSITEM_FROM_SECITEM(&profTime, profileTime); - pprofTime = &profTime; - } else { - pprofTime = NULL; - } - if (emailProfile) { - NSSITEM_FROM_SECITEM(&profData, emailProfile); - pprofData = &profData; - } else { - pprofData = NULL; - } - stanProfile = nssSMIMEProfile_Create(c, pprofTime, pprofData); + NSSITEM_FROM_SECITEM(&profTime, profileTime); + NSSITEM_FROM_SECITEM(&profData, emailProfile); + stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData); if (!stanProfile) goto loser; nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile); rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; diff --git a/security/nss/lib/certdb/xauthkid.c b/security/nss/lib/certdb/xauthkid.c index 8d9df2123..8fb5a0122 100644 --- a/security/nss/lib/certdb/xauthkid.c +++ b/security/nss/lib/certdb/xauthkid.c @@ -119,10 +119,10 @@ CERT_DecodeAuthKeyID (PRArenaPool *arena, SECItem *encodedValue) do { mark = PORT_ArenaMark (arena); - value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); - value->DERAuthCertIssuer = NULL; + value = (CERTAuthKeyID*)PORT_ArenaZAlloc (arena, sizeof (*value)); if (value == NULL) break; + value->DERAuthCertIssuer = NULL; /* copy the DER into the arena, since Quick DER returns data that points into the DER input, which may get freed by the caller */ rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue); diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 2c0ffe7cb..ea7f50a0e 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -443,15 +443,16 @@ CollectNicknames( NSSCertificate *c, void *data) /* allocate the node */ node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode)); if ( node == NULL ) { - return(PR_FAILURE); + PORT_Free(nickname); + return PR_FAILURE; } /* copy the string */ len = PORT_Strlen(nickname) + 1; node->string = (char*)PORT_ArenaAlloc(names->arena, len); if ( node->string == NULL ) { - if (nickname) PORT_Free(nickname); - return(PR_FAILURE); + PORT_Free(nickname); + return PR_FAILURE; } PORT_Memcpy(node->string, nickname, len); @@ -494,7 +495,7 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx) names->totallen = 0; /* make sure we are logged in */ - (void) pk11_TraverseAllSlots(NULL, NULL, wincx); + (void) pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx); NSSTrustDomain_TraverseCertificates(handle, CollectNicknames, (void *)names); @@ -672,12 +673,12 @@ CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) goto loser; - dnames = (CERTDistNames*)PORT_Alloc(sizeof(CERTDistNames)); + dnames = PORT_ArenaZNew(arena, CERTDistNames); if (dnames == NULL) goto loser; dnames->arena = arena; dnames->nnames = nnames; - dnames->names = names = (SECItem*)PORT_Alloc(nnames * sizeof(SECItem)); + dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames); if (names == NULL) goto loser; for (i = 0; i < nnames; i++) { @@ -720,11 +721,9 @@ CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr) if ( name ) { nameItem = SEC_ASN1EncodeItem (arena, NULL, (void *)name, CERT_NameTemplate); - if ( nameItem == NULL ) { - goto loser; + if ( nameItem != NULL ) { + cert = CERT_FindCertByName(handle, nameItem); } - - cert = CERT_FindCertByName(handle, nameItem); CERT_DestroyName(name); } diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index 25d0eaf42..b57720d68 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -101,7 +101,6 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd, void *wincx) { SECStatus rv; - SECOidTag algid; SECItem sig; if ( !pubKey || !sd ) { @@ -114,9 +113,8 @@ CERT_VerifySignedDataWithPublicKey(CERTSignedData *sd, /* convert sig->len from bit counts to byte count. */ DER_ConvertBitString(&sig); - algid = SECOID_GetAlgorithmTag(&sd->signatureAlgorithm); - rv = VFY_VerifyData(sd->data.data, sd->data.len, pubKey, &sig, - algid, wincx); + rv = VFY_VerifyDataWithAlgorithmID(sd->data.data, sd->data.len, pubKey, + &sig, &sd->signatureAlgorithm, NULL, wincx); return rv ? SECFailure : SECSuccess; } @@ -362,20 +360,20 @@ loser: chain, 2, NULL, &status, td, cc); nss_ZFreeIf(nssTime); if (status == PR_SUCCESS) { + PORT_Assert(me == chain[0]); /* if it's a root, the chain will only have one cert */ if (!chain[1]) { /* already has a reference from the call to BuildChain */ return cert; - } else { - CERT_DestroyCertificate(cert); /* the first cert in the chain */ - return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ - } - } else { - if (chain[0]) { - CERT_DestroyCertificate(cert); - } - PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); - } + } + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ + } + if (chain[0]) { + PORT_Assert(me == chain[0]); + NSSCertificate_Destroy(chain[0]); /* the first cert in the chain */ + } + PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); return NULL; #endif } @@ -729,6 +727,13 @@ cert_VerifyCertChain(CERTCertDBHandle *handle, CERTCertificate *cert, namesCount += subjectNameListLen; namesList = cert_CombineNamesLists(namesList, subjectNameList); } + + /* check if the cert has an unsupported critical extension */ + if ( subjectCert->options.bits.hasUnsupportedCriticalExt ) { + PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION); + LOG_ERROR_OR_EXIT(log,subjectCert,count,0); + } + /* find the certificate of the issuer */ issuerCert = CERT_FindCertIssuer(subjectCert, t, certUsage); if ( ! issuerCert ) { @@ -1207,30 +1212,21 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, } valid = SECSuccess ; /* start off assuming cert is valid */ -#ifdef notdef - /* check if this cert is in the Evil list */ - rv = CERT_CheckForEvilCert(cert); - if ( rv != SECSuccess ) { - PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE); - LOG_ERROR(log,cert,0,0); - return SECFailure; - } -#endif - /* make sure that the cert is valid at time t */ allowOverride = (PRBool)((requiredUsages & certificateUsageSSLServer) || (requiredUsages & certificateUsageSSLServerWithStepUp)); validity = CERT_CheckCertValidTimes(cert, t, allowOverride); if ( validity != secCertTimeValid ) { - LOG_ERROR(log,cert,0,validity); - return SECFailure; + valid = SECFailure; + LOG_ERROR_OR_EXIT(log,cert,0,validity); } /* check key usage and netscape cert type */ cert_GetCertType(cert); certType = cert->nsCertType; - for (i=1;i<=certificateUsageHighest && !(SECFailure == valid && !returnedUsages) ;) { + for (i=1; i<=certificateUsageHighest && + (SECSuccess == valid || returnedUsages || log) ; ) { PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE; if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) { NEXT_USAGE(); @@ -1394,7 +1390,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, if (PR_FALSE == checkedOCSP) { checkedOCSP = PR_TRUE; /* only check OCSP once */ statusConfig = CERT_GetStatusConfig(handle); - if ( (! (requiredUsages & certificateUsageStatusResponder)) && + if ( (! (requiredUsages == certificateUsageStatusResponder)) && statusConfig != NULL) { if (statusConfig->statusChecker != NULL) { rv = (* statusConfig->statusChecker)(handle, cert, @@ -1411,6 +1407,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert, NEXT_USAGE(); } +loser: return(valid); } diff --git a/security/nss/lib/certhigh/manifest.mn b/security/nss/lib/certhigh/manifest.mn index bd8de3771..98eb9876d 100644 --- a/security/nss/lib/certhigh/manifest.mn +++ b/security/nss/lib/certhigh/manifest.mn @@ -43,6 +43,7 @@ EXPORTS = \ PRIVATE_EXPORTS = \ ocspti.h \ + ocspi.h \ $(NULL) MODULE = nss diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c index 9eda390b4..183f9b902 100644 --- a/security/nss/lib/certhigh/ocsp.c +++ b/security/nss/lib/certhigh/ocsp.c @@ -68,6 +68,59 @@ #include <stdarg.h> +static struct OCSPGlobalStruct { + PRLock *lock; + const SEC_HttpClientFcn *defaultHttpClientFcn; +} OCSP_Global = { NULL, NULL }; + +SECStatus +SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable) +{ + if (!OCSP_Global.lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PR_Lock(OCSP_Global.lock); + OCSP_Global.defaultHttpClientFcn = fcnTable; + PR_Unlock(OCSP_Global.lock); + + return SECSuccess; +} + +/* this function is called at NSS initialization time */ +SECStatus InitOCSPGlobal(void) +{ + if (OCSP_Global.lock != NULL) { + /* already initialized */ + return SECSuccess; + } + + OCSP_Global.lock = PR_NewLock(); + + return (OCSP_Global.lock) ? SECSuccess : SECFailure; +} + +/* + * A return value of NULL means: + * The application did not register it's own HTTP client. + */ +static const SEC_HttpClientFcn *GetRegisteredHttpClient() +{ + const SEC_HttpClientFcn *retval; + + if (!OCSP_Global.lock) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return NULL; + } + + PR_Lock(OCSP_Global.lock); + retval = OCSP_Global.defaultHttpClientFcn; + PR_Unlock(OCSP_Global.lock); + + return retval; +} + /* * The following structure is only used internally. It is allocated when * someone turns on OCSP checking, and hangs off of the status-configuration @@ -801,6 +854,7 @@ ocsp_AddServiceLocatorExtension(ocspSingleRequest *singleRequest, /* prepare for following loser gotos */ rv = SECFailure; + PORT_SetError(0); extensionHandle = cert_StartExtensions(singleRequest, singleRequest->arena, SetSingleReqExts); @@ -1702,6 +1756,8 @@ ocsp_ParseURL(char *url, char **pHostname, PRUint16 *pPort, char **pPath) path[len] = '\0'; } else { path = PORT_Strdup("/"); + if (path == NULL) + goto loser; } *pHostname = hostname; @@ -1712,8 +1768,6 @@ ocsp_ParseURL(char *url, char **pHostname, PRUint16 *pPort, char **pPath) loser: if (hostname != NULL) PORT_Free(hostname); - if (path != NULL) - PORT_Free(path); PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); return SECFailure; } @@ -2133,6 +2187,110 @@ ocsp_GetEncodedResponse(PRArenaPool *arena, PRFileDesc *sock) return result; } +/* + * Limit the size of http responses we are willing to accept. + */ +#define MAX_WANTED_OCSP_RESPONSE_LEN 64*1024 + +static SECItem * +fetchOcspHttpClientV1(PRArenaPool *arena, + const SEC_HttpClientFcnV1 *hcv1, + char *location, + SECItem *encodedRequest) +{ + char *hostname = NULL; + char *path = NULL; + PRUint16 port; + SECItem *encodedResponse = NULL; + SEC_HTTP_SERVER_SESSION pServerSession = NULL; + SEC_HTTP_REQUEST_SESSION pRequestSession = NULL; + PRUint16 myHttpResponseCode; + const char *myHttpResponseData; + PRUint32 myHttpResponseDataLen; + + if (ocsp_ParseURL(location, &hostname, &port, &path) == SECFailure) { + PORT_SetError(SEC_ERROR_OCSP_MALFORMED_REQUEST); + goto loser; + } + + PORT_Assert(hostname != NULL); + PORT_Assert(path != NULL); + + if ((*hcv1->createSessionFcn)( + hostname, + port, + &pServerSession) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + /* We use a non-zero timeout, which means: + - the client will use blocking I/O + - TryFcn will not return WOULD_BLOCK nor a poll descriptor + - it's sufficient to call TryFcn once + */ + + if ((*hcv1->createFcn)( + pServerSession, + "http", + path, + "POST", + PR_TicksPerSecond() * 60, + &pRequestSession) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + if ((*hcv1->setPostDataFcn)( + pRequestSession, + (char*)encodedRequest->data, + encodedRequest->len, + "application/ocsp-request") != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + /* we don't want result objects larger than this: */ + myHttpResponseDataLen = MAX_WANTED_OCSP_RESPONSE_LEN; + + if ((*hcv1->trySendAndReceiveFcn)( + pRequestSession, + NULL, + &myHttpResponseCode, + NULL, + NULL, + &myHttpResponseData, + &myHttpResponseDataLen) != SECSuccess) { + PORT_SetError(SEC_ERROR_OCSP_SERVER_ERROR); + goto loser; + } + + if (myHttpResponseCode != 200) { + PORT_SetError(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE); + goto loser; + } + + encodedResponse = SECITEM_AllocItem(arena, NULL, myHttpResponseDataLen); + + if (!encodedResponse) { + PORT_SetError(SEC_ERROR_NO_MEMORY); + goto loser; + } + + PORT_Memcpy(encodedResponse->data, myHttpResponseData, myHttpResponseDataLen); + +loser: + if (pRequestSession != NULL) + (*hcv1->freeFcn)(pRequestSession); + if (pServerSession != NULL) + (*hcv1->freeSessionFcn)(pServerSession); + if (path != NULL) + PORT_Free(path); + if (hostname != NULL) + PORT_Free(hostname); + + return encodedResponse; +} /* * FUNCTION: CERT_GetEncodedOCSPResponse @@ -2192,6 +2350,7 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, SECItem *encodedResponse = NULL; PRFileDesc *sock = NULL; SECStatus rv; + const SEC_HttpClientFcn *registeredHttpClient = NULL; request = CERT_CreateOCSPRequest(certList, time, addServiceLocator, signerCert); @@ -2207,11 +2366,27 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList, if (encodedRequest == NULL) goto loser; - sock = ocsp_SendEncodedRequest(location, encodedRequest); - if (sock == NULL) - goto loser; + registeredHttpClient = GetRegisteredHttpClient(); + + if (registeredHttpClient + && + registeredHttpClient->version == 1) { + encodedResponse = fetchOcspHttpClientV1( + arena, + ®isteredHttpClient->fcnTable.ftable1, + location, + encodedRequest); + } + else { + /* use internal http client */ + + sock = ocsp_SendEncodedRequest(location, encodedRequest); + if (sock == NULL) + goto loser; + + encodedResponse = ocsp_GetEncodedResponse(arena, sock); + } - encodedResponse = ocsp_GetEncodedResponse(arena, sock); if (encodedResponse != NULL && pRequest != NULL) { *pRequest = request; request = NULL; /* avoid destroying below */ @@ -2268,6 +2443,7 @@ ocsp_CertIsOCSPSigner(CERTCertificate *cert) loser: retval = PR_FALSE; + PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); goto done; success: retval = PR_TRUE; @@ -2453,7 +2629,7 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs, rv = SECFailure; if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) { /* Make the error a little more specific. */ - PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER); + PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT); } goto finish; } @@ -2504,10 +2680,9 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs, */ DER_ConvertBitString(&rawSignature); - rv = VFY_VerifyData(encodedTBS->data, encodedTBS->len, signerKey, - &rawSignature, - SECOID_GetAlgorithmTag(&signature->signatureAlgorithm), - pwArg); + rv = VFY_VerifyDataWithAlgorithmID(encodedTBS->data, encodedTBS->len, + signerKey, &rawSignature, + &signature->signatureAlgorithm, NULL, pwArg); finish: if (signature->wasChecked) @@ -2622,15 +2797,16 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response, } /* - * See if two certIDs match. This can be easy or difficult, depending - * on whether the same hash algorithm was used. + * See if the request's certID and the single response's certID match. + * This can be easy or difficult, depending on whether the same hash + * algorithm was used. */ static PRBool ocsp_CertIDsMatch(CERTCertDBHandle *handle, - CERTOCSPCertID *certID1, CERTOCSPCertID *certID2) + CERTOCSPCertID *requestCertID, + CERTOCSPCertID *responseCertID) { PRBool match = PR_FALSE; - SECItem *foundHash = NULL; SECOidTag hashAlg; SECItem *keyHash = NULL; SECItem *nameHash = NULL; @@ -2641,52 +2817,54 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle, * * We just compare the easier things first. */ - if (SECITEM_CompareItem(&certID1->serialNumber, - &certID2->serialNumber) != SECEqual) { + if (SECITEM_CompareItem(&requestCertID->serialNumber, + &responseCertID->serialNumber) != SECEqual) { goto done; } - if (SECOID_CompareAlgorithmID(&certID1->hashAlgorithm, - &certID2->hashAlgorithm) == SECEqual) { + /* + * Make sure the "parameters" are not too bogus. Since we encoded + * requestCertID->hashAlgorithm, we don't need to check it. + */ + if (responseCertID->hashAlgorithm.parameters.len > 2) { + goto done; + } + if (SECITEM_CompareItem(&requestCertID->hashAlgorithm.algorithm, + &responseCertID->hashAlgorithm.algorithm) == SECEqual) { /* * If the hash algorithms match then we can do a simple compare * of the hash values themselves. */ - if ((SECITEM_CompareItem(&certID1->issuerNameHash, - &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(&certID1->issuerKeyHash, - &certID2->issuerKeyHash) == SECEqual)) { + if ((SECITEM_CompareItem(&requestCertID->issuerNameHash, + &responseCertID->issuerNameHash) == SECEqual) + && (SECITEM_CompareItem(&requestCertID->issuerKeyHash, + &responseCertID->issuerKeyHash) == SECEqual)) { match = PR_TRUE; } goto done; } - hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm); + hashAlg = SECOID_FindOIDTag(&responseCertID->hashAlgorithm.algorithm); switch (hashAlg) { case SEC_OID_SHA1: - keyHash = &certID1->issuerSHA1KeyHash; - nameHash = &certID1->issuerSHA1NameHash; + keyHash = &requestCertID->issuerSHA1KeyHash; + nameHash = &requestCertID->issuerSHA1NameHash; break; case SEC_OID_MD5: - keyHash = &certID1->issuerMD5KeyHash; - nameHash = &certID1->issuerMD5NameHash; + keyHash = &requestCertID->issuerMD5KeyHash; + nameHash = &requestCertID->issuerMD5NameHash; break; case SEC_OID_MD2: - keyHash = &certID1->issuerMD2KeyHash; - nameHash = &certID1->issuerMD2NameHash; - break; - default: - foundHash = NULL; + keyHash = &requestCertID->issuerMD2KeyHash; + nameHash = &requestCertID->issuerMD2NameHash; break; } - if (foundHash == NULL) { - goto done; - } - PORT_Assert(keyHash && nameHash); - - if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual) - && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) { + if ((keyHash != NULL) + && (SECITEM_CompareItem(nameHash, + &responseCertID->issuerNameHash) == SECEqual) + && (SECITEM_CompareItem(keyHash, + &responseCertID->issuerKeyHash) == SECEqual)) { match = PR_TRUE; } @@ -3025,7 +3203,7 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single, * char * * A copy of the URI for the OCSP method, if found. If either the * extension is not present or it does not contain an entry for OCSP, - * SEC_ERROR_EXTENSION_NOT_FOUND will be set and a NULL returned. + * SEC_ERROR_CERT_BAD_ACCESS_LOCATION will be set and a NULL returned. * Any other error will also result in a NULL being returned. * * This result should be freed (via PORT_Free) when no longer in use. @@ -3053,8 +3231,10 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) rv = CERT_FindCertExtension(cert, SEC_OID_X509_AUTH_INFO_ACCESS, encodedAuthInfoAccess); - if (rv == SECFailure) + if (rv == SECFailure) { + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; + } /* * The rest of the things allocated in the routine will come out of @@ -3084,7 +3264,7 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) * not there at all. */ if (locname == NULL) { - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; } @@ -3101,7 +3281,7 @@ CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert) * this should probably be something more like the extension was * badly formed. */ - PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND); + PORT_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION); goto loser; } @@ -3307,10 +3487,13 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, */ location = ocsp_GetResponderLocation(handle, cert, &locationIsDefault); if (location == NULL) { - if (PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND) + int err = PORT_GetError(); + if (err == SEC_ERROR_EXTENSION_NOT_FOUND || + err == SEC_ERROR_CERT_BAD_ACCESS_LOCATION) { + PORT_SetError(0); return SECSuccess; - else - return SECFailure; + } + return SECFailure; } /* @@ -3590,8 +3773,6 @@ ocsp_InitStatusChecking(CERTCertDBHandle *handle) return SECSuccess; loser: - if (statusContext != NULL) - PORT_Free(statusContext); if (statusConfig != NULL) PORT_Free(statusConfig); return SECFailure; diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h index c188f6780..810bc010c 100644 --- a/security/nss/lib/certhigh/ocsp.h +++ b/security/nss/lib/certhigh/ocsp.h @@ -56,6 +56,18 @@ SEC_BEGIN_PROTOS /* + * This function registers the HttpClient with whose functions the + * HttpClientFcn structure have been populated as the default Http + * client. + * + * The function table must be a global object. + * The caller must ensure that NSS will be able to call + * the registered functions for the lifetime of the process. + */ +extern SECStatus +SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable); + +/* * FUNCTION: CERT_EnableOCSPChecking * Turns on OCSP checking for the given certificate database. * INPUTS: diff --git a/security/nss/lib/certhigh/ocspi.h b/security/nss/lib/certhigh/ocspi.h new file mode 100644 index 000000000..a1c1ccb78 --- /dev/null +++ b/security/nss/lib/certhigh/ocspi.h @@ -0,0 +1,47 @@ +/* ***** 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 ***** */ +/* + * ocspi.h - NSS internal interfaces to OCSP code + * + * $Id$ + */ + +#ifndef _OCSPI_H_ +#define _OCSPI_H_ + +SECStatus InitOCSPGlobal(void); + +#endif /* _OCSPI_H_ */ diff --git a/security/nss/lib/certhigh/ocspt.h b/security/nss/lib/certhigh/ocspt.h index 5171d9cdb..18ca8ecb6 100644 --- a/security/nss/lib/certhigh/ocspt.h +++ b/security/nss/lib/certhigh/ocspt.h @@ -59,4 +59,235 @@ typedef struct CERTOCSPCertIDStr CERTOCSPCertID; typedef struct CERTOCSPCertStatusStr CERTOCSPCertStatus; typedef struct CERTOCSPSingleResponseStr CERTOCSPSingleResponse; +/* + * This interface is described in terms of an HttpClient which + * supports at least a specified set of functions. (An implementer may + * provide HttpClients with additional functionality accessible only to + * users with a particular implementation in mind.) The basic behavior + * is provided by defining a set of functions, listed in an + * SEC_HttpServerFcnStruct. If the implementor of a SpecificHttpClient + * registers his SpecificHttpClient as the default HttpClient, then his + * functions will be called by the user of an HttpClient, such as an + * OCSPChecker. + * + * The implementer of a specific HttpClient (e.g., the NSS-provided + * DefaultHttpClient), populates an SEC_HttpClientFcnStruct, uses it to + * register his client, and waits for his functions to be called. + * + * For future expandability, the SEC_HttpClientFcnStruct is defined as a + * union, with the version field acting as a selector. The proposed + * initial version of the structure is given following the definition + * of the union. The HttpClientState structure is implementation- + * dependent, and should be opaque to the user. + */ + +typedef void * SEC_HTTP_SERVER_SESSION; +typedef void * SEC_HTTP_REQUEST_SESSION; + +/* + * This function creates a SEC_HTTP_SERVER_SESSION object. The implementer of a + * specific HttpClient will allocate the necessary space, when this + * function is called, and will free it when the corresponding FreeFcn + * is called. The SEC_HTTP_SERVER_SESSION object is passed, as an opaque object, + * to subsequent calls. + * + * If the function returns SECSuccess, the returned SEC_HTTP_SERVER_SESSION + * must be cleaned up with a call to SEC_HttpServer_FreeSession, + * after processing is finished. + */ +typedef SECStatus (*SEC_HttpServer_CreateSessionFcn)( + const char *host, + PRUint16 portnum, + SEC_HTTP_SERVER_SESSION *pSession); + +/* + * This function is called to allow the implementation to attempt to keep + * the connection alive. Depending on the underlying platform, it might + * immediately return SECSuccess without having performed any operations. + * (If a connection has not been kept alive, a subsequent call to + * SEC_HttpRequest_TrySendAndReceiveFcn should reopen the connection + * automatically.) + * + * If the connection uses nonblocking I/O, this function may return + * SECWouldBlock and store a nonzero value at "pPollDesc". In that case + * the caller may wait on the poll descriptor, and should call this function + * again until SECSuccess (and a zero value at "pPollDesc") is obtained. + */ +typedef SECStatus (*SEC_HttpServer_KeepAliveSessionFcn)( + SEC_HTTP_SERVER_SESSION session, + PRPollDesc **pPollDesc); + +/* + * This function frees the client SEC_HTTP_SERVER_SESSION object, closes all + * SEC_HTTP_REQUEST_SESSIONs created for that server, discards all partial results, + * frees any memory that was allocated by the client, and invalidates any + * response pointers that might have been returned by prior server or request + * functions. + */ +typedef SECStatus (*SEC_HttpServer_FreeSessionFcn)( + SEC_HTTP_SERVER_SESSION session); + +/* + * This function creates a SEC_HTTP_REQUEST_SESSION object. The implementer of a + * specific HttpClient will allocate the necessary space, when this + * function is called, and will free it when the corresponding FreeFcn + * is called. The SEC_HTTP_REQUEST_SESSION object is passed, as an opaque object, + * to subsequent calls. + * + * An implementation that does not support the requested protocol variant + * (usually "http", but could eventually allow "https") or request method + * should return SECFailure. + * + * Timeout values may include the constants PR_INTERVAL_NO_TIMEOUT (wait + * forever) or PR_INTERVAL_NO_WAIT (nonblocking I/O). + * + * If the function returns SECSuccess, the returned SEC_HTTP_REQUEST_SESSION + * must be cleaned up with a call to SEC_HttpRequest_FreeSession, + * after processing is finished. + */ +typedef SECStatus (*SEC_HttpRequest_CreateFcn)( + SEC_HTTP_SERVER_SESSION session, + const char *http_protocol_variant, /* usually "http" */ + const char *path_and_query_string, + const char *http_request_method, + const PRIntervalTime timeout, + SEC_HTTP_REQUEST_SESSION *pRequest); + +/* + * This function sets data to be sent to the server for an HTTP request + * of http_request_method == POST. If a particular implementation + * supports it, the details for the POST request can be set by calling + * this function, prior to activating the request with TrySendAndReceiveFcn. + * + * An implementation that does not support the POST method should + * implement a SetPostDataFcn function that returns immediately. + * + * Setting http_content_type is optional, the parameter may + * by NULL or the empty string. + */ +typedef SECStatus (*SEC_HttpRequest_SetPostDataFcn)( + SEC_HTTP_REQUEST_SESSION request, + const char *http_data, + const PRUint32 http_data_len, + const char *http_content_type); + +/* + * This function sets an additional HTTP protocol request header. + * If a particular implementation supports it, one or multiple headers + * can be added to the request by calling this function once or multiple + * times, prior to activating the request with TryFcn. + * + * An implementation that does not support setting additional headers + * should implement an AddRequestHeaderFcn function that returns immediately. + */ +typedef SECStatus (*SEC_HttpRequest_AddHeaderFcn)( + SEC_HTTP_REQUEST_SESSION request, + const char *http_header_name, + const char *http_header_value); + +/* + * This function initiates or continues an HTTP request. After + * parameters have been set with the Create function and, optionally, + * modified or enhanced with the AddParams function, this call creates + * the socket connection and initiates the communication. + * + * If a timeout value of zero is specified, indicating non-blocking + * I/O, the client creates a non-blocking socket, and returns a status + * of SECWouldBlock and a non-NULL PRPollDesc if the operation is not + * complete. In that case all other return parameters are undefined. + * The caller is expected to repeat the call, possibly after using + * PRPoll to determine that a completion has occurred, until a return + * value of SECSuccess (and a NULL value for pPollDesc) or a return + * value of SECFailure (indicating failure on the network level) + * is obtained. + * + * http_response_data_len is both input and output parameter. + * If a pointer to a PRUint32 is supplied, the http client is + * expected to check the given integer value and always set an out + * value, even on failure. + * An input value of zero means, the caller will accept any response len. + * A different input value indicates the maximum response value acceptable + * to the caller. + * If data is successfully read and the size is acceptable to the caller, + * the function will return SECSuccess and set http_response_data_len to + * the size of the block returned in http_response_data. + * If the data read from the http server is larger than the acceptable + * size, the function will return SECFailure. + * http_response_data_len will be set to a value different from zero to + * indicate the reason of the failure. + * An out value of "0" means, the failure was unrelated to the + * acceptable size. + * An out value of "1" means, the result data is larger than the + * accpeptable size, but the real size is not yet known to the http client + * implementation and it stopped retrieving it, + * Any other out value combined with a return value of SECFailure + * will indicate the actual size of the server data. + * + * The caller is permitted to provide NULL values for any of the + * http_response arguments, indicating the caller is not interested in + * those values. If the caller does provide an address, the HttpClient + * stores at that address a pointer to the corresponding argument, at + * the completion of the operation. + * + * All returned pointers will be owned by the the HttpClient + * implementation and will remain valid until the call to + * SEC_HttpRequest_FreeFcn. + */ +typedef SECStatus (*SEC_HttpRequest_TrySendAndReceiveFcn)( + SEC_HTTP_REQUEST_SESSION request, + PRPollDesc **pPollDesc, + PRUint16 *http_response_code, + const char **http_response_content_type, + const char **http_response_headers, + const char **http_response_data, + PRUint32 *http_response_data_len); + +/* + * Calling CancelFcn asks for premature termination of the request. + * + * Future calls to SEC_HttpRequest_TrySendAndReceive should + * by avoided, but in this case the HttpClient implementation + * is expected to return immediately with SECFailure. + * + * After calling CancelFcn, a separate call to SEC_HttpRequest_FreeFcn + * is still necessary to free resources. + */ +typedef SECStatus (*SEC_HttpRequest_CancelFcn)( + SEC_HTTP_REQUEST_SESSION request); + +/* + * Before calling this function, it must be assured the request + * has been completed, i.e. either SEC_HttpRequest_TrySendAndReceiveFcn has + * returned SECSuccess, or the request has been canceled with + * a call to SEC_HttpRequest_CancelFcn. + * + * This function frees the client state object, closes all sockets, + * discards all partial results, frees any memory that was allocated + * by the client, and invalidates all response pointers that might + * have been returned by SEC_HttpRequest_TrySendAndReceiveFcn + */ +typedef SECStatus (*SEC_HttpRequest_FreeFcn)( + SEC_HTTP_REQUEST_SESSION request); + +typedef struct SEC_HttpClientFcnV1Struct { + SEC_HttpServer_CreateSessionFcn createSessionFcn; + SEC_HttpServer_KeepAliveSessionFcn keepAliveSessionFcn; + SEC_HttpServer_FreeSessionFcn freeSessionFcn; + SEC_HttpRequest_CreateFcn createFcn; + SEC_HttpRequest_SetPostDataFcn setPostDataFcn; + SEC_HttpRequest_AddHeaderFcn addHeaderFcn; + SEC_HttpRequest_TrySendAndReceiveFcn trySendAndReceiveFcn; + SEC_HttpRequest_CancelFcn cancelFcn; + SEC_HttpRequest_FreeFcn freeFcn; +} SEC_HttpClientFcnV1; + +typedef struct SEC_HttpClientFcnStruct { + PRInt16 version; + union { + SEC_HttpClientFcnV1 ftable1; + /* SEC_HttpClientFcnV2 ftable2; */ + /* ... */ + } fcnTable; +} SEC_HttpClientFcn; + #endif /* _OCSPT_H_ */ diff --git a/security/nss/lib/ckfw/builtins/binst.c b/security/nss/lib/ckfw/builtins/binst.c index 2df0777a0..2d912f4a4 100644 --- a/security/nss/lib/ckfw/builtins/binst.c +++ b/security/nss/lib/ckfw/builtins/binst.c @@ -101,6 +101,11 @@ builtins_mdInstance_GetLibraryVersion NSSCKFWInstance *fwInstance ) { + extern const char __nss_builtins_rcsid[]; + extern const char __nss_builtins_sccsid[]; + volatile char c; /* force a reference that won't get optimized away */ + + c = __nss_builtins_rcsid[0] + __nss_builtins_sccsid[0]; return nss_builtins_LibraryVersion; } diff --git a/security/nss/lib/ckfw/builtins/certdata.c b/security/nss/lib/ckfw/builtins/certdata.c index ca3d68970..c8f3dde8e 100644 --- a/security/nss/lib/ckfw/builtins/certdata.c +++ b/security/nss/lib/ckfw/builtins/certdata.c @@ -623,6 +623,60 @@ static const CK_ATTRIBUTE_TYPE nss_builtins_types_188 [] = { static const CK_ATTRIBUTE_TYPE nss_builtins_types_189 [] = { CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED }; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_190 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_191 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_192 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_193 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_194 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_195 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_196 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_197 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_198 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_199 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_200 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_201 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_202 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_203 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_204 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_205 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_206 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERTIFICATE_TYPE, CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_VALUE +}; +static const CK_ATTRIBUTE_TYPE nss_builtins_types_207 [] = { + CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL, CKA_CERT_SHA1_HASH, CKA_CERT_MD5_HASH, CKA_ISSUER, CKA_SERIAL_NUMBER, CKA_TRUST_SERVER_AUTH, CKA_TRUST_EMAIL_PROTECTION, CKA_TRUST_CODE_SIGNING, CKA_TRUST_STEP_UP_APPROVED +}; #ifdef DEBUG static const NSSItem nss_builtins_items_0 [] = { { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) }, @@ -631,7 +685,7 @@ static const NSSItem nss_builtins_items_0 [] = { { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)"CVS ID", (PRUint32)7 }, { (void *)"NSS", (PRUint32)4 }, - { (void *)"@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$", (PRUint32)160 } + { (void *)"@(#) $RCSfile$ $Revision$ $Date$""; @(#) $RCSfile$ $Revision$ $Date$", (PRUint32)165 } }; #endif /* DEBUG */ static const NSSItem nss_builtins_items_1 [] = { @@ -7566,6 +7620,379 @@ static const NSSItem nss_builtins_items_118 [] = { { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Global CA 2", (PRUint32)21 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\003\146\060\202\002\116\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003\023" +"\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141\154" +"\040\103\101\040\062\060\036\027\015\060\064\060\063\060\064\060" +"\065\060\060\060\060\132\027\015\061\071\060\063\060\064\060\065" +"\060\060\060\060\132\060\104\061\013\060\011\006\003\125\004\006" +"\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107" +"\145\157\124\162\165\163\164\040\111\156\143\056\061\035\060\033" +"\006\003\125\004\003\023\024\107\145\157\124\162\165\163\164\040" +"\107\154\157\142\141\154\040\103\101\040\062\060\202\001\042\060" +"\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202" +"\001\017\000\060\202\001\012\002\202\001\001\000\357\074\115\100" +"\075\020\337\073\123\000\341\147\376\224\140\025\076\205\210\361" +"\211\015\220\310\050\043\231\005\350\053\040\235\306\363\140\106" +"\330\301\262\325\214\061\331\334\040\171\044\201\277\065\062\374" +"\143\151\333\261\052\153\356\041\130\362\010\351\170\313\157\313" +"\374\026\122\310\221\304\377\075\163\336\261\076\247\302\175\146" +"\301\365\176\122\044\032\342\325\147\221\320\202\020\327\170\113" +"\117\053\102\071\275\144\055\100\240\260\020\323\070\110\106\210" +"\241\014\273\072\063\052\142\230\373\000\235\023\131\177\157\073" +"\162\252\356\246\017\206\371\005\141\352\147\177\014\067\226\213" +"\346\151\026\107\021\302\047\131\003\263\246\140\302\041\100\126" +"\372\240\307\175\072\023\343\354\127\307\263\326\256\235\211\200" +"\367\001\347\054\366\226\053\023\015\171\054\331\300\344\206\173" +"\113\214\014\162\202\212\373\027\315\000\154\072\023\074\260\204" +"\207\113\026\172\051\262\117\333\035\324\013\363\146\067\275\330" +"\366\127\273\136\044\172\270\074\213\271\372\222\032\032\204\236" +"\330\164\217\252\033\177\136\364\376\105\042\041\002\003\001\000" +"\001\243\143\060\141\060\017\006\003\125\035\023\001\001\377\004" +"\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004" +"\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251\020" +"\025\130\040\005\011\060\037\006\003\125\035\043\004\030\060\026" +"\200\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251" +"\020\025\130\040\005\011\060\016\006\003\125\035\017\001\001\377" +"\004\004\003\002\001\206\060\015\006\011\052\206\110\206\367\015" +"\001\001\005\005\000\003\202\001\001\000\003\367\265\053\253\135" +"\020\374\173\262\262\136\254\233\016\176\123\170\131\076\102\004" +"\376\165\243\255\254\201\116\327\002\213\136\304\055\310\122\166" +"\307\054\037\374\201\062\230\321\113\306\222\223\063\065\061\057" +"\374\330\035\104\335\340\201\177\235\351\213\341\144\221\142\013" +"\071\010\214\254\164\235\131\331\172\131\122\227\021\271\026\173" +"\157\105\323\226\331\061\175\002\066\017\234\073\156\317\054\015" +"\003\106\105\353\240\364\177\110\104\306\010\100\314\336\033\160" +"\265\051\255\272\213\073\064\145\165\033\161\041\035\054\024\012" +"\260\226\225\270\326\352\362\145\373\051\272\117\352\221\223\164" +"\151\266\362\377\341\032\320\014\321\166\205\313\212\045\275\227" +"\136\054\157\025\231\046\347\266\051\377\042\354\311\002\307\126" +"\000\315\111\271\263\154\173\123\004\032\342\250\311\252\022\005" +"\043\302\316\347\273\004\002\314\300\107\242\344\304\051\057\133" +"\105\127\211\121\356\074\353\122\010\377\007\065\036\237\065\152" +"\107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363" +"\342\042\051\256\175\203\100\250\272\154" +, (PRUint32)874 } +}; +static const NSSItem nss_builtins_items_119 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Global CA 2", (PRUint32)21 }, + { (void *)"\251\351\170\010\024\067\130\210\362\005\031\260\155\053\015\053" +"\140\026\220\175" +, (PRUint32)20 }, + { (void *)"\016\100\247\154\336\003\135\217\321\017\344\321\215\371\154\251" +, (PRUint32)16 }, + { (void *)"\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003" +"\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141" +"\154\040\103\101\040\062" +, (PRUint32)70 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_120 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA", (PRUint32)22 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\005\150\060\202\003\120\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003\023" +"\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162" +"\163\141\154\040\103\101\060\036\027\015\060\064\060\063\060\064" +"\060\065\060\060\060\060\132\027\015\062\071\060\063\060\064\060" +"\065\060\060\060\060\132\060\105\061\013\060\011\006\003\125\004" +"\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015" +"\107\145\157\124\162\165\163\164\040\111\156\143\056\061\036\060" +"\034\006\003\125\004\003\023\025\107\145\157\124\162\165\163\164" +"\040\125\156\151\166\145\162\163\141\154\040\103\101\060\202\002" +"\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000" +"\003\202\002\017\000\060\202\002\012\002\202\002\001\000\246\025" +"\125\240\243\306\340\037\214\235\041\120\327\301\276\053\133\265" +"\244\236\241\331\162\130\275\000\033\114\277\141\311\024\035\105" +"\202\253\306\035\200\326\075\353\020\234\072\257\155\044\370\274" +"\161\001\236\006\365\174\137\036\301\016\125\312\203\232\131\060" +"\256\031\313\060\110\225\355\042\067\215\364\112\232\162\146\076" +"\255\225\300\340\026\000\340\020\037\053\061\016\327\224\124\323" +"\102\063\240\064\035\036\105\166\335\117\312\030\067\354\205\025" +"\172\031\010\374\325\307\234\360\362\251\056\020\251\222\346\075" +"\130\075\251\026\150\074\057\165\041\030\177\050\167\245\341\141" +"\027\267\246\351\370\036\231\333\163\156\364\012\242\041\154\356" +"\332\252\205\222\146\257\366\172\153\202\332\272\042\010\065\017" +"\317\102\361\065\372\152\356\176\053\045\314\072\021\344\155\257" +"\163\262\166\035\255\320\262\170\147\032\244\071\034\121\013\147" +"\126\203\375\070\135\015\316\335\360\273\053\226\037\336\173\062" +"\122\375\035\273\265\006\241\262\041\136\245\326\225\150\177\360" +"\231\236\334\105\010\076\347\322\011\015\065\224\335\200\116\123" +"\227\327\265\011\104\040\144\026\027\003\002\114\123\015\150\336" +"\325\252\162\115\223\155\202\016\333\234\275\317\264\363\134\135" +"\124\172\151\011\226\326\333\021\301\215\165\250\264\317\071\310" +"\316\074\274\044\174\346\142\312\341\275\175\247\275\127\145\013" +"\344\376\045\355\266\151\020\334\050\032\106\275\001\035\320\227" +"\265\341\230\073\300\067\144\326\075\224\356\013\341\365\050\256" +"\013\126\277\161\213\043\051\101\216\206\305\113\122\173\330\161" +"\253\037\212\025\246\073\203\132\327\130\001\121\306\114\101\331" +"\177\330\101\147\162\242\050\337\140\203\251\236\310\173\374\123" +"\163\162\131\365\223\172\027\166\016\316\367\345\134\331\013\125" +"\064\242\252\133\265\152\124\347\023\312\127\354\227\155\364\136" +"\006\057\105\213\130\324\043\026\222\344\026\156\050\143\131\060" +"\337\120\001\234\143\211\032\237\333\027\224\202\160\067\303\044" +"\236\232\107\326\132\312\116\250\151\211\162\037\221\154\333\176" +"\236\033\255\307\037\163\335\054\117\031\145\375\177\223\100\020" +"\056\322\360\355\074\236\056\050\076\151\046\063\305\173\002\003" +"\001\000\001\243\143\060\141\060\017\006\003\125\035\023\001\001" +"\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004" +"\026\004\024\332\273\056\252\260\014\270\210\046\121\164\134\155" +"\003\323\300\330\217\172\326\060\037\006\003\125\035\043\004\030" +"\060\026\200\024\332\273\056\252\260\014\270\210\046\121\164\134" +"\155\003\323\300\330\217\172\326\060\016\006\003\125\035\017\001" +"\001\377\004\004\003\002\001\206\060\015\006\011\052\206\110\206" +"\367\015\001\001\005\005\000\003\202\002\001\000\061\170\346\307" +"\265\337\270\224\100\311\161\304\250\065\354\106\035\302\205\363" +"\050\130\206\260\013\374\216\262\071\217\104\125\253\144\204\134" +"\151\251\320\232\070\074\372\345\037\065\345\104\343\200\171\224" +"\150\244\273\304\237\075\341\064\315\060\106\213\124\053\225\245" +"\357\367\077\231\204\375\065\346\317\061\306\334\152\277\247\327" +"\043\010\341\230\136\303\132\010\166\251\246\257\167\057\267\140" +"\275\104\106\152\357\227\377\163\225\301\216\350\223\373\375\061" +"\267\354\127\021\021\105\233\060\361\032\210\071\301\117\074\247" +"\000\325\307\374\253\155\200\042\160\245\014\340\135\004\051\002" +"\373\313\240\221\321\174\326\303\176\120\325\235\130\276\101\070" +"\353\271\165\074\025\331\233\311\112\203\131\300\332\123\375\063" +"\273\066\030\233\205\017\025\335\356\055\254\166\223\271\331\001" +"\215\110\020\250\373\365\070\206\361\333\012\306\275\204\243\043" +"\101\336\326\167\157\205\324\205\034\120\340\256\121\212\272\215" +"\076\166\342\271\312\047\362\137\237\357\156\131\015\006\330\053" +"\027\244\322\174\153\273\137\024\032\110\217\032\114\347\263\107" +"\034\216\114\105\053\040\356\110\337\347\335\011\216\030\250\332" +"\100\215\222\046\021\123\141\163\135\353\275\347\304\115\051\067" +"\141\353\254\071\055\147\056\026\326\365\000\203\205\241\314\177" +"\166\304\175\344\267\113\146\357\003\105\140\151\266\014\122\226" +"\222\204\136\246\243\265\244\076\053\331\314\330\033\107\252\362" +"\104\332\117\371\003\350\360\024\313\077\363\203\336\320\301\124" +"\343\267\350\012\067\115\213\040\131\003\060\031\241\054\310\275" +"\021\037\337\256\311\112\305\363\047\146\146\206\254\150\221\377" +"\331\346\123\034\017\213\134\151\145\012\046\310\036\064\303\135" +"\121\173\327\251\234\006\241\066\335\325\211\224\274\331\344\055" +"\014\136\011\154\010\227\174\243\075\174\223\377\077\241\024\247" +"\317\265\135\353\333\333\034\304\166\337\210\271\275\105\005\225" +"\033\256\374\106\152\114\257\110\343\316\256\017\322\176\353\346" +"\154\234\117\201\152\172\144\254\273\076\325\347\313\166\056\305" +"\247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157" +"\244\346\216\330\371\051\110\212\316\163\376\054" +, (PRUint32)1388 } +}; +static const NSSItem nss_builtins_items_121 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA", (PRUint32)22 }, + { (void *)"\346\041\363\065\103\171\005\232\113\150\060\235\212\057\164\042" +"\025\207\354\171" +, (PRUint32)20 }, + { (void *)"\222\145\130\213\242\032\061\162\163\150\134\264\245\172\007\110" +, (PRUint32)16 }, + { (void *)"\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003" +"\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101" +, (PRUint32)71 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_122 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA 2", (PRUint32)24 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\005\154\060\202\003\124\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026" +"\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163" +"\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003\023" +"\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162" +"\163\141\154\040\103\101\040\062\060\036\027\015\060\064\060\063" +"\060\064\060\065\060\060\060\060\132\027\015\062\071\060\063\060" +"\064\060\065\060\060\060\060\132\060\107\061\013\060\011\006\003" +"\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012" +"\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061" +"\040\060\036\006\003\125\004\003\023\027\107\145\157\124\162\165" +"\163\164\040\125\156\151\166\145\162\163\141\154\040\103\101\040" +"\062\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001" +"\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002" +"\001\000\263\124\122\301\311\076\362\331\334\261\123\032\131\051" +"\347\261\303\105\050\345\327\321\355\305\305\113\241\252\164\173" +"\127\257\112\046\374\330\365\136\247\156\031\333\164\014\117\065" +"\133\062\013\001\343\333\353\172\167\065\352\252\132\340\326\350" +"\241\127\224\360\220\243\164\126\224\104\060\003\036\134\116\053" +"\205\046\164\202\172\014\166\240\157\115\316\101\055\240\025\006" +"\024\137\267\102\315\173\217\130\141\064\334\052\010\371\056\303" +"\001\246\042\104\034\114\007\202\346\133\316\320\112\174\004\323" +"\031\163\047\360\252\230\177\056\257\116\353\207\036\044\167\152" +"\135\266\350\133\105\272\334\303\241\005\157\126\216\217\020\046" +"\245\111\303\056\327\101\207\042\340\117\206\312\140\265\352\241" +"\143\300\001\227\020\171\275\000\074\022\155\053\025\261\254\113" +"\261\356\030\271\116\226\334\334\166\377\073\276\317\137\003\300" +"\374\073\350\276\106\033\377\332\100\302\122\367\376\343\072\367" +"\152\167\065\320\332\215\353\136\030\152\061\307\036\272\074\033" +"\050\326\153\124\306\252\133\327\242\054\033\031\314\242\002\366" +"\233\131\275\067\153\206\265\155\202\272\330\352\311\126\274\251" +"\066\130\375\076\031\363\355\014\046\251\223\070\370\117\301\135" +"\042\006\320\227\352\341\255\306\125\340\201\053\050\203\072\372" +"\364\173\041\121\000\276\122\070\316\315\146\171\250\364\201\126" +"\342\320\203\011\107\121\133\120\152\317\333\110\032\135\076\367" +"\313\366\145\367\154\361\225\370\002\073\062\126\202\071\172\133" +"\275\057\211\033\277\241\264\350\377\177\215\214\337\003\361\140" +"\116\130\021\114\353\243\077\020\053\203\232\001\163\331\224\155" +"\204\000\047\146\254\360\160\100\011\102\222\255\117\223\015\141" +"\011\121\044\330\222\325\013\224\141\262\207\262\355\377\232\065" +"\377\205\124\312\355\104\103\254\033\074\026\153\110\112\012\034" +"\100\210\037\222\302\013\000\005\377\362\310\002\112\244\252\251" +"\314\231\226\234\057\130\340\175\341\276\273\007\334\137\004\162" +"\134\061\064\303\354\137\055\340\075\144\220\042\346\321\354\270" +"\056\335\131\256\331\241\067\277\124\065\334\163\062\117\214\004" +"\036\063\262\311\106\361\330\134\310\125\120\311\150\275\250\272" +"\066\011\002\003\001\000\001\243\143\060\141\060\017\006\003\125" +"\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003" +"\125\035\016\004\026\004\024\166\363\125\341\372\244\066\373\360" +"\237\134\142\161\355\074\364\107\070\020\053\060\037\006\003\125" +"\035\043\004\030\060\026\200\024\166\363\125\341\372\244\066\373" +"\360\237\134\142\161\355\074\364\107\070\020\053\060\016\006\003" +"\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011" +"\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000" +"\146\301\306\043\363\331\340\056\156\137\350\317\256\260\260\045" +"\115\053\370\073\130\233\100\044\067\132\313\253\026\111\377\263" +"\165\171\063\241\057\155\160\027\064\221\376\147\176\217\354\233" +"\345\136\202\251\125\037\057\334\324\121\007\022\376\254\026\076" +"\054\065\306\143\374\334\020\353\015\243\252\320\174\314\321\320" +"\057\121\056\304\024\132\336\350\031\341\076\306\314\244\051\347" +"\056\204\252\006\060\170\166\124\163\050\230\131\070\340\000\015" +"\142\323\102\175\041\237\256\075\072\214\325\372\167\015\030\053" +"\026\016\137\066\341\374\052\265\060\044\317\340\143\014\173\130" +"\032\376\231\272\102\022\261\221\364\174\150\342\310\350\257\054" +"\352\311\176\256\273\052\075\015\025\334\064\225\266\030\164\250" +"\152\017\307\264\364\023\304\344\133\355\012\322\244\227\114\052" +"\355\057\154\022\211\075\361\047\160\252\152\003\122\041\237\100" +"\250\147\120\362\363\132\037\337\337\043\366\334\170\116\346\230" +"\117\125\072\123\343\357\362\364\237\307\174\330\130\257\051\042" +"\227\270\340\275\221\056\260\166\354\127\021\317\357\051\104\363" +"\351\205\172\140\143\344\135\063\211\027\331\061\252\332\326\363" +"\030\065\162\317\207\053\057\143\043\204\135\204\214\077\127\240" +"\210\374\231\221\050\046\151\231\324\217\227\104\276\216\325\110" +"\261\244\050\051\361\025\264\341\345\236\335\370\217\246\157\046" +"\327\011\074\072\034\021\016\246\154\067\367\255\104\207\054\050" +"\307\330\164\202\263\320\157\112\127\273\065\051\047\240\213\350" +"\041\247\207\144\066\135\314\330\026\254\307\262\047\100\222\125" +"\070\050\215\121\156\335\024\147\123\154\161\134\046\204\115\165" +"\132\266\176\140\126\251\115\255\373\233\036\227\363\015\331\322" +"\227\124\167\332\075\022\267\340\036\357\010\006\254\371\205\207" +"\351\242\334\257\176\030\022\203\375\126\027\101\056\325\051\202" +"\175\231\364\061\366\161\251\317\054\001\047\245\005\271\252\262" +"\110\116\052\357\237\223\122\121\225\074\122\163\216\126\114\027" +"\100\300\011\050\344\213\152\110\123\333\354\315\125\125\361\306" +"\370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246" +"\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222" +, (PRUint32)1392 } +}; +static const NSSItem nss_builtins_items_123 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"GeoTrust Universal CA 2", (PRUint32)24 }, + { (void *)"\067\232\031\173\101\205\105\065\014\246\003\151\363\074\056\257" +"\107\117\040\171" +, (PRUint32)20 }, + { (void *)"\064\374\270\320\066\333\236\024\263\302\362\333\217\344\224\307" +, (PRUint32)16 }, + { (void *)"\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061" +"\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165" +"\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003" +"\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145" +"\162\163\141\154\040\103\101\040\062" +, (PRUint32)73 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_124 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, { (void *)"UTN-USER First-Network Applications", (PRUint32)36 }, { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, { (void *)"\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123" @@ -7669,7 +8096,7 @@ static const NSSItem nss_builtins_items_118 [] = { "\152\372\246\070\254\037\304\204" , (PRUint32)1128 } }; -static const NSSItem nss_builtins_items_119 [] = { +static const NSSItem nss_builtins_items_125 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7700,7 +8127,7 @@ static const NSSItem nss_builtins_items_119 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_120 [] = { +static const NSSItem nss_builtins_items_126 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7787,7 +8214,7 @@ static const NSSItem nss_builtins_items_120 [] = { "\200\072\231\355\165\314\106\173" , (PRUint32)936 } }; -static const NSSItem nss_builtins_items_121 [] = { +static const NSSItem nss_builtins_items_127 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7813,7 +8240,7 @@ static const NSSItem nss_builtins_items_121 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_122 [] = { +static const NSSItem nss_builtins_items_128 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7932,7 +8359,7 @@ static const NSSItem nss_builtins_items_122 [] = { "\105\217\046\221\242\216\376\251" , (PRUint32)1448 } }; -static const NSSItem nss_builtins_items_123 [] = { +static const NSSItem nss_builtins_items_129 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -7958,7 +8385,7 @@ static const NSSItem nss_builtins_items_123 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_124 [] = { +static const NSSItem nss_builtins_items_130 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8046,7 +8473,7 @@ static const NSSItem nss_builtins_items_124 [] = { "\222\340\134\366\007\017" , (PRUint32)934 } }; -static const NSSItem nss_builtins_items_125 [] = { +static const NSSItem nss_builtins_items_131 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8073,7 +8500,7 @@ static const NSSItem nss_builtins_items_125 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_126 [] = { +static const NSSItem nss_builtins_items_132 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8165,7 +8592,7 @@ static const NSSItem nss_builtins_items_126 [] = { "\367\115\146\177\247\360\034\001\046\170\262\146\107\160\121\144" , (PRUint32)864 } }; -static const NSSItem nss_builtins_items_127 [] = { +static const NSSItem nss_builtins_items_133 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8196,7 +8623,7 @@ static const NSSItem nss_builtins_items_127 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_128 [] = { +static const NSSItem nss_builtins_items_134 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8288,7 +8715,7 @@ static const NSSItem nss_builtins_items_128 [] = { "\030\122\051\213\107\064\022\011\324\273\222\065\357\017\333\064" , (PRUint32)864 } }; -static const NSSItem nss_builtins_items_129 [] = { +static const NSSItem nss_builtins_items_135 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8319,7 +8746,7 @@ static const NSSItem nss_builtins_items_129 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_130 [] = { +static const NSSItem nss_builtins_items_136 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8390,7 +8817,7 @@ static const NSSItem nss_builtins_items_130 [] = { "\350\140\052\233\205\112\100\363\153\212\044\354\006\026\054\163" , (PRUint32)784 } }; -static const NSSItem nss_builtins_items_131 [] = { +static const NSSItem nss_builtins_items_137 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8413,7 +8840,7 @@ static const NSSItem nss_builtins_items_131 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_132 [] = { +static const NSSItem nss_builtins_items_138 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8511,7 +8938,7 @@ static const NSSItem nss_builtins_items_132 [] = { "\225\351\066\226\230\156" , (PRUint32)1078 } }; -static const NSSItem nss_builtins_items_133 [] = { +static const NSSItem nss_builtins_items_139 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8538,7 +8965,7 @@ static const NSSItem nss_builtins_items_133 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_134 [] = { +static const NSSItem nss_builtins_items_140 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8637,7 +9064,7 @@ static const NSSItem nss_builtins_items_134 [] = { "\354\375\051" , (PRUint32)1091 } }; -static const NSSItem nss_builtins_items_135 [] = { +static const NSSItem nss_builtins_items_141 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8664,7 +9091,7 @@ static const NSSItem nss_builtins_items_135 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_136 [] = { +static const NSSItem nss_builtins_items_142 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8765,7 +9192,7 @@ static const NSSItem nss_builtins_items_136 [] = { "\160\136\310\304\170\260\142" , (PRUint32)1095 } }; -static const NSSItem nss_builtins_items_137 [] = { +static const NSSItem nss_builtins_items_143 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8793,7 +9220,7 @@ static const NSSItem nss_builtins_items_137 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_138 [] = { +static const NSSItem nss_builtins_items_144 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -8971,7 +9398,7 @@ static const NSSItem nss_builtins_items_138 [] = { "\001\177\046\304\143\365\045\102\136\142\275" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_139 [] = { +static const NSSItem nss_builtins_items_145 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9008,7 +9435,7 @@ static const NSSItem nss_builtins_items_139 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_140 [] = { +static const NSSItem nss_builtins_items_146 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9185,7 +9612,7 @@ static const NSSItem nss_builtins_items_140 [] = { "\206\063\076\346\057\110\156\257\124\220\116\255\261\045" , (PRUint32)2030 } }; -static const NSSItem nss_builtins_items_141 [] = { +static const NSSItem nss_builtins_items_147 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9222,7 +9649,7 @@ static const NSSItem nss_builtins_items_141 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_142 [] = { +static const NSSItem nss_builtins_items_148 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9399,7 +9826,7 @@ static const NSSItem nss_builtins_items_142 [] = { "\257\175\310\352\351\324\126\331\016\023\262\305\105\120" , (PRUint32)2030 } }; -static const NSSItem nss_builtins_items_143 [] = { +static const NSSItem nss_builtins_items_149 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9436,7 +9863,7 @@ static const NSSItem nss_builtins_items_143 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_144 [] = { +static const NSSItem nss_builtins_items_150 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9614,7 +10041,7 @@ static const NSSItem nss_builtins_items_144 [] = { "\336\007\043\162\346\275\040\024\113\264\206" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_145 [] = { +static const NSSItem nss_builtins_items_151 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9651,7 +10078,7 @@ static const NSSItem nss_builtins_items_145 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_146 [] = { +static const NSSItem nss_builtins_items_152 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9829,7 +10256,7 @@ static const NSSItem nss_builtins_items_146 [] = { "\311\024\025\014\343\007\203\233\046\165\357" , (PRUint32)2043 } }; -static const NSSItem nss_builtins_items_147 [] = { +static const NSSItem nss_builtins_items_153 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9866,7 +10293,7 @@ static const NSSItem nss_builtins_items_147 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_148 [] = { +static const NSSItem nss_builtins_items_154 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9946,7 +10373,7 @@ static const NSSItem nss_builtins_items_148 [] = { "\134\152\371\162\224\325\001\117\240\333\102" , (PRUint32)699 } }; -static const NSSItem nss_builtins_items_149 [] = { +static const NSSItem nss_builtins_items_155 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -9976,7 +10403,7 @@ static const NSSItem nss_builtins_items_149 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_150 [] = { +static const NSSItem nss_builtins_items_156 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10160,7 +10587,7 @@ static const NSSItem nss_builtins_items_150 [] = { "\207\112\137\334\357\351\126\360\012\014\350\165" , (PRUint32)2108 } }; -static const NSSItem nss_builtins_items_151 [] = { +static const NSSItem nss_builtins_items_157 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10198,7 +10625,7 @@ static const NSSItem nss_builtins_items_151 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_152 [] = { +static const NSSItem nss_builtins_items_158 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10324,7 +10751,7 @@ static const NSSItem nss_builtins_items_152 [] = { "\112\164\066\371" , (PRUint32)1492 } }; -static const NSSItem nss_builtins_items_153 [] = { +static const NSSItem nss_builtins_items_159 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10352,7 +10779,7 @@ static const NSSItem nss_builtins_items_153 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_154 [] = { +static const NSSItem nss_builtins_items_160 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10432,7 +10859,7 @@ static const NSSItem nss_builtins_items_154 [] = { "\057\317\246\356\311\160\042\024\275\375\276\154\013\003" , (PRUint32)862 } }; -static const NSSItem nss_builtins_items_155 [] = { +static const NSSItem nss_builtins_items_161 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10457,7 +10884,7 @@ static const NSSItem nss_builtins_items_155 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_156 [] = { +static const NSSItem nss_builtins_items_162 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10530,7 +10957,7 @@ static const NSSItem nss_builtins_items_156 [] = { "\127\275\125\232" , (PRUint32)804 } }; -static const NSSItem nss_builtins_items_157 [] = { +static const NSSItem nss_builtins_items_163 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10553,7 +10980,7 @@ static const NSSItem nss_builtins_items_157 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_158 [] = { +static const NSSItem nss_builtins_items_164 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10626,7 +11053,7 @@ static const NSSItem nss_builtins_items_158 [] = { "\160\254\337\114" , (PRUint32)804 } }; -static const NSSItem nss_builtins_items_159 [] = { +static const NSSItem nss_builtins_items_165 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10649,7 +11076,7 @@ static const NSSItem nss_builtins_items_159 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_160 [] = { +static const NSSItem nss_builtins_items_166 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10735,7 +11162,7 @@ static const NSSItem nss_builtins_items_160 [] = { "\025\301\044\174\062\174\003\035\073\241\130\105\062\223" , (PRUint32)958 } }; -static const NSSItem nss_builtins_items_161 [] = { +static const NSSItem nss_builtins_items_167 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10760,7 +11187,7 @@ static const NSSItem nss_builtins_items_161 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_162 [] = { +static const NSSItem nss_builtins_items_168 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10851,7 +11278,7 @@ static const NSSItem nss_builtins_items_162 [] = { "\151\003\142\270\231\005\005\075\153\170\022\275\260\157\145" , (PRUint32)1071 } }; -static const NSSItem nss_builtins_items_163 [] = { +static const NSSItem nss_builtins_items_169 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10875,7 +11302,7 @@ static const NSSItem nss_builtins_items_163 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_164 [] = { +static const NSSItem nss_builtins_items_170 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -10979,7 +11406,7 @@ static const NSSItem nss_builtins_items_164 [] = { "\004\243\103\055\332\374\013\142\352\057\137\142\123" , (PRUint32)1309 } }; -static const NSSItem nss_builtins_items_165 [] = { +static const NSSItem nss_builtins_items_171 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11002,7 +11429,7 @@ static const NSSItem nss_builtins_items_165 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_166 [] = { +static const NSSItem nss_builtins_items_172 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11108,7 +11535,7 @@ static const NSSItem nss_builtins_items_166 [] = { "\364\010" , (PRUint32)1122 } }; -static const NSSItem nss_builtins_items_167 [] = { +static const NSSItem nss_builtins_items_173 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11138,7 +11565,7 @@ static const NSSItem nss_builtins_items_167 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_168 [] = { +static const NSSItem nss_builtins_items_174 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11252,7 +11679,7 @@ static const NSSItem nss_builtins_items_168 [] = { "\005\323\312\003\112\124" , (PRUint32)1190 } }; -static const NSSItem nss_builtins_items_169 [] = { +static const NSSItem nss_builtins_items_175 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11284,7 +11711,7 @@ static const NSSItem nss_builtins_items_169 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_170 [] = { +static const NSSItem nss_builtins_items_176 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11391,7 +11818,7 @@ static const NSSItem nss_builtins_items_170 [] = { "\062\234\036\273\235\370\146\250" , (PRUint32)1144 } }; -static const NSSItem nss_builtins_items_171 [] = { +static const NSSItem nss_builtins_items_177 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11421,7 +11848,7 @@ static const NSSItem nss_builtins_items_171 [] = { { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_172 [] = { +static const NSSItem nss_builtins_items_178 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11527,7 +11954,7 @@ static const NSSItem nss_builtins_items_172 [] = { "\275\023\122\035\250\076\315\000\037\310" , (PRUint32)1130 } }; -static const NSSItem nss_builtins_items_173 [] = { +static const NSSItem nss_builtins_items_179 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11557,7 +11984,7 @@ static const NSSItem nss_builtins_items_173 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_174 [] = { +static const NSSItem nss_builtins_items_180 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11666,7 +12093,7 @@ static const NSSItem nss_builtins_items_174 [] = { "\334" , (PRUint32)1217 } }; -static const NSSItem nss_builtins_items_175 [] = { +static const NSSItem nss_builtins_items_181 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11694,7 +12121,7 @@ static const NSSItem nss_builtins_items_175 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_176 [] = { +static const NSSItem nss_builtins_items_182 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11801,7 +12228,7 @@ static const NSSItem nss_builtins_items_176 [] = { "\166\135\165\220\032\365\046\217\360" , (PRUint32)1225 } }; -static const NSSItem nss_builtins_items_177 [] = { +static const NSSItem nss_builtins_items_183 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11828,7 +12255,189 @@ static const NSSItem nss_builtins_items_177 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_178 [] = { +static const NSSItem nss_builtins_items_184 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"NetLock Qualified (Class QA) Root", (PRUint32)34 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"\002\001\173" +, (PRUint32)3 }, + { (void *)"\060\202\006\321\060\202\005\271\240\003\002\001\002\002\001\173" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125\061" +"\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145" +"\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164" +"\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164" +"\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006" +"\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156" +"\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004\003" +"\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163\151" +"\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151\040" +"\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165\163" +"\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034\006" +"\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146\157" +"\100\156\145\164\154\157\143\153\056\150\165\060\036\027\015\060" +"\063\060\063\063\060\060\061\064\067\061\061\132\027\015\062\062" +"\061\062\061\065\060\061\064\067\061\061\132\060\201\311\061\013" +"\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006" +"\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047" +"\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153" +"\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141" +"\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013" +"\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141" +"\144\157\153\061\102\060\100\006\003\125\004\003\023\071\116\145" +"\164\114\157\143\153\040\115\151\156\157\163\151\164\145\164\164" +"\040\113\157\172\152\145\147\171\172\157\151\040\050\103\154\141" +"\163\163\040\121\101\051\040\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\061\036\060\034\006\011\052\206\110" +"\206\367\015\001\011\001\026\017\151\156\146\157\100\156\145\164" +"\154\157\143\153\056\150\165\060\202\001\042\060\015\006\011\052" +"\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060" +"\202\001\012\002\202\001\001\000\307\122\045\262\330\075\324\204" +"\125\011\247\033\275\154\271\024\364\212\002\333\166\374\152\052" +"\170\253\345\167\360\156\340\214\043\147\333\245\144\231\271\335" +"\001\076\157\357\055\232\074\042\360\135\311\127\240\125\101\177" +"\362\103\136\130\202\123\061\145\316\036\362\046\272\000\124\036" +"\257\260\274\034\344\122\214\240\062\257\267\067\261\123\147\150" +"\164\147\120\366\055\056\144\336\256\046\171\337\337\231\206\253" +"\253\177\205\354\240\373\200\314\364\270\014\036\223\105\143\271" +"\334\270\133\233\355\133\071\324\137\142\260\247\216\174\146\070" +"\054\252\261\010\143\027\147\175\314\275\263\361\303\077\317\120" +"\071\355\321\031\203\025\333\207\022\047\226\267\332\352\345\235" +"\274\272\352\071\117\213\357\164\232\347\305\320\322\352\206\121" +"\034\344\376\144\010\050\004\171\005\353\312\305\161\016\013\357" +"\253\352\354\022\021\241\030\005\062\151\321\014\054\032\075\045" +"\231\077\265\174\312\155\260\256\231\231\372\010\140\347\031\302" +"\362\275\121\323\314\323\002\254\301\021\014\200\316\253\334\224" +"\235\153\243\071\123\072\326\205\002\003\000\305\175\243\202\002" +"\300\060\202\002\274\060\022\006\003\125\035\023\001\001\377\004" +"\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017" +"\001\001\377\004\004\003\002\001\006\060\202\002\165\006\011\140" +"\206\110\001\206\370\102\001\015\004\202\002\146\026\202\002\142" +"\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164" +"\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164" +"\114\157\143\153\040\113\146\164\056\040\115\151\156\157\163\151" +"\164\145\164\164\040\123\172\157\154\147\141\154\164\141\164\141" +"\163\151\040\123\172\141\142\141\154\171\172\141\164\141\142\141" +"\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163\157" +"\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165\154" +"\164\056\040\101\040\155\151\156\157\163\151\164\145\164\164\040" +"\145\154\145\153\164\162\157\156\151\153\165\163\040\141\154\141" +"\151\162\141\163\040\152\157\147\150\141\164\141\163\040\145\162" +"\166\145\156\171\145\163\165\154\145\163\145\156\145\153\054\040" +"\166\141\154\141\155\151\156\164\040\145\154\146\157\147\141\144" +"\141\163\141\156\141\153\040\146\145\154\164\145\164\145\154\145" +"\040\141\040\115\151\156\157\163\151\164\145\164\164\040\123\172" +"\157\154\147\141\154\164\141\164\141\163\151\040\123\172\141\142" +"\141\154\171\172\141\164\142\141\156\054\040\141\172\040\101\154" +"\164\141\154\141\156\157\163\040\123\172\145\162\172\157\144\145" +"\163\151\040\106\145\154\164\145\164\145\154\145\153\142\145\156" +"\040\145\154\157\151\162\164\040\145\154\154\145\156\157\162\172" +"\145\163\151\040\145\154\152\141\162\141\163\040\155\145\147\164" +"\145\164\145\154\145\056\040\101\040\144\157\153\165\155\145\156" +"\164\165\155\157\153\040\155\145\147\164\141\154\141\154\150\141" +"\164\157\153\040\141\040\150\164\164\160\163\072\057\057\167\167" +"\167\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143" +"\163\057\040\143\151\155\145\156\040\166\141\147\171\040\153\145" +"\162\150\145\164\157\153\040\141\172\040\151\156\146\157\100\156" +"\145\164\154\157\143\153\056\156\145\164\040\145\055\155\141\151" +"\154\040\143\151\155\145\156\056\040\127\101\122\116\111\116\107" +"\041\040\124\150\145\040\151\163\163\165\141\156\143\145\040\141" +"\156\144\040\164\150\145\040\165\163\145\040\157\146\040\164\150" +"\151\163\040\143\145\162\164\151\146\151\143\141\164\145\040\141" +"\162\145\040\163\165\142\152\145\143\164\040\164\157\040\164\150" +"\145\040\116\145\164\114\157\143\153\040\121\165\141\154\151\146" +"\151\145\144\040\103\120\123\040\141\166\141\151\154\141\142\154" +"\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167" +"\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143\163" +"\057\040\157\162\040\142\171\040\145\055\155\141\151\154\040\141" +"\164\040\151\156\146\157\100\156\145\164\154\157\143\153\056\156" +"\145\164\060\035\006\003\125\035\016\004\026\004\024\011\152\142" +"\026\222\260\132\273\125\016\313\165\062\072\062\345\262\041\311" +"\050\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000" +"\003\202\001\001\000\221\152\120\234\333\170\201\233\077\213\102" +"\343\073\374\246\303\356\103\340\317\363\342\200\065\111\105\166" +"\002\342\343\057\005\305\361\052\347\300\101\063\306\266\233\320" +"\063\071\315\300\333\241\255\154\067\002\114\130\101\073\362\227" +"\222\306\110\250\315\345\212\071\211\141\371\122\227\351\275\366" +"\371\224\164\350\161\016\274\167\206\303\006\314\132\174\112\176" +"\064\120\060\056\373\177\062\232\215\075\363\040\133\370\152\312" +"\206\363\061\114\054\131\200\002\175\376\070\311\060\165\034\267" +"\125\343\274\237\272\250\155\204\050\005\165\263\213\015\300\221" +"\124\041\347\246\013\264\231\365\121\101\334\315\243\107\042\331" +"\307\001\201\304\334\107\117\046\352\037\355\333\315\015\230\364" +"\243\234\264\163\062\112\226\231\376\274\177\310\045\130\370\130" +"\363\166\146\211\124\244\246\076\304\120\134\272\211\030\202\165" +"\110\041\322\117\023\350\140\176\007\166\333\020\265\121\346\252" +"\271\150\252\315\366\235\220\165\022\352\070\032\312\104\350\267" +"\231\247\052\150\225\146\225\253\255\357\211\313\140\251\006\022" +"\306\224\107\351\050" +, (PRUint32)1749 } +}; +static const NSSItem nss_builtins_items_185 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"NetLock Qualified (Class QA) Root", (PRUint32)34 }, + { (void *)"\001\150\227\341\240\270\362\303\261\064\146\134\040\247\047\267" +"\241\130\342\217" +, (PRUint32)20 }, + { (void *)"\324\200\145\150\044\371\211\042\050\333\365\244\232\027\217\024" +, (PRUint32)16 }, + { (void *)"\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125" +"\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160" +"\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145" +"\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172" +"\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030" +"\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141" +"\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004" +"\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163" +"\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151" +"\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165" +"\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034" +"\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146" +"\157\100\156\145\164\154\157\143\153\056\150\165" +, (PRUint32)204 }, + { (void *)"\002\001\173" +, (PRUint32)3 }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_186 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -11971,7 +12580,7 @@ static const NSSItem nss_builtins_items_178 [] = { "\210" , (PRUint32)1665 } }; -static const NSSItem nss_builtins_items_179 [] = { +static const NSSItem nss_builtins_items_187 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12002,7 +12611,7 @@ static const NSSItem nss_builtins_items_179 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_180 [] = { +static const NSSItem nss_builtins_items_188 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12121,7 +12730,7 @@ static const NSSItem nss_builtins_items_180 [] = { "\066\053\143\254\130\001\153\063\051\120\206\203\361\001\110" , (PRUint32)1359 } }; -static const NSSItem nss_builtins_items_181 [] = { +static const NSSItem nss_builtins_items_189 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12150,7 +12759,7 @@ static const NSSItem nss_builtins_items_181 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_182 [] = { +static const NSSItem nss_builtins_items_190 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12270,7 +12879,7 @@ static const NSSItem nss_builtins_items_182 [] = { "\063\004\324" , (PRUint32)1363 } }; -static const NSSItem nss_builtins_items_183 [] = { +static const NSSItem nss_builtins_items_191 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12299,7 +12908,7 @@ static const NSSItem nss_builtins_items_183 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_184 [] = { +static const NSSItem nss_builtins_items_192 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12400,7 +13009,7 @@ static const NSSItem nss_builtins_items_184 [] = { "\264\003\045\274" , (PRUint32)1076 } }; -static const NSSItem nss_builtins_items_185 [] = { +static const NSSItem nss_builtins_items_193 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12429,7 +13038,7 @@ static const NSSItem nss_builtins_items_185 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_186 [] = { +static const NSSItem nss_builtins_items_194 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12522,7 +13131,7 @@ static const NSSItem nss_builtins_items_186 [] = { "\177\333\275\237" , (PRUint32)1028 } }; -static const NSSItem nss_builtins_items_187 [] = { +static const NSSItem nss_builtins_items_195 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12548,7 +13157,7 @@ static const NSSItem nss_builtins_items_187 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; -static const NSSItem nss_builtins_items_188 [] = { +static const NSSItem nss_builtins_items_196 [] = { { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12642,7 +13251,7 @@ static const NSSItem nss_builtins_items_188 [] = { "\037\027\224" , (PRUint32)1043 } }; -static const NSSItem nss_builtins_items_189 [] = { +static const NSSItem nss_builtins_items_197 [] = { { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, @@ -12668,6 +13277,701 @@ static const NSSItem nss_builtins_items_189 [] = { { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } }; +static const NSSItem nss_builtins_items_198 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"StartCom Ltd.", (PRUint32)14 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"\002\001\000" +, (PRUint32)3 }, + { (void *)"\060\202\005\026\060\202\004\177\240\003\002\001\002\002\001\000" +"\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060" +"\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114\061" +"\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145\154" +"\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141\164" +"\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164" +"\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125\004" +"\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171\040" +"\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040\106" +"\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143" +"\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\061" +"\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026\022" +"\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056\157" +"\162\147\060\036\027\015\060\065\060\063\061\067\061\067\063\067" +"\064\070\132\027\015\063\065\060\063\061\060\061\067\063\067\064" +"\070\132\060\201\260\061\013\060\011\006\003\125\004\006\023\002" +"\111\114\061\017\060\015\006\003\125\004\010\023\006\111\163\162" +"\141\145\154\061\016\060\014\006\003\125\004\007\023\005\105\151" +"\154\141\164\061\026\060\024\006\003\125\004\012\023\015\123\164" +"\141\162\164\103\157\155\040\114\164\144\056\061\032\060\030\006" +"\003\125\004\013\023\021\103\101\040\101\165\164\150\157\162\151" +"\164\171\040\104\145\160\056\061\051\060\047\006\003\125\004\003" +"\023\040\106\162\145\145\040\123\123\114\040\103\145\162\164\151" +"\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151" +"\164\171\061\041\060\037\006\011\052\206\110\206\367\015\001\011" +"\001\026\022\141\144\155\151\156\100\163\164\141\162\164\143\157" +"\155\056\157\162\147\060\201\237\060\015\006\011\052\206\110\206" +"\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002\201" +"\201\000\355\204\140\000\043\236\310\112\121\051\047\336\072\241" +"\071\265\151\253\011\262\057\064\375\141\334\075\323\260\317\261" +"\327\302\304\302\261\344\226\126\304\276\252\024\016\347\314\072" +"\120\310\072\142\235\303\243\254\131\173\216\356\125\032\034\107" +"\276\243\227\071\263\265\357\043\054\010\350\330\257\163\057\271" +"\311\203\350\355\000\017\310\165\245\057\064\114\030\350\166\210" +"\043\111\212\333\266\355\150\332\303\265\142\051\114\245\113\267" +"\230\264\011\024\020\240\370\376\142\166\042\025\013\244\326\010" +"\057\065\002\003\001\000\001\243\202\002\074\060\202\002\070\060" +"\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377" +"\060\013\006\003\125\035\017\004\004\003\002\001\346\060\035\006" +"\003\125\035\016\004\026\004\024\034\211\303\226\314\275\376\062" +"\325\015\214\201\061\266\230\235\215\050\144\215\060\201\335\006" +"\003\125\035\043\004\201\325\060\201\322\200\024\034\211\303\226" +"\314\275\376\062\325\015\214\201\061\266\230\235\215\050\144\215" +"\241\201\266\244\201\263\060\201\260\061\013\060\011\006\003\125" +"\004\006\023\002\111\114\061\017\060\015\006\003\125\004\010\023" +"\006\111\163\162\141\145\154\061\016\060\014\006\003\125\004\007" +"\023\005\105\151\154\141\164\061\026\060\024\006\003\125\004\012" +"\023\015\123\164\141\162\164\103\157\155\040\114\164\144\056\061" +"\032\060\030\006\003\125\004\013\023\021\103\101\040\101\165\164" +"\150\157\162\151\164\171\040\104\145\160\056\061\051\060\047\006" +"\003\125\004\003\023\040\106\162\145\145\040\123\123\114\040\103" +"\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164" +"\150\157\162\151\164\171\061\041\060\037\006\011\052\206\110\206" +"\367\015\001\011\001\026\022\141\144\155\151\156\100\163\164\141" +"\162\164\143\157\155\056\157\162\147\202\001\000\060\035\006\003" +"\125\035\021\004\026\060\024\201\022\141\144\155\151\156\100\163" +"\164\141\162\164\143\157\155\056\157\162\147\060\035\006\003\125" +"\035\022\004\026\060\024\201\022\141\144\155\151\156\100\163\164" +"\141\162\164\143\157\155\056\157\162\147\060\021\006\011\140\206" +"\110\001\206\370\102\001\001\004\004\003\002\000\007\060\057\006" +"\011\140\206\110\001\206\370\102\001\015\004\042\026\040\106\162" +"\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143\141" +"\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\062" +"\006\011\140\206\110\001\206\370\102\001\004\004\045\026\043\150" +"\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164" +"\143\157\155\056\157\162\147\057\143\141\055\143\162\154\056\143" +"\162\154\060\050\006\011\140\206\110\001\206\370\102\001\002\004" +"\033\026\031\150\164\164\160\072\057\057\143\145\162\164\056\163" +"\164\141\162\164\143\157\155\056\157\162\147\057\060\071\006\011" +"\140\206\110\001\206\370\102\001\010\004\054\026\052\150\164\164" +"\160\072\057\057\143\145\162\164\056\163\164\141\162\164\143\157" +"\155\056\157\162\147\057\151\156\144\145\170\056\160\150\160\077" +"\141\160\160\075\061\061\061\060\015\006\011\052\206\110\206\367" +"\015\001\001\004\005\000\003\201\201\000\154\161\045\341\236\064" +"\221\041\357\333\154\275\001\010\126\217\210\330\101\072\123\365" +"\162\337\047\127\113\166\204\367\150\244\376\353\077\011\176\050" +"\270\127\352\037\301\252\342\377\226\237\111\231\346\262\225\163" +"\226\306\110\307\136\215\007\162\126\370\203\217\237\167\257\051" +"\323\105\016\244\356\260\066\164\055\360\315\230\043\173\067\113" +"\332\376\121\230\304\036\064\074\210\375\231\073\120\247\301\213" +"\063\307\302\122\026\022\225\123\145\042\357\272\213\316\142\333" +"\160\043\261\200\337\032\040\070\347\176" +, (PRUint32)1306 } +}; +static const NSSItem nss_builtins_items_199 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"StartCom Ltd.", (PRUint32)14 }, + { (void *)"\225\346\255\370\327\161\106\002\115\325\152\041\262\347\077\315" +"\362\073\065\377" +, (PRUint32)20 }, + { (void *)"\010\174\130\037\122\053\104\264\073\171\315\001\370\305\303\311" +, (PRUint32)16 }, + { (void *)"\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114" +"\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145" +"\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141" +"\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162" +"\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125" +"\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171" +"\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040" +"\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026" +"\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056" +"\157\162\147" +, (PRUint32)179 }, + { (void *)"\002\001\000" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_200 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Taiwan GRCA", (PRUint32)12 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343" +"\136\366" +, (PRUint32)18 }, + { (void *)"\060\202\005\162\060\202\003\132\240\003\002\001\002\002\020\037" +"\235\131\132\327\057\302\006\104\245\200\010\151\343\136\366\060" +"\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077" +"\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060\060" +"\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155\145" +"\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143" +"\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060" +"\036\027\015\060\062\061\062\060\065\061\063\062\063\063\063\132" +"\027\015\063\062\061\062\060\065\061\063\062\063\063\063\132\060" +"\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060" +"\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155" +"\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151" +"\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171" +"\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001" +"\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001" +"\000\232\045\270\354\314\242\165\250\173\367\316\133\131\212\311" +"\321\206\022\010\124\354\234\362\347\106\366\210\363\174\351\245" +"\337\114\107\066\244\033\001\034\177\036\127\212\215\303\305\321" +"\041\343\332\044\077\110\053\373\237\056\241\224\347\054\034\223" +"\321\277\033\001\207\123\231\316\247\365\012\041\166\167\377\251" +"\267\306\163\224\117\106\367\020\111\067\372\250\131\111\135\152" +"\201\007\126\362\212\371\006\320\367\160\042\115\264\267\101\271" +"\062\270\261\360\261\303\234\077\160\375\123\335\201\252\330\143" +"\170\366\330\123\156\241\254\152\204\044\162\124\206\306\322\262" +"\312\034\016\171\201\326\265\160\142\010\001\056\116\117\016\325" +"\021\257\251\257\345\232\277\334\314\207\155\046\344\311\127\242" +"\373\226\371\314\341\077\123\214\154\114\176\233\123\010\013\154" +"\027\373\147\310\302\255\261\315\200\264\227\334\166\001\026\025" +"\351\152\327\244\341\170\107\316\206\325\373\061\363\372\061\276" +"\064\252\050\373\160\114\035\111\307\257\054\235\155\146\246\266" +"\215\144\176\265\040\152\235\073\201\266\217\100\000\147\113\211" +"\206\270\314\145\376\025\123\351\004\301\326\137\035\104\327\012" +"\057\047\232\106\175\241\015\165\255\124\206\025\334\111\073\361" +"\226\316\017\233\240\354\243\172\135\276\325\052\165\102\345\173" +"\336\245\266\252\257\050\254\254\220\254\070\267\325\150\065\046" +"\172\334\367\073\363\375\105\233\321\273\103\170\156\157\361\102" +"\124\152\230\360\015\255\227\351\122\136\351\325\152\162\336\152" +"\367\033\140\024\364\245\344\266\161\147\252\037\352\342\115\301" +"\102\100\376\147\106\027\070\057\107\077\161\234\256\345\041\312" +"\141\055\155\007\250\204\174\055\356\121\045\361\143\220\236\375" +"\341\127\210\153\357\212\043\155\261\346\275\077\255\321\075\226" +"\013\205\215\315\153\047\273\267\005\233\354\273\221\251\012\007" +"\022\002\227\116\040\220\360\377\015\036\342\101\073\323\100\072" +"\347\215\135\332\146\344\002\260\007\122\230\134\016\216\063\234" +"\302\246\225\373\125\031\156\114\216\256\113\017\275\301\070\115" +"\136\217\204\035\146\315\305\140\226\264\122\132\005\211\216\225" +"\172\230\301\221\074\225\043\262\016\364\171\264\311\174\301\112" +"\041\002\003\001\000\001\243\152\060\150\060\035\006\003\125\035" +"\016\004\026\004\024\314\314\357\314\051\140\244\073\261\222\266" +"\074\372\062\142\217\254\045\025\073\060\014\006\003\125\035\023" +"\004\005\060\003\001\001\377\060\071\006\004\147\052\007\000\004" +"\061\060\057\060\055\002\001\000\060\011\006\005\053\016\003\002" +"\032\005\000\060\007\006\005\147\052\003\000\000\004\024\003\233" +"\360\042\023\377\225\050\066\323\334\236\300\062\373\061\072\212" +"\121\145\060\015\006\011\052\206\110\206\367\015\001\001\005\005" +"\000\003\202\002\001\000\100\200\112\372\046\311\316\136\060\335" +"\117\206\164\166\130\365\256\263\203\063\170\244\172\164\027\031" +"\116\351\122\265\271\340\012\164\142\252\150\312\170\240\114\232" +"\216\054\043\056\325\152\022\044\277\324\150\323\212\320\330\234" +"\237\264\037\014\336\070\176\127\070\374\215\342\117\136\014\237" +"\253\073\322\377\165\227\313\244\343\147\010\377\345\300\026\265" +"\110\001\175\351\371\012\377\033\345\152\151\277\170\041\250\302" +"\247\043\251\206\253\166\126\350\016\014\366\023\335\052\146\212" +"\144\111\075\032\030\207\220\004\237\102\122\267\117\313\376\107" +"\101\166\065\357\377\000\166\066\105\062\233\306\106\205\135\342" +"\044\260\036\343\110\226\230\127\107\224\125\172\017\101\261\104" +"\044\363\301\376\032\153\277\210\375\301\246\332\223\140\136\201" +"\112\231\040\234\110\146\031\265\000\171\124\017\270\054\057\113" +"\274\251\135\133\140\177\214\207\245\340\122\143\052\276\330\073" +"\205\100\025\376\036\266\145\077\305\113\332\176\265\172\065\051" +"\243\056\172\230\140\042\243\364\175\047\116\055\352\264\164\074" +"\351\017\244\063\017\020\021\274\023\001\326\345\016\323\277\265" +"\022\242\341\105\043\300\314\010\156\141\267\211\253\203\343\044" +"\036\346\135\007\347\037\040\076\317\147\310\347\254\060\155\047" +"\113\150\156\113\052\134\002\010\064\333\370\166\344\147\243\046" +"\234\077\242\062\302\112\305\201\030\061\020\126\252\204\357\055" +"\012\377\270\037\167\322\277\245\130\240\142\344\327\113\221\165" +"\215\211\200\230\176\155\313\123\116\136\257\366\262\227\205\227" +"\271\332\125\006\271\044\356\327\306\070\036\143\033\022\073\225" +"\341\130\254\362\337\204\325\137\231\057\015\125\133\346\070\333" +"\056\077\162\351\110\205\313\273\051\023\217\036\070\125\271\363" +"\262\304\060\231\043\116\135\362\110\241\022\014\334\022\220\011" +"\220\124\221\003\074\107\345\325\311\145\340\267\113\175\354\107" +"\323\263\013\076\255\236\320\164\000\016\353\275\121\255\300\336" +"\054\300\303\152\376\357\334\013\247\372\106\337\140\333\234\246" +"\131\120\165\043\151\163\223\262\371\374\002\323\107\346\161\316" +"\020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045" +"\245\206\054\174\364\022" +, (PRUint32)1398 } +}; +static const NSSItem nss_builtins_items_201 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Taiwan GRCA", (PRUint32)12 }, + { (void *)"\364\213\021\277\336\253\276\224\124\040\161\346\101\336\153\276" +"\210\053\100\271" +, (PRUint32)20 }, + { (void *)"\067\205\104\123\062\105\037\040\360\363\225\341\045\304\103\116" +, (PRUint32)16 }, + { (void *)"\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061" +"\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156" +"\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146" +"\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164" +"\171" +, (PRUint32)65 }, + { (void *)"\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343" +"\136\366" +, (PRUint32)18 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_202 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Firmaprofesional Root CA", (PRUint32)25 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)"\060\202\004\127\060\202\003\077\240\003\002\001\002\002\001\001" +"\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060" +"\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061" +"\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156" +"\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154" +"\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165" +"\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151" +"\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162" +"\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066" +"\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110" +"\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141" +"\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060" +"\036\027\015\060\061\061\060\062\064\062\062\060\060\060\060\132" +"\027\015\061\063\061\060\062\064\062\062\060\060\060\060\132\060" +"\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061" +"\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156" +"\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154" +"\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165" +"\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151" +"\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162" +"\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066" +"\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110" +"\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141" +"\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060" +"\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001" +"\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000" +"\347\043\003\157\157\043\245\136\170\316\225\054\355\224\036\156" +"\012\236\001\307\352\060\321\054\235\335\067\350\233\230\171\126" +"\323\374\163\337\320\212\336\125\217\121\371\132\352\336\265\160" +"\304\355\244\355\377\243\015\156\017\144\120\061\257\001\047\130" +"\256\376\154\247\112\057\027\055\323\163\325\023\034\217\131\245" +"\064\054\035\124\004\105\315\150\270\240\300\003\245\317\205\102" +"\107\225\050\133\317\357\200\154\340\220\227\212\001\074\035\363" +"\207\020\060\046\110\175\327\374\351\235\221\161\377\101\232\251" +"\100\265\067\234\051\040\117\037\122\343\240\175\023\155\124\267" +"\012\336\351\152\116\007\254\254\031\137\334\176\142\164\366\262" +"\005\000\272\205\240\375\035\070\156\313\132\273\206\274\224\147" +"\063\065\203\054\037\043\315\370\310\221\161\314\227\213\357\256" +"\017\334\051\003\033\300\071\353\160\355\301\156\016\330\147\013" +"\211\251\274\065\344\357\266\064\264\245\266\304\055\245\276\320" +"\303\224\044\110\333\337\226\323\000\265\146\032\213\146\005\017" +"\335\077\077\313\077\252\136\232\112\370\264\112\357\225\067\033" +"\002\003\001\000\001\243\201\237\060\201\234\060\052\006\003\125" +"\035\021\004\043\060\041\206\037\150\164\164\160\072\057\057\167" +"\167\167\056\146\151\162\155\141\160\162\157\146\145\163\151\157" +"\156\141\154\056\143\157\155\060\022\006\003\125\035\023\001\001" +"\377\004\010\060\006\001\001\377\002\001\001\060\053\006\003\125" +"\035\020\004\044\060\042\200\017\062\060\060\061\061\060\062\064" +"\062\062\060\060\060\060\132\201\017\062\060\061\063\061\060\062" +"\064\062\062\060\060\060\060\132\060\016\006\003\125\035\017\001" +"\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004" +"\026\004\024\063\013\240\146\321\352\332\316\336\142\223\004\050" +"\122\265\024\177\070\150\267\060\015\006\011\052\206\110\206\367" +"\015\001\001\005\005\000\003\202\001\001\000\107\163\376\215\047" +"\124\360\365\324\167\234\047\171\127\127\267\025\126\354\307\330" +"\130\267\001\002\364\063\355\223\120\210\236\174\106\261\275\077" +"\024\157\361\263\107\110\213\214\227\006\327\352\176\243\134\052" +"\273\115\057\107\342\370\071\006\311\234\056\061\032\003\170\364" +"\274\070\306\042\213\063\061\360\026\004\004\175\371\166\344\113" +"\327\300\346\203\354\131\314\077\336\377\117\153\267\147\176\246" +"\206\201\062\043\003\235\310\367\137\301\112\140\245\222\251\261" +"\244\240\140\303\170\207\263\042\363\052\353\133\251\355\005\253" +"\067\017\261\342\323\225\166\143\126\164\214\130\162\033\067\345" +"\144\241\276\115\014\223\230\014\227\366\207\155\263\077\347\313" +"\200\246\355\210\307\137\120\142\002\350\231\164\026\320\346\264" +"\071\361\047\313\310\100\326\343\206\020\251\043\022\222\340\151" +"\101\143\247\257\045\013\300\305\222\313\036\230\243\132\272\305" +"\063\017\240\227\001\335\177\340\173\326\006\124\317\241\342\115" +"\070\353\113\120\265\313\046\364\312\332\160\112\152\241\342\171" +"\252\341\247\063\366\375\112\037\366\331\140" +, (PRUint32)1115 } +}; +static const NSSItem nss_builtins_items_203 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Firmaprofesional Root CA", (PRUint32)25 }, + { (void *)"\251\142\217\113\230\251\033\110\065\272\322\301\106\062\206\273" +"\146\144\152\214" +, (PRUint32)20 }, + { (void *)"\021\222\171\100\074\261\203\100\345\253\146\112\147\222\200\337" +, (PRUint32)16 }, + { (void *)"\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123" +"\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165" +"\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145" +"\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101" +"\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164" +"\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160" +"\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101" +"\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206" +"\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155" +"\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155" +, (PRUint32)160 }, + { (void *)"\002\001\001" +, (PRUint32)3 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_valid, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_204 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Wells Fargo Root CA", (PRUint32)20 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"\002\004\071\344\227\236" +, (PRUint32)6 }, + { (void *)"\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071" +"\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005" +"\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002" +"\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154" +"\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004" +"\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103" +"\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164" +"\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023" +"\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157" +"\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165" +"\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061" +"\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064" +"\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003" +"\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012" +"\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060" +"\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141" +"\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157" +"\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006" +"\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147" +"\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141" +"\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042" +"\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003" +"\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063" +"\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167" +"\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307" +"\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077" +"\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304" +"\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053" +"\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153" +"\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016" +"\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250" +"\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270" +"\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256" +"\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121" +"\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260" +"\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204" +"\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336" +"\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031" +"\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001" +"\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377" +"\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105" +"\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001" +"\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026" +"\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154" +"\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160" +"\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001" +"\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053" +"\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150" +"\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330" +"\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355" +"\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177" +"\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036" +"\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023" +"\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173" +"\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000" +"\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345" +"\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361" +"\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250" +"\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135" +"\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220" +"\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267" +"\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326" +"\117\041\145\073\112\177\107\243\373" +, (PRUint32)1001 } +}; +static const NSSItem nss_builtins_items_205 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Wells Fargo Root CA", (PRUint32)20 }, + { (void *)"\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321" +"\321\314\373\145" +, (PRUint32)20 }, + { (void *)"\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005" +, (PRUint32)16 }, + { (void *)"\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123" +"\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163" +"\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023" +"\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162" +"\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157" +"\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127" +"\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040" +"\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150" +"\157\162\151\164\171" +, (PRUint32)133 }, + { (void *)"\002\004\071\344\227\236" +, (PRUint32)6 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; +static const NSSItem nss_builtins_items_206 [] = { + { (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Swisscom Root CA 1", (PRUint32)19 }, + { (void *)&ckc_x_509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE) }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"0", (PRUint32)2 }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235" +"\250\066" +, (PRUint32)18 }, + { (void *)"\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\134" +"\013\205\134\013\347\131\101\337\127\314\077\177\235\250\066\060" +"\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\144" +"\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060" +"\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155" +"\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164" +"\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123" +"\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003" +"\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040" +"\103\101\040\061\060\036\027\015\060\065\060\070\061\070\061\062" +"\060\066\062\060\132\027\015\062\065\060\070\061\070\062\062\060" +"\066\062\060\132\060\144\061\013\060\011\006\003\125\004\006\023" +"\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167" +"\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023" +"\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151" +"\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060" +"\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155" +"\040\122\157\157\164\040\103\101\040\061\060\202\002\042\060\015" +"\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002" +"\017\000\060\202\002\012\002\202\002\001\000\320\271\260\250\014" +"\331\273\077\041\370\033\325\063\223\200\026\145\040\165\262\075" +"\233\140\155\106\310\214\061\157\027\303\372\232\154\126\355\074" +"\305\221\127\303\315\253\226\111\220\052\031\113\036\243\155\127" +"\335\361\053\142\050\165\105\136\252\326\133\372\013\045\330\241" +"\026\371\034\304\056\346\225\052\147\314\320\051\156\074\205\064" +"\070\141\111\261\000\237\326\072\161\137\115\155\316\137\271\251" +"\344\211\177\152\122\372\312\233\362\334\251\371\235\231\107\077" +"\116\051\137\264\246\215\135\173\013\231\021\003\003\376\347\333" +"\333\243\377\035\245\315\220\036\001\037\065\260\177\000\333\220" +"\157\306\176\173\321\356\172\172\247\252\014\127\157\244\155\305" +"\023\073\260\245\331\355\062\034\264\136\147\213\124\334\163\207" +"\345\323\027\174\146\120\162\135\324\032\130\301\331\317\330\211" +"\002\157\247\111\264\066\135\320\244\336\007\054\266\165\267\050" +"\221\326\227\276\050\365\230\036\352\133\046\311\275\260\227\163" +"\332\256\221\046\353\150\301\371\071\025\326\147\113\012\155\117" +"\313\317\260\344\102\161\214\123\171\347\356\341\333\035\240\156" +"\035\214\032\167\065\134\026\036\053\123\037\064\213\321\154\374" +"\362\147\007\172\365\255\355\326\232\253\241\261\113\341\314\067" +"\137\375\177\315\115\256\270\037\234\103\371\052\130\125\103\105" +"\274\226\315\160\016\374\311\343\146\272\116\215\073\201\313\025" +"\144\173\271\224\350\135\063\122\205\161\056\117\216\242\006\021" +"\121\311\343\313\241\156\061\010\144\014\302\322\074\365\066\350" +"\327\320\016\170\043\040\221\311\044\052\145\051\133\042\367\041" +"\316\203\136\244\363\336\113\323\150\217\106\165\134\203\011\156" +"\051\153\304\160\214\365\235\327\040\057\377\106\322\053\070\302" +"\057\165\034\075\176\332\245\357\036\140\205\151\102\323\314\370" +"\143\376\036\103\071\205\246\266\143\101\020\263\163\036\274\323" +"\372\312\175\026\107\342\247\325\320\243\212\012\010\226\142\126" +"\156\064\333\331\002\271\060\165\343\004\322\347\217\302\260\021" +"\100\012\254\325\161\002\142\213\061\276\335\306\043\130\061\102" +"\103\055\164\371\306\236\246\212\017\351\376\277\203\346\103\127" +"\044\272\357\106\064\252\327\022\001\070\355\002\003\001\000\001" +"\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377" +"\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060" +"\024\060\022\006\007\140\205\164\001\123\000\001\006\007\140\205" +"\164\001\123\000\001\060\022\006\003\125\035\023\001\001\377\004" +"\010\060\006\001\001\377\002\001\007\060\037\006\003\125\035\043" +"\004\030\060\026\200\024\003\045\057\336\157\202\001\072\134\054" +"\334\053\241\151\265\147\324\214\323\375\060\035\006\003\125\035" +"\016\004\026\004\024\003\045\057\336\157\202\001\072\134\054\334" +"\053\241\151\265\147\324\214\323\375\060\015\006\011\052\206\110" +"\206\367\015\001\001\005\005\000\003\202\002\001\000\065\020\313" +"\354\246\004\015\015\017\315\300\333\253\250\362\210\227\014\337" +"\223\057\115\174\100\126\061\172\353\244\017\140\315\172\363\276" +"\303\047\216\003\076\244\335\022\357\176\036\164\006\074\077\061" +"\362\034\173\221\061\041\264\360\320\154\227\324\351\227\262\044" +"\126\036\126\303\065\275\210\005\017\133\020\032\144\341\307\202" +"\060\371\062\255\236\120\054\347\170\005\320\061\261\132\230\212" +"\165\116\220\134\152\024\052\340\122\107\202\140\346\036\332\201" +"\261\373\024\013\132\361\237\322\225\272\076\320\033\326\025\035" +"\243\276\206\325\333\017\300\111\144\273\056\120\031\113\322\044" +"\370\335\036\007\126\320\070\240\225\160\040\166\214\327\335\036" +"\336\237\161\304\043\357\203\023\134\243\044\025\115\051\100\074" +"\152\304\251\330\267\246\104\245\015\364\340\235\167\036\100\160" +"\046\374\332\331\066\344\171\344\265\077\274\233\145\276\273\021" +"\226\317\333\306\050\071\072\010\316\107\133\123\132\305\231\376" +"\135\251\335\357\114\324\306\245\255\002\346\214\007\022\036\157" +"\003\321\157\240\243\363\051\275\022\307\120\242\260\177\210\251" +"\231\167\232\261\300\245\071\056\134\174\151\342\054\260\352\067" +"\152\244\341\132\341\365\120\345\203\357\245\273\052\210\347\214" +"\333\375\155\136\227\031\250\176\146\165\153\161\352\277\261\307" +"\157\240\364\216\244\354\064\121\133\214\046\003\160\241\167\325" +"\001\022\127\000\065\333\043\336\016\212\050\231\375\261\020\157" +"\113\377\070\055\140\116\054\234\353\147\265\255\111\356\113\037" +"\254\257\373\015\220\132\146\140\160\135\252\315\170\324\044\356" +"\310\101\240\223\001\222\234\152\236\374\271\044\305\263\025\202" +"\176\276\256\225\053\353\261\300\332\343\001\140\013\136\151\254" +"\204\126\141\276\161\027\376\035\023\017\376\306\207\105\351\376" +"\062\240\032\015\023\244\224\125\161\245\026\213\272\312\211\260" +"\262\307\374\217\330\124\265\223\142\235\316\317\131\373\075\030" +"\316\052\313\065\025\202\135\377\124\042\133\161\122\373\267\311" +"\376\140\233\000\101\144\360\252\052\354\266\102\103\316\211\146" +"\201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372" +"\060\032\365\232\154\364\016\123\371\072\133\321\034" +, (PRUint32)1501 } +}; +static const NSSItem nss_builtins_items_207 [] = { + { (void *)&cko_netscape_trust, (PRUint32)sizeof(CK_OBJECT_CLASS) }, + { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) }, + { (void *)"Swisscom Root CA 1", (PRUint32)19 }, + { (void *)"\137\072\374\012\213\144\366\206\147\064\164\337\176\251\242\376" +"\371\372\172\121" +, (PRUint32)20 }, + { (void *)"\370\070\174\167\210\337\054\026\150\056\302\342\122\113\270\371" +, (PRUint32)16 }, + { (void *)"\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061" +"\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143" +"\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147" +"\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145" +"\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125" +"\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157" +"\164\040\103\101\040\061" +, (PRUint32)102 }, + { (void *)"\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235" +"\250\066" +, (PRUint32)18 }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ckt_netscape_trusted_delegator, (PRUint32)sizeof(CK_TRUST) }, + { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) } +}; PR_IMPLEMENT_DATA(builtinsInternalObject) nss_builtins_data[] = { @@ -12862,11 +14166,29 @@ nss_builtins_data[] = { { 11, nss_builtins_types_186, nss_builtins_items_186, {NULL} }, { 13, nss_builtins_types_187, nss_builtins_items_187, {NULL} }, { 11, nss_builtins_types_188, nss_builtins_items_188, {NULL} }, - { 13, nss_builtins_types_189, nss_builtins_items_189, {NULL} } + { 13, nss_builtins_types_189, nss_builtins_items_189, {NULL} }, + { 11, nss_builtins_types_190, nss_builtins_items_190, {NULL} }, + { 13, nss_builtins_types_191, nss_builtins_items_191, {NULL} }, + { 11, nss_builtins_types_192, nss_builtins_items_192, {NULL} }, + { 13, nss_builtins_types_193, nss_builtins_items_193, {NULL} }, + { 11, nss_builtins_types_194, nss_builtins_items_194, {NULL} }, + { 13, nss_builtins_types_195, nss_builtins_items_195, {NULL} }, + { 11, nss_builtins_types_196, nss_builtins_items_196, {NULL} }, + { 13, nss_builtins_types_197, nss_builtins_items_197, {NULL} }, + { 11, nss_builtins_types_198, nss_builtins_items_198, {NULL} }, + { 13, nss_builtins_types_199, nss_builtins_items_199, {NULL} }, + { 11, nss_builtins_types_200, nss_builtins_items_200, {NULL} }, + { 13, nss_builtins_types_201, nss_builtins_items_201, {NULL} }, + { 11, nss_builtins_types_202, nss_builtins_items_202, {NULL} }, + { 13, nss_builtins_types_203, nss_builtins_items_203, {NULL} }, + { 11, nss_builtins_types_204, nss_builtins_items_204, {NULL} }, + { 13, nss_builtins_types_205, nss_builtins_items_205, {NULL} }, + { 11, nss_builtins_types_206, nss_builtins_items_206, {NULL} }, + { 13, nss_builtins_types_207, nss_builtins_items_207, {NULL} } }; PR_IMPLEMENT_DATA(const PRUint32) #ifdef DEBUG - nss_builtins_nObjects = 189+1; + nss_builtins_nObjects = 207+1; #else - nss_builtins_nObjects = 189; + nss_builtins_nObjects = 207; #endif /* DEBUG */ diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt index 8a8b1c5b6..aa6f1c0f7 100644 --- a/security/nss/lib/ckfw/builtins/certdata.txt +++ b/security/nss/lib/ckfw/builtins/certdata.txt @@ -7603,6 +7603,409 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # +# Certificate "GeoTrust Global CA 2" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Global CA 2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\146\060\202\002\116\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003\023 +\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141\154 +\040\103\101\040\062\060\036\027\015\060\064\060\063\060\064\060 +\065\060\060\060\060\132\027\015\061\071\060\063\060\064\060\065 +\060\060\060\060\132\060\104\061\013\060\011\006\003\125\004\006 +\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015\107 +\145\157\124\162\165\163\164\040\111\156\143\056\061\035\060\033 +\006\003\125\004\003\023\024\107\145\157\124\162\165\163\164\040 +\107\154\157\142\141\154\040\103\101\040\062\060\202\001\042\060 +\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202 +\001\017\000\060\202\001\012\002\202\001\001\000\357\074\115\100 +\075\020\337\073\123\000\341\147\376\224\140\025\076\205\210\361 +\211\015\220\310\050\043\231\005\350\053\040\235\306\363\140\106 +\330\301\262\325\214\061\331\334\040\171\044\201\277\065\062\374 +\143\151\333\261\052\153\356\041\130\362\010\351\170\313\157\313 +\374\026\122\310\221\304\377\075\163\336\261\076\247\302\175\146 +\301\365\176\122\044\032\342\325\147\221\320\202\020\327\170\113 +\117\053\102\071\275\144\055\100\240\260\020\323\070\110\106\210 +\241\014\273\072\063\052\142\230\373\000\235\023\131\177\157\073 +\162\252\356\246\017\206\371\005\141\352\147\177\014\067\226\213 +\346\151\026\107\021\302\047\131\003\263\246\140\302\041\100\126 +\372\240\307\175\072\023\343\354\127\307\263\326\256\235\211\200 +\367\001\347\054\366\226\053\023\015\171\054\331\300\344\206\173 +\113\214\014\162\202\212\373\027\315\000\154\072\023\074\260\204 +\207\113\026\172\051\262\117\333\035\324\013\363\146\067\275\330 +\366\127\273\136\044\172\270\074\213\271\372\222\032\032\204\236 +\330\164\217\252\033\177\136\364\376\105\042\041\002\003\001\000 +\001\243\143\060\141\060\017\006\003\125\035\023\001\001\377\004 +\005\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004 +\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251\020 +\025\130\040\005\011\060\037\006\003\125\035\043\004\030\060\026 +\200\024\161\070\066\362\002\061\123\107\053\156\272\145\106\251 +\020\025\130\040\005\011\060\016\006\003\125\035\017\001\001\377 +\004\004\003\002\001\206\060\015\006\011\052\206\110\206\367\015 +\001\001\005\005\000\003\202\001\001\000\003\367\265\053\253\135 +\020\374\173\262\262\136\254\233\016\176\123\170\131\076\102\004 +\376\165\243\255\254\201\116\327\002\213\136\304\055\310\122\166 +\307\054\037\374\201\062\230\321\113\306\222\223\063\065\061\057 +\374\330\035\104\335\340\201\177\235\351\213\341\144\221\142\013 +\071\010\214\254\164\235\131\331\172\131\122\227\021\271\026\173 +\157\105\323\226\331\061\175\002\066\017\234\073\156\317\054\015 +\003\106\105\353\240\364\177\110\104\306\010\100\314\336\033\160 +\265\051\255\272\213\073\064\145\165\033\161\041\035\054\024\012 +\260\226\225\270\326\352\362\145\373\051\272\117\352\221\223\164 +\151\266\362\377\341\032\320\014\321\166\205\313\212\045\275\227 +\136\054\157\025\231\046\347\266\051\377\042\354\311\002\307\126 +\000\315\111\271\263\154\173\123\004\032\342\250\311\252\022\005 +\043\302\316\347\273\004\002\314\300\107\242\344\304\051\057\133 +\105\127\211\121\356\074\353\122\010\377\007\065\036\237\065\152 +\107\112\126\230\321\132\205\037\214\365\042\277\253\316\203\363 +\342\042\051\256\175\203\100\250\272\154 +END + +# Trust for Certificate "GeoTrust Global CA 2" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Global CA 2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\251\351\170\010\024\067\130\210\362\005\031\260\155\053\015\053 +\140\026\220\175 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\016\100\247\154\336\003\135\217\321\017\344\321\215\371\154\251 +END +CKA_ISSUER MULTILINE_OCTAL +\060\104\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\035\060\033\006\003\125\004\003 +\023\024\107\145\157\124\162\165\163\164\040\107\154\157\142\141 +\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "GeoTrust Universal CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\150\060\202\003\120\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003\023 +\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162 +\163\141\154\040\103\101\060\036\027\015\060\064\060\063\060\064 +\060\065\060\060\060\060\132\027\015\062\071\060\063\060\064\060 +\065\060\060\060\060\132\060\105\061\013\060\011\006\003\125\004 +\006\023\002\125\123\061\026\060\024\006\003\125\004\012\023\015 +\107\145\157\124\162\165\163\164\040\111\156\143\056\061\036\060 +\034\006\003\125\004\003\023\025\107\145\157\124\162\165\163\164 +\040\125\156\151\166\145\162\163\141\154\040\103\101\060\202\002 +\042\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000 +\003\202\002\017\000\060\202\002\012\002\202\002\001\000\246\025 +\125\240\243\306\340\037\214\235\041\120\327\301\276\053\133\265 +\244\236\241\331\162\130\275\000\033\114\277\141\311\024\035\105 +\202\253\306\035\200\326\075\353\020\234\072\257\155\044\370\274 +\161\001\236\006\365\174\137\036\301\016\125\312\203\232\131\060 +\256\031\313\060\110\225\355\042\067\215\364\112\232\162\146\076 +\255\225\300\340\026\000\340\020\037\053\061\016\327\224\124\323 +\102\063\240\064\035\036\105\166\335\117\312\030\067\354\205\025 +\172\031\010\374\325\307\234\360\362\251\056\020\251\222\346\075 +\130\075\251\026\150\074\057\165\041\030\177\050\167\245\341\141 +\027\267\246\351\370\036\231\333\163\156\364\012\242\041\154\356 +\332\252\205\222\146\257\366\172\153\202\332\272\042\010\065\017 +\317\102\361\065\372\152\356\176\053\045\314\072\021\344\155\257 +\163\262\166\035\255\320\262\170\147\032\244\071\034\121\013\147 +\126\203\375\070\135\015\316\335\360\273\053\226\037\336\173\062 +\122\375\035\273\265\006\241\262\041\136\245\326\225\150\177\360 +\231\236\334\105\010\076\347\322\011\015\065\224\335\200\116\123 +\227\327\265\011\104\040\144\026\027\003\002\114\123\015\150\336 +\325\252\162\115\223\155\202\016\333\234\275\317\264\363\134\135 +\124\172\151\011\226\326\333\021\301\215\165\250\264\317\071\310 +\316\074\274\044\174\346\142\312\341\275\175\247\275\127\145\013 +\344\376\045\355\266\151\020\334\050\032\106\275\001\035\320\227 +\265\341\230\073\300\067\144\326\075\224\356\013\341\365\050\256 +\013\126\277\161\213\043\051\101\216\206\305\113\122\173\330\161 +\253\037\212\025\246\073\203\132\327\130\001\121\306\114\101\331 +\177\330\101\147\162\242\050\337\140\203\251\236\310\173\374\123 +\163\162\131\365\223\172\027\166\016\316\367\345\134\331\013\125 +\064\242\252\133\265\152\124\347\023\312\127\354\227\155\364\136 +\006\057\105\213\130\324\043\026\222\344\026\156\050\143\131\060 +\337\120\001\234\143\211\032\237\333\027\224\202\160\067\303\044 +\236\232\107\326\132\312\116\250\151\211\162\037\221\154\333\176 +\236\033\255\307\037\163\335\054\117\031\145\375\177\223\100\020 +\056\322\360\355\074\236\056\050\076\151\046\063\305\173\002\003 +\001\000\001\243\143\060\141\060\017\006\003\125\035\023\001\001 +\377\004\005\060\003\001\001\377\060\035\006\003\125\035\016\004 +\026\004\024\332\273\056\252\260\014\270\210\046\121\164\134\155 +\003\323\300\330\217\172\326\060\037\006\003\125\035\043\004\030 +\060\026\200\024\332\273\056\252\260\014\270\210\046\121\164\134 +\155\003\323\300\330\217\172\326\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\206\060\015\006\011\052\206\110\206 +\367\015\001\001\005\005\000\003\202\002\001\000\061\170\346\307 +\265\337\270\224\100\311\161\304\250\065\354\106\035\302\205\363 +\050\130\206\260\013\374\216\262\071\217\104\125\253\144\204\134 +\151\251\320\232\070\074\372\345\037\065\345\104\343\200\171\224 +\150\244\273\304\237\075\341\064\315\060\106\213\124\053\225\245 +\357\367\077\231\204\375\065\346\317\061\306\334\152\277\247\327 +\043\010\341\230\136\303\132\010\166\251\246\257\167\057\267\140 +\275\104\106\152\357\227\377\163\225\301\216\350\223\373\375\061 +\267\354\127\021\021\105\233\060\361\032\210\071\301\117\074\247 +\000\325\307\374\253\155\200\042\160\245\014\340\135\004\051\002 +\373\313\240\221\321\174\326\303\176\120\325\235\130\276\101\070 +\353\271\165\074\025\331\233\311\112\203\131\300\332\123\375\063 +\273\066\030\233\205\017\025\335\356\055\254\166\223\271\331\001 +\215\110\020\250\373\365\070\206\361\333\012\306\275\204\243\043 +\101\336\326\167\157\205\324\205\034\120\340\256\121\212\272\215 +\076\166\342\271\312\047\362\137\237\357\156\131\015\006\330\053 +\027\244\322\174\153\273\137\024\032\110\217\032\114\347\263\107 +\034\216\114\105\053\040\356\110\337\347\335\011\216\030\250\332 +\100\215\222\046\021\123\141\163\135\353\275\347\304\115\051\067 +\141\353\254\071\055\147\056\026\326\365\000\203\205\241\314\177 +\166\304\175\344\267\113\146\357\003\105\140\151\266\014\122\226 +\222\204\136\246\243\265\244\076\053\331\314\330\033\107\252\362 +\104\332\117\371\003\350\360\024\313\077\363\203\336\320\301\124 +\343\267\350\012\067\115\213\040\131\003\060\031\241\054\310\275 +\021\037\337\256\311\112\305\363\047\146\146\206\254\150\221\377 +\331\346\123\034\017\213\134\151\145\012\046\310\036\064\303\135 +\121\173\327\251\234\006\241\066\335\325\211\224\274\331\344\055 +\014\136\011\154\010\227\174\243\075\174\223\377\077\241\024\247 +\317\265\135\353\333\333\034\304\166\337\210\271\275\105\005\225 +\033\256\374\106\152\114\257\110\343\316\256\017\322\176\353\346 +\154\234\117\201\152\172\144\254\273\076\325\347\313\166\056\305 +\247\110\301\134\220\017\313\310\077\372\346\062\341\215\033\157 +\244\346\216\330\371\051\110\212\316\163\376\054 +END + +# Trust for Certificate "GeoTrust Universal CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\346\041\363\065\103\171\005\232\113\150\060\235\212\057\164\042 +\025\207\354\171 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\222\145\130\213\242\032\061\162\163\150\134\264\245\172\007\110 +END +CKA_ISSUER MULTILINE_OCTAL +\060\105\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\036\060\034\006\003\125\004\003 +\023\025\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "GeoTrust Universal CA 2" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA 2" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\154\060\202\003\124\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061\026 +\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165\163 +\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003\023 +\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145\162 +\163\141\154\040\103\101\040\062\060\036\027\015\060\064\060\063 +\060\064\060\065\060\060\060\060\132\027\015\062\071\060\063\060 +\064\060\065\060\060\060\060\132\060\107\061\013\060\011\006\003 +\125\004\006\023\002\125\123\061\026\060\024\006\003\125\004\012 +\023\015\107\145\157\124\162\165\163\164\040\111\156\143\056\061 +\040\060\036\006\003\125\004\003\023\027\107\145\157\124\162\165 +\163\164\040\125\156\151\166\145\162\163\141\154\040\103\101\040 +\062\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001 +\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002 +\001\000\263\124\122\301\311\076\362\331\334\261\123\032\131\051 +\347\261\303\105\050\345\327\321\355\305\305\113\241\252\164\173 +\127\257\112\046\374\330\365\136\247\156\031\333\164\014\117\065 +\133\062\013\001\343\333\353\172\167\065\352\252\132\340\326\350 +\241\127\224\360\220\243\164\126\224\104\060\003\036\134\116\053 +\205\046\164\202\172\014\166\240\157\115\316\101\055\240\025\006 +\024\137\267\102\315\173\217\130\141\064\334\052\010\371\056\303 +\001\246\042\104\034\114\007\202\346\133\316\320\112\174\004\323 +\031\163\047\360\252\230\177\056\257\116\353\207\036\044\167\152 +\135\266\350\133\105\272\334\303\241\005\157\126\216\217\020\046 +\245\111\303\056\327\101\207\042\340\117\206\312\140\265\352\241 +\143\300\001\227\020\171\275\000\074\022\155\053\025\261\254\113 +\261\356\030\271\116\226\334\334\166\377\073\276\317\137\003\300 +\374\073\350\276\106\033\377\332\100\302\122\367\376\343\072\367 +\152\167\065\320\332\215\353\136\030\152\061\307\036\272\074\033 +\050\326\153\124\306\252\133\327\242\054\033\031\314\242\002\366 +\233\131\275\067\153\206\265\155\202\272\330\352\311\126\274\251 +\066\130\375\076\031\363\355\014\046\251\223\070\370\117\301\135 +\042\006\320\227\352\341\255\306\125\340\201\053\050\203\072\372 +\364\173\041\121\000\276\122\070\316\315\146\171\250\364\201\126 +\342\320\203\011\107\121\133\120\152\317\333\110\032\135\076\367 +\313\366\145\367\154\361\225\370\002\073\062\126\202\071\172\133 +\275\057\211\033\277\241\264\350\377\177\215\214\337\003\361\140 +\116\130\021\114\353\243\077\020\053\203\232\001\163\331\224\155 +\204\000\047\146\254\360\160\100\011\102\222\255\117\223\015\141 +\011\121\044\330\222\325\013\224\141\262\207\262\355\377\232\065 +\377\205\124\312\355\104\103\254\033\074\026\153\110\112\012\034 +\100\210\037\222\302\013\000\005\377\362\310\002\112\244\252\251 +\314\231\226\234\057\130\340\175\341\276\273\007\334\137\004\162 +\134\061\064\303\354\137\055\340\075\144\220\042\346\321\354\270 +\056\335\131\256\331\241\067\277\124\065\334\163\062\117\214\004 +\036\063\262\311\106\361\330\134\310\125\120\311\150\275\250\272 +\066\011\002\003\001\000\001\243\143\060\141\060\017\006\003\125 +\035\023\001\001\377\004\005\060\003\001\001\377\060\035\006\003 +\125\035\016\004\026\004\024\166\363\125\341\372\244\066\373\360 +\237\134\142\161\355\074\364\107\070\020\053\060\037\006\003\125 +\035\043\004\030\060\026\200\024\166\363\125\341\372\244\066\373 +\360\237\134\142\161\355\074\364\107\070\020\053\060\016\006\003 +\125\035\017\001\001\377\004\004\003\002\001\206\060\015\006\011 +\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001\000 +\146\301\306\043\363\331\340\056\156\137\350\317\256\260\260\045 +\115\053\370\073\130\233\100\044\067\132\313\253\026\111\377\263 +\165\171\063\241\057\155\160\027\064\221\376\147\176\217\354\233 +\345\136\202\251\125\037\057\334\324\121\007\022\376\254\026\076 +\054\065\306\143\374\334\020\353\015\243\252\320\174\314\321\320 +\057\121\056\304\024\132\336\350\031\341\076\306\314\244\051\347 +\056\204\252\006\060\170\166\124\163\050\230\131\070\340\000\015 +\142\323\102\175\041\237\256\075\072\214\325\372\167\015\030\053 +\026\016\137\066\341\374\052\265\060\044\317\340\143\014\173\130 +\032\376\231\272\102\022\261\221\364\174\150\342\310\350\257\054 +\352\311\176\256\273\052\075\015\025\334\064\225\266\030\164\250 +\152\017\307\264\364\023\304\344\133\355\012\322\244\227\114\052 +\355\057\154\022\211\075\361\047\160\252\152\003\122\041\237\100 +\250\147\120\362\363\132\037\337\337\043\366\334\170\116\346\230 +\117\125\072\123\343\357\362\364\237\307\174\330\130\257\051\042 +\227\270\340\275\221\056\260\166\354\127\021\317\357\051\104\363 +\351\205\172\140\143\344\135\063\211\027\331\061\252\332\326\363 +\030\065\162\317\207\053\057\143\043\204\135\204\214\077\127\240 +\210\374\231\221\050\046\151\231\324\217\227\104\276\216\325\110 +\261\244\050\051\361\025\264\341\345\236\335\370\217\246\157\046 +\327\011\074\072\034\021\016\246\154\067\367\255\104\207\054\050 +\307\330\164\202\263\320\157\112\127\273\065\051\047\240\213\350 +\041\247\207\144\066\135\314\330\026\254\307\262\047\100\222\125 +\070\050\215\121\156\335\024\147\123\154\161\134\046\204\115\165 +\132\266\176\140\126\251\115\255\373\233\036\227\363\015\331\322 +\227\124\167\332\075\022\267\340\036\357\010\006\254\371\205\207 +\351\242\334\257\176\030\022\203\375\126\027\101\056\325\051\202 +\175\231\364\061\366\161\251\317\054\001\047\245\005\271\252\262 +\110\116\052\357\237\223\122\121\225\074\122\163\216\126\114\027 +\100\300\011\050\344\213\152\110\123\333\354\315\125\125\361\306 +\370\351\242\054\114\246\321\046\137\176\257\132\114\332\037\246 +\362\034\054\176\256\002\026\322\126\320\057\127\123\107\350\222 +END + +# Trust for Certificate "GeoTrust Universal CA 2" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "GeoTrust Universal CA 2" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\067\232\031\173\101\205\105\065\014\246\003\151\363\074\056\257 +\107\117\040\171 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\064\374\270\320\066\333\236\024\263\302\362\333\217\344\224\307 +END +CKA_ISSUER MULTILINE_OCTAL +\060\107\061\013\060\011\006\003\125\004\006\023\002\125\123\061 +\026\060\024\006\003\125\004\012\023\015\107\145\157\124\162\165 +\163\164\040\111\156\143\056\061\040\060\036\006\003\125\004\003 +\023\027\107\145\157\124\162\165\163\164\040\125\156\151\166\145 +\162\163\141\154\040\103\101\040\062 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# # Certificate "UTN-USER First-Network Applications" # CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE @@ -12170,6 +12573,198 @@ CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE # +# Certificate "NetLock Qualified (Class QA) Root" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\173 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\006\321\060\202\005\271\240\003\002\001\002\002\001\173 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125\061 +\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160\145 +\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145\164 +\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172\164 +\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030\006 +\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141\156 +\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004\003 +\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163\151 +\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151\040 +\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165\163 +\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034\006 +\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146\157 +\100\156\145\164\154\157\143\153\056\150\165\060\036\027\015\060 +\063\060\063\063\060\060\061\064\067\061\061\132\027\015\062\062 +\061\062\061\065\060\061\064\067\061\061\132\060\201\311\061\013 +\060\011\006\003\125\004\006\023\002\110\125\061\021\060\017\006 +\003\125\004\007\023\010\102\165\144\141\160\145\163\164\061\047 +\060\045\006\003\125\004\012\023\036\116\145\164\114\157\143\153 +\040\110\141\154\157\172\141\164\142\151\172\164\157\156\163\141 +\147\151\040\113\146\164\056\061\032\060\030\006\003\125\004\013 +\023\021\124\141\156\165\163\151\164\166\141\156\171\153\151\141 +\144\157\153\061\102\060\100\006\003\125\004\003\023\071\116\145 +\164\114\157\143\153\040\115\151\156\157\163\151\164\145\164\164 +\040\113\157\172\152\145\147\171\172\157\151\040\050\103\154\141 +\163\163\040\121\101\051\040\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\061\036\060\034\006\011\052\206\110 +\206\367\015\001\011\001\026\017\151\156\146\157\100\156\145\164 +\154\157\143\153\056\150\165\060\202\001\042\060\015\006\011\052 +\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000\060 +\202\001\012\002\202\001\001\000\307\122\045\262\330\075\324\204 +\125\011\247\033\275\154\271\024\364\212\002\333\166\374\152\052 +\170\253\345\167\360\156\340\214\043\147\333\245\144\231\271\335 +\001\076\157\357\055\232\074\042\360\135\311\127\240\125\101\177 +\362\103\136\130\202\123\061\145\316\036\362\046\272\000\124\036 +\257\260\274\034\344\122\214\240\062\257\267\067\261\123\147\150 +\164\147\120\366\055\056\144\336\256\046\171\337\337\231\206\253 +\253\177\205\354\240\373\200\314\364\270\014\036\223\105\143\271 +\334\270\133\233\355\133\071\324\137\142\260\247\216\174\146\070 +\054\252\261\010\143\027\147\175\314\275\263\361\303\077\317\120 +\071\355\321\031\203\025\333\207\022\047\226\267\332\352\345\235 +\274\272\352\071\117\213\357\164\232\347\305\320\322\352\206\121 +\034\344\376\144\010\050\004\171\005\353\312\305\161\016\013\357 +\253\352\354\022\021\241\030\005\062\151\321\014\054\032\075\045 +\231\077\265\174\312\155\260\256\231\231\372\010\140\347\031\302 +\362\275\121\323\314\323\002\254\301\021\014\200\316\253\334\224 +\235\153\243\071\123\072\326\205\002\003\000\305\175\243\202\002 +\300\060\202\002\274\060\022\006\003\125\035\023\001\001\377\004 +\010\060\006\001\001\377\002\001\004\060\016\006\003\125\035\017 +\001\001\377\004\004\003\002\001\006\060\202\002\165\006\011\140 +\206\110\001\206\370\102\001\015\004\202\002\146\026\202\002\142 +\106\111\107\131\105\114\105\115\041\040\105\172\145\156\040\164 +\141\156\165\163\151\164\166\141\156\171\040\141\040\116\145\164 +\114\157\143\153\040\113\146\164\056\040\115\151\156\157\163\151 +\164\145\164\164\040\123\172\157\154\147\141\154\164\141\164\141 +\163\151\040\123\172\141\142\141\154\171\172\141\164\141\142\141 +\156\040\154\145\151\162\164\040\145\154\152\141\162\141\163\157 +\153\040\141\154\141\160\152\141\156\040\153\145\163\172\165\154 +\164\056\040\101\040\155\151\156\157\163\151\164\145\164\164\040 +\145\154\145\153\164\162\157\156\151\153\165\163\040\141\154\141 +\151\162\141\163\040\152\157\147\150\141\164\141\163\040\145\162 +\166\145\156\171\145\163\165\154\145\163\145\156\145\153\054\040 +\166\141\154\141\155\151\156\164\040\145\154\146\157\147\141\144 +\141\163\141\156\141\153\040\146\145\154\164\145\164\145\154\145 +\040\141\040\115\151\156\157\163\151\164\145\164\164\040\123\172 +\157\154\147\141\154\164\141\164\141\163\151\040\123\172\141\142 +\141\154\171\172\141\164\142\141\156\054\040\141\172\040\101\154 +\164\141\154\141\156\157\163\040\123\172\145\162\172\157\144\145 +\163\151\040\106\145\154\164\145\164\145\154\145\153\142\145\156 +\040\145\154\157\151\162\164\040\145\154\154\145\156\157\162\172 +\145\163\151\040\145\154\152\141\162\141\163\040\155\145\147\164 +\145\164\145\154\145\056\040\101\040\144\157\153\165\155\145\156 +\164\165\155\157\153\040\155\145\147\164\141\154\141\154\150\141 +\164\157\153\040\141\040\150\164\164\160\163\072\057\057\167\167 +\167\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143 +\163\057\040\143\151\155\145\156\040\166\141\147\171\040\153\145 +\162\150\145\164\157\153\040\141\172\040\151\156\146\157\100\156 +\145\164\154\157\143\153\056\156\145\164\040\145\055\155\141\151 +\154\040\143\151\155\145\156\056\040\127\101\122\116\111\116\107 +\041\040\124\150\145\040\151\163\163\165\141\156\143\145\040\141 +\156\144\040\164\150\145\040\165\163\145\040\157\146\040\164\150 +\151\163\040\143\145\162\164\151\146\151\143\141\164\145\040\141 +\162\145\040\163\165\142\152\145\143\164\040\164\157\040\164\150 +\145\040\116\145\164\114\157\143\153\040\121\165\141\154\151\146 +\151\145\144\040\103\120\123\040\141\166\141\151\154\141\142\154 +\145\040\141\164\040\150\164\164\160\163\072\057\057\167\167\167 +\056\156\145\164\154\157\143\153\056\150\165\057\144\157\143\163 +\057\040\157\162\040\142\171\040\145\055\155\141\151\154\040\141 +\164\040\151\156\146\157\100\156\145\164\154\157\143\153\056\156 +\145\164\060\035\006\003\125\035\016\004\026\004\024\011\152\142 +\026\222\260\132\273\125\016\313\165\062\072\062\345\262\041\311 +\050\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000 +\003\202\001\001\000\221\152\120\234\333\170\201\233\077\213\102 +\343\073\374\246\303\356\103\340\317\363\342\200\065\111\105\166 +\002\342\343\057\005\305\361\052\347\300\101\063\306\266\233\320 +\063\071\315\300\333\241\255\154\067\002\114\130\101\073\362\227 +\222\306\110\250\315\345\212\071\211\141\371\122\227\351\275\366 +\371\224\164\350\161\016\274\167\206\303\006\314\132\174\112\176 +\064\120\060\056\373\177\062\232\215\075\363\040\133\370\152\312 +\206\363\061\114\054\131\200\002\175\376\070\311\060\165\034\267 +\125\343\274\237\272\250\155\204\050\005\165\263\213\015\300\221 +\124\041\347\246\013\264\231\365\121\101\334\315\243\107\042\331 +\307\001\201\304\334\107\117\046\352\037\355\333\315\015\230\364 +\243\234\264\163\062\112\226\231\376\274\177\310\045\130\370\130 +\363\166\146\211\124\244\246\076\304\120\134\272\211\030\202\165 +\110\041\322\117\023\350\140\176\007\166\333\020\265\121\346\252 +\271\150\252\315\366\235\220\165\022\352\070\032\312\104\350\267 +\231\247\052\150\225\146\225\253\255\357\211\313\140\251\006\022 +\306\224\107\351\050 +END + +# Trust for Certificate "NetLock Qualified (Class QA) Root" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "NetLock Qualified (Class QA) Root" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\001\150\227\341\240\270\362\303\261\064\146\134\040\247\047\267 +\241\130\342\217 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\324\200\145\150\044\371\211\042\050\333\365\244\232\027\217\024 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\311\061\013\060\011\006\003\125\004\006\023\002\110\125 +\061\021\060\017\006\003\125\004\007\023\010\102\165\144\141\160 +\145\163\164\061\047\060\045\006\003\125\004\012\023\036\116\145 +\164\114\157\143\153\040\110\141\154\157\172\141\164\142\151\172 +\164\157\156\163\141\147\151\040\113\146\164\056\061\032\060\030 +\006\003\125\004\013\023\021\124\141\156\165\163\151\164\166\141 +\156\171\153\151\141\144\157\153\061\102\060\100\006\003\125\004 +\003\023\071\116\145\164\114\157\143\153\040\115\151\156\157\163 +\151\164\145\164\164\040\113\157\172\152\145\147\171\172\157\151 +\040\050\103\154\141\163\163\040\121\101\051\040\124\141\156\165 +\163\151\164\166\141\156\171\153\151\141\144\157\061\036\060\034 +\006\011\052\206\110\206\367\015\001\011\001\026\017\151\156\146 +\157\100\156\145\164\154\157\143\153\056\150\165 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\173 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# # Certificate "NetLock Notary (Class A) Root" # CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE @@ -13068,3 +13663,748 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "StartCom Ltd." +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "StartCom Ltd." +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\000 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\026\060\202\004\177\240\003\002\001\002\002\001\000 +\060\015\006\011\052\206\110\206\367\015\001\001\004\005\000\060 +\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114\061 +\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145\154 +\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141\164 +\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162\164 +\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125\004 +\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171\040 +\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040\106 +\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143 +\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\061 +\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026\022 +\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056\157 +\162\147\060\036\027\015\060\065\060\063\061\067\061\067\063\067 +\064\070\132\027\015\063\065\060\063\061\060\061\067\063\067\064 +\070\132\060\201\260\061\013\060\011\006\003\125\004\006\023\002 +\111\114\061\017\060\015\006\003\125\004\010\023\006\111\163\162 +\141\145\154\061\016\060\014\006\003\125\004\007\023\005\105\151 +\154\141\164\061\026\060\024\006\003\125\004\012\023\015\123\164 +\141\162\164\103\157\155\040\114\164\144\056\061\032\060\030\006 +\003\125\004\013\023\021\103\101\040\101\165\164\150\157\162\151 +\164\171\040\104\145\160\056\061\051\060\047\006\003\125\004\003 +\023\040\106\162\145\145\040\123\123\114\040\103\145\162\164\151 +\146\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151 +\164\171\061\041\060\037\006\011\052\206\110\206\367\015\001\011 +\001\026\022\141\144\155\151\156\100\163\164\141\162\164\143\157 +\155\056\157\162\147\060\201\237\060\015\006\011\052\206\110\206 +\367\015\001\001\001\005\000\003\201\215\000\060\201\211\002\201 +\201\000\355\204\140\000\043\236\310\112\121\051\047\336\072\241 +\071\265\151\253\011\262\057\064\375\141\334\075\323\260\317\261 +\327\302\304\302\261\344\226\126\304\276\252\024\016\347\314\072 +\120\310\072\142\235\303\243\254\131\173\216\356\125\032\034\107 +\276\243\227\071\263\265\357\043\054\010\350\330\257\163\057\271 +\311\203\350\355\000\017\310\165\245\057\064\114\030\350\166\210 +\043\111\212\333\266\355\150\332\303\265\142\051\114\245\113\267 +\230\264\011\024\020\240\370\376\142\166\042\025\013\244\326\010 +\057\065\002\003\001\000\001\243\202\002\074\060\202\002\070\060 +\017\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377 +\060\013\006\003\125\035\017\004\004\003\002\001\346\060\035\006 +\003\125\035\016\004\026\004\024\034\211\303\226\314\275\376\062 +\325\015\214\201\061\266\230\235\215\050\144\215\060\201\335\006 +\003\125\035\043\004\201\325\060\201\322\200\024\034\211\303\226 +\314\275\376\062\325\015\214\201\061\266\230\235\215\050\144\215 +\241\201\266\244\201\263\060\201\260\061\013\060\011\006\003\125 +\004\006\023\002\111\114\061\017\060\015\006\003\125\004\010\023 +\006\111\163\162\141\145\154\061\016\060\014\006\003\125\004\007 +\023\005\105\151\154\141\164\061\026\060\024\006\003\125\004\012 +\023\015\123\164\141\162\164\103\157\155\040\114\164\144\056\061 +\032\060\030\006\003\125\004\013\023\021\103\101\040\101\165\164 +\150\157\162\151\164\171\040\104\145\160\056\061\051\060\047\006 +\003\125\004\003\023\040\106\162\145\145\040\123\123\114\040\103 +\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 +\150\157\162\151\164\171\061\041\060\037\006\011\052\206\110\206 +\367\015\001\011\001\026\022\141\144\155\151\156\100\163\164\141 +\162\164\143\157\155\056\157\162\147\202\001\000\060\035\006\003 +\125\035\021\004\026\060\024\201\022\141\144\155\151\156\100\163 +\164\141\162\164\143\157\155\056\157\162\147\060\035\006\003\125 +\035\022\004\026\060\024\201\022\141\144\155\151\156\100\163\164 +\141\162\164\143\157\155\056\157\162\147\060\021\006\011\140\206 +\110\001\206\370\102\001\001\004\004\003\002\000\007\060\057\006 +\011\140\206\110\001\206\370\102\001\015\004\042\026\040\106\162 +\145\145\040\123\123\114\040\103\145\162\164\151\146\151\143\141 +\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060\062 +\006\011\140\206\110\001\206\370\102\001\004\004\045\026\043\150 +\164\164\160\072\057\057\143\145\162\164\056\163\164\141\162\164 +\143\157\155\056\157\162\147\057\143\141\055\143\162\154\056\143 +\162\154\060\050\006\011\140\206\110\001\206\370\102\001\002\004 +\033\026\031\150\164\164\160\072\057\057\143\145\162\164\056\163 +\164\141\162\164\143\157\155\056\157\162\147\057\060\071\006\011 +\140\206\110\001\206\370\102\001\010\004\054\026\052\150\164\164 +\160\072\057\057\143\145\162\164\056\163\164\141\162\164\143\157 +\155\056\157\162\147\057\151\156\144\145\170\056\160\150\160\077 +\141\160\160\075\061\061\061\060\015\006\011\052\206\110\206\367 +\015\001\001\004\005\000\003\201\201\000\154\161\045\341\236\064 +\221\041\357\333\154\275\001\010\126\217\210\330\101\072\123\365 +\162\337\047\127\113\166\204\367\150\244\376\353\077\011\176\050 +\270\127\352\037\301\252\342\377\226\237\111\231\346\262\225\163 +\226\306\110\307\136\215\007\162\126\370\203\217\237\167\257\051 +\323\105\016\244\356\260\066\164\055\360\315\230\043\173\067\113 +\332\376\121\230\304\036\064\074\210\375\231\073\120\247\301\213 +\063\307\302\122\026\022\225\123\145\042\357\272\213\316\142\333 +\160\043\261\200\337\032\040\070\347\176 +END + +# Trust for Certificate "StartCom Ltd." +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "StartCom Ltd." +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\225\346\255\370\327\161\106\002\115\325\152\041\262\347\077\315 +\362\073\065\377 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\010\174\130\037\122\053\104\264\073\171\315\001\370\305\303\311 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\260\061\013\060\011\006\003\125\004\006\023\002\111\114 +\061\017\060\015\006\003\125\004\010\023\006\111\163\162\141\145 +\154\061\016\060\014\006\003\125\004\007\023\005\105\151\154\141 +\164\061\026\060\024\006\003\125\004\012\023\015\123\164\141\162 +\164\103\157\155\040\114\164\144\056\061\032\060\030\006\003\125 +\004\013\023\021\103\101\040\101\165\164\150\157\162\151\164\171 +\040\104\145\160\056\061\051\060\047\006\003\125\004\003\023\040 +\106\162\145\145\040\123\123\114\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\061\041\060\037\006\011\052\206\110\206\367\015\001\011\001\026 +\022\141\144\155\151\156\100\163\164\141\162\164\143\157\155\056 +\157\162\147 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\000 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Taiwan GRCA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Taiwan GRCA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343 +\136\366 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\162\060\202\003\132\240\003\002\001\002\002\020\037 +\235\131\132\327\057\302\006\104\245\200\010\151\343\136\366\060 +\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\077 +\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060\060 +\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155\145 +\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151\143 +\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171\060 +\036\027\015\060\062\061\062\060\065\061\063\062\063\063\063\132 +\027\015\063\062\061\062\060\065\061\063\062\063\063\063\132\060 +\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061\060 +\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156\155 +\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146\151 +\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164\171 +\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001 +\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001 +\000\232\045\270\354\314\242\165\250\173\367\316\133\131\212\311 +\321\206\022\010\124\354\234\362\347\106\366\210\363\174\351\245 +\337\114\107\066\244\033\001\034\177\036\127\212\215\303\305\321 +\041\343\332\044\077\110\053\373\237\056\241\224\347\054\034\223 +\321\277\033\001\207\123\231\316\247\365\012\041\166\167\377\251 +\267\306\163\224\117\106\367\020\111\067\372\250\131\111\135\152 +\201\007\126\362\212\371\006\320\367\160\042\115\264\267\101\271 +\062\270\261\360\261\303\234\077\160\375\123\335\201\252\330\143 +\170\366\330\123\156\241\254\152\204\044\162\124\206\306\322\262 +\312\034\016\171\201\326\265\160\142\010\001\056\116\117\016\325 +\021\257\251\257\345\232\277\334\314\207\155\046\344\311\127\242 +\373\226\371\314\341\077\123\214\154\114\176\233\123\010\013\154 +\027\373\147\310\302\255\261\315\200\264\227\334\166\001\026\025 +\351\152\327\244\341\170\107\316\206\325\373\061\363\372\061\276 +\064\252\050\373\160\114\035\111\307\257\054\235\155\146\246\266 +\215\144\176\265\040\152\235\073\201\266\217\100\000\147\113\211 +\206\270\314\145\376\025\123\351\004\301\326\137\035\104\327\012 +\057\047\232\106\175\241\015\165\255\124\206\025\334\111\073\361 +\226\316\017\233\240\354\243\172\135\276\325\052\165\102\345\173 +\336\245\266\252\257\050\254\254\220\254\070\267\325\150\065\046 +\172\334\367\073\363\375\105\233\321\273\103\170\156\157\361\102 +\124\152\230\360\015\255\227\351\122\136\351\325\152\162\336\152 +\367\033\140\024\364\245\344\266\161\147\252\037\352\342\115\301 +\102\100\376\147\106\027\070\057\107\077\161\234\256\345\041\312 +\141\055\155\007\250\204\174\055\356\121\045\361\143\220\236\375 +\341\127\210\153\357\212\043\155\261\346\275\077\255\321\075\226 +\013\205\215\315\153\047\273\267\005\233\354\273\221\251\012\007 +\022\002\227\116\040\220\360\377\015\036\342\101\073\323\100\072 +\347\215\135\332\146\344\002\260\007\122\230\134\016\216\063\234 +\302\246\225\373\125\031\156\114\216\256\113\017\275\301\070\115 +\136\217\204\035\146\315\305\140\226\264\122\132\005\211\216\225 +\172\230\301\221\074\225\043\262\016\364\171\264\311\174\301\112 +\041\002\003\001\000\001\243\152\060\150\060\035\006\003\125\035 +\016\004\026\004\024\314\314\357\314\051\140\244\073\261\222\266 +\074\372\062\142\217\254\045\025\073\060\014\006\003\125\035\023 +\004\005\060\003\001\001\377\060\071\006\004\147\052\007\000\004 +\061\060\057\060\055\002\001\000\060\011\006\005\053\016\003\002 +\032\005\000\060\007\006\005\147\052\003\000\000\004\024\003\233 +\360\042\023\377\225\050\066\323\334\236\300\062\373\061\072\212 +\121\145\060\015\006\011\052\206\110\206\367\015\001\001\005\005 +\000\003\202\002\001\000\100\200\112\372\046\311\316\136\060\335 +\117\206\164\166\130\365\256\263\203\063\170\244\172\164\027\031 +\116\351\122\265\271\340\012\164\142\252\150\312\170\240\114\232 +\216\054\043\056\325\152\022\044\277\324\150\323\212\320\330\234 +\237\264\037\014\336\070\176\127\070\374\215\342\117\136\014\237 +\253\073\322\377\165\227\313\244\343\147\010\377\345\300\026\265 +\110\001\175\351\371\012\377\033\345\152\151\277\170\041\250\302 +\247\043\251\206\253\166\126\350\016\014\366\023\335\052\146\212 +\144\111\075\032\030\207\220\004\237\102\122\267\117\313\376\107 +\101\166\065\357\377\000\166\066\105\062\233\306\106\205\135\342 +\044\260\036\343\110\226\230\127\107\224\125\172\017\101\261\104 +\044\363\301\376\032\153\277\210\375\301\246\332\223\140\136\201 +\112\231\040\234\110\146\031\265\000\171\124\017\270\054\057\113 +\274\251\135\133\140\177\214\207\245\340\122\143\052\276\330\073 +\205\100\025\376\036\266\145\077\305\113\332\176\265\172\065\051 +\243\056\172\230\140\042\243\364\175\047\116\055\352\264\164\074 +\351\017\244\063\017\020\021\274\023\001\326\345\016\323\277\265 +\022\242\341\105\043\300\314\010\156\141\267\211\253\203\343\044 +\036\346\135\007\347\037\040\076\317\147\310\347\254\060\155\047 +\113\150\156\113\052\134\002\010\064\333\370\166\344\147\243\046 +\234\077\242\062\302\112\305\201\030\061\020\126\252\204\357\055 +\012\377\270\037\167\322\277\245\130\240\142\344\327\113\221\165 +\215\211\200\230\176\155\313\123\116\136\257\366\262\227\205\227 +\271\332\125\006\271\044\356\327\306\070\036\143\033\022\073\225 +\341\130\254\362\337\204\325\137\231\057\015\125\133\346\070\333 +\056\077\162\351\110\205\313\273\051\023\217\036\070\125\271\363 +\262\304\060\231\043\116\135\362\110\241\022\014\334\022\220\011 +\220\124\221\003\074\107\345\325\311\145\340\267\113\175\354\107 +\323\263\013\076\255\236\320\164\000\016\353\275\121\255\300\336 +\054\300\303\152\376\357\334\013\247\372\106\337\140\333\234\246 +\131\120\165\043\151\163\223\262\371\374\002\323\107\346\161\316 +\020\002\356\047\214\204\377\254\105\015\023\134\203\062\340\045 +\245\206\054\174\364\022 +END + +# Trust for Certificate "Taiwan GRCA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Taiwan GRCA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\364\213\021\277\336\253\276\224\124\040\161\346\101\336\153\276 +\210\053\100\271 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\067\205\104\123\062\105\037\040\360\363\225\341\045\304\103\116 +END +CKA_ISSUER MULTILINE_OCTAL +\060\077\061\013\060\011\006\003\125\004\006\023\002\124\127\061 +\060\060\056\006\003\125\004\012\014\047\107\157\166\145\162\156 +\155\145\156\164\040\122\157\157\164\040\103\145\162\164\151\146 +\151\143\141\164\151\157\156\040\101\165\164\150\157\162\151\164 +\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\037\235\131\132\327\057\302\006\104\245\200\010\151\343 +\136\366 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Firmaprofesional Root CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Firmaprofesional Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\004\127\060\202\003\077\240\003\002\001\002\002\001\001 +\060\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060 +\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156 +\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154 +\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165 +\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151 +\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162 +\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066 +\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110 +\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141 +\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060 +\036\027\015\060\061\061\060\062\064\062\062\060\060\060\060\132 +\027\015\061\063\061\060\062\064\062\062\060\060\060\060\132\060 +\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123\061 +\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165\156 +\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145\154 +\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101\165 +\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164\151 +\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160\162 +\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101\066 +\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206\110 +\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155\141 +\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155\060 +\202\001\042\060\015\006\011\052\206\110\206\367\015\001\001\001 +\005\000\003\202\001\017\000\060\202\001\012\002\202\001\001\000 +\347\043\003\157\157\043\245\136\170\316\225\054\355\224\036\156 +\012\236\001\307\352\060\321\054\235\335\067\350\233\230\171\126 +\323\374\163\337\320\212\336\125\217\121\371\132\352\336\265\160 +\304\355\244\355\377\243\015\156\017\144\120\061\257\001\047\130 +\256\376\154\247\112\057\027\055\323\163\325\023\034\217\131\245 +\064\054\035\124\004\105\315\150\270\240\300\003\245\317\205\102 +\107\225\050\133\317\357\200\154\340\220\227\212\001\074\035\363 +\207\020\060\046\110\175\327\374\351\235\221\161\377\101\232\251 +\100\265\067\234\051\040\117\037\122\343\240\175\023\155\124\267 +\012\336\351\152\116\007\254\254\031\137\334\176\142\164\366\262 +\005\000\272\205\240\375\035\070\156\313\132\273\206\274\224\147 +\063\065\203\054\037\043\315\370\310\221\161\314\227\213\357\256 +\017\334\051\003\033\300\071\353\160\355\301\156\016\330\147\013 +\211\251\274\065\344\357\266\064\264\245\266\304\055\245\276\320 +\303\224\044\110\333\337\226\323\000\265\146\032\213\146\005\017 +\335\077\077\313\077\252\136\232\112\370\264\112\357\225\067\033 +\002\003\001\000\001\243\201\237\060\201\234\060\052\006\003\125 +\035\021\004\043\060\041\206\037\150\164\164\160\072\057\057\167 +\167\167\056\146\151\162\155\141\160\162\157\146\145\163\151\157 +\156\141\154\056\143\157\155\060\022\006\003\125\035\023\001\001 +\377\004\010\060\006\001\001\377\002\001\001\060\053\006\003\125 +\035\020\004\044\060\042\200\017\062\060\060\061\061\060\062\064 +\062\062\060\060\060\060\132\201\017\062\060\061\063\061\060\062 +\064\062\062\060\060\060\060\132\060\016\006\003\125\035\017\001 +\001\377\004\004\003\002\001\006\060\035\006\003\125\035\016\004 +\026\004\024\063\013\240\146\321\352\332\316\336\142\223\004\050 +\122\265\024\177\070\150\267\060\015\006\011\052\206\110\206\367 +\015\001\001\005\005\000\003\202\001\001\000\107\163\376\215\047 +\124\360\365\324\167\234\047\171\127\127\267\025\126\354\307\330 +\130\267\001\002\364\063\355\223\120\210\236\174\106\261\275\077 +\024\157\361\263\107\110\213\214\227\006\327\352\176\243\134\052 +\273\115\057\107\342\370\071\006\311\234\056\061\032\003\170\364 +\274\070\306\042\213\063\061\360\026\004\004\175\371\166\344\113 +\327\300\346\203\354\131\314\077\336\377\117\153\267\147\176\246 +\206\201\062\043\003\235\310\367\137\301\112\140\245\222\251\261 +\244\240\140\303\170\207\263\042\363\052\353\133\251\355\005\253 +\067\017\261\342\323\225\166\143\126\164\214\130\162\033\067\345 +\144\241\276\115\014\223\230\014\227\366\207\155\263\077\347\313 +\200\246\355\210\307\137\120\142\002\350\231\164\026\320\346\264 +\071\361\047\313\310\100\326\343\206\020\251\043\022\222\340\151 +\101\143\247\257\045\013\300\305\222\313\036\230\243\132\272\305 +\063\017\240\227\001\335\177\340\173\326\006\124\317\241\342\115 +\070\353\113\120\265\313\046\364\312\332\160\112\152\241\342\171 +\252\341\247\063\366\375\112\037\366\331\140 +END + +# Trust for Certificate "Firmaprofesional Root CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Firmaprofesional Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\251\142\217\113\230\251\033\110\065\272\322\301\106\062\206\273 +\146\144\152\214 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\021\222\171\100\074\261\203\100\345\253\146\112\147\222\200\337 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\235\061\013\060\011\006\003\125\004\006\023\002\105\123 +\061\042\060\040\006\003\125\004\007\023\031\103\057\040\115\165 +\156\164\141\156\145\162\040\062\064\064\040\102\141\162\143\145 +\154\157\156\141\061\102\060\100\006\003\125\004\003\023\071\101 +\165\164\157\162\151\144\141\144\040\144\145\040\103\145\162\164 +\151\146\151\143\141\143\151\157\156\040\106\151\162\155\141\160 +\162\157\146\145\163\151\157\156\141\154\040\103\111\106\040\101 +\066\062\066\063\064\060\066\070\061\046\060\044\006\011\052\206 +\110\206\367\015\001\011\001\026\027\143\141\100\146\151\162\155 +\141\160\162\157\146\145\163\151\157\156\141\154\056\143\157\155 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\001\001 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_VALID +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Wells Fargo Root CA" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Wells Fargo Root CA" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\071\344\227\236 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\003\345\060\202\002\315\240\003\002\001\002\002\004\071 +\344\227\236\060\015\006\011\052\206\110\206\367\015\001\001\005 +\005\000\060\201\202\061\013\060\011\006\003\125\004\006\023\002 +\125\123\061\024\060\022\006\003\125\004\012\023\013\127\145\154 +\154\163\040\106\141\162\147\157\061\054\060\052\006\003\125\004 +\013\023\043\127\145\154\154\163\040\106\141\162\147\157\040\103 +\145\162\164\151\146\151\143\141\164\151\157\156\040\101\165\164 +\150\157\162\151\164\171\061\057\060\055\006\003\125\004\003\023 +\046\127\145\154\154\163\040\106\141\162\147\157\040\122\157\157 +\164\040\103\145\162\164\151\146\151\143\141\164\145\040\101\165 +\164\150\157\162\151\164\171\060\036\027\015\060\060\061\060\061 +\061\061\066\064\061\062\070\132\027\015\062\061\060\061\061\064 +\061\066\064\061\062\070\132\060\201\202\061\013\060\011\006\003 +\125\004\006\023\002\125\123\061\024\060\022\006\003\125\004\012 +\023\013\127\145\154\154\163\040\106\141\162\147\157\061\054\060 +\052\006\003\125\004\013\023\043\127\145\154\154\163\040\106\141 +\162\147\157\040\103\145\162\164\151\146\151\143\141\164\151\157 +\156\040\101\165\164\150\157\162\151\164\171\061\057\060\055\006 +\003\125\004\003\023\046\127\145\154\154\163\040\106\141\162\147 +\157\040\122\157\157\164\040\103\145\162\164\151\146\151\143\141 +\164\145\040\101\165\164\150\157\162\151\164\171\060\202\001\042 +\060\015\006\011\052\206\110\206\367\015\001\001\001\005\000\003 +\202\001\017\000\060\202\001\012\002\202\001\001\000\325\250\063 +\073\046\371\064\377\315\233\176\345\004\107\316\000\342\175\167 +\347\061\302\056\047\245\115\150\271\061\272\215\103\131\227\307 +\163\252\177\075\134\100\236\005\345\241\342\211\331\114\270\077 +\233\371\014\264\310\142\031\054\105\256\221\036\163\161\101\304 +\113\023\375\160\302\045\254\042\365\165\013\267\123\344\245\053 +\335\316\275\034\072\172\303\367\023\217\046\124\234\026\153\153 +\257\373\330\226\261\140\232\110\340\045\042\044\171\064\316\016 +\046\000\013\116\253\375\213\316\202\327\057\010\160\150\301\250 +\012\371\164\117\007\253\244\371\342\203\176\047\163\164\076\270 +\371\070\102\374\245\250\133\110\043\263\353\343\045\262\200\256 +\226\324\012\234\302\170\232\306\150\030\256\067\142\067\136\121 +\165\250\130\143\300\121\356\100\170\176\250\257\032\240\341\260 +\170\235\120\214\173\347\263\374\216\043\260\333\145\000\160\204 +\001\010\000\024\156\124\206\232\272\314\371\067\020\366\340\336 +\204\055\235\244\205\067\323\207\343\025\320\301\027\220\176\031 +\041\152\022\251\166\375\022\002\351\117\041\136\027\002\003\001 +\000\001\243\141\060\137\060\017\006\003\125\035\023\001\001\377 +\004\005\060\003\001\001\377\060\114\006\003\125\035\040\004\105 +\060\103\060\101\006\013\140\206\110\001\206\373\173\207\007\001 +\013\060\062\060\060\006\010\053\006\001\005\005\007\002\001\026 +\044\150\164\164\160\072\057\057\167\167\167\056\167\145\154\154 +\163\146\141\162\147\157\056\143\157\155\057\143\145\162\164\160 +\157\154\151\143\171\060\015\006\011\052\206\110\206\367\015\001 +\001\005\005\000\003\202\001\001\000\322\047\335\234\012\167\053 +\273\042\362\002\265\112\112\221\371\321\055\276\344\273\032\150 +\357\016\244\000\351\356\347\357\356\366\371\345\164\244\302\330 +\122\130\304\164\373\316\153\265\073\051\171\030\132\357\233\355 +\037\153\066\356\110\045\045\024\266\126\242\020\350\356\247\177 +\320\077\243\320\303\135\046\356\007\314\303\301\044\041\207\036 +\337\052\022\123\157\101\026\347\355\256\224\372\214\162\372\023 +\107\360\074\176\256\175\021\072\023\354\355\372\157\162\144\173 +\235\175\177\046\375\172\373\045\255\352\076\051\177\114\343\000 +\127\062\260\263\351\355\123\027\331\213\262\024\016\060\350\345 +\325\023\306\144\257\304\000\325\330\130\044\374\365\217\354\361 +\307\175\245\333\017\047\321\306\362\100\210\346\037\366\141\250 +\364\102\310\271\067\323\251\276\054\126\170\302\162\233\131\135 +\065\100\212\350\116\143\032\266\351\040\152\121\342\316\244\220 +\337\166\160\231\134\160\103\115\267\266\247\031\144\116\222\267 +\305\221\074\177\110\026\145\173\026\375\313\374\373\331\325\326 +\117\041\145\073\112\177\107\243\373 +END + +# Trust for Certificate "Wells Fargo Root CA" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Wells Fargo Root CA" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\223\346\253\042\003\003\265\043\050\334\332\126\236\272\344\321 +\321\314\373\145 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\040\013\112\172\210\247\251\102\206\212\137\164\126\173\210\005 +END +CKA_ISSUER MULTILINE_OCTAL +\060\201\202\061\013\060\011\006\003\125\004\006\023\002\125\123 +\061\024\060\022\006\003\125\004\012\023\013\127\145\154\154\163 +\040\106\141\162\147\157\061\054\060\052\006\003\125\004\013\023 +\043\127\145\154\154\163\040\106\141\162\147\157\040\103\145\162 +\164\151\146\151\143\141\164\151\157\156\040\101\165\164\150\157 +\162\151\164\171\061\057\060\055\006\003\125\004\003\023\046\127 +\145\154\154\163\040\106\141\162\147\157\040\122\157\157\164\040 +\103\145\162\164\151\146\151\143\141\164\145\040\101\165\164\150 +\157\162\151\164\171 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\004\071\344\227\236 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE + +# +# Certificate "Swisscom Root CA 1" +# +CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Swisscom Root CA 1" +CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509 +CKA_SUBJECT MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_ID UTF8 "0" +CKA_ISSUER MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235 +\250\066 +END +CKA_VALUE MULTILINE_OCTAL +\060\202\005\331\060\202\003\301\240\003\002\001\002\002\020\134 +\013\205\134\013\347\131\101\337\127\314\077\177\235\250\066\060 +\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\144 +\061\013\060\011\006\003\125\004\006\023\002\143\150\061\021\060 +\017\006\003\125\004\012\023\010\123\167\151\163\163\143\157\155 +\061\045\060\043\006\003\125\004\013\023\034\104\151\147\151\164 +\141\154\040\103\145\162\164\151\146\151\143\141\164\145\040\123 +\145\162\166\151\143\145\163\061\033\060\031\006\003\125\004\003 +\023\022\123\167\151\163\163\143\157\155\040\122\157\157\164\040 +\103\101\040\061\060\036\027\015\060\065\060\070\061\070\061\062 +\060\066\062\060\132\027\015\062\065\060\070\061\070\062\062\060 +\066\062\060\132\060\144\061\013\060\011\006\003\125\004\006\023 +\002\143\150\061\021\060\017\006\003\125\004\012\023\010\123\167 +\151\163\163\143\157\155\061\045\060\043\006\003\125\004\013\023 +\034\104\151\147\151\164\141\154\040\103\145\162\164\151\146\151 +\143\141\164\145\040\123\145\162\166\151\143\145\163\061\033\060 +\031\006\003\125\004\003\023\022\123\167\151\163\163\143\157\155 +\040\122\157\157\164\040\103\101\040\061\060\202\002\042\060\015 +\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002 +\017\000\060\202\002\012\002\202\002\001\000\320\271\260\250\014 +\331\273\077\041\370\033\325\063\223\200\026\145\040\165\262\075 +\233\140\155\106\310\214\061\157\027\303\372\232\154\126\355\074 +\305\221\127\303\315\253\226\111\220\052\031\113\036\243\155\127 +\335\361\053\142\050\165\105\136\252\326\133\372\013\045\330\241 +\026\371\034\304\056\346\225\052\147\314\320\051\156\074\205\064 +\070\141\111\261\000\237\326\072\161\137\115\155\316\137\271\251 +\344\211\177\152\122\372\312\233\362\334\251\371\235\231\107\077 +\116\051\137\264\246\215\135\173\013\231\021\003\003\376\347\333 +\333\243\377\035\245\315\220\036\001\037\065\260\177\000\333\220 +\157\306\176\173\321\356\172\172\247\252\014\127\157\244\155\305 +\023\073\260\245\331\355\062\034\264\136\147\213\124\334\163\207 +\345\323\027\174\146\120\162\135\324\032\130\301\331\317\330\211 +\002\157\247\111\264\066\135\320\244\336\007\054\266\165\267\050 +\221\326\227\276\050\365\230\036\352\133\046\311\275\260\227\163 +\332\256\221\046\353\150\301\371\071\025\326\147\113\012\155\117 +\313\317\260\344\102\161\214\123\171\347\356\341\333\035\240\156 +\035\214\032\167\065\134\026\036\053\123\037\064\213\321\154\374 +\362\147\007\172\365\255\355\326\232\253\241\261\113\341\314\067 +\137\375\177\315\115\256\270\037\234\103\371\052\130\125\103\105 +\274\226\315\160\016\374\311\343\146\272\116\215\073\201\313\025 +\144\173\271\224\350\135\063\122\205\161\056\117\216\242\006\021 +\121\311\343\313\241\156\061\010\144\014\302\322\074\365\066\350 +\327\320\016\170\043\040\221\311\044\052\145\051\133\042\367\041 +\316\203\136\244\363\336\113\323\150\217\106\165\134\203\011\156 +\051\153\304\160\214\365\235\327\040\057\377\106\322\053\070\302 +\057\165\034\075\176\332\245\357\036\140\205\151\102\323\314\370 +\143\376\036\103\071\205\246\266\143\101\020\263\163\036\274\323 +\372\312\175\026\107\342\247\325\320\243\212\012\010\226\142\126 +\156\064\333\331\002\271\060\165\343\004\322\347\217\302\260\021 +\100\012\254\325\161\002\142\213\061\276\335\306\043\130\061\102 +\103\055\164\371\306\236\246\212\017\351\376\277\203\346\103\127 +\044\272\357\106\064\252\327\022\001\070\355\002\003\001\000\001 +\243\201\206\060\201\203\060\016\006\003\125\035\017\001\001\377 +\004\004\003\002\001\206\060\035\006\003\125\035\041\004\026\060 +\024\060\022\006\007\140\205\164\001\123\000\001\006\007\140\205 +\164\001\123\000\001\060\022\006\003\125\035\023\001\001\377\004 +\010\060\006\001\001\377\002\001\007\060\037\006\003\125\035\043 +\004\030\060\026\200\024\003\045\057\336\157\202\001\072\134\054 +\334\053\241\151\265\147\324\214\323\375\060\035\006\003\125\035 +\016\004\026\004\024\003\045\057\336\157\202\001\072\134\054\334 +\053\241\151\265\147\324\214\323\375\060\015\006\011\052\206\110 +\206\367\015\001\001\005\005\000\003\202\002\001\000\065\020\313 +\354\246\004\015\015\017\315\300\333\253\250\362\210\227\014\337 +\223\057\115\174\100\126\061\172\353\244\017\140\315\172\363\276 +\303\047\216\003\076\244\335\022\357\176\036\164\006\074\077\061 +\362\034\173\221\061\041\264\360\320\154\227\324\351\227\262\044 +\126\036\126\303\065\275\210\005\017\133\020\032\144\341\307\202 +\060\371\062\255\236\120\054\347\170\005\320\061\261\132\230\212 +\165\116\220\134\152\024\052\340\122\107\202\140\346\036\332\201 +\261\373\024\013\132\361\237\322\225\272\076\320\033\326\025\035 +\243\276\206\325\333\017\300\111\144\273\056\120\031\113\322\044 +\370\335\036\007\126\320\070\240\225\160\040\166\214\327\335\036 +\336\237\161\304\043\357\203\023\134\243\044\025\115\051\100\074 +\152\304\251\330\267\246\104\245\015\364\340\235\167\036\100\160 +\046\374\332\331\066\344\171\344\265\077\274\233\145\276\273\021 +\226\317\333\306\050\071\072\010\316\107\133\123\132\305\231\376 +\135\251\335\357\114\324\306\245\255\002\346\214\007\022\036\157 +\003\321\157\240\243\363\051\275\022\307\120\242\260\177\210\251 +\231\167\232\261\300\245\071\056\134\174\151\342\054\260\352\067 +\152\244\341\132\341\365\120\345\203\357\245\273\052\210\347\214 +\333\375\155\136\227\031\250\176\146\165\153\161\352\277\261\307 +\157\240\364\216\244\354\064\121\133\214\046\003\160\241\167\325 +\001\022\127\000\065\333\043\336\016\212\050\231\375\261\020\157 +\113\377\070\055\140\116\054\234\353\147\265\255\111\356\113\037 +\254\257\373\015\220\132\146\140\160\135\252\315\170\324\044\356 +\310\101\240\223\001\222\234\152\236\374\271\044\305\263\025\202 +\176\276\256\225\053\353\261\300\332\343\001\140\013\136\151\254 +\204\126\141\276\161\027\376\035\023\017\376\306\207\105\351\376 +\062\240\032\015\023\244\224\125\161\245\026\213\272\312\211\260 +\262\307\374\217\330\124\265\223\142\235\316\317\131\373\075\030 +\316\052\313\065\025\202\135\377\124\042\133\161\122\373\267\311 +\376\140\233\000\101\144\360\252\052\354\266\102\103\316\211\146 +\201\310\213\237\071\124\003\045\323\026\065\216\204\320\137\372 +\060\032\365\232\154\364\016\123\371\072\133\321\034 +END + +# Trust for Certificate "Swisscom Root CA 1" +CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST +CKA_TOKEN CK_BBOOL CK_TRUE +CKA_PRIVATE CK_BBOOL CK_FALSE +CKA_MODIFIABLE CK_BBOOL CK_FALSE +CKA_LABEL UTF8 "Swisscom Root CA 1" +CKA_CERT_SHA1_HASH MULTILINE_OCTAL +\137\072\374\012\213\144\366\206\147\064\164\337\176\251\242\376 +\371\372\172\121 +END +CKA_CERT_MD5_HASH MULTILINE_OCTAL +\370\070\174\167\210\337\054\026\150\056\302\342\122\113\270\371 +END +CKA_ISSUER MULTILINE_OCTAL +\060\144\061\013\060\011\006\003\125\004\006\023\002\143\150\061 +\021\060\017\006\003\125\004\012\023\010\123\167\151\163\163\143 +\157\155\061\045\060\043\006\003\125\004\013\023\034\104\151\147 +\151\164\141\154\040\103\145\162\164\151\146\151\143\141\164\145 +\040\123\145\162\166\151\143\145\163\061\033\060\031\006\003\125 +\004\003\023\022\123\167\151\163\163\143\157\155\040\122\157\157 +\164\040\103\101\040\061 +END +CKA_SERIAL_NUMBER MULTILINE_OCTAL +\002\020\134\013\205\134\013\347\131\101\337\127\314\077\177\235 +\250\066 +END +CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR +CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE diff --git a/security/nss/lib/ckfw/builtins/constants.c b/security/nss/lib/ckfw/builtins/constants.c index a4a8bc7c7..6cc62c0e8 100644 --- a/security/nss/lib/ckfw/builtins/constants.c +++ b/security/nss/lib/ckfw/builtins/constants.c @@ -62,7 +62,7 @@ nss_builtins_CryptokiVersion = { NSS_BUILTINS_CRYPTOKI_VERSION_MINOR }; NSS_IMPLEMENT_DATA const NSSUTF8 * -nss_builtins_ManufacturerID = (NSSUTF8 *) "Netscape Communications Corp."; +nss_builtins_ManufacturerID = (NSSUTF8 *) "Mozilla Foundation"; NSS_IMPLEMENT_DATA const NSSUTF8 * nss_builtins_LibraryDescription = (NSSUTF8 *) "NSS Builtin Object Cryptoki Module"; diff --git a/security/nss/lib/ckfw/builtins/nssckbi.h b/security/nss/lib/ckfw/builtins/nssckbi.h index b0378eea9..9397c2710 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.h +++ b/security/nss/lib/ckfw/builtins/nssckbi.h @@ -75,8 +75,8 @@ * of the comment in the CK_VERSION type definition. */ #define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 1 -#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 60 -#define NSS_BUILTINS_LIBRARY_VERSION "1.60" +#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 62 +#define NSS_BUILTINS_LIBRARY_VERSION "1.62" /* These version numbers detail the semantic changes to the ckfw engine. */ #define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1 diff --git a/security/nss/lib/ckfw/builtins/nssckbi.rc b/security/nss/lib/ckfw/builtins/nssckbi.rc index 1ff4fa9c1..2d30b880c 100644 --- a/security/nss/lib/ckfw/builtins/nssckbi.rc +++ b/security/nss/lib/ckfw/builtins/nssckbi.rc @@ -80,11 +80,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_BUILTINS_LIBRARY_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_BUILTINS_LIBRARY_VERSION "\0" diff --git a/security/nss/lib/ckfw/capi/nsscapi.rc b/security/nss/lib/ckfw/capi/nsscapi.rc index d5024f7a6..254599f75 100644 --- a/security/nss/lib/ckfw/capi/nsscapi.rc +++ b/security/nss/lib/ckfw/capi/nsscapi.rc @@ -84,7 +84,6 @@ BEGIN VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_CKCAPI_LIBRARY_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2005 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_CKCAPI_LIBRARY_VERSION "\0" diff --git a/security/nss/lib/ckfw/dbm/Makefile b/security/nss/lib/ckfw/dbm/Makefile index bc6c17f1a..0df6bf84e 100644 --- a/security/nss/lib/ckfw/dbm/Makefile +++ b/security/nss/lib/ckfw/dbm/Makefile @@ -1,35 +1,39 @@ # -# 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. -# +# ***** 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 ***** MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" include manifest.mn diff --git a/security/nss/lib/ckfw/dbm/anchor.c b/security/nss/lib/ckfw/dbm/anchor.c index 6f6137a3c..26f5a3fc6 100644 --- a/security/nss/lib/ckfw/dbm/anchor.c +++ b/security/nss/lib/ckfw/dbm/anchor.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/ckdbm.h b/security/nss/lib/ckfw/dbm/ckdbm.h index a38850a0f..d0b723c14 100644 --- a/security/nss/lib/ckfw/dbm/ckdbm.h +++ b/security/nss/lib/ckfw/dbm/ckdbm.h @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CKDBM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/config.mk b/security/nss/lib/ckfw/dbm/config.mk index 63eb61689..a885d8663 100644 --- a/security/nss/lib/ckfw/dbm/config.mk +++ b/security/nss/lib/ckfw/dbm/config.mk @@ -1,35 +1,39 @@ # -# 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. -# +# ***** 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 ***** CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" ifdef BUILD_IDG diff --git a/security/nss/lib/ckfw/dbm/db.c b/security/nss/lib/ckfw/dbm/db.c index 83d933a67..6abdce6af 100644 --- a/security/nss/lib/ckfw/dbm/db.c +++ b/security/nss/lib/ckfw/dbm/db.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/find.c b/security/nss/lib/ckfw/dbm/find.c index 929142af8..6979e029b 100644 --- a/security/nss/lib/ckfw/dbm/find.c +++ b/security/nss/lib/ckfw/dbm/find.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/instance.c b/security/nss/lib/ckfw/dbm/instance.c index b87625f55..f1fced615 100644 --- a/security/nss/lib/ckfw/dbm/instance.c +++ b/security/nss/lib/ckfw/dbm/instance.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; @@ -119,7 +122,7 @@ nss_dbm_mdInstance_GetManufacturerID CK_RV *pError ) { - return "Netscape Communications Corp."; + return "Mozilla Foundation"; } static NSSUTF8 * diff --git a/security/nss/lib/ckfw/dbm/manifest.mn b/security/nss/lib/ckfw/dbm/manifest.mn index ff4b408ca..0bee9e620 100644 --- a/security/nss/lib/ckfw/dbm/manifest.mn +++ b/security/nss/lib/ckfw/dbm/manifest.mn @@ -1,35 +1,39 @@ # -# 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. -# +# ***** 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 ***** MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$" CORE_DEPTH = ../../../.. diff --git a/security/nss/lib/ckfw/dbm/object.c b/security/nss/lib/ckfw/dbm/object.c index bf85447ad..1a8f76ed3 100644 --- a/security/nss/lib/ckfw/dbm/object.c +++ b/security/nss/lib/ckfw/dbm/object.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/session.c b/security/nss/lib/ckfw/dbm/session.c index 8ce140641..371a94adc 100644 --- a/security/nss/lib/ckfw/dbm/session.c +++ b/security/nss/lib/ckfw/dbm/session.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/slot.c b/security/nss/lib/ckfw/dbm/slot.c index 800815cf7..e43700c75 100644 --- a/security/nss/lib/ckfw/dbm/slot.c +++ b/security/nss/lib/ckfw/dbm/slot.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/dbm/token.c b/security/nss/lib/ckfw/dbm/token.c index ed958ec31..16bd2b3fc 100644 --- a/security/nss/lib/ckfw/dbm/token.c +++ b/security/nss/lib/ckfw/dbm/token.c @@ -1,35 +1,38 @@ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * +/* ***** 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 ***** */ #ifdef DEBUG static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; diff --git a/security/nss/lib/ckfw/find.c b/security/nss/lib/ckfw/find.c index fe9345b42..747c79ef9 100644 --- a/security/nss/lib/ckfw/find.c +++ b/security/nss/lib/ckfw/find.c @@ -176,22 +176,24 @@ nssCKFWFindObjects_Create return fwFindObjects; loser: - nss_ZFreeIf(fwFindObjects); - - if( (NSSCKMDFindObjects *)NULL != mdFindObjects1 ) { - if( (void *)NULL != (void *)mdFindObjects1->Final ) { - fwFindObjects->mdFindObjects = mdFindObjects1; - mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, - fwSession, mdToken, fwToken, mdInstance, fwInstance); + if( fwFindObjects ) { + if( NULL != mdFindObjects1 ) { + if( NULL != mdFindObjects1->Final ) { + fwFindObjects->mdFindObjects = mdFindObjects1; + mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession, + fwSession, mdToken, fwToken, mdInstance, fwInstance); + } } - } - if( (NSSCKMDFindObjects *)NULL != mdFindObjects2 ) { - if( (void *)NULL != (void *)mdFindObjects2->Final ) { - fwFindObjects->mdFindObjects = mdFindObjects2; - mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, - fwSession, mdToken, fwToken, mdInstance, fwInstance); + if( NULL != mdFindObjects2 ) { + if( NULL != mdFindObjects2->Final ) { + fwFindObjects->mdFindObjects = mdFindObjects2; + mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession, + fwSession, mdToken, fwToken, mdInstance, fwInstance); + } } + + nss_ZFreeIf(fwFindObjects); } if( CKR_OK == *pError ) { diff --git a/security/nss/lib/ckfw/session.c b/security/nss/lib/ckfw/session.c index b2a85d75c..2b020d77e 100644 --- a/security/nss/lib/ckfw/session.c +++ b/security/nss/lib/ckfw/session.c @@ -234,7 +234,7 @@ nssCKFWSession_Create loser: if( (NSSArena *)NULL != arena ) { - if( (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) { + if( fwSession && (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) { (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash); } NSSArena_Destroy(arena); diff --git a/security/nss/lib/ckfw/wrap.c b/security/nss/lib/ckfw/wrap.c index b9af321a3..3ffded1f0 100644 --- a/security/nss/lib/ckfw/wrap.c +++ b/security/nss/lib/ckfw/wrap.c @@ -647,7 +647,8 @@ NSSCKFWC_GetTokenInfo switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: @@ -841,7 +842,8 @@ NSSCKFWC_GetMechanismList switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_BUFFER_TOO_SMALL: case CKR_CRYPTOKI_NOT_INITIALIZED: @@ -944,7 +946,8 @@ NSSCKFWC_GetMechanismInfo switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: @@ -1034,7 +1037,8 @@ NSSCKFWC_InitToken switch( error ) { case CKR_DEVICE_REMOVED: case CKR_TOKEN_NOT_PRESENT: - (void)nssCKFWToken_Destroy(fwToken); + if (fwToken) + nssCKFWToken_Destroy(fwToken); break; case CKR_CRYPTOKI_NOT_INITIALIZED: case CKR_DEVICE_ERROR: diff --git a/security/nss/lib/crmf/challcli.c b/security/nss/lib/crmf/challcli.c index 47b390917..a567452d5 100644 --- a/security/nss/lib/crmf/challcli.c +++ b/security/nss/lib/crmf/challcli.c @@ -122,54 +122,39 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, { CMMFChallenge *challenge; SECItem *decryptedRand=NULL; + PRArenaPool *poolp = NULL; SECAlgorithmID *owf; - PK11SlotInfo *slot; - PK11SymKey *symKey = NULL; SECStatus rv = SECFailure; + SECOidTag tag; CMMFRand randStr; SECItem hashItem; - SECOidTag tag; unsigned char hash[HASH_LENGTH_MAX]; - PRArenaPool *poolp = NULL; PORT_Assert(inChalCont != NULL && inPrivKey != NULL); if (inChalCont == NULL || inIndex <0 || inIndex > inChalCont->numChallenges || inPrivKey == NULL){ return SECFailure; } - challenge = inChalCont->challenges[inIndex]; - decryptedRand = PORT_ZNew(SECItem); - if (decryptedRand == NULL) { + + poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); + if (poolp == NULL) { goto loser; } - decryptedRand->data = - PORT_NewArray(unsigned char, challenge->challenge.len); - if (decryptedRand->data == NULL) { + + challenge = inChalCont->challenges[inIndex]; + decryptedRand = SECITEM_AllocItem(poolp, NULL, challenge->challenge.len); + if (decryptedRand == NULL) { goto loser; } - slot = inPrivKey->pkcs11Slot; - symKey = PK11_PubUnwrapSymKey(inPrivKey, &challenge->challenge, - CKM_RSA_PKCS, CKA_VALUE, 0); - if (symKey == NULL) { - rv = SECFailure; - goto loser; - } - rv = PK11_ExtractKeyValue(symKey); + rv = PK11_PrivDecryptPKCS1(inPrivKey, decryptedRand->data, + &decryptedRand->len, decryptedRand->len, + challenge->challenge.data, challenge->challenge.len); if (rv != SECSuccess) { - goto loser; - } - decryptedRand = PK11_GetKeyData(symKey); - - poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); - if (poolp == NULL) { goto loser; } + rv = SEC_ASN1DecodeItem(poolp, &randStr, CMMFRandTemplate, decryptedRand); - /* The decryptedRand returned points to a member within the symKey - * structure, so we don't want to free it. Let the symKey destruction - * function deal with freeing that memory. - */ if (rv != SECSuccess) { goto loser; } @@ -196,6 +181,7 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, /* The hash for the data we decrypted doesn't match the hash provided * in the challenge. Bail out. */ + PORT_SetError(SEC_ERROR_BAD_DATA); rv = SECFailure; goto loser; } @@ -208,6 +194,7 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, /* The hash for the data we decrypted doesn't match the hash provided * in the challenge. Bail out. */ + PORT_SetError(SEC_ERROR_BAD_DATA); rv = SECFailure; goto loser; } @@ -215,9 +202,6 @@ CMMF_POPODecKeyChallContDecryptChallenge(CMMFPOPODecKeyChallContent *inChalCont, rv = SECITEM_CopyItem(inChalCont->poolp, &challenge->randomNumber, &randStr.integer); loser: - if (symKey != NULL) { - PK11_FreeSymKey(symKey); - } if (poolp) { PORT_FreeArena(poolp, PR_FALSE); } @@ -275,7 +259,10 @@ CMMF_EncodePOPODecKeyRespContent(long *inDecodedRand, if (currItem == NULL) { goto loser; } - SEC_ASN1EncodeInteger(poolp, currItem,inDecodedRand[i]); + currItem = SEC_ASN1EncodeInteger(poolp, currItem, inDecodedRand[i]); + if (currItem == NULL) { + goto loser; + } } rv = cmmf_user_encode(response, inCallback, inArg, CMMFPOPODecKeyRespContentTemplate); diff --git a/security/nss/lib/crmf/crmf.h b/security/nss/lib/crmf/crmf.h index d09163ae1..315100702 100644 --- a/security/nss/lib/crmf/crmf.h +++ b/security/nss/lib/crmf/crmf.h @@ -208,7 +208,7 @@ extern SECStatus CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg, * A pointer to the new Certificate Request. A NULL return value * indicates an error in creating the Certificate Request. */ -extern CRMFCertRequest *CRMF_CreateCertRequest (long inRequestID); +extern CRMFCertRequest *CRMF_CreateCertRequest (PRUint32 inRequestID); /* * FUNCTION: CRMF_DestroyCertRequest diff --git a/security/nss/lib/crmf/crmfcont.c b/security/nss/lib/crmf/crmfcont.c index b609e84ea..f2cab57b3 100644 --- a/security/nss/lib/crmf/crmfcont.c +++ b/security/nss/lib/crmf/crmfcont.c @@ -148,21 +148,27 @@ crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue, PRBool freeit) if (inEncrValue != NULL) { if (inEncrValue->intendedAlg) { SECOID_DestroyAlgorithmID(inEncrValue->intendedAlg, PR_TRUE); + inEncrValue->intendedAlg = NULL; } if (inEncrValue->symmAlg) { SECOID_DestroyAlgorithmID(inEncrValue->symmAlg, PR_TRUE); + inEncrValue->symmAlg = NULL; } if (inEncrValue->encSymmKey.data) { PORT_Free(inEncrValue->encSymmKey.data); + inEncrValue->encSymmKey.data = NULL; } if (inEncrValue->keyAlg) { SECOID_DestroyAlgorithmID(inEncrValue->keyAlg, PR_TRUE); + inEncrValue->keyAlg = NULL; } if (inEncrValue->valueHint.data) { PORT_Free(inEncrValue->valueHint.data); + inEncrValue->valueHint.data = NULL; } if (inEncrValue->encValue.data) { PORT_Free(inEncrValue->encValue.data); + inEncrValue->encValue.data = NULL; } if (freeit) { PORT_Free(inEncrValue); @@ -183,15 +189,24 @@ crmf_copy_encryptedvalue_secalg(PRArenaPool *poolp, SECAlgorithmID **destAlgId) { SECAlgorithmID *newAlgId; + SECStatus rv; - *destAlgId = newAlgId = (poolp != NULL) ? - PORT_ArenaZNew(poolp, SECAlgorithmID) : - PORT_ZNew(SECAlgorithmID); + newAlgId = (poolp != NULL) ? PORT_ArenaZNew(poolp, SECAlgorithmID) : + PORT_ZNew(SECAlgorithmID); if (newAlgId == NULL) { return SECFailure; } - return SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId); + rv = SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId); + if (rv != SECSuccess) { + if (!poolp) { + SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE); + } + return rv; + } + *destAlgId = newAlgId; + + return rv; } SECStatus @@ -252,7 +267,7 @@ crmf_copy_encryptedvalue(PRArenaPool *poolp, return SECSuccess; loser: if (poolp == NULL && destValue != NULL) { - crmf_destroy_encrypted_value(destValue, PR_TRUE); + crmf_destroy_encrypted_value(destValue, PR_FALSE); } return SECFailure; } diff --git a/security/nss/lib/crmf/crmfit.h b/security/nss/lib/crmf/crmfit.h index 1edde840b..2f9be4946 100644 --- a/security/nss/lib/crmf/crmfit.h +++ b/security/nss/lib/crmf/crmfit.h @@ -140,7 +140,7 @@ struct CRMFCertRequestStr { * are not part of the encoding. */ PRArenaPool *poolp; - long requestID; /* This is the value that will be encoded into + PRUint32 requestID; /* This is the value that will be encoded into * the certReqId field. */ }; diff --git a/security/nss/lib/crmf/crmfpop.c b/security/nss/lib/crmf/crmfpop.c index e105a90a8..06d5f467f 100644 --- a/security/nss/lib/crmf/crmfpop.c +++ b/security/nss/lib/crmf/crmfpop.c @@ -94,35 +94,14 @@ CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg) } SECOidTag -crmf_map_keytag_to_signtag(SECOidTag inTag) -{ - switch (inTag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; - case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_DSS: - return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; - default: - /* Put this in here to kill warnings. */ - break; - } - return inTag; -} - -SECOidTag crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey) { - CERTSubjectPublicKeyInfo *spki; - SECOidTag tag; - - spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey); - if (spki == NULL) { - return SEC_OID_UNKNOWN; + /* maintain backward compatibility with older + * implementations */ + if (inPubKey->keyType == rsaKey) { + return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; } - tag = SECOID_GetAlgorithmTag(&spki->algorithm); - SECKEY_DestroySubjectPublicKeyInfo(spki); - return crmf_map_keytag_to_signtag(tag); + return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN); } SECAlgorithmID* @@ -206,8 +185,8 @@ crmf_sign_certreq(PRArenaPool *poolp, SECKEYPrivateKey *inKey, SECAlgorithmID *inAlgId) { - SECItem derCertReq; - SECItem certReqSig; + SECItem derCertReq = { siBuffer, NULL, 0 }; + SECItem certReqSig = { siBuffer, NULL, 0 }; SECStatus rv = SECSuccess; rv = crmf_encode_certreq(certReq, &derCertReq); @@ -282,7 +261,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, { SECAlgorithmID *algID; PRArenaPool *poolp; - SECItem derDest = {siBuffer, NULL, 0}; + SECItem derTemp = {siBuffer, NULL, 0}; void *mark; SECStatus rv; CRMFPOPOSigningKeyInput *signKeyInput = NULL; @@ -325,7 +304,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, pop->popChoice.signature.algorithmIdentifier = algID; inCertReqMsg->pop = pop; - rv = crmf_init_encoder_callback_arg (&encoderArg, &derDest); + rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp); if (rv != SECSuccess) { goto loser; } @@ -335,18 +314,18 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, if (rv != SECSuccess) { goto loser; } - rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derDest); - PORT_Free (derDest.data); + rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp); if (rv != SECSuccess) { goto loser; } + PORT_Free (derTemp.data); PORT_ArenaUnmark(poolp,mark); return SECSuccess; loser: PORT_ArenaRelease(poolp,mark); - if (derDest.data != NULL) { - PORT_Free(derDest.data); + if (derTemp.data != NULL) { + PORT_Free(derTemp.data); } return SECFailure; } @@ -379,13 +358,13 @@ crmf_encode_popoprivkey(PRArenaPool *poolp, const SEC_ASN1Template *privKeyTemplate) { struct crmfEncoderArg encoderArg; - SECItem derDest; + SECItem derTemp; SECStatus rv; void *mark; const SEC_ASN1Template *subDerTemplate; mark = PORT_ArenaMark(poolp); - rv = crmf_init_encoder_callback_arg(&encoderArg, &derDest); + rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp); if (rv != SECSuccess) { goto loser; } @@ -399,32 +378,32 @@ crmf_encode_popoprivkey(PRArenaPool *poolp, if (rv != SECSuccess) { goto loser; } - if (encoderArg.allocatedLen > derDest.len+2) { - void *dummy = PORT_Realloc(derDest.data, derDest.len+2); + if (encoderArg.allocatedLen > derTemp.len+2) { + void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2); if (dummy == NULL) { goto loser; } - derDest.data = dummy; + derTemp.data = dummy; } - PORT_Memmove(&derDest.data[2], &derDest.data[0], derDest.len); + PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len); /* I couldn't figure out how to get the ASN1 encoder to implicitly * tag an implicitly tagged der blob. So I'm putting in the outter- * most tag myself. -javi */ - derDest.data[0] = (unsigned char)privKeyTemplate->kind; - derDest.data[1] = (unsigned char)derDest.len; - derDest.len += 2; - rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derDest); + derTemp.data[0] = (unsigned char)privKeyTemplate->kind; + derTemp.data[1] = (unsigned char)derTemp.len; + derTemp.len += 2; + rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp); if (rv != SECSuccess) { goto loser; } - PORT_Free(derDest.data); + PORT_Free(derTemp.data); PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); - if (derDest.data) { - PORT_Free(derDest.data); + if (derTemp.data) { + PORT_Free(derTemp.data); } return SECFailure; } @@ -491,6 +470,47 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, } static SECStatus +crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, + CRMFPOPChoice inChoice) +{ + PRArenaPool *poolp; + void *mark; + CRMFPOPOPrivKey *popoPrivKey; + CRMFProofOfPossession *pop; + SECStatus rv; + + PORT_Assert(inCertReqMsg != NULL && dhmac != NULL); + poolp = inCertReqMsg->poolp; + mark = PORT_ArenaMark(poolp); + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); + if (pop == NULL) { + goto loser; + } + pop->popUsed = inChoice; + popoPrivKey = &pop->popChoice.keyAgreement; + + rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC), + dhmac); + if (rv != SECSuccess) { + goto loser; + } + popoPrivKey->message.dhMAC.len <<= 3; + popoPrivKey->messageChoice = crmfDHMAC; + inCertReqMsg->pop = pop; + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, + crmf_get_template_for_privkey(inChoice)); + if (rv != SECSuccess) { + goto loser; + } + PORT_ArenaUnmark(poolp, mark); + return SECSuccess; + + loser: + PORT_ArenaRelease(poolp, mark); + return SECFailure; +} + +static SECStatus crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg, CRMFSubseqMessOptions subsequentMessage, CRMFPOPChoice inChoice) @@ -599,7 +619,11 @@ CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, crmfKeyAgreement); break; case crmfDHMAC: - /* This case should be added in the future. */ + /* In this case encPrivKey should be the calculated dhMac + * as specified in RFC 2511 */ + rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey, + crmfKeyAgreement); + break; default: rv = SECFailure; } diff --git a/security/nss/lib/crmf/crmfreq.c b/security/nss/lib/crmf/crmfreq.c index b4e06bc32..73a0548b9 100644 --- a/security/nss/lib/crmf/crmfreq.c +++ b/security/nss/lib/crmf/crmfreq.c @@ -63,6 +63,20 @@ crmf_encode_integer(PRArenaPool *poolp, SECItem *dest, long value) return SECSuccess; } +SECStatus +crmf_encode_unsigned_integer(PRArenaPool *poolp, SECItem *dest, + unsigned long value) +{ + SECItem *dummy; + + dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value); + PORT_Assert (dummy == dest); + if (dummy != dest) { + return SECFailure; + } + return SECSuccess; +} + static SECStatus crmf_copy_secitem (PRArenaPool *poolp, SECItem *dest, SECItem *src) { @@ -104,7 +118,8 @@ CRMF_DoesRequestHaveField (CRMFCertRequest *inCertReq, } CRMFCertRequest * -CRMF_CreateCertRequest (long inRequestID) { +CRMF_CreateCertRequest (PRUint32 inRequestID) +{ PRArenaPool *poolp; CRMFCertRequest *certReq; SECStatus rv; @@ -122,7 +137,8 @@ CRMF_CreateCertRequest (long inRequestID) { certReq->poolp = poolp; certReq->requestID = inRequestID; - rv = crmf_encode_integer(poolp, &(certReq->certReqId), inRequestID); + rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId), + inRequestID); if (rv != SECSuccess) { goto loser; } @@ -177,9 +193,12 @@ crmf_template_copy_secalg (PRArenaPool *poolp, SECAlgorithmID **dest, void *mark = NULL; SECAlgorithmID *mySecAlg; - if (poolp != NULL) { - mark = PORT_ArenaMark(poolp); + if (!poolp) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } + + mark = PORT_ArenaMark(poolp); *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID); if (mySecAlg == NULL) { goto loser; diff --git a/security/nss/lib/crmf/crmftmpl.c b/security/nss/lib/crmf/crmftmpl.c index 594feea3e..296975c96 100644 --- a/security/nss/lib/crmf/crmftmpl.c +++ b/security/nss/lib/crmf/crmftmpl.c @@ -229,7 +229,7 @@ const SEC_ASN1Template CRMFSubsequentMessageTemplate[] = { }; const SEC_ASN1Template CRMFDHMACTemplate[] = { - { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, 0, SEC_ASN1_SUB(SEC_BitStringTemplate) }, { 0 } diff --git a/security/nss/lib/crmf/respcmn.c b/security/nss/lib/crmf/respcmn.c index 153ecee51..14de15db8 100644 --- a/security/nss/lib/crmf/respcmn.c +++ b/security/nss/lib/crmf/respcmn.c @@ -46,12 +46,15 @@ cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit) { if (info->status.data != NULL) { PORT_Free(info->status.data); + info->status.data = NULL; } if (info->statusString.data != NULL) { PORT_Free(info->statusString.data); + info->statusString.data = NULL; } if (info->failInfo.data != NULL) { PORT_Free(info->failInfo.data); + info->failInfo.data = NULL; } if (freeit) { PORT_Free(info); @@ -232,6 +235,7 @@ cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit) case cmmfEncryptedCert: crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert, PR_TRUE); + certOrEncCert->cert.encryptedCert = NULL; break; default: break; @@ -263,14 +267,14 @@ CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) PORT_Assert(inCertKeyPair != NULL); if (inCertKeyPair != NULL) { cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); + if (inCertKeyPair->privateKey) { + crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); + } + if (inCertKeyPair->derPublicationInfo.data) { + PORT_Free(inCertKeyPair->derPublicationInfo.data); + } + PORT_Free(inCertKeyPair); } - if (inCertKeyPair->privateKey) { - crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); - } - if (inCertKeyPair->derPublicationInfo.data) { - PORT_Free(inCertKeyPair->derPublicationInfo.data); - } - PORT_Free(inCertKeyPair); return SECSuccess; } @@ -292,17 +296,22 @@ cmmf_CopyCertResponse(PRArenaPool *poolp, return rv; } if (src->certifiedKeyPair != NULL) { - dest->certifiedKeyPair = (poolp == NULL) ? - PORT_ZNew(CMMFCertifiedKeyPair) : - PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); - if (dest->certifiedKeyPair == NULL) { + CMMFCertifiedKeyPair *destKeyPair; + + destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : + PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); + if (!destKeyPair) { return SECFailure; } - rv = cmmf_CopyCertifiedKeyPair(poolp, dest->certifiedKeyPair, + rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair, src->certifiedKeyPair); if (rv != SECSuccess) { + if (!poolp) { + CMMF_DestroyCertifiedKeyPair(destKeyPair); + } return rv; } + dest->certifiedKeyPair = destKeyPair; } return SECSuccess; } @@ -321,16 +330,19 @@ cmmf_CopyCertOrEncCert(PRArenaPool *poolp, CMMFCertOrEncCert *dest, dest->cert.certificate = CERT_DupCertificate(src->cert.certificate); break; case cmmfEncryptedCert: - dest->cert.encryptedCert = encVal = (poolp == NULL) ? - PORT_ZNew(CRMFEncryptedValue) : - PORT_ArenaZNew(poolp, CRMFEncryptedValue); + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : + PORT_ArenaZNew(poolp, CRMFEncryptedValue); if (encVal == NULL) { return SECFailure; } rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal); if (rv != SECSuccess) { + if (!poolp) { + crmf_destroy_encrypted_value(encVal, PR_TRUE); + } return rv; } + dest->cert.encryptedCert = encVal; break; default: rv = SECFailure; @@ -351,19 +363,22 @@ cmmf_CopyCertifiedKeyPair(PRArenaPool *poolp, CMMFCertifiedKeyPair *dest, } if (src->privateKey != NULL) { - CRMFEncryptedValue *encVal; + CRMFEncryptedValue *encVal; - encVal = dest->privateKey = (poolp == NULL) ? - PORT_ZNew(CRMFEncryptedValue) : - PORT_ArenaZNew(poolp, CRMFEncryptedValue); + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : + PORT_ArenaZNew(poolp, CRMFEncryptedValue); if (encVal == NULL) { return SECFailure; } - rv = crmf_copy_encryptedvalue(poolp, src->privateKey, - dest->privateKey); + rv = crmf_copy_encryptedvalue(poolp, src->privateKey, + encVal); if (rv != SECSuccess) { + if (!poolp) { + crmf_destroy_encrypted_value(encVal, PR_TRUE); + } return rv; } + dest->privateKey = encVal; } rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, &src->derPublicationInfo); diff --git a/security/nss/lib/crmf/servget.c b/security/nss/lib/crmf/servget.c index 165ce5924..85be9e556 100644 --- a/security/nss/lib/crmf/servget.c +++ b/security/nss/lib/crmf/servget.c @@ -409,7 +409,7 @@ crmf_copy_poposigningkey(PRArenaPool *poolp, } return SECSuccess; loser: - if (destPopoSignKey && poolp == NULL) { + if (poolp == NULL) { CRMF_DestroyPOPOSigningKey(destPopoSignKey); } return SECFailure; @@ -440,13 +440,10 @@ crmf_copy_popoprivkey(PRArenaPool *poolp, rv = SECFailure; } - if (rv != SECSuccess) { - if (destPrivKey && poolp == NULL) { - CRMF_DestroyPOPOPrivKey(destPrivKey); - } - return SECFailure; + if (rv != SECSuccess && poolp == NULL) { + CRMF_DestroyPOPOPrivKey(destPrivKey); } - return SECSuccess; + return rv; } static CRMFProofOfPossession* @@ -510,10 +507,11 @@ crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg) return NULL; } newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); - newReqMsg->poolp = poolp; if (newReqMsg == NULL) { goto loser; } + + newReqMsg->poolp = poolp; newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq); if (newReqMsg->certReq == NULL) { goto loser; diff --git a/security/nss/lib/cryptohi/cryptohi.h b/security/nss/lib/cryptohi/cryptohi.h index 0cc700703..5897a3a6b 100644 --- a/security/nss/lib/cryptohi/cryptohi.h +++ b/security/nss/lib/cryptohi/cryptohi.h @@ -269,6 +269,25 @@ extern SECStatus VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, void *wincx); +/* + * NOTE: This function is private in NSS 3.11.x +** Verify the signature on a block of data. +** "buf" the input data +** "len" the length of the input data +** "key" the public key to check the signature with +** "sig" the encrypted signature data +** "algid" specifies the signing algorithm and parameters to use. +** This must match the key type. +** "reserved" must be NULL in this version. +** "wincx" void pointer to the window context +*/ +extern SECStatus VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, + int len, const SECKEYPublicKey *key, + const SECItem *sig, + const SECAlgorithmID *algid, + SECOidTag *reserved, + void *wincx); + SEC_END_PROTOS diff --git a/security/nss/lib/cryptohi/keyhi.h b/security/nss/lib/cryptohi/keyhi.h index 8707c3d1d..350b88d0f 100644 --- a/security/nss/lib/cryptohi/keyhi.h +++ b/security/nss/lib/cryptohi/keyhi.h @@ -90,6 +90,11 @@ extern unsigned SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk); extern unsigned SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk); /* +** Return the length of the signature in bytes +*/ +extern unsigned SECKEY_SignatureLen(const SECKEYPublicKey *pubk); + +/* ** Make a copy of the private key "privKey" */ extern SECKEYPrivateKey *SECKEY_CopyPrivateKey(SECKEYPrivateKey *privKey); @@ -283,8 +288,24 @@ SECKEY_AddPublicKeyToListTail( SECKEYPublicKeyList *list, #define PUBKEY_LIST_NEXT(n) ((SECKEYPublicKeyListNode *)n->links.next) #define PUBKEY_LIST_END(n,l) (((void *)n) == ((void *)&l->list)) +/* + * Length in bits of the EC's field size. This is also the length of + * the x and y coordinates of EC points, such as EC public keys and + * base points. + * + * Return 0 on failure (unknown EC domain parameters). + */ extern int SECKEY_ECParamsToKeySize(const SECItem *params); +/* + * Length in bits of the EC base point order, usually denoted n. This + * is also the length of EC private keys and ECDSA signature components + * r and s. + * + * Return 0 on failure (unknown EC domain parameters). + */ +extern int SECKEY_ECParamsToBasePointOrderLen(const SECItem *params); + SEC_END_PROTOS #endif /* _KEYHI_H_ */ diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c index 97f79d99e..8a128af5f 100644 --- a/security/nss/lib/cryptohi/seckey.c +++ b/security/nss/lib/cryptohi/seckey.c @@ -198,8 +198,11 @@ SECKEYPrivateKey * SECKEY_CreateRSAPrivateKey(int keySizeInBits,SECKEYPublicKey **pubk, void *cx) { SECKEYPrivateKey *privk; - PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx); PK11RSAGenParams param; + PK11SlotInfo *slot = PK11_GetBestSlot(CKM_RSA_PKCS_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } param.keySizeInBits = keySizeInBits; param.pe = 65537L; @@ -222,6 +225,9 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c { SECKEYPrivateKey *privk; PK11SlotInfo *slot = PK11_GetBestSlot(CKM_DH_PKCS_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } privk = PK11_GenerateKeyPair(slot, CKM_DH_PKCS_KEY_PAIR_GEN, param, pubk, PR_FALSE, PR_FALSE, cx); @@ -245,6 +251,9 @@ SECKEY_CreateECPrivateKey(SECKEYECParams *param, SECKEYPublicKey **pubk, void *c { SECKEYPrivateKey *privk; PK11SlotInfo *slot = PK11_GetBestSlot(CKM_EC_KEY_PAIR_GEN,cx); + if (!slot) { + return NULL; + } privk = PK11_GenerateKeyPair(slot, CKM_EC_KEY_PAIR_GEN, param, pubk, PR_FALSE, PR_FALSE, cx); @@ -1284,7 +1293,155 @@ SECKEY_ECParamsToKeySize(const SECItem *encodedParams) return 571; default: - return 0; + PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); + return 0; + } +} + +int +SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams) +{ + SECOidTag tag; + SECItem oid = { siBuffer, NULL, 0}; + + /* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID), + * followed by the length of the curve oid and the curve oid. + */ + oid.len = encodedParams->data[1]; + oid.data = encodedParams->data + 2; + if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN) + return 0; + + switch (tag) { + case SEC_OID_SECG_EC_SECP112R1: + return 112; + case SEC_OID_SECG_EC_SECP112R2: + return 110; + + case SEC_OID_SECG_EC_SECT113R1: + case SEC_OID_SECG_EC_SECT113R2: + return 113; + + case SEC_OID_SECG_EC_SECP128R1: + return 128; + case SEC_OID_SECG_EC_SECP128R2: + return 126; + + case SEC_OID_SECG_EC_SECT131R1: + case SEC_OID_SECG_EC_SECT131R2: + return 131; + + case SEC_OID_SECG_EC_SECP160K1: + case SEC_OID_SECG_EC_SECP160R1: + case SEC_OID_SECG_EC_SECP160R2: + return 161; + + case SEC_OID_SECG_EC_SECT163K1: + return 163; + case SEC_OID_SECG_EC_SECT163R1: + return 162; + case SEC_OID_SECG_EC_SECT163R2: + case SEC_OID_ANSIX962_EC_C2PNB163V1: + return 163; + case SEC_OID_ANSIX962_EC_C2PNB163V2: + case SEC_OID_ANSIX962_EC_C2PNB163V3: + return 162; + + case SEC_OID_ANSIX962_EC_C2PNB176V1: + return 161; + + case SEC_OID_ANSIX962_EC_C2TNB191V1: + return 191; + case SEC_OID_ANSIX962_EC_C2TNB191V2: + return 190; + case SEC_OID_ANSIX962_EC_C2TNB191V3: + return 189; + case SEC_OID_ANSIX962_EC_C2ONB191V4: + return 191; + case SEC_OID_ANSIX962_EC_C2ONB191V5: + return 188; + + case SEC_OID_SECG_EC_SECP192K1: + case SEC_OID_ANSIX962_EC_PRIME192V1: + case SEC_OID_ANSIX962_EC_PRIME192V2: + case SEC_OID_ANSIX962_EC_PRIME192V3: + return 192; + + case SEC_OID_SECG_EC_SECT193R1: + case SEC_OID_SECG_EC_SECT193R2: + return 193; + + case SEC_OID_ANSIX962_EC_C2PNB208W1: + return 193; + + case SEC_OID_SECG_EC_SECP224K1: + return 225; + case SEC_OID_SECG_EC_SECP224R1: + return 224; + + case SEC_OID_SECG_EC_SECT233K1: + return 232; + case SEC_OID_SECG_EC_SECT233R1: + return 233; + + case SEC_OID_SECG_EC_SECT239K1: + case SEC_OID_ANSIX962_EC_C2TNB239V1: + return 238; + case SEC_OID_ANSIX962_EC_C2TNB239V2: + return 237; + case SEC_OID_ANSIX962_EC_C2TNB239V3: + return 236; + case SEC_OID_ANSIX962_EC_C2ONB239V4: + return 238; + case SEC_OID_ANSIX962_EC_C2ONB239V5: + return 237; + case SEC_OID_ANSIX962_EC_PRIME239V1: + case SEC_OID_ANSIX962_EC_PRIME239V2: + case SEC_OID_ANSIX962_EC_PRIME239V3: + return 239; + + case SEC_OID_SECG_EC_SECP256K1: + case SEC_OID_ANSIX962_EC_PRIME256V1: + return 256; + + case SEC_OID_ANSIX962_EC_C2PNB272W1: + return 257; + + case SEC_OID_SECG_EC_SECT283K1: + return 281; + case SEC_OID_SECG_EC_SECT283R1: + return 282; + + case SEC_OID_ANSIX962_EC_C2PNB304W1: + return 289; + + case SEC_OID_ANSIX962_EC_C2TNB359V1: + return 353; + + case SEC_OID_ANSIX962_EC_C2PNB368W1: + return 353; + + case SEC_OID_SECG_EC_SECP384R1: + return 384; + + case SEC_OID_SECG_EC_SECT409K1: + return 407; + case SEC_OID_SECG_EC_SECT409R1: + return 409; + + case SEC_OID_ANSIX962_EC_C2TNB431R1: + return 418; + + case SEC_OID_SECG_EC_SECP521R1: + return 521; + + case SEC_OID_SECG_EC_SECT571K1: + case SEC_OID_SECG_EC_SECT571R1: + return 570; + + default: + PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); + return 0; } } @@ -1321,6 +1478,7 @@ SECKEY_PublicKeyStrength(SECKEYPublicKey *pubk) default: break; } + PORT_SetError(SEC_ERROR_INVALID_KEY); return 0; } @@ -1343,6 +1501,33 @@ SECKEY_PublicKeyStrengthInBits(SECKEYPublicKey *pubk) default: break; } + PORT_SetError(SEC_ERROR_INVALID_KEY); + return 0; +} + +/* returns signature length in bytes (not bits) */ +unsigned +SECKEY_SignatureLen(const SECKEYPublicKey *pubk) +{ + unsigned char b0; + unsigned size; + + switch (pubk->keyType) { + case rsaKey: + b0 = pubk->u.rsa.modulus.data[0]; + return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1; + case fortezzaKey: + case dsaKey: + return DSA_SIGNATURE_LEN; + case ecKey: + /* Get the base point order length in bits and adjust */ + size = SECKEY_ECParamsToBasePointOrderLen( + &pubk->u.ec.DEREncodedParams); + return ((size + 7)/8) * 2; + default: + break; + } + PORT_SetError(SEC_ERROR_INVALID_KEY); return 0; } @@ -1352,13 +1537,13 @@ SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk) SECKEYPrivateKey *copyk; PRArenaPool *arena; - if (privk == NULL) { + if (!privk || !privk->pkcs11Slot) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { - PORT_SetError (SEC_ERROR_NO_MEMORY); return NULL; } @@ -1397,7 +1582,8 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) { SECKEYPublicKey *copyk; PRArenaPool *arena; - + SECStatus rv = SECSuccess; + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == NULL) { PORT_SetError (SEC_ERROR_NO_MEMORY); @@ -1405,119 +1591,117 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk) } copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey)); - if (copyk != NULL) { - SECStatus rv = SECSuccess; - - copyk->arena = arena; - copyk->keyType = pubk->keyType; - if (pubk->pkcs11Slot && - PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { - copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); - copyk->pkcs11ID = pubk->pkcs11ID; - } else { - copyk->pkcs11Slot = NULL; /* go get own reference */ - copyk->pkcs11ID = CK_INVALID_HANDLE; - } - switch (pubk->keyType) { - case rsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, - &pubk->u.rsa.modulus); - if (rv == SECSuccess) { - rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, - &pubk->u.rsa.publicExponent); - if (rv == SECSuccess) - return copyk; - } - break; - case dsaKey: - rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, - &pubk->u.dsa.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, - &pubk->u.dsa.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, - &pubk->u.dsa.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, - &pubk->u.dsa.params.base); - break; - case keaKey: - rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, - &pubk->u.kea.publicValue); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.kea.params.hash, - &pubk->u.kea.params.hash); - break; - case fortezzaKey: - copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion; - copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion; - PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID, - sizeof(pubk->u.fortezza.KMID)); - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.clearance, - &pubk->u.fortezza.clearance); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, - &pubk->u.fortezza.KEApriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, - &pubk->u.fortezza.DSSpriviledge); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, - &pubk->u.fortezza.KEAKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, - &pubk->u.fortezza.DSSKey); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, - &pubk->u.fortezza.params.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, - &pubk->u.fortezza.params.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, - &pubk->u.fortezza.params.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, - &pubk->u.fortezza.keaParams.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, - &pubk->u.fortezza.keaParams.subPrime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, - &pubk->u.fortezza.keaParams.base); - break; - case dhKey: - rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, - &pubk->u.dh.publicValue); - break; - case ecKey: - copyk->u.ec.size = pubk->u.ec.size; - rv = SECITEM_CopyItem(arena,©k->u.ec.DEREncodedParams, - &pubk->u.ec.DEREncodedParams); - if (rv != SECSuccess) break; - rv = SECITEM_CopyItem(arena,©k->u.ec.publicValue, - &pubk->u.ec.publicValue); - break; - case nullKey: - return copyk; - default: - rv = SECFailure; - break; - } - if (rv == SECSuccess) - return copyk; + if (!copyk) { + PORT_SetError (SEC_ERROR_NO_MEMORY); + PORT_FreeArena (arena, PR_FALSE); + return NULL; + } - SECKEY_DestroyPublicKey (copyk); + copyk->arena = arena; + copyk->keyType = pubk->keyType; + if (pubk->pkcs11Slot && + PK11_IsPermObject(pubk->pkcs11Slot,pubk->pkcs11ID)) { + copyk->pkcs11Slot = PK11_ReferenceSlot(pubk->pkcs11Slot); + copyk->pkcs11ID = pubk->pkcs11ID; } else { - PORT_SetError (SEC_ERROR_NO_MEMORY); + copyk->pkcs11Slot = NULL; /* go get own reference */ + copyk->pkcs11ID = CK_INVALID_HANDLE; + } + switch (pubk->keyType) { + case rsaKey: + rv = SECITEM_CopyItem(arena, ©k->u.rsa.modulus, + &pubk->u.rsa.modulus); + if (rv == SECSuccess) { + rv = SECITEM_CopyItem (arena, ©k->u.rsa.publicExponent, + &pubk->u.rsa.publicExponent); + if (rv == SECSuccess) + return copyk; + } + break; + case dsaKey: + rv = SECITEM_CopyItem(arena, ©k->u.dsa.publicValue, + &pubk->u.dsa.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.prime, + &pubk->u.dsa.params.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.subPrime, + &pubk->u.dsa.params.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dsa.params.base, + &pubk->u.dsa.params.base); + break; + case keaKey: + rv = SECITEM_CopyItem(arena, ©k->u.kea.publicValue, + &pubk->u.kea.publicValue); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.kea.params.hash, + &pubk->u.kea.params.hash); + break; + case fortezzaKey: + copyk->u.fortezza.KEAversion = pubk->u.fortezza.KEAversion; + copyk->u.fortezza.DSSversion = pubk->u.fortezza.DSSversion; + PORT_Memcpy(copyk->u.fortezza.KMID, pubk->u.fortezza.KMID, + sizeof(pubk->u.fortezza.KMID)); + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.clearance, + &pubk->u.fortezza.clearance); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEApriviledge, + &pubk->u.fortezza.KEApriviledge); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSpriviledge, + &pubk->u.fortezza.DSSpriviledge); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.KEAKey, + &pubk->u.fortezza.KEAKey); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.DSSKey, + &pubk->u.fortezza.DSSKey); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.prime, + &pubk->u.fortezza.params.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.subPrime, + &pubk->u.fortezza.params.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.params.base, + &pubk->u.fortezza.params.base); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.prime, + &pubk->u.fortezza.keaParams.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.subPrime, + &pubk->u.fortezza.keaParams.subPrime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.fortezza.keaParams.base, + &pubk->u.fortezza.keaParams.base); + break; + case dhKey: + rv = SECITEM_CopyItem(arena,©k->u.dh.prime,&pubk->u.dh.prime); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena,©k->u.dh.base,&pubk->u.dh.base); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena, ©k->u.dh.publicValue, + &pubk->u.dh.publicValue); + break; + case ecKey: + copyk->u.ec.size = pubk->u.ec.size; + rv = SECITEM_CopyItem(arena,©k->u.ec.DEREncodedParams, + &pubk->u.ec.DEREncodedParams); + if (rv != SECSuccess) break; + rv = SECITEM_CopyItem(arena,©k->u.ec.publicValue, + &pubk->u.ec.publicValue); + break; + case nullKey: + return copyk; + default: + rv = SECFailure; + break; } + if (rv == SECSuccess) + return copyk; - PORT_FreeArena (arena, PR_FALSE); + SECKEY_DestroyPublicKey (copyk); return NULL; } @@ -1853,7 +2037,6 @@ SECKEY_DecodeDERSubjectPublicKeyInfo(SECItem *spkider) } if (rv == SECSuccess) return spki; - SECKEY_DestroySubjectPublicKeyInfo(spki); } else { PORT_SetError(SEC_ERROR_NO_MEMORY); } @@ -1944,8 +2127,8 @@ SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge, /* check the signature */ sig = sd.signature; DER_ConvertBitString(&sig); - rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig, - SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx); + rv = VFY_VerifyDataWithAlgorithmID(sd.data.data, sd.data.len, pubKey, &sig, + &sd.signatureAlgorithm, NULL, wincx); if ( rv != SECSuccess ) { goto loser; } diff --git a/security/nss/lib/cryptohi/secsign.c b/security/nss/lib/cryptohi/secsign.c index 12e6ed3ad..270889e6c 100644 --- a/security/nss/lib/cryptohi/secsign.c +++ b/security/nss/lib/cryptohi/secsign.c @@ -121,11 +121,26 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) signalg = SEC_OID_MISSI_DSS; /* XXX Is there a better algid? */ keyType = fortezzaKey; break; - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: hashalg = SEC_OID_SHA1; signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; keyType = ecKey; break; + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + hashalg = SEC_OID_SHA256; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + hashalg = SEC_OID_SHA384; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + hashalg = SEC_OID_SHA512; + signalg = SEC_OID_ANSIX962_EC_PUBLIC_KEY; + keyType = ecKey; + break; /* we don't implement MD4 hashes. * we *CERTAINLY* don't want to sign one! */ case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: @@ -142,6 +157,13 @@ SGN_NewContext(SECOidTag alg, SECKEYPrivateKey *key) return 0; } +#ifndef NSS_ECC_MORE_THAN_SUITE_B + if (key->keyType == ecKey) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return 0; + } +#endif + cx = (SGNContext*) PORT_ZAlloc(sizeof(SGNContext)); if (cx) { cx->hashalg = hashalg; @@ -200,7 +222,8 @@ SECStatus SGN_End(SGNContext *cx, SECItem *result) { unsigned char digest[HASH_LENGTH_MAX]; - unsigned part1, signatureLen; + unsigned part1; + int signatureLen; SECStatus rv; SECItem digder, sigitem; PRArenaPool *arena = 0; @@ -248,6 +271,11 @@ SGN_End(SGNContext *cx, SECItem *result) ** block */ signatureLen = PK11_SignatureLen(privKey); + if (signatureLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto loser; + } sigitem.len = signatureLen; sigitem.data = (unsigned char*) PORT_Alloc(signatureLen); @@ -266,7 +294,7 @@ SGN_End(SGNContext *cx, SECItem *result) if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ - rv = DSAU_EncodeDerSigWithLen(result, &sigitem, signatureLen); + rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); PORT_Free(sigitem.data); if (rv != SECSuccess) goto loser; @@ -373,7 +401,7 @@ SEC_DerSignData(PRArenaPool *arena, SECItem *result, algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; case ecKey: - algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + algID = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; default: PORT_SetError(SEC_ERROR_INVALID_KEY); @@ -407,7 +435,7 @@ SECStatus SGN_Digest(SECKEYPrivateKey *privKey, SECOidTag algtag, SECItem *result, SECItem *digest) { - unsigned modulusLen; + int modulusLen; SECStatus rv; SECItem digder; PRArenaPool *arena = 0; @@ -446,6 +474,11 @@ SGN_Digest(SECKEYPrivateKey *privKey, ** block */ modulusLen = PK11_SignatureLen(privKey); + if (modulusLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto loser; + } result->len = modulusLen; result->data = (unsigned char*) PORT_Alloc(modulusLen); @@ -503,8 +536,19 @@ SEC_GetSignatureAlgorithmOidTag(KeyType keyType, SECOidTag hashAlgTag) } break; case ecKey: - /* XXX For now only ECDSA with SHA1 is supported */ - sigTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + switch (hashAlgTag) { + case SEC_OID_UNKNOWN: /* default for ECDSA if hash not specified */ + case SEC_OID_SHA1: /* is ECDSA_SHA1_SIGNTARURE */ + sigTag = SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; break; + case SEC_OID_SHA256: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; break; + case SEC_OID_SHA384: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; break; + case SEC_OID_SHA512: + sigTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; break; + default: + break; + } break; default: break; diff --git a/security/nss/lib/cryptohi/secvfy.c b/security/nss/lib/cryptohi/secvfy.c index 311bec35e..94a0b3563 100644 --- a/security/nss/lib/cryptohi/secvfy.c +++ b/security/nss/lib/cryptohi/secvfy.c @@ -48,16 +48,19 @@ #include "pk11func.h" #include "secdig.h" #include "secerr.h" +#include "secport.h" /* ** Decrypt signature block using public key ** Store the hash algorithm oid tag in *tagp ** Store the digest in the digest buffer +** Store the digest length in *digestlen ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION */ static SECStatus -DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, - SECKEYPublicKey *key, SECItem *sig, char *wincx) +DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, + unsigned int *digestlen, unsigned int maxdigestlen, + SECKEYPublicKey *key, const SECItem *sig, char *wincx) { SGNDigestInfo *di = NULL; unsigned char *buf = NULL; @@ -73,7 +76,7 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, if (!buf) goto loser; /* decrypt the block */ - rv = PK11_VerifyRecover(key, sig, &it, wincx); + rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx); if (rv != SECSuccess) goto loser; di = SGN_DecodeDigestInfo(&it); @@ -84,13 +87,21 @@ DecryptSigBlock(SECOidTag *tagp, unsigned char *digest, unsigned int len, ** ID and the signature block */ tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm); - /* XXX Check that tag is an appropriate algorithm? */ - if (di->digest.len > len) { + /* Check that tag is an appropriate algorithm */ + if (tag == SEC_OID_UNKNOWN) { + goto sigloser; + } + /* make sure the "parameters" are not too bogus. */ + if (di->digestAlgorithm.parameters.len > 2) { + goto sigloser; + } + if (di->digest.len > maxdigestlen) { PORT_SetError(SEC_ERROR_OUTPUT_LEN); goto loser; } PORT_Memcpy(digest, di->digest.data, di->digest.len); *tagp = tag; + *digestlen = di->digest.len; goto done; sigloser: @@ -131,6 +142,7 @@ struct VFYContextStr { /* the full ECDSA signature */ unsigned char ecdsasig[2 * MAX_ECKEY_LEN]; } u; + unsigned int rsadigestlen; void * wincx; void *hashcx; const SECHashObject *hashobj; @@ -153,19 +165,21 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig, SECStatus rv=SECSuccess; switch (algid) { + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + if (len > MAX_ECKEY_LEN * 2) { + PORT_SetError(SEC_ERROR_BAD_DER); + return SECFailure; + } + /* fall through */ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_ANSIX9_DSA_SIGNATURE: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: - if (algid == SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST) { - if (len > MAX_ECKEY_LEN * 2) { - PORT_SetError(SEC_ERROR_BAD_DER); - return SECFailure; - } - dsasig = DSAU_DecodeDerSigToLen(sig, len); - } else { - dsasig = DSAU_DecodeDerSig(sig); - } + dsasig = DSAU_DecodeDerSigToLen(sig, len); if ((dsasig == NULL) || (dsasig->len != len)) { rv = SECFailure; @@ -187,22 +201,32 @@ decodeECorDSASignature(SECOidTag algid, SECItem *sig, unsigned char *dsig, return rv; } +const static SEC_ASN1Template hashParameterTemplate[] = +{ + { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECItem) }, + { SEC_ASN1_OBJECT_ID, 0 }, + { SEC_ASN1_SKIP_REST }, + { 0, } +}; /* * Pulls the hash algorithm, signing algorithm, and key type out of a * composite algorithm. * * alg: the composite algorithm to dissect. * hashalg: address of a SECOidTag which will be set with the hash algorithm. - * signalg: address of a SECOidTag which will be set with the signing alg. - * (not implemented) - * keyType: address of a KeyType which will be set with the key type. - * (not implemented) - * Returns: SECSuccess if the algorithm was acceptable, SECFailure if the + * params: specific signature parameter (from the signature AlgorithmID). + * key: public key to verify against. + * Returns: SECSuccess if the alg algorithm was acceptable, SECFailure if the * algorithm was not found or was not a signing algorithm. */ static SECStatus -decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) +decodeSigAlg(SECOidTag alg, const SECItem *params, const SECKEYPublicKey *key, + SECOidTag *hashalg) { + PRArenaPool *arena; + SECStatus rv; + SECItem oid; + unsigned int len; PR_ASSERT(hashalg!=NULL); switch (alg) { @@ -218,20 +242,67 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) *hashalg = SEC_OID_SHA1; break; + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA256; break; + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA384; break; + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: *hashalg = SEC_OID_SHA512; break; + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + /* This is an EC algorithm. Recommended means the largest + * hash algorithm that is not truncated by the keysize of + * the EC algorithm. Note that key strength is in bytes and + * algorithms are specified in bits. Never use an algorithm + * weaker than sha1. */ + len = SECKEY_PublicKeyStrength((SECKEYPublicKey *)key); + if (len < 28) { /* 28 bytes == 244 bits */ + *hashalg = SEC_OID_SHA1; + } else if (len < 32) { /* 32 bytes == 256 bits */ + /* we don't support 244 bit hash algorithms */ + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } else if (len < 48) { /* 48 bytes == 384 bits */ + *hashalg = SEC_OID_SHA256; + } else if (len < 64) { /* 48 bytes == 512 bits */ + *hashalg = SEC_OID_SHA384; + } else { + /* use the largest in this case */ + *hashalg = SEC_OID_SHA512; + } + break; + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + if (params == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + return SECFailure; + } + rv = SEC_QuickDERDecodeItem(arena, &oid, hashParameterTemplate, params); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return rv; + } + + *hashalg = SECOID_FindOIDTag(&oid); + PORT_FreeArena(arena, PR_FALSE); + if (*hashalg == SEC_OID_UNKNOWN) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return SECFailure; + } + break; /* what about normal DSA? */ case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST: - case SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: *hashalg = SEC_OID_SHA1; break; case SEC_OID_MISSI_DSS: @@ -248,9 +319,9 @@ decodeSigAlg(SECOidTag alg, SECOidTag *hashalg) return SECSuccess; } -VFYContext * -VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, - void *wincx) +static VFYContext * +vfy_CreateContextPrivate(const SECKEYPublicKey *key, const SECItem *sig, + SECOidTag algid, const SECItem *params, void *wincx) { VFYContext *cx; SECStatus rv; @@ -265,14 +336,17 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, switch (key->keyType) { case rsaKey: cx->type = VFY_RSA; - cx->key = SECKEY_CopyPublicKey(key); /* extra safety precautions */ + /* keep our own copy */ + cx->key = SECKEY_CopyPublicKey((SECKEYPublicKey *)key); if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + unsigned int digestlen = 0; + rv = DecryptSigBlock(&hashid, cx->u.buffer, &digestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)wincx); cx->alg = hashid; + cx->rsadigestlen = digestlen; } else { - rv = decodeSigAlg(algid,&cx->alg); + rv = decodeSigAlg(algid, params, key, &cx->alg); } break; case fortezzaKey: @@ -280,16 +354,23 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, case ecKey: if (key->keyType == ecKey) { cx->type = VFY_ECDSA; - /* Unlike DSA, EDSA does not have a fixed signature length + /* Unlike DSA, ECDSA does not have a fixed signature length * (it depends on the key size) */ - sigLen = SECKEY_PublicKeyStrength(key) * 2; + sigLen = SECKEY_SignatureLen(key); } else { cx->type = VFY_DSA; sigLen = DSA_SIGNATURE_LEN; } - cx->alg = SEC_OID_SHA1; - cx->key = SECKEY_CopyPublicKey(key); + if (sigLen == 0) { + rv = SECFailure; + break; + } + rv = decodeSigAlg(algid, params, key, &cx->alg); + if (rv != SECSuccess) { + break; + } + cx->key = SECKEY_CopyPublicKey((SECKEYPublicKey *)key); if (sig) { rv = decodeECorDSASignature(algid,sig,cx->u.buffer,sigLen); } @@ -319,6 +400,13 @@ VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, return 0; } +VFYContext * +VFY_CreateContext(SECKEYPublicKey *key, SECItem *sig, SECOidTag algid, + void *wincx) +{ + return vfy_CreateContextPrivate(key, sig, algid, NULL, wincx); +} + void VFY_DestroyContext(VFYContext *cx, PRBool freeit) { @@ -392,7 +480,10 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) if (cx->type == VFY_DSA) { dsasig.len = DSA_SIGNATURE_LEN; } else { - dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2; + dsasig.len = SECKEY_SignatureLen(cx->key); + } + if (dsasig.len == 0) { + return SECFailure; } if (sig) { rv = decodeECorDSASignature(cx->sigAlg,sig,dsasig.data, @@ -412,14 +503,15 @@ VFY_EndWithSignature(VFYContext *cx, SECItem *sig) case VFY_RSA: if (sig) { SECOidTag hashid = SEC_OID_UNKNOWN; - rv = DecryptSigBlock(&hashid, cx->u.buffer, + rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen, HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx); if ((rv != SECSuccess) || (hashid != cx->alg)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } } - if (PORT_Memcmp(final, cx->u.buffer, part)) { + if ((part != cx->rsadigestlen) || + PORT_Memcmp(final, cx->u.buffer, part)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); return SECFailure; } @@ -458,7 +550,8 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, if (cx != NULL) { switch (key->keyType) { case rsaKey: - if (PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { + if ((digest->len != cx->rsadigestlen) || + PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); } else { rv = SECSuccess; @@ -469,11 +562,14 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, case ecKey: dsasig.data = cx->u.buffer; if (key->keyType == ecKey) { - dsasig.len = SECKEY_PublicKeyStrength(cx->key) * 2; + dsasig.len = SECKEY_SignatureLen(cx->key); } else { /* magic size of dsa signature */ dsasig.len = DSA_SIGNATURE_LEN; } + if (dsasig.len == 0) { + break; + } if (PK11_Verify(cx->key, &dsasig, digest, cx->wincx) != SECSuccess) { PORT_SetError(SEC_ERROR_BAD_SIGNATURE); @@ -489,20 +585,21 @@ VFY_VerifyDigest(SECItem *digest, SECKEYPublicKey *key, SECItem *sig, return rv; } -SECStatus -VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, - SECItem *sig, SECOidTag algid, void *wincx) +static SECStatus +vfy_VerifyDataPrivate(const unsigned char *buf, int len, + const SECKEYPublicKey *key, const SECItem *sig, + SECOidTag algid, const SECItem *params, void *wincx) { SECStatus rv; VFYContext *cx; - cx = VFY_CreateContext(key, sig, algid, wincx); + cx = vfy_CreateContextPrivate(key, sig, algid, params, wincx); if (cx == NULL) return SECFailure; rv = VFY_Begin(cx); if (rv == SECSuccess) { - rv = VFY_Update(cx, buf, len); + rv = VFY_Update(cx, (unsigned char *)buf, len); if (rv == SECSuccess) rv = VFY_End(cx); } @@ -510,3 +607,34 @@ VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, VFY_DestroyContext(cx, PR_TRUE); return rv; } + +SECStatus +VFY_VerifyData(unsigned char *buf, int len, SECKEYPublicKey *key, + SECItem *sig, SECOidTag algid, void *wincx) +{ + return vfy_VerifyDataPrivate(buf, len, key, sig, algid, NULL, wincx); +} + +/* + * this function is private to nss3.dll in NSS 3.11 + */ +SECStatus +VFY_VerifyDataWithAlgorithmID(const unsigned char *buf, int len, + const SECKEYPublicKey *key, + const SECItem *sig, + const SECAlgorithmID *sigAlgorithm, + SECOidTag *reserved, void *wincx) +{ + /* the hash parameter is only provided to match the NSS 3.12 signature */ + PORT_Assert(reserved == NULL); + if (reserved) { + /* shouldn't happen, This function is not exported, and the only + * NSS callers pass 'NULL' */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return vfy_VerifyDataPrivate(buf, len, key, sig, + SECOID_GetAlgorithmTag((SECAlgorithmID *)sigAlgorithm), + &sigAlgorithm->parameters, wincx); +} + diff --git a/security/nss/lib/freebl/GF2m_ecl.c b/security/nss/lib/freebl/GF2m_ecl.c deleted file mode 100644 index 4c0ab88f7..000000000 --- a/security/nss/lib/freebl/GF2m_ecl.c +++ /dev/null @@ -1,540 +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 elliptic curve math library for binary polynomial field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Douglas Stebila <douglas@stebila.ca> - * - * 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 ***** */ - -#ifdef NSS_ENABLE_ECC -/* - * GF2m_ecl.c: Contains an implementation of elliptic curve math library - * for curves over GF2m. - * - * XXX Can be moved to a separate subdirectory later. - * - */ - -#include "GF2m_ecl.h" -#include "mpi/mplogic.h" -#include "mpi/mp_gf2m.h" -#include <stdlib.h> - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err -GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py) -{ - - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) { - return MP_YES; - } else { - return MP_NO; - } - -} - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err -GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py) -{ - mp_zero(px); - mp_zero(py); - return MP_OKAY; -} - -/* Computes R = P + Q based on IEEE P1363 A.10.2. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int lambda, xtemp, ytemp; - unsigned int *p; - int p_size; - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - CHECK_MPI_OK( mp_init(&lambda) ); - CHECK_MPI_OK( mp_init(&xtemp) ); - CHECK_MPI_OK( mp_init(&ytemp) ); - /* if P = inf, then R = Q */ - if (GF2m_ec_pt_is_inf_aff(px, py) == 0) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if Q = inf, then R = P */ - if (GF2m_ec_pt_is_inf_aff(qx, qy) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if px != qx, then lambda = (py+qy) / (px+qx), - * xtemp = a + lambda^2 + lambda + px + qx - */ - if (mp_cmp(px, qx) != 0) { - CHECK_MPI_OK( mp_badd(py, qy, &ytemp) ); - CHECK_MPI_OK( mp_badd(px, qx, &xtemp) ); - CHECK_MPI_OK( mp_bdivmod(&ytemp, &xtemp, pp, p, &lambda) ); - CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, px, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, qx, &xtemp) ); - } else { - /* if py != qy or qx = 0, then R = inf */ - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qx) == 0)) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* lambda = qx + qy / qx */ - CHECK_MPI_OK( mp_bdivmod(qy, qx, pp, p, &lambda) ); - CHECK_MPI_OK( mp_badd(&lambda, qx, &lambda) ); - /* xtemp = a + lambda^2 + lambda */ - CHECK_MPI_OK( mp_bsqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, &lambda, &xtemp) ); - CHECK_MPI_OK( mp_badd(&xtemp, a, &xtemp) ); - } - /* ry = (qx + xtemp) * lambda + xtemp + qy */ - CHECK_MPI_OK( mp_badd(qx, &xtemp, &ytemp) ); - CHECK_MPI_OK( mp_bmulmod(&ytemp, &lambda, p, &ytemp) ); - CHECK_MPI_OK( mp_badd(&ytemp, &xtemp, &ytemp) ); - CHECK_MPI_OK( mp_badd(&ytemp, qy, ry) ); - /* rx = xtemp */ - CHECK_MPI_OK( mp_copy(&xtemp, rx) ); - -cleanup: - mp_clear(&lambda); - mp_clear(&xtemp); - mp_clear(&ytemp); - free(p); - return err; -} - -/* Computes R = P - Q. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int nqy; - MP_DIGITS(&nqy) = 0; - CHECK_MPI_OK( mp_init(&nqy) ); - /* nqy = qx+qy */ - CHECK_MPI_OK( mp_badd(qx, qy, &nqy) ); - err = GF2m_ec_pt_add_aff(pp, a, px, py, qx, &nqy, rx, ry); -cleanup: - mp_clear(&nqy); - return err; -} - -/* Computes R = 2P. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry) -{ - return GF2m_ec_pt_add_aff(pp, a, px, py, px, py, rx, ry); -} - -/* Gets the i'th bit in the binary representation of a. - * If i >= length(a), then return 0. - * (The above behaviour differs from mpl_get_bit, which - * causes an error if i >= length(a).) - */ -#define MP_GET_BIT(a, i) \ - ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) - -/* Computes R = nP based on IEEE P1363 A.10.3. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, k3, qx, qy, sx, sy; - int b1, b3, i, l; - unsigned int *p; - int p_size; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&k3) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&k3) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - /* if n < 0 then Q = -Q, k = -k */ - if (mp_cmp_z(n) < 0) { - CHECK_MPI_OK( mp_badd(&qx, &qy, &qy) ); - CHECK_MPI_OK( mp_neg(&k, &k) ); - } -#ifdef EC_DEBUG /* basic double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (mpl_get_bit(&k, i) != 0) { - CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) ); - } - } -#else /* double and add/subtract method from standard */ - /* k3 = 3 * k */ - mp_set(&k3, 0x3); - CHECK_MPI_OK( mp_mul(&k, &k3, &k3) ); - /* S = Q */ - CHECK_MPI_OK( mp_copy(&qx, &sx) ); - CHECK_MPI_OK( mp_copy(&qy, &sy) ); - /* l = index of high order bit in binary representation of 3*k */ - l = mpl_significant_bits(&k3) - 1; - /* for i = l-1 downto 1 */ - for (i = l - 1; i >= 1; i--) { - /* S = 2S */ - CHECK_MPI_OK( GF2m_ec_pt_dbl_aff(pp, a, &sx, &sy, &sx, &sy) ); - b3 = MP_GET_BIT(&k3, i); - b1 = MP_GET_BIT(&k, i); - /* if k3_i = 1 and k_i = 0, then S = S + Q */ - if ((b3 == 1) && (b1 == 0)) { - CHECK_MPI_OK( GF2m_ec_pt_add_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - /* if k3_i = 0 and k_i = 1, then S = S - Q */ - } else if ((b3 == 0) && (b1 == 1)) { - CHECK_MPI_OK( GF2m_ec_pt_sub_aff(pp, a, &sx, &sy, &qx, &qy, &sx, &sy) ); - } - } -#endif - /* output S */ - CHECK_MPI_OK( mp_copy(&sx, rx) ); - CHECK_MPI_OK( mp_copy(&sy, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&k3); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&sx); - mp_clear(&sy); - free(p); - return err; -} - -/* Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective - * coordinates. - * Uses algorithm Mdouble in appendix of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * modified to not require precomputation of c=b^{2^{m-1}}. - */ -static mp_err -gf2m_Mdouble(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, mp_int *x, mp_int *z) -{ - mp_err err = MP_OKAY; - mp_int t1; - - MP_DIGITS(&t1) = 0; - CHECK_MPI_OK( mp_init(&t1) ); - - CHECK_MPI_OK( mp_bsqrmod(x, p, x) ); - CHECK_MPI_OK( mp_bsqrmod(z, p, &t1) ); - CHECK_MPI_OK( mp_bmulmod(x, &t1, p, z) ); - CHECK_MPI_OK( mp_bsqrmod(x, p, x) ); - CHECK_MPI_OK( mp_bsqrmod(&t1, p, &t1) ); - CHECK_MPI_OK( mp_bmulmod(b, &t1, p, &t1) ); - CHECK_MPI_OK( mp_badd(x, &t1, x) ); - -cleanup: - mp_clear(&t1); - return err; -} - -/* Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery - * projective coordinates. - * Uses algorithm Madd in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - */ -static mp_err -gf2m_Madd(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, const mp_int *x, mp_int *x1, mp_int *z1, mp_int *x2, - mp_int *z2) -{ - mp_err err = MP_OKAY; - mp_int t1, t2; - - MP_DIGITS(&t1) = 0; - MP_DIGITS(&t2) = 0; - CHECK_MPI_OK( mp_init(&t1) ); - CHECK_MPI_OK( mp_init(&t2) ); - - CHECK_MPI_OK( mp_copy(x, &t1) ); - CHECK_MPI_OK( mp_bmulmod(x1, z2, p, x1) ); - CHECK_MPI_OK( mp_bmulmod(z1, x2, p, z1) ); - CHECK_MPI_OK( mp_bmulmod(x1, z1, p, &t2) ); - CHECK_MPI_OK( mp_badd(z1, x1, z1) ); - CHECK_MPI_OK( mp_bsqrmod(z1, p, z1) ); - CHECK_MPI_OK( mp_bmulmod(z1, &t1, p, x1) ); - CHECK_MPI_OK( mp_badd(x1, &t2, x1) ); - -cleanup: - mp_clear(&t1); - mp_clear(&t2); - return err; -} - -/* Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) - * using Montgomery point multiplication algorithm Mxy() in appendix of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * Returns: - * 0 on error - * 1 if return value should be the point at infinity - * 2 otherwise - */ -static int -gf2m_Mxy(const mp_int *pp, const unsigned int p[], const mp_int *a, - const mp_int *b, const mp_int *x, const mp_int *y, mp_int *x1, mp_int *z1, - mp_int *x2, mp_int *z2) -{ - mp_err err = MP_OKAY; - int ret; - mp_int t3, t4, t5; - - MP_DIGITS(&t3) = 0; - MP_DIGITS(&t4) = 0; - MP_DIGITS(&t5) = 0; - CHECK_MPI_OK( mp_init(&t3) ); - CHECK_MPI_OK( mp_init(&t4) ); - CHECK_MPI_OK( mp_init(&t5) ); - - if (mp_cmp_z(z1) == 0) { - mp_zero(x2); - mp_zero(z2); - ret = 1; - goto cleanup; - } - - if (mp_cmp_z(z2) == 0) { - CHECK_MPI_OK( mp_copy(x, x2) ); - CHECK_MPI_OK( mp_badd(x, y, z2) ); - ret = 2; - goto cleanup; - } - - mp_set(&t5, 0x1); - - CHECK_MPI_OK( mp_bmulmod(z1, z2, p, &t3) ); - - CHECK_MPI_OK( mp_bmulmod(z1, x, p, z1) ); - CHECK_MPI_OK( mp_badd(z1, x1, z1) ); - CHECK_MPI_OK( mp_bmulmod(z2, x, p, z2) ); - CHECK_MPI_OK( mp_bmulmod(z2, x1, p, x1) ); - CHECK_MPI_OK( mp_badd(z2, x2, z2) ); - - CHECK_MPI_OK( mp_bmulmod(z2, z1, p, z2) ); - CHECK_MPI_OK( mp_bsqrmod(x, p, &t4) ); - CHECK_MPI_OK( mp_badd(&t4, y, &t4) ); - CHECK_MPI_OK( mp_bmulmod(&t4, &t3, p, &t4) ); - CHECK_MPI_OK( mp_badd(&t4, z2, &t4) ); - - CHECK_MPI_OK( mp_bmulmod(&t3, x, p, &t3) ); - CHECK_MPI_OK( mp_bdivmod(&t5, &t3, pp, p, &t3) ); - CHECK_MPI_OK( mp_bmulmod(&t3, &t4, p, &t4) ); - CHECK_MPI_OK( mp_bmulmod(x1, &t3, p, x2) ); - CHECK_MPI_OK( mp_badd(x2, x, z2) ); - - CHECK_MPI_OK( mp_bmulmod(z2, &t4, p, z2) ); - CHECK_MPI_OK( mp_badd(z2, y, z2) ); - - ret = 2; - -cleanup: - mp_clear(&t3); - mp_clear(&t4); - mp_clear(&t5); - if (err == MP_OKAY) { - return ret; - } else { - return 0; - } -} - -/* Computes R = nP based on algorithm 2P of - * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation". - * Elliptic curve points P and R can be identical. - * Uses Montgomery projective coordinates. - */ -mp_err -GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int x1, x2, z1, z2; - int i, j; - mp_digit top_bit, mask; - unsigned int *p; - int p_size; - - MP_DIGITS(&x1) = 0; - MP_DIGITS(&x2) = 0; - MP_DIGITS(&z1) = 0; - MP_DIGITS(&z2) = 0; - CHECK_MPI_OK( mp_init(&x1) ); - CHECK_MPI_OK( mp_init(&x2) ); - CHECK_MPI_OK( mp_init(&z1) ); - CHECK_MPI_OK( mp_init(&z2) ); - - p_size = mp_bpoly2arr(pp, p, 0) + 1; - p = (unsigned int *) (malloc(sizeof(unsigned int) * p_size)); - if (p == NULL) goto cleanup; - mp_bpoly2arr(pp, p, p_size); - - /* if result should be point at infinity */ - if ((mp_cmp_z(n) == 0) || (GF2m_ec_pt_is_inf_aff(px, py) == MP_YES)) { - CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) ); - goto cleanup; - } - - CHECK_MPI_OK( mp_copy(rx, &x2) ); /* x2 = rx */ - CHECK_MPI_OK( mp_copy(ry, &z2) ); /* z2 = ry */ - - CHECK_MPI_OK( mp_copy(px, &x1) ); /* x1 = px */ - mp_set(&z1, 0x1); /* z1 = 1 */ - CHECK_MPI_OK( mp_bsqrmod(&x1, p, &z2) ); /* z2 = x1^2 = x2^2 */ - CHECK_MPI_OK( mp_bsqrmod(&z2, p, &x2) ); - CHECK_MPI_OK( mp_badd(&x2, b, &x2) ); /* x2 = px^4 + b */ - - /* find top-most bit and go one past it */ - i = MP_USED(n) - 1; - j = MP_DIGIT_BIT - 1; - top_bit = 1; - top_bit <<= MP_DIGIT_BIT - 1; - mask = top_bit; - while (!(MP_DIGITS(n)[i] & mask)) { - mask >>= 1; - j--; - } - mask >>= 1; j--; - - /* if top most bit was at word break, go to next word */ - if (!mask) { - i--; - j = MP_DIGIT_BIT - 1; - mask = top_bit; - } - - for (; i >= 0; i--) { - for (; j >= 0; j--) { - if (MP_DIGITS(n)[i] & mask) { - CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x1, &z1, &x2, &z2) ); - CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x2, &z2) ); - } else { - CHECK_MPI_OK( gf2m_Madd(pp, p, a, b, px, &x2, &z2, &x1, &z1) ); - CHECK_MPI_OK( gf2m_Mdouble(pp, p, a, b, &x1, &z1) ); - } - mask >>= 1; - } - j = MP_DIGIT_BIT - 1; - mask = top_bit; - } - - /* convert out of "projective" coordinates */ - i = gf2m_Mxy(pp, p, a, b, px, py, &x1, &z1, &x2, &z2); - if (i == 0) { - err = MP_BADARG; - goto cleanup; - } else if (i == 1) { - CHECK_MPI_OK( GF2m_ec_pt_set_inf_aff(rx, ry) ); - } else { - CHECK_MPI_OK( mp_copy(&x2, rx) ); - CHECK_MPI_OK( mp_copy(&z2, ry) ); - } - -cleanup: - mp_clear(&x1); - mp_clear(&x2); - mp_clear(&z1); - mp_clear(&z2); - free(p); - return err; -} - -#endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/freebl/GF2m_ecl.h b/security/nss/lib/freebl/GF2m_ecl.h deleted file mode 100644 index 3641d63da..000000000 --- a/security/nss/lib/freebl/GF2m_ecl.h +++ /dev/null @@ -1,97 +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 elliptic curve math library for binary polynomial field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Douglas Stebila <douglas@stebila.ca> - * - * 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 ***** */ - -#ifndef __gf2m_ecl_h_ -#define __gf2m_ecl_h_ -#ifdef NSS_ENABLE_ECC - -#include "secmpi.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err GF2m_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py); - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err GF2m_ec_pt_set_inf_aff(mp_int *px, mp_int *py); - -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy). - * Uses affine coordinates. - */ -mp_err GF2m_ec_pt_add_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = P - Q. Uses affine coordinates. */ -mp_err GF2m_ec_pt_sub_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = 2P. Uses affine coordinates. */ -mp_err GF2m_ec_pt_dbl_aff(const mp_int *pp, const mp_int *a, - const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the irreducible that - * determines the field GF2m. Uses affine coordinates. - */ -mp_err GF2m_ec_pt_mul_aff(const mp_int *pp, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the irreducible that - * determines the field GF2m. Uses Montgomery projective coordinates. - */ -mp_err GF2m_ec_pt_mul_mont(const mp_int *pp, const mp_int *a, - const mp_int *b, const mp_int *px, const mp_int *py, - const mp_int *n, mp_int *rx, mp_int *ry); - -#define GF2m_ec_pt_is_inf(px, py) GF2m_ec_pt_is_inf_aff((px), (py)) -#define GF2m_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \ - GF2m_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry)) - -#define GF2m_ECL_MONTGOMERY -#ifdef GF2m_ECL_AFFINE -#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \ - GF2m_ec_pt_mul_aff((pp), (a), (b), (px), (py), (n), (rx), (ry)) -#elif defined(GF2m_ECL_MONTGOMERY) -#define GF2m_ec_pt_mul(pp, a, b, px, py, n, rx, ry) \ - GF2m_ec_pt_mul_mont((pp), (a), (b), (px), (py), (n), (rx), (ry)) -#endif /* GF2m_ECL_AFFINE or GF2m_ECL_MONTGOMERY */ - -#endif /* NSS_ENABLE_ECC */ -#endif /* __gf2m_ecl_h_ */ diff --git a/security/nss/lib/freebl/GFp_ecl.c b/security/nss/lib/freebl/GFp_ecl.c deleted file mode 100644 index 7b460cc58..000000000 --- a/security/nss/lib/freebl/GFp_ecl.c +++ /dev/null @@ -1,648 +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 elliptic curve math library for prime field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Sheueling Chang Shantz <sheueling.chang@sun.com> and - * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories - * Bodo Moeller <moeller@cdc.informatik.tu-darmstadt.de>, - * Nils Larsch <nla@trustcenter.de>, and - * Lenka Fibikova <fibikova@exp-math.uni-essen.de>, the OpenSSL Project - * - * 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 ***** */ - -#ifdef NSS_ENABLE_ECC -/* - * GFp_ecl.c: Contains an implementation of elliptic curve math library - * for curves over GFp. - * - * XXX Can be moved to a separate subdirectory later. - * - */ - -#include "GFp_ecl.h" -#include "mpi/mplogic.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -mp_err -GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py) -{ - - if ((mp_cmp_z(px) == 0) && (mp_cmp_z(py) == 0)) { - return MP_YES; - } else { - return MP_NO; - } - -} - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -mp_err -GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py) -{ - mp_zero(px); - mp_zero(py); - return MP_OKAY; -} - -/* Computes R = P + Q based on IEEE P1363 A.10.1. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int lambda, temp, xtemp, ytemp; - - CHECK_MPI_OK( mp_init(&lambda) ); - CHECK_MPI_OK( mp_init(&temp) ); - CHECK_MPI_OK( mp_init(&xtemp) ); - CHECK_MPI_OK( mp_init(&ytemp) ); - /* if P = inf, then R = Q */ - if (GFp_ec_pt_is_inf_aff(px, py) == 0) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if Q = inf, then R = P */ - if (GFp_ec_pt_is_inf_aff(qx, qy) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - err = MP_OKAY; - goto cleanup; - } - /* if px != qx, then lambda = (py-qy) / (px-qx) */ - if (mp_cmp(px, qx) != 0) { - CHECK_MPI_OK( mp_submod(py, qy, p, &ytemp) ); - CHECK_MPI_OK( mp_submod(px, qx, p, &xtemp) ); - CHECK_MPI_OK( mp_invmod(&xtemp, p, &xtemp) ); - CHECK_MPI_OK( mp_mulmod(&ytemp, &xtemp, p, &lambda) ); - } else { - /* if py != qy or qy = 0, then R = inf */ - if (((mp_cmp(py, qy) != 0)) || (mp_cmp_z(qy) == 0)) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* lambda = (3qx^2+a) / (2qy) */ - CHECK_MPI_OK( mp_sqrmod(qx, p, &xtemp) ); - mp_set(&temp, 0x3); - CHECK_MPI_OK( mp_mulmod(&xtemp, &temp, p, &xtemp) ); - CHECK_MPI_OK( mp_addmod(&xtemp, a, p, &xtemp) ); - mp_set(&temp, 0x2); - CHECK_MPI_OK( mp_mulmod(qy, &temp, p, &ytemp) ); - CHECK_MPI_OK( mp_invmod(&ytemp, p, &ytemp) ); - CHECK_MPI_OK( mp_mulmod(&xtemp, &ytemp, p, &lambda) ); - } - /* rx = lambda^2 - px - qx */ - CHECK_MPI_OK( mp_sqrmod(&lambda, p, &xtemp) ); - CHECK_MPI_OK( mp_submod(&xtemp, px, p, &xtemp) ); - CHECK_MPI_OK( mp_submod(&xtemp, qx, p, &xtemp) ); - /* ry = (x1-x2) * lambda - y1 */ - CHECK_MPI_OK( mp_submod(qx, &xtemp, p, &ytemp) ); - CHECK_MPI_OK( mp_mulmod(&ytemp, &lambda, p, &ytemp) ); - CHECK_MPI_OK( mp_submod(&ytemp, qy, p, &ytemp) ); - CHECK_MPI_OK( mp_copy(&xtemp, rx) ); - CHECK_MPI_OK( mp_copy(&ytemp, ry) ); - -cleanup: - mp_clear(&lambda); - mp_clear(&temp); - mp_clear(&xtemp); - mp_clear(&ytemp); - return err; -} - -/* Computes R = P - Q. - * Elliptic curve points P, Q, and R can all be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int nqy; - MP_DIGITS(&nqy) = 0; - CHECK_MPI_OK( mp_init(&nqy) ); - /* nqy = -qy */ - CHECK_MPI_OK( mp_neg(qy, &nqy) ); - err = GFp_ec_pt_add_aff(p, a, px, py, qx, &nqy, rx, ry); -cleanup: - mp_clear(&nqy); - return err; -} - -/* Computes R = 2P. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, mp_int *rx, mp_int *ry) -{ - return GFp_ec_pt_add_aff(p, a, px, py, px, py, rx, ry); -} - -/* Gets the i'th bit in the binary representation of a. - * If i >= length(a), then return 0. - * (The above behaviour differs from mpl_get_bit, which - * causes an error if i >= length(a).) - */ -#define MP_GET_BIT(a, i) \ - ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) - -/* Computes R = nP based on IEEE P1363 A.10.3. - * Elliptic curve points P and R can be identical. - * Uses affine coordinates. - */ -mp_err -GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, mp_int *rx, - mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, k3, qx, qy, sx, sy; - int b1, b3, i, l; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&k3) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&k3) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - /* if n < 0 Q = -Q, k = -k */ - if (mp_cmp_z(n) < 0) { - CHECK_MPI_OK( mp_neg(&qy, &qy) ); - CHECK_MPI_OK( mp_mod(&qy, p, &qy) ); - CHECK_MPI_OK( mp_neg(&k, &k) ); - CHECK_MPI_OK( mp_mod(&k, p, &k) ); - } -#ifdef EC_DEBUG /* basic double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (mpl_get_bit(&k, i) != 0) { - CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) ); - } - } -#else /* double and add/subtract method from standard */ - /* k3 = 3 * k */ - mp_set(&k3, 0x3); - CHECK_MPI_OK( mp_mul(&k, &k3, &k3) ); - /* S = Q */ - CHECK_MPI_OK( mp_copy(&qx, &sx) ); - CHECK_MPI_OK( mp_copy(&qy, &sy) ); - /* l = index of high order bit in binary representation of 3*k */ - l = mpl_significant_bits(&k3) - 1; - /* for i = l-1 downto 1 */ - for (i = l - 1; i >= 1; i--) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_aff(p, a, &sx, &sy, &sx, &sy) ); - b3 = MP_GET_BIT(&k3, i); - b1 = MP_GET_BIT(&k, i); - /* if k3_i = 1 and k_i = 0, then S = S + Q */ - if ((b3 == 1) && (b1 == 0)) { - CHECK_MPI_OK( GFp_ec_pt_add_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - /* if k3_i = 0 and k_i = 1, then S = S - Q */ - } else if ((b3 == 0) && (b1 == 1)) { - CHECK_MPI_OK( GFp_ec_pt_sub_aff(p, a, &sx, &sy, - &qx, &qy, &sx, &sy) ); - } - } -#endif - /* output S */ - CHECK_MPI_OK( mp_copy(&sx, rx) ); - CHECK_MPI_OK( mp_copy(&sy, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&k3); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&sx); - mp_clear(&sy); - return err; -} - -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to - * affine coordinates R(rx, ry). P and R can share x and y coordinates. - */ -mp_err -GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, const mp_int *pz, - const mp_int *p, mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int z1, z2, z3; - MP_DIGITS(&z1) = 0; - MP_DIGITS(&z2) = 0; - MP_DIGITS(&z3) = 0; - CHECK_MPI_OK( mp_init(&z1) ); - CHECK_MPI_OK( mp_init(&z2) ); - CHECK_MPI_OK( mp_init(&z3) ); - - /* if point at infinity, then set point at infinity and exit */ - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( GFp_ec_pt_set_inf_aff(rx, ry) ); - goto cleanup; - } - - /* transform (px, py, pz) into (px / pz^2, py / pz^3) */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - } else { - CHECK_MPI_OK( mp_invmod(pz, p, &z1) ); - CHECK_MPI_OK( mp_sqrmod(&z1, p, &z2) ); - CHECK_MPI_OK( mp_mulmod(&z1, &z2, p, &z3) ); - CHECK_MPI_OK( mp_mulmod(px, &z2, p, rx) ); - CHECK_MPI_OK( mp_mulmod(py, &z3, p, ry) ); - } - -cleanup: - mp_clear(&z1); - mp_clear(&z2); - mp_clear(&z3); - return err; -} - -/* Checks if point P(px, py, pz) is at infinity. - * Uses Jacobian coordinates. - */ -mp_err -GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, const mp_int *pz) -{ - return mp_cmp_z(pz); -} - -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian - * coordinates. - */ -mp_err -GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz) -{ - mp_zero(pz); - return MP_OKAY; -} - -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and - * Q is (qx, qy, qz). Elliptic curve points P, Q, and R can all be - * identical. Uses Jacobian coordinates. - * - * This routine implements Point Addition in the Jacobian Projective - * space as described in the paper "Efficient elliptic curve exponentiation - * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono. - */ -mp_err -GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *pz, const mp_int *qx, - const mp_int *qy, const mp_int *qz, mp_int *rx, mp_int *ry, mp_int *rz) -{ - mp_err err = MP_OKAY; - mp_int n0, u1, u2, s1, s2, H, G; - MP_DIGITS(&n0) = 0; - MP_DIGITS(&u1) = 0; - MP_DIGITS(&u2) = 0; - MP_DIGITS(&s1) = 0; - MP_DIGITS(&s2) = 0; - MP_DIGITS(&H) = 0; - MP_DIGITS(&G) = 0; - CHECK_MPI_OK( mp_init(&n0) ); - CHECK_MPI_OK( mp_init(&u1) ); - CHECK_MPI_OK( mp_init(&u2) ); - CHECK_MPI_OK( mp_init(&s1) ); - CHECK_MPI_OK( mp_init(&s2) ); - CHECK_MPI_OK( mp_init(&H) ); - CHECK_MPI_OK( mp_init(&G) ); - - /* Use point double if pointers are equal. */ - if ((px == qx) && (py == qy) && (pz == qz)) { - err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, rx, ry, rz); - goto cleanup; - } - - /* If either P or Q is the point at infinity, then return - * the other point - */ - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( mp_copy(qx, rx) ); - CHECK_MPI_OK( mp_copy(qy, ry) ); - CHECK_MPI_OK( mp_copy(qz, rz) ); - goto cleanup; - } - if (GFp_ec_pt_is_inf_jac(qx, qy, qz) == MP_YES) { - CHECK_MPI_OK( mp_copy(px, rx) ); - CHECK_MPI_OK( mp_copy(py, ry) ); - CHECK_MPI_OK( mp_copy(pz, rz) ); - goto cleanup; - } - - /* Compute u1 = px * qz^2, s1 = py * qz^3 */ - if (mp_cmp_d(qz, 1) == 0) { - CHECK_MPI_OK( mp_copy(px, &u1) ); - CHECK_MPI_OK( mp_copy(py, &s1) ); - } else { - CHECK_MPI_OK( mp_sqrmod(qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(px, &n0, p, &u1) ); - CHECK_MPI_OK( mp_mulmod(&n0, qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(py, &n0, p, &s1) ); - } - - /* Compute u2 = qx * pz^2, s2 = qy * pz^3 */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_copy(qx, &u2) ); - CHECK_MPI_OK( mp_copy(qy, &s2) ); - } else { - CHECK_MPI_OK( mp_sqrmod(pz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(qx, &n0, p, &u2) ); - CHECK_MPI_OK( mp_mulmod(&n0, pz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(qy, &n0, p, &s2) ); - } - - /* Compute H = u2 - u1 ; G = s2 - s1 */ - CHECK_MPI_OK( mp_submod(&u2, &u1, p, &H) ); - CHECK_MPI_OK( mp_submod(&s2, &s1, p, &G) ); - - if (mp_cmp_z(&H) == 0) { - if (mp_cmp_z(&G) == 0) { - /* P = Q; double */ - err = GFp_ec_pt_dbl_jac(p, a, px, py, pz, - rx, ry, rz); - goto cleanup; - } else { - /* P = -Q; return point at infinity */ - CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) ); - goto cleanup; - } - } - - /* rz = pz * qz * H */ - if (mp_cmp_d(pz, 1) == 0) { - if (mp_cmp_d(qz, 1) == 0) { - /* if pz == qz == 1, then rz = H */ - CHECK_MPI_OK( mp_copy(&H, rz) ); - } else { - CHECK_MPI_OK( mp_mulmod(qz, &H, p, rz) ); - } - } else { - if (mp_cmp_d(qz, 1) == 0) { - CHECK_MPI_OK( mp_mulmod(pz, &H, p, rz) ); - } else { - CHECK_MPI_OK( mp_mulmod(pz, qz, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(&n0, &H, p, rz) ); - } - } - - /* rx = G^2 - H^3 - 2 * u1 * H^2 */ - CHECK_MPI_OK( mp_sqrmod(&G, p, rx) ); - CHECK_MPI_OK( mp_sqrmod(&H, p, &n0) ); - CHECK_MPI_OK( mp_mulmod(&n0, &u1, p, &u1) ); - CHECK_MPI_OK( mp_addmod(&u1, &u1, p, &u2) ); - CHECK_MPI_OK( mp_mulmod(&H, &n0, p, &H) ); - CHECK_MPI_OK( mp_submod(rx, &H, p, rx) ); - CHECK_MPI_OK( mp_submod(rx, &u2, p, rx) ); - - /* ry = - s1 * H^3 + G * (u1 * H^2 - rx) */ - /* (formula based on values of variables before block above) */ - CHECK_MPI_OK( mp_submod(&u1, rx, p, &u1) ); - CHECK_MPI_OK( mp_mulmod(&G, &u1, p, ry) ); - CHECK_MPI_OK( mp_mulmod(&s1, &H, p, &s1) ); - CHECK_MPI_OK( mp_submod(ry, &s1, p, ry) ); - -cleanup: - mp_clear(&n0); - mp_clear(&u1); - mp_clear(&u2); - mp_clear(&s1); - mp_clear(&s2); - mp_clear(&H); - mp_clear(&G); - return err; -} - -/* Computes R = 2P. Elliptic curve points P and R can be identical. Uses - * Jacobian coordinates. - * - * This routine implements Point Doubling in the Jacobian Projective - * space as described in the paper "Efficient elliptic curve exponentiation - * using mixed coordinates", by H. Cohen, A Miyaji, T. Ono. - */ -mp_err -GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, const mp_int *px, - const mp_int *py, const mp_int *pz, mp_int *rx, mp_int *ry, mp_int *rz) -{ - mp_err err = MP_OKAY; - mp_int t0, t1, M, S; - MP_DIGITS(&t0) = 0; - MP_DIGITS(&t1) = 0; - MP_DIGITS(&M) = 0; - MP_DIGITS(&S) = 0; - CHECK_MPI_OK( mp_init(&t0) ); - CHECK_MPI_OK( mp_init(&t1) ); - CHECK_MPI_OK( mp_init(&M) ); - CHECK_MPI_OK( mp_init(&S) ); - - if (GFp_ec_pt_is_inf_jac(px, py, pz) == MP_YES) { - CHECK_MPI_OK( GFp_ec_pt_set_inf_jac(rx, ry, rz) ); - goto cleanup; - } - - if (mp_cmp_d(pz, 1) == 0) { - /* M = 3 * px^2 + a */ - CHECK_MPI_OK( mp_sqrmod(px, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, a, p, &M) ); - } else if (mp_cmp_int(a, -3) == 0) { - /* M = 3 * (px + pz^2) * (px - pz) */ - CHECK_MPI_OK( mp_sqrmod(pz, p, &M) ); - CHECK_MPI_OK( mp_addmod(px, &M, p, &t0) ); - CHECK_MPI_OK( mp_submod(px, &M, p, &t1) ); - CHECK_MPI_OK( mp_mulmod(&t0, &t1, p, &M) ); - CHECK_MPI_OK( mp_addmod(&M, &M, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &M) ); - } else { - CHECK_MPI_OK( mp_sqrmod(px, p, &t0) ); - CHECK_MPI_OK( mp_addmod(&t0, &t0, p, &M) ); - CHECK_MPI_OK( mp_addmod(&t0, &M, p, &t0) ); - CHECK_MPI_OK( mp_sqrmod(pz, p, &M) ); - CHECK_MPI_OK( mp_sqrmod(&M, p, &M) ); - CHECK_MPI_OK( mp_mulmod(&M, a, p, &M) ); - CHECK_MPI_OK( mp_addmod(&M, &t0, p, &M) ); - } - - /* rz = 2 * py * pz */ - if (mp_cmp_d(pz, 1) == 0) { - CHECK_MPI_OK( mp_addmod(py, py, p, rz) ); - CHECK_MPI_OK( mp_sqrmod(rz, p, &t0) ); - } else { - CHECK_MPI_OK( mp_addmod(py, py, p, &t0) ); - CHECK_MPI_OK( mp_mulmod(&t0, pz, p, rz) ); - CHECK_MPI_OK( mp_sqrmod(&t0, p, &t0) ); - } - - /* S = 4 * px * py^2 = pz * (2 * py)^2 */ - CHECK_MPI_OK( mp_mulmod(px, &t0, p, &S) ); - - /* rx = M^2 - 2 * S */ - CHECK_MPI_OK( mp_addmod(&S, &S, p, &t1) ); - CHECK_MPI_OK( mp_sqrmod(&M, p, rx) ); - CHECK_MPI_OK( mp_submod(rx, &t1, p, rx) ); - - /* ry = M * (S - rx) - 8 * py^4 */ - CHECK_MPI_OK( mp_sqrmod(&t0, p, &t1) ); - if (mp_isodd(&t1)) { - CHECK_MPI_OK( mp_add(&t1, p, &t1) ); - } - CHECK_MPI_OK( mp_div_2(&t1, &t1) ); - CHECK_MPI_OK( mp_submod(&S, rx, p, &S) ); - CHECK_MPI_OK( mp_mulmod(&M, &S, p, &M) ); - CHECK_MPI_OK( mp_submod(&M, &t1, p, ry) ); - -cleanup: - mp_clear(&t0); - mp_clear(&t1); - mp_clear(&M); - mp_clear(&S); - return err; -} - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Elliptic curve points P and R can be - * identical. Uses Jacobian coordinates. - */ -mp_err -GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry) -{ - mp_err err = MP_OKAY; - mp_int k, qx, qy, qz, sx, sy, sz; - int i, l; - - MP_DIGITS(&k) = 0; - MP_DIGITS(&qx) = 0; - MP_DIGITS(&qy) = 0; - MP_DIGITS(&qz) = 0; - MP_DIGITS(&sx) = 0; - MP_DIGITS(&sy) = 0; - MP_DIGITS(&sz) = 0; - CHECK_MPI_OK( mp_init(&k) ); - CHECK_MPI_OK( mp_init(&qx) ); - CHECK_MPI_OK( mp_init(&qy) ); - CHECK_MPI_OK( mp_init(&qz) ); - CHECK_MPI_OK( mp_init(&sx) ); - CHECK_MPI_OK( mp_init(&sy) ); - CHECK_MPI_OK( mp_init(&sz) ); - - /* if n = 0 then r = inf */ - if (mp_cmp_z(n) == 0) { - mp_zero(rx); - mp_zero(ry); - err = MP_OKAY; - goto cleanup; - /* if n < 0 then out of range error */ - } else if (mp_cmp_z(n) < 0) { - err = MP_RANGE; - goto cleanup; - } - /* Q = P, k = n */ - CHECK_MPI_OK( mp_copy(px, &qx) ); - CHECK_MPI_OK( mp_copy(py, &qy) ); - CHECK_MPI_OK( mp_set_int(&qz, 1) ); - CHECK_MPI_OK( mp_copy(n, &k) ); - - /* double and add method */ - l = mpl_significant_bits(&k) - 1; - mp_zero(&sx); - mp_zero(&sy); - mp_zero(&sz); - for (i = l; i >= 0; i--) { - /* if k_i = 1, then S = S + Q */ - if (MP_GET_BIT(&k, i) != 0) { - CHECK_MPI_OK( GFp_ec_pt_add_jac(p, a, &sx, &sy, &sz, - &qx, &qy, &qz, &sx, &sy, &sz) ); - } - if (i > 0) { - /* S = 2S */ - CHECK_MPI_OK( GFp_ec_pt_dbl_jac(p, a, &sx, &sy, &sz, - &sx, &sy, &sz) ); - } - } - - /* convert result S to affine coordinates */ - CHECK_MPI_OK( GFp_ec_pt_jac2aff(&sx, &sy, &sz, p, rx, ry) ); - -cleanup: - mp_clear(&k); - mp_clear(&qx); - mp_clear(&qy); - mp_clear(&qz); - mp_clear(&sx); - mp_clear(&sy); - mp_clear(&sz); - return err; -} -#endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/freebl/GFp_ecl.h b/security/nss/lib/freebl/GFp_ecl.h deleted file mode 100644 index d920b2e7c..000000000 --- a/security/nss/lib/freebl/GFp_ecl.h +++ /dev/null @@ -1,127 +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 elliptic curve math library for prime field curves. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are Copyright (C) 2003 - * 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 - * 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 ***** */ - -#ifndef __gfp_ecl_h_ -#define __gfp_ecl_h_ -#ifdef NSS_ENABLE_ECC - -#include "secmpi.h" - -/* Checks if point P(px, py) is at infinity. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_is_inf_aff(const mp_int *px, const mp_int *py); - -/* Sets P(px, py) to be the point at infinity. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_set_inf_aff(mp_int *px, mp_int *py); - -/* Computes R = P + Q where R is (rx, ry), P is (px, py) and Q is (qx, qy). - * Uses affine coordinates. - */ -extern mp_err GFp_ec_pt_add_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = P - Q. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_sub_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *qx, const mp_int *qy, - mp_int *rx, mp_int *ry); - -/* Computes R = 2P. Uses affine coordinates. */ -extern mp_err GFp_ec_pt_dbl_aff(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, mp_int *rx, mp_int *ry); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Uses affine coordinates. - */ -extern mp_err GFp_ec_pt_mul_aff(const mp_int *p, const mp_int *a, - const mp_int *b, const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -/* Converts a point P(px, py, pz) from Jacobian projective coordinates to - * affine coordinates R(rx, ry). - */ -extern mp_err GFp_ec_pt_jac2aff(const mp_int *px, const mp_int *py, - const mp_int *pz, const mp_int *p, mp_int *rx, mp_int *ry); - -/* Checks if point P(px, py, pz) is at infinity. Uses Jacobian - * coordinates. - */ -extern mp_err GFp_ec_pt_is_inf_jac(const mp_int *px, const mp_int *py, - const mp_int *pz); - -/* Sets P(px, py, pz) to be the point at infinity. Uses Jacobian - * coordinates. - */ -extern mp_err GFp_ec_pt_set_inf_jac(mp_int *px, mp_int *py, mp_int *pz); - -/* Computes R = P + Q where R is (rx, ry, rz), P is (px, py, pz) and - * Q is (qx, qy, qz). Uses Jacobian coordinates. - */ -extern mp_err GFp_ec_pt_add_jac(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *pz, - const mp_int *qx, const mp_int *qy, const mp_int *qz, - mp_int *rx, mp_int *ry, mp_int *rz); - -/* Computes R = 2P. Uses Jacobian coordinates. */ -extern mp_err GFp_ec_pt_dbl_jac(const mp_int *p, const mp_int *a, - const mp_int *px, const mp_int *py, const mp_int *pz, - mp_int *rx, mp_int *ry, mp_int *rz); - -/* Computes R = nP where R is (rx, ry) and P is (px, py). The parameters - * a, b and p are the elliptic curve coefficients and the prime that - * determines the field GFp. Uses Jacobian coordinates. - */ -mp_err GFp_ec_pt_mul_jac(const mp_int *p, const mp_int *a, const mp_int *b, - const mp_int *px, const mp_int *py, const mp_int *n, - mp_int *rx, mp_int *ry); - -#define GFp_ec_pt_is_inf(px, py) GFp_ec_pt_is_inf_aff((px), (py)) -#define GFp_ec_pt_add(p, a, px, py, qx, qy, rx, ry) \ - GFp_ec_pt_add_aff((p), (a), (px), (py), (qx), (qy), (rx), (ry)) - -#define GFp_ECL_JACOBIAN -#ifdef GFp_ECL_AFFINE -#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \ - GFp_ec_pt_mul_aff((p), (a), (b), (px), (py), (n), (rx), (ry)) -#elif defined(GFp_ECL_JACOBIAN) -#define GFp_ec_pt_mul(p, a, b, px, py, n, rx, ry) \ - GFp_ec_pt_mul_jac((p), (a), (b), (px), (py), (n), (rx), (ry)) -#endif /* GFp_ECL_AFFINE or GFp_ECL_JACOBIAN*/ - -#endif /* NSS_ENABLE_ECC */ -#endif /* __gfp_ecl_h_ */ diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 11c0843a8..a3100a5b9 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -98,7 +98,7 @@ ifdef NS_USE_GCC ASFILES = DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT else - ASFILES = mpi_x86.asm + MPI_SRCS += mpi_x86_asm.c DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD ifdef BUILD_OPT @@ -112,12 +112,6 @@ ifeq ($(OS_TARGET),WINCE) DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512 endif -ifdef XP_OS2_VACPP - ASFILES = mpi_x86.asm - DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE - DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -endif - ifeq ($(OS_TARGET),IRIX) ifeq ($(USE_N32),1) ASFILES = mpi_mips.s @@ -137,12 +131,15 @@ ifeq ($(CPU_ARCH),x86_64) ASFLAGS += -march=opteron -m64 -fPIC DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY DEFINES += -DNSS_USE_COMBA + DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +# DEFINES += -DMPI_AMD64_ADD MPI_SRCS += mpi_amd64.c mp_comba.c endif ifeq ($(CPU_ARCH),x86) ASFILES = mpi_x86.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE DEFINES += -DMP_ASSEMBLY_DIV_2DX1D + DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN # The floating point ECC code doesn't work on Linux x86 (bug 311432). #ECL_USE_FP = 1 endif @@ -171,13 +168,13 @@ ifdef USE_ABI32_INT32 DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512 else ifdef USE_64 -# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 32-bit digits +# this builds for DA2.0W (HP PA 2.0 Wide), the LP64 ABI, using 64-bit digits MPI_SRCS += mpi_hp.c ASFILES += hpma512.s hppa20.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE else # this builds for DA2.0 (HP PA 2.0 Narrow) ABI32_FPU model -# (the 32-bit ABI with 64-bit registers) using 32-bit digits +# (the 32-bit ABI with 64-bit registers) using 64-bit digits MPI_SRCS += mpi_hp.c ASFILES += hpma512.s hppa20.s DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE @@ -188,6 +185,17 @@ endif endif endif +# The blapi functions are defined not only in the freebl shared +# libraries but also in the shared libraries linked with loader.c +# (libsoftokn3.so and libssl3.so). We need to use GNU ld's +# -Bsymbolic option or the equivalent option for other linkers +# to bind the blapi function references in FREEBLVector vector +# (ldvector.c) to the blapi functions defined in the freebl +# shared libraries. +ifeq (,$(filter-out BSD_OS FreeBSD Linux NetBSD, $(OS_TARGET))) + MKSHLIB += -Wl,-Bsymbolic +endif + ifeq ($(OS_TARGET),SunOS) # The -R '$ORIGIN' linker option instructs this library to search for its @@ -227,18 +235,36 @@ ifeq ($(CPU_ARCH),sparc) endif ifdef USE_ABI32_INT64 ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus + SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC endif ifdef USE_ABI32_FPU - ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plus + ARCHFLAG=-mcpu=v9 -Wa,-xarch=v8plusa + SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC endif # USE_ABI32_FPU ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture + ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9 + SOLARIS_AS_FLAGS = -xarch=v9 -K PIC endif ifdef USE_ABI64_FPU # this builds for Sparc v9a pure 64-bit architecture # It uses floating point, and 32-bit word size + ARCHFLAG += -mcpu=v9 -Wa,-xarch=v9a + SOLARIS_AS_FLAGS = -xarch=v9a -K PIC endif else # NS_USE_GCC + # FPU_TARGET_OPTIMIZER specifies the target processor and cache + # properties of the ABI32_FPU and ABI64_FPU architectures for use + # by the optimizer. + ifeq (,$(findstring Sun WorkShop 6,$(shell $(CC) -V 2>&1))) + # if the compiler is not Forte 6 + FPU_TARGET_OPTIMIZER = -xcache=64/32/4:1024/64/4 -xchip=ultra3 + else + # Forte 6 C compiler generates incorrect code for rijndael.c + # if -xchip=ultra3 is used (Bugzilla bug 333925). So we revert + # to what we used in NSS 3.10. + FPU_TARGET_OPTIMIZER = -xchip=ultra2 + endif ifdef USE_ABI32_INT32 #ARCHFLAG=-xarch=v8 set in coreconf/sunOS5.mk endif @@ -248,7 +274,10 @@ ifeq ($(CPU_ARCH),sparc) # no FPU (non-VIS cpus). # These flags were suggested by the compiler group for building # with SunStudio 10. - SOL_CFLAGS += -xO4 -xtarget=generic + ifdef BUILD_OPT + SOL_CFLAGS += -xO4 + endif + SOL_CFLAGS += -xtarget=generic ARCHFLAG = -xarch=v8plus SOLARIS_AS_FLAGS = -xarch=v8plus -K PIC endif @@ -257,17 +286,23 @@ ifeq ($(CPU_ARCH),sparc) # 32-bit ABI, it uses FPU code, and 32-bit word size. # these flags were determined by running cc -### -fast and copying # the generated flag settings - SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle - SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all - SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend - SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5 + SOL_CFLAGS += -fsingle -xmemalign=8s + ifdef BUILD_OPT + SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1 + SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all + SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend + SOL_CFLAGS += -xlibmil -xO5 + endif ARCHFLAG = -xarch=v8plusa SOLARIS_AS_FLAGS = -xarch=v8plusa -K PIC endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture, # no FPU (non-VIS cpus). For building with SunStudio 10. - SOL_CFLAGS += -xO4 -xtarget=generic + ifdef BUILD_OPT + SOL_CFLAGS += -xO4 + endif + SOL_CFLAGS += -xtarget=generic ARCHFLAG = -xarch=v9 SOLARIS_AS_FLAGS = -xarch=v9 -K PIC endif @@ -275,16 +310,19 @@ ifeq ($(CPU_ARCH),sparc) # this builds for Sparc v9a pure 64-bit architecture # It uses floating point, and 32-bit word size. # See comment for USE_ABI32_FPU. - SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fns -fsimple=2 -fsingle - SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all - SOL_CFLAGS += -xcache=64/32/4:1024/64/4 -xchip=ultra3 -xdepend - SOL_CFLAGS += -xlibmil -xmemalign=8s -xO5 + SOL_CFLAGS += -fsingle -xmemalign=8s + ifdef BUILD_OPT + SOL_CFLAGS += -D__MATHERR_ERRNO_DONTCARE -fsimple=1 + SOL_CFLAGS += -xalias_level=basic -xbuiltin=%all + SOL_CFLAGS += $(FPU_TARGET_OPTIMIZER) -xdepend + SOL_CFLAGS += -xlibmil -xO5 + endif ARCHFLAG = -xarch=v9a SOLARIS_AS_FLAGS = -xarch=v9a -K PIC endif endif # NS_USE_GCC - ### set MP_ flags for both GCC and Sun cc + ### set flags for both GCC and Sun cc ifdef USE_ABI32_INT32 # this builds for Sparc v8 pure 32-bit architecture DEFINES += -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY @@ -303,6 +341,7 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv8.s montmulfv8.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL + ECL_USE_FP = 1 endif ifdef USE_ABI64_INT # this builds for Sparc v9a pure 64-bit architecture @@ -315,9 +354,9 @@ ifeq ($(CPU_ARCH),sparc) ASFILES = mpv_sparcv9.s montmulfv9.s DEFINES += -DMP_NO_MP_WORD -DMP_USE_UINT_DIGIT -DMP_ASSEMBLY_MULTIPLY DEFINES += -DMP_USING_MONT_MULF -DMP_MONT_USE_MP_MUL + ECL_USE_FP = 1 endif - ECL_USE_FP = 1 else # Solaris for non-sparc family CPUs ifdef NS_USE_GCC @@ -392,7 +431,6 @@ vpath %.h mpi ecl vpath %.c mpi ecl vpath %.S mpi ecl vpath %.s mpi ecl -vpath %.asm mpi ecl INCLUDES += -Impi -Iecl @@ -533,5 +571,19 @@ endif # FREEBL_CHILD_BUILD ifdef XP_OS2_VACPP $(OBJDIR)/alg2268.obj: alg2268.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) +endif + +# Bugzilla Bug 333917: the non-x86 code in desblapi.c seems to violate +# ANSI C's strict aliasing rules. +ifeq ($(OS_TARGET),Linux) +ifneq ($(CPU_ARCH),x86) +$(OBJDIR)/$(PROG_PREFIX)desblapi$(OBJ_SUFFIX): desblapi.c + @$(MAKE_OBJDIR) +ifdef NEED_ABSOLUTE_PATH + $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $(call core_abspath,$<) +else + $(CC) -o $@ -c $(CFLAGS) -fno-strict-aliasing $< +endif +endif endif diff --git a/security/nss/lib/freebl/arcfour-amd64-gas.s b/security/nss/lib/freebl/arcfour-amd64-gas.s index 66daf07ba..e131fd16a 100644 --- a/security/nss/lib/freebl/arcfour-amd64-gas.s +++ b/security/nss/lib/freebl/arcfour-amd64-gas.s @@ -114,3 +114,7 @@ ARCFOUR: ret .L_ARCFOUR_end: .size ARCFOUR,.L_ARCFOUR_end-ARCFOUR + +# Magic indicating no need for an executable stack +.section .note.GNU-stack,"",@progbits +.previous diff --git a/security/nss/lib/freebl/blapi.h b/security/nss/lib/freebl/blapi.h index 899eadd45..06e3ef2ab 100644 --- a/security/nss/lib/freebl/blapi.h +++ b/security/nss/lib/freebl/blapi.h @@ -984,6 +984,50 @@ extern void RNG_RNGShutdown(void); extern void RNG_SystemInfoForRNG(void); +/* + * FIPS 186-2 Change Notice 1 RNG Algorithm 1, used both to + * generate the DSA X parameter and as a generic purpose RNG. + * + * The following two FIPS186Change functions are needed for + * NIST RNG Validation System. + */ + +/* + * Given the seed-key and the seed, generate the random output. + * + * Parameters: + * XKEY [input/output]: the state of the RNG (seed-key) + * XSEEDj [input]: optional user input (seed) + * x_j [output]: output of the RNG + * + * Return value: + * This function usually returns SECSuccess. The only reason + * this function returns SECFailure is that XSEEDj equals + * XKEY, including the intermediate XKEY value between the two + * iterations. (This test is actually a FIPS 140-2 requirement + * and not required for FIPS algorithm testing, but it is too + * hard to separate from this function.) If this function fails, + * XKEY is not updated, but some data may have been written to + * x_j, which should be ignored. + */ +extern SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, + const unsigned char *XSEEDj, + unsigned char *x_j); + +/* + * When generating the DSA X parameter, we generate 2*GSIZE bytes + * of random output and reduce it mod q. + * + * Input: w, 2*GSIZE bytes + * q, DSA_SUBPRIME_LEN bytes + * Output: xj, DSA_SUBPRIME_LEN bytes + */ +extern SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj); + /* Generate PQGParams and PQGVerify structs. * Length of seed and length of h both equal length of P. * All lengths are specified by "j", according to the table above. @@ -1043,6 +1087,8 @@ extern SECStatus PQG_VerifyParams(const PQGParams *params, */ extern void BL_Cleanup(void); +/* unload freebl shared library from memory */ +extern void BL_Unload(void); /************************************************************************** * Verify a given Shared library signature * diff --git a/security/nss/lib/freebl/config.mk b/security/nss/lib/freebl/config.mk index ecbc9373f..cef7dad9c 100644 --- a/security/nss/lib/freebl/config.mk +++ b/security/nss/lib/freebl/config.mk @@ -75,6 +75,10 @@ PROGRAM = EXTRA_LIBS += $(DIST)/lib/$(LIB_PREFIX)secutil.$(LIB_SUFFIX) +ifeq ($(OS_TARGET), SunOS) +OS_LIBS += -lkstat +endif + ifeq (,$(filter-out WIN%,$(OS_TARGET))) # don't want the 32 in the shared library name diff --git a/security/nss/lib/freebl/des.c b/security/nss/lib/freebl/des.c index 684a466f8..92c84692b 100644 --- a/security/nss/lib/freebl/des.c +++ b/security/nss/lib/freebl/des.c @@ -658,7 +658,7 @@ DES_Do1Block(HALF * ks, const BYTE * inbuf, BYTE * outbuf) HALFPTR(outbuf)[0] = left; HALFPTR(outbuf)[1] = right; #else - if (((ptrdiff_t)inbuf & 0x03) == 0) { + if (((ptrdiff_t)outbuf & 0x03) == 0) { #if defined(IS_LITTLE_ENDIAN) BYTESWAP(left, temp); BYTESWAP(right, temp); diff --git a/security/nss/lib/freebl/ec.c b/security/nss/lib/freebl/ec.c index 563e10438..196ad7442 100644 --- a/security/nss/lib/freebl/ec.c +++ b/security/nss/lib/freebl/ec.c @@ -42,6 +42,7 @@ #include "secerr.h" #include "secmpi.h" #include "secitem.h" +#include "mplogic.h" #include "ec.h" #include "ecl.h" @@ -53,7 +54,7 @@ PRBool ec_point_at_infinity(SECItem *pointP) { - int i; + unsigned int i; for (i = 1; i < pointP->len; i++) { if (pointP->data[i] != 0x00) return PR_FALSE; @@ -353,28 +354,26 @@ EC_NewKeyFromSeed(ECParams *ecParams, ECPrivateKey **privKey, return rv; } -/* Generates a new EC key pair. The private key is a random value and - * the public key is the result of performing a scalar point multiplication - * of that value with the curve's base point. The random value for the - * private key is generated using the algorithm A.4.1 of ANSI X9.62, +/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the * random number generator. + * + * Parameters + * - order: a buffer that holds the curve's group order + * - len: the length in octets of the order buffer + * + * Return Value + * Returns a buffer of len octets that holds the private key. The caller + * is responsible for freeing the buffer with PORT_ZFree. */ -SECStatus -EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) +static unsigned char * +ec_GenerateRandomPrivateKey(const unsigned char *order, int len) { - SECStatus rv = SECFailure; -#ifdef NSS_ENABLE_ECC + SECStatus rv = SECSuccess; mp_err err; - int len; unsigned char *privKeyBytes = NULL; mp_int privKeyVal, order_1, one; - if (!ecParams || !privKey) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - MP_DIGITS(&privKeyVal) = 0; MP_DIGITS(&order_1) = 0; MP_DIGITS(&one) = 0; @@ -382,36 +381,62 @@ EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) CHECK_MPI_OK( mp_init(&order_1) ); CHECK_MPI_OK( mp_init(&one) ); - /* Generate random private key. - * Generates 2*len random bytes using the global random bit generator + /* Generates 2*len random bytes using the global random bit generator * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then * reduces modulo the group order. */ - len = ecParams->order.len; if ((privKeyBytes = PORT_Alloc(2*len)) == NULL) goto cleanup; CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) ); CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) ); - CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, - ecParams->order.data, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) ); CHECK_MPI_OK( mp_set_int(&one, 1) ); CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); - CHECK_MPI_OK( mp_to_unsigned_octets(&privKeyVal, privKeyBytes, len) ); - /* generate public key */ - CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) ); - + CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); + memset(privKeyBytes+len, 0, len); cleanup: mp_clear(&privKeyVal); mp_clear(&order_1); mp_clear(&one); - if (privKeyBytes) { - PORT_ZFree(privKeyBytes, 2*len); - } if (err < MP_OKAY) { MP_TO_SEC_ERROR(err); rv = SECFailure; } + if (rv != SECSuccess && privKeyBytes) { + PORT_Free(privKeyBytes); + privKeyBytes = NULL; + } + return privKeyBytes; +} + +/* Generates a new EC key pair. The private key is a random value and + * the public key is the result of performing a scalar point multiplication + * of that value with the curve's base point. + */ +SECStatus +EC_NewKey(ECParams *ecParams, ECPrivateKey **privKey) +{ + SECStatus rv = SECFailure; +#ifdef NSS_ENABLE_ECC + int len; + unsigned char *privKeyBytes = NULL; + + if (!ecParams) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + len = ecParams->order.len; + privKeyBytes = ec_GenerateRandomPrivateKey(ecParams->order.data, len); + if (privKeyBytes == NULL) goto cleanup; + /* generate public key */ + CHECK_SEC_OK( ec_NewKey(ecParams, privKey, privKeyBytes, len) ); + +cleanup: + if (privKeyBytes) { + PORT_ZFree(privKeyBytes, len); + } #if EC_DEBUG printf("EC_NewKey returning %s\n", (rv == SECSuccess) ? "success" : "failure"); @@ -613,33 +638,41 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, mp_err err = MP_OKAY; ECParams *ecParams = NULL; SECItem kGpoint = { siBuffer, NULL, 0}; - int len = 0; + int flen = 0; /* length in bytes of the field size */ + unsigned olen; /* length in bytes of the base point order */ #if EC_DEBUG char mpstr[256]; #endif + /* Initialize MPI integers. */ + /* must happen before the first potential call to cleanup */ + MP_DIGITS(&x1) = 0; + MP_DIGITS(&d) = 0; + MP_DIGITS(&k) = 0; + MP_DIGITS(&r) = 0; + MP_DIGITS(&s) = 0; + MP_DIGITS(&n) = 0; + /* Check args */ - if (!key || !signature || !digest || !kb || (kblen < 0) || - (digest->len != SHA1_LENGTH)) { + if (!key || !signature || !digest || !kb || (kblen < 0)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto cleanup; } ecParams = &(key->ecParams); - len = (ecParams->fieldID.size + 7) >> 3; - if (signature->len < 2*len) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); + flen = (ecParams->fieldID.size + 7) >> 3; + olen = ecParams->order.len; + if (signature->data == NULL) { + /* a call to get the signature length only */ + goto finish; + } + if (signature->len < 2*olen) { + PORT_SetError(SEC_ERROR_OUTPUT_LEN); goto cleanup; } - /* Initialize MPI integers. */ - MP_DIGITS(&x1) = 0; - MP_DIGITS(&d) = 0; - MP_DIGITS(&k) = 0; - MP_DIGITS(&r) = 0; - MP_DIGITS(&s) = 0; - MP_DIGITS(&n) = 0; + CHECK_MPI_OK( mp_init(&x1) ); CHECK_MPI_OK( mp_init(&d) ); CHECK_MPI_OK( mp_init(&k) ); @@ -668,8 +701,8 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** ** Compute kG */ - kGpoint.len = 2*len + 1; - kGpoint.data = PORT_Alloc(2*len + 1); + kGpoint.len = 2*flen + 1; + kGpoint.data = PORT_Alloc(2*flen + 1); if ((kGpoint.data == NULL) || (ec_points_mul(ecParams, &k, NULL, NULL, &kGpoint) != SECSuccess)) @@ -681,7 +714,7 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** Extract the x co-ordinate of kG into x1 */ CHECK_MPI_OK( mp_read_unsigned_octets(&x1, kGpoint.data + 1, - (mp_size) len) ); + (mp_size) flen) ); /* ** ANSI X9.62, Section 5.3.3, Step 2 @@ -703,9 +736,16 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, /* ** ANSI X9.62, Section 5.3.3, Step 4 ** - ** s = (k**-1 * (SHA1(M) + d*r)) mod n + ** s = (k**-1 * (HASH(M) + d*r)) mod n */ - SECITEM_TO_MPINT(*digest, &s); /* s = SHA1(M) */ + SECITEM_TO_MPINT(*digest, &s); /* s = HASH(M) */ + + /* In the definition of EC signing, digests are truncated + * to the length of n in bits. + * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ + if (digest->len*8 > ecParams->fieldID.size) { + mpl_rsh(&s,&s,digest->len*8 - ecParams->fieldID.size); + } #if EC_DEBUG mp_todecimal(&n, mpstr); @@ -748,9 +788,10 @@ ECDSA_SignDigestWithSeed(ECPrivateKey *key, SECItem *signature, ** ** Signature is tuple (r, s) */ - CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, len) ); - CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + len, len) ); - signature->len = 2*len; + CHECK_MPI_OK( mp_to_fixlen_octets(&r, signature->data, olen) ); + CHECK_MPI_OK( mp_to_fixlen_octets(&s, signature->data + olen, olen) ); +finish: + signature->len = 2*olen; rv = SECSuccess; err = MP_OKAY; @@ -763,7 +804,7 @@ cleanup: mp_clear(&n); if (kGpoint.data) { - PORT_ZFree(kGpoint.data, 2*len + 1); + PORT_ZFree(kGpoint.data, 2*flen + 1); } if (err) { @@ -791,47 +832,26 @@ ECDSA_SignDigest(ECPrivateKey *key, SECItem *signature, const SECItem *digest) { SECStatus rv = SECFailure; #ifdef NSS_ENABLE_ECC - int prerr = 0; - int n = key->ecParams.order.len; - unsigned char *kseed = NULL; - unsigned char *mask; - int i; + int len; + unsigned char *kBytes= NULL; - /* Generate random seed of appropriate size as dictated - * by field size. - */ - if ((kseed = PORT_Alloc(n)) == NULL) return SECFailure; - - do { - if (RNG_GenerateGlobalRandomBytes(kseed, n) != SECSuccess) - goto cleanup; - /* make sure that kseed is smaller than the curve order */ - mask = key->ecParams.order.data; - for (i = 0; (i < n) && (*mask == 0x00); i++, mask++) { -#if EC_DEBUG - printf("replacing byte %02x in position %d [n=%d] with zero\n", - *(kseed + i), i, n); -#endif - *(kseed + i) = 0x00; - } + if (!key) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } - if (i == n) { - rv = SECFailure; - prerr = SEC_ERROR_NEED_RANDOM; - } else { -#if EC_DEBUG - printf("replacing byte %02x in position %d [n=%d] with %d\n", - *(kseed + i), i, n, (*mask - 1)); -#endif - if (*(kseed + i) >= *mask) - *(kseed + i) = *mask - 1; - rv = ECDSA_SignDigestWithSeed(key, signature, digest, kseed, n); - if (rv) prerr = PORT_GetError(); - } - } while ((rv != SECSuccess) && (prerr == SEC_ERROR_NEED_RANDOM)); + /* Generate random value k */ + len = key->ecParams.order.len; + kBytes = ec_GenerateRandomPrivateKey(key->ecParams.order.data, len); + if (kBytes == NULL) goto cleanup; + + /* Generate ECDSA signature with the specified k value */ + rv = ECDSA_SignDigestWithSeed(key, signature, digest, kBytes, len); cleanup: - if (kseed) PORT_ZFree(kseed, n); + if (kBytes) { + PORT_ZFree(kBytes, len); + } #if EC_DEBUG printf("ECDSA signing %s\n", @@ -855,75 +875,65 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, #ifdef NSS_ENABLE_ECC mp_int r_, s_; /* tuple (r', s') is received signature) */ mp_int c, u1, u2, v; /* intermediate values used in verification */ - mp_int x1, y1; - mp_int x2, y2; + mp_int x1; mp_int n; mp_err err = MP_OKAY; - PRArenaPool *arena = NULL; ECParams *ecParams = NULL; - SECItem pointA = { siBuffer, NULL, 0 }; - SECItem pointB = { siBuffer, NULL, 0 }; SECItem pointC = { siBuffer, NULL, 0 }; - int len; + int slen; /* length in bytes of a half signature (r or s) */ + int flen; /* length in bytes of the field size */ + unsigned olen; /* length in bytes of the base point order */ #if EC_DEBUG char mpstr[256]; printf("ECDSA verification called\n"); #endif + /* Initialize MPI integers. */ + /* must happen before the first potential call to cleanup */ + MP_DIGITS(&r_) = 0; + MP_DIGITS(&s_) = 0; + MP_DIGITS(&c) = 0; + MP_DIGITS(&u1) = 0; + MP_DIGITS(&u2) = 0; + MP_DIGITS(&x1) = 0; + MP_DIGITS(&v) = 0; + MP_DIGITS(&n) = 0; + /* Check args */ - if (!key || !signature || !digest || - (digest->len != SHA1_LENGTH)) { + if (!key || !signature || !digest) { PORT_SetError(SEC_ERROR_INVALID_ARGS); goto cleanup; } ecParams = &(key->ecParams); - len = (ecParams->fieldID.size + 7) >> 3; - if (signature->len < 2*len) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); + flen = (ecParams->fieldID.size + 7) >> 3; + olen = ecParams->order.len; + if (signature->len == 0 || signature->len%2 != 0 || + signature->len > 2*olen) { + PORT_SetError(SEC_ERROR_INPUT_LEN); goto cleanup; } + slen = signature->len/2; - /* Initialize an arena for pointA, pointB and pointC */ - if ((arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)) == NULL) + SECITEM_AllocItem(NULL, &pointC, 2*flen + 1); + if (pointC.data == NULL) goto cleanup; - SECITEM_AllocItem(arena, &pointA, 2*len + 1); - SECITEM_AllocItem(arena, &pointB, 2*len + 1); - SECITEM_AllocItem(arena, &pointC, 2*len + 1); - if (pointA.data == NULL || pointB.data == NULL || pointC.data == NULL) - goto cleanup; - - /* Initialize MPI integers. */ - MP_DIGITS(&r_) = 0; - MP_DIGITS(&s_) = 0; - MP_DIGITS(&c) = 0; - MP_DIGITS(&u1) = 0; - MP_DIGITS(&u2) = 0; - MP_DIGITS(&x1) = 0; - MP_DIGITS(&y1) = 0; - MP_DIGITS(&x2) = 0; - MP_DIGITS(&y2) = 0; - MP_DIGITS(&v) = 0; - MP_DIGITS(&n) = 0; CHECK_MPI_OK( mp_init(&r_) ); CHECK_MPI_OK( mp_init(&s_) ); CHECK_MPI_OK( mp_init(&c) ); CHECK_MPI_OK( mp_init(&u1) ); CHECK_MPI_OK( mp_init(&u2) ); CHECK_MPI_OK( mp_init(&x1) ); - CHECK_MPI_OK( mp_init(&y1) ); - CHECK_MPI_OK( mp_init(&x2) ); - CHECK_MPI_OK( mp_init(&y2) ); CHECK_MPI_OK( mp_init(&v) ); CHECK_MPI_OK( mp_init(&n) ); /* ** Convert received signature (r', s') into MPI integers. */ - CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, len) ); - CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + len, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&r_, signature->data, slen) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&s_, signature->data + slen, slen) ); /* ** ANSI X9.62, Section 5.4.2, Steps 1 and 2 @@ -932,8 +942,10 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, */ SECITEM_TO_MPINT(ecParams->order, &n); if (mp_cmp_z(&r_) <= 0 || mp_cmp_z(&s_) <= 0 || - mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) + mp_cmp(&r_, &n) >= 0 || mp_cmp(&s_, &n) >= 0) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); goto cleanup; /* will return rv == SECFailure */ + } /* ** ANSI X9.62, Section 5.4.2, Step 3 @@ -945,9 +957,16 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, /* ** ANSI X9.62, Section 5.4.2, Step 4 ** - ** u1 = ((SHA1(M')) * c) mod n + ** u1 = ((HASH(M')) * c) mod n */ - SECITEM_TO_MPINT(*digest, &u1); /* u1 = SHA1(M') */ + SECITEM_TO_MPINT(*digest, &u1); /* u1 = HASH(M) */ + + /* In the definition of EC signing, digests are truncated + * to the length of n in bits. + * (see SEC 1 "Elliptic Curve Digit Signature Algorithm" section 4.1.*/ + if (digest->len*8 > ecParams->fieldID.size) { /* u1 = HASH(M') */ + mpl_rsh(&u1,&u1,digest->len*8- ecParams->fieldID.size); + } #if EC_DEBUG mp_todecimal(&r_, mpstr); @@ -976,13 +995,18 @@ ECDSA_VerifyDigest(ECPublicKey *key, const SECItem *signature, ** Here, A = u1.G B = u2.Q and C = A + B ** If the result, C, is the point at infinity, reject the signature */ - if ((ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC) == SECFailure) || - ec_point_at_infinity(&pointC)) { - rv = SECFailure; - goto cleanup; + if (ec_points_mul(ecParams, &u1, &u2, &key->publicValue, &pointC) + != SECSuccess) { + rv = SECFailure; + goto cleanup; + } + if (ec_point_at_infinity(&pointC)) { + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); + rv = SECFailure; + goto cleanup; } - CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, len) ); + CHECK_MPI_OK( mp_read_unsigned_octets(&x1, pointC.data + 1, flen) ); /* ** ANSI X9.62, Section 5.4.4, Step 2 @@ -1028,13 +1052,10 @@ cleanup: mp_clear(&u1); mp_clear(&u2); mp_clear(&x1); - mp_clear(&y1); - mp_clear(&x2); - mp_clear(&y2); mp_clear(&v); mp_clear(&n); - if (arena) PORT_FreeArena(arena, PR_TRUE); + if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; diff --git a/security/nss/lib/freebl/ecl/Makefile b/security/nss/lib/freebl/ecl/Makefile index c791531eb..7af8d48e3 100644 --- a/security/nss/lib/freebl/ecl/Makefile +++ b/security/nss/lib/freebl/ecl/Makefile @@ -113,7 +113,7 @@ LIBOBJS = ecl.o ecl_curve.o ecl_mult.o ecl_gf.o \ ec2_163.o ec2_193.o ec2_233.o \ ecp_aff.o ecp_jac.o ecp_mont.o \ ec_naf.o ecp_jm.o \ - ecp_192.o ecp_224.o + ecp_192.o ecp_224.o ecp_256.o ecp_384.o ecp_521.o ifeq ($(ECL_USE_FP),1) LIBOBJS+= ecp_fp160.o ecp_fp192.o ecp_fp224.o ecp_fp.o endif @@ -162,6 +162,9 @@ ecp_jm.o: ecp_jm.c $(LIBHDRS) ecp_mont.o: ecp_mont.c $(LIBHDRS) ecp_192.o: ecp_192.c $(LIBHDRS) ecp_224.o: ecp_224.c $(LIBHDRS) +ecp_256.o: ecp_256.c $(LIBHDRS) +ecp_384.o: ecp_384.c $(LIBHDRS) +ecp_521.o: ecp_521.c $(LIBHDRS) ecp_fp.o: ecp_fp.c $(LIBHDRS) ifeq ($(ECL_USE_FP),1) ecp_fp160.o: ecp_fp160.c ecp_fpinc.c $(LIBHDRS) diff --git a/security/nss/lib/freebl/ecl/ec2_aff.c b/security/nss/lib/freebl/ecl/ec2_aff.c index 45b277001..64bb6fecc 100644 --- a/security/nss/lib/freebl/ecl/ec2_aff.c +++ b/security/nss/lib/freebl/ecl/ec2_aff.c @@ -312,7 +312,6 @@ ec_GF2m_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group) /* left-hand side: y^2 + x*y */ MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) ); MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) ); - MP_CHECKOK( group->meth->field_mul(&pxt, &pyt, &tmp, group->meth) ); MP_CHECKOK( group->meth->field_add(&accl, &tmp, &accl, group->meth) ); /* right-hand side: x^3 + a*x^2 + b */ MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) ); diff --git a/security/nss/lib/freebl/ecl/ecl-curve.h b/security/nss/lib/freebl/ecl/ecl-curve.h index cba22b2a7..3a01dc835 100644 --- a/security/nss/lib/freebl/ecl/ecl-curve.h +++ b/security/nss/lib/freebl/ecl/ecl-curve.h @@ -42,25 +42,10 @@ #ifndef __ecl_curve_h_ #define __ecl_curve_h_ -/* NIST prime curves */ -static const ECCurveParams ecCurve_NIST_P192 = { - "NIST-P192", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", - "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 1 -}; -static const ECCurveParams ecCurve_NIST_P224 = { - "NIST-P224", ECField_GFp, 224, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", - "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", - "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", - "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1 -}; +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#error This source file is for Basic ECC only . +#endif + static const ECCurveParams ecCurve_NIST_P256 = { "NIST-P256", ECField_GFp, 256, "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", @@ -70,6 +55,7 @@ static const ECCurveParams ecCurve_NIST_P256 = { "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 1 }; + static const ECCurveParams ecCurve_NIST_P384 = { "NIST-P384", ECField_GFp, 384, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", @@ -80,6 +66,7 @@ static const ECCurveParams ecCurve_NIST_P384 = { "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 1 }; + static const ECCurveParams ecCurve_NIST_P521 = { "NIST-P521", ECField_GFp, 521, "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", @@ -91,558 +78,67 @@ static const ECCurveParams ecCurve_NIST_P521 = { 1 }; -/* NIST binary curves */ -static const ECCurveParams ecCurve_NIST_K163 = { - "NIST-K163", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "000000000000000000000000000000000000000001", - "000000000000000000000000000000000000000001", - "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", - "0289070FB05D38FF58321F2E800536D538CCDAA3D9", - "04000000000000000000020108A2E0CC0D99F8A5EF", 2 -}; -static const ECCurveParams ecCurve_NIST_B163 = { - "NIST-B163", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "000000000000000000000000000000000000000001", - "020A601907B8C953CA1481EB10512F78744A3205FD", - "03F0EBA16286A2D57EA0991168D4994637E8343E36", - "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", - "040000000000000000000292FE77E70C12A4234C33", 2 -}; -static const ECCurveParams ecCurve_NIST_K233 = { - "NIST-K233", ECField_GF2m, 233, - "020000000000000000000000000000000000000004000000000000000001", - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", - "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", - "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 4 -}; -static const ECCurveParams ecCurve_NIST_B233 = { - "NIST-B233", ECField_GF2m, 233, - "020000000000000000000000000000000000000004000000000000000001", - "000000000000000000000000000000000000000000000000000000000001", - "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", - "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", - "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", - "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 2 -}; -static const ECCurveParams ecCurve_NIST_K283 = { - "NIST-K283", ECField_GF2m, 283, - "0800000000000000000000000000000000000000000000000000000000000000000010A1", - "000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000001", - "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", - "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", - 4 -}; -static const ECCurveParams ecCurve_NIST_B283 = { - "NIST-B283", ECField_GF2m, 283, - "0800000000000000000000000000000000000000000000000000000000000000000010A1", - "000000000000000000000000000000000000000000000000000000000000000000000001", - "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", - "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", - "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", - 2 -}; -static const ECCurveParams ecCurve_NIST_K409 = { - "NIST-K409", ECField_GF2m, 409, - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", - "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", - "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", - 4 -}; -static const ECCurveParams ecCurve_NIST_B409 = { - "NIST-B409", ECField_GF2m, 409, - "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", - "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", - "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", - "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", - "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", - 2 -}; -static const ECCurveParams ecCurve_NIST_K571 = { - "NIST-K571", ECField_GF2m, 571, - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", - "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", - "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", - 4 -}; -static const ECCurveParams ecCurve_NIST_B571 = { - "NIST-B571", ECField_GF2m, 571, - "080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", - "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", - "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", - "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", - "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", - "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", - 2 -}; - -/* ANSI X9.62 prime curves */ -static const ECCurveParams ecCurve_X9_62_PRIME_192V2 = { - "X9.62 P-192V2", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", - "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A", - "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15", - "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_192V3 = { - "X9.62 P-192V3", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", - "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", - "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896", - "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0", - "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V1 = { - "X9.62 P-239V1", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", - "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF", - "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V2 = { - "X9.62 P-239V2", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", - "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7", - "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA", - "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063", 1 -}; -static const ECCurveParams ecCurve_X9_62_PRIME_239V3 = { - "X9.62 P-239V3", ECField_GFp, 239, - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", - "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", - "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A", - "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3", - "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551", 1 -}; - -/* ANSI X9.62 binary curves */ -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V1 = { - "X9.62 C2-PNB163V1", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "072546B5435234A422E0789675F432C89435DE5242", - "00C9517D06D5240D3CFF38C74B20B6CD4D6F9DD4D9", - "07AF69989546103D79329FCC3D74880F33BBE803CB", - "01EC23211B5966ADEA1D3F87F7EA5848AEF0B7CA9F", - "0400000000000000000001E60FC8821CC74DAEAFC1", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V2 = { - "X9.62 C2-PNB163V2", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "0108B39E77C4B108BED981ED0E890E117C511CF072", - "0667ACEB38AF4E488C407433FFAE4F1C811638DF20", - "0024266E4EB5106D0A964D92C4860E2671DB9B6CC5", - "079F684DDF6684C5CD258B3890021B2386DFD19FC5", - "03FFFFFFFFFFFFFFFFFFFDF64DE1151ADBB78F10A7", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB163V3 = { - "X9.62 C2-PNB163V3", ECField_GF2m, 163, - "080000000000000000000000000000000000000107", - "07A526C63D3E25A256A007699F5447E32AE456B50E", - "03F7061798EB99E238FD6F1BF95B48FEEB4854252B", - "02F9F87B7C574D0BDECF8A22E6524775F98CDEBDCB", - "05B935590C155E17EA48EB3FF3718B893DF59A05D0", - "03FFFFFFFFFFFFFFFFFFFE1AEE140F110AFF961309", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB176V1 = { - "X9.62 C2-PNB176V1", ECField_GF2m, 176, - "0100000000000000000000000000000000080000000007", - "E4E6DB2995065C407D9D39B8D0967B96704BA8E9C90B", - "5DDA470ABE6414DE8EC133AE28E9BBD7FCEC0AE0FFF2", - "8D16C2866798B600F9F08BB4A8E860F3298CE04A5798", - "6FA4539C2DADDDD6BAB5167D61B436E1D92BB16A562C", - "00010092537397ECA4F6145799D62B0A19CE06FE26AD", 0xFF6E -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V1 = { - "X9.62 C2-TNB191V1", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "2866537B676752636A68F56554E12640276B649EF7526267", - "2E45EF571F00786F67B0081B9495A3D95462F5DE0AA185EC", - "36B3DAF8A23206F9C4F299D7B21A9C369137F2C84AE1AA0D", - "765BE73433B3F95E332932E70EA245CA2418EA0EF98018FB", - "40000000000000000000000004A20E90C39067C893BBB9A5", 2 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V2 = { - "X9.62 C2-TNB191V2", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "401028774D7777C7B7666D1366EA432071274F89FF01E718", - "0620048D28BCBD03B6249C99182B7C8CD19700C362C46A01", - "3809B2B7CC1B28CC5A87926AAD83FD28789E81E2C9E3BF10", - "17434386626D14F3DBF01760D9213A3E1CF37AEC437D668A", - "20000000000000000000000050508CB89F652824E06B8173", 4 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB191V3 = { - "X9.62 C2-TNB191V3", ECField_GF2m, 191, - "800000000000000000000000000000000000000000000201", - "6C01074756099122221056911C77D77E77A777E7E7E77FCB", - "71FE1AF926CF847989EFEF8DB459F66394D90F32AD3F15E8", - "375D4CE24FDE434489DE8746E71786015009E66E38A926DD", - "545A39176196575D985999366E6AD34CE0A77CD7127B06BE", - "155555555555555555555555610C0B196812BFB6288A3EA3", 6 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB208W1 = { - "X9.62 C2-PNB208W1", ECField_GF2m, 208, - "010000000000000000000000000000000800000000000000000007", - "0000000000000000000000000000000000000000000000000000", - "C8619ED45A62E6212E1160349E2BFA844439FAFC2A3FD1638F9E", - "89FDFBE4ABE193DF9559ECF07AC0CE78554E2784EB8C1ED1A57A", - "0F55B51A06E78E9AC38A035FF520D8B01781BEB1A6BB08617DE3", - "000101BAF95C9723C57B6C21DA2EFF2D5ED588BDD5717E212F9D", 0xFE48 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V1 = { - "X9.62 C2-TNB239V1", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "32010857077C5431123A46B808906756F543423E8D27877578125778AC76", - "790408F2EEDAF392B012EDEFB3392F30F4327C0CA3F31FC383C422AA8C16", - "57927098FA932E7C0A96D3FD5B706EF7E5F5C156E16B7E7C86038552E91D", - "61D8EE5077C33FECF6F1A16B268DE469C3C7744EA9A971649FC7A9616305", - "2000000000000000000000000000000F4D42FFE1492A4993F1CAD666E447", 4 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V2 = { - "X9.62 C2-TNB239V2", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "4230017757A767FAE42398569B746325D45313AF0766266479B75654E65F", - "5037EA654196CFF0CD82B2C14A2FCF2E3FF8775285B545722F03EACDB74B", - "28F9D04E900069C8DC47A08534FE76D2B900B7D7EF31F5709F200C4CA205", - "5667334C45AFF3B5A03BAD9DD75E2C71A99362567D5453F7FA6E227EC833", - "1555555555555555555555555555553C6F2885259C31E3FCDF154624522D", 6 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB239V3 = { - "X9.62 C2-TNB239V3", ECField_GF2m, 239, - "800000000000000000000000000000000000000000000000001000000001", - "01238774666A67766D6676F778E676B66999176666E687666D8766C66A9F", - "6A941977BA9F6A435199ACFC51067ED587F519C5ECB541B8E44111DE1D40", - "70F6E9D04D289C4E89913CE3530BFDE903977D42B146D539BF1BDE4E9C92", - "2E5A0EAF6E5E1305B9004DCE5C0ED7FE59A35608F33837C816D80B79F461", - "0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCAC4912D2D9DF903EF9888B8A0E4CFF", 0xA -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB272W1 = { - "X9.62 C2-PNB272W1", ECField_GF2m, 272, - "010000000000000000000000000000000000000000000000000000010000000000000B", - "91A091F03B5FBA4AB2CCF49C4EDD220FB028712D42BE752B2C40094DBACDB586FB20", - "7167EFC92BB2E3CE7C8AAAFF34E12A9C557003D7C73A6FAF003F99F6CC8482E540F7", - "6108BABB2CEEBCF787058A056CBE0CFE622D7723A289E08A07AE13EF0D10D171DD8D", - "10C7695716851EEF6BA7F6872E6142FBD241B830FF5EFCACECCAB05E02005DDE9D23", - "000100FAF51354E0E39E4892DF6E319C72C8161603FA45AA7B998A167B8F1E629521", - 0xFF06 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB304W1 = { - "X9.62 C2-PNB304W1", ECField_GF2m, 304, - "010000000000000000000000000000000000000000000000000000000000000000000000000807", - "FD0D693149A118F651E6DCE6802085377E5F882D1B510B44160074C1288078365A0396C8E681", - "BDDB97E555A50A908E43B01C798EA5DAA6788F1EA2794EFCF57166B8C14039601E55827340BE", - "197B07845E9BE2D96ADB0F5F3C7F2CFFBD7A3EB8B6FEC35C7FD67F26DDF6285A644F740A2614", - "E19FBEB76E0DA171517ECF401B50289BF014103288527A9B416A105E80260B549FDC1B92C03B", - "000101D556572AABAC800101D556572AABAC8001022D5C91DD173F8FB561DA6899164443051D", - 0xFE2E -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB359V1 = { - "X9.62 C2-TNB359V1", ECField_GF2m, 359, - "800000000000000000000000000000000000000000000000000000000000000000000000100000000000000001", - "5667676A654B20754F356EA92017D946567C46675556F19556A04616B567D223A5E05656FB549016A96656A557", - "2472E2D0197C49363F1FE7F5B6DB075D52B6947D135D8CA445805D39BC345626089687742B6329E70680231988", - "3C258EF3047767E7EDE0F1FDAA79DAEE3841366A132E163ACED4ED2401DF9C6BDCDE98E8E707C07A2239B1B097", - "53D7E08529547048121E9C95F3791DD804963948F34FAE7BF44EA82365DC7868FE57E4AE2DE211305A407104BD", - "01AF286BCA1AF286BCA1AF286BCA1AF286BCA1AF286BC9FB8F6B85C556892C20A7EB964FE7719E74F490758D3B", - 0x4C -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_PNB368W1 = { - "X9.62 C2-PNB368W1", ECField_GF2m, 368, - "0100000000000000000000000000000000000000000000000000000000000000000000002000000000000000000007", - "E0D2EE25095206F5E2A4F9ED229F1F256E79A0E2B455970D8D0D865BD94778C576D62F0AB7519CCD2A1A906AE30D", - "FC1217D4320A90452C760A58EDCD30C8DD069B3C34453837A34ED50CB54917E1C2112D84D164F444F8F74786046A", - "1085E2755381DCCCE3C1557AFA10C2F0C0C2825646C5B34A394CBCFA8BC16B22E7E789E927BE216F02E1FB136A5F", - "7B3EB1BDDCBA62D5D8B2059B525797FC73822C59059C623A45FF3843CEE8F87CD1855ADAA81E2A0750B80FDA2310", - "00010090512DA9AF72B08349D98A5DD4C7B0532ECA51CE03E2D10F3B7AC579BD87E909AE40A6F131E9CFCE5BD967", - 0xFF70 -}; -static const ECCurveParams ecCurve_X9_62_CHAR2_TNB431R1 = { - "X9.62 C2-TNB431R1", ECField_GF2m, 431, - "800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001", - "1A827EF00DD6FC0E234CAF046C6A5D8A85395B236CC4AD2CF32A0CADBDC9DDF620B0EB9906D0957F6C6FEACD615468DF104DE296CD8F", - "10D9B4A3D9047D8B154359ABFB1B7F5485B04CEB868237DDC9DEDA982A679A5A919B626D4E50A8DD731B107A9962381FB5D807BF2618", - "120FC05D3C67A99DE161D2F4092622FECA701BE4F50F4758714E8A87BBF2A658EF8C21E7C5EFE965361F6C2999C0C247B0DBD70CE6B7", - "20D0AF8903A96F8D5FA2C255745D3C451B302C9346D9B7E485E7BCE41F6B591F3E8F6ADDCBB0BC4C2F947A7DE1A89B625D6A598B3760", - "0340340340340340340340340340340340340340340340340340340323C313FAB50589703B5EC68D3587FEC60D161CC149C1AD4A91", - 0x2760 -}; - -/* SEC2 prime curves */ -static const ECCurveParams ecCurve_SECG_PRIME_112R1 = { - "SECP-112R1", ECField_GFp, 112, - "DB7C2ABF62E35E668076BEAD208B", - "DB7C2ABF62E35E668076BEAD2088", - "659EF8BA043916EEDE8911702B22", - "09487239995A5EE76B55F9C2F098", - "A89CE5AF8724C0A23E0E0FF77500", - "DB7C2ABF62E35E7628DFAC6561C5", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_112R2 = { - "SECP-112R2", ECField_GFp, 112, - "DB7C2ABF62E35E668076BEAD208B", - "6127C24C05F38A0AAAF65C0EF02C", - "51DEF1815DB5ED74FCC34C85D709", - "4BA30AB5E892B4E1649DD0928643", - "adcd46f5882e3747def36e956e97", - "36DF0AAFD8B8D7597CA10520D04B", 4 -}; -static const ECCurveParams ecCurve_SECG_PRIME_128R1 = { - "SECP-128R1", ECField_GFp, 128, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", - "E87579C11079F43DD824993C2CEE5ED3", - "161FF7528B899B2D0C28607CA52C5B86", - "CF5AC8395BAFEB13C02DA292DDED7A83", - "FFFFFFFE0000000075A30D1B9038A115", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_128R2 = { - "SECP-128R2", ECField_GFp, 128, - "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", - "D6031998D1B3BBFEBF59CC9BBFF9AEE1", - "5EEEFCA380D02919DC2C6558BB6D8A5D", - "7B6AA5D85E572983E6FB32A7CDEBC140", - "27B6916A894D3AEE7106FE805FC34B44", - "3FFFFFFF7FFFFFFFBE0024720613B5A3", 4 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160K1 = { - "SECP-160K1", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000007", - "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", - "938CF935318FDCED6BC28286531733C3F03C4FEE", - "0100000000000000000001B8FA16DFAB9ACA16B6B3", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160R1 = { - "SECP-160R1", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", - "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", - "4A96B5688EF573284664698968C38BB913CBFC82", - "23A628553168947D59DCC912042351377AC5FB32", - "0100000000000000000001F4C8F927AED3CA752257", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_160R2 = { - "SECP-160R2", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", - "B4E134D3FB59EB8BAB57274904664D5AF50388BA", - "52DCB034293A117E1F4FF11B30F7199D3144CE6D", - "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", - "0100000000000000000000351EE786A818F3A1A16B", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_192K1 = { - "SECP-192K1", ECField_GFp, 192, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", - "000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000003", - "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", - "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", - "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_224K1 = { - "SECP-224K1", ECField_GFp, 224, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", - "00000000000000000000000000000000000000000000000000000000", - "00000000000000000000000000000000000000000000000000000005", - "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", - "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", - "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 1 -}; -static const ECCurveParams ecCurve_SECG_PRIME_256K1 = { - "SECP-256K1", ECField_GFp, 256, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0000000000000000000000000000000000000000000000000000000000000000", - "0000000000000000000000000000000000000000000000000000000000000007", - "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 1 -}; - -/* SEC2 binary curves */ -static const ECCurveParams ecCurve_SECG_CHAR2_113R1 = { - "SECT-113R1", ECField_GF2m, 113, - "020000000000000000000000000201", - "003088250CA6E7C7FE649CE85820F7", - "00E8BEE4D3E2260744188BE0E9C723", - "009D73616F35F4AB1407D73562C10F", - "00A52830277958EE84D1315ED31886", - "0100000000000000D9CCEC8A39E56F", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_113R2 = { - "SECT-113R2", ECField_GF2m, 113, - "020000000000000000000000000201", - "00689918DBEC7E5A0DD6DFC0AA55C7", - "0095E9A9EC9B297BD4BF36E059184F", - "01A57A6A7B26CA5EF52FCDB8164797", - "00B3ADC94ED1FE674C06E695BABA1D", - "010000000000000108789B2496AF93", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_131R1 = { - "SECT-131R1", ECField_GF2m, 131, - "080000000000000000000000000000010D", - "07A11B09A76B562144418FF3FF8C2570B8", - "0217C05610884B63B9C6C7291678F9D341", - "0081BAF91FDF9833C40F9C181343638399", - "078C6E7EA38C001F73C8134B1B4EF9E150", - "0400000000000000023123953A9464B54D", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_131R2 = { - "SECT-131R2", ECField_GF2m, 131, - "080000000000000000000000000000010D", - "03E5A88919D7CAFCBF415F07C2176573B2", - "04B8266A46C55657AC734CE38F018F2192", - "0356DCD8F2F95031AD652D23951BB366A8", - "0648F06D867940A5366D9E265DE9EB240F", - "0400000000000000016954A233049BA98F", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_163R1 = { - "SECT-163R1", ECField_GF2m, 163, - "0800000000000000000000000000000000000000C9", - "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", - "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", - "0369979697AB43897789566789567F787A7876A654", - "00435EDB42EFAFB2989D51FEFCE3C80988F41FF883", - "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_193R1 = { - "SECT-193R1", ECField_GF2m, 193, - "02000000000000000000000000000000000000000000008001", - "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", - "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", - "01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1", - "0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", - "01000000000000000000000000C7F34A778F443ACC920EBA49", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_193R2 = { - "SECT-193R2", ECField_GF2m, 193, - "02000000000000000000000000000000000000000000008001", - "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", - "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", - "00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F", - "01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", - "010000000000000000000000015AAB561B005413CCD4EE99D5", 2 -}; -static const ECCurveParams ecCurve_SECG_CHAR2_239K1 = { - "SECT-239K1", ECField_GF2m, 239, - "800000000000000000004000000000000000000000000000000000000001", - "000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000001", - "29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC", - "76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", - "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", 4 -}; - -/* WTLS curves */ -static const ECCurveParams ecCurve_WTLS_1 = { - "WTLS-1", ECField_GF2m, 113, - "020000000000000000000000000201", - "000000000000000000000000000001", - "000000000000000000000000000001", - "01667979A40BA497E5D5C270780617", - "00F44B4AF1ECC2630E08785CEBCC15", - "00FFFFFFFFFFFFFFFDBF91AF6DEA73", 2 -}; -static const ECCurveParams ecCurve_WTLS_8 = { - "WTLS-8", ECField_GFp, 112, - "FFFFFFFFFFFFFFFFFFFFFFFFFDE7", - "0000000000000000000000000000", - "0000000000000000000000000003", - "0000000000000000000000000001", - "0000000000000000000000000002", - "0100000000000001ECEA551AD837E9", 1 -}; -static const ECCurveParams ecCurve_WTLS_9 = { - "WTLS-9", ECField_GFp, 160, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F", - "0000000000000000000000000000000000000000", - "0000000000000000000000000000000000000003", - "0000000000000000000000000000000000000001", - "0000000000000000000000000000000000000002", - "0100000000000000000001CDC98AE0E2DE574ABF33", 1 -}; - /* mapping between ECCurveName enum and pointers to ECCurveParams */ static const ECCurveParams *ecCurve_map[] = { - NULL, /* ECCurve_noName */ - &ecCurve_NIST_P192, /* ECCurve_NIST_P192 */ - &ecCurve_NIST_P224, /* ECCurve_NIST_P224 */ - &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */ - &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */ - &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */ - &ecCurve_NIST_K163, /* ECCurve_NIST_K163 */ - &ecCurve_NIST_B163, /* ECCurve_NIST_B163 */ - &ecCurve_NIST_K233, /* ECCurve_NIST_K233 */ - &ecCurve_NIST_B233, /* ECCurve_NIST_B233 */ - &ecCurve_NIST_K283, /* ECCurve_NIST_K283 */ - &ecCurve_NIST_B283, /* ECCurve_NIST_B283 */ - &ecCurve_NIST_K409, /* ECCurve_NIST_K409 */ - &ecCurve_NIST_B409, /* ECCurve_NIST_B409 */ - &ecCurve_NIST_K571, /* ECCurve_NIST_K571 */ - &ecCurve_NIST_B571, /* ECCurve_NIST_B571 */ - &ecCurve_X9_62_PRIME_192V2, /* ECCurve_X9_62_PRIME_192V2 */ - &ecCurve_X9_62_PRIME_192V3, /* ECCurve_X9_62_PRIME_192V3 */ - &ecCurve_X9_62_PRIME_239V1, /* ECCurve_X9_62_PRIME_239V1 */ - &ecCurve_X9_62_PRIME_239V2, /* ECCurve_X9_62_PRIME_239V2 */ - &ecCurve_X9_62_PRIME_239V3, /* ECCurve_X9_62_PRIME_239V3 */ - &ecCurve_X9_62_CHAR2_PNB163V1, /* ECCurve_X9_62_CHAR2_PNB163V1 */ - &ecCurve_X9_62_CHAR2_PNB163V2, /* ECCurve_X9_62_CHAR2_PNB163V2 */ - &ecCurve_X9_62_CHAR2_PNB163V3, /* ECCurve_X9_62_CHAR2_PNB163V3 */ - &ecCurve_X9_62_CHAR2_PNB176V1, /* ECCurve_X9_62_CHAR2_PNB176V1 */ - &ecCurve_X9_62_CHAR2_TNB191V1, /* ECCurve_X9_62_CHAR2_TNB191V1 */ - &ecCurve_X9_62_CHAR2_TNB191V2, /* ECCurve_X9_62_CHAR2_TNB191V2 */ - &ecCurve_X9_62_CHAR2_TNB191V3, /* ECCurve_X9_62_CHAR2_TNB191V3 */ - &ecCurve_X9_62_CHAR2_PNB208W1, /* ECCurve_X9_62_CHAR2_PNB208W1 */ - &ecCurve_X9_62_CHAR2_TNB239V1, /* ECCurve_X9_62_CHAR2_TNB239V1 */ - &ecCurve_X9_62_CHAR2_TNB239V2, /* ECCurve_X9_62_CHAR2_TNB239V2 */ - &ecCurve_X9_62_CHAR2_TNB239V3, /* ECCurve_X9_62_CHAR2_TNB239V3 */ - &ecCurve_X9_62_CHAR2_PNB272W1, /* ECCurve_X9_62_CHAR2_PNB272W1 */ - &ecCurve_X9_62_CHAR2_PNB304W1, /* ECCurve_X9_62_CHAR2_PNB304W1 */ - &ecCurve_X9_62_CHAR2_TNB359V1, /* ECCurve_X9_62_CHAR2_TNB359V1 */ - &ecCurve_X9_62_CHAR2_PNB368W1, /* ECCurve_X9_62_CHAR2_PNB368W1 */ - &ecCurve_X9_62_CHAR2_TNB431R1, /* ECCurve_X9_62_CHAR2_TNB431R1 */ - &ecCurve_SECG_PRIME_112R1, /* ECCurve_SECG_PRIME_112R1 */ - &ecCurve_SECG_PRIME_112R2, /* ECCurve_SECG_PRIME_112R2 */ - &ecCurve_SECG_PRIME_128R1, /* ECCurve_SECG_PRIME_128R1 */ - &ecCurve_SECG_PRIME_128R2, /* ECCurve_SECG_PRIME_128R2 */ - &ecCurve_SECG_PRIME_160K1, /* ECCurve_SECG_PRIME_160K1 */ - &ecCurve_SECG_PRIME_160R1, /* ECCurve_SECG_PRIME_160R1 */ - &ecCurve_SECG_PRIME_160R2, /* ECCurve_SECG_PRIME_160R2 */ - &ecCurve_SECG_PRIME_192K1, /* ECCurve_SECG_PRIME_192K1 */ - &ecCurve_SECG_PRIME_224K1, /* ECCurve_SECG_PRIME_224K1 */ - &ecCurve_SECG_PRIME_256K1, /* ECCurve_SECG_PRIME_256K1 */ - &ecCurve_SECG_CHAR2_113R1, /* ECCurve_SECG_CHAR2_113R1 */ - &ecCurve_SECG_CHAR2_113R2, /* ECCurve_SECG_CHAR2_113R2 */ - &ecCurve_SECG_CHAR2_131R1, /* ECCurve_SECG_CHAR2_131R1 */ - &ecCurve_SECG_CHAR2_131R2, /* ECCurve_SECG_CHAR2_131R2 */ - &ecCurve_SECG_CHAR2_163R1, /* ECCurve_SECG_CHAR2_163R1 */ - &ecCurve_SECG_CHAR2_193R1, /* ECCurve_SECG_CHAR2_193R1 */ - &ecCurve_SECG_CHAR2_193R2, /* ECCurve_SECG_CHAR2_193R2 */ - &ecCurve_SECG_CHAR2_239K1, /* ECCurve_SECG_CHAR2_239K1 */ - &ecCurve_WTLS_1, /* ECCurve_WTLS_1 */ - &ecCurve_WTLS_8, /* ECCurve_WTLS_8 */ - &ecCurve_WTLS_9, /* ECCurve_WTLS_9 */ - NULL /* ECCurve_pastLastCurve */ + NULL, /* ECCurve_noName */ + NULL, /* ECCurve_NIST_P192 */ + NULL, /* ECCurve_NIST_P224 */ + &ecCurve_NIST_P256, /* ECCurve_NIST_P256 */ + &ecCurve_NIST_P384, /* ECCurve_NIST_P384 */ + &ecCurve_NIST_P521, /* ECCurve_NIST_P521 */ + NULL, /* ECCurve_NIST_K163 */ + NULL, /* ECCurve_NIST_B163 */ + NULL, /* ECCurve_NIST_K233 */ + NULL, /* ECCurve_NIST_B233 */ + NULL, /* ECCurve_NIST_K283 */ + NULL, /* ECCurve_NIST_B283 */ + NULL, /* ECCurve_NIST_K409 */ + NULL, /* ECCurve_NIST_B409 */ + NULL, /* ECCurve_NIST_K571 */ + NULL, /* ECCurve_NIST_B571 */ + NULL, /* ECCurve_X9_62_PRIME_192V2 */ + NULL, /* ECCurve_X9_62_PRIME_192V3 */ + NULL, /* ECCurve_X9_62_PRIME_239V1 */ + NULL, /* ECCurve_X9_62_PRIME_239V2 */ + NULL, /* ECCurve_X9_62_PRIME_239V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V2 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB163V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB176V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V2 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB191V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB208W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V2 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB239V3 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB272W1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB304W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB359V1 */ + NULL, /* ECCurve_X9_62_CHAR2_PNB368W1 */ + NULL, /* ECCurve_X9_62_CHAR2_TNB431R1 */ + NULL, /* ECCurve_SECG_PRIME_112R1 */ + NULL, /* ECCurve_SECG_PRIME_112R2 */ + NULL, /* ECCurve_SECG_PRIME_128R1 */ + NULL, /* ECCurve_SECG_PRIME_128R2 */ + NULL, /* ECCurve_SECG_PRIME_160K1 */ + NULL, /* ECCurve_SECG_PRIME_160R1 */ + NULL, /* ECCurve_SECG_PRIME_160R2 */ + NULL, /* ECCurve_SECG_PRIME_192K1 */ + NULL, /* ECCurve_SECG_PRIME_224K1 */ + NULL, /* ECCurve_SECG_PRIME_256K1 */ + NULL, /* ECCurve_SECG_CHAR2_113R1 */ + NULL, /* ECCurve_SECG_CHAR2_113R2 */ + NULL, /* ECCurve_SECG_CHAR2_131R1 */ + NULL, /* ECCurve_SECG_CHAR2_131R2 */ + NULL, /* ECCurve_SECG_CHAR2_163R1 */ + NULL, /* ECCurve_SECG_CHAR2_193R1 */ + NULL, /* ECCurve_SECG_CHAR2_193R2 */ + NULL, /* ECCurve_SECG_CHAR2_239K1 */ + NULL, /* ECCurve_WTLS_1 */ + NULL, /* ECCurve_WTLS_8 */ + NULL, /* ECCurve_WTLS_9 */ + NULL /* ECCurve_pastLastCurve */ }; #endif diff --git a/security/nss/lib/freebl/ecl/ecl-priv.h b/security/nss/lib/freebl/ecl/ecl-priv.h index bce7ccf09..05abb4dff 100644 --- a/security/nss/lib/freebl/ecl/ecl-priv.h +++ b/security/nss/lib/freebl/ecl/ecl-priv.h @@ -45,22 +45,62 @@ #include "mplogic.h" /* MAX_FIELD_SIZE_DIGITS is the maximum size of field element supported */ +/* the following needs to go away... */ #if defined(MP_USE_LONG_LONG_DIGIT) || defined(MP_USE_LONG_DIGIT) #define ECL_SIXTY_FOUR_BIT -#define ECL_BITS 64 -#define ECL_MAX_FIELD_SIZE_DIGITS 10 #else #define ECL_THIRTY_TWO_BIT -#define ECL_BITS 32 -#define ECL_MAX_FIELD_SIZE_DIGITS 20 #endif +#define ECL_CURVE_DIGITS(curve_size_in_bits) \ + (((curve_size_in_bits)+(sizeof(mp_digit)*8-1))/(sizeof(mp_digit)*8)) +#define ECL_BITS (sizeof(mp_digit)*8) +#define ECL_MAX_FIELD_SIZE_DIGITS (80/sizeof(mp_digit)) + /* Gets the i'th bit in the binary representation of a. If i >= length(a), * then return 0. (The above behaviour differs from mpl_get_bit, which * causes an error if i >= length(a).) */ #define MP_GET_BIT(a, i) \ ((i) >= mpl_significant_bits((a))) ? 0 : mpl_get_bit((a), (i)) +#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD) +#define MP_ADD_CARRY(a1, a2, s, cin, cout) \ + { mp_word w; \ + w = ((mp_word)(cin)) + (a1) + (a2); \ + s = ACCUM(w); \ + cout = CARRYOUT(w); } + +#define MP_SUB_BORROW(a1, a2, s, bin, bout) \ + { mp_word w; \ + w = ((mp_word)(a1)) - (a2) - (bin); \ + s = ACCUM(w); \ + bout = (w >> MP_DIGIT_BIT) & 1; } + +#else +/* NOTE, + * cin and cout could be the same variable. + * bin and bout could be the same variable. + * a1 or a2 and s could be the same variable. + * don't trash those outputs until their respective inputs have + * been read. */ +#define MP_ADD_CARRY(a1, a2, s, cin, cout) \ + { mp_digit tmp,sum; \ + tmp = (a1); \ + sum = tmp + (a2); \ + tmp = (sum < tmp); /* detect overflow */ \ + s = sum += (cin); \ + cout = tmp + (sum < (cin)); } + +#define MP_SUB_BORROW(a1, a2, s, bin, bout) \ + { mp_digit tmp; \ + tmp = (a1); \ + s = tmp - (a2); \ + tmp = (s > tmp); /* detect borrow */ \ + if ((bin) && !s--) tmp++; \ + bout = tmp; } +#endif + + struct GFMethodStr; typedef struct GFMethodStr GFMethod; struct GFMethodStr { @@ -158,6 +198,25 @@ mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r, mp_err ec_GFp_neg(const mp_int *a, mp_int *r, const GFMethod *meth); mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth); + +/* fixed length in-line adds. Count is in words */ +mp_err ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); +mp_err ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth); + mp_err ec_GFp_mod(const mp_int *a, mp_int *r, const GFMethod *meth); mp_err ec_GFp_mul(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth); @@ -205,6 +264,9 @@ mp_err ec_compute_wNAF(signed char *out, int bitsize, const mp_int *in, /* Optimized field arithmetic */ mp_err ec_group_set_gfp192(ECGroup *group, ECCurveName); mp_err ec_group_set_gfp224(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp256(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp384(ECGroup *group, ECCurveName); +mp_err ec_group_set_gfp521(ECGroup *group, ECCurveName); mp_err ec_group_set_gf2m163(ECGroup *group, ECCurveName name); mp_err ec_group_set_gf2m193(ECGroup *group, ECCurveName name); mp_err ec_group_set_gf2m233(ECGroup *group, ECCurveName name); diff --git a/security/nss/lib/freebl/ecl/ecl.c b/security/nss/lib/freebl/ecl/ecl.c index 520755f6a..4521e5b57 100644 --- a/security/nss/lib/freebl/ecl/ecl.c +++ b/security/nss/lib/freebl/ecl/ecl.c @@ -55,23 +55,24 @@ ECGroup_new() if (group == NULL) return NULL; group->constructed = MP_YES; + group->meth = NULL; group->text = NULL; MP_DIGITS(&group->curvea) = 0; MP_DIGITS(&group->curveb) = 0; MP_DIGITS(&group->genx) = 0; MP_DIGITS(&group->geny) = 0; MP_DIGITS(&group->order) = 0; - MP_CHECKOK(mp_init(&group->curvea)); - MP_CHECKOK(mp_init(&group->curveb)); - MP_CHECKOK(mp_init(&group->genx)); - MP_CHECKOK(mp_init(&group->geny)); - MP_CHECKOK(mp_init(&group->order)); group->base_point_mul = NULL; group->points_mul = NULL; group->validate_point = NULL; group->extra1 = NULL; group->extra2 = NULL; group->extra_free = NULL; + MP_CHECKOK(mp_init(&group->curvea)); + MP_CHECKOK(mp_init(&group->curveb)); + MP_CHECKOK(mp_init(&group->genx)); + MP_CHECKOK(mp_init(&group->geny)); + MP_CHECKOK(mp_init(&group->order)); CLEANUP: if (res != MP_OKAY) { @@ -164,6 +165,7 @@ ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea, return group; } +#ifdef NSS_ECC_MORE_THAN_SUITE_B /* Construct a generic ECGroup for elliptic curves over binary polynomial * fields. */ ECGroup * @@ -205,13 +207,7 @@ ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5], } return group; } - -/* Helper macros for ecgroup_fromNameAndHex. */ -#define CHECK_GROUP \ - if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } -#define CONS_GF2M \ - group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); \ - CHECK_GROUP +#endif /* Construct ECGroup from hex parameters and name, if any. Called by * ECGroup_fromHex and ECGroup_fromName. */ @@ -253,82 +249,85 @@ ecgroup_fromNameAndHex(const ECCurveName name, /* determine which optimizations (if any) to use */ if (params->field == ECField_GFp) { - if ((name == ECCurve_SECG_PRIME_160K1) - || (name == ECCurve_SECG_PRIME_160R2)) { +#ifdef NSS_ECC_MORE_THAN_SUITE_B + switch (name) { +#ifdef ECL_USE_FP + case ECCurve_SECG_PRIME_160R1: group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - } else if ((name == ECCurve_SECG_PRIME_160R1)) { + ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, + &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_secp160r1_fp(group)); + break; +#endif + case ECCurve_SECG_PRIME_192R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_secp160r1_fp(group)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_nistp192_fp(group)); #else group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); + ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, + &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp192(group, name)); #endif - } else if ((name == ECCurve_SECG_PRIME_192K1)) { - group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name)); - } else if ((name == ECCurve_SECG_PRIME_192R1)) { + break; + case ECCurve_SECG_PRIME_224R1: #ifdef ECL_USE_FP group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_nistp192_fp(group)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_nistp224_fp(group)); #else group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp192(group, name)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp224(group, name)); #endif - } else if ((name == ECCurve_SECG_PRIME_224K1)) { - group = - ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, - &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name)); - } else if ((name == ECCurve_SECG_PRIME_224R1)) { -#ifdef ECL_USE_FP + break; + case ECCurve_SECG_PRIME_256R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_nistp224_fp(group)); -#else + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp256(group, name)); + break; + case ECCurve_SECG_PRIME_521R1: group = ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP MP_CHECKOK(ec_group_set_gfp224(group, name)); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + MP_CHECKOK(ec_group_set_gfp521(group, name)); + break; + default: + /* use generic arithmetic */ #endif - } else { group = ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny, &order, params->cofactor); - CHECK_GROUP} - /* XXX secp521r1 fails ecp_test with &ec_GFp_pts_mul_jac */ - if (name == ECCurve_SECG_PRIME_521R1) { - group->points_mul = &ec_pts_mul_simul_w2; + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } +#ifdef NSS_ECC_MORE_THAN_SUITE_B } } else if (params->field == ECField_GF2m) { - switch (bits) { - case 163: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m163(group, name)); - break; - case 193: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m193(group, name)); - break; - case 233: - CONS_GF2M MP_CHECKOK(ec_group_set_gf2m233(group, name)); - break; - default: - group = - ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, - &geny, &order, params->cofactor); - CHECK_GROUP break; + group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor); + if (group == NULL) { res = MP_UNDEF; goto CLEANUP; } + if ((name == ECCurve_NIST_K163) || + (name == ECCurve_NIST_B163) || + (name == ECCurve_SECG_CHAR2_163R1)) { + MP_CHECKOK(ec_group_set_gf2m163(group, name)); + } else if ((name == ECCurve_SECG_CHAR2_193R1) || + (name == ECCurve_SECG_CHAR2_193R2)) { + MP_CHECKOK(ec_group_set_gf2m193(group, name)); + } else if ((name == ECCurve_NIST_K233) || + (name == ECCurve_NIST_B233)) { + MP_CHECKOK(ec_group_set_gf2m233(group, name)); } +#endif } /* set name, if any */ @@ -353,10 +352,6 @@ ecgroup_fromNameAndHex(const ECCurveName name, return group; } -#undef CHECK_GROUP -#undef CONS_GFP -#undef CONS_GF2M - /* Construct ECGroup from hexadecimal representations of parameters. */ ECGroup * ECGroup_fromHex(const ECCurveParams * params) @@ -418,6 +413,11 @@ ECGroup_free(ECGroup *group) GFMethod_free(group->meth); if (group->constructed == MP_NO) return; + mp_clear(&group->curvea); + mp_clear(&group->curveb); + mp_clear(&group->genx); + mp_clear(&group->geny); + mp_clear(&group->order); if (group->text != NULL) free(group->text); if (group->extra_free != NULL) diff --git a/security/nss/lib/freebl/ecl/ecl_curve.c b/security/nss/lib/freebl/ecl/ecl_curve.c index b0a7d5074..a0a7bd316 100644 --- a/security/nss/lib/freebl/ecl/ecl_curve.c +++ b/security/nss/lib/freebl/ecl/ecl_curve.c @@ -51,7 +51,7 @@ ECCurveParams_dup(const ECCurveParams * params) int res = 1; ECCurveParams *ret = NULL; - CHECK(ret = (ECCurveParams *) malloc(sizeof(ECCurveParams))); + CHECK(ret = (ECCurveParams *) calloc(1, sizeof(ECCurveParams))); if (params->text != NULL) { CHECK(ret->text = strdup(params->text)); } @@ -91,7 +91,8 @@ ECCurveParams_dup(const ECCurveParams * params) ECCurveParams * EC_GetNamedCurveParams(const ECCurveName name) { - if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name)) { + if ((name <= ECCurve_noName) || (ECCurve_pastLastCurve <= name) || + (ecCurve_map[name] == NULL)) { return NULL; } else { return ECCurveParams_dup(ecCurve_map[name]); diff --git a/security/nss/lib/freebl/ecl/ecl_gf.c b/security/nss/lib/freebl/ecl/ecl_gf.c index 9ee3bb6ac..08fa0c3e0 100644 --- a/security/nss/lib/freebl/ecl/ecl_gf.c +++ b/security/nss/lib/freebl/ecl/ecl_gf.c @@ -40,6 +40,7 @@ #include "mpi.h" #include "mp_gf2m.h" #include "ecl-priv.h" +#include "mpi-priv.h" #include <stdlib.h> /* Allocate memory for a new GFMethod object. */ @@ -52,8 +53,9 @@ GFMethod_new() if (meth == NULL) return NULL; meth->constructed = MP_YES; - MP_CHECKOK(mp_init(&meth->irr)); + MP_DIGITS(&meth->irr) = 0; meth->extra_free = NULL; + MP_CHECKOK(mp_init(&meth->irr)); CLEANUP: if (res != MP_OKAY) { @@ -79,9 +81,29 @@ GFMethod_consGFp(const mp_int *irr) meth->irr_arr[0] = mpl_significant_bits(irr); meth->irr_arr[1] = meth->irr_arr[2] = meth->irr_arr[3] = meth->irr_arr[4] = 0; - meth->field_add = &ec_GFp_add; + switch(MP_USED(&meth->irr)) { + /* maybe we need 1 and 2 words here as well?*/ + case 3: + meth->field_add = &ec_GFp_add_3; + meth->field_sub = &ec_GFp_sub_3; + break; + case 4: + meth->field_add = &ec_GFp_add_4; + meth->field_sub = &ec_GFp_sub_4; + break; + case 5: + meth->field_add = &ec_GFp_add_5; + meth->field_sub = &ec_GFp_sub_5; + break; + case 6: + meth->field_add = &ec_GFp_add_6; + meth->field_sub = &ec_GFp_sub_6; + break; + default: + meth->field_add = &ec_GFp_add; + meth->field_sub = &ec_GFp_sub; + } meth->field_neg = &ec_GFp_neg; - meth->field_sub = &ec_GFp_sub; meth->field_mod = &ec_GFp_mod; meth->field_mul = &ec_GFp_mul; meth->field_sqr = &ec_GFp_sqr; @@ -164,6 +186,7 @@ GFMethod_free(GFMethod *meth) return; if (meth->constructed == MP_NO) return; + mp_clear(&meth->irr); if (meth->extra_free != NULL) meth->extra_free(meth); free(meth); @@ -223,6 +246,676 @@ ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r, CLEANUP: return res; } +/* + * Inline adds for small curve lengths. + */ +/* 3 words */ +mp_err +ec_GFp_add_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a2 = MP_DIGIT(&meth->irr,2); + if (carry || r2 > a2 || + ((r2 == a2) && mp_cmp(r,&meth->irr) != MP_LT)) { + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); +#else + __asm__ ( + "subq %3,%0 \n\t" + "sbbq %4,%1 \n\t" + "sbbq %5,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "r" (a0), "r" (a1), "r" (a2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 4 words */ +mp_err +ec_GFp_add_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); +#else + __asm__ ( + "xorq %4,%4 \n\t" + "addq %5,%0 \n\t" + "adcq %6,%1 \n\t" + "adcq %7,%2 \n\t" + "adcq %8,%3 \n\t" + "adcq $0,%4 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), "r" (a3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + + MP_CHECKOK(s_mp_pad(r, 4)); + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a3 = MP_DIGIT(&meth->irr,3); + if (carry || r3 > a3 || + ((r3 == a3) && mp_cmp(r,&meth->irr) != MP_LT)) { + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); +#else + __asm__ ( + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "sbbq %7,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3) + : "r" (a0), "r" (a1), "r" (a2), "r" (a3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 5 words */ +mp_err +ec_GFp_add_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 5: + a4 = MP_DIGIT(a,4); + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 5: + r4 = MP_DIGIT(b,4); + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); + MP_ADD_CARRY(a4, r4, r4, carry, carry); + + MP_CHECKOK(s_mp_pad(r, 5)); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 5; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a4 = MP_DIGIT(&meth->irr,4); + if (carry || r4 > a4 || + ((r4 == a4) && mp_cmp(r,&meth->irr) != MP_LT)) { + a3 = MP_DIGIT(&meth->irr,3); + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); + MP_SUB_BORROW(r4, a4, r4, carry, carry); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 6 words */ +mp_err +ec_GFp_add_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0, a3 = 0, a4 = 0, a5 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 6: + a5 = MP_DIGIT(a,5); + case 5: + a4 = MP_DIGIT(a,4); + case 4: + a3 = MP_DIGIT(a,3); + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 6: + r5 = MP_DIGIT(b,5); + case 5: + r4 = MP_DIGIT(b,4); + case 4: + r3 = MP_DIGIT(b,3); + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); + MP_ADD_CARRY(a3, r3, r3, carry, carry); + MP_ADD_CARRY(a4, r4, r4, carry, carry); + MP_ADD_CARRY(a5, r5, r5, carry, carry); + + MP_CHECKOK(s_mp_pad(r, 6)); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 6; + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + a5 = MP_DIGIT(&meth->irr,5); + if (carry || r5 > a5 || + ((r5 == a5) && mp_cmp(r,&meth->irr) != MP_LT)) { + a4 = MP_DIGIT(&meth->irr,4); + a3 = MP_DIGIT(&meth->irr,3); + a2 = MP_DIGIT(&meth->irr,2); + a1 = MP_DIGIT(&meth->irr,1); + a0 = MP_DIGIT(&meth->irr,0); + MP_SUB_BORROW(r0, a0, r0, 0, carry); + MP_SUB_BORROW(r1, a1, r1, carry, carry); + MP_SUB_BORROW(r2, a2, r2, carry, carry); + MP_SUB_BORROW(r3, a3, r3, carry, carry); + MP_SUB_BORROW(r4, a4, r4, carry, carry); + MP_SUB_BORROW(r5, a5, r5, carry, carry); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + } + + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* + * The following subraction functions do in-line subractions based + * on our curve size. + * + * ... 3 words + */ +mp_err +ec_GFp_sub_3(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r" (borrow) + : "r" (b0), "r" (b1), "r" (b2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); +#else + __asm__ ( + "addq %3,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq %5,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "r" (b0), "r" (b1), "r" (b2), + "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + } + +#ifdef MPI_AMD64_ADD + /* compiler fakeout? */ + if ((r2 == b0) && (r1 == b0) && (r0 == b0)) { + MP_CHECKOK(s_mp_pad(r, 4)); + } +#endif + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 4 words */ +mp_err +ec_GFp_sub_4(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); +#else + __asm__ ( + "xorq %4,%4 \n\t" + "subq %5,%0 \n\t" + "sbbq %6,%1 \n\t" + "sbbq %7,%2 \n\t" + "sbbq %8,%3 \n\t" + "adcq $0,%4 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r" (borrow) + : "r" (b0), "r" (b1), "r" (b2), "r" (b3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); +#else + __asm__ ( + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq %7,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3) + : "r" (b0), "r" (b1), "r" (b2), "r" (b3), + "0" (r0), "1" (r1), "2" (r2), "3" (r3) + : "%cc" ); +#endif + } +#ifdef MPI_AMD64_ADD + /* compiler fakeout? */ + if ((r3 == b0) && (r1 == b0) && (r0 == b0)) { + MP_CHECKOK(s_mp_pad(r, 4)); + } +#endif + MP_CHECKOK(s_mp_pad(r, 4)); + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 5 words */ +mp_err +ec_GFp_sub_5(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 5: + r4 = MP_DIGIT(a,4); + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 5: + b4 = MP_DIGIT(b,4); + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); + MP_SUB_BORROW(r4, b4, r4, borrow, borrow); + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b4 = MP_DIGIT(&meth->irr,4); + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); + } + MP_CHECKOK(s_mp_pad(r, 5)); + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 5; + s_mp_clamp(r); + + CLEANUP: + return res; +} + +/* 6 words */ +mp_err +ec_GFp_sub_6(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 6: + r5 = MP_DIGIT(a,5); + case 5: + r4 = MP_DIGIT(a,4); + case 4: + r3 = MP_DIGIT(a,3); + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 6: + b5 = MP_DIGIT(b,5); + case 5: + b4 = MP_DIGIT(b,4); + case 4: + b3 = MP_DIGIT(b,3); + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); + MP_SUB_BORROW(r3, b3, r3, borrow, borrow); + MP_SUB_BORROW(r4, b4, r4, borrow, borrow); + MP_SUB_BORROW(r5, b5, r5, borrow, borrow); + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { + b5 = MP_DIGIT(&meth->irr,5); + b4 = MP_DIGIT(&meth->irr,4); + b3 = MP_DIGIT(&meth->irr,3); + b2 = MP_DIGIT(&meth->irr,2); + b1 = MP_DIGIT(&meth->irr,1); + b0 = MP_DIGIT(&meth->irr,0); + MP_ADD_CARRY(b0, r0, r0, 0, borrow); + MP_ADD_CARRY(b1, r1, r1, borrow, borrow); + MP_ADD_CARRY(b2, r2, r2, borrow, borrow); + MP_ADD_CARRY(b3, r3, r3, borrow, borrow); + MP_ADD_CARRY(b4, r4, r4, borrow, borrow); + } + + MP_CHECKOK(s_mp_pad(r, 6)); + MP_DIGIT(r, 5) = r5; + MP_DIGIT(r, 4) = r4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 6; + s_mp_clamp(r); + + CLEANUP: + return res; +} + /* Reduces an integer to a field element. */ mp_err diff --git a/security/nss/lib/freebl/ecl/ecl_mult.c b/security/nss/lib/freebl/ecl/ecl_mult.c index 69eae6965..050d0a747 100644 --- a/security/nss/lib/freebl/ecl/ecl_mult.c +++ b/security/nss/lib/freebl/ecl/ecl_mult.c @@ -57,7 +57,7 @@ ECPoint_mul(const ECGroup *group, const mp_int *k, const mp_int *px, MP_DIGITS(&kt) = 0; /* want scalar to be less than or equal to group order */ - if (mp_cmp(k, &group->order) >= 0) { + if (mp_cmp(k, &group->order) > 0) { MP_CHECKOK(mp_init(&kt)); MP_CHECKOK(mp_mod(k, &group->order, &kt)); } else { @@ -162,7 +162,6 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, { mp_err res = MP_OKAY; mp_int precomp[4][4][2]; - mp_digit precomp_arr[ECL_MAX_FIELD_SIZE_DIGITS * 4 * 4 * 2], *t; const mp_int *a, *b; int i, j; int ai, bi, d; @@ -180,23 +179,18 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } /* initialize precomputation table */ - t = precomp_arr; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - /* x co-ord */ - MP_SIGN(&precomp[i][j][0]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][0]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][0]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][0]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; - /* y co-ord */ - MP_SIGN(&precomp[i][j][1]) = MP_ZPOS; - MP_ALLOC(&precomp[i][j][1]) = ECL_MAX_FIELD_SIZE_DIGITS; - MP_USED(&precomp[i][j][1]) = 1; - *t = 0; - MP_DIGITS(&precomp[i][j][1]) = t; - t += ECL_MAX_FIELD_SIZE_DIGITS; + MP_DIGITS(&precomp[i][j][0]) = 0; + MP_DIGITS(&precomp[i][j][1]) = 0; + } + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + MP_CHECKOK( mp_init_size(&precomp[i][j][0], + ECL_MAX_FIELD_SIZE_DIGITS) ); + MP_CHECKOK( mp_init_size(&precomp[i][j][1], + ECL_MAX_FIELD_SIZE_DIGITS) ); } } @@ -298,6 +292,12 @@ ec_pts_mul_simul_w2(const mp_int *k1, const mp_int *k2, const mp_int *px, } CLEANUP: + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + mp_clear(&precomp[i][j][0]); + mp_clear(&precomp[i][j][1]); + } + } return res; } diff --git a/security/nss/lib/freebl/ecl/ecp_192.c b/security/nss/lib/freebl/ecl/ecp_192.c index 26867ae3e..f4cd42bc3 100644 --- a/security/nss/lib/freebl/ecl/ecp_192.c +++ b/security/nss/lib/freebl/ecl/ecp_192.c @@ -42,6 +42,8 @@ #include "mpi-priv.h" #include <stdlib.h> +#define ECP192_DIGITS ECL_CURVE_DIGITS(192) + /* Fast modular reduction for p192 = 2^192 - 2^64 - 1. a can be r. Uses * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software * Implementation of the NIST Elliptic Curves over Prime Fields. */ @@ -50,101 +52,127 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth) { mp_err res = MP_OKAY; mp_size a_used = MP_USED(a); - - /* s is a statically-allocated mp_int of exactly the size we need */ - mp_int s; - + mp_digit r3; +#ifndef MPI_AMD64_ADD + mp_digit carry; +#endif #ifdef ECL_THIRTY_TWO_BIT - mp_digit sa[6]; - mp_digit a11 = 0, a10, a9 = 0, a8, a7 = 0, a6; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 6; - MP_USED(&s) = 6; - MP_DIGITS(&s) = sa; + mp_digit a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0; + mp_digit r0a, r0b, r1a, r1b, r2a, r2b; #else - mp_digit sa[3]; mp_digit a5 = 0, a4 = 0, a3 = 0; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 3; - MP_USED(&s) = 3; - MP_DIGITS(&s) = sa; + mp_digit r0, r1, r2; #endif /* reduction not needed if a is not larger than field size */ -#ifdef ECL_THIRTY_TWO_BIT - if (a_used < 6) { -#else - if (a_used < 3) { -#endif + if (a_used < ECP192_DIGITS) { + if (a == r) { + return MP_OKAY; + } return mp_copy(a, r); } -#ifdef ECL_THIRTY_TWO_BIT + /* for polynomials larger than twice the field size, use regular * reduction */ - if (a_used > 12) { + if (a_used > ECP192_DIGITS*2) { MP_CHECKOK(mp_mod(a, &meth->irr, r)); } else { /* copy out upper words of a */ + +#ifdef ECL_THIRTY_TWO_BIT + + /* in all the math below, + * nXb is most signifiant, nXa is least significant */ switch (a_used) { case 12: - a11 = MP_DIGIT(a, 11); + a5b = MP_DIGIT(a, 11); case 11: - a10 = MP_DIGIT(a, 10); + a5a = MP_DIGIT(a, 10); case 10: - a9 = MP_DIGIT(a, 9); + a4b = MP_DIGIT(a, 9); case 9: - a8 = MP_DIGIT(a, 8); + a4a = MP_DIGIT(a, 8); case 8: - a7 = MP_DIGIT(a, 7); + a3b = MP_DIGIT(a, 7); case 7: - a6 = MP_DIGIT(a, 6); + a3a = MP_DIGIT(a, 6); } + + + r2b= MP_DIGIT(a, 5); + r2a= MP_DIGIT(a, 4); + r1b = MP_DIGIT(a, 3); + r1a = MP_DIGIT(a, 2); + r0b = MP_DIGIT(a, 1); + r0a = MP_DIGIT(a, 0); + + /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */ + MP_ADD_CARRY(r0a, a3a, r0a, 0, carry); + MP_ADD_CARRY(r0b, a3b, r0b, carry, carry); + MP_ADD_CARRY(r1a, a3a, r1a, carry, carry); + MP_ADD_CARRY(r1b, a3b, r1b, carry, carry); + MP_ADD_CARRY(r2a, a4a, r2a, carry, carry); + MP_ADD_CARRY(r2b, a4b, r2b, carry, carry); + r3 = carry; carry = 0; + MP_ADD_CARRY(r0a, a5a, r0a, 0, carry); + MP_ADD_CARRY(r0b, a5b, r0b, carry, carry); + MP_ADD_CARRY(r1a, a5a, r1a, carry, carry); + MP_ADD_CARRY(r1b, a5b, r1b, carry, carry); + MP_ADD_CARRY(r2a, a5a, r2a, carry, carry); + MP_ADD_CARRY(r2b, a5b, r2b, carry, carry); + r3 += carry; + MP_ADD_CARRY(r1a, a4a, r1a, 0, carry); + MP_ADD_CARRY(r1b, a4b, r1b, carry, carry); + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + r3 += carry; + + /* reduce out the carry */ + while (r3) { + MP_ADD_CARRY(r0a, r3, r0a, 0, carry); + MP_ADD_CARRY(r0b, 0, r0b, carry, carry); + MP_ADD_CARRY(r1a, r3, r1a, carry, carry); + MP_ADD_CARRY(r1b, 0, r1b, carry, carry); + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + r3 = carry; + } + + /* check for final reduction */ + /* + * our field is 0xffffffffffffffff, 0xfffffffffffffffe, + * 0xffffffffffffffff. That means we can only be over and need + * one more reduction + * if r2 == 0xffffffffffffffffff (same as r2+1 == 0) + * and + * r1 == 0xffffffffffffffffff or + * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff + * In all cases, we subtract the field (or add the 2's + * complement value (1,1,0)). (r0, r1, r2) + */ + if (((r2b == 0xffffffff) && (r2a == 0xffffffff) + && (r1b == 0xffffffff) ) && + ((r1a == 0xffffffff) || + (r1a == 0xfffffffe) && (r0a == 0xffffffff) && + (r0b == 0xffffffff)) ) { + /* do a quick subtract */ + MP_ADD_CARRY(r0a, 1, r0a, 0, carry); + r0b += carry; + r1a = r1b = r2a = r2b = 0; + } + /* set the lower words of r */ if (a != r) { - MP_CHECKOK(s_mp_pad(r, 7)); - MP_DIGIT(r, 5) = MP_DIGIT(a, 5); - MP_DIGIT(r, 4) = MP_DIGIT(a, 4); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + MP_CHECKOK(s_mp_pad(r, 6)); } + MP_DIGIT(r, 5) = r2b; + MP_DIGIT(r, 4) = r2a; + MP_DIGIT(r, 3) = r1b; + MP_DIGIT(r, 2) = r1a; + MP_DIGIT(r, 1) = r0b; + MP_DIGIT(r, 0) = r0a; MP_USED(r) = 6; - /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 = - * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5), for - * sixty-four-bit words */ - switch (a_used) { - case 12: - case 11: - sa[5] = sa[3] = sa[1] = a11; - sa[4] = sa[2] = sa[0] = a10; - MP_CHECKOK(mp_add(r, &s, r)); - case 10: - case 9: - sa[5] = sa[3] = a9; - sa[4] = sa[2] = a8; - sa[1] = sa[0] = 0; - MP_CHECKOK(mp_add(r, &s, r)); - case 8: - case 7: - sa[5] = sa[4] = 0; - sa[3] = sa[1] = a7; - sa[2] = sa[0] = a6; - MP_CHECKOK(mp_add(r, &s, r)); - } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } #else - /* for polynomials larger than twice the field size, use regular - * reduction */ - if (a_used > 6) { - MP_CHECKOK(mp_mod(a, &meth->irr, r)); - } else { - /* copy out upper words of a */ switch (a_used) { case 6: a5 = MP_DIGIT(a, 5); @@ -153,39 +181,268 @@ ec_GFp_nistp192_mod(const mp_int *a, mp_int *r, const GFMethod *meth) case 4: a3 = MP_DIGIT(a, 3); } + + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* implement r = (a2,a1,a0)+(a5,a5,a5)+(a4,a4,0)+(0,a3,a3) */ +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, a3, r0, 0, carry); + MP_ADD_CARRY(r1, a3, r1, carry, carry); + MP_ADD_CARRY(r2, a4, r2, carry, carry); + r3 = carry; + MP_ADD_CARRY(r0, a5, r0, 0, carry); + MP_ADD_CARRY(r1, a5, r1, carry, carry); + MP_ADD_CARRY(r2, a5, r2, carry, carry); + r3 += carry; + MP_ADD_CARRY(r1, a4, r1, 0, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + r3 += carry; + +#else + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* set the lower words of r */ + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq %5,%2 \n\t" + "adcq $0,%3 \n\t" + "addq %6,%0 \n\t" + "adcq %6,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + "addq %5,%1 \n\t" + "adcq $0,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3), + "=r"(a4), "=r"(a5) + : "0" (r0), "1" (r1), "2" (r2), "3" (r3), + "4" (a3), "5" (a4), "6"(a5) + : "%cc" ); +#endif + + /* reduce out the carry */ + while (r3) { +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, r3, r0, 0, carry); + MP_ADD_CARRY(r1, r3, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + r3 = carry; +#else + a3=r3; + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %4,%1 \n\t" + "adcq $0,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(r3), "=r"(a3) + : "0" (r0), "1" (r1), "2" (r2), "3" (r3), "4"(a3) + : "%cc" ); +#endif + } + + /* check for final reduction */ + /* + * our field is 0xffffffffffffffff, 0xfffffffffffffffe, + * 0xffffffffffffffff. That means we can only be over and need + * one more reduction + * if r2 == 0xffffffffffffffffff (same as r2+1 == 0) + * and + * r1 == 0xffffffffffffffffff or + * r1 == 0xfffffffffffffffffe and r0 = 0xfffffffffffffffff + * In all cases, we subtract the field (or add the 2's + * complement value (1,1,0)). (r0, r1, r2) + */ + if (r3 || ((r2 == MP_DIGIT_MAX) && + ((r1 == MP_DIGIT_MAX) || + ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) { + /* do a quick subtract */ + r0++; + r1 = r2 = 0; + } /* set the lower words of r */ if (a != r) { - MP_CHECKOK(s_mp_pad(r, 4)); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + MP_CHECKOK(s_mp_pad(r, 3)); } + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; MP_USED(r) = 3; - /* compute r = s1 + s2 + s3 + s4, where s1 = (a2,a1,a0), s2 = - * (0,a3,a3), s3 = (a4,a4,0), and s4 = (a5,a5,a5) */ - switch (a_used) { - case 6: - sa[2] = sa[1] = sa[0] = a5; - MP_CHECKOK(mp_add(r, &s, r)); - case 5: - sa[2] = sa[1] = a4; - sa[0] = 0; - MP_CHECKOK(mp_add(r, &s, r)); - case 4: - sa[2] = 0; - sa[1] = sa[0] = a3; - MP_CHECKOK(mp_add(r, &s, r)); - } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); +#endif } + + CLEANUP: + return res; +} + +#ifndef ECL_THIRTY_TWO_BIT +/* Compute the sum of 192 bit curves. Do the work in-line since the + * number of words are so small, we don't want to overhead of mp function + * calls. Uses optimized modular reduction for p192. + */ +mp_err +ec_GFp_nistp192_add(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit a0 = 0, a1 = 0, a2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit carry; + + switch(MP_USED(a)) { + case 3: + a2 = MP_DIGIT(a,2); + case 2: + a1 = MP_DIGIT(a,1); + case 1: + a0 = MP_DIGIT(a,0); + } + switch(MP_USED(b)) { + case 3: + r2 = MP_DIGIT(b,2); + case 2: + r1 = MP_DIGIT(b,1); + case 1: + r0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(a0, r0, r0, 0, carry); + MP_ADD_CARRY(a1, r1, r1, carry, carry); + MP_ADD_CARRY(a2, r2, r2, carry, carry); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "addq %4,%0 \n\t" + "adcq %5,%1 \n\t" + "adcq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(carry) + : "r" (a0), "r" (a1), "r" (a2), "0" (r0), + "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'subract' if we've gone over + * (add the 2's complement of the curve field) */ + if (carry || ((r2 == MP_DIGIT_MAX) && + ((r1 == MP_DIGIT_MAX) || + ((r1 == (MP_DIGIT_MAX-1)) && (r0 == MP_DIGIT_MAX))))) { +#ifndef MPI_AMD64_ADD + MP_ADD_CARRY(r0, 1, r0, 0, carry); + MP_ADD_CARRY(r1, 1, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); +#else + __asm__ ( + "addq $1,%0 \n\t" + "adcq $1,%1 \n\t" + "adcq $0,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); +#endif + } + + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); + + + CLEANUP: + return res; +} + +/* Compute the diff of 192 bit curves. Do the work in-line since the + * number of words are so small, we don't want to overhead of mp function + * calls. Uses optimized modular reduction for p192. + */ +mp_err +ec_GFp_nistp192_sub(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_digit b0 = 0, b1 = 0, b2 = 0; + mp_digit r0 = 0, r1 = 0, r2 = 0; + mp_digit borrow; + + switch(MP_USED(a)) { + case 3: + r2 = MP_DIGIT(a,2); + case 2: + r1 = MP_DIGIT(a,1); + case 1: + r0 = MP_DIGIT(a,0); + } + + switch(MP_USED(b)) { + case 3: + b2 = MP_DIGIT(b,2); + case 2: + b1 = MP_DIGIT(b,1); + case 1: + b0 = MP_DIGIT(b,0); + } + +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, b0, r0, 0, borrow); + MP_SUB_BORROW(r1, b1, r1, borrow, borrow); + MP_SUB_BORROW(r2, b2, r2, borrow, borrow); +#else + __asm__ ( + "xorq %3,%3 \n\t" + "subq %4,%0 \n\t" + "sbbq %5,%1 \n\t" + "sbbq %6,%2 \n\t" + "adcq $0,%3 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2), "=r"(borrow) + : "r" (b0), "r" (b1), "r" (b2), "0" (r0), + "1" (r1), "2" (r2) + : "%cc" ); +#endif + + /* Do quick 'add' if we've gone under 0 + * (subtract the 2's complement of the curve field) */ + if (borrow) { +#ifndef MPI_AMD64_ADD + MP_SUB_BORROW(r0, 1, r0, 0, borrow); + MP_SUB_BORROW(r1, 1, r1, borrow, borrow); + MP_SUB_BORROW(r2, 0, r2, borrow, borrow); +#else + __asm__ ( + "subq $1,%0 \n\t" + "sbbq $1,%1 \n\t" + "sbbq $0,%2 \n\t" + : "=r"(r0), "=r"(r1), "=r"(r2) + : "0" (r0), "1" (r1), "2" (r2) + : "%cc" ); #endif + } + + MP_CHECKOK(s_mp_pad(r, 3)); + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 3; + s_mp_clamp(r); CLEANUP: return res; } +#endif + /* Compute the square of polynomial a, reduce modulo p192. Store the * result in r. r could be a. Uses optimized modular reduction for p192. */ @@ -215,6 +472,31 @@ ec_GFp_nistp192_mul(const mp_int *a, const mp_int *b, mp_int *r, return res; } +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp192_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp192_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + /* Wire in fast field arithmetic and precomputation of base point for * named curves. */ mp_err @@ -224,6 +506,11 @@ ec_group_set_gfp192(ECGroup *group, ECCurveName name) group->meth->field_mod = &ec_GFp_nistp192_mod; group->meth->field_mul = &ec_GFp_nistp192_mul; group->meth->field_sqr = &ec_GFp_nistp192_sqr; + group->meth->field_div = &ec_GFp_nistp192_div; +#ifndef ECL_THIRTY_TWO_BIT + group->meth->field_add = &ec_GFp_nistp192_add; + group->meth->field_sub = &ec_GFp_nistp192_sub; +#endif } return MP_OKAY; } diff --git a/security/nss/lib/freebl/ecl/ecp_224.c b/security/nss/lib/freebl/ecl/ecp_224.c index c3d8fa362..56683e9ef 100644 --- a/security/nss/lib/freebl/ecl/ecp_224.c +++ b/security/nss/lib/freebl/ecl/ecp_224.c @@ -42,6 +42,8 @@ #include "mpi-priv.h" #include <stdlib.h> +#define ECP224_DIGITS ECL_CURVE_DIGITS(224) + /* Fast modular reduction for p224 = 2^224 - 2^96 + 1. a can be r. Uses * algorithm 7 from Brown, Hankerson, Lopez, Menezes. Software * Implementation of the NIST Elliptic Curves over Prime Fields. */ @@ -51,213 +53,251 @@ ec_GFp_nistp224_mod(const mp_int *a, mp_int *r, const GFMethod *meth) mp_err res = MP_OKAY; mp_size a_used = MP_USED(a); - /* s is a statically-allocated mp_int of exactly the size we need */ - mp_int s; - + int r3b; + mp_digit carry; #ifdef ECL_THIRTY_TWO_BIT - mp_digit sa[8]; - mp_digit a13 = 0, a12 = 0, a11 = 0, a10, a9 = 0, a8, a7; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 8; - MP_USED(&s) = 7; - MP_DIGITS(&s) = sa; + mp_digit a6a = 0, a6b = 0, + a5a = 0, a5b = 0, a4a = 0, a4b = 0, a3a = 0, a3b = 0; + mp_digit r0a, r0b, r1a, r1b, r2a, r2b, r3a; #else - mp_digit sa[4]; - mp_digit a6 = 0, a5 = 0, a4 = 0, a3 = 0; - - MP_SIGN(&s) = MP_ZPOS; - MP_ALLOC(&s) = 4; - MP_USED(&s) = 4; - MP_DIGITS(&s) = sa; + mp_digit a6 = 0, a5 = 0, a4 = 0, a3b = 0, a5a = 0; + mp_digit a6b = 0, a6a_a5b = 0, a5b = 0, a5a_a4b = 0, a4a_a3b = 0; + mp_digit r0, r1, r2, r3; #endif /* reduction not needed if a is not larger than field size */ -#ifdef ECL_THIRTY_TWO_BIT - if (a_used < 8) { -#else - if (a_used < 4) { -#endif + if (a_used < ECP224_DIGITS) { + if (a == r) return MP_OKAY; return mp_copy(a, r); } -#ifdef ECL_THIRTY_TWO_BIT /* for polynomials larger than twice the field size, use regular * reduction */ - if (a_used > 14) { + if (a_used > ECL_CURVE_DIGITS(224*2)) { MP_CHECKOK(mp_mod(a, &meth->irr, r)); } else { +#ifdef ECL_THIRTY_TWO_BIT /* copy out upper words of a */ switch (a_used) { case 14: - a13 = MP_DIGIT(a, 13); + a6b = MP_DIGIT(a, 13); case 13: - a12 = MP_DIGIT(a, 12); + a6a = MP_DIGIT(a, 12); case 12: - a11 = MP_DIGIT(a, 11); + a5b = MP_DIGIT(a, 11); case 11: - a10 = MP_DIGIT(a, 10); + a5a = MP_DIGIT(a, 10); case 10: - a9 = MP_DIGIT(a, 9); + a4b = MP_DIGIT(a, 9); case 9: - a8 = MP_DIGIT(a, 8); + a4a = MP_DIGIT(a, 8); case 8: - a7 = MP_DIGIT(a, 7); + a3b = MP_DIGIT(a, 7); } - /* set the lower words of r */ - if (a != r) { - MP_CHECKOK(s_mp_pad(r, 8)); - MP_DIGIT(r, 6) = MP_DIGIT(a, 6); - MP_DIGIT(r, 5) = MP_DIGIT(a, 5); - MP_DIGIT(r, 4) = MP_DIGIT(a, 4); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3); - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); + r3a = MP_DIGIT(a, 6); + r2b= MP_DIGIT(a, 5); + r2a= MP_DIGIT(a, 4); + r1b = MP_DIGIT(a, 3); + r1a = MP_DIGIT(a, 2); + r0b = MP_DIGIT(a, 1); + r0a = MP_DIGIT(a, 0); + + + /* implement r = (a3a,a2,a1,a0) + +(a5a, a4,a3b, 0) + +( 0, a6,a5b, 0) + -( 0 0, 0|a6b, a6a|a5b ) + -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */ + MP_ADD_CARRY (r1b, a3b, r1b, 0, carry); + MP_ADD_CARRY (r2a, a4a, r2a, carry, carry); + MP_ADD_CARRY (r2b, a4b, r2b, carry, carry); + MP_ADD_CARRY (r3a, a5a, r3a, carry, carry); + r3b = carry; + MP_ADD_CARRY (r1b, a5b, r1b, 0, carry); + MP_ADD_CARRY (r2a, a6a, r2a, carry, carry); + MP_ADD_CARRY (r2b, a6b, r2b, carry, carry); + MP_ADD_CARRY (r3a, 0, r3a, carry, carry); + r3b += carry; + MP_SUB_BORROW(r0a, a3b, r0a, 0, carry); + MP_SUB_BORROW(r0b, a4a, r0b, carry, carry); + MP_SUB_BORROW(r1a, a4b, r1a, carry, carry); + MP_SUB_BORROW(r1b, a5a, r1b, carry, carry); + MP_SUB_BORROW(r2a, a5b, r2a, carry, carry); + MP_SUB_BORROW(r2b, a6a, r2b, carry, carry); + MP_SUB_BORROW(r3a, a6b, r3a, carry, carry); + r3b -= carry; + MP_SUB_BORROW(r0a, a5b, r0a, 0, carry); + MP_SUB_BORROW(r0b, a6a, r0b, carry, carry); + MP_SUB_BORROW(r1a, a6b, r1a, carry, carry); + if (carry) { + MP_SUB_BORROW(r1b, 0, r1b, carry, carry); + MP_SUB_BORROW(r2a, 0, r2a, carry, carry); + MP_SUB_BORROW(r2b, 0, r2b, carry, carry); + MP_SUB_BORROW(r3a, 0, r3a, carry, carry); + r3b -= carry; } - MP_USED(r) = 7; - switch (a_used) { - case 14: - case 13: - case 12: - case 11: - sa[6] = a10; - case 10: - sa[5] = a9; - case 9: - sa[4] = a8; - case 8: - sa[3] = a7; - sa[2] = sa[1] = sa[0] = 0; - MP_USED(&s) = a_used - 4; - if (MP_USED(&s) > 7) - MP_USED(&s) = 7; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b > 0) { + int tmp; + MP_ADD_CARRY(r1b, r3b, r1b, 0, carry); + if (carry) { + MP_ADD_CARRY(r2a, 0, r2a, carry, carry); + MP_ADD_CARRY(r2b, 0, r2b, carry, carry); + MP_ADD_CARRY(r3a, 0, r3a, carry, carry); + } + tmp = carry; + MP_SUB_BORROW(r0a, r3b, r0a, 0, carry); + if (carry) { + MP_SUB_BORROW(r0b, 0, r0b, carry, carry); + MP_SUB_BORROW(r1a, 0, r1a, carry, carry); + MP_SUB_BORROW(r1b, 0, r1b, carry, carry); + MP_SUB_BORROW(r2a, 0, r2a, carry, carry); + MP_SUB_BORROW(r2b, 0, r2b, carry, carry); + MP_SUB_BORROW(r3a, 0, r3a, carry, carry); + tmp -= carry; + } + r3b = tmp; } - switch (a_used) { - case 14: - sa[5] = a13; - case 13: - sa[4] = a12; - case 12: - sa[3] = a11; - sa[2] = sa[1] = sa[0] = 0; - MP_USED(&s) = a_used - 8; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b < 0) { + mp_digit maxInt = MP_DIGIT_MAX; + MP_ADD_CARRY (r0a, 1, r0a, 0, carry); + MP_ADD_CARRY (r0b, 0, r0b, carry, carry); + MP_ADD_CARRY (r1a, 0, r1a, carry, carry); + MP_ADD_CARRY (r1b, maxInt, r1b, carry, carry); + MP_ADD_CARRY (r2a, maxInt, r2a, carry, carry); + MP_ADD_CARRY (r2b, maxInt, r2b, carry, carry); + MP_ADD_CARRY (r3a, maxInt, r3a, carry, carry); + r3b += carry; } - switch (a_used) { - case 14: - sa[6] = a13; - case 13: - sa[5] = a12; - case 12: - sa[4] = a11; - case 11: - sa[3] = a10; - case 10: - sa[2] = a9; - case 9: - sa[1] = a8; - case 8: - sa[0] = a7; - MP_USED(&s) = a_used - 7; - MP_CHECKOK(mp_sub(r, &s, r)); + /* check for final reduction */ + /* now the only way we are over is if the top 4 words are all ones */ + if ((r3a == MP_DIGIT_MAX) && (r2b == MP_DIGIT_MAX) + && (r2a == MP_DIGIT_MAX) && (r1b == MP_DIGIT_MAX) && + ((r1a != 0) || (r0b != 0) || (r0a != 0)) ) { + /* one last subraction */ + MP_SUB_BORROW(r0a, 1, r0a, 0, carry); + MP_SUB_BORROW(r0b, 0, r0b, carry, carry); + MP_SUB_BORROW(r1a, 0, r1a, carry, carry); + r1b = r2a = r2b = r3a = 0; } - switch (a_used) { - case 14: - sa[2] = a13; - case 13: - sa[1] = a12; - case 12: - sa[0] = a11; - MP_USED(&s) = a_used - 11; - MP_CHECKOK(mp_sub(r, &s, r)); + + + if (a != r) { + MP_CHECKOK(s_mp_pad(r, 7)); } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } + /* set the lower words of r */ + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 7; + MP_DIGIT(r, 6) = r3a; + MP_DIGIT(r, 5) = r2b; + MP_DIGIT(r, 4) = r2a; + MP_DIGIT(r, 3) = r1b; + MP_DIGIT(r, 2) = r1a; + MP_DIGIT(r, 1) = r0b; + MP_DIGIT(r, 0) = r0a; #else - /* for polynomials larger than twice the field size, use regular - * reduction */ - if (a_used > 7) { - MP_CHECKOK(mp_mod(a, &meth->irr, r)); - } else { /* copy out upper words of a */ switch (a_used) { case 7: a6 = MP_DIGIT(a, 6); + a6b = a6 >> 32; + a6a_a5b = a6 << 32; case 6: a5 = MP_DIGIT(a, 5); + a5b = a5 >> 32; + a6a_a5b |= a5b; + a5b = a5b << 32; + a5a_a4b = a5 << 32; + a5a = a5 & 0xffffffff; case 5: a4 = MP_DIGIT(a, 4); + a5a_a4b |= a4 >> 32; + a4a_a3b = a4 << 32; case 4: - a3 = MP_DIGIT(a, 3) >> 32; + a3b = MP_DIGIT(a, 3) >> 32; + a4a_a3b |= a3b; + a3b = a3b << 32; } - /* set the lower words of r */ - if (a != r) { - MP_CHECKOK(s_mp_pad(r, 5)); - MP_DIGIT(r, 3) = MP_DIGIT(a, 3) & 0xFFFFFFFF; - MP_DIGIT(r, 2) = MP_DIGIT(a, 2); - MP_DIGIT(r, 1) = MP_DIGIT(a, 1); - MP_DIGIT(r, 0) = MP_DIGIT(a, 0); - } else { - MP_DIGIT(r, 3) &= 0xFFFFFFFF; + + r3 = MP_DIGIT(a, 3) & 0xffffffff; + r2 = MP_DIGIT(a, 2); + r1 = MP_DIGIT(a, 1); + r0 = MP_DIGIT(a, 0); + + /* implement r = (a3a,a2,a1,a0) + +(a5a, a4,a3b, 0) + +( 0, a6,a5b, 0) + -( 0 0, 0|a6b, a6a|a5b ) + -( a6b, a6a|a5b, a5a|a4b, a4a|a3b ) */ + MP_ADD_CARRY (r1, a3b, r1, 0, carry); + MP_ADD_CARRY (r2, a4 , r2, carry, carry); + MP_ADD_CARRY (r3, a5a, r3, carry, carry); + MP_ADD_CARRY (r1, a5b, r1, 0, carry); + MP_ADD_CARRY (r2, a6 , r2, carry, carry); + MP_ADD_CARRY (r3, 0, r3, carry, carry); + + MP_SUB_BORROW(r0, a4a_a3b, r0, 0, carry); + MP_SUB_BORROW(r1, a5a_a4b, r1, carry, carry); + MP_SUB_BORROW(r2, a6a_a5b, r2, carry, carry); + MP_SUB_BORROW(r3, a6b , r3, carry, carry); + MP_SUB_BORROW(r0, a6a_a5b, r0, 0, carry); + MP_SUB_BORROW(r1, a6b , r1, carry, carry); + if (carry) { + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); } - MP_USED(r) = 4; - switch (a_used) { - case 7: - case 6: - sa[3] = a5 & 0xFFFFFFFF; - case 5: - sa[2] = a4; - case 4: - sa[1] = a3 << 32; - sa[0] = 0; - MP_USED(&s) = a_used - 2; - if (MP_USED(&s) == 5) - MP_USED(&s) = 4; - MP_CHECKOK(mp_add(r, &s, r)); + + + /* if the value is negative, r3 has a 2's complement + * high value */ + r3b = (int)(r3 >>32); + while (r3b > 0) { + r3 &= 0xffffffff; + MP_ADD_CARRY(r1,((mp_digit)r3b) << 32, r1, 0, carry); + if (carry) { + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, 0, r3, carry, carry); + } + MP_SUB_BORROW(r0, r3b, r0, 0, carry); + if (carry) { + MP_SUB_BORROW(r1, 0, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); + } + r3b = (int)(r3 >>32); } - switch (a_used) { - case 7: - sa[2] = a6; - case 6: - sa[1] = (a5 >> 32) << 32; - sa[0] = 0; - MP_USED(&s) = a_used - 4; - MP_CHECKOK(mp_add(r, &s, r)); + + while (r3b < 0) { + MP_ADD_CARRY (r0, 1, r0, 0, carry); + MP_ADD_CARRY (r1, MP_DIGIT_MAX <<32, r1, carry, carry); + MP_ADD_CARRY (r2, MP_DIGIT_MAX, r2, carry, carry); + MP_ADD_CARRY (r3, MP_DIGIT_MAX >> 32, r3, carry, carry); + r3b = (int)(r3 >>32); } - sa[2] = sa[1] = sa[0] = 0; - switch (a_used) { - case 7: - sa[3] = a6 >> 32; - sa[2] = a6 << 32; - case 6: - sa[2] |= a5 >> 32; - sa[1] = a5 << 32; - case 5: - sa[1] |= a4 >> 32; - sa[0] = a4 << 32; - case 4: - sa[0] |= a3; - MP_USED(&s) = a_used - 3; - MP_CHECKOK(mp_sub(r, &s, r)); + /* check for final reduction */ + /* now the only way we are over is if the top 4 words are all ones */ + if ((r3 == (MP_DIGIT_MAX >> 32)) && (r2 == MP_DIGIT_MAX) + && ((r1 & MP_DIGIT_MAX << 32)== MP_DIGIT_MAX << 32) && + ((r1 != MP_DIGIT_MAX << 32 ) || (r0 != 0)) ) { + /* one last subraction */ + MP_SUB_BORROW(r0, 1, r0, 0, carry); + MP_SUB_BORROW(r1, 0, r1, carry, carry); + r2 = r3 = 0; } - sa[0] = 0; - switch (a_used) { - case 7: - sa[1] = a6 >> 32; - sa[0] = a6 << 32; - case 6: - sa[0] |= a5 >> 32; - MP_USED(&s) = a_used - 5; - MP_CHECKOK(mp_sub(r, &s, r)); + + + if (a != r) { + MP_CHECKOK(s_mp_pad(r, 4)); } - /* there might be 1 or 2 bits left to reduce; use regular - * reduction for this */ - MP_CHECKOK(mp_mod(r, &meth->irr, r)); - } + /* set the lower words of r */ + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + MP_DIGIT(r, 3) = r3; + MP_DIGIT(r, 2) = r2; + MP_DIGIT(r, 1) = r1; + MP_DIGIT(r, 0) = r0; #endif + } CLEANUP: return res; @@ -292,6 +332,31 @@ ec_GFp_nistp224_mul(const mp_int *a, const mp_int *b, mp_int *r, return res; } +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp224_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp224_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + /* Wire in fast field arithmetic and precomputation of base point for * named curves. */ mp_err @@ -301,6 +366,7 @@ ec_group_set_gfp224(ECGroup *group, ECCurveName name) group->meth->field_mod = &ec_GFp_nistp224_mod; group->meth->field_mul = &ec_GFp_nistp224_mul; group->meth->field_sqr = &ec_GFp_nistp224_sqr; + group->meth->field_div = &ec_GFp_nistp224_div; } return MP_OKAY; } diff --git a/security/nss/lib/freebl/ecl/ecp_256.c b/security/nss/lib/freebl/ecl/ecp_256.c new file mode 100644 index 000000000..15d29ab6e --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_256.c @@ -0,0 +1,429 @@ +/* + * ***** 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * 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 "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +/* Fast modular reduction for p256 = 2^256 - 2^224 + 2^192+ 2^96 - 1. a can be r. + * Uses algorithm 2.29 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp256_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_size a_used = MP_USED(a); + int a_bits = mpl_significant_bits(a); + mp_digit carry; + +#ifdef ECL_THIRTY_TWO_BIT + mp_digit a8=0, a9=0, a10=0, a11=0, a12=0, a13=0, a14=0, a15=0; + mp_digit r0, r1, r2, r3, r4, r5, r6, r7; + int r8; /* must be a signed value ! */ +#else + mp_digit a4=0, a5=0, a6=0, a7=0; + mp_digit a4h, a4l, a5h, a5l, a6h, a6l, a7h, a7l; + mp_digit r0, r1, r2, r3; + int r4; /* must be a signed value ! */ +#endif + /* for polynomials larger than twice the field size + * use regular reduction */ + if (a_bits < 256) { + if (a == r) return MP_OKAY; + return mp_copy(a,r); + } + if (a_bits > 512) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + +#ifdef ECL_THIRTY_TWO_BIT + switch (a_used) { + case 16: + a15 = MP_DIGIT(a,15); + case 15: + a14 = MP_DIGIT(a,14); + case 14: + a13 = MP_DIGIT(a,13); + case 13: + a12 = MP_DIGIT(a,12); + case 12: + a11 = MP_DIGIT(a,11); + case 11: + a10 = MP_DIGIT(a,10); + case 10: + a9 = MP_DIGIT(a,9); + case 9: + a8 = MP_DIGIT(a,8); + } + + r0 = MP_DIGIT(a,0); + r1 = MP_DIGIT(a,1); + r2 = MP_DIGIT(a,2); + r3 = MP_DIGIT(a,3); + r4 = MP_DIGIT(a,4); + r5 = MP_DIGIT(a,5); + r6 = MP_DIGIT(a,6); + r7 = MP_DIGIT(a,7); + + /* sum 1 */ + MP_ADD_CARRY(r3, a11, r3, 0, carry); + MP_ADD_CARRY(r4, a12, r4, carry, carry); + MP_ADD_CARRY(r5, a13, r5, carry, carry); + MP_ADD_CARRY(r6, a14, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); + r8 = carry; + MP_ADD_CARRY(r3, a11, r3, 0, carry); + MP_ADD_CARRY(r4, a12, r4, carry, carry); + MP_ADD_CARRY(r5, a13, r5, carry, carry); + MP_ADD_CARRY(r6, a14, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); + r8 += carry; + /* sum 2 */ + MP_ADD_CARRY(r3, a12, r3, 0, carry); + MP_ADD_CARRY(r4, a13, r4, carry, carry); + MP_ADD_CARRY(r5, a14, r5, carry, carry); + MP_ADD_CARRY(r6, a15, r6, carry, carry); + MP_ADD_CARRY(r7, 0, r7, carry, carry); + r8 += carry; + /* combine last bottom of sum 3 with second sum 2 */ + MP_ADD_CARRY(r0, a8, r0, 0, carry); + MP_ADD_CARRY(r1, a9, r1, carry, carry); + MP_ADD_CARRY(r2, a10, r2, carry, carry); + MP_ADD_CARRY(r3, a12, r3, carry, carry); + MP_ADD_CARRY(r4, a13, r4, carry, carry); + MP_ADD_CARRY(r5, a14, r5, carry, carry); + MP_ADD_CARRY(r6, a15, r6, carry, carry); + MP_ADD_CARRY(r7, a15, r7, carry, carry); /* from sum 3 */ + r8 += carry; + /* sum 3 (rest of it)*/ + MP_ADD_CARRY(r6, a14, r6, 0, carry); + MP_ADD_CARRY(r7, 0, r7, carry, carry); + r8 += carry; + /* sum 4 (rest of it)*/ + MP_ADD_CARRY(r0, a9, r0, 0, carry); + MP_ADD_CARRY(r1, a10, r1, carry, carry); + MP_ADD_CARRY(r2, a11, r2, carry, carry); + MP_ADD_CARRY(r3, a13, r3, carry, carry); + MP_ADD_CARRY(r4, a14, r4, carry, carry); + MP_ADD_CARRY(r5, a15, r5, carry, carry); + MP_ADD_CARRY(r6, a13, r6, carry, carry); + MP_ADD_CARRY(r7, a8, r7, carry, carry); + r8 += carry; + /* diff 5 */ + MP_SUB_BORROW(r0, a11, r0, 0, carry); + MP_SUB_BORROW(r1, a12, r1, carry, carry); + MP_SUB_BORROW(r2, a13, r2, carry, carry); + MP_SUB_BORROW(r3, 0, r3, carry, carry); + MP_SUB_BORROW(r4, 0, r4, carry, carry); + MP_SUB_BORROW(r5, 0, r5, carry, carry); + MP_SUB_BORROW(r6, a8, r6, carry, carry); + MP_SUB_BORROW(r7, a10, r7, carry, carry); + r8 -= carry; + /* diff 6 */ + MP_SUB_BORROW(r0, a12, r0, 0, carry); + MP_SUB_BORROW(r1, a13, r1, carry, carry); + MP_SUB_BORROW(r2, a14, r2, carry, carry); + MP_SUB_BORROW(r3, a15, r3, carry, carry); + MP_SUB_BORROW(r4, 0, r4, carry, carry); + MP_SUB_BORROW(r5, 0, r5, carry, carry); + MP_SUB_BORROW(r6, a9, r6, carry, carry); + MP_SUB_BORROW(r7, a11, r7, carry, carry); + r8 -= carry; + /* diff 7 */ + MP_SUB_BORROW(r0, a13, r0, 0, carry); + MP_SUB_BORROW(r1, a14, r1, carry, carry); + MP_SUB_BORROW(r2, a15, r2, carry, carry); + MP_SUB_BORROW(r3, a8, r3, carry, carry); + MP_SUB_BORROW(r4, a9, r4, carry, carry); + MP_SUB_BORROW(r5, a10, r5, carry, carry); + MP_SUB_BORROW(r6, 0, r6, carry, carry); + MP_SUB_BORROW(r7, a12, r7, carry, carry); + r8 -= carry; + /* diff 8 */ + MP_SUB_BORROW(r0, a14, r0, 0, carry); + MP_SUB_BORROW(r1, a15, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, a9, r3, carry, carry); + MP_SUB_BORROW(r4, a10, r4, carry, carry); + MP_SUB_BORROW(r5, a11, r5, carry, carry); + MP_SUB_BORROW(r6, 0, r6, carry, carry); + MP_SUB_BORROW(r7, a13, r7, carry, carry); + r8 -= carry; + + /* reduce the overflows */ + while (r8 > 0) { + mp_digit r8_d = r8; + MP_ADD_CARRY(r0, r8_d, r0, 0, carry); + MP_ADD_CARRY(r1, 0, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, -r8_d, r3, carry, carry); + MP_ADD_CARRY(r4, MP_DIGIT_MAX, r4, carry, carry); + MP_ADD_CARRY(r5, MP_DIGIT_MAX, r5, carry, carry); + MP_ADD_CARRY(r6, -(r8_d+1), r6, carry, carry); + MP_ADD_CARRY(r7, (r8_d-1), r7, carry, carry); + r8 = carry; + } + + /* reduce the underflows */ + while (r8 < 0) { + mp_digit r8_d = -r8; + MP_SUB_BORROW(r0, r8_d, r0, 0, carry); + MP_SUB_BORROW(r1, 0, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, -r8_d, r3, carry, carry); + MP_SUB_BORROW(r4, MP_DIGIT_MAX, r4, carry, carry); + MP_SUB_BORROW(r5, MP_DIGIT_MAX, r5, carry, carry); + MP_SUB_BORROW(r6, -(r8_d+1), r6, carry, carry); + MP_SUB_BORROW(r7, (r8_d-1), r7, carry, carry); + r8 = -carry; + } + if (a != r) { + MP_CHECKOK(s_mp_pad(r,8)); + } + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 8; + + MP_DIGIT(r,7) = r7; + MP_DIGIT(r,6) = r6; + MP_DIGIT(r,5) = r5; + MP_DIGIT(r,4) = r4; + MP_DIGIT(r,3) = r3; + MP_DIGIT(r,2) = r2; + MP_DIGIT(r,1) = r1; + MP_DIGIT(r,0) = r0; + + /* final reduction if necessary */ + if ((r7 == MP_DIGIT_MAX) && + ((r6 > 1) || ((r6 == 1) && + (r5 || r4 || r3 || + ((r2 == MP_DIGIT_MAX) && (r1 == MP_DIGIT_MAX) + && (r0 == MP_DIGIT_MAX)))))) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } +#ifdef notdef + + + /* smooth the negatives */ + while (MP_SIGN(r) != MP_ZPOS) { + MP_CHECKOK(mp_add(r, &meth->irr, r)); + } + while (MP_USED(r) > 8) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + + /* final reduction if necessary */ + if (MP_DIGIT(r,7) >= MP_DIGIT(&meth->irr,7)) { + if (mp_cmp(r,&meth->irr) != MP_LT) { + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + } +#endif + s_mp_clamp(r); +#else + switch (a_used) { + case 8: + a7 = MP_DIGIT(a,7); + case 7: + a6 = MP_DIGIT(a,6); + case 6: + a5 = MP_DIGIT(a,5); + case 5: + a4 = MP_DIGIT(a,4); + } + a7l = a7 << 32; + a7h = a7 >> 32; + a6l = a6 << 32; + a6h = a6 >> 32; + a5l = a5 << 32; + a5h = a5 >> 32; + a4l = a4 << 32; + a4h = a4 >> 32; + r3 = MP_DIGIT(a,3); + r2 = MP_DIGIT(a,2); + r1 = MP_DIGIT(a,1); + r0 = MP_DIGIT(a,0); + + /* sum 1 */ + MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry); + MP_ADD_CARRY(r2, a6, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 = carry; + MP_ADD_CARRY(r1, a5h << 32, r1, 0, carry); + MP_ADD_CARRY(r2, a6, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 += carry; + /* sum 2 */ + MP_ADD_CARRY(r1, a6l, r1, 0, carry); + MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry); + MP_ADD_CARRY(r3, a7h, r3, carry, carry); + r4 += carry; + MP_ADD_CARRY(r1, a6l, r1, 0, carry); + MP_ADD_CARRY(r2, a6h | a7l, r2, carry, carry); + MP_ADD_CARRY(r3, a7h, r3, carry, carry); + r4 += carry; + + /* sum 3 */ + MP_ADD_CARRY(r0, a4, r0, 0, carry); + MP_ADD_CARRY(r1, a5l >> 32, r1, carry, carry); + MP_ADD_CARRY(r2, 0, r2, carry, carry); + MP_ADD_CARRY(r3, a7, r3, carry, carry); + r4 += carry; + /* sum 4 */ + MP_ADD_CARRY(r0, a4h | a5l, r0, 0, carry); + MP_ADD_CARRY(r1, a5h|(a6h<<32), r1, carry, carry); + MP_ADD_CARRY(r2, a7, r2, carry, carry); + MP_ADD_CARRY(r3, a6h | a4l, r3, carry, carry); + r4 += carry; + /* diff 5 */ + MP_SUB_BORROW(r0, a5h | a6l, r0, 0, carry); + MP_SUB_BORROW(r1, a6h, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, (a4l>>32)|a5l,r3, carry, carry); + r4 -= carry; + /* diff 6 */ + MP_SUB_BORROW(r0, a6, r0, 0, carry); + MP_SUB_BORROW(r1, a7, r1, carry, carry); + MP_SUB_BORROW(r2, 0, r2, carry, carry); + MP_SUB_BORROW(r3, a4h|(a5h<<32),r3, carry, carry); + r4 -= carry; + /* diff 7 */ + MP_SUB_BORROW(r0, a6h|a7l, r0, 0, carry); + MP_SUB_BORROW(r1, a7h|a4l, r1, carry, carry); + MP_SUB_BORROW(r2, a4h|a5l, r2, carry, carry); + MP_SUB_BORROW(r3, a6l, r3, carry, carry); + r4 -= carry; + /* diff 8 */ + MP_SUB_BORROW(r0, a7, r0, 0, carry); + MP_SUB_BORROW(r1, a4h<<32, r1, carry, carry); + MP_SUB_BORROW(r2, a5, r2, carry, carry); + MP_SUB_BORROW(r3, a6h<<32, r3, carry, carry); + r4 -= carry; + + /* reduce the overflows */ + while (r4 > 0) { + mp_digit r4_long = r4; + mp_digit r4l = (r4_long << 32); + MP_ADD_CARRY(r0, r4_long, r0, 0, carry); + MP_ADD_CARRY(r1, -r4l, r1, carry, carry); + MP_ADD_CARRY(r2, MP_DIGIT_MAX, r2, carry, carry); + MP_ADD_CARRY(r3, r4l-r4_long-1,r3, carry, carry); + r4 = carry; + } + + /* reduce the underflows */ + while (r4 < 0) { + mp_digit r4_long = -r4; + mp_digit r4l = (r4_long << 32); + MP_SUB_BORROW(r0, r4_long, r0, 0, carry); + MP_SUB_BORROW(r1, -r4l, r1, carry, carry); + MP_SUB_BORROW(r2, MP_DIGIT_MAX, r2, carry, carry); + MP_SUB_BORROW(r3, r4l-r4_long-1,r3, carry, carry); + r4 = -carry; + } + + if (a != r) { + MP_CHECKOK(s_mp_pad(r,4)); + } + MP_SIGN(r) = MP_ZPOS; + MP_USED(r) = 4; + + MP_DIGIT(r,3) = r3; + MP_DIGIT(r,2) = r2; + MP_DIGIT(r,1) = r1; + MP_DIGIT(r,0) = r0; + + /* final reduction if necessary */ + if ((r3 > 0xFFFFFFFF00000001ULL) || + ((r3 == 0xFFFFFFFF00000001ULL) && + (r2 || (r1 >> 32)|| + (r1 == 0xFFFFFFFFULL && r0 == MP_DIGIT_MAX)))) { + /* very rare, just use mp_sub */ + MP_CHECKOK(mp_sub(r, &meth->irr, r)); + } + + s_mp_clamp(r); +#endif + } + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p256. Store the + * result in r. r could be a. Uses optimized modular reduction for p256. + */ +mp_err +ec_GFp_nistp256_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p256. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p256. */ +mp_err +ec_GFp_nistp256_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp256_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp256(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P256) { + group->meth->field_mod = &ec_GFp_nistp256_mod; + group->meth->field_mul = &ec_GFp_nistp256_mul; + group->meth->field_sqr = &ec_GFp_nistp256_sqr; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/ecp_384.c b/security/nss/lib/freebl/ecl/ecp_384.c new file mode 100644 index 000000000..4ad4137d2 --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_384.c @@ -0,0 +1,293 @@ +/* + * ***** 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * 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 "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +/* Fast modular reduction for p384 = 2^384 - 2^128 - 2^96 + 2^32 - 1. a can be r. + * Uses algorithm 2.30 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp384_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + int a_bits = mpl_significant_bits(a); + int i; + + /* m1, m2 are statically-allocated mp_int of exactly the size we need */ + mp_int m[10]; + +#ifdef ECL_THIRTY_TWO_BIT + mp_digit s[10][12]; + for (i = 0; i < 10; i++) { + MP_SIGN(&m[i]) = MP_ZPOS; + MP_ALLOC(&m[i]) = 12; + MP_USED(&m[i]) = 12; + MP_DIGITS(&m[i]) = s[i]; + } +#else + mp_digit s[10][6]; + for (i = 0; i < 10; i++) { + MP_SIGN(&m[i]) = MP_ZPOS; + MP_ALLOC(&m[i]) = 6; + MP_USED(&m[i]) = 6; + MP_DIGITS(&m[i]) = s[i]; + } +#endif + +#ifdef ECL_THIRTY_TWO_BIT + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if ((a_bits > 768) || (a_bits <= 736)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + for (i = 0; i < 12; i++) { + s[0][i] = MP_DIGIT(a, i); + } + s[1][0] = 0; + s[1][1] = 0; + s[1][2] = 0; + s[1][3] = 0; + s[1][4] = MP_DIGIT(a, 21); + s[1][5] = MP_DIGIT(a, 22); + s[1][6] = MP_DIGIT(a, 23); + s[1][7] = 0; + s[1][8] = 0; + s[1][9] = 0; + s[1][10] = 0; + s[1][11] = 0; + for (i = 0; i < 12; i++) { + s[2][i] = MP_DIGIT(a, i+12); + } + s[3][0] = MP_DIGIT(a, 21); + s[3][1] = MP_DIGIT(a, 22); + s[3][2] = MP_DIGIT(a, 23); + for (i = 3; i < 12; i++) { + s[3][i] = MP_DIGIT(a, i+9); + } + s[4][0] = 0; + s[4][1] = MP_DIGIT(a, 23); + s[4][2] = 0; + s[4][3] = MP_DIGIT(a, 20); + for (i = 4; i < 12; i++) { + s[4][i] = MP_DIGIT(a, i+8); + } + s[5][0] = 0; + s[5][1] = 0; + s[5][2] = 0; + s[5][3] = 0; + s[5][4] = MP_DIGIT(a, 20); + s[5][5] = MP_DIGIT(a, 21); + s[5][6] = MP_DIGIT(a, 22); + s[5][7] = MP_DIGIT(a, 23); + s[5][8] = 0; + s[5][9] = 0; + s[5][10] = 0; + s[5][11] = 0; + s[6][0] = MP_DIGIT(a, 20); + s[6][1] = 0; + s[6][2] = 0; + s[6][3] = MP_DIGIT(a, 21); + s[6][4] = MP_DIGIT(a, 22); + s[6][5] = MP_DIGIT(a, 23); + s[6][6] = 0; + s[6][7] = 0; + s[6][8] = 0; + s[6][9] = 0; + s[6][10] = 0; + s[6][11] = 0; + s[7][0] = MP_DIGIT(a, 23); + for (i = 1; i < 12; i++) { + s[7][i] = MP_DIGIT(a, i+11); + } + s[8][0] = 0; + s[8][1] = MP_DIGIT(a, 20); + s[8][2] = MP_DIGIT(a, 21); + s[8][3] = MP_DIGIT(a, 22); + s[8][4] = MP_DIGIT(a, 23); + s[8][5] = 0; + s[8][6] = 0; + s[8][7] = 0; + s[8][8] = 0; + s[8][9] = 0; + s[8][10] = 0; + s[8][11] = 0; + s[9][0] = 0; + s[9][1] = 0; + s[9][2] = 0; + s[9][3] = MP_DIGIT(a, 23); + s[9][4] = MP_DIGIT(a, 23); + s[9][5] = 0; + s[9][6] = 0; + s[9][7] = 0; + s[9][8] = 0; + s[9][9] = 0; + s[9][10] = 0; + s[9][11] = 0; + + MP_CHECKOK(mp_add(&m[0], &m[1], r)); + MP_CHECKOK(mp_add(r, &m[1], r)); + MP_CHECKOK(mp_add(r, &m[2], r)); + MP_CHECKOK(mp_add(r, &m[3], r)); + MP_CHECKOK(mp_add(r, &m[4], r)); + MP_CHECKOK(mp_add(r, &m[5], r)); + MP_CHECKOK(mp_add(r, &m[6], r)); + MP_CHECKOK(mp_sub(r, &m[7], r)); + MP_CHECKOK(mp_sub(r, &m[8], r)); + MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r)); + s_mp_clamp(r); + } +#else + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if ((a_bits > 768) || (a_bits <= 736)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { + for (i = 0; i < 6; i++) { + s[0][i] = MP_DIGIT(a, i); + } + s[1][0] = 0; + s[1][1] = 0; + s[1][2] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[1][3] = MP_DIGIT(a, 11) >> 32; + s[1][4] = 0; + s[1][5] = 0; + for (i = 0; i < 6; i++) { + s[2][i] = MP_DIGIT(a, i+6); + } + s[3][0] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[3][1] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32); + for (i = 2; i < 6; i++) { + s[3][i] = (MP_DIGIT(a, i+4) >> 32) | (MP_DIGIT(a, i+5) << 32); + } + s[4][0] = (MP_DIGIT(a, 11) >> 32) << 32; + s[4][1] = MP_DIGIT(a, 10) << 32; + for (i = 2; i < 6; i++) { + s[4][i] = MP_DIGIT(a, i+4); + } + s[5][0] = 0; + s[5][1] = 0; + s[5][2] = MP_DIGIT(a, 10); + s[5][3] = MP_DIGIT(a, 11); + s[5][4] = 0; + s[5][5] = 0; + s[6][0] = (MP_DIGIT(a, 10) << 32) >> 32; + s[6][1] = (MP_DIGIT(a, 10) >> 32) << 32; + s[6][2] = MP_DIGIT(a, 11); + s[6][3] = 0; + s[6][4] = 0; + s[6][5] = 0; + s[7][0] = (MP_DIGIT(a, 11) >> 32) | (MP_DIGIT(a, 6) << 32); + for (i = 1; i < 6; i++) { + s[7][i] = (MP_DIGIT(a, i+5) >> 32) | (MP_DIGIT(a, i+6) << 32); + } + s[8][0] = MP_DIGIT(a, 10) << 32; + s[8][1] = (MP_DIGIT(a, 10) >> 32) | (MP_DIGIT(a, 11) << 32); + s[8][2] = MP_DIGIT(a, 11) >> 32; + s[8][3] = 0; + s[8][4] = 0; + s[8][5] = 0; + s[9][0] = 0; + s[9][1] = (MP_DIGIT(a, 11) >> 32) << 32; + s[9][2] = MP_DIGIT(a, 11) >> 32; + s[9][3] = 0; + s[9][4] = 0; + s[9][5] = 0; + + MP_CHECKOK(mp_add(&m[0], &m[1], r)); + MP_CHECKOK(mp_add(r, &m[1], r)); + MP_CHECKOK(mp_add(r, &m[2], r)); + MP_CHECKOK(mp_add(r, &m[3], r)); + MP_CHECKOK(mp_add(r, &m[4], r)); + MP_CHECKOK(mp_add(r, &m[5], r)); + MP_CHECKOK(mp_add(r, &m[6], r)); + MP_CHECKOK(mp_sub(r, &m[7], r)); + MP_CHECKOK(mp_sub(r, &m[8], r)); + MP_CHECKOK(mp_submod(r, &m[9], &meth->irr, r)); + s_mp_clamp(r); + } +#endif + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p384. Store the + * result in r. r could be a. Uses optimized modular reduction for p384. + */ +mp_err +ec_GFp_nistp384_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p384. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p384. */ +mp_err +ec_GFp_nistp384_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp384_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp384(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P384) { + group->meth->field_mod = &ec_GFp_nistp384_mod; + group->meth->field_mul = &ec_GFp_nistp384_mul; + group->meth->field_sqr = &ec_GFp_nistp384_sqr; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/ecp_521.c b/security/nss/lib/freebl/ecl/ecp_521.c new file mode 100644 index 000000000..685d19b9f --- /dev/null +++ b/security/nss/lib/freebl/ecl/ecp_521.c @@ -0,0 +1,170 @@ +/* + * ***** 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 elliptic curve math library for prime field curves. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Douglas Stebila <douglas@stebila.ca> + * + * 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 "ecp.h" +#include "mpi.h" +#include "mplogic.h" +#include "mpi-priv.h" +#include <stdlib.h> + +#define ECP521_DIGITS ECL_CURVE_DIGITS(521) + +/* Fast modular reduction for p521 = 2^521 - 1. a can be r. Uses + * algorithm 2.31 from Hankerson, Menezes, Vanstone. Guide to + * Elliptic Curve Cryptography. */ +mp_err +ec_GFp_nistp521_mod(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + int a_bits = mpl_significant_bits(a); + int i; + + /* m1, m2 are statically-allocated mp_int of exactly the size we need */ + mp_int m1; + + mp_digit s1[ECP521_DIGITS] = { 0 }; + + MP_SIGN(&m1) = MP_ZPOS; + MP_ALLOC(&m1) = ECP521_DIGITS; + MP_USED(&m1) = ECP521_DIGITS; + MP_DIGITS(&m1) = s1; + + if (a_bits < 521) { + if (a==r) return MP_OKAY; + return mp_copy(a, r); + } + /* for polynomials larger than twice the field size or polynomials + * not using all words, use regular reduction */ + if (a_bits > (521*2)) { + MP_CHECKOK(mp_mod(a, &meth->irr, r)); + } else { +#define FIRST_DIGIT (ECP521_DIGITS-1) + for (i = FIRST_DIGIT; i < MP_USED(a)-1; i++) { + s1[i-FIRST_DIGIT] = (MP_DIGIT(a, i) >> 9) + | (MP_DIGIT(a, 1+i) << (MP_DIGIT_BIT-9)); + } + s1[i-FIRST_DIGIT] = MP_DIGIT(a, i) >> 9; + + if ( a != r ) { + MP_CHECKOK(s_mp_pad(r,ECP521_DIGITS)); + for (i = 0; i < ECP521_DIGITS; i++) { + MP_DIGIT(r,i) = MP_DIGIT(a, i); + } + } + MP_USED(r) = ECP521_DIGITS; + MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF; + + MP_CHECKOK(s_mp_add(r, &m1)); + if (MP_DIGIT(r, FIRST_DIGIT) & 0x200) { + MP_CHECKOK(s_mp_add_d(r,1)); + MP_DIGIT(r,FIRST_DIGIT) &= 0x1FF; + } + s_mp_clamp(r); + } + + CLEANUP: + return res; +} + +/* Compute the square of polynomial a, reduce modulo p521. Store the + * result in r. r could be a. Uses optimized modular reduction for p521. + */ +mp_err +ec_GFp_nistp521_sqr(const mp_int *a, mp_int *r, const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_sqr(a, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Compute the product of two polynomials a and b, reduce modulo p521. + * Store the result in r. r could be a or b; a could be b. Uses + * optimized modular reduction for p521. */ +mp_err +ec_GFp_nistp521_mul(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + + MP_CHECKOK(mp_mul(a, b, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + return res; +} + +/* Divides two field elements. If a is NULL, then returns the inverse of + * b. */ +mp_err +ec_GFp_nistp521_div(const mp_int *a, const mp_int *b, mp_int *r, + const GFMethod *meth) +{ + mp_err res = MP_OKAY; + mp_int t; + + /* If a is NULL, then return the inverse of b, otherwise return a/b. */ + if (a == NULL) { + return mp_invmod(b, &meth->irr, r); + } else { + /* MPI doesn't support divmod, so we implement it using invmod and + * mulmod. */ + MP_CHECKOK(mp_init(&t)); + MP_CHECKOK(mp_invmod(b, &meth->irr, &t)); + MP_CHECKOK(mp_mul(a, &t, r)); + MP_CHECKOK(ec_GFp_nistp521_mod(r, r, meth)); + CLEANUP: + mp_clear(&t); + return res; + } +} + +/* Wire in fast field arithmetic and precomputation of base point for + * named curves. */ +mp_err +ec_group_set_gfp521(ECGroup *group, ECCurveName name) +{ + if (name == ECCurve_NIST_P521) { + group->meth->field_mod = &ec_GFp_nistp521_mod; + group->meth->field_mul = &ec_GFp_nistp521_mul; + group->meth->field_sqr = &ec_GFp_nistp521_sqr; + group->meth->field_div = &ec_GFp_nistp521_div; + } + return MP_OKAY; +} diff --git a/security/nss/lib/freebl/ecl/tests/ec2_test.c b/security/nss/lib/freebl/ecl/tests/ec2_test.c index e82b47da0..cf6540221 100644 --- a/security/nss/lib/freebl/ecl/tests/ec2_test.c +++ b/security/nss/lib/freebl/ecl/tests/ec2_test.c @@ -455,6 +455,36 @@ main(int argv, char **argc) ECTEST_GENERIC_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); /* specific arithmetic tests */ + ECTEST_NAMED_GF2M("NIST-K163", ECCurve_NIST_K163); + ECTEST_NAMED_GF2M("NIST-B163", ECCurve_NIST_B163); + ECTEST_NAMED_GF2M("NIST-K233", ECCurve_NIST_K233); + ECTEST_NAMED_GF2M("NIST-B233", ECCurve_NIST_B233); + ECTEST_NAMED_GF2M("NIST-K283", ECCurve_NIST_K283); + ECTEST_NAMED_GF2M("NIST-B283", ECCurve_NIST_B283); + ECTEST_NAMED_GF2M("NIST-K409", ECCurve_NIST_K409); + ECTEST_NAMED_GF2M("NIST-B409", ECCurve_NIST_B409); + ECTEST_NAMED_GF2M("NIST-K571", ECCurve_NIST_K571); + ECTEST_NAMED_GF2M("NIST-B571", ECCurve_NIST_B571); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V1", ECCurve_X9_62_CHAR2_PNB163V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V2", ECCurve_X9_62_CHAR2_PNB163V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V3", ECCurve_X9_62_CHAR2_PNB163V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB176V1", ECCurve_X9_62_CHAR2_PNB176V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V1", ECCurve_X9_62_CHAR2_TNB191V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V2", ECCurve_X9_62_CHAR2_TNB191V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V3", ECCurve_X9_62_CHAR2_TNB191V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB208W1", ECCurve_X9_62_CHAR2_PNB208W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V1", ECCurve_X9_62_CHAR2_TNB239V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V2", ECCurve_X9_62_CHAR2_TNB239V2); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V3", ECCurve_X9_62_CHAR2_TNB239V3); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB272W1", ECCurve_X9_62_CHAR2_PNB272W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB304W1", ECCurve_X9_62_CHAR2_PNB304W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB359V1", ECCurve_X9_62_CHAR2_TNB359V1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB368W1", ECCurve_X9_62_CHAR2_PNB368W1); + ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB431R1", ECCurve_X9_62_CHAR2_TNB431R1); + ECTEST_NAMED_GF2M("SECT-113R1", ECCurve_SECG_CHAR2_113R1); + ECTEST_NAMED_GF2M("SECT-113R2", ECCurve_SECG_CHAR2_113R2); + ECTEST_NAMED_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1); + ECTEST_NAMED_GF2M("SECT-131R2", ECCurve_SECG_CHAR2_131R2); ECTEST_NAMED_GF2M("SECT-163K1", ECCurve_SECG_CHAR2_163K1); ECTEST_NAMED_GF2M("SECT-163R1", ECCurve_SECG_CHAR2_163R1); ECTEST_NAMED_GF2M("SECT-163R2", ECCurve_SECG_CHAR2_163R2); @@ -462,6 +492,19 @@ main(int argv, char **argc) ECTEST_NAMED_GF2M("SECT-193R2", ECCurve_SECG_CHAR2_193R2); ECTEST_NAMED_GF2M("SECT-233K1", ECCurve_SECG_CHAR2_233K1); ECTEST_NAMED_GF2M("SECT-233R1", ECCurve_SECG_CHAR2_233R1); + ECTEST_NAMED_GF2M("SECT-239K1", ECCurve_SECG_CHAR2_239K1); + ECTEST_NAMED_GF2M("SECT-283K1", ECCurve_SECG_CHAR2_283K1); + ECTEST_NAMED_GF2M("SECT-283R1", ECCurve_SECG_CHAR2_283R1); + ECTEST_NAMED_GF2M("SECT-409K1", ECCurve_SECG_CHAR2_409K1); + ECTEST_NAMED_GF2M("SECT-409R1", ECCurve_SECG_CHAR2_409R1); + ECTEST_NAMED_GF2M("SECT-571K1", ECCurve_SECG_CHAR2_571K1); + ECTEST_NAMED_GF2M("SECT-571R1", ECCurve_SECG_CHAR2_571R1); + ECTEST_NAMED_GF2M("WTLS-1 (113)", ECCurve_WTLS_1); + ECTEST_NAMED_GF2M("WTLS-3 (163)", ECCurve_WTLS_3); + ECTEST_NAMED_GF2M("WTLS-4 (113)", ECCurve_WTLS_4); + ECTEST_NAMED_GF2M("WTLS-5 (163)", ECCurve_WTLS_5); + ECTEST_NAMED_GF2M("WTLS-10 (233)", ECCurve_WTLS_10); + ECTEST_NAMED_GF2M("WTLS-11 (233)", ECCurve_WTLS_11); CLEANUP: EC_FreeCurveParams(params); diff --git a/security/nss/lib/freebl/ecl/tests/ecp_test.c b/security/nss/lib/freebl/ecl/tests/ecp_test.c index d7ce299ec..eb2844fe5 100644 --- a/security/nss/lib/freebl/ecl/tests/ecp_test.c +++ b/security/nss/lib/freebl/ecl/tests/ecp_test.c @@ -417,6 +417,22 @@ main(int argv, char **argc) ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); /* specific arithmetic tests */ + ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192); + ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224); + ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256); + ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384); + ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3); + ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1); + ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1); + ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2); + ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1); + ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2); ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1); ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1); ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2); @@ -424,6 +440,15 @@ main(int argv, char **argc) ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1); ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1); ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1); + ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1); + ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1); + ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1); + ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1); + ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6); + ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7); + ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8); + ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9); + ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12); CLEANUP: EC_FreeCurveParams(params); diff --git a/security/nss/lib/freebl/freebl.rc b/security/nss/lib/freebl/freebl.rc index 4f60cba9f..39b0e70bc 100644 --- a/security/nss/lib/freebl/freebl.rc +++ b/security/nss/lib/freebl/freebl.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 2005 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/freebl/ldvector.c b/security/nss/lib/freebl/ldvector.c index 595d7dd8b..70a4eed50 100644 --- a/security/nss/lib/freebl/ldvector.c +++ b/security/nss/lib/freebl/ldvector.c @@ -222,6 +222,11 @@ static const struct FREEBLVectorStr vector = RNG_SystemInfoForRNG, /* End of Version 3.008. */ + + FIPS186Change_GenerateX, + FIPS186Change_ReduceModQForDSA, + + /* End of Version 3.009. */ }; const FREEBLVector * diff --git a/security/nss/lib/freebl/loader.c b/security/nss/lib/freebl/loader.c index b98ea9c68..2bce3bea2 100644 --- a/security/nss/lib/freebl/loader.c +++ b/security/nss/lib/freebl/loader.c @@ -125,20 +125,18 @@ static const char * getLibName(void) { return default_name; } #ifdef XP_UNIX #include <unistd.h> -#endif #define BL_MAXSYMLINKS 20 /* * If 'link' is a symbolic link, this function follows the symbolic links * and returns the pathname of the ultimate source of the symbolic links. - * If 'link' is not a symbolic link, this function returns a copy of 'link'. + * If 'link' is not a symbolic link, this function returns NULL. * The caller should call PR_Free to free the string returned by this * function. */ static char* bl_GetOriginalPathname(const char* link) { -#ifdef XP_UNIX char* resolved = NULL; char* input = NULL; PRUint32 iterations = 0; @@ -168,16 +166,13 @@ static char* bl_GetOriginalPathname(const char* link) resolved = tmp; } PR_Free(resolved); - return input; -#else - if (link) { - return PL_strdup(link); - } else { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; + if (iterations == 1 && retlen < 0) { + PR_Free(input); + input = NULL; } -#endif + return input; } +#endif /* XP_UNIX */ /* * We use PR_GetLibraryFilePathname to get the pathname of the loaded @@ -192,26 +187,49 @@ static char* bl_GetOriginalPathname(const char* link) const char* softoken=SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX; -typedef struct { - PRLibrary *dlh; -} BLLibrary; +static PRLibrary* blLib; + +/* + * Load the freebl library with the file name 'name' residing in the same + * directory as libsoftoken, whose pathname is 'softokenPath'. + */ +static PRLibrary * +bl_LoadFreeblLibInSoftokenDir(const char *softokenPath, const char *name) +{ + PRLibrary *dlh = NULL; + char *fullName = NULL; + char* c; + PRLibSpec libSpec; + + /* Remove "libsoftokn" from the pathname and add the freebl libname */ + c = strrchr(softokenPath, PR_GetDirectorySeparator()); + if (c) { + size_t softoknPathSize = 1 + c - softokenPath; + fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); + if (fullName) { + memcpy(fullName, softokenPath, softoknPathSize); + strcpy(fullName + softoknPathSize, name); +#ifdef DEBUG_LOADER + PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", + fullName); +#endif + libSpec.type = PR_LibSpec_Pathname; + libSpec.value.pathname = fullName; + dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + PORT_Free(fullName); + } + } + return dlh; +} -static BLLibrary * +static PRLibrary * bl_LoadLibrary(const char *name) { - BLLibrary *lib = NULL; + PRLibrary *lib = NULL; PRFuncPtr fn_addr; char* softokenPath = NULL; - char* fullName = NULL; PRLibSpec libSpec; - libSpec.type = PR_LibSpec_Pathname; - lib = PR_NEWZAP(BLLibrary); - if (NULL == lib) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - /* Get the pathname for the loaded libsoftokn, i.e. /usr/lib/libsoftokn3.so * PR_GetLibraryFilePathname works with either the base library name or a * function pointer, depending on the platform. We can't query an exported @@ -222,70 +240,40 @@ bl_LoadLibrary(const char *name) fn_addr = (PRFuncPtr) &bl_LoadLibrary; softokenPath = PR_GetLibraryFilePathname(softoken, fn_addr); - /* Remove "libsoftokn" from the pathname and add the freebl libname */ if (softokenPath) { - char* c; - char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); - if (originalSoftokenPath) { - PR_Free(softokenPath); - softokenPath = originalSoftokenPath; - } - c = strrchr(softokenPath, PR_GetDirectorySeparator()); - if (c) { - size_t softoknPathSize = 1 + c - softokenPath; - fullName = (char*) PORT_Alloc(strlen(name) + softoknPathSize + 1); - if (fullName) { - memcpy(fullName, softokenPath, softoknPathSize); - strcpy(fullName + softoknPathSize, name); - } - } - PR_Free(softokenPath); - } - if (fullName) { -#ifdef DEBUG_LOADER - PR_fprintf(PR_STDOUT, "\nAttempting to load fully-qualified %s\n", - fullName); + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); +#ifdef XP_UNIX + if (!lib) { + /* + * If softokenPath is a symbolic link, resolve the symbolic + * link and try again. + */ + char* originalSoftokenPath = bl_GetOriginalPathname(softokenPath); + if (originalSoftokenPath) { + PR_Free(softokenPath); + softokenPath = originalSoftokenPath; + lib = bl_LoadFreeblLibInSoftokenDir(softokenPath, name); + } + } #endif - libSpec.value.pathname = fullName; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); - PORT_Free(fullName); + PR_Free(softokenPath); } - if (!lib->dlh) { + if (!lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nAttempting to load %s\n", name); #endif + libSpec.type = PR_LibSpec_Pathname; libSpec.value.pathname = name; - lib->dlh = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); + lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL); } - if (NULL == lib->dlh) { + if (NULL == lib) { #ifdef DEBUG_LOADER PR_fprintf(PR_STDOUT, "\nLoading failed : %s.\n", name); #endif - PR_Free(lib); - lib = NULL; } return lib; } -static void * -bl_FindSymbol(BLLibrary *lib, const char *name) -{ - void *f; - - f = PR_FindSymbol(lib->dlh, name); - return f; -} - -static PRStatus -bl_UnloadLibrary(BLLibrary *lib) -{ - if (PR_SUCCESS != PR_UnloadLibrary(lib->dlh)) { - return PR_FAILURE; - } - PR_Free(lib); - return PR_SUCCESS; -} - #define LSB(x) ((x)&0xff) #define MSB(x) ((x)>>8) @@ -297,7 +285,7 @@ static const char *libraryName = NULL; static PRStatus freebl_LoadDSO( void ) { - BLLibrary * handle; + PRLibrary * handle; const char * name = getLibName(); if (!name) { @@ -307,7 +295,8 @@ freebl_LoadDSO( void ) handle = bl_LoadLibrary(name); if (handle) { - void * address = bl_FindSymbol(handle, "FREEBL_GetVector"); + PRFuncPtr address = PR_FindFunctionSymbol(handle, "FREEBL_GetVector"); + PRStatus status; if (address) { FREEBLGetVectorFn * getVector = (FREEBLGetVectorFn *)address; const FREEBLVector * dsoVector = getVector(); @@ -319,22 +308,26 @@ freebl_LoadDSO( void ) dsoVector->length >= sizeof(FREEBLVector)) { vector = dsoVector; libraryName = name; + blLib = handle; return PR_SUCCESS; } } } - bl_UnloadLibrary(handle); + status = PR_UnloadLibrary(handle); + PORT_Assert(PR_SUCCESS == status); } return PR_FAILURE; } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType loadFreeBLOnce; + static PRStatus freebl_RunLoaderOnce( void ) { PRStatus status; - static PRCallOnceType once; - status = PR_CallOnce(&once, &freebl_LoadDSO); + status = PR_CallOnce(&loadFreeBLOnce, &freebl_LoadDSO); return status; } @@ -987,6 +980,25 @@ BL_Cleanup(void) (vector->p_BL_Cleanup)(); } +void +BL_Unload(void) +{ + /* This function is not thread-safe, but doesn't need to be, because it is + * only called from functions that are also defined as not thread-safe, + * namely C_Finalize in softoken, and the SSL bypass shutdown callback called + * from NSS_Shutdown. */ + vector = NULL; + /* If an SSL socket is configured with SSL_BYPASS_PKCS11, but the application + * never does a handshake on it, BL_Unload will be called even though freebl + * was never loaded. So, don't assert blLib. */ + if (blLib) { + PRStatus status = PR_UnloadLibrary(blLib); + PORT_Assert(PR_SUCCESS == status); + blLib = NULL; + } + loadFreeBLOnce = pristineCallOnce; +} + /* ============== New for 3.003 =============================== */ SECStatus @@ -1614,3 +1626,22 @@ RNG_SystemInfoForRNG(void) (vector->p_RNG_SystemInfoForRNG)(); } + +SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, const unsigned char *XSEEDj, + unsigned char *x_j) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) + return SECFailure; + return (vector->p_FIPS186Change_GenerateX)(XKEY, XSEEDj, x_j); +} + +SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj) +{ + if (!vector && PR_SUCCESS != freebl_RunLoaderOnce()) + return SECFailure; + return (vector->p_FIPS186Change_ReduceModQForDSA)(w, q, xj); +} diff --git a/security/nss/lib/freebl/loader.h b/security/nss/lib/freebl/loader.h index 89bab5401..df7c5c99b 100644 --- a/security/nss/lib/freebl/loader.h +++ b/security/nss/lib/freebl/loader.h @@ -44,7 +44,7 @@ #include "blapi.h" -#define FREEBL_VERSION 0x0308 +#define FREEBL_VERSION 0x0309 struct FREEBLVectorStr { @@ -449,6 +449,15 @@ struct FREEBLVectorStr { void (* p_RNG_SystemInfoForRNG)(void); /* Version 3.008 came to here */ + + SECStatus (* p_FIPS186Change_GenerateX)(unsigned char *XKEY, + const unsigned char *XSEEDj, + unsigned char *x_j); + SECStatus (* p_FIPS186Change_ReduceModQForDSA)(const unsigned char *w, + const unsigned char *q, + unsigned char *xj); + + /* Version 3.009 came to here */ }; typedef struct FREEBLVectorStr FREEBLVector; diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index 787c7fbec..8e172c426 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -104,11 +104,13 @@ MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h ifdef NSS_ENABLE_ECC ECL_SRCS = ecl.c ecl_curve.c ecl_mult.c ecl_gf.c \ - ec2_aff.c ec2_mont.c ec2_proj.c \ - ec2_163.c ec2_193.c ec2_233.c \ ecp_aff.c ecp_jac.c ecp_mont.c \ - ecp_192.c ecp_224.c \ ec_naf.c ecp_jm.c +ifdef NSS_ECC_MORE_THAN_SUITE_B +ECL_SRCS += ec2_aff.c ec2_mont.c ec2_proj.c \ + ec2_163.c ec2_193.c ec2_233.c \ + ecp_192.c ecp_224.c ecp_256.c ecp_384.c ecp_521.c +endif else ECL_SRCS = $(NULL) endif @@ -158,6 +160,7 @@ ALL_HDRS = \ secmpi.h \ sha.h \ sha_fast.h \ + sha256.h \ shsign.h \ vis_proto.h \ $(NULL) diff --git a/security/nss/lib/freebl/mpi/Makefile b/security/nss/lib/freebl/mpi/Makefile index 3c780f5ac..4716f6ac5 100644 --- a/security/nss/lib/freebl/mpi/Makefile +++ b/security/nss/lib/freebl/mpi/Makefile @@ -112,7 +112,7 @@ DOCS=README doc utils/README utils/PRIMES TOOLS=gcd invmod isprime lap dec2hex hex2dec primegen prng \ basecvt fact exptmod pi makeprime identest -LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o $(AS_OBJS) +LIBOBJS = mpprime.o mpmontg.o mplogic.o mp_gf2m.o mpi.o mpcpucache.o $(AS_OBJS) LIBHDRS = mpi-config.h mpi-priv.h mpi.h APPHDRS = mpi-config.h mpi.h mplogic.h mp_gf2m.h mpprime.h @@ -154,6 +154,8 @@ mpmontg.o: mpmontg.c mpi-priv.h mplogic.h mpprime.h $(LIBHDRS) mpprime.o: mpprime.c mpi-priv.h mpprime.h mplogic.h primes.c $(LIBHDRS) +mpcpucache.o: mpcpucache.c $(LIBHDRS) + mpi_mips.o: mpi_mips.s $(CC) -o $@ $(ASFLAGS) -c mpi_mips.s diff --git a/security/nss/lib/freebl/mpi/mp_gf2m.c b/security/nss/lib/freebl/mpi/mp_gf2m.c index 962fdb1fb..5ce9fed9e 100644 --- a/security/nss/lib/freebl/mpi/mp_gf2m.c +++ b/security/nss/lib/freebl/mpi/mp_gf2m.c @@ -92,7 +92,7 @@ s_bmul_1x1(mp_digit *rh, mp_digit *rl, const mp_digit a, const mp_digit b) mp_digit tab[16], top3b = a >> 61; register mp_digit a1, a2, a4, a8; - a1 = a & (0x1FFFFFFFFFFFFFFF); a2 = a1 << 1; + a1 = a & (0x1FFFFFFFFFFFFFFFULL); a2 = a1 << 1; a4 = a2 << 1; a8 = a4 << 1; tab[ 0] = 0; tab[ 1] = a1; tab[ 2] = a2; tab[ 3] = a1^a2; tab[ 4] = a4; tab[ 5] = a1^a4; tab[ 6] = a2^a4; tab[ 7] = a1^a2^a4; diff --git a/security/nss/lib/freebl/mpi/mpi.c b/security/nss/lib/freebl/mpi/mpi.c index f9602c6aa..2ea3ad15e 100644 --- a/security/nss/lib/freebl/mpi/mpi.c +++ b/security/nss/lib/freebl/mpi/mpi.c @@ -4759,6 +4759,8 @@ mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_unsigned_octets() */ /* }}} */ @@ -4797,6 +4799,8 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return pos; } /* end mp_to_signed_octets() */ /* }}} */ @@ -4832,6 +4836,8 @@ mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) str[pos++] = x; } } + if (!pos) + str[pos++] = 0; return MP_OKAY; } /* end mp_to_fixlen_octets() */ /* }}} */ diff --git a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s index 7515ac20a..86e16e362 100644 --- a/security/nss/lib/freebl/mpi/mpi_amd64_gas.s +++ b/security/nss/lib/freebl/mpi/mpi_amd64_gas.s @@ -416,3 +416,7 @@ ret .size s_mpv_mul_add_vec64, [.-s_mpv_mul_add_vec64] + +# Magic indicating no need for an executable stack +.section .note.GNU-stack, "", @progbits +.previous diff --git a/security/nss/lib/freebl/mpi/mpi_sparc.c b/security/nss/lib/freebl/mpi/mpi_sparc.c index eb2317dd0..f7eb19c19 100644 --- a/security/nss/lib/freebl/mpi/mpi_sparc.c +++ b/security/nss/lib/freebl/mpi/mpi_sparc.c @@ -177,11 +177,11 @@ v8_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) #endif } -/* vis versions of these functions run only on v8+vis or v9+vis CPUs. */ +/* These functions run only on v8plus+vis or v9+vis CPUs. */ /* c = a * b */ -static void -vis_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -204,8 +204,8 @@ vis_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) } /* c += a * b, where a is a_len words long. */ -static void -vis_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -227,9 +227,8 @@ vis_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) } /* c += a * b, where a is y words long. */ -static void -vis_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, - mp_digit *c) +void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) { mp_digit d; mp_digit x[258]; @@ -256,106 +255,3 @@ vis_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, v8_mpv_mul_d_add_prop(a, a_len, b, c); } } - -#if defined(SOLARIS2_5) -static int -isSparcV8PlusVis(void) -{ - long buflen; - int rv = 0; /* false */ - char buf[256]; - buflen = sysinfo(SI_MACHINE, buf, sizeof buf); - if (buflen > 0) { - rv = (!strcmp(buf, "sun4u") || !strcmp(buf, "sun4u1")); - } - return rv; -} -#else /* SunOS2.6or higher has SI_ISALIST */ - -static int -isSparcV8PlusVis(void) -{ - long buflen; - int rv = 0; /* false */ - char buf[256]; - buflen = sysinfo(SI_ISALIST, buf, sizeof buf); - if (buflen > 0) { -#if defined(MP_USE_LONG_DIGIT) - char * found = strstr(buf, "sparcv9+vis"); -#else - char * found = strstr(buf, "sparcv8plus+vis"); -#endif - rv = (found != 0); - } - return rv; -} -#endif - -typedef void MPVmpy(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c); - -/* forward static function declarations */ -static MPVmpy sp_mpv_mul_d; -static MPVmpy sp_mpv_mul_d_add; -static MPVmpy sp_mpv_mul_d_add_prop; - -static MPVmpy *p_mpv_mul_d = &sp_mpv_mul_d; -static MPVmpy *p_mpv_mul_d_add = &sp_mpv_mul_d_add; -static MPVmpy *p_mpv_mul_d_add_prop = &sp_mpv_mul_d_add_prop; - -static void -initPtrs(void) -{ - if (isSparcV8PlusVis()) { - p_mpv_mul_d = &vis_mpv_mul_d; - p_mpv_mul_d_add = &vis_mpv_mul_d_add; - p_mpv_mul_d_add_prop = &vis_mpv_mul_d_add_prop; - } else { - p_mpv_mul_d = &v8_mpv_mul_d; - p_mpv_mul_d_add = &v8_mpv_mul_d_add; - p_mpv_mul_d_add_prop = &v8_mpv_mul_d_add_prop; - } -} - -static void -sp_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d)(a, a_len, b, c); -} - -static void -sp_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d_add)(a, a_len, b, c); -} - -static void -sp_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - initPtrs(); - (* p_mpv_mul_d_add_prop)(a, a_len, b, c); -} - - -/* This is the external interface */ - -void -s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d)(a, a_len, b, c); -} - -void -s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d_add)(a, a_len, b, c); -} - -void -s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) -{ - (* p_mpv_mul_d_add_prop)(a, a_len, b, c); -} - - diff --git a/security/nss/lib/freebl/mpi/mpi_x86.asm b/security/nss/lib/freebl/mpi/mpi_x86.asm deleted file mode 100644 index 826747c39..000000000 --- a/security/nss/lib/freebl/mpi/mpi_x86.asm +++ /dev/null @@ -1,356 +0,0 @@ -; -; mpi_x86.asm - assembly language implementation of s_mpv_ functions. -; -; ***** 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) 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 ***** - -; $Id$ - - .386p - .MODEL FLAT - ASSUME CS: FLAT, DS: FLAT, SS: FLAT -_TEXT SEGMENT - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr - -public _s_mpv_mul_d -_s_mpv_mul_d PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_2 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a - cld -L_1: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_1 ; jmp if a_len != 0 -L_2: - mov [edi],ebx ; *c = carry - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d ENDP - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -public _s_mpv_mul_d_add -_s_mpv_mul_d_add PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_4 ; jmp if a_len == 0 - mov esi,[ebp+8] ; esi = a - cld -L_3: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_3 ; jmp if a_len != 0 -L_4: - mov [edi],ebx ; *c = carry - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d_add ENDP - -; ebp - 36: caller's esi -; ebp - 32: caller's edi -; ebp - 28: -; ebp - 24: -; ebp - 20: -; ebp - 16: -; ebp - 12: -; ebp - 8: -; ebp - 4: -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: a argument -; ebp + 12: a_len argument -; ebp + 16: b argument -; ebp + 20: c argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -public _s_mpv_mul_d_add_prop -_s_mpv_mul_d_add_prop PROC NEAR - push ebp - mov ebp,esp - sub esp,28 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; ecx = a_len - mov edi,[ebp+20] - cmp ecx,0 - je L_6 ; jmp if a_len == 0 - cld - mov esi,[ebp+8] ; esi = a -L_5: - lodsd ; eax = [ds:esi]; esi += 4 - mov edx,[ebp+16] ; edx = b - mul edx ; edx:eax = Phi:Plo = a_i * b - - add eax,ebx ; add carry (ebx) to edx:eax - adc edx,0 - mov ebx,[edi] ; add in current word from *c - add eax,ebx - adc edx,0 - mov ebx,edx ; high half of product becomes next carry - - stosd ; [es:edi] = ax; edi += 4; - dec ecx ; --a_len - jnz L_5 ; jmp if a_len != 0 -L_6: - cmp ebx,0 ; is carry zero? - jz L_8 - mov eax,[edi] ; add in current word from *c - add eax,ebx - stosd ; [es:edi] = ax; edi += 4; - jnc L_8 -L_7: - mov eax,[edi] ; add in current word from *c - adc eax,0 - stosd ; [es:edi] = ax; edi += 4; - jc L_7 -L_8: - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_mul_d_add_prop ENDP - -; ebp - 20: caller's esi -; ebp - 16: caller's edi -; ebp - 12: -; ebp - 8: carry -; ebp - 4: a_len local -; ebp + 0: caller's ebp -; ebp + 4: return address -; ebp + 8: pa argument -; ebp + 12: a_len argument -; ebp + 16: ps argument -; ebp + 20: -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr - -public _s_mpv_sqr_add_prop -_s_mpv_sqr_add_prop PROC NEAR - push ebp - mov ebp,esp - sub esp,12 - push edi - push esi - push ebx - mov ebx,0 ; carry = 0 - mov ecx,[ebp+12] ; a_len - mov edi,[ebp+16] ; edi = ps - cmp ecx,0 - je L_11 ; jump if a_len == 0 - cld - mov esi,[ebp+8] ; esi = pa -L_10: - lodsd ; eax = [ds:si]; si += 4; - mul eax - - add eax,ebx ; add "carry" - adc edx,0 - mov ebx,[edi] - add eax,ebx ; add low word from result - mov ebx,[edi+4] - stosd ; [es:di] = eax; di += 4; - adc edx,ebx ; add high word from result - mov ebx,0 - mov eax,edx - adc ebx,0 - stosd ; [es:di] = eax; di += 4; - dec ecx ; --a_len - jnz L_10 ; jmp if a_len != 0 -L_11: - cmp ebx,0 ; is carry zero? - jz L_14 - mov eax,[edi] ; add in current word from *c - add eax,ebx - stosd ; [es:edi] = ax; edi += 4; - jnc L_14 -L_12: - mov eax,[edi] ; add in current word from *c - adc eax,0 - stosd ; [es:edi] = ax; edi += 4; - jc L_12 -L_14: - pop ebx - pop esi - pop edi - leave - ret - nop -_s_mpv_sqr_add_prop ENDP - -; -; Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized -; so its high bit is 1. This code is from NSPR. -; -; mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, -; mp_digit *qp, mp_digit *rp) - -; Dump of assembler code for function s_mpv_div_2dx1d: -; -; esp + 0: Caller's ebx -; esp + 4: return address -; esp + 8: Nhi argument -; esp + 12: Nlo argument -; esp + 16: divisor argument -; esp + 20: qp argument -; esp + 24: rp argument -; registers: -; eax: -; ebx: carry -; ecx: a_len -; edx: -; esi: a ptr -; edi: c ptr -; -public _s_mpv_div_2dx1d -_s_mpv_div_2dx1d PROC NEAR - push ebx - mov edx,[esp+8] - mov eax,[esp+12] - mov ebx,[esp+16] - div ebx - mov ebx,[esp+20] - mov [ebx],eax - mov ebx,[esp+24] - mov [ebx],edx - xor eax,eax ; return zero - pop ebx - ret - nop -_s_mpv_div_2dx1d ENDP - -_TEXT ENDS -END diff --git a/security/nss/lib/freebl/mpi/mpi_x86_asm.c b/security/nss/lib/freebl/mpi/mpi_x86_asm.c new file mode 100644 index 000000000..b8a224f14 --- /dev/null +++ b/security/nss/lib/freebl/mpi/mpi_x86_asm.c @@ -0,0 +1,368 @@ +/* + * mpi_x86.c - MSVC inline assembly implementation of s_mpv_ functions. + * + * ***** 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) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Benjamin Smedberg <benjamin@smedbergs.us> + * + * 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 "mpi-priv.h" + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_2 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a + cld +L_1: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_1 ; jmp if a_len != 0 +L_2: + mov [edi],ebx ; *c = carry + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_4 ; jmp if a_len == 0 + mov esi,[ebp+8] ; esi = a + cld +L_3: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,[edi] ; add in current word from *c + add eax,ebx + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_3 ; jmp if a_len != 0 +L_4: + mov [edi],ebx ; *c = carry + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 36: caller's esi + * ebp - 32: caller's edi + * ebp - 28: + * ebp - 24: + * ebp - 20: + * ebp - 16: + * ebp - 12: + * ebp - 8: + * ebp - 4: + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: a argument + * ebp + 12: a_len argument + * ebp + 16: b argument + * ebp + 20: c argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c) +{ + __asm { + push ebp + mov ebp,esp + sub esp,28 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; ecx = a_len + mov edi,[ebp+20] + cmp ecx,0 + je L_6 ; jmp if a_len == 0 + cld + mov esi,[ebp+8] ; esi = a +L_5: + lodsd ; eax = [ds:esi]; esi += 4 + mov edx,[ebp+16] ; edx = b + mul edx ; edx:eax = Phi:Plo = a_i * b + + add eax,ebx ; add carry (ebx) to edx:eax + adc edx,0 + mov ebx,[edi] ; add in current word from *c + add eax,ebx + adc edx,0 + mov ebx,edx ; high half of product becomes next carry + + stosd ; [es:edi] = ax; edi += 4; + dec ecx ; --a_len + jnz L_5 ; jmp if a_len != 0 +L_6: + cmp ebx,0 ; is carry zero? + jz L_8 + mov eax,[edi] ; add in current word from *c + add eax,ebx + stosd ; [es:edi] = ax; edi += 4; + jnc L_8 +L_7: + mov eax,[edi] ; add in current word from *c + adc eax,0 + stosd ; [es:edi] = ax; edi += 4; + jc L_7 +L_8: + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * ebp - 20: caller's esi + * ebp - 16: caller's edi + * ebp - 12: + * ebp - 8: carry + * ebp - 4: a_len local + * ebp + 0: caller's ebp + * ebp + 4: return address + * ebp + 8: pa argument + * ebp + 12: a_len argument + * ebp + 16: ps argument + * ebp + 20: + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) void +s_mpv_sqr_add_prop(const mp_digit *a, mp_size a_len, mp_digit *sqrs) +{ + __asm { + push ebp + mov ebp,esp + sub esp,12 + push edi + push esi + push ebx + mov ebx,0 ; carry = 0 + mov ecx,[ebp+12] ; a_len + mov edi,[ebp+16] ; edi = ps + cmp ecx,0 + je L_11 ; jump if a_len == 0 + cld + mov esi,[ebp+8] ; esi = pa +L_10: + lodsd ; eax = [ds:si]; si += 4; + mul eax + + add eax,ebx ; add "carry" + adc edx,0 + mov ebx,[edi] + add eax,ebx ; add low word from result + mov ebx,[edi+4] + stosd ; [es:di] = eax; di += 4; + adc edx,ebx ; add high word from result + mov ebx,0 + mov eax,edx + adc ebx,0 + stosd ; [es:di] = eax; di += 4; + dec ecx ; --a_len + jnz L_10 ; jmp if a_len != 0 +L_11: + cmp ebx,0 ; is carry zero? + jz L_14 + mov eax,[edi] ; add in current word from *c + add eax,ebx + stosd ; [es:edi] = ax; edi += 4; + jnc L_14 +L_12: + mov eax,[edi] ; add in current word from *c + adc eax,0 + stosd ; [es:edi] = ax; edi += 4; + jc L_12 +L_14: + pop ebx + pop esi + pop edi + leave + ret + nop + } +} + +/* + * Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized + * so its high bit is 1. This code is from NSPR. + * + * Dump of assembler code for function s_mpv_div_2dx1d: + * + * esp + 0: Caller's ebx + * esp + 4: return address + * esp + 8: Nhi argument + * esp + 12: Nlo argument + * esp + 16: divisor argument + * esp + 20: qp argument + * esp + 24: rp argument + * registers: + * eax: + * ebx: carry + * ecx: a_len + * edx: + * esi: a ptr + * edi: c ptr + */ +__declspec(naked) mp_err +s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor, + mp_digit *qp, mp_digit *rp) +{ + __asm { + push ebx + mov edx,[esp+8] + mov eax,[esp+12] + mov ebx,[esp+16] + div ebx + mov ebx,[esp+20] + mov [ebx],eax + mov ebx,[esp+24] + mov [ebx],edx + xor eax,eax ; return zero + pop ebx + ret + nop + } +} diff --git a/security/nss/lib/freebl/mpi/mpmontg.c b/security/nss/lib/freebl/mpi/mpmontg.c index 1e0f0fd6d..bea8009c2 100644 --- a/security/nss/lib/freebl/mpi/mpmontg.c +++ b/security/nss/lib/freebl/mpi/mpmontg.c @@ -60,8 +60,8 @@ /* if MP_CHAR_STORE_SLOW is defined, we */ /* need to know endianness of this platform. */ #ifdef MP_CHAR_STORE_SLOW -#if !defined(MPI_IS_BIG_ENDIAN) && !defined(MPI_IS_LITTLE_ENDIAN) -#error "You must define MPI_IS_BIG_ENDIAN or MPI_IS_LITTLE_ENDIAN\n" \ +#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN) +#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \ " if you define MP_CHAR_STORE_SLOW." #endif #endif @@ -541,108 +541,106 @@ mp_err mp_set_safe_modexp(int value) #ifndef MP_CHAR_STORE_SLOW /* - * mpi_to_weave takes MPI data and stores in into a byte array interleaved. + * mpi_to_weave takes an array of bignums, a matrix in which each bignum + * occupies all the columns of a row, and transposes it into a matrix in + * which each bignum occupies a column of every row. The first row of the + * input matrix becomes the first column of the output matrix. The n'th + * row of input becomes the n'th column of output. The input data is said + * to be "interleaved" or "woven" into the output matrix. * - * The purpose of this interleaving is to hide our access to the array of - * modulus powers from and attacker snooping on cache hits and misses. Because - * the array is interleaved, each reference will cause exactly the same cache - * lines to reload. + * The array of bignums is left in this woven form. Each time a single + * bignum value is needed, it is recreated by fetching the n'th column, + * forming a single row which is the new bignum. * - * There are 2 different implementations in this file, one which works with just - * byte loads and stores, the second which works with mp_weave_word loads and - * stores. These 2 implementations have DIFFERENT results in exactly which byte - * of an mp_digit winds up in which location in the byte array. That is why - * there are 2 sets of explanations for how the array is set up. + * The purpose of this interleaving is make it impossible to determine which + * of the bignums is being used in any one operation by examining the pattern + * of cache misses. * + * The weaving function does not transpose the entire input matrix in one call. + * It transposes 4 rows of mp_ints into their respective columns of output. * - * a is an array of WEAVE_WORD_SIZE mp_ints (that is 4). - * It is a partial window into a logical array mp_int p[count] containing - * the base to the 0 through count-1 powers. Ideally this code would be - * simpler if we stored one element of that array at a time, but on some - * platforms the cost of storing a byte incurs a full read modify write cycle - * and increases the memory bandwidth cost by a factor of 4 or 8. By collecting - * for mp_ints together, we can arrange to store all 4 values in a single - * word write. - * - * b is the targeted weaved location. b[0] points to the first byte where - * first byte of the a array needs to be stored. Each b is an offset into the - * weave array. - * - * count is 2^window size. - * - * b_size is the size in mp_digits of each mp_int in the array. mp_ints - * with less than b_size elements are logically padded with zeros before - * storing. + * There are two different implementations of the weaving and unweaving code + * in this file. One uses byte loads and stores. The second uses loads and + * stores of mp_weave_word size values. The weaved forms of these two + * implementations differ. Consequently, each one has its own explanation. * + * Here is the explanation for the byte-at-a-time implementation. * - * Data is stored as follows : - * The mp_int array is treated as a byte array. + * This implementation treats each mp_int bignum as an array of bytes, + * rather than as an array of mp_digits. It stores those bytes as a + * column of bytes in the output matrix. It doesn't care if the machine + * uses big-endian or little-endian byte ordering within mp_digits. + * The first byte of the mp_digit array becomes the first byte in the output + * column, regardless of whether that byte is the MSB or LSB of the mp_digit. * + * "bignums" is an array of mp_ints. + * It points to four rows, four mp_ints, a subset of a larger array of mp_ints. * - * we want to eventually store the logical array mp_int p[count] into the - * weave array as follows: - - * p[count].digit is treated as a byte array (rather than * an mp_digit array), - * N is count, and n is b_size * *sizeof(mp_digit): - * - * p[0].digit[0] p[1].digit[0] ...... p[N-2].digit[0] p[N-1].digit[0] - * p[0].digit[1] p[1].digit[1] ...... p[N-2].digit[1] p[N-1].digit[1] - * . . - * . . - * p[0].digit[n-2] p[1].digit[n-2] ...... p[N-2].digit[n-2] p[N-1].digit[n-2] - * p[0].digit[n-1] p[1].digit[n-1] ...... p[N-2].digit[n-1] p[N-1].digit[n-1] + * "weaved" is the weaved output matrix. + * The first byte of bignums[0] is stored in weaved[0]. + * + * "nBignums" is the total number of bignums in the array of which "bignums" + * is a part. * - * This function stores that a window of p in each call. + * "nDigits" is the size in mp_digits of each mp_int in the "bignums" array. + * mp_ints that use less than nDigits digits are logically padded with zeros + * while being stored in the weaved array. */ -mp_err mpi_to_weave(const mp_int *a, unsigned char *b, - mp_size b_size, mp_size count) +mp_err mpi_to_weave(const mp_int *bignums, + unsigned char *weaved, + mp_size nDigits, /* in each mp_int of input */ + mp_size nBignums) /* in the entire source array */ { - mp_size i, j; - unsigned char *bsave = b; + mp_size i; + unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit)); for (i=0; i < WEAVE_WORD_SIZE; i++) { - unsigned char *pb = (unsigned char *)MP_DIGITS(&a[i]); - mp_size useda = MP_USED(&a[i]); - mp_size zero = b_size - useda; - unsigned char *end = pb+ (useda*sizeof(mp_digit)); - b = bsave+i; - + mp_size used = MP_USED(&bignums[i]); + unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]); + unsigned char *endSrc = pSrc + (used * sizeof(mp_digit)); + unsigned char *pDest = weaved + i; - ARGCHK(MP_SIGN(&a[i]) == MP_ZPOS, MP_BADARG); - ARGCHK(useda <= b_size, MP_BADARG); + ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG); + ARGCHK(used <= nDigits, MP_BADARG); - for (; pb < end; pb++) { - *b = *pb; - b += count; + for (; pSrc < endSrc; pSrc++) { + *pDest = *pSrc; + pDest += nBignums; } - for (j=0; j < zero; j++) { - *b = 0; - b += count; + while (pDest < endDest) { + *pDest = 0; + pDest += nBignums; } } return MP_OKAY; } -/* reverse the operation above for one entry. - * b points to the offset into the weave array of the power we are - * calculating */ -mp_err weave_to_mpi(mp_int *a, const unsigned char *b, - mp_size b_size, mp_size count) +/* Reverse the operation above for one mp_int. + * Reconstruct one mp_int from its column in the weaved array. + * "pSrc" points to the offset into the weave array of the bignum we + * are going to reconstruct. + */ +mp_err weave_to_mpi(mp_int *a, /* output, result */ + const unsigned char *pSrc, /* input, byte matrix */ + mp_size nDigits, /* per mp_int output */ + mp_size nBignums) /* bignums in weaved matrix */ { - unsigned char *pb = (unsigned char *)MP_DIGITS(a); - unsigned char *end = pb+ (b_size*sizeof(mp_digit)); + unsigned char *pDest = (unsigned char *)MP_DIGITS(a); + unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit)); MP_SIGN(a) = MP_ZPOS; - MP_USED(a) = b_size; + MP_USED(a) = nDigits; - for (; pb < end; b+=count, pb++) { - *pb = *b; + for (; pDest < endDest; pSrc += nBignums, pDest++) { + *pDest = *pSrc; } s_mp_clamp(a); return MP_OKAY; } + #else + /* Need a primitive that we know is 32 bits long... */ /* this is true on all modern processors we know of today*/ typedef unsigned int mp_weave_word; @@ -703,8 +701,8 @@ mp_err mpi_to_weave(const mp_int *a, unsigned char *b, count = count/sizeof(mp_weave_word); /* this code pretty much depends on this ! */ -#if MP_ARGCHK < 2 - assert(WEAVE_WORD_SIZE == 4); +#if MP_ARGCHK == 2 + assert(WEAVE_WORD_SIZE == 4); assert(sizeof(mp_weave_word) == 4); #endif @@ -754,19 +752,19 @@ mp_err mpi_to_weave(const mp_int *a, unsigned char *b, * NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE * is 4. */ -#ifdef IS_LITTLE_ENDIAN +#ifdef MP_IS_LITTLE_ENDIAN #define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BITS-32)) & 0xff000000; d3 <<= 8; /*b3*/ \ + acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \ + acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \ + acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \ + acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \ *weaved = acc; weaved += count; #else #define MPI_WEAVE_ONE_STEP \ - acc = (d0 >> (MP_DIGIT_BITS-32)) & 0xff000000; d0 <<= 8; /*b0*/ \ - acc |= (d1 >> (MP_DIGIT_BITS-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \ - acc |= (d2 >> (MP_DIGIT_BITS-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \ - acc |= (d3 >> (MP_DIGIT_BITS-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \ + acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \ + acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \ + acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \ + acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \ *weaved = acc; weaved += count; #endif switch (sizeof(mp_digit)) { @@ -898,7 +896,7 @@ mp_err weave_to_mpi(mp_int *a, const unsigned char *b, MUL_NOWEAVE(&tmp,a,b) #define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp -#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(~((y)-1))) +#define MP_ALIGN(x,y) ((((ptrdiff_t)(x))+((y)-1))&(((ptrdiff_t)0)-(y))) /* Do modular exponentiation using integer multiply code. */ mp_err mp_exptmod_safe_i(const mp_int * montBase, @@ -921,6 +919,14 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, unsigned char *powersArray; unsigned char *powers; + MP_DIGITS(&accum1) = 0; + MP_DIGITS(&accum2) = 0; + MP_DIGITS(&accum[0]) = 0; + MP_DIGITS(&accum[1]) = 0; + MP_DIGITS(&accum[2]) = 0; + MP_DIGITS(&accum[3]) = 0; + MP_DIGITS(&tmp) = 0; + powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1)); if (powersArray == NULL) { res = MP_MEM; @@ -930,13 +936,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, /* powers[i] = base ** (i); */ powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); - MP_DIGITS(&accum1) = 0; - MP_DIGITS(&accum2) = 0; - MP_DIGITS(&accum[0]) = 0; - MP_DIGITS(&accum[1]) = 0; - MP_DIGITS(&accum[2]) = 0; - MP_DIGITS(&accum[3]) = 0; - /* grab the first window value. This allows us to preload accumulator1 * and save a conversion, some squares and a multiple*/ MP_CHECKOK( mpl_get_bits(exponent, @@ -945,7 +944,6 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase, MP_CHECKOK( mp_init_size(&accum1, 3 * nLen + 2) ); MP_CHECKOK( mp_init_size(&accum2, 3 * nLen + 2) ); - MP_DIGITS(&tmp) = 0; MP_CHECKOK( mp_init_size(&tmp, 3 * nLen + 2) ); /* build the first WEAVE_WORD powers inline */ @@ -1070,6 +1068,7 @@ CLEANUP: mp_clear(&accum[1]); mp_clear(&accum[2]); mp_clear(&accum[3]); + mp_clear(&tmp); /* PORT_Memset(powers,0,num_powers*nLen*sizeof(mp_digit)); */ free(powersArray); return res; diff --git a/security/nss/lib/freebl/mpi/mpprime.c b/security/nss/lib/freebl/mpi/mpprime.c index dfe7988f7..32d6f6f70 100644 --- a/security/nss/lib/freebl/mpi/mpprime.c +++ b/security/nss/lib/freebl/mpi/mpprime.c @@ -427,20 +427,10 @@ mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong, mp_int trial; mp_int q; mp_size num_tests; - /* - * Always make sieve the last variabale allocated so that - * Mac builds don't break by adding an extra variable - * on the stack. -javi - */ -#if defined(macintosh) || defined (XP_OS2) \ - || (defined(HPUX) && defined(__ia64)) unsigned char *sieve; sieve = malloc(SIEVE_SIZE); ARGCHK(sieve != NULL, MP_MEM); -#else - unsigned char sieve[SIEVE_SIZE]; -#endif ARGCHK(start != 0, MP_BADARG); ARGCHK(nBits > 16, MP_RANGE); @@ -575,13 +565,10 @@ CLEANUP: mp_clear(&q); if (nTries) *nTries += i; -#if defined(macintosh) || defined(XP_OS2) \ - || (defined(HPUX) && defined(__ia64)) if (sieve != NULL) { memset(sieve, 0, SIEVE_SIZE); free (sieve); } -#endif return res; } diff --git a/security/nss/lib/freebl/mpi/target.mk b/security/nss/lib/freebl/mpi/target.mk index c17854819..6f71e8053 100644 --- a/security/nss/lib/freebl/mpi/target.mk +++ b/security/nss/lib/freebl/mpi/target.mk @@ -229,3 +229,21 @@ MPICMN += $(MP_CONFIG) mpi_amd64_asm.o: mpi_amd64_sun.s $(AS) -xarch=generic64 -P -D_ASM mpi_amd64_sun.s endif + +ifeq ($(TARGET),WIN32) +AS_OBJS = mpi_x86.obj +MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D +MPICMN += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD -DMP_API_COMPATIBLE +MPICMN += -DMP_MONT_USE_MP_MUL +MPICMN += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN +CFLAGS = -Od -Z7 -MDd -W3 -nologo -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USER) +CFLAGS += -DWIN32 -D_WINDOWS -D_X86_ -DWIN95 -DXP_PC -DNSS_ENABLE_ECC +CFLAGS += $(MPICMN) + +$(AS_OBJS): %.obj : %.asm + ml -Cp -Sn -Zi -coff -nologo -c $< + +$(LIBOBJS): %.obj : %.c + cl $(CFLAGS) -Fo$@ -c $< + +endif diff --git a/security/nss/lib/freebl/mpi/tests/mptest-7.c b/security/nss/lib/freebl/mpi/tests/mptest-7.c index a32be1978..3153133cb 100644 --- a/security/nss/lib/freebl/mpi/tests/mptest-7.c +++ b/security/nss/lib/freebl/mpi/tests/mptest-7.c @@ -47,7 +47,7 @@ #include <limits.h> #include <time.h> -#define MP_IOFUNC +#define MP_IOFUNC 1 #include "mpi.h" #include "mpprime.h" diff --git a/security/nss/lib/freebl/mpi/tests/mptest-8.c b/security/nss/lib/freebl/mpi/tests/mptest-8.c index 7cf95a9b1..8bff49b20 100644 --- a/security/nss/lib/freebl/mpi/tests/mptest-8.c +++ b/security/nss/lib/freebl/mpi/tests/mptest-8.c @@ -47,7 +47,7 @@ #include <limits.h> #include <time.h> -#define MP_IOFUNC +#define MP_IOFUNC 1 #include "mpi.h" #include "mpprime.h" diff --git a/security/nss/lib/freebl/nss.h b/security/nss/lib/freebl/nss.h new file mode 100644 index 000000000..d0f72fb07 --- /dev/null +++ b/security/nss/lib/freebl/nss.h @@ -0,0 +1,253 @@ +/*********************************************************************** + * + * A copy of nss.h from NSS 3.11.4 for the directories that make up the + * NSS cryptographic module (lib/freebl and lib/softoken). + * + * When compiling in these directories, the compiler uses the local copy + * of nss.h, allowing the NSS cryptographic module to stay at version + * 3.11.4 (the version submitted to NIST for FIPS 140-2 validation). + * + * DO NOT CHANGE THIS FILE. + * + ***********************************************************************/ +/* + * NSS utility functions + * + * ***** 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 ***** */ +/* $Id$ */ + +#ifndef __nss_h_ +#define __nss_h_ + +#include "seccomon.h" + +SEC_BEGIN_PROTOS + +/* + * NSS's major version, minor version, patch level, and whether + * this is a beta release. + * + * The format of the version string should be + * "<major version>.<minor version>[.<patch level>] [<Beta>]" + */ +/* ***** DO NOT CHANGE THIS FILE. ***** */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define NSS_VERSION "3.11.4 Extended ECC" +#else +#define NSS_VERSION "3.11.4 Basic ECC" +#endif +#else +#define NSS_VERSION "3.11.4" +#endif +#define NSS_VMAJOR 3 +#define NSS_VMINOR 11 +#define NSS_VPATCH 4 +#define NSS_BETA PR_FALSE + +/* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. + * + * The only argument is a string, which should be the verson + * identifier of the NSS library. That string will be compared + * against a string that represents the actual build version of + * the NSS library. It also invokes the version checking functions + * of the dependent libraries such as NSPR. + */ +extern PRBool NSS_VersionCheck(const char *importedVersion); + +/* + * Open the Cert, Key, and Security Module databases, read only. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_Init(const char *configdir); + +/* + * Returns whether NSS has already been initialized or not. + */ +extern PRBool NSS_IsInitialized(void); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_InitReadWrite(const char *configdir); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + * + * This allows using application defined prefixes for the cert and key db's + * and an alternate name for the secmod database. NOTE: In future releases, + * the database prefixes my not necessarily map to database names. + * + * configdir - base directory where all the cert, key, and module datbases live. + * certPrefix - prefix added to the beginning of the cert database example: " + * "https-server1-" + * keyPrefix - prefix added to the beginning of the key database example: " + * "https-server1-" + * secmodName - name of the security module database (usually "secmod.db"). + * flags - change the open options of NSS_Initialize as follows: + * NSS_INIT_READONLY - Open the databases read only. + * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just + * initialize the volatile certdb. + * NSS_INIT_NOMODDB - Don't open the security module DB, just + * initialize the PKCS #11 module. + * NSS_INIT_FORCEOPEN - Continue to force initializations even if the + * databases cannot be opened. + * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module + * automatically. + * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches. + * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are + * thread-safe, ie. that support locking - either OS + * locking or NSS-provided locks . If a PKCS#11 + * module isn't thread-safe, don't serialize its + * calls; just don't load it instead. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example the Java SunPKCS11 provider. + * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED + * error when loading PKCS#11 modules. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example Java SunPKCS11 provider. + * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any + * PKCS#11 module. This may be necessary in order to + * ensure continuous operation and proper shutdown + * sequence if another piece of code is using the same + * PKCS#11 modules that NSS is accessing without going + * through NSS, for example Java SunPKCS11 provider. + * The following limitation applies when this is set : + * SECMOD_WaitForAnyTokenEvent will not use + * C_WaitForSlotEvent, in order to prevent the need for + * C_Finalize. This call will be emulated instead. + * NSS_INIT_RESERVED - Currently has no effect, but may be used in the + * future to trigger better cooperation between PKCS#11 + * modules used by both NSS and the Java SunPKCS11 + * provider. This should occur after a new flag is defined + * for C_Initialize by the PKCS#11 working group. + * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that + * use both NSS and the Java SunPKCS11 provider. + * + * Also NOTE: This is not the recommended method for initializing NSS. + * The prefered method is NSS_init(). + */ +#define NSS_INIT_READONLY 0x1 +#define NSS_INIT_NOCERTDB 0x2 +#define NSS_INIT_NOMODDB 0x4 +#define NSS_INIT_FORCEOPEN 0x8 +#define NSS_INIT_NOROOTINIT 0x10 +#define NSS_INIT_OPTIMIZESPACE 0x20 +#define NSS_INIT_PK11THREADSAFE 0x40 +#define NSS_INIT_PK11RELOAD 0x80 +#define NSS_INIT_NOPK11FINALIZE 0x100 +#define NSS_INIT_RESERVED 0x200 + +#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \ + NSS_INIT_PK11RELOAD | \ + NSS_INIT_NOPK11FINALIZE | \ + NSS_INIT_RESERVED + +#ifdef macintosh +#define SECMOD_DB "Security Modules" +#else +#define SECMOD_DB "secmod.db" +#endif + +extern SECStatus NSS_Initialize(const char *configdir, + const char *certPrefix, const char *keyPrefix, + const char *secmodName, PRUint32 flags); + +/* + * initialize NSS without a creating cert db's, key db's, or secmod db's. + */ +SECStatus NSS_NoDB_Init(const char *configdir); + +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Close the Cert, Key databases. + */ +extern SECStatus NSS_Shutdown(void); + +/* + * set the PKCS #11 strings for the internal token. + */ +void PK11_ConfigurePKCS11(const char *man, const char *libdes, + const char *tokdes, const char *ptokdes, const char *slotdes, + const char *pslotdes, const char *fslotdes, const char *fpslotdes, + int minPwd, int pwRequired); + +/* + * Dump the contents of the certificate cache and the temporary cert store. + * Use to detect leaked references of certs at shutdown time. + */ +void nss_DumpCertificateCacheInfo(void); + +SEC_END_PROTOS + +#endif /* __nss_h_ */ diff --git a/security/nss/lib/freebl/os2_rand.c b/security/nss/lib/freebl/os2_rand.c index 8138d30ae..467774b8b 100644 --- a/security/nss/lib/freebl/os2_rand.c +++ b/security/nss/lib/freebl/os2_rand.c @@ -37,7 +37,8 @@ #define INCL_DOS #define INCL_DOSERRORS #include <os2.h> -#include <secrng.h> +#include "secrng.h" +#include "prerror.h" #include <stdlib.h> #include <time.h> #include <stdio.h> @@ -331,3 +332,9 @@ void RNG_FileForRNG(const char *filename) nBytes = RNG_GetNoise(buffer, 20); RNG_RandomUpdate(buffer, nBytes); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; +} diff --git a/security/nss/lib/freebl/pqg.c b/security/nss/lib/freebl/pqg.c index c3e92c62d..66c535fe9 100644 --- a/security/nss/lib/freebl/pqg.c +++ b/security/nss/lib/freebl/pqg.c @@ -78,6 +78,8 @@ static const unsigned char fips_186_1_a5_pqseed[] = { static SECStatus getPQseed(SECItem *seed, PRArenaPool* arena) { + SECStatus rv; + if (!seed->data) { seed->data = (unsigned char*)PORT_ArenaZAlloc(arena, seed->len); } @@ -89,7 +91,15 @@ getPQseed(SECItem *seed, PRArenaPool* arena) memcpy(seed->data, fips_186_1_a5_pqseed, seed->len); return SECSuccess; #else - return RNG_GenerateGlobalRandomBytes(seed->data, seed->len); + rv = RNG_GenerateGlobalRandomBytes(seed->data, seed->len); + /* + * NIST CMVP disallows a sequence of 20 bytes with the most + * significant byte equal to 0. Perhaps they interpret + * "a sequence of at least 160 bits" as "a number >= 2^159". + * So we always set the most significant bit to 1. (bug 334533) + */ + seed->data[0] |= 0x80; + return rv; #endif } @@ -322,8 +332,8 @@ makeGfromH(const mp_int *P, /* input. */ CHECK_MPI_OK( mp_init(&exp) ); CHECK_MPI_OK( mp_init(&pm1) ); CHECK_MPI_OK( mp_sub_d(P, 1, &pm1) ); /* P - 1 */ - if ( mp_cmp(H, &pm1) > 0) /* H = H mod (P-1) */ - CHECK_MPI_OK( mp_sub(H, &pm1, H) ); + if ( mp_cmp(H, &pm1) >= 0) /* H >= P-1 */ + CHECK_MPI_OK( mp_sub(H, &pm1, H) ); /* H = H mod (P-1) */ /* Let b = 2**n (smallest power of 2 greater than P). ** Since P-1 >= b/2, and H < b, quotient(H/(P-1)) = 0 or 1 ** so the above operation safely computes H mod (P-1) @@ -392,7 +402,7 @@ PQG_ParamGenSeedLen(unsigned int j, unsigned int seedBytes, mp_err err = MP_OKAY; SECStatus rv = SECFailure; int iterations = 0; - if (j > 8 || !pParams || !pVfy) { + if (j > 8 || seedBytes < 20 || !pParams || !pVfy) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } @@ -538,7 +548,7 @@ step_15: ** in certifying the proper generation of p and q." */ /* Generate h. */ - SECITEM_AllocItem(NULL, &hit, seedBytes); /* h is no longer than p */ + SECITEM_AllocItem(NULL, &hit, L/8); /* h is no longer than p */ if (!hit.data) goto cleanup; do { /* loop generate h until 1<h<p-1 and (h**[(p-1)/q])mod p > 1 */ @@ -628,7 +638,6 @@ PQG_VerifyParams(const PQGParams *params, /* 6. P is prime */ CHECKPARAM( mpp_pprime(&P, PQG_P_PRIMALITY_TESTS) == MP_YES ); /* Steps 7-12 are done only if the optional PQGVerify is supplied. */ - if (!vfy) goto cleanup; /* 7. counter < 4096 */ CHECKPARAM( vfy->counter < 4096 ); /* 8. g >= 160 and g < 2048 (g is length of seed in bits) */ diff --git a/security/nss/lib/freebl/prng_fips1861.c b/security/nss/lib/freebl/prng_fips1861.c index 900b98ab8..50c29692e 100644 --- a/security/nss/lib/freebl/prng_fips1861.c +++ b/security/nss/lib/freebl/prng_fips1861.c @@ -46,6 +46,7 @@ #include "nssilock.h" #include "secitem.h" #include "sha_fast.h" +#include "sha256.h" #include "secrng.h" /* for RNG_GetNoise() */ #include "secmpi.h" @@ -74,8 +75,10 @@ * SHA-256, or SHA-512). */ #define FIPS_B 256 -#define B_HASH_BUF SHA256_HashBuf #define BSIZE (FIPS_B / PR_BITS_PER_BYTE) +#if BSIZE != SHA256_LENGTH +#error "this file requires that BSIZE and SHA256_LENGTH be equal" +#endif /* Output size of the G function */ #define FIPS_G 160 @@ -106,9 +109,10 @@ * q, DSA_SUBPRIME_LEN bytes * Output: xj, DSA_SUBPRIME_LEN bytes */ -static SECStatus -dsa_reduce_mod_q(const unsigned char *w, const unsigned char *q, - unsigned char *xj) +SECStatus +FIPS186Change_ReduceModQForDSA(const unsigned char *w, + const unsigned char *q, + unsigned char *xj) { mp_int W, Q, Xj; mp_err err; @@ -168,28 +172,52 @@ struct RNGContextStr { }; typedef struct RNGContextStr RNGContext; static RNGContext *globalrng = NULL; +static RNGContext theGlobalRng; /* - * Free the global RNG context + * Clean up the global RNG context */ static void freeRNGContext() { + unsigned char inputhash[BSIZE]; + SECStatus rv; + + /* destroy context lock */ PZ_DestroyLock(globalrng->lock); - PORT_ZFree(globalrng, sizeof *globalrng); + + /* zero global RNG context except for XKEY to preserve entropy */ + rv = SHA256_HashBuf(inputhash, globalrng->XKEY, BSIZE); + PORT_Assert(SECSuccess == rv); + memset(globalrng, 0, sizeof(*globalrng)); + memcpy(globalrng->XKEY, inputhash, BSIZE); + globalrng = NULL; } /* - * Implementation of Algorithm 1 of FIPS 186-2 Change Notice 1, - * hereinafter called alg_cn_1(). It is assumed a lock for the global - * rng context has already been acquired. - * Calling this function with XSEEDj == NULL is equivalent to saying there - * is no optional user input, which is further equivalent to saying that - * the optional user input is 0. + * The core of Algorithm 1 of FIPS 186-2 Change Notice 1, + * separated from alg_fips186_2_cn_1 as a standalone function + * for FIPS algorithm testing. + * + * Parameters: + * XKEY [input/output]: the state of the RNG (seed-key) + * XSEEDj [input]: optional user input (seed) + * x_j [output]: output of the RNG + * + * Return value: + * This function usually returns SECSuccess. The only reason + * this function returns SECFailure is that XSEEDj equals + * XKEY, including the intermediate XKEY value between the two + * iterations. (This test is actually a FIPS 140-2 requirement + * and not required for FIPS algorithm testing, but it is too + * hard to separate from this function.) If this function fails, + * XKEY is not updated, but some data may have been written to + * x_j, which should be ignored. */ -static SECStatus -alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) +SECStatus +FIPS186Change_GenerateX(unsigned char *XKEY, const unsigned char *XSEEDj, + unsigned char *x_j) { /* SHA1 context for G(t, XVAL) function */ SHA1Context sha1cx; @@ -199,8 +227,6 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) PRUint8 *XKEY_new; /* input to hash function */ PRUint8 XVAL[BSIZE]; - /* store a copy of the output to compare with the previous output */ - PRUint8 x_j[2*GSIZE]; /* used by ADD_B_BIT macros */ int k, carry; /* store the output of G(t, XVAL) in the rightmost GSIZE bytes */ @@ -209,11 +235,6 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) unsigned int len; SECStatus rv = SECSuccess; - if (!rng->isValid) { - /* RNG has alread entered an invalid state. */ - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); - return SECFailure; - } #if GSIZE < BSIZE /* zero the leftmost bytes so we can pass it to ADD_B_BIT_PLUS_CARRY */ memset(w_i, 0, BSIZE - GSIZE); @@ -224,15 +245,15 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) * <Step 3.1> XSEEDj is optional user input */ for (i = 0; i < 2; i++) { - /* only update rng->XKEY when both iterations have been completed */ + /* only update XKEY when both iterations have been completed */ if (i == 0) { /* for iteration 0 */ - XKEY_old = rng->XKEY; + XKEY_old = XKEY; XKEY_new = XKEY_1; } else { /* for iteration 1 */ XKEY_old = XKEY_1; - XKEY_new = rng->XKEY; + XKEY_new = XKEY; } /* * <Step 3.2a> XVAL = (XKEY + XSEEDj) mod 2^b @@ -270,6 +291,39 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) */ memcpy(&x_j[i*GSIZE], &w_i[BSIZE - GSIZE], GSIZE); } + +done: + /* housekeeping */ + memset(&w_i[BSIZE - GSIZE], 0, GSIZE); + memset(XVAL, 0, BSIZE); + memset(XKEY_1, 0, BSIZE); + return rv; +} + +/* + * Implementation of Algorithm 1 of FIPS 186-2 Change Notice 1, + * hereinafter called alg_cn_1(). It is assumed a lock for the global + * rng context has already been acquired. + * Calling this function with XSEEDj == NULL is equivalent to saying there + * is no optional user input, which is further equivalent to saying that + * the optional user input is 0. + */ +static SECStatus +alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) +{ + /* store a copy of the output to compare with the previous output */ + PRUint8 x_j[2*GSIZE]; + SECStatus rv; + + if (!rng->isValid) { + /* RNG has alread entered an invalid state. */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + rv = FIPS186Change_GenerateX(rng->XKEY, XSEEDj, x_j); + if (rv != SECSuccess) { + goto done; + } /* [FIPS 140-2] verify output does not match previous output */ if (memcmp(x_j, rng->Xj, 2*GSIZE) == 0) { /* failed FIPS 140-2 continuous RNG test. RNG now invalid. */ @@ -285,32 +339,26 @@ alg_fips186_2_cn_1(RNGContext *rng, const unsigned char *XSEEDj) done: /* housekeeping */ - memset(&w_i[BSIZE - GSIZE], 0, GSIZE); memset(x_j, 0, 2*GSIZE); - memset(XVAL, 0, BSIZE); - memset(XKEY_1, 0, BSIZE); return rv; } /* Use NSPR to prevent RNG_RNGInit from being called from separate * threads, creating a race condition. */ -static PRCallOnceType coRNGInit = { 0, 0, 0 }; +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType coRNGInit; static PRStatus rng_init(void) { - unsigned char bytes[120]; + unsigned char bytes[SYSTEM_RNG_SEED_COUNT]; unsigned int numBytes; if (globalrng == NULL) { /* create a new global RNG context */ - globalrng = (RNGContext *)PORT_ZAlloc(sizeof(RNGContext)); - if (globalrng == NULL) { - PORT_SetError(PR_OUT_OF_MEMORY_ERROR); - return PR_FAILURE; - } + globalrng = &theGlobalRng; + PORT_Assert(NULL == globalrng->lock); /* create a lock for it */ globalrng->lock = PZ_NewLock(nssILockOther); if (globalrng->lock == NULL) { - PORT_Free(globalrng); globalrng = NULL; PORT_SetError(PR_OUT_OF_MEMORY_ERROR); return PR_FAILURE; @@ -318,6 +366,18 @@ static PRStatus rng_init(void) /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; /* Try to get some seed data for the RNG */ + numBytes = RNG_SystemRNG(bytes, sizeof bytes); + PORT_Assert(numBytes == 0 || numBytes == sizeof bytes); + if (numBytes != 0) { + RNG_RandomUpdate(bytes, numBytes); + memset(bytes, 0, numBytes); + } else if (PORT_GetError() != PR_NOT_IMPLEMENTED_ERROR) { + PZ_DestroyLock(globalrng->lock); + globalrng->lock = NULL; + globalrng->isValid = PR_FALSE; + globalrng = NULL; + return PR_FAILURE; + } numBytes = RNG_GetNoise(bytes, sizeof bytes); RNG_RandomUpdate(bytes, numBytes); } @@ -350,7 +410,6 @@ static SECStatus prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) { SECStatus rv = SECSuccess; - unsigned char inputhash[BSIZE]; /* check for a valid global RNG context */ PORT_Assert(rng != NULL); if (rng == NULL) { @@ -360,17 +419,6 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) /* RNG_SystemInfoForRNG() sometimes does this, not really an error */ if (bytes == 0) return SECSuccess; - /* If received 20 bytes of input, use it, else hash the input before - * locking. - */ - if (bytes == BSIZE) - memcpy(inputhash, data, BSIZE); - else - rv = B_HASH_BUF(inputhash, data, bytes); - if (rv != SECSuccess) { - /* B_HASH_BUF set error */ - return SECFailure; - } /* --- LOCKED --- */ PZ_Lock(rng->lock); /* @@ -380,20 +428,17 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * Algorithm 1 of FIPS 186-2 Change Notice 1, step 1 specifies that * a secret value for the seed-key must be chosen before the * generator can begin. The size of XKEY is b bits, so fill it - * with the first b bits sent to RNG_RandomUpdate(). + * with the b-bit hash of the input to the first RNG_RandomUpdate() + * call. */ if (rng->seedCount == 0) { /* This is the first call to RandomUpdate(). Use a hash - * of the input to set the seed, XKEY. + * of the input to set the seed-key, XKEY. * - * <Step 1> copy seed bytes into context's XKEY - */ - memcpy(rng->XKEY, inputhash, BSIZE); - /* - * Now continue with algorithm. Since the input was used to - * initialize XKEY, the "optional user input" at this stage - * will be a pad of zeros, XSEEDj = 0. + * <Step 1> copy hash of seed bytes into context's XKEY */ + SHA256_HashBuf(rng->XKEY, data, bytes); + /* Now continue with algorithm. */ rv = alg_fips186_2_cn_1(rng, NULL); /* As per FIPS 140-2 continuous RNG test requirement, the first * iteration of output is discarded. So here there is really @@ -401,17 +446,28 @@ prng_RandomUpdate(RNGContext *rng, const void *data, size_t bytes) * before any bytes can be extracted from the generator. */ rng->avail = 0; + } else if (bytes == BSIZE && memcmp(rng->XKEY, data, BSIZE) == 0) { + /* Should we add the error code SEC_ERROR_BAD_RNG_SEED? */ + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; } else { - /* Execute the algorithm from FIPS 186-2 Change Notice 1 */ - rv = alg_fips186_2_cn_1(rng, inputhash); + /* + * FIPS 186-2 does not specify how to reseed the RNG. We retrofit + * our RNG with a reseed function from NIST SP 800-90. + * + * Use a hash of the seed-key and the input to reseed the RNG. + */ + SHA256Context ctx; + SHA256_Begin(&ctx); + SHA256_Update(&ctx, rng->XKEY, BSIZE); + SHA256_Update(&ctx, data, bytes); + SHA256_End(&ctx, rng->XKEY, NULL, BSIZE); } /* If got this far, have added bytes of seed data. */ if (rv == SECSuccess) rng->seedCount += bytes; PZ_Unlock(rng->lock); /* --- UNLOCKED --- */ - /* housekeeping */ - memset(inputhash, 0, BSIZE); return rv; } @@ -429,7 +485,7 @@ RNG_RandomUpdate(const void *data, size_t bytes) ** Generate some random bytes, using the global random number generator ** object. */ -SECStatus +static SECStatus prng_GenerateGlobalRandomBytes(RNGContext *rng, void *dest, size_t len) { @@ -501,8 +557,8 @@ RNG_RNGShutdown(void) } /* clear */ freeRNGContext(); - /* zero the callonce struct to allow a new call to RNG_RNGInit() */ - memset(&coRNGInit, 0, sizeof coRNGInit); + /* reset the callonce struct to allow a new call to RNG_RNGInit() */ + coRNGInit = pristineCallOnce; } /* @@ -581,6 +637,6 @@ DSA_GenerateGlobalRandomBytes(void *dest, size_t len, const unsigned char *q) if (rv != SECSuccess) { return rv; } - dsa_reduce_mod_q(w, q, (unsigned char *)dest); + FIPS186Change_ReduceModQForDSA(w, q, (unsigned char *)dest); return rv; } diff --git a/security/nss/lib/freebl/secrng.h b/security/nss/lib/freebl/secrng.h index d3e97c927..036a3f71a 100644 --- a/security/nss/lib/freebl/secrng.h +++ b/security/nss/lib/freebl/secrng.h @@ -51,11 +51,14 @@ #include "blapi.h" +/* the number of bytes to read from the system random number generator */ +#define SYSTEM_RNG_SEED_COUNT 1024 + SEC_BEGIN_PROTOS /* -** The following 3 functions are provided by the security library -** but are differently implemented for the UNIX, Mac and Win +** The following functions are provided by the security library +** but are differently implemented for the UNIX, Win, and OS/2 ** versions */ @@ -80,6 +83,17 @@ extern void RNG_SystemInfoForRNG(void); */ extern void RNG_FileForRNG(const char *filename); +/* +** Get maxbytes bytes of random data from the system random number +** generator. +** Returns the number of bytes copied into buf -- maxbytes if success +** or zero if error. +** Errors: +** PR_NOT_IMPLEMENTED_ERROR There is no system RNG on the platform. +** SEC_ERROR_NEED_RANDOM The system RNG failed. +*/ +extern size_t RNG_SystemRNG(void *buf, size_t maxbytes); + SEC_END_PROTOS #endif /* _SECRNG_H_ */ diff --git a/security/nss/lib/freebl/sha256.h b/security/nss/lib/freebl/sha256.h new file mode 100644 index 000000000..f59813257 --- /dev/null +++ b/security/nss/lib/freebl/sha256.h @@ -0,0 +1,51 @@ +/* ***** 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) 2002 + * 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 ***** */ + +#ifndef _SHA_256_H_ +#define _SHA_256_H_ + +#include "prtypes.h" + +struct SHA256ContextStr { + union { + PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ + PRUint8 b[256]; + } u; + PRUint32 h[8]; /* 8 state variables */ + PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ +}; + +#endif /* _SHA_256_H_ */ diff --git a/security/nss/lib/freebl/sha512.c b/security/nss/lib/freebl/sha512.c index 672aa9a0f..a25b83d6d 100644 --- a/security/nss/lib/freebl/sha512.c +++ b/security/nss/lib/freebl/sha512.c @@ -45,6 +45,7 @@ #include "prtypes.h" /* for PRUintXX */ #include "secport.h" /* for PORT_XXX */ #include "blapi.h" +#include "sha256.h" /* for struct SHA256ContextStr */ /* ============= Common constants and defines ======================= */ @@ -92,15 +93,6 @@ static const PRUint32 H256[8] = { 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 }; -struct SHA256ContextStr { - union { - PRUint32 w[64]; /* message schedule, input buffer, plus 48 words */ - PRUint8 b[256]; - } u; - PRUint32 h[8]; /* 8 state variables */ - PRUint32 sizeHi,sizeLo; /* 64-bit count of hashed bytes. */ -}; - #if defined(_MSC_VER) && defined(_X86_) #ifndef FORCEINLINE #if (MSC_VER >= 1200) diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c index f61da8b29..13617b1e7 100644 --- a/security/nss/lib/freebl/unix_rand.c +++ b/security/nss/lib/freebl/unix_rand.c @@ -43,8 +43,9 @@ #include <sys/time.h> #include <sys/wait.h> #include <sys/stat.h> -#include <assert.h> #include "secrng.h" +#include "secerr.h" +#include "prerror.h" size_t RNG_FileUpdate(const char *fileName, size_t limit); @@ -80,6 +81,108 @@ static size_t CopyLowBits(void *dst, size_t dstlen, void *src, size_t srclen) return dstlen; } +#ifdef SOLARIS + +#include <kstat.h> + +static const PRUint32 entropy_buf_len = 4096; /* buffer up to 4 KB */ + +/* Buffer entropy data, and feed it to the RNG, entropy_buf_len bytes at a time. + * Returns error if RNG_RandomUpdate fails. Also increments *total_fed + * by the number of bytes successfully buffered. + */ +static SECStatus BufferEntropy(char* inbuf, PRUint32 inlen, + char* entropy_buf, PRUint32* entropy_buffered, + PRUint32* total_fed) +{ + PRUint32 tocopy = 0; + PRUint32 avail = 0; + SECStatus rv = SECSuccess; + + while (inlen) { + avail = entropy_buf_len - *entropy_buffered; + if (!avail) { + /* Buffer is full, time to feed it to the RNG. */ + rv = RNG_RandomUpdate(entropy_buf, entropy_buf_len); + if (SECSuccess != rv) { + break; + } + *entropy_buffered = 0; + avail = entropy_buf_len; + } + tocopy = PR_MIN(avail, inlen); + memcpy(entropy_buf + *entropy_buffered, inbuf, tocopy); + *entropy_buffered += tocopy; + inlen -= tocopy; + inbuf += tocopy; + *total_fed += tocopy; + } + return rv; +} + +/* Feed kernel statistics structures and ks_data field to the RNG. + * Returns status as well as the number of bytes successfully fed to the RNG. + */ +static SECStatus RNG_kstat(PRUint32* fed) +{ + kstat_ctl_t* kc = NULL; + kstat_t* ksp = NULL; + PRUint32 entropy_buffered = 0; + char* entropy_buf = NULL; + SECStatus rv = SECSuccess; + + PORT_Assert(fed); + if (!fed) { + return SECFailure; + } + *fed = 0; + + kc = kstat_open(); + PORT_Assert(kc); + if (!kc) { + return SECFailure; + } + entropy_buf = (char*) PORT_Alloc(entropy_buf_len); + PORT_Assert(entropy_buf); + if (entropy_buf) { + for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { + if (-1 == kstat_read(kc, ksp, NULL)) { + /* missing data from a single kstat shouldn't be fatal */ + continue; + } + rv = BufferEntropy((char*)ksp, sizeof(kstat_t), + entropy_buf, &entropy_buffered, + fed); + if (SECSuccess != rv) { + break; + } + + if (ksp->ks_data && ksp->ks_data_size>0 && ksp->ks_ndata>0) { + rv = BufferEntropy((char*)ksp->ks_data, ksp->ks_data_size, + entropy_buf, &entropy_buffered, + fed); + if (SECSuccess != rv) { + break; + } + } + } + if (SECSuccess == rv && entropy_buffered) { + /* Buffer is not empty, time to feed it to the RNG */ + rv = RNG_RandomUpdate(entropy_buf, entropy_buffered); + } + PORT_Free(entropy_buf); + } else { + rv = SECFailure; + } + if (kstat_close(kc)) { + PORT_Assert(0); + rv = SECFailure; + } + return rv; +} + +#endif + #if defined(SCO) || defined(UNIXWARE) || defined(BSDI) || defined(FREEBSD) \ || defined(NETBSD) || defined(NTO) || defined(DARWIN) || defined(OPENBSD) #include <sys/times.h> @@ -277,7 +380,7 @@ GiveSystemInfo(void) #endif /* IBM R2 */ #if defined(LINUX) -#include <linux/kernel.h> +#include <sys/sysinfo.h> static size_t GetHighResClock(void *buf, size_t maxbytes) @@ -288,14 +391,10 @@ GetHighResClock(void *buf, size_t maxbytes) static void GiveSystemInfo(void) { - /* XXX sysinfo() does not seem be implemented anywhwere */ -#if 0 struct sysinfo si; - char hn[2000]; if (sysinfo(&si) == 0) { RNG_RandomUpdate(&si, sizeof(si)); } -#endif } #endif /* LINUX */ @@ -774,6 +873,11 @@ safe_pclose(FILE *fp) #include <crt_externs.h> #endif +/* Fork netstat to collect its output by default. Do not unset this unless + * another source of entropy is available + */ +#define DO_NETSTAT 1 + void RNG_SystemInfoForRNG(void) { FILE *fp; @@ -842,13 +946,13 @@ for the small amount of entropy it provides. } /* Give in system information */ - if (gethostname(buf, sizeof(buf)) > 0) { + if (gethostname(buf, sizeof(buf)) == 0) { RNG_RandomUpdate(buf, strlen(buf)); } GiveSystemInfo(); /* grab some data from system's PRNG before any other files. */ - bytes = RNG_FileUpdate("/dev/urandom", 1024); + bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT); /* If the user points us to a random file, pass it through the rng */ randfile = getenv("NSRANDFILE"); @@ -872,6 +976,29 @@ for the small amount of entropy it provides. return; #endif +#ifdef SOLARIS + +/* + * On Solaris, NSS may be initialized automatically from libldap in + * applications that are unaware of the use of NSS. safe_popen forks, and + * sometimes creates issues with some applications' pthread_atfork handlers. + * We always have /dev/urandom on Solaris 9 and above as an entropy source, + * and for Solaris 8 we have the libkstat interface, so we don't need to + * fork netstat. + */ + +#undef DO_NETSTAT + if (!bytes) { + /* On Solaris 8, /dev/urandom isn't available, so we use libkstat. */ + PRUint32 kstat_bytes = 0; + if (SECSuccess != RNG_kstat(&kstat_bytes)) { + PORT_Assert(0); + } + bytes += kstat_bytes; + PORT_Assert(bytes); + } +#endif + #ifdef DO_PS fp = safe_popen(ps_cmd); if (fp != NULL) { @@ -880,12 +1007,15 @@ for the small amount of entropy it provides. safe_pclose(fp); } #endif + +#ifdef DO_NETSTAT fp = safe_popen(netstat_ni_cmd); if (fp != NULL) { while ((bytes = fread(buf, 1, sizeof(buf), fp)) > 0) RNG_RandomUpdate(buf, bytes); safe_pclose(fp); } +#endif } #else @@ -959,6 +1089,9 @@ size_t RNG_FileUpdate(const char *fileName, size_t limit) unsigned char buffer[BUFSIZ]; static size_t totalFileBytes = 0; + /* suppress valgrind warnings due to holes in struct stat */ + memset(&stat_buf, 0, sizeof(stat_buf)); + if (stat((char *)fileName, &stat_buf) < 0) return fileBytes; RNG_RandomUpdate(&stat_buf, sizeof(stat_buf)); @@ -994,3 +1127,31 @@ void RNG_FileForRNG(const char *fileName) { RNG_FileUpdate(fileName, TOTAL_FILE_LIMIT); } + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + FILE *file; + size_t bytes; + size_t fileBytes = 0; + unsigned char *buffer = dest; + + file = fopen("/dev/urandom", "r"); + if (file == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return fileBytes; + } + while (maxLen > fileBytes) { + bytes = maxLen - fileBytes; + bytes = fread(buffer, 1, bytes, file); + if (bytes == 0) + break; + fileBytes += bytes; + buffer += bytes; + } + fclose(file); + if (fileBytes != maxLen) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + fileBytes = 0; + } + return fileBytes; +} diff --git a/security/nss/lib/freebl/win_rand.c b/security/nss/lib/freebl/win_rand.c index 20218b967..286ad3522 100644 --- a/security/nss/lib/freebl/win_rand.c +++ b/security/nss/lib/freebl/win_rand.c @@ -35,6 +35,7 @@ * ***** END LICENSE BLOCK ***** */ #include "secrng.h" +#include "secerr.h" #ifdef XP_WIN #include <windows.h> @@ -56,6 +57,7 @@ #endif #include "prio.h" +#include "prerror.h" static PRInt32 filesToRead; static DWORD totalFileBytes; @@ -545,4 +547,96 @@ void RNG_FileForRNG(const char *filename) } #endif /* not WinCE */ + +/* + * CryptoAPI requires Windows NT 4.0 or Windows 95 OSR2 and later. + * Until we drop support for Windows 95, we need to emulate some + * definitions and declarations in <wincrypt.h> and look up the + * functions in advapi32.dll at run time. + */ + +typedef unsigned long HCRYPTPROV; + +#define CRYPT_VERIFYCONTEXT 0xF0000000 + +#define PROV_RSA_FULL 1 + +typedef BOOL +(WINAPI *CryptAcquireContextAFn)( + HCRYPTPROV *phProv, + LPCSTR pszContainer, + LPCSTR pszProvider, + DWORD dwProvType, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptReleaseContextFn)( + HCRYPTPROV hProv, + DWORD dwFlags); + +typedef BOOL +(WINAPI *CryptGenRandomFn)( + HCRYPTPROV hProv, + DWORD dwLen, + BYTE *pbBuffer); + +/* + * Windows XP and Windows Server 2003 and later have RtlGenRandom, + * which must be looked up by the name SystemFunction036. + */ +typedef BOOLEAN +(APIENTRY *RtlGenRandomFn)( + PVOID RandomBuffer, + ULONG RandomBufferLength); + +size_t RNG_SystemRNG(void *dest, size_t maxLen) +{ + HMODULE hModule; + RtlGenRandomFn pRtlGenRandom; + CryptAcquireContextAFn pCryptAcquireContextA; + CryptReleaseContextFn pCryptReleaseContext; + CryptGenRandomFn pCryptGenRandom; + HCRYPTPROV hCryptProv; + size_t bytes = 0; + + hModule = LoadLibrary("advapi32.dll"); + if (hModule == NULL) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return 0; + } + pRtlGenRandom = (RtlGenRandomFn) + GetProcAddress(hModule, "SystemFunction036"); + if (pRtlGenRandom) { + if (pRtlGenRandom(dest, maxLen)) { + bytes = maxLen; + } else { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } + goto done; + } + pCryptAcquireContextA = (CryptAcquireContextAFn) + GetProcAddress(hModule, "CryptAcquireContextA"); + pCryptReleaseContext = (CryptReleaseContextFn) + GetProcAddress(hModule, "CryptReleaseContext"); + pCryptGenRandom = (CryptGenRandomFn) + GetProcAddress(hModule, "CryptGenRandom"); + if (!pCryptAcquireContextA || !pCryptReleaseContext || !pCryptGenRandom) { + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + goto done; + } + if (pCryptAcquireContextA(&hCryptProv, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + if (pCryptGenRandom(hCryptProv, maxLen, dest)) { + bytes = maxLen; + } + pCryptReleaseContext(hCryptProv, 0); + } + if (bytes == 0) { + PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */ + } +done: + FreeLibrary(hModule); + return bytes; +} + #endif /* is XP_WIN */ diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk index 5cdb444e5..9ba5ce176 100644 --- a/security/nss/lib/nss/config.mk +++ b/security/nss/lib/nss/config.mk @@ -122,6 +122,14 @@ MKSHLIB += -R '$$ORIGIN' endif endif +ifeq ($(OS_ARCH), HP-UX) +ifneq ($(OS_TEST), ia64) +# pa-risc +ifeq ($(USE_64), 1) +MKSHLIB += +b '$$ORIGIN' +endif +endif +endif ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET))) ifndef NS_USE_GCC diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index b02dd61ef..622614da5 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -872,3 +872,18 @@ SECMOD_OpenUserDB; ;+ local: ;+ *; ;+}; +;+NSS_3.11.1 { +;+ global: +NSS_RegisterShutdown; +NSS_UnregisterShutdown; +SEC_ASN1EncodeUnsignedInteger; +SEC_RegisterDefaultHttpClient; +;+ local: +;+ *; +;+}; +;+NSS_3.11.2 { +;+ global: +SECKEY_SignatureLen; +;+ local: +;+ *; +;+}; diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index 18245f52d..07329658c 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -45,20 +45,30 @@ SEC_BEGIN_PROTOS +/* The private macro _NSS_ECC_STRING is for NSS internal use only. */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define _NSS_ECC_STRING " Extended ECC" +#else +#define _NSS_ECC_STRING " Basic ECC" +#endif +#else +#define _NSS_ECC_STRING "" +#endif + /* * NSS's major version, minor version, patch level, and whether * this is a beta release. * * The format of the version string should be - * "<major version>.<minor version>[.<patch level>] [<Beta>]" + * "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" */ -#define NSS_VERSION "3.11" +#define NSS_VERSION "3.11.5" _NSS_ECC_STRING #define NSS_VMAJOR 3 #define NSS_VMINOR 11 -#define NSS_VPATCH 0 +#define NSS_VPATCH 5 #define NSS_BETA PR_FALSE - /* * Return a boolean that indicates whether the underlying library * will perform as the caller expects. @@ -184,6 +194,31 @@ extern SECStatus NSS_Initialize(const char *configdir, */ SECStatus NSS_NoDB_Init(const char *configdir); +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + /* * Close the Cert, Key databases. */ diff --git a/security/nss/lib/nss/nss.rc b/security/nss/lib/nss/nss.rc index be82dab75..156309e6a 100644 --- a/security/nss/lib/nss/nss.rc +++ b/security/nss/lib/nss/nss.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/nss/nssinit.c b/security/nss/lib/nss/nssinit.c index adf3efb04..fc36e78e1 100644 --- a/security/nss/lib/nss/nssinit.c +++ b/security/nss/lib/nss/nssinit.c @@ -57,6 +57,7 @@ #include "pki3hack.h" #include "certi.h" #include "secmodi.h" +#include "ocspi.h" /* * On Windows nss3.dll needs to export the symbol 'mktemp' to be @@ -300,14 +301,15 @@ static const char *dllname = /* Should we have platform ifdefs here??? */ #define FILE_SEP '/' -static void nss_FindExternalRootPaths(const char *dbpath, const char* secmodprefix, +static void nss_FindExternalRootPaths(const char *dbpath, + const char* secmodprefix, char** retoldpath, char** retnewpath) { char *path, *oldpath = NULL, *lastsep; int len, path_len, secmod_len, dll_len; path_len = PORT_Strlen(dbpath); - secmod_len = PORT_Strlen(secmodprefix); + secmod_len = secmodprefix ? PORT_Strlen(secmodprefix) : 0; dll_len = PORT_Strlen(dllname); len = path_len + secmod_len + dll_len + 2; /* FILE_SEP + NULL */ @@ -320,7 +322,7 @@ static void nss_FindExternalRootPaths(const char *dbpath, const char* secmodpref path[path_len++] = FILE_SEP; } PORT_Strcpy(&path[path_len],dllname); - if (secmodprefix) { + if (secmod_len > 0) { lastsep = PORT_Strrchr(secmodprefix, FILE_SEP); if (lastsep) { int secmoddir_len = lastsep-secmodprefix+1; /* FILE_SEP */ @@ -395,6 +397,11 @@ nss_FindExternalRoot(const char *dbpath, const char* secmodprefix) static PRBool nss_IsInitted = PR_FALSE; extern SECStatus secoid_Init(void); +static SECStatus nss_InitShutdownList(void); + +#ifdef DEBUG +static CERTCertificate dummyCert; +#endif static SECStatus nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, @@ -416,9 +423,16 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, return SECSuccess; } + /* New option bits must not change the size of CERTCertificate. */ + PORT_Assert(sizeof(dummyCert.options) == sizeof(void *)); + if (SECSuccess != InitCRLCache()) { return SECFailure; } + + if (SECSuccess != InitOCSPGlobal()) { + return SECFailure; + } flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen, pk11_password_required, optimizeSpace); @@ -479,6 +493,9 @@ loser: if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) { return SECFailure; } + if (nss_InitShutdownList() != SECSuccess) { + return SECFailure; + } CERT_SetDefaultCertDB((CERTCertDBHandle *) STAN_GetDefaultTrustDomain()); #ifndef XP_MAC @@ -586,28 +603,207 @@ NSS_NoDB_Init(const char * configdir) PR_FALSE,PR_FALSE,PR_FALSE); } + +#define NSS_SHUTDOWN_STEP 10 + +struct NSSShutdownFuncPair { + NSS_ShutdownFunc func; + void *appData; +}; + +static struct NSSShutdownListStr { + PZLock *lock; + int maxFuncs; + int numFuncs; + struct NSSShutdownFuncPair *funcs; +} nssShutdownList = { 0 }; + +/* + * find and existing shutdown function + */ +static int +nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData) +{ + int count, i; + count = nssShutdownList.numFuncs; + /* expect the list to be short, just do a linear search */ + for (i=0; i < count; i++) { + if ((nssShutdownList.funcs[i].func == sFunc) && + (nssShutdownList.funcs[i].appData == appData)){ + return i; + } + } + return -1; +} + +/* + * register a callback to be called when NSS shuts down + */ +SECStatus +NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData) +{ + int i; + + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + if (sFunc == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + + PORT_Assert(nssShutdownList.lock); + PZ_Lock(nssShutdownList.lock); + + /* make sure we don't have a duplicate */ + i = nss_GetShutdownEntry(sFunc, appData); + if (i > 0) { + PZ_Unlock(nssShutdownList.lock); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + /* find an empty slot */ + i = nss_GetShutdownEntry(NULL, NULL); + if (i > 0) { + nssShutdownList.funcs[i].func = sFunc; + nssShutdownList.funcs[i].appData = appData; + PZ_Unlock(nssShutdownList.lock); + return SECFailure; + } + if (nssShutdownList.maxFuncs == nssShutdownList.numFuncs) { + struct NSSShutdownFuncPair *funcs = + (struct NSSShutdownFuncPair *)PORT_Realloc + (nssShutdownList.funcs, + (nssShutdownList.maxFuncs + NSS_SHUTDOWN_STEP) + *sizeof(struct NSSShutdownFuncPair)); + if (!funcs) { + return SECFailure; + } + nssShutdownList.funcs = funcs; + nssShutdownList.maxFuncs += NSS_SHUTDOWN_STEP; + } + nssShutdownList.funcs[nssShutdownList.numFuncs].func = sFunc; + nssShutdownList.funcs[nssShutdownList.numFuncs].appData = appData; + nssShutdownList.numFuncs++; + PZ_Unlock(nssShutdownList.lock); + return SECSuccess; +} + +/* + * unregister a callback so it won't get called on shutdown. + */ +SECStatus +NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData) +{ + int i; + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + PORT_Assert(nssShutdownList.lock); + PZ_Lock(nssShutdownList.lock); + i = nss_GetShutdownEntry(sFunc, appData); + if (i > 0) { + nssShutdownList.funcs[i].func = NULL; + nssShutdownList.funcs[i].appData = NULL; + } + PZ_Unlock(nssShutdownList.lock); + + if (i < 0) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + return SECSuccess; +} + +/* + * bring up and shutdown the shutdown list + */ +static SECStatus +nss_InitShutdownList(void) +{ + nssShutdownList.lock = PZ_NewLock(nssILockOther); + if (nssShutdownList.lock == NULL) { + return SECFailure; + } + nssShutdownList.funcs = PORT_ZNewArray(struct NSSShutdownFuncPair, + NSS_SHUTDOWN_STEP); + if (nssShutdownList.funcs == NULL) { + PZ_DestroyLock(nssShutdownList.lock); + nssShutdownList.lock = NULL; + return SECFailure; + } + nssShutdownList.maxFuncs = NSS_SHUTDOWN_STEP; + nssShutdownList.numFuncs = 0; + + return SECSuccess; +} + +static SECStatus +nss_ShutdownShutdownList(void) +{ + SECStatus rv = SECSuccess; + int i; + + /* call all the registerd functions first */ + for (i=0; i < nssShutdownList.numFuncs; i++) { + struct NSSShutdownFuncPair *funcPair = &nssShutdownList.funcs[i]; + if (funcPair->func) { + if ((*funcPair->func)(funcPair->appData,NULL) != SECSuccess) { + rv = SECFailure; + } + } + } + + nssShutdownList.numFuncs = 0; + nssShutdownList.maxFuncs = 0; + PORT_Free(nssShutdownList.funcs); + nssShutdownList.funcs = NULL; + if (nssShutdownList.lock) { + PZ_DestroyLock(nssShutdownList.lock); + } + nssShutdownList.lock = NULL; + return rv; +} + + extern const NSSError NSS_ERROR_BUSY; SECStatus NSS_Shutdown(void) { + SECStatus shutdownRV = SECSuccess; SECStatus rv; PRStatus status; + if (!nss_IsInitted) { + PORT_SetError(SEC_ERROR_NOT_INITIALIZED); + return SECFailure; + } + + rv = nss_ShutdownShutdownList(); + if (rv != SECSuccess) { + shutdownRV = SECFailure; + } ShutdownCRLCache(); SECOID_Shutdown(); status = STAN_Shutdown(); cert_DestroySubjectKeyIDHashTable(); rv = SECMOD_Shutdown(); + if (rv != SECSuccess) { + shutdownRV = SECFailure; + } pk11sdr_Shutdown(); if (status == PR_FAILURE) { if (NSS_GetError() == NSS_ERROR_BUSY) { PORT_SetError(SEC_ERROR_BUSY); } - rv = SECFailure; + shutdownRV = SECFailure; } nss_IsInitted = PR_FALSE; - return rv; + return shutdownRV; } PRBool diff --git a/security/nss/lib/pk11wrap/Makefile b/security/nss/lib/pk11wrap/Makefile index 95766f79e..0b3017de6 100644 --- a/security/nss/lib/pk11wrap/Makefile +++ b/security/nss/lib/pk11wrap/Makefile @@ -96,8 +96,8 @@ endif ifdef XP_OS2_VACPP $(OBJDIR)/pk11skey.obj: pk11skey.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) $(OBJDIR)/pk11slot.obj: pk11slot.c @$(MAKE_OBJDIR) - $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call abspath,$<) + $(CC) -Fo$@ -c $(filter-out /O+, $(CFLAGS)) $(call core_abspath,$<) endif diff --git a/security/nss/lib/pk11wrap/pk11akey.c b/security/nss/lib/pk11wrap/pk11akey.c index a6189cf43..707989d9f 100644 --- a/security/nss/lib/pk11wrap/pk11akey.c +++ b/security/nss/lib/pk11wrap/pk11akey.c @@ -1313,68 +1313,6 @@ PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx) return NULL; } -static int -pk11_private_key_encrypt_buffer_length(SECKEYPrivateKey *key) - -{ - CK_ATTRIBUTE rsaTemplate = { CKA_MODULUS, NULL, 0 }; - CK_ATTRIBUTE dsaTemplate = { CKA_PRIME, NULL, 0 }; - /* XXX We should normally choose an attribute such that - * factor times its size is enough to hold the private key. - * For EC keys, we have no choice but to use CKA_EC_PARAMS, - * CKA_VALUE is not available for token keys. But for named - * curves, the number of bytes needed to represent the params - * is quite small so we bump up factor from 10 to 15. - */ - CK_ATTRIBUTE ecTemplate = { CKA_EC_PARAMS, NULL, 0 }; - CK_ATTRIBUTE_PTR pTemplate; - CK_RV crv; - int length; - int factor = 10; - - if(!key) { - return -1; - } - - switch (key->keyType) { - case rsaKey: - pTemplate = &rsaTemplate; - break; - case dsaKey: - case dhKey: - pTemplate = &dsaTemplate; - break; - case ecKey: - pTemplate = &ecTemplate; - factor = 15; - break; - case fortezzaKey: - default: - pTemplate = NULL; - } - - if(!pTemplate) { - return -1; - } - - crv = PK11_GetAttributes(NULL, key->pkcs11Slot, key->pkcs11ID, - pTemplate, 1); - if(crv != CKR_OK) { - PORT_SetError( PK11_MapError(crv) ); - return -1; - } - - length = pTemplate->ulValueLen; - length *= factor; - - - if(pTemplate->pValue != NULL) { - PORT_Free(pTemplate->pValue); - } - - return length; -} - SECKEYEncryptedPrivateKeyInfo * PK11_ExportEncryptedPrivKeyInfo( PK11SlotInfo *slot, /* optional, encrypt key in this slot */ @@ -1390,14 +1328,12 @@ PK11_ExportEncryptedPrivKeyInfo( SECItem *pbe_param = NULL; PK11SymKey *key = NULL; SECStatus rv = SECSuccess; - int encryptBufLen; CK_RV crv; - CK_ULONG encBufLenPtr; + CK_ULONG encBufLen; CK_MECHANISM_TYPE mechanism; CK_MECHANISM pbeMech; CK_MECHANISM cryptoMech; SECItem crypto_param; - SECItem encryptedKey = {siBuffer, NULL, 0}; if (!pwitem || !pk) { PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -1461,20 +1397,6 @@ PK11_ExportEncryptedPrivKeyInfo( crypto_param.data = (unsigned char *)cryptoMech.pParameter; crypto_param.len = cryptoMech.ulParameterLen; - - encryptBufLen = pk11_private_key_encrypt_buffer_length(pk); - if(encryptBufLen == -1) { - rv = SECFailure; - goto loser; - } - encryptedKey.len = (unsigned int)encryptBufLen; - encBufLenPtr = (CK_ULONG) encryptBufLen; - encryptedKey.data = (unsigned char *)PORT_ZAlloc(encryptedKey.len); - if(!encryptedKey.data) { - rv = SECFailure; - goto loser; - } - /* If the key isn't in the private key slot, move it */ if (key->slot != pk->pkcs11Slot) { PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot, @@ -1488,30 +1410,40 @@ PK11_ExportEncryptedPrivKeyInfo( PK11_FreeSymKey(key); key = newkey; } - + /* we are extracting an encrypted privateKey structure. * which needs to be freed along with the buffer into which it is * returned. eventually, we should retrieve an encrypted key using * pkcs8/pkcs5. */ + encBufLen = 0; PK11_EnterSlotMonitor(pk->pkcs11Slot); crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, - &cryptoMech, key->objectID, pk->pkcs11ID, encryptedKey.data, - &encBufLenPtr); + &cryptoMech, key->objectID, pk->pkcs11ID, NULL, + &encBufLen); PK11_ExitSlotMonitor(pk->pkcs11Slot); - encryptedKey.len = (unsigned int) encBufLenPtr; - if(crv != CKR_OK) { + if (crv != CKR_OK) { rv = SECFailure; goto loser; } - - if(!encryptedKey.len) { + epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen); + if (!epki->encryptedData.data) { + rv = SECFailure; + goto loser; + } + PK11_EnterSlotMonitor(pk->pkcs11Slot); + crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session, + &cryptoMech, key->objectID, pk->pkcs11ID, + epki->encryptedData.data, &encBufLen); + PK11_ExitSlotMonitor(pk->pkcs11Slot); + epki->encryptedData.len = (unsigned int) encBufLen; + if(crv != CKR_OK) { rv = SECFailure; goto loser; } - - rv = SECITEM_CopyItem(arena, &epki->encryptedData, &encryptedKey); - if(rv != SECSuccess) { + + if(!epki->encryptedData.len) { + rv = SECFailure; goto loser; } @@ -1739,18 +1671,17 @@ SECStatus PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force) { CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey); + SECStatus rv = SECWouldBlock; - /* found a cert matching the private key?. */ - if (!force && cert != NULL) { - /* yes, don't delete the key */ - CERT_DestroyCertificate(cert); - SECKEY_DestroyPrivateKey(privKey); - return SECWouldBlock; + if (!cert || force) { + /* now, then it's safe for the key to go away */ + rv = PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); + } + if (cert) { + CERT_DestroyCertificate(cert); } - /* now, then it's safe for the key to go away */ - PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID); SECKEY_DestroyPrivateKey(privKey); - return SECSuccess; + return rv; } /* @@ -1787,6 +1718,9 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) SECStatus rv = SECSuccess; SECKEYPrivateKey *privKey; pk11KeyCallback *keycb = (pk11KeyCallback *) arg; + if (!arg) { + return SECFailure; + } privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx); @@ -1794,7 +1728,7 @@ pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg) return SECFailure; } - if (keycb && (keycb->callback)) { + if (keycb->callback) { rv = (*keycb->callback)(privKey,keycb->callbackArg); } @@ -2026,6 +1960,7 @@ PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname) keys = SECKEY_NewPublicKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { @@ -2071,6 +2006,7 @@ PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx) keys = SECKEY_NewPrivateKeyList(); if (keys == NULL) { PORT_Free(key_ids); + return NULL; } for (i=0; i < objCount ; i++) { diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 08c0af2db..eb1a358b1 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -273,7 +273,7 @@ static CERTCertificate } /* Create a PKI object from the cryptoki instance */ - pkio = nssPKIObject_Create(NULL, co, td, NULL); + pkio = nssPKIObject_Create(NULL, co, td, NULL, nssPKIMonitor); if (!pkio) { nssCryptokiObject_Destroy(co); return NULL; @@ -481,7 +481,7 @@ PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *), struct nss3_cert_cbstr pk11cb; /* authenticate to the tokens first */ - (void) pk11_TraverseAllSlots( NULL, NULL, wincx); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, wincx); fda.callback = callback; fda.arg = arg; @@ -702,7 +702,30 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) &status); nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); - nssList_Destroy(nameList); + + /* if it wasn't found, repeat the process for email address */ + if (nssPKIObjectCollection_Count(collection) == 0 && + PORT_Strchr(nickname, '@') != NULL) + { + char* lowercaseName = CERT_FixupEmailAddr(nickname); + if (lowercaseName) { + (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, + lowercaseName, + nameList); + transfer_token_certs_to_collection(nameList, token, collection); + instances = nssToken_FindCertificatesByEmail(token, + NULL, + lowercaseName, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); + PORT_Free(lowercaseName); + } + } + + nssList_Destroy(nameList); foundCerts = nssPKIObjectCollection_GetCertificates(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); @@ -796,6 +819,8 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, NSSToken *token = PK11Slot_GetNSSToken(slot); SECItem *keyID = pk11_mkcertKeyID(cert); char *emailAddr = NULL; + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; if (keyID == NULL) { goto loser; @@ -815,9 +840,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, if (c->object.cryptoContext) { /* Delete the temp instance */ NSSCryptoContext *cc = c->object.cryptoContext; - nssCertificateStore_Lock(cc->certStore); + nssCertificateStore_Lock(cc->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); c->object.cryptoContext = NULL; cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; @@ -925,6 +951,7 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert, SECKEYPrivateKey * PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) { + int err; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_ATTRIBUTE theTemplate[] = { { CKA_VALUE, NULL, 0 }, @@ -935,6 +962,7 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, CK_OBJECT_HANDLE certh; CK_OBJECT_HANDLE keyh; CK_ATTRIBUTE *attrs = theTemplate; + PRBool needLogin; SECStatus rv; PK11_SETATTRS(attrs, CKA_VALUE, cert->derCert.data, @@ -953,10 +981,18 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert, if (certh == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY); - if ((keyh == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot, wincx)) { + if ((keyh == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* try it again authenticated */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) { @@ -983,6 +1019,7 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, CK_OBJECT_HANDLE key; PK11SlotInfo *slot = NULL; SECStatus rv; + int err; keyID = pk11_mkcertKeyID(cert); /* get them all! */ @@ -995,10 +1032,18 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr, /* Look for the slot that holds the Key */ for (le = list->head ; le; le = le->next) { + /* + * prevent a login race condition. If le->slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCertID, the find will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + PRBool needLogin = pk11_LoginStillRequired(le->slot,wincx); key = pk11_FindPrivateKeyFromCertID(le->slot,keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(le->slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(le->slot, PR_TRUE, wincx); if (rv != SECSuccess) continue; @@ -1084,7 +1129,6 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1159,7 +1203,7 @@ PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot, if (!instance) { goto loser; } - object = nssPKIObject_Create(NULL, instance, td, NULL); + object = nssPKIObject_Create(NULL, instance, td, NULL, nssPKIMonitor); if (!object) { goto loser; } @@ -1248,7 +1292,6 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1319,7 +1362,6 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr, /* get them all! */ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx); if (list == NULL) { - if (list) PK11_FreeSlotList(list); return CK_INVALID_HANDLE; } @@ -1553,16 +1595,26 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx) CK_OBJECT_HANDLE keyHandle; PK11SlotInfo *slot = NULL; SECKEYPrivateKey *privKey = NULL; + PRBool needLogin; SECStatus rv; + int err; certHandle = PK11_FindObjectForCert(cert, wincx, &slot); if (certHandle == CK_INVALID_HANDLE) { return NULL; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * PK11_MatchItem. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY); - if ((keyHandle == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((keyHandle == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err ) ) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv == SECSuccess) { @@ -1947,6 +1999,8 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, SECItem *keyID; CK_OBJECT_HANDLE key; SECStatus rv; + PRBool needLogin; + int err; if((slot == NULL) || (cert == NULL)) { return CK_INVALID_HANDLE; @@ -1957,10 +2011,18 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert, return CK_INVALID_HANDLE; } + /* + * prevent a login race condition. If slot is logged in between + * our call to pk11_LoginStillRequired and the + * pk11_FindPrivateKeyFromCerID. The matchItem call will either succeed, or + * we will call it one more time after calling PK11_Authenticate + * (which is a noop on an authenticated token). + */ + needLogin = pk11_LoginStillRequired(slot,wincx); key = pk11_FindPrivateKeyFromCertID(slot, keyID); - if ((key == CK_INVALID_HANDLE) && - (PORT_GetError() == SSL_ERROR_NO_CERTIFICATE) && - pk11_LoginStillRequired(slot,wincx)) { + if ((key == CK_INVALID_HANDLE) && needLogin && + (SSL_ERROR_NO_CERTIFICATE == (err = PORT_GetError()) || + SEC_ERROR_TOKEN_NOT_LOGGED_IN == err )) { /* authenticate and try again */ rv = PK11_Authenticate(slot, PR_TRUE, wincx); if (rv != SECSuccess) goto loser; @@ -2284,7 +2346,7 @@ PK11_ListCerts(PK11CertListType type, void *pwarg) listCerts.certList = certList; /* authenticate to the slots */ - (void) pk11_TraverseAllSlots( NULL, NULL, pwarg); + (void) pk11_TraverseAllSlots( NULL, NULL, PR_TRUE, pwarg); NSSTrustDomain_TraverseCertificates(defaultTD, pk11ListCertCallback, &listCerts); return certList; @@ -2348,6 +2410,9 @@ listCertsCallback(CERTCertificate* cert, void*arg) NSSCertificate *c = STAN_GetNSSCertificate(cert); instances = nssPKIObject_GetInstances(&c->object); + if (!instances) { + return SECFailure; + } instance = NULL; for (ci = instances; *ci; ci++) { if ((*ci)->token->pk11slot == cdata->slot) { diff --git a/security/nss/lib/pk11wrap/pk11cxt.c b/security/nss/lib/pk11wrap/pk11cxt.c index 4428fda9b..d4ce2b68d 100644 --- a/security/nss/lib/pk11wrap/pk11cxt.c +++ b/security/nss/lib/pk11wrap/pk11cxt.c @@ -249,7 +249,7 @@ static PK11Context *pk11_CreateNewContextInSlot(CK_MECHANISM_TYPE type, SECStatus rv; PORT_Assert(slot != NULL); - if (!slot) { + if (!slot || (!symKey && operation != CKA_DIGEST)) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } @@ -325,15 +325,15 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin, CK_ATTRIBUTE_TYPE operation, SECItem *key, SECItem *param, void *wincx) { - PK11SymKey *symKey; - PK11Context *context; + PK11SymKey *symKey = NULL; + PK11Context *context = NULL; /* first get a slot */ if (slot == NULL) { slot = PK11_GetBestSlot(type,wincx); if (slot == NULL) { PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; + goto loser; } } else { PK11_ReferenceSlot(slot); @@ -341,12 +341,17 @@ __PK11_CreateContextByRawKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, /* now import the key */ symKey = PK11_ImportSymKey(slot, type, origin, operation, key, wincx); - if (symKey == NULL) return NULL; + if (symKey == NULL) goto loser; context = PK11_CreateContextBySymKey(type, operation, symKey, param); - PK11_FreeSymKey(symKey); - PK11_FreeSlot(slot); +loser: + if (symKey) { + PK11_FreeSymKey(symKey); + } + if (slot) { + PK11_FreeSlot(slot); + } return context; } diff --git a/security/nss/lib/pk11wrap/pk11err.c b/security/nss/lib/pk11wrap/pk11err.c index a63475636..588d6512c 100644 --- a/security/nss/lib/pk11wrap/pk11err.c +++ b/security/nss/lib/pk11wrap/pk11err.c @@ -113,7 +113,7 @@ PK11_MapError(CK_RV rv) { MAPERROR(CKR_UNWRAPPING_KEY_SIZE_RANGE, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY) MAPERROR(CKR_USER_ALREADY_LOGGED_IN, 0) - MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_LIBRARY_FAILURE) /* XXXX */ + MAPERROR(CKR_USER_NOT_LOGGED_IN, SEC_ERROR_TOKEN_NOT_LOGGED_IN) MAPERROR(CKR_USER_PIN_NOT_INITIALIZED, SEC_ERROR_NO_TOKEN) MAPERROR(CKR_USER_TYPE_INVALID, SEC_ERROR_LIBRARY_FAILURE) MAPERROR(CKR_WRAPPED_KEY_INVALID, SEC_ERROR_INVALID_KEY) diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c index a0db40729..7664d8071 100644 --- a/security/nss/lib/pk11wrap/pk11kea.c +++ b/security/nss/lib/pk11wrap/pk11kea.c @@ -152,82 +152,6 @@ rsa_failed: return newSymKey; } - /* KEA */ - if (PK11_DoesMechanism(symKey->slot, CKM_KEA_KEY_DERIVE) && - PK11_DoesMechanism(slot,CKM_KEA_KEY_DERIVE)) { - CERTCertificate *certSource = NULL; - CERTCertificate *certTarget = NULL; - SECKEYPublicKey *pubKeySource = NULL; - SECKEYPublicKey *pubKeyTarget = NULL; - SECKEYPrivateKey *privKeySource = NULL; - SECKEYPrivateKey *privKeyTarget = NULL; - PK11SymKey *tekSource = NULL; - PK11SymKey *tekTarget = NULL; - SECItem Ra,wrap; - - /* can only exchange skipjack keys */ - if ((type != CKM_SKIPJACK_CBC64) || (isPerm)) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - /* find a pair of certs we can use */ - rv = PK11_GetKEAMatchedCerts(symKey->slot,slot,&certSource,&certTarget); - if (rv != SECSuccess) goto kea_failed; - - /* get all the key pairs */ - pubKeyTarget = CERT_ExtractPublicKey(certSource); - pubKeySource = CERT_ExtractPublicKey(certTarget); - privKeySource = - PK11_FindKeyByDERCert(symKey->slot,certSource,symKey->cx); - privKeyTarget = - PK11_FindKeyByDERCert(slot,certTarget,symKey->cx); - - if ((pubKeySource == NULL) || (pubKeyTarget == NULL) || - (privKeySource == NULL) || (privKeyTarget == NULL)) goto kea_failed; - - /* generate the wrapping TEK's */ - Ra.data = (unsigned char*)PORT_Alloc(128 /* FORTEZZA RA MAGIC */); - Ra.len = 128; - if (Ra.data == NULL) goto kea_failed; - - tekSource = PK11_PubDerive(privKeySource,pubKeyTarget,PR_TRUE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - tekTarget = PK11_PubDerive(privKeyTarget,pubKeySource,PR_FALSE,&Ra,NULL, - CKM_SKIPJACK_WRAP, CKM_KEA_KEY_DERIVE,CKA_WRAP,0,symKey->cx); - PORT_Free(Ra.data); - - if ((tekSource == NULL) || (tekTarget == NULL)) { goto kea_failed; } - - /* wrap the key out of Source into target */ - wrap.data = (unsigned char*)PORT_Alloc(12); /* MAGIC SKIPJACK LEN */ - wrap.len = 12; - - /* paranoia to prevent infinite recursion on bugs */ - PORT_Assert(tekSource->slot == symKey->slot); - if (tekSource->slot != symKey->slot) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - goto kea_failed; - } - - rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP,NULL,tekSource,symKey,&wrap); - if (rv == SECSuccess) { - newSymKey = PK11_UnwrapSymKeyWithFlags(tekTarget, - CKM_SKIPJACK_WRAP, NULL, - &wrap, type, operation, flags, symKey->size); - } - PORT_Free(wrap.data); -kea_failed: - if (certSource == NULL) CERT_DestroyCertificate(certSource); - if (certTarget == NULL) CERT_DestroyCertificate(certTarget); - if (pubKeySource == NULL) SECKEY_DestroyPublicKey(pubKeySource); - if (pubKeyTarget == NULL) SECKEY_DestroyPublicKey(pubKeyTarget); - if (privKeySource == NULL) SECKEY_DestroyPrivateKey(privKeySource); - if (privKeyTarget == NULL) SECKEY_DestroyPrivateKey(privKeyTarget); - if (tekSource == NULL) PK11_FreeSymKey(tekSource); - if (tekTarget == NULL) PK11_FreeSymKey(tekTarget); - return newSymKey; - } PORT_SetError( SEC_ERROR_NO_MODULE ); return NULL; } diff --git a/security/nss/lib/pk11wrap/pk11mech.c b/security/nss/lib/pk11wrap/pk11mech.c index 1f8f2a372..fe106de50 100644 --- a/security/nss/lib/pk11wrap/pk11mech.c +++ b/security/nss/lib/pk11wrap/pk11mech.c @@ -823,7 +823,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) rc5_cbc_params = (CK_RC5_CBC_PARAMS *) PORT_Alloc(sizeof(CK_RC5_CBC_PARAMS) + ((iv) ? iv->len : 0)); if (rc5_cbc_params == NULL) break; - if (iv && iv->data) { + if (iv && iv->data && iv->len) { rc5_cbc_params->pIv = ((CK_BYTE_PTR) rc5_cbc_params) + sizeof(CK_RC5_CBC_PARAMS); PORT_Memcpy(rc5_cbc_params->pIv,iv->data,iv->len); @@ -832,7 +832,7 @@ PK11_ParamFromIV(CK_MECHANISM_TYPE type,SECItem *iv) } else { rc5_cbc_params->ulWordsize = 4; rc5_cbc_params->pIv = NULL; - rc5_cbc_params->ulIvLen = iv->len; + rc5_cbc_params->ulIvLen = 0; } rc5_cbc_params->ulRounds = 16; param->data = (unsigned char *) rc5_cbc_params; diff --git a/security/nss/lib/pk11wrap/pk11nobj.c b/security/nss/lib/pk11wrap/pk11nobj.c index db9aa6ba9..3a88ef4ae 100644 --- a/security/nss/lib/pk11wrap/pk11nobj.c +++ b/security/nss/lib/pk11wrap/pk11nobj.c @@ -270,7 +270,7 @@ PK11_LookupCrls(CERTCrlHeadNode *nodes, int type, void *wincx) { creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } struct crlOptionsStr { @@ -421,7 +421,7 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, creater.findTemplate = theTemplate; creater.templateCount = (attrs - theTemplate); - return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx); + return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, PR_FALSE, wincx); } /* @@ -429,12 +429,15 @@ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, - SECItem *name, int type, char **url) + SECItem *name, int type, char **pUrl) { - NSSCRL **crls, **crlp, *crl; + NSSCRL **crls, **crlp, *crl = NULL; NSSDER subject; SECItem *rvItem; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); + char * url = NULL; + + PORT_SetError(0); NSSITEM_FROM_SECITEM(&subject, name); if (*slot) { nssCryptokiObject **instances; @@ -443,7 +446,7 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, NSSToken *token = PK11Slot_GetNSSToken(*slot); collection = nssCRLCollection_Create(td, NULL); if (!collection) { - return NULL; + goto loser; } instances = nssToken_FindCRLsBySubject(token, NULL, &subject, tokenOnly, 0, NULL); @@ -461,9 +464,8 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, if (NSS_GetError() == NSS_ERROR_NOT_FOUND) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } - return NULL; + goto loser; } - crl = NULL; for (crlp = crls; *crlp; crlp++) { if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || ((*crlp)->isKRL && type != SEC_CRL_TYPE)) @@ -477,28 +479,34 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, /* CRL collection was found, but no interesting CRL's were on it. * Not an error */ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); - return NULL; + goto loser; } if (crl->url) { - *url = PORT_Strdup(crl->url); - if (!*url) { - nssCRL_Destroy(crl); - return NULL; + url = PORT_Strdup(crl->url); + if (!url) { + goto loser; } - } else { - *url = NULL; } rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); if (!rvItem) { - PORT_Free(*url); - nssCRL_Destroy(crl); - return NULL; + goto loser; } memcpy(rvItem->data, crl->encoding.data, crl->encoding.size); *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot); *crlHandle = crl->object.instances[0]->handle; + *pUrl = url; nssCRL_Destroy(crl); return rvItem; + +loser: + if (url) + PORT_Free(url); + if (crl) + nssCRL_Destroy(crl); + if (PORT_GetError() == 0) { + PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); + } + return NULL; } CK_OBJECT_HANDLE diff --git a/security/nss/lib/pk11wrap/pk11obj.c b/security/nss/lib/pk11wrap/pk11obj.c index 65b47ef96..91a28321e 100644 --- a/security/nss/lib/pk11wrap/pk11obj.c +++ b/security/nss/lib/pk11wrap/pk11obj.c @@ -571,11 +571,14 @@ PK11_SignatureLen(SECKEYPrivateKey *key) if (theTemplate.pValue != NULL) { params.len = theTemplate.ulValueLen; params.data = (unsigned char *) theTemplate.pValue; - length = SECKEY_ECParamsToKeySize(¶ms); + length = SECKEY_ECParamsToBasePointOrderLen(¶ms); PORT_Free(theTemplate.pValue); + if (length == 0) { + return pk11_backupGetSignLength(key); + } + length = ((length + 7)/8) * 2; + return length; } - length = ((length + 7)/8) * 2; - return length; } break; default: @@ -948,7 +951,9 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, sizeof(cktrue)); attrs++; PK11_SETATTRS(attrs, CKA_SENSITIVE, sensitive ? &cktrue : &ckfalse, sizeof(cktrue)); attrs++; - PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + if (label && label->data) { + PK11_SETATTRS(attrs, CKA_LABEL, label->data, label->len); attrs++; + } PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); attrs++; for (i=0; i < usageCount; i++) { PK11_SETATTRS(attrs, usage[i], &cktrue, sizeof(cktrue)); attrs++; @@ -1568,8 +1573,8 @@ PK11_TraverseSlot(PK11SlotInfo *slot, void *arg) * Traverse all the objects in all slots. */ SECStatus -pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *arg,void *wincx) { +pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), + void *arg, PRBool forceLogin, void *wincx) { PK11SlotList *list; PK11SlotListElement *le; SECStatus rv; @@ -1580,9 +1585,11 @@ pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), /* look at each slot and authenticate as necessary */ for (le = list->head ; le; le = le->next) { - rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); - if (rv != SECSuccess) { - continue; + if (forceLogin) { + rv = pk11_AuthenticateUnfriendly(le->slot, PR_FALSE, wincx); + if (rv != SECSuccess) { + continue; + } } if (callback) { (*callback)(le->slot,arg); diff --git a/security/nss/lib/pk11wrap/pk11pbe.c b/security/nss/lib/pk11wrap/pk11pbe.c index 1234af856..07ac7dff4 100644 --- a/security/nss/lib/pk11wrap/pk11pbe.c +++ b/security/nss/lib/pk11wrap/pk11pbe.c @@ -704,10 +704,10 @@ pk11_destroy_ck_pbe_params(CK_PBE_PARAMS *pbe_params) { if (pbe_params) { if (pbe_params->pPassword) - PORT_ZFree(pbe_params->pPassword, PR_FALSE); + PORT_ZFree(pbe_params->pPassword, pbe_params->ulPasswordLen); if (pbe_params->pSalt) - PORT_ZFree(pbe_params->pSalt, PR_FALSE); - PORT_ZFree(pbe_params, PR_TRUE); + PORT_ZFree(pbe_params->pSalt, pbe_params->ulSaltLen); + PORT_ZFree(pbe_params, sizeof(CK_PBE_PARAMS)); } } @@ -716,30 +716,49 @@ PK11_CreatePBEParams(SECItem *salt, SECItem *pwd, unsigned int iterations) { CK_PBE_PARAMS *pbe_params = NULL; SECItem *paramRV = NULL; - pbe_params = (CK_PBE_PARAMS *)PORT_ZAlloc(sizeof(CK_PBE_PARAMS)); + + paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); + if (!paramRV ) { + goto loser; + } + /* init paramRV->data with zeros. SECITEM_AllocItem does not do it */ + PORT_Memset(paramRV->data, 0, sizeof(CK_PBE_PARAMS)); + + pbe_params = (CK_PBE_PARAMS *)paramRV->data; pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwd->len); - if (pbe_params->pPassword != NULL) { - PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); - pbe_params->ulPasswordLen = pwd->len; - } else goto loser; + if (!pbe_params->pPassword) { + goto loser; + } + PORT_Memcpy(pbe_params->pPassword, pwd->data, pwd->len); + pbe_params->ulPasswordLen = pwd->len; + pbe_params->pSalt = (CK_CHAR_PTR)PORT_ZAlloc(salt->len); - if (pbe_params->pSalt != NULL) { - PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); - pbe_params->ulSaltLen = salt->len; - } else goto loser; + if (!pbe_params->pSalt) { + goto loser; + } + PORT_Memcpy(pbe_params->pSalt, salt->data, salt->len); + pbe_params->ulSaltLen = salt->len; + pbe_params->ulIteration = (CK_ULONG)iterations; - paramRV = SECITEM_AllocItem(NULL, NULL, sizeof(CK_PBE_PARAMS)); - paramRV->data = (unsigned char *)pbe_params; return paramRV; + loser: - pk11_destroy_ck_pbe_params(pbe_params); + if (pbe_params) + pk11_destroy_ck_pbe_params(pbe_params); + if (paramRV) + PORT_ZFree(paramRV, sizeof(SECItem)); return NULL; } void -PK11_DestroyPBEParams(SECItem *params) +PK11_DestroyPBEParams(SECItem *pItem) { - pk11_destroy_ck_pbe_params((CK_PBE_PARAMS *)params->data); + if (pItem) { + CK_PBE_PARAMS * params = (CK_PBE_PARAMS *)(pItem->data); + if (params) + pk11_destroy_ck_pbe_params(params); + PORT_ZFree(pItem, sizeof(SECItem)); + } } SECAlgorithmID * @@ -766,6 +785,9 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, } pbe_params = (CK_PBE_PARAMS *)mech->data; + if (!pbe_params) { + return NULL; + } pbe_params->pPassword = (CK_CHAR_PTR)PORT_ZAlloc(pwitem->len); if(pbe_params->pPassword != NULL) { PORT_Memcpy(pbe_params->pPassword, pwitem->data, pwitem->len); @@ -775,7 +797,8 @@ PK11_RawPBEKeyGen(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *mech, return NULL; } - symKey = PK11_KeyGen(slot, type, mech, 0, wincx); + symKey = PK11_TokenKeyGenWithFlags(slot, type, mech, 0, NULL, + CKF_SIGN|CKF_ENCRYPT|CKF_DECRYPT|CKF_UNWRAP|CKF_WRAP, 0, wincx); PORT_ZFree(pbe_params->pPassword, pwitem->len); pbe_params->pPassword = NULL; diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c index 35a4cbc07..9c8afdf4e 100644 --- a/security/nss/lib/pk11wrap/pk11pk12.c +++ b/security/nss/lib/pk11wrap/pk11pk12.c @@ -250,7 +250,13 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, SECStatus rv = SECFailure; temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (!temparena) + return rv; pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); + if (!pki) { + PORT_FreeArena(temparena, PR_FALSE); + return rv; + } pki->arena = temparena; rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, @@ -263,10 +269,8 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, publicValue, isPerm, isPrivate, keyUsage, privk, wincx); finish: - if( pki != NULL ) { - /* this zeroes the key and frees the arena */ - SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); - } + /* this zeroes the key and frees the arena */ + SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); return rv; } diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c index 62afc7756..711818639 100644 --- a/security/nss/lib/pk11wrap/pk11pqg.c +++ b/security/nss/lib/pk11wrap/pk11pqg.c @@ -119,6 +119,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, } parena = PORT_NewArena(60); + if (!parena) { + goto loser; + } + crv = PK11_GetAttributes(parena, slot, objectID, pTemplate, pTemplateCount); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); @@ -145,6 +149,10 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes, varena = PORT_NewArena(60); + if (!varena) { + goto loser; + } + crv = PK11_GetAttributes(varena, slot, objectID, vTemplate, vTemplateCount); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); diff --git a/security/nss/lib/pk11wrap/pk11priv.h b/security/nss/lib/pk11wrap/pk11priv.h index 6d0b012b0..feef1959a 100644 --- a/security/nss/lib/pk11wrap/pk11priv.h +++ b/security/nss/lib/pk11wrap/pk11priv.h @@ -207,7 +207,7 @@ SECStatus PK11_SetObjectNickname(PK11SlotInfo *slot, CK_OBJECT_HANDLE id, /* private */ SECStatus pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *), - void *cbArg, void *pwArg); + void *cbArg, PRBool forceLogin, void *pwArg); /* fetch multiple CRLs for a specific issuer */ SECStatus pk11_RetrieveCrls(CERTCrlHeadNode *nodes, SECItem* issuer, diff --git a/security/nss/lib/pk11wrap/pk11pub.h b/security/nss/lib/pk11wrap/pk11pub.h index 8a933cc93..4c674d48e 100644 --- a/security/nss/lib/pk11wrap/pk11pub.h +++ b/security/nss/lib/pk11wrap/pk11pub.h @@ -582,6 +582,14 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url, /********************************************************************** * Sign/Verify **********************************************************************/ + +/* + * Return the length in bytes of a signature generated with the + * private key. + * + * Return 0 or -1 on failure. (XXX Should we fix it to always return + * -1 on failure?) + */ int PK11_SignatureLen(SECKEYPrivateKey *key); PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key); SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, SECItem *hash); diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index ce5cbd811..f7cb05411 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -929,6 +929,13 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, count = attrs - genTemplate; PR_ASSERT(count <= sizeof(genTemplate)/sizeof(CK_ATTRIBUTE)); + /* Initialize the Key Gen Mechanism */ + mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); + if (mechanism.mechanism == CKM_FAKE_RANDOM) { + PORT_SetError( SEC_ERROR_NO_MODULE ); + return NULL; + } + /* find a slot to generate the key into */ /* Only do slot management if this is not a token key */ if (!isToken && (slot == NULL || !PK11_DoesMechanism(slot,type))) { @@ -951,13 +958,6 @@ PK11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, symKey->size = keySize; symKey->origin = PK11_OriginGenerated; - /* Initialize the Key Gen Mechanism */ - mechanism.mechanism = PK11_GetKeyGenWithSize(type, keySize); - if (mechanism.mechanism == CKM_FAKE_RANDOM) { - PORT_SetError( SEC_ERROR_NO_MODULE ); - return NULL; - } - /* Set the parameters for the key gen if provided */ mechanism.pParameter = NULL; mechanism.ulParameterLen = 0; @@ -1646,17 +1646,35 @@ PK11_PubDerive(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, return NULL; } -PK11SymKey * -PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, - PRBool isSender, SECItem *randomA, SECItem *randomB, - CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize, - CK_ULONG kdf, SECItem *sharedData, void *wincx) +static PK11SymKey * +pk11_PubDeriveECKeyWithKDF( + SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, + PRBool isSender, SECItem *randomA, SECItem *randomB, + CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_ULONG kdf, SECItem *sharedData, void *wincx) { - PK11SlotInfo *slot = privKey->pkcs11Slot; - PK11SymKey *symKey; - CK_MECHANISM mechanism; - CK_RV crv; + PK11SlotInfo *slot = privKey->pkcs11Slot; + PK11SymKey *symKey; + CK_MECHANISM mechanism; + CK_RV crv; + CK_BBOOL cktrue = CK_TRUE; + CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; + CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; + CK_ULONG key_size = 0; + CK_ATTRIBUTE keyTemplate[4]; + int templateCount; + CK_ATTRIBUTE *attrs = keyTemplate; + CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; + + if (pubKey->keyType != ecKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } + if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + return NULL; + } /* get our key Structure */ symKey = pk11_CreateSymKey(slot, target, PR_TRUE, PR_TRUE, wincx); @@ -1666,6 +1684,62 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, symKey->origin = PK11_OriginDerive; + PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); attrs++; + PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); attrs++; + PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; + PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); attrs++; + templateCount = attrs - keyTemplate; + PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); + + keyType = PK11_GetKeyType(target,keySize); + key_size = keySize; + symKey->size = keySize; + if (key_size == 0) + templateCount--; + + mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); + if (!mechParams) { + PK11_FreeSymKey(symKey); + return NULL; + } + mechParams->kdf = kdf; + if (sharedData == NULL) { + mechParams->ulSharedDataLen = 0; + mechParams->pSharedData = NULL; + } else { + mechParams->ulSharedDataLen = sharedData->len; + mechParams->pSharedData = sharedData->data; + } + mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; + mechParams->pPublicData = pubKey->u.ec.publicValue.data; + + mechanism.mechanism = derive; + mechanism.pParameter = mechParams; + mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); + + pk11_EnterKeyMonitor(symKey); + crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, &mechanism, + privKey->pkcs11ID, keyTemplate, templateCount, &symKey->objectID); + pk11_ExitKeyMonitor(symKey); + + PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); + + if (crv != CKR_OK) { + PK11_FreeSymKey(symKey); + symKey = NULL; + PORT_SetError( PK11_MapError(crv) ); + } + return symKey; +} + +PK11SymKey * +PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, + PRBool isSender, SECItem *randomA, SECItem *randomB, + CK_MECHANISM_TYPE derive, CK_MECHANISM_TYPE target, + CK_ATTRIBUTE_TYPE operation, int keySize, + CK_ULONG kdf, SECItem *sharedData, void *wincx) +{ + switch (privKey->keyType) { case rsaKey: case nullKey: @@ -1673,75 +1747,16 @@ PK11_PubDeriveWithKDF(SECKEYPrivateKey *privKey, SECKEYPublicKey *pubKey, case keaKey: case fortezzaKey: case dhKey: - PK11_FreeSymKey(symKey); return PK11_PubDerive(privKey, pubKey, isSender, randomA, randomB, derive, target, operation, keySize, wincx); case ecKey: - { - CK_BBOOL cktrue = CK_TRUE; - CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; - CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; - CK_ULONG key_size = 0; - CK_ATTRIBUTE keyTemplate[4]; - int templateCount; - CK_ATTRIBUTE *attrs = keyTemplate; - CK_ECDH1_DERIVE_PARAMS *mechParams = NULL; - - if (pubKey->keyType != ecKey) { - PORT_SetError(SEC_ERROR_BAD_KEY); - break; - } - - PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass)); - attrs++; - PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType)); - attrs++; - PK11_SETATTRS(attrs, operation, &cktrue, 1); attrs++; - PK11_SETATTRS(attrs, CKA_VALUE_LEN, &key_size, sizeof(key_size)); - attrs++; - templateCount = attrs - keyTemplate; - PR_ASSERT(templateCount <= sizeof(keyTemplate)/sizeof(CK_ATTRIBUTE)); - - keyType = PK11_GetKeyType(target,keySize); - key_size = keySize; - symKey->size = keySize; - if (key_size == 0) templateCount--; - - mechParams = PORT_ZNew(CK_ECDH1_DERIVE_PARAMS); - if ((kdf < CKD_NULL) || (kdf > CKD_SHA1_KDF)) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - break; - } - mechParams->kdf = kdf; - if (sharedData == NULL) { - mechParams->ulSharedDataLen = 0; - mechParams->pSharedData = NULL; - } else { - mechParams->ulSharedDataLen = sharedData->len; - mechParams->pSharedData = sharedData->data; - } - mechParams->ulPublicDataLen = pubKey->u.ec.publicValue.len; - mechParams->pPublicData = pubKey->u.ec.publicValue.data; - - mechanism.mechanism = derive; - mechanism.pParameter = mechParams; - mechanism.ulParameterLen = sizeof(CK_ECDH1_DERIVE_PARAMS); - - pk11_EnterKeyMonitor(symKey); - crv = PK11_GETTAB(slot)->C_DeriveKey(symKey->session, - &mechanism, privKey->pkcs11ID, keyTemplate, - templateCount, &symKey->objectID); - pk11_ExitKeyMonitor(symKey); - - PORT_ZFree(mechParams, sizeof(CK_ECDH1_DERIVE_PARAMS)); - - if (crv == CKR_OK) return symKey; - PORT_SetError( PK11_MapError(crv) ); - } - } + return pk11_PubDeriveECKeyWithKDF( privKey, pubKey, isSender, + randomA, randomB, derive, target, operation, keySize, + kdf, sharedData, wincx); + default: break; + } - PK11_FreeSymKey(symKey); - return NULL; + return NULL; } /* diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index a92fbf7df..94d4ffaba 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -354,7 +354,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_NewLock(nssILockSession) : mod->refLock; if (slot->sessionLock == NULL) { PORT_Free(slot); - return slot; + return NULL; } slot->freeListLock = PZ_NewLock(nssILockFreelist); if (slot->freeListLock == NULL) { @@ -362,7 +362,7 @@ PK11_NewSlotInfo(SECMODModule *mod) PZ_DestroyLock(slot->sessionLock); } PORT_Free(slot); - return slot; + return NULL; } slot->freeSymKeysWithSessionHead = NULL; slot->freeSymKeysHead = NULL; diff --git a/security/nss/lib/pk11wrap/secmod.h b/security/nss/lib/pk11wrap/secmod.h index 83545f5e3..68ac59f27 100644 --- a/security/nss/lib/pk11wrap/secmod.h +++ b/security/nss/lib/pk11wrap/secmod.h @@ -55,6 +55,9 @@ #define PUBLIC_MECH_MD2_FLAG 0x00000400ul #define PUBLIC_MECH_SSL_FLAG 0x00000800ul #define PUBLIC_MECH_TLS_FLAG 0x00001000ul +#define PUBLIC_MECH_AES_FLAG 0x00002000ul +#define PUBLIC_MECH_SHA256_FLAG 0x00004000ul +#define PUBLIC_MECH_SHA512_FLAG 0x00008000ul #define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul #define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul @@ -62,7 +65,7 @@ #define PUBLIC_DISABLE_FLAG 0x40000000ul /* warning: reserved means reserved */ -#define PUBLIC_MECH_RESERVED_FLAGS 0x87FFE000ul +#define PUBLIC_MECH_RESERVED_FLAGS 0x87FF0000ul /* These cipher flags are visible to all other libraries, */ /* But they must be converted before used in functions */ diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c index 2d4d29cae..bcbea25a5 100644 --- a/security/nss/lib/pkcs12/p12d.c +++ b/security/nss/lib/pkcs12/p12d.c @@ -543,15 +543,15 @@ sec_pkcs12_decoder_safe_contents_init_decode(SEC_PKCS12DecoderContext *p12dcx, if(!p12dcx->safeContentsCnt) { p12dcx->safeContentsList = (sec_PKCS12SafeContentsContext**)PORT_ArenaZAlloc(p12dcx->arena, - sizeof(sec_PKCS12SafeContentsContext *)); + 2 * sizeof(sec_PKCS12SafeContentsContext *)); } else { p12dcx->safeContentsList = (sec_PKCS12SafeContentsContext **) PORT_ArenaGrow(p12dcx->arena, p12dcx->safeContentsList, - (p12dcx->safeContentsCnt * - sizeof(sec_PKCS12SafeContentsContext *)), - (1 + p12dcx->safeContentsCnt * - sizeof(sec_PKCS12SafeContentsContext *))); + (1 + p12dcx->safeContentsCnt) * + sizeof(sec_PKCS12SafeContentsContext *), + (2 + p12dcx->safeContentsCnt) * + sizeof(sec_PKCS12SafeContentsContext *)); } if(!p12dcx->safeContentsList) { p12dcx->errorValue = SEC_ERROR_NO_MEMORY; @@ -2561,7 +2561,7 @@ CERTCertList * SEC_PKCS12DecoderGetCerts(SEC_PKCS12DecoderContext *p12dcx) { CERTCertList *certList = NULL; - sec_PKCS12SafeBag **safeBags = p12dcx->safeBags; + sec_PKCS12SafeBag **safeBags; int i; if (!p12dcx || !p12dcx->safeBags || !p12dcx->safeBags[0]) { @@ -2721,7 +2721,7 @@ SEC_PKCS12DecoderValidateBags(SEC_PKCS12DecoderContext *p12dcx, { SECStatus rv; int i, noInstallCnt, probCnt, bagCnt, errorVal = 0; - if(!p12dcx || p12dcx->error) { + if(!p12dcx || p12dcx->error || !p12dcx->safeBags) { return SECFailure; } diff --git a/security/nss/lib/pkcs7/p7decode.c b/security/nss/lib/pkcs7/p7decode.c index 37a0c5b40..df3919975 100644 --- a/security/nss/lib/pkcs7/p7decode.c +++ b/security/nss/lib/pkcs7/p7decode.c @@ -1665,7 +1665,9 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, algiddata = SECOID_FindOID (&(signerinfo->digestEncAlg.algorithm)); if (algiddata == NULL || ((algiddata->offset != SEC_OID_PKCS1_RSA_ENCRYPTION) && +#ifdef NSS_ECC_MORE_THAN_SUITE_B (algiddata->offset != SEC_OID_ANSIX962_EC_PUBLIC_KEY) && +#endif (algiddata->offset != SEC_OID_ANSIX9_DSA_SIGNATURE))) { PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); goto done; diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 3abca38c1..8c7609a8b 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -79,6 +79,7 @@ nssCertificate_Create ( /* mark? */ NSSArena *arena = object->arena; PR_ASSERT(object->instances != NULL && object->numInstances > 0); + PR_ASSERT(object->lockType == nssPKIMonitor); rvCert = nss_ZNEW(arena, NSSCertificate); if (!rvCert) { return (NSSCertificate *)NULL; @@ -120,6 +121,10 @@ nssCertificate_Destroy ( NSSCertificate *c ) { + nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; + PRBool locked = PR_FALSE; + if (c) { PRUint32 i; nssDecodedCert *dc = c->decoding; @@ -130,7 +135,8 @@ nssCertificate_Destroy ( /* --- LOCK storage --- */ if (cc) { - nssCertificateStore_Lock(cc->certStore); + nssCertificateStore_Lock(cc->certStore, &lockTrace); + locked = PR_TRUE; } else { nssTrustDomain_LockCertCache(td); } @@ -138,7 +144,10 @@ nssCertificate_Destroy ( /* --- remove cert and UNLOCK storage --- */ if (cc) { nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, &lockTrace, + &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); + } else { nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); nssTrustDomain_UnlockCertCache(td); @@ -147,18 +156,24 @@ nssCertificate_Destroy ( for (i=0; i<c->object.numInstances; i++) { nssCryptokiObject_Destroy(c->object.instances[i]); } - PZ_DestroyLock(c->object.lock); + nssPKIObject_DestroyLock(&c->object); nssArena_Destroy(c->object.arena); nssDecodedCert_Destroy(dc); } else { /* --- UNLOCK storage --- */ if (cc) { - nssCertificateStore_Unlock(cc->certStore); + nssCertificateStore_Unlock(cc->certStore, + &lockTrace, + &unlockTrace); + nssCertificateStore_Check(&lockTrace, &unlockTrace); } else { nssTrustDomain_UnlockCertCache(td); } } } + if (locked) { + nssCertificateStore_Check(&lockTrace, &unlockTrace); + } return PR_SUCCESS; } @@ -304,25 +319,17 @@ nssCertificate_GetDecoding ( NSSCertificate *c ) { - /* There is a race in assigning c->decoding. - ** This is a workaround. Bugzilla bug 225525. - */ + nssDecodedCert* deco = NULL; + nssPKIObject_Lock(&c->object); if (!c->decoding) { - nssDecodedCert * deco = - nssDecodedCert_Create(NULL, &c->encoding, c->type); - /* Once this race is fixed, an assertion should be put - ** here to detect any regressions. + deco = nssDecodedCert_Create(NULL, &c->encoding, c->type); PORT_Assert(!c->decoding); - */ - if (!c->decoding) { - /* we won the race. Use our copy. */ - c->decoding = deco; - } else { - /* we lost the race. discard deco. */ - nssDecodedCert_Destroy(deco); - } + c->decoding = deco; + } else { + deco = c->decoding; } - return c->decoding; + nssPKIObject_Unlock(&c->object); + return deco; } static NSSCertificate ** @@ -896,7 +903,7 @@ nssSMIMEProfile_Create ( if (!arena) { return NULL; } - object = nssPKIObject_Create(arena, NULL, td, cc); + object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock); if (!object) { goto loser; } @@ -916,7 +923,8 @@ nssSMIMEProfile_Create ( } return rvProfile; loser: - nssPKIObject_Destroy(object); + if (object) nssPKIObject_Destroy(object); + else if (arena) nssArena_Destroy(arena); return (nssSMIMEProfile *)NULL; } @@ -991,7 +999,7 @@ nssTrust_Create ( sha1_hash.data = sha1_hashin; sha1_hash.size = sizeof (sha1_hashin); /* trust has to peek into the base object members */ - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { instance = object->instances[i]; myTrustOrder = nssToken_GetTrustOrder(instance->token); @@ -1003,11 +1011,11 @@ nssTrust_Create ( &emailProtection, &stepUp); if (status != PR_SUCCESS) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (PORT_Memcmp(sha1_hashin,sha1_hashcmp,SHA1_LENGTH) != 0) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (rvt->serverAuth == nssTrustLevel_Unknown || @@ -1033,7 +1041,7 @@ nssTrust_Create ( rvt->stepUpApproved = stepUp; lastTrustOrder = myTrustOrder; } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return rvt; } diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c index 6b8a724c3..5e1be597e 100644 --- a/security/nss/lib/pki/cryptocontext.c +++ b/security/nss/lib/pki/cryptocontext.c @@ -65,6 +65,7 @@ struct NSSCryptoContextStr #endif extern const NSSError NSS_ERROR_NOT_FOUND; +extern const NSSError NSS_ERROR_INVALID_ARGUMENT; NSS_IMPLEMENT NSSCryptoContext * nssCryptoContext_Create ( @@ -84,6 +85,12 @@ nssCryptoContext_Create ( } rvCC->td = td; rvCC->arena = arena; + rvCC->certStore = nssCertificateStore_Create(rvCC->arena); + if (!rvCC->certStore) { + nssArena_Destroy(arena); + return NULL; + } + return rvCC; } @@ -93,11 +100,14 @@ NSSCryptoContext_Destroy ( ) { PRStatus status = PR_SUCCESS; + PORT_Assert(cc->certStore); if (cc->certStore) { status = nssCertificateStore_Destroy(cc->certStore); if (status == PR_FAILURE) { return status; } + } else { + status = PR_FAILURE; } nssArena_Destroy(cc->arena); return status; @@ -133,24 +143,33 @@ NSSCryptoContext_GetTrustDomain ( return NULL; } -NSS_IMPLEMENT PRStatus -NSSCryptoContext_ImportCertificate ( + +NSS_IMPLEMENT NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( NSSCryptoContext *cc, NSSCertificate *c ) { - PRStatus nssrv; + NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + nss_SetError(NSS_ERROR_INVALID_ARGUMENT); + return rvCert; } - nssrv = nssCertificateStore_Add(cc->certStore, c); - if (nssrv == PR_SUCCESS) { + rvCert = nssCertificateStore_FindOrAdd(cc->certStore, c); + if (rvCert == c && c->object.cryptoContext != cc) { + PORT_Assert(!c->object.cryptoContext); c->object.cryptoContext = cc; + } + if (rvCert) { + /* an NSSCertificate cannot be part of two crypto contexts + ** simultaneously. If this assertion fails, then there is + ** a serious Stan design flaw. + */ + PORT_Assert(cc == c->object.cryptoContext); } - return nssrv; + return rvCert; } NSS_IMPLEMENT NSSCertificate * @@ -190,11 +209,9 @@ nssCryptoContext_ImportTrust ( ) { PRStatus nssrv; + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + return PR_FAILURE; } nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); #if 0 @@ -212,11 +229,9 @@ nssCryptoContext_ImportSMIMEProfile ( ) { PRStatus nssrv; + PORT_Assert(cc->certStore); if (!cc->certStore) { - cc->certStore = nssCertificateStore_Create(cc->arena); - if (!cc->certStore) { - return PR_FAILURE; - } + return PR_FAILURE; } nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); #if 0 @@ -238,6 +253,7 @@ NSSCryptoContext_FindBestCertificateByNickname ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -264,6 +280,7 @@ NSSCryptoContext_FindCertificatesByNickname ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -282,6 +299,7 @@ NSSCryptoContext_FindCertificateByIssuerAndSerialNumber ( NSSDER *serialNumber ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -302,6 +320,7 @@ NSSCryptoContext_FindBestCertificateBySubject ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -328,6 +347,7 @@ nssCryptoContext_FindCertificatesBySubject ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -385,6 +405,7 @@ NSSCryptoContext_FindCertificateByEncodedCertificate ( NSSBER *encodedCertificate ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -404,6 +425,8 @@ NSSCryptoContext_FindBestCertificateByEmail ( { NSSCertificate **certs; NSSCertificate *rvCert = NULL; + + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -430,6 +453,7 @@ NSSCryptoContext_FindCertificatesByEmail ( ) { NSSCertificate **rvCerts; + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -546,6 +570,7 @@ nssCryptoContext_FindTrustForCertificate ( NSSCertificate *cert ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } @@ -558,6 +583,7 @@ nssCryptoContext_FindSMIMEProfileForCertificate ( NSSCertificate *cert ) { + PORT_Assert(cc->certStore); if (!cc->certStore) { return NULL; } diff --git a/security/nss/lib/pki/nsspki.h b/security/nss/lib/pki/nsspki.h index f50433620..689e4c240 100644 --- a/security/nss/lib/pki/nsspki.h +++ b/security/nss/lib/pki/nsspki.h @@ -2235,15 +2235,24 @@ NSSCryptoContext_GetTrustDomain /* Importing things */ /* - * NSSCryptoContext_ImportCertificate + * NSSCryptoContext_FindOrImportCertificate * - * If there's not a "distinguished certificate" for this context, this - * sets the specified one to be it. + * If the certificate store already contains this DER cert, return the + * address of the matching NSSCertificate that is already in the store, + * and bump its reference count. + * + * If this DER cert is NOT already in the store, then add the new + * NSSCertificate to the store and bump its reference count, + * then return its address. + * + * if this DER cert is not in the store and cannot be added to it, + * return NULL; + * + * Record the associated crypto context in the certificate. */ -NSS_EXTERN PRStatus -NSSCryptoContext_ImportCertificate -( +NSS_EXTERN NSSCertificate * +NSSCryptoContext_FindOrImportCertificate ( NSSCryptoContext *cc, NSSCertificate *c ); diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index bbbeb5d4b..559d7c5bd 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -146,9 +146,12 @@ STAN_LoadDefaultNSS3TrustDomain ( * we hold the tokensLock. We can use the NSSRWLock Rank feature to * guarrentee this. tokensLock have a higher rank than module lock. */ + td->tokenList = nssList_Create(td->arena, PR_TRUE); + if (!td->tokenList) { + goto loser; + } SECMOD_GetReadLock(moduleLock); NSSRWLock_LockWrite(td->tokensLock); - td->tokenList = nssList_Create(td->arena, PR_TRUE); for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]); @@ -157,9 +160,19 @@ STAN_LoadDefaultNSS3TrustDomain ( td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); SECMOD_ReleaseReadLock(moduleLock); - g_default_trust_domain = td; + if (!td->tokens) { + goto loser; + } g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL); + if (!g_default_crypto_context) { + goto loser; + } + g_default_trust_domain = td; return PR_SUCCESS; + + loser: + NSSTrustDomain_Destroy(td); + return PR_FAILURE; } /* @@ -693,17 +706,30 @@ STAN_GetCERTCertificateNameForInstance ( char * STAN_GetCERTCertificateName(PLArenaPool *arenaOpt, NSSCertificate *c) { + char * result; nssCryptokiInstance *instance = get_cert_instance(c); - return STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + /* It's OK to call this function, even if instance is NULL */ + result = STAN_GetCERTCertificateNameForInstance(arenaOpt, c, instance); + if (instance) + nssCryptokiObject_Destroy(instance); + return result; } static void fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) { + CERTCertTrust* trust = NULL; NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; - nssCryptokiInstance *instance = get_cert_instance(c); + nssCryptokiInstance *instance; NSSUTF8 *stanNick = NULL; + + /* We are holding the base class object's lock on entry of this function + * This lock protects writes to fields of the CERTCertificate . + * It is also needed by some functions to compute values such as trust. + */ + instance = get_cert_instance(c); + if (instance) { stanNick = instance->label; } else if (context) { @@ -725,15 +751,16 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced if (stanNick) { nicklen = nssUTF8_Size(stanNick, &nssrv); len = tokenlen + nicklen; - cc->nickname = PORT_ArenaAlloc(cc->arena, len); - nick = cc->nickname; + nick = PORT_ArenaAlloc(cc->arena, len); if (tokenName) { memcpy(nick, tokenName, tokenlen-1); - nick += tokenlen-1; - *nick++ = ':'; + nick[tokenlen-1] = ':'; + memcpy(nick+tokenlen, stanNick, nicklen-1); + } else { + memcpy(nick, stanNick, nicklen-1); } - memcpy(nick, stanNick, nicklen-1); - cc->nickname[len-1] = '\0'; + nick[len-1] = '\0'; + cc->nickname = nick; } else { cc->nickname = NULL; } @@ -742,7 +769,13 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced /* trust */ nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); if (nssTrust) { - cc->trust = cert_trust_from_stan_trust(nssTrust, cc->arena); + trust = cert_trust_from_stan_trust(nssTrust, cc->arena); + if (trust) { + /* we should destroy cc->trust before replacing it, but it's + allocated in cc->arena, so memory growth will occur on each + refresh */ + cc->trust = trust; + } nssTrust_Destroy(nssTrust); } } else if (instance) { @@ -757,7 +790,13 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced /* pkcs11ID */ cc->pkcs11ID = instance->handle; /* trust */ - cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); + trust = nssTrust_GetCERTCertTrustForCert(c, cc); + if (trust) { + /* we should destroy cc->trust before replacing it, but it's + allocated in cc->arena, so memory growth will occur on each + refresh */ + cc->trust = trust; + } nssCryptokiObject_Destroy(instance); } /* database handle is now the trust domain */ @@ -773,52 +812,54 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced static CERTCertificate * stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) { - nssDecodedCert *dc = c->decoding; - CERTCertificate *cc; + nssDecodedCert *dc = NULL; + CERTCertificate *cc = NULL; - /* There is a race in assigning c->decoding. - ** This is a workaround. Bugzilla bug 225525. - */ + nssPKIObject_Lock(&c->object); + + dc = c->decoding; if (!dc) { dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding); - if (!dc) - return NULL; + if (!dc) { + goto loser; + } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); /* software error */ if (!cc) { nssDecodedPKIXCertificate_Destroy(dc); nss_SetError(NSS_ERROR_INTERNAL_ERROR); - return NULL; + goto loser; } - /* Once this race is fixed, an assertion should be put - ** here to detect any regressions. PORT_Assert(!c->decoding); - */ if (!c->decoding) { c->decoding = dc; } else { - /* Reduce the leaks here, until the race is fixed. */ + /* this should never happen. Fail. */ nssDecodedPKIXCertificate_Destroy(dc); - dc = c->decoding; + nss_SetError(NSS_ERROR_INTERNAL_ERROR); + goto loser; } } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); - /* When c->decoding is non-NULL on input, but dc->data is - * NULL, we don't destroy dc because some other errant - * code allocated it . - */ - if (cc) { - if (!cc->nssCertificate || forceUpdate) { - fill_CERTCertificateFields(c, cc, forceUpdate); - } else if (!cc->trust && !c->object.cryptoContext) { - /* if it's a perm cert, it might have been stored before the - * trust, so look for the trust again. But a temp cert can be - * ignored. - */ - cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); - } + if (!cc) { + nss_SetError(NSS_ERROR_INTERNAL_ERROR); + goto loser; + } + if (!cc->nssCertificate || forceUpdate) { + fill_CERTCertificateFields(c, cc, forceUpdate); + } else if (!cc->trust && !c->object.cryptoContext) { + /* if it's a perm cert, it might have been stored before the + * trust, so look for the trust again. But a temp cert can be + * ignored. + */ + CERTCertTrust* trust = NULL; + trust = nssTrust_GetCERTCertTrustForCert(c, cc); + cc->trust = trust; } + + loser: + nssPKIObject_Unlock(&c->object); return cc; } @@ -903,7 +944,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc) } NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; - pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKIMonitor); if (!pkiob) { nssArena_Destroy(arena); return NULL; @@ -1023,7 +1064,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) arena = nssArena_Create(); if (!arena) return PR_FAILURE; nssTrust = nss_ZNEW(arena, NSSTrust); - pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock); if (!pkiob) { nssArena_Destroy(arena); return PR_FAILURE; @@ -1165,6 +1206,9 @@ nssTrustDomain_TraverseCertificatesBySubject ( NSSCertificate *c; PRIntn i; tmpArena = NSSArena_Create(); + if (!tmpArena) { + return PR_FAILURE; + } subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, subject, NULL, 0, tmpArena); if (subjectCerts) { @@ -1192,6 +1236,9 @@ nssTrustDomain_TraverseCertificatesByNickname ( NSSCertificate *c; PRIntn i; tmpArena = NSSArena_Create(); + if (!tmpArena) { + return PR_FAILURE; + } nickCerts = NSSTrustDomain_FindCertificatesByNickname(td, nickname, NULL, 0, tmpArena); if (nickCerts) { diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c index deef58b52..f8b5a47ed 100644 --- a/security/nss/lib/pki/pkibase.c +++ b/security/nss/lib/pki/pkibase.c @@ -52,12 +52,79 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; extern const NSSError NSS_ERROR_NOT_FOUND; +NSS_IMPLEMENT void +nssPKIObject_Lock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_EnterMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Lock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT void +nssPKIObject_Unlock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_ExitMonitor(object->sync.mlock); + break; + case nssPKILock: + PZ_Unlock(object->sync.lock); + break; + default: + PORT_Assert(0); + } +} + +NSS_IMPLEMENT PRStatus +nssPKIObject_NewLock(nssPKIObject * object, nssPKILockType lockType) +{ + object->lockType = lockType; + switch (lockType) { + case nssPKIMonitor: + object->sync.mlock = PZ_NewMonitor(nssILockSSL); + return (object->sync.mlock ? PR_SUCCESS : PR_FAILURE); + case nssPKILock: + object->sync.lock = PZ_NewLock(nssILockSSL); + return (object->sync.lock ? PR_SUCCESS : PR_FAILURE); + default: + PORT_Assert(0); + return PR_FAILURE; + } +} + +NSS_IMPLEMENT void +nssPKIObject_DestroyLock(nssPKIObject * object) +{ + switch (object->lockType) { + case nssPKIMonitor: + PZ_DestroyMonitor(object->sync.mlock); + object->sync.mlock = NULL; + break; + case nssPKILock: + PZ_DestroyLock(object->sync.lock); + object->sync.lock = NULL; + break; + default: + PORT_Assert(0); + } +} + + + NSS_IMPLEMENT nssPKIObject * nssPKIObject_Create ( NSSArena *arenaOpt, nssCryptokiObject *instanceOpt, NSSTrustDomain *td, - NSSCryptoContext *cc + NSSCryptoContext *cc, + nssPKILockType lockType ) { NSSArena *arena; @@ -79,8 +146,7 @@ nssPKIObject_Create ( object->arena = arena; object->trustDomain = td; /* XXX */ object->cryptoContext = cc; - object->lock = PZ_NewLock(nssILockOther); - if (!object->lock) { + if (PR_SUCCESS != nssPKIObject_NewLock(object, lockType)) { goto loser; } if (instanceOpt) { @@ -113,7 +179,7 @@ nssPKIObject_Destroy ( for (i=0; i<object->numInstances; i++) { nssCryptokiObject_Destroy(object->instances[i]); } - PZ_DestroyLock(object->lock); + nssPKIObject_DestroyLock(object); nssArena_Destroy(object->arena); return PR_TRUE; } @@ -135,7 +201,7 @@ nssPKIObject_AddInstance ( nssCryptokiObject *instance ) { - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances == 0) { object->instances = nss_ZNEWARRAY(object->arena, nssCryptokiObject *, @@ -144,7 +210,7 @@ nssPKIObject_AddInstance ( PRUint32 i; for (i=0; i<object->numInstances; i++) { if (nssCryptokiObject_Equal(object->instances[i], instance)) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); if (instance->label) { if (!object->instances[i]->label || !nssUTF8_Equal(instance->label, @@ -171,11 +237,11 @@ nssPKIObject_AddInstance ( object->numInstances + 1); } if (!object->instances) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_FAILURE; } object->instances[object->numInstances++] = instance; - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } @@ -187,14 +253,14 @@ nssPKIObject_HasInstance ( { PRUint32 i; PRBool hasIt = PR_FALSE;; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if (nssCryptokiObject_Equal(object->instances[i], instance)) { hasIt = PR_TRUE; break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return hasIt; } @@ -206,9 +272,9 @@ nssPKIObject_RemoveInstanceForToken ( { PRUint32 i; nssCryptokiObject *instanceToRemove = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances == 0) { - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } for (i=0; i<object->numInstances; i++) { @@ -230,7 +296,7 @@ nssPKIObject_RemoveInstanceForToken ( nss_ZFreeIf(object->instances); } nssCryptokiObject_Destroy(instanceToRemove); - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return PR_SUCCESS; } @@ -253,7 +319,7 @@ nssPKIObject_DeleteStoredObject ( nssTrustDomain_GetDefaultCallback(td, NULL); #endif numNotDestroyed = 0; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { nssCryptokiObject *instance = object->instances[i]; #ifndef NSS_3_4_CODE @@ -288,7 +354,7 @@ nssPKIObject_DeleteStoredObject ( } else { object->numInstances = numNotDestroyed; } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return status; } @@ -299,7 +365,7 @@ nssPKIObject_GetTokens ( ) { NSSToken **tokens = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); if (object->numInstances > 0) { tokens = nss_ZNEWARRAY(NULL, NSSToken *, object->numInstances + 1); if (tokens) { @@ -309,7 +375,7 @@ nssPKIObject_GetTokens ( } } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); if (statusOpt) *statusOpt = PR_SUCCESS; /* until more logic here */ return tokens; } @@ -322,7 +388,7 @@ nssPKIObject_GetNicknameForToken ( { PRUint32 i; NSSUTF8 *nickname = NULL; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if ((!tokenOpt && object->instances[i]->label) || (object->instances[i]->token == tokenOpt)) @@ -332,7 +398,7 @@ nssPKIObject_GetNicknameForToken ( break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return nickname; } @@ -347,7 +413,7 @@ nssPKIObject_GetInstances ( if (object->numInstances == 0) { return (nssCryptokiObject **)NULL; } - PZ_Lock(object->lock); + nssPKIObject_Lock(object); instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *, object->numInstances + 1); if (instances) { @@ -355,7 +421,7 @@ nssPKIObject_GetInstances ( instances[i] = nssCryptokiObject_Clone(object->instances[i]); } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return instances; } #endif @@ -595,12 +661,14 @@ struct nssPKIObjectCollectionStr PRStatus (* getUIDFromInstance)(nssCryptokiObject *co, NSSItem *uid, NSSArena *arena); nssPKIObject * (* createObject)(nssPKIObject *o); + nssPKILockType lockType; /* type of lock to use for new proto-objects */ }; static nssPKIObjectCollection * nssPKIObjectCollection_Create ( NSSTrustDomain *td, - NSSCryptoContext *ccOpt + NSSCryptoContext *ccOpt, + nssPKILockType lockType ) { NSSArena *arena; @@ -617,6 +685,7 @@ nssPKIObjectCollection_Create ( rvCollection->arena = arena; rvCollection->td = td; /* XXX */ rvCollection->cc = ccOpt; + rvCollection->lockType = lockType; return rvCollection; loser: nssArena_Destroy(arena); @@ -763,7 +832,7 @@ add_object_instance ( */ node = find_object_in_collection(collection, uid); if (node) { - /* This is a object with multiple instances */ + /* This is an object with multiple instances */ status = nssPKIObject_AddInstance(node->object, instance); } else { /* This is a completely new object. Create a node for it. */ @@ -772,7 +841,8 @@ add_object_instance ( goto loser; } node->object = nssPKIObject_Create(NULL, instance, - collection->td, collection->cc); + collection->td, collection->cc, + collection->lockType); if (!node->object) { goto loser; } @@ -1059,7 +1129,7 @@ nssCertificateCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKIMonitor); collection->objectType = pkiObjectType_Certificate; collection->destroyObject = cert_destroyObject; collection->getUIDFromObject = cert_getUIDFromObject; @@ -1162,7 +1232,7 @@ nssCRLCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_CRL; collection->destroyObject = crl_destroyObject; collection->getUIDFromObject = crl_getUIDFromObject; @@ -1264,7 +1334,7 @@ nssPrivateKeyCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_PrivateKey; collection->destroyObject = privkey_destroyObject; collection->getUIDFromObject = privkey_getUIDFromObject; @@ -1365,7 +1435,7 @@ nssPublicKeyCollection_Create ( { PRStatus status; nssPKIObjectCollection *collection; - collection = nssPKIObjectCollection_Create(td, NULL); + collection = nssPKIObjectCollection_Create(td, NULL, nssPKILock); collection->objectType = pkiObjectType_PublicKey; collection->destroyObject = pubkey_destroyObject; collection->getUIDFromObject = pubkey_getUIDFromObject; diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h index 5fad8a13f..4e4268b77 100644 --- a/security/nss/lib/pki/pkim.h +++ b/security/nss/lib/pki/pkim.h @@ -72,6 +72,12 @@ PR_BEGIN_EXTERN_C * nssPKIObject_DeleteStoredObject */ +NSS_EXTERN void nssPKIObject_Lock (nssPKIObject * object); +NSS_EXTERN void nssPKIObject_Unlock (nssPKIObject * object); +NSS_EXTERN PRStatus nssPKIObject_NewLock (nssPKIObject * object, + nssPKILockType lockType); +NSS_EXTERN void nssPKIObject_DestroyLock(nssPKIObject * object); + /* nssPKIObject_Create * * A generic PKI object. It must live in a trust domain. It may be @@ -83,7 +89,8 @@ nssPKIObject_Create NSSArena *arenaOpt, nssCryptokiObject *instanceOpt, NSSTrustDomain *td, - NSSCryptoContext *ccOpt + NSSCryptoContext *ccOpt, + nssPKILockType lockType ); /* nssPKIObject_AddRef diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c index ed35c9749..e44051b9e 100644 --- a/security/nss/lib/pki/pkistore.c +++ b/security/nss/lib/pki/pkistore.c @@ -89,6 +89,14 @@ struct certificate_hash_entry_str nssSMIMEProfile *profile; }; +/* forward static declarations */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +); + NSS_IMPLEMENT nssCertificateStore * nssCertificateStore_Create ( NSSArena *arenaOpt @@ -225,29 +233,46 @@ remove_certificate_entry ( NSSCertificate *cert ); -NSS_IMPLEMENT PRStatus -nssCertificateStore_Add ( +/* Caller must hold store->lock */ +static PRStatus +nssCertificateStore_AddLocked ( nssCertificateStore *store, NSSCertificate *cert ) { - PRStatus nssrv; - PZ_Lock(store->lock); - if (nssHash_Exists(store->issuer_and_serial, cert)) { - PZ_Unlock(store->lock); - return PR_SUCCESS; - } - nssrv = add_certificate_entry(store, cert); + PRStatus nssrv = add_certificate_entry(store, cert); if (nssrv == PR_SUCCESS) { nssrv = add_subject_entry(store, cert); if (nssrv == PR_FAILURE) { remove_certificate_entry(store, cert); } } - PZ_Unlock(store->lock); return nssrv; } + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindOrAdd ( + nssCertificateStore *store, + NSSCertificate *c +) +{ + PRStatus nssrv; + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked( + store, &c->issuer, &c->serial); + if (!rvCert) { + nssrv = nssCertificateStore_AddLocked(store, c); + if (PR_SUCCESS == nssrv) { + rvCert = nssCertificate_AddRef(c); + } + } + PZ_Unlock(store->lock); + return rvCert; +} + static void remove_certificate_entry ( nssCertificateStore *store, @@ -313,18 +338,41 @@ nssCertificateStore_RemoveCertLOCKED ( NSS_IMPLEMENT void nssCertificateStore_Lock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* out ) { +#ifdef DEBUG + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + out->locked = PR_TRUE; + PZ_Lock(out->lock); +#else PZ_Lock(store->lock); +#endif } NSS_IMPLEMENT void nssCertificateStore_Unlock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out ) { +#ifdef DEBUG + PORT_Assert(in); + PORT_Assert(out); + out->store = store; + out->lock = store->lock; + out->unlocked = PR_TRUE; + + PORT_Assert(in->store == out->store); + PORT_Assert(in->lock == out->lock); + PORT_Assert(in->locked); + + PZ_Unlock(out->lock); +#else PZ_Unlock(store->lock); +#endif } static NSSCertificate ** @@ -501,24 +549,40 @@ nssCertificateStore_FindCertificatesByEmail ( return rvArray; } -NSS_IMPLEMENT NSSCertificate * -nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( +/* Caller holds store->lock */ +static NSSCertificate * +nssCertStore_FindCertByIssuerAndSerialNumberLocked ( nssCertificateStore *store, NSSDER *issuer, NSSDER *serial ) { certificate_hash_entry *entry; - NSSCertificate index; NSSCertificate *rvCert = NULL; + NSSCertificate index; + index.issuer = *issuer; index.serial = *serial; - PZ_Lock(store->lock); entry = (certificate_hash_entry *) nssHash_Lookup(store->issuer_and_serial, &index); if (entry) { rvCert = nssCertificate_AddRef(entry->cert); } + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +nssCertificateStore_FindCertificateByIssuerAndSerialNumber ( + nssCertificateStore *store, + NSSDER *issuer, + NSSDER *serial +) +{ + NSSCertificate *rvCert = NULL; + + PZ_Lock(store->lock); + rvCert = nssCertStore_FindCertByIssuerAndSerialNumberLocked ( + store, issuer, serial); PZ_Unlock(store->lock); return rvCert; } diff --git a/security/nss/lib/pki/pkistore.h b/security/nss/lib/pki/pkistore.h index d2f222a1c..0c347296f 100644 --- a/security/nss/lib/pki/pkistore.h +++ b/security/nss/lib/pki/pkistore.h @@ -81,11 +81,14 @@ nssCertificateStore_Destroy nssCertificateStore *store ); -NSS_EXTERN PRStatus -nssCertificateStore_Add +/* Atomic Find cert in store, or add this cert to the store. +** Ref counts properly maintained. +*/ +NSS_EXTERN NSSCertificate * +nssCertificateStore_FindOrAdd ( nssCertificateStore *store, - NSSCertificate *cert + NSSCertificate *c ); NSS_EXTERN void @@ -95,14 +98,36 @@ nssCertificateStore_RemoveCertLOCKED NSSCertificate *cert ); +struct nssCertificateStoreTraceStr { + nssCertificateStore* store; + PZLock* lock; + PRBool locked; + PRBool unlocked; +}; + +typedef struct nssCertificateStoreTraceStr nssCertificateStoreTrace; + +static void nssCertificateStore_Check(nssCertificateStoreTrace* a, + nssCertificateStoreTrace* b) { + PORT_Assert(a->locked); + PORT_Assert(b->unlocked); + + PORT_Assert(!a->unlocked); + PORT_Assert(!b->locked); + + PORT_Assert(a->lock == b->lock); + PORT_Assert(a->store == b->store); +}; + NSS_EXTERN void nssCertificateStore_Lock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* out ); NSS_EXTERN void nssCertificateStore_Unlock ( - nssCertificateStore *store + nssCertificateStore *store, nssCertificateStoreTrace* in, + nssCertificateStoreTrace* out ); NSS_EXTERN NSSCertificate ** diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index fb04cbaed..46ae1a3b2 100644 --- a/security/nss/lib/pki/pkit.h +++ b/security/nss/lib/pki/pkit.h @@ -93,6 +93,11 @@ PR_BEGIN_EXTERN_C * for each object. */ +typedef enum { + nssPKILock = 1, + nssPKIMonitor = 2 +} nssPKILockType; + /* nssPKIObject * * This is the base object class, common to all PKI objects defined in @@ -105,7 +110,11 @@ struct nssPKIObjectStr /* Atomically incremented/decremented reference counting */ PRInt32 refCount; /* lock protects the array of nssCryptokiInstance's of the object */ - PZLock *lock; + union { + PZLock* lock; + PZMonitor *mlock; + } sync; + nssPKILockType lockType; /* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot * be compared against the update level of the trust domain, since it is * also affected by import/export. Where is this array needed? diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index 90727d011..3c3e0eeb1 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -429,7 +429,7 @@ remove_token_certs(const void *k, void *v, void *a) nssPKIObject *object = &c->object; struct token_cert_dtor *dtor = a; PRUint32 i; - PZ_Lock(object->lock); + nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { if (object->instances[i]->token == dtor->token) { nssCryptokiObject_Destroy(object->instances[i]); @@ -446,7 +446,7 @@ remove_token_certs(const void *k, void *v, void *a) break; } } - PZ_Unlock(object->lock); + nssPKIObject_Unlock(object); return; } @@ -1150,6 +1150,9 @@ nssTrustDomain_GetCertsFromCache ( certList = certListOpt; } else { certList = nssList_Create(NULL, PR_FALSE); + if (!certList) { + return NULL; + } } PZ_Lock(td->cache->lock); nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList); diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index 0ecb8846d..7e93bd092 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -134,10 +134,15 @@ NSSTrustDomain_Destroy ( /* Destroy each token in the list of tokens */ if (td->tokens) { nssListIterator_Destroy(td->tokens); + td->tokens = NULL; + } + if (td->tokenList) { nssList_Clear(td->tokenList, token_destructor); nssList_Destroy(td->tokenList); + td->tokenList = NULL; } NSSRWLock_Destroy(td->tokensLock); + td->tokensLock = NULL; status = nssTrustDomain_DestroyCache(td); if (status == PR_FAILURE) { return status; @@ -1217,7 +1222,7 @@ nssTrustDomain_FindTrustForCertificate ( nssTokenSearchType_TokenOnly); if (to) { if (!pkio) { - pkio = nssPKIObject_Create(NULL, to, td, NULL); + pkio = nssPKIObject_Create(NULL, to, td, NULL, nssPKILock); if (!pkio) { nssToken_Destroy(token); nssCryptokiObject_Destroy(to); diff --git a/security/nss/lib/smime/cmscipher.c b/security/nss/lib/smime/cmscipher.c index 00042937a..071e56538 100644 --- a/security/nss/lib/smime/cmscipher.c +++ b/security/nss/lib/smime/cmscipher.c @@ -224,8 +224,9 @@ NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgori } cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext)); - if (cc == NULL) - return NULL; + if (cc == NULL) { + goto loser; + } /* now find pad and block sizes for our mechanism */ cc->pad_size = PK11_GetBlockSize(mechanism,param); diff --git a/security/nss/lib/smime/cmsencode.c b/security/nss/lib/smime/cmsencode.c index 34e097cf2..7e5d2b514 100644 --- a/security/nss/lib/smime/cmsencode.c +++ b/security/nss/lib/smime/cmsencode.c @@ -563,8 +563,10 @@ NSS_CMSEncoder_Start(NSSCMSMessage *cmsg, rv = SECFailure; break; } - if (rv != SECSuccess) + if (rv != SECSuccess) { + PORT_Free(p7ecx); return NULL; + } /* Initialize the BER encoder. * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */ diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c index 07236adc1..c77d113ad 100644 --- a/security/nss/lib/smime/cmsrecinfo.c +++ b/security/nss/lib/smime/cmsrecinfo.c @@ -187,24 +187,6 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type, rv = SECFailure; } break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - PORT_Assert(type == NSSCMSRecipientID_IssuerSN); - if (type != NSSCMSRecipientID_IssuerSN) { - rv = SECFailure; - break; - } - /* backward compatibility - this is not really a keytrans operation */ - ri->recipientInfoType = NSSCMSRecipientInfoID_KeyTrans; - /* hardcoded issuerSN choice for now */ - ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType = NSSCMSRecipientID_IssuerSN; - ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert); - if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) { - rv = SECFailure; - break; - } - break; case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ PORT_Assert(type == NSSCMSRecipientID_IssuerSN); if (type != NSSCMSRecipientID_IssuerSN) { @@ -295,6 +277,9 @@ done: return ri; loser: + if (ri && ri->cert) { + CERT_DestroyCertificate(ri->cert); + } if (freeSpki) { SECKEY_DestroySubjectPublicKeyInfo(freeSpki); } @@ -527,20 +512,6 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL); break; - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - rv = NSS_CMSUtil_EncryptSymKey_MISSI(poolp, cert, bulkkey, - bulkalgtag, - &ri->ri.keyTransRecipientInfo.encKey, - ¶ms, ri->cmsg->pwfn_arg); - if (rv != SECSuccess) - break; - - /* here, we DO need to pass the params to the wrap function because, with - * RSA, there is no funny stuff going on with generation of IV vectors or so */ - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, params); - break; case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0]; if (rek == NULL) { diff --git a/security/nss/lib/smime/cmsreclist.c b/security/nss/lib/smime/cmsreclist.c index 34e31d582..61eb260be 100644 --- a/security/nss/lib/smime/cmsreclist.c +++ b/security/nss/lib/smime/cmsreclist.c @@ -66,25 +66,33 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien switch (ri->recipientInfoType) { case NSSCMSRecipientInfoID_KeyTrans: if (recipient_list) { + NSSCMSRecipientIdentifier *recipId = + &ri->ri.keyTransRecipientInfo.recipientIdentifier; + + if (recipId->identifierType != NSSCMSRecipientID_IssuerSN && + recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return -1; + } /* alloc one & fill it out */ rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) + if (!rle) return -1; rle->riIndex = i; rle->subIndex = -1; - switch (ri->ri.keyTransRecipientInfo.recipientIdentifier.identifierType) { + switch (recipId->identifierType) { case NSSCMSRecipientID_IssuerSN: rle->kind = RLIssuerSN; - rle->id.issuerAndSN = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN; + rle->id.issuerAndSN = recipId->id.issuerAndSN; break; case NSSCMSRecipientID_SubjectKeyID: rle->kind = RLSubjKeyID; - rle->id.subjectKeyID = ri->ri.keyTransRecipientInfo.recipientIdentifier.id.subjectKeyID; + rle->id.subjectKeyID = recipId->id.subjectKeyID; + break; + default: /* we never get here because of identifierType check + we done before. Leaving it to kill compiler warning */ break; - default: - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return -1; } recipient_list[rlindex++] = rle; } else { @@ -99,7 +107,7 @@ nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipien rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j]; /* alloc one & fill it out */ rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient)); - if (rle == NULL) + if (!rle) return -1; rle->riIndex = i; diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c index 675040b66..508632f69 100644 --- a/security/nss/lib/smime/cmssiginfo.c +++ b/security/nss/lib/smime/cmssiginfo.c @@ -386,7 +386,9 @@ NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, case SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST: case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: +#ifdef NSS_ECC_MORE_THAN_SUITE_B case SEC_OID_ANSIX962_EC_PUBLIC_KEY: +#endif /* ok */ break; case SEC_OID_UNKNOWN: diff --git a/security/nss/lib/smime/cmsutil.c b/security/nss/lib/smime/cmsutil.c index 1765655bb..710a749c6 100644 --- a/security/nss/lib/smime/cmsutil.c +++ b/security/nss/lib/smime/cmsutil.c @@ -259,7 +259,13 @@ NSS_CMSUtil_MakeSignatureAlgorithm(SECOidTag hashalg, SECOidTag encalg) case SEC_OID_ANSIX962_EC_PUBLIC_KEY: switch (hashalg) { case SEC_OID_SHA1: - return SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; + return SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE; + case SEC_OID_SHA256: + return SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE; + case SEC_OID_SHA384: + return SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; + case SEC_OID_SHA512: + return SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE; default: return SEC_OID_UNKNOWN; } diff --git a/security/nss/lib/smime/smime.rc b/security/nss/lib/smime/smime.rc index 05fb11bfa..7fd7298d1 100644 --- a/security/nss/lib/smime/smime.rc +++ b/security/nss/lib/smime/smime.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c index 6fb10ec07..c26330ba5 100644 --- a/security/nss/lib/smime/smimeutil.c +++ b/security/nss/lib/smime/smimeutil.c @@ -116,15 +116,18 @@ static const SEC_ASN1Template smime_encryptionkeypref_template[] = { { SEC_ASN1_CHOICE, offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL, sizeof(NSSSMIMEEncryptionKeyPreference) }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN), SEC_ASN1_SUB(CERT_IssuerAndSNTemplate), NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID), NSSCMSRecipientKeyIdentifierTemplate, - NSSSMIMEEncryptionKeyPref_IssuerSN }, - { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2, + NSSSMIMEEncryptionKeyPref_RKeyID }, + { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 + | SEC_ASN1_CONSTRUCTED, offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID), SEC_ASN1_SUB(SEC_OctetStringTemplate), NSSSMIMEEncryptionKeyPref_SubjectKeyID }, diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk index 2e097c8a5..bc48130aa 100644 --- a/security/nss/lib/softoken/config.mk +++ b/security/nss/lib/softoken/config.mk @@ -91,6 +91,7 @@ ifeq ($(OS_TARGET),SunOS) # The -R '$ORIGIN' linker option instructs this library to search for its # dependencies in the same directory where it resides. MKSHLIB += -R '$$ORIGIN' +OS_LIBS += -lbsm endif ifeq ($(OS_TARGET),WINCE) diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c index 2b7f81a73..d1f7fd303 100644 --- a/security/nss/lib/softoken/dbinit.c +++ b/security/nss/lib/softoken/dbinit.c @@ -291,6 +291,7 @@ sftk_freeCertDB(NSSLOWCERTCertDBHandle *certHandle) PRInt32 ref = PR_AtomicDecrement(&certHandle->ref); if (ref == 0) { nsslowcert_ClosePermCertDB(certHandle); + PORT_Free(certHandle); } } diff --git a/security/nss/lib/softoken/dbmshim.c b/security/nss/lib/softoken/dbmshim.c index 04c291d7f..f75f4d70d 100644 --- a/security/nss/lib/softoken/dbmshim.c +++ b/security/nss/lib/softoken/dbmshim.c @@ -406,14 +406,6 @@ dbs_readBlob(DBS *dbsp, DBT *data) loser: /* preserve the error code */ error = PR_GetError(); - if (addr) { - if (mapfile) { - PORT_Assert(len != -1); - PR_MemUnmap(addr,len); - } else { - PORT_Free(addr); - } - } if (mapfile) { PR_CloseFileMap(mapfile); } diff --git a/security/nss/lib/softoken/ecdecode.c b/security/nss/lib/softoken/ecdecode.c index e649ff899..dbf1cb3f8 100644 --- a/security/nss/lib/softoken/ecdecode.c +++ b/security/nss/lib/softoken/ecdecode.c @@ -49,7 +49,12 @@ #define CHECK_OK(func) if (func == NULL) goto cleanup #define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup -/* Initializes a SECItem from a hexadecimal string */ +/* + * Initializes a SECItem from a hexadecimal string + * + * Warning: This function ignores leading 00's, so any leading 00's + * in the hexadecimal string must be optional. + */ static SECItem * hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) { @@ -59,6 +64,12 @@ hexString2SECItem(PRArenaPool *arena, SECItem *item, const char *str) if ((tmp % 2) != 0) return NULL; + /* skip leading 00's unless the hex string is "00" */ + while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) { + str += 2; + tmp -= 2; + } + item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2); if (item->data == NULL) return NULL; item->len = tmp/2; @@ -136,7 +147,8 @@ EC_FillParams(PRArenaPool *arena, const SECItem *encodedParams, SECOidTag tag; SECItem oid = { siBuffer, NULL, 0}; const ECCurveParams *curveParams; - char genenc[2 + 2 * 2 * MAX_ECKEY_LEN]; + /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */ + char genenc[3 + 2 * 2 * MAX_ECKEY_LEN]; #if EC_DEBUG int i; diff --git a/security/nss/lib/softoken/fipsaudt.c b/security/nss/lib/softoken/fipsaudt.c new file mode 100644 index 000000000..d17496deb --- /dev/null +++ b/security/nss/lib/softoken/fipsaudt.c @@ -0,0 +1,351 @@ +/* ***** 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 Network Security Services (NSS). + * + * The Initial Developer of the Original Code is + * Red Hat, Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * 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 ***** */ + +/* + * This file implements audit logging required by FIPS 140-2 Security + * Level 2. + */ + +#include "prprf.h" +#include "softoken.h" + +/* + * Print the value of the returned object handle in the output buffer + * on a successful return of the PKCS #11 function. If the PKCS #11 + * function failed or the pointer to object handle is NULL (which is + * the case for C_DeriveKey with CKM_TLS_KEY_AND_MAC_DERIVE), an empty + * string is stored in the output buffer. + * + * out: the output buffer + * outlen: the length of the output buffer + * argName: the name of the "pointer to object handle" argument + * phObject: the pointer to object handle + * rv: the return value of the PKCS #11 function + */ +static void sftk_PrintReturnedObjectHandle(char *out, PRUint32 outlen, + const char *argName, CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) +{ + if ((rv == CKR_OK) && phObject) { + PR_snprintf(out, outlen, + " *%s=0x%08lX", argName, (PRUint32)*phObject); + } else { + PORT_Assert(outlen != 0); + out[0] = '\0'; + } +} + +/* + * MECHANISM_BUFSIZE needs to be large enough for sftk_PrintMechanism, + * which uses <= 49 bytes. + */ +#define MECHANISM_BUFSIZE 64 + +static void sftk_PrintMechanism(char *out, PRUint32 outlen, + CK_MECHANISM_PTR pMechanism) +{ + if (pMechanism) { + /* + * If we change the format string, we need to make sure + * MECHANISM_BUFSIZE is still large enough. We allow + * 20 bytes for %p on a 64-bit platform. + */ + PR_snprintf(out, outlen, "%p {mechanism=0x%08lX, ...}", + pMechanism, (PRUint32)pMechanism->mechanism); + } else { + PR_snprintf(out, outlen, "%p", pMechanism); + } +} + +void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject, CK_RV rv) +{ + char msg[256]; + char shObject[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintReturnedObjectHandle(shObject, sizeof shObject, + "phObject", phObject, rv); + PR_snprintf(msg, sizeof msg, + "C_CreateObject(hSession=0x%08lX, pTemplate=%p, ulCount=%lu, " + "phObject=%p)=0x%08lX%s", + (PRUint32)hSession, pTemplate, (PRUint32)ulCount, + phObject, (PRUint32)rv, shObject); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv) +{ + char msg[256]; + char shNewObject[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintReturnedObjectHandle(shNewObject, sizeof shNewObject, + "phNewObject", phNewObject, rv); + PR_snprintf(msg, sizeof msg, + "C_CopyObject(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu, phNewObject=%p)=0x%08lX%s", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, phNewObject, (PRUint32)rv, shNewObject); + sftk_LogAuditMessage(severity, msg); +} + +/* WARNING: hObject has been destroyed and can only be printed. */ +void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_DestroyObject(hSession=0x%08lX, hObject=0x%08lX)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_GetObjectSize(hSession=0x%08lX, hObject=0x%08lX, " + "pulSize=%p)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pulSize, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_GetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_SetAttributeValue(hSession=0x%08lX, hObject=0x%08lX, " + "pTemplate=%p, ulCount=%lu)=0x%08lX", + (PRUint32)hSession, (PRUint32)hObject, + pTemplate, (PRUint32)ulCount, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditCryptInit(const char *opName, CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + PR_snprintf(msg, sizeof msg, + "C_%sInit(hSession=0x%08lX, pMechanism=%s, " + "hKey=0x%08lX)=0x%08lX", + opName, (PRUint32)hSession, mech, + (PRUint32)hKey, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + PR_snprintf(msg, sizeof msg, + "C_GenerateKey(hSession=0x%08lX, pMechanism=%s, " + "pTemplate=%p, ulCount=%lu, phKey=%p)=0x%08lX%s", + (PRUint32)hSession, mech, + pTemplate, (PRUint32)ulCount, phKey, (PRUint32)rv, shKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv) +{ + char msg[512]; + char mech[MECHANISM_BUFSIZE]; + char shPublicKey[32]; + char shPrivateKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shPublicKey, sizeof shPublicKey, + "phPublicKey", phPublicKey, rv); + sftk_PrintReturnedObjectHandle(shPrivateKey, sizeof shPrivateKey, + "phPrivateKey", phPrivateKey, rv); + PR_snprintf(msg, sizeof msg, + "C_GenerateKeyPair(hSession=0x%08lX, pMechanism=%s, " + "pPublicKeyTemplate=%p, ulPublicKeyAttributeCount=%lu, " + "pPrivateKeyTemplate=%p, ulPrivateKeyAttributeCount=%lu, " + "phPublicKey=%p, phPrivateKey=%p)=0x%08lX%s%s", + (PRUint32)hSession, mech, + pPublicKeyTemplate, (PRUint32)ulPublicKeyAttributeCount, + pPrivateKeyTemplate, (PRUint32)ulPrivateKeyAttributeCount, + phPublicKey, phPrivateKey, (PRUint32)rv, shPublicKey, shPrivateKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + PR_snprintf(msg, sizeof msg, + "C_WrapKey(hSession=0x%08lX, pMechanism=%s, hWrappingKey=0x%08lX, " + "hKey=0x%08lX, pWrappedKey=%p, pulWrappedKeyLen=%p)=0x%08lX", + (PRUint32)hSession, mech, (PRUint32)hWrappingKey, + (PRUint32)hKey, pWrappedKey, pulWrappedKeyLen, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[256]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + PR_snprintf(msg, sizeof msg, + "C_UnwrapKey(hSession=0x%08lX, pMechanism=%s, " + "hUnwrappingKey=0x%08lX, pWrappedKey=%p, ulWrappedKeyLen=%lu, " + "pTemplate=%p, ulAttributeCount=%lu, phKey=%p)=0x%08lX%s", + (PRUint32)hSession, mech, + (PRUint32)hUnwrappingKey, pWrappedKey, (PRUint32)ulWrappedKeyLen, + pTemplate, (PRUint32)ulAttributeCount, phKey, (PRUint32)rv, shKey); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv) +{ + char msg[512]; + char mech[MECHANISM_BUFSIZE]; + char shKey[32]; + char sTlsKeys[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + sftk_PrintMechanism(mech, sizeof mech, pMechanism); + sftk_PrintReturnedObjectHandle(shKey, sizeof shKey, "phKey", phKey, rv); + if ((rv == CKR_OK) && + (pMechanism->mechanism == CKM_TLS_KEY_AND_MAC_DERIVE)) { + CK_SSL3_KEY_MAT_PARAMS *param = + (CK_SSL3_KEY_MAT_PARAMS *)pMechanism->pParameter; + CK_SSL3_KEY_MAT_OUT *keymat = param->pReturnedKeyMaterial; + PR_snprintf(sTlsKeys, sizeof sTlsKeys, + " hClientMacSecret=0x%08lX hServerMacSecret=0x%08lX" + " hClientKey=0x%08lX hServerKey=0x%08lX", + (PRUint32)keymat->hClientMacSecret, + (PRUint32)keymat->hServerMacSecret, + (PRUint32)keymat->hClientKey, + (PRUint32)keymat->hServerKey); + } else { + sTlsKeys[0] = '\0'; + } + PR_snprintf(msg, sizeof msg, + "C_DeriveKey(hSession=0x%08lX, pMechanism=%s, " + "hBaseKey=0x%08lX, pTemplate=%p, ulAttributeCount=%lu, " + "phKey=%p)=0x%08lX%s%s", + (PRUint32)hSession, mech, + (PRUint32)hBaseKey, pTemplate,(PRUint32)ulAttributeCount, + phKey, (PRUint32)rv, shKey, sTlsKeys); + sftk_LogAuditMessage(severity, msg); +} + +void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey, CK_RV rv) +{ + char msg[256]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + + PR_snprintf(msg, sizeof msg, + "C_DigestKey(hSession=0x%08lX, hKey=0x%08lX)=0x%08lX", + (PRUint32)hSession, (PRUint32)hKey, (PRUint32)rv); + sftk_LogAuditMessage(severity, msg); +} diff --git a/security/nss/lib/softoken/fipstest.c b/security/nss/lib/softoken/fipstest.c index acee77676..942bd4034 100644 --- a/security/nss/lib/softoken/fipstest.c +++ b/security/nss/lib/softoken/fipstest.c @@ -42,10 +42,21 @@ /* DES-CBC, DES3-ECB, DES3-CBC, RSA */ /* and DSA. */ #include "seccomon.h" /* Required for RSA and DSA. */ -#include "lowkeyi.h" /* Required for RSA and DSA. */ +#include "lowkeyi.h" /* Required for RSA and DSA. */ #include "pkcs11.h" /* Required for PKCS #11. */ #include "secerr.h" +#ifdef NSS_ENABLE_ECC +#include "secdert.h" /* Required for ECDSA */ +#include "ec.h" /* Required for ECDSA */ +extern SECStatus +EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); +extern SECStatus +EC_CopyParams(PRArenaPool *arena, ECParams *dstParams, + const ECParams *srcParams); +#endif + + /* FIPS preprocessor directives for RC2-ECB and RC2-CBC. */ #define FIPS_RC2_KEY_LENGTH 5 /* 40-bits */ #define FIPS_RC2_ENCRYPT_LENGTH 8 /* 64-bits */ @@ -81,31 +92,33 @@ #define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */ -/* FIPS preprocessor directives for RSA. */ +/* FIPS preprocessor directives for RSA. */ #define FIPS_RSA_TYPE siBuffer -#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 1 /* 8-bits */ -#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */ -#define FIPS_RSA_MESSAGE_LENGTH 16 /* 128-bits */ -#define FIPS_RSA_COEFFICIENT_LENGTH 32 /* 256-bits */ -#define FIPS_RSA_PRIME0_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_PRIME1_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_EXPONENT0_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_EXPONENT1_LENGTH 33 /* 264-bits */ -#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_ENCRYPT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_DECRYPT_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_CRYPTO_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_SIGNATURE_LENGTH 64 /* 512-bits */ -#define FIPS_RSA_MODULUS_LENGTH 65 /* 520-bits */ +#define FIPS_RSA_PUBLIC_EXPONENT_LENGTH 3 /* 24-bits */ +#define FIPS_RSA_PRIVATE_VERSION_LENGTH 1 /* 8-bits */ +#define FIPS_RSA_MESSAGE_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_COEFFICIENT_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIME0_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIME1_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_EXPONENT0_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_EXPONENT1_LENGTH 64 /* 512-bits */ +#define FIPS_RSA_PRIVATE_EXPONENT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_ENCRYPT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_DECRYPT_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_SIGNATURE_LENGTH 128 /* 1024-bits */ +#define FIPS_RSA_MODULUS_LENGTH 128 /* 1024-bits */ /* FIPS preprocessor directives for DSA. */ #define FIPS_DSA_TYPE siBuffer -#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */ -#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ -#define FIPS_DSA_PRIME_LENGTH 64 /* 512-bits */ -#define FIPS_DSA_BASE_LENGTH 64 /* 512-bits */ +#define FIPS_DSA_DIGEST_LENGTH 20 /* 160-bits */ +#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */ +#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */ +#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */ +#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */ + +/* FIPS preprocessor directives for RNG. */ +#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */ static CK_RV sftk_fips_RC2_PowerUpSelfTest( void ) @@ -1046,121 +1059,324 @@ sftk_fips_SHA_PowerUpSelfTest( void ) return( CKR_OK ); } +/* +* Single round RSA Signature Known Answer Test +*/ +static SECStatus +sftk_fips_RSA_PowerUpSigSelfTest (HASH_HashType shaAlg, + NSSLOWKEYPublicKey *rsa_public_key, + NSSLOWKEYPrivateKey *rsa_private_key, + const unsigned char *rsa_known_msg, + const unsigned int rsa_kmsg_length, + const unsigned char *rsa_known_signature) +{ + SECOidTag shaOid; /* SHA OID */ + unsigned char sha[HASH_LENGTH_MAX]; /* SHA digest */ + unsigned int shaLength = 0; /* length of SHA */ + unsigned int rsa_bytes_signed; + unsigned char rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; + SECStatus rv; + + if (shaAlg == HASH_AlgSHA1) { + if (SHA1_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA1_LENGTH; + shaOid = SEC_OID_SHA1; + } else if (shaAlg == HASH_AlgSHA256) { + if (SHA256_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA256_LENGTH; + shaOid = SEC_OID_SHA256; + } else if (shaAlg == HASH_AlgSHA384) { + if (SHA384_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA384_LENGTH; + shaOid = SEC_OID_SHA384; + } else if (shaAlg == HASH_AlgSHA512) { + if (SHA512_HashBuf(sha, rsa_known_msg, rsa_kmsg_length) + != SECSuccess) { + goto loser; + } + shaLength = SHA512_LENGTH; + shaOid = SEC_OID_SHA512; + } else { + goto loser; + } + + /*************************************************/ + /* RSA Single-Round Known Answer Signature Test. */ + /*************************************************/ + + /* Perform RSA signature with the RSA private key. */ + rv = RSA_HashSign( shaOid, + rsa_private_key, + rsa_computed_signature, + &rsa_bytes_signed, + FIPS_RSA_SIGNATURE_LENGTH, + sha, + shaLength); + + if( ( rv != SECSuccess ) || + ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) || + ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature, + FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) { + goto loser; + } + + /****************************************************/ + /* RSA Single-Round Known Answer Verification Test. */ + /****************************************************/ + + /* 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 ) { + goto loser; + } + return( SECSuccess ); + +loser: + + return( SECFailure ); + +} static CK_RV sftk_fips_RSA_PowerUpSelfTest( void ) { - /* RSA Known Modulus used in both Public/Private Key Values (520-bits). */ + /* RSA Known Modulus used in both Public/Private Key Values (1024-bits). */ static const PRUint8 rsa_modulus[FIPS_RSA_MODULUS_LENGTH] = { - 0x00,0xa1,0xe9,0x5e,0x66,0x88,0xe2,0xf2, - 0x2b,0xe7,0x70,0x36,0x33,0xbc,0xeb,0x55, - 0x55,0xf1,0x60,0x18,0x3c,0xfb,0xd2,0x79, - 0xf6,0xc4,0xb8,0x09,0xe3,0x12,0xf6,0x63, - 0x6d,0xc7,0x8e,0x19,0xc0,0x0e,0x10,0x78, - 0xc1,0xfe,0x2a,0x41,0x74,0x2d,0xf7,0xc4, - 0x69,0xa7,0x3c,0xbc,0x8a,0xc8,0x31,0x2b, - 0x4f,0x60,0xf0,0xf1,0xec,0x5a,0x29,0xec, - 0x6b}; - - /* RSA Known Public Key Values (8-bits). */ - static const PRUint8 rsa_public_exponent[] = { 0x03 }; - - /* RSA Known Private Key Values (version is 8-bits), */ - /* (private exponent is 512-bits), */ - /* (private prime0 is 264-bits), */ - /* (private prime1 is 264-bits), */ - /* (private prime exponent0 is 264-bits), */ - /* (private prime exponent1 is 264-bits), */ - /* and (private coefficient is 256-bits). */ + 0xd5, 0x84, 0x95, 0x07, 0xf4, 0xd0, 0x1f, 0x82, + 0xf3, 0x79, 0xf4, 0x99, 0x48, 0x10, 0xe1, 0x71, + 0xa5, 0x62, 0x22, 0xa3, 0x4b, 0x00, 0xe3, 0x5b, + 0x3a, 0xcc, 0x10, 0x83, 0xe0, 0xaf, 0x61, 0x13, + 0x54, 0x6a, 0xa2, 0x6a, 0x2c, 0x5e, 0xb3, 0xcc, + 0xa3, 0x71, 0x9a, 0xb2, 0x3e, 0x78, 0xec, 0xb5, + 0x0e, 0x6e, 0x31, 0x3b, 0x77, 0x1f, 0x6e, 0x94, + 0x41, 0x60, 0xd5, 0x6e, 0xd9, 0xc6, 0xf9, 0x29, + 0xc3, 0x40, 0x36, 0x25, 0xdb, 0xea, 0x0b, 0x07, + 0xae, 0x76, 0xfd, 0x99, 0x29, 0xf4, 0x22, 0xc1, + 0x1a, 0x8f, 0x05, 0xfe, 0x98, 0x09, 0x07, 0x05, + 0xc2, 0x0f, 0x0b, 0x11, 0x83, 0x39, 0xca, 0xc7, + 0x43, 0x63, 0xff, 0x33, 0x80, 0xe7, 0xc3, 0x78, + 0xae, 0xf1, 0x73, 0x52, 0x98, 0x1d, 0xde, 0x5c, + 0x53, 0x6e, 0x01, 0x73, 0x0d, 0x12, 0x7e, 0x77, + 0x03, 0xf1, 0xef, 0x1b, 0xc8, 0xa8, 0x0f, 0x97}; + + /* RSA Known Public Key Values (24-bits). */ + static const PRUint8 rsa_public_exponent[FIPS_RSA_PUBLIC_EXPONENT_LENGTH] + = { 0x01, 0x00, 0x01 }; + /* RSA Known Private Key Values (version is 8-bits), */ + /* (private exponent is 1024-bits), */ + /* (private prime0 is 512-bits), */ + /* (private prime1 is 512-bits), */ + /* (private prime exponent0 is 512-bits), */ + /* (private prime exponent1 is 512-bits), */ + /* and (private coefficient is 512-bits). */ static const PRUint8 rsa_version[] = { 0x00 }; - static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] = { - 0x6b,0xf0,0xe9,0x99,0xb0,0x97,0x4c,0x1d, - 0x44,0xf5,0x79,0x77,0xd3,0x47,0x8e,0x39, - 0x4b,0x95,0x65,0x7d,0xfd,0x36,0xfb,0xf9, - 0xd8,0x7a,0xb1,0x42,0x0c,0xa4,0x42,0x48, - 0x20,0x1c,0x6b,0x7d,0x5d,0xa3,0x58,0xd6, - 0x95,0xd6,0x41,0xe3,0xd6,0x73,0xad,0xdb, - 0x3b,0x89,0x00,0x8a,0xcd,0x1d,0xb9,0x06, - 0xac,0xac,0x0e,0x02,0x72,0x1c,0xf8,0xab }; + + static const PRUint8 rsa_private_exponent[FIPS_RSA_PRIVATE_EXPONENT_LENGTH] + = { 0x85, 0x27, 0x47, 0x61, 0x4c, 0xd4, 0xb5, 0xb2, + 0x0e, 0x70, 0x91, 0x8f, 0x3d, 0x97, 0xf9, 0x5f, + 0xcc, 0x09, 0x65, 0x1c, 0x7c, 0x5b, 0xb3, 0x6d, + 0x63, 0x3f, 0x7b, 0x55, 0x22, 0xbb, 0x7c, 0x48, + 0x77, 0xae, 0x80, 0x56, 0xc2, 0x10, 0xd5, 0x03, + 0xdb, 0x31, 0xaf, 0x8d, 0x54, 0xd4, 0x48, 0x99, + 0xa8, 0xc4, 0x23, 0x43, 0xb8, 0x48, 0x0b, 0xc7, + 0xbc, 0xf5, 0xcc, 0x64, 0x72, 0xbf, 0x59, 0x06, + 0x04, 0x1c, 0x32, 0xf5, 0x14, 0x2e, 0x6e, 0xe2, + 0x0f, 0x5c, 0xde, 0x36, 0x3c, 0x6e, 0x7c, 0x4d, + 0xcc, 0xd3, 0x00, 0x6e, 0xe5, 0x45, 0x46, 0xef, + 0x4d, 0x25, 0x46, 0x6d, 0x7f, 0xed, 0xbb, 0x4f, + 0x4d, 0x9f, 0xda, 0x87, 0x47, 0x8f, 0x74, 0x44, + 0xb7, 0xbe, 0x9d, 0xf5, 0xdd, 0xd2, 0x4c, 0xa5, + 0xab, 0x74, 0xe5, 0x29, 0xa1, 0xd2, 0x45, 0x3b, + 0x33, 0xde, 0xd5, 0xae, 0xf7, 0x03, 0x10, 0x21}; + static const PRUint8 rsa_prime0[FIPS_RSA_PRIME0_LENGTH] = { - 0x00,0xd2,0x2c,0x9d,0xef,0x7c,0x8f,0x58, - 0x93,0x19,0xa1,0x77,0x0e,0x38,0x3e,0x85, - 0xb4,0xaf,0xcc,0x99,0xa5,0x43,0xbf,0x97, - 0xdc,0x46,0xb8,0x3f,0x6e,0x85,0x18,0x00, - 0x81}; + 0xf9, 0x74, 0x8f, 0x16, 0x02, 0x6b, 0xa0, 0xee, + 0x7f, 0x28, 0x97, 0x91, 0xdc, 0xec, 0xc0, 0x7c, + 0x49, 0xc2, 0x85, 0x76, 0xee, 0x66, 0x74, 0x2d, + 0x1a, 0xb8, 0xf7, 0x2f, 0x11, 0x5b, 0x36, 0xd8, + 0x46, 0x33, 0x3b, 0xd8, 0xf3, 0x2d, 0xa1, 0x03, + 0x83, 0x2b, 0xec, 0x35, 0x43, 0x32, 0xff, 0xdd, + 0x81, 0x7c, 0xfd, 0x65, 0x13, 0x04, 0x7c, 0xfc, + 0x03, 0x97, 0xf0, 0xd5, 0x62, 0xdc, 0x0d, 0xbf}; static const PRUint8 rsa_prime1[FIPS_RSA_PRIME1_LENGTH] = { - 0x00,0xc5,0x36,0xda,0x94,0x85,0x0c,0x1a, - 0xed,0x03,0xc7,0x67,0x90,0x34,0x0b,0xb9, - 0xec,0x1e,0x22,0xa2,0x15,0x50,0xc4,0xfd, - 0xe9,0x17,0x36,0x9d,0x7a,0x29,0xe6,0x76, - 0xeb}; + 0xdb, 0x1e, 0xa7, 0x3d, 0xe7, 0xfa, 0x8b, 0x04, + 0x83, 0x48, 0xf3, 0xa5, 0x31, 0x9d, 0x35, 0x5e, + 0x4d, 0x54, 0x77, 0xcc, 0x84, 0x09, 0xf3, 0x11, + 0x0d, 0x54, 0xed, 0x85, 0x39, 0xa9, 0xca, 0xa8, + 0xea, 0xae, 0x19, 0x9c, 0x75, 0xdb, 0x88, 0xb8, + 0x04, 0x8d, 0x54, 0xc6, 0xa4, 0x80, 0xf8, 0x93, + 0xf0, 0xdb, 0x19, 0xef, 0xd7, 0x87, 0x8a, 0x8f, + 0x5a, 0x09, 0x2e, 0x54, 0xf3, 0x45, 0x24, 0x29}; static const PRUint8 rsa_exponent0[FIPS_RSA_EXPONENT0_LENGTH] = { - 0x00,0x8c,0x1d,0xbe,0x9f,0xa8, - 0x5f,0x90,0x62,0x11,0x16,0x4f, - 0x5e,0xd0,0x29,0xae,0x78,0x75, - 0x33,0x11,0x18,0xd7,0xd5,0x0f, - 0xe8,0x2f,0x25,0x7f,0x9f,0x03, - 0x65,0x55,0xab}; + 0x6a, 0xd1, 0x25, 0x80, 0x18, 0x33, 0x3c, 0x2b, + 0x44, 0x19, 0xfe, 0xa5, 0x40, 0x03, 0xc4, 0xfc, + 0xb3, 0x9c, 0xef, 0x07, 0x99, 0x58, 0x17, 0xc1, + 0x44, 0xa3, 0x15, 0x7d, 0x7b, 0x22, 0x22, 0xdf, + 0x03, 0x58, 0x66, 0xf5, 0x24, 0x54, 0x52, 0x91, + 0x2d, 0x76, 0xfe, 0x63, 0x64, 0x4e, 0x0f, 0x50, + 0x2b, 0x65, 0x79, 0x1f, 0xf1, 0xbf, 0xc7, 0x41, + 0x26, 0xcc, 0xc6, 0x1c, 0xa9, 0x83, 0x6f, 0x03}; static const PRUint8 rsa_exponent1[FIPS_RSA_EXPONENT1_LENGTH] = { - 0x00,0x83,0x79,0xe7,0x0d,0xae, - 0x08,0x11,0xf3,0x57,0xda,0x45, - 0x0a,0xcd,0x5d,0x26,0x9d,0x69, - 0x6c,0x6c,0x0e,0x35,0xd8,0xa9, - 0x46,0x0f,0x79,0xbe,0x51,0x71, - 0x44,0x4f,0x47}; + 0x12, 0x84, 0x1a, 0x99, 0xce, 0x9a, 0x8b, 0x58, + 0xcc, 0x47, 0x43, 0xdf, 0x77, 0xbb, 0xd3, 0x20, + 0xae, 0xe4, 0x2e, 0x63, 0x67, 0xdc, 0xf7, 0x5f, + 0x3f, 0x83, 0x27, 0xb7, 0x14, 0x52, 0x56, 0xbf, + 0xc3, 0x65, 0x06, 0xe1, 0x03, 0xcc, 0x93, 0x57, + 0x09, 0x7b, 0x6f, 0xe8, 0x81, 0x4a, 0x2c, 0xb7, + 0x43, 0xa9, 0x20, 0x1d, 0xf6, 0x56, 0x8b, 0xcc, + 0xe5, 0x4c, 0xd5, 0x4f, 0x74, 0x67, 0x29, 0x51}; static const PRUint8 rsa_coefficient[FIPS_RSA_COEFFICIENT_LENGTH] = { - 0x54,0x8d,0xb8,0xdc,0x8b,0xde,0xbb, - 0x08,0xc9,0x67,0xb7,0xa9,0x5f,0xa5, - 0xc4,0x5e,0x67,0xaa,0xfe,0x1a,0x08, - 0xeb,0x48,0x43,0xcb,0xb0,0xb9,0x38, - 0x3a,0x31,0x39,0xde}; - - - /* RSA Known Plaintext (512-bits). */ - static const PRUint8 rsa_known_plaintext[] = { - "Known plaintext utilized for RSA" - " Encryption and Decryption test." }; - - /* RSA Known Ciphertext (512-bits). */ + 0x23, 0xab, 0xf4, 0x03, 0x2f, 0x29, 0x95, 0x74, + 0xac, 0x1a, 0x33, 0x96, 0x62, 0xed, 0xf7, 0xf6, + 0xae, 0x07, 0x2a, 0x2e, 0xe8, 0xab, 0xfb, 0x1e, + 0xb9, 0xb2, 0x88, 0x1e, 0x85, 0x05, 0x42, 0x64, + 0x03, 0xb2, 0x8b, 0xc1, 0x81, 0x75, 0xd7, 0xba, + 0xaa, 0xd4, 0x31, 0x3c, 0x8a, 0x96, 0x23, 0x9d, + 0x3f, 0x06, 0x3e, 0x44, 0xa9, 0x62, 0x2f, 0x61, + 0x5a, 0x51, 0x82, 0x2c, 0x04, 0x85, 0x73, 0xd1}; + + /* RSA Known Plaintext Message (1024-bits). */ + static const PRUint8 rsa_known_plaintext_msg[FIPS_RSA_MESSAGE_LENGTH] = { + "Known plaintext message utilized" + "for RSA Encryption & Decryption" + "block, SHA1, SHA256, SHA384 and" + "SHA512 RSA Signature KAT tests."}; + + /* RSA Known Ciphertext (1024-bits). */ static const PRUint8 rsa_known_ciphertext[] = { - 0x12,0x80,0x3a,0x53,0xee,0x93,0x81,0xa5, - 0xf7,0x40,0xc5,0xb1,0xef,0xd9,0x27,0xaf, - 0xef,0x4b,0x87,0x44,0x00,0xd0,0xda,0xcf, - 0x10,0x57,0x4c,0xd5,0xc3,0xed,0x84,0xdc, - 0x74,0x03,0x19,0x69,0x2c,0xd6,0x54,0x3e, - 0xd2,0xe3,0x90,0xb6,0x67,0x91,0x2f,0x1f, - 0x54,0x13,0x99,0x00,0x0b,0xfd,0x52,0x7f, - 0xd8,0xc6,0xdb,0x8a,0xfe,0x06,0xf3,0xb1}; - - /* RSA Known Message (128-bits). */ - static const PRUint8 rsa_known_message[] = { "Netscape Forever" }; - - /* RSA Known Signed Hash (512-bits). */ - static const PRUint8 rsa_known_signature[] = { - 0x27,0x23,0xa6,0x71,0x57,0xc8,0x70,0x5f, - 0x70,0x0e,0x06,0x7b,0x96,0x6a,0xaa,0x41, - 0x6e,0xab,0x67,0x4b,0x5f,0x76,0xc4,0x53, - 0x23,0xd7,0x57,0x7a,0x3a,0xbc,0x4c,0x27, - 0x65,0xca,0xde,0x9f,0xd3,0x1d,0xa4,0x5a, - 0xf9,0x8f,0xb2,0x05,0xa3,0x86,0xf9,0x66, - 0x55,0x4c,0x68,0x50,0x66,0xa4,0xe9,0x17, - 0x45,0x11,0xb8,0x1a,0xfc,0xbc,0x79,0x3b}; - - - static const RSAPublicKey bl_public_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH } + 0x1e, 0x7e, 0x12, 0xbb, 0x15, 0x62, 0xd0, 0x23, + 0x53, 0x4c, 0x51, 0x97, 0x77, 0x06, 0xa0, 0xbb, + 0x26, 0x99, 0x9a, 0x8f, 0x39, 0xad, 0x88, 0x5c, + 0xc4, 0xce, 0x33, 0x40, 0x94, 0x92, 0xb4, 0x0e, + 0xab, 0x71, 0xa9, 0x5d, 0x9a, 0x37, 0xe3, 0x9a, + 0x24, 0x95, 0x13, 0xea, 0x0f, 0xbb, 0xf7, 0xff, + 0xdf, 0x31, 0x33, 0x23, 0x1d, 0xce, 0x26, 0x9e, + 0xd1, 0xde, 0x98, 0x40, 0xde, 0x57, 0x86, 0x12, + 0xf1, 0xe6, 0x5a, 0x3f, 0x08, 0x02, 0x81, 0x85, + 0xe0, 0xd9, 0xad, 0x3c, 0x8c, 0x71, 0xf8, 0xcf, + 0x0a, 0x98, 0xc5, 0x08, 0xdc, 0xc4, 0xca, 0x8c, + 0x23, 0x1b, 0x4d, 0x9b, 0xb5, 0x13, 0x44, 0xe1, + 0x5f, 0xf9, 0x30, 0x80, 0x25, 0xe0, 0x1e, 0x94, + 0xa3, 0x0c, 0xdc, 0x82, 0x2e, 0xfb, 0x30, 0xbe, + 0x89, 0xba, 0x76, 0xb6, 0x23, 0xf7, 0xda, 0x7c, + 0xca, 0xe6, 0x02, 0xbd, 0x92, 0xce, 0x64, 0xfc}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha1_signature[] = { + 0xd2, 0xa4, 0xe0, 0x2b, 0xc7, 0x03, 0x7f, 0xc6, + 0x06, 0x9e, 0xa2, 0x82, 0x19, 0xe9, 0x2b, 0xaf, + 0xe3, 0x48, 0x88, 0xc1, 0xf3, 0xb5, 0x0d, 0xe4, + 0x52, 0x9e, 0xad, 0xd5, 0x58, 0xb5, 0x9f, 0xe8, + 0x40, 0xe9, 0xb7, 0x2e, 0xc6, 0x71, 0x58, 0x56, + 0x04, 0xac, 0xb0, 0xf3, 0x3a, 0x42, 0x38, 0x08, + 0xc4, 0x43, 0x39, 0xba, 0x19, 0xce, 0xb1, 0x99, + 0xf1, 0x8d, 0x89, 0xd8, 0x50, 0x07, 0x14, 0x3d, + 0xcf, 0xd0, 0xb6, 0x79, 0xde, 0x9c, 0x89, 0x32, + 0xb0, 0x73, 0x3f, 0xed, 0x03, 0x0b, 0xdf, 0x6d, + 0x7e, 0xc9, 0x1c, 0x39, 0xe8, 0x2b, 0x16, 0x09, + 0xbb, 0x5f, 0x99, 0x2f, 0xeb, 0xf3, 0x37, 0x73, + 0x0d, 0x0e, 0xcc, 0x95, 0xad, 0x90, 0x80, 0x03, + 0x1d, 0x80, 0x55, 0x37, 0xa1, 0x2a, 0x71, 0x76, + 0x23, 0x87, 0x8c, 0x9b, 0x41, 0x07, 0xc6, 0x3d, + 0xc6, 0xa3, 0x7d, 0x1b, 0xff, 0x4e, 0x11, 0x19}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha256_signature[] = { + 0x27, 0x35, 0xdd, 0xc4, 0xf8, 0xe2, 0x0b, 0xa3, + 0xef, 0x63, 0x57, 0x3b, 0xe1, 0x58, 0x9a, 0xbc, + 0x20, 0x9c, 0x25, 0x12, 0x01, 0xbf, 0xbb, 0x29, + 0x80, 0x1a, 0xb1, 0x37, 0x9c, 0xcd, 0x67, 0xc7, + 0x0d, 0xf8, 0x64, 0x10, 0x9f, 0xe2, 0xa1, 0x9b, + 0x21, 0x90, 0xcc, 0xda, 0x8b, 0x76, 0x5e, 0x79, + 0x00, 0x9d, 0x58, 0x8b, 0x8a, 0xb3, 0xc3, 0xb5, + 0xf1, 0x54, 0xc5, 0x8c, 0x72, 0xba, 0xde, 0x51, + 0x3c, 0x6b, 0x94, 0xd6, 0xf3, 0x1b, 0xa2, 0x53, + 0xe6, 0x1a, 0x46, 0x1d, 0x7f, 0x14, 0x86, 0xcc, + 0xa6, 0x30, 0x92, 0x96, 0xc0, 0x96, 0x24, 0xf0, + 0x42, 0x53, 0x4c, 0xdd, 0x27, 0xdf, 0x1d, 0x2e, + 0x8b, 0x83, 0xbe, 0xed, 0x85, 0x1d, 0x50, 0x46, + 0xa3, 0x7d, 0x20, 0xea, 0x3e, 0x91, 0xfb, 0xf6, + 0x86, 0x51, 0xfd, 0x8c, 0xe5, 0x31, 0xe6, 0x7e, + 0x60, 0x08, 0x0e, 0xec, 0xa6, 0xea, 0x24, 0x8d}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha384_signature[] = { + 0x0b, 0x03, 0x94, 0x4f, 0x94, 0x78, 0x9b, 0x96, + 0x76, 0xeb, 0x72, 0x58, 0xe1, 0xc5, 0xc7, 0x5f, + 0x85, 0x01, 0xa8, 0xc4, 0xf6, 0x1a, 0xb5, 0x2c, + 0xd1, 0xd8, 0x87, 0xde, 0x3a, 0x9c, 0x9f, 0x57, + 0x81, 0x2a, 0x1e, 0x23, 0x07, 0x70, 0xb0, 0xf9, + 0x28, 0x3d, 0xfa, 0xe5, 0x2e, 0x1b, 0x9a, 0x72, + 0xc3, 0x74, 0xb3, 0x42, 0x1c, 0x9a, 0x13, 0xdc, + 0xc9, 0xd6, 0xd5, 0x88, 0xc9, 0x9c, 0x46, 0xf1, + 0x0c, 0xa6, 0xf7, 0xd8, 0x06, 0xa3, 0x1b, 0xdf, + 0x55, 0xb3, 0x1b, 0x7b, 0x58, 0x1d, 0xff, 0x19, + 0xc7, 0xe0, 0xdd, 0x59, 0xac, 0x2f, 0x78, 0x71, + 0xe7, 0xe0, 0x17, 0xa3, 0x1c, 0x5c, 0x92, 0xef, + 0xb6, 0x75, 0xed, 0xbe, 0x18, 0x39, 0x6b, 0xd7, + 0xc9, 0x08, 0x62, 0x55, 0x62, 0xac, 0x5d, 0xa1, + 0x9b, 0xd5, 0xb8, 0x98, 0x15, 0xc0, 0xf5, 0x41, + 0x85, 0x44, 0x96, 0xca, 0x10, 0xdc, 0x57, 0x21}; + + /* RSA Known Signed Hash (1024-bits). */ + static const PRUint8 rsa_known_sha512_signature[] = { + 0xa5, 0xd0, 0x80, 0x04, 0x22, 0xfc, 0x80, 0x73, + 0x7d, 0x46, 0xc8, 0x7b, 0xac, 0x44, 0x7b, 0xe6, + 0x07, 0xe5, 0x61, 0x4c, 0x33, 0x7f, 0x6f, 0x46, + 0x7c, 0x30, 0xe3, 0x75, 0x59, 0x4b, 0x42, 0xf3, + 0x9f, 0x35, 0x3c, 0x10, 0x56, 0xdb, 0xd2, 0x69, + 0x43, 0xcb, 0x77, 0xe9, 0x7d, 0xcd, 0x07, 0x43, + 0xc5, 0xd4, 0x0c, 0x9d, 0xf5, 0x92, 0xbd, 0x0e, + 0x3b, 0xb7, 0x68, 0x88, 0x84, 0xca, 0xae, 0x0d, + 0xab, 0x71, 0x10, 0xad, 0xab, 0x27, 0xe4, 0xa3, + 0x24, 0x41, 0xeb, 0x1c, 0xa6, 0x5f, 0xf1, 0x85, + 0xd0, 0xf6, 0x22, 0x74, 0x3d, 0x81, 0xbe, 0xdd, + 0x1b, 0x2a, 0x4c, 0xd1, 0x6c, 0xb5, 0x6d, 0x7a, + 0xbb, 0x99, 0x69, 0x01, 0xa6, 0xc0, 0x98, 0xfa, + 0x97, 0xa3, 0xd1, 0xb0, 0xdf, 0x09, 0xe3, 0x3d, + 0x88, 0xee, 0x90, 0xf3, 0x10, 0x41, 0x0f, 0x06, + 0x31, 0xe9, 0x60, 0x2d, 0xbf, 0x63, 0x7b, 0xf8}; + + static const RSAPublicKey bl_public_key = { NULL, + { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, + FIPS_RSA_MODULUS_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, + FIPS_RSA_PUBLIC_EXPONENT_LENGTH } }; static const RSAPrivateKey bl_private_key = { NULL, - { FIPS_RSA_TYPE, (unsigned char *)rsa_version, FIPS_RSA_PRIVATE_VERSION_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, FIPS_RSA_MODULUS_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, FIPS_RSA_PUBLIC_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, FIPS_RSA_PRIVATE_EXPONENT_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, FIPS_RSA_PRIME0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, FIPS_RSA_PRIME1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, FIPS_RSA_EXPONENT0_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, FIPS_RSA_EXPONENT1_LENGTH }, - { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, FIPS_RSA_COEFFICIENT_LENGTH } + { FIPS_RSA_TYPE, (unsigned char *)rsa_version, + FIPS_RSA_PRIVATE_VERSION_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_modulus, + FIPS_RSA_MODULUS_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_public_exponent, + FIPS_RSA_PUBLIC_EXPONENT_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_private_exponent, + FIPS_RSA_PRIVATE_EXPONENT_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_prime0, + FIPS_RSA_PRIME0_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_prime1, + FIPS_RSA_PRIME1_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent0, + FIPS_RSA_EXPONENT0_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_exponent1, + FIPS_RSA_EXPONENT1_LENGTH }, + { FIPS_RSA_TYPE, (unsigned char *)rsa_coefficient, + FIPS_RSA_COEFFICIENT_LENGTH } }; /* RSA variables. */ @@ -1170,14 +1386,12 @@ sftk_fips_RSA_PowerUpSelfTest( void ) #endif NSSLOWKEYPublicKey * rsa_public_key; NSSLOWKEYPrivateKey * rsa_private_key; - unsigned int rsa_bytes_signed; SECStatus rsa_status; NSSLOWKEYPublicKey low_public_key = { NULL, NSSLOWKEYRSAKey, }; NSSLOWKEYPrivateKey low_private_key = { NULL, NSSLOWKEYRSAKey, }; PRUint8 rsa_computed_ciphertext[FIPS_RSA_ENCRYPT_LENGTH]; PRUint8 rsa_computed_plaintext[FIPS_RSA_DECRYPT_LENGTH]; - PRUint8 rsa_computed_signature[FIPS_RSA_SIGNATURE_LENGTH]; /****************************************/ /* Compose RSA Public/Private Key Pair. */ @@ -1216,8 +1430,9 @@ sftk_fips_RSA_PowerUpSelfTest( void ) /**************************************************/ /* Perform RSA Public Key Encryption. */ - rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa, - rsa_computed_ciphertext, rsa_known_plaintext); + rsa_status = RSA_PublicKeyOp(&rsa_public_key->u.rsa, + rsa_computed_ciphertext, + rsa_known_plaintext_msg); if( ( rsa_status != SECSuccess ) || ( PORT_Memcmp( rsa_computed_ciphertext, rsa_known_ciphertext, @@ -1229,44 +1444,40 @@ sftk_fips_RSA_PowerUpSelfTest( void ) /**************************************************/ /* Perform RSA Private Key Decryption. */ - rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa, - rsa_computed_plaintext, rsa_known_ciphertext); + rsa_status = RSA_PrivateKeyOp(&rsa_private_key->u.rsa, + rsa_computed_plaintext, + rsa_known_ciphertext); if( ( rsa_status != SECSuccess ) || - ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext, + ( PORT_Memcmp( rsa_computed_plaintext, rsa_known_plaintext_msg, FIPS_RSA_DECRYPT_LENGTH ) != 0 ) ) goto rsa_loser; - - /*************************************************/ - /* RSA Single-Round Known Answer Signature Test. */ - /*************************************************/ - - /* Perform RSA signature with the RSA private key. */ - rsa_status = RSA_Sign( rsa_private_key, rsa_computed_signature, - &rsa_bytes_signed, - FIPS_RSA_SIGNATURE_LENGTH, - (unsigned char *)rsa_known_message, - FIPS_RSA_MESSAGE_LENGTH ); - - if( ( rsa_status != SECSuccess ) || - ( rsa_bytes_signed != FIPS_RSA_SIGNATURE_LENGTH ) || - ( PORT_Memcmp( rsa_computed_signature, rsa_known_signature, - FIPS_RSA_SIGNATURE_LENGTH ) != 0 ) ) + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA1, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha1_signature); + if( rsa_status != SECSuccess ) goto rsa_loser; + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA256, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha256_signature); + if( rsa_status != SECSuccess ) + goto rsa_loser; - /****************************************************/ - /* RSA Single-Round Known Answer Verification Test. */ - /****************************************************/ - - /* Perform RSA verification with the RSA public key. */ - rsa_status = RSA_CheckSign( rsa_public_key, - rsa_computed_signature, - FIPS_RSA_SIGNATURE_LENGTH, - (unsigned char *)rsa_known_message, - FIPS_RSA_MESSAGE_LENGTH ); + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA384, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha384_signature); + if( rsa_status != SECSuccess ) + goto rsa_loser; + rsa_status = sftk_fips_RSA_PowerUpSigSelfTest (HASH_AlgSHA512, + rsa_public_key, rsa_private_key, + rsa_known_plaintext_msg, FIPS_RSA_MESSAGE_LENGTH, + rsa_known_sha512_signature); if( rsa_status != SECSuccess ) goto rsa_loser; @@ -1276,7 +1487,6 @@ sftk_fips_RSA_PowerUpSelfTest( void ) return( CKR_OK ); - rsa_loser: nsslowkey_DestroyPublicKey( rsa_public_key ); @@ -1285,33 +1495,235 @@ rsa_loser: return( CKR_DEVICE_ERROR ); } +#ifdef NSS_ENABLE_ECC + +static CK_RV +sftk_fips_ECDSA_Test(const PRUint8 *encodedParams, + unsigned int encodedParamsLen, + const PRUint8 *knownSignature, + unsigned int knownSignatureLen) { + + /* ECDSA Known Seed info for curves nistp256 and nistk283 */ + static const PRUint8 ecdsa_Known_Seed[] = { + 0x6a, 0x9b, 0xf6, 0xf7, 0xce, 0xed, 0x79, 0x11, + 0xf0, 0xc7, 0xc8, 0x9a, 0xa5, 0xd1, 0x57, 0xb1, + 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc, + 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f}; + + static const PRUint8 msg[] = { + "Firefox and ThunderBird are awesome!"}; + + unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */ + unsigned char sig[2*MAX_ECKEY_LEN]; + SECItem signature, digest; + SECItem encodedparams; + ECParams *ecparams = NULL; + ECPrivateKey *ecdsa_private_key = NULL; + ECPublicKey ecdsa_public_key; + SECStatus ecdsaStatus = SECSuccess; + + /* construct the ECDSA private/public key pair */ + encodedparams.type = siBuffer; + encodedparams.data = (unsigned char *) encodedParams; + encodedparams.len = encodedParamsLen; + + if (EC_DecodeParams(&encodedparams, &ecparams) != SECSuccess) { + return( CKR_DEVICE_ERROR ); + } + + /* Generates a new EC key pair. The private key is a supplied + * random value (in seed) and the public key is the result of + * performing a scalar point multiplication of that value with + * the curve's base point. + */ + ecdsaStatus = EC_NewKeyFromSeed(ecparams, &ecdsa_private_key, + ecdsa_Known_Seed, + sizeof(ecdsa_Known_Seed)); + /* free the ecparams they are no longer needed */ + PORT_FreeArena(ecparams->arena, PR_FALSE); + ecparams = NULL; + if (ecdsaStatus != SECSuccess) { + return ( CKR_DEVICE_ERROR ); + } + + /* construct public key from private key. */ + ecdsaStatus = EC_CopyParams(ecdsa_private_key->ecParams.arena, + &ecdsa_public_key.ecParams, + &ecdsa_private_key->ecParams); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + ecdsa_public_key.publicValue = ecdsa_private_key->publicValue; + + /* validate public key value */ + ecdsaStatus = EC_ValidatePublicKey(&ecdsa_public_key.ecParams, + &ecdsa_public_key.publicValue); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + /* validate public key value */ + ecdsaStatus = EC_ValidatePublicKey(&ecdsa_private_key->ecParams, + &ecdsa_private_key->publicValue); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + /***************************************************/ + /* ECDSA Single-Round Known Answer Signature Test. */ + /***************************************************/ + + ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + digest.type = siBuffer; + digest.data = sha1; + digest.len = SHA1_LENGTH; + + memset(sig, 0, sizeof sig); + signature.type = siBuffer; + signature.data = sig; + signature.len = sizeof sig; + + ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature, + &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + if( ( signature.len != knownSignatureLen ) || + ( PORT_Memcmp( signature.data, knownSignature, + knownSignatureLen ) != 0 ) ) { + ecdsaStatus = SECFailure; + goto loser; + } + + /******************************************************/ + /* ECDSA Single-Round Known Answer Verification Test. */ + /******************************************************/ + + /* Perform ECDSA verification process. */ + ecdsaStatus = ECDSA_VerifyDigest(&ecdsa_public_key, &signature, &digest); + +loser: + /* free the memory for the private key arena*/ + if (ecdsa_private_key != NULL) { + PORT_FreeArena(ecdsa_private_key->ecParams.arena, PR_FALSE); + } + + if (ecdsaStatus != SECSuccess) { + return CKR_DEVICE_ERROR ; + } + return( CKR_OK ); +} + +static CK_RV +sftk_fips_ECDSA_PowerUpSelfTest() { + + /* ECDSA Known curve nistp256 == SEC_OID_SECG_EC_SECP256R1 params */ + static const PRUint8 ecdsa_known_P256_EncodedParams[] = { + 0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03, + 0x01,0x07}; + + static const PRUint8 ecdsa_known_P256_signature[] = { + 0x07,0xb1,0xcb,0x57,0x20,0xa7,0x10,0xd6, + 0x9d,0x37,0x4b,0x1c,0xdc,0x35,0x90,0xff, + 0x1a,0x2d,0x98,0x95,0x1b,0x2f,0xeb,0x7f, + 0xbb,0x81,0xca,0xc0,0x69,0x75,0xea,0xc5, + 0x59,0x6a,0x62,0x49,0x3d,0x50,0xc9,0xe1, + 0x27,0x3b,0xff,0x9b,0x13,0x66,0x67,0xdd, + 0x7d,0xd1,0x0d,0x2d,0x7c,0x44,0x04,0x1b, + 0x16,0x21,0x12,0xc5,0xcb,0xbd,0x9e,0x75}; + +#ifdef NSS_ECC_MORE_THAN_SUITE_B + /* ECDSA Known curve nistk283 == SEC_OID_SECG_EC_SECT283K1 params */ + static const PRUint8 ecdsa_known_K283_EncodedParams[] = { + 0x06,0x05,0x2b,0x81,0x04,0x00,0x10}; + + static const PRUint8 ecdsa_known_K283_signature[] = { + 0x00,0x45,0x88,0xc0,0x79,0x09,0x07,0xd1, + 0x4e,0x88,0xe6,0xd5,0x2f,0x22,0x04,0x74, + 0x35,0x24,0x65,0xe8,0x15,0xde,0x90,0x66, + 0x94,0x70,0xdd,0x3a,0x14,0x70,0x02,0xd1, + 0xef,0x86,0xbd,0x15,0x00,0xd9,0xdc,0xfc, + 0x87,0x2e,0x7c,0x99,0xe2,0xe3,0x79,0xb8, + 0xd9,0x10,0x49,0x78,0x4b,0x59,0x8b,0x05, + 0x77,0xec,0x6c,0xe8,0x35,0xe6,0x2e,0xa9, + 0xf9,0x77,0x1f,0x71,0x86,0xa5,0x4a,0xd0}; +#endif + + CK_RV crv; + + /* ECDSA GF(p) prime field curve test */ + crv = sftk_fips_ECDSA_Test(ecdsa_known_P256_EncodedParams, + sizeof ecdsa_known_P256_EncodedParams, + ecdsa_known_P256_signature, + sizeof ecdsa_known_P256_signature ); + if (crv != CKR_OK) { + return( CKR_DEVICE_ERROR ); + } + +#ifdef NSS_ECC_MORE_THAN_SUITE_B + /* ECDSA GF(2m) binary field curve test */ + crv = sftk_fips_ECDSA_Test(ecdsa_known_K283_EncodedParams, + sizeof ecdsa_known_K283_EncodedParams, + ecdsa_known_K283_signature, + sizeof ecdsa_known_K283_signature ); + if (crv != CKR_OK) { + return( CKR_DEVICE_ERROR ); + } +#endif + + return( CKR_OK ); +} + +#endif /* NSS_ENABLE_ECC */ static CK_RV sftk_fips_DSA_PowerUpSelfTest( void ) { - /* DSA Known P (512-bits), Q (160-bits), and G (512-bits) Values. */ + /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ static const PRUint8 dsa_P[] = { - 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, - 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, - 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, - 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, - 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, - 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac, - 0x49,0x69,0x3d,0xfb,0xf8,0x37,0x24,0xc2, - 0xec,0x07,0x36,0xee,0x31,0xc8,0x02,0x91}; + 0x80,0xb0,0xd1,0x9d,0x6e,0xa4,0xf3,0x28, + 0x9f,0x24,0xa9,0x8a,0x49,0xd0,0x0c,0x63, + 0xe8,0x59,0x04,0xf9,0x89,0x4a,0x5e,0xc0, + 0x6d,0xd2,0x67,0x6b,0x37,0x81,0x83,0x0c, + 0xfe,0x3a,0x8a,0xfd,0xa0,0x3b,0x08,0x91, + 0x1c,0xcb,0xb5,0x63,0xb0,0x1c,0x70,0xd0, + 0xae,0xe1,0x60,0x2e,0x12,0xeb,0x54,0xc7, + 0xcf,0xc6,0xcc,0xae,0x97,0x52,0x32,0x63, + 0xd3,0xeb,0x55,0xea,0x2f,0x4c,0xd5,0xd7, + 0x3f,0xda,0xec,0x49,0x27,0x0b,0x14,0x56, + 0xc5,0x09,0xbe,0x4d,0x09,0x15,0x75,0x2b, + 0xa3,0x42,0x0d,0x03,0x71,0xdf,0x0f,0xf4, + 0x0e,0xe9,0x0c,0x46,0x93,0x3d,0x3f,0xa6, + 0x6c,0xdb,0xca,0xe5,0xac,0x96,0xc8,0x64, + 0x5c,0xec,0x4b,0x35,0x65,0xfc,0xfb,0x5a, + 0x1b,0x04,0x1b,0xa1,0x0e,0xfd,0x88,0x15}; + static const PRUint8 dsa_Q[] = { - 0xc7,0x73,0x21,0x8c,0x73,0x7e,0xc8,0xee, - 0x99,0x3b,0x4f,0x2d,0xed,0x30,0xf4,0x8e, - 0xda,0xce,0x91,0x5f}; + 0xad,0x22,0x59,0xdf,0xe5,0xec,0x4c,0x6e, + 0xf9,0x43,0xf0,0x4b,0x2d,0x50,0x51,0xc6, + 0x91,0x99,0x8b,0xcf}; + static const PRUint8 dsa_G[] = { - 0x62,0x6d,0x02,0x78,0x39,0xea,0x0a,0x13, - 0x41,0x31,0x63,0xa5,0x5b,0x4c,0xb5,0x00, - 0x29,0x9d,0x55,0x22,0x95,0x6c,0xef,0xcb, - 0x3b,0xff,0x10,0xf3,0x99,0xce,0x2c,0x2e, - 0x71,0xcb,0x9d,0xe5,0xfa,0x24,0xba,0xbf, - 0x58,0xe5,0xb7,0x95,0x21,0x92,0x5c,0x9c, - 0xc4,0x2e,0x9f,0x6f,0x46,0x4b,0x08,0x8c, - 0xc5,0x72,0xaf,0x53,0xe6,0xd7,0x88,0x02}; + 0x78,0x6e,0xa9,0xd8,0xcd,0x4a,0x85,0xa4, + 0x45,0xb6,0x6e,0x5d,0x21,0x50,0x61,0xf6, + 0x5f,0xdf,0x5c,0x7a,0xde,0x0d,0x19,0xd3, + 0xc1,0x3b,0x14,0xcc,0x8e,0xed,0xdb,0x17, + 0xb6,0xca,0xba,0x86,0xa9,0xea,0x51,0x2d, + 0xc1,0xa9,0x16,0xda,0xf8,0x7b,0x59,0x8a, + 0xdf,0xcb,0xa4,0x67,0x00,0x44,0xea,0x24, + 0x73,0xe5,0xcb,0x4b,0xaf,0x2a,0x31,0x25, + 0x22,0x28,0x3f,0x16,0x10,0x82,0xf7,0xeb, + 0x94,0x0d,0xdd,0x09,0x22,0x14,0x08,0x79, + 0xba,0x11,0x0b,0xf1,0xff,0x2d,0x67,0xac, + 0xeb,0xb6,0x55,0x51,0x69,0x97,0xa7,0x25, + 0x6b,0x9c,0xa0,0x9b,0xd5,0x08,0x9b,0x27, + 0x42,0x1c,0x7a,0x69,0x57,0xe6,0x2e,0xed, + 0xa9,0x5b,0x25,0xe8,0x1f,0xd2,0xed,0x1f, + 0xdf,0xe7,0x80,0x17,0xba,0x0d,0x4d,0x38}; /* DSA Known Random Values (known random key block is 160-bits) */ /* and (known random signature block is 160-bits). */ @@ -1325,11 +1737,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* DSA Known Signature (320-bits). */ static const PRUint8 dsa_known_signature[] = { - 0x39,0x0d,0x84,0xb1,0xf7,0x52,0x89,0xba, - 0xec,0x1e,0xa8,0xe2,0x00,0x8e,0x37,0x8f, - 0xc2,0xf5,0xf8,0x70,0x11,0xa8,0xc7,0x02, - 0x0e,0x75,0xcf,0x6b,0x54,0x4a,0x52,0xe8, - 0xd8,0x6d,0x4a,0xe8,0xee,0x56,0x8e,0x59}; + 0x25,0x7c,0x3a,0x79,0x32,0x45,0xb7,0x32, + 0x70,0xca,0x62,0x63,0x2b,0xf6,0x29,0x2c, + 0x22,0x2a,0x03,0xce,0x48,0x15,0x11,0x72, + 0x7b,0x7e,0xf5,0x7a,0xf3,0x10,0x3b,0xde, + 0x34,0xc1,0x9e,0xd7,0x27,0x9e,0x77,0x38}; /* DSA variables. */ DSAPrivateKey * dsa_private_key; @@ -1348,12 +1760,11 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /*******************************************/ /* Generate a DSA public/private key pair. */ - dsa_status = DSA_NewKeyFromSeed(&dsa_pqg, dsa_known_random_key_block, &dsa_private_key); if( dsa_status != SECSuccess ) - return( CKR_HOST_MEMORY ); + return( CKR_HOST_MEMORY ); /* construct public key from private key. */ dsa_public_key.params = dsa_private_key->params; @@ -1372,8 +1783,8 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA signature process. */ dsa_status = DSA_SignDigestWithSeed( dsa_private_key, &dsa_signature_item, - &dsa_digest_item, - dsa_known_random_signature_block ); + &dsa_digest_item, + dsa_known_random_signature_block ); if( ( dsa_status != SECSuccess ) || ( dsa_signature_item.len != FIPS_DSA_SIGNATURE_LENGTH ) || @@ -1389,7 +1800,7 @@ sftk_fips_DSA_PowerUpSelfTest( void ) /* Perform DSA verification process. */ dsa_status = DSA_VerifyDigest( &dsa_public_key, &dsa_signature_item, - &dsa_digest_item); + &dsa_digest_item); } PORT_FreeArena(dsa_private_key->params.arena, PR_TRUE); @@ -1404,6 +1815,79 @@ sftk_fips_DSA_PowerUpSelfTest( void ) } +static CK_RV +sftk_fips_RNG_PowerUpSelfTest( void ) +{ + static const PRUint8 XKeyValue[] = { + 0x8d,0xf2,0xa4,0x94,0x49,0x22,0x76,0xaa, + 0x3d,0x25,0x75,0x9b,0xb0,0x68,0x69,0xcb, + 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, + 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5}; + static const PRUint8 XSeed[] = { + 0xea,0xc0,0xd8,0x3a,0xfb,0x8d,0x0c,0xf7, + 0xcb,0xb8,0x32,0x4f,0x0d,0x78,0x82,0xe5, + 0xd0,0x76,0x2f,0xc5,0xb7,0x21,0x0e,0xaf, + 0xc2,0xe9,0xad,0xac,0x32,0xab,0x7a,0xac}; + static const PRUint8 Q[] = { + 0x85,0x89,0x9c,0x77,0xa3,0x79,0xff,0x1a, + 0x86,0x6f,0x2f,0x3e,0x2e,0xf9,0x8c,0x9c, + 0x9d,0xef,0xeb,0xed}; + static const PRUint8 rng_known_GENX[] = { + 0x65,0x48,0xe3,0xca,0xac,0x64,0x2d,0xf7, + 0x7b,0xd3,0x4e,0x79,0xc9,0x7d,0xa6,0xa8, + 0xa2,0xc2,0x1f,0x8f,0xe9,0xb9,0xd3,0xa1, + 0x3f,0xf7,0x0c,0xcd,0xa6,0xca,0xbf,0xce, + 0x84,0x0e,0xb6,0xf1,0x0d,0xbe,0xa9,0xa3}; + static const PRUint8 rng_known_DSAX[] = { + 0x7a,0x86,0xf1,0x7f,0xbd,0x4e,0x6e,0xd9, + 0x0a,0x26,0x21,0xd0,0x19,0xcb,0x86,0x73, + 0x10,0x1f,0x60,0xd7}; + + SECStatus rng_status = SECSuccess; + PRUint8 GENX[2*SHA1_LENGTH]; + PRUint8 DSAX[FIPS_DSA_SUBPRIME_LENGTH]; + PRUint8 XKey[FIPS_RNG_XKEY_LENGTH]; + + PORT_Memcpy (XKey, XKeyValue, FIPS_RNG_XKEY_LENGTH); + + /*******************************************/ + /* Generate X with a known seed. */ + /*******************************************/ + rng_status = FIPS186Change_GenerateX(XKey, XSeed, GENX); + + /* Verify GENX to perform the RNG integrity check */ + if( ( rng_status != SECSuccess ) || + ( PORT_Memcmp( GENX, rng_known_GENX, + (2*SHA1_LENGTH) ) != 0 ) ) + return( CKR_DEVICE_ERROR ); + + /*******************************************/ + /* Generate DSAX fow given Q. */ + /*******************************************/ + + rng_status = FIPS186Change_ReduceModQForDSA(GENX, Q, DSAX); + + /* Verify DSAX to perform the RNG integrity check */ + if( ( rng_status != SECSuccess ) || + ( PORT_Memcmp( DSAX, rng_known_DSAX, + (FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) ) + return( CKR_DEVICE_ERROR ); + + return( CKR_OK ); +} + +static CK_RV +sftk_fipsSoftwareIntegrityTest(void) +{ + CK_RV crv = CKR_OK; + + /* make sure that our check file signatures are OK */ + if( !BLAPI_VerifySelf( NULL ) || + !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) { + crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ + } + return crv; +} CK_RV sftk_fipsPowerUpSelfTest( void ) @@ -1488,6 +1972,26 @@ sftk_fipsPowerUpSelfTest( void ) if( rv != CKR_OK ) return rv; + /* RNG Power-Up SelfTest(s). */ + rv = sftk_fips_RNG_PowerUpSelfTest(); + + if( rv != CKR_OK ) + return rv; + +#ifdef NSS_ENABLE_ECC + /* ECDSA Power-Up SelfTest(s). */ + rv = sftk_fips_ECDSA_PowerUpSelfTest(); + + if( rv != CKR_OK ) + return rv; +#endif + + /* Software/Firmware Integrity Test. */ + rv = sftk_fipsSoftwareIntegrityTest(); + + if( rv != CKR_OK ) + return rv; + /* Passed Power-Up SelfTest(s). */ return( CKR_OK ); } diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c index 9ef144cb8..6cfcfcb05 100644 --- a/security/nss/lib/softoken/fipstokn.c +++ b/security/nss/lib/softoken/fipstokn.c @@ -55,15 +55,77 @@ #include "pcert.h" #include "pkcs11.h" #include "pkcs11i.h" +#include "prenv.h" +#include "prprf.h" #include <ctype.h> +#ifdef XP_UNIX +#define NSS_AUDIT_WITH_SYSLOG 1 +#include <syslog.h> +#include <unistd.h> +#endif + +#ifdef SOLARIS +#include <bsm/libbsm.h> +#define AUE_FIPS_AUDIT 34444 +#endif + +#ifdef LINUX +#include <pthread.h> +#include <dlfcn.h> +#define LIBAUDIT_NAME "libaudit.so.0" +#ifndef AUDIT_USER +#define AUDIT_USER 1005 /* message type: message from userspace */ +#endif +static void *libaudit_handle; +static int (*audit_open_func)(void); +static void (*audit_close_func)(int fd); +static int (*audit_log_user_message_func)(int audit_fd, int type, + const char *message, const char *hostname, const char *addr, + const char *tty, int result); +static int (*audit_send_user_message_func)(int fd, int type, + const char *message); + +static pthread_once_t libaudit_once_control = PTHREAD_ONCE_INIT; + +static void +libaudit_init(void) +{ + libaudit_handle = dlopen(LIBAUDIT_NAME, RTLD_LAZY); + if (!libaudit_handle) { + return; + } + audit_open_func = dlsym(libaudit_handle, "audit_open"); + audit_close_func = dlsym(libaudit_handle, "audit_close"); + /* + * audit_send_user_message is the older function. + * audit_log_user_message, if available, is preferred. + */ + audit_log_user_message_func = dlsym(libaudit_handle, + "audit_log_user_message"); + if (!audit_log_user_message_func) { + audit_send_user_message_func = dlsym(libaudit_handle, + "audit_send_user_message"); + } + if (!audit_open_func || !audit_close_func || + (!audit_log_user_message_func && !audit_send_user_message_func)) { + dlclose(libaudit_handle); + libaudit_handle = NULL; + audit_open_func = NULL; + audit_close_func = NULL; + audit_log_user_message_func = NULL; + audit_send_user_message_func = NULL; + } +} +#endif /* LINUX */ + /* * ******************** Password Utilities ******************************* */ static PRBool isLoggedIn = PR_FALSE; -static PRBool fatalError = PR_FALSE; +PRBool sftk_fatalError = PR_FALSE; /* * This function returns @@ -161,10 +223,10 @@ static CK_RV sftk_newPinCheck(CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { /* FIPS required checks before any useful cryptographic services */ static CK_RV sftk_fipsCheck(void) { - if (isLoggedIn != PR_TRUE) - return CKR_USER_NOT_LOGGED_IN; - if (fatalError) + if (sftk_fatalError) return CKR_DEVICE_ERROR; + if (!isLoggedIn) + return CKR_USER_NOT_LOGGED_IN; return CKR_OK; } @@ -174,7 +236,7 @@ static CK_RV sftk_fipsCheck(void) { if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; #define SFTK_FIPSFATALCHECK() \ - if (fatalError) return CKR_DEVICE_ERROR; + if (sftk_fatalError) return CKR_DEVICE_ERROR; /* grab an attribute out of a raw template */ @@ -233,24 +295,135 @@ static CK_FUNCTION_LIST sftk_fipsTable = { #undef __PASTE +/* CKO_NOT_A_KEY can be any object class that's not a key object. */ +#define CKO_NOT_A_KEY CKO_DATA + +#define SFTK_IS_KEY_OBJECT(objClass) \ + (((objClass) == CKO_PUBLIC_KEY) || \ + ((objClass) == CKO_PRIVATE_KEY) || \ + ((objClass) == CKO_SECRET_KEY)) + +#define SFTK_IS_NONPUBLIC_KEY_OBJECT(objClass) \ + (((objClass) == CKO_PRIVATE_KEY) || ((objClass) == CKO_SECRET_KEY)) + static CK_RV -fips_login_if_key_object(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) +sftk_get_object_class_and_fipsCheck(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_OBJECT_CLASS *pObjClass) { CK_RV rv; - CK_OBJECT_CLASS objClass; CK_ATTRIBUTE class; class.type = CKA_CLASS; - class.pValue = &objClass; - class.ulValueLen = sizeof(objClass); + class.pValue = pObjClass; + class.ulValueLen = sizeof(*pObjClass); rv = NSC_GetAttributeValue(hSession, hObject, &class, 1); - if (rv == CKR_OK) { - if ((objClass == CKO_PRIVATE_KEY) || (objClass == CKO_SECRET_KEY)) { - rv = sftk_fipsCheck(); - } + if ((rv == CKR_OK) && SFTK_IS_NONPUBLIC_KEY_OBJECT(*pObjClass)) { + rv = sftk_fipsCheck(); } return rv; } +/********************************************************************** + * + * FIPS 140 auditable event logging + * + **********************************************************************/ + +PRBool sftk_audit_enabled = PR_FALSE; + +/* + * Each audit record must have the following information: + * - Date and time of the event + * - Type of event + * - user (subject) identity + * - outcome (success or failure) of the event + * - process ID + * - name (ID) of the object + * - for changes to data (except for authentication data and CSPs), the new + * and old values of the data + * - for authentication attempts, the origin of the attempt (e.g., terminal + * identifier) + * - for assuming a role, the type of role, and the location of the request + */ +void +sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg) +{ +#ifdef NSS_AUDIT_WITH_SYSLOG + int level; + + switch (severity) { + case NSS_AUDIT_ERROR: + level = LOG_ERR; + break; + case NSS_AUDIT_WARNING: + level = LOG_WARNING; + break; + default: + level = LOG_INFO; + break; + } + /* timestamp is provided by syslog in the message header */ + syslog(level | LOG_USER /* facility */, + "NSS " SOFTOKEN_LIB_NAME "[pid=%d uid=%d]: %s", + (int)getpid(), (int)getuid(), msg); +#ifdef LINUX + if (pthread_once(&libaudit_once_control, libaudit_init) != 0) { + return; + } + if (libaudit_handle) { + int audit_fd; + int result = (severity != NSS_AUDIT_ERROR); /* 1=success; 0=failed */ + char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); + if (!message) { + return; + } + audit_fd = audit_open_func(); + if (audit_fd < 0) { + PR_smprintf_free(message); + return; + } + if (audit_log_user_message_func) { + audit_log_user_message_func(audit_fd, AUDIT_USER, message, + NULL, NULL, NULL, result); + } else { + audit_send_user_message_func(audit_fd, AUDIT_USER, message); + } + audit_close_func(audit_fd); + PR_smprintf_free(message); + } +#endif /* LINUX */ +#ifdef SOLARIS + { + int rd; + char *message = PR_smprintf("NSS " SOFTOKEN_LIB_NAME ": %s", msg); + + if (!message) { + return; + } + + /* open the record descriptor */ + if ((rd = au_open()) == -1) { + PR_smprintf_free(message); + return; + } + + /* write the audit tokens to the audit record */ + if (au_write(rd, au_to_text(message))) { + (void)au_close(rd, AU_TO_NO_WRITE, AUE_FIPS_AUDIT); + PR_smprintf_free(message); + return; + } + + /* close the record and send it to the audit trail */ + (void)au_close(rd, AU_TO_WRITE, AUE_FIPS_AUDIT); + + PR_smprintf_free(message); + } +#endif /* SOLARIS */ +#else + /* do nothing */ +#endif +} + /********************************************************************** * @@ -268,26 +441,39 @@ PRBool nsf_init = PR_FALSE; /* FC_Initialize initializes the PKCS #11 library. */ CK_RV FC_Initialize(CK_VOID_PTR pReserved) { + const char *envp; CK_RV crv; if (nsf_init) { return CKR_CRYPTOKI_ALREADY_INITIALIZED; } + if ((envp = PR_GetEnv("NSS_ENABLE_AUDIT")) != NULL) { + sftk_audit_enabled = (atoi(envp) == 1); + } + crv = nsc_CommonInitialize(pReserved, PR_TRUE); /* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/ if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; return crv; } - fatalError = PR_FALSE; /* any error has been reset */ + sftk_fatalError = PR_FALSE; /* any error has been reset */ crv = sftk_fipsPowerUpSelfTest(); if (crv != CKR_OK) { nsc_CommonFinalize(NULL, PR_TRUE); - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_Initialize()=0x%08lX " + "power-up self-tests failed", + (PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } return crv; } nsf_init = PR_TRUE; @@ -321,15 +507,7 @@ CK_RV FC_GetSlotList(CK_BBOOL tokenPresent, /* FC_GetSlotInfo obtains information about a particular slot in the system. */ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { - - CK_RV crv; - - crv = NSC_GetSlotInfo(slotID,pInfo); - if (crv != CKR_OK) { - return crv; - } - - return CKR_OK; + return NSC_GetSlotInfo(slotID,pInfo); } @@ -338,7 +516,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV crv; crv = NSC_GetTokenInfo(slotID,pInfo); - pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED; + if (crv == CKR_OK) + pInfo->flags |= CKF_LOGIN_REQUIRED; return crv; } @@ -369,7 +548,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_InitToken initializes a token. */ CK_RV FC_InitToken(CK_SLOT_ID slotID,CK_CHAR_PTR pPin, CK_ULONG usPinLen,CK_CHAR_PTR pLabel) { - return NSC_InitToken(slotID,pPin,usPinLen,pLabel); + CK_RV crv; + + crv = NSC_InitToken(slotID,pPin,usPinLen,pLabel); + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (crv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + /* pLabel points to a 32-byte label, which is not null-terminated */ + PR_snprintf(msg,sizeof msg, + "C_InitToken(slotID=%lu, pLabel=\"%.32s\")=0x%08lX", + (PRUint32)slotID,pLabel,(PRUint32)crv); + sftk_LogAuditMessage(severity, msg); + } + return crv; } @@ -377,9 +569,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_InitPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pPin, CK_ULONG ulPinLen) { CK_RV rv; - SFTK_FIPSFATALCHECK(); - if ((rv = sftk_newPinCheck(pPin,ulPinLen)) != CKR_OK) return rv; - return NSC_InitPIN(hSession,pPin,ulPinLen); + if (sftk_fatalError) return CKR_DEVICE_ERROR; + if ((rv = sftk_newPinCheck(pPin,ulPinLen)) == CKR_OK) { + rv = NSC_InitPIN(hSession,pPin,ulPinLen); + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_InitPIN(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } + return rv; } @@ -388,9 +591,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, CK_ULONG usOldLen, CK_CHAR_PTR pNewPin, CK_ULONG usNewLen) { CK_RV rv; - if ((rv = sftk_fipsCheck()) != CKR_OK) return rv; - if ((rv = sftk_newPinCheck(pNewPin,usNewLen)) != CKR_OK) return rv; - return NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); + if ((rv = sftk_fipsCheck()) == CKR_OK && + (rv = sftk_newPinCheck(pNewPin,usNewLen)) == CKR_OK) { + rv = NSC_SetPIN(hSession,pOldPin,usOldLen,pNewPin,usNewLen); + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_SetPIN(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } + return rv; } /* FC_OpenSession opens a session between an application and a token. */ @@ -435,30 +649,40 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_CHAR_PTR pPin, CK_ULONG usPinLen) { CK_RV rv; - SFTK_FIPSFATALCHECK(); + PRBool successful; + if (sftk_fatalError) return CKR_DEVICE_ERROR; rv = NSC_Login(hSession,userType,pPin,usPinLen); - if (rv == CKR_OK) + successful = (rv == CKR_OK) || (rv == CKR_USER_ALREADY_LOGGED_IN); + if (successful) isLoggedIn = PR_TRUE; - else if (rv == CKR_USER_ALREADY_LOGGED_IN) - { - isLoggedIn = PR_TRUE; - - /* Provide FIPS PUB 140-1 power-up self-tests on demand. */ - rv = sftk_fipsPowerUpSelfTest(); - if (rv == CKR_OK) - return CKR_USER_ALREADY_LOGGED_IN; - else - fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity; + severity = successful ? NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_Login(hSession=0x%08lX, userType=%lu)=0x%08lX", + (PRUint32)hSession,(PRUint32)userType,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); } return rv; } /* FC_Logout logs a user out from a token. */ CK_RV FC_Logout(CK_SESSION_HANDLE hSession) { - SFTK_FIPSCHECK(); - - rv = NSC_Logout(hSession); - isLoggedIn = PR_FALSE; + CK_RV rv; + if ((rv = sftk_fipsCheck()) == CKR_OK) { + rv = NSC_Logout(hSession); + isLoggedIn = PR_FALSE; + } + if (sftk_audit_enabled) { + char msg[128]; + NSSAuditSeverity severity = (rv == CKR_OK) ? + NSS_AUDIT_INFO : NSS_AUDIT_ERROR; + PR_snprintf(msg,sizeof msg, + "C_Logout(hSession=0x%08lX)=0x%08lX", + (PRUint32)hSession,(PRUint32)rv); + sftk_LogAuditMessage(severity, msg); + } return rv; } @@ -473,10 +697,15 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { if (classptr == NULL) return CKR_TEMPLATE_INCOMPLETE; /* FIPS can't create keys from raw key material */ - if ((*classptr == CKO_SECRET_KEY) || (*classptr == CKO_PRIVATE_KEY)) { - return CKR_ATTRIBUTE_VALUE_INVALID; + if (SFTK_IS_NONPUBLIC_KEY_OBJECT(*classptr)) { + rv = CKR_ATTRIBUTE_VALUE_INVALID; + } else { + rv = NSC_CreateObject(hSession,pTemplate,ulCount,phObject); } - return NSC_CreateObject(hSession,pTemplate,ulCount,phObject); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(*classptr)) { + sftk_AuditCreateObject(hSession,pTemplate,ulCount,phObject,rv); + } + return rv; } @@ -485,15 +714,20 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_CopyObject copies an object, creating a new object for the copy. */ CK_RV FC_CopyObject(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phNewObject) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_CopyObject(hSession,hObject,pTemplate,ulCount,phNewObject); } - return NSC_CopyObject(hSession,hObject,pTemplate,usCount,phNewObject); + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditCopyObject(hSession, + hObject,pTemplate,ulCount,phNewObject,rv); + } + return rv; } @@ -501,51 +735,67 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_DestroyObject(hSession,hObject); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditDestroyObject(hSession,hObject,rv); } - return NSC_DestroyObject(hSession,hObject); + return rv; } /* FC_GetObjectSize gets the size of an object in bytes. */ CK_RV FC_GetObjectSize(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pusSize) { + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_GetObjectSize(hSession, hObject, pulSize); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditGetObjectSize(hSession, hObject, pulSize, rv); } - return NSC_GetObjectSize(hSession, hObject, pusSize); + return rv; } /* FC_GetAttributeValue obtains the value of one or more object attributes. */ CK_RV FC_GetAttributeValue(CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_GetAttributeValue(hSession,hObject,pTemplate,ulCount); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditGetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); } - return NSC_GetAttributeValue(hSession,hObject,pTemplate,usCount); + return rv; } /* FC_SetAttributeValue modifies the value of one or more object attributes */ CK_RV FC_SetAttributeValue (CK_SESSION_HANDLE hSession, - CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG usCount) { + CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount) { CK_RV rv; + CK_OBJECT_CLASS objClass = CKO_NOT_A_KEY; SFTK_FIPSFATALCHECK(); - rv = fips_login_if_key_object(hSession, hObject); - if (rv != CKR_OK) { - return rv; + rv = sftk_get_object_class_and_fipsCheck(hSession, hObject, &objClass); + if (rv == CKR_OK) { + rv = NSC_SetAttributeValue(hSession,hObject,pTemplate,ulCount); + } + if (sftk_audit_enabled && SFTK_IS_KEY_OBJECT(objClass)) { + sftk_AuditSetAttributeValue(hSession,hObject,pTemplate,ulCount,rv); } - return NSC_SetAttributeValue(hSession,hObject,pTemplate,usCount); + return rv; } @@ -605,7 +855,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_EncryptInit(hSession,pMechanism,hKey); + rv = NSC_EncryptInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Encrypt",hSession,pMechanism,hKey,rv); + } + return rv; } /* FC_Encrypt encrypts single-part data. */ @@ -646,7 +900,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_DecryptInit( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DecryptInit(hSession,pMechanism,hKey); + rv = NSC_DecryptInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Decrypt",hSession,pMechanism,hKey,rv); + } + return rv; } /* FC_Decrypt decrypts encrypted data in a single part. */ @@ -724,7 +982,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignInit(hSession,pMechanism,hKey); + rv = NSC_SignInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Sign",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -766,7 +1028,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_SignRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_SignRecoverInit(hSession,pMechanism,hKey); + rv = NSC_SignRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("SignRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -789,7 +1055,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyInit(hSession,pMechanism,hKey); + rv = NSC_VerifyInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("Verify",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -832,7 +1102,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_VerifyRecoverInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + rv = NSC_VerifyRecoverInit(hSession,pMechanism,hKey); + if (sftk_audit_enabled) { + sftk_AuditCryptInit("VerifyRecover",hSession,pMechanism,hKey,rv); + } + return rv; } @@ -868,7 +1142,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { } } - return NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + rv = NSC_GenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey); + if (sftk_audit_enabled) { + sftk_AuditGenerateKey(hSession,pMechanism,pTemplate,ulCount,phKey,rv); + } + return rv; } @@ -898,7 +1176,12 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { usPrivateKeyAttributeCount,phPublicKey,phPrivateKey); if (crv == CKR_GENERAL_ERROR) { /* pairwise consistency check failed. */ - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + } + if (sftk_audit_enabled) { + sftk_AuditGenerateKeyPair(hSession,pMechanism,pPublicKeyTemplate, + usPublicKeyAttributeCount,pPrivateKeyTemplate, + usPrivateKeyAttributeCount,phPublicKey,phPrivateKey,crv); } return crv; } @@ -908,18 +1191,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { CK_RV FC_WrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, - CK_ULONG_PTR pusWrappedKeyLen) { + CK_ULONG_PTR pulWrappedKeyLen) { SFTK_FIPSCHECK(); - return NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, - pusWrappedKeyLen); + rv = NSC_WrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, + pulWrappedKeyLen); + if (sftk_audit_enabled) { + sftk_AuditWrapKey(hSession,pMechanism,hWrappingKey,hKey,pWrappedKey, + pulWrappedKeyLen,rv); + } + return rv; } /* FC_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */ CK_RV FC_UnwrapKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, - CK_BYTE_PTR pWrappedKey, CK_ULONG usWrappedKeyLen, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -928,21 +1216,26 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, - usWrappedKeyLen,pTemplate,usAttributeCount,phKey); + rv = NSC_UnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey); + if (sftk_audit_enabled) { + sftk_AuditUnwrapKey(hSession,pMechanism,hUnwrappingKey,pWrappedKey, + ulWrappedKeyLen,pTemplate,ulAttributeCount,phKey,rv); + } + return rv; } /* FC_DeriveKey derives a key from a base key, creating a new key object. */ CK_RV FC_DeriveKey( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, - CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usAttributeCount, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) { CK_BBOOL *boolptr; @@ -951,14 +1244,19 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* all secret keys must be sensitive, if the upper level code tries to say * otherwise, reject it. */ boolptr = (CK_BBOOL *) fc_getAttribute(pTemplate, - usAttributeCount, CKA_SENSITIVE); + ulAttributeCount, CKA_SENSITIVE); if (boolptr != NULL) { if (!(*boolptr)) { return CKR_ATTRIBUTE_VALUE_INVALID; } } - return NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, - usAttributeCount, phKey); + rv = NSC_DeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount, phKey); + if (sftk_audit_enabled) { + sftk_AuditDeriveKey(hSession,pMechanism,hBaseKey,pTemplate, + ulAttributeCount,phKey,rv); + } + return rv; } /* @@ -974,7 +1272,7 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { SFTK_FIPSFATALCHECK(); crv = NSC_SeedRandom(hSession,pSeed,usSeedLen); if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; } return crv; } @@ -982,13 +1280,23 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { /* FC_GenerateRandom generates random data. */ CK_RV FC_GenerateRandom(CK_SESSION_HANDLE hSession, - CK_BYTE_PTR pRandomData, CK_ULONG usRandomLen) { + CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen) { CK_RV crv; SFTK_FIPSFATALCHECK(); - crv = NSC_GenerateRandom(hSession,pRandomData,usRandomLen); + crv = NSC_GenerateRandom(hSession,pRandomData,ulRandomLen); if (crv != CKR_OK) { - fatalError = PR_TRUE; + sftk_fatalError = PR_TRUE; + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_GenerateRandom(hSession=0x%08lX, pRandomData=%p, " + "ulRandomLen=%lu)=0x%08lX " + "self-test: continuous RNG test failed", + (PRUint32)hSession,pRandomData, + (PRUint32)ulRandomLen,(PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } } return crv; } @@ -1091,7 +1399,11 @@ CK_RV FC_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession, */ CK_RV FC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) { SFTK_FIPSCHECK(); - return NSC_DigestKey(hSession,hKey); + rv = NSC_DigestKey(hSession,hKey); + if (sftk_audit_enabled) { + sftk_AuditDigestKey(hSession,hKey,rv); + } + return rv; } diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c index 2f685a5a6..df17f7f4b 100644 --- a/security/nss/lib/softoken/keydb.c +++ b/security/nss/lib/softoken/keydb.c @@ -52,12 +52,8 @@ #include "nsslocks.h" #include "keydbi.h" +#include "softoken.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, - ECParams *params); -#endif /* * Record keys for keydb @@ -584,13 +580,18 @@ makeGlobalSalt(NSSLOWKEYDBHandle *handle) DBT saltData; unsigned char saltbuf[16]; int status; + SECStatus rv; saltKey.data = SALT_STRING; saltKey.size = sizeof(SALT_STRING) - 1; saltData.data = (void *)saltbuf; saltData.size = sizeof(saltbuf); - RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf)); + rv = RNG_GenerateGlobalRandomBytes(saltbuf, sizeof(saltbuf)); + if ( rv != SECSuccess ) { + sftk_fatalError = PR_TRUE; + return(rv); + } /* put global salt into the database now */ status = keydb_Put(handle, &saltKey, &saltData, 0); @@ -717,7 +718,6 @@ nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle) DBT key; DBT data; unsigned char version; - SECItem *rc4key = NULL; NSSLOWKEYDBKey *dbkey = NULL; NSSLOWKEYDBHandle *update = NULL; SECItem *oldSalt = NULL; @@ -886,10 +886,6 @@ done: nsslowkey_CloseKeyDB(update); - if ( rc4key ) { - SECITEM_FreeItem(rc4key, PR_TRUE); - } - if ( oldSalt ) { SECITEM_FreeItem(oldSalt, PR_TRUE); } @@ -942,7 +938,7 @@ openNewDB(const char *appName, const char *prefix, const char *dbname, * local database we can update from. */ if (appName) { - NSSLOWKEYDBHandle *updateHandle = nsslowkey_NewHandle(updatedb); + NSSLOWKEYDBHandle *updateHandle; updatedb = dbopen( dbname, NO_RDONLY, 0600, DB_HASH, 0 ); if (!updatedb) { goto noupdate; @@ -1429,50 +1425,6 @@ nsslowkey_DeriveKeyDBPassword(NSSLOWKEYDBHandle *keydb, char *pw) return nsslowkey_HashPassword(pw, keydb->global_salt); } -#if 0 -/* Appears obsolete - TNH */ -/* get the algorithm with which a private key - * is encrypted. - */ -SECOidTag -seckey_get_private_key_algorithm(NSSLOWKEYDBHandle *keydb, DBT *index) -{ - NSSLOWKEYDBKey *dbkey = NULL; - SECOidTag algorithm = SEC_OID_UNKNOWN; - NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL; - PLArenaPool *poolp = NULL; - SECStatus rv; - - poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if(poolp == NULL) - return (SECOidTag)SECFailure; /* TNH - this is bad */ - - dbkey = get_dbkey(keydb, index); - if(dbkey == NULL) - return (SECOidTag)SECFailure; - - epki = (NSSLOWKEYEncryptedPrivateKeyInfo *)PORT_ArenaZAlloc(poolp, - sizeof(NSSLOWKEYEncryptedPrivateKeyInfo)); - if(epki == NULL) - goto loser; - rv = SEC_ASN1DecodeItem(poolp, epki, - nsslowkey_EncryptedPrivateKeyInfoTemplate, &dbkey->derPK); - if(rv == SECFailure) - goto loser; - - algorithm = SECOID_GetAlgorithmTag(&epki->algorithm); - - /* let success fall through */ -loser: - if(poolp != NULL) - PORT_FreeArena(poolp, PR_TRUE);\ - if(dbkey != NULL) - sec_destroy_dbkey(dbkey); - - return algorithm; -} -#endif - /* * Derive an RC4 key from a password key and a salt. This * was the method to used to encrypt keys in the version 2? @@ -1531,11 +1483,12 @@ seckey_create_rc4_salt(void) if(salt->data != NULL) { salt->len = SALT_LENGTH; - RNG_GenerateGlobalRandomBytes(salt->data, salt->len); - rv = SECSuccess; + rv = RNG_GenerateGlobalRandomBytes(salt->data, salt->len); + if(rv != SECSuccess) + sftk_fatalError = PR_TRUE; } - if(rv == SECFailure) + if(rv != SECSuccess) { SECITEM_FreeItem(salt, PR_TRUE); salt = NULL; @@ -1816,7 +1769,7 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, { NSSLOWKEYDBKey *dbkey = NULL; NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL; - PLArenaPool *temparena = NULL, *permarena = NULL; + PLArenaPool *arena = NULL; SECItem *dummy = NULL; SECItem *salt = NULL; SECStatus rv = SECFailure; @@ -1825,14 +1778,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, (pk == NULL)) return SECFailure; - permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); - if(permarena == NULL) + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if(arena == NULL) return SECFailure; - dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(permarena, sizeof(NSSLOWKEYDBKey)); + dbkey = (NSSLOWKEYDBKey *)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYDBKey)); if(dbkey == NULL) goto loser; - dbkey->arena = permarena; + dbkey->arena = arena; dbkey->nickname = nickname; /* TNH - for RC4, the salt should be created here */ @@ -1840,15 +1793,14 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm, &salt); if(epki == NULL) goto loser; - temparena = epki->arena; if(salt != NULL) { - rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt); + rv = SECITEM_CopyItem(arena, &(dbkey->salt), salt); SECITEM_ZfreeItem(salt, PR_TRUE); } - dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki, + dummy = SEC_ASN1EncodeItem(arena, &(dbkey->derPK), epki, nsslowkey_EncryptedPrivateKeyInfoTemplate); if(dummy == NULL) rv = SECFailure; @@ -1857,11 +1809,10 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem, /* let success fall through */ loser: - if(rv != SECSuccess) - if(permarena != NULL) - PORT_FreeArena(permarena, PR_TRUE); - if(temparena != NULL) - PORT_FreeArena(temparena, PR_TRUE); + if(arena != NULL) + PORT_FreeArena(arena, PR_TRUE); + if(epki != NULL) + PORT_FreeArena(epki->arena, PR_TRUE); return rv; } @@ -2046,6 +1997,9 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki, rv = EC_FillParams(permarena, &pk->u.ec.ecParams.DEREncoding, &pk->u.ec.ecParams); + if (rv != SECSuccess) + goto loser; + /* * NOTE: Encoding of the publicValue is optional * so we need to be able to regenerate the publicValue diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c index cb048307d..008687e52 100644 --- a/security/nss/lib/softoken/lowcert.c +++ b/security/nss/lib/softoken/lowcert.c @@ -51,12 +51,8 @@ #include "secasn1.h" #include "secoid.h" #include "secerr.h" +#include "softoken.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, - ECParams *params); -#endif static const SEC_ASN1Template nsslowcert_SubjectPublicKeyInfoTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSLOWCERTSubjectPublicKeyInfo) }, diff --git a/security/nss/lib/softoken/lowkey.c b/security/nss/lib/softoken/lowkey.c index fb6e30fdc..9c984b4d3 100644 --- a/security/nss/lib/softoken/lowkey.c +++ b/security/nss/lib/softoken/lowkey.c @@ -295,7 +295,6 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) if (rv == SECSuccess) return pubk; } - nsslowkey_DestroyPublicKey (pubk); } else { PORT_SetError (SEC_ERROR_NO_MEMORY); } diff --git a/security/nss/lib/softoken/lowpbe.c b/security/nss/lib/softoken/lowpbe.c index 81a0cb06b..6b4605b4e 100644 --- a/security/nss/lib/softoken/lowpbe.c +++ b/security/nss/lib/softoken/lowpbe.c @@ -546,13 +546,15 @@ loser: PORT_FreeArena(arena, PR_TRUE); } - /* if i != c, then we didn't complete the loop above and must of failed - * somwhere along the way */ - if (i != c) { - SECITEM_ZfreeItem(A,PR_TRUE); - A = NULL; - } else { - A->len = bytesNeeded; + if (A) { + /* if i != c, then we didn't complete the loop above and must of failed + * somwhere along the way */ + if (i != c) { + SECITEM_ZfreeItem(A,PR_TRUE); + A = NULL; + } else { + A->len = bytesNeeded; + } } return A; @@ -634,7 +636,7 @@ nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PORT_Memcpy(key->data, hash->data, key->len); } - SECITEM_FreeItem(hash, PR_TRUE); + SECITEM_ZfreeItem(hash, PR_TRUE); return key; loser: @@ -822,7 +824,7 @@ void nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param) { if (pbe_param != NULL) { - PORT_FreeArena(pbe_param->poolp, PR_TRUE); + PORT_FreeArena(pbe_param->poolp, PR_FALSE); } } diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn index 52d1f75cd..983d66887 100644 --- a/security/nss/lib/softoken/manifest.mn +++ b/security/nss/lib/softoken/manifest.mn @@ -59,12 +59,18 @@ EXPORTS = \ PRIVATE_EXPORTS = \ pk11pars.h \ pkcs11ni.h \ + lowkeyi.h \ + lowkeyti.h \ + pcertt.h \ + softoken.h \ + softoknt.h \ $(NULL) CSRCS = \ dbinit.c \ dbmshim.c \ ecdecode.c \ + fipsaudt.c \ fipstest.c \ fipstokn.c \ keydb.c \ diff --git a/security/nss/lib/softoken/nss.h b/security/nss/lib/softoken/nss.h new file mode 100644 index 000000000..d0f72fb07 --- /dev/null +++ b/security/nss/lib/softoken/nss.h @@ -0,0 +1,253 @@ +/*********************************************************************** + * + * A copy of nss.h from NSS 3.11.4 for the directories that make up the + * NSS cryptographic module (lib/freebl and lib/softoken). + * + * When compiling in these directories, the compiler uses the local copy + * of nss.h, allowing the NSS cryptographic module to stay at version + * 3.11.4 (the version submitted to NIST for FIPS 140-2 validation). + * + * DO NOT CHANGE THIS FILE. + * + ***********************************************************************/ +/* + * NSS utility functions + * + * ***** 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 ***** */ +/* $Id$ */ + +#ifndef __nss_h_ +#define __nss_h_ + +#include "seccomon.h" + +SEC_BEGIN_PROTOS + +/* + * NSS's major version, minor version, patch level, and whether + * this is a beta release. + * + * The format of the version string should be + * "<major version>.<minor version>[.<patch level>] [<Beta>]" + */ +/* ***** DO NOT CHANGE THIS FILE. ***** */ +#ifdef NSS_ENABLE_ECC +#ifdef NSS_ECC_MORE_THAN_SUITE_B +#define NSS_VERSION "3.11.4 Extended ECC" +#else +#define NSS_VERSION "3.11.4 Basic ECC" +#endif +#else +#define NSS_VERSION "3.11.4" +#endif +#define NSS_VMAJOR 3 +#define NSS_VMINOR 11 +#define NSS_VPATCH 4 +#define NSS_BETA PR_FALSE + +/* + * Return a boolean that indicates whether the underlying library + * will perform as the caller expects. + * + * The only argument is a string, which should be the verson + * identifier of the NSS library. That string will be compared + * against a string that represents the actual build version of + * the NSS library. It also invokes the version checking functions + * of the dependent libraries such as NSPR. + */ +extern PRBool NSS_VersionCheck(const char *importedVersion); + +/* + * Open the Cert, Key, and Security Module databases, read only. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_Init(const char *configdir); + +/* + * Returns whether NSS has already been initialized or not. + */ +extern PRBool NSS_IsInitialized(void); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + */ +extern SECStatus NSS_InitReadWrite(const char *configdir); + +/* + * Open the Cert, Key, and Security Module databases, read/write. + * Initialize the Random Number Generator. + * Does not initialize the cipher policies or enables. + * Default policy settings disallow all ciphers. + * + * This allows using application defined prefixes for the cert and key db's + * and an alternate name for the secmod database. NOTE: In future releases, + * the database prefixes my not necessarily map to database names. + * + * configdir - base directory where all the cert, key, and module datbases live. + * certPrefix - prefix added to the beginning of the cert database example: " + * "https-server1-" + * keyPrefix - prefix added to the beginning of the key database example: " + * "https-server1-" + * secmodName - name of the security module database (usually "secmod.db"). + * flags - change the open options of NSS_Initialize as follows: + * NSS_INIT_READONLY - Open the databases read only. + * NSS_INIT_NOCERTDB - Don't open the cert DB and key DB's, just + * initialize the volatile certdb. + * NSS_INIT_NOMODDB - Don't open the security module DB, just + * initialize the PKCS #11 module. + * NSS_INIT_FORCEOPEN - Continue to force initializations even if the + * databases cannot be opened. + * NSS_INIT_NOROOTINIT - Don't try to look for the root certs module + * automatically. + * NSS_INIT_OPTIMIZESPACE - Use smaller tables and caches. + * NSS_INIT_PK11THREADSAFE - only load PKCS#11 modules that are + * thread-safe, ie. that support locking - either OS + * locking or NSS-provided locks . If a PKCS#11 + * module isn't thread-safe, don't serialize its + * calls; just don't load it instead. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example the Java SunPKCS11 provider. + * NSS_INIT_PK11RELOAD - ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED + * error when loading PKCS#11 modules. This is necessary + * if another piece of code is using the same PKCS#11 + * modules that NSS is accessing without going through + * NSS, for example Java SunPKCS11 provider. + * NSS_INIT_NOPK11FINALIZE - never call C_Finalize on any + * PKCS#11 module. This may be necessary in order to + * ensure continuous operation and proper shutdown + * sequence if another piece of code is using the same + * PKCS#11 modules that NSS is accessing without going + * through NSS, for example Java SunPKCS11 provider. + * The following limitation applies when this is set : + * SECMOD_WaitForAnyTokenEvent will not use + * C_WaitForSlotEvent, in order to prevent the need for + * C_Finalize. This call will be emulated instead. + * NSS_INIT_RESERVED - Currently has no effect, but may be used in the + * future to trigger better cooperation between PKCS#11 + * modules used by both NSS and the Java SunPKCS11 + * provider. This should occur after a new flag is defined + * for C_Initialize by the PKCS#11 working group. + * NSS_INIT_COOPERATE - Sets 4 recommended options for applications that + * use both NSS and the Java SunPKCS11 provider. + * + * Also NOTE: This is not the recommended method for initializing NSS. + * The prefered method is NSS_init(). + */ +#define NSS_INIT_READONLY 0x1 +#define NSS_INIT_NOCERTDB 0x2 +#define NSS_INIT_NOMODDB 0x4 +#define NSS_INIT_FORCEOPEN 0x8 +#define NSS_INIT_NOROOTINIT 0x10 +#define NSS_INIT_OPTIMIZESPACE 0x20 +#define NSS_INIT_PK11THREADSAFE 0x40 +#define NSS_INIT_PK11RELOAD 0x80 +#define NSS_INIT_NOPK11FINALIZE 0x100 +#define NSS_INIT_RESERVED 0x200 + +#define NSS_INIT_COOPERATE NSS_INIT_PK11THREADSAFE | \ + NSS_INIT_PK11RELOAD | \ + NSS_INIT_NOPK11FINALIZE | \ + NSS_INIT_RESERVED + +#ifdef macintosh +#define SECMOD_DB "Security Modules" +#else +#define SECMOD_DB "secmod.db" +#endif + +extern SECStatus NSS_Initialize(const char *configdir, + const char *certPrefix, const char *keyPrefix, + const char *secmodName, PRUint32 flags); + +/* + * initialize NSS without a creating cert db's, key db's, or secmod db's. + */ +SECStatus NSS_NoDB_Init(const char *configdir); + +/* + * Allow applications and libraries to register with NSS so that they are called + * when NSS shuts down. + * + * void *appData application specific data passed in by the application at + * NSS_RegisterShutdown() time. + * void *nssData is NULL in this release, but is reserved for future versions of + * NSS to pass some future status information * back to the shutdown function. + * + * If the shutdown function returns SECFailure, + * Shutdown will still complete, but NSS_Shutdown() will return SECFailure. + */ +typedef SECStatus (*NSS_ShutdownFunc)(void *appData, void *nssData); + +/* + * Register a shutdown function. + */ +SECStatus NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Remove an existing shutdown function (you may do this if your library is + * complete and going away, but NSS is still running). + */ +SECStatus NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData); + +/* + * Close the Cert, Key databases. + */ +extern SECStatus NSS_Shutdown(void); + +/* + * set the PKCS #11 strings for the internal token. + */ +void PK11_ConfigurePKCS11(const char *man, const char *libdes, + const char *tokdes, const char *ptokdes, const char *slotdes, + const char *pslotdes, const char *fslotdes, const char *fpslotdes, + int minPwd, int pwRequired); + +/* + * Dump the contents of the certificate cache and the temporary cert store. + * Use to detect leaked references of certs at shutdown time. + */ +void nss_DumpCertificateCacheInfo(void); + +SEC_END_PROTOS + +#endif /* __nss_h_ */ diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h index a808373d8..d4314f634 100644 --- a/security/nss/lib/softoken/pcert.h +++ b/security/nss/lib/softoken/pcert.h @@ -41,9 +41,16 @@ #include "prlong.h" #include "pcertt.h" +#include "lowkeyti.h" /* for struct NSSLOWKEYPublicKeyStr */ + SEC_BEGIN_PROTOS /* + * initialize any global certificate locks + */ +SECStatus nsslowcert_InitLocks(void); + +/* ** Add a DER encoded certificate to the permanent database. ** "derCert" is the DER encoded certificate. ** "nickname" is the nickname to use for the cert @@ -244,6 +251,11 @@ pkcs11_copyStaticData(unsigned char *data, int datalen, unsigned char *space, int spaceLen); NSSLOWCERTCertificate * nsslowcert_CreateCert(void); + +certDBEntry * +nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey, + certDBEntryType entryType, void *pdata); + SEC_END_PROTOS #endif /* _PCERTDB_H_ */ diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c index 4a7706378..3c9959a30 100644 --- a/security/nss/lib/softoken/pcertdb.c +++ b/security/nss/lib/softoken/pcertdb.c @@ -91,6 +91,9 @@ static int entryListCount = 0; * a global lock to make the database thread safe. */ static PZLock *dbLock = NULL; +static PZLock *certRefCountLock = NULL; +static PZLock *certTrustLock = NULL; +static PZLock *freeListLock = NULL; void certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle) @@ -99,8 +102,31 @@ certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle) nss_InitLock(&dbLock, nssILockCertDB); PORT_Assert(dbLock != NULL); } +} - return; +SECStatus +nsslowcert_InitLocks(void) +{ + if (freeListLock == NULL) { + nss_InitLock(&freeListLock, nssILockRefLock); + if (freeListLock == NULL) { + return SECFailure; + } + } + if (certRefCountLock == NULL) { + nss_InitLock(&certRefCountLock, nssILockRefLock); + if (certRefCountLock == NULL) { + return SECFailure; + } + } + if (certTrustLock == NULL ) { + nss_InitLock(&certTrustLock, nssILockCertDB); + if (certTrustLock == NULL) { + return SECFailure; + } + } + + return SECSuccess; } /* @@ -133,7 +159,6 @@ nsslowcert_UnlockDB(NSSLOWCERTCertDBHandle *handle) return; } -static PZLock *certRefCountLock = NULL; /* * Acquire the cert reference count lock @@ -144,10 +169,7 @@ static PZLock *certRefCountLock = NULL; static void nsslowcert_LockCertRefCount(NSSLOWCERTCertificate *cert) { - if ( certRefCountLock == NULL ) { - nss_InitLock(&certRefCountLock, nssILockRefLock); - PORT_Assert(certRefCountLock != NULL); - } + PORT_Assert(certRefCountLock != NULL); PZ_Lock(certRefCountLock); return; @@ -170,8 +192,6 @@ nsslowcert_UnlockCertRefCount(NSSLOWCERTCertificate *cert) return; } -static PZLock *certTrustLock = NULL; - /* * Acquire the cert trust lock * There is currently one global lock for all certs, but I'm putting a cert @@ -181,11 +201,8 @@ static PZLock *certTrustLock = NULL; void nsslowcert_LockCertTrust(NSSLOWCERTCertificate *cert) { - if ( certTrustLock == NULL ) { - nss_InitLock(&certTrustLock, nssILockCertDB); - PORT_Assert(certTrustLock != NULL); - } - + PORT_Assert(certTrustLock != NULL); + PZ_Lock(certTrustLock); return; } @@ -207,7 +224,6 @@ nsslowcert_UnlockCertTrust(NSSLOWCERTCertificate *cert) return; } -static PZLock *freeListLock = NULL; /* * Acquire the cert reference count lock @@ -218,10 +234,7 @@ static PZLock *freeListLock = NULL; static void nsslowcert_LockFreeList(void) { - if ( freeListLock == NULL ) { - nss_InitLock(&freeListLock, nssILockRefLock); - PORT_Assert(freeListLock != NULL); - } + PORT_Assert(freeListLock != NULL); PZ_Lock(freeListLock); return; @@ -825,8 +838,7 @@ NewDBCertEntry(SECItem *derCert, char *nickname, goto loser; } - entry = (certDBEntryCert *)PORT_ArenaZAlloc(arena, sizeof(certDBEntryCert)); - + entry = PORT_ArenaZNew(arena, certDBEntryCert); if ( entry == NULL ) { goto loser; } @@ -917,21 +929,6 @@ DecodeV4DBCertEntry(unsigned char *buf, int len) goto loser; } - entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); - if ( !entry->derCert.data ) { - goto loser; - } - entry->derCert.len = certlen; - - if ( nnlen ) { - entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); - if ( !entry->nickname ) { - goto loser; - } - } else { - entry->nickname = 0; - } - entry->common.arena = arena; entry->common.version = CERT_DB_FILE_VERSION; entry->common.type = certDBEntryTypeCert; @@ -940,11 +937,25 @@ DecodeV4DBCertEntry(unsigned char *buf, int len) entry->trust.emailFlags = buf[1]; entry->trust.objectSigningFlags = buf[2]; + entry->derCert.data = (unsigned char *)PORT_ArenaAlloc(arena, certlen); + if ( !entry->derCert.data ) { + goto loser; + } + entry->derCert.len = certlen; PORT_Memcpy(entry->derCert.data, &buf[DBCERT_V4_HEADER_LEN], certlen); - PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); - if (PORT_Strcmp(entry->nickname,"Server-Cert") == 0) { - entry->trust.sslFlags |= CERTDB_USER; + if ( nnlen ) { + entry->nickname = (char *) PORT_ArenaAlloc(arena, nnlen); + if ( !entry->nickname ) { + goto loser; + } + PORT_Memcpy(entry->nickname, &buf[DBCERT_V4_HEADER_LEN + certlen], nnlen); + + if (PORT_Strcmp(entry->nickname, "Server-Cert") == 0) { + entry->trust.sslFlags |= CERTDB_USER; + } + } else { + entry->nickname = 0; } return(entry); @@ -1056,7 +1067,7 @@ CreateCertEntry(void) return entry; } - return PORT_ZAlloc(sizeof(certDBEntryCert)); + return PORT_ZNew(certDBEntryCert); } static void @@ -1121,9 +1132,8 @@ loser: pkcs11_freeStaticData(dbkey.data,buf); dbkey.data = NULL; if ( entry ) { - + DestroyDBEntry((certDBEntry *)entry); } - DestroyDBEntry((certDBEntry *)entry); return(NULL); } @@ -1245,9 +1255,7 @@ NewDBCrlEntry(SECItem *derCrl, char * url, certDBEntryType crlType, int flags) goto loser; } - entry = (certDBEntryRevocation*) - PORT_ArenaZAlloc(arena, sizeof(certDBEntryRevocation)); - + entry = PORT_ArenaZNew(arena, certDBEntryRevocation); if ( entry == NULL ) { goto loser; } @@ -1457,7 +1465,6 @@ EncodeDBNicknameEntry(certDBEntryNickname *entry, PRArenaPool *arena, dbitem->data = (unsigned char *)PORT_ArenaAlloc(arena, dbitem->len); if ( dbitem->data == NULL) { - PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; } @@ -2706,36 +2713,37 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, entry = ReadDBSubjectEntry(dbhandle,derSubject); if (entry == NULL) { - goto loser; + rv = SECFailure; + goto done; } - if ( entry->emailAddrs ) { - for (i=0; i < (int)(entry->nemailAddrs); i++) { - if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) { - index = i; - } + for (i=0; i < (int)(entry->nemailAddrs); i++) { + if (PORT_Strcmp(entry->emailAddrs[i],emailAddr) == 0) { + index = i; } } - if (updateType == nsslowcert_remove) { if (index == -1) { - return SECSuccess; + rv = SECSuccess; + goto done; } - entry->nemailAddrs--; for (i=index; i < (int)(entry->nemailAddrs); i++) { entry->emailAddrs[i] = entry->emailAddrs[i+1]; } } else { char **newAddrs = NULL; + if (index != -1) { - return SECSuccess; + rv = SECSuccess; + goto done; } newAddrs = (char **)PORT_ArenaAlloc(entry->common.arena, (entry->nemailAddrs+1)* sizeof(char *)); if (!newAddrs) { - goto loser; + rv = SECFailure; + goto done; } for (i=0; i < (int)(entry->nemailAddrs); i++) { newAddrs[i] = entry->emailAddrs[i]; @@ -2743,7 +2751,8 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, newAddrs[entry->nemailAddrs] = PORT_ArenaStrdup(entry->common.arena,emailAddr); if (!newAddrs[entry->nemailAddrs]) { - goto loser; + rv = SECFailure; + goto done; } entry->emailAddrs = newAddrs; entry->nemailAddrs++; @@ -2754,18 +2763,11 @@ nsslowcert_UpdateSubjectEmailAddr(NSSLOWCERTCertDBHandle *dbhandle, /* write the new one */ rv = WriteDBSubjectEntry(dbhandle, entry); - if ( rv != SECSuccess ) { - goto loser; - } - - DestroyDBEntry((certDBEntry *)entry); - if (emailAddr) PORT_Free(emailAddr); - return(SECSuccess); -loser: + done: if (entry) DestroyDBEntry((certDBEntry *)entry); if (emailAddr) PORT_Free(emailAddr); - return(SECFailure); + return rv; } /* @@ -2794,8 +2796,7 @@ AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle, goto loser; } - entry->nickname = (nickname) ? - PORT_ArenaStrdup(entry->common.arena, nickname) : NULL; + entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname); if ( entry->nickname == NULL ) { goto loser; @@ -2876,8 +2877,7 @@ ReadDBVersionEntry(NSSLOWCERTCertDBHandle *handle) goto loser; } - entry = (certDBEntryVersion *)PORT_ArenaAlloc(arena, - sizeof(certDBEntryVersion)); + entry = PORT_ArenaZNew(arena, certDBEntryVersion); if ( entry == NULL ) { PORT_SetError(SEC_ERROR_NO_MEMORY); goto loser; @@ -3070,6 +3070,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, } if ( nsslowcert_IsNewer(cert, cmpcert) ) { + nsslowcert_DestroyCertificate(cmpcert); /* insert before cmpcert */ rv = SECITEM_CopyItem(entry->common.arena, &newCertKeys[new_i], &cert->certKey); @@ -3097,6 +3098,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert, added = PR_TRUE; break; } + nsslowcert_DestroyCertificate(cmpcert); /* copy this cert entry */ newCertKeys[new_i] = entry->certKeys[i]; newKeyIDs[new_i] = entry->keyIDs[i]; @@ -3849,6 +3851,8 @@ UpdateV5DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb) updatehandle.permCertDB = updatedb; updatehandle.dbMon = PZ_NewMonitor(nssILockCertDB); + updatehandle.dbVerify = 0; + updatehandle.ref = 1; /* prevent premature close */ rv = nsslowcert_TraversePermCerts(&updatehandle, updateV5Callback, (void *)handle); @@ -4298,7 +4302,8 @@ nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle, keybuf = (unsigned char *)key.data; keyitem.data = &keybuf[SEC_DB_KEY_HEADER_LEN]; keyitem.type = siBuffer; - + /* type should equal keybuf[0]. */ + rv = (* callback)(&dataitem, &keyitem, type, udata); if ( rv != SECSuccess ) { return(rv); @@ -4352,7 +4357,7 @@ CreateTrust(void) return trust; } - return PORT_ZAlloc(sizeof(NSSLOWCERTTrust)); + return PORT_ZNew(NSSLOWCERTTrust); } static void @@ -5079,7 +5084,7 @@ nsslowcert_CreateCert(void) if (cert) { return cert; } - return (NSSLOWCERTCertificate *) PORT_ZAlloc(sizeof(NSSLOWCERTCertificate)); + return PORT_ZNew(NSSLOWCERTCertificate); } static void @@ -5106,6 +5111,9 @@ nsslowcert_DestroyTrust(NSSLOWCERTTrust *trust) if ( entry ) { DestroyDBEntry((certDBEntry *)entry); } + if (trust->dbhandle) { + sftk_freeCertDB(trust->dbhandle); + } pkcs11_freeStaticData(trust->dbKey.data,trust->dbKeySpace); PORT_Memset(trust, 0, sizeof(*trust)); @@ -5338,9 +5346,6 @@ nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr, return(rv); } -/* If the freeListLock doesn't exist when this function is called, -** this function will create it, use it 3 times, and delete it. -*/ void nsslowcert_DestroyFreeLists(void) { @@ -5368,3 +5373,77 @@ nsslowcert_DestroyGlobalLocks(void) } } +certDBEntry * +nsslowcert_DecodeAnyDBEntry(SECItem *dbData, SECItem *dbKey, + certDBEntryType entryType, void *pdata) +{ + PLArenaPool *arena = NULL; + certDBEntry *entry; + SECStatus rv; + SECItem dbEntry; + + + if ((dbData->len < SEC_DB_ENTRY_HEADER_LEN) || (dbKey->len == 0)) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + goto loser; + } + dbEntry.data = &dbData->data[SEC_DB_ENTRY_HEADER_LEN]; + dbEntry.len = dbData->len - SEC_DB_ENTRY_HEADER_LEN; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) { + goto loser; + } + entry = PORT_ArenaZNew(arena, certDBEntry); + if (!entry) + goto loser; + + entry->common.version = (unsigned int)dbData->data[0]; + entry->common.flags = (unsigned int)dbData->data[2]; + entry->common.type = entryType; + entry->common.arena = arena; + + switch (entryType) { + case certDBEntryTypeContentVersion: /* This type appears to be unused */ + case certDBEntryTypeVersion: /* This type has only the common hdr */ + rv = SECSuccess; + break; + + case certDBEntryTypeSubject: + rv = DecodeDBSubjectEntry(&entry->subject, &dbEntry, dbKey); + break; + + case certDBEntryTypeNickname: + rv = DecodeDBNicknameEntry(&entry->nickname, &dbEntry, + (char *)dbKey->data); + break; + + /* smime profiles need entries created after the certs have + * been imported, loop over them in a second run */ + case certDBEntryTypeSMimeProfile: + rv = DecodeDBSMimeEntry(&entry->smime, &dbEntry, (char *)dbKey->data); + break; + + case certDBEntryTypeCert: + rv = DecodeDBCertEntry(&entry->cert, &dbEntry); + break; + + case certDBEntryTypeKeyRevocation: + case certDBEntryTypeRevocation: + rv = DecodeDBCrlEntry(&entry->revocation, &dbEntry); + break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } + + if (rv == SECSuccess) + return entry; + +loser: + if (arena) + PORT_FreeArena(arena, PR_FALSE); + return NULL; +} + diff --git a/security/nss/lib/softoken/pcertt.h b/security/nss/lib/softoken/pcertt.h index e805950e1..848fe69e9 100644 --- a/security/nss/lib/softoken/pcertt.h +++ b/security/nss/lib/softoken/pcertt.h @@ -410,12 +410,14 @@ typedef struct { #define SEC_DB_CONTENT_VERSION_KEY_LEN sizeof(SEC_DB_CONTENT_VERSION_KEY) typedef union { - certDBEntryCommon common; - certDBEntryVersion version; - certDBEntryCert cert; - certDBEntryNickname nickname; - certDBEntrySubject subject; - certDBEntryRevocation revocation; + certDBEntryCommon common; + certDBEntryCert cert; + certDBEntryContentVersion content; + certDBEntryNickname nickname; + certDBEntryRevocation revocation; + certDBEntrySMime smime; + certDBEntrySubject subject; + certDBEntryVersion version; } certDBEntry; /* length of the fixed part of a database entry */ diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c index c60e87780..30584c91e 100644 --- a/security/nss/lib/softoken/pk11db.c +++ b/security/nss/lib/softoken/pk11db.c @@ -868,7 +868,7 @@ secmod_ReadPermDB(const char *appName, const char *filename, DBT key,data; int ret; DB *pkcs11db = NULL; - char **moduleList = NULL; + char **moduleList = NULL, **newModuleList = NULL; int moduleCount = 1; int useCount = SECMOD_STEP; @@ -888,9 +888,10 @@ secmod_ReadPermDB(const char *appName, const char *filename, PRBool internal = PR_FALSE; if ((moduleCount+1) >= useCount) { useCount += SECMOD_STEP; - moduleList = + newModuleList = (char **)PORT_Realloc(moduleList,useCount*sizeof(char *)); - if (moduleList == NULL) goto done; + if (newModuleList == NULL) goto done; + moduleList = newModuleList; PORT_Memset(&moduleList[moduleCount+1],0, sizeof(char *)*SECMOD_STEP); } diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 10a7bcfb7..f913735a4 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -67,9 +67,8 @@ #include "keydbi.h" -#ifdef NSS_ENABLE_ECC -extern SECStatus EC_FillParams(PRArenaPool *arena, - const SECItem *encodedParams, ECParams *params); +#ifdef DEBUG +#include "cdbhdl.h" #endif /* @@ -77,7 +76,7 @@ extern SECStatus EC_FillParams(PRArenaPool *arena, */ /* The next three strings must be exactly 32 characters long */ -static char *manufacturerID = "mozilla.org "; +static char *manufacturerID = "Mozilla Foundation "; static char manufacturerID_space[33]; static char *libraryDescription = "NSS Internal Crypto Services "; static char libraryDescription_space[33]; @@ -1228,6 +1227,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE { CK_BBOOL cktrue = CK_TRUE; CK_BBOOL encrypt = CK_TRUE; + CK_BBOOL sign = CK_FALSE; CK_BBOOL recover = CK_TRUE; CK_BBOOL wrap = CK_TRUE; CK_BBOOL derive = CK_FALSE; @@ -1268,15 +1268,18 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE sftk_item_expand(&mod)); if (mod.data) PORT_Free(mod.data); if (crv != CKR_OK) return crv; - + + sign = CK_TRUE; break; case CKK_DSA: if ( !sftk_hasAttribute(object, CKA_SUBPRIME)) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { + if (sftk_isTrue(object,CKA_TOKEN) && + !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { return CKR_TEMPLATE_INCOMPLETE; } + sign = CK_TRUE; /* fall through */ case CKK_DH: if ( !sftk_hasAttribute(object, CKA_PRIME)) { @@ -1300,10 +1303,12 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE if ( !sftk_hasAttribute(object, CKA_VALUE)) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { + if (sftk_isTrue(object,CKA_TOKEN) && + !sftk_hasAttribute(object, CKA_NETSCAPE_DB)) { return CKR_TEMPLATE_INCOMPLETE; } encrypt = CK_FALSE; + sign = CK_TRUE; recover = CK_FALSE; wrap = CK_FALSE; derive = CK_TRUE; @@ -1320,7 +1325,7 @@ sftk_handlePrivateKeyObject(SFTKSession *session,SFTKObject *object,CK_KEY_TYPE if (crv != CKR_OK) return crv; crv = sftk_defaultAttribute(object,CKA_DECRYPT,&encrypt,sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; - crv = sftk_defaultAttribute(object,CKA_SIGN,&cktrue,sizeof(CK_BBOOL)); + crv = sftk_defaultAttribute(object,CKA_SIGN,&sign,sizeof(CK_BBOOL)); if (crv != CKR_OK) return crv; crv = sftk_defaultAttribute(object,CKA_SIGN_RECOVER,&recover, sizeof(CK_BBOOL)); @@ -1532,6 +1537,9 @@ sftk_GenerateSecretCKA_ID(NSSLOWKEYDBHandle *handle, SECItem *id, char *label) (++retries <= SFTK_KEY_MAX_RETRIES)); if ((rv != SECSuccess) || (retries > SFTK_KEY_MAX_RETRIES)) { + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; /* random number generator is bad */ PORT_Free(id->data); id->data = NULL; @@ -1644,6 +1652,9 @@ sftk_handleKeyObject(SFTKSession *session, SFTKObject *object) /* get the key type */ attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); + if (!attribute) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; sftk_FreeAttribute(attribute); @@ -1750,6 +1761,9 @@ sftk_handleKeyParameterObject(SFTKSession *session, SFTKObject *object) /* get the key type */ attribute = sftk_FindAttribute(object,CKA_KEY_TYPE); + if (!attribute) { + return CKR_ATTRIBUTE_VALUE_INVALID; + } key_type = *(CK_KEY_TYPE *)attribute->attrib.pValue; sftk_FreeAttribute(attribute); @@ -1952,7 +1966,10 @@ NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object,CK_KEY_TYPE key_type, * based on the encoded params */ if (EC_FillParams(arena, &pubKey->u.ec.ecParams.DEREncoding, - &pubKey->u.ec.ecParams) != SECSuccess) break; + &pubKey->u.ec.ecParams) != SECSuccess) { + crv = CKR_DOMAIN_PARAMS_INVALID; + break; + } crv = sftk_Attribute2SSecItem(arena,&pubKey->u.ec.publicValue, object,CKA_EC_POINT); @@ -2045,9 +2062,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&privKey->u.dsa.publicValue, - object,CKA_NETSCAPE_DB); - /* can't set the public value.... */ + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.dsa.publicValue, + object,CKA_NETSCAPE_DB); + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } break; case CKK_DH: @@ -2061,8 +2081,12 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena,&privKey->u.dh.publicValue, - object,CKA_NETSCAPE_DB); + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.dh.publicValue, + object,CKA_NETSCAPE_DB); + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } break; #ifdef NSS_ENABLE_ECC @@ -2077,13 +2101,20 @@ sftk_mkPrivKey(SFTKObject *object, CK_KEY_TYPE key_type, CK_RV *crvp) * based on the encoded params */ if (EC_FillParams(arena, &privKey->u.ec.ecParams.DEREncoding, - &privKey->u.ec.ecParams) != SECSuccess) break; + &privKey->u.ec.ecParams) != SECSuccess) { + crv = CKR_DOMAIN_PARAMS_INVALID; + break; + } crv = sftk_Attribute2SSecItem(arena,&privKey->u.ec.privateValue, object,CKA_VALUE); if (crv != CKR_OK) break; - crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue, + if (sftk_hasAttribute(object,CKA_NETSCAPE_DB)) { + crv = sftk_Attribute2SSecItem(arena, &privKey->u.ec.publicValue, object,CKA_NETSCAPE_DB); - if (crv != CKR_OK) break; + if (crv != CKR_OK) break; + /* privKey was zero'd so public value is already set to NULL, 0 + * if we don't set it explicitly */ + } rv = DER_SetUInteger(privKey->arena, &privKey->u.ec.version, NSSLOWKEY_EC_PRIVATE_KEY_VERSION); if (rv != SECSuccess) crv = CKR_HOST_MEMORY; @@ -2333,7 +2364,7 @@ sftk_getDefTokName(CK_SLOT_ID slotID) case PRIVATE_KEY_SLOT_ID: return "NSS Certificate DB "; case FIPS_SLOT_ID: - return "NSS FIPS-140-1 Certificate DB "; + return "NSS FIPS 140-2 Certificate DB "; default: break; } @@ -2355,7 +2386,7 @@ sftk_getDefSlotName(CK_SLOT_ID slotID) "NSS User Private Key and Certificate Services "; case FIPS_SLOT_ID: return - "Netscape FIPS-140-1 User Private Key Services "; + "NSS FIPS 140-2 User Private Key Services "; default: break; } @@ -2388,6 +2419,8 @@ sftk_SlotFromID(CK_SLOT_ID slotID, PRBool all) { SFTKSlot *slot; int index = sftk_GetModuleIndex(slotID); + + if (nscSlotHashTable[index] == NULL) return NULL; slot = (SFTKSlot *)PL_HashTableLookupConst(nscSlotHashTable[index], (void *)slotID); /* cleared slots shouldn't 'show up' */ @@ -2756,9 +2789,11 @@ sftk_DBShutdown(SFTKSlot *slot) slot->keyDB = NULL; PZ_Unlock(slot->slotLock); if (certHandle) { + PORT_Assert(certHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID); sftk_freeCertDB(certHandle); } if (keyHandle) { + PORT_Assert(keyHandle->ref == 1 || slot->slotID > FIPS_SLOT_ID); sftk_freeKeyDB(keyHandle); } } @@ -2953,13 +2988,6 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) if (isFIPS) { - /* make sure that our check file signatures are OK */ - if (!BLAPI_VerifySelf(NULL) || - !BLAPI_SHVerify(SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_closePeer)) { - crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */ - return crv; - } - loginWaitTime = PR_SecondsToInterval(1); } @@ -2976,6 +3004,12 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) } RNG_SystemInfoForRNG(); + rv = nsslowcert_InitLocks(); + if (rv != SECSuccess) { + crv = CKR_DEVICE_ERROR; + return crv; + } + /* NOTE: * we should be getting out mutexes from this list, not statically binding @@ -3022,6 +3056,13 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS) * don't clobber each other. */ if ((isFIPS && nsc_init) || (!isFIPS && nsf_init)) { sftk_closePeer(isFIPS); + if (sftk_audit_enabled) { + if (isFIPS && nsc_init) { + sftk_LogAuditMessage(NSS_AUDIT_INFO, "enabled FIPS mode"); + } else { + sftk_LogAuditMessage(NSS_AUDIT_INFO, "disabled FIPS mode"); + } + } } for (i=0; i < paramStrings.token_count; i++) { @@ -3076,21 +3117,13 @@ CK_RV nsc_CommonFinalize (CK_VOID_PTR pReserved, PRBool isFIPS) nsslowcert_DestroyFreeLists(); nsslowcert_DestroyGlobalLocks(); -#ifdef LEAK_TEST - /* - * do we really want to throw away all our hard earned entropy here!!? - * No we don't! Not calling RNG_RNGShutdown only 'leaks' data on the - * initial call to RNG_Init(). So the only reason to call this is to clean - * up leak detection warnings on shutdown. In many cases we *don't* want - * to free up the global RNG context because the application has Finalized - * simply to swap profiles. We don't want to loose the entropy we've - * already collected. - */ + /* This function does not discard all our previously aquired entropy. */ RNG_RNGShutdown(); -#endif /* tell freeBL to clean up after itself */ BL_Cleanup(); + /* unload freeBL shared library from memory */ + BL_Unload(); /* clean up the default OID table */ SECOID_Shutdown(); nsc_init = PR_FALSE; @@ -3178,7 +3211,6 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) return CKR_OK; } -#define CKF_THREAD_SAFE 0x8000 /* for now */ /* * check the current state of the 'needLogin' flag in case the database has * been changed underneath us. @@ -3206,14 +3238,17 @@ sftk_checkNeedLogin(SFTKSlot *slot, NSSLOWKEYDBHandle *keyHandle) * the system. */ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) { - SFTKSlot *slot = sftk_SlotFromID(slotID, PR_FALSE); + SFTKSlot *slot; NSSLOWKEYDBHandle *handle; + if (!nsc_init && !nsf_init) return CKR_CRYPTOKI_NOT_INITIALIZED; + slot = sftk_SlotFromID(slotID, PR_FALSE); if (slot == NULL) return CKR_SLOT_ID_INVALID; PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32); PORT_Memcpy(pInfo->model,"NSS 3 ",16); PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16); + PORT_Memcpy(pInfo->utcTime,"0000000000000000",16); pInfo->ulMaxSessionCount = 0; /* arbitrarily large */ pInfo->ulSessionCount = slot->sessionCount; pInfo->ulMaxRwSessionCount = 0; /* arbitarily large */ @@ -3222,8 +3257,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) pInfo->firmwareVersion.minor = 0; PORT_Memcpy(pInfo->label,slot->tokDescription,32); handle = sftk_getKeyDB(slot); + pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS; if (handle == NULL) { - pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE; + pInfo->flags |= CKF_WRITE_PROTECTED; pInfo->ulMaxPinLen = 0; pInfo->ulMinPinLen = 0; pInfo->ulTotalPublicMemory = 0; @@ -3243,12 +3279,11 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) * we will need to prompt for it. */ if (nsslowkey_HasKeyDBPassword(handle) == SECFailure) { - pInfo->flags = CKF_THREAD_SAFE | CKF_LOGIN_REQUIRED; + pInfo->flags |= CKF_LOGIN_REQUIRED; } else if (!sftk_checkNeedLogin(slot,handle)) { - pInfo->flags = CKF_THREAD_SAFE | CKF_USER_PIN_INITIALIZED; + pInfo->flags |= CKF_USER_PIN_INITIALIZED; } else { - pInfo->flags = CKF_THREAD_SAFE | - CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; + pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; } pInfo->ulMaxPinLen = SFTK_MAX_PIN; pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen; @@ -3260,6 +3295,18 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) pInfo->hardwareVersion.minor = handle->version; sftk_freeKeyDB(handle); } + /* + * CKF_LOGIN_REQUIRED CKF_USER_PIN_INITIALIZED how CKF_TOKEN_INITIALIZED + * should be set + * 0 0 1 + * 1 0 0 + * 0 1 1 + * 1 1 1 + */ + if (!(pInfo->flags & CKF_LOGIN_REQUIRED) || + (pInfo->flags & CKF_USER_PIN_INITIALIZED)) { + pInfo->flags |= CKF_TOKEN_INITIALIZED; + } return CKR_OK; } @@ -3551,7 +3598,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin, handle = sftk_getKeyDB(slot); if (handle == NULL) { sftk_FreeSession(sp); - return CKR_PIN_LEN_RANGE; + return CKR_PIN_LEN_RANGE; /* XXX FIXME wrong return value */ } if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) { @@ -3927,7 +3974,7 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class, if (attribute == NULL) { return CKR_TEMPLATE_INCOMPLETE; } - paramString = (unsigned char *)attribute->attrib.pValue; + paramString = (char *)attribute->attrib.pValue; crv = secmod_parseParameters(paramString, ¶mStrings, isFIPS); if (crv != CKR_OK) { goto loser; @@ -3990,7 +4037,9 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession, SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); SFTKSession *session; SFTKObject *object; - CK_OBJECT_CLASS class; + /* make sure class isn't randomly CKO_NETSCAPE_NEWSLOT or + * CKO_NETSCPE_DELSLOT. */ + CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED; CK_RV crv; int i; diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c index 56eb1814c..b722d3d4c 100644 --- a/security/nss/lib/softoken/pkcs11c.c +++ b/security/nss/lib/softoken/pkcs11c.c @@ -73,6 +73,7 @@ #include "pcert.h" #include "ssl3prot.h" /* for SSL3_RANDOM_LENGTH */ +#include "prprf.h" #define __PASTE(x,y) x##y @@ -441,17 +442,23 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, break; } context->multi = PR_FALSE; - context->cipherInfo = isEncrypt ? - (void *)sftk_GetPubKey(key,CKK_RSA,&crv) : - (void *)sftk_GetPrivKey(key,CKK_RSA,&crv); - if (context->cipherInfo == NULL) { - break; - } if (isEncrypt) { + NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv); + if (pubKey == NULL) { + break; + } + context->maxLen = nsslowkey_PublicModulusLen(pubKey); + context->cipherInfo = (void *)pubKey; context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_EncryptRaw : RSA_EncryptBlock); } else { + NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv); + if (privKey == NULL) { + break; + } + context->maxLen = nsslowkey_PrivateModulusLen(privKey); + context->cipherInfo = (void *)privKey; context->update = (SFTKCipher) (pMechanism->mechanism == CKM_RSA_X_509 ? RSA_DecryptRaw : RSA_DecryptBlock); @@ -717,6 +724,18 @@ CK_RV NSC_EncryptUpdate(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_ENCRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; + if (!pEncryptedPart) { + if (context->doPad) { + CK_ULONG totalDataAvailable = ulPartLen + context->padDataLength; + CK_ULONG blocksToSend = totalDataAvailable/context->blockSize; + + *pulEncryptedPartLen = blocksToSend * context->blockSize; + return CKR_OK; + } + *pulEncryptedPartLen = ulPartLen; + return CKR_OK; + } + /* do padding */ if (context->doPad) { /* deal with previous buffered data */ @@ -837,7 +856,8 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (crv != CKR_OK) return crv; if (!pEncryptedData) { - *pulEncryptedDataLen = ulDataLen + 2 * context->blockSize; + *pulEncryptedDataLen = context->multi ? + ulDataLen + 2 * context->blockSize : context->maxLen; goto finish; } @@ -923,6 +943,35 @@ CK_RV NSC_DecryptUpdate(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,NULL); if (crv != CKR_OK) return crv; + /* this can only happen on an NSS programming error */ + PORT_Assert((context->padDataLength == 0) + || context->padDataLength == context->blockSize); + + + if (!pPart) { + if (context->doPad) { + /* we can check the data length here because if we are padding, + * then we must be using a block cipher. In the non-padding case + * the error will be returned by the underlying decryption + * function when do do the actual decrypt. We need to do the + * check here to avoid returning a negative length to the caller. + */ + if ((ulEncryptedPartLen == 0) || + (ulEncryptedPartLen % context->blockSize) != 0) { + return CKR_ENCRYPTED_DATA_LEN_RANGE; + } + *pulPartLen = + ulEncryptedPartLen + context->padDataLength - context->blockSize; + return CKR_OK; + } + /* for stream ciphers there is are no constraints on ulEncryptedPartLen. + * for block ciphers, it must be a multiple of blockSize. The error is + * detected when this function is called again do decrypt the output. + */ + *pulPartLen = ulEncryptedPartLen; + return CKR_OK; + } + if (context->doPad) { /* first decrypt our saved buffer */ if (context->padDataLength != 0) { @@ -957,7 +1006,6 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, unsigned int maxout = *pulLastPartLen; CK_RV crv; SECStatus rv = SECSuccess; - PRBool contextFinished = PR_TRUE; /* make sure we're legal */ crv = sftk_GetContext(hSession,&context,SFTK_DECRYPT,PR_TRUE,&session); @@ -967,9 +1015,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, if (!pLastPart) { /* caller is checking the amount of remaining data */ if (context->padDataLength > 0) { - *pulLastPartLen = 2 * context->blockSize; - contextFinished = PR_FALSE; /* still have padding to go */ + *pulLastPartLen = context->padDataLength; } + rv = SECSuccess; goto finish; } @@ -992,11 +1040,9 @@ CK_RV NSC_DecryptFinal(CK_SESSION_HANDLE hSession, } } + sftk_SetContextByType(session, SFTK_DECRYPT, NULL); + sftk_FreeContext(context); finish: - if (contextFinished) { - sftk_SetContextByType(session, SFTK_DECRYPT, NULL); - sftk_FreeContext(context); - } sftk_FreeSession(session); return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; } @@ -1247,7 +1293,7 @@ static SECStatus sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen, unsigned char *hash, unsigned int hashLen) { - return PORT_Memcmp(sig,hash,*copyLen) ? SECSuccess : SECFailure ; + return (PORT_Memcmp(sig,hash,*copyLen) == 0) ? SECSuccess : SECFailure ; } /* @@ -1548,6 +1594,15 @@ static SECStatus sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, unsigned int maxLen,unsigned char *hash, unsigned int hashLen) { + return RSA_HashSign(info->hashOid,info->key,sig,sigLen,maxLen, + hash,hashLen); +} + +SECStatus +RSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key, + unsigned char *sig, unsigned int *sigLen, unsigned int maxLen, + unsigned char *hash, unsigned int hashLen) +{ SECStatus rv = SECFailure; SECItem digder; @@ -1560,7 +1615,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, if ( !arena ) { goto loser; } /* Construct digest info */ - di = SGN_CreateDigestInfo(info->hashOid, hash, hashLen); + di = SGN_CreateDigestInfo(hashOid, hash, hashLen); if (!di) { goto loser; } /* Der encode the digest as a DigestInfo */ @@ -1573,7 +1628,7 @@ sftk_HashSign(SFTKHashSignInfo *info,unsigned char *sig,unsigned int *sigLen, ** Encrypt signature after constructing appropriate PKCS#1 signature ** block */ - rv = RSA_Sign(info->key,sig,sigLen,maxLen,digder.data,digder.len); + rv = RSA_Sign(key,sig,sigLen,maxLen,digder.data,digder.len); loser: SGN_DestroyDigestInfo(di); @@ -1611,6 +1666,9 @@ nsc_DSA_Sign_Stub(void *ctx, void *sigBuf, digest.data = (unsigned char *)dataBuf; digest.len = dataLen; rv = DSA_SignDigest(&(key->u.dsa), &signature, &digest); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *sigLen = signature.len; return rv; } @@ -1644,6 +1702,9 @@ nsc_ECDSASignStub(void *ctx, void *sigBuf, digest.data = (unsigned char *)dataBuf; digest.len = dataLen; rv = ECDSA_SignDigest(&(key->u.ec), &signature, &digest); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *sigLen = signature.len; return rv; } @@ -1857,7 +1918,7 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart, SECStatus rv; /* make sure we're legal */ - crv = sftk_GetContext(hSession,&context,type,PR_FALSE,NULL); + crv = sftk_GetContext(hSession,&context,type,PR_TRUE,NULL); if (crv != CKR_OK) return crv; if (context->hashInfo) { @@ -2055,11 +2116,20 @@ CK_RV NSC_SignRecover(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ************** Crypto Functions: verify ************************ */ -/* Handle RSA Signature formating */ +/* Handle RSA Signature formatting */ static SECStatus sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, unsigned int sigLen, unsigned char *digest, unsigned int digestLen) { + return RSA_HashCheckSign(info->hashOid, info->key, sig, sigLen, + digest, digestLen); +} + +SECStatus +RSA_HashCheckSign(SECOidTag hashOid, NSSLOWKEYPublicKey *key, + unsigned char *sig, unsigned int sigLen, + unsigned char *digest, unsigned int digestLen) +{ SECItem it; SGNDigestInfo *di = NULL; @@ -2067,16 +2137,16 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, it.data = NULL; - if (info->key == NULL) goto loser; + if (key == NULL) goto loser; - it.len = nsslowkey_PublicModulusLen(info->key); + it.len = nsslowkey_PublicModulusLen(key); if (!it.len) goto loser; it.data = (unsigned char *) PORT_Alloc(it.len); if (it.data == NULL) goto loser; /* decrypt the block */ - rv = RSA_CheckSignRecover(info->key, it.data, &it.len, it.len, sig, sigLen); + rv = RSA_CheckSignRecover(key, it.data, &it.len, it.len, sig, sigLen); if (rv != SECSuccess) goto loser; di = SGN_DecodeDigestInfo(&it); @@ -2084,7 +2154,11 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, if (di->digest.len != digestLen) goto loser; /* make sure the tag is OK */ - if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != info->hashOid) { + if (SECOID_GetAlgorithmTag(&di->digestAlgorithm) != hashOid) { + goto loser; + } + /* make sure the "parameters" are not too bogus. */ + if (di->digestAlgorithm.parameters.len > 2) { goto loser; } /* Now check the signature */ @@ -2093,6 +2167,7 @@ sftk_hashCheckSign(SFTKHashVerifyInfo *info, unsigned char *sig, } loser: + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); rv = SECFailure; done: @@ -2202,7 +2277,6 @@ finish_rsa: crv = CKR_KEY_TYPE_INCONSISTENT; break; } - context->multi = PR_FALSE; pubKey = sftk_GetPubKey(key,CKK_EC,&crv); if (pubKey == NULL) { crv = CKR_HOST_MEMORY; @@ -2246,6 +2320,7 @@ finish_rsa: } if (crv != CKR_OK) { + if (info) PORT_Free(info); PORT_Free(context); sftk_FreeSession(session); return crv; @@ -2263,13 +2338,22 @@ CK_RV NSC_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, { SFTKSession *session; SFTKSessionContext *context; - CK_RV crv; + CK_RV crv, crv2; SECStatus rv; /* make sure we're legal */ crv = sftk_GetContext(hSession,&context,SFTK_VERIFY,PR_FALSE,&session); if (crv != CKR_OK) return crv; + /* multi part Verifying are completely implemented by VerifyUpdate and + * VerifyFinal */ + if (context->multi) { + sftk_FreeSession(session); + crv = NSC_VerifyUpdate(hSession, pData, ulDataLen); + crv2 = NSC_VerifyFinal(hSession, pSignature, ulSignatureLen); + return crv == CKR_OK ? crv2 :crv; + } + rv = (*context->verify)(context->cipherInfo,pSignature, ulSignatureLen, pData, ulDataLen); sftk_FreeContext(context); @@ -2414,14 +2498,23 @@ CK_RV NSC_VerifyRecover(CK_SESSION_HANDLE hSession, crv = sftk_GetContext(hSession,&context,SFTK_VERIFY_RECOVER, PR_FALSE,&session); if (crv != CKR_OK) return crv; + if (pData == NULL) { + /* to return the actual size, we need to do the decrypt, just return + * the max size, which is the size of the input signature. */ + *pulDataLen = ulSignatureLen; + rv = SECSuccess; + goto finish; + } rv = (*context->update)(context->cipherInfo, pData, &outlen, maxoutlen, pSignature, ulSignatureLen); *pulDataLen = (CK_ULONG) outlen; + sftk_FreeContext(context); sftk_SetContextByType(session, SFTK_VERIFY_RECOVER, NULL); +finish: sftk_FreeSession(session); - return (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; + return (rv == SECSuccess) ? CKR_OK : CKR_SIGNATURE_INVALID; } /* @@ -2482,9 +2575,13 @@ nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism, SECITEM_ZfreeItem(pbe_key, PR_TRUE); pbe_key = NULL; - if (iv.data && pbe_params->pInitVector != NULL) { - PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); + if (iv.data) { + if (pbe_params->pInitVector != NULL) { + PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len); + } + PORT_Free(iv.data); } + return CKR_OK; } static CK_RV @@ -2527,6 +2624,9 @@ nsc_parameter_gen(CK_KEY_TYPE key_type, SFTKObject *key) } if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } return CKR_DEVICE_ERROR; } crv = sftk_AddAttributeType(key,CKA_PRIME, @@ -3355,6 +3455,9 @@ CK_RV NSC_GenerateKeyPair (CK_SESSION_HANDLE hSession, rsaPriv = RSA_NewKey(public_modulus_bits, &pubExp); PORT_Free(pubExp.data); if (rsaPriv == NULL) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; break; } @@ -3471,7 +3574,13 @@ kpg_done: PORT_Free(pqgParam.subPrime.data); PORT_Free(pqgParam.base.data); - if (rv != SECSuccess) { crv = CKR_DEVICE_ERROR; break; } + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } + crv = CKR_DEVICE_ERROR; + break; + } /* store the generated key into the attributes */ crv = sftk_AddAttributeType(publicKey,CKA_VALUE, @@ -3539,6 +3648,9 @@ dsagn_done: PORT_Free(dhParam.prime.data); PORT_Free(dhParam.base.data); if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } crv = CKR_DEVICE_ERROR; break; } @@ -3588,8 +3700,11 @@ dhgn_done: rv = EC_NewKey(ecParams, &ecPriv); PORT_FreeArena(ecParams->arena, PR_TRUE); if (rv != SECSuccess) { - crv = CKR_DEVICE_ERROR; - break; + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } + crv = CKR_DEVICE_ERROR; + break; } crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, @@ -3695,6 +3810,16 @@ ecgn_done: sftk_FreeObject(publicKey); NSC_DestroyObject(hSession,privateKey->handle); sftk_FreeObject(privateKey); + if (sftk_audit_enabled) { + char msg[128]; + PR_snprintf(msg,sizeof msg, + "C_GenerateKeyPair(hSession=0x%08lX, " + "pMechanism->mechanism=0x%08lX)=0x%08lX " + "self-test: pair-wise consistency test failed", + (PRUint32)hSession,(PRUint32)pMechanism->mechanism, + (PRUint32)crv); + sftk_LogAuditMessage(NSS_AUDIT_ERROR, msg); + } return crv; } @@ -3937,6 +4062,17 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, crv = NSC_Encrypt(hSession, (CK_BYTE_PTR)pText.data, pText.len, pWrappedKey, pulWrappedKeyLen); + /* always force a finalize, both on errors and when + * we are just getting the size */ + if (crv != CKR_OK || pWrappedKey == NULL) { + CK_RV lcrv ; + lcrv = sftk_GetContext(hSession,&context, + SFTK_ENCRYPT,PR_FALSE,NULL); + sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); + if (lcrv == CKR_OK && context) { + sftk_FreeContext(context); + } + } if (pText.data != (unsigned char *)attribute->attrib.pValue) PORT_ZFree(pText.data, pText.len); @@ -3947,6 +4083,7 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, case CKO_PRIVATE_KEY: { SECItem *bpki = sftk_PackagePrivateKey(key, &crv); + SFTKSessionContext *context = NULL; if(!bpki) { break; @@ -3962,6 +4099,16 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession, crv = NSC_Encrypt(hSession, bpki->data, bpki->len, pWrappedKey, pulWrappedKeyLen); + /* always force a finalize */ + if (crv != CKR_OK || pWrappedKey == NULL) { + CK_RV lcrv ; + lcrv = sftk_GetContext(hSession,&context, + SFTK_ENCRYPT,PR_FALSE,NULL); + sftk_SetContextByType(session, SFTK_ENCRYPT, NULL); + if (lcrv == CKR_OK && context) { + sftk_FreeContext(context); + } + } SECITEM_ZfreeItem(bpki, PR_TRUE); break; } @@ -3989,7 +4136,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) PLArenaPool *arena; NSSLOWKEYPrivateKey *lpk = NULL; NSSLOWKEYPrivateKeyInfo *pki = NULL; - SECItem *ck_id = NULL; CK_RV crv = CKR_KEY_TYPE_INCONSISTENT; arena = PORT_NewArena(2048); @@ -4000,13 +4146,13 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, sizeof(NSSLOWKEYPrivateKeyInfo)); if(!pki) { - PORT_FreeArena(arena, PR_TRUE); + PORT_FreeArena(arena, PR_FALSE); return SECFailure; } if(SEC_ASN1DecodeItem(arena, pki, nsslowkey_PrivateKeyInfoTemplate, bpki) != SECSuccess) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_TRUE); return SECFailure; } @@ -4197,10 +4343,6 @@ sftk_unwrapPrivateKey(SFTKObject *key, SECItem *bpki) } loser: - if(ck_id) { - SECITEM_ZfreeItem(ck_id, PR_TRUE); - } - if(lpk) { nsslowkey_DestroyPrivateKey(lpk); } @@ -4605,14 +4747,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, return CKR_KEY_HANDLE_INVALID; } - /* don't use key derive to expose sensitive keys */ - crv = sftk_DeriveSensitiveCheck(sourceKey,key); - if (crv != CKR_OK) { - sftk_FreeObject(key); - sftk_FreeObject(sourceKey); - return crv; - } - /* get the value of the base key */ att = sftk_FindAttribute(sourceKey,CKA_VALUE); if (att == NULL) { @@ -4633,7 +4767,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, case CKM_SSL3_MASTER_KEY_DERIVE_DH: { CK_SSL3_MASTER_KEY_DERIVE_PARAMS *ssl3_master; - SSL3RSAPreMasterSecret *rsa_pms; + SSL3RSAPreMasterSecret * rsa_pms; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; + if ((pMechanism->mechanism == CKM_SSL3_MASTER_KEY_DERIVE_DH) || (pMechanism->mechanism == CKM_TLS_MASTER_KEY_DERIVE_DH)) isDH = PR_TRUE; @@ -4660,10 +4796,15 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } - /* finally do the key gen */ ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(crsrdata, + ssl3_master->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + if (ssl3_master->pVersion) { SFTKSessionObject *sessKey = sftk_narrowToSessionObject(key); rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue; @@ -4686,23 +4827,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, } if (isTLS) { - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - SECItem crsr = { siBuffer, NULL, 0 }; - SECItem master = { siBuffer, NULL, 0 }; - SECItem pms = { siBuffer, NULL, 0 }; SECStatus status; + SECItem crsr = { siBuffer, NULL, 0 }; + SECItem master = { siBuffer, NULL, 0 }; + SECItem pms = { siBuffer, NULL, 0 }; - pms.data = (unsigned char*)att->attrib.pValue; - pms.len = att->attrib.ulValueLen; - master.data = key_block; - master.len = SSL3_MASTER_SECRET_LENGTH; - crsr.data = crsrdata; - crsr.len = sizeof(crsrdata); - - PORT_Memcpy(crsrdata, ssl3_master->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_master->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + crsr.data = crsrdata; + crsr.len = sizeof crsrdata; + master.data = key_block; + master.len = SSL3_MASTER_SECRET_LENGTH; + pms.data = (unsigned char*)att->attrib.pValue; + pms.len = att->attrib.ulValueLen; status = TLS_PRF(&pms, "master secret", &crsr, &master, isFIPS); if (status != SECSuccess) { @@ -4727,12 +4862,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pClientRandom, - ssl3_master->RandomInfo.ulClientRandomLen); - SHA1_Update(sha, ssl3_master->RandomInfo.pServerRandom, - ssl3_master->RandomInfo.ulServerRandomLen); + SHA1_Update(sha, crsrdata, sizeof crsrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); + MD5_Begin(md5); MD5_Update(md5, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); @@ -4773,6 +4906,9 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, CK_SSL3_KEY_MAT_PARAMS *ssl3_keys; CK_SSL3_KEY_MAT_OUT * ssl3_keys_out; CK_ULONG effKeySize; + unsigned int block_needed; + unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; crv = sftk_DeriveSensitiveCheck(sourceKey,key); if (crv != CKR_OK) break; @@ -4801,6 +4937,17 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, break; } ssl3_keys = (CK_SSL3_KEY_MAT_PARAMS *) pMechanism->pParameter; + + PORT_Memcpy(srcrdata, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + + PORT_Memcpy(crsrdata, + ssl3_keys->RandomInfo.pClientRandom, SSL3_RANDOM_LENGTH); + PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, + ssl3_keys->RandomInfo.pServerRandom, SSL3_RANDOM_LENGTH); + /* * clear out our returned keys so we can recover on failure */ @@ -4811,29 +4958,36 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ssl3_keys_out->hServerKey = CK_INVALID_HANDLE; /* + * How much key material do we need? + */ + macSize = ssl3_keys->ulMacSizeInBits/8; + effKeySize = ssl3_keys->ulKeySizeInBits/8; + IVSize = ssl3_keys->ulIVSizeInBits/8; + if (keySize == 0) { + effKeySize = keySize; + } + block_needed = 2 * (macSize + effKeySize + + ((!ssl3_keys->bIsExport) * IVSize)); + PORT_Assert(block_needed <= sizeof key_block); + if (block_needed > sizeof key_block) + block_needed = sizeof key_block; + + /* * generate the key material: This looks amazingly similar to the * PMS code, and is clearly crying out for a function to provide it. */ if (isTLS) { SECStatus status; - SECItem master = { siBuffer, NULL, 0 }; SECItem srcr = { siBuffer, NULL, 0 }; SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; + SECItem master = { siBuffer, NULL, 0 }; - master.data = (unsigned char*)att->attrib.pValue; - master.len = att->attrib.ulValueLen; srcr.data = srcrdata; srcr.len = sizeof srcrdata; keyblk.data = key_block; - keyblk.len = sizeof key_block; - - PORT_Memcpy(srcrdata, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); + keyblk.len = block_needed; + master.data = (unsigned char*)att->attrib.pValue; + master.len = att->attrib.ulValueLen; status = TLS_PRF(&master, "key expansion", &srcr, &keyblk, isFIPS); @@ -4841,6 +4995,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, goto key_and_mac_derive_fail; } } else { + unsigned int block_bytes = 0; /* key_block = * MD5(master_secret + SHA('A' + master_secret + * ServerHello.random + ClientHello.random)) + @@ -4850,15 +5005,12 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * ServerHello.random + ClientHello.random)) + * [...]; */ - for (i = 0; i < NUM_MIXERS; i++) { + for (i = 0; i < NUM_MIXERS && block_bytes < block_needed; i++) { SHA1_Begin(sha); SHA1_Update(sha, (unsigned char*) mixers[i], strlen(mixers[i])); SHA1_Update(sha, (const unsigned char*)att->attrib.pValue, att->attrib.ulValueLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - SHA1_Update(sha, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + SHA1_Update(sha, srcrdata, sizeof srcrdata); SHA1_End(sha, sha_out, &outLen, SHA1_LENGTH); PORT_Assert(outLen == SHA1_LENGTH); MD5_Begin(md5); @@ -4867,6 +5019,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, MD5_Update(md5, sha_out, outLen); MD5_End(md5, &key_block[i*MD5_LENGTH], &outLen, MD5_LENGTH); PORT_Assert(outLen == MD5_LENGTH); + block_bytes += outLen; } } @@ -4874,12 +5027,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, * Put the key material where it goes. */ i = 0; /* now shows how much consumed */ - macSize = ssl3_keys->ulMacSizeInBits/8; - effKeySize = ssl3_keys->ulKeySizeInBits/8; - IVSize = ssl3_keys->ulIVSizeInBits/8; - if (keySize == 0) { - effKeySize = keySize; - } /* * The key_block is partitioned as follows: @@ -4954,10 +5101,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -4973,10 +5117,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, */ MD5_Begin(md5); MD5_Update(md5, &key_block[i], effKeySize); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); i += effKeySize; crv = sftk_buildSSLKey(hSession,key,PR_FALSE,key_block2, @@ -4990,10 +5131,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ClientHello.random + ServerHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); + MD5_Update(md5, crsrdata, sizeof crsrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVClient, key_block2, IVSize); @@ -5002,10 +5140,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, ** MD5(ServerHello.random + ClientHello.random); */ MD5_Begin(md5); - MD5_Update(md5, ssl3_keys->RandomInfo.pServerRandom, - ssl3_keys->RandomInfo.ulServerRandomLen); - MD5_Update(md5, ssl3_keys->RandomInfo.pClientRandom, - ssl3_keys->RandomInfo.ulClientRandomLen); + MD5_Update(md5, srcrdata, sizeof srcrdata); MD5_End(md5, key_block2, &outLen, MD5_LENGTH); PORT_Memcpy(ssl3_keys_out->pIVServer, key_block2, IVSize); @@ -5018,18 +5153,6 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, SECItem secret = { siBuffer, NULL, 0 }; SECItem crsr = { siBuffer, NULL, 0 }; SECItem keyblk = { siBuffer, NULL, 0 }; - unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; - - crsr.data = crsrdata; - crsr.len = sizeof crsrdata; - - PORT_Memcpy(crsrdata, - ssl3_keys->RandomInfo.pClientRandom, - SSL3_RANDOM_LENGTH); - PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, - ssl3_keys->RandomInfo.pServerRandom, - SSL3_RANDOM_LENGTH); - /* ** client_write_key[CipherSpec.key_material] @@ -5040,6 +5163,8 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession, secret.data = &key_block[i]; secret.len = effKeySize; i += effKeySize; + crsr.data = crsrdata; + crsr.len = sizeof crsrdata; keyblk.data = key_block2; keyblk.len = sizeof key_block2; status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, @@ -5177,6 +5302,9 @@ key_and_mac_derive_fail: } case CKM_CONCATENATE_BASE_AND_DATA: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *) pMechanism->pParameter; tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; if (keySize == 0) keySize = tmpKeySize; @@ -5198,6 +5326,9 @@ key_and_mac_derive_fail: PORT_ZFree(buf,tmpKeySize); break; case CKM_CONCATENATE_DATA_AND_BASE: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; tmpKeySize = att->attrib.ulValueLen+stringPtr->ulLen; if (keySize == 0) keySize = tmpKeySize; @@ -5219,6 +5350,9 @@ key_and_mac_derive_fail: PORT_ZFree(buf,tmpKeySize); break; case CKM_XOR_BASE_AND_DATA: + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + stringPtr = (CK_KEY_DERIVATION_STRING_DATA *)pMechanism->pParameter; tmpKeySize = PR_MIN(att->attrib.ulValueLen,stringPtr->ulLen); if (keySize == 0) keySize = tmpKeySize; @@ -5249,6 +5383,9 @@ key_and_mac_derive_fail: CK_ULONG shift = extract & 0x7; /* extract mod 8 the fast way */ CK_ULONG offset = extract >> 3; /* extract div 8 the fast way */ + crv = sftk_DeriveSensitiveCheck(sourceKey,key); + if (crv != CKR_OK) break; + if (keySize == 0) { crv = CKR_TEMPLATE_INCOMPLETE; break; @@ -5382,6 +5519,7 @@ key_and_mac_derive_fail: PRBool withCofactor = PR_FALSE; unsigned char secret_hash[20]; unsigned char *secret; + unsigned char *keyData = NULL; int secretlen; CK_ECDH1_DERIVE_PARAMS *mechParams; NSSLOWKEYPrivateKey *privKey; @@ -5435,26 +5573,59 @@ key_and_mac_derive_fail: break; } + /* + * tmp is the raw data created by ECDH_Derive, + * secret and secretlen are the values we will eventually pass as our + * generated key. + */ secret = tmp.data; secretlen = tmp.len; + + /* + * apply the kdf function. + */ if (mechParams->kdf == CKD_SHA1_KDF) { /* Compute SHA1 hash */ - memset(secret_hash, 0, 20); + PORT_Memset(secret_hash, 0, 20); rv = SHA1_HashBuf(secret_hash, tmp.data, tmp.len); if (rv != SECSuccess) { PORT_ZFree(tmp.data, tmp.len); + crv = CKR_HOST_MEMORY; + break; + } + secret = secret_hash; + secretlen = 20; + } + + /* + * if keySize is supplied, then we are generating a key of a specific + * length. This is done by taking the least significant 'keySize' + * bytes from the unsigned value calculated by ECDH. Note: this may + * mean padding temp with extra leading zeros from what ECDH_Derive + * already returned (which itself may contain leading zeros). + */ + if (keySize) { + if (secretlen < keySize) { + keyData = PORT_ZAlloc(keySize); + if (!keyData) { + PORT_ZFree(tmp.data, tmp.len); + crv = CKR_HOST_MEMORY; + break; + } + PORT_Memcpy(&keyData[keySize-secretlen],secret,secretlen); + secret = keyData; } else { - secret = secret_hash; - secretlen = 20; + secret += (secretlen - keySize); } + secretlen = keySize; } - if (rv == SECSuccess) { - sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); - PORT_ZFree(tmp.data, tmp.len); - memset(secret_hash, 0, 20); - } else - crv = CKR_HOST_MEMORY; + sftk_forceAttribute(key, CKA_VALUE, secret, secretlen); + PORT_ZFree(tmp.data, tmp.len); + if (keyData) { + PORT_ZFree(keyData, keySize); + } + PORT_Memset(secret_hash, 0, 20); break; } @@ -5700,7 +5871,9 @@ CK_RV NSC_DigestKey(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey) /* get the key value */ att = sftk_FindAttribute(key,CKA_VALUE); sftk_FreeObject(key); - + if (!att) { + return CKR_KEY_HANDLE_INVALID; + } crv = NSC_DigestUpdate(hSession,(CK_BYTE_PTR)att->attrib.pValue, att->attrib.ulValueLen); sftk_FreeAttribute(att); diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h index 0eaf5bf37..6f77994fd 100644 --- a/security/nss/lib/softoken/pkcs11i.h +++ b/security/nss/lib/softoken/pkcs11i.h @@ -555,8 +555,8 @@ typedef struct sftk_parametersStr { SEC_BEGIN_PROTOS -/* shared functions between PKCS11.c and SFTKFIPS.c */ -extern int nsf_init; +/* shared functions between pkcs11.c and fipstokn.c */ +extern PRBool nsf_init; extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS); extern CK_RV nsc_CommonFinalize(CK_VOID_PTR pReserved, PRBool isFIPS); extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent, diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index 8e68587ce..9790f0ca3 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -67,6 +67,7 @@ sftk_NewAttribute(SFTKObject *object, if (so == NULL) { /* allocate new attribute in a buffer */ PORT_Assert(0); + return NULL; } /* * We attempt to keep down contention on Malloc and Arena locks by @@ -891,6 +892,11 @@ sftk_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, case CKA_BASE: return sftk_NewTokenAttributeSigned(type,key->u.dsa.params.base.data, key->u.dsa.params.base.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.dsa.publicValue.data, + key->u.dsa.publicValue.len, + PR_FALSE); default: break; } @@ -925,6 +931,11 @@ sftk_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type) case CKA_BASE: return sftk_NewTokenAttributeSigned(type,key->u.dh.base.data, key->u.dh.base.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.dh.publicValue.data, + key->u.dh.publicValue.len, + PR_FALSE); default: break; } @@ -960,6 +971,11 @@ sftk_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type) key->u.ec.ecParams.DEREncoding.data, key->u.ec.ecParams.DEREncoding.len, PR_FALSE); + case CKA_NETSCAPE_DB: + return sftk_NewTokenAttributeSigned(type, + key->u.ec.publicValue.data, + key->u.ec.publicValue.len, + PR_FALSE); default: break; } @@ -1502,7 +1518,6 @@ sftk_DeleteAttribute(SFTKObject *object, SFTKAttribute *attribute) sessObject->head, sessObject->hashSize); } PZ_Unlock(sessObject->attributeLock); - sftk_FreeAttribute(attribute); } /* @@ -2749,7 +2764,7 @@ stfk_CopyTokenPrivateKey(SFTKObject *destObject,SFTKTokenObject *src_to) } /* copy the common attributes for all private keys next */ crv = stfk_CopyTokenAttributes(destObject, src_to, commonPrivKeyAttrs, - commonKeyAttrsCount); + commonPrivKeyAttrsCount); if (crv != CKR_OK) { goto fail; } diff --git a/security/nss/lib/softoken/rsawrapr.c b/security/nss/lib/softoken/rsawrapr.c index b40a30d80..c60c71344 100644 --- a/security/nss/lib/softoken/rsawrapr.c +++ b/security/nss/lib/softoken/rsawrapr.c @@ -193,6 +193,7 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, unsigned char *bp; int padLen; int i; + SECStatus rv; block = (unsigned char *) PORT_Alloc(modulusLen); if (block == NULL) @@ -254,8 +255,13 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, for (i = 0; i < padLen; i++) { /* Pad with non-zero random data. */ do { - RNG_GenerateGlobalRandomBytes(bp + i, 1); - } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); + rv = RNG_GenerateGlobalRandomBytes(bp + i, 1); + } while (rv == SECSuccess && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } } bp += padLen; *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; @@ -292,7 +298,12 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, /* * Salt */ - RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); + rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } bp += OAEP_SALT_LEN; /* @@ -310,8 +321,14 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType, /* * Pad2 */ - if (bp < (block + modulusLen)) - RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen); + if (bp < (block + modulusLen)) { + rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen); + if (rv != SECSuccess) { + sftk_fatalError = PR_TRUE; + PORT_Free (block); + return NULL; + } + } /* * Now we have the following: @@ -463,6 +480,9 @@ RSA_Sign(NSSLOWKEYPrivateKey *key, goto done; rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *output_len = modulus_len; goto done; @@ -489,7 +509,13 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key, modulus_len = nsslowkey_PublicModulusLen(key); if (sign_len != modulus_len) goto failure; - if (hash_len > modulus_len - 8) + /* + * 0x00 || BT || Pad || 0x00 || ActualData + * + * The "3" below is the first octet + the second octet + the 0x00 + * octet that always comes just before the ActualData. + */ + if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN)) goto failure; PORT_Assert(key->keyType == NSSLOWKEYRSAKey); if (key->keyType != NSSLOWKEYRSAKey) @@ -509,11 +535,11 @@ RSA_CheckSign(NSSLOWKEYPublicKey *key, if (buffer[0] != 0 || buffer[1] != 1) goto loser; for (i = 2; i < modulus_len - hash_len - 1; i++) { - if (buffer[i] == 0) - break; if (buffer[i] != 0xff) goto loser; } + if (buffer[i] != 0) + goto loser; /* * make sure we get the same results @@ -659,8 +685,12 @@ RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, goto failure; rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input); - if (rv != SECSuccess) + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } goto loser; + } if (buffer[0] != 0 || buffer[1] != 2) goto loser; @@ -719,6 +749,9 @@ RSA_SignRaw(NSSLOWKEYPrivateKey *key, goto done; rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output, formatted.data); + if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } *output_len = modulus_len; done: @@ -868,8 +901,12 @@ RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, goto failure; rv = RSA_PrivateKeyOp(&key->u.rsa, output, input); - if (rv != SECSuccess) + if (rv != SECSuccess) { + if (PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) { + sftk_fatalError = PR_TRUE; + } goto failure; + } *output_len = modulus_len; return SECSuccess; diff --git a/security/nss/lib/softoken/softoken.h b/security/nss/lib/softoken/softoken.h index b89546e53..ed9108dcc 100644 --- a/security/nss/lib/softoken/softoken.h +++ b/security/nss/lib/softoken/softoken.h @@ -81,7 +81,7 @@ extern unsigned char *RSA_FormatOneBlock(unsigned int modulusLen, /* * convenience wrappers for doing single RSA operations. They create the * RSA context internally and take care of the formatting - * requirements. Blinding happens automagically within RSA_SignHash and + * requirements. Blinding happens automagically within RSA_Sign and * RSA_DecryptBlock. */ extern @@ -89,10 +89,20 @@ SECStatus RSA_Sign(NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *outputLen, unsigned int maxOutputLen, unsigned char *input, unsigned int inputLen); extern +SECStatus RSA_HashSign(SECOidTag hashOid, + NSSLOWKEYPrivateKey *key, unsigned char *sig, + unsigned int *sigLen, unsigned int maxLen, + unsigned char *hash, unsigned int hashLen); +extern SECStatus RSA_CheckSign(NSSLOWKEYPublicKey *key, unsigned char *sign, unsigned int signLength, unsigned char *hash, unsigned int hashLength); extern +SECStatus RSA_HashCheckSign(SECOidTag hashOid, + NSSLOWKEYPublicKey *key, unsigned char *sig, + unsigned int sigLen, unsigned char *digest, + unsigned int digestLen); +extern SECStatus RSA_CheckSignRecover(NSSLOWKEYPublicKey *key, unsigned char *data, unsigned int *data_len,unsigned int max_output_len, unsigned char *sign, unsigned int sign_len); @@ -131,6 +141,14 @@ SECStatus RSA_DecryptRaw(NSSLOWKEYPrivateKey *key, unsigned char *output, unsigned int *output_len, unsigned int max_output_len, unsigned char *input, unsigned int input_len); +#ifdef NSS_ENABLE_ECC +/* +** pepare an ECParam structure from DEREncoded params + */ +extern SECStatus EC_FillParams(PRArenaPool *arena, + const SECItem *encodedParams, ECParams *params); +#endif + /* ** Prepare a buffer for DES encryption, growing to the appropriate boundary, @@ -159,6 +177,83 @@ extern CK_RV sftk_fipsPowerUpSelfTest( void ); */ unsigned long sftk_MapKeySize(CK_KEY_TYPE keyType); +/* +** FIPS 140-2 auditing +*/ +extern PRBool sftk_audit_enabled; + +extern void sftk_LogAuditMessage(NSSAuditSeverity severity, const char *msg); + +extern void sftk_AuditCreateObject(CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject, CK_RV rv); + +extern void sftk_AuditCopyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject, CK_RV rv); + +extern void sftk_AuditDestroyObject(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_RV rv); + +extern void sftk_AuditGetObjectSize(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize, + CK_RV rv); + +extern void sftk_AuditGetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv); + +extern void sftk_AuditSetAttributeValue(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, CK_RV rv); + +extern void sftk_AuditCryptInit(const char *opName, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey, CK_RV rv); + +extern void sftk_AuditGenerateKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditGenerateKeyPair(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey, CK_RV rv); + +extern void sftk_AuditWrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen, CK_RV rv); + +extern void sftk_AuditUnwrapKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditDeriveKey(CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey, CK_RV rv); + +extern void sftk_AuditDigestKey(CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey, CK_RV rv); + +/* +** FIPS 140-2 Error state +*/ +extern PRBool sftk_fatalError; + SEC_END_PROTOS #endif /* _SOFTOKEN_H_ */ diff --git a/security/nss/lib/softoken/softokn.rc b/security/nss/lib/softoken/softokn.rc index 0fcaa1219..bbf8905a0 100644 --- a/security/nss/lib/softoken/softokn.rc +++ b/security/nss/lib/softoken/softokn.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/softoken/softoknt.h b/security/nss/lib/softoken/softoknt.h index b499eb6b0..3af94e286 100644 --- a/security/nss/lib/softoken/softoknt.h +++ b/security/nss/lib/softoken/softoknt.h @@ -61,4 +61,13 @@ typedef enum { #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE 2048 +/* + * FIPS 140-2 auditing + */ +typedef enum { + NSS_AUDIT_ERROR = 3, /* errors */ + NSS_AUDIT_WARNING = 2, /* warning messages */ + NSS_AUDIT_INFO = 1 /* informational messages */ +} NSSAuditSeverity; + #endif /* _SOFTOKNT_H_ */ diff --git a/security/nss/lib/ssl/derive.c b/security/nss/lib/ssl/derive.c index c00822bee..9e7727398 100644 --- a/security/nss/lib/ssl/derive.c +++ b/security/nss/lib/ssl/derive.c @@ -52,6 +52,7 @@ buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result) result->type = siBuffer; result->data = keyBlock; result->len = keyLen; + PRINT_BUF(100, (NULL, "key value", keyBlock, keyLen)); } #else #define buildSSLKey(keyBlock, keyLen, result) \ @@ -59,6 +60,7 @@ buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result) (result)->type = siBuffer; \ (result)->data = keyBlock; \ (result)->len = keyLen; \ + PRINT_BUF(100, (NULL, "key value", keyBlock, keyLen)); \ } #endif @@ -122,6 +124,9 @@ ssl3_KeyAndMacDeriveBypass( return rv; } + PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, + pwSpec->msItem.len)); + /* figure out how much is needed */ macSize = pwSpec->mac_size; keySize = cipher_def->key_size; @@ -153,6 +158,7 @@ ssl3_KeyAndMacDeriveBypass( crsr.len = sizeof crsrdata; PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); + PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); /* * generate the key material: @@ -203,6 +209,7 @@ ssl3_KeyAndMacDeriveBypass( } PORT_Assert(block_bytes >= block_needed); PORT_Assert(block_bytes <= sizeof pwSpec->key_block); + PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); /* * Put the key material where it goes. @@ -395,7 +402,9 @@ key_and_mac_derive_fail: /* derive the Master Secret from the PMS */ -/* Presently, this is only done wtih RSA PMS, os isRSA is always true. */ +/* Presently, this is only done wtih RSA PMS, and only on the server side, + * so isRSA is always true. + */ SECStatus ssl3_MasterKeyDeriveBypass( ssl3CipherSpec * pwSpec, @@ -434,6 +443,7 @@ ssl3_MasterKeyDeriveBypass( crsr.len = sizeof crsrdata; PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); + PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); /* finally do the key gen */ if (isTLS) { @@ -474,6 +484,8 @@ ssl3_MasterKeyDeriveBypass( SSL3_MASTER_SECRET_LENGTH); pwSpec->msItem.data = pwSpec->raw_master_secret; pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; + PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, + pwSpec->msItem.len)); return rv; } diff --git a/security/nss/lib/ssl/emulate.c b/security/nss/lib/ssl/emulate.c deleted file mode 100644 index a381cd7d2..000000000 --- a/security/nss/lib/ssl/emulate.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Functions that emulate PR_AcceptRead and PR_TransmitFile for SSL sockets. - * Each Layered NSPR protocol (like SSL) must unfortunately contain its - * own implementation of these functions. This code was taken from NSPR. - * - * ***** 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 ***** */ -/* $Id$ */ - -#include "nspr.h" - -#if defined( XP_UNIX ) || defined( XP_BEOS ) -#include <fcntl.h> -#endif -#if defined(WIN32) -#include <windef.h> -#include <winbase.h> -#endif -#include <string.h> - -#define AMASK 7 /* mask for alignment of PRNetAddr */ - -/* - * _PR_EmulateAcceptRead - * - * Accept an incoming connection on sd, set *nd to point to the - * newly accepted socket, read 'amount' bytes from the accepted - * socket. - * - * buf is a buffer of length = amount + (2 * sizeof(PRNetAddr)) + 32 - * *raddr points to the PRNetAddr of the accepted connection upon - * return - * - * return number of bytes read or -1 on error - * - */ -PRInt32 -ssl_EmulateAcceptRead( PRFileDesc * sd, - PRFileDesc ** nd, - PRNetAddr ** raddr, - void * buf, - PRInt32 amount, - PRIntervalTime timeout) -{ - PRFileDesc * newsockfd; - PRInt32 rv; - PRNetAddr remote; - - if (!(newsockfd = PR_Accept(sd, &remote, PR_INTERVAL_NO_TIMEOUT))) { - return -1; - } - - rv = PR_Recv(newsockfd, buf, amount, 0, timeout); - if (rv >= 0) { - ptrdiff_t pNetAddr = (((ptrdiff_t)buf) + amount + AMASK) & ~AMASK; - - *nd = newsockfd; - *raddr = (PRNetAddr *)pNetAddr; - memcpy((void *)pNetAddr, &remote, sizeof(PRNetAddr)); - return rv; - } - - PR_Close(newsockfd); - return -1; -} - - -#if !defined( XP_UNIX ) && !defined( WIN32 ) && !defined( XP_BEOS ) -/* - * _PR_EmulateTransmitFile - * - * Send file fd across socket sd. If headers is non-NULL, 'hlen' - * bytes of headers is sent before sending the file. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ -#define _TRANSMITFILE_BUFSIZE (16 * 1024) - -PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout) -{ - char * buf = NULL; - PRInt32 count = 0; - PRInt32 rlen; - PRInt32 rv; - - buf = PR_MALLOC(_TRANSMITFILE_BUFSIZE); - if (buf == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - /* - * send headers, first - */ - while (hlen) { - rv = PR_Send(sd, headers, hlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - count += rv; - headers = (const void*) ((const char*)headers + rv); - hlen -= rv; - } - /* - * send file, next - */ - while ((rlen = PR_Read(fd, buf, _TRANSMITFILE_BUFSIZE)) > 0) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen,0,PR_INTERVAL_NO_TIMEOUT); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - count += rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - if (rlen == 0) { - /* - * end-of-file - */ - if (flags & PR_TRANSMITFILE_CLOSE_SOCKET) - PR_Close(sd); - rv = count; - } else { - PR_ASSERT(rlen < 0); - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - } - -done: - if (buf) - PR_DELETE(buf); - return rv; -} -#else - -#define TRANSMITFILE_MMAP_CHUNK (256 * 1024) - -/* - * _PR_UnixTransmitFile - * - * Send file fd across socket sd. If headers is non-NULL, 'hlen' - * bytes of headers is sent before sending the file. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ - -PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout) -{ - void * addr = NULL; - PRFileMap * mapHandle = NULL; - PRInt32 count = 0; - PRInt32 index = 0; - PRInt32 len = 0; - PRInt32 rv; - struct PRFileInfo info; - struct PRIOVec iov[2]; - - /* Get file size */ - if (PR_SUCCESS != PR_GetOpenFileInfo(fd, &info)) { - count = -1; - goto done; - } - if (hlen) { - iov[index].iov_base = (char *) headers; - iov[index].iov_len = hlen; - index++; - } - if (info.size > 0) { - mapHandle = PR_CreateFileMap(fd, info.size, PR_PROT_READONLY); - if (mapHandle == NULL) { - count = -1; - goto done; - } - /* - * If the file is large, mmap and send the file in chunks so as - * to not consume too much virtual address space - */ - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - /* - * Map in (part of) file. Take care of zero-length files. - */ - if (len) { - addr = PR_MemMap(mapHandle, 0, len); - if (addr == NULL) { - count = -1; - goto done; - } - } - iov[index].iov_base = (char*)addr; - iov[index].iov_len = len; - index++; - } - if (!index) - goto done; - rv = PR_Writev(sd, iov, index, timeout); - if (len) { - PR_MemUnmap(addr, len); - } - if (rv >= 0) { - PR_ASSERT(rv == hlen + len); - info.size -= len; - count += rv; - } else { - count = -1; - goto done; - } - /* - * send remaining bytes of the file, if any - */ - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - while (len > 0) { - /* - * Map in (part of) file - */ - PR_ASSERT((count - hlen) % TRANSMITFILE_MMAP_CHUNK == 0); - addr = PR_MemMap(mapHandle, count - hlen, len); - if (addr == NULL) { - count = -1; - goto done; - } - rv = PR_Send(sd, addr, len, 0, timeout); - PR_MemUnmap(addr, len); - if (rv >= 0) { - PR_ASSERT(rv == len); - info.size -= rv; - count += rv; - len = PR_MIN(info.size , TRANSMITFILE_MMAP_CHUNK ); - } else { - count = -1; - goto done; - } - } -done: - if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - if (mapHandle != NULL) - PR_CloseFileMap(mapHandle); - return count; -} -#endif /* XP_UNIX || WIN32 || XP_BEOS */ - - - - -#if !defined( XP_UNIX ) && !defined( WIN32 ) && !defined( XP_BEOS ) -/* - * _PR_EmulateSendFile - * - * Send file sfd->fd across socket sd. The header and trailer buffers - * specified in the 'sfd' argument are sent before and after the file, - * respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ - -PRInt32 -ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - char * buf = NULL; - const void * buffer; - PRInt32 rv; - PRInt32 count = 0; - PRInt32 rlen; - PRInt32 buflen; - PRInt32 sendbytes; - PRInt32 readbytes; - -#define _SENDFILE_BUFSIZE (16 * 1024) - - buf = (char*)PR_MALLOC(_SENDFILE_BUFSIZE); - if (buf == NULL) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return -1; - } - - /* - * send header, first - */ - buflen = sfd->hlen; - buffer = sfd->header; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - /* - * send file, next - */ - - if (PR_Seek(sfd->fd, sfd->file_offset, PR_SEEK_SET) < 0) { - rv = -1; - goto done; - } - sendbytes = sfd->file_nbytes; - if (sendbytes == 0) { - /* send entire file */ - while ((rlen = PR_Read(sfd->fd, buf, _SENDFILE_BUFSIZE)) > 0) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } - } else { - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - while (readbytes && ((rlen = PR_Read(sfd->fd, buf, readbytes)) > 0)) { - while (rlen) { - char *bufptr = buf; - - rv = PR_Send(sd, bufptr, rlen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - sendbytes -= rv; - bufptr = ((char*)bufptr + rv); - rlen -= rv; - } - } - readbytes = PR_MIN(sendbytes, _SENDFILE_BUFSIZE); - } - if (rlen < 0) { - /* PR_Read() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else if (sendbytes != 0) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = -1; - goto done; - } - } - /* - * send trailer, last - */ - buflen = sfd->tlen; - buffer = sfd->trailer; - while (buflen) { - rv = PR_Send(sd, buffer, buflen, 0, timeout); - if (rv < 0) { - /* PR_Send() has invoked PR_SetError(). */ - rv = -1; - goto done; - } else { - count += rv; - buffer = (const void*) ((const char*)buffer + rv); - buflen -= rv; - } - } - rv = count; - -done: - if (buf) - PR_DELETE(buf); - if ((rv >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return rv; -} - -#else /* UNIX, NT, and BEOS handled below */ - -/* - * _PR_UnixSendFile - * - * Send file sfd->fd across socket sd. If header/trailer are specified - * they are sent before and after the file, respectively. - * - * PR_TRANSMITFILE_CLOSE_SOCKET flag - close socket after sending file - * - * return number of bytes sent or -1 on error - * - */ -#define SENDFILE_MMAP_CHUNK (256 * 1024) - -PRInt32 -ssl_EmulateSendFile(PRFileDesc *sd, PRSendFileData *sfd, - PRTransmitFileFlags flags, PRIntervalTime timeout) -{ - void * addr = NULL; - PRFileMap * mapHandle = NULL; - PRInt32 count = 0; - PRInt32 file_bytes; - PRInt32 index = 0; - PRInt32 len; - PRInt32 rv; - PRUint32 addr_offset; - PRUint32 file_mmap_offset; - PRUint32 mmap_len; - PRUint32 pagesize; - struct PRFileInfo info; - struct PRIOVec iov[3]; - - /* Get file size */ - if (PR_SUCCESS != PR_GetOpenFileInfo(sfd->fd, &info)) { - count = -1; - goto done; - } - if (sfd->file_nbytes && - (info.size < (sfd->file_offset + sfd->file_nbytes))) { - /* - * there are fewer bytes in file to send than specified - */ - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - count = -1; - goto done; - } - if (sfd->file_nbytes) - file_bytes = sfd->file_nbytes; - else - file_bytes = info.size - sfd->file_offset; - -#if defined(WIN32) - { - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - pagesize = sysinfo.dwAllocationGranularity; - } -#else - pagesize = PR_GetPageSize(); -#endif - /* - * If the file is large, mmap and send the file in chunks so as - * to not consume too much virtual address space - */ - if (!sfd->file_offset || !(sfd->file_offset & (pagesize - 1))) { - /* - * case 1: page-aligned file offset - */ - mmap_len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - len = mmap_len; - file_mmap_offset = sfd->file_offset; - addr_offset = 0; - } else { - /* - * case 2: non page-aligned file offset - */ - /* find previous page boundary */ - file_mmap_offset = (sfd->file_offset & ~(pagesize - 1)); - - /* number of initial bytes to skip in mmap'd segment */ - addr_offset = sfd->file_offset - file_mmap_offset; - PR_ASSERT(addr_offset > 0); - mmap_len = PR_MIN(file_bytes + addr_offset, SENDFILE_MMAP_CHUNK); - len = mmap_len - addr_offset; - } - /* - * OK I've convinced myself that length has to be possitive (file_bytes is - * negative or SENDFILE_MMAP_CHUNK is less than pagesize). Just assert - * that this is the case so we catch problems in debug builds. - */ - PR_ASSERT(len >= 0); - - /* - * Map in (part of) file. Take care of zero-length files. - */ - if (len > 0) { - mapHandle = PR_CreateFileMap(sfd->fd, info.size, PR_PROT_READONLY); - if (!mapHandle) { - count = -1; - goto done; - } - addr = PR_MemMap(mapHandle, file_mmap_offset, mmap_len); - if (!addr) { - count = -1; - goto done; - } - } - /* - * send headers, first, followed by the file - */ - if (sfd->hlen) { - iov[index].iov_base = (char *) sfd->header; - iov[index].iov_len = sfd->hlen; - index++; - } - if (len) { - iov[index].iov_base = (char*)addr + addr_offset; - iov[index].iov_len = len; - index++; - } - if ((file_bytes == len) && (sfd->tlen)) { - /* - * all file data is mapped in; send the trailer too - */ - iov[index].iov_base = (char *) sfd->trailer; - iov[index].iov_len = sfd->tlen; - index++; - } - rv = PR_Writev(sd, iov, index, timeout); - if (len) - PR_MemUnmap(addr, mmap_len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == sfd->hlen + len + ((len == file_bytes) ? sfd->tlen : 0)); - - file_bytes -= len; - count += rv; - if (!file_bytes) /* header, file and trailer are sent */ - goto done; - - /* - * send remaining bytes of the file, if any - */ - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - while (len > 0) { - /* - * Map in (part of) file - */ - file_mmap_offset = sfd->file_offset + count - sfd->hlen; - PR_ASSERT((file_mmap_offset % pagesize) == 0); - - addr = PR_MemMap(mapHandle, file_mmap_offset, len); - if (!addr) { - count = -1; - goto done; - } - rv = PR_Send(sd, addr, len, 0, timeout); - PR_MemUnmap(addr, len); - if (rv < 0) { - count = -1; - goto done; - } - - PR_ASSERT(rv == len); - file_bytes -= rv; - count += rv; - len = PR_MIN(file_bytes, SENDFILE_MMAP_CHUNK); - } - PR_ASSERT(0 == file_bytes); - if (sfd->tlen) { - rv = PR_Send(sd, sfd->trailer, sfd->tlen, 0, timeout); - if (rv >= 0) { - PR_ASSERT(rv == sfd->tlen); - count += rv; - } else - count = -1; - } -done: - if (mapHandle) - PR_CloseFileMap(mapHandle); - if ((count >= 0) && (flags & PR_TRANSMITFILE_CLOSE_SOCKET)) - PR_Close(sd); - return count; -} -#endif /* UNIX, NT, and BEOS */ diff --git a/security/nss/lib/ssl/manifest.mn b/security/nss/lib/ssl/manifest.mn index 6428ce5c7..06e2eb118 100644 --- a/security/nss/lib/ssl/manifest.mn +++ b/security/nss/lib/ssl/manifest.mn @@ -56,7 +56,6 @@ MAPFILE = $(OBJDIR)/ssl.def CSRCS = \ derive.c \ - emulate.c \ prelib.c \ ssl3con.c \ ssl3gthr.c \ diff --git a/security/nss/lib/ssl/ssl.def b/security/nss/lib/ssl/ssl.def index 745934e92..ae12b2bf5 100644 --- a/security/nss/lib/ssl/ssl.def +++ b/security/nss/lib/ssl/ssl.def @@ -126,3 +126,10 @@ SSL_ShutdownServerSessionIDCache; ;+ local: ;+*; ;+}; +;+NSS_3.11.4 { # NSS 3.11.4 release +;+ global: +SSL_ForceHandshakeWithTimeout; +SSL_ReHandshakeWithTimeout; +;+ local: +;+*; +;+}; diff --git a/security/nss/lib/ssl/ssl.rc b/security/nss/lib/ssl/ssl.rc index b20493219..b7d827de7 100644 --- a/security/nss/lib/ssl/ssl.rc +++ b/security/nss/lib/ssl/ssl.rc @@ -84,11 +84,10 @@ BEGIN BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN - VALUE "CompanyName", "Netscape Communications Corporation\0" + VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", NSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" - VALUE "LegalCopyright", "Copyright \251 1994-2001 Netscape Communications Corporation\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services\0" VALUE "ProductVersion", NSS_VERSION "\0" diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c index 2b34b9519..bf37f19d3 100644 --- a/security/nss/lib/ssl/ssl3con.c +++ b/security/nss/lib/ssl/ssl3con.c @@ -74,7 +74,7 @@ static void ssl3_CleanupPeerCerts(sslSocket *ss); static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec, PK11SlotInfo * serverKeySlot); -static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms); +static SECStatus ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms); static SECStatus ssl3_DeriveConnectionKeysPKCS11(sslSocket *ss); static SECStatus ssl3_HandshakeFailure( sslSocket *ss); static SECStatus ssl3_InitState( sslSocket *ss); @@ -103,6 +103,10 @@ static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, */ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { /* cipher_suite policy enabled is_present*/ +#ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#endif /* NSS_ENABLE_ECC */ { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC @@ -112,7 +116,9 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { TLS_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #endif /* NSS_ENABLE_ECC */ { TLS_DHE_DSS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, @@ -128,6 +134,10 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, +#endif /* NSS_ENABLE_ECC */ { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, #ifdef NSS_ENABLE_ECC @@ -140,10 +150,6 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, -#ifdef NSS_ENABLE_ECC - { TLS_ECDH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, - { TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, -#endif /* NSS_ENABLE_ECC */ { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, { TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, @@ -153,6 +159,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, #ifdef NSS_ENABLE_ECC + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_NOT_ALLOWED, PR_FALSE, PR_FALSE}, #endif /* NSS_ENABLE_ECC */ @@ -236,6 +244,7 @@ static const ssl3KEADef kea_defs[] = {kea_ecdhe_ecdsa, kt_ecdh, sign_ecdsa, PR_FALSE, 0, PR_FALSE}, {kea_ecdh_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, {kea_ecdhe_rsa, kt_ecdh, sign_rsa, PR_FALSE, 0, PR_FALSE}, + {kea_ecdh_anon, kt_ecdh, sign_null, PR_FALSE, 0, PR_FALSE}, #endif /* NSS_ENABLE_ECC */ }; @@ -315,24 +324,37 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips}, #ifdef NSS_ENABLE_ECC - /* Experimental TLS cipher suites using Elliptic Curves */ {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa}, - {TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_ecdsa}, {TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDH_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_rsa}, - {TLS_ECDH_RSA_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_rsa}, {TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_rsa}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_ecdsa}, + {TLS_ECDHE_RSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa}, + {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdhe_rsa}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdhe_rsa}, +#if 0 + {TLS_ECDH_anon_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_AES_128_CBC_SHA, cipher_aes_128, mac_sha, kea_ecdh_anon}, + {TLS_ECDH_anon_WITH_AES_256_CBC_SHA, cipher_aes_256, mac_sha, kea_ecdh_anon}, +#endif #endif /* NSS_ENABLE_ECC */ }; @@ -395,6 +417,29 @@ const char * const ssl3_cipherName[] = { "missing" }; +#ifdef NSS_ENABLE_ECC +/* The ECCWrappedKeyInfo structure defines how various pieces of + * information are laid out within wrappedSymmetricWrappingkey + * for ECDH key exchange. Since wrappedSymmetricWrappingkey is + * a 512-byte buffer (see sslimpl.h), the variable length field + * in ECCWrappedKeyInfo can be at most (512 - 8) = 504 bytes. + * + * XXX For now, NSS only supports named elliptic curves of size 571 bits + * or smaller. The public value will fit within 145 bytes and EC params + * will fit within 12 bytes. We'll need to revisit this when NSS + * supports arbitrary curves. + */ +#define MAX_EC_WRAPPED_KEY_BUFLEN 504 + +typedef struct ECCWrappedKeyInfoStr { + PRUint16 size; /* EC public key size in bits */ + PRUint16 encodedParamLen; /* length (in bytes) of DER encoded EC params */ + PRUint16 pubValueLen; /* length (in bytes) of EC public value */ + PRUint16 wrappedKeyLen; /* length (in bytes) of the wrapped key */ + PRUint8 var[MAX_EC_WRAPPED_KEY_BUFLEN]; /* this buffer contains the */ + /* EC public-key params, the EC public value and the wrapped key */ +} ECCWrappedKeyInfo; +#endif /* NSS_ENABLE_ECC */ #if defined(TRACE) @@ -450,6 +495,26 @@ SSL_GetStatistics(void) return &ssl3stats; } +typedef struct tooLongStr { +#if defined(IS_LITTLE_ENDIAN) + PRInt32 low; + PRInt32 high; +#else + PRInt32 high; + PRInt32 low; +#endif +} tooLong; + +static void SSL_AtomicIncrementLong(long * x) +{ + if ((sizeof *x) == sizeof(PRInt32)) { + PR_AtomicIncrement((PRInt32 *)x); + } else { + tooLong * tl = (tooLong *)x; + PR_AtomicIncrement(&tl->low) || PR_AtomicIncrement(&tl->high); + } +} + /* return pointer to ssl3CipherSuiteDef for suite, or NULL */ /* XXX This does a linear search. A binary search would be better. */ static const ssl3CipherSuiteDef * @@ -504,10 +569,15 @@ ssl3_config_match_init(sslSocket *ss) PRBool isServer; sslServerCerts *svrAuth; + PORT_Assert(ss); + if (!ss) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return 0; + } if (!ss->opt.enableSSL3 && !ss->opt.enableTLS) { return 0; } - isServer = (PRBool)( ss && ss->sec.isServer ); + isServer = (PRBool)(ss->sec.isServer != 0); for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) { suite = &ss->cipherSuites[i]; @@ -536,7 +606,15 @@ ssl3_config_match_init(sslSocket *ss) */ switch (cipher_def->key_exchange_alg) { case kea_ecdhe_rsa: +#if NSS_SERVER_DHE_IMPLEMENTED + /* XXX NSS does not yet implement the server side of _DHE_ + * cipher suites. Correcting the computation for svrAuth, + * as the case below does, causes NSS SSL servers to begin to + * negotiate cipher suites they do not implement. So, until + * server side _DHE_ is implemented, keep this disabled. + */ case kea_dhe_rsa: +#endif svrAuth = ss->serverCerts + kt_rsa; break; case kea_ecdh_ecdsa: @@ -715,7 +793,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, } buf->len = (unsigned)signatureLen; - buf->data = (unsigned char *)PORT_Alloc(signatureLen + 1); + buf->data = (unsigned char *)PORT_Alloc(signatureLen); if (!buf->data) goto done; /* error code was set. */ @@ -749,7 +827,7 @@ ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, SECItem *buf, SECItem derSig = {siBuffer, NULL, 0}; /* This also works for an ECDSA signature */ - rv = DSAU_EncodeDerSigWithLen(&derSig, buf, (unsigned) signatureLen); + rv = DSAU_EncodeDerSigWithLen(&derSig, buf, buf->len); if (rv == SECSuccess) { PORT_Free(buf->data); /* discard unencoded signature. */ *buf = derSig; /* give caller encoded signature. */ @@ -818,7 +896,7 @@ ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, * using ASN (unlike DSA where ASN encoding is used * with TLS but not with SSL3) */ - len = SECKEY_PublicKeyStrength(key) * 2; + len = SECKEY_SignatureLen(key); if (len == 0) { SECKEY_DestroyPublicKey(key); PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); @@ -1693,32 +1771,164 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) { return isPresent; } +static SECStatus +ssl3_CompressMACEncryptRecord(sslSocket * ss, + SSL3ContentType type, + const SSL3Opaque * pIn, + PRUint32 contentLen) +{ + ssl3CipherSpec * cwSpec; + const ssl3BulkCipherDef * cipher_def; + sslBuffer * wrBuf = &ss->sec.writeBuf; + SECStatus rv; + PRUint32 macLen = 0; + PRUint32 fragLen; + PRUint32 p1Len, p2Len, oddLen = 0; + PRInt32 cipherBytes = 0; + + /* + * null compression is easy to do + PORT_Memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, pIn, contentLen); + */ + + ssl_GetSpecReadLock(ss); /********************************/ + + cwSpec = ss->ssl3.cwSpec; + cipher_def = cwSpec->cipher_def; + /* + * Add the MAC + */ + rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), + type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen, + wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); + if (rv != SECSuccess) { + ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); + goto spec_locked_loser; + } + p1Len = contentLen; + p2Len = macLen; + fragLen = contentLen + macLen; /* needs to be encrypted */ + PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); + + /* + * Pad the text (if we're doing a block cipher) + * then Encrypt it + */ + if (cipher_def->type == type_block) { + unsigned char * pBuf; + int padding_length; + int i; + + oddLen = contentLen % cipher_def->block_size; + /* Assume blockSize is a power of two */ + padding_length = cipher_def->block_size - 1 - + ((fragLen) & (cipher_def->block_size - 1)); + fragLen += padding_length + 1; + PORT_Assert((fragLen % cipher_def->block_size) == 0); + + /* Pad according to TLS rules (also acceptable to SSL3). */ + pBuf = &wrBuf->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1]; + for (i = padding_length + 1; i > 0; --i) { + *pBuf-- = padding_length; + } + /* now, if contentLen is not a multiple of block size, fix it */ + p2Len = fragLen - p1Len; + } + if (p1Len < 256) { + oddLen = p1Len; + p1Len = 0; + } else { + p1Len -= oddLen; + } + if (oddLen) { + p2Len += oddLen; + PORT_Assert( (cipher_def->block_size < 2) || \ + (p2Len % cipher_def->block_size) == 0); + memcpy(wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + pIn + p1Len, oddLen); + } + if (p1Len > 0) { + rv = cwSpec->encode( cwSpec->encodeContext, + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, /* output */ + &cipherBytes, /* actual outlen */ + p1Len, /* max outlen */ + pIn, p1Len); /* input, and inputlen */ + PORT_Assert(rv == SECSuccess && cipherBytes == p1Len); + if (rv != SECSuccess || cipherBytes != p1Len) { + PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); + goto spec_locked_loser; + } + } + if (p2Len > 0) { + PRInt32 cipherBytesPart2 = -1; + rv = cwSpec->encode( cwSpec->encodeContext, + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + &cipherBytesPart2, /* output and actual outLen */ + p2Len, /* max outlen */ + wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, + p2Len); /* input and inputLen*/ + PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len); + if (rv != SECSuccess || cipherBytesPart2 != p2Len) { + PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); + goto spec_locked_loser; + } + cipherBytes += cipherBytesPart2; + } + PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024); + + ssl3_BumpSequenceNumber(&cwSpec->write_seq_num); + + wrBuf->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH; + wrBuf->buf[0] = type; + wrBuf->buf[1] = MSB(cwSpec->version); + wrBuf->buf[2] = LSB(cwSpec->version); + wrBuf->buf[3] = MSB(cipherBytes); + wrBuf->buf[4] = LSB(cipherBytes); + + ssl_ReleaseSpecReadLock(ss); /************************************/ + + return SECSuccess; + +spec_locked_loser: + ssl_ReleaseSpecReadLock(ss); + return SECFailure; +} + /* Process the plain text before sending it. * Returns the number of bytes of plaintext that were succesfully sent * plus the number of bytes of plaintext that were copied into the * output (write) buffer. * Returns SECFailure on a hard IO error, memory error, or crypto error. * Does NOT return SECWouldBlock. + * + * Notes on the use of the private ssl flags: + * (no private SSL flags) + * Attempt to make and send SSL records for all plaintext + * If non-blocking and a send gets WOULD_BLOCK, + * or if the pending (ciphertext) buffer is not empty, + * then buffer remaining bytes of ciphertext into pending buf, + * and continue to do that for all succssive records until all + * bytes are used. + * ssl_SEND_FLAG_FORCE_INTO_BUFFER + * As above, except this suppresses all write attempts, and forces + * all ciphertext into the pending ciphertext buffer. + * */ static PRInt32 ssl3_SendRecord( sslSocket * ss, SSL3ContentType type, - const SSL3Opaque * buf, - PRInt32 bytes, + const SSL3Opaque * pIn, /* input buffer */ + PRInt32 nIn, /* bytes of input */ PRInt32 flags) { - ssl3CipherSpec * cwSpec; - sslBuffer * write = &ss->sec.writeBuf; - const ssl3BulkCipherDef * cipher_def; + sslBuffer * wrBuf = &ss->sec.writeBuf; SECStatus rv; - PRUint32 bufSize = 0; - PRInt32 sent = 0; - PRBool isBlocking = ssl_SocketIsBlocking(ss); + PRInt32 totalSent = 0; - SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s bytes=%d", + SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), - bytes)); - PRINT_BUF(3, (ss, "Send record (plain text)", buf, bytes)); + nIn)); + PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); @@ -1740,149 +1950,30 @@ ssl3_SendRecord( sslSocket * ss, return SECFailure; } - while (bytes > 0) { - PRInt32 count; - PRUint32 contentLen; - PRUint32 fragLen; - PRUint32 macLen; - PRInt32 cipherBytes = 0; - PRUint32 p1Len, p2Len, oddLen = 0; + while (nIn > 0) { + PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); - contentLen = PR_MIN(bytes, MAX_FRAGMENT_LENGTH); - if (write->space < contentLen + SSL3_BUFFER_FUDGE) { - rv = sslBuffer_Grow(write, contentLen + SSL3_BUFFER_FUDGE); + if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) { + PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen); + newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH); + newSpace += SSL3_BUFFER_FUDGE; + rv = sslBuffer_Grow(wrBuf, newSpace); if (rv != SECSuccess) { SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", - SSL_GETPID(), ss->fd, contentLen + SSL3_BUFFER_FUDGE)); + SSL_GETPID(), ss->fd, newSpace)); return SECFailure; /* sslBuffer_Grow set a memory error code. */ } } - /* This variable records the actual size of the buffer allocated above. - * Some algorithms may expand the number of bytes needed to send data. - * If we only supply the output buffer with the same number - * of bytes as the input buffer, we will fail. - */ - bufSize = contentLen + SSL3_BUFFER_FUDGE; - - /* - * null compression is easy to do - PORT_Memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH, buf, contentLen); - */ - - ssl_GetSpecReadLock(ss); /********************************/ - - cwSpec = ss->ssl3.cwSpec; - cipher_def = cwSpec->cipher_def; - /* - * Add the MAC - */ - rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer), - type, cwSpec->version, cwSpec->write_seq_num, buf, contentLen, - write->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen); - if (rv != SECSuccess) { - ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); - goto spec_locked_loser; - } - p1Len = contentLen; - p2Len = macLen; - fragLen = contentLen + macLen; /* needs to be encrypted */ - PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); - - /* - * Pad the text (if we're doing a block cipher) - * then Encrypt it - */ - if (cipher_def->type == type_block) { - unsigned char * pBuf; - int padding_length; - int i; - - oddLen = contentLen % cipher_def->block_size; - /* Assume blockSize is a power of two */ - padding_length = cipher_def->block_size - 1 - - ((fragLen) & (cipher_def->block_size - 1)); - fragLen += padding_length + 1; - PORT_Assert((fragLen % cipher_def->block_size) == 0); - - /* Pad according to TLS rules (also acceptable to SSL3). */ - pBuf = &write->buf[fragLen + SSL3_RECORD_HEADER_LENGTH - 1]; - for (i = padding_length + 1; i > 0; --i) { - *pBuf-- = padding_length; - } - /* now, if contentLen is not a multiple of block size, fix it */ - p2Len = fragLen - p1Len; - } - if (p1Len < 256) { - oddLen = p1Len; - p1Len = 0; - } else { - p1Len -= oddLen; - } - if (oddLen) { - p2Len += oddLen; - PORT_Assert( (cipher_def->block_size < 2) || \ - (p2Len % cipher_def->block_size) == 0); - memcpy(write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - buf + p1Len, oddLen); - } - if (p1Len > 0) { - rv = cwSpec->encode( cwSpec->encodeContext, - write->buf + SSL3_RECORD_HEADER_LENGTH, /* output */ - &cipherBytes, /* actual outlen */ - p1Len, /* max outlen */ - buf, p1Len); /* input, and inputlen */ - PORT_Assert(rv == SECSuccess && cipherBytes == p1Len); - if (rv != SECSuccess || cipherBytes != p1Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); - goto spec_locked_loser; - } - } - if (p2Len > 0) { - PRInt32 cipherBytesPart2 = -1; - rv = cwSpec->encode( cwSpec->encodeContext, - write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - &cipherBytesPart2, /* output and actual outLen */ - p2Len, /* max outlen */ - write->buf + SSL3_RECORD_HEADER_LENGTH + p1Len, - p2Len); /* input and inputLen*/ - PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len); - if (rv != SECSuccess || cipherBytesPart2 != p2Len) { - PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); - goto spec_locked_loser; - } - cipherBytes += cipherBytesPart2; - } - if (rv != SECSuccess) { - ssl_MapLowLevelError(SSL_ERROR_ENCRYPTION_FAILURE); -spec_locked_loser: - ssl_ReleaseSpecReadLock(ss); + rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen); + if (rv != SECSuccess) return SECFailure; - } - PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024); - /* - * XXX should we zero out our copy of the buffer after compressing - * and encryption ?? - */ - - ssl3_BumpSequenceNumber(&cwSpec->write_seq_num); - - ssl_ReleaseSpecReadLock(ss); /************************************/ - - buf += contentLen; - bytes -= contentLen; - PORT_Assert( bytes >= 0 ); + pIn += contentLen; + nIn -= contentLen; + PORT_Assert( nIn >= 0 ); - /* PORT_Assert(fragLen == cipherBytes); */ - write->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH; - write->buf[0] = type; - write->buf[1] = MSB(cwSpec->version); - write->buf[2] = LSB(cwSpec->version); - write->buf[3] = MSB(cipherBytes); - write->buf[4] = LSB(cipherBytes); - - PRINT_BUF(50, (ss, "send (encrypted) record data:", write->buf, write->len)); + PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len)); /* If there's still some previously saved ciphertext, * or the caller doesn't want us to send the data yet, @@ -1891,59 +1982,57 @@ spec_locked_loser: if ((ss->pendingBuf.len > 0) || (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - rv = ssl_SaveWriteData(ss, &ss->pendingBuf, - write->buf, write->len); + rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ return SECFailure; } - write->len = 0; /* All cipher text is saved away. */ + wrBuf->len = 0; /* All cipher text is saved away. */ if (!(flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) { - + PRInt32 sent; ss->handshakeBegun = 1; - count = ssl_SendSavedWriteData(ss, &ss->pendingBuf, - &ssl_DefSend); - if (count < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) { + sent = ssl_SendSavedWriteData(ss); + if (sent < 0 && PR_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); return SECFailure; } + if (ss->pendingBuf.len) { + flags |= ssl_SEND_FLAG_FORCE_INTO_BUFFER; + } } - } else if (write->len > 0) { + } else if (wrBuf->len > 0) { + PRInt32 sent; ss->handshakeBegun = 1; - count = ssl_DefSend(ss, write->buf, write->len, - flags & ~ssl_SEND_FLAG_MASK); - if (count < 0) { + sent = ssl_DefSend(ss, wrBuf->buf, wrBuf->len, + flags & ~ssl_SEND_FLAG_MASK); + if (sent < 0) { if (PR_GetError() != PR_WOULD_BLOCK_ERROR) { ssl_MapLowLevelError(SSL_ERROR_SOCKET_WRITE_FAILURE); - return (sent > 0) ? sent : SECFailure; + return SECFailure; } /* we got PR_WOULD_BLOCK_ERROR, which means none was sent. */ - count = 0; + sent = 0; } - /* now take all the remaining unsent newly-generated ciphertext and - * append it to the buffer of previously unsent ciphertext. - */ - if ((unsigned)count < write->len) { - rv = ssl_SaveWriteData(ss, &ss->pendingBuf, - write->buf + (unsigned)count, - write->len - (unsigned)count); + wrBuf->len -= sent; + if (wrBuf->len) { + /* now take all the remaining unsent new ciphertext and + * append it to the buffer of previously unsent ciphertext. + */ + rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); if (rv != SECSuccess) { /* presumably a memory error, SEC_ERROR_NO_MEMORY */ return SECFailure; } } - write->len = 0; - } - sent += contentLen; - if ((flags & ssl_SEND_FLAG_NO_BUFFER) && - (isBlocking || (ss->pendingBuf.len > 0))) { - break; } + totalSent += contentLen; } - return sent; + return totalSent; } +#define SSL3_PENDING_HIGH_WATER 1024 + /* Attempt to send the content of "in" in an SSL application_data record. * Returns "len" or SECFailure, never SECWouldBlock, nor SECSuccess. */ @@ -1951,14 +2040,36 @@ int ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, PRInt32 len, PRInt32 flags) { - PRInt32 sent = 0; + PRInt32 totalSent = 0; + PRInt32 discarded = 0; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); + if (len < 0 || !in) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return SECFailure; + } + + if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && + !ssl_SocketIsBlocking(ss)) { + PORT_Assert(!ssl_SocketIsBlocking(ss)); + PORT_SetError(PR_WOULD_BLOCK_ERROR); + return SECFailure; + } - while (len > 0) { - PRInt32 count; + if (ss->appDataBuffered && len) { + PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); + if (in[0] != (unsigned char)(ss->appDataBuffered)) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return SECFailure; + } + in++; + len--; + discarded = 1; + } + while (len > totalSent) { + PRInt32 sent, toSend; - if (sent > 0) { + if (totalSent > 0) { /* * The thread yield is intended to give the reader thread a * chance to get some cycles while the writer thread is in @@ -1969,23 +2080,45 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, PR_Sleep(PR_INTERVAL_NO_WAIT); /* PR_Yield(); */ ssl_GetXmitBufLock(ss); } - count = ssl3_SendRecord(ss, content_application_data, in, len, - flags | ssl_SEND_FLAG_NO_BUFFER); - if (count < 0) { - return (sent > 0) ? sent : count; - /* error code set by ssl3_SendRecord */ + toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH); + sent = ssl3_SendRecord(ss, content_application_data, + in + totalSent, toSend, flags); + if (sent < 0) { + if (totalSent > 0 && PR_GetError() == PR_WOULD_BLOCK_ERROR) { + PORT_Assert(ss->lastWriteBlocked); + break; + } + return SECFailure; /* error code set by ssl3_SendRecord */ + } + totalSent += sent; + if (ss->pendingBuf.len) { + /* must be a non-blocking socket */ + PORT_Assert(!ssl_SocketIsBlocking(ss)); + PORT_Assert(ss->lastWriteBlocked); + break; } - sent += count; - len -= count; - in += count; } - return sent; + if (ss->pendingBuf.len) { + /* Must be non-blocking. */ + PORT_Assert(!ssl_SocketIsBlocking(ss)); + if (totalSent > 0) { + ss->appDataBuffered = 0x100 | in[totalSent - 1]; + } + + totalSent = totalSent + discarded - 1; + if (totalSent <= 0) { + PORT_SetError(PR_WOULD_BLOCK_ERROR); + totalSent = SECFailure; + } + return totalSent; + } + ss->appDataBuffered = 0; + return totalSent + discarded; } /* Attempt to send the content of sendBuf buffer in an SSL handshake record. * This function returns SECSuccess or SECFailure, never SECWouldBlock. - * It used to always set sendBuf.len to 0, even when returning SECFailure. - * Now it does not. + * Always set sendBuf.len to 0, even when returning SECFailure. * * Called from SSL3_SendAlert(), ssl3_SendChangeCipherSpecs(), * ssl3_AppendHandshake(), ssl3_SendClientHello(), @@ -1995,21 +2128,41 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in, static SECStatus ssl3_FlushHandshake(sslSocket *ss, PRInt32 flags) { - PRInt32 rv; + PRInt32 rv = SECSuccess; PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); if (!ss->sec.ci.sendBuf.buf || !ss->sec.ci.sendBuf.len) - return SECSuccess; + return rv; - rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf, - ss->sec.ci.sendBuf.len, flags); - if (rv < 0) { - return (SECStatus)rv; /* error code set by ssl3_SendRecord */ + /* only this flag is allowed */ + PORT_Assert(!(flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER)); + if ((flags & ~ssl_SEND_FLAG_FORCE_INTO_BUFFER) != 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; + } else { + rv = ssl3_SendRecord(ss, content_handshake, ss->sec.ci.sendBuf.buf, + ss->sec.ci.sendBuf.len, flags); } + if (rv < 0) { + int err = PORT_GetError(); + PORT_Assert(err != PR_WOULD_BLOCK_ERROR); + if (err == PR_WOULD_BLOCK_ERROR) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + } + } else if (rv < ss->sec.ci.sendBuf.len) { + /* short write should never happen */ + PORT_Assert(rv >= ss->sec.ci.sendBuf.len); + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + } else { + rv = SECSuccess; + } + + /* Whether we succeeded or failed, toss the old handshake data. */ ss->sec.ci.sendBuf.len = 0; - return SECSuccess; + return rv; } /* @@ -2218,7 +2371,19 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffer *buf) case internal_error: error = SSL_ERROR_INTERNAL_ERROR_ALERT; break; case user_canceled: error = SSL_ERROR_USER_CANCELED_ALERT; break; case no_renegotiation: error = SSL_ERROR_NO_RENEGOTIATION_ALERT; break; - default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; + + /* Alerts for TLS client hello extensions */ + case unsupported_extension: + error = SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT; break; + case certificate_unobtainable: + error = SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT; break; + case unrecognized_name: + error = SSL_ERROR_UNRECOGNIZED_NAME_ALERT; break; + case bad_certificate_status_response: + error = SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT; break; + case bad_certificate_hash_value: + error = SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT; break; + default: error = SSL_ERROR_RX_UNKNOWN_ALERT; break; } if (level == alert_fatal) { ss->sec.uncache(ss->sec.ci.sid); @@ -2348,7 +2513,7 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) ss->ssl3.prSpec = ss->ssl3.crSpec; ss->ssl3.crSpec = prSpec; - ss->ssl3.hs.ws = wait_finished; + ss->ssl3.hs.ws = wait_finished; SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", SSL_GETPID(), ss->fd )); @@ -2369,7 +2534,7 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) ** Called from ssl3_InitPendingCipherSpec. prSpec is pwSpec. */ static SECStatus -ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms) +ssl3_DeriveMasterSecret(sslSocket *ss, PK11SymKey *pms) { ssl3CipherSpec * pwSpec = ss->ssl3.pwSpec; const ssl3KEADef *kea_def= ss->ssl3.hs.kea_def; @@ -2419,9 +2584,20 @@ ssl3_DeriveMasterSecret(sslSocket *ss, const PK11SymKey *pms) } if (pms != NULL) { - pwSpec->master_secret = PK11_DeriveWithFlags((PK11SymKey *)pms, - master_derive, ¶ms, key_derive, - CKA_DERIVE, 0, keyFlags); +#if defined(TRACE) + if (ssl_trace >= 100) { + SECStatus extractRV = PK11_ExtractKeyValue(pms); + if (extractRV == SECSuccess) { + SECItem * keyData = PK11_GetKeyData(pms); + if (keyData && keyData->data && keyData->len) { + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); + } + } + } +#endif + pwSpec->master_secret = PK11_DeriveWithFlags(pms, master_derive, + ¶ms, key_derive, CKA_DERIVE, 0, keyFlags); if (!isDH && pwSpec->master_secret && ss->opt.detectRollBack) { SSL3ProtocolVersion client_version; client_version = pms_version.major << 8 | pms_version.minor; @@ -2715,7 +2891,7 @@ ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes) return SECSuccess; } -static SECStatus +SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, PRInt32 lenSize) { SECStatus rv; @@ -2820,7 +2996,7 @@ ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, * Thus, the largest value that may be sent this way is 0x7fffffff. * On error, an alert has been sent, and a generic error code has been set. */ -static PRInt32 +PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length) { @@ -3192,6 +3368,7 @@ ssl3_SendClientHello(sslSocket *ss) int length; int num_suites; int actual_count = 0; + PRInt32 total_exten_len = 0; SSL_TRC(3, ("%d: SSL3[%d]: send client_hello handshake", SSL_GETPID(), ss->fd)); @@ -3269,7 +3446,7 @@ ssl3_SendClientHello(sslSocket *ss) } if (!sidOK) { - ++ssl3stats.sch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_not_ok ); (*ss->sec.uncache)(sid); ssl_FreeSID(sid); sid = NULL; @@ -3277,7 +3454,7 @@ ssl3_SendClientHello(sslSocket *ss) } if (sid) { - ++ssl3stats.sch_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits ); rv = ssl3_NegotiateVersion(ss, sid->version); if (rv != SECSuccess) @@ -3288,7 +3465,7 @@ ssl3_SendClientHello(sslSocket *ss) ss->ssl3.policy = sid->u.ssl3.policy; } else { - ++ssl3stats.sch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_misses ); rv = ssl3_NegotiateVersion(ss, SSL_LIBRARY_VERSION_3_1_TLS); if (rv != SECSuccess) @@ -3327,6 +3504,26 @@ ssl3_SendClientHello(sslSocket *ss) if (!num_suites) return SECFailure; /* ssl3_config_match_init has set error code. */ + if (ss->opt.enableTLS) { + PRUint32 maxBytes = 65535; /* 2^16 - 1 */ + PRInt32 extLen; + + extLen = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, NULL); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + total_exten_len += extLen; + + if (total_exten_len > 0) + total_exten_len += 2; + } +#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B) + else { /* SSL3 only */ + ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ + } +#endif + /* how many suites are permitted by policy and user preference? */ num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); if (!num_suites) @@ -3335,7 +3532,7 @@ ssl3_SendClientHello(sslSocket *ss) length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 + ((sid == NULL) ? 0 : sid->u.ssl3.sessionIDLength) + 2 + num_suites*sizeof(ssl3CipherSuite) + - 1 + compressionMethodsCount; + 1 + compressionMethodsCount + total_exten_len; rv = ssl3_AppendHandshakeHeader(ss, client_hello, length); if (rv != SECSuccess) { @@ -3409,6 +3606,24 @@ ssl3_SendClientHello(sslSocket *ss) } } + if (total_exten_len) { + PRUint32 maxBytes = total_exten_len - 2; + PRInt32 extLen; + + rv = ssl3_AppendHandshakeNumber(ss, maxBytes, 2); + if (rv != SECSuccess) { + return rv; /* err set by AppendHandshake. */ + } + + extLen = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, maxBytes, NULL); + if (extLen < 0) { + return SECFailure; + } + maxBytes -= extLen; + PORT_Assert(!maxBytes); + } + + rv = ssl3_FlushHandshake(ss, 0); if (rv != SECSuccess) { return rv; /* error code set by ssl3_FlushHandshake */ @@ -3470,6 +3685,7 @@ static const CK_MECHANISM_TYPE wrapMechanismList[SSL_NUM_WRAP_MECHS] = { CKM_CDMF_ECB, CKM_SKIPJACK_WRAP, CKM_SKIPJACK_CBC64, + CKM_AES_ECB, UNKNOWN_WRAP_MECHANISM }; @@ -3495,6 +3711,11 @@ ssl_UnwrapSymWrappingKey( { PK11SymKey * unwrappedWrappingKey = NULL; SECItem wrappedKey; +#ifdef NSS_ENABLE_ECC + PK11SymKey * Ks; + SECKEYPublicKey pubWrapKey; + ECCWrappedKeyInfo *ecWrapped; +#endif /* NSS_ENABLE_ECC */ /* found the wrapping key on disk. */ PORT_Assert(pWswk->symWrapMechanism == masterWrapMech); @@ -3515,6 +3736,60 @@ ssl_UnwrapSymWrappingKey( PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey, masterWrapMech, CKA_UNWRAP, 0); break; + +#ifdef NSS_ENABLE_ECC + case kt_ecdh: + /* + * For kt_ecdh, we first create an EC public key based on + * data stored with the wrappedSymmetricWrappingkey. Next, + * we do an ECDH computation involving this public key and + * the SSL server's (long-term) EC private key. The resulting + * shared secret is treated the same way as Fortezza's Ks, i.e., + * it is used to recover the symmetric wrapping key. + * + * The data in wrappedSymmetricWrappingkey is laid out as defined + * in the ECCWrappedKeyInfo structure. + */ + ecWrapped = (ECCWrappedKeyInfo *) pWswk->wrappedSymmetricWrappingkey; + + PORT_Assert(ecWrapped->encodedParamLen + ecWrapped->pubValueLen + + ecWrapped->wrappedKeyLen <= MAX_EC_WRAPPED_KEY_BUFLEN); + + if (ecWrapped->encodedParamLen + ecWrapped->pubValueLen + + ecWrapped->wrappedKeyLen > MAX_EC_WRAPPED_KEY_BUFLEN) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + goto loser; + } + + pubWrapKey.keyType = ecKey; + pubWrapKey.u.ec.size = ecWrapped->size; + pubWrapKey.u.ec.DEREncodedParams.len = ecWrapped->encodedParamLen; + pubWrapKey.u.ec.DEREncodedParams.data = ecWrapped->var; + pubWrapKey.u.ec.publicValue.len = ecWrapped->pubValueLen; + pubWrapKey.u.ec.publicValue.data = ecWrapped->var + + ecWrapped->encodedParamLen; + + wrappedKey.len = ecWrapped->wrappedKeyLen; + wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + + ecWrapped->pubValueLen; + + /* Derive Ks using ECDH */ + Ks = PK11_PubDeriveWithKDF(svrPrivKey, &pubWrapKey, PR_FALSE, NULL, + NULL, CKM_ECDH1_DERIVE, masterWrapMech, + CKA_DERIVE, 0, CKD_NULL, NULL, NULL); + if (Ks == NULL) { + goto loser; + } + + /* Use Ks to unwrap the wrapping key */ + unwrappedWrappingKey = PK11_UnwrapSymKey(Ks, masterWrapMech, NULL, + &wrappedKey, masterWrapMech, + CKA_UNWRAP, 0); + PK11_FreeSymKey(Ks); + + break; +#endif + default: /* Assert? */ SET_ERROR_CODE @@ -3580,7 +3855,6 @@ getWrappingKey( sslSocket * ss, CK_MECHANISM_TYPE masterWrapMech, void * pwArg) { - CERTCertificate * svrCert; SECKEYPrivateKey * svrPrivKey; SECKEYPublicKey * svrPubKey = NULL; PK11SymKey * unwrappedWrappingKey = NULL; @@ -3650,12 +3924,12 @@ getWrappingKey( sslSocket * ss, */ PORT_Memset(&wswk, 0, sizeof wswk); /* eliminate UMRs. */ - svrCert = ss->serverCerts[exchKeyType].serverCert; - svrPubKey = CERT_ExtractPublicKey(svrCert); + if (ss->serverCerts[exchKeyType].serverKeyPair) { + svrPubKey = ss->serverCerts[exchKeyType].serverKeyPair->pubKey; + } if (svrPubKey == NULL) { - /* CERT_ExtractPublicKey doesn't set error code */ - PORT_SetError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE); - goto loser; + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + goto loser; } wrappedKey.type = siBuffer; wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey); @@ -3667,6 +3941,12 @@ getWrappingKey( sslSocket * ss, /* wrap symmetric wrapping key in server's public key. */ switch (exchKeyType) { +#ifdef NSS_ENABLE_ECC + PK11SymKey * Ks; + SECKEYPublicKey *pubWrapKey = NULL; + SECKEYPrivateKey *privWrapKey = NULL; + ECCWrappedKeyInfo *ecWrapped; +#endif /* NSS_ENABLE_ECC */ case kt_rsa: asymWrapMechanism = CKM_RSA_PKCS; @@ -3674,6 +3954,94 @@ getWrappingKey( sslSocket * ss, unwrappedWrappingKey, &wrappedKey); break; +#ifdef NSS_ENABLE_ECC + case kt_ecdh: + /* + * We generate an ephemeral EC key pair. Perform an ECDH + * computation involving this ephemeral EC public key and + * the SSL server's (long-term) EC private key. The resulting + * shared secret is treated in the same way as Fortezza's Ks, + * i.e., it is used to wrap the wrapping key. To facilitate + * unwrapping in ssl_UnwrapWrappingKey, we also store all + * relevant info about the ephemeral EC public key in + * wswk.wrappedSymmetricWrappingkey and lay it out as + * described in the ECCWrappedKeyInfo structure. + */ + PORT_Assert(svrPubKey->keyType == ecKey); + if (svrPubKey->keyType != ecKey) { + /* something is wrong in sslsecur.c if this isn't an ecKey */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + rv = SECFailure; + goto ec_cleanup; + } + + privWrapKey = SECKEY_CreateECPrivateKey( + &svrPubKey->u.ec.DEREncodedParams, &pubWrapKey, NULL); + if ((privWrapKey == NULL) || (pubWrapKey == NULL)) { + rv = SECFailure; + goto ec_cleanup; + } + + /* Set the key size in bits */ + if (pubWrapKey->u.ec.size == 0) { + pubWrapKey->u.ec.size = SECKEY_PublicKeyStrengthInBits(svrPubKey); + } + + PORT_Assert(pubWrapKey->u.ec.DEREncodedParams.len + + pubWrapKey->u.ec.publicValue.len < MAX_EC_WRAPPED_KEY_BUFLEN); + if (pubWrapKey->u.ec.DEREncodedParams.len + + pubWrapKey->u.ec.publicValue.len >= MAX_EC_WRAPPED_KEY_BUFLEN) { + PORT_SetError(SEC_ERROR_INVALID_KEY); + rv = SECFailure; + goto ec_cleanup; + } + + /* Derive Ks using ECDH */ + Ks = PK11_PubDeriveWithKDF(svrPrivKey, pubWrapKey, PR_FALSE, NULL, + NULL, CKM_ECDH1_DERIVE, masterWrapMech, + CKA_DERIVE, 0, CKD_NULL, NULL, NULL); + if (Ks == NULL) { + rv = SECFailure; + goto ec_cleanup; + } + + ecWrapped = (ECCWrappedKeyInfo *) (wswk.wrappedSymmetricWrappingkey); + ecWrapped->size = pubWrapKey->u.ec.size; + ecWrapped->encodedParamLen = pubWrapKey->u.ec.DEREncodedParams.len; + PORT_Memcpy(ecWrapped->var, pubWrapKey->u.ec.DEREncodedParams.data, + pubWrapKey->u.ec.DEREncodedParams.len); + + ecWrapped->pubValueLen = pubWrapKey->u.ec.publicValue.len; + PORT_Memcpy(ecWrapped->var + ecWrapped->encodedParamLen, + pubWrapKey->u.ec.publicValue.data, + pubWrapKey->u.ec.publicValue.len); + + wrappedKey.len = MAX_EC_WRAPPED_KEY_BUFLEN - + (ecWrapped->encodedParamLen + ecWrapped->pubValueLen); + wrappedKey.data = ecWrapped->var + ecWrapped->encodedParamLen + + ecWrapped->pubValueLen; + + /* wrap symmetricWrapping key with the local Ks */ + rv = PK11_WrapSymKey(masterWrapMech, NULL, Ks, + unwrappedWrappingKey, &wrappedKey); + + if (rv != SECSuccess) { + goto ec_cleanup; + } + + /* Write down the length of wrapped key in the buffer + * wswk.wrappedSymmetricWrappingkey at the appropriate offset + */ + ecWrapped->wrappedKeyLen = wrappedKey.len; + +ec_cleanup: + if (privWrapKey) SECKEY_DestroyPrivateKey(privWrapKey); + if (pubWrapKey) SECKEY_DestroyPublicKey(pubWrapKey); + if (Ks) PK11_FreeSymKey(Ks); + asymWrapMechanism = masterWrapMech; + break; +#endif /* NSS_ENABLE_ECC */ + default: rv = SECFailure; break; @@ -3716,10 +4084,6 @@ install: loser: done: - if (svrPubKey) { - SECKEY_DestroyPublicKey(svrPubKey); - svrPubKey = NULL; - } PZ_Unlock(symWrapKeysLock); return unwrappedWrappingKey; } @@ -3749,6 +4113,19 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) goto loser; } +#if defined(TRACE) + if (ssl_trace >= 100) { + SECStatus extractRV = PK11_ExtractKeyValue(pms); + if (extractRV == SECSuccess) { + SECItem * keyData = PK11_GetKeyData(pms); + if (keyData && keyData->data && keyData->len) { + ssl_PrintBuf(ss, "Pre-Master Secret", + keyData->data, keyData->len); + } + } + } +#endif + /* Get the wrapped (encrypted) pre-master secret, enc_pms */ enc_pms.len = SECKEY_PublicKeyStrength(svrPubKey); enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); @@ -3818,6 +4195,10 @@ sendDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) /* Copy DH parameters from server key */ + if (svrPubKey->keyType != dhKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + goto loser; + } dhParam.prime.data = svrPubKey->u.dh.prime.data; dhParam.prime.len = svrPubKey->u.dh.prime.len; dhParam.base.data = svrPubKey->u.dh.base.data; @@ -4260,7 +4641,7 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } /* Got a Match */ - ++ssl3stats.hsh_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_hits ); ss->ssl3.hs.ws = wait_change_cipher; ss->ssl3.hs.isResuming = PR_TRUE; @@ -4279,9 +4660,9 @@ ssl3_HandleServerHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } while (0); if (sid_match) - ++ssl3stats.hsh_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_not_ok ); else - ++ssl3stats.hsh_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hsh_sid_cache_misses ); /* throw the old one away */ sid->u.ssl3.keys.resumable = PR_FALSE; @@ -4576,6 +4957,14 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length) CERT_DestroyCertificateList(ss->ssl3.clientCertChain); ss->ssl3.clientCertChain = NULL; } + if (ss->ssl3.clientCertificate != NULL) { + CERT_DestroyCertificate(ss->ssl3.clientCertificate); + ss->ssl3.clientCertificate = NULL; + } + if (ss->ssl3.clientPrivateKey != NULL) { + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; + } isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length); @@ -5101,11 +5490,6 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) goto loser; /* malformed */ } - /* It's OK for length to be non-zero here. - * Non-zero length means that some new protocol revision has extended - * the client hello message. - */ - desc = handshake_failure; if (sid != NULL) { @@ -5121,33 +5505,54 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) ((ss->opt.requireCertificate == SSL_REQUIRE_FIRST_HANDSHAKE) && !ss->firstHsDone))) { - ++ssl3stats.hch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } } +#ifdef NSS_ENABLE_ECC + /* Disable any ECC cipher suites for which we have no cert. */ + ssl3_FilterECCipherSuitesByServerCerts(ss); +#endif + +#ifdef PARANOID /* Look for a matching cipher suite. */ j = ssl3_config_match_init(ss); if (j <= 0) { /* no ciphers are working/supported by PK11 */ errCode = PORT_GetError(); /* error code is already set. */ goto alert_loser; } +#endif + /* If we already have a session for this client, be sure to pick the ** same cipher suite we picked before. ** This is not a loop, despite appearances. */ if (sid) do { ssl3CipherSuiteCfg *suite = ss->cipherSuites; + /* Find the entry for the cipher suite used in the cached session. */ for (j = ssl_V3_SUITES_IMPLEMENTED; j > 0; --j, ++suite) { if (suite->cipher_suite == sid->u.ssl3.cipherSuite) break; } - if (!j) + PORT_Assert(j > 0); + if (j <= 0) break; +#ifdef PARANOID + /* Double check that the cached cipher suite is still enabled, + * implemented, and allowed by policy. Might have been disabled. + * The product policy won't change during the process lifetime. + * Implemented ("isPresent") shouldn't change for servers. + */ if (!config_match(suite, ss->ssl3.policy, PR_TRUE)) break; +#else + if (!suite->enabled) + break; +#endif + /* Double check that the cached cipher suite is in the client's list */ for (i = 0; i < suites.len; i += 2) { if ((suites.data[i] == MSB(suite->cipher_suite)) && (suites.data[i + 1] == LSB(suite->cipher_suite))) { @@ -5160,6 +5565,37 @@ ssl3_HandleClientHello(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } } while (0); + /* START A NEW SESSION */ + + /* Handle TLS hello extensions, for SSL3 & TLS, + * only if we're not restarting a previous session. + */ + if (length) { + /* Get length of hello extensions */ + PRInt32 extension_length; + extension_length = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); + if (extension_length < 0) { + goto loser; /* alert already sent */ + } + if (extension_length != length) { + ssl3_DecodeError(ss); /* send alert */ + goto loser; + } + rv = ssl3_HandleClientHelloExtensions(ss, &b, &length); + if (rv != SECSuccess) { + goto loser; /* malformed */ + } + } + +#ifndef PARANOID + /* Look for a matching cipher suite. */ + j = ssl3_config_match_init(ss); + if (j <= 0) { /* no ciphers are working/supported by PK11 */ + errCode = PORT_GetError(); /* error code is already set. */ + goto alert_loser; + } +#endif + /* Select a cipher suite. ** NOTE: This suite selection algorithm should be the same as the one in ** ssl3_HandleV2ClientHello(). @@ -5294,7 +5730,7 @@ compression_found: * * XXX make sure compression still matches */ - ++ssl3stats.hch_sid_cache_hits; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_hits ); ss->ssl3.hs.isResuming = PR_TRUE; ss->sec.authAlgorithm = sid->authAlgorithm; @@ -5356,12 +5792,12 @@ compression_found: } if (sid) { /* we had a sid, but it's no longer valid, free it */ - ++ssl3stats.hch_sid_cache_not_ok; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_not_ok ); ss->sec.uncache(sid); ssl_FreeSID(sid); sid = NULL; } - ++ssl3stats.hch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); sid = ssl3_NewSessionID(ss, PR_TRUE); if (sid == NULL) { @@ -5488,7 +5924,10 @@ ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length) PRINT_BUF(60, (ss, "client random:", &ss->ssl3.hs.client_random.rand[0], SSL3_RANDOM_LENGTH)); - +#ifdef NSS_ENABLE_ECC + /* Disable any ECC cipher suites for which we have no cert. */ + ssl3_FilterECCipherSuitesByServerCerts(ss); +#endif i = ssl3_config_match_init(ss); if (i <= 0) { errCode = PORT_GetError(); /* error code is already set. */ @@ -5524,7 +5963,7 @@ suite_found: ss->sec.send = ssl3_SendApplicationData; /* we don't even search for a cache hit here. It's just a miss. */ - ++ssl3stats.hch_sid_cache_misses; + SSL_AtomicIncrementLong(& ssl3stats.hch_sid_cache_misses ); sid = ssl3_NewSessionID(ss, PR_TRUE); if (sid == NULL) { errCode = PORT_GetError(); @@ -5577,7 +6016,9 @@ ssl3_SendServerHello(sslSocket *ss) { sslSessionID *sid; SECStatus rv; + PRUint32 maxBytes = 65535; PRUint32 length; + PRInt32 extensions_len = 0; SSL_TRC(3, ("%d: SSL3[%d]: send server_hello handshake", SSL_GETPID(), ss->fd)); @@ -5592,9 +6033,15 @@ ssl3_SendServerHello(sslSocket *ss) } sid = ss->sec.ci.sid; + + extensions_len = ssl3_CallHelloExtensionSenders(ss, PR_FALSE, maxBytes, + &ss->serverExtensionSenders[0]); + if (extensions_len > 0) + extensions_len += 2; /* Add sizeof total extension length */ + length = sizeof(SSL3ProtocolVersion) + SSL3_RANDOM_LENGTH + 1 + ((sid == NULL) ? 0: SSL3_SESSIONID_BYTES) + - sizeof(ssl3CipherSuite) + 1; + sizeof(ssl3CipherSuite) + 1 + extensions_len; rv = ssl3_AppendHandshakeHeader(ss, server_hello, length); if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ @@ -5632,6 +6079,22 @@ ssl3_SendServerHello(sslSocket *ss) if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } + if (extensions_len) { + PRInt32 sent_len; + + extensions_len -= 2; + rv = ssl3_AppendHandshakeNumber(ss, extensions_len, 2); + if (rv != SECSuccess) + return rv; /* err set by ssl3_SetupPendingCipherSpec */ + sent_len = ssl3_CallHelloExtensionSenders(ss, PR_TRUE, extensions_len, + &ss->serverExtensionSenders[0]); + PORT_Assert(sent_len == extensions_len); + if (sent_len != extensions_len) { + if (sent_len >= 0) + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + } rv = ssl3_SetupPendingCipherSpec(ss); if (rv != SECSuccess) { return rv; /* err set by ssl3_SetupPendingCipherSpec */ @@ -6085,6 +6548,7 @@ ssl3_HandleClientKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECKEYPrivateKey *serverKey = NULL; SECStatus rv; const ssl3KEADef * kea_def; + ssl3KeyPair *serverKeyPair = NULL; #ifdef NSS_ENABLE_ECC SECKEYPublicKey *serverPubKey = NULL; #endif /* NSS_ENABLE_ECC */ @@ -6103,6 +6567,20 @@ const ssl3KEADef * kea_def; kea_def = ss->ssl3.hs.kea_def; + if (ss->ssl3.hs.usedStepDownKey) { + PORT_Assert(kea_def->is_limited /* XXX OR cert is signing only */ + && kea_def->exchKeyType == kt_rsa + && ss->stepDownKeyPair != NULL); + if (!kea_def->is_limited || + kea_def->exchKeyType != kt_rsa || + ss->stepDownKeyPair == NULL) { + /* shouldn't happen, don't use step down if it does */ + goto skip; + } + serverKeyPair = ss->stepDownKeyPair; + ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; + } else +skip: #ifdef NSS_ENABLE_ECC /* XXX Using SSLKEAType to index server certifiates * does not work for (EC)DHE ciphers. Until we have @@ -6111,42 +6589,25 @@ const ssl3KEADef * kea_def; * one seprately. */ if ((kea_def->kea == kea_ecdhe_rsa) || - (kea_def->kea == kea_ecdhe_ecdsa)) { - if (ss->ephemeralECDHKeyPair != NULL) { - serverKey = ss->ephemeralECDHKeyPair->privKey; - ss->sec.keaKeyBits = - SECKEY_PublicKeyStrengthInBits(ss->ephemeralECDHKeyPair->pubKey); - } - } else { -#endif /* NSS_ENABLE_ECC */ - - serverKey = (ss->ssl3.hs.usedStepDownKey -#ifdef DEBUG - && kea_def->is_limited /* XXX OR cert is signing only */ - && kea_def->exchKeyType == kt_rsa - && ss->stepDownKeyPair != NULL -#endif - ) ? ss->stepDownKeyPair->privKey - : ss->serverCerts[kea_def->exchKeyType].SERVERKEY; - - if (ss->ssl3.hs.usedStepDownKey -#ifdef DEBUG - && kea_def->is_limited /* XXX OR cert is signing only */ - && kea_def->exchKeyType == kt_rsa - && ss->stepDownKeyPair != NULL + (kea_def->kea == kea_ecdhe_ecdsa)) { + if (ss->ephemeralECDHKeyPair != NULL) { + serverKeyPair = ss->ephemeralECDHKeyPair; + if (serverKeyPair->pubKey) { + ss->sec.keaKeyBits = + SECKEY_PublicKeyStrengthInBits(serverKeyPair->pubKey); + } + } + } else #endif - ) { - serverKey = ss->stepDownKeyPair->privKey; - ss->sec.keaKeyBits = EXPORT_RSA_KEY_LENGTH * BPB; - } else { + { sslServerCerts * sc = ss->serverCerts + kea_def->exchKeyType; - serverKey = sc->SERVERKEY; + serverKeyPair = sc->serverKeyPair; ss->sec.keaKeyBits = sc->serverKeyBits; } -#ifdef NSS_ENABLE_ECC + if (serverKeyPair) { + serverKey = serverKeyPair->privKey; } -#endif /* NSS_ENABLE_ECC */ if (serverKey == NULL) { SEND_ALERT @@ -6168,19 +6629,14 @@ const ssl3KEADef * kea_def; #ifdef NSS_ENABLE_ECC case kt_ecdh: - /* XXX We really ought to be able to store multiple + /* XXX We really ought to be able to store multiple * EC certs (a requirement if we wish to support both * ECDH-RSA and ECDH-ECDSA key exchanges concurrently). * When we make that change, we'll need an index other * than kt_ecdh to pick the right EC certificate. */ - if (((kea_def->kea == kea_ecdhe_ecdsa) || - (kea_def->kea == kea_ecdhe_rsa)) && - (ss->ephemeralECDHKeyPair != NULL)) { - serverPubKey = ss->ephemeralECDHKeyPair->pubKey; - } else { - serverPubKey = CERT_ExtractPublicKey( - ss->serverCerts[kt_ecdh].serverCert); + if (serverKeyPair) { + serverPubKey = serverKeyPair->pubKey; } if (serverPubKey == NULL) { /* XXX Is this the right error code? */ @@ -6358,23 +6814,25 @@ ssl3_SendCertificate(sslSocket *ss) if (rv != SECSuccess) { return rv; /* err set by AppendHandshake. */ } - for (i = 0; i < certChain->len; i++) { + if (certChain) { + for (i = 0; i < certChain->len; i++) { #ifdef NISCC_TEST - if (fakeCert.len > 0 && i == ndex) { - rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, fakeCert.len, - 3); - SECITEM_FreeItem(&fakeCert, PR_FALSE); - } else { - rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, - certChain->certs[i].len, 3); - } + if (fakeCert.len > 0 && i == ndex) { + rv = ssl3_AppendHandshakeVariable(ss, fakeCert.data, + fakeCert.len, 3); + SECITEM_FreeItem(&fakeCert, PR_FALSE); + } else { + rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, + certChain->certs[i].len, 3); + } #else - rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, - certChain->certs[i].len, 3); + rv = ssl3_AppendHandshakeVariable(ss, certChain->certs[i].data, + certChain->certs[i].len, 3); #endif - if (rv != SECSuccess) { - return rv; /* err set by AppendHandshake. */ - } + if (rv != SECSuccess) { + return rv; /* err set by AppendHandshake. */ + } + } } return SECSuccess; @@ -7066,6 +7524,9 @@ xmit_loser: sid->u.ssl3.cipherSuite = ss->ssl3.hs.cipher_suite; sid->u.ssl3.compression = ss->ssl3.hs.compression; sid->u.ssl3.policy = ss->ssl3.policy; +#ifdef NSS_ENABLE_ECC + sid->u.ssl3.negotiatedECCurves = ss->ssl3.hs.negotiatedECCurves; +#endif sid->u.ssl3.exchKeyType = effectiveExchKeyType; sid->version = ss->version; sid->authAlgorithm = ss->sec.authAlgorithm; @@ -7596,9 +8057,9 @@ process_it: case content_handshake: rv = ssl3_HandleHandshake(ss, databuf); break; - case content_application_data: - rv = SECSuccess; - break; + /* + case content_application_data is handled before this switch + */ default: SSL_DBG(("%d: SSL3[%d]: bogus content type=%d", SSL_GETPID(), ss->fd, cText->type)); @@ -7688,6 +8149,9 @@ ssl3_InitState(sslSocket *ss) ssl3_InitCipherSpec(ss, ss->ssl3.prSpec); ss->ssl3.hs.ws = (ss->sec.isServer) ? wait_client_hello : wait_server_hello; +#ifdef NSS_ENABLE_ECC + ss->ssl3.hs.negotiatedECCurves = SSL3_SUPPORTED_CURVES_MASK; +#endif ssl_ReleaseSpecWriteLock(ss); /* @@ -7742,8 +8206,7 @@ ssl3_NewKeyPair( SECKEYPrivateKey * privKey, SECKEYPublicKey * pubKey) { ssl3KeyPair * pair; - if (!privKey && !pubKey) { - /* one or the other may be NULL, but not both. */ + if (!privKey || !pubKey) { PORT_SetError(PR_INVALID_ARGUMENT_ERROR); return NULL; } diff --git a/security/nss/lib/ssl/ssl3ecc.c b/security/nss/lib/ssl/ssl3ecc.c index af7cdb30f..ab2e96144 100644 --- a/security/nss/lib/ssl/ssl3ecc.c +++ b/security/nss/lib/ssl/ssl3ecc.c @@ -42,9 +42,8 @@ /* ECC code moved here from ssl3con.c */ /* $Id$ */ -#ifdef NSS_ENABLE_ECC - #include "nssrenam.h" +#include "nss.h" #include "cert.h" #include "ssl.h" #include "cryptohi.h" /* for DSAU_ stuff */ @@ -60,6 +59,7 @@ #include "prerror.h" #include "pratom.h" #include "prthread.h" +#include "prinit.h" #include "pk11func.h" #include "secmod.h" @@ -69,38 +69,59 @@ #include <stdio.h> -/* - line 297: implicit function declaration: ssl3_InitPendingCipherSpec - line 305: implicit function declaration: ssl3_AppendHandshakeHeader - line 311: implicit function declaration: ssl3_AppendHandshakeVariable - line 356: implicit function declaration: ssl3_ConsumeHandshakeVariable -*/ - +#ifdef NSS_ENABLE_ECC #ifndef PK11_SETATTRS #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ (x)->pValue=(v); (x)->ulValueLen = (l); #endif +#define SSL_GET_SERVER_PUBLIC_KEY(sock, type) \ + (ss->serverCerts[type].serverKeyPair ? \ + ss->serverCerts[type].serverKeyPair->pubKey : NULL) + +#define SSL_IS_CURVE_NEGOTIATED(ss, curveName) \ + ((curveName > ec_noName) && \ + (curveName < ec_pastLastName) && \ + ((1UL << curveName) & ss->ssl3.hs.negotiatedECCurves) != 0) + /* Types and names of elliptic curves used in TLS */ -typedef enum { ec_type_explicitPrime = 1, - ec_type_explicitChar2Curve, +typedef enum { ec_type_explicitPrime = 1, + ec_type_explicitChar2Curve = 2, ec_type_named } ECType; -typedef enum { ec_noName = 0, - ec_sect163k1, ec_sect163r1, ec_sect163r2, - ec_sect193r1, ec_sect193r2, ec_sect233k1, - ec_sect233r1, ec_sect239k1, ec_sect283k1, - ec_sect283r1, ec_sect409k1, ec_sect409r1, - ec_sect571k1, ec_sect571r1, ec_secp160k1, - ec_secp160r1, ec_secp160r2, ec_secp192k1, - ec_secp192r1, ec_secp224k1, ec_secp224r1, - ec_secp256k1, ec_secp256r1, ec_secp384r1, - ec_secp521r1, +typedef enum { ec_noName = 0, + ec_sect163k1 = 1, + ec_sect163r1 = 2, + ec_sect163r2 = 3, + ec_sect193r1 = 4, + ec_sect193r2 = 5, + ec_sect233k1 = 6, + ec_sect233r1 = 7, + ec_sect239k1 = 8, + ec_sect283k1 = 9, + ec_sect283r1 = 10, + ec_sect409k1 = 11, + ec_sect409r1 = 12, + ec_sect571k1 = 13, + ec_sect571r1 = 14, + ec_secp160k1 = 15, + ec_secp160r1 = 16, + ec_secp160r2 = 17, + ec_secp192k1 = 18, + ec_secp192r1 = 19, + ec_secp224k1 = 20, + ec_secp224r1 = 21, + ec_secp256k1 = 22, + ec_secp256r1 = 23, + ec_secp384r1 = 24, + ec_secp521r1 = 25, ec_pastLastName } ECName; +static SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve); + #define supportedCurve(x) (((x) > ec_noName) && ((x) < ec_pastLastName)) /* Table containing OID tags for elliptic curves named in the @@ -135,6 +156,79 @@ static const SECOidTag ecName2OIDTag[] = { SEC_OID_SECG_EC_SECP521R1, /* 25 */ }; +static const PRUint16 curve2bits[] = { + 0, /* ec_noName = 0, */ + 163, /* ec_sect163k1 = 1, */ + 163, /* ec_sect163r1 = 2, */ + 163, /* ec_sect163r2 = 3, */ + 193, /* ec_sect193r1 = 4, */ + 193, /* ec_sect193r2 = 5, */ + 233, /* ec_sect233k1 = 6, */ + 233, /* ec_sect233r1 = 7, */ + 239, /* ec_sect239k1 = 8, */ + 283, /* ec_sect283k1 = 9, */ + 283, /* ec_sect283r1 = 10, */ + 409, /* ec_sect409k1 = 11, */ + 409, /* ec_sect409r1 = 12, */ + 571, /* ec_sect571k1 = 13, */ + 571, /* ec_sect571r1 = 14, */ + 160, /* ec_secp160k1 = 15, */ + 160, /* ec_secp160r1 = 16, */ + 160, /* ec_secp160r2 = 17, */ + 192, /* ec_secp192k1 = 18, */ + 192, /* ec_secp192r1 = 19, */ + 224, /* ec_secp224k1 = 20, */ + 224, /* ec_secp224r1 = 21, */ + 256, /* ec_secp256k1 = 22, */ + 256, /* ec_secp256r1 = 23, */ + 384, /* ec_secp384r1 = 24, */ + 521, /* ec_secp521r1 = 25, */ + 65535 /* ec_pastLastName */ +}; + +typedef struct Bits2CurveStr { + PRUint16 bits; + ECName curve; +} Bits2Curve; + +static const Bits2Curve bits2curve [] = { + { 192, ec_secp192r1 /* = 19, fast */ }, + { 160, ec_secp160r2 /* = 17, fast */ }, + { 160, ec_secp160k1 /* = 15, */ }, + { 160, ec_secp160r1 /* = 16, */ }, + { 163, ec_sect163k1 /* = 1, */ }, + { 163, ec_sect163r1 /* = 2, */ }, + { 163, ec_sect163r2 /* = 3, */ }, + { 192, ec_secp192k1 /* = 18, */ }, + { 193, ec_sect193r1 /* = 4, */ }, + { 193, ec_sect193r2 /* = 5, */ }, + { 224, ec_secp224r1 /* = 21, fast */ }, + { 224, ec_secp224k1 /* = 20, */ }, + { 233, ec_sect233k1 /* = 6, */ }, + { 233, ec_sect233r1 /* = 7, */ }, + { 239, ec_sect239k1 /* = 8, */ }, + { 256, ec_secp256r1 /* = 23, fast */ }, + { 256, ec_secp256k1 /* = 22, */ }, + { 283, ec_sect283k1 /* = 9, */ }, + { 283, ec_sect283r1 /* = 10, */ }, + { 384, ec_secp384r1 /* = 24, fast */ }, + { 409, ec_sect409k1 /* = 11, */ }, + { 409, ec_sect409r1 /* = 12, */ }, + { 521, ec_secp521r1 /* = 25, fast */ }, + { 571, ec_sect571k1 /* = 13, */ }, + { 571, ec_sect571r1 /* = 14, */ }, + { 65535, ec_noName } +}; + +typedef struct ECDHEKeyPairStr { + ssl3KeyPair * pair; + int error; /* error code of the call-once function */ + PRCallOnceType once; +} ECDHEKeyPair; + +/* arrays of ECDHE KeyPairs */ +static ECDHEKeyPair gECDHEKeyPairs[ec_pastLastName]; + static SECStatus ecName2params(PRArenaPool * arena, ECName curve, SECKEYECParams * params) { @@ -229,7 +323,6 @@ ssl3_ComputeECDHKeyHash(SECItem ec_params, SECItem server_ecpoint, PRINT_BUF(95, (NULL, "ECDHkey hash: MD5 result", hashes->md5, MD5_LENGTH)); PRINT_BUF(95, (NULL, "ECDHkey hash: SHA1 result", hashes->sha, SHA1_LENGTH)); -done: if (hashBuf != buf && hashBuf != NULL) PORT_Free(hashBuf); return rv; @@ -246,7 +339,6 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) CK_MECHANISM_TYPE target; SECKEYPublicKey *pubKey = NULL; /* Ephemeral ECDH key */ SECKEYPrivateKey *privKey = NULL; /* Ephemeral ECDH key */ - CK_EC_KDF_TYPE kdf; PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); @@ -254,6 +346,11 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); /* Generate ephemeral EC keypair */ + if (svrPubKey->keyType != ecKey) { + PORT_SetError(SEC_ERROR_BAD_KEY); + goto loser; + } + /* XXX SHOULD CALL ssl3_CreateECDHEphemeralKeys here, instead! */ privKey = SECKEY_CreateECPrivateKey(&svrPubKey->u.ec.DEREncodedParams, &pubKey, NULL); if (!privKey || !pubKey) { @@ -268,21 +365,14 @@ ssl3_SendECDHClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey) if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; - /* If field size is not more than 24 octets, then use SHA-1 hash of result; - * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt). - */ - if ((pubKey->u.ec.publicValue.len - 1) / 2 <= 24) { - kdf = CKD_SHA1_KDF; - } else { - kdf = CKD_NULL; - } - /* Determine the PMS */ pms = PK11_PubDeriveWithKDF(privKey, svrPubKey, PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, - kdf, NULL, NULL); + CKD_NULL, NULL, NULL); if (pms == NULL) { + SSL3AlertDescription desc = illegal_parameter; + (void)SSL3_SendAlert(ss, alert_fatal, desc); ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE); goto loser; } @@ -338,7 +428,6 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, SECKEYPublicKey clntPubKey; CK_MECHANISM_TYPE target; PRBool isTLS; - CK_EC_KDF_TYPE kdf; PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); @@ -361,19 +450,10 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, if (isTLS) target = CKM_TLS_MASTER_KEY_DERIVE_DH; else target = CKM_SSL3_MASTER_KEY_DERIVE_DH; - /* If field size is not more than 24 octets, then use SHA-1 hash of result; - * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt). - */ - if (srvrPubKey->u.ec.size <= 24 * 8) { - kdf = CKD_SHA1_KDF; - } else { - kdf = CKD_NULL; - } - /* Determine the PMS */ pms = PK11_PubDeriveWithKDF(srvrPrivKey, &clntPubKey, PR_FALSE, NULL, NULL, CKM_ECDH1_DERIVE, target, CKA_DERIVE, 0, - kdf, NULL, NULL); + CKD_NULL, NULL, NULL); if (pms == NULL) { /* last gasp. */ @@ -390,38 +470,174 @@ ssl3_HandleECDHClientKeyExchange(sslSocket *ss, SSL3Opaque *b, return SECSuccess; } +/* find the "weakest link". Get strength of signature key and of sym key. + * choose curve for the weakest of those two. + */ +ECName +ssl3_GetCurveNameForServerSocket(sslSocket *ss) +{ + SECKEYPublicKey * svrPublicKey = NULL; + ECName ec_curve = ec_noName; + int signatureKeyStrength = 521; + int requiredECCbits = ss->sec.secretKeyBits * 2; + int i; + + if (ss->ssl3.hs.kea_def->kea == kea_ecdhe_ecdsa) { + svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_ecdh); + if (svrPublicKey) + ec_curve = params2ecName(&svrPublicKey->u.ec.DEREncodedParams); + if (!SSL_IS_CURVE_NEGOTIATED(ss, ec_curve)) { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; + } + signatureKeyStrength = curve2bits[ ec_curve ]; + } else { + /* RSA is our signing cert */ + int serverKeyStrengthInBits; + + svrPublicKey = SSL_GET_SERVER_PUBLIC_KEY(ss, kt_rsa); + if (!svrPublicKey) { + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; + } + + /* currently strength in bytes */ + serverKeyStrengthInBits = svrPublicKey->u.rsa.modulus.len; + if (svrPublicKey->u.rsa.modulus.data[0] == 0) { + serverKeyStrengthInBits--; + } + /* convert to strength in bits */ + serverKeyStrengthInBits *= BPB; + + if (serverKeyStrengthInBits <= 1024) { + signatureKeyStrength = 160; + } else if (serverKeyStrengthInBits <= 2048) { + signatureKeyStrength = 224; + } else if (serverKeyStrengthInBits <= 3072) { + signatureKeyStrength = 256; + } else if (serverKeyStrengthInBits <= 7168) { + signatureKeyStrength = 384; + } else { + signatureKeyStrength = 521; + } + } + if ( requiredECCbits > signatureKeyStrength ) + requiredECCbits = signatureKeyStrength; + + for ( i = 0; bits2curve[i].curve != ec_noName; i++) { + if (bits2curve[i].bits < requiredECCbits) + continue; + if (SSL_IS_CURVE_NEGOTIATED(ss, bits2curve[i].curve)) { + return bits2curve[i].curve; + } + } + PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); + return ec_noName; +} + +/* function to clear out the lists */ +static SECStatus +ssl3_ShutdownECDHECurves(void *appData, void *nssData) +{ + int i; + ECDHEKeyPair *keyPair = &gECDHEKeyPairs[0]; + + for (i=0; i < ec_pastLastName; i++, keyPair++) { + if (keyPair->pair) { + ssl3_FreeKeyPair(keyPair->pair); + } + } + memset(gECDHEKeyPairs, 0, sizeof gECDHEKeyPairs); + return SECSuccess; +} + +static PRStatus +ssl3_ECRegister(void) +{ + SECStatus rv; + rv = NSS_RegisterShutdown(ssl3_ShutdownECDHECurves, gECDHEKeyPairs); + if (rv != SECSuccess) { + gECDHEKeyPairs[ec_noName].error = PORT_GetError(); + } + return (PRStatus)rv; +} + +/* CallOnce function, called once for each named curve. */ +static PRStatus +ssl3_CreateECDHEphemeralKeyPair(void * arg) +{ + SECKEYPrivateKey * privKey = NULL; + SECKEYPublicKey * pubKey = NULL; + ssl3KeyPair * keyPair = NULL; + ECName ec_curve = (ECName)arg; + SECKEYECParams ecParams = { siBuffer, NULL, 0 }; + + PORT_Assert(gECDHEKeyPairs[ec_curve].pair == NULL); + + /* ok, no one has generated a global key for this curve yet, do so */ + if (ecName2params(NULL, ec_curve, &ecParams) != SECSuccess) { + gECDHEKeyPairs[ec_curve].error = PORT_GetError(); + return PR_FAILURE; + } + + privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); + SECITEM_FreeItem(&ecParams, PR_FALSE); + + if (!privKey || !pubKey || !(keyPair = ssl3_NewKeyPair(privKey, pubKey))) { + if (privKey) { + SECKEY_DestroyPrivateKey(privKey); + } + if (pubKey) { + SECKEY_DestroyPublicKey(pubKey); + } + ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); + gECDHEKeyPairs[ec_curve].error = PORT_GetError(); + return PR_FAILURE; + } + + gECDHEKeyPairs[ec_curve].pair = keyPair; + return PR_SUCCESS; +} /* * Creates the ephemeral public and private ECDH keys used by * server in ECDHE_RSA and ECDHE_ECDSA handshakes. - * XXX For now, the elliptic curve is hardcoded to NIST P-224. + * For now, the elliptic curve is chosen to be the same + * strength as the signing certificate (ECC or RSA). * We need an API to specify the curve. This won't be a real * issue until we further develop server-side support for ECC * cipher suites. */ -SECStatus -ssl3_CreateECDHEphemeralKeys(sslSocket *ss) +static SECStatus +ssl3_CreateECDHEphemeralKeys(sslSocket *ss, ECName ec_curve) { - SECStatus rv = SECSuccess; - SECKEYPrivateKey * privKey; - SECKEYPublicKey * pubKey; - SECKEYECParams ecParams = { siBuffer, NULL, 0 }; + ssl3KeyPair * keyPair = NULL; - if (ss->ephemeralECDHKeyPair) - ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); - ss->ephemeralECDHKeyPair = NULL; + /* if there's no global key for this curve, make one. */ + if (gECDHEKeyPairs[ec_curve].pair == NULL) { + PRStatus status; - if (ecName2params(NULL, ec_secp224r1, &ecParams) == SECFailure) - return SECFailure; - privKey = SECKEY_CreateECPrivateKey(&ecParams, &pubKey, NULL); - if (!privKey || !pubKey || - !(ss->ephemeralECDHKeyPair = ssl3_NewKeyPair(privKey, pubKey))) { - ssl_MapLowLevelError(SEC_ERROR_KEYGEN_FAIL); - rv = SECFailure; + status = PR_CallOnce(&gECDHEKeyPairs[ec_noName].once, ssl3_ECRegister); + if (status != PR_SUCCESS) { + PORT_SetError(gECDHEKeyPairs[ec_noName].error); + return SECFailure; + } + status = PR_CallOnceWithArg(&gECDHEKeyPairs[ec_curve].once, + ssl3_CreateECDHEphemeralKeyPair, + (void *)ec_curve); + if (status != PR_SUCCESS) { + PORT_SetError(gECDHEKeyPairs[ec_curve].error); + return SECFailure; + } } - PORT_Free(ecParams.data); - return rv; + keyPair = gECDHEKeyPairs[ec_curve].pair; + PORT_Assert(keyPair != NULL); + if (!keyPair) + return SECFailure; + ss->ephemeralECDHKeyPair = ssl3_GetKeyPairRef(keyPair); + + return SECSuccess; } SECStatus @@ -438,24 +654,24 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) SECItem ec_params = {siBuffer, NULL, 0}; SECItem ec_point = {siBuffer, NULL, 0}; - unsigned char paramBuf[2]; + unsigned char paramBuf[3]; /* only for curve_type == named_curve */ isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); /* XXX This works only for named curves, revisit this when * we support generic curves. */ - ec_params.len = 2; + ec_params.len = sizeof paramBuf; ec_params.data = paramBuf; - rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, - &b, &length); + rv = ssl3_ConsumeHandshake(ss, ec_params.data, ec_params.len, &b, &length); if (rv != SECSuccess) { goto loser; /* malformed. */ } /* Fail if the curve is not a named curve */ if ((ec_params.data[0] != ec_type_named) || - !supportedCurve(ec_params.data[1])) { + (ec_params.data[1] != 0) || + !supportedCurve(ec_params.data[2])) { errCode = SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE; desc = handshake_failure; goto alert_loser; @@ -526,7 +742,7 @@ ssl3_HandleECDHServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) peerKey->keyType = ecKey; /* set up EC parameters in peerKey */ - if (ecName2params(arena, ec_params.data[1], + if (ecName2params(arena, ec_params.data[2], &peerKey->u.ec.DEREncodedParams) != SECSuccess) { /* we should never get here since we already * checked that we are dealing with a supported curve @@ -572,12 +788,17 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; SECKEYPublicKey * ecdhePub; SECItem ec_params = {siBuffer, NULL, 0}; + unsigned char paramBuf[3]; ECName curve; SSL3KEAType certIndex; /* Generate ephemeral ECDH key pair and send the public key */ - rv = ssl3_CreateECDHEphemeralKeys(ss); + curve = ssl3_GetCurveNameForServerSocket(ss); + if (curve == ec_noName) { + goto loser; + } + rv = ssl3_CreateECDHEphemeralKeys(ss, curve); if (rv != SECSuccess) { goto loser; /* err set by AppendHandshake. */ } @@ -588,12 +809,13 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; return SECFailure; } - ec_params.len = 2; - ec_params.data = (unsigned char*)PORT_Alloc(ec_params.len); + ec_params.len = sizeof paramBuf; + ec_params.data = paramBuf; curve = params2ecName(&ecdhePub->u.ec.DEREncodedParams); if (curve != ec_noName) { ec_params.data[0] = ec_type_named; - ec_params.data[1] = curve; + ec_params.data[1] = 0x00; + ec_params.data[2] = curve; } else { PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE); goto loser; @@ -656,18 +878,512 @@ const ssl3KEADef * kea_def = ss->ssl3.hs.kea_def; goto loser; /* err set by AppendHandshake. */ } - PORT_Free(ec_params.data); PORT_Free(signed_hash.data); return SECSuccess; loser: - if (ec_params.data != NULL) - PORT_Free(ec_params.data); if (signed_hash.data != NULL) PORT_Free(signed_hash.data); return SECFailure; } +/* Lists of ECC cipher suites for searching and disabling. */ + +static const ssl3CipherSuite ecdh_suites[] = { + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdh_ecdsa_suites[] = { + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdh_rsa_suites[] = { + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +static const ssl3CipherSuite ecdhe_rsa_suites[] = { + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +/* List of all ECC cipher suites */ +static const ssl3CipherSuite ecSuites[] = { + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + 0 /* end of list marker */ +}; + +/* On this socket, Disable the ECC cipher suites in the argument's list */ +SECStatus +ssl3_DisableECCSuites(sslSocket * ss, const ssl3CipherSuite * suite) +{ + if (!suite) + suite = ecSuites; + for (; *suite; ++suite) { + SECStatus rv = ssl3_CipherPrefSet(ss, *suite, PR_FALSE); + + PORT_Assert(rv == SECSuccess); /* else is coding error */ + } + return SECSuccess; +} + +/* Look at the server certs configured on this socket, and disable any + * ECC cipher suites that are not supported by those certs. + */ +void +ssl3_FilterECCipherSuitesByServerCerts(sslSocket * ss) +{ + CERTCertificate * svrCert; + + svrCert = ss->serverCerts[kt_rsa].serverCert; + if (!svrCert) { + ssl3_DisableECCSuites(ss, ecdhe_rsa_suites); + } + + svrCert = ss->serverCerts[kt_ecdh].serverCert; + if (!svrCert) { + ssl3_DisableECCSuites(ss, ecdh_suites); + ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); + } else { + SECOidTag sigTag = SECOID_GetAlgorithmTag(&svrCert->signature); + + switch (sigTag) { + case SEC_OID_PKCS1_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: + ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); + break; + case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST: + case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST: + ssl3_DisableECCSuites(ss, ecdh_rsa_suites); + break; + default: + ssl3_DisableECCSuites(ss, ecdh_suites); + break; + } + } +} + +/* Ask: is ANY ECC cipher suite enabled on this socket? */ +/* Order(N^2). Yuk. Also, this ignores export policy. */ +PRBool +ssl3_IsECCEnabled(sslSocket * ss) +{ + const ssl3CipherSuite * suite; + + for (suite = ecSuites; *suite; ++suite) { + PRBool enabled = PR_FALSE; + SECStatus rv = ssl3_CipherPrefGet(ss, *suite, &enabled); + + PORT_Assert(rv == SECSuccess); /* else is coding error */ + if (rv == SECSuccess && enabled) + return PR_TRUE; + } + return PR_FALSE; +} + +#define BE(n) 0, n + +#ifndef NSS_ECC_MORE_THAN_SUITE_B +/* Prefabricated TLS client hello extension, Elliptic Curves List, + * offers only 3 curves, the Suite B curves, 23-25 + */ +static const PRUint8 EClist[12] = { + BE(10), /* Extension type */ + BE( 8), /* octets that follow ( 3 pairs + 1 length pair) */ + BE( 6), /* octets that follow ( 3 pairs) */ + BE(23), BE(24), BE(25) +}; +#else +/* Prefabricated TLS client hello extension, Elliptic Curves List, + * offers curves 1-25. + */ +static const PRUint8 EClist[56] = { + BE(10), /* Extension type */ + BE(52), /* octets that follow (25 pairs + 1 length pair) */ + BE(50), /* octets that follow (25 pairs) */ + BE( 1), BE( 2), BE( 3), BE( 4), BE( 5), BE( 6), BE( 7), + BE( 8), BE( 9), BE(10), BE(11), BE(12), BE(13), BE(14), BE(15), + BE(16), BE(17), BE(18), BE(19), BE(20), BE(21), BE(22), BE(23), + BE(24), BE(25) +}; +#endif + +static const PRUint8 ECPtFmt[6] = { + BE(11), /* Extension type */ + BE( 2), /* octets that follow */ + 1, /* octets that follow */ + 0 /* uncompressed type only */ +}; + +/* Send our "canned" (precompiled) Supported Elliptic Curves extension, + * which says that we support all TLS-defined named curves. + */ +PRInt32 +ssl3_SendSupportedEllipticCurvesExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + if (!ss || !ssl3_IsECCEnabled(ss)) + return 0; + if (append && maxBytes >= (sizeof EClist)) { + SECStatus rv = ssl3_AppendHandshake(ss, EClist, (sizeof EClist)); + } + return (sizeof EClist); +} + +/* Send our "canned" (precompiled) Supported Point Formats extension, + * which says that we only support uncompressed points. + */ +PRInt32 +ssl3_SendSupportedPointFormatsExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + if (!ss || !ssl3_IsECCEnabled(ss)) + return 0; + if (append && maxBytes >= (sizeof ECPtFmt)) { + SECStatus rv = ssl3_AppendHandshake(ss, ECPtFmt, (sizeof ECPtFmt)); + } + return (sizeof ECPtFmt); +} + +/* Just make sure that the remote client supports uncompressed points, + * Since that is all we support. Disable ECC cipher suites if it doesn't. + */ +static SECStatus +ssl3_HandleSupportedPointFormatsExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + int i; + + if (data->len < 2 || data->len > 255 || !data->data || + data->len != (unsigned int)data->data[0] + 1) { + /* malformed */ + goto loser; + } + for (i = data->len; --i > 0; ) { + if (data->data[i] == 0) { + /* indicate that we should send a reply */ + SECStatus rv; + rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, + &ssl3_SendSupportedPointFormatsExtension); + return rv; + } + } +loser: + /* evil client doesn't support uncompressed */ + ssl3_DisableECCSuites(ss, ecSuites); + return SECFailure; +} + + +#define SSL3_GET_SERVER_PUBLICKEY(sock, type) \ + (ss->serverCerts[type].serverKeyPair ? \ + ss->serverCerts[type].serverKeyPair->pubKey : NULL) + +/* Extract the TLS curve name for the public key in our EC server cert. */ +ECName ssl3_GetSvrCertCurveName(sslSocket *ss) +{ + SECKEYPublicKey *srvPublicKey; + ECName ec_curve = ec_noName; + + srvPublicKey = SSL3_GET_SERVER_PUBLICKEY(ss, kt_ecdh); + if (srvPublicKey) { + ec_curve = params2ecName(&srvPublicKey->u.ec.DEREncodedParams); + } + return ec_curve; +} + +/* Ensure that the curve in our server cert is one of the ones suppored + * by the remote client, and disable all ECC cipher suites if not. + */ +static SECStatus +ssl3_HandleSupportedEllipticCurvesExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + PRInt32 list_len; + PRUint32 peerCurves = 0; + PRUint32 mutualCurves = 0; + PRUint16 svrCertCurveName; + + if (!data->data || data->len < 4 || data->len > 65535) + goto loser; + /* get the length of elliptic_curve_list */ + list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (list_len < 0 || data->len != list_len || (data->len % 2) != 0) { + /* malformed */ + goto loser; + } + /* build bit vector of peer's supported curve names */ + while (data->len) { + PRInt32 curve_name = + ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); + if (curve_name > ec_noName && curve_name < ec_pastLastName) { + peerCurves |= (1U << curve_name); + } + } + /* What curves do we support in common? */ + mutualCurves = ss->ssl3.hs.negotiatedECCurves &= peerCurves; + if (!mutualCurves) { /* no mutually supported EC Curves */ + goto loser; + } + + /* if our ECC cert doesn't use one of these supported curves, + * disable ECC cipher suites that require an ECC cert. + */ + svrCertCurveName = ssl3_GetSvrCertCurveName(ss); + if (svrCertCurveName != ec_noName && + (mutualCurves & (1U << svrCertCurveName)) != 0) { + return SECSuccess; + } + /* Our EC cert doesn't contain a mutually supported curve. + * Disable all ECC cipher suites that require an EC cert + */ + ssl3_DisableECCSuites(ss, ecdh_ecdsa_suites); + ssl3_DisableECCSuites(ss, ecdhe_ecdsa_suites); + return SECFailure; + +loser: + /* no common curve supported */ + ssl3_DisableECCSuites(ss, ecSuites); + return SECFailure; +} #endif /* NSS_ENABLE_ECC */ +/* Format an SNI extension, using the name from the socket's URL, + * unless that name is a dotted decimal string. + */ +PRInt32 +ssl3_SendServerNameIndicationExtension( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + PRUint32 len, span; + /* must have a hostname */ + if (!ss || !ss->url || !ss->url[0]) + return 0; + /* must have at lest one character other than [0-9\.] */ + len = PORT_Strlen(ss->url); + span = strspn(ss->url, "0123456789."); + if (len == span) { + /* is a dotted decimal IP address */ + return 0; + } + if (append && maxBytes >= len + 9) { + SECStatus rv; + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, 0, 2); + if (rv != SECSuccess) return 0; + /* length of extension_data */ + rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2); + if (rv != SECSuccess) return 0; + /* length of server_name_list */ + rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); + if (rv != SECSuccess) return 0; + /* Name Type (host_name) */ + rv = ssl3_AppendHandshake(ss, "\0", 1); + if (rv != SECSuccess) return 0; + /* HostName (length and value) */ + rv = ssl3_AppendHandshakeVariable(ss, ss->url, len, 2); + if (rv != SECSuccess) return 0; + } + return len + 9; +} + +/* handle an incoming SNI extension, by ignoring it. */ +SECStatus +ssl3_HandleServerNameIndicationExtension(sslSocket * ss, PRUint16 ex_type, + SECItem *data) +{ + /* For now, we ignore this, as if we didn't understand it. :-) */ + return SECSuccess; +} + +/* Table of handlers for received TLS hello extensions, one per extension. + * In the second generation, this table will be dynamic, and functions + * will be registered here. + */ +static const ssl3HelloExtensionHandler handlers[] = { + { 0, &ssl3_HandleServerNameIndicationExtension }, +#ifdef NSS_ENABLE_ECC + { 10, &ssl3_HandleSupportedEllipticCurvesExtension }, + { 11, &ssl3_HandleSupportedPointFormatsExtension }, +#endif + { -1, NULL } +}; + +/* Table of functions to format TLS hello extensions, one per extension. + * This static table is for the formatting of client hello extensions. + * The server's table of hello senders is dynamic, in the socket struct, + * and sender functions are registered there. + */ +static const +ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSION_SENDERS] = { + { 0, &ssl3_SendServerNameIndicationExtension }, +#ifdef NSS_ENABLE_ECC + { 10, &ssl3_SendSupportedEllipticCurvesExtension }, + { 11, &ssl3_SendSupportedPointFormatsExtension }, +#else + { -1, NULL } +#endif +}; + +/* go through hello extensions in buffer "b". + * For each one, find the extension handler in the table above, and + * if present, invoke that handler. + * ignore any extensions with unknown extension types. + */ +SECStatus +ssl3_HandleClientHelloExtensions(sslSocket *ss, + SSL3Opaque **b, + PRUint32 *length) +{ + while (*length) { + const ssl3HelloExtensionHandler * handler; + SECStatus rv; + PRInt32 extension_type; + SECItem extension_data; + + /* Get the extension's type field */ + extension_type = ssl3_ConsumeHandshakeNumber(ss, 2, b, length); + if (extension_type < 0) /* failure to decode extension_type */ + return SECFailure; /* alert already sent */ + + /* get the data for this extension, so we can pass it or skip it. */ + rv = ssl3_ConsumeHandshakeVariable(ss, &extension_data, 2, b, length); + if (rv != SECSuccess) + return rv; + + /* find extension_type in table of Client Hello Extension Handlers */ + for (handler = handlers; handler->ex_type >= 0; handler++) { + if (handler->ex_type == extension_type) + break; + } + + /* if found, Call this handler */ + if (handler->ex_type == extension_type) { + rv = (*handler->ex_handler)(ss, (PRUint16)extension_type, + &extension_data); + /* Ignore this result */ + /* Essentially, treat all bad extensions as unrecognized types. */ + } + } + return SECSuccess; +} + +/* Add a callback function to the table of senders of server hello extensions. + */ +SECStatus +ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb) +{ + int i; + ssl3HelloExtensionSender *sender = &ss->serverExtensionSenders[0]; + + for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) { + if (!sender->ex_sender) { + sender->ex_type = ex_type; + sender->ex_sender = cb; + return SECSuccess; + } + /* detect duplicate senders */ + PORT_Assert(sender->ex_type != ex_type); + if (sender->ex_type == ex_type) { + /* duplicate */ + break; + } + } + PORT_Assert(i < MAX_EXTENSION_SENDERS); /* table needs to grow */ + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; +} + +/* call each of the extension senders and return the accumulated length */ +PRInt32 +ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender) +{ + PRInt32 total_exten_len = 0; + int i; + + if (!sender) + sender = &clientHelloSenders[0]; + + for (i = 0; i < MAX_EXTENSION_SENDERS; ++i, ++sender) { + if (sender->ex_sender) { + PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); + if (extLen < 0) + return -1; + maxBytes -= extLen; + total_exten_len += extLen; + } + } + return total_exten_len; +} + diff --git a/security/nss/lib/ssl/ssl3prot.h b/security/nss/lib/ssl/ssl3prot.h index d466c614d..b57314005 100644 --- a/security/nss/lib/ssl/ssl3prot.h +++ b/security/nss/lib/ssl/ssl3prot.h @@ -130,7 +130,14 @@ typedef enum { insufficient_security = 71, internal_error = 80, user_canceled = 90, - no_renegotiation = 100 + no_renegotiation = 100, + +/* Alerts for client hello extensions */ + unsupported_extension = 110, + certificate_unobtainable = 111, + unrecognized_name = 112, + bad_certificate_status_response = 113, + bad_certificate_hash_value = 114 } SSL3AlertDescription; @@ -210,7 +217,8 @@ typedef enum { kea_ecdh_ecdsa, kea_ecdhe_ecdsa, kea_ecdh_rsa, - kea_ecdhe_rsa + kea_ecdhe_rsa, + kea_ecdh_anon } SSL3KeyExchangeAlgorithm; typedef struct { @@ -250,13 +258,9 @@ typedef enum { ct_DSS_fixed_DH = 4, ct_RSA_ephemeral_DH = 5, ct_DSS_ephemeral_DH = 6, - /* XXX The numbers assigned to the following EC-based - * certificate types might change before the ECC in TLS - * draft becomes an IETF RFC. - */ - ct_ECDSA_sign = 7, - ct_RSA_fixed_ECDH = 8, - ct_ECDSA_fixed_ECDH = 9 + ct_ECDSA_sign = 64, + ct_RSA_fixed_ECDH = 65, + ct_ECDSA_fixed_ECDH = 66 } SSL3ClientCertificateType; diff --git a/security/nss/lib/ssl/sslauth.c b/security/nss/lib/ssl/sslauth.c index 848f5aa63..45108afd7 100644 --- a/security/nss/lib/ssl/sslauth.c +++ b/security/nss/lib/ssl/sslauth.c @@ -116,11 +116,14 @@ SSL_SecurityStatus(PRFileDesc *fd, int *op, char **cp, int *kp0, int *kp1, } else { cipherName = ssl3_cipherName[ss->sec.cipherType]; } - if (cipherName && PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; - - if (cp) { - *cp = PORT_Strdup(cipherName); - } + PORT_Assert(cipherName); + if (cipherName) { + if (PORT_Strstr(cipherName, "DES")) isDes = PR_TRUE; + + if (cp) { + *cp = PORT_Strdup(cipherName); + } + } if (kp0) { *kp0 = ss->sec.keyBits; diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c index 06ec09813..1cfe54220 100644 --- a/security/nss/lib/ssl/sslcon.c +++ b/security/nss/lib/ssl/sslcon.c @@ -230,7 +230,7 @@ ssl2_ConstructCipherSpecs(sslSocket *ss) (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { const PRUint8 * hs = implementedCipherSuites + i; - int ok = allowed & (1U << hs[0]); + unsigned int ok = allowed & (1U << hs[0]); if (ok) { cs[0] = hs[0]; cs[1] = hs[1]; @@ -679,7 +679,7 @@ done: * Acquires and releases the socket's xmitBufLock. */ static SECStatus -ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, +ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keyBits, PRUint8 *ca, int caLen, PRUint8 *ck, int ckLen, PRUint8 *ek, int ekLen) @@ -704,8 +704,8 @@ ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, msg = ss->sec.ci.sendBuf.buf; msg[0] = SSL_MT_CLIENT_MASTER_KEY; msg[1] = cipher; - msg[2] = MSB(keySize); - msg[3] = LSB(keySize); + msg[2] = MSB(keyBits); + msg[3] = LSB(keyBits); msg[4] = MSB(ckLen); msg[5] = LSB(ckLen); msg[6] = MSB(ekLen); @@ -926,8 +926,8 @@ ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if ((unsigned)rv < (amount + 2)) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - amount + 2 - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) + == SECFailure) { count = SECFailure; } else { count += amount; @@ -1023,8 +1023,7 @@ ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if ((unsigned)rv < buflen) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - buflen - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { count = SECFailure; } else { count += amount; @@ -1152,8 +1151,7 @@ ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) if (rv < (op - out)) { /* Short write. Save the data and return. */ - if (ssl_SaveWriteData(ss, &ss->pendingBuf, out + rv, - op - out - rv) == SECFailure) { + if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { count = SECFailure; } else { count += amount; @@ -1581,15 +1579,17 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PRUint8 *ek, unsigned int ekLen, PRUint8 *ca, unsigned int caLen) { - PRUint8 *kk = NULL; + PRUint8 * dk = NULL; /* decrypted master key */ sslSessionID * sid; + sslServerCerts * sc = ss->serverCerts + kt_rsa; PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */ - unsigned int el1; /* length of RSA decrypted data in kbuf */ + unsigned int ddLen; /* length of RSA decrypted data in kbuf */ unsigned int keySize; - unsigned int modulusLen; + unsigned int dkLen; /* decrypted key length in bytes */ + int modulusLen; SECStatus rv; + PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; - sslServerCerts * sc = ss->serverCerts + kt_rsa; PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); @@ -1597,18 +1597,6 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, PORT_Assert((ss->sec.ci.sid != 0)); sid = ss->sec.ci.sid; - keySize = (keyBits + 7) >> 3; - /* Is the message just way too big? */ - if (keySize > SSL_MAX_MASTER_KEY_BYTES) { - /* bummer */ - SSL_DBG(("%d: SSL[%d]: keySize=%d ckLen=%d max session key size=%d", - SSL_GETPID(), ss->fd, keySize, ckLen, - SSL_MAX_MASTER_KEY_BYTES)); - PORT_SetError(SSL_ERROR_BAD_CLIENT); - goto loser; - } - - /* Trying to cut down on all these switch statements that should be tables. * So, test cipherType once, here, and then use tables below. */ @@ -1628,50 +1616,72 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, goto loser; } - /* For export ciphers, make sure they didn't send too much key data. */ + allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; + if (!(allowed & (1U << cipher))) { + /* client chose a kind we don't allow! */ + SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", + SSL_GETPID(), ss->fd, cipher)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + keySize = ssl_Specs[cipher].keyLen; + if (keyBits != keySize * BPB) { + SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", + SSL_GETPID(), ss->fd, keyBits)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + if (ckLen != ssl_Specs[cipher].pubLen) { - SSL_DBG(("%d: SSL[%d]: odd secret key size, keySize=%d ckLen=%d!", - SSL_GETPID(), ss->fd, keySize, ckLen)); - /* Somebody tried to sneak by a strange secret key */ + SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", + SSL_GETPID(), ss->fd, ckLen)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + if (caLen != ssl_Specs[cipher].ivLen) { + SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", + SSL_GETPID(), ss->fd, caLen)); + PORT_SetError(SSL_ERROR_BAD_CLIENT); + goto loser; + } + + modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); + if (modulusLen == -1) { + /* If the key is bad, then PK11_PubDecryptRaw will fail below. */ + modulusLen = ekLen; + } + /* RSA modulus size presently limited to 8k bits maximum */ + if (ekLen > modulusLen || ekLen > 1024 || ekLen + ckLen < keySize) { + SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", + SSL_GETPID(), ss->fd, ekLen)); PORT_SetError(SSL_ERROR_BAD_CLIENT); goto loser; } /* allocate the buffer to hold the decrypted portion of the key. */ - /* XXX Haven't done any range check on ekLen. */ - kbuf = (PRUint8*) PORT_Alloc(ekLen); + kbuf = (PRUint8*)PORT_Alloc(modulusLen); if (!kbuf) { goto loser; } + dkLen = keySize - ckLen; + dk = kbuf + modulusLen - dkLen; - /* - ** Decrypt encrypted half of the key. Note that encrypted half has - ** been made to match the modulus size of our public key using - ** PKCS#1. keySize is the real size of the data that is interesting. + /* Decrypt encrypted half of the key. ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is ** desired behavior here. */ - rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &el1, ekLen, ek, ekLen); + rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); if (rv != SECSuccess) goto hide_loser; - modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); - if (modulusLen == -1) { - /* If the key was really bad, then PK11_pubDecryptRaw - * would have failed, therefore the we must assume that the card - * is just being a pain and not giving us the modulus... but it - * should be the same size as the encrypted key length, so use it - * and keep cranking */ - modulusLen = ekLen; - } - /* Is the length of the decrypted data (el1) the expected value? */ - if (modulusLen != el1) + /* Is the length of the decrypted data (ddLen) the expected value? */ + if (modulusLen != ddLen) goto hide_loser; /* Cheaply verify that PKCS#1 was used to format the encryption block */ - kk = kbuf + modulusLen - (keySize - ckLen); - if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (kk[-1] != 0x00)) { - /* Tsk tsk. */ + if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { SSL_DBG(("%d: SSL[%d]: strange encryption block", SSL_GETPID(), ss->fd)); PORT_SetError(SSL_ERROR_BAD_CLIENT); @@ -1680,10 +1690,10 @@ ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, /* Make sure we're not subject to a version rollback attack. */ if (ss->opt.enableSSL3 || ss->opt.enableTLS) { - PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03 }; + static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03 }; - if (PORT_Memcmp(kk - 8 - 1, threes, 8) == 0) { + if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { PORT_SetError(SSL_ERROR_BAD_CLIENT); goto hide_loser; } @@ -1695,10 +1705,7 @@ hide_loser: * was erroneous. Don't send any error messages. * Instead, Generate a completely bogus master key . */ - PK11_GenerateRandom(kbuf, ekLen); - if (!kk) { - kk = kbuf + ekLen - (keySize-ckLen); - } + PK11_GenerateRandom(dk, dkLen); } /* @@ -1707,7 +1714,7 @@ hide_loser: if (ckLen) { PORT_Memcpy(mkbuf, ck, ckLen); } - PORT_Memcpy(mkbuf+ckLen, kk, keySize-ckLen); + PORT_Memcpy(mkbuf + ckLen, dk, dkLen); /* Fill in session-id */ rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, @@ -1750,6 +1757,8 @@ hide_loser: * in the first byte, and none of the SSLv2 ciphers do. * * Called from ssl2_HandleClientHelloMessage(). +* Returns the number of bytes of "qualified cipher specs", +* which is typically a multiple of 3, but will be zero if there are none. */ static int ssl2_QualifyCypherSpecs(sslSocket *ss, @@ -1767,7 +1776,9 @@ ssl2_QualifyCypherSpecs(sslSocket *ss, PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); if (!ss->cipherSpecs) { - ssl2_ConstructCipherSpecs(ss); + SECStatus rv = ssl2_ConstructCipherSpecs(ss); + if (rv != SECSuccess || !ss->cipherSpecs) + return 0; } PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); @@ -1823,19 +1834,23 @@ ssl2_ChooseSessionCypher(sslSocket *ss, int keySize; int realKeySize; PRUint8 * ohs = hs; + const PRUint8 * preferred; + static const PRUint8 noneSuch[3] = { 0, 0, 0 }; PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); if (!ss->cipherSpecs) { - ssl2_ConstructCipherSpecs(ss); + SECStatus rv = ssl2_ConstructCipherSpecs(ss); + if (rv != SECSuccess || !ss->cipherSpecs) + goto loser; } if (!ss->preferredCipher) { - const PRUint8 * preferred = implementedCipherSuites; - unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & + unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; if (allowed) { + preferred = implementedCipherSuites; for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { if (0 != (allowed & (1U << preferred[0]))) { ss->preferredCipher = preferred; @@ -1845,6 +1860,7 @@ ssl2_ChooseSessionCypher(sslSocket *ss, } } } + preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; /* ** Scan list of ciphers recieved from peer and look for a match in ** our list. @@ -1857,9 +1873,9 @@ ssl2_ChooseSessionCypher(sslSocket *ss, bestCypher = -1; while (--hc >= 0) { for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) { - if ((hs[0] == ss->preferredCipher[0]) && - (hs[1] == ss->preferredCipher[1]) && - (hs[2] == ss->preferredCipher[2]) && + if ((hs[0] == preferred[0]) && + (hs[1] == preferred[1]) && + (hs[2] == preferred[2]) && hs[0] != 0) { /* Pick this cipher immediately! */ *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; @@ -1974,7 +1990,10 @@ ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) SECStatus rv; int i; - PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))); + if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return NULL; + } block = (unsigned char *) PORT_Alloc(modulusLen); if (block == NULL) return NULL; @@ -3113,7 +3132,16 @@ ssl2_BeginClientHandshake(sslSocket *ss) return rv; } - +#if defined(NSS_ENABLE_ECC) && !defined(NSS_ECC_MORE_THAN_SUITE_B) + /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ + ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ + if (ss->cipherSpecs != NULL) { + PORT_Free(ss->cipherSpecs); + ss->cipherSpecs = NULL; + ss->sizeCipherSpecs = 0; + } +#endif + if (!ss->cipherSpecs) { rv = ssl2_ConstructCipherSpecs(ss); if (rv < 0) { @@ -3207,7 +3235,7 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) unsigned int caLen; unsigned int ckLen; unsigned int ekLen; - unsigned int keySize; + unsigned int keyBits; int cipher; SECStatus rv; @@ -3222,13 +3250,13 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) goto bad_client; } cipher = data[1]; - keySize = (data[2] << 8) | data[3]; + keyBits = (data[2] << 8) | data[3]; ckLen = (data[4] << 8) | data[5]; ekLen = (data[6] << 8) | data[7]; caLen = (data[8] << 8) | data[9]; - SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keySize=%d ckLen=%d ekLen=%d caLen=%d", - SSL_GETPID(), ss->fd, cipher, keySize, ckLen, ekLen, caLen)); + SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d", + SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); if (ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { @@ -3238,8 +3266,7 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) } /* Use info from client to setup session key */ - /* XXX should validate cipher&keySize are in our array */ - rv = ssl2_ServerSetupSessionCypher(ss, cipher, keySize, + rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); @@ -3266,7 +3293,8 @@ ssl2_HandleClientSessionKeyMessage(sslSocket *ss) } SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", - SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); + SSL_GETPID(), ss->fd, + ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); ss->handshake = ssl_GatherRecord1stHandshake; ss->nextHandshake = ssl2_HandleMessage; @@ -3742,7 +3770,8 @@ ssl2_BeginServerHandshake(sslSocket *ss) ss->sec.rcvSequence = 0; /* don't turn on SSL2 if we don't have an RSA key and cert */ - if (!rsaAuth->SERVERKEY || !rsaAuth->serverCert) { + if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || + !rsaAuth->serverCert) { ss->opt.enableSSL2 = PR_FALSE; } diff --git a/security/nss/lib/ssl/ssldef.c b/security/nss/lib/ssl/ssldef.c index 23ef9cafe..9a473380e 100644 --- a/security/nss/lib/ssl/ssldef.c +++ b/security/nss/lib/ssl/ssldef.c @@ -104,14 +104,15 @@ int ssl_DefRecv(sslSocket *ss, unsigned char *buf, int len, int flags) } /* Default (unencrypted) send. - * Returns SECSuccess or SECFailure, NOT SECWouldBlock. - * Returns positive count if any data was written. - * ALWAYS check for a short write after calling ssl_DefSend. + * For blocking sockets, always returns len or SECFailure, no short writes. + * For non-blocking sockets: + * Returns positive count if any data was written, else returns SECFailure. + * Short writes may occur. Does not return SECWouldBlock. */ int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) { PRFileDesc *lower = ss->fd->lower; - int rv, count; + int sent = 0; #if NSS_DISABLE_NAGLE_DELAYS /* Although this is overkill, we disable Nagle delays completely for @@ -122,32 +123,24 @@ int ssl_DefSend(sslSocket *ss, const unsigned char *buf, int len, int flags) ss->delayDisabled = 1; } #endif - count = 0; - for (;;) { - rv = lower->methods->send(lower, (const void *)buf, len, - flags, ss->wTimeout); + do { + int rv = lower->methods->send(lower, (const void *)(buf + sent), + len - sent, flags, ss->wTimeout); if (rv < 0) { PRErrorCode err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { ss->lastWriteBlocked = 1; - return count ? count : rv; + return sent ? sent : SECFailure; } ss->lastWriteBlocked = 0; MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) /* Loser */ return rv; } - count += rv; - if (rv < len) { - /* Short send. Send the rest in the next call */ - buf += rv; - len -= rv; - continue; - } - break; - } + sent += rv; + } while (len > sent); ss->lastWriteBlocked = 0; - return count; + return sent; } int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) @@ -166,33 +159,26 @@ int ssl_DefRead(sslSocket *ss, unsigned char *buf, int len) int ssl_DefWrite(sslSocket *ss, const unsigned char *buf, int len) { PRFileDesc *lower = ss->fd->lower; - int rv, count; + int sent = 0; - count = 0; - for (;;) { - rv = lower->methods->write(lower, (void *)buf, len); + do { + int rv = lower->methods->write(lower, (const void *)(buf + sent), + len - sent); if (rv < 0) { PRErrorCode err = PR_GetError(); if (err == PR_WOULD_BLOCK_ERROR) { ss->lastWriteBlocked = 1; - return count ? count : rv; + return sent ? sent : SECFailure; } ss->lastWriteBlocked = 0; MAP_ERROR(PR_CONNECT_ABORTED_ERROR, PR_CONNECT_RESET_ERROR) /* Loser */ return rv; } - count += rv; - if (rv != len) { - /* Short write. Send the rest in the next call */ - buf += rv; - len -= rv; - continue; - } - break; - } + sent += rv; + } while (len > sent); ss->lastWriteBlocked = 0; - return count; + return sent; } int ssl_DefGetpeername(sslSocket *ss, PRNetAddr *name) diff --git a/security/nss/lib/ssl/sslenum.c b/security/nss/lib/ssl/sslenum.c index d28d689b7..f53bd2268 100644 --- a/security/nss/lib/ssl/sslenum.c +++ b/security/nss/lib/ssl/sslenum.c @@ -47,6 +47,10 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 256-bit */ +#ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, +#endif /* NSS_ENABLE_ECC */ TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, #ifdef NSS_ENABLE_ECC @@ -57,7 +61,9 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 128-bit */ #ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, #endif /* NSS_ENABLE_ECC */ TLS_DHE_DSS_WITH_RC4_128_SHA, @@ -74,6 +80,10 @@ const PRUint16 SSL_ImplementedCiphers[] = { TLS_RSA_WITH_AES_128_CBC_SHA, /* 112-bit 3DES */ +#ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, +#endif /* NSS_ENABLE_ECC */ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, #ifdef NSS_ENABLE_ECC @@ -86,10 +96,6 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* 56-bit DES "domestic" cipher suites */ SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, -#ifdef NSS_ENABLE_ECC - TLS_ECDH_RSA_WITH_DES_CBC_SHA, - TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, -#endif /* NSS_ENABLE_ECC */ SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, @@ -103,6 +109,8 @@ const PRUint16 SSL_ImplementedCiphers[] = { /* ciphersuites with no encryption */ #ifdef NSS_ENABLE_ECC + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, TLS_ECDH_RSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_NULL_SHA, #endif /* NSS_ENABLE_ECC */ diff --git a/security/nss/lib/ssl/sslerr.h b/security/nss/lib/ssl/sslerr.h index be808b8bc..c17014c24 100644 --- a/security/nss/lib/ssl/sslerr.h +++ b/security/nss/lib/ssl/sslerr.h @@ -186,6 +186,12 @@ SSL_ERROR_NO_RENEGOTIATION_ALERT = (SSL_ERROR_BASE + 102), SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED = (SSL_ERROR_BASE + 103), +SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT = (SSL_ERROR_BASE + 104), +SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT = (SSL_ERROR_BASE + 105), +SSL_ERROR_UNRECOGNIZED_NAME_ALERT = (SSL_ERROR_BASE + 106), +SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT = (SSL_ERROR_BASE + 107), +SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT = (SSL_ERROR_BASE + 108), + SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ } SSLErrorCodes; #endif /* NO_SECURITY_ERROR_ENUM */ diff --git a/security/nss/lib/ssl/sslimpl.h b/security/nss/lib/ssl/sslimpl.h index 45e7fa552..26c353b29 100644 --- a/security/nss/lib/ssl/sslimpl.h +++ b/security/nss/lib/ssl/sslimpl.h @@ -170,13 +170,22 @@ typedef enum { SSLAppOpRead = 0, #define SSL3_MASTER_SECRET_LENGTH 48 /* number of wrap mechanisms potentially used to wrap master secrets. */ -#define SSL_NUM_WRAP_MECHS 13 +#define SSL_NUM_WRAP_MECHS 14 /* This makes the cert cache entry exactly 4k. */ #define SSL_MAX_CACHED_CERT_LEN 4060 +#define MAX_EXTENSION_SENDERS 3 + #define NUM_MIXERS 9 +/* Mask of the 25 named curves we support. */ +#ifndef NSS_ECC_MORE_THAN_SUITE_B +#define SSL3_SUPPORTED_CURVES_MASK 0x3800000 /* only 3 curves, suite B*/ +#else +#define SSL3_SUPPORTED_CURVES_MASK 0x3fffffe +#endif + #ifndef BPB #define BPB 8 /* Bits Per Byte */ #endif @@ -217,6 +226,38 @@ typedef sslSessionID *(*sslSessionIDLookupFunc)(const PRIPv6Addr *addr, unsigned int sidLen, CERTCertDBHandle * dbHandle); +/* registerable callback function that either appends extension to buffer + * or returns length of data that it would have appended. + */ +typedef PRInt32 (*ssl3HelloExtensionSenderFunc)(sslSocket *ss, PRBool append, + PRUint32 maxBytes); + +/* registerable callback function that handles a received extension, + * of the given type. + */ +typedef SECStatus (* ssl3HelloExtensionHandlerFunc)(sslSocket *ss, + PRUint16 ex_type, + SECItem * data); + +/* row in a table of hello extension senders */ +typedef struct { + PRInt32 ex_type; + ssl3HelloExtensionSenderFunc ex_sender; +} ssl3HelloExtensionSender; + +/* row in a table of hello extension handlers */ +typedef struct { + PRInt32 ex_type; + ssl3HelloExtensionHandlerFunc ex_handler; +} ssl3HelloExtensionHandler; + +extern SECStatus +ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, + ssl3HelloExtensionSenderFunc cb); + +extern PRInt32 +ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, + const ssl3HelloExtensionSender *sender); /* Socket ops */ struct sslSocketOpsStr { @@ -270,9 +311,9 @@ typedef struct { } ssl3CipherSuiteCfg; #ifdef NSS_ENABLE_ECC -#define ssl_V3_SUITES_IMPLEMENTED 40 +#define ssl_V3_SUITES_IMPLEMENTED 43 #else -#define ssl_V3_SUITES_IMPLEMENTED 26 +#define ssl_V3_SUITES_IMPLEMENTED 23 #endif /* NSS_ENABLE_ECC */ typedef struct sslOptionsStr { @@ -552,6 +593,9 @@ struct sslSessionIDStr { SSL3KEAType exchKeyType; /* key type used in exchange algorithm, * and to wrap the sym wrapping key. */ +#ifdef NSS_ENABLE_ECC + PRUint32 negotiatedECCurves; +#endif /* NSS_ENABLE_ECC */ /* The following values are NOT restored from the server's on-disk * session cache, but are restored from the client's cache. @@ -677,6 +721,9 @@ const ssl3CipherSuiteDef *suite_def; PRBool usedStepDownKey; /* we did a server key exchange. */ sslBuffer msgState; /* current state for handshake messages*/ /* protected by recvBufLock */ +#ifdef NSS_ENABLE_ECC + PRUint32 negotiatedECCurves; /* bit mask */ +#endif /* NSS_ENABLE_ECC */ } SSL3HandshakeState; @@ -727,8 +774,8 @@ typedef struct { } SSL3Ciphertext; struct ssl3KeyPairStr { - SECKEYPrivateKey * privKey; /* RSA step down key */ - SECKEYPublicKey * pubKey; /* RSA step down key */ + SECKEYPrivateKey * privKey; + SECKEYPublicKey * pubKey; PRInt32 refCount; /* use PR_Atomic calls for this. */ }; @@ -897,6 +944,7 @@ struct sslSocketStr { unsigned long lastWriteBlocked; unsigned long recvdCloseNotify; /* received SSL EOF. */ unsigned long TCPconnected; + unsigned long appDataBuffered; /* version of the protocol to use */ SSL3ProtocolVersion version; @@ -911,6 +959,9 @@ struct sslSocketStr { sslHandshakeFunc nextHandshake; /*firstHandshakeLock*/ sslHandshakeFunc securityHandshake; /*firstHandshakeLock*/ + /* registered callbacks that send server hello extensions */ + ssl3HelloExtensionSender serverExtensionSenders[MAX_EXTENSION_SENDERS]; + /* the following variable is only used with socks or other proxies. */ char * peerID; /* String uniquely identifies target server. */ @@ -1084,9 +1135,8 @@ extern sslSocket * ssl_DupSocket(sslSocket *old); extern void ssl_PrintBuf(sslSocket *ss, const char *msg, const void *cp, int len); extern void ssl_DumpMsg(sslSocket *ss, unsigned char *bp, unsigned len); -extern int ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, - sslSendFunc fp); -extern SECStatus ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, +extern int ssl_SendSavedWriteData(sslSocket *ss); +extern SECStatus ssl_SaveWriteData(sslSocket *ss, const void* p, unsigned int l); extern SECStatus ssl2_BeginClientHandshake(sslSocket *ss); extern SECStatus ssl2_BeginServerHandshake(sslSocket *ss); @@ -1222,7 +1272,10 @@ int ssl3_GatherCompleteHandshake(sslSocket *ss, int flags); extern SECStatus ssl3_CreateRSAStepDownKeys(sslSocket *ss); #ifdef NSS_ENABLE_ECC -extern SECStatus ssl3_CreateECDHEphemeralKeys(sslSocket *ss); +extern void ssl3_FilterECCipherSuitesByServerCerts(sslSocket *ss); +extern PRBool ssl3_IsECCEnabled(sslSocket *ss); +extern SECStatus ssl3_DisableECCSuites(sslSocket * ss, + const ssl3CipherSuite * suite); #endif /* NSS_ENABLE_ECC */ extern SECStatus ssl3_CipherPrefSetDefault(ssl3CipherSuite which, PRBool on); @@ -1276,10 +1329,14 @@ extern SECStatus ssl3_AppendHandshake(sslSocket *ss, const void *void_src, PRInt32 bytes); extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss, SSL3HandshakeType t, PRUint32 length); +extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num, + PRInt32 lenSize); extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss, const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize); extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); +extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes, + SSL3Opaque **b, PRUint32 *length); extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i, PRInt32 bytes, SSL3Opaque **b, PRUint32 *length); extern SECStatus ssl3_SignHashes(SSL3Hashes *hash, SECKEYPrivateKey *key, @@ -1288,6 +1345,14 @@ extern SECStatus ssl3_VerifySignedHashes(SSL3Hashes *hash, CERTCertificate *cert, SECItem *buf, PRBool isTLS, void *pwArg); +/* functions that append extensions to hello messages. */ +extern PRInt32 ssl3_SendServerNameIndicationExtension( sslSocket * ss, + PRBool append, PRUint32 maxBytes); + +/* call the registered extension handlers. */ +extern SECStatus ssl3_HandleClientHelloExtensions(sslSocket *ss, + SSL3Opaque **b, PRUint32 *length); + /* Construct a new NSPR socket for the app to use */ extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd); extern void ssl_FreePRSocket(PRFileDesc *fd); @@ -1338,27 +1403,6 @@ extern int ssl_MapLowLevelError(int hiLevelError); extern PRUint32 ssl_Time(void); -/* emulation of NSPR routines. */ -extern PRInt32 -ssl_EmulateAcceptRead( PRFileDesc * sd, - PRFileDesc ** nd, - PRNetAddr ** raddr, - void * buf, - PRInt32 amount, - PRIntervalTime timeout); -extern PRInt32 -ssl_EmulateTransmitFile( PRFileDesc * sd, - PRFileDesc * fd, - const void * headers, - PRInt32 hlen, - PRTransmitFileFlags flags, - PRIntervalTime timeout); -extern PRInt32 -ssl_EmulateSendFile( PRFileDesc * sd, - PRSendFileData * sfd, - PRTransmitFileFlags flags, - PRIntervalTime timeout); - SECStatus SSL_DisableDefaultExportCipherSuites(void); SECStatus SSL_DisableExportCipherSuites(PRFileDesc * fd); diff --git a/security/nss/lib/ssl/sslinfo.c b/security/nss/lib/ssl/sslinfo.c index d3a9735f0..020c892e9 100644 --- a/security/nss/lib/ssl/sslinfo.c +++ b/security/nss/lib/ssl/sslinfo.c @@ -163,21 +163,27 @@ static const SSLCipherSuiteInfo suiteInfo[] = { /* ECC cipher suites */ {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, -{0,CS(TLS_ECDH_ECDSA_WITH_DES_CBC_SHA), S_ECDSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, + {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA), S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, -{0,CS(TLS_ECDH_RSA_WITH_DES_CBC_SHA), S_RSA, K_ECDH, C_DES, B_DES, M_SHA, 0, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, }, -{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, - +{0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA), S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA), S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA), S_RSA, K_ECDHE, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, {0,CS(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, +{0,CS(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA), S_RSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, #endif /* NSS_ENABLE_ECC */ /* SSL 2 table */ diff --git a/security/nss/lib/ssl/sslmutex.c b/security/nss/lib/ssl/sslmutex.c index 0c5ae4cee..77860b3fa 100644 --- a/security/nss/lib/ssl/sslmutex.c +++ b/security/nss/lib/ssl/sslmutex.c @@ -143,17 +143,6 @@ sslMutex_Init(sslMutex *pMutex, int shared) if (err) { return err; } - /* close-on-exec is false by default */ - if (!shared) { - err = fcntl(pMutex->u.pipeStr.mPipes[0], F_SETFD, FD_CLOEXEC); - if (err) - goto loser; - - err = fcntl(pMutex->u.pipeStr.mPipes[1], F_SETFD, FD_CLOEXEC); - if (err) - goto loser; - } - #if NONBLOCKING_POSTS err = setNonBlocking(pMutex->u.pipeStr.mPipes[1], 1); if (err) diff --git a/security/nss/lib/ssl/sslproto.h b/security/nss/lib/ssl/sslproto.h index e7a998126..f94359cb4 100644 --- a/security/nss/lib/ssl/sslproto.h +++ b/security/nss/lib/ssl/sslproto.h @@ -165,28 +165,35 @@ #define TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x0065 #define TLS_DHE_DSS_WITH_RC4_128_SHA 0x0066 -#ifdef NSS_ENABLE_ECC -/* "Experimental" ECC cipher suites. -** XXX These numbers might change before the current IETF draft -** on ECC cipher suites for TLS becomes an RFC. -*/ -#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0x0047 -#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0x0048 -#define TLS_ECDH_ECDSA_WITH_DES_CBC_SHA 0x0049 -#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0x004A -#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x004B -#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x004C - -#define TLS_ECDH_RSA_WITH_NULL_SHA 0x004D -#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0x004E -#define TLS_ECDH_RSA_WITH_DES_CBC_SHA 0x004F -#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0x0050 -#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0051 -#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0052 - -#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0077 -#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0078 -#endif /* NSS_ENABLE_ECC */ +#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 + +#define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A + +#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F + +#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 + +#define TLS_ECDH_anon_WITH_NULL_SHA 0xC015 +#define TLS_ECDH_anon_WITH_RC4_128_SHA 0xC016 +#define TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA 0xC017 +#define TLS_ECDH_anon_WITH_AES_128_CBC_SHA 0xC018 +#define TLS_ECDH_anon_WITH_AES_256_CBC_SHA 0xC019 /* Netscape "experimental" cipher suites. */ #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0 diff --git a/security/nss/lib/ssl/sslsecur.c b/security/nss/lib/ssl/sslsecur.c index a30b062df..0d395f64e 100644 --- a/security/nss/lib/ssl/sslsecur.c +++ b/security/nss/lib/ssl/sslsecur.c @@ -440,24 +440,23 @@ sslBuffer_Grow(sslBuffer *b, unsigned int newLen) ** Caller must hold xmitBufLock */ SECStatus -ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data, - unsigned int len) +ssl_SaveWriteData(sslSocket *ss, const void *data, unsigned int len) { unsigned int newlen; SECStatus rv; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); - newlen = buf->len + len; - if (newlen > buf->space) { - rv = sslBuffer_Grow(buf, newlen); + newlen = ss->pendingBuf.len + len; + if (newlen > ss->pendingBuf.space) { + rv = sslBuffer_Grow(&ss->pendingBuf, newlen); if (rv) { return rv; } } SSL_TRC(5, ("%d: SSL[%d]: saving %d bytes of data (%d total saved so far)", SSL_GETPID(), ss->fd, len, newlen)); - PORT_Memcpy(buf->buf + buf->len, data, len); - buf->len = newlen; + PORT_Memcpy(ss->pendingBuf.buf + ss->pendingBuf.len, data, len); + ss->pendingBuf.len = newlen; return SECSuccess; } @@ -468,28 +467,23 @@ ssl_SaveWriteData(sslSocket *ss, sslBuffer *buf, const void *data, ** Caller must hold xmitBufLock */ int -ssl_SendSavedWriteData(sslSocket *ss, sslBuffer *buf, sslSendFunc send) +ssl_SendSavedWriteData(sslSocket *ss) { int rv = 0; - int len = buf->len; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); - if (len != 0) { + if (ss->pendingBuf.len != 0) { SSL_TRC(5, ("%d: SSL[%d]: sending %d bytes of saved data", - SSL_GETPID(), ss->fd, len)); - rv = (*send)(ss, buf->buf, len, 0); + SSL_GETPID(), ss->fd, ss->pendingBuf.len)); + rv = ssl_DefSend(ss, ss->pendingBuf.buf, ss->pendingBuf.len, 0); if (rv < 0) { return rv; } - if (rv < len) { - /* UGH !! This shifts the whole buffer down by copying it, and - ** it depends on PORT_Memmove doing overlapping moves correctly! - ** It should advance the pointer offset instead !! - */ - PORT_Memmove(buf->buf, buf->buf + rv, len - rv); - buf->len = len - rv; - } else { - buf->len = 0; + ss->pendingBuf.len -= rv; + if (ss->pendingBuf.len > 0 && rv > 0) { + /* UGH !! This shifts the whole buffer down by copying it */ + PORT_Memmove(ss->pendingBuf.buf, ss->pendingBuf.buf + rv, + ss->pendingBuf.len); } } return rv; @@ -632,6 +626,7 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, SECStatus rv; sslSocket *ss; sslServerCerts *sc; + SECKEYPublicKey * pubKey = NULL; ss = ssl_FindSocket(fd); if (!ss) { @@ -664,7 +659,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, sc->serverCert = NULL; } if (cert) { - SECKEYPublicKey * pubKey; sc->serverCert = CERT_DupCertificate(cert); if (!sc->serverCert) goto loser; @@ -673,8 +667,6 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, if (!pubKey) goto loser; sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(pubKey); - SECKEY_DestroyPublicKey(pubKey); - pubKey = NULL; } @@ -723,11 +715,12 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, if (keyCopy == NULL) goto loser; SECKEY_CacheStaticFlags(keyCopy); - sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, NULL); + sc->serverKeyPair = ssl3_NewKeyPair(keyCopy, pubKey); if (sc->serverKeyPair == NULL) { SECKEY_DestroyPrivateKey(keyCopy); goto loser; } + pubKey = NULL; /* adopted by serverKeyPair */ } if (kea == kt_rsa && cert && sc->serverKeyBits > 512) { @@ -748,6 +741,10 @@ SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert, return SECSuccess; loser: + if (pubKey) { + SECKEY_DestroyPublicKey(pubKey); + pubKey = NULL; + } if (sc->serverCert != NULL) { CERT_DestroyCertificate(sc->serverCert); sc->serverCert = NULL; @@ -1017,7 +1014,7 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags) if (!ssl_SocketIsBlocking(ss) && !ss->opt.fdx) { ssl_GetXmitBufLock(ss); if (ss->pendingBuf.len != 0) { - rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend); + rv = ssl_SendSavedWriteData(ss); if ((rv < 0) && (PORT_GetError() != PR_WOULD_BLOCK_ERROR)) { ssl_ReleaseXmitBufLock(ss); return SECFailure; @@ -1072,7 +1069,7 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) ssl_GetXmitBufLock(ss); if (ss->pendingBuf.len != 0) { PORT_Assert(ss->pendingBuf.len > 0); - rv = ssl_SendSavedWriteData(ss, &ss->pendingBuf, ssl_DefSend); + rv = ssl_SendSavedWriteData(ss); if (rv >= 0 && ss->pendingBuf.len != 0) { PORT_Assert(ss->pendingBuf.len > 0); PORT_SetError(PR_WOULD_BLOCK_ERROR); @@ -1106,6 +1103,10 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags) return 0; } PORT_Assert(buf != NULL); + if (!buf) { + PORT_SetError(PR_INVALID_ARGUMENT_ERROR); + return PR_FAILURE; + } SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes", SSL_GETPID(), ss->fd, len)); diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c index 877a5a995..b0649f76e 100644 --- a/security/nss/lib/ssl/sslsnce.c +++ b/security/nss/lib/ssl/sslsnce.c @@ -224,6 +224,7 @@ struct cacheDescStr { struct cacheDescStr * sharedCache; /* shared copy of this struct */ PRFileMap * cacheMemMap; PRThread * poller; + PRUint32 mutexTimeout; PRBool shared; }; typedef struct cacheDescStr cacheDesc; @@ -270,6 +271,7 @@ static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS; static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl); static SECStatus LaunchLockPoller(cacheDesc *cache); +static SECStatus StopLockPoller(cacheDesc *cache); struct inheritanceStr { @@ -750,12 +752,14 @@ ServerSessionIDCache(sslSessionID *sid) if (sid->cached == never_cached || sid->cached == invalid_cache) { PRUint32 set; - PORT_Assert(sid->creationTime != 0 && sid->expirationTime != 0); + PORT_Assert(sid->creationTime != 0); if (!sid->creationTime) sid->lastAccessTime = sid->creationTime = ssl_Time(); if (version < SSL_LIBRARY_VERSION_3_0) { - if (!sid->expirationTime) - sid->expirationTime = sid->creationTime + ssl_sid_timeout; + /* override caller's expiration time, which uses client timeout + * duration, not server timeout duration. + */ + sid->expirationTime = sid->creationTime + cache->ssl2Timeout; SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipher=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], @@ -769,8 +773,10 @@ ServerSessionIDCache(sslSessionID *sid) sid->u.ssl2.cipherArg.len)); } else { - if (!sid->expirationTime) - sid->expirationTime = sid->creationTime + ssl3_sid_timeout; + /* override caller's expiration time, which uses client timeout + * duration, not server timeout duration. + */ + sid->expirationTime = sid->creationTime + cache->ssl3Timeout; SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x " "cipherSuite=%d", myPid, sid->cached, sid->addr.pr_s6_addr32[0], sid->addr.pr_s6_addr32[1], @@ -888,7 +894,8 @@ CloseCache(cacheDesc *cache) ** be) in use by multiple processes. We do not wish to destroy ** the mutexes while they are still in use. */ - if (PR_FALSE == cache->sharedCache->everInherited) { + if (cache->sharedCache && + PR_FALSE == cache->sharedCache->everInherited) { sidCacheLock *pLock = cache->sidCacheLocks; for (; locks_initialized > 0; --locks_initialized, ++pLock ) { sslMutex_Destroy(&pLock->mutex); @@ -937,6 +944,13 @@ InitCache(cacheDesc *cache, int maxCacheEntries, PRUint32 ssl2_timeout, cache->cacheMemMap = cacheMemMap = NULL; cache->sharedCache = (cacheDesc *)0; + cache->numSIDCacheLocksInitialized = 0; + cache->nextCertCacheEntry = 0; + cache->stopPolling = PR_FALSE; + cache->everInherited = PR_FALSE; + cache->poller = NULL; + cache->mutexTimeout = 0; + cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries : DEF_SID_CACHE_ENTRIES; cache->numSIDCacheSets = @@ -1185,6 +1199,10 @@ SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache) SECStatus SSL_ShutdownServerSessionIDCache(void) { +#if defined(XP_UNIX) || defined(XP_BEOS) + /* Stop the thread that polls cache for expired locks on Unix */ + StopLockPoller(&globalCache); +#endif SSL3_ShutdownServerCache(); return SSL_ShutdownServerSessionIDCacheInstance(&globalCache); } @@ -1436,23 +1454,12 @@ LockPoller(void * arg) cacheDesc * cache = (cacheDesc *)arg; cacheDesc * sharedCache = cache->sharedCache; sidCacheLock * pLock; - const char * timeoutString; PRIntervalTime timeout; PRUint32 now; PRUint32 then; int locks_polled = 0; int locks_to_poll = cache->numSIDCacheLocks + 2; - PRUint32 expiration = SID_LOCK_EXPIRATION_TIMEOUT; - - timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); - if (timeoutString) { - long newTime = strtol(timeoutString, 0, 0); - if (newTime == 0) - return; /* application doesn't want this function */ - if (newTime > 0) - expiration = (PRUint32)newTime; - /* if error (newTime < 0) ignore it and use default */ - } + PRUint32 expiration = cache->mutexTimeout; timeout = PR_SecondsToInterval(expiration); while(!sharedCache->stopPolling) { @@ -1494,17 +1501,47 @@ LockPoller(void * arg) static SECStatus LaunchLockPoller(cacheDesc *cache) { - PRThread * pollerThread; + const char * timeoutString; + PRThread * pollerThread; + + cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT; + timeoutString = getenv("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT"); + if (timeoutString) { + long newTime = strtol(timeoutString, 0, 0); + if (newTime == 0) + return SECSuccess; /* application doesn't want poller thread */ + if (newTime > 0) + cache->mutexTimeout = (PRUint32)newTime; + /* if error (newTime < 0) ignore it and use default */ + } pollerThread = PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0); + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); if (!pollerThread) { return SECFailure; } cache->poller = pollerThread; return SECSuccess; } + +/* Stop the thread that polls cache for expired locks */ +static SECStatus +StopLockPoller(cacheDesc *cache) +{ + if (!cache->poller) { + return SECSuccess; + } + cache->sharedCache->stopPolling = PR_TRUE; + if (PR_Interrupt(cache->poller) != PR_SUCCESS) { + return SECFailure; + } + if (PR_JoinThread(cache->poller) != PR_SUCCESS) { + return SECFailure; + } + cache->poller = NULL; + return SECSuccess; +} #endif /************************************************************************ diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c index 6344c99c5..924d993d0 100644 --- a/security/nss/lib/ssl/sslsock.c +++ b/security/nss/lib/ssl/sslsock.c @@ -48,6 +48,9 @@ #include "sslimpl.h" #include "sslproto.h" #include "nspr.h" +#include "private/pprio.h" +#include "blapi.h" +#include "nss.h" #define SET_ERROR_CODE /* reminder */ @@ -97,18 +100,24 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */ #ifdef NSS_ENABLE_ECC { TLS_ECDH_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, { TLS_ECDH_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDH_ECDSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, - { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, #endif /* NSS_ENABLE_ECC */ { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED } }; @@ -291,6 +300,8 @@ ssl_DupSocket(sslSocket *os) } ss->stepDownKeyPair = !os->stepDownKeyPair ? NULL : ssl3_GetKeyPairRef(os->stepDownKeyPair); + ss->ephemeralECDHKeyPair = !os->ephemeralECDHKeyPair ? NULL : + ssl3_GetKeyPairRef(os->ephemeralECDHKeyPair); /* * XXX the preceeding CERT_ and SECKEY_ functions can fail and return NULL. * XXX We should detect this, and not just march on with NULL pointers. @@ -396,6 +407,10 @@ ssl_DestroySocketContents(sslSocket *ss) ssl3_FreeKeyPair(ss->stepDownKeyPair); ss->stepDownKeyPair = NULL; } + if (ss->ephemeralECDHKeyPair) { + ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); + ss->ephemeralECDHKeyPair = NULL; + } } /* @@ -488,6 +503,29 @@ SSL_Enable(PRFileDesc *fd, int which, PRBool on) return SSL_OptionSet(fd, which, on); } +static const PRCallOnceType pristineCallOnce; +static PRCallOnceType setupBypassOnce; + +static SECStatus SSL_BypassShutdown(void* appData, void* nssData) +{ + /* unload freeBL shared library from memory */ + BL_Unload(); + setupBypassOnce = pristineCallOnce; + return SECSuccess; +} + +static PRStatus SSL_BypassRegisterShutdown(void) +{ + SECStatus rv = NSS_RegisterShutdown(SSL_BypassShutdown, NULL); + PORT_Assert(SECSuccess == rv); + return SECSuccess == rv ? PR_SUCCESS : PR_FAILURE; +} + +static PRStatus SSL_BypassSetup(void) +{ + return PR_CallOnce(&setupBypassOnce, &SSL_BypassRegisterShutdown); +} + SECStatus SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) { @@ -612,7 +650,15 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) PORT_SetError(PR_INVALID_STATE_ERROR); rv = SECFailure; } else { - ss->opt.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup() ) { + ss->opt.bypassPKCS11 = on; + } else { + rv = SECFailure; + } + } else { + ss->opt.bypassPKCS11 = PR_FALSE; + } } break; @@ -833,7 +879,15 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) break; case SSL_BYPASS_PKCS11: - ssl_defaults.bypassPKCS11 = on; + if (PR_FALSE != on) { + if (PR_SUCCESS == SSL_BypassSetup()) { + ssl_defaults.bypassPKCS11 = on; + } else { + return SECFailure; + } + } else { + ssl_defaults.bypassPKCS11 = PR_FALSE; + } break; case SSL_NO_LOCKS: @@ -1586,6 +1640,24 @@ ssl_Poll(PRFileDesc *fd, PRInt16 how_flags, PRInt16 *p_out_flags) return new_flags; } +static PRInt32 PR_CALLBACK +ssl_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, + const void *headers, PRInt32 hlen, + PRTransmitFileFlags flags, PRIntervalTime timeout) +{ + PRSendFileData sfd; + + sfd.fd = fd; + sfd.file_offset = 0; + sfd.file_nbytes = 0; + sfd.header = headers; + sfd.hlen = hlen; + sfd.trailer = NULL; + sfd.tlen = 0; + + return sd->methods->sendfile(sd, &sfd, flags, timeout); +} + PRBool ssl_FdIsBlocking(PRFileDesc *fd) @@ -1646,7 +1718,7 @@ ssl_WriteV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 vectors, } \ /* Only a nonblocking socket can have partial sends */ \ PR_ASSERT(!blocking); \ - return sent; \ + return sent + rv; \ } #define SEND(bfr, len) \ do { \ @@ -1842,15 +1914,15 @@ static const PRIOMethods ssl_methods = { ssl_RecvFrom, /* recvfrom */ ssl_SendTo, /* sendto */ ssl_Poll, /* poll */ - ssl_EmulateAcceptRead, /* acceptread */ - ssl_EmulateTransmitFile, /* transmitfile */ + PR_EmulateAcceptRead, /* acceptread */ + ssl_TransmitFile, /* transmitfile */ ssl_GetSockName, /* getsockname */ ssl_GetPeerName, /* getpeername */ NULL, /* getsockopt OBSOLETE */ NULL, /* setsockopt OBSOLETE */ NULL, /* getsocketoption */ NULL, /* setsocketoption */ - ssl_EmulateSendFile, /* Send a (partial) file with header/trailer*/ + PR_EmulateSendFile, /* Send a (partial) file with header/trailer*/ NULL, /* reserved for future use */ NULL, /* reserved for future use */ NULL, /* reserved for future use */ diff --git a/security/nss/lib/util/derenc.c b/security/nss/lib/util/derenc.c index c894ed729..3470f74f7 100644 --- a/security/nss/lib/util/derenc.c +++ b/security/nss/lib/util/derenc.c @@ -124,6 +124,7 @@ header_length(DERTemplate *dtemplate, uint32 contents_len) under_kind = dtemplate->arg; } } else if (encode_kind & DER_INLINE) { + PORT_Assert (dtemplate->sub != NULL); under_kind = dtemplate->sub->kind; if (universal) { encode_kind = under_kind; @@ -229,9 +230,8 @@ contents_length(DERTemplate *dtemplate, void *src) if (under_kind & DER_INDEFINITE) { uint32 sub_len; - void **indp; + void **indp = *(void ***)src; - indp = *(void ***)src; if (indp == NULL) return 0; @@ -239,13 +239,11 @@ contents_length(DERTemplate *dtemplate, void *src) under_kind &= ~DER_INDEFINITE; if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; + DERTemplate *tmpt = dtemplate->sub; + PORT_Assert (tmpt != NULL); for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); + void *sub_src = (void *)((char *)(*indp) + tmpt->offset); sub_len = contents_length (tmpt, sub_src); len += sub_len + header_length (tmpt, sub_len); } @@ -255,8 +253,7 @@ contents_length(DERTemplate *dtemplate, void *src) * DER_INDEFINITE | DER_OCTET_STRING) is right. */ for (; *indp != NULL; indp++) { - SECItem *item; - item = (SECItem *)(*indp); + SECItem *item = (SECItem *)(*indp); sub_len = item->len; if (under_kind == DER_BIT_STRING) { sub_len = (sub_len + 7) >> 3; @@ -391,12 +388,10 @@ der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src) under_kind &= ~DER_INDEFINITE; if (under_kind == DER_SET || under_kind == DER_SEQUENCE) { - DERTemplate *tmpt; - void *sub_src; - - tmpt = dtemplate->sub; + DERTemplate *tmpt = dtemplate->sub; + PORT_Assert (tmpt != NULL); for (; *indp != NULL; indp++) { - sub_src = (void *)((char *)(*indp) + tmpt->offset); + void *sub_src = (void *)((char *)(*indp) + tmpt->offset); buf = der_encode (buf, tmpt, sub_src); } } else { diff --git a/security/nss/lib/util/secasn1d.c b/security/nss/lib/util/secasn1d.c index ab0914b5d..068d52ed6 100644 --- a/security/nss/lib/util/secasn1d.c +++ b/security/nss/lib/util/secasn1d.c @@ -1256,6 +1256,12 @@ regular_string_type: struct subitem *subitem; int len; + PORT_Assert (item); + if (!item) { + PORT_SetError (SEC_ERROR_BAD_DER); + state->top->status = decodeError; + return; + } PORT_Assert (item->len == 0 && item->data == NULL); /* * Check for and handle an ANY which has stashed aside the @@ -1408,7 +1414,7 @@ sec_asn1d_free_child (sec_asn1d_state *state, PRBool error) if (state->child != NULL) { PORT_Assert (error || state->child->consumed == 0); PORT_Assert (state->our_mark != NULL); - PORT_ArenaRelease (state->top->our_pool, state->our_mark); + PORT_ArenaZRelease (state->top->our_pool, state->our_mark); if (error && state->top->their_pool == NULL) { /* * XXX We need to free anything allocated. @@ -1664,6 +1670,8 @@ sec_asn1d_add_to_subitems (sec_asn1d_state *state, copy = sec_asn1d_alloc (state->top->our_pool, len); if (copy == NULL) { state->top->status = decodeError; + if (!state->top->our_pool) + PORT_Free(thing); return NULL; } PORT_Memcpy (copy, data, len); @@ -2841,7 +2849,7 @@ SEC_ASN1DecoderFinish (SEC_ASN1DecoderContext *cx) * XXX anything else that needs to be finished? */ - PORT_FreeArena (cx->our_pool, PR_FALSE); + PORT_FreeArena (cx->our_pool, PR_TRUE); return rv; } diff --git a/security/nss/lib/util/secasn1e.c b/security/nss/lib/util/secasn1e.c index db7792cb1..2300060df 100644 --- a/security/nss/lib/util/secasn1e.c +++ b/security/nss/lib/util/secasn1e.c @@ -1639,7 +1639,7 @@ SEC_ASN1EncodeInteger(PRArenaPool *poolp, SECItem *dest, long value) } -extern SECItem * +SECItem * SEC_ASN1EncodeUnsignedInteger(PRArenaPool *poolp, SECItem *dest, unsigned long value) { diff --git a/security/nss/lib/util/secdig.c b/security/nss/lib/util/secdig.c index 263c8030f..07c136a74 100644 --- a/security/nss/lib/util/secdig.c +++ b/security/nss/lib/util/secdig.c @@ -166,21 +166,26 @@ SGN_DecodeDigestInfo(SECItem *didata) PRArenaPool *arena; SGNDigestInfo *di; SECStatus rv = SECFailure; + SECItem diCopy = {siBuffer, NULL, 0}; arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); if(arena == NULL) return NULL; + rv = SECITEM_CopyItem(arena, &diCopy, didata); + if (rv != SECSuccess) { + PORT_FreeArena(arena, PR_FALSE); + return NULL; + } + di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo)); - if(di != NULL) - { + if (di != NULL) { di->arena = arena; - rv = SEC_ASN1DecodeItem(arena, di, sgn_DigestInfoTemplate, didata); + rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy); } - if((di == NULL) || (rv != SECSuccess)) - { - PORT_FreeArena(arena, PR_TRUE); + if ((di == NULL) || (rv != SECSuccess)) { + PORT_FreeArena(arena, PR_FALSE); di = NULL; } diff --git a/security/nss/lib/util/secerr.h b/security/nss/lib/util/secerr.h index 2cc1bcef3..d47734fe1 100644 --- a/security/nss/lib/util/secerr.h +++ b/security/nss/lib/util/secerr.h @@ -204,6 +204,8 @@ SEC_ERROR_UNKNOWN_OBJECT_TYPE = (SEC_ERROR_BASE + 150), SEC_ERROR_INCOMPATIBLE_PKCS11 = (SEC_ERROR_BASE + 151), SEC_ERROR_NO_EVENT = (SEC_ERROR_BASE + 152), SEC_ERROR_CRL_ALREADY_EXISTS = (SEC_ERROR_BASE + 153), +SEC_ERROR_NOT_INITIALIZED = (SEC_ERROR_BASE + 154), +SEC_ERROR_TOKEN_NOT_LOGGED_IN = (SEC_ERROR_BASE + 155), /* Add new error codes above here. */ SEC_ERROR_END_OF_LIST diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h index b73083f2b..fee905c2f 100644 --- a/security/nss/lib/util/secitem.h +++ b/security/nss/lib/util/secitem.h @@ -53,7 +53,8 @@ SEC_BEGIN_PROTOS ** Allocate an item. If "arena" is not NULL, then allocate from there, ** otherwise allocate from the heap. If "item" is not NULL, allocate ** only the data for the item, not the item itself. The item structure -** is allocated zero-filled; the data buffer is not zeroed. +** is allocated zero-filled; the data buffer is not zeroed. The caller +** is responsible for initializing the type field of the item. ** ** The resulting item is returned; NULL if any error occurs. ** diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index 550f09b4f..79536ad11 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/nss/lib/util/secoid.c @@ -166,6 +166,8 @@ #define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03 #define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00 #define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01 +#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04 +#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03 #define CONST_OID static const unsigned char @@ -453,8 +455,14 @@ CONST_OID sha256[] = { SHAXXX, 1 }; CONST_OID sha384[] = { SHAXXX, 2 }; CONST_OID sha512[] = { SHAXXX, 3 }; -CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 }; -CONST_OID ansix962ECDSASignaturewithSHA1Digest[] = { ANSI_X962_OID, 0x04, 0x01 }; +CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 }; +CONST_OID ansix962SignaturewithSHA1Digest[] = { ANSI_X962_SIGNATURE_OID, 0x01 }; +CONST_OID ansix962SignatureRecommended[] = { ANSI_X962_SIGNATURE_OID, 0x02 }; +CONST_OID ansix962SignatureSpecified[] = { ANSI_X962_SPECIFY_OID }; +CONST_OID ansix962SignaturewithSHA224Digest[] = { ANSI_X962_SPECIFY_OID, 0x01 }; +CONST_OID ansix962SignaturewithSHA256Digest[] = { ANSI_X962_SPECIFY_OID, 0x02 }; +CONST_OID ansix962SignaturewithSHA384Digest[] = { ANSI_X962_SPECIFY_OID, 0x03 }; +CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 }; /* ANSI X9.62 prime curve OIDs */ /* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the @@ -1150,8 +1158,8 @@ const static SECOidData oids[] = { OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY, "X9.62 elliptic curve public key", CKM_ECDH1_DERIVE, INVALID_CERT_EXTENSION ), - OD( ansix962ECDSASignaturewithSHA1Digest, - SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST, + OD( ansix962SignaturewithSHA1Digest, + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, "X9.62 ECDSA signature with SHA1", CKM_ECDSA_SHA1, INVALID_CERT_EXTENSION ), @@ -1435,6 +1443,32 @@ const static SECOidData oids[] = { OD( pkcs9ExtensionRequest, SEC_OID_PKCS9_EXTENSION_REQUEST, "PKCS #9 Extension Request", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ), + + /* more ECC Signature Oids */ + OD( ansix962SignatureRecommended, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST, + "X9.62 ECDSA signature with recommended digest", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignatureSpecified, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, + "X9.62 ECDSA signature with specified digest", CKM_ECDSA, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA224Digest, + SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE, + "X9.62 ECDSA signature with SHA224", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA256Digest, + SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, + "X9.62 ECDSA signature with SHA256", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA384Digest, + SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, + "X9.62 ECDSA signature with SHA384", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), + OD( ansix962SignaturewithSHA512Digest, + SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, + "X9.62 ECDSA signature with SHA512", CKM_INVALID_MECHANISM, + INVALID_CERT_EXTENSION ), }; /* diff --git a/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h index e1072c5bb..64e75c720 100644 --- a/security/nss/lib/util/secoidt.h +++ b/security/nss/lib/util/secoidt.h @@ -314,7 +314,10 @@ typedef enum { /* Elliptic Curve Cryptography (ECC) OIDs */ SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200, - SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST = 201, + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201, + +#define SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST \ + SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE /* ANSI X9.62 named elliptic curves (prime field) */ SEC_OID_ANSIX962_EC_PRIME192V1 = 202, @@ -403,6 +406,13 @@ typedef enum { SEC_OID_PKIX_CA_ISSUERS = 273, SEC_OID_PKCS9_EXTENSION_REQUEST = 274, + /* new EC Signature oids */ + SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275, + SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276, + SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277, + SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278, + SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279, + SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280, SEC_OID_TOTAL } SECOidTag; diff --git a/security/nss/lib/util/secport.c b/security/nss/lib/util/secport.c index 4ad02ba91..9b9fda1c5 100644 --- a/security/nss/lib/util/secport.c +++ b/security/nss/lib/util/secport.c @@ -271,7 +271,9 @@ PORT_ArenaZAlloc(PLArenaPool *arena, size_t size) return(p); } -/* XXX - need to zeroize!! - jsw */ +/* + * If zero is true, zeroize the arena memory before freeing it. + */ void PORT_FreeArena(PLArenaPool *arena, PRBool zero) { @@ -303,6 +305,13 @@ PORT_FreeArena(PLArenaPool *arena, PRBool zero) if (!ev) doFreeArenaPool = PR_TRUE; } } + if (zero) { + PLArena *a; + for (a = arena->first.next; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + memset((void *)a->base, 0, a->avail - a->base); + } + } if (doFreeArenaPool) { PL_FreeArenaPool(arena); } else { @@ -385,8 +394,32 @@ PORT_ArenaMark(PLArenaPool *arena) return result; } -void -PORT_ArenaRelease(PLArenaPool *arena, void *mark) +static void +port_ArenaZeroAfterMark(PLArenaPool *arena, void *mark) +{ + PLArena *a = arena->current; + if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) { + /* fast path: mark falls in the current arena */ + memset(mark, 0, a->avail - (PRUword)mark); + } else { + /* slow path: need to find the arena that mark falls in */ + for (a = arena->first.next; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + if (a->base <= (PRUword)mark && (PRUword)mark <= a->avail) { + memset(mark, 0, a->avail - (PRUword)mark); + a = a->next; + break; + } + } + for (; a; a = a->next) { + PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); + memset((void *)a->base, 0, a->avail - a->base); + } + } +} + +static void +port_ArenaRelease(PLArenaPool *arena, void *mark, PRBool zero) { PORTArenaPool *pool = (PORTArenaPool *)arena; if (ARENAPOOL_MAGIC == pool->magic ) { @@ -418,6 +451,9 @@ PORT_ArenaRelease(PLArenaPool *arena, void *mark) tm = *pw; *pw = (threadmark_mark *)NULL; + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); if (! pool->first_mark ) { @@ -425,15 +461,36 @@ PORT_ArenaRelease(PLArenaPool *arena, void *mark) } } #else /* THREADMARK */ + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); #endif /* THREADMARK */ PZ_Unlock(pool->lock); } else { + if (zero) { + port_ArenaZeroAfterMark(arena, mark); + } PL_ARENA_RELEASE(arena, mark); } } void +PORT_ArenaRelease(PLArenaPool *arena, void *mark) +{ + port_ArenaRelease(arena, mark, PR_FALSE); +} + +/* + * Zeroize the arena memory before releasing it. + */ +void +PORT_ArenaZRelease(PLArenaPool *arena, void *mark) +{ + port_ArenaRelease(arena, mark, PR_TRUE); +} + +void PORT_ArenaUnmark(PLArenaPool *arena, void *mark) { #ifdef THREADMARK diff --git a/security/nss/lib/util/secport.h b/security/nss/lib/util/secport.h index 65c14def0..d30328de0 100644 --- a/security/nss/lib/util/secport.h +++ b/security/nss/lib/util/secport.h @@ -137,6 +137,7 @@ extern void *PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize); extern void *PORT_ArenaMark(PLArenaPool *arena); extern void PORT_ArenaRelease(PLArenaPool *arena, void *mark); +extern void PORT_ArenaZRelease(PLArenaPool *arena, void *mark); extern void PORT_ArenaUnmark(PLArenaPool *arena, void *mark); extern char *PORT_ArenaStrdup(PLArenaPool *arena, const char *str); diff --git a/security/nss/manifest.mn b/security/nss/manifest.mn index b080f94d6..caed79aee 100644 --- a/security/nss/manifest.mn +++ b/security/nss/manifest.mn @@ -37,7 +37,7 @@ CORE_DEPTH = .. DEPTH = .. -IMPORTS = nspr20/v4.6 \ +IMPORTS = nspr20/v4.6.4 \ $(NULL) RELEASE = nss diff --git a/security/nss/pkg/linux/Makefile b/security/nss/pkg/linux/Makefile index a4ecce510..13e34131f 100644 --- a/security/nss/pkg/linux/Makefile +++ b/security/nss/pkg/linux/Makefile @@ -48,7 +48,8 @@ ifndef RPM_RELEASE RPM_RELEASE = 1 endif VERSION = `grep NSS_VERSION $(CORE_DEPTH)/../dist/public/nss/nss.h \ - | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` + | head -1 \ + | sed -e 's/[^"]*"//' -e 's/".*//' -e 's/ .*//'` PWD = `pwd` BUILDROOT = $(PWD)\/$(NAME)-root diff --git a/security/nss/pkg/solaris/Makefile-devl.com b/security/nss/pkg/solaris/Makefile-devl.com index 5d28d5ffd..9a0116dc0 100755 --- a/security/nss/pkg/solaris/Makefile-devl.com +++ b/security/nss/pkg/solaris/Makefile-devl.com @@ -57,7 +57,9 @@ FILES = $(DATAFILES) pkginfo PACKAGE = $(shell basename `pwd`) -PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') +PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h \ + | head -1 \ + | sed -e 's/[^"]*"//' -e 's/".*//' -e 's/ .*//') LN = /usr/bin/ln diff --git a/security/nss/pkg/solaris/Makefile-tlsu.com b/security/nss/pkg/solaris/Makefile-tlsu.com index 5d28d5ffd..9a0116dc0 100755 --- a/security/nss/pkg/solaris/Makefile-tlsu.com +++ b/security/nss/pkg/solaris/Makefile-tlsu.com @@ -57,7 +57,9 @@ FILES = $(DATAFILES) pkginfo PACKAGE = $(shell basename `pwd`) -PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') +PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/nss/lib/nss/nss.h \ + | head -1 \ + | sed -e 's/[^"]*"//' -e 's/".*//' -e 's/ .*//') LN = /usr/bin/ln diff --git a/security/nss/pkg/solaris/Makefile.com b/security/nss/pkg/solaris/Makefile.com index 297a2ee8f..0478ac1e3 100644 --- a/security/nss/pkg/solaris/Makefile.com +++ b/security/nss/pkg/solaris/Makefile.com @@ -57,7 +57,8 @@ FILES = $(DATAFILES) pkginfo prototype PACKAGE = $(shell basename `pwd`) PRODUCT_VERSION = $(shell grep NSS_VERSION $(CORE_DEPTH)/../dist/public/nss/nss.h \ - | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') + | head -1 \ + | sed -e 's/[^"]*"//' -e 's/".*//' -e 's/ .*//') LN = /usr/bin/ln CP = /usr/bin/cp diff --git a/security/nss/tests/all.sh b/security/nss/tests/all.sh index f664ed488..67aa561bd 100755 --- a/security/nss/tests/all.sh +++ b/security/nss/tests/all.sh @@ -78,7 +78,8 @@ # ######################################################################## -TESTS="cert ssl sdr cipher smime crmf perf tools fips dbtests" +tests="cipher perf cert dbtests tools fips sdr crmf smime ssl" +TESTS=${TESTS:-$tests} SCRIPTNAME=all.sh CLEANUP="${SCRIPTNAME}" cd `dirname $0` # will cause problems if sourced @@ -92,12 +93,17 @@ fi for i in ${TESTS} do SCRIPTNAME=${i}.sh - echo "Running Tests for $i" if [ "$O_CRON" = "ON" ] then - (cd ${QADIR}/$i ; . ./$SCRIPTNAME all file >> ${LOGFILE} 2>&1) + echo "Running tests for $i" >> ${LOGFILE} + echo "TIMESTAMP $i BEGIN: `date`" >> ${LOGFILE} + (cd ${QADIR}/$i ; . ./$SCRIPTNAME all file) >> ${LOGFILE} 2>&1 + echo "TIMESTAMP $i END: `date`" >> ${LOGFILE} else - (cd ${QADIR}/$i ; . ./$SCRIPTNAME all file 2>&1 | tee -a ${LOGFILE}) + echo "Running tests for $i" | tee -a ${LOGFILE} + echo "TIMESTAMP $i BEGIN: `date`" | tee -a ${LOGFILE} + (cd ${QADIR}/$i ; . ./$SCRIPTNAME all file) 2>&1 | tee -a ${LOGFILE} + echo "TIMESTAMP $i END: `date`" | tee -a ${LOGFILE} fi done diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh index 3956a3b23..e667be958 100755 --- a/security/nss/tests/cert/cert.sh +++ b/security/nss/tests/cert/cert.sh @@ -21,6 +21,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 @@ -75,7 +76,11 @@ cert_init() fi SCRIPTNAME="cert.sh" CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"` - html_head "Certutil and Crlutil Tests" + if [ -n "$NSS_ENABLE_ECC" ] ; then + html_head "Certutil and Crlutil Tests with ECC" + else + html_head "Certutil and Crlutil Tests" + fi ################## Generate noise for our CA cert. ###################### # NOTE: these keys are only suitable for testing, as this whole thing @@ -140,7 +145,7 @@ certu() return $RET } -################################ certu ################################# +################################ crlu ################################# # local shell function to call crlutil, also: writes action and options to # stdout, sets variable RET and writes results to the html file results ######################################################################## @@ -148,7 +153,7 @@ crlu() { echo "$SCRIPTNAME: ${CU_ACTION} --------------------------" - CRLUTIL=crlutil + CRLUTIL="crlutil -q" echo "$CRLUTIL $*" $CRLUTIL $* RET=$? @@ -257,6 +262,14 @@ cert_create_cert() if [ "$RET" -ne 0 ]; then return $RET fi + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Import EC Root CA for $CERTNAME" + certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" \ + -d "${PROFILEDIR}" -i "${R_CADIR}/ecroot.cert" 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + fi cert_add_cert "$5" return $? } @@ -270,7 +283,6 @@ cert_create_cert() ######################################################################## cert_add_cert() { - CU_ACTION="Generate Cert Request for $CERTNAME" CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 @@ -293,6 +305,64 @@ cert_add_cert() fi cert_log "SUCCESS: $CERTNAME's Cert Created" + +# +# Generate and add EC cert +# + if [ -n "$NSS_ENABLE_ECC" ] ; then + CURVE="secp384r1" + CU_ACTION="Generate EC Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -k ec -q "${CURVE}" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + + CU_ACTION="Sign ${CERTNAME}'s EC Request" + certu -C -c "TestCA-ec" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" "$1" 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + + CU_ACTION="Import $CERTNAME's EC Cert" + certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ec.cert" 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + cert_log "SUCCESS: $CERTNAME's EC Cert Created" + +# Generate EC certificate signed with RSA + CU_ACTION="Generate mixed EC Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ecmixed@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -k ec -q "${CURVE}" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + + CU_ACTION="Sign ${CERTNAME}'s EC Request with RSA" +# Avoid conflicting serial numbers with TestCA issuer by keeping +# this set far away. A smaller number risks colliding with the +# extended ssl user certificates. + NEWSERIAL=`expr ${CERTSERIAL} + 10000` + certu -C -c "TestCA" -m "$NEWSERIAL" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}-ecmixed.cert" -f "${R_PWFILE}" "$1" 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + + CU_ACTION="Import $CERTNAME's mixed EC Cert" + certu -A -n "${CERTNAME}-ecmixed" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ecmixed.cert" 2>&1 + if [ "$RET" -ne 0 ]; then + return $RET + fi + cert_log "SUCCESS: $CERTNAME's mixed EC Cert Created" + fi + return 0 } @@ -325,8 +395,37 @@ cert_all_CA() cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u" ${D_CLIENT_CA} "7" rm $CLIENT_CADIR/root.cert $SERVER_CADIR/root.cert - # root.cert in $CLIENT_CADIR and in $SERVER_CADIR is the one of the last + + # root.cert in $CLIENT_CADIR and in $SERVER_CADIR is one of the last # in the chain + + if [ -n "$NSS_ENABLE_ECC" ] ; then +# +# Create EC version of TestCA + CA_CURVE="secp521r1" + ALL_CU_SUBJECT="CN=NSS Test CA (ECC), O=BOGUS NSS, L=Mountain View, ST=California, C=US" + cert_ec_CA $CADIR TestCA-ec -x "CTu,CTu,CTu" ${D_CA} "1" ${CA_CURVE} +# +# Create EC versions of the intermediate CA certs + ALL_CU_SUBJECT="CN=NSS Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $SERVER_CADIR serverCA-ec -x "Cu,Cu,Cu" ${D_SERVER_CA} "2" ${CA_CURVE} + ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $SERVER_CADIR chain-1-serverCA-ec "-c serverCA-ec" "u,u,u" ${D_SERVER_CA} "3" ${CA_CURVE} + ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $SERVER_CADIR chain-2-serverCA-ec "-c chain-1-serverCA-ec" "u,u,u" ${D_SERVER_CA} "4" ${CA_CURVE} + + ALL_CU_SUBJECT="CN=NSS Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $CLIENT_CADIR clientCA-ec -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5" ${CA_CURVE} + ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $CLIENT_CADIR chain-1-clientCA-ec "-c clientCA-ec" "u,u,u" ${D_CLIENT_CA} "6" ${CA_CURVE} + ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" + cert_ec_CA $CLIENT_CADIR chain-2-clientCA-ec "-c chain-1-clientCA-ec" "u,u,u" ${D_CLIENT_CA} "7" ${CA_CURVE} + + rm $CLIENT_CADIR/ecroot.cert $SERVER_CADIR/ecroot.cert +# ecroot.cert in $CLIENT_CADIR and in $SERVER_CADIR is one of the last +# in the chain + + fi } ################################# cert_CA ################################ @@ -400,6 +499,70 @@ CERTSCRIPT cp root.cert ${NICKNAME}.ca.cert } +################################ cert_ec_CA ############################## +# local shell function to build the Temp. Certificate Authority (CA) +# used for testing purposes, creating a CA Certificate and a root cert +# This is the ECC version of cert_CA. +########################################################################## +cert_ec_CA() +{ + CUR_CADIR=$1 + NICKNAME=$2 + SIGNER=$3 + TRUSTARG=$4 + DOMAIN=$5 + CERTSERIAL=$6 + CURVE=$7 + + echo "$SCRIPTNAME: Creating an EC CA Certificate $NICKNAME ==========================" + + if [ ! -d "${CUR_CADIR}" ]; then + mkdir -p "${CUR_CADIR}" + fi + cd ${CUR_CADIR} + pwd + + LPROFILE=. + if [ -n "${MULTIACCESS_DBM}" ]; then + LPROFILE="multiaccess:${DOMAIN}" + fi + + ################# Creating an EC CA Cert ################################ + # + CU_ACTION="Creating EC CA Cert $NICKNAME " + CU_SUBJECT=$ALL_CU_SUBJECT + certu -S -n $NICKNAME -k ec -q $CURVE -t $TRUSTARG -v 600 $SIGNER \ + -d ${LPROFILE} -1 -2 -5 -f ${R_PWFILE} -z ${R_NOISE_FILE} \ + -m $CERTSERIAL 2>&1 <<CERTSCRIPT +5 +6 +9 +n +y +-1 +n +5 +6 +7 +9 +n +CERTSCRIPT + + if [ "$RET" -ne 0 ]; then + echo "return value is $RET" + Exit 6 "Fatal - failed to create EC CA cert" + fi + + ################# Exporting EC Root Cert ################################ + # + CU_ACTION="Exporting EC Root Cert" + certu -L -n $NICKNAME -r -d ${LPROFILE} -o ecroot.cert + if [ "$RET" -ne 0 ]; then + Exit 7 "Fatal - failed to export ec root cert" + fi + cp ecroot.cert ${NICKNAME}.ca.cert +} + ############################## cert_smime_client ############################# # local shell function to create client Certificates for S/MIME tests ############################################################################## @@ -414,6 +577,17 @@ cert_smime_client() echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------" cert_create_cert "${DAVEDIR}" Dave 50 ${D_DAVE} +## XXX With this new script merging ECC and non-ECC tests, the +## call to cert_create_cert ends up creating two separate certs +## one for Eve and another for Eve-ec but they both end up with +## the same Subject Alt Name Extension, i.e., both the cert for +## Eve@bogus.com and the cert for Eve-ec@bogus.com end up +## listing eve@bogus.net in the Certificate Subject Alt Name extension. +## This can cause a problem later when cmsutil attempts to create +## enveloped data and accidently picks up the ECC cert (NSS currently +## does not support ECC for enveloped data creation). This script +## avoids the problem by ensuring that these conflicting certs are +## never added to the same cert database (see comment marked XXXX). echo "$SCRIPTNAME: Creating multiEmail's Certificate --------------------" cert_create_cert "${EVEDIR}" "Eve" 60 ${D_EVE} "-7 eve@bogus.net,eve@bogus.cc,beve@bogus.com" @@ -456,6 +630,32 @@ cert_smime_client() certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \ -i ${R_EVEDIR}/Eve.cert 2>&1 + if [ -n "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: Importing EC Certificates ==============================" + CU_ACTION="Import Bob's EC cert into Alice's db" + certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ + -i ${R_BOBDIR}/Bob-ec.cert 2>&1 + + CU_ACTION="Import Dave's EC cert into Alice's DB" + certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ + -i ${R_DAVEDIR}/Dave-ec.cert 2>&1 + + CU_ACTION="Import Dave's EC cert into Bob's DB" + certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \ + -i ${R_DAVEDIR}/Dave-ec.cert 2>&1 + +## XXXX Do not import Eve's EC cert until we can make sure that +## the email addresses listed in the Subject Alt Name Extension +## inside Eve's ECC and non-ECC certs are different. +# CU_ACTION="Import Eve's EC cert into Alice's DB" +# certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ +# -i ${R_EVEDIR}/Eve-ec.cert 2>&1 + +# CU_ACTION="Import Eve's EC cert into Bob's DB" +# certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \ +# -i ${R_EVEDIR}/Eve-ec.cert 2>&1 + fi + if [ "$CERTFAILED" != 0 ] ; then cert_log "ERROR: SMIME failed $RET" else @@ -463,11 +663,12 @@ cert_smime_client() fi } -############################## cert_ssl ################################ +############################## cert_extended_ssl ####################### # local shell function to create client + server certs for extended SSL test ######################################################################## cert_extended_ssl() { + ################# Creating Certs for extended SSL test #################### # CERTFAILED=0 @@ -496,11 +697,60 @@ cert_extended_ssl() CU_ACTION="Import Client Root CA -t T,, for $CERTNAME (ext.)" certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \ -i "${CLIENT_CADIR}/clientCA.ca.cert" 2>&1 + + if [ -n "$NSS_ENABLE_ECC" ] ; then +# +# Repeat the above for EC certs +# + EC_CURVE="secp256r1" + CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)" + cp ${CERTDIR}/req ${SERVER_CADIR} + certu -C -c "chain-2-serverCA-ec" -m 200 -v 60 -d "${P_SERVER_CADIR}" \ + -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1 + + CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)" + certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ec.cert" 2>&1 + + CU_ACTION="Import Client EC Root CA -t T,, for $CERTNAME (ext.)" + certu -A -n "clientCA-ec" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \ + -i "${CLIENT_CADIR}/clientCA-ec.ca.cert" 2>&1 +# +# done with EC certs +# +# Repeat again for mixed EC certs +# + EC_CURVE="secp256r1" + CU_ACTION="Generate mixed EC Cert Request for $CERTNAME (ext)" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ecmixed@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s mixed EC Request (ext)" + cp ${CERTDIR}/req ${SERVER_CADIR} + certu -C -c "chain-2-serverCA" -m 201 -v 60 -d "${P_SERVER_CADIR}" \ + -i req -o "${CERTNAME}-ecmixed.cert" -f "${R_PWFILE}" 2>&1 + + CU_ACTION="Import $CERTNAME's mixed EC Cert -t u,u,u (ext)" + certu -A -n "${CERTNAME}-ecmixed" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ecmixed.cert" 2>&1 + +# CU_ACTION="Import Client mixed EC Root CA -t T,, for $CERTNAME (ext.)" +# certu -A -n "clientCA-ecmixed" -t "T,," -f "${R_PWFILE}" \ +# -d "${PROFILEDIR}" -i "${CLIENT_CADIR}/clientCA-ecmixed.ca.cert" \ +# 2>&1 + fi + echo "Importing all the server's own CA chain into the servers DB" for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ; do N=`basename $CA | sed -e "s/.ca.cert//"` - if [ $N = "serverCA" ] ; then + if [ $N = "serverCA" -o $N = "serverCA-ec" ] ; then T="-t C,C,C" else T="-t u,u,u" @@ -518,7 +768,8 @@ cert_extended_ssl() CU_ACTION="Generate Cert Request for $CERTNAME (ext)" CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 + certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" \ + -o req 2>&1 CU_ACTION="Sign ${CERTNAME}'s Request (ext)" cp ${CERTDIR}/req ${CLIENT_CADIR} @@ -531,11 +782,61 @@ cert_extended_ssl() CU_ACTION="Import Server Root CA -t C,C,C for $CERTNAME (ext.)" certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ -i "${SERVER_CADIR}/serverCA.ca.cert" 2>&1 + + if [ -n "$NSS_ENABLE_ECC" ] ; then +# +# Repeat the above for EC certs +# + CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)" + cp ${CERTDIR}/req ${CLIENT_CADIR} + certu -C -c "chain-2-clientCA-ec" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \ + -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1 + + CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)" + certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ec.cert" 2>&1 + + CU_ACTION="Import Server EC Root CA -t C,C,C for $CERTNAME (ext.)" + certu -A -n "serverCA-ec" -t "C,C,C" -f "${R_PWFILE}" \ + -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-ec.ca.cert" 2>&1 +# +# done with EC certs +# +# +# Repeat the above for mixed EC certs +# + CU_ACTION="Generate mixed EC Cert Request for $CERTNAME (ext)" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ecmixed@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + + CU_ACTION="Sign ${CERTNAME}'s mixed EC Request (ext)" + cp ${CERTDIR}/req ${CLIENT_CADIR} + certu -C -c "chain-2-clientCA" -m 301 -v 60 -d "${P_CLIENT_CADIR}" \ + -i req -o "${CERTNAME}-ecmixed.cert" -f "${R_PWFILE}" 2>&1 + + CU_ACTION="Import $CERTNAME's mixed EC Cert -t u,u,u (ext)" + certu -A -n "${CERTNAME}-ecmixed" -t "u,u,u" -d "${PROFILEDIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ecmixed.cert" 2>&1 + +# CU_ACTION="Import Server EC Root CA -t C,C,C for $CERTNAME (ext.)" +# certu -A -n "serverCA-ec" -t "C,C,C" -f "${R_PWFILE}" \ +# -d "${PROFILEDIR}" -i "${SERVER_CADIR}/serverCA-ec.ca.cert" 2>&1 +# +# done with mixed EC certs +# + fi + echo "Importing all the client's own CA chain into the servers DB" for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ; do N=`basename $CA | sed -e "s/.ca.cert//"` - if [ $N = "clientCA" ] ; then + if [ $N = "clientCA" -o $N = "clientCA-ec" ] ; then T="-t T,C,C" else T="-t u,u,u" @@ -565,7 +866,12 @@ cert_ssl() echo "$SCRIPTNAME: Creating Server CA Issued Certificate for \\" echo " ${HOSTADDR} ------------------------------------" cert_create_cert ${SERVERDIR} "${HOSTADDR}" 100 ${D_SERVER} + CU_ACTION="Modify trust attributes of Root CA -t TC,TC,TC" certu -M -n "TestCA" -t "TC,TC,TC" -d ${PROFILEDIR} + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Modify trust attributes of EC Root CA -t TC,TC,TC" + certu -M -n "TestCA-ec" -t "TC,TC,TC" -d ${PROFILEDIR} + fi # cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER} # echo "************* Copying CA files to ${SERVERDIR}" # cp ${CADIR}/*.db . @@ -623,8 +929,8 @@ cert_stresscerts() cert_fips() { CERTFAILED=0 - echo "$SCRIPTNAME: Creating FIPS 140-1 DSA Certificates ==============" - cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000 "${D_FIPS}" + echo "$SCRIPTNAME: Creating FIPS 140 DSA Certificates ==============" + cert_init_cert "${FIPSDIR}" "FIPS PUB 140 Test Certificate" 1000 "${D_FIPS}" CU_ACTION="Initializing ${CERTNAME}'s Cert DB" certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1 @@ -644,15 +950,151 @@ MODSCRIPT fi CU_ACTION="Generate Certificate for ${CERTNAME}" - CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US" + CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140, L=Mountain View, ST=California, C=US" certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -v 600 -m 500 -z "${R_NOISE_FILE}" 2>&1 if [ "$RET" -eq 0 ]; then cert_log "SUCCESS: FIPS passed" fi } +############################## cert_eccurves ########################### +# local shell function to create server certs for all EC curves +######################################################################## +cert_eccurves() +{ + ################# Creating Certs for EC curves test ######################## + # + if [ -n "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: Creating Server CA Issued Certificate for " + echo " EC Curves Test Certificates ------------------------------------" + cert_init_cert ${ECCURVES_DIR} "EC Curves Test Certificates" 1 ${D_ECCURVES} + CU_ACTION="Initializing EC Curve's Cert DB" + certu -N -d "${ECCURVES_DIR}" -f "${R_PWFILE}" 2>&1 + CU_ACTION="Import EC Root CA for $CERTNAME" + certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" \ + -d "${PROFILEDIR}" -i "${R_CADIR}/ecroot.cert" 2>&1 + + if [ -n "${NSS_ECC_MORE_THAN_SUITE_B}" ] ; then + CURVE_LIST="c2pnb163v1 c2pnb163v2 c2pnb163v3 c2pnb176v1 \ + c2pnb208w1 c2pnb272w1 c2pnb304w1 c2pnb368w1 \ + c2tnb191v1 c2tnb191v2 c2tnb191v3 c2tnb239v1 \ + c2tnb239v2 c2tnb239v3 c2tnb359v1 c2tnb431r1 \ + nistb163 nistb233 nistb283 nistb409 nistb571 \ + nistk163 nistk233 nistk283 nistk409 nistk571 \ + nistp192 nistp224 nistp256 nistp384 nistp521 \ + prime192v1 prime192v2 prime192v3 \ + prime239v1 prime239v2 prime239v3 \ + secp112r1 secp112r2 secp128r1 secp128r2 secp160k1 \ + secp160r1 secp160r2 secp192k1 secp192r1 secp224k1 \ + secp224r1 secp256k1 secp256r1 secp384r1 secp521r1 \ + sect113r1 sect113r2 sect131r1 sect131r2 sect163k1 sect163r1 \ + sect163r2 sect193r1 sect193r2 sect233k1 sect233r1 sect239k1 \ + sect283k1 sect283r1 sect409k1 sect409r1 sect571k1 sect571r1" + else + CURVE_LIST="nistp256 nistp384 nistp521" + fi + CERTSERIAL=2000 + + for CURVE in ${CURVE_LIST} + do + CERTFAILED=0 + CERTNAME="Curve-${CURVE}" + CERTSERIAL=`expr $CERTSERIAL + 1 ` + CU_ACTION="Generate EC Cert Request for $CERTNAME" + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + certu -R -k ec -q "${CURVE}" -d "${ECCURVES_DIR}" -f "${R_PWFILE}" \ + -z "${R_NOISE_FILE}" -o req 2>&1 + + if [ $RET -eq 0 ] ; then + CU_ACTION="Sign ${CERTNAME}'s EC Request" + certu -C -c "TestCA-ec" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \ + -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" "$1" 2>&1 + fi + + if [ $RET -eq 0 ] ; then + CU_ACTION="Import $CERTNAME's EC Cert" + certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${ECCURVES_DIR}" \ + -f "${R_PWFILE}" -i "${CERTNAME}-ec.cert" 2>&1 + fi + done + + fi # if NSS_ENABLE_ECC=1 +} +############################## cert_extensions ############################### +# local shell function to test cert extensions generation. +############################################################################## + +checkRes() +{ + res=$1 + filterList=$2 + + [ $res -ne 0 ] && return 1 + + for fl in `echo $filterList | tr \| ' '`; do + fl="`echo $fl | tr _ ' '`" + expStat=0 + if [ X`echo "$fl" | cut -c 1` = 'X!' ]; then + expStat=1 + fl=`echo $fl | tr -d '!'` + fi + certutil -d ${CERT_EXTENSIONS_DIR} -L -n $CERTNAME | grep "$fl" >/dev/null 2>&1 + [ $? -ne $expStat ] && return 1 + done + return 0 +} + -############################## cert_stresscerts ################################ +cert_extensions() +{ + + CERTNAME=TestExt + cert_create_cert ${CERT_EXTENSIONS_DIR} $CERTNAME 90 ${D_CERT_EXTENSTIONS} + TARG_FILE=${CERT_EXTENSIONS_DIR}/test.args + + CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" + + count=0 + while read arg opt filterList; do + if [ X"`echo $arg | cut -c 1`" = "X#" ]; then + continue + fi + if [ X"`echo $arg | cut -c 1`" = "X!" ]; then + testName="$filterList" + continue + fi + if [ X"$arg" = "X=" ]; then + count=`expr $count + 1` + echo "#################################################" + CU_ACTION="Testing $testName" + certutil -d ${CERT_EXTENSIONS_DIR} -D -n $CERTNAME + echo certutil -d ${CERT_EXTENSIONS_DIR} -S -n $CERTNAME \ + -t "u,u,u" -o /tmp/cert -s "${CU_SUBJECT}" -x -f ${R_PWFILE} \ + -z "${R_NOISE_FILE}" -$opt < $TARG_FILE + certutil -d ${CERT_EXTENSIONS_DIR} -S -n $CERTNAME -t "u,u,u" \ + -o /tmp/cert -s "${CU_SUBJECT}" -x -f ${R_PWFILE} \ + -z "${R_NOISE_FILE}" -$opt < $TARG_FILE + ret=$? + echo "certutil options:" + cat $TARG_FILE + checkRes $ret "$filterList" + RET=$? + if [ "$RET" -ne 0 ]; then + CERTFAILED=$RET + html_failed "<TR><TD>${CU_ACTION} ($RET) " + cert_log "ERROR: ${CU_ACTION} failed $RET" + else + html_passed "<TR><TD>${CU_ACTION}" + fi + rm -f $TARG_FILE + else + echo $arg >> $TARG_FILE + fi + done < ${QADIR}/cert/certext.txt +} + + +############################## cert_crl_ssl ############################ # local shell function to generate certs and crls for SSL tests ######################################################################## cert_crl_ssl() @@ -688,48 +1130,92 @@ cert_crl_ssl() CRLUPDATE=`date +%Y%m%d%H%M%SZ` CU_ACTION="Generating CRL for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA authority" CRL_GRP_END_=`expr ${CRL_GRP_END} - 1` - crlu -d $CADIR -G -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}_or <<EOF_CRLINI + crlu -d $CADIR -G -n "TestCA" -f ${R_PWFILE} \ + -o ${CRL_FILE_GRP_1}_or <<EOF_CRLINI update=$CRLUPDATE addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE addext reasonCode 0 4 -addext issuerAltNames 0 "rfc822Name:caemail@ca.com|dnsName:ca.com|x400Address:x400Address|directoryName:CN=NSS Test CA,O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca.com|ipAddress:192.168.0.1|registerID=reg CA" +addext issuerAltNames 0 "rfc822Name:caemail@ca.com|dnsName:ca.com|directoryName:CN=NSS Test CA,O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca.com|ipAddress:192.168.0.1|registerID=reg CA" EOF_CRLINI # This extension should be added to the list, but currently nss has bug #addext authKeyId 0 "CN=NSS Test CA,O=BOGUS NSS,L=Mountain View,ST=California,C=US" 1 CRL_GEN_RES=`expr $? + $CRL_GEN_RES` - chmod 600 ${CRL_FILE_GRP_1}_or + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Generating CRL (ECC) for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA-ec authority" + +# Until Bug 292285 is resolved, do not encode x400 Addresses. After +# the bug is resolved, reintroduce "x400Address:x400Address" within +# addext issuerAltNames ... + crlu -q -d $CADIR -G -n "TestCA-ec" -f ${R_PWFILE} \ + -o ${CRL_FILE_GRP_1}_or-ec <<EOF_CRLINI +update=$CRLUPDATE +addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE +addext reasonCode 0 4 +addext issuerAltNames 0 "rfc822Name:ca-ecemail@ca.com|dnsName:ca-ec.com|directoryName:CN=NSS Test CA (ECC),O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca-ec.com|ipAddress:192.168.0.1|registerID=reg CA (ECC)" +EOF_CRLINI + CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + chmod 600 ${CRL_FILE_GRP_1}_or-ec + fi + echo test > file ############################# Modification ################################## echo "$SCRIPTNAME: Modifying CA CRL by adding one more cert ============" sleep 2 + CRLUPDATE=`date "+%Y%m%d%H%M%SZ"` CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"` - CU_ACTION="Modification CRL by adding one more cert" + CU_ACTION="Modify CRL by adding one more cert" crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}_or1 \ -i ${CRL_FILE_GRP_1}_or <<EOF_CRLINI +update=$CRLUPDATE addcert ${CRL_GRP_END} $CRL_GRP_DATE EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_1}_or1 TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or" + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Modify CRL (ECC) by adding one more cert" + crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} \ + -o ${CRL_FILE_GRP_1}_or1-ec -i ${CRL_FILE_GRP_1}_or-ec <<EOF_CRLINI +update=$CRLUPDATE +addcert ${CRL_GRP_END} $CRL_GRP_DATE +EOF_CRLINI + CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + chmod 600 ${CRL_FILE_GRP_1}_or1-ec + TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or-ec" + fi ########### Removing one cert ${UNREVOKED_CERT_GRP_1} ####################### echo "$SCRIPTNAME: Modifying CA CRL by removing one cert ===============" - CU_ACTION="Modification CRL by removing one cert" + CU_ACTION="Modify CRL by removing one cert" + sleep 2 + CRLUPDATE=`date "+%Y%m%d%H%M%SZ"` crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1} \ -i ${CRL_FILE_GRP_1}_or1 <<EOF_CRLINI +update=$CRLUPDATE rmcert ${UNREVOKED_CERT_GRP_1} EOF_CRLINI chmod 600 ${CRL_FILE_GRP_1} TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1" + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Modify CRL (ECC) by removing one cert" + crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}-ec \ + -i ${CRL_FILE_GRP_1}_or1-ec <<EOF_CRLINI +update=$CRLUPDATE +rmcert ${UNREVOKED_CERT_GRP_1} +EOF_CRLINI + chmod 600 ${CRL_FILE_GRP_1}-ec + TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1-ec" + fi ########### Creating second CRL which includes groups 1 and 2 ############## CRL_GRP_END=`expr ${CRL_GRP_2_BEGIN} + ${CRL_GRP_2_RANGE} - 1` CRL_FILE_GRP_2=${R_SERVERDIR}/root.crl_${CRL_GRP_2_BEGIN}-${CRL_GRP_END} echo "$SCRIPTNAME: Creating CA CRL for groups 1 and 2 ===============" + sleep 2 CRLUPDATE=`date "+%Y%m%d%H%M%SZ"` CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"` CU_ACTION="Creating CRL for groups 1 and 2" @@ -742,6 +1228,18 @@ rmcert ${UNREVOKED_CERT_GRP_2} EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_2} + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Creating CRL (ECC) for groups 1 and 2" + crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_2}-ec \ + -i ${CRL_FILE_GRP_1}-ec <<EOF_CRLINI +update=$CRLUPDATE +addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE +addext invalidityDate 0 $CRLUPDATE +rmcert ${UNREVOKED_CERT_GRP_2} +EOF_CRLINI + CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + chmod 600 ${CRL_FILE_GRP_2}-ec + fi ########### Creating second CRL which includes groups 1, 2 and 3 ############## CRL_GRP_END=`expr ${CRL_GRP_3_BEGIN} + ${CRL_GRP_3_RANGE} - 1` @@ -761,13 +1259,33 @@ addext crlNumber 0 2 EOF_CRLINI CRL_GEN_RES=`expr $? + $CRL_GEN_RES` chmod 600 ${CRL_FILE_GRP_3} + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Creating CRL (ECC) for groups 1, 2 and 3" + crlu -d $CADIR -M -n "TestCA-ec" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3}-ec \ + -i ${CRL_FILE_GRP_2}-ec <<EOF_CRLINI +update=$CRLUPDATE +addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE +rmcert ${UNREVOKED_CERT_GRP_3} +addext crlNumber 0 2 +EOF_CRLINI + CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + chmod 600 ${CRL_FILE_GRP_3}-ec + fi ############ Importing Server CA Issued CRL for certs of first group ####### echo "$SCRIPTNAME: Importing Server CA Issued CRL for certs ${CRL_GRP_BEGIN} trough ${CRL_GRP_END}" CU_ACTION="Importing CRL for groups 1" + crlu -D -n TestCA -f "${R_PWFILE}" -d "${R_SERVERDIR}" crlu -I -i ${CRL_FILE} -n "TestCA" -f "${R_PWFILE}" -d "${R_SERVERDIR}" CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + if [ -n "$NSS_ENABLE_ECC" ] ; then + CU_ACTION="Importing CRL (ECC) for groups 1" + crlu -D -n TestCA-ec -f "${R_PWFILE}" -d "${R_SERVERDIR}" + crlu -I -i ${CRL_FILE}-ec -n "TestCA-ec" -f "${R_PWFILE}" \ + -d "${R_SERVERDIR}" + CRL_GEN_RES=`expr $? + $CRL_GEN_RES` + fi if [ "$CERTFAILED" != 0 -o "$CRL_GEN_RES" != 0 ] ; then cert_log "ERROR: SSL CRL prep failed $CERTFAILED : $CRL_GEN_RES" @@ -796,6 +1314,8 @@ cert_extended_ssl cert_ssl cert_smime_client cert_fips +cert_eccurves +cert_extensions cert_crl_ssl if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then cert_stresscerts diff --git a/security/nss/tests/cert/certext.txt b/security/nss/tests/cert/certext.txt new file mode 100644 index 000000000..493cd375e --- /dev/null +++ b/security/nss/tests/cert/certext.txt @@ -0,0 +1,132 @@ +# File syntax: +# '#' comments. +# If the line starts from '!'('! TEST_N Test Name String'), +# then 'Test Name String' will be the name of a test(starting +# from second space till the rest of the line). +# All uncommented lines are hard codded answers to certutil +# extension questions. +# Line '= N string1|string2|string3': '=' is a stop sign +# of certutil inputs and start of the test. 'N' is the number +# of extension that will be tested. 'string1|string2|string3' +# are grep patterns for test result verification. '_' in stringN +# will be replaced to a space. +# ################################################################ +! TEST_1 Certificate Key Usage Extension +0 +1 +2 +3 +4 +5 +6 +10 +n += 1 Certificate_Key_Usage|Digital_Signature|Non-Repudiation|Key_Encipherment|Data_Encipherment|Key_Agreement|Certificate_Signing|CRL_Signing +# ################################################################ +! TEST_2 Certificate Key Usage Extension +0 +1 +2 +3 +4 +5 +6 +10 +y += 1 Certificate_Key_Usage|Digital_Signature|Critical:_True +# ################################################################ +! TEST_3 Certificate Basic Constraints Extension +y +-1 +n += 2 Name:_Certificate_Basic_Constraints|Data:_Is_a_CA_with_no_maximum +# ################################################################ +! TEST_4 Certificate Basic Constraints Extension +n +-1 +y += 2 Name:_Certificate_Basic_Constraints|Data:_Is_not_a_CA|Critical:_True +# ################################################################ +! TEST_5 Certificate Authority Key Identifier Extension +y +12341235123 + + +y += 3 Name:_Certificate_Authority_Key_Identifier|Critical:_True|Key_ID:|12341235123 +# ################################################################ +! TEST_6 Certificate Authority Key Identifier Extension +y + +3 +test.com + +214123 +y += 3 Name:_Certificate_Authority_Key_Identifier|Critical:_True|Issuer:|DNS_name:_"test.com"|Serial_Number:|214123 +# ################################################################ +! TEST_7 CRL Distribution Points Extension +1 +1 +InstanceOfOtherName +2 +rfc822Name +3 +test.com +4 +test@test.com +6 +ediPArtyName +8 +ipAddress +9 +123451235 +10 +0 +10 +n +n += 4 Name:_CRL_Distribution_Points|InstanceOfOtherName|rfc822Name|test.com|test@test.com|ediPArtyName +# ################################################################# +! TEST_8 CRL Distribution Points Extension +2 +SN=asdfsdf +4 +3 +test.com +10 +n +n += 4 Name:_CRL_Distribution_Points|X520_Title|"asdfsdf"|Reasons:|DNS_name:_"test.com" +# ################################################################ +! TEST_9 Certificate Type Extension +0 +1 +2 +10 +n += 5 Name:_Certificate_Type|Data:_<SSL_Client,SSL_Server,S/MIME> +# ################################################################ +! TEST_10 Extended Key Usage Extension +0 +1 +2 +3 +4 +5 +6 +10 +y += 6 Name:_Extended_Key_Usage|Critical:_True|TLS_Web_Server_Authentication_Certificate|TLS_Web_Client_Authentication_Certificate|Code_Signing_Certificate|E-Mail_Protection_Certificate|Time_Stamping_Certifcate|OCSP_Responder_Certificate|Strong_Crypto_Export_Approved +# ################################################################ +! TEST_11 Certificate Key Usage Extension + +1 +2 +3 +4 +5 +6 +10 +n += 1 Certificate_Key_Usage|!Digital_Signature|Non-Repudiation|Key_Encipherment|Data_Encipherment|Key_Agreement|Certificate_Signing|CRL_Signing diff --git a/security/nss/tests/cert/eccert.sh b/security/nss/tests/cert/eccert.sh deleted file mode 100644 index e1a172455..000000000 --- a/security/nss/tests/cert/eccert.sh +++ /dev/null @@ -1,886 +0,0 @@ -#! /bin/sh -# -# ***** 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): -# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 -# 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 ***** - -######################################################################## -# -# mozilla/security/nss/tests/cert/rcert.sh -# -# Certificate generating and handeling for NSS QA, can be included -# multiple times from all.sh and the individual scripts -# -# needs to work on all Unix and Windows platforms -# -# included from (don't expect this to be up to date) -# -------------------------------------------------- -# all.sh -# ssl.sh -# smime.sh -# tools.sh -# -# special strings -# --------------- -# FIXME ... known problems, search for this string -# NOTE .... unexpected behavior -# -# FIXME - Netscape - NSS -######################################################################## - -############################## cert_init ############################### -# local shell function to initialize this script -######################################################################## -cert_init() -{ - SCRIPTNAME="cert.sh" - if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for - CLEANUP="${SCRIPTNAME}" # cleaning this script will do it - fi - if [ -z "${INIT_SOURCED}" ] ; then - cd ../common - . ./init.sh - fi - SCRIPTNAME="cert.sh" - html_head "Certutil Tests" - - ################## Generate noise for our CA cert. ###################### - # NOTE: these keys are only suitable for testing, as this whole thing - # bypasses the entropy gathering. Don't use this method to generate - # keys and certs for product use or deployment. - # - ps -efl > ${NOISE_FILE} 2>&1 - ps aux >> ${NOISE_FILE} 2>&1 - noise - -} - -cert_log() ###################### write the cert_status file -{ - echo "$SCRIPTNAME $*" - echo $* >>${CERT_LOG_FILE} -} - -################################ noise ################################## -# Generate noise for our certs -# -# NOTE: these keys are only suitable for testing, as this whole thing bypasses -# the entropy gathering. Don't use this method to generate keys and certs for -# product use or deployment. -######################################################################### -noise() -{ - #netstat >> ${NOISE_FILE} 2>&1 - date >> ${NOISE_FILE} 2>&1 -} - -################################ certu ################################# -# local shell function to call certutil, also: writes action and options to -# stdout, sets variable RET and writes results to the html file results -######################################################################## -certu() -{ - echo "$SCRIPTNAME: ${CU_ACTION} --------------------------" - - if [ -n "${CU_SUBJECT}" ]; then - #the subject of the cert contains blanks, and the shell - #will strip the quotes off the string, if called otherwise... - echo "certutil -s \"${CU_SUBJECT}\" $*" - certutil -s "${CU_SUBJECT}" $* - RET=$? - CU_SUBJECT="" - else - echo "certutil $*" - certutil $* - RET=$? - fi - if [ "$RET" -ne 0 ]; then - CERTFAILED=$RET - html_failed "<TR><TD>${CU_ACTION} ($RET) " - cert_log "ERROR: ${CU_ACTION} failed $RET" - else - html_passed "<TR><TD>${CU_ACTION}" - fi - - # echo "Contine?" - # cat > /dev/null - return $RET -} - -############################# cert_init_cert ########################## -# local shell function to initialize creation of client and server certs -######################################################################## -cert_init_cert() -{ - CERTDIR="$1" - CERTNAME="$2" - CERTSERIAL="$3" - DOMAIN="$4" - - if [ ! -d "${CERTDIR}" ]; then - mkdir -p "${CERTDIR}" - else - echo "$SCRIPTNAME: WARNING - ${CERTDIR} exists" - fi - cd "${CERTDIR}" - CERTDIR="." - - PROFILEDIR=${CERTDIR} - if [ -n "${MULTIACCESS_DBM}" ]; then - PROFILEDIR="multiaccess:${DOMAIN}" - fi - - noise -} - -############################# hw_acc ################################# -# local shell function to add hw accelerator modules to the db -######################################################################## -hw_acc() -{ - HW_ACC_RET=0 - HW_ACC_ERR="" - if [ -n "$O_HWACC" -a "$O_HWACC" = ON -a -z "$USE_64" ] ; then - echo "creating $CERTNAME s cert with hwaccelerator..." - #case $ACCELERATOR in - #rainbow) - - - echo "modutil -add rainbow -libfile /usr/lib/libcryptoki22.so " - echo " -dbdir ${PROFILEDIR} 2>&1 " - echo | modutil -add rainbow -libfile /usr/lib/libcryptoki22.so \ - -dbdir ${PROFILEDIR} 2>&1 - if [ "$?" -ne 0 ]; then - echo "modutil -add rainbow failed in `pwd`" - HW_ACC_RET=1 - HW_ACC_ERR="modutil -add rainbow" - fi - - echo "modutil -add ncipher " - echo " -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so " - echo " -dbdir ${PROFILEDIR} 2>&1 " - echo | modutil -add ncipher \ - -libfile /opt/nfast/toolkits/pkcs11/libcknfast.so \ - -dbdir ${PROFILEDIR} 2>&1 - if [ "$?" -ne 0 ]; then - echo "modutil -add ncipher failed in `pwd`" - HW_ACC_RET=`expr $HW_ACC_RET + 2` - HW_ACC_ERR="$HW_ACC_ERR,modutil -add ncipher" - fi - if [ "$HW_ACC_RET" -ne 0 ]; then - html_failed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME} ($HW_ACC_RET) " - else - html_passed "<TR><TD>Adding HW accelerators to certDB for ${CERTNAME}" - fi - - fi - return $HW_ACC_RET -} - -############################# cert_create_cert ######################### -# local shell function to create client certs -# initialize DB, import -# root cert -# add cert to DB -######################################################################## -cert_create_cert() -{ - cert_init_cert "$1" "$2" "$3" "$4" - - CU_ACTION="Initializing ${CERTNAME}'s Cert DB" - certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - hw_acc - CU_ACTION="Import Root CA for $CERTNAME" - certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${R_CADIR}/root.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - cert_add_cert "$5" - return $? -} - -############################# cert_create_certs ######################## -# local shell function to create client certs -# initialize DB, import -# root certs (RSA and EC) -# add certs (RSA and EC) to DB -######################################################################## -cert_create_certs() -{ - cert_init_cert "$1" "$2" "$3" "$4" - - CU_ACTION="Initializing ${CERTNAME}'s Cert DB" - certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - hw_acc - CU_ACTION="Import Root CA for $CERTNAME" - certu -A -n "TestCA" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${R_CADIR}/root.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - CU_ACTION="Import EC Root CA for $CERTNAME" - certu -A -n "TestCA-ec" -t "TC,TC,TC" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${R_CADIR}/ecroot.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - cert_add_certs "$5" - return $? -} - -############################# cert_add_cert ############################ -# local shell function to add client certs to an existing CERT DB -# generate request -# sign request -# import Cert -# -######################################################################## -cert_add_cert() -{ - - CU_ACTION="Generate Cert Request for $CERTNAME" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Sign ${CERTNAME}'s Request" - certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \ - -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Import $CERTNAME's Cert" - certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - cert_log "SUCCESS: $CERTNAME's Cert Created" - return 0 -} - -############################# cert_add_certs ############################ -# local shell function to add client certs to an existing CERT DB -# generate request -# sign request -# import Cert -# -# Do this for both RSA and EC certs -######################################################################## -cert_add_certs() -{ - CURVE="secp160r2" - - CU_ACTION="Generate Cert Request for $CERTNAME" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Sign ${CERTNAME}'s Request" - certu -C -c "TestCA" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \ - -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" "$1" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Import $CERTNAME's Cert" - certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - cert_log "SUCCESS: $CERTNAME's Cert Created" - -# -# Generate and add EC cert -# - CU_ACTION="Generate EC Cert Request for $CERTNAME" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -k ec -q "${CURVE}" -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Sign ${CERTNAME}'s EC Request" - certu -C -c "TestCA-ec" -m "$CERTSERIAL" -v 60 -d "${P_R_CADIR}" \ - -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" "$1" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - CU_ACTION="Import $CERTNAME's EC Cert" - certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}-ec.cert" 2>&1 - if [ "$RET" -ne 0 ]; then - return $RET - fi - - cert_log "SUCCESS: $CERTNAME's EC Cert Created" - - return 0 -} - -################################# cert_all_CA ################################ -# local shell function to build the additional Temp. Certificate Authority (CA) -# used for the "real life" ssl test with 2 different CA's in the -# client and in teh server's dir -########################################################################## -cert_all_CA() -{ - CA_CURVE="secp160r1" - - echo nss > ${PWFILE} - - ALL_CU_SUBJECT="CN=NSS Test CA, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - cert_CA $CADIR TestCA -x "CTu,CTu,CTu" ${D_CA} "1" - -# Create EC version of TestCA - ALL_CU_SUBJECT="CN=NSS Test CA (ECC), O=BOGUS NSS, L=Mountain View, ST=California, C=US" - cert_ec_CA $CADIR TestCA-ec -x "CTu,CTu,CTu" ${D_CA} "1" ${CA_CURVE} - - ALL_CU_SUBJECT="CN=NSS Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $SERVER_CADIR serverCA -x "Cu,Cu,Cu" ${D_SERVER_CA} "2" - ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $SERVER_CADIR chain-1-serverCA "-c serverCA" "u,u,u" ${D_SERVER_CA} "3" - ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $SERVER_CADIR chain-2-serverCA "-c chain-1-serverCA" "u,u,u" ${D_SERVER_CA} "4" - -# -# Create EC versions of the above CA certs -# - ALL_CU_SUBJECT="CN=NSS Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $SERVER_CADIR serverCA-ec -x "Cu,Cu,Cu" ${D_SERVER_CA} "2" ${CA_CURVE} - ALL_CU_SUBJECT="CN=NSS Chain1 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $SERVER_CADIR chain-1-serverCA-ec "-c serverCA-ec" "u,u,u" ${D_SERVER_CA} "3" ${CA_CURVE} - ALL_CU_SUBJECT="CN=NSS Chain2 Server Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $SERVER_CADIR chain-2-serverCA-ec "-c chain-1-serverCA-ec" "u,u,u" ${D_SERVER_CA} "4" ${CA_CURVE} - - - ALL_CU_SUBJECT="CN=NSS Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $CLIENT_CADIR clientCA -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5" - ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $CLIENT_CADIR chain-1-clientCA "-c clientCA" "u,u,u" ${D_CLIENT_CA} "6" - ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA, O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_CA $CLIENT_CADIR chain-2-clientCA "-c chain-1-clientCA" "u,u,u" ${D_CLIENT_CA} "7" - -# -# Create EC versions of the above CA certs -# - ALL_CU_SUBJECT="CN=NSS Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $CLIENT_CADIR clientCA-ec -x "Tu,Cu,Cu" ${D_CLIENT_CA} "5" ${CA_CURVE} - ALL_CU_SUBJECT="CN=NSS Chain1 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $CLIENT_CADIR chain-1-clientCA-ec "-c clientCA-ec" "u,u,u" ${D_CLIENT_CA} "6" ${CA_CURVE} - ALL_CU_SUBJECT="CN=NSS Chain2 Client Test CA (ECC), O=BOGUS NSS, L=Santa Clara, ST=California, C=US" - cert_ec_CA $CLIENT_CADIR chain-2-clientCA-ec "-c chain-1-clientCA-ec" "u,u,u" ${D_CLIENT_CA} "7" ${CA_CURVE} - - rm $CLIENT_CADIR/root.cert $SERVER_CADIR/root.cert - rm $CLIENT_CADIR/ecroot.cert $SERVER_CADIR/ecroot.cert - # root.cert in $CLIENT_CADIR and in $SERVER_CADIR is the one of the last - # in the chain -} - -################################# cert_CA ################################ -# local shell function to build the Temp. Certificate Authority (CA) -# used for testing purposes, creating a CA Certificate and a root cert -########################################################################## -cert_CA() -{ - CUR_CADIR=$1 - NICKNAME=$2 - SIGNER=$3 - TRUSTARG=$4 - DOMAIN=$5 - CERTSERIAL=$6 - - echo "$SCRIPTNAME: Creating a CA Certificate $NICKNAME ==========================" - - if [ ! -d "${CUR_CADIR}" ]; then - mkdir -p "${CUR_CADIR}" - fi - cd ${CUR_CADIR} - pwd - - LPROFILE=. - if [ -n "${MULTIACCESS_DBM}" ]; then - LPROFILE="multiaccess:${DOMAIN}" - fi - - if [ "$SIGNER" = "-x" ] ; then # self signed -> create DB - CU_ACTION="Creating CA Cert DB" - certu -N -d ${LPROFILE} -f ${R_PWFILE} 2>&1 - if [ "$RET" -ne 0 ]; then - Exit 5 "Fatal - failed to create CA $NICKNAME " - fi - echo "$SCRIPTNAME: Certificate initialized ----------" - fi - - - ################# Creating CA Cert ###################################### - # - CU_ACTION="Creating CA Cert $NICKNAME " - CU_SUBJECT=$ALL_CU_SUBJECT - certu -S -n $NICKNAME -t $TRUSTARG -v 60 $SIGNER -d ${LPROFILE} -1 -2 -5 \ - -f ${R_PWFILE} -z ${R_NOISE_FILE} -m $CERTSERIAL 2>&1 <<CERTSCRIPT -5 -9 -n -y --1 -n -5 -6 -7 -9 -n -CERTSCRIPT - - if [ "$RET" -ne 0 ]; then - echo "return value is $RET" - Exit 6 "Fatal - failed to create CA cert" - fi - - ################# Exporting Root Cert ################################### - # - CU_ACTION="Exporting Root Cert" - certu -L -n $NICKNAME -r -d ${LPROFILE} -o root.cert - if [ "$RET" -ne 0 ]; then - Exit 7 "Fatal - failed to export root cert" - fi - cp root.cert ${NICKNAME}.ca.cert -} - -################################ cert_ec_CA ############################## -# local shell function to build the Temp. Certificate Authority (CA) -# used for testing purposes, creating a CA Certificate and a root cert -# This is the ECC version of cert_CA. -########################################################################## -cert_ec_CA() -{ - CUR_CADIR=$1 - NICKNAME=$2 - SIGNER=$3 - TRUSTARG=$4 - DOMAIN=$5 - CERTSERIAL=$6 - CURVE=$7 - - echo "$SCRIPTNAME: Creating an EC CA Certificate $NICKNAME ==========================" - - if [ ! -d "${CUR_CADIR}" ]; then - mkdir -p "${CUR_CADIR}" - fi - cd ${CUR_CADIR} - pwd - - LPROFILE=. - if [ -n "${MULTIACCESS_DBM}" ]; then - LPROFILE="multiaccess:${DOMAIN}" - fi - - ################# Creating an EC CA Cert ################################ - # - CU_ACTION="Creating EC CA Cert $NICKNAME " - CU_SUBJECT=$ALL_CU_SUBJECT - certu -S -n $NICKNAME -k ec -q $CURVE -t $TRUSTARG -v 60 $SIGNER \ - -d ${LPROFILE} -1 -2 -5 -f ${R_PWFILE} -z ${R_NOISE_FILE} \ - -m $CERTSERIAL 2>&1 <<CERTSCRIPT -5 -9 -n -y --1 -n -5 -6 -7 -9 -n -CERTSCRIPT - - if [ "$RET" -ne 0 ]; then - echo "return value is $RET" - Exit 6 "Fatal - failed to create EC CA cert" - fi - - ################# Exporting EC Root Cert ################################ - # - CU_ACTION="Exporting EC Root Cert" - certu -L -n $NICKNAME -r -d ${LPROFILE} -o ecroot.cert - if [ "$RET" -ne 0 ]; then - Exit 7 "Fatal - failed to export ec root cert" - fi - cp ecroot.cert ${NICKNAME}.ca.cert -} - -############################## cert_smime_client ############################# -# local shell function to create client Certificates for S/MIME tests -############################################################################## -cert_smime_client() -{ - CERTFAILED=0 - echo "$SCRIPTNAME: Creating Client CA Issued Certificates ==============" - - cert_create_certs ${ALICEDIR} "Alice" 30 ${D_ALICE} - cert_create_certs ${BOBDIR} "Bob" 40 ${D_BOB} - - echo "$SCRIPTNAME: Creating Dave's Certificate -------------------------" - cert_create_cert "${DAVEDIR}" Dave 50 ${D_DAVE} - - echo "$SCRIPTNAME: Creating multiEmail's Certificate --------------------" - cert_create_cert "${EVEDIR}" "Eve" 60 ${D_EVE} "-7 eve@bogus.net,eve@bogus.cc,beve@bogus.com" - - #echo "************* Copying CA files to ${SERVERDIR}" - #cp ${CADIR}/*.db . - #hw_acc - - ######################################################################### - # - #cd ${CERTDIR} - #CU_ACTION="Creating ${CERTNAME}'s Server Cert" - #CU_SUBJECT="CN=${CERTNAME}, E=${CERTNAME}@bogus.com, O=BOGUS Netscape, L=Mountain View, ST=California, C=US" - #certu -S -n "${CERTNAME}" -c "TestCA" -t "u,u,u" -m "$CERTSERIAL" \ - # -d ${PROFILEDIR} -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1 - - #CU_ACTION="Export Dave's Cert" - #cd ${DAVEDIR} - #certu -L -n "Dave" -r -d ${P_R_DAVE} -o Dave.cert - - ################# Importing Certificates for S/MIME tests ############### - # - echo "$SCRIPTNAME: Importing Certificates ==============================" - CU_ACTION="Import Bob's cert into Alice's db" - certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ - -i ${R_BOBDIR}/Bob.cert 2>&1 - - CU_ACTION="Import Dave's cert into Alice's DB" - certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ - -i ${R_DAVEDIR}/Dave.cert 2>&1 - - CU_ACTION="Import Dave's cert into Bob's DB" - certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \ - -i ${R_DAVEDIR}/Dave.cert 2>&1 - - CU_ACTION="Import Eve's cert into Alice's DB" - certu -E -t "p,p,p" -d ${P_R_ALICEDIR} -f ${R_PWFILE} \ - -i ${R_EVEDIR}/Eve.cert 2>&1 - - CU_ACTION="Import Eve's cert into Bob's DB" - certu -E -t "p,p,p" -d ${P_R_BOBDIR} -f ${R_PWFILE} \ - -i ${R_EVEDIR}/Eve.cert 2>&1 - - if [ "$CERTFAILED" != 0 ] ; then - cert_log "ERROR: SMIME failed $RET" - else - cert_log "SUCCESS: SMIME passed" - fi -} - -############################## cert_ssl ################################ -# local shell function to create client + server certs for extended SSL test -######################################################################## -cert_extended_ssl() -{ - EC_CURVE="sect163r1" - - ################# Creating Certs for extended SSL test #################### - # - CERTFAILED=0 - echo "$SCRIPTNAME: Creating Certificates, issued by the last ===============" - echo " of a chain of CA's which are not in the same database============" - - echo "Server Cert" - cert_init_cert ${EXT_SERVERDIR} "${HOSTADDR}" 1 ${D_EXT_SERVER} - - CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)" - certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Generate Cert Request for $CERTNAME (ext)" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - - CU_ACTION="Sign ${CERTNAME}'s Request (ext)" - cp ${CERTDIR}/req ${SERVER_CADIR} - certu -C -c "chain-2-serverCA" -m 200 -v 60 -d "${P_SERVER_CADIR}" \ - -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)" - certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}.cert" 2>&1 - - CU_ACTION="Import Client Root CA -t T,, for $CERTNAME (ext.)" - certu -A -n "clientCA" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${CLIENT_CADIR}/clientCA.ca.cert" 2>&1 -# -# Repeat the above for EC certs -# - CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - - CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)" - cp ${CERTDIR}/req ${SERVER_CADIR} - certu -C -c "chain-2-serverCA-ec" -m 200 -v 60 -d "${P_SERVER_CADIR}" \ - -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)" - certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}-ec.cert" 2>&1 - - CU_ACTION="Import Client EC Root CA -t T,, for $CERTNAME (ext.)" - certu -A -n "clientCA-ec" -t "T,," -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${CLIENT_CADIR}/clientCA-ec.ca.cert" 2>&1 -# -# done with EC certs -# - echo "Importing all the server's own CA chain into the servers DB" - for CA in `find ${SERVER_CADIR} -name "?*.ca.cert"` ; - do - N=`basename $CA | sed -e "s/.ca.cert//"` - if [ $N = "serverCA" ] ; then - T="-t C,C,C" - else - T="-t u,u,u" - fi - CU_ACTION="Import $N CA $T for $CERTNAME (ext.) " - certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${CA}" 2>&1 - done -#============ - echo "Client Cert" - cert_init_cert ${EXT_CLIENTDIR} ExtendedSSLUser 1 ${D_EXT_CLIENT} - - CU_ACTION="Initializing ${CERTNAME}'s Cert DB (ext.)" - certu -N -d "${PROFILEDIR}" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Generate Cert Request for $CERTNAME (ext)" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - - CU_ACTION="Sign ${CERTNAME}'s Request (ext)" - cp ${CERTDIR}/req ${CLIENT_CADIR} - certu -C -c "chain-2-clientCA" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \ - -i req -o "${CERTNAME}.cert" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Import $CERTNAME's Cert -t u,u,u (ext)" - certu -A -n "$CERTNAME" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}.cert" 2>&1 - CU_ACTION="Import Server Root CA -t C,C,C for $CERTNAME (ext.)" - certu -A -n "serverCA" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${SERVER_CADIR}/serverCA.ca.cert" 2>&1 -# -# Repeat the above for EC certs -# - CU_ACTION="Generate EC Cert Request for $CERTNAME (ext)" - CU_SUBJECT="CN=$CERTNAME, E=${CERTNAME}-ec@bogus.com, O=BOGUS NSS, L=Mountain View, ST=California, C=US" - certu -R -d "${PROFILEDIR}" -k ec -q "${EC_CURVE}" -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -o req 2>&1 - - CU_ACTION="Sign ${CERTNAME}'s EC Request (ext)" - cp ${CERTDIR}/req ${CLIENT_CADIR} - certu -C -c "chain-2-clientCA-ec" -m 300 -v 60 -d "${P_CLIENT_CADIR}" \ - -i req -o "${CERTNAME}-ec.cert" -f "${R_PWFILE}" 2>&1 - - CU_ACTION="Import $CERTNAME's EC Cert -t u,u,u (ext)" - certu -A -n "${CERTNAME}-ec" -t "u,u,u" -d "${PROFILEDIR}" -f "${R_PWFILE}" \ - -i "${CERTNAME}-ec.cert" 2>&1 - CU_ACTION="Import Server EC Root CA -t C,C,C for $CERTNAME (ext.)" - certu -A -n "serverCA-ec" -t "C,C,C" -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${SERVER_CADIR}/serverCA-ec.ca.cert" 2>&1 -# -# done with EC certs -# - echo "Importing all the client's own CA chain into the servers DB" - for CA in `find ${CLIENT_CADIR} -name "?*.ca.cert"` ; - do - N=`basename $CA | sed -e "s/.ca.cert//"` - if [ $N = "clientCA" ] ; then - T="-t T,C,C" - else - T="-t u,u,u" - fi - CU_ACTION="Import $N CA $T for $CERTNAME (ext.)" - certu -A -n $N $T -f "${R_PWFILE}" -d "${PROFILEDIR}" \ - -i "${CA}" 2>&1 - done - if [ "$CERTFAILED" != 0 ] ; then - cert_log "ERROR: EXT failed $RET" - else - cert_log "SUCCESS: EXT passed" - fi -} - -############################## cert_ssl ################################ -# local shell function to create client + server certs for SSL test -######################################################################## -cert_ssl() -{ - ################# Creating Certs for SSL test ########################### - # - CERTFAILED=0 - echo "$SCRIPTNAME: Creating Client CA Issued Certificates ===============" - cert_create_certs ${CLIENTDIR} "TestUser" 70 ${D_CLIENT} - - echo "$SCRIPTNAME: Creating Server CA Issued Certificate for \\" - echo " ${HOSTADDR} ------------------------------------" - cert_create_certs ${SERVERDIR} "${HOSTADDR}" 100 ${D_SERVER} - certu -M -n "TestCA" -t "TC,TC,TC" -d ${PROFILEDIR} - certu -M -n "TestCA-ec" -t "TC,TC,TC" -d ${PROFILEDIR} -# cert_init_cert ${SERVERDIR} "${HOSTADDR}" 1 ${D_SERVER} -# echo "************* Copying CA files to ${SERVERDIR}" -# cp ${CADIR}/*.db . -# hw_acc -# CU_ACTION="Creating ${CERTNAME}'s Server Cert" -# CU_SUBJECT="CN=${CERTNAME}, O=BOGUS Netscape, L=Mountain View, ST=California, C=US" -# certu -S -n "${CERTNAME}" -c "TestCA" -t "Pu,Pu,Pu" -d ${PROFILEDIR} \ -# -f "${R_PWFILE}" -z "${R_NOISE_FILE}" -v 60 2>&1 - - if [ "$CERTFAILED" != 0 ] ; then - cert_log "ERROR: SSL failed $RET" - else - cert_log "SUCCESS: SSL passed" - fi -} -############################## cert_stresscerts ################################ -# local shell function to create client certs for SSL stresstest -######################################################################## -cert_stresscerts() -{ - - ############### Creating Certs for SSL stress test ####################### - # - CERTDIR="$CLIENTDIR" - cd "${CERTDIR}" - - PROFILEDIR=${CERTDIR} - if [ -n "${MULTIACCESS_DBM}" ]; then - PROFILEDIR="multiaccess:${D_CLIENT}" - fi - CERTFAILED=0 - echo "$SCRIPTNAME: Creating Client CA Issued Certificates ===============" - - CONTINUE=$GLOB_MAX_CERT - CERTSERIAL=10 - - while [ $CONTINUE -ge $GLOB_MIN_CERT ] - do - CERTNAME="TestUser$CONTINUE" -# cert_add_cert ${CLIENTDIR} "TestUser$CONTINUE" $CERTSERIAL - cert_add_certs - CERTSERIAL=`expr $CERTSERIAL + 1 ` - CONTINUE=`expr $CONTINUE - 1 ` - done - if [ "$CERTFAILED" != 0 ] ; then - cert_log "ERROR: StressCert failed $RET" - else - cert_log "SUCCESS: StressCert passed" - fi -} - -############################## cert_fips ##################################### -# local shell function to create certificates for FIPS tests -############################################################################## -cert_fips() -{ - CERTFAILED=0 - echo "$SCRIPTNAME: Creating FIPS 140-1 DSA Certificates ==============" - cert_init_cert "${FIPSDIR}" "FIPS PUB 140-1 Test Certificate" 1000 "${D_FIPS}" - - CU_ACTION="Initializing ${CERTNAME}'s Cert DB" - certu -N -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" 2>&1 - - echo "$SCRIPTNAME: Enable FIPS mode on database -----------------------" - CU_ACTION="Enable FIPS mode on database for ${CERTNAME}" - echo "modutil -dbdir ${PROFILEDIR} -fips true " - modutil -dbdir ${PROFILEDIR} -fips true 2>&1 <<MODSCRIPT -y -MODSCRIPT - RET=$? - if [ "$RET" -ne 0 ]; then - html_failed "<TR><TD>${CU_ACTION} ($RET) " - cert_log "ERROR: ${CU_ACTION} failed $RET" - else - html_passed "<TR><TD>${CU_ACTION}" - fi - - CU_ACTION="Generate Certificate for ${CERTNAME}" - CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US" - certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -m 500 -z "${R_NOISE_FILE}" 2>&1 - if [ "$RET" -eq 0 ]; then - cert_log "SUCCESS: FIPS passed" - fi -} - -############################## cert_cleanup ############################ -# local shell function to finish this script (no exit since it might be -# sourced) -######################################################################## -cert_cleanup() -{ - cert_log "$SCRIPTNAME: finished $SCRIPTNAME" - html "</TABLE><BR>" - cd ${QADIR} - . common/cleanup.sh -} - -################## main ################################################# - -cert_init -cert_all_CA -cert_extended_ssl -cert_ssl -cert_smime_client -cert_fips -if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then - cert_stresscerts - #following lines to be used when databases are to be reused - #cp -r /u/sonmi/tmp/stress/kentuckyderby.13/* $HOSTDIR - #cp -r $HOSTDIR/../${HOST}.2/* $HOSTDIR - -fi -cert_cleanup diff --git a/security/nss/tests/cipher/cipher.sh b/security/nss/tests/cipher/cipher.sh index 50ff55104..b154e06b5 100755 --- a/security/nss/tests/cipher/cipher.sh +++ b/security/nss/tests/cipher/cipher.sh @@ -75,7 +75,7 @@ cipher_init() mkdir -p ${CIPHERDIR} - cd ${CIPHERTESTDIR} + cd ${CIPHERDIR} P_CIPHER=. if [ -n "${MULTIACCESS_DBM}" ]; then P_CIPHER="multiaccess:${D_CIPHER}" @@ -93,10 +93,29 @@ cipher_main() PARAM=`echo $PARAM | sed -e "s/_-/ -/g"` TESTNAME=`echo $TESTNAME | sed -e "s/_/ /g"` echo "$SCRIPTNAME: $TESTNAME --------------------------------" - echo "bltest -T -m $PARAM -d ${P_CIPHER}" - - bltest -T -m $PARAM -d ${P_CIPHER} - html_msg $? $EXP_RET "$TESTNAME" + failedStr="" + inOff=0 + res=0 + while [ $inOff -lt 8 ] + do + outOff=0 + while [ $outOff -lt 8 ] + do + echo "bltest -T -m $PARAM -d $CIPHERTESTDIR -1 $inOff -2 $outOff" + bltest -T -m $PARAM -d $CIPHERTESTDIR -1 $inOff -2 $outOff + if [ $? -ne 0 ]; then + failedStr="$failedStr[$inOff:$outOff]" + fi + outOff=`expr $outOff + 1` + done + inOff=`expr $inOff + 1` + done + if [ -n "$failedStr" ]; then + html_msg 1 $EXP_RET "$TESTNAME (Failed in/out offset pairs:" \ + " $failedStr)" + else + html_msg $res $EXP_RET "$TESTNAME" + fi fi done < ${CIPHER_TXT} } diff --git a/security/nss/tests/common/init.sh b/security/nss/tests/common/init.sh index 0c0126372..7ad4caff0 100644 --- a/security/nss/tests/common/init.sh +++ b/security/nss/tests/common/init.sh @@ -102,6 +102,19 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then esac } + detect_core() + { + [ ! -f $CORELIST_FILE ] && touch $CORELIST_FILE + mv $CORELIST_FILE ${CORELIST_FILE}.old + coreStr=`find $HOSTDIR -type f -name '*core*'` + res=0 + if [ -n "$coreStr" ]; then + sum $coreStr > $CORELIST_FILE + res=`cat $CORELIST_FILE ${CORELIST_FILE}.old | sort | uniq -u | wc -l` + fi + return $res + } + #html functions to give the resultfiles a consistant look html() ######################### write the results.html file { # 3 functions so we can put targets in the output.log easier @@ -109,12 +122,24 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then } html_passed() { + html_detect_core "$@" || return html "$* ${HTML_PASSED}" } html_failed() { + html_detect_core "$@" || return html "$* ${HTML_FAILED}" } + html_detect_core() + { + detect_core + if [ $? -ne 0 ]; then + echo "$*. Core file is detected." + html "$* ${HTML_FAILED_CORE}" + return 1 + fi + return 0 + } html_head() { html "<TABLE BORDER=1><TR><TH COLSPAN=3>$*</TH></TR>" @@ -136,6 +161,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then fi } HTML_FAILED='</TD><TD bgcolor=red>Failed</TD><TR>' + HTML_FAILED_CORE='</TD><TD bgcolor=red>Failed Core</TD><TR>' HTML_PASSED='</TD><TD bgcolor=lightGreen>Passed</TD><TR>' @@ -176,7 +202,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then PATH=.\;${DIST}/${OBJDIR}/bin\;${DIST}/${OBJDIR}/lib\;$PATH PATH=`perl ../path_uniq -d ';' "$PATH"` else - PATH=.:/bin:/usr/bin:${DIST}/${OBJDIR}/bin:${DIST}/${OBJDIR}/lib:$PATH + PATH=.:${DIST}/${OBJDIR}/bin:${DIST}/${OBJDIR}/lib:/bin:/usr/bin:$PATH # added /bin and /usr/bin in the beginning so a local perl will # be used PATH=`perl ../path_uniq -d ':' "$PATH"` @@ -354,19 +380,23 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then DAVEDIR=${HOSTDIR}/dave EVEDIR=${HOSTDIR}/eve FIPSDIR=${HOSTDIR}/fips + ECCURVES_DIR=${HOSTDIR}/eccurves SERVER_CADIR=${HOSTDIR}/serverCA CLIENT_CADIR=${HOSTDIR}/clientCA EXT_SERVERDIR=${HOSTDIR}/ext_server EXT_CLIENTDIR=${HOSTDIR}/ext_client + CERT_EXTENSIONS_DIR=${HOSTDIR}/cert_extensions + PWFILE=${TMP}/tests.pw.$$ NOISE_FILE=${TMP}/tests_noise.$$ + CORELIST_FILE=${TMP}/clist.$$ FIPSPWFILE=${TMP}/tests.fipspw.$$ FIPSBADPWFILE=${TMP}/tests.fipsbadpw.$$ FIPSP12PWFILE=${TMP}/tests.fipsp12pw.$$ - FIPSCERTNICK="FIPS_PUB_140-1_Test_Certificate" + FIPSCERTNICK="FIPS_PUB_140_Test_Certificate" # domains to handle ipc based access to databases D_CA="TestCA.$version" @@ -379,8 +409,10 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then D_SERVER="Server.$version" D_CLIENT="Client.$version" D_FIPS="FIPS.$version" + D_ECCURVES="ECCURVES.$version" D_EXT_SERVER="ExtendedServer.$version" D_EXT_CLIENT="ExtendedClient.$version" + D_CERT_EXTENSTIONS="CertExtensions.$version" # we need relative pathnames of these files abd directories, since our # tools can't handle the unix style absolut pathnames on cygnus @@ -394,6 +426,7 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then R_EVEDIR=../eve R_EXT_SERVERDIR=../ext_server R_EXT_CLIENTDIR=../ext_client + R_CERT_EXT=../cert_extensions # # profiles are either paths or domains depending on the setting of diff --git a/security/nss/tests/dbtests/dbtests.sh b/security/nss/tests/dbtests/dbtests.sh index 313978316..86b9d7e61 100755 --- a/security/nss/tests/dbtests/dbtests.sh +++ b/security/nss/tests/dbtests/dbtests.sh @@ -84,10 +84,6 @@ dbtest_init() # in the output.log, otherwise we can't tell what's a real error RONLY_DIR=${HOSTDIR}/ronlydir EMPTY_DIR=${HOSTDIR}/emptydir - grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null || { - html_head "SSL Test failure" - Exit : "Fatal - SSL of cert.sh needs to pass first" - } html_head "CERT and Key DB Tests" diff --git a/security/nss/tests/fips/fips.sh b/security/nss/tests/fips/fips.sh index 6a4986f0f..71dd9a28c 100755 --- a/security/nss/tests/fips/fips.sh +++ b/security/nss/tests/fips/fips.sh @@ -70,7 +70,7 @@ fips_init() . ./cert.sh fi SCRIPTNAME=fips.sh - html_head "FIPS 140-1 Compliance Tests" + html_head "FIPS 140 Compliance Tests" grep "SUCCESS: FIPS passed" $CERT_LOG_FILE >/dev/null || { Exit 15 "Fatal - FIPS of cert.sh needs to pass first" @@ -92,11 +92,11 @@ fips_init() cd ${FIPSDIR} } -############################## fips_140_1 ############################## +############################## fips_140 ############################## # local shell function to test basic functionality of NSS while in -# FIPS 140-1 compliant mode +# FIPS 140 compliant mode ######################################################################## -fips_140_1() +fips_140() { echo "$SCRIPTNAME: Verify this module is in FIPS mode -----------------" echo "modutil -dbdir ${P_R_FIPSDIR} -list" @@ -214,6 +214,6 @@ fips_cleanup() fips_init -fips_140_1 +fips_140 fips_cleanup diff --git a/security/nss/tests/fixtests.sh b/security/nss/tests/fixtests.sh deleted file mode 100755 index 42cbdf8ee..000000000 --- a/security/nss/tests/fixtests.sh +++ /dev/null @@ -1,117 +0,0 @@ -#!/bin/sh -# -# ***** 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 elliptic curve test suite. -# -# The Initial Developer of the Original Code is -# Sun Microsystems, Inc. -# Portions created by the Initial Developer are Copyright (C) 2003 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 -# 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 ***** - -####################### fix_test_scripts ####################### -# -# Depending on the argument either enable or disable EC based -# tests in the cert and ssl directories. -# -################################################################ -fix_test_scripts() -{ - FLAG=$1 - CERT_DIR=cert - CERT_SCRIPT=cert.sh - SMIME_DIR=smime - SMIME_SCRIPT=smime.sh - SSL_DIR=ssl - SSLAUTH=sslauth.txt - SSLCOV=sslcov.txt - SSL_SCRIPT=ssl.sh - SSLSTRESS=sslstress.txt - TOOLS_DIR=tools - TOOLS_SCRIPT=tools.sh - EC_PREFIX=ec - NOEC_PREFIX=noec - - if [ xx$FLAG = xx"enable_ecc" ]; then - if [ -f $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT -a \ - -f $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLSTRESS -a \ - -f $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT ]; then - echo "noecc files exist" - else - echo "noecc files are missing" - echo "Saving files as noec" - cp $CERT_DIR/$CERT_SCRIPT $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT - cp $SMIME_DIR/$SMIME_SCRIPT $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT - cp $SSL_DIR/$SSLAUTH $SSL_DIR/$NOEC_PREFIX$SSLAUTH - cp $SSL_DIR/$SSLCOV $SSL_DIR/$NOEC_PREFIX$SSLCOV - cp $SSL_DIR/$SSL_SCRIPT $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT - cp $SSL_DIR/$SSLSTRESS $SSL_DIR/$NOEC_PREFIX$SSLSTRESS - cp $TOOLS_DIR/$TOOLS_SCRIPT $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT - fi - echo "Overwriting with ec versions" - cp $CERT_DIR/$EC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT - cp $SMIME_DIR/$EC_PREFIX$SMIME_SCRIPT $SMIME_DIR/$SMIME_SCRIPT - cp $SSL_DIR/$EC_PREFIX$SSLAUTH $SSL_DIR/$SSLAUTH - cp $SSL_DIR/$EC_PREFIX$SSLCOV $SSL_DIR/$SSLCOV - cp $SSL_DIR/$EC_PREFIX$SSL_SCRIPT $SSL_DIR/$SSL_SCRIPT - cp $SSL_DIR/$EC_PREFIX$SSLSTRESS $SSL_DIR/$SSLSTRESS - cp $TOOLS_DIR/$EC_PREFIX$TOOLS_SCRIPT $TOOLS_DIR/$TOOLS_SCRIPT - elif [ xx$FLAG = xx"disable_ecc" ]; then - if [ -f $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT -a \ - -f $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLAUTH -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLCOV -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT -a \ - -f $SSL_DIR/$NOEC_PREFIX$SSLSTRESS -a \ - -f $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT ]; then - echo "noecc files exist" - echo "Overwriting with noec versions" - cp $CERT_DIR/$NOEC_PREFIX$CERT_SCRIPT $CERT_DIR/$CERT_SCRIPT - cp $SMIME_DIR/$NOEC_PREFIX$SMIME_SCRIPT $SMIME_DIR/$SMIME_SCRIPT - cp $SSL_DIR/$NOEC_PREFIX$SSLAUTH $SSL_DIR/$SSLAUTH - cp $SSL_DIR/$NOEC_PREFIX$SSLCOV $SSL_DIR/$SSLCOV - cp $SSL_DIR/$NOEC_PREFIX$SSL_SCRIPT $SSL_DIR/$SSL_SCRIPT - cp $SSL_DIR/$NOEC_PREFIX$SSLSTRESS $SSL_DIR/$SSLSTRESS - cp $TOOLS_DIR/$NOEC_PREFIX$TOOLS_SCRIPT $TOOLS_DIR/$TOOLS_SCRIPT - else - echo "Already disabled." - fi - else - echo "Needs either \"enable_ecc\" or \"disable_ecc\" as argument." - fi -} - - -fix_test_scripts $1 diff --git a/security/nss/tests/perf/perf.sh b/security/nss/tests/perf/perf.sh index 7fee17c1e..d92182754 100755 --- a/security/nss/tests/perf/perf.sh +++ b/security/nss/tests/perf/perf.sh @@ -67,6 +67,7 @@ perf_init() } perf_init +cd ${PERFDIR} RSAPERF_OUT=`rsaperf -i 300 -s -n none` RSAPERF_OUT=`echo $RSAPERF_OUT | sed \ -e "s/^/RSAPERF: $OBJDIR /" \ diff --git a/security/nss/tests/pkcs11/netscape/trivial/configure.in b/security/nss/tests/pkcs11/netscape/trivial/configure.in index 32889ddc1..62950b97a 100644 --- a/security/nss/tests/pkcs11/netscape/trivial/configure.in +++ b/security/nss/tests/pkcs11/netscape/trivial/configure.in @@ -1,34 +1,39 @@ dnl -dnl The contents of this file are subject to the Mozilla Public -dnl License Version 1.1 (the "License"); you may not use this file -dnl except in compliance with the License. You may obtain a copy of -dnl the License at http://www.mozilla.org/MPL/ -dnl -dnl Software distributed under the License is distributed on an "AS -dnl IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or -dnl implied. See the License for the specific language governing -dnl rights and limitations under the License. -dnl +dnl ***** BEGIN LICENSE BLOCK ***** +dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1 +dnl +dnl The contents of this file are subject to the Mozilla Public License Version +dnl 1.1 (the "License"); you may not use this file except in compliance with +dnl the License. You may obtain a copy of the License at +dnl http://www.mozilla.org/MPL/ +dnl +dnl Software distributed under the License is distributed on an "AS IS" basis, +dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +dnl for the specific language governing rights and limitations under the +dnl License. +dnl dnl The Original Code is a trivial PKCS#11 test program. -dnl -dnl The Initial Developer of the Original Code is Netscape -dnl Communications Corp. Portions created by Netscape are -dnl Copyright (C) 2000. All Rights Reserved. -dnl -dnl Contributor(s): dnl -dnl Alternatively, the contents of this file may be used under the -dnl terms of the GNU General Public License Version 2 or later (the -dnl "GPL"), in which case the provisions of the GPL are applicable -dnl instead of those above. If you wish to allow use of your -dnl version of this file only under the terms of the GPL and not to -dnl allow others to use your version of this file under the MPL, -dnl indicate your decision by deleting the provisions above and -dnl replace them with the notice and other provisions required by -dnl the GPL. If you do not delete the provisions above, a recipient -dnl may use your version of this file under either the MPL or the -dnl GPL. +dnl The Initial Developer of the Original Code is +dnl Netscape Communications Corp. +dnl Portions created by the Initial Developer are Copyright (C) 2000 +dnl the Initial Developer. All Rights Reserved. +dnl +dnl Contributor(s): +dnl +dnl Alternatively, the contents of this file may be used under the terms of +dnl either the GNU General Public License Version 2 or later (the "GPL"), or +dnl the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +dnl in which case the provisions of the GPL or the LGPL are applicable instead +dnl of those above. If you wish to allow use of your version of this file only +dnl under the terms of either the GPL or the LGPL, and not to allow others to +dnl use your version of this file under the terms of the MPL, indicate your +dnl decision by deleting the provisions above and replace them with the notice +dnl and other provisions required by the GPL or the LGPL. If you do not delete +dnl the provisions above, a recipient may use your version of this file under +dnl the terms of any one of the MPL, the GPL or the LGPL. dnl +dnl ***** END LICENSE BLOCK ***** dnl My revision info: "@(#) $RCSfile$ $Revision$ $Date$" dnl Don't use AC_REVISION; it's broken diff --git a/security/nss/tests/smime/ecsmime.sh b/security/nss/tests/smime/ecsmime.sh deleted file mode 100644 index e94000bfa..000000000 --- a/security/nss/tests/smime/ecsmime.sh +++ /dev/null @@ -1,260 +0,0 @@ -#! /bin/sh -# -# ***** 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 ***** - -######################################################################## -# -# mozilla/security/nss/tests/smime/smime.sh -# -# Script to test NSS smime -# -# needs to work on all Unix and Windows platforms -# -# special strings -# --------------- -# FIXME ... known problems, search for this string -# NOTE .... unexpected behavior -# -######################################################################## - -############################## smime_init ############################## -# local shell function to initialize this script -######################################################################## -smime_init() -{ - SCRIPTNAME=smime.sh # sourced - $0 would point to all.sh - - if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for - CLEANUP="${SCRIPTNAME}" # cleaning this script will do it - fi - - if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then - cd ../common - . ./init.sh - fi - if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here - cd ../cert - . ./cert.sh - fi - SCRIPTNAME=smime.sh - html_head "S/MIME Tests" - - grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { - Exit 11 "Fatal - S/MIME of cert.sh needs to pass first" - } - - SMIMEDIR=${HOSTDIR}/smime - R_SMIMEDIR=../smime - mkdir -p ${SMIMEDIR} - cd ${SMIMEDIR} - cp ${QADIR}/smime/alice.txt ${SMIMEDIR} -} - - -############################## smime_main ############################## -# local shell function to test basic signed and enveloped messages -# from 1 --> 2" -######################################################################## -smime_main() -{ - - echo "$SCRIPTNAME: Signing Attached Message (ECDSA SHA1) ------------------" - echo "cmsutil -S -N Alice-ec -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.sig" - cmsutil -S -N Alice-ec -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.sig - html_msg $? 0 "Create Signature Alice (ECDSA SHA1)" "." - - echo "cmsutil -D -i alice-ec.sig -d ${P_R_BOBDIR} -o alice-ec.data1" - cmsutil -D -i alice-ec.sig -d ${P_R_BOBDIR} -o alice-ec.data1 - html_msg $? 0 "Decode Alice's Signature (ECDSA SHA1)" "." - - echo "diff alice.txt alice-ec.data1" - diff alice.txt alice-ec.data1 - html_msg $? 0 "Compare Decoded Signature and Original (ECDSA SHA1)" "." - - echo "$SCRIPTNAME: Signing Attached Message (SHA1) ------------------" - echo "cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig" - cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig - html_msg $? 0 "Create Signature Alice (SHA1)" "." - - echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1" - cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1 - html_msg $? 0 "Decode Alice's Signature (SHA1)" "." - - echo "diff alice.txt alice.data1" - diff alice.txt alice.data1 - html_msg $? 0 "Compare Decoded Signature and Original (SHA1)" "." - - echo "$SCRIPTNAME: Signing Attached Message (SHA256) ------------------" - echo "cmsutil -S -N Alice -H SHA256 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig" - cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig - html_msg $? 0 "Create Signature Alice (SHA256)" "." - - echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1" - cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1 - html_msg $? 0 "Decode Alice's Signature (SHA256)" "." - - echo "diff alice.txt alice.data1" - diff alice.txt alice.data1 - html_msg $? 0 "Compare Decoded Signature and Original (SHA256)" "." - - echo "$SCRIPTNAME: Signing Attached Message (SHA384) ------------------" - echo "cmsutil -S -N Alice -H SHA384 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig" - cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig - html_msg $? 0 "Create Signature Alice (SHA384)" "." - - echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1" - cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1 - html_msg $? 0 "Decode Alice's Signature (SHA384)" "." - - echo "diff alice.txt alice.data1" - diff alice.txt alice.data1 - html_msg $? 0 "Compare Decoded Signature and Original (SHA384)" "." - - echo "$SCRIPTNAME: Signing Attached Message (SHA512) ------------------" - echo "cmsutil -S -N Alice -H SHA512 -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig" - cmsutil -S -N Alice -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.sig - html_msg $? 0 "Create Signature Alice (SHA512)" "." - - echo "cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1" - cmsutil -D -i alice.sig -d ${P_R_BOBDIR} -o alice.data1 - html_msg $? 0 "Decode Alice's Signature (SHA512)" "." - - echo "diff alice.txt alice.data1" - diff alice.txt alice.data1 - html_msg $? 0 "Compare Decoded Signature and Original (SHA512)" "." - - echo "$SCRIPTNAME: Enveloped Data Tests ------------------------------" - echo "cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss \\" - echo " -o alice.env" - cmsutil -E -r bob@bogus.com -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice.env - html_msg $? 0 "Create Enveloped Data Alice" "." - - echo "cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1" - cmsutil -D -i alice.env -d ${P_R_BOBDIR} -p nss -o alice.data1 - html_msg $? 0 "Decode Enveloped Data Alice" "." - - echo "diff alice.txt alice.data1" - diff alice.txt alice.data1 - html_msg $? 0 "Compare Decoded Enveloped Data and Original" "." - - # multiple recip - echo "$SCRIPTNAME: Testing multiple recipients ------------------------------" - echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o alicecc.env \\" - echo " -r bob@bogus.com,dave@bogus.com" - cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \ - -r bob@bogus.com,dave@bogus.com - ret=$? - html_msg $ret 0 "Create Multiple Recipients Enveloped Data Alice" "." - if [ $ret != 0 ] ; then - echo "certutil -L -d ${P_R_ALICEDIR}" - certutil -L -d ${P_R_ALICEDIR} - echo "certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com" - certutil -L -d ${P_R_ALICEDIR} -n dave@bogus.com - fi - - echo "$SCRIPTNAME: Testing multiple email addrs ------------------------------" - echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o aliceve.env \\" - echo " -r eve@bogus.net" - cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o aliceve.env \ - -r eve@bogus.net - ret=$? - html_msg $ret 0 "Encrypt to a Multiple Email cert" "." - - echo "cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2" - cmsutil -D -i alicecc.env -d ${P_R_BOBDIR} -p nss -o alice.data2 - html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Bob" "." - - echo "cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3" - cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3 - html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Dave" "." - - echo "cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4" - cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4 - html_msg $? 0 "Decrypt with a Multiple Email cert" "." - - diff alice.txt alice.data2 - html_msg $? 0 "Compare Decoded Mult. Recipients Enveloped Data Alice/Bob" "." - - diff alice.txt alice.data3 - html_msg $? 0 "Compare Decoded Mult. Recipients Enveloped Data Alice/Dave" "." - - diff alice.txt alice.data4 - html_msg $? 0 "Compare Decoded with Multiple Email cert" "." - - echo "$SCRIPTNAME: Sending CERTS-ONLY Message ------------------------------" - echo "cmsutil -O -r \"Alice,bob@bogus.com,dave@bogus.com\" \\" - echo " -d ${P_R_ALICEDIR} > co.der" - cmsutil -O -r "Alice,bob@bogus.com,dave@bogus.com" -d ${P_R_ALICEDIR} > co.der - html_msg $? 0 "Create Certs-Only Alice" "." - - echo "cmsutil -D -i co.der -d ${P_R_BOBDIR}" - cmsutil -D -i co.der -d ${P_R_BOBDIR} - html_msg $? 0 "Verify Certs-Only by CA" "." - - echo "$SCRIPTNAME: Encrypted-Data Message ---------------------------------" - echo "cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \\" - echo " -r \"bob@bogus.com\" > alice.enc" - cmsutil -C -i alice.txt -e alicehello.env -d ${P_R_ALICEDIR} \ - -r "bob@bogus.com" > alice.enc - html_msg $? 0 "Create Encrypted-Data" "." - - echo "cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss \\" - echo " -o alice.data2" - cmsutil -D -i alice.enc -d ${P_R_BOBDIR} -e alicehello.env -p nss -o alice.data2 - html_msg $? 0 "Decode Encrypted-Data" "." - - diff alice.txt alice.data2 - html_msg $? 0 "Compare Decoded and Original Data" "." -} - -############################## smime_cleanup ########################### -# local shell function to finish this script (no exit since it might be -# sourced) -######################################################################## -smime_cleanup() -{ - html "</TABLE><BR>" - cd ${QADIR} - . common/cleanup.sh -} - -################## main ################################################# - -smime_init -smime_main -smime_cleanup - diff --git a/security/nss/tests/smime/smime.sh b/security/nss/tests/smime/smime.sh index f8e2e6c8c..78d840099 100755 --- a/security/nss/tests/smime/smime.sh +++ b/security/nss/tests/smime/smime.sh @@ -21,6 +21,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 @@ -71,7 +72,12 @@ smime_init() . ./cert.sh fi SCRIPTNAME=smime.sh - html_head "S/MIME Tests" + + if [ -n "$NSS_ENABLE_ECC" ] ; then + html_head "S/MIME Tests with ECC" + else + html_head "S/MIME Tests" + fi grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { Exit 11 "Fatal - S/MIME of cert.sh needs to pass first" @@ -86,7 +92,7 @@ smime_init() smime_sign() { - HASH_CMD=-H ${HASH} + HASH_CMD="-H ${HASH}" SIG=sig.${HASH} echo "$SCRIPTNAME: Signing Detached Message {$HASH} ------------------" @@ -110,6 +116,32 @@ smime_sign() echo "diff alice.txt alice.data.${HASH}" diff alice.txt alice.data.${HASH} html_msg $? 0 "Compare Attached Signed Data and Original (${HASH})" "." + +# Test ECDSA signing for all hash algorithms. + if [ -n "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: Signing Detached Message ECDSA w/ {$HASH} ------------------" + echo "cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG}" + cmsutil -S -T -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.d${SIG} + html_msg $? 0 "Create Detached Signature Alice (ECDSA w/ ${HASH})" "." + + echo "cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} " + cmsutil -D -i alice-ec.d${SIG} -c alice.txt -d ${P_R_BOBDIR} + html_msg $? 0 "Verifying Alice's Detached Signature (ECDSA w/ ${HASH})" "." + + echo "$SCRIPTNAME: Signing Attached Message (ECDSA w/ ${HASH}) ------------------" + echo "cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG}" + cmsutil -S -N Alice-ec ${HASH_CMD} -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.${SIG} + html_msg $? 0 "Create Attached Signature Alice (ECDSA w/ ${HASH})" "." + + echo "cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH}" + cmsutil -D -i alice-ec.${SIG} -d ${P_R_BOBDIR} -o alice-ec.data.${HASH} + html_msg $? 0 "Decode Alice's Attached Signature (ECDSA w/ ${HASH})" "." + + echo "diff alice.txt alice-ec.data.${HASH}" + diff alice.txt alice-ec.data.${HASH} + html_msg $? 0 "Compare Attached Signed Data and Original (ECDSA w/ ${HASH})" "." + fi + } @@ -146,7 +178,7 @@ smime_main() # multiple recip echo "$SCRIPTNAME: Testing multiple recipients ------------------------------" - echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o alicecc.env \\" + echo "cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \\" echo " -r bob@bogus.com,dave@bogus.com" cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \ -r bob@bogus.com,dave@bogus.com @@ -160,7 +192,7 @@ smime_main() fi echo "$SCRIPTNAME: Testing multiple email addrs ------------------------------" - echo "cmsutil -E -i alicecc.txt -d ${P_R_ALICEDIR} -o aliceve.env \\" + echo "cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o aliceve.env \\" echo " -r eve@bogus.net" cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o aliceve.env \ -r eve@bogus.net diff --git a/security/nss/tests/ssl/ecssl.sh b/security/nss/tests/ssl/ecssl.sh deleted file mode 100644 index e2c3e8dd8..000000000 --- a/security/nss/tests/ssl/ecssl.sh +++ /dev/null @@ -1,350 +0,0 @@ -#! /bin/sh -# -# ***** 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): -# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 -# 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 ***** - -######################################################################## -# -# mozilla/security/nss/tests/ssl/ecssl.sh -# -# Script to test NSS SSL -# -# needs to work on all Unix and Windows platforms -# -# special strings -# --------------- -# FIXME ... known problems, search for this string -# NOTE .... unexpected behavior -# -######################################################################## - -############################## ssl_init ################################ -# local shell function to initialize this script -######################################################################## -ssl_init() -{ - SCRIPTNAME=ssl.sh # sourced - $0 would point to all.sh - - if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for - CLEANUP="${SCRIPTNAME}" # cleaning this script will do it - fi - - if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then - cd ../common - . ./init.sh - fi - if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here - cd ../cert - . ./cert.sh - fi - SCRIPTNAME=ssl.sh - echo "$SCRIPTNAME: SSL tests ===============================" - - grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null || { - html_head "SSL Test failure" - Exit 8 "Fatal - SSL of cert.sh needs to pass first" - } - - PORT=${PORT-8443} - - # Test case files - SSLCOV=${QADIR}/ssl/sslcov.txt - SSLAUTH=${QADIR}/ssl/sslauth.txt - SSLSTRESS=${QADIR}/ssl/sslstress.txt - REQUEST_FILE=${QADIR}/ssl/sslreq.txt - - #temparary files - SERVEROUTFILE=${TMP}/tests_server.$$ - SERVERPID=${TMP}/tests_pid.$$ - - R_SERVERPID=../tests_pid.$$ - - TEMPFILES="$TMPFILES ${SERVEROUTFILE} ${SERVERPID}" - - fileout=0 #FIXME, looks like all.sh tried to turn this on but actually didn't - #fileout=1 - #verbose="-v" #FIXME - see where this is usefull - - USER_NICKNAME=TestUser - NORM_EXT="" - - cd ${CLIENTDIR} -} - -########################### is_selfserv_alive ########################## -# local shell function to exit with a fatal error if selfserver is not -# running -######################################################################## -is_selfserv_alive() -{ - if [ ! -f "${SERVERPID}" ]; then - echo "$SCRIPTNAME: Error - selfserv PID file ${SERVERPID} doesn't exist" - sleep 5 - if [ ! -f "${SERVERPID}" ]; then - Exit 9 "Fatal - selfserv pid file ${SERVERPID} does not exist" - fi - fi - PID=`cat ${SERVERPID}` - #if [ "${OS_ARCH}" = "Linux" ]; then - kill -0 $PID >/dev/null 2>/dev/null || Exit 10 "Fatal - selfserv process not detectable" - #else - #$PS -e | grep $PID >/dev/null || \ - #Exit 10 "Fatal - selfserv process not detectable" - #fi -} - -########################### wait_for_selfserv ########################## -# local shell function to wait until selfserver is running and initialized -######################################################################## -wait_for_selfserv() -{ - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -q " - echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \\" - #echo "tstclnt -q started at `date`" - tstclnt -p ${PORT} -h ${HOSTADDR} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} - if [ $? -ne 0 ]; then - html_failed "<TR><TD> Wait for Server " - echo "RETRY: tstclnt -p ${PORT} -h ${HOSTADDR} -q \\" - echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}" - tstclnt -p ${PORT} -h ${HOSTADDR} -q -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} - elif [ sparam = "-c ABCDEFGHIJKLMNOPQRSTabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then - html_passed "<TR><TD> Wait for Server" - fi - is_selfserv_alive -} - -########################### kill_selfserv ############################## -# local shell function to kill the selfserver after the tests are done -######################################################################## -kill_selfserv() -{ - ${KILL} `cat ${SERVERPID}` - wait `cat ${SERVERPID}` - if [ ${fileout} -eq 1 ]; then - cat ${SERVEROUTFILE} - fi - # On Linux selfserv needs up to 30 seconds to fully die and free - # the port. Wait until the port is free. (Bug 129701) - if [ "${OS_ARCH}" = "Linux" ]; then - until selfserv -b -p ${PORT} 2>/dev/null; do - sleep 1 - done - fi - rm ${SERVERPID} -} - -########################### start_selfserv ############################# -# local shell function to start the selfserver with the parameters required -# for this test and log information (parameters, start time) -# also: wait until the server is up and running -######################################################################## -start_selfserv() -{ - if [ -n "$testname" ] ; then - echo "$SCRIPTNAME: $testname ----" - fi - sparam=`echo $sparam | sed -e 's;_; ;g'` - echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \\" - echo " -e ${HOSTADDR}-ec \\" - echo " -w nss ${sparam} -i ${R_SERVERPID} $verbose &" - echo "selfserv started at `date`" - if [ ${fileout} -eq 1 ]; then - selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \ - -e ${HOSTADDR}-ec \ - -w nss ${sparam} -i ${R_SERVERPID} $verbose \ - > ${SERVEROUTFILE} 2>&1 & - else - selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} \ - -e ${HOSTADDR}-ec \ - -w nss ${sparam} -i ${R_SERVERPID} $verbose & - fi - wait_for_selfserv -} - -############################## ssl_cov ################################# -# local shell function to perform SSL Cipher Coverage tests -######################################################################## -ssl_cov() -{ - html_head "SSL Cipher Coverage $NORM_EXT" - - testname="" - sparam="-c ABCDEFGHIJKLMNOPQRSTabcdefghijklmnvyz" - start_selfserv # Launch the server - - p="" - - while read tls param testname - do - p=`echo "$testname" | sed -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS - - if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended test" ] ; then - echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - elif [ "$tls" != "#" ] ; then - echo "$SCRIPTNAME: running $testname ----------------------------" - TLS_FLAG=-T - if [ $tls = "TLS" ]; then - TLS_FLAG="" - fi - - is_selfserv_alive - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} \\" - echo " -f -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}" - - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} -f \ - -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \ - >${TMP}/$HOST.tmp.$$ 2>&1 - ret=$? - cat ${TMP}/$HOST.tmp.$$ - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - html_msg $ret 0 "${testname}" - fi - done < ${SSLCOV} - - kill_selfserv - html "</TABLE><BR>" -} - -############################## ssl_auth ################################ -# local shell function to perform SSL Client Authentication tests -######################################################################## -ssl_auth() -{ - html_head "SSL Client Authentication $NORM_EXT" - - while read value sparam cparam testname - do - if [ $value != "#" ]; then - cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` - start_selfserv - - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} \\" - echo " ${cparam} < ${REQUEST_FILE}" - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ - -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} \ - >${TMP}/$HOST.tmp.$$ 2>&1 - ret=$? - cat ${TMP}/$HOST.tmp.$$ - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - - html_msg $ret $value "${testname}" \ - "produced a returncode of $ret, expected is $value" - kill_selfserv - fi - done < ${SSLAUTH} - - html "</TABLE><BR>" -} - - -############################## ssl_stress ############################## -# local shell function to perform SSL stress test -######################################################################## -ssl_stress() -{ - html_head "SSL Stress Test $NORM_EXT" - - while read value sparam cparam testname - do - p=`echo "$testname" | sed -e "s/Stress //" -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS - if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended test" ] ; then - echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - elif [ $value != "#" ]; then - cparam=`echo $cparam | sed -e 's;_; ;g'` - start_selfserv - if [ `uname -n` = "sjsu" ] ; then - echo "debugging disapering selfserv... ps -ef | grep selfserv" - ps -ef | grep selfserv - fi - - echo "strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \\" - echo " $verbose ${HOSTADDR}" - echo "strsclnt started at `date`" - strsclnt -q -p ${PORT} -d ${P_R_CLIENTDIR} -w nss $cparam \ - $verbose ${HOSTADDR} - ret=$? - echo "strsclnt completed at `date`" - html_msg $ret $value "${testname}" - if [ `uname -n` = "sjsu" ] ; then - echo "debugging disapering selfserv... ps -ef | grep selfserv" - ps -ef | grep selfserv - fi - kill_selfserv - fi - done < ${SSLSTRESS} - - html "</TABLE><BR>" -} - - -############################## ssl_cleanup ############################# -# local shell function to finish this script (no exit since it might be -# sourced) -######################################################################## -ssl_cleanup() -{ - rm $SERVERPID 2>/dev/null - cd ${QADIR} - . common/cleanup.sh -} - -################## main ################################################# - -#this script may be sourced from the distributed stress test - in this case do nothing... - -if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then - ssl_init - ssl_cov - ssl_auth - ssl_stress - - SERVERDIR=$EXT_SERVERDIR - CLIENTDIR=$EXT_CLIENTDIR - R_SERVERDIR=$R_EXT_SERVERDIR - R_CLIENTDIR=$R_EXT_CLIENTDIR - P_R_SERVERDIR=$P_R_EXT_SERVERDIR - P_R_CLIENTDIR=$P_R_EXT_CLIENTDIR - USER_NICKNAME=ExtendedSSLUser - NORM_EXT="Extended test" - cd ${CLIENTDIR} - ssl_cov - ssl_auth - ssl_stress - ssl_cleanup -fi diff --git a/security/nss/tests/ssl/ecsslauth.txt b/security/nss/tests/ssl/ecsslauth.txt deleted file mode 100644 index e7204feb2..000000000 --- a/security/nss/tests/ssl/ecsslauth.txt +++ /dev/null @@ -1,50 +0,0 @@ -# -# This file defines the tests for client auth. -# -# expected -# return server client Test Case name -# value params params -# ------ ------ ------ --------------- - 0 -r -w_nss TLS Request don't require client auth (client does not provide auth) - 0 -r -w_bogus_-n_TestUser TLS Request don't require client auth (bad password) - 0 -r -w_nss_-n_TestUser TLS Request don't require client auth (client auth) - 0 -r_-r -w_nss TLS Require client auth (client does not provide auth) - 254 -r_-r -w_bogus_-n_TestUser TLS Require client auth (bad password) - 0 -r_-r -w_nss_-n_TestUser_ TLS Require client auth (client auth) - 0 -r -T_-w_nss SSL3 Request don't require client auth (client does not provide auth) - 0 -r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth (bad password) - 0 -r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth (client auth) - 0 -r_-r -T_-w_nss SSL3 Require client auth (client does not provide auth) - 254 -r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth (bad password) - 0 -r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth (client auth) - 0 -r_-r_-r -w_nss TLS Request don't require client auth on 2nd hs (client does not provide auth) - 0 -r_-r_-r -w_bogus_-n_TestUser TLS Request don't require client auth on 2nd hs (bad password) - 0 -r_-r_-r -w_nss_-n_TestUser TLS Request don't require client auth on 2nd hs (client auth) - 0 -r_-r_-r_-r -w_nss TLS Require client auth on 2nd hs (client does not provide auth) - 1 -r_-r_-r_-r -w_bogus_-n_TestUser TLS Require client auth on 2nd hs (bad password) - 0 -r_-r_-r_-r -w_nss_-n_TestUser_ TLS Require client auth on 2nd hs (client auth) - 0 -r_-r_-r -T_-w_nss SSL3 Request don't require client auth on 2nd hs (client does not provide auth) - 0 -r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth on 2nd hs (bad password) - 0 -r_-r_-r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth on 2nd hs (client auth) - 0 -r_-r_-r_-r -T_-w_nss SSL3 Require client auth on 2nd hs (client does not provide auth) - 1 -r_-r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth on 2nd hs (bad password) - 0 -r_-r_-r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth on 2nd hs (client auth) -# -# Use EC cert for client authentication -# - 0 -r -w_bogus_-n_TestUser-ec TLS Request don't require client auth (EC) (bad password) - 0 -r -w_nss_-n_TestUser-ec TLS Request don't require client auth (EC) (client auth) - 254 -r_-r -w_bogus_-n_TestUser-ec TLS Require client auth (EC) (bad password) - 0 -r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth (EC) (client auth) - 0 -r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth (EC) (bad password) - 0 -r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth (EC) (client auth) - 254 -r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth (EC) (bad password) - 0 -r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth (EC) (client auth) - 0 -r_-r_-r -w_bogus_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (bad password) - 0 -r_-r_-r -w_nss_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (client auth) - 1 -r_-r_-r_-r -w_bogus_-n_TestUser-ec TLS Require client auth on 2nd hs (EC) (bad password) - 0 -r_-r_-r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth on 2nd hs (EC) (client auth) - 0 -r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth on 2nd hs (EC) (bad password) - 0 -r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth on 2nd hs (EC) (client auth) - 1 -r_-r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth on 2nd hs (EC) (bad password) - 0 -r_-r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth on 2nd hs (EC) (client auth) diff --git a/security/nss/tests/ssl/ecsslcov.txt b/security/nss/tests/ssl/ecsslcov.txt deleted file mode 100644 index f01e56899..000000000 --- a/security/nss/tests/ssl/ecsslcov.txt +++ /dev/null @@ -1,83 +0,0 @@ -# -# This file enables test coverage of the various SSL ciphers -# -# NOTE: SSL2 ciphers are independent of whether TLS is enabled or not. We -# mix up the enable functions so we can tests boths paths. -# -# Enable Cipher Test Name -# TLS -# - noTLS A SSL2 RC4 128 WITH MD5 - TLS B SSL2 RC4 128 EXPORT40 WITH MD5 - TLS C SSL2 RC2 128 CBC WITH MD5 - noTLS D SSL2 RC2 128 CBC EXPORT40 WITH MD5 - TLS E SSL2 DES 64 CBC WITH MD5 - noTLS F SSL2 DES 192 EDE3 CBC WITH MD5 -# -# ECC ciphers (SSL3) -# - noTLS G SSL3 ECDH ECDSA WITH NULL SHA - noTLS H SSL3 ECDH ECDSA WITH RC4 128 SHA - noTLS I SSL3 ECDH ECDSA WITH DES CBC SHA - noTLS J SSL3 ECDH ECDSA WITH 3DES EDE CBC SHA - noTLS K SSL3 ECDH ECDSA WITH AES 128 CBC SHA - noTLS L SSL3 ECDH ECDSA WITH AES 256 CBC SHA - noTLS M SSL3 ECDH RSA WITH NULL SHA - noTLS N SSL3 ECDH RSA WITH RC4 128 SHA - noTLS O SSL3 ECDH RSA WITH DES CBC SHA - noTLS P SSL3 ECDH RSA WITH 3DES EDE CBC SHA - noTLS Q SSL3 ECDH RSA WITH AES 128 CBC SHA - noTLS R SSL3 ECDH RSA WITH AES 256 CBC SHA - noTLS S SSL3 ECDHE ECDSA WITH AES 128 CBC SHA - noTLS T SSL3 ECDHE RSA WITH AES 128 CBC SHA -# -# ECC ciphers (TLS) -# - TLS G TLS ECDH ECDSA WITH NULL SHA - TLS H TLS ECDH ECDSA WITH RC4 128 SHA - TLS I TLS ECDH ECDSA WITH DES CBC SHA - TLS J TLS ECDH ECDSA WITH 3DES EDE CBC SHA - TLS K TLS ECDH ECDSA WITH AES 128 CBC SHA - TLS L TLS ECDH ECDSA WITH AES 256 CBC SHA - TLS M TLS ECDH RSA WITH NULL SHA - TLS N TLS ECDH RSA WITH RC4 128 SHA - TLS O TLS ECDH RSA WITH DES CBC SHA - TLS P TLS ECDH RSA WITH 3DES EDE CBC SHA - TLS Q TLS ECDH RSA WITH AES 128 CBC SHA - TLS R TLS ECDH RSA WITH AES 256 CBC SHA - TLS S TLS ECDHE ECDSA WITH AES 128 CBC SHA - TLS T TLS ECDHE RSA WITH AES 128 CBC SHA -# -# -# noTLS a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA -# noTLS b SSL3 FORTEZZA DMS WITH RC4 128 SHA - noTLS c SSL3 RSA WITH RC4 128 MD5 - noTLS d SSL3 RSA WITH 3DES EDE CBC SHA - noTLS e SSL3 RSA WITH DES CBC SHA - noTLS f SSL3 RSA EXPORT WITH RC4 40 MD5 - noTLS g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5 -# noTLS h SSL3 FORTEZZA DMS WITH NULL SHA - noTLS i SSL3 RSA WITH NULL MD5 - noTLS j SSL3 RSA FIPS WITH 3DES EDE CBC SHA - noTLS k SSL3 RSA FIPS WITH DES CBC SHA - noTLS l SSL3 RSA EXPORT WITH DES CBC SHA (new) - noTLS m SSL3 RSA EXPORT WITH RC4 56 SHA (new) - noTLS n SSL3 RSA WITH RC4 128 SHA - noTLS v SSL3 RSA WITH AES 128 CBC SHA - noTLS y SSL3 RSA WITH AES 256 CBC SHA - noTLS z SSL3 RSA WITH NULL SHA -# - TLS c TLS RSA WITH RC4 128 MD5 - TLS d TLS RSA WITH 3DES EDE CBC SHA - TLS e TLS RSA WITH DES CBC SHA - TLS f TLS RSA EXPORT WITH RC4 40 MD5 - TLS g TLS RSA EXPORT WITH RC2 CBC 40 MD5 - TLS i TLS RSA WITH NULL MD5 - TLS j TLS RSA FIPS WITH 3DES EDE CBC SHA - TLS k TLS RSA FIPS WITH DES CBC SHA - TLS l TLS RSA EXPORT WITH DES CBC SHA (new) - TLS m TLS RSA EXPORT WITH RC4 56 SHA (new) - TLS n TLS RSA WITH RC4 128 SHA - TLS v TLS RSA WITH AES 128 CBC SHA - TLS y TLS RSA WITH AES 256 CBC SHA - TLS z TLS RSA WITH NULL SHA diff --git a/security/nss/tests/ssl/ecsslstress.txt b/security/nss/tests/ssl/ecsslstress.txt deleted file mode 100644 index f9feb5d99..000000000 --- a/security/nss/tests/ssl/ecsslstress.txt +++ /dev/null @@ -1,24 +0,0 @@ -# -# This file defines the tests for client auth. -# -# expected -# return server client Test Case name -# value params params -# ------ ------ ------ --------------- - 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5 - 0 _ -c_1000_-C_c Stress SSL3 RC4 128 with MD5 - 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5 -# -# ECC ciphers -# XXX Session reuse does not seem to work for ECDH-ECDSA, ECDHE-ECDSA ciphers -# but works ok for ECDHE-RSA ciphers. With session reuse turned off -# setting up 1000 connections would take too long so use only 10 connections -# - 0 -c_H -c_10_-C_H_-N Stress TLS ECDH-ECDSA RC4 128 with SHA (no reuse) - 0 -c_S -c_10_-C_S_-N Stress TLS ECDHE-ECDSA AES 128 CBC with SHA (no reuse) - 0 -c_T -c_1000_-C_T Stress TLS ECDHE-RSA AES 128 CBC with SHA - -# -# add client auth versions here... -# -# 0 -r -w_bogus_-n_"Test_User" TLS Request don't require client auth (bad password) diff --git a/security/nss/tests/ssl/ssl.sh b/security/nss/tests/ssl/ssl.sh index 1ad1ca843..9603f1805 100755 --- a/security/nss/tests/ssl/ssl.sh +++ b/security/nss/tests/ssl/ssl.sh @@ -21,6 +21,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 @@ -102,6 +103,12 @@ ssl_init() USER_NICKNAME=TestUser NORM_EXT="" + if [ -n "$NSS_ENABLE_ECC" ] ; then + ECC_STRING=" - with ECC" + else + ECC_STRING="" + fi + cd ${CLIENTDIR} } @@ -123,12 +130,11 @@ is_selfserv_alive() else PID=`cat ${SERVERPID}` fi - #if [ "${OS_ARCH}" = "Linux" ]; then - kill -0 $PID >/dev/null 2>/dev/null || Exit 10 "Fatal - selfserv process not detectable" - #else - #$PS -e | grep $PID >/dev/null || \ - #Exit 10 "Fatal - selfserv process not detectable" - #fi + + echo "kill -0 ${PID} >/dev/null 2>/dev/null" + kill -0 ${PID} >/dev/null 2>/dev/null || Exit 10 "Fatal - selfserv process not detectable" + + echo "selfserv with PID ${PID} found at `date`" } ########################### wait_for_selfserv ########################## @@ -136,9 +142,9 @@ is_selfserv_alive() ######################################################################## wait_for_selfserv() { + echo "waiting for selfserv at `date`" echo "tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \\" echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}" - #echo "tstclnt -q started at `date`" tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} if [ $? -ne 0 ]; then @@ -147,7 +153,7 @@ wait_for_selfserv() echo " -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}" tstclnt -p ${PORT} -h ${HOSTADDR} ${CLIENT_OPTIONS} -q \ -d ${P_R_CLIENTDIR} < ${REQUEST_FILE} - elif [ sparam = "-c ABCDEFabcdefghijklmnvy" ] ; then # "$1" = "cov" ] ; then + elif [ "$sparam" = "$CSHORT" -o "$sparam" = "$CLONG" ] ; then html_passed "<TR><TD> Wait for Server" fi is_selfserv_alive @@ -163,18 +169,33 @@ kill_selfserv() else PID=`cat ${SERVERPID}` fi - ${KILL} ${PID} + + echo "trying to kill selfserv with PID ${PID} at `date`" + + if [ "${OS_ARCH}" = "WINNT" -o "${OS_ARCH}" = "WIN95" -o "${OS_ARCH}" = "OS2" ]; then + echo "${KILL} ${PID}" + ${KILL} ${PID} + else + echo "${KILL} -USR1 ${PID}" + ${KILL} -USR1 ${PID} + fi wait ${PID} if [ ${fileout} -eq 1 ]; then cat ${SERVEROUTFILE} fi + # On Linux selfserv needs up to 30 seconds to fully die and free # the port. Wait until the port is free. (Bug 129701) if [ "${OS_ARCH}" = "Linux" ]; then + echo "selfserv -b -p ${PORT} 2>/dev/null;" until selfserv -b -p ${PORT} 2>/dev/null; do + echo "RETRY: selfserv -b -p ${PORT} 2>/dev/null;" sleep 1 done fi + + echo "selfserv with PID ${PID} killed at `date`" + rm ${SERVERPID} } @@ -189,16 +210,24 @@ start_selfserv() echo "$SCRIPTNAME: $testname ----" fi sparam=`echo $sparam | sed -e 's;_; ;g'` + if [ -n "$NSS_ENABLE_ECC" ] ; then + ECC_OPTIONS="-e ${HOSTADDR}-ec" + else + ECC_OPTIONS="" + fi + if [ "$1" = "mixed" ]; then + ECC_OPTIONS="-e ${HOSTADDR}-ecmixed" + fi + echo "selfserv starting at `date`" echo "selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \\" - echo " -w nss ${sparam} -i ${R_SERVERPID} $verbose &" - echo "selfserv started at `date`" + echo " ${ECC_OPTIONS} -w nss ${sparam} -i ${R_SERVERPID} $verbose &" if [ ${fileout} -eq 1 ]; then selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \ - -w nss ${sparam} -i ${R_SERVERPID} $verbose \ + ${ECC_OPTIONS} -w nss ${sparam} -i ${R_SERVERPID} $verbose \ > ${SERVEROUTFILE} 2>&1 & else selfserv -D -p ${PORT} -d ${P_R_SERVERDIR} -n ${HOSTADDR} ${SERVER_OPTIONS} \ - -w nss ${sparam} -i ${R_SERVERPID} $verbose & + ${ECC_OPTIONS} -w nss ${sparam} -i ${R_SERVERPID} $verbose & fi # The PID $! returned by the MKS or Cygwin shell is not the PID of # the real background process, but rather the PID of a helper @@ -214,6 +243,14 @@ start_selfserv() # other than the MKS shell.) SHELL_SERVERPID=$! wait_for_selfserv + + if [ "${OS_ARCH}" = "WINNT" -a "$OS_NAME" = "CYGWIN_NT" ]; then + PID=${SHELL_SERVERPID} + else + PID=`cat ${SERVERPID}` + fi + + echo "selfserv with PID ${PID} started at `date`" } ############################## ssl_cov ################################# @@ -221,28 +258,63 @@ start_selfserv() ######################################################################## ssl_cov() { - html_head "SSL Cipher Coverage $NORM_EXT - $BYPASS_STRING" + html_head "SSL Cipher Coverage $NORM_EXT - $BYPASS_STRING $ECC_STRING" testname="" - sparam="-c ABCDEFabcdefghijklmnvyz" + if [ -n "$NSS_ENABLE_ECC" ] ; then + sparam="$CLONG" + else + sparam="$CSHORT" + fi + + mixed=0 start_selfserv # Launch the server p="" - while read tls param testname + while read ectype tls param testname do p=`echo "$testname" | sed -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended Test" ] ; then echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - elif [ "$tls" != "#" ] ; then + elif [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: skipping $testname (ECC only)" + elif [ "$ectype" != "#" ] ; then echo "$SCRIPTNAME: running $testname ----------------------------" TLS_FLAG=-T - if [ $tls = "TLS" ]; then + if [ "$tls" = "TLS" ]; then TLS_FLAG="" fi - is_selfserv_alive +# These five tests need an EC cert signed with RSA +# This requires a different certificate loaded in selfserv +# due to a (current) NSS limitation of only loaded one cert +# per type so the default selfserv setup will not work. +#:C00B TLS ECDH RSA WITH NULL SHA +#:C00C TLS ECDH RSA WITH RC4 128 SHA +#:C00D TLS ECDH RSA WITH 3DES EDE CBC SHA +#:C00E TLS ECDH RSA WITH AES 128 CBC SHA +#:C00F TLS ECDH RSA WITH AES 256 CBC SHA + + if [ $mixed -eq 0 ]; then + if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then + kill_selfserv + start_selfserv mixed + mixed=1 + else + is_selfserv_alive + fi + else + if [ "${param}" = ":C00B" -o "${param}" = ":C00C" -o "${param}" = ":C00D" -o "${param}" = ":C00E" -o "${param}" = ":C00F" ]; then + is_selfserv_alive + else + kill_selfserv + start_selfserv + mixed=0 + fi + fi + echo "tstclnt -p ${PORT} -h ${HOSTADDR} -c ${param} ${TLS_FLAG} ${CLIENT_OPTIONS} \\" echo " -f -d ${P_R_CLIENTDIR} < ${REQUEST_FILE}" @@ -253,7 +325,8 @@ ssl_cov() ret=$? cat ${TMP}/$HOST.tmp.$$ rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - html_msg $ret 0 "${testname}" + html_msg $ret 0 "${testname}" \ + "produced a returncode of $ret, expected is 0" fi done < ${SSLCOV} @@ -266,11 +339,13 @@ ssl_cov() ######################################################################## ssl_auth() { - html_head "SSL Client Authentication $NORM_EXT - $BYPASS_STRING" + html_head "SSL Client Authentication $NORM_EXT - $BYPASS_STRING $ECC_STRING" - while read value sparam cparam testname + while read ectype value sparam cparam testname do - if [ $value != "#" ]; then + if [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: skipping $testname (ECC only)" + elif [ "$ectype" != "#" ]; then cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` start_selfserv @@ -299,17 +374,33 @@ ssl_auth() ######################################################################## ssl_stress() { - html_head "SSL Stress Test $NORM_EXT - $BYPASS_STRING" + html_head "SSL Stress Test $NORM_EXT - $BYPASS_STRING $ECC_STRING" - while read value sparam cparam testname + while read ectype value sparam cparam testname do + if [ -z "$ectype" ]; then + # silently ignore blank lines + continue + fi p=`echo "$testname" | sed -e "s/Stress //" -e "s/ .*//"` #sonmi, only run extended test on SSL3 and TLS if [ "$p" = "SSL2" -a "$NORM_EXT" = "Extended Test" ] ; then echo "$SCRIPTNAME: skipping $testname for $NORM_EXT" - elif [ $value != "#" ]; then - cparam=`echo $cparam | sed -e 's;_; ;g'` - start_selfserv - if [ `uname -n` = "sjsu" ] ; then + elif [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: skipping $testname (ECC only)" + elif [ "$ectype" != "#" ]; then + cparam=`echo $cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` + +# These tests need the mixed cert +# Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse) +# Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse, client auth) + p=`echo "$sparam" | sed -e "s/\(.*\)\(-c_:C0..\)\(.*\)/\2/"`; + if [ "$p" = "-c_:C00E" ]; then + start_selfserv mixed + else + start_selfserv + fi + + if [ "`uname -n`" = "sjsu" ] ; then echo "debugging disapering selfserv... ps -ef | grep selfserv" ps -ef | grep selfserv fi @@ -321,8 +412,10 @@ ssl_stress() $verbose ${HOSTADDR} ret=$? echo "strsclnt completed at `date`" - html_msg $ret $value "${testname}" - if [ `uname -n` = "sjsu" ] ; then + html_msg $ret $value \ + "${testname}" \ + "produced a returncode of $ret, expected is $value. " + if [ "`uname -n`" = "sjsu" ] ; then echo "debugging disapering selfserv... ps -ef | grep selfserv" ps -ef | grep selfserv fi @@ -339,7 +432,7 @@ ssl_stress() ssl_crl_ssl() { - html_head "CRL SSL Client Tests $NORM_EXT" + html_head "CRL SSL Client Tests $NORM_EXT $ECC_STRING" # Using First CRL Group for this test. There are $CRL_GRP_1_RANGE certs in it. # Cert number $UNREVOKED_CERT_GRP_1 was not revoked @@ -347,9 +440,11 @@ ssl_crl_ssl() CRL_GROUP_RANGE=$CRL_GRP_1_RANGE UNREVOKED_CERT=$UNREVOKED_CERT_GRP_1 - while read value sparam cparam testname + while read ectype value sparam cparam testname do - if [ $value != "#" ]; then + if [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: skipping $testname (ECC only)" + elif [ "$ectype" != "#" ]; then servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` pwd=`echo $cparam | grep nss` user=`echo $cparam | grep TestUser` @@ -443,6 +538,7 @@ is_revoked() { load_group_crl() { group=$1 + ectype=$2 OUTFILE_TMP=${TMP}/$HOST.tmp.$$ grpBegin=`eval echo \$\{CRL_GRP_${group}_BEGIN\}` @@ -454,6 +550,15 @@ load_group_crl() { return 1; fi + # Add -ec suffix for ECC + if [ "$ectype" = "ECC" ] ; then + ecsuffix="-ec" + eccomment="ECC " + else + ecsuffix="" + eccomment="" + fi + if [ "$RELOAD_CRL" != "" ]; then if [ $group -eq 1 ]; then echo "==================== Resetting to group 1 crl ===================" @@ -461,18 +566,18 @@ load_group_crl() { start_selfserv is_selfserv_alive fi - echo "================= Reloading CRL for group $grpBegin - $grpEnd =============" + echo "================= Reloading ${eccomment}CRL for group $grpBegin - $grpEnd =============" echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\" - echo " -w nss -n TestUser${UNREVOKED_CERT_GRP_1}" + echo " -w nss -n TestUser${UNREVOKED_CERT_GRP_1}${ecsuffix}" echo "Request:" - echo "GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}" + echo "GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}${ecsuffix}" echo "" echo "RELOAD time $i" tstclnt -p ${PORT} -h ${HOSTADDR} -f \ - -d ${R_CLIENTDIR} -w nss -n TestUser${UNREVOKED_CERT_GRP_1} \ - <<_EOF_REQUEST_ >${OUTFILE_TMP} 2>&1 -GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd} + -d ${R_CLIENTDIR} -w nss -n TestUser${UNREVOKED_CERT_GRP_1}${ecsuffix} \ + >${OUTFILE_TMP} 2>&1 <<_EOF_REQUEST_ +GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}${ecsuffix} _EOF_REQUEST_ cat ${OUTFILE_TMP} @@ -485,11 +590,12 @@ _EOF_REQUEST_ echo "=== Updating DB for group $grpBegin - $grpEnd and restarting selfserv =====" kill_selfserv - CU_ACTION="Importing CRL for groups $grpBegin - $grpEnd" - crlu -d ${R_SERVERDIR} -I -i ${SERVERDIR}/root.crl_${grpBegin}-${grpEnd} \ + CU_ACTION="Importing ${eccomment}CRL for groups $grpBegin - $grpEnd" + crlu -d ${R_SERVERDIR} -I -i ${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}${ecsuffix} \ -p ../tests.pw.928 ret=$? if [ "$ret" -eq 0 ]; then + html_passed "<TR><TD> ${CU_ACTION}" return 1 fi start_selfserv @@ -502,7 +608,7 @@ _EOF_REQUEST_ ssl_crl_cache() { - html_head "Cache CRL SSL Client Tests $NORM_EXT" + html_head "Cache CRL SSL Client Tests $NORM_EXT $ECC_STRING" SSLAUTH_TMP=${TMP}/authin.tl.tmp SERV_ARG=-r_-r rm -f ${SSLAUTH_TMP} @@ -514,82 +620,89 @@ ssl_crl_cache() do sparam=$SERV_ARG start_selfserv - while read value sparam cparam testname + while read ectype value sparam cparam testname do - servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` - pwd=`echo $cparam | grep nss` - user=`echo $cparam | grep TestUser` - _cparam=$cparam - case $servarg in - 1) if [ -z "$pwd" -o -z "$user" ]; then - rev_modvalue=0 - else - rev_modvalue=254 - fi - ;; - 2) rev_modvalue=254 ;; - - 3) if [ -z "$pwd" -o -z "$user" ]; then - rev_modvalue=0 - else - rev_modvalue=1 - fi - ;; - 4) rev_modvalue=1 ;; - esac - TEMP_NUM=0 - LOADED_GRP=1 - while [ ${LOADED_GRP} -le ${TOTAL_GRP_NUM} ] - do - while [ $TEMP_NUM -lt $TOTAL_CRL_RANGE ] + if [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: skipping $testname (ECC only)" + else + servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'` + pwd=`echo $cparam | grep nss` + user=`echo $cparam | grep TestUser` + _cparam=$cparam + case $servarg in + 1) if [ -z "$pwd" -o -z "$user" ]; then + rev_modvalue=0 + else + rev_modvalue=254 + fi + ;; + 2) rev_modvalue=254 ;; + + 3) if [ -z "$pwd" -o -z "$user" ]; then + rev_modvalue=0 + else + rev_modvalue=1 + fi + ;; + 4) rev_modvalue=1 ;; + esac + TEMP_NUM=0 + LOADED_GRP=1 + while [ ${LOADED_GRP} -le ${TOTAL_GRP_NUM} ] do - CURR_SER_NUM=`expr ${CRL_GRP_1_BEGIN} + ${TEMP_NUM}` - TEMP_NUM=`expr $TEMP_NUM + 1` - USER_NICKNAME="TestUser${CURR_SER_NUM}" - cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` - - echo "Server Args: $SERV_ARG" - echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\" - echo " ${cparam} < ${REQUEST_FILE}" - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ - -d ${R_CLIENTDIR} < ${REQUEST_FILE} \ - >${TMP}/$HOST.tmp.$$ 2>&1 - ret=$? - cat ${TMP}/$HOST.tmp.$$ - rm ${TMP}/$HOST.tmp.$$ 2>/dev/null - is_revoked ${CURR_SER_NUM} ${LOADED_GRP} - isRevoked=$? - if [ $isRevoked -eq 0 ]; then - modvalue=$rev_modvalue - testAddMsg="revoked" - else - modvalue=$value - testAddMsg="not revoked" - fi - - is_selfserv_alive - ss_status=$? - if [ "$ss_status" -ne 0 ]; then - html_msg $ret $modvalue \ - "${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \ - "produced a returncode of $ret, expected is $modvalue. " \ - "selfserv is not alive!" - else - html_msg $ret $modvalue \ - "${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \ - "produced a returncode of $ret, expected is $modvalue" + while [ $TEMP_NUM -lt $TOTAL_CRL_RANGE ] + do + CURR_SER_NUM=`expr ${CRL_GRP_1_BEGIN} + ${TEMP_NUM}` + TEMP_NUM=`expr $TEMP_NUM + 1` + USER_NICKNAME="TestUser${CURR_SER_NUM}" + cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" ` + + echo "Server Args: $SERV_ARG" + echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\" + echo " ${cparam} < ${REQUEST_FILE}" + rm ${TMP}/$HOST.tmp.$$ 2>/dev/null + tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \ + -d ${R_CLIENTDIR} < ${REQUEST_FILE} \ + >${TMP}/$HOST.tmp.$$ 2>&1 + ret=$? + cat ${TMP}/$HOST.tmp.$$ + rm ${TMP}/$HOST.tmp.$$ 2>/dev/null + is_revoked ${CURR_SER_NUM} ${LOADED_GRP} + isRevoked=$? + if [ $isRevoked -eq 0 ]; then + modvalue=$rev_modvalue + testAddMsg="revoked" + else + modvalue=$value + testAddMsg="not revoked" + fi + + is_selfserv_alive + ss_status=$? + if [ "$ss_status" -ne 0 ]; then + html_msg $ret $modvalue \ + "${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \ + "produced a returncode of $ret, expected is $modvalue. " \ + "selfserv is not alive!" + else + html_msg $ret $modvalue \ + "${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \ + "produced a returncode of $ret, expected is $modvalue" + fi + done + LOADED_GRP=`expr $LOADED_GRP + 1` + TEMP_NUM=0 + if [ "$LOADED_GRP" -le "$TOTAL_GRP_NUM" ]; then + load_group_crl $LOADED_GRP $ectype + html_msg $ret 0 "Load group $LOADED_GRP ${eccomment}crl " \ + "produced a returncode of $ret, expected is 0" fi done - LOADED_GRP=`expr $LOADED_GRP + 1` - TEMP_NUM=0 - if [ "$LOADED_GRP" -le "$TOTAL_GRP_NUM" ]; then - load_group_crl $LOADED_GRP - html_msg $ret 0 "Load group $LOADED_GRP crl " \ - "produced a returncode of $ret, expected is 0" - fi - done - load_group_crl 1 + # Restart selfserv to roll back to two initial group 1 crls + # TestCA CRL and TestCA-ec CRL + kill_selfserv + start_selfserv + fi done < ${SSLAUTH_TMP} kill_selfserv SERV_ARG="${SERV_ARG}_-r" @@ -637,7 +750,7 @@ ssl_run() ssl_auth ssl_stress - # the next round off ssl tests will only run if these vars are reset + # the next round of ssl tests will only run if these vars are reset SERVERDIR=$ORIG_SERVERDIR CLIENTDIR=$ORIG_CLIENTDIR R_SERVERDIR=$ORIG_R_SERVERDIR @@ -647,13 +760,15 @@ ssl_run() USER_NICKNAME=TestUser NORM_EXT= cd ${QADIR}/ssl - ssl_cleanup } ################## main ################################################# #this script may be sourced from the distributed stress test - in this case do nothing... +CSHORT="-c ABCDEFcdefgijklmnvyz" +CLONG="-c ABCDEF:C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014cdefgijklmnvyz" + if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then ssl_init @@ -668,7 +783,6 @@ if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then ssl_crl_ssl ssl_crl_cache - ssl_cleanup # Test all combinations of server bypass and client bypass CLIENT_OPTIONS="-B -s" @@ -680,4 +794,5 @@ if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then BYPASS_STRING="Server Bypass" ssl_run + ssl_cleanup fi diff --git a/security/nss/tests/ssl/sslauth.txt b/security/nss/tests/ssl/sslauth.txt index c150e1090..deb30c3b6 100644 --- a/security/nss/tests/ssl/sslauth.txt +++ b/security/nss/tests/ssl/sslauth.txt @@ -1,31 +1,50 @@ # # This file defines the tests for client auth. # -# expected -# return server client Test Case name -# value params params -# ------ ------ ------ --------------- - 0 -r -w_nss_-n_none TLS Request don't require client auth (client does not provide auth) - 0 -r -w_bogus_-n_TestUser TLS Request don't require client auth (bad password) - 0 -r -w_nss_-n_TestUser TLS Request don't require client auth (client auth) - 254 -r_-r -w_nss_-n_none TLS Require client auth (client does not provide auth) - 254 -r_-r -w_bogus_-n_TestUser TLS Require client auth (bad password) - 0 -r_-r -w_nss_-n_TestUser_ TLS Require client auth (client auth) - 0 -r -T_-w_nss_-n_none SSL3 Request don't require client auth (client does not provide auth) - 0 -r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth (bad password) - 0 -r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth (client auth) - 254 -r_-r -T_-w_nss_-n_none SSL3 Require client auth (client does not provide auth) - 254 -r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth (bad password) - 0 -r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth (client auth) - 0 -r_-r_-r -w_nss_-n_none TLS Request don't require client auth on 2nd hs (client does not provide auth) - 0 -r_-r_-r -w_bogus_-n_TestUser TLS Request don't require client auth on 2nd hs (bad password) - 0 -r_-r_-r -w_nss_-n_TestUser TLS Request don't require client auth on 2nd hs (client auth) - 1 -r_-r_-r_-r -w_nss_-n_none TLS Require client auth on 2nd hs (client does not provide auth) - 1 -r_-r_-r_-r -w_bogus_-n_TestUser TLS Require client auth on 2nd hs (bad password) - 0 -r_-r_-r_-r -w_nss_-n_TestUser_ TLS Require client auth on 2nd hs (client auth) - 0 -r_-r_-r -T_-w_nss_-n_none SSL3 Request don't require client auth on 2nd hs (client does not provide auth) - 0 -r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth on 2nd hs (bad password) - 0 -r_-r_-r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth on 2nd hs (client auth) - 1 -r_-r_-r_-r -T_-w_nss_-n_none SSL3 Require client auth on 2nd hs (client does not provide auth) - 1 -r_-r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth on 2nd hs (bad password) - 0 -r_-r_-r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth on 2nd hs (client auth) +# expected +# Enable return server client Test Case name +# ECC value params params +# ------- ------ ------ ------ --------------- + noECC 0 -r -w_nss_-n_none TLS Request don't require client auth (client does not provide auth) + noECC 0 -r -w_bogus_-n_TestUser TLS Request don't require client auth (bad password) + noECC 0 -r -w_nss_-n_TestUser TLS Request don't require client auth (client auth) + noECC 254 -r_-r -w_nss_-n_none TLS Require client auth (client does not provide auth) + noECC 254 -r_-r -w_bogus_-n_TestUser TLS Require client auth (bad password) + noECC 0 -r_-r -w_nss_-n_TestUser_ TLS Require client auth (client auth) + noECC 0 -r -T_-w_nss_-n_none SSL3 Request don't require client auth (client does not provide auth) + noECC 0 -r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth (bad password) + noECC 0 -r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth (client auth) + noECC 254 -r_-r -T_-w_nss_-n_none SSL3 Require client auth (client does not provide auth) + noECC 254 -r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth (bad password) + noECC 0 -r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth (client auth) + noECC 0 -r_-r_-r -w_nss_-n_none TLS Request don't require client auth on 2nd hs (client does not provide auth) + noECC 0 -r_-r_-r -w_bogus_-n_TestUser TLS Request don't require client auth on 2nd hs (bad password) + noECC 0 -r_-r_-r -w_nss_-n_TestUser TLS Request don't require client auth on 2nd hs (client auth) + noECC 1 -r_-r_-r_-r -w_nss_-n_none TLS Require client auth on 2nd hs (client does not provide auth) + noECC 1 -r_-r_-r_-r -w_bogus_-n_TestUser TLS Require client auth on 2nd hs (bad password) + noECC 0 -r_-r_-r_-r -w_nss_-n_TestUser_ TLS Require client auth on 2nd hs (client auth) + noECC 0 -r_-r_-r -T_-w_nss_-n_none SSL3 Request don't require client auth on 2nd hs (client does not provide auth) + noECC 0 -r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Request don't require client auth on 2nd hs (bad password) + noECC 0 -r_-r_-r -T_-n_TestUser_-w_nss SSL3 Request don't require client auth on 2nd hs (client auth) + noECC 1 -r_-r_-r_-r -T_-w_nss_-n_none SSL3 Require client auth on 2nd hs (client does not provide auth) + noECC 1 -r_-r_-r_-r -T_-n_TestUser_-w_bogus SSL3 Require client auth on 2nd hs (bad password) + noECC 0 -r_-r_-r_-r -T_-n_TestUser_-w_nss SSL3 Require client auth on 2nd hs (client auth) +# +# Use EC cert for client authentication +# + ECC 0 -r -w_bogus_-n_TestUser-ec TLS Request don't require client auth (EC) (bad password) + ECC 0 -r -w_nss_-n_TestUser-ec TLS Request don't require client auth (EC) (client auth) + ECC 254 -r_-r -w_bogus_-n_TestUser-ec TLS Require client auth (EC) (bad password) + ECC 0 -r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth (EC) (client auth) + ECC 0 -r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth (EC) (bad password) + ECC 0 -r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth (EC) (client auth) + ECC 254 -r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth (EC) (bad password) + ECC 0 -r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth (EC) (client auth) + ECC 0 -r_-r_-r -w_bogus_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (bad password) + ECC 0 -r_-r_-r -w_nss_-n_TestUser-ec TLS Request don't require client auth on 2nd hs (EC) (client auth) + ECC 1 -r_-r_-r_-r -w_bogus_-n_TestUser-ec TLS Require client auth on 2nd hs (EC) (bad password) + ECC 0 -r_-r_-r_-r -w_nss_-n_TestUser-ec_ TLS Require client auth on 2nd hs (EC) (client auth) + ECC 0 -r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Request don't require client auth on 2nd hs (EC) (bad password) + ECC 0 -r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Request don't require client auth on 2nd hs (EC) (client auth) + ECC 1 -r_-r_-r_-r -T_-n_TestUser-ec_-w_bogus SSL3 Require client auth on 2nd hs (EC) (bad password) + ECC 0 -r_-r_-r_-r -T_-n_TestUser-ec_-w_nss SSL3 Require client auth on 2nd hs (EC) (client auth) diff --git a/security/nss/tests/ssl/sslcov.txt b/security/nss/tests/ssl/sslcov.txt index 52cbae7f5..739988645 100644 --- a/security/nss/tests/ssl/sslcov.txt +++ b/security/nss/tests/ssl/sslcov.txt @@ -4,45 +4,91 @@ # NOTE: SSL2 ciphers are independent of whether TLS is enabled or not. We # mix up the enable functions so we can tests boths paths. # -# Enable Cipher Test Name -# TLS -# - noTLS A SSL2 RC4 128 WITH MD5 - TLS B SSL2 RC4 128 EXPORT40 WITH MD5 - TLS C SSL2 RC2 128 CBC WITH MD5 - noTLS D SSL2 RC2 128 CBC EXPORT40 WITH MD5 - TLS E SSL2 DES 64 CBC WITH MD5 - noTLS F SSL2 DES 192 EDE3 CBC WITH MD5 -# -# noTLS a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA -# noTLS b SSL3 FORTEZZA DMS WITH RC4 128 SHA - noTLS c SSL3 RSA WITH RC4 128 MD5 - noTLS d SSL3 RSA WITH 3DES EDE CBC SHA - noTLS e SSL3 RSA WITH DES CBC SHA - noTLS f SSL3 RSA EXPORT WITH RC4 40 MD5 - noTLS g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5 -# noTLS h SSL3 FORTEZZA DMS WITH NULL SHA - noTLS i SSL3 RSA WITH NULL MD5 - noTLS j SSL3 RSA FIPS WITH 3DES EDE CBC SHA - noTLS k SSL3 RSA FIPS WITH DES CBC SHA - noTLS l SSL3 RSA EXPORT WITH DES CBC SHA (new) - noTLS m SSL3 RSA EXPORT WITH RC4 56 SHA (new) - noTLS n SSL3 RSA WITH RC4 128 SHA - noTLS v SSL3 RSA WITH AES 128 CBC SHA - noTLS y SSL3 RSA WITH AES 256 CBC SHA - noTLS z SSL3 RSA WITH NULL SHA -# - TLS c TLS RSA WITH RC4 128 MD5 - TLS d TLS RSA WITH 3DES EDE CBC SHA - TLS e TLS RSA WITH DES CBC SHA - TLS f TLS RSA EXPORT WITH RC4 40 MD5 - TLS g TLS RSA EXPORT WITH RC2 CBC 40 MD5 - TLS i TLS RSA WITH NULL MD5 - TLS j TLS RSA FIPS WITH 3DES EDE CBC SHA - TLS k TLS RSA FIPS WITH DES CBC SHA - TLS l TLS RSA EXPORT WITH DES CBC SHA (new) - TLS m TLS RSA EXPORT WITH RC4 56 SHA (new) - TLS n TLS RSA WITH RC4 128 SHA - TLS v TLS RSA WITH AES 128 CBC SHA - TLS y TLS RSA WITH AES 256 CBC SHA - TLS z TLS RSA WITH NULL SHA +# Enable Enable Cipher Test Name +# EC TLS +# + noECC noTLS A SSL2 RC4 128 WITH MD5 + noECC TLS B SSL2 RC4 128 EXPORT40 WITH MD5 + noECC TLS C SSL2 RC2 128 CBC WITH MD5 + noECC noTLS D SSL2 RC2 128 CBC EXPORT40 WITH MD5 + noECC TLS E SSL2 DES 64 CBC WITH MD5 + noECC noTLS F SSL2 DES 192 EDE3 CBC WITH MD5 +# +# noECC noTLS a SSL3 FORTEZZA DMS WITH FORTEZZA CBC SHA +# noECC noTLS b SSL3 FORTEZZA DMS WITH RC4 128 SHA + noECC noTLS c SSL3 RSA WITH RC4 128 MD5 + noECC noTLS d SSL3 RSA WITH 3DES EDE CBC SHA + noECC noTLS e SSL3 RSA WITH DES CBC SHA + noECC noTLS f SSL3 RSA EXPORT WITH RC4 40 MD5 + noECC noTLS g SSL3 RSA EXPORT WITH RC2 CBC 40 MD5 +# noECC noTLS h SSL3 FORTEZZA DMS WITH NULL SHA + noECC noTLS i SSL3 RSA WITH NULL MD5 + noECC noTLS j SSL3 RSA FIPS WITH 3DES EDE CBC SHA + noECC noTLS k SSL3 RSA FIPS WITH DES CBC SHA + noECC noTLS l SSL3 RSA EXPORT WITH DES CBC SHA (new) + noECC noTLS m SSL3 RSA EXPORT WITH RC4 56 SHA (new) + noECC noTLS n SSL3 RSA WITH RC4 128 SHA + noECC noTLS v SSL3 RSA WITH AES 128 CBC SHA + noECC noTLS y SSL3 RSA WITH AES 256 CBC SHA + noECC noTLS z SSL3 RSA WITH NULL SHA +# + noECC TLS c TLS RSA WITH RC4 128 MD5 + noECC TLS d TLS RSA WITH 3DES EDE CBC SHA + noECC TLS e TLS RSA WITH DES CBC SHA + noECC TLS f TLS RSA EXPORT WITH RC4 40 MD5 + noECC TLS g TLS RSA EXPORT WITH RC2 CBC 40 MD5 + noECC TLS i TLS RSA WITH NULL MD5 + noECC TLS j TLS RSA FIPS WITH 3DES EDE CBC SHA + noECC TLS k TLS RSA FIPS WITH DES CBC SHA + noECC TLS l TLS RSA EXPORT WITH DES CBC SHA (new) + noECC TLS m TLS RSA EXPORT WITH RC4 56 SHA (new) + noECC TLS n TLS RSA WITH RC4 128 SHA + noECC TLS v TLS RSA WITH AES 128 CBC SHA + noECC TLS y TLS RSA WITH AES 256 CBC SHA + noECC TLS z TLS RSA WITH NULL SHA +# +# ECC ciphers (SSL3) +# + ECC noTLS :C001 SSL3 ECDH ECDSA WITH NULL SHA + ECC noTLS :C002 SSL3 ECDH ECDSA WITH RC4 128 SHA + ECC noTLS :C003 SSL3 ECDH ECDSA WITH 3DES EDE CBC SHA + ECC noTLS :C004 SSL3 ECDH ECDSA WITH AES 128 CBC SHA + ECC noTLS :C005 SSL3 ECDH ECDSA WITH AES 256 CBC SHA + ECC noTLS :C006 SSL3 ECDHE ECDSA WITH NULL SHA + ECC noTLS :C007 SSL3 ECDHE ECDSA WITH RC4 128 SHA + ECC noTLS :C008 SSL3 ECDHE ECDSA WITH 3DES EDE CBC SHA + ECC noTLS :C009 SSL3 ECDHE ECDSA WITH AES 128 CBC SHA + ECC noTLS :C00A SSL3 ECDHE ECDSA WITH AES 256 CBC SHA + ECC noTLS :C00B SSL3 ECDH RSA WITH NULL SHA + ECC noTLS :C00C SSL3 ECDH RSA WITH RC4 128 SHA + ECC noTLS :C00D SSL3 ECDH RSA WITH 3DES EDE CBC SHA + ECC noTLS :C00E SSL3 ECDH RSA WITH AES 128 CBC SHA + ECC noTLS :C00F SSL3 ECDH RSA WITH AES 256 CBC SHA + ECC noTLS :C010 SSL3 ECDHE RSA WITH NULL SHA + ECC noTLS :C011 SSL3 ECDHE RSA WITH RC4 128 SHA + ECC noTLS :C012 SSL3 ECDHE RSA WITH 3DES EDE CBC SHA + ECC noTLS :C013 SSL3 ECDHE RSA WITH AES 128 CBC SHA + ECC noTLS :C014 SSL3 ECDHE RSA WITH AES 256 CBC SHA +# +# ECC ciphers (TLS) +# + ECC TLS :C001 TLS ECDH ECDSA WITH NULL SHA + ECC TLS :C002 TLS ECDH ECDSA WITH RC4 128 SHA + ECC TLS :C003 TLS ECDH ECDSA WITH 3DES EDE CBC SHA + ECC TLS :C004 TLS ECDH ECDSA WITH AES 128 CBC SHA + ECC TLS :C005 TLS ECDH ECDSA WITH AES 256 CBC SHA + ECC TLS :C006 TLS ECDHE ECDSA WITH NULL SHA + ECC TLS :C007 TLS ECDHE ECDSA WITH RC4 128 SHA + ECC TLS :C008 TLS ECDHE ECDSA WITH 3DES EDE CBC SHA + ECC TLS :C009 TLS ECDHE ECDSA WITH AES 128 CBC SHA + ECC TLS :C00A TLS ECDHE ECDSA WITH AES 256 CBC SHA + ECC TLS :C00B TLS ECDH RSA WITH NULL SHA + ECC TLS :C00C TLS ECDH RSA WITH RC4 128 SHA + ECC TLS :C00D TLS ECDH RSA WITH 3DES EDE CBC SHA + ECC TLS :C00E TLS ECDH RSA WITH AES 128 CBC SHA + ECC TLS :C00F TLS ECDH RSA WITH AES 256 CBC SHA + ECC TLS :C010 TLS ECDHE RSA WITH NULL SHA + ECC TLS :C011 TLS ECDHE RSA WITH RC4 128 SHA + ECC TLS :C012 TLS ECDHE RSA WITH 3DES EDE CBC SHA + ECC TLS :C013 TLS ECDHE RSA WITH AES 128 CBC SHA + ECC TLS :C014 TLS ECDHE RSA WITH AES 256 CBC SHA diff --git a/security/nss/tests/ssl/sslstress.txt b/security/nss/tests/ssl/sslstress.txt index 253faa48e..97f67c207 100644 --- a/security/nss/tests/ssl/sslstress.txt +++ b/security/nss/tests/ssl/sslstress.txt @@ -1,14 +1,34 @@ # -# This file defines the tests for client auth. +# This file defines the stress tests for SSL/TLS. # -# expected -# return server client Test Case name -# value params params -# ------ ------ ------ --------------- - 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5 - 0 _ -c_1000_-C_c_-T Stress SSL3 RC4 128 with MD5 - 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5 +# expected +# Enable return server client Test Case name +# ECC value params params +# ------- ------ ------ ------ --------------- + noECC 0 _ -c_1000_-C_A Stress SSL2 RC4 128 with MD5 + noECC 0 _ -c_1000_-C_c_-T Stress SSL3 RC4 128 with MD5 + noECC 0 _ -c_1000_-C_c Stress TLS RC4 128 with MD5 + # # add client auth versions here... # -# 0 -r -w_bogus_-n_"Test_User" TLS Request don't require client auth (bad password) + noECC 0 -r_-r -c_100_-C_A_-N_-n_TestUser Stress SSL2 RC4 128 with MD5 (client auth) + noECC 0 -r_-r -c_100_-C_c_-T_-N_-n_TestUser Stress SSL3 RC4 128 with MD5 (client auth) + noECC 0 -r_-r -c_100_-C_c_-N_-n_TestUser Stress TLS RC4 128 with MD5 (client auth) + +# +# ############################ ECC ciphers ############################ +# + ECC 0 -c_:C009 -c_100_-C_:C009_-N_-T Stress SSL3 ECDHE-ECDSA AES 128 CBC with SHA (no reuse) + ECC 0 -c_:C013 -c_1000_-C_:C013_-T Stress SSL3 ECDHE-RSA AES 128 CBC with SHA + ECC 0 -c_:C004 -2_-c_100_-C_:C004_-N Stress TLS ECDH-ECDSA AES 128 CBC with SHA (no reuse) + ECC 0 -c_:C00E -2_-c_100_-C_:C00E_-N Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse) + ECC 0 -c_:C013 -2_-c_1000_-C_:C013 Stress TLS ECDHE-RSA AES 128 CBC with SHA +# +# add client auth versions here... +# + ECC 0 -r_-r_-c_:C009 -c_10_-C_:C009_-N_-T_-n_TestUser-ec Stress SSL3 ECDHE-ECDSA AES 128 CBC with SHA (no reuse, client auth) + ECC 0 -r_-r_-c_:C013 -c_100_-C_:C013_-T_-n_TestUser-ec Stress SSL3 ECDHE-RSA AES 128 CBC with SHA (client auth) + ECC 0 -r_-r_-c_:C004 -c_10_-C_:C004_-N_-n_TestUser-ec Stress TLS ECDH-ECDSA AES 128 CBC with SHA (no reuse, client auth) + ECC 0 -r_-r_-c_:C00E -c_10_-C_:C00E_-N_-n_TestUser-ecmixed Stress TLS ECDH-RSA AES 128 CBC with SHA (no reuse, client auth) + ECC 0 -r_-r_-c_:C013 -c_100_-C_:C013_-n_TestUser-ec Stress TLS ECDHE-RSA AES 128 CBC with SHA(client auth) diff --git a/security/nss/tests/tools/ectools.sh b/security/nss/tests/tools/ectools.sh deleted file mode 100644 index 65e8d7ce1..000000000 --- a/security/nss/tests/tools/ectools.sh +++ /dev/null @@ -1,210 +0,0 @@ -#! /bin/sh -# -# ***** 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): -# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 -# 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 ***** - -######################################################################## -# -# mozilla/security/nss/tests/tools/tools.sh -# -# Script to test basic functionallity of NSS tools -# -# needs to work on all Unix and Windows platforms -# -# tests implemented: -# pk12util -# signtool -# -# special strings -# --------------- -# FIXME ... known problems, search for this string -# NOTE .... unexpected behavior -######################################################################## - -############################## tools_init ############################## -# local shell function to initialize this script -######################################################################## -tools_init() -{ - SCRIPTNAME=tools.sh # sourced - $0 would point to all.sh - - if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for - CLEANUP="${SCRIPTNAME}" # cleaning this script will do it - fi - - if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then - cd ../common - . ./init.sh - fi - if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here - cd ../cert - . ./cert.sh - fi - SCRIPTNAME=tools.sh - html_head "Tools Tests" - - grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { - Exit 15 "Fatal - S/MIME of cert.sh needs to pass first" - } - - TOOLSDIR=${HOSTDIR}/tools - COPYDIR=${TOOLSDIR}/copydir - - R_TOOLSDIR=../tools - R_COPYDIR=../tools/copydir - P_R_COPYDIR=${R_COPYDIR} - if [ -n "${MULTIACCESS_DBM}" ]; then - P_R_COPYDIR="multiaccess:Tools.$version" - fi - - mkdir -p ${TOOLSDIR} - mkdir -p ${COPYDIR} - mkdir -p ${TOOLSDIR}/html - cp ${QADIR}/tools/sign*.html ${TOOLSDIR}/html - - cd ${TOOLSDIR} -} - -############################## tools_p12 ############################### -# local shell function to test basic functionality of pk12util -######################################################################## -tools_p12() -{ - echo "$SCRIPTNAME: Exporting Alice's email cert & key------------------" - echo "pk12util -o Alice.p12 -n \"Alice\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\" - echo " -w ${R_PWFILE}" - pk12util -o Alice.p12 -n "Alice" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \ - -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Exporting Alice's email cert & key (pk12util -o)" - check_tmpfile - - echo "$SCRIPTNAME: Importing Alice's email cert & key -----------------" - echo "pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" - pk12util -i Alice.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Importing Alice's email cert & key (pk12util -i)" - check_tmpfile - - echo "$SCRIPTNAME: Exporting Alice's email EC cert & key---------------" - echo "pk12util -o Alice-ec.p12 -n \"Alice-ec\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\" - echo " -w ${R_PWFILE}" - pk12util -o Alice-ec.p12 -n "Alice-ec" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \ - -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Exporting Alice's email EC cert & key (pk12util -o)" - check_tmpfile - - echo "$SCRIPTNAME: Importing Alice's email EC cert & key --------------" - echo "pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" - pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 - ret=$? - html_msg $ret 0 "Importing Alice's email EC cert & key (pk12util -i)" - check_tmpfile - -} - -############################## tools_sign ############################## -# local shell function pk12util uses a hardcoded tmp file, if this exists -# and is owned by another user we don't get reasonable errormessages -######################################################################## -check_tmpfile() -{ - if [ $ret != "0" -a -f /tmp/Pk12uTemp ] ; then - echo "Error: pk12util temp file exists. Please remove this file and" - echo " rerun the test (/tmp/Pk12uTemp) " - fi -} - -############################## tools_sign ############################## -# local shell function to test basic functionality of signtool -######################################################################## -tools_sign() -{ - echo "$SCRIPTNAME: Create objsign cert -------------------------------" - echo "signtool -G \"objectsigner\" -d ${P_R_ALICEDIR} -p \"nss\"" - signtool -G "objsigner" -d ${P_R_ALICEDIR} -p "nss" 2>&1 <<SIGNSCRIPT -y -TEST -MOZ -NSS -NY -US -liz -liz@moz.org -SIGNSCRIPT - html_msg $? 0 "Create objsign cert (signtool -G)" - - echo "$SCRIPTNAME: Signing a set of files ----------------------------" - echo "signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p \"nss\" -k objsigner \\" - echo " ${R_TOOLSDIR}/html" - signtool -Z nojs.jar -d ${P_R_ALICEDIR} -p "nss" -k objsigner \ - ${R_TOOLSDIR}/html - html_msg $? 0 "Signing a set of files (signtool -Z)" - - echo "$SCRIPTNAME: Listing signed files in jar ----------------------" - echo "signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner" - signtool -v nojs.jar -d ${P_R_ALICEDIR} -p nss -k objsigner - html_msg $? 0 "Listing signed files in jar (signtool -v)" - - echo "$SCRIPTNAME: Show who signed jar ------------------------------" - echo "signtool -w nojs.jar -d ${P_R_ALICEDIR}" - signtool -w nojs.jar -d ${P_R_ALICEDIR} - html_msg $? 0 "Show who signed jar (signtool -w)" -} - -############################## tools_cleanup ########################### -# local shell function to finish this script (no exit since it might be -# sourced) -######################################################################## -tools_cleanup() -{ - html "</TABLE><BR>" - cd ${QADIR} - . common/cleanup.sh -} - -################## main ################################################# - -tools_init - -tools_p12 - -tools_sign -tools_cleanup - - diff --git a/security/nss/tests/tools/tools.sh b/security/nss/tests/tools/tools.sh index 73d817366..b32eed254 100644 --- a/security/nss/tests/tools/tools.sh +++ b/security/nss/tests/tools/tools.sh @@ -21,6 +21,7 @@ # the Initial Developer. All Rights Reserved. # # Contributor(s): +# Dr Vipul Gupta <vipul.gupta@sun.com>, 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 @@ -74,7 +75,12 @@ tools_init() . ./cert.sh fi SCRIPTNAME=tools.sh - html_head "Tools Tests" + + if [ -n "$NSS_ENABLE_ECC" ] ; then + html_head "Tools Tests with ECC" + else + html_head "Tools Tests" + fi grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || { Exit 15 "Fatal - S/MIME of cert.sh needs to pass first" @@ -87,7 +93,7 @@ tools_init() R_COPYDIR=../tools/copydir P_R_COPYDIR=${R_COPYDIR} if [ -n "${MULTIACCESS_DBM}" ]; then - P_R_COPYDIR="multiaccess:Tools.$version" + P_R_COPYDIR="multiaccess:Tools.$version" fi mkdir -p ${TOOLSDIR} @@ -125,6 +131,32 @@ tools_p12() ret=$? html_msg $ret 0 "Listing Alice's pk12 file (pk12util -l)" check_tmpfile + + if [ -n "$NSS_ENABLE_ECC" ] ; then + echo "$SCRIPTNAME: Exporting Alice's email EC cert & key---------------" + echo "pk12util -o Alice-ec.p12 -n \"Alice-ec\" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \\" + echo " -w ${R_PWFILE}" + pk12util -o Alice-ec.p12 -n "Alice-ec" -d ${P_R_ALICEDIR} -k ${R_PWFILE} \ + -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Exporting Alice's email EC cert & key (pk12util -o)" + check_tmpfile + + echo "$SCRIPTNAME: Importing Alice's email EC cert & key --------------" + echo "pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE}" + pk12util -i Alice-ec.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Importing Alice's email EC cert & key (pk12util -i)" + check_tmpfile + + echo "$SCRIPTNAME: Listing Alice's pk12 EC file -----------------" + echo "pk12util -l Alice-ec.p12 -w ${R_PWFILE}" + pk12util -l Alice-ec.p12 -w ${R_PWFILE} 2>&1 + ret=$? + html_msg $ret 0 "Listing Alice's pk12 EC file (pk12util -l)" + check_tmpfile + fi + } ############################## tools_sign ############################## |