forked from mirrors/gecko-dev
		
	Bug 527659, Update mozilla-central to NSS 3.12.6 (beta)
== NSS portion == r=rrelyea/wtc for upgrading mozilla-central to cvs tag NSS_3_12_6_BETA1 == This includes reapplying the (merged) patch from bug 519550 on top of NSS. == PSM portion == Includes the patch to disable TLS compression, r=kaie == Include the patch to disable zlib test programs, which don't work on maemo, r=kaie
This commit is contained in:
		
							parent
							
								
									fa3f6ebdd8
								
							
						
					
					
						commit
						d6c30005d8
					
				
					 227 changed files with 91953 additions and 34207 deletions
				
			
		|  | @ -41,6 +41,12 @@ | ||||||
| #// | #// | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
| 
 | 
 | ||||||
|  | !if "$(MOZ_BITS)" == "16" | ||||||
|  | !ifndef MOZ_DEBUG | ||||||
|  | OPTIMIZER=-Os -UDEBUG -DNDEBUG | ||||||
|  | !endif | ||||||
|  | !endif | ||||||
|  | 
 | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
| #// | #// | ||||||
| #// Specify the depth of the current directory relative to the | #// Specify the depth of the current directory relative to the | ||||||
|  |  | ||||||
|  | @ -46,7 +46,7 @@ LIBRARY_NAME	= mozdbm_s | ||||||
| LIB_IS_C_ONLY	= 1 | LIB_IS_C_ONLY	= 1 | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS_ARCH),WINNT) | ifeq ($(OS_ARCH),WINNT) | ||||||
| LIBRARY_NAME	= dbm32 | LIBRARY_NAME	= dbm$(MOZ_BITS) | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| CSRCS		= \
 | CSRCS		= \
 | ||||||
|  |  | ||||||
|  | @ -41,6 +41,12 @@ | ||||||
| #// | #// | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
| 
 | 
 | ||||||
|  | !if "$(MOZ_BITS)" == "16" | ||||||
|  | !ifndef MOZ_DEBUG | ||||||
|  | OPTIMIZER=-Os -UDEBUG -DNDEBUG | ||||||
|  | !endif | ||||||
|  | !endif | ||||||
|  | 
 | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
| #// | #// | ||||||
| #// Specify the depth of the current directory relative to the | #// Specify the depth of the current directory relative to the | ||||||
|  | @ -58,7 +64,7 @@ MAKE_OBJ_TYPE=EXE | ||||||
| #// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...) | #// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...) | ||||||
| #// | #// | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
| LIBNAME=dbm32 | LIBNAME=dbm$(MOZ_BITS) | ||||||
| PDBFILE=$(LIBNAME).pdb | PDBFILE=$(LIBNAME).pdb | ||||||
| 
 | 
 | ||||||
| #//------------------------------------------------------------------------ | #//------------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | @ -51,7 +51,7 @@ PROGRAM		= lots$(BIN_SUFFIX) | ||||||
| CSRCS		= lots.c | CSRCS		= lots.c | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS_ARCH),WINNT) | ifeq ($(OS_ARCH),WINNT) | ||||||
| EXTRA_DSO_LIBS	= dbm32 | EXTRA_DSO_LIBS	= dbm$(MOZ_BITS) | ||||||
| else | else | ||||||
| EXTRA_DSO_LIBS	= mozdbm_s | EXTRA_DSO_LIBS	= mozdbm_s | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | @ -71,9 +71,7 @@ OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -DBSD_OS -DBSDI -D | ||||||
| ARCH			= bsdos | ARCH			= bsdos | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS		= -fPIC -DPIC | DSO_CFLAGS		= -fPIC -DPIC | ||||||
| DSO_LDOPTS		= -shared | DSO_LDOPTS		= -shared -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) | ||||||
| DSO_LDFLAGS		= |  | ||||||
| DSO_LDOPTS		+= -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) |  | ||||||
| 
 | 
 | ||||||
| ifdef LIBRUNPATH | ifdef LIBRUNPATH | ||||||
| DSO_LDOPTS		+= -Wl,-R$(LIBRUNPATH) | DSO_LDOPTS		+= -Wl,-R$(LIBRUNPATH) | ||||||
|  |  | ||||||
|  | @ -77,5 +77,3 @@ ARCH			= beos | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS		= -fPIC | DSO_CFLAGS		= -fPIC | ||||||
| DSO_LDOPTS		= | DSO_LDOPTS		= | ||||||
| DSO_LDFLAGS		= |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -121,8 +121,10 @@ endif | ||||||
| ARCH		= darwin | ARCH		= darwin | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS	= -fPIC | DSO_CFLAGS	= -fPIC | ||||||
|  | # May override this with different compatibility and current version numbers.
 | ||||||
|  | DARWIN_DYLIB_VERSIONS = -compatibility_version 1 -current_version 1 | ||||||
| # May override this with -bundle to create a loadable module.
 | # 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 | DSO_LDOPTS	= -dynamiclib $(DARWIN_DYLIB_VERSIONS) -install_name @executable_path/$(notdir $@) -headerpad_max_install_names | ||||||
| 
 | 
 | ||||||
| MKSHLIB		= $(CC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS) | MKSHLIB		= $(CC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS) | ||||||
| DLL_SUFFIX	= dylib | DLL_SUFFIX	= dylib | ||||||
|  |  | ||||||
|  | @ -42,11 +42,16 @@ CC			= gcc | ||||||
| CCC			= g++ | CCC			= g++ | ||||||
| RANLIB			= ranlib | RANLIB			= ranlib | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS_TEST),alpha) | CPU_ARCH		= $(OS_TEST) | ||||||
| CPU_ARCH		= alpha | ifeq ($(CPU_ARCH),i386) | ||||||
| else |  | ||||||
| CPU_ARCH		= x86 | CPU_ARCH		= x86 | ||||||
| endif | endif | ||||||
|  | ifeq ($(CPU_ARCH),pc98) | ||||||
|  | CPU_ARCH		= x86 | ||||||
|  | endif | ||||||
|  | ifeq ($(CPU_ARCH),amd64) | ||||||
|  | CPU_ARCH		= x86_64 | ||||||
|  | endif | ||||||
| 
 | 
 | ||||||
| OS_CFLAGS		= $(DSO_CFLAGS) -ansi -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK | OS_CFLAGS		= $(DSO_CFLAGS) -ansi -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -91,7 +91,6 @@ ifndef USE_64 | ||||||
| RPATH			= | RPATH			= | ||||||
| endif | endif | ||||||
| endif | endif | ||||||
| DSO_LDFLAGS		= |  | ||||||
| 
 | 
 | ||||||
| # +Z generates position independent code for use in shared libraries.
 | # +Z generates position independent code for use in shared libraries.
 | ||||||
| DSO_CFLAGS = +Z | DSO_CFLAGS = +Z | ||||||
|  |  | ||||||
|  | @ -53,48 +53,41 @@ RANLIB			= ranlib | ||||||
| DEFAULT_COMPILER = gcc | DEFAULT_COMPILER = gcc | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS_TEST),ppc64) | ifeq ($(OS_TEST),ppc64) | ||||||
| 	OS_REL_CFLAGS	= -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH	= ppc | 	CPU_ARCH	= ppc | ||||||
| ifeq ($(USE_64),1) | ifeq ($(USE_64),1) | ||||||
| 	ARCHFLAG	= -m64 | 	ARCHFLAG	= -m64 | ||||||
| endif | endif | ||||||
| else | else | ||||||
| ifeq ($(OS_TEST),alpha) | ifeq ($(OS_TEST),alpha) | ||||||
|         OS_REL_CFLAGS   = -D_ALPHA_ -DLINUX1_2 -D_XOPEN_SOURCE |         OS_REL_CFLAGS   = -D_ALPHA_ | ||||||
| 	CPU_ARCH	= alpha | 	CPU_ARCH	= alpha | ||||||
| else | else | ||||||
| ifeq ($(OS_TEST),x86_64) | ifeq ($(OS_TEST),x86_64) | ||||||
| ifeq ($(USE_64),1) | ifeq ($(USE_64),1) | ||||||
| 	OS_REL_CFLAGS	= -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH	= x86_64 | 	CPU_ARCH	= x86_64 | ||||||
| else | else | ||||||
| 	OS_REL_CFLAGS	= -DLINUX1_2 -Di386 -D_XOPEN_SOURCE | 	OS_REL_CFLAGS	= -Di386 | ||||||
| 	CPU_ARCH	= x86 | 	CPU_ARCH	= x86 | ||||||
| 	ARCHFLAG	= -m32 | 	ARCHFLAG	= -m32 | ||||||
| endif | endif | ||||||
| else | else | ||||||
| ifeq ($(OS_TEST),sparc64) | ifeq ($(OS_TEST),sparc64) | ||||||
| 	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH        = sparc | 	CPU_ARCH        = sparc | ||||||
| else | else | ||||||
| ifeq (,$(filter-out arm% sa110,$(OS_TEST))) | ifeq (,$(filter-out arm% sa110,$(OS_TEST))) | ||||||
| 	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH        = arm | 	CPU_ARCH        = arm | ||||||
| else | else | ||||||
| ifeq (,$(filter-out parisc%,$(OS_TEST))) | ifeq (,$(filter-out parisc%,$(OS_TEST))) | ||||||
| 	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH        = hppa | 	CPU_ARCH        = hppa | ||||||
| else | else | ||||||
| ifeq (,$(filter-out i%86,$(OS_TEST))) | ifeq (,$(filter-out i%86,$(OS_TEST))) | ||||||
| 	OS_REL_CFLAGS	= -DLINUX1_2 -Di386 -D_XOPEN_SOURCE | 	OS_REL_CFLAGS	= -Di386 | ||||||
| 	CPU_ARCH	= x86 | 	CPU_ARCH	= x86 | ||||||
| else | else | ||||||
| ifeq ($(OS_TEST),sh4a) | ifeq ($(OS_TEST),sh4a) | ||||||
| 	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH        = sh4 | 	CPU_ARCH        = sh4 | ||||||
| else | else | ||||||
| # $(OS_TEST) == m68k, ppc, ia64, sparc, s390, s390x, mips, sh3, sh4
 | # $(OS_TEST) == m68k, ppc, ia64, sparc, s390, s390x, mips, sh3, sh4
 | ||||||
| 	OS_REL_CFLAGS   = -DLINUX1_2 -D_XOPEN_SOURCE |  | ||||||
| 	CPU_ARCH	= $(OS_TEST) | 	CPU_ARCH	= $(OS_TEST) | ||||||
| endif | endif | ||||||
| endif | endif | ||||||
|  | @ -134,7 +127,12 @@ ifeq ($(USE_PTHREADS),1) | ||||||
| OS_PTHREAD = -lpthread  | OS_PTHREAD = -lpthread  | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -ansi -Wall -Werror-implicit-function-declaration -Wno-switch -pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR | # See bug 537829, in particular comment 23.
 | ||||||
|  | # Place -ansi and *_SOURCE before $(DSO_CFLAGS) so DSO_CFLAGS can override
 | ||||||
|  | # -ansi on platforms like Android where the system headers are C99 and do
 | ||||||
|  | # not build with -ansi.
 | ||||||
|  | STANDARDS_CFLAGS	= -ansi -D_POSIX_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE | ||||||
|  | OS_CFLAGS		= $(STANDARDS_CFLAGS) $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -Werror-implicit-function-declaration -Wno-switch -pipe -DLINUX -Dlinux -DHAVE_STRERROR | ||||||
| OS_LIBS			= $(OS_PTHREAD) -ldl -lc | OS_LIBS			= $(OS_PTHREAD) -ldl -lc | ||||||
| 
 | 
 | ||||||
| ifdef USE_PTHREADS | ifdef USE_PTHREADS | ||||||
|  | @ -150,7 +148,6 @@ DSO_LDOPTS		= -shared $(ARCHFLAG) | ||||||
| # we don't use -z defs there.
 | # we don't use -z defs there.
 | ||||||
| ZDEFS_FLAG		= -Wl,-z,defs | ZDEFS_FLAG		= -Wl,-z,defs | ||||||
| DSO_LDOPTS		+= $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) | DSO_LDOPTS		+= $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) | ||||||
| DSO_LDFLAGS		= |  | ||||||
| LDFLAGS			+= $(ARCHFLAG) | LDFLAGS			+= $(ARCHFLAG) | ||||||
| 
 | 
 | ||||||
| # INCLUDES += -I/usr/include -Y/usr/include/linux
 | # INCLUDES += -I/usr/include -Y/usr/include/linux
 | ||||||
|  |  | ||||||
|  | @ -46,5 +46,8 @@ endif | ||||||
| PROCESS_MAP_FILE = grep -v ';-' $< | \
 | PROCESS_MAP_FILE = grep -v ';-' $< | \
 | ||||||
|         sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ |         sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ | ||||||
|          |          | ||||||
| NSS_NO_FORK_CHECK=1 | # Softoken 3.13 uses NO_FORK_CHECK only.
 | ||||||
|  | # Softoken 3.12 uses NO_FORK_CHECK and NO_CHECK_FORK.
 | ||||||
|  | # Don't use NO_CHECK_FORK in new code.
 | ||||||
|  | DEFINES += -DNO_FORK_CHECK -DNO_CHECK_FORK | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -66,7 +66,6 @@ ARCH			= netbsd | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS		= -fPIC -DPIC | DSO_CFLAGS		= -fPIC -DPIC | ||||||
| DSO_LDOPTS		= -shared | DSO_LDOPTS		= -shared | ||||||
| DSO_LDFLAGS		= |  | ||||||
| ifeq ($(OBJECT_FMT),ELF) | ifeq ($(OBJECT_FMT),ELF) | ||||||
| DSO_LDOPTS		+= -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) | DSO_LDOPTS		+= -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | @ -66,7 +66,6 @@ ARCH			= openbsd | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS		= -fPIC -DPIC | DSO_CFLAGS		= -fPIC -DPIC | ||||||
| DSO_LDOPTS		= -shared -fPIC -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) | DSO_LDOPTS		= -shared -fPIC -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) | ||||||
| DSO_LDFLAGS		= |  | ||||||
| 
 | 
 | ||||||
| MKSHLIB			= $(CC) $(DSO_LDOPTS) | MKSHLIB			= $(CC) $(DSO_LDOPTS) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -87,7 +87,6 @@ PROCESS_MAP_FILE = cp $< $@ | ||||||
| BUILD_UNIX_PLUGINS  = 1 | BUILD_UNIX_PLUGINS  = 1 | ||||||
| #DSO_LDOPTS         += -b elf -G -z defs
 | #DSO_LDOPTS         += -b elf -G -z defs
 | ||||||
| DSO_LDOPTS         += -G | DSO_LDOPTS         += -G | ||||||
| DSO_LDFLAGS        += -nostdlib -L/lib -L/usr/lib -lXm -lXt -lX11 -lgen |  | ||||||
| 
 | 
 | ||||||
| # Used for Java compiler
 | # Used for Java compiler
 | ||||||
| EXPORT_FLAGS += -W l,-Bexport | EXPORT_FLAGS += -W l,-Bexport | ||||||
|  |  | ||||||
|  | @ -69,4 +69,3 @@ ARCH			= QNX | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS		= -Wc,-fPIC | DSO_CFLAGS		= -Wc,-fPIC | ||||||
| DSO_LDOPTS		= -shared | DSO_LDOPTS		= -shared | ||||||
| DSO_LDFLAGS		= |  | ||||||
|  |  | ||||||
|  | @ -49,7 +49,6 @@ OS_TARGET  = RISCOS | ||||||
| 
 | 
 | ||||||
| DSO_CFLAGS  = -fPIC | DSO_CFLAGS  = -fPIC | ||||||
| DSO_LDOPTS  = -shared | DSO_LDOPTS  = -shared | ||||||
| DSO_LDFLAGS             = |  | ||||||
| 
 | 
 | ||||||
| ifdef BUILD_OPT | ifdef BUILD_OPT | ||||||
| 	OPTIMIZER = -O3 | 	OPTIMIZER = -O3 | ||||||
|  |  | ||||||
|  | @ -87,7 +87,6 @@ PROCESS_MAP_FILE = cp $< $@ | ||||||
| BUILD_UNIX_PLUGINS  = 1 | BUILD_UNIX_PLUGINS  = 1 | ||||||
| #DSO_LDOPTS         += -b elf -G -z defs
 | #DSO_LDOPTS         += -b elf -G -z defs
 | ||||||
| DSO_LDOPTS         += -b elf -G | DSO_LDOPTS         += -b elf -G | ||||||
| DSO_LDFLAGS        += -nostdlib -L/lib -L/usr/lib -lXm -lXt -lX11 -lgen |  | ||||||
| 
 | 
 | ||||||
| # Used for Java compiler
 | # Used for Java compiler
 | ||||||
| EXPORT_FLAGS += -W l,-Bexport | EXPORT_FLAGS += -W l,-Bexport | ||||||
|  |  | ||||||
|  | @ -194,11 +194,6 @@ ifdef NSS_DISABLE_DBM | ||||||
| DEFINES += -DNSS_DISABLE_DBM | DEFINES += -DNSS_DISABLE_DBM | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifdef NSS_NO_FORK_CHECK |  | ||||||
| DEFINES += -DNO_FORK_CHECK |  | ||||||
| DEFINES += -DNO_CHECK_FORK |  | ||||||
| endif |  | ||||||
| 
 |  | ||||||
| # Avoid building object leak test code for optimized library
 | # Avoid building object leak test code for optimized library
 | ||||||
| ifndef BUILD_OPT | ifndef BUILD_OPT | ||||||
| ifdef PKIX_OBJECT_LEAK_TEST | ifdef PKIX_OBJECT_LEAK_TEST | ||||||
|  |  | ||||||
|  | @ -42,4 +42,3 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #error "Do not include this header file." | #error "Do not include this header file." | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -410,7 +410,8 @@ PWD := $(shell pwd) | ||||||
| endif | endif | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| core_abspath = $(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1))) | # The quotes allow absolute paths to contain spaces.
 | ||||||
|  | core_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))" | ||||||
| 
 | 
 | ||||||
| $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c | $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c | ||||||
| 	@$(MAKE_OBJDIR) | 	@$(MAKE_OBJDIR) | ||||||
|  |  | ||||||
|  | @ -243,6 +243,13 @@ ifeq ($(OS_ARCH),Linux) | ||||||
| DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=1 | DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=1 | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | # Turn off TLS compression support because NSS 3.12.5 Beta can't be built
 | ||||||
|  | # with Mozilla's zlib.h.  See bug 527659 comment 10.
 | ||||||
|  | DEFAULT_GMAKE_FLAGS += USE_SYSTEM_ZLIB= | ||||||
|  | 
 | ||||||
|  | # Disable building of the test programs in security/nss/lib/zlib
 | ||||||
|  | DEFAULT_GMAKE_FLAGS += PROGRAMS= | ||||||
|  | 
 | ||||||
| ifdef CROSS_COMPILE | ifdef CROSS_COMPILE | ||||||
| 
 | 
 | ||||||
| ifdef WINCE | ifdef WINCE | ||||||
|  |  | ||||||
|  | @ -46,10 +46,6 @@ ifdef BUILD_LIBPKIX_TESTS | ||||||
| DIRS += libpkix | DIRS += libpkix | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifndef USE_SYSTEM_ZLIB |  | ||||||
| ZLIB_SRCDIR = zlib  # Add the zlib directory to DIRS. |  | ||||||
| endif |  | ||||||
| 
 |  | ||||||
| INCLUDES += \
 | INCLUDES += \
 | ||||||
| 	-I$(DIST)/../public/security \
 | 	-I$(DIST)/../public/security \
 | ||||||
| 	-I./include \
 | 	-I./include \
 | ||||||
|  |  | ||||||
|  | @ -257,6 +257,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, | ||||||
|      |      | ||||||
|     /* Generate certificate request */ |     /* Generate certificate request */ | ||||||
|     cr = CERT_CreateCertificateRequest(subject, spki, NULL); |     cr = CERT_CreateCertificateRequest(subject, spki, NULL); | ||||||
|  |     SECKEY_DestroySubjectPublicKeyInfo(spki); | ||||||
|     if (!cr) { |     if (!cr) { | ||||||
| 	SECU_PrintError(progName, "unable to make certificate request"); | 	SECU_PrintError(progName, "unable to make certificate request"); | ||||||
| 	return SECFailure; | 	return SECFailure; | ||||||
|  |  | ||||||
|  | @ -56,47 +56,6 @@ | ||||||
| #include "crlgen.h" | #include "crlgen.h" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* these reroutines were taken from secitem.c, which is supposed to
 |  | ||||||
|  * replace this file some day */ |  | ||||||
| /*
 |  | ||||||
|  * This is the hash function.  We simply XOR the encoded form with |  | ||||||
|  * itself in sizeof(PLHashNumber)-byte chunks.  Improving this |  | ||||||
|  * routine is left as an excercise for the more mathematically |  | ||||||
|  * inclined student. |  | ||||||
|  */ |  | ||||||
| PLHashNumber PR_CALLBACK |  | ||||||
| SECITEM_Hash ( const void *key) |  | ||||||
| { |  | ||||||
|     const SECItem *item = (const SECItem *)key; |  | ||||||
|     PLHashNumber rv = 0; |  | ||||||
| 
 |  | ||||||
|     PRUint8 *data = (PRUint8 *)item->data; |  | ||||||
|     PRUint32 i; |  | ||||||
|     PRUint8 *rvc = (PRUint8 *)&rv; |  | ||||||
| 
 |  | ||||||
|     for( i = 0; i < item->len; i++ ) { |  | ||||||
|         rvc[ i % sizeof(rv) ] ^= *data; |  | ||||||
|         data++; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return rv; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * This is the key-compare function.  It simply does a lexical |  | ||||||
|  * comparison on the item data.  This does not result in |  | ||||||
|  * quite the same ordering as the "sequence of numbers" order, |  | ||||||
|  * but heck it's only used internally by the hash table anyway. |  | ||||||
|  */ |  | ||||||
| PRIntn PR_CALLBACK |  | ||||||
| SECITEM_HashCompare ( const void *k1, const void *k2) |  | ||||||
| { |  | ||||||
|     const SECItem *i1 = (const SECItem *)k1; |  | ||||||
|     const SECItem *i2 = (const SECItem *)k2; |  | ||||||
| 
 |  | ||||||
|     return SECITEM_ItemsAreEqual(i1,i2); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Destroys extHandle and data. data was create on heap.
 | /* Destroys extHandle and data. data was create on heap.
 | ||||||
|  * extHandle creaded by CERT_StartCRLEntryExtensions. entry |  * extHandle creaded by CERT_StartCRLEntryExtensions. entry | ||||||
|  * was allocated on arena.*/ |  * was allocated on arena.*/ | ||||||
|  |  | ||||||
|  | @ -390,3 +390,15 @@ ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109), | ||||||
| 
 | 
 | ||||||
| ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110), | ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110), | ||||||
| "SSL received a malformed New Session Ticket handshake message.") | "SSL received a malformed New Session Ticket handshake message.") | ||||||
|  | 
 | ||||||
|  | ER3(SSL_ERROR_DECOMPRESSION_FAILURE,           (SSL_ERROR_BASE + 111), | ||||||
|  | "SSL received a compressed record that could not be decompressed.") | ||||||
|  | 
 | ||||||
|  | ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED,       (SSL_ERROR_BASE + 112), | ||||||
|  | "Renegotiation is not allowed on this SSL socket.") | ||||||
|  | 
 | ||||||
|  | ER3(SSL_ERROR_UNSAFE_NEGOTIATION,              (SSL_ERROR_BASE + 113), | ||||||
|  | "Peer attempted old style (potentially vulnerable) handshake.") | ||||||
|  | 
 | ||||||
|  | ER3(SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD, (SSL_ERROR_BASE + 114), | ||||||
|  | "SSL received an unexpected uncompressed record.") | ||||||
|  |  | ||||||
|  | @ -41,7 +41,6 @@ DEPTH	= ../.. | ||||||
| REQUIRES = nss nspr libdbm | REQUIRES = nss nspr libdbm | ||||||
| 
 | 
 | ||||||
| DIRS = lib  \ | DIRS = lib  \ | ||||||
|  $(ZLIB_SRCDIR) \ |  | ||||||
|  addbuiltin \ |  addbuiltin \ | ||||||
|  atob  \ |  atob  \ | ||||||
|  bltest \ |  bltest \ | ||||||
|  | @ -56,6 +55,7 @@ DIRS = lib  \ | ||||||
|  digest  \ |  digest  \ | ||||||
|  fipstest  \ |  fipstest  \ | ||||||
|  makepqg  \ |  makepqg  \ | ||||||
|  |  multinit \ | ||||||
|  ocspclnt  \ |  ocspclnt  \ | ||||||
|  oidcalc  \ |  oidcalc  \ | ||||||
|  p7content  \ |  p7content  \ | ||||||
|  |  | ||||||
							
								
								
									
										79
									
								
								security/nss/cmd/multinit/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								security/nss/cmd/multinit/Makefile
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | ||||||
|  | #! 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 Original Code is the Netscape security libraries.
 | ||||||
|  | #
 | ||||||
|  | # The Initial Developer of the Original Code is
 | ||||||
|  | # Netscape Communications Corporation.
 | ||||||
|  | # Portions created by the Initial Developer are Copyright (C) 1994-2000
 | ||||||
|  | # the Initial Developer. All Rights Reserved.
 | ||||||
|  | #
 | ||||||
|  | # Contributor(s):
 | ||||||
|  | #
 | ||||||
|  | # Alternatively, the contents of this file may be used under the terms of
 | ||||||
|  | # either the GNU General Public License Version 2 or later (the "GPL"), or
 | ||||||
|  | # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 | ||||||
|  | # in which case the provisions of the GPL or the LGPL are applicable instead
 | ||||||
|  | # of those above. If you wish to allow use of your version of this file only
 | ||||||
|  | # under the terms of either the GPL or the LGPL, and not to allow others to
 | ||||||
|  | # use your version of this file under the terms of the MPL, indicate your
 | ||||||
|  | # decision by deleting the provisions above and replace them with the notice
 | ||||||
|  | # and other provisions required by the GPL or the LGPL. If you do not delete
 | ||||||
|  | # the provisions above, a recipient may use your version of this file under
 | ||||||
|  | # the terms of any one of the MPL, the GPL or the LGPL.
 | ||||||
|  | #
 | ||||||
|  | # ***** END LICENSE BLOCK *****
 | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (1) Include initial platform-independent assignments (MANDATORY).   #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | include manifest.mn | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (2) Include "global" configuration information. (OPTIONAL)          #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | include $(CORE_DEPTH)/coreconf/config.mk | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (3) Include "component" configuration information. (OPTIONAL)       #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (4) Include "local" platform-dependent assignments (OPTIONAL).      #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | include ../platlibs.mk | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (5) Execute "global" rules. (OPTIONAL)                              #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | include $(CORE_DEPTH)/coreconf/rules.mk | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (6) Execute "component" rules. (OPTIONAL)                           #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #######################################################################
 | ||||||
|  | # (7) Execute "local" rules. (OPTIONAL).                              #
 | ||||||
|  | #######################################################################
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | include ../platrules.mk | ||||||
|  | 
 | ||||||
							
								
								
									
										45
									
								
								security/nss/cmd/multinit/manifest.mn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								security/nss/cmd/multinit/manifest.mn
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | ||||||
|  | # | ||||||
|  | # ***** 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 | ||||||
|  | # Red Hat, Inc. | ||||||
|  | # Portions created by the Initial Developer are Copyright (C) 2009 | ||||||
|  | # 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 public and private header  directories are implicitly REQUIRED. | ||||||
|  | MODULE = nss  | ||||||
|  | 
 | ||||||
|  | CSRCS = multinit.c | ||||||
|  | 
 | ||||||
|  | PROGRAM	= multinit | ||||||
							
								
								
									
										940
									
								
								security/nss/cmd/multinit/multinit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										940
									
								
								security/nss/cmd/multinit/multinit.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,940 @@ | ||||||
|  | /* ***** 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 | ||||||
|  |  * Red Hat, Inc. | ||||||
|  |  * Portions created by the Initial Developer are Copyright (C) 2009 | ||||||
|  |  * 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 <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include "nss.h" | ||||||
|  | #include "secutil.h" | ||||||
|  | #include "pk11pub.h" | ||||||
|  | #include "cert.h" | ||||||
|  | 
 | ||||||
|  | typedef struct commandDescriptStr { | ||||||
|  |     int required; | ||||||
|  |     char *arg; | ||||||
|  |     char *des; | ||||||
|  | } commandDescript; | ||||||
|  | 
 | ||||||
|  | enum optionNames { | ||||||
|  |     opt_liborder = 0,  | ||||||
|  |     opt_mainDB,  | ||||||
|  |     opt_lib1DB, | ||||||
|  |     opt_lib2DB, | ||||||
|  |     opt_mainRO, | ||||||
|  |     opt_lib1RO, | ||||||
|  |     opt_lib2RO, | ||||||
|  |     opt_mainCMD, | ||||||
|  |     opt_lib1CMD, | ||||||
|  |     opt_lib2CMD, | ||||||
|  |     opt_mainTokNam, | ||||||
|  |     opt_lib1TokNam, | ||||||
|  |     opt_lib2TokNam, | ||||||
|  |     opt_oldStyle, | ||||||
|  |     opt_verbose, | ||||||
|  |     opt_summary, | ||||||
|  |     opt_help, | ||||||
|  |     opt_last | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static const | ||||||
|  | secuCommandFlag options_init[] = | ||||||
|  | { | ||||||
|  |    { /* opt_liborder */  'o', PR_TRUE, "1M2zmi", PR_TRUE,  "order" }, | ||||||
|  |    { /* opt_mainDB */    'd', PR_TRUE,     0,    PR_FALSE, "main_db" }, | ||||||
|  |    { /* opt_lib1DB */    '1', PR_TRUE,     0,    PR_FALSE, "lib1_db" }, | ||||||
|  |    { /* opt_lib2DB */    '2', PR_TRUE,     0,    PR_FALSE, "lib2_db" }, | ||||||
|  |    { /* opt_mainRO */    'r', PR_FALSE,    0,    PR_FALSE, "main_readonly" }, | ||||||
|  |    { /* opt_lib1RO */     0,  PR_FALSE,    0,    PR_FALSE, "lib1_readonly" }, | ||||||
|  |    { /* opt_lib2RO */     0,  PR_FALSE,    0,    PR_FALSE, "lib2_readonly" }, | ||||||
|  |    { /* opt_mainCMD */   'c', PR_TRUE,     0,    PR_FALSE, "main_command" }, | ||||||
|  |    { /* opt_lib1CMD */    0,  PR_TRUE,     0,    PR_FALSE, "lib1_command" }, | ||||||
|  |    { /* opt_lib2CMD */    0,  PR_TRUE,     0,    PR_FALSE, "lib2_command" }, | ||||||
|  |    { /* opt_mainTokNam */'t', PR_TRUE,     0,    PR_FALSE, "main_token_name" }, | ||||||
|  |    { /* opt_lib1TokNam */ 0,  PR_TRUE,     0,    PR_FALSE, "lib1_token_name" }, | ||||||
|  |    { /* opt_lib2TokNam */ 0,  PR_TRUE,     0,    PR_FALSE, "lib2_token_name" }, | ||||||
|  |    { /* opt_oldStype */  's', PR_FALSE,    0,    PR_FALSE, "oldStype" }, | ||||||
|  |    { /* opt_verbose */   'v', PR_FALSE,    0,    PR_FALSE, "verbose" }, | ||||||
|  |    { /* opt_summary */   'z', PR_FALSE,    0,    PR_FALSE, "summary" }, | ||||||
|  |    { /* opt_help */      'h', PR_FALSE,    0,    PR_FALSE, "help" } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const | ||||||
|  | commandDescript options_des[] = | ||||||
|  | { | ||||||
|  |    { /* opt_liborder */  PR_FALSE, "initOrder",  | ||||||
|  | 	" Specifies the order of NSS initialization and shutdown. Order is\n" | ||||||
|  | 	" given as a string where each character represents either an init or\n" | ||||||
|  | 	" a shutdown of the main program or one of the 2 test libraries\n" | ||||||
|  | 	" (library 1 and library 2). The valid characters are as follows:\n" | ||||||
|  | 	"   M Init the main program\n   1 Init library 1\n" | ||||||
|  | 	"   2 Init library 2\n" | ||||||
|  | 	"   m Shutdown the main program\n   i Shutdown library 1\n" | ||||||
|  | 	"   z Shutdown library 2\n" }, | ||||||
|  |    { /* opt_mainDB */   PR_TRUE, "nss_db", | ||||||
|  | 	" Specified the directory to open the nss database for the main\n"  | ||||||
|  | 	" program. Must be specified if \"M\" is given in the order string\n"}, | ||||||
|  |    { /* opt_lib1DB */   PR_FALSE, "nss_db", | ||||||
|  | 	" Specified the directory to open the nss database for library 1.\n"  | ||||||
|  | 	" Must be specified if \"1\" is given in the order string\n"}, | ||||||
|  |    { /* opt_lib2DB */   PR_FALSE, "nss_db", | ||||||
|  | 	" Specified the directory to open the nss database for library 2.\n"  | ||||||
|  | 	" Must be specified if \"2\" is given in the order string\n"}, | ||||||
|  |    { /* opt_mainRO */   PR_FALSE,    NULL, | ||||||
|  | 	" Open the main program's database read only.\n" }, | ||||||
|  |    { /* opt_lib1RO */   PR_FALSE,    NULL, | ||||||
|  | 	" Open library 1's database read only.\n" }, | ||||||
|  |    { /* opt_lib2RO */   PR_FALSE,    NULL, | ||||||
|  | 	" Open library 2's database read only.\n" }, | ||||||
|  |    { /* opt_mainCMD */  PR_FALSE,  "nss_command", | ||||||
|  | 	" Specifies the NSS command to execute in the main program.\n" | ||||||
|  | 	" Valid commands are: \n" | ||||||
|  | 	"   key_slot, list_slots, list_certs, add_cert, none.\n" | ||||||
|  | 	" Default is \"none\".\n" }, | ||||||
|  |    { /* opt_lib1CMD */  PR_FALSE,  "nss_command", | ||||||
|  | 	" Specifies the NSS command to execute in library 1.\n" }, | ||||||
|  |    { /* opt_lib2CMD */  PR_FALSE,  "nss_command", | ||||||
|  | 	" Specifies the NSS command to execute in library 2.\n" }, | ||||||
|  |    { /* opt_mainTokNam */PR_FALSE,  "token_name", | ||||||
|  | 	" Specifies the name of PKCS11 token for the main program's " | ||||||
|  | 	"database.\n" }, | ||||||
|  |    { /* opt_lib1TokNam */PR_FALSE,  "token_name", | ||||||
|  | 	" Specifies the name of PKCS11 token for library 1's database.\n" }, | ||||||
|  |    { /* opt_lib2TokNam */PR_FALSE,  "token_name", | ||||||
|  | 	" Specifies the name of PKCS11 token for library 2's database.\n" }, | ||||||
|  |    { /* opt_oldStype */ PR_FALSE,   NULL, | ||||||
|  | 	" Use NSS_Shutdown rather than NSS_ShutdownContext in the main\n" | ||||||
|  | 	" program.\n" }, | ||||||
|  |    { /* opt_verbose */  PR_FALSE,   NULL, | ||||||
|  | 	" Noisily output status to standard error\n" }, | ||||||
|  |    { /* opt_summarize */ PR_FALSE,  NULL,  | ||||||
|  | 	"report a summary of the test results\n" }, | ||||||
|  |    { /* opt_help */ PR_FALSE,   NULL, " give this message\n" } | ||||||
|  | };  | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * output our short help (table driven). (does not exit). | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | short_help(const char *prog) | ||||||
|  | { | ||||||
|  |     int count = opt_last; | ||||||
|  |     int i,words_found; | ||||||
|  | 
 | ||||||
|  |     /* make sure all the tables are up to date before we allow compiles to
 | ||||||
|  |      * succeed */ | ||||||
|  |     PR_STATIC_ASSERT(sizeof(options_init)/sizeof(secuCommandFlag) == opt_last); | ||||||
|  |     PR_STATIC_ASSERT(sizeof(options_init)/sizeof(secuCommandFlag) ==  | ||||||
|  | 		     sizeof(options_des)/sizeof(commandDescript)); | ||||||
|  | 
 | ||||||
|  |     /* print the base usage */ | ||||||
|  |     fprintf(stderr,"usage: %s ",prog); | ||||||
|  |     for (i=0, words_found=0; i < count; i++) { | ||||||
|  | 	if (!options_des[i].required) { | ||||||
|  | 	    fprintf(stderr,"["); | ||||||
|  | 	} | ||||||
|  | 	if (options_init[i].longform) { | ||||||
|  | 	    fprintf(stderr, "--%s", options_init[i].longform); | ||||||
|  | 	    words_found++; | ||||||
|  | 	} else { | ||||||
|  | 	    fprintf(stderr, "-%c", options_init[i].flag); | ||||||
|  | 	} | ||||||
|  | 	if (options_init[i].needsArg) { | ||||||
|  | 	    if (options_des[i].arg) { | ||||||
|  | 		fprintf(stderr," %s",options_des[i].arg); | ||||||
|  | 	    } else { | ||||||
|  | 		fprintf(stderr," arg"); | ||||||
|  | 	    } | ||||||
|  | 	    words_found++; | ||||||
|  | 	} | ||||||
|  | 	if (!options_des[i].required) { | ||||||
|  | 	    fprintf(stderr,"]"); | ||||||
|  | 	} | ||||||
|  | 	if (i < count-1 ) { | ||||||
|  | 	    if (words_found >= 5) { | ||||||
|  |  		fprintf(stderr,"\n      "); | ||||||
|  | 		words_found=0; | ||||||
|  | 	    } else { | ||||||
|  | 		fprintf(stderr," "); | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     fprintf(stderr,"\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * print out long help. like short_help, this does not exit | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | long_help(const char *prog) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     int count = opt_last; | ||||||
|  | 
 | ||||||
|  |     short_help(prog); | ||||||
|  |     /* print the option descriptions */ | ||||||
|  |     fprintf(stderr,"\n"); | ||||||
|  |     for (i=0; i < count; i++) { | ||||||
|  | 	fprintf(stderr,"        "); | ||||||
|  | 	if (options_init[i].flag) { | ||||||
|  | 	    fprintf(stderr, "-%c", options_init[i].flag); | ||||||
|  | 	    if (options_init[i].longform) { | ||||||
|  | 		fprintf(stderr,","); | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 	if (options_init[i].longform) { | ||||||
|  | 	    fprintf(stderr,"--%s", options_init[i].longform); | ||||||
|  | 	} | ||||||
|  | 	if (options_init[i].needsArg) { | ||||||
|  | 	    if (options_des[i].arg) { | ||||||
|  | 		fprintf(stderr," %s",options_des[i].arg); | ||||||
|  | 	    } else { | ||||||
|  | 		fprintf(stderr," arg"); | ||||||
|  | 	    } | ||||||
|  | 	    if (options_init[i].arg) { | ||||||
|  | 		fprintf(stderr," (default = \"%s\")",options_init[i].arg); | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 	fprintf(stderr,"\n%s",options_des[i].des); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * record summary data | ||||||
|  |  */ | ||||||
|  | struct bufferData { | ||||||
|  |    char * data;		/* lowest address of the buffer */ | ||||||
|  |    char * next;		/* pointer to the next element on the buffer */ | ||||||
|  |    int  len;		/* length of the buffer */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* our actual buffer. If data is NULL, then all append ops 
 | ||||||
|  |  * except are noops */ | ||||||
|  | static struct bufferData buffer= { NULL, NULL, 0 }; | ||||||
|  | 
 | ||||||
|  | #define CHUNK_SIZE 1000 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * get our initial data. and set the buffer variables up. on failure, | ||||||
|  |  * just don't initialize the buffer. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | initBuffer(void) | ||||||
|  | { | ||||||
|  |    buffer.data = PORT_Alloc(CHUNK_SIZE); | ||||||
|  |    if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  |    buffer.next = buffer.data; | ||||||
|  |    buffer.len = CHUNK_SIZE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * grow the buffer. If we can't get more data, record a 'D' in the second | ||||||
|  |  * to last record and allow the rest of the data to overwrite the last | ||||||
|  |  * element. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | growBuffer(void) | ||||||
|  | { | ||||||
|  |    char *new = PORT_Realloc(buffer.data, buffer.len + CHUNK_SIZE); | ||||||
|  |    if (!new) { | ||||||
|  | 	buffer.data[buffer.len-2] = 'D'; /* signal malloc failure in summary */ | ||||||
|  | 	/* buffer must always point to good memory if it exists */ | ||||||
|  | 	buffer.next = buffer.data + (buffer.len -1); | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  |    buffer.next = new + (buffer.next-buffer.data); | ||||||
|  |    buffer.data = new; | ||||||
|  |    buffer.len += CHUNK_SIZE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a label, doubles as appending a single character. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendLabel(char label) | ||||||
|  | { | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *buffer.next++ = label; | ||||||
|  |     if (buffer.data+buffer.len >= buffer.next) { | ||||||
|  | 	growBuffer(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a string onto the buffer. The result will be <string> | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendString(char *string) | ||||||
|  | { | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     appendLabel('<'); | ||||||
|  |     while (*string) { | ||||||
|  | 	appendLabel(*string++); | ||||||
|  |     } | ||||||
|  |     appendLabel('>'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a bool, T= true, F=false | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendBool(PRBool bool) | ||||||
|  | { | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (bool) { | ||||||
|  | 	appendLabel('t'); | ||||||
|  |     } else { | ||||||
|  | 	appendLabel('f'); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a single hex nibble. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendHex(unsigned char nibble) | ||||||
|  | { | ||||||
|  |     if (nibble <= 9) { | ||||||
|  | 	appendLabel('0'+nibble); | ||||||
|  |     } else { | ||||||
|  | 	appendLabel('a'+nibble-10); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a secitem as colon separated hex bytes. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendItem(SECItem *item) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     appendLabel(':'); | ||||||
|  |     for (i=0; i < item->len; i++) { | ||||||
|  | 	unsigned char byte=item->data[i]; | ||||||
|  | 	appendHex(byte >> 4); | ||||||
|  | 	appendHex(byte & 0xf); | ||||||
|  | 	appendLabel(':'); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * append a 32 bit integer (even on a 64 bit platform). | ||||||
|  |  * for simplicity append it as a hex value, full extension with 0x prefix. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | appendInt(unsigned int value) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     appendLabel('0'); | ||||||
|  |     appendLabel('x'); | ||||||
|  |     value = value & 0xffffffff; /* only look at the buttom 8 bytes */ | ||||||
|  |     for (i=0; i < 8; i++) { | ||||||
|  | 	appendHex(value >> 28 ); | ||||||
|  | 	value = value << 4; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* append a trust flag */ | ||||||
|  | static void | ||||||
|  | appendFlags(unsigned int flag) | ||||||
|  | { | ||||||
|  |   char trust[10]; | ||||||
|  |   char *cp=trust; | ||||||
|  | 
 | ||||||
|  |   trust[0] = 0; | ||||||
|  |   printflags(trust, flag); | ||||||
|  |   while (*cp) { | ||||||
|  |     appendLabel(*cp++); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * dump our buffer out with a result= flag so we can find it easily. | ||||||
|  |  * free the buffer as a side effect. | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | dumpBuffer(void) | ||||||
|  | { | ||||||
|  |     if (!buffer.data) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     appendLabel(0); /* terminate */ | ||||||
|  |     printf("\nresult=%s\n",buffer.data); | ||||||
|  |     PORT_Free(buffer.data); | ||||||
|  |     buffer.data = buffer.next = NULL; | ||||||
|  |     buffer.len = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * usage, like traditional usage, automatically exit | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | usage(const char *prog) | ||||||
|  | { | ||||||
|  |     short_help(prog); | ||||||
|  |     dumpBuffer(); | ||||||
|  |     exit(1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * like usage, except prints the long version of help | ||||||
|  |  */ | ||||||
|  | static void | ||||||
|  | usage_long(const char *prog) | ||||||
|  | { | ||||||
|  |     long_help(prog); | ||||||
|  |     dumpBuffer(); | ||||||
|  |     exit(1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char * | ||||||
|  | bool2String(PRBool bool)  | ||||||
|  | {  | ||||||
|  |     return bool ? "true" : "false"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * print out interesting info about the given slot | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | print_slot(PK11SlotInfo *slot, int log) | ||||||
|  | { | ||||||
|  |     if (log) { | ||||||
|  | 	fprintf(stderr, "* Name=%s Token_Name=%s present=%s, ro=%s *\n", | ||||||
|  | 		PK11_GetSlotName(slot), PK11_GetTokenName(slot), | ||||||
|  | 		bool2String(PK11_IsPresent(slot)),  | ||||||
|  | 		bool2String(PK11_IsReadOnly(slot))); | ||||||
|  |     } | ||||||
|  |     appendLabel('S'); | ||||||
|  |     appendString(PK11_GetTokenName(slot)); | ||||||
|  |     appendBool(PK11_IsPresent(slot)); | ||||||
|  |     appendBool(PK11_IsReadOnly(slot)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * list all our slots | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | do_list_slots(const char *progName, int log) | ||||||
|  | { | ||||||
|  |    PK11SlotList *list; | ||||||
|  |    PK11SlotListElement *le; | ||||||
|  | 
 | ||||||
|  |    list= PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL); | ||||||
|  |    if (list == NULL) { | ||||||
|  | 	fprintf(stderr,"ERROR: no tokens found %s\n",  | ||||||
|  | 		SECU_Strerror(PORT_GetError())); | ||||||
|  | 	appendLabel('S'); | ||||||
|  | 	appendString("none"); | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    for (le= PK11_GetFirstSafe(list); le;  | ||||||
|  | 				le = PK11_GetNextSafe(list,le,PR_TRUE)) { | ||||||
|  | 	print_slot(le->slot, log); | ||||||
|  |    } | ||||||
|  |    PK11_FreeSlotList(list); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static PRBool | ||||||
|  | sort_CN(CERTCertificate *certa, CERTCertificate *certb, void *arg) | ||||||
|  | { | ||||||
|  |     char *commonNameA, *commonNameB; | ||||||
|  |     int ret; | ||||||
|  | 
 | ||||||
|  |     commonNameA = CERT_GetCommonName(&certa->subject); | ||||||
|  |     commonNameB = CERT_GetCommonName(&certb->subject); | ||||||
|  | 
 | ||||||
|  |     if (commonNameA == NULL) { | ||||||
|  | 	PORT_Free(commonNameB); | ||||||
|  | 	return PR_TRUE; | ||||||
|  |     } | ||||||
|  |     if (commonNameB == NULL) { | ||||||
|  | 	PORT_Free(commonNameA); | ||||||
|  | 	return PR_FALSE; | ||||||
|  |     } | ||||||
|  |     ret = PORT_Strcmp(commonNameA,commonNameB); | ||||||
|  |     PORT_Free(commonNameA); | ||||||
|  |     PORT_Free(commonNameB); | ||||||
|  |     return (ret < 0) ? PR_TRUE: PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * list all the certs | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | do_list_certs(const char *progName, int log) | ||||||
|  | { | ||||||
|  |    CERTCertList *list; | ||||||
|  |    CERTCertList *sorted; | ||||||
|  |    CERTCertListNode *node; | ||||||
|  |    int i; | ||||||
|  | 
 | ||||||
|  |    list = PK11_ListCerts(PK11CertListUnique, NULL); | ||||||
|  |    if (list == NULL) { | ||||||
|  | 	fprintf(stderr,"ERROR: no certs found %s\n",  | ||||||
|  | 		SECU_Strerror(PORT_GetError())); | ||||||
|  | 	appendLabel('C'); | ||||||
|  | 	appendString("none"); | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    sorted = CERT_NewCertList(); | ||||||
|  |    if (sorted == NULL) { | ||||||
|  | 	fprintf(stderr,"ERROR: no certs found %s\n",  | ||||||
|  | 		SECU_Strerror(PORT_GetError())); | ||||||
|  | 	appendLabel('C'); | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendInt(PORT_GetError()); | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /* sort the list */ | ||||||
|  |    for (node = CERT_LIST_HEAD(list); !CERT_LIST_END(node,list);  | ||||||
|  | 				node = CERT_LIST_NEXT(node)) { | ||||||
|  | 	CERT_AddCertToListSorted(sorted, node->cert, sort_CN, NULL); | ||||||
|  |    } | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |    for (node = CERT_LIST_HEAD(sorted); !CERT_LIST_END(node,sorted);  | ||||||
|  | 				node = CERT_LIST_NEXT(node)) { | ||||||
|  | 	CERTCertificate *cert = node->cert; | ||||||
|  | 	char *commonName; | ||||||
|  | 
 | ||||||
|  | 	SECU_PrintCertNickname(node, stderr); | ||||||
|  | 	if (log) { | ||||||
|  | 	    fprintf(stderr, "*	Slot=%s*\n", cert->slot ? | ||||||
|  | 		 PK11_GetTokenName(cert->slot) : "none"); | ||||||
|  | 	    fprintf(stderr, "*	Nickname=%s*\n", cert->nickname); | ||||||
|  | 	    fprintf(stderr, "*	Subject=<%s>*\n", cert->subjectName); | ||||||
|  | 	    fprintf(stderr, "*	Issuer=<%s>*\n", cert->issuerName); | ||||||
|  | 	    fprintf(stderr, "*	SN="); | ||||||
|  | 	    for (i=0; i < cert->serialNumber.len; i++) { | ||||||
|  | 		if (i!=0) fprintf(stderr,":"); | ||||||
|  | 		fprintf(stderr, "%02x",cert->serialNumber.data[0]); | ||||||
|  | 	    } | ||||||
|  | 	    fprintf(stderr," *\n"); | ||||||
|  | 	} | ||||||
|  | 	appendLabel('C'); | ||||||
|  | 	commonName = CERT_GetCommonName(&cert->subject); | ||||||
|  | 	appendString(commonName?commonName:"*NoName*"); | ||||||
|  | 	PORT_Free(commonName); | ||||||
|  | 	if (cert->trust) { | ||||||
|  | 	    appendFlags(cert->trust->sslFlags); | ||||||
|  | 	    appendFlags(cert->trust->emailFlags); | ||||||
|  | 	    appendFlags(cert->trust->objectSigningFlags); | ||||||
|  | 	} | ||||||
|  |    } | ||||||
|  |    CERT_DestroyCertList(list); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * need to implement yet... try to add a new certificate | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | do_add_cert(const char *progName, int log) | ||||||
|  | { | ||||||
|  |   PORT_Assert(/* do_add_cert not implemented */ 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * display the current key slot | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | do_key_slot(const char *progName, int log) | ||||||
|  | { | ||||||
|  |    PK11SlotInfo *slot = PK11_GetInternalKeySlot(); | ||||||
|  |    if (!slot) { | ||||||
|  | 	fprintf(stderr,"ERROR: no internal key slot found %s\n",  | ||||||
|  | 		SECU_Strerror(PORT_GetError())); | ||||||
|  | 	appendLabel('K'); | ||||||
|  | 	appendLabel('S'); | ||||||
|  | 	appendString("none"); | ||||||
|  |    } | ||||||
|  |    print_slot(slot, log); | ||||||
|  |    PK11_FreeSlot(slot); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * execute some NSS command. | ||||||
|  |  */ | ||||||
|  | void | ||||||
|  | do_command(const char *label, int initialized, secuCommandFlag *command,  | ||||||
|  | 	   const char *progName, int log) | ||||||
|  | { | ||||||
|  |    char * command_string; | ||||||
|  |    if (!initialized) { | ||||||
|  | 	return; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (command->activated) { | ||||||
|  | 	command_string = command->arg; | ||||||
|  |    } else { | ||||||
|  | 	command_string = "none"; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (log) { | ||||||
|  | 	fprintf(stderr, "*Executing nss command \"%s\" for %s*\n",  | ||||||
|  | 						command_string,label); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    /* do something */ | ||||||
|  |    if (PORT_Strcasecmp(command_string, "list_slots") == 0) { | ||||||
|  | 	do_list_slots(progName, log); | ||||||
|  |    } else if (PORT_Strcasecmp(command_string, "list_certs") == 0) { | ||||||
|  | 	do_list_certs(progName, log); | ||||||
|  |    } else if (PORT_Strcasecmp(command_string, "add_cert") == 0) { | ||||||
|  | 	do_add_cert(progName, log); | ||||||
|  |    } else if (PORT_Strcasecmp(command_string, "key_slot") == 0) { | ||||||
|  | 	do_key_slot(progName, log); | ||||||
|  |    } else if (PORT_Strcasecmp(command_string, "none") != 0) { | ||||||
|  | 	fprintf(stderr, ">> Unknown command (%s)\n", command_string); | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendString("bc"); | ||||||
|  | 	usage_long(progName); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * functions do handle | ||||||
|  |  * different library initializations. | ||||||
|  |  */ | ||||||
|  | static int main_initialized; | ||||||
|  | static int lib1_initialized; | ||||||
|  | static int lib2_initialized; | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | main_Init(secuCommandFlag *db, secuCommandFlag *tokNam, | ||||||
|  | 	  int readOnly, const char *progName, int log) | ||||||
|  | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     if (log) { | ||||||
|  | 	fprintf(stderr,"*NSS_Init for the main program*\n"); | ||||||
|  |     } | ||||||
|  |     appendLabel('M'); | ||||||
|  |     if (!db->activated) {  | ||||||
|  | 	fprintf(stderr, ">> No main_db has been specified\n"); | ||||||
|  | 	usage(progName); | ||||||
|  |     } | ||||||
|  |     if (main_initialized) { | ||||||
|  | 	fprintf(stderr,"Warning: Second initialization of Main\n"); | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendString("2M"); | ||||||
|  |     } | ||||||
|  |     if (tokNam->activated) { | ||||||
|  | 	PK11_ConfigurePKCS11(NULL, NULL, NULL, tokNam->arg, | ||||||
|  | 			 NULL, NULL, NULL, NULL, 0, 0); | ||||||
|  |     } | ||||||
|  |     rv = NSS_Initialize(db->arg, "", "", "",  | ||||||
|  | 		NSS_INIT_NOROOTINIT|(readOnly?NSS_INIT_READONLY:0)); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendInt(PORT_GetError()); | ||||||
|  | 	fprintf(stderr,">> %s\n", SECU_Strerror(PORT_GetError())); | ||||||
|  | 	dumpBuffer(); | ||||||
|  | 	exit(1); | ||||||
|  |     } | ||||||
|  |     main_initialized = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | main_Do(secuCommandFlag *command, const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     do_command("main", main_initialized, command, progName, log); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | main_Shutdown(int old_style, const char *progName, int log) | ||||||
|  | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     appendLabel('N'); | ||||||
|  |     if (log) { | ||||||
|  | 	fprintf(stderr,"*NSS_Shutdown for the main program*\n"); | ||||||
|  |     } | ||||||
|  |     if (!main_initialized) { | ||||||
|  | 	fprintf(stderr,"Warning: Main shutdown without corresponding init\n"); | ||||||
|  |     } | ||||||
|  |     if (old_style) { | ||||||
|  | 	rv = NSS_Shutdown(); | ||||||
|  |     } else { | ||||||
|  | 	rv = NSS_ShutdownContext(NULL); | ||||||
|  |     } | ||||||
|  |     fprintf(stderr, "Shutdown main state = %d\n", rv); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendInt(PORT_GetError()); | ||||||
|  | 	fprintf(stderr,"ERROR: %s\n", SECU_Strerror(PORT_GetError())); | ||||||
|  |     } | ||||||
|  |     main_initialized = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* common library init */ | ||||||
|  | NSSInitContext * | ||||||
|  | lib_Init(const char *lableString, char label, int initialized,  | ||||||
|  | 	 secuCommandFlag *db, secuCommandFlag *tokNam, int readonly,  | ||||||
|  | 	 const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     NSSInitContext *ctxt; | ||||||
|  |     NSSInitParameters initStrings; | ||||||
|  |     NSSInitParameters *initStringPtr = NULL; | ||||||
|  | 
 | ||||||
|  |     appendLabel(label); | ||||||
|  |     if (log) { | ||||||
|  | 	fprintf(stderr,"*NSS_Init for %s*\n", lableString); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!db->activated) {  | ||||||
|  | 	fprintf(stderr, ">> No %s_db has been specified\n", lableString); | ||||||
|  | 	usage(progName); | ||||||
|  |     } | ||||||
|  |     if (initialized) { | ||||||
|  | 	fprintf(stderr,"Warning: Second initialization of %s\n", lableString); | ||||||
|  |     } | ||||||
|  |     if (tokNam->activated) { | ||||||
|  | 	PORT_Memset(&initStrings, 0, sizeof(initStrings)); | ||||||
|  | 	initStrings.length = sizeof(initStrings); | ||||||
|  | 	initStrings.dbTokenDescription = tokNam->arg; | ||||||
|  | 	initStringPtr = &initStrings; | ||||||
|  |     } | ||||||
|  |     ctxt = NSS_InitContext(db->arg, "", "", "", initStringPtr, | ||||||
|  | 		NSS_INIT_NOROOTINIT|(readonly?NSS_INIT_READONLY:0)); | ||||||
|  |     if (ctxt == NULL) { | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendInt(PORT_GetError()); | ||||||
|  | 	fprintf(stderr,">> %s\n",SECU_Strerror(PORT_GetError())); | ||||||
|  | 	dumpBuffer(); | ||||||
|  | 	exit(1); | ||||||
|  |     } | ||||||
|  |     return ctxt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* common library shutdown */ | ||||||
|  | void | ||||||
|  | lib_Shutdown(const char *labelString, char label, NSSInitContext *ctx,  | ||||||
|  | 	     int initialize, const char *progName, int log) | ||||||
|  | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     appendLabel(label); | ||||||
|  |     if (log) { | ||||||
|  | 	fprintf(stderr,"*NSS_Shutdown for %s\n*", labelString); | ||||||
|  |     } | ||||||
|  |     if (!initialize) { | ||||||
|  | 	fprintf(stderr,"Warning: %s shutdown without corresponding init\n", | ||||||
|  | 		 labelString); | ||||||
|  |     } | ||||||
|  |     rv = NSS_ShutdownContext(ctx); | ||||||
|  |     fprintf(stderr, "Shutdown %s state = %d\n", labelString, rv); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	appendLabel('E'); | ||||||
|  | 	appendInt(PORT_GetError()); | ||||||
|  | 	fprintf(stderr,"ERROR: %s\n", SECU_Strerror(PORT_GetError())); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static NSSInitContext *lib1_context; | ||||||
|  | static NSSInitContext *lib2_context; | ||||||
|  | void | ||||||
|  | lib1_Init(secuCommandFlag *db, secuCommandFlag *tokNam, | ||||||
|  | 	  int readOnly, const char *progName, int log) | ||||||
|  | { | ||||||
|  |     lib1_context = lib_Init("lib1", '1', lib1_initialized, db, tokNam, | ||||||
|  | 			     readOnly, progName, log); | ||||||
|  |     lib1_initialized = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | lib2_Init(secuCommandFlag *db, secuCommandFlag *tokNam, | ||||||
|  | 	  int readOnly, const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     lib2_context = lib_Init("lib2", '2', lib2_initialized, | ||||||
|  | 			    db, tokNam, readOnly, progName, log); | ||||||
|  |     lib2_initialized = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void     | ||||||
|  | lib1_Do(secuCommandFlag *command, const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     do_command("lib1", lib1_initialized, command, progName, log); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | lib2_Do(secuCommandFlag *command, const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     do_command("lib2", lib2_initialized, command, progName, log); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | lib1_Shutdown(const char *progName, int log)  | ||||||
|  | { | ||||||
|  |      lib_Shutdown("lib1", 'I', lib1_context, lib1_initialized, progName, log); | ||||||
|  |      lib1_initialized = 0; | ||||||
|  |      /* don't clear lib1_Context, so we can test multiple attempts to close
 | ||||||
|  |       * the same context produces correct errors*/ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | lib2_Shutdown(const char *progName, int log)  | ||||||
|  | { | ||||||
|  |     lib_Shutdown("lib2", 'Z', lib2_context, lib2_initialized, progName, log); | ||||||
|  |     lib2_initialized = 0; | ||||||
|  |     /* don't clear lib2_Context, so we can test multiple attempts to close
 | ||||||
|  |      * the same context produces correct errors*/ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | main(int argc, char **argv) | ||||||
|  | { | ||||||
|  |    SECStatus rv; | ||||||
|  |    secuCommand libinit; | ||||||
|  |    char *progName; | ||||||
|  |    char *order; | ||||||
|  |    secuCommandFlag *options; | ||||||
|  |    int log = 0; | ||||||
|  | 
 | ||||||
|  |    progName = strrchr(argv[0], '/'); | ||||||
|  |    progName = progName ? progName+1 : argv[0]; | ||||||
|  | 
 | ||||||
|  |    libinit.numCommands = 0; | ||||||
|  |    libinit.commands = 0;  | ||||||
|  |    libinit.numOptions = opt_last; | ||||||
|  |    options = (secuCommandFlag *)PORT_Alloc(sizeof(options_init)); | ||||||
|  |    if (options == NULL) { | ||||||
|  | 	fprintf(stderr, ">> %s:Not enough free memory to run command\n", | ||||||
|  | 		progName); | ||||||
|  | 	exit(1); | ||||||
|  |    } | ||||||
|  |    PORT_Memcpy(options, options_init, sizeof(options_init)); | ||||||
|  |    libinit.options = options; | ||||||
|  | 
 | ||||||
|  |    rv = SECU_ParseCommandLine(argc, argv, progName, & libinit); | ||||||
|  |    if (rv != SECSuccess) { | ||||||
|  | 	usage(progName); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (libinit.options[opt_help].activated) { | ||||||
|  | 	long_help(progName); | ||||||
|  | 	exit (0); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    log = libinit.options[opt_verbose].activated; | ||||||
|  |    if (libinit.options[opt_summary].activated) { | ||||||
|  | 	initBuffer(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    order = libinit.options[opt_liborder].arg; | ||||||
|  |    if (!order) { | ||||||
|  | 	usage(progName); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (log) { | ||||||
|  | 	fprintf(stderr,"* initializing with order \"%s\"*\n", order); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    for (;*order; order++) { | ||||||
|  | 	switch (*order) { | ||||||
|  | 	case 'M': | ||||||
|  | 	    main_Init(&libinit.options[opt_mainDB], | ||||||
|  | 		      &libinit.options[opt_mainTokNam], | ||||||
|  | 		       libinit.options[opt_mainRO].activated, | ||||||
|  | 		       progName, log); | ||||||
|  | 	    break; | ||||||
|  | 	case '1': | ||||||
|  | 	    lib1_Init(&libinit.options[opt_lib1DB], | ||||||
|  | 		      &libinit.options[opt_lib1TokNam], | ||||||
|  | 		       libinit.options[opt_lib1RO].activated, | ||||||
|  | 		        progName,log); | ||||||
|  | 	    break; | ||||||
|  | 	case '2': | ||||||
|  | 	    lib2_Init(&libinit.options[opt_lib2DB], | ||||||
|  | 		      &libinit.options[opt_lib2TokNam], | ||||||
|  | 		       libinit.options[opt_lib2RO].activated, | ||||||
|  | 		       progName,log); | ||||||
|  | 	    break; | ||||||
|  | 	case 'm': | ||||||
|  | 	    main_Shutdown(libinit.options[opt_oldStyle].activated,  | ||||||
|  | 			  progName, log); | ||||||
|  | 	    break; | ||||||
|  | 	case 'i': | ||||||
|  | 	    lib1_Shutdown(progName, log); | ||||||
|  | 	    break; | ||||||
|  | 	case 'z': | ||||||
|  | 	    lib2_Shutdown(progName, log); | ||||||
|  | 	    break; | ||||||
|  | 	default: | ||||||
|  | 	    fprintf(stderr,">> Unknown init/shutdown command \"%c\"", *order); | ||||||
|  | 	    usage_long(progName); | ||||||
|  | 	} | ||||||
|  | 	main_Do(&libinit.options[opt_mainCMD], progName, log); | ||||||
|  | 	lib1_Do(&libinit.options[opt_lib1CMD], progName, log); | ||||||
|  | 	lib2_Do(&libinit.options[opt_lib2CMD], progName, log); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (NSS_IsInitialized()) { | ||||||
|  | 	appendLabel('X'); | ||||||
|  | 	fprintf(stderr, "Warning: NSS is initialized\n"); | ||||||
|  |    } | ||||||
|  |    dumpBuffer(); | ||||||
|  | 
 | ||||||
|  |    exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @ -90,26 +90,27 @@ endif | ||||||
| 
 | 
 | ||||||
| ifdef USE_STATIC_LIBS | ifdef USE_STATIC_LIBS | ||||||
| 
 | 
 | ||||||
| # can't do this in manifest.mn because OS_ARCH isn't defined there.
 |  | ||||||
| ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))  |  | ||||||
| SQLITE = $(LIB_PREFIX)sqlite3.$(LIB_SUFFIX) |  | ||||||
| 
 |  | ||||||
| DEFINES += -DNSS_USE_STATIC_LIBS | DEFINES += -DNSS_USE_STATIC_LIBS | ||||||
| # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 | # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 | ||||||
| CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) | CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) | ||||||
| 
 | 
 | ||||||
| PKIXLIB = \
 | PKIXLIB = \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixchecker.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixparams.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixcrlsel.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixstore.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixpki.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixsystem.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)pkixsystem.$(LIB_SUFFIX) \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixmodule.$(LIB_SUFFIX) | 	$(DIST)/lib/$(LIB_PREFIX)pkixcrlsel.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixmodule.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixstore.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixparams.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixchecker.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixpki.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
 | ||||||
|  | 	$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX) | ||||||
|  | 
 | ||||||
|  | # can't do this in manifest.mn because OS_ARCH isn't defined there.
 | ||||||
|  | ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))  | ||||||
|  | SQLITE = $(LIB_PREFIX)sqlite3.$(LIB_SUFFIX) | ||||||
| 
 | 
 | ||||||
| EXTRA_LIBS += \
 | EXTRA_LIBS += \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 | ||||||
|  | @ -144,23 +145,6 @@ EXTRA_LIBS += \ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
| else | else | ||||||
| 
 | 
 | ||||||
| # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 |  | ||||||
| CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) |  | ||||||
| 
 |  | ||||||
| PKIXLIB = \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixutil.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixsystem.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixcrlsel.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixmodule.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixstore.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixparams.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixchecker.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixpki.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixtop.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixresults.$(LIB_SUFFIX) \
 |  | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)pkixcertsel.$(LIB_SUFFIX) |  | ||||||
| 
 |  | ||||||
| EXTRA_LIBS += \
 | EXTRA_LIBS += \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
 | ||||||
| 	$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
 | 	$(DIST)/lib/$(LIB_PREFIX)ssl.$(LIB_SUFFIX) \
 | ||||||
|  |  | ||||||
|  | @ -176,6 +176,7 @@ Usage(const char *progName) | ||||||
| "Usage: %s -n rsa_nickname -p port [-3BDENRSTbjlmrsuvx] [-w password]\n" | "Usage: %s -n rsa_nickname -p port [-3BDENRSTbjlmrsuvx] [-w password]\n" | ||||||
| "         [-t threads] [-i pid_file] [-c ciphers] [-d dbdir] [-g numblocks]\n" | "         [-t threads] [-i pid_file] [-c ciphers] [-d dbdir] [-g numblocks]\n" | ||||||
| "         [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" | "         [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n" | ||||||
|  | "         [-a sni_name]\n" | ||||||
| #ifdef NSS_ENABLE_ECC | #ifdef NSS_ENABLE_ECC | ||||||
| "         [-C SSLCacheEntries] [-e ec_nickname]\n" | "         [-C SSLCacheEntries] [-e ec_nickname]\n" | ||||||
| #else | #else | ||||||
|  | @ -189,6 +190,8 @@ Usage(const char *progName) | ||||||
| "-D means disable Nagle delays in TCP\n" | "-D means disable Nagle delays in TCP\n" | ||||||
| "-E means disable export ciphersuites and SSL step down key gen\n" | "-E means disable export ciphersuites and SSL step down key gen\n" | ||||||
| "-R means disable detection of rollback from TLS to SSL3\n" | "-R means disable detection of rollback from TLS to SSL3\n" | ||||||
|  | "-a configure server for SNI.\n" | ||||||
|  | "-k expected name negotiated on server sockets" | ||||||
| "-b means try binding to the port and exit\n" | "-b means try binding to the port and exit\n" | ||||||
| "-m means test the model-socket feature of SSL_ImportFD.\n" | "-m means test the model-socket feature of SSL_ImportFD.\n" | ||||||
| "-r flag is interepreted as follows:\n" | "-r flag is interepreted as follows:\n" | ||||||
|  | @ -200,6 +203,7 @@ Usage(const char *progName) | ||||||
| "-u means enable Session Ticket extension for TLS.\n" | "-u means enable Session Ticket extension for TLS.\n" | ||||||
| "-v means verbose output\n" | "-v means verbose output\n" | ||||||
| "-x means use export policy.\n" | "-x means use export policy.\n" | ||||||
|  | "-z means enable compression.\n" | ||||||
| "-L seconds means log statistics every 'seconds' seconds (default=30).\n" | "-L seconds means log statistics every 'seconds' seconds (default=30).\n" | ||||||
| "-M maxProcs tells how many processes to run in a multi-process server\n" | "-M maxProcs tells how many processes to run in a multi-process server\n" | ||||||
| "-N means do NOT use the server session cache.  Incompatible with -M.\n" | "-N means do NOT use the server session cache.  Incompatible with -M.\n" | ||||||
|  | @ -387,9 +391,23 @@ printSecurityInfo(PRFileDesc *fd) | ||||||
| 	       suite.effectiveKeyBits, suite.symCipherName,  | 	       suite.effectiveKeyBits, suite.symCipherName,  | ||||||
| 	       suite.macBits, suite.macAlgorithmName); | 	       suite.macBits, suite.macAlgorithmName); | ||||||
| 	    FPRINTF(stderr,  | 	    FPRINTF(stderr,  | ||||||
| 	    "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n", | 	    "selfserv: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" | ||||||
|  | 	    "          Compression: %s\n", | ||||||
| 	       channel.authKeyBits, suite.authAlgorithmName, | 	       channel.authKeyBits, suite.authAlgorithmName, | ||||||
| 	       channel.keaKeyBits,  suite.keaTypeName); | 	       channel.keaKeyBits,  suite.keaTypeName, | ||||||
|  | 	       channel.compressionMethodName); | ||||||
|  |     	} | ||||||
|  |     } | ||||||
|  |     if (verbose) { | ||||||
|  |         SECItem *hostInfo  = SSL_GetNegotiatedHostInfo(fd); | ||||||
|  |         if (hostInfo) { | ||||||
|  |             char namePref[] = "selfserv: Negotiated server name: "; | ||||||
|  | 
 | ||||||
|  |             fprintf(stderr, "%s", namePref); | ||||||
|  |             fwrite(hostInfo->data, hostInfo->len, 1, stderr); | ||||||
|  |             SECITEM_FreeItem(hostInfo, PR_TRUE); | ||||||
|  |             hostInfo = NULL; | ||||||
|  |             fprintf(stderr, "\n"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     if (requestCert) |     if (requestCert) | ||||||
|  | @ -426,6 +444,71 @@ myBadCertHandler( void *arg, PRFileDesc *fd) | ||||||
|     return (MakeCertOK ? SECSuccess : SECFailure); |     return (MakeCertOK ? SECSuccess : SECFailure); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #define MAX_VIRT_SERVER_NAME_ARRAY_INDEX  10 | ||||||
|  | 
 | ||||||
|  | /* Simple SNI socket config function that does not use SSL_ReconfigFD.
 | ||||||
|  |  * Only uses one server name but verifies that the names match. */ | ||||||
|  | PRInt32  | ||||||
|  | mySSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr, | ||||||
|  |                      PRUint32 sniNameArrSize, void *arg) | ||||||
|  | { | ||||||
|  |     PRInt32        i = 0; | ||||||
|  |     const SECItem *current = sniNameArr; | ||||||
|  |     const char    **nameArr = (const char**)arg; | ||||||
|  |     const secuPWData *pwdata; | ||||||
|  |     CERTCertificate *    cert = NULL; | ||||||
|  |     SECKEYPrivateKey *   privKey = NULL; | ||||||
|  | 
 | ||||||
|  |     PORT_Assert(fd && sniNameArr); | ||||||
|  |     if (!fd || !sniNameArr) { | ||||||
|  | 	return SSL_SNI_SEND_ALERT; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pwdata = SSL_RevealPinArg(fd); | ||||||
|  | 
 | ||||||
|  |     for (;current && i < sniNameArrSize;i++) { | ||||||
|  |         int j = 0; | ||||||
|  |         for (;j < MAX_VIRT_SERVER_NAME_ARRAY_INDEX && nameArr[j];j++) { | ||||||
|  |             if (!PORT_Strncmp(nameArr[j], | ||||||
|  |                               (const char *)current[i].data, | ||||||
|  |                               current[i].len) && | ||||||
|  |                 PORT_Strlen(nameArr[j]) == current[i].len) { | ||||||
|  |                 const char *nickName = nameArr[j]; | ||||||
|  |                 if (j == 0) { | ||||||
|  |                     /* default cert */ | ||||||
|  |                     return 0; | ||||||
|  |                 } | ||||||
|  |                 /* if pwdata is NULL, then we would not get the key and
 | ||||||
|  |                  * return an error status. */ | ||||||
|  |                 cert = PK11_FindCertFromNickname(nickName, &pwdata); | ||||||
|  |                 if (cert == NULL) { | ||||||
|  |                     goto loser; /* Send alert */ | ||||||
|  |                 } | ||||||
|  |                 privKey = PK11_FindKeyByAnyCert(cert, &pwdata); | ||||||
|  |                 if (privKey == NULL) { | ||||||
|  |                     goto loser; /* Send alert */ | ||||||
|  |                 } | ||||||
|  |                 if (SSL_ConfigSecureServer(fd, cert, privKey, | ||||||
|  |                                            kt_rsa) != SECSuccess) { | ||||||
|  |                     goto loser; /* Send alert */ | ||||||
|  |                 } | ||||||
|  |                 SECKEY_DestroyPrivateKey(privKey); | ||||||
|  |                 CERT_DestroyCertificate(cert); | ||||||
|  |                 return i; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | loser: | ||||||
|  |     if (privKey) { | ||||||
|  |         SECKEY_DestroyPrivateKey(privKey); | ||||||
|  |     } | ||||||
|  |     if (cert) { | ||||||
|  |         CERT_DestroyCertificate(cert); | ||||||
|  |     } | ||||||
|  |     return SSL_SNI_SEND_ALERT; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /**************************************************************************
 | /**************************************************************************
 | ||||||
| ** Begin thread management routines and data. | ** Begin thread management routines and data. | ||||||
| **************************************************************************/ | **************************************************************************/ | ||||||
|  | @ -717,6 +800,9 @@ PRBool bypassPKCS11    = PR_FALSE; | ||||||
| PRBool disableLocking  = PR_FALSE; | PRBool disableLocking  = PR_FALSE; | ||||||
| PRBool testbypass      = PR_FALSE; | PRBool testbypass      = PR_FALSE; | ||||||
| PRBool enableSessionTickets = PR_FALSE; | PRBool enableSessionTickets = PR_FALSE; | ||||||
|  | PRBool enableCompression    = PR_FALSE; | ||||||
|  | PRBool failedToNegotiateName  = PR_FALSE; | ||||||
|  | static char  *virtServerNameArray[MAX_VIRT_SERVER_NAME_ARRAY_INDEX]; | ||||||
| 
 | 
 | ||||||
| static const char stopCmd[] = { "GET /stop " }; | static const char stopCmd[] = { "GET /stop " }; | ||||||
| static const char getCmd[]  = { "GET " }; | static const char getCmd[]  = { "GET " }; | ||||||
|  | @ -1520,12 +1606,26 @@ void initLoggingLayer(void) | ||||||
|     loggingMethods.send   = logSend; |     loggingMethods.send   = logSend; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void | ||||||
|  | handshakeCallback(PRFileDesc *fd, void *client_data) | ||||||
|  | { | ||||||
|  |     const char *handshakeName = (const char *)client_data; | ||||||
|  |     if (handshakeName && !failedToNegotiateName) { | ||||||
|  |         SECItem *hostInfo  = SSL_GetNegotiatedHostInfo(fd); | ||||||
|  |         if (!hostInfo || PORT_Strncmp(handshakeName, (char*)hostInfo->data, | ||||||
|  |                                       hostInfo->len)) { | ||||||
|  |             failedToNegotiateName = PR_TRUE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| server_main( | server_main( | ||||||
|     PRFileDesc *        listen_sock, |     PRFileDesc *        listen_sock, | ||||||
|     int                 requestCert,  |     int                 requestCert,  | ||||||
|     SECKEYPrivateKey ** privKey, |     SECKEYPrivateKey ** privKey, | ||||||
|     CERTCertificate **  cert) |     CERTCertificate **  cert, | ||||||
|  |     const char *expectedHostNameVal) | ||||||
| { | { | ||||||
|     PRFileDesc *model_sock	= NULL; |     PRFileDesc *model_sock	= NULL; | ||||||
|     int         rv; |     int         rv; | ||||||
|  | @ -1599,6 +1699,19 @@ server_main( | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (enableCompression) { | ||||||
|  | 	rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); | ||||||
|  | 	if (rv != SECSuccess) { | ||||||
|  | 	    errExit("error enabling compression "); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     rv = SSL_SNISocketConfigHook(model_sock, mySSLSNISocketConfig, | ||||||
|  |                                  (void*)&virtServerNameArray); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  |         errExit("error enabling SNI extension "); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     for (kea = kt_rsa; kea < kt_kea_size; kea++) { |     for (kea = kt_rsa; kea < kt_kea_size; kea++) { | ||||||
| 	if (cert[kea] != NULL) { | 	if (cert[kea] != NULL) { | ||||||
| 	    secStatus = SSL_ConfigSecureServer(model_sock,  | 	    secStatus = SSL_ConfigSecureServer(model_sock,  | ||||||
|  | @ -1631,6 +1744,10 @@ server_main( | ||||||
| 	errExit("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5"); | 	errExit("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (expectedHostNameVal) { | ||||||
|  |         SSL_HandshakeCallback(model_sock, handshakeCallback, | ||||||
|  |                               (void*)expectedHostNameVal); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (requestCert) { |     if (requestCert) { | ||||||
| 	SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,  | 	SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,  | ||||||
|  | @ -1818,6 +1935,8 @@ main(int argc, char **argv) | ||||||
|     SSL3Statistics      *ssl3stats; |     SSL3Statistics      *ssl3stats; | ||||||
|     PRUint32             i; |     PRUint32             i; | ||||||
|     secuPWData  pwdata = { PW_NONE, 0 }; |     secuPWData  pwdata = { PW_NONE, 0 }; | ||||||
|  |     int                  virtServerNameIndex = 1; | ||||||
|  |     char                *expectedHostNameVal = NULL; | ||||||
| 
 | 
 | ||||||
|     tmp = strrchr(argv[0], '/'); |     tmp = strrchr(argv[0], '/'); | ||||||
|     tmp = tmp ? tmp + 1 : argv[0]; |     tmp = tmp ? tmp + 1 : argv[0]; | ||||||
|  | @ -1830,7 +1949,7 @@ main(int argc, char **argv) | ||||||
|     ** numbers, then capital letters, then lower case, alphabetical.  |     ** numbers, then capital letters, then lower case, alphabetical.  | ||||||
|     */ |     */ | ||||||
|     optstate = PL_CreateOptState(argc, argv,  |     optstate = PL_CreateOptState(argc, argv,  | ||||||
|         "2:3BC:DEL:M:NP:RSTbc:d:e:f:g:hi:jlmn:op:qrst:uvw:xy"); |         "2:3BC:DEL:M:NP:RSTa:bc:d:e:f:g:hi:jk:lmn:op:qrst:uvw:xyz"); | ||||||
|     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { |     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { | ||||||
| 	++optionsFound; | 	++optionsFound; | ||||||
| 	switch(optstate->option) { | 	switch(optstate->option) { | ||||||
|  | @ -1869,6 +1988,12 @@ main(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
| 	case 'T': disableTLS = PR_TRUE; break; | 	case 'T': disableTLS = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
|  | 	case 'a': if (virtServerNameIndex >= MAX_VIRT_SERVER_NAME_ARRAY_INDEX) { | ||||||
|  |                       Usage(progName); | ||||||
|  |                   } | ||||||
|  |                   virtServerNameArray[virtServerNameIndex++] = | ||||||
|  |                       PORT_Strdup(optstate->value); break; | ||||||
|  | 
 | ||||||
| 	case 'b': bindOnly = PR_TRUE; break; | 	case 'b': bindOnly = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
| 	case 'c': cipherString = PORT_Strdup(optstate->value); break; | 	case 'c': cipherString = PORT_Strdup(optstate->value); break; | ||||||
|  | @ -1898,11 +2023,16 @@ main(int argc, char **argv) | ||||||
|             loggingLayer = PR_TRUE; |             loggingLayer = PR_TRUE; | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|  |         case 'k': expectedHostNameVal = PORT_Strdup(optstate->value); | ||||||
|  |                   break; | ||||||
|  | 
 | ||||||
|         case 'l': useLocalThreads = PR_TRUE; break; |         case 'l': useLocalThreads = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
| 	case 'm': useModelSocket = PR_TRUE; break; | 	case 'm': useModelSocket = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
| 	case 'n': nickName = PORT_Strdup(optstate->value); break; | 	case 'n': nickName = PORT_Strdup(optstate->value); | ||||||
|  |                   virtServerNameArray[0] = PORT_Strdup(optstate->value); | ||||||
|  |                   break; | ||||||
| 
 | 
 | ||||||
| 	case 'P': certPrefix = PORT_Strdup(optstate->value); break; | 	case 'P': certPrefix = PORT_Strdup(optstate->value); break; | ||||||
| 
 | 
 | ||||||
|  | @ -1935,6 +2065,8 @@ main(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
| 	case 'y': debugCache = PR_TRUE; break; | 	case 'y': debugCache = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
|  | 	case 'z': enableCompression = PR_TRUE; break; | ||||||
|  | 
 | ||||||
| 	default: | 	default: | ||||||
| 	case '?': | 	case '?': | ||||||
| 	    fprintf(stderr, "Unrecognized or bad option specified.\n"); | 	    fprintf(stderr, "Unrecognized or bad option specified.\n"); | ||||||
|  | @ -2228,7 +2360,8 @@ main(int argc, char **argv) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (rv == SECSuccess) { |     if (rv == SECSuccess) { | ||||||
| 	server_main(listen_sock, requestCert, privKey, cert); | 	server_main(listen_sock, requestCert, privKey, cert, | ||||||
|  |                     expectedHostNameVal); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     VLOG(("selfserv: server_thread: exiting")); |     VLOG(("selfserv: server_thread: exiting")); | ||||||
|  | @ -2240,6 +2373,10 @@ cleanup: | ||||||
| 	fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n"); | 	fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n"); | ||||||
| 	exit(1); | 	exit(1); | ||||||
|     } |     } | ||||||
|  |     if (failedToNegotiateName) { | ||||||
|  |         fprintf(stderr, "selfserv: Failed properly negotiate server name\n"); | ||||||
|  |         exit(1); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
| 	int i; | 	int i; | ||||||
|  | @ -2251,15 +2388,20 @@ cleanup: | ||||||
| 		SECKEY_DestroyPrivateKey(privKey[i]); | 		SECKEY_DestroyPrivateKey(privKey[i]); | ||||||
| 	    } | 	    } | ||||||
| 	} | 	} | ||||||
|  |         for (i = 0;virtServerNameArray[i];i++) { | ||||||
|  |             PORT_Free(virtServerNameArray[i]); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (debugCache) { |     if (debugCache) { | ||||||
| 	nss_DumpCertificateCacheInfo(); | 	nss_DumpCertificateCacheInfo(); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     if (nickName) { |     if (nickName) { | ||||||
|         PORT_Free(nickName); |         PORT_Free(nickName); | ||||||
|     } |     } | ||||||
|  |     if (expectedHostNameVal) { | ||||||
|  |         PORT_Free(expectedHostNameVal); | ||||||
|  |     } | ||||||
|     if (passwd) { |     if (passwd) { | ||||||
|         PORT_Free(passwd); |         PORT_Free(passwd); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -18,11 +18,11 @@ WIN*) | ||||||
|         PATH=${ARG1}/lib:${ARG1}/bin:${ARG4}:${PATH} |         PATH=${ARG1}/lib:${ARG1}/bin:${ARG4}:${PATH} | ||||||
|     fi |     fi | ||||||
|     export PATH |     export PATH | ||||||
|     echo ${2}/shlibsign -v -i ${5} |     echo "${2}"/shlibsign -v -i "${5}" | ||||||
|     ${2}/shlibsign -v -i ${5} |     "${2}"/shlibsign -v -i "${5}" | ||||||
|     ;; |     ;; | ||||||
| *) | *) | ||||||
|     LIBPATH=`(cd ${1}/lib; pwd)`:`(cd ${4}; pwd)`:$LIBPATH |     LIBPATH=`(cd "${1}"/lib; pwd)`:`(cd "${4}"; pwd)`:$LIBPATH | ||||||
|     export LIBPATH |     export LIBPATH | ||||||
|     SHLIB_PATH=${1}/lib:${4}:$SHLIB_PATH |     SHLIB_PATH=${1}/lib:${4}:$SHLIB_PATH | ||||||
|     export SHLIB_PATH |     export SHLIB_PATH | ||||||
|  | @ -34,7 +34,7 @@ WIN*) | ||||||
|     export LIBRARY_PATH |     export LIBRARY_PATH | ||||||
|     ADDON_PATH=${1}/lib:${4}:$ADDON_PATH |     ADDON_PATH=${1}/lib:${4}:$ADDON_PATH | ||||||
|     export ADDON_PATH |     export ADDON_PATH | ||||||
|     echo ${2}/shlibsign -v -i ${5} |     echo "${2}"/shlibsign -v -i "${5}" | ||||||
|     ${2}/shlibsign -v -i ${5} |     "${2}"/shlibsign -v -i "${5}" | ||||||
|     ;; |     ;; | ||||||
| esac | esac | ||||||
|  |  | ||||||
|  | @ -613,6 +613,9 @@ make_cert_request(char *subject, SECKEYPublicKey *pubk) | ||||||
| 	exit (ERRX); | 	exit (ERRX); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     SECKEY_DestroySubjectPublicKeyInfo(spki); | ||||||
|  |     CERT_DestroyName(subj); | ||||||
|  | 
 | ||||||
|     if (verbosity >= 0) { |     if (verbosity >= 0) { | ||||||
| 	PR_fprintf(outputFD, "certificate request generated\n"); | 	PR_fprintf(outputFD, "certificate request generated\n"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -66,7 +66,7 @@ | ||||||
| #include "cert.h" | #include "cert.h" | ||||||
| #include "sslproto.h" | #include "sslproto.h" | ||||||
| 
 | 
 | ||||||
| #define VERSIONSTRING "$Revision: 1.13 $ ($Date: 2009/03/13 02:24:07 $) $Author: nelson%bolyard.com $" | #define VERSIONSTRING "$Revision: 1.17 $ ($Date: 2010/01/28 06:19:11 $) $Author: nelson%bolyard.com $" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| struct _DataBufferList; | struct _DataBufferList; | ||||||
|  | @ -365,6 +365,10 @@ const char * V2CipherString(int cs_int) | ||||||
|   case 0x000039:    cs_str = "TLS/DHE-RSA/AES256-CBC/SHA";	break; |   case 0x000039:    cs_str = "TLS/DHE-RSA/AES256-CBC/SHA";	break; | ||||||
|   case 0x00003A:    cs_str = "TLS/DH-ANON/AES256-CBC/SHA";	break; |   case 0x00003A:    cs_str = "TLS/DH-ANON/AES256-CBC/SHA";	break; | ||||||
| 
 | 
 | ||||||
|  |   case 0x00003C:    cs_str = "TLS/RSA/AES128-CBC/SHA256";  	break; | ||||||
|  |   case 0x00003D:    cs_str = "TLS/RSA/AES256-CBC/SHA256";  	break; | ||||||
|  |   case 0x000040:    cs_str = "TLS/DHE-DSS/AES128-CBC/SHA256";	break; | ||||||
|  | 
 | ||||||
|   case 0x000041:    cs_str = "TLS/RSA/CAMELLIA128-CBC/SHA";	break; |   case 0x000041:    cs_str = "TLS/RSA/CAMELLIA128-CBC/SHA";	break; | ||||||
|   case 0x000042:    cs_str = "TLS/DH-DSS/CAMELLIA128-CBC/SHA";	break; |   case 0x000042:    cs_str = "TLS/DH-DSS/CAMELLIA128-CBC/SHA";	break; | ||||||
|   case 0x000043:    cs_str = "TLS/DH-RSA/CAMELLIA128-CBC/SHA";	break; |   case 0x000043:    cs_str = "TLS/DH-RSA/CAMELLIA128-CBC/SHA";	break; | ||||||
|  | @ -380,6 +384,8 @@ const char * V2CipherString(int cs_int) | ||||||
|   case 0x000065:    cs_str = "TLS/DHE-DSS_EXPORT1024/RC4-56/SHA";  break; |   case 0x000065:    cs_str = "TLS/DHE-DSS_EXPORT1024/RC4-56/SHA";  break; | ||||||
|   case 0x000066:    cs_str = "TLS/DHE-DSS/RC4-128/SHA";		   break; |   case 0x000066:    cs_str = "TLS/DHE-DSS/RC4-128/SHA";		   break; | ||||||
| 
 | 
 | ||||||
|  |   case 0x00006A:    cs_str = "TLS/DHE-DSS/AES256-CBC/SHA256";	break; | ||||||
|  | 
 | ||||||
|   case 0x000072:    cs_str = "TLS/DHE-DSS/3DESEDE-CBC/RMD160"; break; |   case 0x000072:    cs_str = "TLS/DHE-DSS/3DESEDE-CBC/RMD160"; break; | ||||||
|   case 0x000073:    cs_str = "TLS/DHE-DSS/AES128-CBC/RMD160";  break; |   case 0x000073:    cs_str = "TLS/DHE-DSS/AES128-CBC/RMD160";  break; | ||||||
|   case 0x000074:    cs_str = "TLS/DHE-DSS/AES256-CBC/RMD160";  break; |   case 0x000074:    cs_str = "TLS/DHE-DSS/AES256-CBC/RMD160";  break; | ||||||
|  | @ -420,6 +426,8 @@ const char * V2CipherString(int cs_int) | ||||||
|   case 0x00009A:    cs_str = "TLS/DHE-RSA/SEED-CBC/SHA";	break;      |   case 0x00009A:    cs_str = "TLS/DHE-RSA/SEED-CBC/SHA";	break;      | ||||||
|   case 0x00009B:    cs_str = "TLS/DH-ANON/SEED-CBC/SHA";	break;      |   case 0x00009B:    cs_str = "TLS/DH-ANON/SEED-CBC/SHA";	break;      | ||||||
| 
 | 
 | ||||||
|  |   case 0x0000FF:    cs_str = "TLS_RENEGO_PROTECTION_REQUEST";	break; | ||||||
|  | 
 | ||||||
|   case 0x00C001:    cs_str = "TLS/ECDH-ECDSA/NULL/SHA";         break; |   case 0x00C001:    cs_str = "TLS/ECDH-ECDSA/NULL/SHA";         break; | ||||||
|   case 0x00C002:    cs_str = "TLS/ECDH-ECDSA/RC4-128/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 0x00C003:    cs_str = "TLS/ECDH-ECDSA/3DES-EDE-CBC/SHA"; break; | ||||||
|  | @ -446,10 +454,17 @@ const char * V2CipherString(int cs_int) | ||||||
|   case 0x00C018:    cs_str = "TLS/ECDH-anon/AES128-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 0x00C019:    cs_str = "TLS/ECDH-anon/AES256-CBC/SHA";    break; | ||||||
| 
 | 
 | ||||||
|   case 0x00feff:    cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA";	break; |   case 0x00C023:    cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA256"; break; | ||||||
|   case 0x00fefe:    cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA";	break; |   case 0x00C024:    cs_str = "TLS/ECDHE-ECDSA/AES256-CBC/SHA384"; break; | ||||||
|   case 0x00ffe1:    cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA";     break; |   case 0x00C027:    cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA256"; break; | ||||||
|   case 0x00ffe0:    cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA";break; |   case 0x00C028:    cs_str = "TLS/ECDHE-RSA/AES256-CBC/SHA384"; break; | ||||||
|  |   case 0x00C02B:    cs_str = "TLS/ECDHE-ECDSA/AES128-GCM/SHA256"; break; | ||||||
|  |   case 0x00C02C:    cs_str = "TLS/ECDHE-ECDSA/AES256-GCM/SHA384"; 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; | ||||||
| 
 | 
 | ||||||
|   /* the string literal is broken up to avoid trigraphs */ |   /* the string literal is broken up to avoid trigraphs */ | ||||||
|   default:          cs_str = "????" "/????????" "/?????????" "/???"; break; |   default:          cs_str = "????" "/????????" "/?????????" "/???"; break; | ||||||
|  | @ -458,6 +473,20 @@ const char * V2CipherString(int cs_int) | ||||||
|   return cs_str; |   return cs_str; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const char * CompressionMethodString(int cm_int)  | ||||||
|  | { | ||||||
|  |   char *cm_str; | ||||||
|  |   cm_str = NULL; | ||||||
|  |   switch (cm_int) { | ||||||
|  |   case  0: cm_str = "NULL";     break; | ||||||
|  |   case  1: cm_str = "DEFLATE";  break;  /* RFC 3749 */ | ||||||
|  |   case 64: cm_str = "LZS";      break;  /* RFC 3943 */ | ||||||
|  |   default: cm_str = "???";      break; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return cm_str; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const char * helloExtensionNameString(int ex_num)  | const char * helloExtensionNameString(int ex_num)  | ||||||
| { | { | ||||||
|   const char *ex_name = NULL; |   const char *ex_name = NULL; | ||||||
|  | @ -472,7 +501,9 @@ const char * helloExtensionNameString(int ex_num) | ||||||
|   case  5: ex_name = "status_request";                 break; |   case  5: ex_name = "status_request";                 break; | ||||||
|   case 10: ex_name = "elliptic_curves";                break; |   case 10: ex_name = "elliptic_curves";                break; | ||||||
|   case 11: ex_name = "ec_point_formats";               break; |   case 11: ex_name = "ec_point_formats";               break; | ||||||
|  |   case 13: ex_name = "signature_algorithms";           break; | ||||||
|   case 35: ex_name = "session_ticket";                 break; |   case 35: ex_name = "session_ticket";                 break; | ||||||
|  |   case 0xff01: ex_name = "renegotiation_info";         break; | ||||||
|   default: sprintf(buf, "%d", ex_num);  ex_name = (const char *)buf; break; |   default: sprintf(buf, "%d", ex_num);  ex_name = (const char *)buf; break; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -554,10 +585,8 @@ void print_sslv2(DataBufferList *s, unsigned char *recordBuf, unsigned int recor | ||||||
| 	       (PRUint32)(GET_SHORT((chv2->rndlength)))); | 	       (PRUint32)(GET_SHORT((chv2->rndlength)))); | ||||||
|     PR_fprintf(PR_STDOUT,"           cipher-suites = { \n"); |     PR_fprintf(PR_STDOUT,"           cipher-suites = { \n"); | ||||||
|     for (p=0;p<GET_SHORT((chv2->cslength));p+=3) { |     for (p=0;p<GET_SHORT((chv2->cslength));p+=3) { | ||||||
|       const char *cs_str=NULL; |       PRUint32 cs_int    = GET_24((&chv2->csuites[p])); | ||||||
|       PRUint32 cs_int=0; |       const char *cs_str = V2CipherString(cs_int); | ||||||
|       cs_int = GET_24((&chv2->csuites[p])); |  | ||||||
|       cs_str = V2CipherString(cs_int); |  | ||||||
| 
 | 
 | ||||||
|       PR_fprintf(PR_STDOUT,"                (0x%06x) %s\n", |       PR_fprintf(PR_STDOUT,"                (0x%06x) %s\n", | ||||||
| 		  cs_int, cs_str); | 		  cs_int, cs_str); | ||||||
|  | @ -641,10 +670,8 @@ void print_sslv2(DataBufferList *s, unsigned char *recordBuf, unsigned int recor | ||||||
|     PR_fprintf(PR_STDOUT,"           cipher-suites = { "); |     PR_fprintf(PR_STDOUT,"           cipher-suites = { "); | ||||||
|     len = GET_SHORT((shv2->cslength)); |     len = GET_SHORT((shv2->cslength)); | ||||||
|     for (p = 0; p < len; p += 3) { |     for (p = 0; p < len; p += 3) { | ||||||
|       const char *cs_str=NULL; |       PRUint32 cs_int    = GET_24((pos+p)); | ||||||
|       PRUint32 cs_int=0; |       const char *cs_str = V2CipherString(cs_int); | ||||||
|       cs_int = GET_24((pos+p)); |  | ||||||
|       cs_str = V2CipherString(cs_int); |  | ||||||
|       PR_fprintf(PR_STDOUT,"\n              "); |       PR_fprintf(PR_STDOUT,"\n              "); | ||||||
|       PR_fprintf(PR_STDOUT,"(0x%06x) %s", cs_int, cs_str); |       PR_fprintf(PR_STDOUT,"(0x%06x) %s", cs_int, cs_str); | ||||||
|     } |     } | ||||||
|  | @ -727,7 +754,11 @@ unsigned int print_hello_extension(unsigned char *  hsdata, | ||||||
|   return pos; |   return pos; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | /* In the case of renegotiation, handshakes that occur in an already MAC'ed 
 | ||||||
|  |  * channel, by the time of this call, the caller has already removed the MAC  | ||||||
|  |  * from input recordLen. The only MAC'ed record that will get here with its  | ||||||
|  |  * MAC intact (not removed) is the first Finished message on the connection. | ||||||
|  |  */ | ||||||
| void print_ssl3_handshake(unsigned char *recordBuf,  | void print_ssl3_handshake(unsigned char *recordBuf,  | ||||||
|                           unsigned int   recordLen, |                           unsigned int   recordLen, | ||||||
|                           SSLRecord *    sr, |                           SSLRecord *    sr, | ||||||
|  | @ -757,10 +788,10 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
|     recordLen = s->msgBufOffset; |     recordLen = s->msgBufOffset; | ||||||
|     recordBuf = s->msgBuf; |     recordBuf = s->msgBuf; | ||||||
|   } |   } | ||||||
|   while (offset + 4 + s->hMACsize <= recordLen) { |   while (offset + 4 <= recordLen) { | ||||||
|     sslh.type = recordBuf[offset];  |     sslh.type = recordBuf[offset];  | ||||||
|     sslh.length = GET_24(recordBuf+offset+1); |     sslh.length = GET_24(recordBuf+offset+1); | ||||||
|     if (offset + 4 + sslh.length + s->hMACsize > recordLen) |     if (offset + 4 + sslh.length > recordLen) | ||||||
|       break; |       break; | ||||||
|     /* finally have a complete message */ |     /* finally have a complete message */ | ||||||
|     if (sslhexparse)  |     if (sslhexparse)  | ||||||
|  | @ -816,17 +847,15 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
| 	  /* pretty print cipher suites */ | 	  /* pretty print cipher suites */ | ||||||
| 	  { | 	  { | ||||||
| 	    int csuitelength = GET_SHORT((hsdata+pos)); | 	    int csuitelength = GET_SHORT((hsdata+pos)); | ||||||
| 	    PR_fprintf(PR_STDOUT,"            cipher_suites[%d] = { \n", | 	    PR_fprintf(PR_STDOUT,"            cipher_suites[%d] = {\n", | ||||||
| 		       csuitelength/2); | 		       csuitelength/2); | ||||||
| 	    if (csuitelength % 2) { | 	    if (csuitelength % 2) { | ||||||
| 	      PR_fprintf(PR_STDOUT, | 	      PR_fprintf(PR_STDOUT, | ||||||
| 		 "*error in protocol - csuitelength shouldn't be odd*\n"); | 		 "*error in protocol - csuitelength shouldn't be odd*\n"); | ||||||
| 	    } | 	    } | ||||||
| 	    for (w=0; w<csuitelength; w+=2) { | 	    for (w=0; w<csuitelength; w+=2) { | ||||||
| 	      const char *cs_str=NULL; | 	      PRUint32 cs_int    = GET_SHORT((hsdata+pos+2+w)); | ||||||
| 	      PRUint32 cs_int=0; | 	      const char *cs_str = V2CipherString(cs_int); | ||||||
| 	      cs_int = GET_SHORT((hsdata+pos+2+w)); |  | ||||||
| 	      cs_str = V2CipherString(cs_int); |  | ||||||
| 	      PR_fprintf(PR_STDOUT, | 	      PR_fprintf(PR_STDOUT, | ||||||
| 		"                (0x%04x) %s\n", cs_int, cs_str); | 		"                (0x%04x) %s\n", cs_int, cs_str); | ||||||
| 	    } | 	    } | ||||||
|  | @ -837,10 +866,13 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
| 	  /* pretty print compression methods */ | 	  /* pretty print compression methods */ | ||||||
| 	  { | 	  { | ||||||
| 	    int complength = hsdata[pos]; | 	    int complength = hsdata[pos]; | ||||||
| 	    PR_fprintf(PR_STDOUT,"            compression[%d] = {", | 	    PR_fprintf(PR_STDOUT,"            compression[%d] = {\n", | ||||||
| 	               complength); | 	               complength); | ||||||
| 	    for (w=0; w < complength; w++) { | 	    for (w=0; w < complength; w++) { | ||||||
| 	      PR_fprintf(PR_STDOUT, " %02x", hsdata[pos+1+w]); | 	      PRUint32 cm_int    = hsdata[pos+1+w]; | ||||||
|  | 	      const char *cm_str = CompressionMethodString(cm_int); | ||||||
|  | 	      PR_fprintf(PR_STDOUT, | ||||||
|  | 		"                (%02x) %s\n", cm_int, cm_str); | ||||||
| 	    } | 	    } | ||||||
| 	    pos += 1 + complength; | 	    pos += 1 + complength; | ||||||
| 	    PR_fprintf(PR_STDOUT,"            }\n"); | 	    PR_fprintf(PR_STDOUT,"            }\n"); | ||||||
|  | @ -887,8 +919,13 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
| 	  currentcipher = cs_int; | 	  currentcipher = cs_int; | ||||||
| 	  pos += 2; | 	  pos += 2; | ||||||
| 	} | 	} | ||||||
| 	PR_fprintf(PR_STDOUT,  "            compression method = %02x\n",  | 	/* pretty print chosen compression method */ | ||||||
| 		   hsdata[pos++]); | 	{ | ||||||
|  | 	  PRUint32 cm_int    = hsdata[pos++]; | ||||||
|  | 	  const char *cm_str = CompressionMethodString(cm_int); | ||||||
|  | 	  PR_fprintf(PR_STDOUT,"            compression method = (%02x) %s\n", | ||||||
|  | 		     cm_int, cm_str); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	/* pretty print extensions, if any */ | 	/* pretty print extensions, if any */ | ||||||
| 	pos = print_hello_extension(hsdata, sslh.length, pos); | 	pos = print_hello_extension(hsdata, sslh.length, pos); | ||||||
|  | @ -1057,10 +1094,18 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
|       PR_fprintf(PR_STDOUT,"         }\n"); |       PR_fprintf(PR_STDOUT,"         }\n"); | ||||||
| 
 | 
 | ||||||
|       if (!isNULLmac(currentcipher) && !s->hMACsize) { |       if (!isNULLmac(currentcipher) && !s->hMACsize) { | ||||||
|           /* To calculate the size of MAC, we subtract the number
 |           /* To calculate the size of MAC, we subtract the number of known 
 | ||||||
|            * of known bytes of message from the number of remaining | 	   * bytes of message from the number of remaining bytes in the  | ||||||
|            * bytes in the record. */ | 	   * record. This assumes that this is the first record on the  | ||||||
|  | 	   * connection to have a MAC, and that the sender has not put another  | ||||||
|  | 	   * message after the finished message in the handshake record.  | ||||||
|  | 	   * This is only correct for the first transition from unMACed to  | ||||||
|  | 	   * MACed. If the connection switches from one cipher suite to  | ||||||
|  | 	   * another one with a different MAC, this logic will not track that  | ||||||
|  | 	   * change correctly. | ||||||
|  | 	   */ | ||||||
|           s->hMACsize = recordLen - (sslh.length + 4); |           s->hMACsize = recordLen - (sslh.length + 4); | ||||||
|  | 	  sslh.length += s->hMACsize;  /* skip over the MAC data */ | ||||||
|       } |       } | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|  | @ -1075,8 +1120,8 @@ void print_ssl3_handshake(unsigned char *recordBuf, | ||||||
|     }  /* end of switch sslh.type */ |     }  /* end of switch sslh.type */ | ||||||
|     offset += sslh.length + 4;  |     offset += sslh.length + 4;  | ||||||
|   } /* while */ |   } /* while */ | ||||||
|   if (offset + s->hMACsize < recordLen) { /* stuff left over */ |   if (offset < recordLen) { /* stuff left over */ | ||||||
|     int newMsgLen = recordLen - (offset + s->hMACsize); |     int newMsgLen = recordLen - offset; | ||||||
|     if (!s->msgBuf) { |     if (!s->msgBuf) { | ||||||
|       s->msgBuf = PORT_Alloc(newMsgLen); |       s->msgBuf = PORT_Alloc(newMsgLen); | ||||||
|       if (!s->msgBuf) { |       if (!s->msgBuf) { | ||||||
|  |  | ||||||
|  | @ -161,6 +161,7 @@ static PRBool bypassPKCS11    = PR_FALSE; | ||||||
| static PRBool disableLocking  = PR_FALSE; | static PRBool disableLocking  = PR_FALSE; | ||||||
| static PRBool ignoreErrors    = PR_FALSE; | static PRBool ignoreErrors    = PR_FALSE; | ||||||
| static PRBool enableSessionTickets = PR_FALSE; | static PRBool enableSessionTickets = PR_FALSE; | ||||||
|  | static PRBool enableCompression    = PR_FALSE; | ||||||
| 
 | 
 | ||||||
| PRIntervalTime maxInterval    = PR_INTERVAL_NO_TIMEOUT; | PRIntervalTime maxInterval    = PR_INTERVAL_NO_TIMEOUT; | ||||||
| 
 | 
 | ||||||
|  | @ -179,8 +180,8 @@ Usage(const char *progName) | ||||||
|     fprintf(stderr,  |     fprintf(stderr,  | ||||||
|     	"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n" |     	"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n" | ||||||
|  	"          [-23BDNTovqs] [-f filename] [-N | -P percentage]\n" |  	"          [-23BDNTovqs] [-f filename] [-N | -P percentage]\n" | ||||||
| 	"          [-w dbpasswd] [-C cipher(s)] [-t threads] hostname\n" | 	"          [-w dbpasswd] [-C cipher(s)] [-t threads] [-W pwfile]\n" | ||||||
|         "          [-W pwfile]\n" |         "          [-a sniHostName] hostname\n" | ||||||
| 	" where -v means verbose\n" | 	" where -v means verbose\n" | ||||||
|         "       -o flag is interpreted as follows:\n" |         "       -o flag is interpreted as follows:\n" | ||||||
|         "          1 -o   means override the result of server certificate validation.\n" |         "          1 -o   means override the result of server certificate validation.\n" | ||||||
|  | @ -195,7 +196,8 @@ Usage(const char *progName) | ||||||
|         "       -T means disable TLS\n" |         "       -T means disable TLS\n" | ||||||
|         "       -U means enable throttling up threads\n" |         "       -U means enable throttling up threads\n" | ||||||
| 	"       -B bypasses the PKCS11 layer for SSL encryption and MACing\n" | 	"       -B bypasses the PKCS11 layer for SSL encryption and MACing\n" | ||||||
| 	"       -u enable TLS Session Ticket extension\n", | 	"       -u enable TLS Session Ticket extension\n" | ||||||
|  | 	"       -z enable compression\n", | ||||||
| 	progName); | 	progName); | ||||||
|     exit(1); |     exit(1); | ||||||
| } | } | ||||||
|  | @ -312,9 +314,11 @@ printSecurityInfo(PRFileDesc *fd) | ||||||
| 	       suite.effectiveKeyBits, suite.symCipherName,  | 	       suite.effectiveKeyBits, suite.symCipherName,  | ||||||
| 	       suite.macBits, suite.macAlgorithmName); | 	       suite.macBits, suite.macAlgorithmName); | ||||||
| 	    FPRINTF(stderr,  | 	    FPRINTF(stderr,  | ||||||
| 	    "strsclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n", | 	    "strsclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" | ||||||
|  | 	    "          Compression: %s\n", | ||||||
| 	       channel.authKeyBits, suite.authAlgorithmName, | 	       channel.authKeyBits, suite.authAlgorithmName, | ||||||
| 	       channel.keaKeyBits,  suite.keaTypeName); | 	       channel.keaKeyBits,  suite.keaTypeName, | ||||||
|  | 	       channel.compressionMethodName); | ||||||
|     	} |     	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1074,7 +1078,8 @@ client_main( | ||||||
|     unsigned short      port,  |     unsigned short      port,  | ||||||
|     int                 connections, |     int                 connections, | ||||||
|     cert_and_key* Cert_And_Key, |     cert_and_key* Cert_And_Key, | ||||||
|     const char *	hostName) |     const char *	hostName, | ||||||
|  |     const char *	sniHostName) | ||||||
| { | { | ||||||
|     PRFileDesc *model_sock	= NULL; |     PRFileDesc *model_sock	= NULL; | ||||||
|     int         i; |     int         i; | ||||||
|  | @ -1233,6 +1238,12 @@ client_main( | ||||||
| 	    errExit("SSL_OptionSet SSL_ENABLE_SESSION_TICKETS"); | 	    errExit("SSL_OptionSet SSL_ENABLE_SESSION_TICKETS"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (enableCompression) { | ||||||
|  | 	rv = SSL_OptionSet(model_sock, SSL_ENABLE_DEFLATE, PR_TRUE); | ||||||
|  | 	if (rv != SECSuccess) | ||||||
|  | 	    errExit("SSL_OptionSet SSL_ENABLE_DEFLATE"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     SSL_SetURL(model_sock, hostName); |     SSL_SetURL(model_sock, hostName); | ||||||
| 
 | 
 | ||||||
|     SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,  |     SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,  | ||||||
|  | @ -1241,6 +1252,9 @@ client_main( | ||||||
| 
 | 
 | ||||||
|     SSL_GetClientAuthDataHook(model_sock, StressClient_GetClientAuthData, (void*)Cert_And_Key); |     SSL_GetClientAuthDataHook(model_sock, StressClient_GetClientAuthData, (void*)Cert_And_Key); | ||||||
| 
 | 
 | ||||||
|  |     if (sniHostName) { | ||||||
|  |         SSL_SetURL(model_sock, sniHostName); | ||||||
|  |     } | ||||||
|     /* I'm not going to set the HandshakeCallback function. */ |     /* I'm not going to set the HandshakeCallback function. */ | ||||||
| 
 | 
 | ||||||
|     /* end of ssl configuration. */ |     /* end of ssl configuration. */ | ||||||
|  | @ -1328,6 +1342,7 @@ main(int argc, char **argv) | ||||||
|     PLOptStatus          status; |     PLOptStatus          status; | ||||||
|     cert_and_key         Cert_And_Key; |     cert_and_key         Cert_And_Key; | ||||||
|     secuPWData           pwdata  = { PW_NONE, 0 }; |     secuPWData           pwdata  = { PW_NONE, 0 }; | ||||||
|  |     char *               sniHostName = NULL; | ||||||
| 
 | 
 | ||||||
|     /* Call the NSPR initialization routines */ |     /* Call the NSPR initialization routines */ | ||||||
|     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |     PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); | ||||||
|  | @ -1338,7 +1353,8 @@ main(int argc, char **argv) | ||||||
|     progName = progName ? progName + 1 : tmp; |     progName = progName ? progName + 1 : tmp; | ||||||
|   |   | ||||||
| 
 | 
 | ||||||
|     optstate = PL_CreateOptState(argc, argv, "23BC:DNP:TUW:c:d:f:in:op:qst:uvw:"); |     optstate = PL_CreateOptState(argc, argv, | ||||||
|  |                                  "23BC:DNP:TUW:a:c:d:f:in:op:qst:uvw:z"); | ||||||
|     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { |     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { | ||||||
| 	switch(optstate->option) { | 	switch(optstate->option) { | ||||||
| 
 | 
 | ||||||
|  | @ -1360,6 +1376,8 @@ main(int argc, char **argv) | ||||||
|              |              | ||||||
| 	case 'U': ThrottleUp = PR_TRUE; break; | 	case 'U': ThrottleUp = PR_TRUE; break; | ||||||
| 
 | 
 | ||||||
|  | 	case 'a': sniHostName = PL_strdup(optstate->value); break; | ||||||
|  | 
 | ||||||
| 	case 'c': connections = PORT_Atoi(optstate->value); break; | 	case 'c': connections = PORT_Atoi(optstate->value); break; | ||||||
| 
 | 
 | ||||||
| 	case 'd': dir = optstate->value; break; | 	case 'd': dir = optstate->value; break; | ||||||
|  | @ -1398,6 +1416,8 @@ main(int argc, char **argv) | ||||||
|             pwdata.data = PL_strdup(optstate->value); |             pwdata.data = PL_strdup(optstate->value); | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|  | 	case 'z': enableCompression = PR_TRUE; break; | ||||||
|  | 
 | ||||||
| 	case 0:   /* positional parameter */ | 	case 0:   /* positional parameter */ | ||||||
| 	    if (hostName) { | 	    if (hostName) { | ||||||
| 		Usage(progName); | 		Usage(progName); | ||||||
|  | @ -1464,7 +1484,8 @@ main(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     client_main(port, connections, &Cert_And_Key, hostName); |     client_main(port, connections, &Cert_And_Key, hostName, | ||||||
|  |                 sniHostName); | ||||||
| 
 | 
 | ||||||
|     /* clean up */ |     /* clean up */ | ||||||
|     if (Cert_And_Key.cert) { |     if (Cert_And_Key.cert) { | ||||||
|  | @ -1482,6 +1503,9 @@ main(int argc, char **argv) | ||||||
|     if (Cert_And_Key.nickname) { |     if (Cert_And_Key.nickname) { | ||||||
|         PL_strfree(Cert_And_Key.nickname); |         PL_strfree(Cert_And_Key.nickname); | ||||||
|     } |     } | ||||||
|  |     if (sniHostName) { | ||||||
|  |         PL_strfree(sniHostName); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     PL_strfree(hostName); |     PL_strfree(hostName); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										129
									
								
								security/nss/cmd/tests/dertimetest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								security/nss/cmd/tests/dertimetest.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,129 @@ | ||||||
|  | /* ***** 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) 2009 | ||||||
|  |  * 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 <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | #include "secder.h" | ||||||
|  | #include "secerr.h" | ||||||
|  | 
 | ||||||
|  | int main() | ||||||
|  | { | ||||||
|  |     SECItem badTime; | ||||||
|  |     PRTime prtime; | ||||||
|  |     SECStatus rv; | ||||||
|  |     int error; | ||||||
|  |     PRBool failed = PR_FALSE; | ||||||
|  | 
 | ||||||
|  |     /* A UTCTime string with an embedded null. */ | ||||||
|  |     badTime.type = siBuffer; | ||||||
|  |     badTime.data = (unsigned char *)"091219000000Z\0junkjunkjunkjunkjunkjunk"; | ||||||
|  |     badTime.len = 38; | ||||||
|  |     rv = DER_UTCTimeToTime(&prtime, &badTime); | ||||||
|  |     if (rv == SECSuccess) { | ||||||
|  |         fprintf(stderr, "DER_UTCTimeToTime should have failed but " | ||||||
|  |                 "succeeded\n"); | ||||||
|  |         failed = PR_TRUE; | ||||||
|  |     } else { | ||||||
|  |         error = PORT_GetError(); | ||||||
|  |         if (error != SEC_ERROR_INVALID_TIME) { | ||||||
|  |             fprintf(stderr, "DER_UTCTimeToTime failed with error %d, " | ||||||
|  |                     "expected error %d\n", error, SEC_ERROR_INVALID_TIME); | ||||||
|  |             failed = PR_TRUE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* A UTCTime string with junk after a valid date/time. */ | ||||||
|  |     badTime.type = siBuffer; | ||||||
|  |     badTime.data = (unsigned char *)"091219000000Zjunk"; | ||||||
|  |     badTime.len = 17; | ||||||
|  |     rv = DER_UTCTimeToTime(&prtime, &badTime); | ||||||
|  |     if (rv == SECSuccess) { | ||||||
|  |         fprintf(stderr, "DER_UTCTimeToTime should have failed but " | ||||||
|  |                 "succeeded\n"); | ||||||
|  |         failed = PR_TRUE; | ||||||
|  |     } else { | ||||||
|  |         error = PORT_GetError(); | ||||||
|  |         if (error != SEC_ERROR_INVALID_TIME) { | ||||||
|  |             fprintf(stderr, "DER_UTCTimeToTime failed with error %d, " | ||||||
|  |                     "expected error %d\n", error, SEC_ERROR_INVALID_TIME); | ||||||
|  |             failed = PR_TRUE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* A GeneralizedTime string with an embedded null. */ | ||||||
|  |     badTime.type = siBuffer; | ||||||
|  |     badTime.data = (unsigned char *)"20091219000000Z\0junkjunkjunkjunkjunkjunk"; | ||||||
|  |     badTime.len = 40; | ||||||
|  |     rv = DER_GeneralizedTimeToTime(&prtime, &badTime); | ||||||
|  |     if (rv == SECSuccess) { | ||||||
|  |         fprintf(stderr, "DER_GeneralizedTimeToTime should have failed but " | ||||||
|  |                 "succeeded\n"); | ||||||
|  |         failed = PR_TRUE; | ||||||
|  |     } else { | ||||||
|  |         error = PORT_GetError(); | ||||||
|  |         if (error != SEC_ERROR_INVALID_TIME) { | ||||||
|  |             fprintf(stderr, "DER_GeneralizedTimeToTime failed with error %d, " | ||||||
|  |                     "expected error %d\n", error, SEC_ERROR_INVALID_TIME); | ||||||
|  |             failed = PR_TRUE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* A GeneralizedTime string with junk after a valid date/time. */ | ||||||
|  |     badTime.type = siBuffer; | ||||||
|  |     badTime.data = (unsigned char *)"20091219000000Zjunk"; | ||||||
|  |     badTime.len = 19; | ||||||
|  |     rv = DER_GeneralizedTimeToTime(&prtime, &badTime); | ||||||
|  |     if (rv == SECSuccess) { | ||||||
|  |         fprintf(stderr, "DER_GeneralizedTimeToTime should have failed but " | ||||||
|  |                 "succeeded\n"); | ||||||
|  |         failed = PR_TRUE; | ||||||
|  |     } else { | ||||||
|  |         error = PORT_GetError(); | ||||||
|  |         if (error != SEC_ERROR_INVALID_TIME) { | ||||||
|  |             fprintf(stderr, "DER_GeneralizedTimeToTime failed with error %d, " | ||||||
|  |                     "expected error %d\n", error, SEC_ERROR_INVALID_TIME); | ||||||
|  |             failed = PR_TRUE; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (failed) { | ||||||
|  |         fprintf(stderr, "FAIL\n"); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     printf("PASS\n"); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | @ -43,6 +43,7 @@ MODULE = nss | ||||||
| CSRCS = \ | CSRCS = \ | ||||||
| 	baddbdir.c \ | 	baddbdir.c \ | ||||||
| 	conflict.c \ | 	conflict.c \ | ||||||
|  | 	dertimetest.c \ | ||||||
| 	nonspr10.c \ | 	nonspr10.c \ | ||||||
| 	remtest.c \ | 	remtest.c \ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
|  |  | ||||||
|  | @ -122,7 +122,8 @@ int ssl3CipherSuites[] = { | ||||||
| 
 | 
 | ||||||
| unsigned long __cmp_umuls; | unsigned long __cmp_umuls; | ||||||
| PRBool verbose; | PRBool verbose; | ||||||
| int renegotiate = 0; | int renegotiationsToDo = 0; | ||||||
|  | int renegotiationsDone = 0; | ||||||
| 
 | 
 | ||||||
| static char *progName; | static char *progName; | ||||||
| 
 | 
 | ||||||
|  | @ -149,9 +150,11 @@ void printSecurityInfo(PRFileDesc *fd) | ||||||
| 	       suite.effectiveKeyBits, suite.symCipherName,  | 	       suite.effectiveKeyBits, suite.symCipherName,  | ||||||
| 	       suite.macBits, suite.macAlgorithmName); | 	       suite.macBits, suite.macAlgorithmName); | ||||||
| 	    FPRINTF(stderr,  | 	    FPRINTF(stderr,  | ||||||
| 	    "tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n", | 	    "tstclnt: Server Auth: %d-bit %s, Key Exchange: %d-bit %s\n" | ||||||
|  | 	    "         Compression: %s\n", | ||||||
| 	       channel.authKeyBits, suite.authAlgorithmName, | 	       channel.authKeyBits, suite.authAlgorithmName, | ||||||
| 	       channel.keaKeyBits,  suite.keaTypeName); | 	       channel.keaKeyBits,  suite.keaTypeName, | ||||||
|  | 	       channel.compressionMethodName); | ||||||
|     	} |     	} | ||||||
|     } |     } | ||||||
|     cert = SSL_RevealCert(fd); |     cert = SSL_RevealCert(fd); | ||||||
|  | @ -179,18 +182,27 @@ void printSecurityInfo(PRFileDesc *fd) | ||||||
| void | void | ||||||
| handshakeCallback(PRFileDesc *fd, void *client_data) | handshakeCallback(PRFileDesc *fd, void *client_data) | ||||||
| { | { | ||||||
|  |     const char *secondHandshakeName = (char *)client_data; | ||||||
|  |     if (secondHandshakeName) { | ||||||
|  |         SSL_SetURL(fd, secondHandshakeName); | ||||||
|  |     } | ||||||
|     printSecurityInfo(fd); |     printSecurityInfo(fd); | ||||||
|     if (renegotiate > 0) { |     if (renegotiationsDone < renegotiationsToDo) { | ||||||
| 	renegotiate--; | 	SSL_ReHandshake(fd, (renegotiationsToDo < 2)); | ||||||
| 	SSL_ReHandshake(fd, PR_FALSE); | 	++renegotiationsDone; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void Usage(const char *progName) | static void Usage(const char *progName) | ||||||
| { | { | ||||||
|     fprintf(stderr,  |     fprintf(stderr,  | ||||||
| "Usage:  %s -h host [-p port] [-d certdir] [-n nickname] [-23BTfosvxr] \n" | "Usage:  %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n" | ||||||
| "                   [-c ciphers] [-w passwd] [-W pwfile] [-q]\n", progName); |                     "[-d certdir] [-n nickname] [-23BTafosvx] [-c ciphers]\n" | ||||||
|  |                     "[-r N] [-w passwd] [-W pwfile] [-q]\n", progName); | ||||||
|  |     fprintf(stderr, "%-20s Send different SNI name. 1st_hs_name - at first\n" | ||||||
|  |                     "%-20s handshake, 2nd_hs_name - at second handshake.\n" | ||||||
|  |                     "%-20s Defualt is host from the -h argument.\n", "-a name", | ||||||
|  |                     "", ""); | ||||||
|     fprintf(stderr, "%-20s Hostname to connect with\n", "-h host"); |     fprintf(stderr, "%-20s Hostname to connect with\n", "-h host"); | ||||||
|     fprintf(stderr, "%-20s Port number for SSL server\n", "-p port"); |     fprintf(stderr, "%-20s Port number for SSL server\n", "-p port"); | ||||||
|     fprintf(stderr,  |     fprintf(stderr,  | ||||||
|  | @ -210,8 +222,9 @@ static void Usage(const char *progName) | ||||||
|     fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v"); |     fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v"); | ||||||
|     fprintf(stderr, "%-20s Use export policy.\n", "-x"); |     fprintf(stderr, "%-20s Use export policy.\n", "-x"); | ||||||
|     fprintf(stderr, "%-20s Ping the server and then exit.\n", "-q"); |     fprintf(stderr, "%-20s Ping the server and then exit.\n", "-q"); | ||||||
|     fprintf(stderr, "%-20s Renegotiate with session resumption.\n", "-r"); |     fprintf(stderr, "%-20s Renegotiate N times (resuming session if N>1).\n", "-r N"); | ||||||
|     fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u"); |     fprintf(stderr, "%-20s Enable the session ticket extension.\n", "-u"); | ||||||
|  |     fprintf(stderr, "%-20s Enable compression.\n", "-z"); | ||||||
|     fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",  |     fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",  | ||||||
|                     "-c ciphers"); |                     "-c ciphers"); | ||||||
|     fprintf(stderr,  |     fprintf(stderr,  | ||||||
|  | @ -507,6 +520,7 @@ int main(int argc, char **argv) | ||||||
|     int                disableLocking = 0; |     int                disableLocking = 0; | ||||||
|     int                useExportPolicy = 0; |     int                useExportPolicy = 0; | ||||||
|     int                enableSessionTickets = 0; |     int                enableSessionTickets = 0; | ||||||
|  |     int                enableCompression = 0; | ||||||
|     PRSocketOptionData opt; |     PRSocketOptionData opt; | ||||||
|     PRNetAddr          addr; |     PRNetAddr          addr; | ||||||
|     PRPollDesc         pollset[2]; |     PRPollDesc         pollset[2]; | ||||||
|  | @ -517,6 +531,8 @@ int main(int argc, char **argv) | ||||||
|     int                headerSeparatorPtrnId = 0; |     int                headerSeparatorPtrnId = 0; | ||||||
|     int                error = 0; |     int                error = 0; | ||||||
|     PRUint16           portno = 443; |     PRUint16           portno = 443; | ||||||
|  |     char *             hs1SniHostName = NULL; | ||||||
|  |     char *             hs2SniHostName = NULL; | ||||||
|     PLOptState *optstate; |     PLOptState *optstate; | ||||||
|     PLOptStatus optstatus; |     PLOptStatus optstatus; | ||||||
|     PRStatus prStatus; |     PRStatus prStatus; | ||||||
|  | @ -534,7 +550,8 @@ int main(int argc, char **argv) | ||||||
|        } |        } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     optstate = PL_CreateOptState(argc, argv, "23BTSfc:h:p:d:m:n:oqr:suvw:xW:"); |     optstate = PL_CreateOptState(argc, argv, | ||||||
|  |                                  "23BSTW:a:c:d:fh:m:n:op:qr:suvw:xz"); | ||||||
|     while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { |     while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) { | ||||||
| 	switch (optstate->option) { | 	switch (optstate->option) { | ||||||
| 	  case '?': | 	  case '?': | ||||||
|  | @ -546,17 +563,26 @@ int main(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
|           case 'B': bypassPKCS11 = 1; 			break; |           case 'B': bypassPKCS11 = 1; 			break; | ||||||
| 
 | 
 | ||||||
|  |           case 'S': skipProtoHeader = PR_TRUE;                 break; | ||||||
|  | 
 | ||||||
|           case 'T': disableTLS  = 1; 			break; |           case 'T': disableTLS  = 1; 			break; | ||||||
| 
 | 
 | ||||||
|           case 'S': skipProtoHeader = PR_TRUE;                 break; |           case 'a': if (!hs1SniHostName) { | ||||||
|  |                         hs1SniHostName = PORT_Strdup(optstate->value); | ||||||
|  |                     } else if (!hs2SniHostName) { | ||||||
|  |                         hs2SniHostName =  PORT_Strdup(optstate->value); | ||||||
|  |                     } else { | ||||||
|  |                         Usage(progName); | ||||||
|  |                     } | ||||||
|  |                     break; | ||||||
| 
 | 
 | ||||||
|           case 'c': cipherString = PORT_Strdup(optstate->value); break; |           case 'c': cipherString = PORT_Strdup(optstate->value); break; | ||||||
| 
 | 
 | ||||||
|           case 'h': host = PORT_Strdup(optstate->value);	break; |           case 'd': certDir = PORT_Strdup(optstate->value);   break; | ||||||
| 
 | 
 | ||||||
|           case 'f': clientSpeaksFirst = PR_TRUE;        break; |           case 'f': clientSpeaksFirst = PR_TRUE;        break; | ||||||
| 
 | 
 | ||||||
|           case 'd': certDir = PORT_Strdup(optstate->value);   break; |           case 'h': host = PORT_Strdup(optstate->value);	break; | ||||||
| 
 | 
 | ||||||
| 	  case 'm': | 	  case 'm': | ||||||
| 	    multiplier = atoi(optstate->value); | 	    multiplier = atoi(optstate->value); | ||||||
|  | @ -578,7 +604,7 @@ int main(int argc, char **argv) | ||||||
| 
 | 
 | ||||||
| 	  case 'v': verbose++;	 			break; | 	  case 'v': verbose++;	 			break; | ||||||
| 
 | 
 | ||||||
| 	  case 'r': renegotiate = atoi(optstate->value);	break; | 	  case 'r': renegotiationsToDo = atoi(optstate->value);	break; | ||||||
| 
 | 
 | ||||||
|           case 'w': |           case 'w': | ||||||
|                 pwdata.source = PW_PLAINTEXT; |                 pwdata.source = PW_PLAINTEXT; | ||||||
|  | @ -591,6 +617,8 @@ int main(int argc, char **argv) | ||||||
|                 break; |                 break; | ||||||
| 
 | 
 | ||||||
| 	  case 'x': useExportPolicy = 1; 		break; | 	  case 'x': useExportPolicy = 1; 		break; | ||||||
|  | 
 | ||||||
|  | 	  case 'z': enableCompression = 1;		break; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -829,6 +857,13 @@ int main(int argc, char **argv) | ||||||
| 	return 1; | 	return 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* enable compression. */ | ||||||
|  |     rv = SSL_OptionSet(s, SSL_ENABLE_DEFLATE, enableCompression); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	SECU_PrintError(progName, "error enabling compression"); | ||||||
|  | 	return 1; | ||||||
|  |     } | ||||||
|  |                 | ||||||
|     SSL_SetPKCS11PinArg(s, &pwdata); |     SSL_SetPKCS11PinArg(s, &pwdata); | ||||||
| 
 | 
 | ||||||
|     SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle); |     SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle); | ||||||
|  | @ -836,8 +871,12 @@ int main(int argc, char **argv) | ||||||
| 	SSL_BadCertHook(s, ownBadCertHandler, NULL); | 	SSL_BadCertHook(s, ownBadCertHandler, NULL); | ||||||
|     } |     } | ||||||
|     SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); |     SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname); | ||||||
|     SSL_HandshakeCallback(s, handshakeCallback, NULL); |     SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName); | ||||||
|  |     if (hs1SniHostName) { | ||||||
|  |         SSL_SetURL(s, hs1SniHostName); | ||||||
|  |     } else { | ||||||
|         SSL_SetURL(s, host); |         SSL_SetURL(s, host); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /* Try to connect to the server */ |     /* Try to connect to the server */ | ||||||
|     status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); |     status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT); | ||||||
|  | @ -1045,6 +1084,12 @@ int main(int argc, char **argv) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   done: |   done: | ||||||
|  |     if (hs1SniHostName) { | ||||||
|  |         PORT_Free(hs1SniHostName); | ||||||
|  |     } | ||||||
|  |     if (hs2SniHostName) { | ||||||
|  |         PORT_Free(hs2SniHostName); | ||||||
|  |     } | ||||||
|     if (nickname) { |     if (nickname) { | ||||||
|         PORT_Free(nickname); |         PORT_Free(nickname); | ||||||
|     } |     } | ||||||
|  |  | ||||||
							
								
								
									
										163
									
								
								security/nss/coverage/cov.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										163
									
								
								security/nss/coverage/cov.sh
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,163 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # ***** 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 Network Security Services | ||||||
|  | # | ||||||
|  | # The Initial Developer of the Original Code is Sun Microsystems, Inc. | ||||||
|  | # Portions created by the Initial Developer are Copyright (C) 2007-2009 | ||||||
|  | # Sun Microsystems, Inc. All Rights Reserved. | ||||||
|  | # | ||||||
|  | # Contributor(s): | ||||||
|  | #   Slavomir Katuscak <slavomir.katuscak@sun.com>, Sun Microsystems, Inc. | ||||||
|  | # | ||||||
|  | # 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 ***** | ||||||
|  | 
 | ||||||
|  | OS=`uname -s` | ||||||
|  | ARCH=`uname -p` | ||||||
|  | SCRIPT_DIR=`pwd` | ||||||
|  | DATE=`date +%Y%m%d` | ||||||
|  | 
 | ||||||
|  | if [ $# -ne 1 ]; then | ||||||
|  |     echo "Usage: $0 [securitytip|securityjes5]" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | BRANCH="$1" | ||||||
|  | 
 | ||||||
|  | if [ "${BRANCH}" != "securitytip" -a "${BRANCH}" != "securityjes5" ]; then | ||||||
|  |     echo "Usage: $0 [securitytip|securityjes5]" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | COV_DIR="/share/builds/mccrel3/security/coverage" | ||||||
|  | BRANCH_DIR="${COV_DIR}/${BRANCH}" | ||||||
|  | DATE_DIR="${BRANCH_DIR}/${DATE}-${ARCH}" | ||||||
|  | CVS_DIR="${DATE_DIR}/cvs_mozilla" | ||||||
|  | TCOV_DIR="${DATE_DIR}/tcov_mozilla" | ||||||
|  | 
 | ||||||
|  | CVS_CHECKOUT_BRANCH="cvs_checkout_${BRANCH}" | ||||||
|  | 
 | ||||||
|  | export HOST=`hostname` | ||||||
|  | export DOMSUF=red.iplanet.com | ||||||
|  | 
 | ||||||
|  | export NSS_ENABLE_ECC=1 | ||||||
|  | export NSS_ECC_MORE_THAN_SUITE_B=1 | ||||||
|  | export IOPR_HOSTADDR_LIST="dochinups.red.iplanet.com" | ||||||
|  | export NSS_AIA_PATH="/share/builds/mccrel3/security/aia_certs" | ||||||
|  | export NSS_AIA_HTTP="http://cindercone.red.iplanet.com/share/builds/mccrel3/security/aia_certs" | ||||||
|  | 
 | ||||||
|  | export USE_TCOV=1 | ||||||
|  | export SUN_PROFDATA_DIR="${DATE_DIR}" | ||||||
|  | export SUN_PROFDATA="tcov_data" | ||||||
|  | 
 | ||||||
|  | if [ "${OS}" != "SunOS" ]; then | ||||||
|  |     echo "OS not supported" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | case "${ARCH}" in  | ||||||
|  | "sparc") | ||||||
|  |     export PATH="/usr/dist/share/sunstudio_sparc,v12.0/SUNWspro/prod/bin:/usr/sfw/bin:/usr/bin:/usr/ccs/bin:/usr/ucb:/tools/ns/bin:/usr/local/bin" | ||||||
|  |     ;; | ||||||
|  | "i386") | ||||||
|  |     export PATH="/usr/dist/share/sunstudio_i386,v12.0/SUNWspro/bin:/usr/sfw/bin:/usr/bin:/usr/ccs/bin:/usr/ucb:/tools/ns/bin:/usr/local/bin" | ||||||
|  |     ;; | ||||||
|  | *) | ||||||
|  |     echo "Platform not supported" | ||||||
|  |     exit 1 | ||||||
|  |     ;; | ||||||
|  | esac | ||||||
|  | 
 | ||||||
|  | cvs_checkout_securitytip() | ||||||
|  | { | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/nsprpub | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/dbm | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/dbm | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/coreconf | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/nss | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/jss | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_1_RTM mozilla/security/nss/lib/freebl/ecl/ecl-curve.h | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | cvs_checkout_securityjes5() | ||||||
|  | { | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSPR_4_6_BRANCH mozilla/nsprpub | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/dbm | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/dbm | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/coreconf | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/nss | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r JSS_4_2_BRANCH mozilla/security/jss | ||||||
|  |     cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_1_RTM mozilla/security/nss/lib/freebl/ecl/ecl-curve.h | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | cvs_checkout() | ||||||
|  | { | ||||||
|  |     rm -rf "${DATE_DIR}" | ||||||
|  |     mkdir -p "${CVS_DIR}" | ||||||
|  |     cd "${CVS_DIR}" | ||||||
|  | 
 | ||||||
|  |     ${CVS_CHECKOUT_BRANCH} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | run_build() | ||||||
|  | { | ||||||
|  |     cd "${CVS_DIR}/mozilla/security/nss" | ||||||
|  |     gmake nss_build_all | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | run_tests() | ||||||
|  | { | ||||||
|  |     cd "${CVS_DIR}/mozilla/security/nss/tests" | ||||||
|  |     ./all.sh | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | process_results() | ||||||
|  | { | ||||||
|  |     rm -rf "${TCOV_DIR}" | ||||||
|  |     mkdir -p "${TCOV_DIR}" | ||||||
|  | 
 | ||||||
|  |     cat "${SUN_PROFDATA_DIR}/${SUN_PROFDATA}/tcovd" | grep SRCFILE | grep "${CVS_DIR}/.*.c$" | sed "s:[^/]*\(.*\):\1:" | sort -u | | ||||||
|  |     while read line | ||||||
|  |     do | ||||||
|  | 	DIR=`echo "${line}" | sed "s:${CVS_DIR}/\(.*\)/.*:\1:"` | ||||||
|  | 	FILE=`echo "${line}" | sed "s:.*/\(.*\):\1:"` | ||||||
|  | 
 | ||||||
|  | 	mkdir -p "${TCOV_DIR}/${DIR}" | ||||||
|  | 	tcov -o "${TCOV_DIR}/${DIR}/$FILE" -x "${SUN_PROFDATA}" $line >/dev/null 2>&1 | ||||||
|  |     done | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | cvs_checkout | ||||||
|  | run_build | ||||||
|  | run_tests | ||||||
|  | process_results | ||||||
|  | 
 | ||||||
|  | cd "${SCRIPT_DIR}" | ||||||
|  | ./report.sh "${BRANCH}" "${DATE}" "${ARCH}"   | ||||||
|  | 
 | ||||||
|  | exit 0 | ||||||
|  | 
 | ||||||
							
								
								
									
										238
									
								
								security/nss/coverage/report.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										238
									
								
								security/nss/coverage/report.sh
									
									
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,238 @@ | ||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # ***** 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 Network Security Services | ||||||
|  | # | ||||||
|  | # The Initial Developer of the Original Code is Sun Microsystems, Inc. | ||||||
|  | # Portions created by the Initial Developer are Copyright (C) 2007-2009 | ||||||
|  | # Sun Microsystems, Inc. All Rights Reserved. | ||||||
|  | # | ||||||
|  | # Contributor(s): | ||||||
|  | #   Slavomir Katuscak <slavomir.katuscak@sun.com>, Sun Microsystems, Inc. | ||||||
|  | # | ||||||
|  | # 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 ***** | ||||||
|  | 
 | ||||||
|  | OS=`uname -s` | ||||||
|  | ARCH=`uname -p` | ||||||
|  | SCRIPT_DIR=`pwd` | ||||||
|  | DATE=`date +%Y-%m-%d` | ||||||
|  | 
 | ||||||
|  | if [ $# -lt 1 -o $# -gt 3 ]; then | ||||||
|  |     echo "Usage: $0 [securitytip|securityjes5] <date> <architecture>" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | BRANCH="$1" | ||||||
|  | 
 | ||||||
|  | if [ "${BRANCH}" != "securitytip" -a "${BRANCH}" != "securityjes5" ]; then | ||||||
|  |     echo "Usage: $0 [securitytip|securityjes5] <date> <architecture>" | ||||||
|  |     exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | if [ $# -ge 2 ]; then | ||||||
|  |     DATE=$2 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | if [ $# -ge 3 ]; then | ||||||
|  |     ARCH=$3 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | HEADER="Code Coverage - NSS - ${BRANCH} - ${OS}/${ARCH} - ${DATE}" | ||||||
|  | 
 | ||||||
|  | COV_DIR="/share/builds/mccrel3/security/coverage" | ||||||
|  | BRANCH_DIR="${COV_DIR}/${BRANCH}" | ||||||
|  | DATE_DIR="${BRANCH_DIR}/${DATE}-${ARCH}" | ||||||
|  | CVS_DIR="${DATE_DIR}/cvs_mozilla" | ||||||
|  | TCOV_DIR="${DATE_DIR}/tcov_mozilla" | ||||||
|  | OUTPUT="${DATE_DIR}/nss.html" | ||||||
|  | 
 | ||||||
|  | LIB_PATH="/mozilla/security/nss/lib" | ||||||
|  | CVS_PATH="${CVS_DIR}${LIB_PATH}" | ||||||
|  | TCOV_PATH="${TCOV_DIR}${LIB_PATH}" | ||||||
|  | 
 | ||||||
|  | MIN_GREEN=70 | ||||||
|  | MIN_YELLOW=40 | ||||||
|  | 
 | ||||||
|  | print_header() | ||||||
|  | { | ||||||
|  |     echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final\">"  | ||||||
|  |     echo "<HTML><HEAD><TITLE>${HEADER}</TITLE></HEAD><BODY>"  | ||||||
|  |     echo "<TABLE ALIGN=\"CENTER\" WIDTH=\"100%\">" | ||||||
|  |     echo "<TR><TH BGCOLOR=\"GREY\"><H2>${HEADER}</H2></TH></TR>" | ||||||
|  |     echo "</TABLE><BR>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | print_footer() | ||||||
|  | { | ||||||
|  |     echo "</BODY></HTML>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | print_notes() | ||||||
|  | { | ||||||
|  |     echo "<TABLE ALIGN=\"CENTER\" WIDTH=\"100%\">" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"LIGHTGREY\"><TD><A HREF=\"http://wikihome.sfbay.sun.com/jes-security/Wiki.jsp?page=Code_Coverage_Test_Execution\">Test Execution Notes</A></TD></TR>" | ||||||
|  |     echo "</TABLE><BR>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | print_legend() | ||||||
|  | { | ||||||
|  |     echo "<TABLE ALIGN=\"CENTER\" WIDTH=\"100%\">" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"GREY\"><TH>Legend</TH></TR>" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"LIGHTGREEN\"><TD>${MIN_GREEN}% - 100% of blocks tested</TD></TR>" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"YELLOW\"><TD>${MIN_YELLOW}% - ${MIN_GREEN}% of blocks tested</TD></TR>" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"ORANGE\"><TD>0% - ${MIN_YELLOW}% of blocks tested</TD></TR>" | ||||||
|  |     echo "<TR ALIGN=\"CENTER\" BGCOLOR=\"RED\"><TD>File not tested (these files are not included into statistics)</TD></TR>" | ||||||
|  |     echo "</TABLE>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | set_color() | ||||||
|  | { | ||||||
|  |     if [ ${PERCENT_INT} -le ${MIN_YELLOW} ]; then | ||||||
|  |         bgcolor="ORANGE" | ||||||
|  |     elif [ ${PERCENT_INT} -le ${MIN_GREEN} ]; then | ||||||
|  |         bgcolor="YELLOW" | ||||||
|  |     else | ||||||
|  |         bgcolor="LIGHTGREEN" | ||||||
|  |     fi     | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | create_table() | ||||||
|  | { | ||||||
|  |     echo "<TABLE ALIGN=\"CENTER\" WIDTH=\"100%\">" | ||||||
|  |     echo "<TR><TH BGCOLOR=\"GREY\" COLSPAN=\"2\">${DIR}</TH></TR>" | ||||||
|  |     echo "<TR BGCOLOR=\"DARKGREY\"><TH WIDTH=\"50%\">File</TH>" | ||||||
|  |     echo "<TH>Tested blocks (Tested blocks/Total blocks/Total lines)</TR>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | close_table() | ||||||
|  | { | ||||||
|  |     if [ "${LASTDIR}" != "" ]; then | ||||||
|  |         if [ ${DFILES} -gt 0 ]; then | ||||||
|  |             if [ ${DBLOCKS_TOTAL} -eq 0 ]; then | ||||||
|  |                 PERCENT_INT=0 | ||||||
|  |             else | ||||||
|  |                 PERCENT_INT=`expr ${DBLOCKS_EXEC} \* 100 \/ ${DBLOCKS_TOTAL}` | ||||||
|  |             fi | ||||||
|  |             set_color | ||||||
|  | 
 | ||||||
|  |             echo "<TR><TH BGCOLOR=\"${bgcolor}\" COLSPAN=\"2\">Total: ${PERCENT_INT}% (${DBLOCKS_EXEC}/${DBLOCKS_TOTAL})</TH></TR>" | ||||||
|  |         else | ||||||
|  |             echo "<TR><TH BGCOLOR=\"RED\" COLSPAN=\"2\">Total: Not tested</TH></TR>" | ||||||
|  |         fi | ||||||
|  |         echo "</TABLE><BR>" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | print_line() | ||||||
|  | { | ||||||
|  |     LINES_TOTAL=`wc -l "${file}" | /usr/bin/awk '{print $1}'` | ||||||
|  | 
 | ||||||
|  |     if [ -r "${TCOV_PATH}/${DIR}/${FILE}" ]; then | ||||||
|  |         BLOCKS_EXEC=`cat "${TCOV_PATH}/${DIR}/${FILE}" | grep "Basic blocks executed" | /usr/bin/awk '{print $1}'` | ||||||
|  |         BLOCKS_TOTAL=`cat "${TCOV_PATH}/${DIR}/${FILE}" | grep "Basic blocks in this file" | /usr/bin/awk '{print $1}'` | ||||||
|  | 
 | ||||||
|  |         DBLOCKS_EXEC=`expr ${DBLOCKS_EXEC} + ${BLOCKS_EXEC}` | ||||||
|  |         DBLOCKS_TOTAL=`expr ${DBLOCKS_TOTAL} + ${BLOCKS_TOTAL}` | ||||||
|  |         TBLOCKS_EXEC=`expr ${TBLOCKS_EXEC} + ${BLOCKS_EXEC}` | ||||||
|  |         TBLOCKS_TOTAL=`expr ${TBLOCKS_TOTAL} + ${BLOCKS_TOTAL}` | ||||||
|  | 
 | ||||||
|  |         TFILES=`expr ${TFILES} + 1` | ||||||
|  |         DFILES=`expr ${DFILES} + 1` | ||||||
|  | 
 | ||||||
|  |         PERCENT_EXEC=`cat "${TCOV_PATH}/${DIR}/${FILE}" | grep "Percent of the file executed" | /usr/bin/awk '{print $1}'` | ||||||
|  |         PERCENT_INT=`echo ${PERCENT_EXEC} | cut -d. -f1` | ||||||
|  |         set_color | ||||||
|  | 
 | ||||||
|  |         echo "<TR><TD BGCOLOR=\"LIGHTGREY\"><A HREF=\"${TCOV_PATH}/${DIR}/${FILE}\">${FILE}</A></TD>" | ||||||
|  |         echo "<TD BGCOLOR=\"${bgcolor}\">${PERCENT_EXEC}% (${BLOCKS_EXEC}/${BLOCKS_TOTAL}/${LINES_TOTAL})</TD></TR>" | ||||||
|  |     else | ||||||
|  |         echo "<TR><TD BGCOLOR=\"LIGHTGREY\"><A HREF=\"${file}\">${FILE}</A></TD>" | ||||||
|  |         echo "<TD BGCOLOR=\"RED\">Not tested (0/?/${LINES_TOTAL})</TD></TR>" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | print_total() | ||||||
|  | { | ||||||
|  |     echo "<TABLE ALIGN=\"CENTER\" WIDTH=\"100%\">" | ||||||
|  |     if [ ${TFILES} -gt 0 ]; then | ||||||
|  |         if [ ${TBLOCKS_TOTAL} -eq 0 ]; then | ||||||
|  |             PERCENT_INT=0 | ||||||
|  |         else | ||||||
|  |             PERCENT_INT=`expr ${TBLOCKS_EXEC} \* 100 \/ ${TBLOCKS_TOTAL}` | ||||||
|  |         fi | ||||||
|  |         set_color | ||||||
|  | 
 | ||||||
|  |         echo "<TR><TH BGCOLOR=\"${bgcolor}\"><H2>Total: ${PERCENT_INT}% (${TBLOCKS_EXEC}/${TBLOCKS_TOTAL})</H2></TH></TR>" | ||||||
|  |     else | ||||||
|  |         echo "<TR><TH BGCOLOR=\"RED\"><H2>Total: Not tested</H2></TH></TR>" | ||||||
|  |     fi | ||||||
|  |     echo "</TABLE><BR>" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | process_cmd() | ||||||
|  | { | ||||||
|  |     LASTDIR="" | ||||||
|  |     TBLOCKS_EXEC=0 | ||||||
|  |     TBLOCKS_TOTAL=0 | ||||||
|  |     TFILES=0 | ||||||
|  | 
 | ||||||
|  |     for dir in `find "${CVS_PATH}" -type d | sort` | ||||||
|  |     do | ||||||
|  |         DIR=`echo "${dir}" | sed "s:^${CVS_PATH}/::"` | ||||||
|  |         for file in `ls -1 ${dir}/*.c 2> /dev/null` | ||||||
|  |         do  | ||||||
|  |             if [ "${DIR}" != "${LASTDIR}" ]; then | ||||||
|  |                 close_table | ||||||
|  |                 create_table  | ||||||
|  | 
 | ||||||
|  |                 LASTDIR="${DIR}"; | ||||||
|  |                 DBLOCKS_EXEC=0 | ||||||
|  |                 DBLOCKS_TOTAL=0 | ||||||
|  |                 DFILES=0 | ||||||
|  |             fi | ||||||
|  | 
 | ||||||
|  |             FILE=`echo "${file}" | sed "s:^.*/\(.*.c\):\1:"` | ||||||
|  |             print_line | ||||||
|  |         done | ||||||
|  |     done | ||||||
|  | 
 | ||||||
|  |     close_table | ||||||
|  |     print_total | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | report() | ||||||
|  | { | ||||||
|  |     print_header > "${OUTPUT}" | ||||||
|  |     print_notes >> "${OUTPUT}" | ||||||
|  |     process_cmd >> "${OUTPUT}" | ||||||
|  |     print_legend >> "${OUTPUT}" | ||||||
|  |     print_footer >> "${OUTPUT}" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | report | ||||||
|  | 
 | ||||||
|  | exit 0 | ||||||
|  | @ -58,13 +58,13 @@ include $(CORE_DEPTH)/coreconf/config.mk | ||||||
| # (4) Include "local" platform-dependent assignments (OPTIONAL).      #
 | # (4) Include "local" platform-dependent assignments (OPTIONAL).      #
 | ||||||
| #######################################################################
 | #######################################################################
 | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS_TARGET), WINCE) | ifndef USE_SYSTEM_ZLIB | ||||||
| DIRS := $(filter-out fortcrypt,$(DIRS)) | ZLIB_SRCDIR = zlib  # Add the zlib directory to DIRS. | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
| ifndef MOZILLA_CLIENT | ifndef MOZILLA_CLIENT | ||||||
| ifndef NSS_USE_SYSTEM_SQLITE | ifndef NSS_USE_SYSTEM_SQLITE | ||||||
| DIRS := sqlite $(DIRS) | SQLITE_SRCDIR = sqlite  # Add the sqlite directory to DIRS. | ||||||
| endif | endif | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * cert.h - public data structures and prototypes for the certificate library |  * cert.h - public data structures and prototypes for the certificate library | ||||||
|  * |  * | ||||||
|  * $Id: cert.h,v 1.78 2009/05/14 01:33:36 julien.pierre.boogz%sun.com Exp $ |  * $Id: cert.h,v 1.79 2010/01/14 22:15:23 alexei.volkov.bugs%sun.com Exp $ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _CERT_H_ | #ifndef _CERT_H_ | ||||||
|  | @ -1077,12 +1077,20 @@ extern CERTDistNames *CERT_GetSSLCACerts(CERTCertDBHandle *handle); | ||||||
| 
 | 
 | ||||||
| extern void CERT_FreeDistNames(CERTDistNames *names); | extern void CERT_FreeDistNames(CERTDistNames *names); | ||||||
| 
 | 
 | ||||||
|  | /* Duplicate distinguished name array */ | ||||||
|  | extern CERTDistNames *CERT_DupDistNames(CERTDistNames *orig); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Generate an array of Distinguished names from an array of nicknames | ** Generate an array of Distinguished names from an array of nicknames | ||||||
| */ | */ | ||||||
| extern CERTDistNames *CERT_DistNamesFromNicknames | extern CERTDistNames *CERT_DistNamesFromNicknames | ||||||
|    (CERTCertDBHandle *handle, char **nicknames, int nnames); |    (CERTCertDBHandle *handle, char **nicknames, int nnames); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  | ** Generate an array of Distinguished names from a list of certs. | ||||||
|  | */ | ||||||
|  | extern CERTDistNames *CERT_DistNamesFromCertList(CERTCertList *list); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Generate a certificate chain from a certificate. | ** Generate a certificate chain from a certificate. | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | @ -617,6 +617,54 @@ CollectDistNames( CERTCertificate *cert, SECItem *k, void *data) | ||||||
| /*
 | /*
 | ||||||
|  * Return all of the CAs that are "trusted" for SSL. |  * Return all of the CAs that are "trusted" for SSL. | ||||||
|  */ |  */ | ||||||
|  | CERTDistNames * | ||||||
|  | CERT_DupDistNames(CERTDistNames *orig) | ||||||
|  | { | ||||||
|  |     PRArenaPool *arena; | ||||||
|  |     CERTDistNames *names; | ||||||
|  |     int i; | ||||||
|  |     SECStatus rv; | ||||||
|  |      | ||||||
|  |     /* allocate an arena to use */ | ||||||
|  |     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | ||||||
|  |     if (arena == NULL) { | ||||||
|  | 	PORT_SetError(SEC_ERROR_NO_MEMORY); | ||||||
|  | 	return(NULL); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     /* allocate the header structure */ | ||||||
|  |     names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames)); | ||||||
|  |     if (names == NULL) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* initialize the header struct */ | ||||||
|  |     names->arena = arena; | ||||||
|  |     names->head = NULL; | ||||||
|  |     names->nnames = orig->nnames; | ||||||
|  |     names->names = NULL; | ||||||
|  |      | ||||||
|  |     /* construct the array from the list */ | ||||||
|  |     if (orig->nnames) { | ||||||
|  | 	names->names = (SECItem*)PORT_ArenaNewArray(arena, SECItem, | ||||||
|  |                                                     orig->nnames); | ||||||
|  | 	if (names->names == NULL) { | ||||||
|  | 	    goto loser; | ||||||
|  | 	} | ||||||
|  | 	for (i = 0; i < orig->nnames; i++) { | ||||||
|  |             rv = SECITEM_CopyItem(arena, &names->names[i], &orig->names[i]); | ||||||
|  |             if (rv != SECSuccess) { | ||||||
|  |                 goto loser; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return(names); | ||||||
|  |      | ||||||
|  | loser: | ||||||
|  |     PORT_FreeArena(arena, PR_FALSE); | ||||||
|  |     return(NULL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| CERTDistNames * | CERTDistNames * | ||||||
| CERT_GetSSLCACerts(CERTCertDBHandle *handle) | CERT_GetSSLCACerts(CERTCertDBHandle *handle) | ||||||
| { | { | ||||||
|  | @ -678,6 +726,53 @@ loser: | ||||||
|     return(NULL); |     return(NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | CERTDistNames * | ||||||
|  | CERT_DistNamesFromCertList(CERTCertList *certList) | ||||||
|  | { | ||||||
|  |     CERTDistNames *   dnames = NULL; | ||||||
|  |     PRArenaPool *     arena; | ||||||
|  |     CERTCertListNode *node = NULL; | ||||||
|  |     SECItem *         names = NULL; | ||||||
|  |     int               listLen = 0, i = 0; | ||||||
|  | 
 | ||||||
|  |     if (certList == NULL) { | ||||||
|  |         PORT_SetError(SEC_ERROR_INVALID_ARGS); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     node = CERT_LIST_HEAD(certList); | ||||||
|  |     while ( ! CERT_LIST_END(node, certList) ) { | ||||||
|  |         listLen += 1; | ||||||
|  |         node = CERT_LIST_NEXT(node); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | ||||||
|  |     if (arena == NULL) goto loser; | ||||||
|  |     dnames = PORT_ArenaZNew(arena, CERTDistNames); | ||||||
|  |     if (dnames == NULL) goto loser; | ||||||
|  | 
 | ||||||
|  |     dnames->arena = arena; | ||||||
|  |     dnames->nnames = listLen; | ||||||
|  |     dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen); | ||||||
|  |     if (names == NULL) goto loser; | ||||||
|  | 
 | ||||||
|  |     node = CERT_LIST_HEAD(certList); | ||||||
|  |     while ( ! CERT_LIST_END(node, certList) ) { | ||||||
|  |         CERTCertificate *cert = node->cert; | ||||||
|  |         SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject); | ||||||
|  |         if (rv == SECFailure) { | ||||||
|  |             goto loser; | ||||||
|  |         } | ||||||
|  |         node = CERT_LIST_NEXT(node); | ||||||
|  |     } | ||||||
|  |     return dnames; | ||||||
|  | loser: | ||||||
|  |     if (arena) { | ||||||
|  |         PORT_FreeArena(arena, PR_FALSE); | ||||||
|  |     } | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| CERTDistNames * | CERTDistNames * | ||||||
| CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, | CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames, | ||||||
| 			   int nnames) | 			   int nnames) | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ | ||||||
|  * Implementation of OCSP services, for both client and server. |  * Implementation of OCSP services, for both client and server. | ||||||
|  * (XXX, really, mostly just for client right now, but intended to do both.) |  * (XXX, really, mostly just for client right now, but intended to do both.) | ||||||
|  * |  * | ||||||
|  * $Id: ocsp.c,v 1.59 2009/06/10 22:59:09 julien.pierre.boogz%sun.com Exp $ |  * $Id: ocsp.c,v 1.64 2010/02/01 20:09:31 wtc%google.com Exp $ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include "prerror.h" | #include "prerror.h" | ||||||
|  | @ -150,6 +150,18 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, | ||||||
|                               void *pwArg, |                               void *pwArg, | ||||||
|                               PRBool *certIDWasConsumed, |                               PRBool *certIDWasConsumed, | ||||||
|                               SECStatus *rv_ocsp); |                               SECStatus *rv_ocsp); | ||||||
|  | 
 | ||||||
|  | static SECStatus | ||||||
|  | ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle, | ||||||
|  | 			      CERTOCSPCertID *certID, | ||||||
|  | 			      CERTCertificate *cert, | ||||||
|  | 			      int64 time, | ||||||
|  | 			      void *pwArg, | ||||||
|  | 			      SECItem *encodedResponse, | ||||||
|  | 			      PRBool *certIDWasConsumed, | ||||||
|  | 			      PRBool cacheNegative, | ||||||
|  | 			      SECStatus *rv_ocsp); | ||||||
|  | 
 | ||||||
| static SECStatus | static SECStatus | ||||||
| ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,  | ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,  | ||||||
|                                         CERTOCSPResponse *response,  |                                         CERTOCSPResponse *response,  | ||||||
|  | @ -158,6 +170,9 @@ ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, | ||||||
|                                         int64             time, |                                         int64             time, | ||||||
|                                         CERTOCSPSingleResponse **pSingleResponse); |                                         CERTOCSPSingleResponse **pSingleResponse); | ||||||
| 
 | 
 | ||||||
|  | static SECStatus | ||||||
|  | ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time); | ||||||
|  | 
 | ||||||
| #ifndef DEBUG | #ifndef DEBUG | ||||||
| #define OCSP_TRACE(msg) | #define OCSP_TRACE(msg) | ||||||
| #define OCSP_TRACE_TIME(msg, time) | #define OCSP_TRACE_TIME(msg, time) | ||||||
|  | @ -4284,6 +4299,33 @@ ocsp_TimeIsRecent(int64 checkTime) | ||||||
| 
 | 
 | ||||||
| static PRUint32 ocspsloptime = OCSP_SLOP;	/* seconds */ | static PRUint32 ocspsloptime = OCSP_SLOP;	/* seconds */ | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * If an old response contains the revoked certificate status, we want | ||||||
|  |  * to return SECSuccess so the response will be used. | ||||||
|  |  */ | ||||||
|  | static SECStatus | ||||||
|  | ocsp_HandleOldSingleResponse(CERTOCSPSingleResponse *single, PRTime time) | ||||||
|  | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     ocspCertStatus *status = single->certStatus; | ||||||
|  |     if (status->certStatusType == ocspCertStatus_revoked) { | ||||||
|  |         rv = ocsp_CertRevokedAfter(status->certStatusInfo.revokedInfo, time); | ||||||
|  |         if (rv != SECSuccess && | ||||||
|  |             PORT_GetError() == SEC_ERROR_REVOKED_CERTIFICATE) { | ||||||
|  |             /*
 | ||||||
|  |              * Return SECSuccess now.  The subsequent ocsp_CertRevokedAfter | ||||||
|  |              * call in ocsp_CertHasGoodStatus will cause | ||||||
|  |              * ocsp_CertHasGoodStatus to fail with | ||||||
|  |              * SEC_ERROR_REVOKED_CERTIFICATE. | ||||||
|  |              */ | ||||||
|  |             return SECSuccess; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  |     PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); | ||||||
|  |     return SECFailure; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Check that this single response is okay.  A return of SECSuccess means: |  * Check that this single response is okay.  A return of SECSuccess means: | ||||||
|  *   1. The signer (represented by "signerCert") is authorized to give status |  *   1. The signer (represented by "signerCert") is authorized to give status | ||||||
|  | @ -4365,13 +4407,10 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single, | ||||||
| 	    return rv; | 	    return rv; | ||||||
| 
 | 
 | ||||||
| 	LL_ADD(tmp, tmp, nextUpdate); | 	LL_ADD(tmp, tmp, nextUpdate); | ||||||
| 	if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate)) { | 	if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate)) | ||||||
| 	    PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); | 	    return ocsp_HandleOldSingleResponse(single, now); | ||||||
| 	    return SECFailure; |  | ||||||
| 	} |  | ||||||
|     } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) { |     } else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) { | ||||||
| 	PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE); | 	return ocsp_HandleOldSingleResponse(single, now); | ||||||
| 	return SECFailure; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return SECSuccess; |     return SECSuccess; | ||||||
|  | @ -4645,6 +4684,9 @@ ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID, | ||||||
|         /* having an arena means, we have a cached certStatus */ |         /* having an arena means, we have a cached certStatus */ | ||||||
|         if (cacheItem->certStatusArena) { |         if (cacheItem->certStatusArena) { | ||||||
|             *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time); |             *rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time); | ||||||
|  |             if (*rvOcsp != SECSuccess) { | ||||||
|  |                 *missingResponseError = PORT_GetError(); | ||||||
|  |             } | ||||||
|             rv = SECSuccess; |             rv = SECSuccess; | ||||||
|         } else { |         } else { | ||||||
|             /*
 |             /*
 | ||||||
|  | @ -4766,6 +4808,77 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, | ||||||
|     return rvOcsp; |     return rvOcsp; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * FUNCTION: CERT_CacheOCSPResponseFromSideChannel | ||||||
|  |  *   First, this function checks the OCSP cache to see if a good response | ||||||
|  |  *   for the given certificate already exists. If it does, then the function | ||||||
|  |  *   returns successfully. | ||||||
|  |  * | ||||||
|  |  *   If not, then it validates that the given OCSP response is a valid, | ||||||
|  |  *   good response for the given certificate and inserts it into the | ||||||
|  |  *   cache. | ||||||
|  |  * | ||||||
|  |  *   This function is intended for use when OCSP responses are provided via a | ||||||
|  |  *   side-channel, i.e. TLS OCSP stapling (a.k.a. the status_request extension). | ||||||
|  |  * | ||||||
|  |  * INPUTS: | ||||||
|  |  *   CERTCertDBHandle *handle | ||||||
|  |  *     certificate DB of the cert that is being checked | ||||||
|  |  *   CERTCertificate *cert | ||||||
|  |  *     the certificate being checked | ||||||
|  |  *   int64 time | ||||||
|  |  *     time for which status is to be determined | ||||||
|  |  *   SECItem *encodedResponse | ||||||
|  |  *     the DER encoded bytes of the OCSP response | ||||||
|  |  *   void *pwArg | ||||||
|  |  *     argument for password prompting, if needed | ||||||
|  |  * RETURN: | ||||||
|  |  *   SECSuccess if the cert was found in the cache, or if the OCSP response was | ||||||
|  |  *   found to be valid and inserted into the cache. SECFailure otherwise. | ||||||
|  |  */ | ||||||
|  | SECStatus | ||||||
|  | CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle, | ||||||
|  | 				      CERTCertificate *cert, | ||||||
|  | 				      int64 time, | ||||||
|  | 				      SECItem *encodedResponse, | ||||||
|  | 				      void *pwArg) | ||||||
|  | { | ||||||
|  |     CERTOCSPCertID *certID; | ||||||
|  |     PRBool certIDWasConsumed = PR_FALSE; | ||||||
|  |     SECStatus rv = SECFailure; | ||||||
|  |     SECStatus rvOcsp; | ||||||
|  |     SECErrorCodes dummy_error_code; /* we ignore this */ | ||||||
|  | 
 | ||||||
|  |     certID = CERT_CreateOCSPCertID(cert, time); | ||||||
|  |     if (!certID) | ||||||
|  |         return SECFailure; | ||||||
|  |     rv = ocsp_GetCachedOCSPResponseStatusIfFresh( | ||||||
|  |         certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */ | ||||||
|  |         &rvOcsp, &dummy_error_code); | ||||||
|  |     if (rv == SECSuccess && rvOcsp == SECSuccess) { | ||||||
|  | 	/* The cached value is good. We don't want to waste time validating
 | ||||||
|  | 	 * this OCSP response. */ | ||||||
|  |         CERT_DestroyOCSPCertID(certID); | ||||||
|  |         return rv; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Since the OCSP response came from a side channel it is attacker
 | ||||||
|  |      * controlled. The attacker can have chosen any valid OCSP response, | ||||||
|  |      * including responses from the past. In this case, | ||||||
|  |      * ocsp_GetVerifiedSingleResponseForCertID will fail. If we recorded a | ||||||
|  |      * negative cache entry in this case, then the attacker would have | ||||||
|  |      * 'poisoned' our cache (denial of service), so we don't record negative | ||||||
|  |      * results. */ | ||||||
|  |     rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg, | ||||||
|  |                                        encodedResponse, &certIDWasConsumed, | ||||||
|  |                                        PR_FALSE /* don't cache failures */, | ||||||
|  |                                        &rvOcsp); | ||||||
|  |     if (!certIDWasConsumed) { | ||||||
|  |         CERT_DestroyOCSPCertID(certID); | ||||||
|  |     } | ||||||
|  |     return rv == SECSuccess ? rvOcsp : rv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Status in *certIDWasConsumed will always be correct, regardless of  |  * Status in *certIDWasConsumed will always be correct, regardless of  | ||||||
|  * return value. |  * return value. | ||||||
|  | @ -4783,11 +4896,7 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, | ||||||
|     PRBool locationIsDefault; |     PRBool locationIsDefault; | ||||||
|     SECItem *encodedResponse = NULL; |     SECItem *encodedResponse = NULL; | ||||||
|     CERTOCSPRequest *request = NULL; |     CERTOCSPRequest *request = NULL; | ||||||
|     CERTOCSPResponse *response = NULL; |  | ||||||
|     CERTCertificate *signerCert = NULL; |  | ||||||
|     CERTCertificate *issuerCert = NULL; |  | ||||||
|     SECStatus rv = SECFailure; |     SECStatus rv = SECFailure; | ||||||
|     CERTOCSPSingleResponse *single = NULL; |  | ||||||
| 
 | 
 | ||||||
|     if (!certIDWasConsumed || !rv_ocsp) { |     if (!certIDWasConsumed || !rv_ocsp) { | ||||||
|         PORT_SetError(SEC_ERROR_INVALID_ARGS); |         PORT_SetError(SEC_ERROR_INVALID_ARGS); | ||||||
|  | @ -4849,6 +4958,75 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, | ||||||
|         goto loser; |         goto loser; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg, | ||||||
|  | 	                               encodedResponse, certIDWasConsumed, | ||||||
|  | 	                               PR_TRUE /* cache failures */, rv_ocsp); | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     if (request != NULL) | ||||||
|  | 	CERT_DestroyOCSPRequest(request); | ||||||
|  |     if (encodedResponse != NULL) | ||||||
|  | 	SECITEM_FreeItem(encodedResponse, PR_TRUE); | ||||||
|  |     if (location != NULL) | ||||||
|  | 	PORT_Free(location); | ||||||
|  | 
 | ||||||
|  |     return rv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * FUNCTION: ocsp_CacheEncodedOCSPResponse | ||||||
|  |  *   This function decodes an OCSP response and checks for a valid response | ||||||
|  |  *   concerning the given certificate. If such a response is not found | ||||||
|  |  *   then nothing is cached. Otherwise, if it is a good response, or if | ||||||
|  |  *   cacheNegative is true, the results are stored in the OCSP cache. | ||||||
|  |  * | ||||||
|  |  *   Note: a 'valid' response is one that parses successfully, is not an OCSP | ||||||
|  |  *   exception (see RFC 2560 Section 2.3), is correctly signed and is current. | ||||||
|  |  *   A 'good' response is a valid response that attests that the certificate | ||||||
|  |  *   is not currently revoked (see RFC 2560 Section 2.2). | ||||||
|  |  * | ||||||
|  |  * INPUTS: | ||||||
|  |  *   CERTCertDBHandle *handle | ||||||
|  |  *     certificate DB of the cert that is being checked | ||||||
|  |  *   CERTOCSPCertID *certID | ||||||
|  |  *     the cert ID corresponding to |cert| | ||||||
|  |  *   CERTCertificate *cert | ||||||
|  |  *     the certificate being checked | ||||||
|  |  *   int64 time | ||||||
|  |  *     time for which status is to be determined | ||||||
|  |  *   void *pwArg | ||||||
|  |  *     the opaque argument to the password prompting function. | ||||||
|  |  *   SECItem *encodedResponse | ||||||
|  |  *     the DER encoded bytes of the OCSP response | ||||||
|  |  *   PRBool *certIDWasConsumed | ||||||
|  |  *     (output) on return, this is true iff |certID| was consumed by this | ||||||
|  |  *     function. | ||||||
|  |  *   SECStatus *rv_ocsp | ||||||
|  |  *     (output) on return, this is SECSuccess iff the response is good (see | ||||||
|  |  *     definition of 'good' above). | ||||||
|  |  * RETURN: | ||||||
|  |  *   SECSuccess iff the response is valid. | ||||||
|  |  */ | ||||||
|  | static SECStatus | ||||||
|  | ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle, | ||||||
|  | 			      CERTOCSPCertID *certID, | ||||||
|  | 			      CERTCertificate *cert, | ||||||
|  | 			      int64 time, | ||||||
|  | 			      void *pwArg, | ||||||
|  | 			      SECItem *encodedResponse, | ||||||
|  | 			      PRBool *certIDWasConsumed, | ||||||
|  | 			      PRBool cacheNegative, | ||||||
|  | 			      SECStatus *rv_ocsp) | ||||||
|  | { | ||||||
|  |     CERTOCSPResponse *response = NULL; | ||||||
|  |     CERTCertificate *signerCert = NULL; | ||||||
|  |     CERTCertificate *issuerCert = NULL; | ||||||
|  |     CERTOCSPSingleResponse *single = NULL; | ||||||
|  |     SECStatus rv = SECFailure; | ||||||
|  | 
 | ||||||
|  |     *certIDWasConsumed = PR_FALSE; | ||||||
|  |     *rv_ocsp = SECFailure; | ||||||
|  | 
 | ||||||
|     response = CERT_DecodeOCSPResponse(encodedResponse); |     response = CERT_DecodeOCSPResponse(encodedResponse); | ||||||
|     if (response == NULL) { |     if (response == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|  | @ -4896,6 +5074,7 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle, | ||||||
|     *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time); |     *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time); | ||||||
| 
 | 
 | ||||||
| loser: | loser: | ||||||
|  |     if (cacheNegative || *rv_ocsp == SECSuccess) { | ||||||
| 	PR_EnterMonitor(OCSP_Global.monitor); | 	PR_EnterMonitor(OCSP_Global.monitor); | ||||||
| 	if (OCSP_Global.maxCacheEntries >= 0) { | 	if (OCSP_Global.maxCacheEntries >= 0) { | ||||||
| 	    /* single == NULL means: remember response failure */ | 	    /* single == NULL means: remember response failure */ | ||||||
|  | @ -4904,6 +5083,9 @@ loser: | ||||||
| 	    /* ignore cache update failures */ | 	    /* ignore cache update failures */ | ||||||
| 	} | 	} | ||||||
| 	PR_ExitMonitor(OCSP_Global.monitor); | 	PR_ExitMonitor(OCSP_Global.monitor); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* 'single' points within the response so there's no need to free it. */ | ||||||
| 
 | 
 | ||||||
|     if (issuerCert != NULL) |     if (issuerCert != NULL) | ||||||
| 	CERT_DestroyCertificate(issuerCert); | 	CERT_DestroyCertificate(issuerCert); | ||||||
|  | @ -4911,12 +5093,6 @@ loser: | ||||||
| 	CERT_DestroyCertificate(signerCert); | 	CERT_DestroyCertificate(signerCert); | ||||||
|     if (response != NULL) |     if (response != NULL) | ||||||
| 	CERT_DestroyOCSPResponse(response); | 	CERT_DestroyOCSPResponse(response); | ||||||
|     if (request != NULL) |  | ||||||
| 	CERT_DestroyOCSPRequest(request); |  | ||||||
|     if (encodedResponse != NULL) |  | ||||||
| 	SECITEM_FreeItem(encodedResponse, PR_TRUE); |  | ||||||
|     if (location != NULL) |  | ||||||
| 	PORT_Free(location); |  | ||||||
|     return rv; |     return rv; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Interface to the OCSP implementation. |  * Interface to the OCSP implementation. | ||||||
|  * |  * | ||||||
|  * $Id: ocsp.h,v 1.14 2009/03/21 01:40:35 nelson%bolyard.com Exp $ |  * $Id: ocsp.h,v 1.17 2010/02/01 20:09:32 wtc%google.com Exp $ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _OCSP_H_ | #ifndef _OCSP_H_ | ||||||
|  | @ -550,6 +550,42 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath); | ||||||
| extern SECStatus  | extern SECStatus  | ||||||
| CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, | CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert, | ||||||
| 		     PRTime time, void *pwArg); | 		     PRTime time, void *pwArg); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * FUNCTION: CERT_CacheOCSPResponseFromSideChannel | ||||||
|  |  *   First, this function checks the OCSP cache to see if a good response | ||||||
|  |  *   for the given certificate already exists. If it does, then the function | ||||||
|  |  *   returns successfully. | ||||||
|  |  * | ||||||
|  |  *   If not, then it validates that the given OCSP response is a valid, | ||||||
|  |  *   good response for the given certificate and inserts it into the | ||||||
|  |  *   cache. | ||||||
|  |  * | ||||||
|  |  *   This function is intended for use when OCSP responses are provided via a | ||||||
|  |  *   side-channel, i.e. TLS OCSP stapling (a.k.a. the status_request extension). | ||||||
|  |  * | ||||||
|  |  * INPUTS: | ||||||
|  |  *   CERTCertDBHandle *handle | ||||||
|  |  *     certificate DB of the cert that is being checked | ||||||
|  |  *   CERTCertificate *cert | ||||||
|  |  *     the certificate being checked | ||||||
|  |  *   PRTime time | ||||||
|  |  *     time for which status is to be determined | ||||||
|  |  *   SECItem *encodedResponse | ||||||
|  |  *     the DER encoded bytes of the OCSP response | ||||||
|  |  *   void *pwArg | ||||||
|  |  *     argument for password prompting, if needed | ||||||
|  |  * RETURN: | ||||||
|  |  *   SECSuccess if the cert was found in the cache, or if the OCSP response was | ||||||
|  |  *   found to be valid and inserted into the cache. SECFailure otherwise. | ||||||
|  |  */ | ||||||
|  | extern SECStatus | ||||||
|  | CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle, | ||||||
|  | 				      CERTCertificate *cert, | ||||||
|  | 				      PRTime time, | ||||||
|  | 				      SECItem *encodedResponse, | ||||||
|  | 				      void *pwArg); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * FUNCTION: CERT_GetOCSPStatusForCertID |  * FUNCTION: CERT_GetOCSPStatusForCertID | ||||||
|  *  Returns the OCSP status contained in the passed in paramter response |  *  Returns the OCSP status contained in the passed in paramter response | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ | ||||||
| # the terms of any one of the MPL, the GPL or the LGPL.
 | # the terms of any one of the MPL, the GPL or the LGPL.
 | ||||||
| #
 | #
 | ||||||
| # ***** END LICENSE BLOCK *****
 | # ***** END LICENSE BLOCK *****
 | ||||||
| MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.19 $ $Date: 2007/05/09 00:09:38 $" | MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.20 $ $Date: 2009/12/17 22:00:47 $" | ||||||
| 
 | 
 | ||||||
| include manifest.mn | include manifest.mn | ||||||
| include $(CORE_DEPTH)/coreconf/config.mk | include $(CORE_DEPTH)/coreconf/config.mk | ||||||
|  | @ -49,7 +49,7 @@ EXTRA_LIBS = \ | ||||||
| ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ||||||
| 
 | 
 | ||||||
| ifdef NS_USE_GCC | ifdef NS_USE_GCC | ||||||
| EXTRA_LIBS += \
 | EXTRA_SHARED_LIBS += \
 | ||||||
| 	-L$(NSPR_LIB_DIR) \
 | 	-L$(NSPR_LIB_DIR) \
 | ||||||
| 	-lplc4 \
 | 	-lplc4 \
 | ||||||
| 	-lplds4 \
 | 	-lplds4 \
 | ||||||
|  | @ -64,7 +64,7 @@ EXTRA_SHARED_LIBS += \ | ||||||
| endif # NS_USE_GCC
 | endif # NS_USE_GCC
 | ||||||
| else | else | ||||||
| 
 | 
 | ||||||
| EXTRA_LIBS += \
 | EXTRA_SHARED_LIBS += \
 | ||||||
| 	-L$(NSPR_LIB_DIR) \
 | 	-L$(NSPR_LIB_DIR) \
 | ||||||
| 	-lplc4 \
 | 	-lplc4 \
 | ||||||
| 	-lplds4 \
 | 	-lplds4 \
 | ||||||
|  | @ -78,25 +78,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk | ||||||
| # Generate certdata.c.
 | # Generate certdata.c.
 | ||||||
| generate: | generate: | ||||||
| 	$(PERL) certdata.perl < certdata.txt | 	$(PERL) certdata.perl < certdata.txt | ||||||
| 
 |  | ||||||
| # This'll need some help from a build person.
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1) |  | ||||||
| DSO_LDOPTS              = -bM:SRE -bh:4 -bnoentry |  | ||||||
| EXTRA_DSO_LDOPTS        = -lc |  | ||||||
| MKSHLIB                 = xlC $(DSO_LDOPTS) |  | ||||||
| 
 |  | ||||||
| $(SHARED_LIBRARY): $(OBJS) |  | ||||||
| 	@$(MAKE_OBJDIR) |  | ||||||
| 	rm -f $@ |  | ||||||
| 	$(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DSO_LDOPTS) |  | ||||||
| 	chmod +x $@ |  | ||||||
| 
 |  | ||||||
| endif |  | ||||||
| 
 |  | ||||||
| ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.2) |  | ||||||
| LD      += -G |  | ||||||
| endif  |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ | ||||||
| # the terms of any one of the MPL, the GPL or the LGPL. | # the terms of any one of the MPL, the GPL or the LGPL. | ||||||
| # | # | ||||||
| # ***** END LICENSE BLOCK ***** | # ***** END LICENSE BLOCK ***** | ||||||
| MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.10 $ $Date: 2005/01/20 02:25:46 $" | MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.11 $ $Date: 2009/12/17 22:00:48 $" | ||||||
| 
 | 
 | ||||||
| CORE_DEPTH = ../../../.. | CORE_DEPTH = ../../../.. | ||||||
| 
 | 
 | ||||||
|  | @ -61,5 +61,3 @@ CSRCS =			\ | ||||||
| REQUIRES = nspr | REQUIRES = nspr | ||||||
| 
 | 
 | ||||||
| LIBRARY_NAME = nssckbi | LIBRARY_NAME = nssckbi | ||||||
| 
 |  | ||||||
| #EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4 |  | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: cryptohi.h,v 1.12 2008/06/14 14:20:00 wtc%google.com Exp $ */ | /* $Id: cryptohi.h,v 1.13 2009/09/23 22:51:56 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #ifndef _CRYPTOHI_H_ | #ifndef _CRYPTOHI_H_ | ||||||
| #define _CRYPTOHI_H_ | #define _CRYPTOHI_H_ | ||||||
|  | @ -114,7 +114,7 @@ extern SECStatus SGN_Begin(SGNContext *cx); | ||||||
| **	"input" the input data to sign | **	"input" the input data to sign | ||||||
| **	"inputLen" the length of the input data | **	"inputLen" the length of the input data | ||||||
| */ | */ | ||||||
| extern SECStatus SGN_Update(SGNContext *cx, unsigned char *input, | extern SECStatus SGN_Update(SGNContext *cx, const unsigned char *input, | ||||||
| 			   unsigned int inputLen); | 			   unsigned int inputLen); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
|  | @ -33,7 +33,9 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: key.h,v 1.4 2004/04/27 23:04:35 gerv%gerv.net Exp $ */ | /* $Id: key.h,v 1.5 2009/10/15 23:58:13 wtc%google.com Exp $ */ | ||||||
|  | 
 | ||||||
|  | /* This header is deprecated.  Please include keyhi.h instead. */ | ||||||
| 
 | 
 | ||||||
| #ifndef _KEY_H_ | #ifndef _KEY_H_ | ||||||
| #define _KEY_H_ | #define _KEY_H_ | ||||||
|  |  | ||||||
|  | @ -2014,10 +2014,10 @@ SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk) | ||||||
|     /* DER-encode the subjectpublickeyinfo */ |     /* DER-encode the subjectpublickeyinfo */ | ||||||
|     spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki, |     spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki, | ||||||
| 					CERT_SubjectPublicKeyInfoTemplate); | 					CERT_SubjectPublicKeyInfoTemplate); | ||||||
| finish: | 
 | ||||||
|     if (spki!=NULL) { |  | ||||||
|     SECKEY_DestroySubjectPublicKeyInfo(spki); |     SECKEY_DestroySubjectPublicKeyInfo(spki); | ||||||
|     } | 
 | ||||||
|  | finish: | ||||||
|     return spkiDER; |     return spkiDER; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: secsign.c,v 1.20 2007/11/07 02:37:21 julien.pierre.boogz%sun.com Exp $ */ | /* $Id: secsign.c,v 1.21 2009/09/23 22:51:56 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include "cryptohi.h" | #include "cryptohi.h" | ||||||
|  | @ -140,7 +140,7 @@ SGN_Begin(SGNContext *cx) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SECStatus | SECStatus | ||||||
| SGN_Update(SGNContext *cx, unsigned char *input, unsigned inputLen) | SGN_Update(SGNContext *cx, const unsigned char *input, unsigned int inputLen) | ||||||
| { | { | ||||||
|     if (cx->hashcx == NULL) { |     if (cx->hashcx == NULL) { | ||||||
| 	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 	PORT_SetError(SEC_ERROR_INVALID_ARGS); | ||||||
|  |  | ||||||
|  | @ -35,12 +35,10 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.39 $ $Date: 2009/01/22 01:29:24 $"; | static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.40 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKEPV_H | #include "pkcs11.h" | ||||||
| #include "nssckepv.h" |  | ||||||
| #endif /* NSSCKEPV_H */ |  | ||||||
| 
 | 
 | ||||||
| #ifndef DEVM_H | #ifndef DEVM_H | ||||||
| #include "devm.h" | #include "devm.h" | ||||||
|  |  | ||||||
|  | @ -44,13 +44,9 @@ | ||||||
| #define CKHELPER_H | #define CKHELPER_H | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.19 $ $Date: 2005/01/20 02:25:47 $"; | static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.20 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKT_H |  | ||||||
| #include "nssckt.h" |  | ||||||
| #endif /* NSSCKT_H */ |  | ||||||
| 
 |  | ||||||
| PR_BEGIN_EXTERN_C | PR_BEGIN_EXTERN_C | ||||||
| 
 | 
 | ||||||
| /* Some globals to keep from constantly redeclaring common cryptoki
 | /* Some globals to keep from constantly redeclaring common cryptoki
 | ||||||
|  |  | ||||||
|  | @ -44,13 +44,9 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.41 $ $Date: 2008/05/29 17:24:15 $"; | static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.42 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKT_H |  | ||||||
| #include "nssckt.h" |  | ||||||
| #endif /* NSSCKT_H */ |  | ||||||
| 
 |  | ||||||
| #ifndef NSSDEV_H | #ifndef NSSDEV_H | ||||||
| #include "nssdev.h" | #include "nssdev.h" | ||||||
| #endif /* NSSDEV_H */ | #endif /* NSSDEV_H */ | ||||||
|  |  | ||||||
|  | @ -38,17 +38,13 @@ | ||||||
| #define DEVM_H | #define DEVM_H | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.11 $ $Date: 2005/01/20 02:25:47 $"; | static const char DEVM_CVS_ID[] = "@(#) $RCSfile: devm.h,v $ $Revision: 1.12 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef BASE_H | #ifndef BASE_H | ||||||
| #include "base.h" | #include "base.h" | ||||||
| #endif /* BASE_H */ | #endif /* BASE_H */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKT_H |  | ||||||
| #include "nssckt.h" |  | ||||||
| #endif /* NSSCKT_H */ |  | ||||||
| 
 |  | ||||||
| #ifndef DEV_H | #ifndef DEV_H | ||||||
| #include "dev.h" | #include "dev.h" | ||||||
| #endif /* DEV_H */ | #endif /* DEV_H */ | ||||||
|  |  | ||||||
|  | @ -35,12 +35,10 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char CVS_ID[] = "@(#) $RCSfile: devslot.c,v $ $Revision: 1.25 $ $Date: 2008/11/20 04:53:44 $"; | static const char CVS_ID[] = "@(#) $RCSfile: devslot.c,v $ $Revision: 1.26 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKEPV_H | #include "pkcs11.h" | ||||||
| #include "nssckepv.h" |  | ||||||
| #endif /* NSSCKEPV_H */ |  | ||||||
| 
 | 
 | ||||||
| #ifndef DEVM_H | #ifndef DEVM_H | ||||||
| #include "devm.h" | #include "devm.h" | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ | ||||||
| #define DEVT_H | #define DEVT_H | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.23 $ $Date: 2007/11/16 05:29:25 $"; | static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.24 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -59,10 +59,6 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.23 $ $ | ||||||
| #include "nssdevt.h" | #include "nssdevt.h" | ||||||
| #endif /* NSSDEVT_H */ | #endif /* NSSDEVT_H */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKT_H |  | ||||||
| #include "nssckt.h" |  | ||||||
| #endif /* NSSCKT_H */ |  | ||||||
| 
 |  | ||||||
| #ifndef BASET_H | #ifndef BASET_H | ||||||
| #include "baset.h" | #include "baset.h" | ||||||
| #endif /* BASET_H */ | #endif /* BASET_H */ | ||||||
|  |  | ||||||
|  | @ -35,12 +35,10 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.51 $ $Date: 2008/09/30 04:09:02 $"; | static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.53 $ $Date: 2010/01/08 02:00:58 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| #ifndef NSSCKEPV_H | #include "pkcs11.h" | ||||||
| #include "nssckepv.h" |  | ||||||
| #endif /* NSSCKEPV_H */ |  | ||||||
| 
 | 
 | ||||||
| #ifndef DEVM_H | #ifndef DEVM_H | ||||||
| #include "devm.h" | #include "devm.h" | ||||||
|  | @ -431,6 +429,13 @@ find_objects_by_template ( | ||||||
|     CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; |     CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1; | ||||||
|     nssCryptokiObject **objects = NULL; |     nssCryptokiObject **objects = NULL; | ||||||
|     PRUint32 i; |     PRUint32 i; | ||||||
|  | 
 | ||||||
|  |     if (!token) { | ||||||
|  |     	PORT_SetError(SEC_ERROR_NO_TOKEN); | ||||||
|  | 	if (statusOpt)  | ||||||
|  | 	    *statusOpt = PR_FAILURE; | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|     for (i=0; i<otsize; i++) { |     for (i=0; i<otsize; i++) { | ||||||
| 	if (obj_template[i].type == CKA_CLASS) { | 	if (obj_template[i].type == CKA_CLASS) { | ||||||
| 	    objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; | 	    objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue; | ||||||
|  | @ -491,6 +496,10 @@ nssToken_ImportCertificate ( | ||||||
|     nssTokenSearchType searchType; |     nssTokenSearchType searchType; | ||||||
|     nssCryptokiObject *rvObject = NULL; |     nssCryptokiObject *rvObject = NULL; | ||||||
| 
 | 
 | ||||||
|  |     if (!tok) { | ||||||
|  |     	PORT_SetError(SEC_ERROR_NO_TOKEN); | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|     if (certType == NSSCertificateType_PKIX) { |     if (certType == NSSCertificateType_PKIX) { | ||||||
| 	cert_type = CKC_X_509; | 	cert_type = CKC_X_509; | ||||||
|     } else { |     } else { | ||||||
|  | @ -842,6 +851,13 @@ nssToken_FindCertificateByIssuerAndSerialNumber ( | ||||||
|     nssCryptokiObject **objects; |     nssCryptokiObject **objects; | ||||||
|     nssCryptokiObject *rvObject = NULL; |     nssCryptokiObject *rvObject = NULL; | ||||||
|     NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); |     NSS_CK_TEMPLATE_START(cert_template, attr, ctsize); | ||||||
|  | 
 | ||||||
|  |     if (!token) { | ||||||
|  |     	PORT_SetError(SEC_ERROR_NO_TOKEN); | ||||||
|  | 	if (statusOpt)  | ||||||
|  | 	    *statusOpt = PR_FAILURE; | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|     /* Set the search to token/session only if provided */ |     /* Set the search to token/session only if provided */ | ||||||
|     if (searchType == nssTokenSearchType_SessionOnly) { |     if (searchType == nssTokenSearchType_SessionOnly) { | ||||||
| 	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | 	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false); | ||||||
|  |  | ||||||
|  | @ -163,8 +163,8 @@ ifeq ($(CPU_ARCH),x86_64) | ||||||
|     DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN |     DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN | ||||||
| #   DEFINES += -DMPI_AMD64_ADD
 | #   DEFINES += -DMPI_AMD64_ADD
 | ||||||
|     # comment the next two lines to turn off intel HW accelleration |     # comment the next two lines to turn off intel HW accelleration | ||||||
|     DEFINES += -DUSE_HW_AES | #    DEFINES += -DUSE_HW_AES
 | ||||||
|     ASFILES += intel-aes.s | #    ASFILES += intel-aes.s
 | ||||||
|     MPI_SRCS += mpi_amd64.c mp_comba.c |     MPI_SRCS += mpi_amd64.c mp_comba.c | ||||||
| endif | endif | ||||||
| ifeq ($(CPU_ARCH),x86) | ifeq ($(CPU_ARCH),x86) | ||||||
|  | @ -410,8 +410,8 @@ else | ||||||
| 	DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY | 	DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY | ||||||
| 	DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN | 	DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN | ||||||
| 	# comment the next two lines to turn off intel HW accelleration | 	# comment the next two lines to turn off intel HW accelleration | ||||||
| 	DEFINES += -DUSE_HW_AES | #	DEFINES += -DUSE_HW_AES
 | ||||||
| 	ASFILES += intel-aes.s | #	ASFILES += intel-aes.s
 | ||||||
| 	MPI_SRCS += mpi_amd64.c | 	MPI_SRCS += mpi_amd64.c | ||||||
|     else |     else | ||||||
| 	# Solaris x86 | 	# Solaris x86 | ||||||
|  |  | ||||||
|  | @ -139,6 +139,20 @@ cleanup: | ||||||
|         PKIX_RETURN(OCSPCHECKER); |         PKIX_RETURN(OCSPCHECKER); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * FUNCTION: pkix_OcspChecker_MapResultCodeToRevStatus | ||||||
|  |  */ | ||||||
|  | PKIX_RevocationStatus | ||||||
|  | pkix_OcspChecker_MapResultCodeToRevStatus(SECErrorCodes resultCode) | ||||||
|  | { | ||||||
|  |         switch (resultCode) { | ||||||
|  |             case SEC_ERROR_REVOKED_CERTIFICATE: | ||||||
|  |                 return PKIX_RevStatus_Revoked; | ||||||
|  |             default: | ||||||
|  |                 return PKIX_RevStatus_NoInfo; | ||||||
|  |         } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* --Public-Functions--------------------------------------------- */ | /* --Public-Functions--------------------------------------------- */ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -198,7 +212,7 @@ pkix_OcspChecker_CheckLocal( | ||||||
|                 revStatus = PKIX_RevStatus_Success; |                 revStatus = PKIX_RevStatus_Success; | ||||||
|                 resultCode = 0; |                 resultCode = 0; | ||||||
|             } else { |             } else { | ||||||
|                 revStatus = PKIX_RevStatus_Revoked; |                 revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -326,7 +340,7 @@ pkix_OcspChecker_CheckExternal( | ||||||
|                                                   plContext), |                                                   plContext), | ||||||
|             PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED); |             PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED); | ||||||
|         if (passed == PKIX_FALSE) { |         if (passed == PKIX_FALSE) { | ||||||
|             revStatus = PKIX_RevStatus_Revoked; |             revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode); | ||||||
|         } else { |         } else { | ||||||
|             revStatus = PKIX_RevStatus_Success; |             revStatus = PKIX_RevStatus_Success; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -395,7 +395,10 @@ pkix_hash( | ||||||
|         PKIX_UInt32 hash; |         PKIX_UInt32 hash; | ||||||
| 
 | 
 | ||||||
|         PKIX_ENTER(OBJECT, "pkix_hash"); |         PKIX_ENTER(OBJECT, "pkix_hash"); | ||||||
|         PKIX_NULLCHECK_TWO(bytes, pHash); |         if (length != 0) { | ||||||
|  |                 PKIX_NULLCHECK_ONE(bytes); | ||||||
|  |         } | ||||||
|  |         PKIX_NULLCHECK_ONE(pHash); | ||||||
| 
 | 
 | ||||||
|         hash = 0; |         hash = 0; | ||||||
|         for (i = 0; i < length; i++) { |         for (i = 0; i < length; i++) { | ||||||
|  |  | ||||||
|  | @ -48,11 +48,11 @@ DEPTH      = ../.. | ||||||
| #  smime | #  smime | ||||||
| #  ckfw (builtins module) | #  ckfw (builtins module) | ||||||
| #  crmf jar (not dll's) | #  crmf jar (not dll's) | ||||||
| DIRS =  util freebl softoken \ | DIRS =  util freebl $(SQLITE_SRCDIR) softoken \ | ||||||
| 	base dev pki pki1 \ | 	base dev pki pki1 \ | ||||||
| 	libpkix \ | 	libpkix \ | ||||||
| 	certdb certhigh pk11wrap cryptohi nss \ | 	certdb certhigh pk11wrap cryptohi nss \ | ||||||
| 	ssl \ | 	$(ZLIB_SRCDIR) ssl \ | ||||||
| 	pkcs12 pkcs7 smime \ | 	pkcs12 pkcs7 smime \ | ||||||
| 	crmf jar \ | 	crmf jar \ | ||||||
| 	ckfw      \ | 	ckfw      \ | ||||||
|  |  | ||||||
|  | @ -35,11 +35,6 @@ | ||||||
| #
 | #
 | ||||||
| # ***** END LICENSE BLOCK *****
 | # ***** END LICENSE BLOCK *****
 | ||||||
| 
 | 
 | ||||||
| #
 |  | ||||||
| #  Override TARGETS variable so that only static libraries
 |  | ||||||
| #  are specifed as dependencies within rules.mk.
 |  | ||||||
| #
 |  | ||||||
| 
 |  | ||||||
| # can't do this in manifest.mn because OS_TARGET isn't defined there.
 | # can't do this in manifest.mn because OS_TARGET isn't defined there.
 | ||||||
| ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -979,3 +979,21 @@ SECMOD_OpenNewSlot; | ||||||
| ;+    local: | ;+    local: | ||||||
| ;+       *; | ;+       *; | ||||||
| ;+}; | ;+}; | ||||||
|  | ;+NSS_3.12.5 { 	# NSS 3.12.5 release | ||||||
|  | ;+    global: | ||||||
|  | CERT_AddCertToListSorted; | ||||||
|  | NSS_InitContext; | ||||||
|  | NSS_ShutdownContext; | ||||||
|  | SECMOD_GetDefaultModDBFlag; | ||||||
|  | SECMOD_GetSkipFirstFlag; | ||||||
|  | ;+    local: | ||||||
|  | ;+       *; | ||||||
|  | ;+}; | ||||||
|  | ;+NSS_3.12.6 { 	# NSS 3.12.6 release | ||||||
|  | ;+    global: | ||||||
|  | CERT_CacheOCSPResponseFromSideChannel; | ||||||
|  | CERT_DistNamesFromCertList; | ||||||
|  | CERT_DupDistNames; | ||||||
|  | ;+    local: | ||||||
|  | ;+       *; | ||||||
|  | ;+}; | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: nss.h,v 1.69 2009/08/13 18:11:22 christophe.ravel.bugs%sun.com Exp $ */ | /* $Id: nss.h,v 1.74 2009/11/20 20:15:05 christophe.ravel.bugs%sun.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #ifndef __nss_h_ | #ifndef __nss_h_ | ||||||
| #define __nss_h_ | #define __nss_h_ | ||||||
|  | @ -60,22 +60,97 @@ | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * NSS's major version, minor version, patch level, and whether |  * NSS's major version, minor version, patch level, build number, and whether | ||||||
|  * this is a beta release. |  * this is a beta release. | ||||||
|  * |  * | ||||||
|  * The format of the version string should be |  * The format of the version string should be | ||||||
|  *     "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" |  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" | ||||||
|  */ |  */ | ||||||
| #define NSS_VERSION  "3.12.4.5" _NSS_ECC_STRING _NSS_CUSTOMIZED | #define NSS_VERSION  "3.12.6.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta" | ||||||
| #define NSS_VMAJOR   3 | #define NSS_VMAJOR   3 | ||||||
| #define NSS_VMINOR   12 | #define NSS_VMINOR   12 | ||||||
| #define NSS_VPATCH   4 | #define NSS_VPATCH   6 | ||||||
| #define NSS_BETA     PR_FALSE | #define NSS_VBUILD   0 | ||||||
|  | #define NSS_BETA     PR_TRUE | ||||||
| 
 | 
 | ||||||
| #ifndef RC_INVOKED | #ifndef RC_INVOKED | ||||||
| 
 | 
 | ||||||
| #include "seccomon.h" | #include "seccomon.h" | ||||||
| 
 | 
 | ||||||
|  | typedef struct NSSInitParametersStr NSSInitParameters; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * parameters used to initialize softoken. Mostly strings used to  | ||||||
|  |  * internationalize softoken. Memory for the strings are owned by the caller, | ||||||
|  |  * who is free to free them once NSS_ContextInit returns. If the string  | ||||||
|  |  * parameter is NULL (as opposed to empty, zero length), then the softoken | ||||||
|  |  * default is used. These are equivalent to the parameters for  | ||||||
|  |  * PK11_ConfigurePKCS11(). | ||||||
|  |  * | ||||||
|  |  * field names match their equivalent parameter names for softoken strings  | ||||||
|  |  * documented at https://developer.mozilla.org/en/PKCS11_Module_Specs.
 | ||||||
|  |  *  | ||||||
|  |  * minPWLen  | ||||||
|  |  *     Minimum password length in bytes.  | ||||||
|  |  * manufacturerID  | ||||||
|  |  *     Override the default manufactureID value for the module returned in  | ||||||
|  |  *     the CK_INFO, CK_SLOT_INFO, and CK_TOKEN_INFO structures with an  | ||||||
|  |  *     internationalize string (UTF8). This value will be truncated at 32  | ||||||
|  |  *     bytes (not including the trailing NULL, partial UTF8 characters will be | ||||||
|  |  *     dropped).  | ||||||
|  |  * libraryDescription  | ||||||
|  |  *     Override the default libraryDescription value for the module returned in | ||||||
|  |  *     the CK_INFO structure with an internationalize string (UTF8). This value | ||||||
|  |  *     will be truncated at 32 bytes(not including the trailing NULL, partial  | ||||||
|  |  *     UTF8 characters will be dropped).  | ||||||
|  |  * cryptoTokenDescription  | ||||||
|  |  *     Override the default label value for the internal crypto token returned | ||||||
|  |  *     in the CK_TOKEN_INFO structure with an internationalize string (UTF8). | ||||||
|  |  *     This value will be truncated at 32 bytes (not including the trailing | ||||||
|  |  *     NULL, partial UTF8 characters will be dropped).  | ||||||
|  |  * dbTokenDescription  | ||||||
|  |  *     Override the default label value for the internal DB token returned in  | ||||||
|  |  *     the CK_TOKEN_INFO structure with an internationalize string (UTF8). This | ||||||
|  |  *     value will be truncated at 32 bytes (not including the trailing NULL, | ||||||
|  |  *     partial UTF8 characters will be dropped).  | ||||||
|  |  * FIPSTokenDescription  | ||||||
|  |  *     Override the default label value for the internal FIPS token returned in | ||||||
|  |  *     the CK_TOKEN_INFO structure with an internationalize string (UTF8). This | ||||||
|  |  *     value will be truncated at 32 bytes (not including the trailing NULL, | ||||||
|  |  *     partial UTF8 characters will be dropped).  | ||||||
|  |  * cryptoSlotDescription  | ||||||
|  |  *     Override the default slotDescription value for the internal crypto token | ||||||
|  |  *     returned in the CK_SLOT_INFO structure with an internationalize string | ||||||
|  |  *     (UTF8). This value will be truncated at 64 bytes (not including the | ||||||
|  |  *     trailing NULL, partial UTF8 characters will be dropped).  | ||||||
|  |  * dbSlotDescription  | ||||||
|  |  *     Override the default slotDescription value for the internal DB token  | ||||||
|  |  *     returned in the CK_SLOT_INFO structure with an internationalize string  | ||||||
|  |  *     (UTF8). This value will be truncated at 64 bytes (not including the | ||||||
|  |  *     trailing NULL, partial UTF8 characters will be dropped).  | ||||||
|  |  * FIPSSlotDescription  | ||||||
|  |  *     Override the default slotDecription value for the internal FIPS token | ||||||
|  |  *     returned in the CK_SLOT_INFO structure with an internationalize string | ||||||
|  |  *     (UTF8). This value will be truncated at 64 bytes (not including the | ||||||
|  |  *     trailing NULL, partial UTF8 characters will be dropped).  | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | struct NSSInitParametersStr { | ||||||
|  |    unsigned int	  length;      /* allow this structure to grow in the future,
 | ||||||
|  | 				* must be set */ | ||||||
|  |    PRBool passwordRequired; | ||||||
|  |    int    minPWLen; | ||||||
|  |    char * manufactureID;           /* variable names for strings match the */ | ||||||
|  |    char * libraryDescription;      /*   parameter name in softoken */ | ||||||
|  |    char * cryptoTokenDescription; | ||||||
|  |    char * dbTokenDescription; | ||||||
|  |    char * FIPSTokenDescription; | ||||||
|  |    char * cryptoSlotDescription; | ||||||
|  |    char * dbSlotDescription; | ||||||
|  |    char * FIPSSlotDescription; | ||||||
|  | }; | ||||||
|  |     | ||||||
|  | 
 | ||||||
| SEC_BEGIN_PROTOS | SEC_BEGIN_PROTOS | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -194,10 +269,19 @@ extern SECStatus NSS_InitReadWrite(const char *configdir); | ||||||
| #define SECMOD_DB "secmod.db" | #define SECMOD_DB "secmod.db" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | typedef struct NSSInitContextStr NSSInitContext; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| extern SECStatus NSS_Initialize(const char *configdir,  | extern SECStatus NSS_Initialize(const char *configdir,  | ||||||
| 	const char *certPrefix, const char *keyPrefix,  | 	const char *certPrefix, const char *keyPrefix,  | ||||||
| 	const char *secmodName, PRUint32 flags); | 	const char *secmodName, PRUint32 flags); | ||||||
| 
 | 
 | ||||||
|  | extern NSSInitContext *NSS_InitContext(const char *configdir,  | ||||||
|  | 	const char *certPrefix, const char *keyPrefix,  | ||||||
|  | 	const char *secmodName, NSSInitParameters *initParams, PRUint32 flags); | ||||||
|  | 
 | ||||||
|  | extern SECStatus NSS_ShutdownContext(NSSInitContext *); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * same as NSS_Init, but checks to see if we need to merge an |  * same as NSS_Init, but checks to see if we need to merge an | ||||||
|  * old database in. |  * old database in. | ||||||
|  | @ -251,9 +335,9 @@ extern SECStatus NSS_Shutdown(void); | ||||||
| /*
 | /*
 | ||||||
|  * set the PKCS #11 strings for the internal token. |  * set the PKCS #11 strings for the internal token. | ||||||
|  */ |  */ | ||||||
| void PK11_ConfigurePKCS11(const char *man, const char *libdes,  | void PK11_ConfigurePKCS11(const char *man, const char *libdesc,  | ||||||
| 	const char *tokdes, const char *ptokdes, const char *slotdes,  | 	const char *tokdesc, const char *ptokdesc, const char *slotdesc,  | ||||||
| 	const char *pslotdes, const char *fslotdes, const char *fpslotdes, | 	const char *pslotdesc, const char *fslotdesc, const char *fpslotdesc, | ||||||
|         int minPwd, int pwRequired); |         int minPwd, int pwRequired); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  |  | ||||||
|  | @ -71,8 +71,8 @@ | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK |  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK | ||||||
|  FILEFLAGS MY_FILEFLAGS_2 |  FILEFLAGS MY_FILEFLAGS_2 | ||||||
|  FILEOS MY_FILEOS |  FILEOS MY_FILEOS | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: nssinit.c,v 1.99 2009/07/23 01:56:40 nelson%bolyard.com Exp $ */ | /* $Id: nssinit.c,v 1.105 2010/01/22 02:10:54 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | @ -46,8 +46,6 @@ | ||||||
| #include "prmem.h" | #include "prmem.h" | ||||||
| #include "cert.h" | #include "cert.h" | ||||||
| #include "key.h" | #include "key.h" | ||||||
| #include "ssl.h" |  | ||||||
| #include "sslproto.h" |  | ||||||
| #include "secmod.h" | #include "secmod.h" | ||||||
| #include "secoid.h" | #include "secoid.h" | ||||||
| #include "nss.h" | #include "nss.h" | ||||||
|  | @ -128,6 +126,89 @@ nss_makeFlags(PRBool readOnly, PRBool noCertDB, | ||||||
|     return flags; |     return flags; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * build config string from individual internationalized strings | ||||||
|  |  */ | ||||||
|  | char * | ||||||
|  | nss_MkConfigString(const char *man, const char *libdesc, const char *tokdesc, | ||||||
|  | 	const char *ptokdesc, const char *slotdesc, const char *pslotdesc,  | ||||||
|  | 	const char *fslotdesc, const char *fpslotdesc, int minPwd) | ||||||
|  | { | ||||||
|  |     char *strings = NULL; | ||||||
|  |     char *newStrings; | ||||||
|  | 
 | ||||||
|  |     /* make sure the internationalization was done correctly... */ | ||||||
|  |     strings = PR_smprintf(""); | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (man) { | ||||||
|  |         newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (libdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (tokdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s cryptoTokenDescription='%s'",strings, | ||||||
|  | 								tokdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (ptokdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (slotdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s cryptoSlotDescription='%s'",strings, | ||||||
|  | 								slotdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (pslotdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (fslotdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s FIPSSlotDescription='%s'", | ||||||
|  | 							strings,fslotdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     if (fpslotdesc) { | ||||||
|  |         newStrings = PR_smprintf("%s FIPSTokenDescription='%s'", | ||||||
|  | 							strings,fpslotdesc); | ||||||
|  | 	PR_smprintf_free(strings); | ||||||
|  | 	strings = newStrings; | ||||||
|  |     } | ||||||
|  |     if (strings == NULL) return NULL; | ||||||
|  | 
 | ||||||
|  |     newStrings = PR_smprintf("%s minPS=%d", strings, minPwd); | ||||||
|  |     PR_smprintf_free(strings); | ||||||
|  |     strings = newStrings; | ||||||
|  | 
 | ||||||
|  |     return(strings); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * statics to remember the PK11_ConfigurePKCS11() |  * statics to remember the PK11_ConfigurePKCS11() | ||||||
|  * info. |  * info. | ||||||
|  | @ -141,85 +222,25 @@ static PRBool pk11_password_required = PR_FALSE; | ||||||
|  * the PKCS #11 internal token. |  * the PKCS #11 internal token. | ||||||
|  */ |  */ | ||||||
| void | void | ||||||
| PK11_ConfigurePKCS11(const char *man, const char *libdes, const char *tokdes, | PK11_ConfigurePKCS11(const char *man, const char *libdesc, const char *tokdesc, | ||||||
| 	const char *ptokdes, const char *slotdes, const char *pslotdes,  | 	const char *ptokdesc, const char *slotdesc, const char *pslotdesc,  | ||||||
| 	const char *fslotdes, const char *fpslotdes, int minPwd, int pwRequired) | 	const char *fslotdesc, const char *fpslotdesc, int minPwd,  | ||||||
|  | 	int pwRequired) | ||||||
| { | { | ||||||
|    char *strings = NULL; |     char * strings; | ||||||
|    char *newStrings; |  | ||||||
| 
 | 
 | ||||||
|    /* make sure the internationalization was done correctly... */ |     strings = nss_MkConfigString(man,libdesc,tokdesc,ptokdesc,slotdesc, | ||||||
|    strings = PR_smprintf(""); | 	pslotdesc,fslotdesc,fpslotdesc,minPwd); | ||||||
|    if (strings == NULL) return; |     if (strings == NULL) { | ||||||
| 
 | 	return; | ||||||
|     if (man) { |  | ||||||
|         newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |     } | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 | 
 | ||||||
|     if (libdes) { |     if (libdesc) { | ||||||
|         newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
| 	if (pk11_config_name != NULL) { | 	if (pk11_config_name != NULL) { | ||||||
| 	    PORT_Free(pk11_config_name); | 	    PORT_Free(pk11_config_name); | ||||||
| 	} | 	} | ||||||
| 	pk11_config_name = PORT_Strdup(libdes); | 	pk11_config_name = PORT_Strdup(libdesc); | ||||||
|     } |     } | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (tokdes) { |  | ||||||
|         newStrings = PR_smprintf("%s cryptoTokenDescription='%s'",strings, |  | ||||||
| 								tokdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (ptokdes) { |  | ||||||
|         newStrings = PR_smprintf("%s dbTokenDescription='%s'",strings,ptokdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (slotdes) { |  | ||||||
|         newStrings = PR_smprintf("%s cryptoSlotDescription='%s'",strings, |  | ||||||
| 								slotdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (pslotdes) { |  | ||||||
|         newStrings = PR_smprintf("%s dbSlotDescription='%s'",strings,pslotdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (fslotdes) { |  | ||||||
|         newStrings = PR_smprintf("%s FIPSSlotDescription='%s'", |  | ||||||
| 							strings,fslotdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     if (fpslotdes) { |  | ||||||
|         newStrings = PR_smprintf("%s FIPSTokenDescription='%s'", |  | ||||||
| 							strings,fpslotdes); |  | ||||||
| 	PR_smprintf_free(strings); |  | ||||||
| 	strings = newStrings; |  | ||||||
|     } |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 |  | ||||||
|     newStrings = PR_smprintf("%s minPS=%d", strings, minPwd); |  | ||||||
|     PR_smprintf_free(strings); |  | ||||||
|     strings = newStrings; |  | ||||||
|    if (strings == NULL) return; |  | ||||||
| 
 | 
 | ||||||
|     if (pk11_config_strings != NULL) { |     if (pk11_config_strings != NULL) { | ||||||
| 	PR_smprintf_free(pk11_config_strings); | 	PR_smprintf_free(pk11_config_strings); | ||||||
|  | @ -242,56 +263,6 @@ void PK11_UnconfigurePKCS11(void) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static char * |  | ||||||
| nss_addEscape(const char *string, char quote) |  | ||||||
| { |  | ||||||
|     char *newString = 0; |  | ||||||
|     int escapes = 0, size = 0; |  | ||||||
|     const char *src; |  | ||||||
|     char *dest; |  | ||||||
| 
 |  | ||||||
|     for (src=string; *src ; src++) { |  | ||||||
| 	if ((*src == quote) || (*src == '\\')) escapes++; |  | ||||||
| 	size++; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     newString = PORT_ZAlloc(escapes+size+1);  |  | ||||||
|     if (newString == NULL) { |  | ||||||
| 	return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for (src=string, dest=newString; *src; src++,dest++) { |  | ||||||
| 	if ((*src == '\\') || (*src == quote)) { |  | ||||||
| 	    *dest++ = '\\'; |  | ||||||
| 	} |  | ||||||
| 	*dest = *src; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return newString; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static char * |  | ||||||
| nss_doubleEscape(const char *string) |  | ||||||
| { |  | ||||||
|     char *round1 = NULL; |  | ||||||
|     char *retValue = NULL; |  | ||||||
|     if (string == NULL) { |  | ||||||
| 	goto done; |  | ||||||
|     } |  | ||||||
|     round1 = nss_addEscape(string,'\''); |  | ||||||
|     if (round1) { |  | ||||||
| 	retValue = nss_addEscape(round1,'"'); |  | ||||||
| 	PORT_Free(round1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| done: |  | ||||||
|     if (retValue == NULL) { |  | ||||||
| 	retValue = PORT_Strdup(""); |  | ||||||
|     } |  | ||||||
|     return retValue; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * The following code is an attempt to automagically find the external root |  * The following code is an attempt to automagically find the external root | ||||||
|  * module. |  * module. | ||||||
|  | @ -389,46 +360,25 @@ nss_FindExternalRoot(const char *dbpath, const char* secmodprefix) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * OK there are now lots of options here, lets go through them all: |  * see nss_Init for definitions of the various options. | ||||||
|  * |  * | ||||||
|  * configdir - base directory where all the cert, key, and module datbases live. |  * this function builds a moduleSpec string from the options and previously | ||||||
|  * certPrefix - prefix added to the beginning of the cert database example: " |  * set statics (from PKCS11_Configure, for instance), and uses it to kick off | ||||||
|  * 			"https-server1-" |  * the loading of the various PKCS #11 modules. | ||||||
|  * keyPrefix - prefix added to the beginning of the key database example: " |  | ||||||
|  * 			"https-server1-" |  | ||||||
|  * secmodName - name of the security module database (usually "secmod.db"). |  | ||||||
|  * readOnly - Boolean: true if the databases are to be opened read only. |  | ||||||
|  * nocertdb - Don't open the cert DB and key DB's, just initialize the  |  | ||||||
|  *			Volatile certdb. |  | ||||||
|  * nomoddb - Don't open the security module DB, just initialize the  |  | ||||||
|  *			PKCS #11 module. |  | ||||||
|  * forceOpen - Continue to force initializations even if the databases cannot |  | ||||||
|  * 			be opened. |  | ||||||
|  */ |  */ | ||||||
| 
 |  | ||||||
| static PRBool nss_IsInitted = PR_FALSE; |  | ||||||
| static void* plContext = NULL; |  | ||||||
| 
 |  | ||||||
| static SECStatus nss_InitShutdownList(void); |  | ||||||
| 
 |  | ||||||
| #ifdef DEBUG |  | ||||||
| static CERTCertificate dummyCert; |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| static SECStatus | static SECStatus | ||||||
| nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, | nss_InitModules(const char *configdir, const char *certPrefix,  | ||||||
| 		 const char *secmodName, const char *updateDir,  | 		const char *keyPrefix, const char *secmodName,  | ||||||
| 		 const char *updCertPrefix, const char *updKeyPrefix, | 		const char *updateDir, const char *updCertPrefix,  | ||||||
| 		 const char *updateID, const char *updateName, | 		const char *updKeyPrefix, const char *updateID,  | ||||||
| 			PRBool readOnly, PRBool noCertDB,  | 		const char *updateName, char *configName, char *configStrings, | ||||||
| 			PRBool noModDB, PRBool forceOpen, PRBool noRootInit, | 		PRBool pwRequired, PRBool readOnly, PRBool noCertDB, | ||||||
| 			PRBool optimizeSpace, PRBool noSingleThreadedModules, | 		PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace, | ||||||
| 			PRBool allowAlreadyInitializedModules, | 		PRBool isContextInit) | ||||||
| 			PRBool dontFinalizeModules) |  | ||||||
| { | { | ||||||
|  |     SECStatus rv = SECFailure; | ||||||
|     char *moduleSpec = NULL; |     char *moduleSpec = NULL; | ||||||
|     char *flags = NULL; |     char *flags = NULL; | ||||||
|     SECStatus rv = SECFailure; |  | ||||||
|     char *lconfigdir = NULL; |     char *lconfigdir = NULL; | ||||||
|     char *lcertPrefix = NULL; |     char *lcertPrefix = NULL; | ||||||
|     char *lkeyPrefix = NULL; |     char *lkeyPrefix = NULL; | ||||||
|  | @ -438,88 +388,62 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, | ||||||
|     char *lupdKeyPrefix = NULL; |     char *lupdKeyPrefix = NULL; | ||||||
|     char *lupdateID = NULL; |     char *lupdateID = NULL; | ||||||
|     char *lupdateName = NULL; |     char *lupdateName = NULL; | ||||||
|     PKIX_UInt32 actualMinorVersion = 0; |  | ||||||
|     PKIX_Error *pkixError = NULL;; |  | ||||||
| 
 |  | ||||||
|     if (nss_IsInitted) { |  | ||||||
| 	return SECSuccess; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* New option bits must not change the size of CERTCertificate. */ |  | ||||||
|     PORT_Assert(sizeof(dummyCert.options) == sizeof(void *)); |  | ||||||
| 
 |  | ||||||
|     if (SECSuccess != cert_InitLocks()) { |  | ||||||
|         return SECFailure; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (SECSuccess != InitCRLCache()) { |  | ||||||
|         return SECFailure; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (SECSuccess != OCSP_InitGlobal()) { |  | ||||||
|         return SECFailure; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen, |     flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen, | ||||||
| 					pk11_password_required, optimizeSpace); | 					pwRequired, optimizeSpace); | ||||||
|     if (flags == NULL) return rv; |     if (flags == NULL) return rv; | ||||||
| 
 | 
 | ||||||
|     /*
 |     /*
 | ||||||
|      * configdir is double nested, and Windows uses the same character |      * configdir is double nested, and Windows uses the same character | ||||||
|      * for file seps as we use for escapes! (sigh). |      * for file seps as we use for escapes! (sigh). | ||||||
|      */ |      */ | ||||||
|     lconfigdir = nss_doubleEscape(configdir); |     lconfigdir = secmod_DoubleEscape(configdir, '\'', '\"'); | ||||||
|     if (lconfigdir == NULL) { |     if (lconfigdir == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lcertPrefix = nss_doubleEscape(certPrefix); |     lcertPrefix = secmod_DoubleEscape(certPrefix, '\'', '\"'); | ||||||
|     if (lcertPrefix == NULL) { |     if (lcertPrefix == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lkeyPrefix = nss_doubleEscape(keyPrefix); |     lkeyPrefix = secmod_DoubleEscape(keyPrefix, '\'', '\"'); | ||||||
|     if (lkeyPrefix == NULL) { |     if (lkeyPrefix == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lsecmodName = nss_doubleEscape(secmodName); |     lsecmodName = secmod_DoubleEscape(secmodName, '\'', '\"'); | ||||||
|     if (lsecmodName == NULL) { |     if (lsecmodName == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lupdateDir = nss_doubleEscape(updateDir); |     lupdateDir = secmod_DoubleEscape(updateDir, '\'', '\"'); | ||||||
|     if (lupdateDir == NULL) { |     if (lupdateDir == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lupdCertPrefix = nss_doubleEscape(updCertPrefix); |     lupdCertPrefix = secmod_DoubleEscape(updCertPrefix, '\'', '\"'); | ||||||
|     if (lupdCertPrefix == NULL) { |     if (lupdCertPrefix == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lupdKeyPrefix = nss_doubleEscape(updKeyPrefix); |     lupdKeyPrefix = secmod_DoubleEscape(updKeyPrefix, '\'', '\"'); | ||||||
|     if (lupdKeyPrefix == NULL) { |     if (lupdKeyPrefix == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lupdateID = nss_doubleEscape(updateID); |     lupdateID = secmod_DoubleEscape(updateID, '\'', '\"'); | ||||||
|     if (lupdateID == NULL) { |     if (lupdateID == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     lupdateName = nss_doubleEscape(updateName); |     lupdateName = secmod_DoubleEscape(updateName, '\'', '\"'); | ||||||
|     if (lupdateName == NULL) { |     if (lupdateName == NULL) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|     if (noSingleThreadedModules || allowAlreadyInitializedModules || |  | ||||||
|         dontFinalizeModules) { |  | ||||||
|         pk11_setGlobalOptions(noSingleThreadedModules, |  | ||||||
|                               allowAlreadyInitializedModules, |  | ||||||
|                               dontFinalizeModules); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     moduleSpec = PR_smprintf( |     moduleSpec = PR_smprintf( | ||||||
|      "name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' " |      "name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' " | ||||||
|      "secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' " |      "secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' " | ||||||
|      "updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" " |      "updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" " | ||||||
|      "NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"", |      "NSS=\"flags=internal,moduleDB,moduleDBOnly,critical%s\"", | ||||||
| 		pk11_config_name ? pk11_config_name : NSS_DEFAULT_MOD_NAME, | 		configName ? configName : NSS_DEFAULT_MOD_NAME, | ||||||
| 		lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags, | 		lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags, | ||||||
| 		lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,  | 		lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,  | ||||||
| 		lupdateName, pk11_config_strings ? pk11_config_strings : ""); | 		lupdateName, configStrings ? configStrings : "", | ||||||
|  | 		isContextInit ? "" : ",defaultModDB,internalKeySlot"); | ||||||
| 
 | 
 | ||||||
| loser: | loser: | ||||||
|     PORT_Free(flags); |     PORT_Free(flags); | ||||||
|  | @ -541,65 +465,262 @@ loser: | ||||||
| 	    SECMOD_DestroyModule(module); | 	    SECMOD_DestroyModule(module); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |     return rv; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     if (rv == SECSuccess) { | /*
 | ||||||
| 	if (SECOID_Init() != SECSuccess) { |  * OK there are now lots of options here, lets go through them all: | ||||||
|  |  * | ||||||
|  |  * 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"). | ||||||
|  |  * updateDir - used in initMerge, old directory to update from. | ||||||
|  |  * updateID - used in initMerge, unique ID to represent the updated directory. | ||||||
|  |  * updateName - used in initMerge, token name when updating. | ||||||
|  |  * initContextPtr -  used in initContext, pointer to return a unique context | ||||||
|  |  *            value. | ||||||
|  |  * readOnly - Boolean: true if the databases are to be opened read only. | ||||||
|  |  * nocertdb - Don't open the cert DB and key DB's, just initialize the  | ||||||
|  |  *			Volatile certdb. | ||||||
|  |  * nomoddb - Don't open the security module DB, just initialize the  | ||||||
|  |  *			PKCS #11 module. | ||||||
|  |  * forceOpen - Continue to force initializations even if the databases cannot | ||||||
|  |  * 			be opened. | ||||||
|  |  * noRootInit - don't try to automatically load the root cert store if one is | ||||||
|  |  *           not found. | ||||||
|  |  * optimizeSpace - tell NSS to use fewer hash table buckets. | ||||||
|  |  * | ||||||
|  |  * The next three options are used in an attempt to share PKCS #11 modules | ||||||
|  |  * with other loaded, running libraries. PKCS #11 was not designed with this | ||||||
|  |  * sort of sharing in mind, so use of these options may lead to questionable | ||||||
|  |  * results. These options are may be incompatible with NSS_LoadContext() calls. | ||||||
|  |  * | ||||||
|  |  * noSingleThreadedModules - don't load modules that are not thread safe (many | ||||||
|  |  *           smart card tokens will not work). | ||||||
|  |  * allowAlreadyInitializedModules - if a module has already been loaded and | ||||||
|  |  *           initialize try to use it. | ||||||
|  |  * don'tFinalizeModules -  dont shutdown modules we may have loaded. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | static PRBool          nssIsInitted = PR_FALSE; | ||||||
|  | static NSSInitContext *nssInitContextList = NULL; | ||||||
|  | static void*           plContext = NULL; | ||||||
|  | 
 | ||||||
|  | struct NSSInitContextStr { | ||||||
|  |     NSSInitContext *next; | ||||||
|  |     PRUint32 magic; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define NSS_INIT_MAGIC 0x1413A91C | ||||||
|  | static SECStatus nss_InitShutdownList(void); | ||||||
|  | 
 | ||||||
|  | #ifdef DEBUG | ||||||
|  | static CERTCertificate dummyCert; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static SECStatus | ||||||
|  | nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix, | ||||||
|  | 		 const char *secmodName, const char *updateDir,  | ||||||
|  | 		 const char *updCertPrefix, const char *updKeyPrefix, | ||||||
|  | 		 const char *updateID, const char *updateName, | ||||||
|  | 		 NSSInitContext ** initContextPtr, | ||||||
|  | 		 NSSInitParameters *initParams, | ||||||
|  | 		 PRBool readOnly, PRBool noCertDB,  | ||||||
|  | 		 PRBool noModDB, PRBool forceOpen, PRBool noRootInit, | ||||||
|  | 		 PRBool optimizeSpace, PRBool noSingleThreadedModules, | ||||||
|  | 		 PRBool allowAlreadyInitializedModules, | ||||||
|  | 		 PRBool dontFinalizeModules) | ||||||
|  | { | ||||||
|  |     SECStatus rv = SECFailure; | ||||||
|  |     PKIX_UInt32 actualMinorVersion = 0; | ||||||
|  |     PKIX_Error *pkixError = NULL; | ||||||
|  |     PRBool isReallyInitted; | ||||||
|  |     char *configStrings = NULL; | ||||||
|  |     char *configName = NULL; | ||||||
|  |     PRBool passwordRequired = PR_FALSE; | ||||||
|  | 
 | ||||||
|  |     /* if we are trying to init with a traditional NSS_Init call, maintain
 | ||||||
|  |      * the traditional idempotent behavior. */ | ||||||
|  |     if (!initContextPtr && nssIsInitted) { | ||||||
|  | 	return SECSuccess; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* this tells us whether or not some library has already initialized us.
 | ||||||
|  |      * if so, we don't want to double call some of the basic initialization | ||||||
|  |      * functions */ | ||||||
|  |     isReallyInitted = NSS_IsInitialized(); | ||||||
|  | 
 | ||||||
|  |     if (!isReallyInitted) { | ||||||
|  | 	/* New option bits must not change the size of CERTCertificate. */ | ||||||
|  | 	PORT_Assert(sizeof(dummyCert.options) == sizeof(void *)); | ||||||
|  | 
 | ||||||
|  | 	if (SECSuccess != cert_InitLocks()) { | ||||||
|             return SECFailure; |             return SECFailure; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if (SECSuccess != InitCRLCache()) { | ||||||
|  |             return SECFailure; | ||||||
|  | 	} | ||||||
|  |      | ||||||
|  | 	if (SECSuccess != OCSP_InitGlobal()) { | ||||||
|  |             return SECFailure; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (noSingleThreadedModules || allowAlreadyInitializedModules || | ||||||
|  |         dontFinalizeModules) { | ||||||
|  |         pk11_setGlobalOptions(noSingleThreadedModules, | ||||||
|  |                               allowAlreadyInitializedModules, | ||||||
|  |                               dontFinalizeModules); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (initContextPtr) { | ||||||
|  | 	*initContextPtr = PORT_ZNew(NSSInitContext); | ||||||
|  | 	if (*initContextPtr == NULL) { | ||||||
|  | 	    return SECFailure; | ||||||
|  | 	} | ||||||
|  | 	/*
 | ||||||
|  | 	 * For traditional NSS_Init, we used the PK11_Configure() call to set | ||||||
|  | 	 * globals. with InitContext, we pass those strings in as parameters. | ||||||
|  | 	 * | ||||||
|  | 	 * This allows old NSS_Init calls to work as before, while at the same | ||||||
|  | 	 * time new calls and old calls will not interfere with each other. | ||||||
|  | 	 */ | ||||||
|  |         if (initParams) { | ||||||
|  | 	    if (initParams->length < sizeof(NSSInitParameters)) { | ||||||
|  | 		PORT_SetError(SEC_ERROR_INVALID_ARGS); | ||||||
|  | 		return SECFailure; | ||||||
|  | 	    } | ||||||
|  | 	    configStrings = nss_MkConfigString(initParams->manufactureID, | ||||||
|  | 		initParams->libraryDescription, | ||||||
|  | 		initParams->cryptoTokenDescription, | ||||||
|  | 		initParams->dbTokenDescription, | ||||||
|  | 		initParams->cryptoSlotDescription, | ||||||
|  | 		initParams->dbSlotDescription, | ||||||
|  | 		initParams->FIPSSlotDescription, | ||||||
|  | 		initParams->FIPSTokenDescription, | ||||||
|  | 		initParams->minPWLen); | ||||||
|  | 	    if (configStrings == NULL) { | ||||||
|  | 		PORT_SetError(SEC_ERROR_NO_MEMORY); | ||||||
|  | 		return SECFailure; | ||||||
|  | 	    } | ||||||
|  | 	    configName = initParams->libraryDescription; | ||||||
|  | 	    passwordRequired = initParams->passwordRequired; | ||||||
|  | 	} | ||||||
|  |     } else { | ||||||
|  | 	configStrings = pk11_config_strings; | ||||||
|  | 	configName = pk11_config_name; | ||||||
|  | 	passwordRequired = pk11_password_required; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* we always try to initialize the modules */ | ||||||
|  |     rv = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName,  | ||||||
|  | 		updateDir, updCertPrefix, updKeyPrefix, updateID,  | ||||||
|  | 		updateName, configName, configStrings, passwordRequired, | ||||||
|  | 		readOnly, noCertDB, noModDB, forceOpen, optimizeSpace,  | ||||||
|  | 		(initContextPtr != NULL)); | ||||||
|  | 
 | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /* finish up initialization */ | ||||||
|  |     if (!isReallyInitted) { | ||||||
|  | 	if (SECOID_Init() != SECSuccess) { | ||||||
|  | 	    goto loser; | ||||||
|  | 	} | ||||||
| 	if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) { | 	if (STAN_LoadDefaultNSS3TrustDomain() != PR_SUCCESS) { | ||||||
| 	    return SECFailure; | 	    goto loser; | ||||||
| 	} | 	} | ||||||
| 	if (nss_InitShutdownList() != SECSuccess) { | 	if (nss_InitShutdownList() != SECSuccess) { | ||||||
| 	    return SECFailure; | 	    goto loser; | ||||||
| 	} | 	} | ||||||
| 	CERT_SetDefaultCertDB((CERTCertDBHandle *) | 	CERT_SetDefaultCertDB((CERTCertDBHandle *) | ||||||
| 				STAN_GetDefaultTrustDomain()); | 				STAN_GetDefaultTrustDomain()); | ||||||
| 	if ((!noModDB) && (!noCertDB) && (!noRootInit)) { | 	if ((!noModDB) && (!noCertDB) && (!noRootInit)) { | ||||||
| 	    if (!SECMOD_HasRootCerts()) { | 	    if (!SECMOD_HasRootCerts()) { | ||||||
| 		const char *dbpath = configdir; | 		const char *dbpath = configdir; | ||||||
|  | 		/* handle supported database modifiers */ | ||||||
| 		if (strncmp(dbpath, "sql:", 4) == 0) { | 		if (strncmp(dbpath, "sql:", 4) == 0) { | ||||||
| 		    dbpath += 4; | 		    dbpath += 4; | ||||||
|  | 		} else if(strncmp(dbpath, "dbm:", 4) == 0) { | ||||||
|  | 		    dbpath += 4; | ||||||
|  | 		} else if(strncmp(dbpath, "extern:", 7) == 0) { | ||||||
|  | 		    dbpath += 7; | ||||||
|  | 		} else if(strncmp(dbpath, "rdb:", 4) == 0) { | ||||||
|  | 		    /* if rdb: is specified, the configdir isn't really a 
 | ||||||
|  | 		     * path. Skip it */ | ||||||
|  | 		    dbpath = NULL; | ||||||
| 		} | 		} | ||||||
|  | 		if (dbpath) { | ||||||
| 		    nss_FindExternalRoot(dbpath, secmodName); | 		    nss_FindExternalRoot(dbpath, secmodName); | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
| 	pk11sdr_Init(); |  | ||||||
| 	cert_CreateSubjectKeyIDHashTable(); |  | ||||||
| 	nss_IsInitted = PR_TRUE; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|     if (SECSuccess == rv) { | 	pk11sdr_Init(); | ||||||
|  | 	cert_CreateSubjectKeyIDHashTable(); | ||||||
|  | 
 | ||||||
| 	pkixError = PKIX_Initialize | 	pkixError = PKIX_Initialize | ||||||
| 	    (PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION, | 	    (PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION, | ||||||
| 	    PKIX_MINOR_VERSION, &actualMinorVersion, &plContext); | 	    PKIX_MINOR_VERSION, &actualMinorVersion, &plContext); | ||||||
| 
 | 
 | ||||||
| 	if (pkixError != NULL) { | 	if (pkixError != NULL) { | ||||||
| 	    rv = SECFailure; | 	    goto loser; | ||||||
| 	} else { | 	} else { | ||||||
|             char *ev = getenv("NSS_ENABLE_PKIX_VERIFY"); |             char *ev = getenv("NSS_ENABLE_PKIX_VERIFY"); | ||||||
|             if (ev && ev[0]) { |             if (ev && ev[0]) { | ||||||
|                 CERT_SetUsePKIXForValidation(PR_TRUE); |                 CERT_SetUsePKIXForValidation(PR_TRUE); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return rv; |     /*
 | ||||||
|  |      * Now mark the appropriate init state. If initContextPtr was passed | ||||||
|  |      * in, then return the new context pointer and add it to the | ||||||
|  |      * nssInitContextList. Otherwise set the global nss_isInitted flag | ||||||
|  |      */ | ||||||
|  |     if (!initContextPtr) { | ||||||
|  | 	nssIsInitted = PR_TRUE; | ||||||
|  |     } else { | ||||||
|  | 	(*initContextPtr)->magic = NSS_INIT_MAGIC; | ||||||
|  | 	(*initContextPtr)->next = nssInitContextList; | ||||||
|  | 	nssInitContextList = (*initContextPtr); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return SECSuccess; | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     if (initContextPtr && *initContextPtr) { | ||||||
|  | 	PORT_Free(*initContextPtr); | ||||||
|  | 	*initContextPtr = NULL; | ||||||
|  | 	if (configStrings) { | ||||||
|  | 	   PR_smprintf_free(configStrings); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     return SECFailure; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| SECStatus | SECStatus | ||||||
| NSS_Init(const char *configdir) | NSS_Init(const char *configdir) | ||||||
| { | { | ||||||
|     return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", |     return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL, | ||||||
| 		PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,  | 		NULL, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,  | ||||||
| 		PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE); | 		PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| SECStatus | SECStatus | ||||||
| NSS_InitReadWrite(const char *configdir) | NSS_InitReadWrite(const char *configdir) | ||||||
| { | { | ||||||
|     return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", |     return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL, | ||||||
| 		PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,  | 		NULL, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,  | ||||||
| 		PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE); | 		PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -656,7 +777,7 @@ NSS_Initialize(const char *configdir, const char *certPrefix, | ||||||
| 	const char *keyPrefix, const char *secmodName, PRUint32 flags) | 	const char *keyPrefix, const char *secmodName, PRUint32 flags) | ||||||
| { | { | ||||||
|     return nss_Init(configdir, certPrefix, keyPrefix, secmodName, |     return nss_Init(configdir, certPrefix, keyPrefix, secmodName, | ||||||
| 	"", "", "", "", "", | 	"", "", "", "", "", NULL, NULL, | ||||||
| 	((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY), | 	((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY), | ||||||
| 	((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB), | 	((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB), | ||||||
| 	((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB), | 	((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB), | ||||||
|  | @ -668,6 +789,27 @@ NSS_Initialize(const char *configdir, const char *certPrefix, | ||||||
|         ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE)); |         ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | NSSInitContext * | ||||||
|  | NSS_InitContext(const char *configdir, const char *certPrefix,  | ||||||
|  | 	const char *keyPrefix, const char *secmodName,  | ||||||
|  | 	NSSInitParameters *initParams, PRUint32 flags) | ||||||
|  | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     NSSInitContext *context; | ||||||
|  | 
 | ||||||
|  |     rv = nss_Init(configdir, certPrefix, keyPrefix, secmodName, | ||||||
|  | 	"", "", "", "", "", &context, initParams, | ||||||
|  | 	((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY), | ||||||
|  | 	((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB), | ||||||
|  | 	((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB), | ||||||
|  | 	((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN), PR_TRUE, | ||||||
|  | 	((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE), | ||||||
|  |         ((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE), | ||||||
|  |         ((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD), | ||||||
|  |         ((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE)); | ||||||
|  |     return (rv == SECSuccess) ? context : NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| SECStatus | SECStatus | ||||||
| NSS_InitWithMerge(const char *configdir, const char *certPrefix,  | NSS_InitWithMerge(const char *configdir, const char *certPrefix,  | ||||||
| 	const char *keyPrefix, const char *secmodName,  | 	const char *keyPrefix, const char *secmodName,  | ||||||
|  | @ -677,6 +819,7 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix, | ||||||
| { | { | ||||||
|     return nss_Init(configdir, certPrefix, keyPrefix, secmodName, |     return nss_Init(configdir, certPrefix, keyPrefix, secmodName, | ||||||
| 	updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,  | 	updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,  | ||||||
|  | 	NULL, NULL, | ||||||
| 	((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY), | 	((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY), | ||||||
| 	((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB), | 	((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB), | ||||||
| 	((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB), | 	((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB), | ||||||
|  | @ -694,7 +837,7 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix, | ||||||
| SECStatus | SECStatus | ||||||
| NSS_NoDB_Init(const char * configdir) | NSS_NoDB_Init(const char * configdir) | ||||||
| { | { | ||||||
|       return nss_Init("","","","", "", "", "", "", "", |       return nss_Init("","","","", "", "", "", "", "", NULL, NULL, | ||||||
| 			PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE, | 			PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE, | ||||||
| 			PR_FALSE,PR_FALSE,PR_FALSE); | 			PR_FALSE,PR_FALSE,PR_FALSE); | ||||||
| } | } | ||||||
|  | @ -722,7 +865,7 @@ nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData) | ||||||
| { | { | ||||||
|     int count, i; |     int count, i; | ||||||
|     count = nssShutdownList.peakFuncs; |     count = nssShutdownList.peakFuncs; | ||||||
|     /* expect the list to be short, just do a linear search */ | 
 | ||||||
|     for (i=0; i < count; i++) { |     for (i=0; i < count; i++) { | ||||||
| 	if ((nssShutdownList.funcs[i].func == sFunc) && | 	if ((nssShutdownList.funcs[i].func == sFunc) && | ||||||
| 	    (nssShutdownList.funcs[i].appData == appData)){ | 	    (nssShutdownList.funcs[i].appData == appData)){ | ||||||
|  | @ -740,8 +883,8 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData) | ||||||
| { | { | ||||||
|     int i; |     int i; | ||||||
| 
 | 
 | ||||||
|     if (!nss_IsInitted) { |     if (!NSS_IsInitialized()) { | ||||||
| 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | ||||||
| 	return SECFailure; | 	return SECFailure; | ||||||
|     } |     } | ||||||
|     if (sFunc == NULL) { |     if (sFunc == NULL) { | ||||||
|  | @ -794,8 +937,8 @@ SECStatus | ||||||
| NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData) | NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData) | ||||||
| { | { | ||||||
|     int i; |     int i; | ||||||
|     if (!nss_IsInitted) { |     if (!NSS_IsInitialized()) { | ||||||
| 	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | ||||||
| 	return SECFailure; | 	return SECFailure; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -821,6 +964,9 @@ NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData) | ||||||
| static SECStatus | static SECStatus | ||||||
| nss_InitShutdownList(void) | nss_InitShutdownList(void) | ||||||
| { | { | ||||||
|  |     if (nssShutdownList.lock != NULL) { | ||||||
|  | 	return SECSuccess; | ||||||
|  |     } | ||||||
|     nssShutdownList.lock = PZ_NewLock(nssILockOther); |     nssShutdownList.lock = PZ_NewLock(nssILockOther); | ||||||
|     if (nssShutdownList.lock == NULL) { |     if (nssShutdownList.lock == NULL) { | ||||||
| 	return SECFailure; | 	return SECFailure; | ||||||
|  | @ -869,16 +1015,12 @@ nss_ShutdownShutdownList(void) | ||||||
| extern const NSSError NSS_ERROR_BUSY; | extern const NSSError NSS_ERROR_BUSY; | ||||||
| 
 | 
 | ||||||
| SECStatus | SECStatus | ||||||
| NSS_Shutdown(void) | nss_Shutdown(void) | ||||||
| { | { | ||||||
|     SECStatus shutdownRV = SECSuccess; |     SECStatus shutdownRV = SECSuccess; | ||||||
|     SECStatus rv; |     SECStatus rv; | ||||||
|     PRStatus status; |     PRStatus status; | ||||||
| 
 |     NSSInitContext *temp; | ||||||
|     if (!nss_IsInitted) { |  | ||||||
| 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED); |  | ||||||
| 	return SECFailure; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     rv = nss_ShutdownShutdownList(); |     rv = nss_ShutdownShutdownList(); | ||||||
|     if (rv != SECSuccess) { |     if (rv != SECSuccess) { | ||||||
|  | @ -891,6 +1033,7 @@ NSS_Shutdown(void) | ||||||
|     SECOID_Shutdown(); |     SECOID_Shutdown(); | ||||||
|     status = STAN_Shutdown(); |     status = STAN_Shutdown(); | ||||||
|     cert_DestroySubjectKeyIDHashTable(); |     cert_DestroySubjectKeyIDHashTable(); | ||||||
|  |     pk11_SetInternalKeySlot(NULL); | ||||||
|     rv = SECMOD_Shutdown(); |     rv = SECMOD_Shutdown(); | ||||||
|     if (rv != SECSuccess) { |     if (rv != SECSuccess) { | ||||||
| 	shutdownRV = SECFailure; | 	shutdownRV = SECFailure; | ||||||
|  | @ -911,14 +1054,87 @@ NSS_Shutdown(void) | ||||||
| 	} | 	} | ||||||
| 	shutdownRV = SECFailure; | 	shutdownRV = SECFailure; | ||||||
|     } |     } | ||||||
|     nss_IsInitted = PR_FALSE; |     nssIsInitted = PR_FALSE; | ||||||
|  |     temp = nssInitContextList; | ||||||
|  |     nssInitContextList = NULL; | ||||||
|  |     /* free the old list. This is necessary when we are called from
 | ||||||
|  |      * NSS_Shutdown(). */ | ||||||
|  |     while (temp) { | ||||||
|  | 	NSSInitContext *next = temp->next; | ||||||
|  | 	temp->magic = 0; | ||||||
|  | 	PORT_Free(temp); | ||||||
|  | 	temp = next; | ||||||
|  |     } | ||||||
|     return shutdownRV; |     return shutdownRV; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SECStatus | ||||||
|  | NSS_Shutdown(void) | ||||||
|  | { | ||||||
|  |     if (!nssIsInitted) { | ||||||
|  | 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return nss_Shutdown(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * remove the context from a list. return true if found, false if not | ||||||
|  |  */ | ||||||
|  | PRBool | ||||||
|  | nss_RemoveList(NSSInitContext *context) { | ||||||
|  |     NSSInitContext *this = nssInitContextList; | ||||||
|  |     NSSInitContext **last = &nssInitContextList; | ||||||
|  | 
 | ||||||
|  |     while (this) { | ||||||
|  | 	if (this == context) { | ||||||
|  | 	    *last = this->next; | ||||||
|  | 	    this->magic = 0; | ||||||
|  | 	    PORT_Free(this); | ||||||
|  | 	    return PR_TRUE; | ||||||
|  | 	} | ||||||
|  | 	last = &this->next; | ||||||
|  | 	this=this->next; | ||||||
|  |     } | ||||||
|  |     return PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This form of shutdown is safe in the case where we may have multiple  | ||||||
|  |  * entities using NSS in a single process. Each entity calls shutdown with | ||||||
|  |  * it's own context. The application (which doesn't get a context), calls | ||||||
|  |  * shutdown with NULL. Once all users have 'checked in' NSS will shutdown. | ||||||
|  |  * This is different than NSS_Shutdown, where calling it will shutdown NSS | ||||||
|  |  * irreguardless of who else may have NSS open. | ||||||
|  |  */ | ||||||
|  | SECStatus | ||||||
|  | NSS_ShutdownContext(NSSInitContext *context) | ||||||
|  | { | ||||||
|  |    if (!context) { | ||||||
|  | 	if (!nssIsInitted) { | ||||||
|  | 	    PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | ||||||
|  | 	    return SECFailure; | ||||||
|  | 	} | ||||||
|  | 	nssIsInitted = 0; | ||||||
|  |     } else if (! nss_RemoveList(context)) { | ||||||
|  | 	/* context was already freed or wasn't valid */ | ||||||
|  | 	PORT_SetError(SEC_ERROR_NOT_INITIALIZED); | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     if ((nssIsInitted == 0) && (nssInitContextList == NULL)) { | ||||||
|  | 	return nss_Shutdown(); | ||||||
|  |     } | ||||||
|  |     return SECSuccess; | ||||||
|  | } | ||||||
|  | 	 | ||||||
|  | 	 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| PRBool | PRBool | ||||||
| NSS_IsInitialized(void) | NSS_IsInitialized(void) | ||||||
| { | { | ||||||
|     return nss_IsInitted; |     return (nssIsInitted) || (nssInitContextList != NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -935,9 +1151,9 @@ NSS_VersionCheck(const char *importedVersion) | ||||||
|      * check algorithm.  This release is not backward |      * check algorithm.  This release is not backward | ||||||
|      * compatible with previous major releases.  It is |      * compatible with previous major releases.  It is | ||||||
|      * not compatible with future major, minor, or |      * not compatible with future major, minor, or | ||||||
|      * patch releases. |      * patch releases or builds. | ||||||
|      */ |      */ | ||||||
|     int vmajor = 0, vminor = 0, vpatch = 0; |     int vmajor = 0, vminor = 0, vpatch = 0, vbuild = 0; | ||||||
|     const char *ptr = importedVersion; |     const char *ptr = importedVersion; | ||||||
|     volatile char c; /* force a reference that won't get optimized away */ |     volatile char c; /* force a reference that won't get optimized away */ | ||||||
| 
 | 
 | ||||||
|  | @ -959,6 +1175,13 @@ NSS_VersionCheck(const char *importedVersion) | ||||||
|                 vpatch = 10 * vpatch + *ptr - '0'; |                 vpatch = 10 * vpatch + *ptr - '0'; | ||||||
|                 ptr++; |                 ptr++; | ||||||
|             } |             } | ||||||
|  |             if (*ptr == '.') { | ||||||
|  |                 ptr++; | ||||||
|  |                 while (isdigit(*ptr)) { | ||||||
|  |                     vbuild = 10 * vbuild + *ptr - '0'; | ||||||
|  |                     ptr++; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -971,6 +1194,10 @@ NSS_VersionCheck(const char *importedVersion) | ||||||
|     if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR && vpatch > NSS_VPATCH) { |     if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR && vpatch > NSS_VPATCH) { | ||||||
|         return PR_FALSE; |         return PR_FALSE; | ||||||
|     } |     } | ||||||
|  |     if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR && | ||||||
|  |         vpatch == NSS_VPATCH && vbuild > NSS_VBUILD) { | ||||||
|  |         return PR_FALSE; | ||||||
|  |     } | ||||||
|     /* Check dependent libraries */ |     /* Check dependent libraries */ | ||||||
|     if (PR_VersionCheck(PR_VERSION) == PR_FALSE) { |     if (PR_VersionCheck(PR_VERSION) == PR_FALSE) { | ||||||
|         return PR_FALSE; |         return PR_FALSE; | ||||||
|  |  | ||||||
|  | @ -1894,25 +1894,7 @@ PK11_ExportEncryptedPrivateKeyInfo( | ||||||
| SECItem* | SECItem* | ||||||
| PK11_DEREncodePublicKey(SECKEYPublicKey *pubk) | PK11_DEREncodePublicKey(SECKEYPublicKey *pubk) | ||||||
| { | { | ||||||
|     CERTSubjectPublicKeyInfo *spki=NULL; |     return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk); | ||||||
|     SECItem *spkiDER = NULL; |  | ||||||
| 
 |  | ||||||
|     if( pubk == NULL ) { |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* get the subjectpublickeyinfo */ |  | ||||||
|     spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); |  | ||||||
|     if( spki == NULL ) { |  | ||||||
|         goto finish; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* DER-encode the subjectpublickeyinfo */ |  | ||||||
|     spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki, |  | ||||||
|                     CERT_SubjectPublicKeyInfoTemplate); |  | ||||||
| 
 |  | ||||||
| finish: |  | ||||||
|     return spkiDER; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| char * | char * | ||||||
|  |  | ||||||
|  | @ -854,6 +854,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, | ||||||
|     nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; |     nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; | ||||||
| 
 | 
 | ||||||
|     if (keyID == NULL) { |     if (keyID == NULL) { | ||||||
|  | 	goto loser; /* error code should be set already */ | ||||||
|  |     } | ||||||
|  |     if (!token) { | ||||||
|  |     	PORT_SetError(SEC_ERROR_NO_TOKEN); | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -871,17 +875,6 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (c->object.cryptoContext) { |  | ||||||
| 	/* Delete the temp instance */ |  | ||||||
| 	NSSCryptoContext *cc = c->object.cryptoContext; |  | ||||||
| 	nssCertificateStore_Lock(cc->certStore, &lockTrace); |  | ||||||
| 	nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); |  | ||||||
| 	nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); |  | ||||||
| 	c->object.cryptoContext = NULL; |  | ||||||
| 	cert->istemp = PR_FALSE; |  | ||||||
| 	cert->isperm = PR_TRUE; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /* set the id for the cert */ |     /* set the id for the cert */ | ||||||
|     nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data); |     nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data); | ||||||
|     if (!c->id.data) { |     if (!c->id.data) { | ||||||
|  | @ -926,6 +919,18 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, | ||||||
| 	} | 	} | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if (c->object.cryptoContext) { | ||||||
|  | 	/* Delete the temp instance */ | ||||||
|  | 	NSSCryptoContext *cc = c->object.cryptoContext; | ||||||
|  | 	nssCertificateStore_Lock(cc->certStore, &lockTrace); | ||||||
|  | 	nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); | ||||||
|  | 	nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); | ||||||
|  | 	c->object.cryptoContext = NULL; | ||||||
|  | 	cert->istemp = PR_FALSE; | ||||||
|  | 	cert->isperm = PR_TRUE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* add the new instance to the cert, force an update of the
 |     /* add the new instance to the cert, force an update of the
 | ||||||
|      * CERTCertificate, and finish |      * CERTCertificate, and finish | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|  | @ -37,8 +37,9 @@ | ||||||
| #define _PK11FUNC_H_ | #define _PK11FUNC_H_ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * the original pk11func.h had a mix of public and private functions. |  * The original pk11func.h had a mix of public and private functions. | ||||||
|  * continue to provide those for backward compatibility. |  * Continue to provide those for backward compatibility.  New code should | ||||||
|  |  * include pk11pub.h instead of pk11func.h. | ||||||
|  */ |  */ | ||||||
| #include "pk11pub.h" | #include "pk11pub.h" | ||||||
| #include "pk11priv.h" | #include "pk11priv.h" | ||||||
|  |  | ||||||
|  | @ -119,16 +119,122 @@ PRBool pk11_getFinalizeModulesOption(void) | ||||||
|     return finalizeModules; |     return finalizeModules; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Allow specification loading the same module more than once at init time. | ||||||
|  |  * This enables 2 things. | ||||||
|  |  * | ||||||
|  |  *    1) we can load additional databases by manipulating secmod.db/pkcs11.txt. | ||||||
|  |  *    2) we can handle the case where some library has already initialized NSS | ||||||
|  |  *    before the main application. | ||||||
|  |  * | ||||||
|  |  * oldModule is the module we have already initialized. | ||||||
|  |  * char *modulespec is the full module spec for the library we want to | ||||||
|  |  * initialize. | ||||||
|  |  */ | ||||||
|  | static SECStatus | ||||||
|  | secmod_handleReload(SECMODModule *oldModule, SECMODModule *newModule) | ||||||
|  | { | ||||||
|  |     PK11SlotInfo *slot; | ||||||
|  |     char *modulespec; | ||||||
|  |     char *newModuleSpec; | ||||||
|  |     char **children; | ||||||
|  |     CK_SLOT_ID *ids; | ||||||
|  |     SECStatus rv; | ||||||
|  |     SECMODConfigList *conflist; | ||||||
|  |     int count = 0; | ||||||
|  | 
 | ||||||
|  |     /* first look for tokens= key words from the module spec */ | ||||||
|  |     modulespec = newModule->libraryParams; | ||||||
|  |     newModuleSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, | ||||||
|  | 				newModule->isFIPS, modulespec, &children, &ids); | ||||||
|  |     if (!newModuleSpec) { | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* 
 | ||||||
|  |      * We are now trying to open a new slot on an already loaded module. | ||||||
|  |      * If that slot represents a cert/key database, we don't want to open | ||||||
|  |      * multiple copies of that same database. Unfortunately we understand | ||||||
|  |      * the softoken flags well enough to be able to do this, so we can only get | ||||||
|  |      * the list of already loaded databases if we are trying to open another | ||||||
|  |      * internal module.  | ||||||
|  |      */ | ||||||
|  |     if (oldModule->internal) { | ||||||
|  | 	conflist = secmod_GetConfigList(oldModule->isFIPS,  | ||||||
|  | 					oldModule->libraryParams, &count); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /* don't open multiple of the same db */ | ||||||
|  |     if (conflist && secmod_MatchConfigList(newModuleSpec, conflist, count)) {  | ||||||
|  | 	rv = SECSuccess; | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  |     slot = SECMOD_OpenNewSlot(oldModule, newModuleSpec); | ||||||
|  |     if (slot) { | ||||||
|  | 	int newID; | ||||||
|  | 	char **thisChild; | ||||||
|  | 	CK_SLOT_ID *thisID; | ||||||
|  | 	char *oldModuleSpec; | ||||||
|  | 
 | ||||||
|  | 	if (secmod_IsInternalKeySlot(newModule)) { | ||||||
|  | 	    pk11_SetInternalKeySlot(slot); | ||||||
|  | 	} | ||||||
|  | 	newID = slot->slotID; | ||||||
|  | 	PK11_FreeSlot(slot); | ||||||
|  | 	for (thisChild=children, thisID=ids; thisChild && *thisChild;  | ||||||
|  | 						thisChild++,thisID++) { | ||||||
|  | 	    if (conflist && | ||||||
|  | 		       secmod_MatchConfigList(*thisChild, conflist, count)) { | ||||||
|  | 		*thisID = (CK_SLOT_ID) -1; | ||||||
|  | 		continue; | ||||||
|  | 	    } | ||||||
|  | 	    slot = SECMOD_OpenNewSlot(oldModule, *thisChild); | ||||||
|  | 	    if (slot) { | ||||||
|  | 		*thisID = slot->slotID; | ||||||
|  | 		PK11_FreeSlot(slot); | ||||||
|  | 	    } else { | ||||||
|  | 		*thisID = (CK_SLOT_ID) -1; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/* update the old module initialization string in case we need to
 | ||||||
|  | 	 * shutdown and reinit the whole mess (this is rare, but can happen | ||||||
|  | 	 * when trying to stop smart card insertion/removal threads)... */ | ||||||
|  | 	oldModuleSpec = secmod_MkAppendTokensList(oldModule->arena,  | ||||||
|  | 		oldModule->libraryParams, newModuleSpec, newID,  | ||||||
|  | 		children, ids); | ||||||
|  | 	if (oldModuleSpec) { | ||||||
|  | 	    oldModule->libraryParams = oldModuleSpec; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	rv = SECSuccess; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     secmod_FreeChildren(children, ids); | ||||||
|  |     PORT_Free(newModuleSpec); | ||||||
|  |     if (conflist) { | ||||||
|  | 	secmod_FreeConfigList(conflist, count); | ||||||
|  |     } | ||||||
|  |     return rv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * collect the steps we need to initialize a module in a single function |  * collect the steps we need to initialize a module in a single function | ||||||
|  */ |  */ | ||||||
| SECStatus | SECStatus | ||||||
| secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded) | secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,  | ||||||
|  | 		  PRBool* alreadyLoaded) | ||||||
| { | { | ||||||
|     CK_C_INITIALIZE_ARGS moduleArgs; |     CK_C_INITIALIZE_ARGS moduleArgs; | ||||||
|     CK_VOID_PTR pInitArgs; |     CK_VOID_PTR pInitArgs; | ||||||
|     CK_RV crv; |     CK_RV crv; | ||||||
| 
 | 
 | ||||||
|  |     if (reload) { | ||||||
|  | 	*reload = NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (!mod || !alreadyLoaded) { |     if (!mod || !alreadyLoaded) { | ||||||
|         PORT_SetError(SEC_ERROR_INVALID_ARGS); |         PORT_SetError(SEC_ERROR_INVALID_ARGS); | ||||||
|         return SECFailure; |         return SECFailure; | ||||||
|  | @ -144,11 +250,37 @@ secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded) | ||||||
| 	pInitArgs = &moduleArgs; | 	pInitArgs = &moduleArgs; | ||||||
|     } |     } | ||||||
|     crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs); |     crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs); | ||||||
|     if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) && |     if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) { | ||||||
|         (!enforceAlreadyInitializedError)) { | 	SECMODModule *oldModule = NULL; | ||||||
|  | 
 | ||||||
|  | 	/* Library has already been loaded once, if caller expects it, and it
 | ||||||
|  | 	 * has additional configuration, try reloading it as well. */ | ||||||
|  | 	if (reload != NULL && mod->libraryParams) { | ||||||
|  | 	    oldModule = secmod_FindModuleByFuncPtr(mod->functionList); | ||||||
|  | 	} | ||||||
|  | 	/* Library has been loaded by NSS. It means it may be capable of
 | ||||||
|  | 	 * reloading */ | ||||||
|  | 	if (oldModule) { | ||||||
|  | 	    SECStatus rv; | ||||||
|  | 	    rv = secmod_handleReload(oldModule, mod); | ||||||
|  | 	    if (rv == SECSuccess) { | ||||||
|  | 		/* This module should go away soon, since we've
 | ||||||
|  | 		 * simply expanded the slots on the old module. | ||||||
|  | 		 * When it goes away, it should not Finalize since | ||||||
|  | 		 * that will close our old module as well. Setting | ||||||
|  | 		 * the function list to NULL will prevent that close */ | ||||||
|  | 		mod->functionList = NULL; | ||||||
|  | 		*reload = oldModule; | ||||||
|  | 		return SECSuccess; | ||||||
|  | 	    } | ||||||
|  | 	    SECMOD_DestroyModule(oldModule); | ||||||
|  | 	} | ||||||
|  | 	/* reload not possible, fall back to old semantics */ | ||||||
|  | 	if (!enforceAlreadyInitializedError) { | ||||||
|        	    *alreadyLoaded = PR_TRUE; |        	    *alreadyLoaded = PR_TRUE; | ||||||
|             return SECSuccess; |             return SECSuccess; | ||||||
| 	} | 	} | ||||||
|  |     } | ||||||
|     if (crv != CKR_OK) { |     if (crv != CKR_OK) { | ||||||
| 	if (pInitArgs == NULL || | 	if (pInitArgs == NULL || | ||||||
| 		crv == CKR_NETSCAPE_CERTDB_FAILED || | 		crv == CKR_NETSCAPE_CERTDB_FAILED || | ||||||
|  | @ -217,9 +349,9 @@ SECMOD_SetRootCerts(PK11SlotInfo *slot, SECMODModule *mod) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const char* NameOfThisSharedLib = | static const char* my_shlib_name = | ||||||
|     SHLIB_PREFIX"nss"SHLIB_VERSION"."SHLIB_SUFFIX; |     SHLIB_PREFIX"nss"SHLIB_VERSION"."SHLIB_SUFFIX; | ||||||
| static const char* softoken_default_name = | static const char* softoken_shlib_name = | ||||||
|     SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX; |     SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX; | ||||||
| static const PRCallOnceType pristineCallOnce; | static const PRCallOnceType pristineCallOnce; | ||||||
| static PRCallOnceType loadSoftokenOnce; | static PRCallOnceType loadSoftokenOnce; | ||||||
|  | @ -231,22 +363,16 @@ static PRInt32 softokenLoadCount; | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include "prsystem.h" | #include "prsystem.h" | ||||||
| 
 | 
 | ||||||
| #include "../freebl/genload.c" |  | ||||||
| 
 |  | ||||||
| /* This function must be run only once. */ | /* This function must be run only once. */ | ||||||
| /*  determine if hybrid platform, then actually load the DSO. */ | /*  determine if hybrid platform, then actually load the DSO. */ | ||||||
| static PRStatus | static PRStatus | ||||||
| softoken_LoadDSO( void )  | softoken_LoadDSO( void )  | ||||||
| { | { | ||||||
|   PRLibrary *  handle; |   PRLibrary *  handle; | ||||||
|   const char * name = softoken_default_name; |  | ||||||
| 
 | 
 | ||||||
|   if (!name) { |   handle = PORT_LoadLibraryFromOrigin(my_shlib_name, | ||||||
|     PR_SetError(PR_LOAD_LIBRARY_ERROR, 0); |                                       (PRFuncPtr) &softoken_LoadDSO, | ||||||
|     return PR_FAILURE; |                                       softoken_shlib_name); | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   handle = loader_LoadLibrary(name); |  | ||||||
|   if (handle) { |   if (handle) { | ||||||
|     softokenLib = handle; |     softokenLib = handle; | ||||||
|     return PR_SUCCESS; |     return PR_SUCCESS; | ||||||
|  | @ -258,7 +384,7 @@ softoken_LoadDSO( void ) | ||||||
|  * load a new module into our address space and initialize it. |  * load a new module into our address space and initialize it. | ||||||
|  */ |  */ | ||||||
| SECStatus | SECStatus | ||||||
| SECMOD_LoadPKCS11Module(SECMODModule *mod) { | secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) { | ||||||
|     PRLibrary *library = NULL; |     PRLibrary *library = NULL; | ||||||
|     CK_C_GetFunctionList entry = NULL; |     CK_C_GetFunctionList entry = NULL; | ||||||
|     char * full_name; |     char * full_name; | ||||||
|  | @ -271,7 +397,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) { | ||||||
|     if (mod->loaded) return SECSuccess; |     if (mod->loaded) return SECSuccess; | ||||||
| 
 | 
 | ||||||
|     /* intenal modules get loaded from their internal list */ |     /* intenal modules get loaded from their internal list */ | ||||||
|     if (mod->internal) { |     if (mod->internal && (mod->dllName == NULL)) { | ||||||
|     /*
 |     /*
 | ||||||
|      * Loads softoken as a dynamic library, |      * Loads softoken as a dynamic library, | ||||||
|      * even though the rest of NSS assumes this as the "internal" module. |      * even though the rest of NSS assumes this as the "internal" module. | ||||||
|  | @ -308,26 +434,14 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) { | ||||||
| 	    return SECFailure; | 	    return SECFailure; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| #ifdef notdef |  | ||||||
| 	/* look up the library name */ |  | ||||||
| 	full_name = PR_GetLibraryName(PR_GetLibraryPath(),mod->dllName); |  | ||||||
| 	if (full_name == NULL) { |  | ||||||
| 	    return SECFailure; |  | ||||||
| 	} |  | ||||||
| #else |  | ||||||
| 	full_name = PORT_Strdup(mod->dllName); | 	full_name = PORT_Strdup(mod->dllName); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	/* load the library. If this succeeds, then we have to remember to
 | 	/* load the library. If this succeeds, then we have to remember to
 | ||||||
| 	 * unload the library if anything goes wrong from here on out... | 	 * unload the library if anything goes wrong from here on out... | ||||||
| 	 */ | 	 */ | ||||||
| 	library = PR_LoadLibrary(full_name); | 	library = PR_LoadLibrary(full_name); | ||||||
| 	mod->library = (void *)library; | 	mod->library = (void *)library; | ||||||
| #ifdef notdef |  | ||||||
| 	PR_FreeLibraryName(full_name); |  | ||||||
| #else |  | ||||||
| 	PORT_Free(full_name); | 	PORT_Free(full_name); | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	if (library == NULL) { | 	if (library == NULL) { | ||||||
| 	    return SECFailure; | 	    return SECFailure; | ||||||
|  | @ -375,11 +489,18 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) { | ||||||
|     mod->isThreadSafe = PR_TRUE; |     mod->isThreadSafe = PR_TRUE; | ||||||
| 
 | 
 | ||||||
|     /* Now we initialize the module */ |     /* Now we initialize the module */ | ||||||
|     rv = secmod_ModuleInit(mod, &alreadyLoaded); |     rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded); | ||||||
|     if (rv != SECSuccess) { |     if (rv != SECSuccess) { | ||||||
| 	goto fail; | 	goto fail; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* module has been reloaded, this module itself is done, 
 | ||||||
|  |      * return to the caller */ | ||||||
|  |     if (mod->functionList == NULL) { | ||||||
|  | 	mod->loaded = PR_TRUE; /* technically the module is loaded.. */ | ||||||
|  | 	return SECSuccess; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /* check the version number */ |     /* check the version number */ | ||||||
|     if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2; |     if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2; | ||||||
|     if (info.cryptokiVersion.major != 2) goto fail2; |     if (info.cryptokiVersion.major != 2) goto fail2; | ||||||
|  | @ -460,7 +581,9 @@ SECMOD_UnloadModule(SECMODModule *mod) { | ||||||
| 	return SECFailure; | 	return SECFailure; | ||||||
|     } |     } | ||||||
|     if (finalizeModules) { |     if (finalizeModules) { | ||||||
|         if (!mod->moduleDBOnly) PK11_GETTAB(mod)->C_Finalize(NULL); |         if (mod->functionList &&!mod->moduleDBOnly) { | ||||||
|  | 	    PK11_GETTAB(mod)->C_Finalize(NULL); | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
|     mod->moduleID = 0; |     mod->moduleID = 0; | ||||||
|     mod->loaded = PR_FALSE; |     mod->loaded = PR_FALSE; | ||||||
|  |  | ||||||
|  | @ -681,7 +681,6 @@ pk11_IncrementNickname(char *nickname) | ||||||
| { | { | ||||||
|     char *newNickname = NULL; |     char *newNickname = NULL; | ||||||
|     int end; |     int end; | ||||||
|     PRBool needCarry; |  | ||||||
|     int digit; |     int digit; | ||||||
|     int len = strlen(nickname); |     int len = strlen(nickname); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -107,6 +107,58 @@ secmod_NewModule(void) | ||||||
|      |      | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* private flags for isModuleDB (field in SECMODModule). */ | ||||||
|  | /* The meaing of these flags is as follows:
 | ||||||
|  |  * | ||||||
|  |  * SECMOD_FLAG_MODULE_DB_IS_MODULE_DB - This is a module that accesses the  | ||||||
|  |  *   database of other modules to load. Module DBs are loadable modules that | ||||||
|  |  *   tells NSS which PKCS #11 modules to load and when. These module DBs are  | ||||||
|  |  *   chainable. That is, one module DB can load another one. NSS system init  | ||||||
|  |  *   design takes advantage of this feature. In system NSS, a fixed system  | ||||||
|  |  *   module DB loads the system defined libraries, then chains out to the  | ||||||
|  |  *   traditional module DBs to load any system or user configured modules  | ||||||
|  |  *   (like smart cards). This bit is the same as the already existing meaning  | ||||||
|  |  *   of  isModuleDB = PR_TRUE. None of the other module db flags should be set  | ||||||
|  |  *   if this flag isn't on. | ||||||
|  |  * | ||||||
|  |  * SECMOD_FLAG_MODULE_DB_SKIP_FIRST - This flag tells NSS to skip the first  | ||||||
|  |  *   PKCS #11 module presented by a module DB. This allows the OS to load a  | ||||||
|  |  *   softoken from the system module, then ask the existing module DB code to  | ||||||
|  |  *   load the other PKCS #11 modules in that module DB (skipping it's request  | ||||||
|  |  *   to load softoken). This gives the system init finer control over the  | ||||||
|  |  *   configuration of that softoken module. | ||||||
|  |  * | ||||||
|  |  * SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB - This flag allows system init to mark a  | ||||||
|  |  *   different module DB as the 'default' module DB (the one in which  | ||||||
|  |  *   'Add module' changes will go). Without this flag NSS takes the first  | ||||||
|  |  *   module as the default Module DB, but in system NSS, that first module  | ||||||
|  |  *   is the system module, which is likely read only (at least to the user). | ||||||
|  |  *   This  allows system NSS to delegate those changes to the user's module DB,  | ||||||
|  |  *   preserving the user's ability to load new PKCS #11 modules (which only  | ||||||
|  |  *   affect him), from existing applications like Firefox. | ||||||
|  |  */ | ||||||
|  | #define SECMOD_FLAG_MODULE_DB_IS_MODULE_DB  0x01 /* must be set if any of the  | ||||||
|  | 						  *other flags are set */ | ||||||
|  | #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST    0x02 | ||||||
|  | #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* private flags for internal (field in SECMODModule). */ | ||||||
|  | /* The meaing of these flags is as follows:
 | ||||||
|  |  * | ||||||
|  |  * SECMOD_FLAG_INTERNAL_IS_INTERNAL - This is a marks the the module is | ||||||
|  |  *   the internal module (that is, softoken). This bit is the same as the  | ||||||
|  |  *   already existing meaning of internal = PR_TRUE. None of the other  | ||||||
|  |  *   internal flags should be set if this flag isn't on. | ||||||
|  |  * | ||||||
|  |  * SECMOD_FLAG_MODULE_INTERNAL_KEY_SLOT - This flag allows system init to mark  | ||||||
|  |  *   a  different slot returned byt PK11_GetInternalKeySlot(). The 'primary' | ||||||
|  |  *   slot defined by this module will be the new internal key slot. | ||||||
|  |  */ | ||||||
|  | #define SECMOD_FLAG_INTERNAL_IS_INTERNAL       0x01 /* must be set if any of  | ||||||
|  | 						     *the other flags are set */ | ||||||
|  | #define SECMOD_FLAG_INTERNAL_KEY_SLOT          0x02 | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * for 3.4 we continue to use the old SECMODModule structure |  * for 3.4 we continue to use the old SECMODModule structure | ||||||
|  */ |  */ | ||||||
|  | @ -146,6 +198,33 @@ SECMOD_CreateModule(const char *library, const char *moduleName, | ||||||
|     mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc); |     mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc); | ||||||
|     if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE; |     if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE; | ||||||
| 
 | 
 | ||||||
|  |     /* we need more bits, but we also want to preserve binary compatibility 
 | ||||||
|  |      * so we overload the isModuleDB PRBool with additional flags.  | ||||||
|  |      * These flags are only valid if mod->isModuleDB is already set. | ||||||
|  |      * NOTE: this depends on the fact that PRBool is at least a char on  | ||||||
|  |      * all platforms. These flags are only valid if moduleDB is set, so  | ||||||
|  |      * code checking if (mod->isModuleDB) will continue to work correctly. */ | ||||||
|  |     if (mod->isModuleDB) { | ||||||
|  | 	char flags = SECMOD_FLAG_MODULE_DB_IS_MODULE_DB; | ||||||
|  | 	if (secmod_argHasFlag("flags","skipFirst",nssc)) { | ||||||
|  | 	    flags |= SECMOD_FLAG_MODULE_DB_SKIP_FIRST; | ||||||
|  | 	} | ||||||
|  | 	if (secmod_argHasFlag("flags","defaultModDB",nssc)) { | ||||||
|  | 	    flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB; | ||||||
|  | 	} | ||||||
|  | 	/* additional moduleDB flags could be added here in the future */ | ||||||
|  | 	mod->isModuleDB = (PRBool) flags; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (mod->internal) { | ||||||
|  | 	char flags = SECMOD_FLAG_INTERNAL_IS_INTERNAL; | ||||||
|  | 
 | ||||||
|  | 	if (secmod_argHasFlag("flags", "internalKeySlot", nssc)) { | ||||||
|  | 	    flags |= SECMOD_FLAG_INTERNAL_KEY_SLOT; | ||||||
|  | 	} | ||||||
|  | 	mod->internal = (PRBool) flags; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     ciphers = secmod_argGetParamValue("ciphers",nssc); |     ciphers = secmod_argGetParamValue("ciphers",nssc); | ||||||
|     secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers); |     secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers); | ||||||
|     if (ciphers) PORT_Free(ciphers); |     if (ciphers) PORT_Free(ciphers); | ||||||
|  | @ -155,6 +234,708 @@ SECMOD_CreateModule(const char *library, const char *moduleName, | ||||||
|     return mod; |     return mod; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | PRBool | ||||||
|  | SECMOD_GetSkipFirstFlag(SECMODModule *mod) | ||||||
|  | { | ||||||
|  |    char flags = (char) mod->isModuleDB; | ||||||
|  | 
 | ||||||
|  |    return (flags & SECMOD_FLAG_MODULE_DB_SKIP_FIRST) ? PR_TRUE : PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PRBool | ||||||
|  | SECMOD_GetDefaultModDBFlag(SECMODModule *mod) | ||||||
|  | { | ||||||
|  |    char flags = (char) mod->isModuleDB; | ||||||
|  | 
 | ||||||
|  |    return (flags & SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB) ? PR_TRUE : PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | PRBool | ||||||
|  | secmod_IsInternalKeySlot(SECMODModule *mod) | ||||||
|  | { | ||||||
|  |    char flags = (char) mod->internal; | ||||||
|  | 
 | ||||||
|  |    return (flags & SECMOD_FLAG_INTERNAL_KEY_SLOT) ? PR_TRUE : PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* forward declarations */ | ||||||
|  | static int secmod_escapeSize(const char *string, char quote); | ||||||
|  | static char *secmod_addEscape(const char *string, char quote); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * copy desc and value into target. Target is known to be big enough to | ||||||
|  |  * hold desc +2 +value, which is good because the result of this will be | ||||||
|  |  * *desc"*value". We may, however, have to add some escapes for special | ||||||
|  |  * characters imbedded into value (rare). This string potentially comes from | ||||||
|  |  * a user, so we don't want the user overflowing the target buffer by using | ||||||
|  |  * excessive escapes. To prevent this we count the escapes we need to add and | ||||||
|  |  * try to expand the buffer with Realloc. | ||||||
|  |  */ | ||||||
|  | static char * | ||||||
|  | secmod_doDescCopy(char *target, int *targetLen, const char *desc, | ||||||
|  | 			int descLen, char *value) | ||||||
|  | { | ||||||
|  |     int diff, esc_len; | ||||||
|  | 
 | ||||||
|  |     esc_len = secmod_escapeSize(value, '\"') - 1; | ||||||
|  |     diff = esc_len - strlen(value); | ||||||
|  |     if (diff > 0) { | ||||||
|  | 	/* we need to escape... expand newSpecPtr as well to make sure
 | ||||||
|  | 	 * we don't overflow it */ | ||||||
|  | 	char *newPtr = PORT_Realloc(target, *targetLen * diff); | ||||||
|  | 	if (!newPtr) { | ||||||
|  | 	    return target; /* not enough space, just drop the whole copy */ | ||||||
|  | 	} | ||||||
|  | 	*targetLen += diff; | ||||||
|  | 	target = newPtr; | ||||||
|  | 	value = secmod_addEscape(value, '\"'); | ||||||
|  | 	if (value == NULL) { | ||||||
|  | 	    return target; /* couldn't escape value, just drop the copy */ | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     PORT_Memcpy(target, desc, descLen); | ||||||
|  |     target += descLen; | ||||||
|  |     *target++='\"'; | ||||||
|  |     PORT_Memcpy(target, value, esc_len); | ||||||
|  |     target += esc_len; | ||||||
|  |     *target++='\"'; | ||||||
|  |     return target; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define SECMOD_SPEC_COPY(new, start, end)    \ | ||||||
|  |   if (end > start) {                         \ | ||||||
|  | 	int _cnt = end - start;	             \ | ||||||
|  | 	PORT_Memcpy(new, start, _cnt);       \ | ||||||
|  | 	new += _cnt;                         \ | ||||||
|  |   } | ||||||
|  | #define SECMOD_TOKEN_DESCRIPTION "tokenDescription=" | ||||||
|  | #define SECMOD_SLOT_DESCRIPTION   "slotDescription=" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Find any tokens= values in the module spec.  | ||||||
|  |  * Always return a new spec which does not have any tokens= arguments. | ||||||
|  |  * If tokens= arguments are found, Split the the various tokens defined into | ||||||
|  |  * an array of child specs to return. | ||||||
|  |  * | ||||||
|  |  * Caller is responsible for freeing the child spec and the new token | ||||||
|  |  * spec. | ||||||
|  |  */ | ||||||
|  | char * | ||||||
|  | secmod_ParseModuleSpecForTokens(PRBool convert, PRBool isFIPS,  | ||||||
|  | 				char *moduleSpec, char ***children,  | ||||||
|  | 				CK_SLOT_ID **ids) | ||||||
|  | { | ||||||
|  |     int        newSpecLen   = PORT_Strlen(moduleSpec)+2; | ||||||
|  |     char       *newSpec     = PORT_Alloc(newSpecLen); | ||||||
|  |     char       *newSpecPtr  = newSpec; | ||||||
|  |     char       *modulePrev  = moduleSpec; | ||||||
|  |     char       *target      = NULL; | ||||||
|  |     char *tmp = NULL; | ||||||
|  |     char       **childArray = NULL; | ||||||
|  |     char       *tokenIndex; | ||||||
|  |     CK_SLOT_ID *idArray     = NULL; | ||||||
|  |     int        tokenCount = 0; | ||||||
|  |     int        i; | ||||||
|  | 
 | ||||||
|  |     if (newSpec == NULL) { | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *children = NULL; | ||||||
|  |     if (ids) { | ||||||
|  | 	*ids = NULL; | ||||||
|  |     } | ||||||
|  |     moduleSpec = secmod_argStrip(moduleSpec); | ||||||
|  |     SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); | ||||||
|  | 
 | ||||||
|  |     /* Notes on 'convert' and 'isFIPS' flags: The base parameters for opening 
 | ||||||
|  |      * a new softoken module takes the following parameters to name the  | ||||||
|  |      * various tokens: | ||||||
|  |      *   | ||||||
|  |      *  cryptoTokenDescription: name of the non-fips crypto token. | ||||||
|  |      *  cryptoSlotDescription: name of the non-fips crypto slot. | ||||||
|  |      *  dbTokenDescription: name of the non-fips db token. | ||||||
|  |      *  dbSlotDescription: name of the non-fips db slot. | ||||||
|  |      *  FIPSTokenDescription: name of the fips db/crypto token. | ||||||
|  |      *  FIPSSlotDescription: name of the fips db/crypto slot. | ||||||
|  |      * | ||||||
|  |      * if we are opening a new slot, we need to have the following | ||||||
|  |      * parameters: | ||||||
|  |      *  tokenDescription: name of the token. | ||||||
|  |      *  slotDescription: name of the slot. | ||||||
|  |      * | ||||||
|  |      * | ||||||
|  |      * The convert flag tells us to drop the unnecessary *TokenDescription  | ||||||
|  |      * and *SlotDescription arguments and convert the appropriate pair  | ||||||
|  |      * (either db or FIPS based on the isFIPS flag) to tokenDescription and  | ||||||
|  |      * slotDescription). | ||||||
|  |      */ | ||||||
|  |     /*
 | ||||||
|  |      * walk down the list. if we find a tokens= argument, save it, | ||||||
|  |      * otherise copy the argument. | ||||||
|  |      */ | ||||||
|  |     while (*moduleSpec) { | ||||||
|  | 	int next; | ||||||
|  | 	modulePrev = moduleSpec; | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, target, "tokens=", | ||||||
|  | 			modulePrev = moduleSpec; /* skip copying */ ) | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoTokenDescription=", | ||||||
|  | 			if (convert) { modulePrev = moduleSpec; } ); | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "cryptoSlotDescription=", | ||||||
|  | 			if (convert) { modulePrev = moduleSpec; } ); | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "dbTokenDescription=", | ||||||
|  | 			if (convert) { | ||||||
|  | 			    modulePrev = moduleSpec;  | ||||||
|  | 			    if (!isFIPS) { | ||||||
|  | 				newSpecPtr = secmod_doDescCopy(newSpecPtr,  | ||||||
|  | 				    &newSpecLen, SECMOD_TOKEN_DESCRIPTION,  | ||||||
|  | 				    sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp); | ||||||
|  | 			    } | ||||||
|  | 			}); | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "dbSlotDescription=", | ||||||
|  | 			if (convert) { | ||||||
|  | 			    modulePrev = moduleSpec; /* skip copying */  | ||||||
|  | 			    if (!isFIPS) { | ||||||
|  | 				newSpecPtr = secmod_doDescCopy(newSpecPtr,  | ||||||
|  | 				    &newSpecLen, SECMOD_SLOT_DESCRIPTION,  | ||||||
|  | 				    sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp); | ||||||
|  | 			    } | ||||||
|  | 			} ); | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSTokenDescription=", | ||||||
|  | 			if (convert) { | ||||||
|  | 			    modulePrev = moduleSpec; /* skip copying */  | ||||||
|  | 			    if (isFIPS) { | ||||||
|  | 				newSpecPtr = secmod_doDescCopy(newSpecPtr,  | ||||||
|  | 				    &newSpecLen, SECMOD_TOKEN_DESCRIPTION,  | ||||||
|  | 				    sizeof(SECMOD_TOKEN_DESCRIPTION)-1, tmp); | ||||||
|  | 			    } | ||||||
|  | 			} ); | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(moduleSpec, tmp, "FIPSSlotDescription=", | ||||||
|  | 			if (convert) { | ||||||
|  | 			    modulePrev = moduleSpec; /* skip copying */  | ||||||
|  | 			    if (isFIPS) { | ||||||
|  | 				newSpecPtr = secmod_doDescCopy(newSpecPtr,  | ||||||
|  | 				    &newSpecLen, SECMOD_SLOT_DESCRIPTION,  | ||||||
|  | 				    sizeof(SECMOD_SLOT_DESCRIPTION)-1, tmp); | ||||||
|  | 			    } | ||||||
|  | 			} ); | ||||||
|  | 	SECMOD_HANDLE_FINAL_ARG(moduleSpec) | ||||||
|  | 	SECMOD_SPEC_COPY(newSpecPtr, modulePrev, moduleSpec); | ||||||
|  |     } | ||||||
|  |     if (tmp) { | ||||||
|  | 	PORT_Free(tmp); | ||||||
|  | 	tmp = NULL; | ||||||
|  |     } | ||||||
|  |     *newSpecPtr = 0; | ||||||
|  | 
 | ||||||
|  |     /* no target found, return the newSpec */ | ||||||
|  |     if (target == NULL) { | ||||||
|  | 	return newSpec; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* now build the child array from target */ | ||||||
|  |     /*first count them */ | ||||||
|  |     for (tokenIndex = secmod_argStrip(target); *tokenIndex; | ||||||
|  | 	tokenIndex = secmod_argStrip(secmod_argSkipParameter(tokenIndex))) { | ||||||
|  | 	tokenCount++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     childArray = PORT_NewArray(char *, tokenCount+1); | ||||||
|  |     if (childArray == NULL) { | ||||||
|  | 	/* just return the spec as is then */ | ||||||
|  | 	PORT_Free(target); | ||||||
|  | 	return newSpec; | ||||||
|  |     } | ||||||
|  |     if (ids) { | ||||||
|  | 	idArray = PORT_NewArray(CK_SLOT_ID, tokenCount+1); | ||||||
|  | 	if (idArray == NULL) { | ||||||
|  | 	    PORT_Free(childArray); | ||||||
|  | 	    PORT_Free(target); | ||||||
|  | 	    return newSpec; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* now fill them in */ | ||||||
|  |     for (tokenIndex = secmod_argStrip(target), i=0 ;  | ||||||
|  | 			*tokenIndex && (i < tokenCount);  | ||||||
|  | 			tokenIndex=secmod_argStrip(tokenIndex)) { | ||||||
|  | 	int next; | ||||||
|  | 	char *name = secmod_argGetName(tokenIndex, &next); | ||||||
|  | 	tokenIndex += next; | ||||||
|  | 
 | ||||||
|  |  	if (idArray) { | ||||||
|  | 	   idArray[i] = secmod_argDecodeNumber(name); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	PORT_Free(name); /* drop the explicit number */ | ||||||
|  | 
 | ||||||
|  | 	/* if anything is left, copy the args to the child array */ | ||||||
|  | 	if (!secmod_argIsBlank(*tokenIndex)) { | ||||||
|  | 	    childArray[i++] = secmod_argFetchValue(tokenIndex, &next); | ||||||
|  | 	    tokenIndex += next; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     PORT_Free(target); | ||||||
|  |     childArray[i] = 0; | ||||||
|  |     if (idArray) { | ||||||
|  | 	idArray[i] = 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* return it */ | ||||||
|  |     *children = childArray; | ||||||
|  |     if (ids) { | ||||||
|  | 	*ids = idArray; | ||||||
|  |     } | ||||||
|  |     return newSpec; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* get the database and flags from the spec */ | ||||||
|  | static char * | ||||||
|  | secmod_getConfigDir(char *spec, char **certPrefix, char **keyPrefix, | ||||||
|  | 			  PRBool *readOnly) | ||||||
|  | { | ||||||
|  |     char * config = NULL; | ||||||
|  | 
 | ||||||
|  |     *certPrefix = NULL; | ||||||
|  |     *keyPrefix = NULL; | ||||||
|  |     *readOnly = secmod_argHasFlag("flags","readOnly",spec); | ||||||
|  | 
 | ||||||
|  |     spec = secmod_argStrip(spec); | ||||||
|  |     while (*spec) { | ||||||
|  | 	int next; | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(spec, config, "configdir=", ;) | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(spec, *certPrefix, "certPrefix=", ;) | ||||||
|  | 	SECMOD_HANDLE_STRING_ARG(spec, *keyPrefix, "keyPrefix=", ;) | ||||||
|  | 	SECMOD_HANDLE_FINAL_ARG(spec) | ||||||
|  |     } | ||||||
|  |     return config; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct SECMODConfigListStr { | ||||||
|  |     char *config; | ||||||
|  |     char *certPrefix; | ||||||
|  |     char *keyPrefix; | ||||||
|  |     PRBool isReadOnly; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * return an array of already openned databases from a spec list. | ||||||
|  |  */ | ||||||
|  | SECMODConfigList * | ||||||
|  | secmod_GetConfigList(PRBool isFIPS, char *spec, int *count) | ||||||
|  | { | ||||||
|  |     char **children; | ||||||
|  |     CK_SLOT_ID *ids; | ||||||
|  |     char *strippedSpec; | ||||||
|  |     int childCount; | ||||||
|  |     SECMODConfigList *conflist = NULL; | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     strippedSpec = secmod_ParseModuleSpecForTokens(PR_TRUE, isFIPS,  | ||||||
|  | 						spec,&children,&ids); | ||||||
|  |     if (strippedSpec == NULL) { | ||||||
|  | 	return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (childCount=0; children && children[childCount]; childCount++) ; | ||||||
|  |     *count = childCount+1; /* include strippedSpec */ | ||||||
|  |     conflist = PORT_NewArray(SECMODConfigList,*count); | ||||||
|  |     if (conflist == NULL) { | ||||||
|  | 	*count = 0; | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     conflist[0].config = secmod_getConfigDir(strippedSpec,  | ||||||
|  | 					    &conflist[0].certPrefix,  | ||||||
|  | 					    &conflist[0].keyPrefix, | ||||||
|  | 					    &conflist[0].isReadOnly); | ||||||
|  |     for (i=0; i < childCount; i++) { | ||||||
|  | 	conflist[i+1].config = secmod_getConfigDir(children[i],  | ||||||
|  | 					    &conflist[i+1].certPrefix,  | ||||||
|  | 					    &conflist[i+1].keyPrefix, | ||||||
|  | 					    &conflist[i+1].isReadOnly); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     secmod_FreeChildren(children, ids); | ||||||
|  |     PORT_Free(strippedSpec); | ||||||
|  |     return conflist; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * determine if we are trying to open an old dbm database. For this test | ||||||
|  |  * RDB databases should return PR_FALSE. | ||||||
|  |  */ | ||||||
|  | static PRBool | ||||||
|  | secmod_configIsDBM(char *configDir) | ||||||
|  | { | ||||||
|  |     char *env; | ||||||
|  | 
 | ||||||
|  |     /* explicit dbm open */ | ||||||
|  |     if (strncmp(configDir, "dbm:", 4) == 0) { | ||||||
|  | 	return PR_TRUE; | ||||||
|  |     } | ||||||
|  |     /* explicit open of a non-dbm database */ | ||||||
|  |     if ((strncmp(configDir, "sql:",4) == 0)  | ||||||
|  | 	|| (strncmp(configDir, "rdb:", 4) == 0) | ||||||
|  | 	|| (strncmp(configDir, "extern:", 7) == 0)) { | ||||||
|  | 	return PR_FALSE; | ||||||
|  |     } | ||||||
|  |     env = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); | ||||||
|  |     /* implicit dbm open */ | ||||||
|  |     if ((env == NULL) || (strcmp(env,"dbm") == 0)) { | ||||||
|  | 	return PR_TRUE; | ||||||
|  |     } | ||||||
|  |     /* implicit non-dbm open */ | ||||||
|  |     return PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * match two prefixes. prefix may be NULL. NULL patches '\0' | ||||||
|  |  */ | ||||||
|  | static PRBool | ||||||
|  | secmod_matchPrefix(char *prefix1, char *prefix2) | ||||||
|  | { | ||||||
|  |     if ((prefix1 == NULL) || (*prefix1 == 0)) { | ||||||
|  | 	if ((prefix2 == NULL) || (*prefix2 == 0)) { | ||||||
|  | 	    return PR_TRUE; | ||||||
|  | 	} | ||||||
|  | 	return PR_FALSE; | ||||||
|  |     } | ||||||
|  |     if (strcmp(prefix1, prefix2) == 0) { | ||||||
|  | 	return PR_TRUE; | ||||||
|  |     } | ||||||
|  |     return PR_FALSE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * return true if we are requesting a database that is already openned. | ||||||
|  |  */ | ||||||
|  | PRBool | ||||||
|  | secmod_MatchConfigList(char *spec, SECMODConfigList *conflist, int count) | ||||||
|  | { | ||||||
|  |     char *config; | ||||||
|  |     char *certPrefix; | ||||||
|  |     char *keyPrefix; | ||||||
|  |     PRBool isReadOnly; | ||||||
|  |     PRBool ret=PR_FALSE; | ||||||
|  |     int i; | ||||||
|  | 
 | ||||||
|  |     config = secmod_getConfigDir(spec, &certPrefix, &keyPrefix, &isReadOnly); | ||||||
|  |     if (!config) { | ||||||
|  | 	ret=PR_TRUE; | ||||||
|  | 	goto done; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* NOTE: we dbm isn't multiple open safe. If we open the same database 
 | ||||||
|  |      * twice from two different locations, then we can corrupt our database | ||||||
|  |      * (the cache will be inconsistent). Protect against this by claiming | ||||||
|  |      * for comparison only that we are always openning dbm databases read only. | ||||||
|  |      */ | ||||||
|  |     if (secmod_configIsDBM(config)) { | ||||||
|  | 	isReadOnly = 1; | ||||||
|  |     } | ||||||
|  |     for (i=0; i < count; i++) { | ||||||
|  | 	if ((strcmp(config,conflist[i].config) == 0)  && | ||||||
|  | 	    secmod_matchPrefix(certPrefix, conflist[i].certPrefix) && | ||||||
|  | 	    secmod_matchPrefix(keyPrefix, conflist[i].keyPrefix) && | ||||||
|  | 	    /* this last test -- if we just need the DB open read only,
 | ||||||
|  | 	     * than any open will suffice, but if we requested it read/write | ||||||
|  | 	     * and it's only open read only, we need to open it again */ | ||||||
|  | 	    (isReadOnly || !conflist[i].isReadOnly)) { | ||||||
|  | 	    ret = PR_TRUE; | ||||||
|  | 	    goto done; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ret = PR_FALSE; | ||||||
|  | done: | ||||||
|  |     PORT_Free(config); | ||||||
|  |     PORT_Free(certPrefix); | ||||||
|  |     PORT_Free(keyPrefix); | ||||||
|  |     return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | secmod_FreeConfigList(SECMODConfigList *conflist, int count) | ||||||
|  | { | ||||||
|  |     int i; | ||||||
|  |     for (i=0; i < count; i++) { | ||||||
|  | 	PORT_Free(conflist[i].config); | ||||||
|  | 	PORT_Free(conflist[i].certPrefix); | ||||||
|  | 	PORT_Free(conflist[i].keyPrefix); | ||||||
|  |     } | ||||||
|  |     PORT_Free(conflist); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | secmod_FreeChildren(char **children, CK_SLOT_ID *ids) | ||||||
|  | { | ||||||
|  |     char **thisChild; | ||||||
|  | 
 | ||||||
|  |     if (!children) { | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (thisChild = children; thisChild && *thisChild; thisChild++ ) { | ||||||
|  | 	PORT_Free(*thisChild); | ||||||
|  |     } | ||||||
|  |     PORT_Free(children); | ||||||
|  |     if (ids) { | ||||||
|  | 	PORT_Free(ids); | ||||||
|  |     } | ||||||
|  |     return; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | secmod_escapeSize(const char *string, char quote) | ||||||
|  | { | ||||||
|  |     int escapes = 0, size = 0; | ||||||
|  |     const char *src; | ||||||
|  |     for (src=string; *src ; src++) { | ||||||
|  |         if ((*src == quote) || (*src == '\\')) escapes++; | ||||||
|  |         size++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return escapes+size+1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * add escapes to protect quote characters... | ||||||
|  |  */ | ||||||
|  | static char * | ||||||
|  | secmod_addEscape(const char *string, char quote) | ||||||
|  | { | ||||||
|  |     char *newString = 0; | ||||||
|  |     int size = 0; | ||||||
|  |     const char *src; | ||||||
|  |     char *dest; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     size = secmod_escapeSize(string,quote); | ||||||
|  |     newString = PORT_ZAlloc(size); | ||||||
|  |     if (newString == NULL) { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (src=string, dest=newString; *src; src++,dest++) { | ||||||
|  |         if ((*src == '\\') || (*src == quote)) { | ||||||
|  |             *dest++ = '\\'; | ||||||
|  |         } | ||||||
|  |         *dest = *src; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return newString; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | secmod_doubleEscapeSize(const char *string, char quote1, char quote2) | ||||||
|  | { | ||||||
|  |     int escapes = 0, size = 0; | ||||||
|  |     const char *src; | ||||||
|  |     for (src=string; *src ; src++) { | ||||||
|  |         if (*src == '\\')   escapes+=3; /* \\\\ */ | ||||||
|  |         if (*src == quote1) escapes+=2; /* \\quote1 */ | ||||||
|  |         if (*src == quote2) escapes++;   /* \quote2 */ | ||||||
|  |         size++; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return escapes+size+1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | char * | ||||||
|  | secmod_DoubleEscape(const char *string, char quote1, char quote2) | ||||||
|  | { | ||||||
|  |     char *round1 = NULL; | ||||||
|  |     char *retValue = NULL; | ||||||
|  |     if (string == NULL) { | ||||||
|  |         goto done; | ||||||
|  |     } | ||||||
|  |     round1 = secmod_addEscape(string,quote1); | ||||||
|  |     if (round1) { | ||||||
|  |         retValue = secmod_addEscape(round1,quote2); | ||||||
|  |         PORT_Free(round1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | done: | ||||||
|  |     if (retValue == NULL) { | ||||||
|  |         retValue = PORT_Strdup(""); | ||||||
|  |     } | ||||||
|  |     return retValue; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * caclulate the length of each child record: | ||||||
|  |  * " 0x{id}=<{escaped_child}>" | ||||||
|  |  */ | ||||||
|  | static int | ||||||
|  | secmod_getChildLength(char *child, CK_SLOT_ID id) | ||||||
|  | { | ||||||
|  |     int length = secmod_doubleEscapeSize(child, '>', ']'); | ||||||
|  |     if (id == 0) { | ||||||
|  | 	length++; | ||||||
|  |     } | ||||||
|  |     while (id) { | ||||||
|  | 	length++; | ||||||
|  | 	id = id >> 4; | ||||||
|  |     } | ||||||
|  |     length += 6; /* {sp}0x[id]=<{child}> */ | ||||||
|  |     return length; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Build a child record: | ||||||
|  |  * " 0x{id}=<{escaped_child}>" | ||||||
|  |  */ | ||||||
|  | static SECStatus | ||||||
|  | secmod_mkTokenChild(char **next, int *length, char *child, CK_SLOT_ID id) | ||||||
|  | { | ||||||
|  |     int len; | ||||||
|  |     char *escSpec; | ||||||
|  | 
 | ||||||
|  |     len = PR_snprintf(*next, *length, " 0x%x=<",id); | ||||||
|  |     if (len < 0) { | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     *next += len; | ||||||
|  |     *length -= len; | ||||||
|  |     escSpec = secmod_DoubleEscape(child, '>', ']'); | ||||||
|  |     if (escSpec == NULL) { | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     if (*child && (*escSpec == 0)) { | ||||||
|  | 	PORT_Free(escSpec); | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     len = strlen(escSpec); | ||||||
|  |     if (len+1 > *length) { | ||||||
|  | 	PORT_Free(escSpec); | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     PORT_Memcpy(*next,escSpec, len); | ||||||
|  |     *next += len; | ||||||
|  |     *length -= len; | ||||||
|  |     PORT_Free(escSpec); | ||||||
|  |     **next = '>'; | ||||||
|  |     (*next)++; | ||||||
|  |     (*length)--; | ||||||
|  |     return SECSuccess; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #define TOKEN_STRING " tokens=[" | ||||||
|  | 
 | ||||||
|  | char * | ||||||
|  | secmod_MkAppendTokensList(PRArenaPool *arena, char *oldParam, char *newToken,  | ||||||
|  | 			CK_SLOT_ID newID, char **children, CK_SLOT_ID *ids) | ||||||
|  | { | ||||||
|  |     char *rawParam = NULL;	/* oldParam with tokens stripped off */ | ||||||
|  |     char *newParam = NULL;	/* space for the return parameter */ | ||||||
|  |     char *nextParam = NULL;	/* current end of the new parameter */ | ||||||
|  |     char **oldChildren = NULL; | ||||||
|  |     CK_SLOT_ID *oldIds = NULL; | ||||||
|  |     void *mark = NULL;         /* mark the arena pool in case we need 
 | ||||||
|  | 				* to release it */ | ||||||
|  |     int length, i, tmpLen; | ||||||
|  |     SECStatus rv; | ||||||
|  | 
 | ||||||
|  |     /* first strip out and save the old tokenlist */ | ||||||
|  |     rawParam = secmod_ParseModuleSpecForTokens(PR_FALSE,PR_FALSE,  | ||||||
|  | 					oldParam,&oldChildren,&oldIds); | ||||||
|  |     if (!rawParam) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* now calculate the total length of the new buffer */ | ||||||
|  |     /* First the 'fixed stuff', length of rawparam (does not include a NULL),
 | ||||||
|  |      * length of the token string (does include the NULL), closing bracket */ | ||||||
|  |     length = strlen(rawParam) + sizeof(TOKEN_STRING) + 1; | ||||||
|  |     /* now add then length of all the old children */ | ||||||
|  |     for (i=0; oldChildren && oldChildren[i]; i++) { | ||||||
|  | 	length += secmod_getChildLength(oldChildren[i], oldIds[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* add the new token */ | ||||||
|  |     length += secmod_getChildLength(newToken, newID); | ||||||
|  | 
 | ||||||
|  |     /* and it's new children */ | ||||||
|  |     for (i=0; children && children[i]; i++) { | ||||||
|  | 	if (ids[i] == -1) { | ||||||
|  | 	    continue; | ||||||
|  | 	} | ||||||
|  | 	length += secmod_getChildLength(children[i], ids[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* now allocate and build the string */ | ||||||
|  |     mark = PORT_ArenaMark(arena); | ||||||
|  |     if (!mark) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  |     newParam =  PORT_ArenaAlloc(arena,length); | ||||||
|  |     if (!newParam) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     PORT_Strcpy(newParam, oldParam); | ||||||
|  |     tmpLen = strlen(oldParam); | ||||||
|  |     nextParam = newParam + tmpLen; | ||||||
|  |     length -= tmpLen; | ||||||
|  |     PORT_Memcpy(nextParam, TOKEN_STRING, sizeof(TOKEN_STRING)-1); | ||||||
|  |     nextParam += sizeof(TOKEN_STRING)-1; | ||||||
|  |     length -= sizeof(TOKEN_STRING)-1; | ||||||
|  | 
 | ||||||
|  |     for (i=0; oldChildren && oldChildren[i]; i++) { | ||||||
|  | 	rv = secmod_mkTokenChild(&nextParam,&length,oldChildren[i],oldIds[i]); | ||||||
|  | 	if (rv != SECSuccess) { | ||||||
|  | 	    goto loser; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     rv = secmod_mkTokenChild(&nextParam, &length, newToken, newID); | ||||||
|  |     if (rv != SECSuccess) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i=0; children && children[i]; i++) { | ||||||
|  | 	if (ids[i] == -1) { | ||||||
|  | 	    continue; | ||||||
|  | 	} | ||||||
|  | 	rv = secmod_mkTokenChild(&nextParam, &length, children[i], ids[i]); | ||||||
|  | 	if (rv != SECSuccess) { | ||||||
|  | 	    goto loser; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (length < 2) { | ||||||
|  | 	goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     *nextParam++ = ']'; | ||||||
|  |     *nextParam++ = 0; | ||||||
|  | 
 | ||||||
|  |     /* we are going to return newParam now, don't release the mark */ | ||||||
|  |     PORT_ArenaUnmark(arena, mark); | ||||||
|  |     mark = NULL; | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     if (mark) { | ||||||
|  | 	PORT_ArenaRelease(arena, mark); | ||||||
|  | 	newParam = NULL; /* if the mark is still active, 
 | ||||||
|  | 			  * don't return the param */ | ||||||
|  |     } | ||||||
|  |     if (rawParam) { | ||||||
|  | 	PORT_Free(rawParam); | ||||||
|  |     } | ||||||
|  |     if (oldChildren) { | ||||||
|  | 	secmod_FreeChildren(oldChildren, oldIds); | ||||||
|  |     } | ||||||
|  |     return newParam; | ||||||
|  | } | ||||||
|  |      | ||||||
| static char * | static char * | ||||||
| secmod_mkModuleSpec(SECMODModule * module) | secmod_mkModuleSpec(SECMODModule * module) | ||||||
| { | { | ||||||
|  | @ -296,6 +1077,7 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse) | ||||||
|     char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL; |     char *library = NULL, *moduleName = NULL, *parameters = NULL, *nss= NULL; | ||||||
|     SECStatus status; |     SECStatus status; | ||||||
|     SECMODModule *module = NULL; |     SECMODModule *module = NULL; | ||||||
|  |     SECMODModule *oldModule = NULL; | ||||||
|     SECStatus rv; |     SECStatus rv; | ||||||
| 
 | 
 | ||||||
|     /* initialize the underlying module structures */ |     /* initialize the underlying module structures */ | ||||||
|  | @ -317,14 +1099,26 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse) | ||||||
|     } |     } | ||||||
|     if (parent) { |     if (parent) { | ||||||
|     	module->parent = SECMOD_ReferenceModule(parent); |     	module->parent = SECMOD_ReferenceModule(parent); | ||||||
|  | 	if (module->internal && secmod_IsInternalKeySlot(parent)) { | ||||||
|  | 	    module->internal = parent->internal; | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* load it */ |     /* load it */ | ||||||
|     rv = SECMOD_LoadPKCS11Module(module); |     rv = secmod_LoadPKCS11Module(module, &oldModule); | ||||||
|     if (rv != SECSuccess) { |     if (rv != SECSuccess) { | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /* if we just reload an old module, no need to add it to any lists.
 | ||||||
|  |      * we simple release all our references */ | ||||||
|  |     if (oldModule) { | ||||||
|  | 	/* This module already exists, don't link it anywhere. This
 | ||||||
|  | 	 * will probably destroy this module */ | ||||||
|  | 	SECMOD_DestroyModule(module); | ||||||
|  | 	return oldModule; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     if (recurse && module->isModuleDB) { |     if (recurse && module->isModuleDB) { | ||||||
| 	char ** moduleSpecList; | 	char ** moduleSpecList; | ||||||
| 	PORT_SetError(0); | 	PORT_SetError(0); | ||||||
|  | @ -333,7 +1127,12 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse) | ||||||
| 	if (moduleSpecList) { | 	if (moduleSpecList) { | ||||||
| 	    char **index; | 	    char **index; | ||||||
| 
 | 
 | ||||||
| 	    for (index = moduleSpecList; *index; index++) { | 	    index = moduleSpecList; | ||||||
|  | 	    if (*index && SECMOD_GetSkipFirstFlag(module)) { | ||||||
|  | 		index++; | ||||||
|  | 	    } | ||||||
|  | 
 | ||||||
|  | 	    for (; *index; index++) { | ||||||
| 		SECMODModule *child; | 		SECMODModule *child; | ||||||
| 		child = SECMOD_LoadModule(*index,module,PR_TRUE); | 		child = SECMOD_LoadModule(*index,module,PR_TRUE); | ||||||
| 		if (!child) break; | 		if (!child) break; | ||||||
|  |  | ||||||
|  | @ -291,18 +291,12 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, | ||||||
|     CK_ATTRIBUTE theTemplate[20]; |     CK_ATTRIBUTE theTemplate[20]; | ||||||
|     int templateCount = 0; |     int templateCount = 0; | ||||||
|     SECStatus rv = SECFailure; |     SECStatus rv = SECFailure; | ||||||
|     PRArenaPool *arena; |  | ||||||
|     CK_ATTRIBUTE *attrs; |     CK_ATTRIBUTE *attrs; | ||||||
|     CK_ATTRIBUTE *signedattr = NULL; |     CK_ATTRIBUTE *signedattr = NULL; | ||||||
|     int signedcount = 0; |     int signedcount = 0; | ||||||
|     CK_ATTRIBUTE *ap; |     CK_ATTRIBUTE *ap; | ||||||
|     SECItem *ck_id = NULL; |     SECItem *ck_id = NULL; | ||||||
| 
 | 
 | ||||||
|     arena = PORT_NewArena(2048); |  | ||||||
|     if(!arena) { |  | ||||||
| 	return SECFailure; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     attrs = theTemplate; |     attrs = theTemplate; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -114,6 +114,7 @@ SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts); | ||||||
| void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot); | void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot); | ||||||
| PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot); | PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot); | ||||||
| SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot); | SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot); | ||||||
|  | void pk11_SetInternalKeySlot(PK11SlotInfo *slot); | ||||||
| 
 | 
 | ||||||
| /*********************************************************************
 | /*********************************************************************
 | ||||||
|  *       Mechanism Mapping functions |  *       Mechanism Mapping functions | ||||||
|  |  | ||||||
|  | @ -574,6 +574,10 @@ SECKEYPrivateKey *PK11_UnwrapPrivKey(PK11SlotInfo *slot, | ||||||
| SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, | SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey, | ||||||
| 			   SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType, | 			   SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType, | ||||||
| 			   SECItem *param, SECItem *wrappedKey, void *wincx); | 			   SECItem *param, SECItem *wrappedKey, void *wincx); | ||||||
|  | /*
 | ||||||
|  |  * The caller of PK11_DEREncodePublicKey should free the returned SECItem with | ||||||
|  |  * a SECITEM_FreeItem(..., PR_TRUE) call. | ||||||
|  |  */ | ||||||
| SECItem* PK11_DEREncodePublicKey(SECKEYPublicKey *pubk); | SECItem* PK11_DEREncodePublicKey(SECKEYPublicKey *pubk); | ||||||
| PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey, | PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey, | ||||||
| 	CK_MECHANISM_TYPE mech); | 	CK_MECHANISM_TYPE mech); | ||||||
|  | @ -791,6 +795,11 @@ PK11GenericObject *PK11_CreateGenericObject(PK11SlotInfo *slot, | ||||||
|  * |  * | ||||||
|  *  All other types are considered invalid. If type does not match the object |  *  All other types are considered invalid. If type does not match the object | ||||||
|  *  passed, unpredictable results will occur. |  *  passed, unpredictable results will occur. | ||||||
|  |  * | ||||||
|  |  * PK11_ReadRawAttribute allocates the buffer for returning the attribute | ||||||
|  |  * value.  The caller of PK11_ReadRawAttribute should free the data buffer | ||||||
|  |  * pointed to by item using a SECITEM_FreeItem(item, PR_FALSE) or | ||||||
|  |  * PORT_Free(item->data) call. | ||||||
|  */ |  */ | ||||||
| SECStatus PK11_ReadRawAttribute(PK11ObjectType type, void *object,  | SECStatus PK11_ReadRawAttribute(PK11ObjectType type, void *object,  | ||||||
| 				CK_ATTRIBUTE_TYPE attr, SECItem *item); | 				CK_ATTRIBUTE_TYPE attr, SECItem *item); | ||||||
|  |  | ||||||
|  | @ -1129,6 +1129,8 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) | ||||||
| 							PR_TRUE : PR_FALSE); | 							PR_TRUE : PR_FALSE); | ||||||
|     slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?  |     slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?  | ||||||
| 							PR_TRUE : PR_FALSE); | 							PR_TRUE : PR_FALSE); | ||||||
|  | 	 | ||||||
|  | 	  | ||||||
|     slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); |     slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE); | ||||||
|     slot->protectedAuthPath = |     slot->protectedAuthPath = | ||||||
|     		((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)  |     		((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)  | ||||||
|  | @ -1248,7 +1250,33 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) | ||||||
| 	    PK11_FreeSlot(int_slot); | 	    PK11_FreeSlot(int_slot); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|  |     /* work around a problem in softoken where it incorrectly
 | ||||||
|  |      * reports databases opened read only as read/write. */ | ||||||
|  |     if (slot->isInternal && !slot->readOnly) { | ||||||
|  | 	CK_SESSION_HANDLE session = CK_INVALID_SESSION; | ||||||
| 
 | 
 | ||||||
|  | 	/* try to open a R/W session */ | ||||||
|  | 	crv =PK11_GETTAB(slot)->C_OpenSession(slot->slotID, | ||||||
|  | 	      CKF_RW_SESSION|CKF_SERIAL_SESSION, slot, pk11_notify ,&session); | ||||||
|  | 	/* what a well behaved token should return if you open 
 | ||||||
|  | 	 * a RW session on a read only token */ | ||||||
|  | 	if (crv == CKR_TOKEN_WRITE_PROTECTED) { | ||||||
|  | 	    slot->readOnly = PR_TRUE; | ||||||
|  | 	} else if (crv == CKR_OK) { | ||||||
|  | 	    CK_SESSION_INFO sessionInfo; | ||||||
|  | 
 | ||||||
|  | 	    /* Because of a second bug in softoken, which silently returns
 | ||||||
|  | 	     * a RO session, we need to check what type of session we got. */ | ||||||
|  | 	    crv = PK11_GETTAB(slot)->C_GetSessionInfo(session, &sessionInfo); | ||||||
|  | 	    if (crv == CKR_OK) { | ||||||
|  | 		if ((sessionInfo.flags & CKF_RW_SESSION) == 0) { | ||||||
|  | 		    /* session was readonly, so this softoken slot must be 			     * readonly */ | ||||||
|  | 		    slot->readOnly = PR_TRUE; | ||||||
|  | 		} | ||||||
|  | 	    } | ||||||
|  | 	    PK11_GETTAB(slot)->C_CloseSession(session); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
| 	 | 	 | ||||||
|     return SECSuccess; |     return SECSuccess; | ||||||
| } | } | ||||||
|  | @ -1697,12 +1725,29 @@ PK11_NeedUserInit(PK11SlotInfo *slot) | ||||||
|     return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0); |     return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static PK11SlotInfo *pk11InternalKeySlot = NULL; | ||||||
|  | void | ||||||
|  | pk11_SetInternalKeySlot(PK11SlotInfo *slot) | ||||||
|  | { | ||||||
|  |    if (pk11InternalKeySlot) { | ||||||
|  | 	PK11_FreeSlot(pk11InternalKeySlot); | ||||||
|  |    } | ||||||
|  |    pk11InternalKeySlot = slot ? PK11_ReferenceSlot(slot) : NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* get the internal key slot. FIPS has only one slot for both key slots and
 | /* get the internal key slot. FIPS has only one slot for both key slots and
 | ||||||
|  * default slots */ |  * default slots */ | ||||||
| PK11SlotInfo * | PK11SlotInfo * | ||||||
| PK11_GetInternalKeySlot(void) | PK11_GetInternalKeySlot(void) | ||||||
| { | { | ||||||
|     SECMODModule *mod = SECMOD_GetInternalModule(); |     SECMODModule *mod; | ||||||
|  | 
 | ||||||
|  |     if (pk11InternalKeySlot) { | ||||||
|  | 	return PK11_ReferenceSlot(pk11InternalKeySlot); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     mod = SECMOD_GetInternalModule(); | ||||||
|     PORT_Assert(mod != NULL); |     PORT_Assert(mod != NULL); | ||||||
|     if (!mod) { |     if (!mod) { | ||||||
| 	PORT_SetError( SEC_ERROR_NO_MODULE ); | 	PORT_SetError( SEC_ERROR_NO_MODULE ); | ||||||
|  | @ -1721,6 +1766,9 @@ PK11_GetInternalSlot(void) | ||||||
| 	PORT_SetError( SEC_ERROR_NO_MODULE ); | 	PORT_SetError( SEC_ERROR_NO_MODULE ); | ||||||
| 	return NULL; | 	return NULL; | ||||||
|     } |     } | ||||||
|  |     if (mod->isFIPS) { | ||||||
|  | 	return PK11_GetInternalKeySlot(); | ||||||
|  |     } | ||||||
|     return PK11_ReferenceSlot(mod->slots[0]); |     return PK11_ReferenceSlot(mod->slots[0]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -179,7 +179,10 @@ SECMOD_AddModuleToList(SECMODModule *newModule) | ||||||
| SECStatus | SECStatus | ||||||
| SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule) | SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule) | ||||||
| { | { | ||||||
|     if (defaultDBModule == NULL) { |     if (defaultDBModule && SECMOD_GetDefaultModDBFlag(newModule)) { | ||||||
|  | 	SECMOD_DestroyModule(defaultDBModule); | ||||||
|  | 	defaultDBModule = SECMOD_ReferenceModule(newModule); | ||||||
|  |     } else if (defaultDBModule == NULL) { | ||||||
| 	defaultDBModule = SECMOD_ReferenceModule(newModule); | 	defaultDBModule = SECMOD_ReferenceModule(newModule); | ||||||
|     } |     } | ||||||
|     return secmod_AddModuleToList(&modulesDB,newModule); |     return secmod_AddModuleToList(&modulesDB,newModule); | ||||||
|  | @ -281,6 +284,34 @@ SECMOD_FindModuleByID(SECMODModuleID id) | ||||||
|     return module; |     return module; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * find the function pointer. | ||||||
|  |  */ | ||||||
|  | SECMODModule * | ||||||
|  | secmod_FindModuleByFuncPtr(void *funcPtr)  | ||||||
|  | { | ||||||
|  |     SECMODModuleList *mlp; | ||||||
|  |     SECMODModule *module = NULL; | ||||||
|  | 
 | ||||||
|  |     SECMOD_GetReadLock(moduleLock); | ||||||
|  |     for(mlp = modules; mlp != NULL; mlp = mlp->next) { | ||||||
|  | 	/* paranoia, shouldn't ever happen */ | ||||||
|  | 	if (!mlp->module) { | ||||||
|  | 	    continue; | ||||||
|  | 	} | ||||||
|  | 	if (funcPtr == mlp->module->functionList) { | ||||||
|  | 	    module = mlp->module; | ||||||
|  | 	    SECMOD_ReferenceModule(module); | ||||||
|  | 	    break; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     SECMOD_ReleaseReadLock(moduleLock); | ||||||
|  |     if (module == NULL) { | ||||||
|  | 	PORT_SetError(SEC_ERROR_NO_MODULE); | ||||||
|  |     } | ||||||
|  |     return module; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Find the Slot based on ID and the module. |  * Find the Slot based on ID and the module. | ||||||
|  */ |  */ | ||||||
|  | @ -505,7 +536,7 @@ SECMOD_AddModule(SECMODModule *newModule) | ||||||
|         /* module already exists. */ |         /* module already exists. */ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     rv = SECMOD_LoadPKCS11Module(newModule); |     rv = secmod_LoadPKCS11Module(newModule, NULL); | ||||||
|     if (rv != SECSuccess) { |     if (rv != SECSuccess) { | ||||||
| 	return rv; | 	return rv; | ||||||
|     } |     } | ||||||
|  | @ -1199,7 +1230,7 @@ SECMOD_CancelWait(SECMODModule *mod) | ||||||
| 	 * we intend to use it again */ | 	 * we intend to use it again */ | ||||||
| 	if (CKR_OK == crv) { | 	if (CKR_OK == crv) { | ||||||
|             PRBool alreadyLoaded; |             PRBool alreadyLoaded; | ||||||
| 	    secmod_ModuleInit(mod, &alreadyLoaded); | 	    secmod_ModuleInit(mod, NULL, &alreadyLoaded); | ||||||
| 	} else { | 	} else { | ||||||
| 	    /* Finalized failed for some reason,  notify the application
 | 	    /* Finalized failed for some reason,  notify the application
 | ||||||
| 	     * so maybe it has a prayer of recovering... */ | 	     * so maybe it has a prayer of recovering... */ | ||||||
|  | @ -1275,58 +1306,6 @@ secmod_UserDBOp(PK11SlotInfo *slot, CK_OBJECT_CLASS objClass, | ||||||
|     return SECMOD_UpdateSlotList(slot->module); |     return SECMOD_UpdateSlotList(slot->module); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 |  | ||||||
|  * add escapes to protect quote characters... |  | ||||||
|  */ |  | ||||||
| static char * |  | ||||||
| nss_addEscape(const char *string, char quote) |  | ||||||
| { |  | ||||||
|     char *newString = 0; |  | ||||||
|     int escapes = 0, size = 0; |  | ||||||
|     const char *src; |  | ||||||
|     char *dest; |  | ||||||
| 
 |  | ||||||
|     for (src=string; *src ; src++) { |  | ||||||
|         if ((*src == quote) || (*src == '\\')) escapes++; |  | ||||||
|         size++; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     newString = PORT_ZAlloc(escapes+size+1); |  | ||||||
|     if (newString == NULL) { |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     for (src=string, dest=newString; *src; src++,dest++) { |  | ||||||
|         if ((*src == '\\') || (*src == quote)) { |  | ||||||
|             *dest++ = '\\'; |  | ||||||
|         } |  | ||||||
|         *dest = *src; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return newString; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static char * |  | ||||||
| nss_doubleEscape(const char *string) |  | ||||||
| { |  | ||||||
|     char *round1 = NULL; |  | ||||||
|     char *retValue = NULL; |  | ||||||
|     if (string == NULL) { |  | ||||||
|         goto done; |  | ||||||
|     } |  | ||||||
|     round1 = nss_addEscape(string,'>'); |  | ||||||
|     if (round1) { |  | ||||||
|         retValue = nss_addEscape(round1,']'); |  | ||||||
|         PORT_Free(round1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| done: |  | ||||||
|     if (retValue == NULL) { |  | ||||||
|         retValue = PORT_Strdup(""); |  | ||||||
|     } |  | ||||||
|     return retValue; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /*
 | /*
 | ||||||
|  * return true if the selected slot ID is not present or doesn't exist |  * return true if the selected slot ID is not present or doesn't exist | ||||||
|  */ |  */ | ||||||
|  | @ -1409,7 +1388,7 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* we've found the slot, now build the moduleSpec */ |     /* we've found the slot, now build the moduleSpec */ | ||||||
|     escSpec = nss_doubleEscape(moduleSpec); |     escSpec = secmod_DoubleEscape(moduleSpec, '>', ']'); | ||||||
|     if (escSpec == NULL) { |     if (escSpec == NULL) { | ||||||
| 	PK11_FreeSlot(slot); | 	PK11_FreeSlot(slot); | ||||||
| 	return NULL; | 	return NULL; | ||||||
|  |  | ||||||
|  | @ -151,6 +151,10 @@ extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,const char *name); | ||||||
| /* of modType has been installed */ | /* of modType has been installed */ | ||||||
| PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags ); | PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags ); | ||||||
| 
 | 
 | ||||||
|  | /* accessors */ | ||||||
|  | PRBool SECMOD_GetSkipFirstFlag(SECMODModule *mod); | ||||||
|  | PRBool SECMOD_GetDefaultModDBFlag(SECMODModule *mod); | ||||||
|  | 
 | ||||||
| /* Functions used to convert between internal & public representation
 | /* Functions used to convert between internal & public representation
 | ||||||
|  * of Mechanism Flags and Cipher Enable Flags */ |  * of Mechanism Flags and Cipher Enable Flags */ | ||||||
| extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags); | extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags); | ||||||
|  |  | ||||||
|  | @ -58,7 +58,8 @@ void nss_DumpModuleLog(void); | ||||||
| extern int secmod_PrivateModuleCount; | extern int secmod_PrivateModuleCount; | ||||||
| 
 | 
 | ||||||
| extern void SECMOD_Init(void); | extern void SECMOD_Init(void); | ||||||
| SECStatus secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded); | SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule, | ||||||
|  | 			    PRBool* alreadyLoaded); | ||||||
| 
 | 
 | ||||||
| /* list managment */ | /* list managment */ | ||||||
| extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule); | extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule); | ||||||
|  | @ -73,6 +74,7 @@ extern void SECMOD_ReleaseWriteLock(SECMODListLock *); | ||||||
| 
 | 
 | ||||||
| /* Operate on modules by name */ | /* Operate on modules by name */ | ||||||
| extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID); | extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID); | ||||||
|  | extern SECMODModule *secmod_FindModuleByFuncPtr(void *funcPtr); | ||||||
| 
 | 
 | ||||||
| /* database/memory management */ | /* database/memory management */ | ||||||
| extern SECMODModuleList *SECMOD_NewModuleListElement(void); | extern SECMODModuleList *SECMOD_NewModuleListElement(void); | ||||||
|  | @ -84,9 +86,37 @@ extern unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags); | ||||||
| extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags); | extern unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags); | ||||||
| 
 | 
 | ||||||
| /* Library functions */ | /* Library functions */ | ||||||
| SECStatus SECMOD_LoadPKCS11Module(SECMODModule *); | SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule); | ||||||
| SECStatus SECMOD_UnloadModule(SECMODModule *); | SECStatus SECMOD_UnloadModule(SECMODModule *); | ||||||
| void SECMOD_SetInternalModule(SECMODModule *); | void SECMOD_SetInternalModule(SECMODModule *); | ||||||
|  | PRBool secmod_IsInternalKeySlot(SECMODModule *); | ||||||
|  | 
 | ||||||
|  | /* tools for checking if we are loading the same database twice */ | ||||||
|  | typedef struct SECMODConfigListStr SECMODConfigList; | ||||||
|  | /* collect all the databases in a given spec */ | ||||||
|  | SECMODConfigList *secmod_GetConfigList(PRBool isFIPS, char *spec, int *count); | ||||||
|  | /* see is a spec matches a database on the list */ | ||||||
|  | PRBool secmod_MatchConfigList(char *spec,  | ||||||
|  | 			      SECMODConfigList *conflist, int count); | ||||||
|  | /* free our list of databases */ | ||||||
|  | void secmod_FreeConfigList(SECMODConfigList *conflist, int count); | ||||||
|  | 
 | ||||||
|  | /* parsing parameters */ | ||||||
|  | /* returned char * must be freed by caller with PORT_Free */ | ||||||
|  | /* children and ids are null terminated arrays which must be freed with
 | ||||||
|  |  * secmod_FreeChildren */ | ||||||
|  | char *secmod_ParseModuleSpecForTokens(PRBool convert, | ||||||
|  | 				      PRBool isFIPS, | ||||||
|  | 				      char *moduleSpec, | ||||||
|  | 				      char ***children,  | ||||||
|  | 				      CK_SLOT_ID **ids); | ||||||
|  | void secmod_FreeChildren(char **children, CK_SLOT_ID *ids); | ||||||
|  | char *secmod_MkAppendTokensList(PRArenaPool *arena, char *origModuleSpec,  | ||||||
|  | 				char *newModuleSpec, CK_SLOT_ID newID, | ||||||
|  | 				char **children, CK_SLOT_ID *ids); | ||||||
|  | char *secmod_DoubleEscape(const char *string, char quote1, char quote2); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot); | void SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot); | ||||||
| CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, | CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.97 $ $Date: 2009/07/30 22:43:32 $"; | static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.98 $ $Date: 2009/10/01 17:14:02 $"; | ||||||
| #endif /* DEBUG */ | #endif /* DEBUG */ | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -101,6 +101,11 @@ STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot) | ||||||
|     NSSToken *token; |     NSSToken *token; | ||||||
|     if (!td) { |     if (!td) { | ||||||
| 	td = g_default_trust_domain; | 	td = g_default_trust_domain; | ||||||
|  | 	if (!td) { | ||||||
|  | 	    /* we're called while still initting. slot will get added
 | ||||||
|  | 	     * appropriately through normal init processes */ | ||||||
|  | 	    return PR_SUCCESS; | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
|     token = nssToken_CreateFromPK11SlotInfo(td, slot); |     token = nssToken_CreateFromPK11SlotInfo(td, slot); | ||||||
|     PK11Slot_SetNSSToken(slot, token); |     PK11Slot_SetNSSToken(slot, token); | ||||||
|  | @ -118,6 +123,11 @@ STAN_ResetTokenInterator(NSSTrustDomain *td) | ||||||
| { | { | ||||||
|     if (!td) { |     if (!td) { | ||||||
| 	td = g_default_trust_domain; | 	td = g_default_trust_domain; | ||||||
|  | 	if (!td) { | ||||||
|  | 	    /* we're called while still initting. slot will get added
 | ||||||
|  | 	     * appropriately through normal init processes */ | ||||||
|  | 	    return PR_SUCCESS; | ||||||
|  | 	} | ||||||
|     } |     } | ||||||
|     NSSRWLock_LockWrite(td->tokensLock); |     NSSRWLock_LockWrite(td->tokensLock); | ||||||
|     nssListIterator_Destroy(td->tokens); |     nssListIterator_Destroy(td->tokens); | ||||||
|  |  | ||||||
|  | @ -71,8 +71,8 @@ | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK |  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK | ||||||
|  FILEFLAGS MY_FILEFLAGS_2 |  FILEFLAGS MY_FILEFLAGS_2 | ||||||
|  FILEOS MY_FILEOS |  FILEOS MY_FILEOS | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ | ||||||
|  * The format of the version string should be |  * The format of the version string should be | ||||||
|  *     "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" |  *     "<major version>.<minor version>[.<patch level>][ <ECC>][ <Beta>]" | ||||||
|  */ |  */ | ||||||
| #define SOFTOKEN_VERSION  "3.12.4.5" SOFTOKEN_ECC_STRING | #define SOFTOKEN_VERSION  "3.12.4.6" SOFTOKEN_ECC_STRING | ||||||
| #define SOFTOKEN_VMAJOR   3 | #define SOFTOKEN_VMAJOR   3 | ||||||
| #define SOFTOKEN_VMINOR   12 | #define SOFTOKEN_VMINOR   12 | ||||||
| #define SOFTOKEN_VPATCH   4 | #define SOFTOKEN_VPATCH   4 | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								security/nss/lib/sqlite/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								security/nss/lib/sqlite/README
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | This is SQLite 3.6.22. | ||||||
|  | 
 | ||||||
|  | Local changes: | ||||||
|  | 
 | ||||||
|  | 1. Allow System V one-argument version of gettimeofday when compiled with | ||||||
|  | -D_SVID_GETTOD on Solaris.  See CVS revision 1.6. | ||||||
|  | @ -58,3 +58,12 @@ ifeq ($(OS_TARGET),SunOS) | ||||||
| OS_LIBS += -lbsm  | OS_LIBS += -lbsm  | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | ifeq ($(OS_TARGET),Darwin) | ||||||
|  | # These version numbers come from the -version-info 8:6:8 libtool option in
 | ||||||
|  | # sqlite upstream's Makefile.in.  (Given -version-info current:revision:age,
 | ||||||
|  | # libtool passes
 | ||||||
|  | #     -compatibility_version current+1 -current_version current+1.revision
 | ||||||
|  | # to the linker.)  Apple builds the system libsqlite3.dylib with these
 | ||||||
|  | # version numbers, so we use the same to be compatible.
 | ||||||
|  | DARWIN_DYLIB_VERSIONS = -compatibility_version 9 -current_version 9.6 | ||||||
|  | endif | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ MODULE = nss | ||||||
| LIBRARY_NAME = sqlite | LIBRARY_NAME = sqlite | ||||||
| LIBRARY_VERSION = 3 | LIBRARY_VERSION = 3 | ||||||
| MAPFILE = $(OBJDIR)/sqlite.def | MAPFILE = $(OBJDIR)/sqlite.def | ||||||
| DEFINES += -DTHREADSAFE=1 | DEFINES += -DSQLITE_THREADSAFE=1 | ||||||
| 
 | 
 | ||||||
| EXPORTS = \ | EXPORTS = \ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
|  |  | ||||||
|  | @ -18,7 +18,6 @@ LIBRARY sqlite3 ;- | ||||||
| EXPORTS ;- | EXPORTS ;- | ||||||
| sqlite3_aggregate_context; | sqlite3_aggregate_context; | ||||||
| sqlite3_aggregate_count; | sqlite3_aggregate_count; | ||||||
| sqlite3_apis; |  | ||||||
| sqlite3_auto_extension; | sqlite3_auto_extension; | ||||||
| sqlite3_bind_blob; | sqlite3_bind_blob; | ||||||
| sqlite3_bind_double; | sqlite3_bind_double; | ||||||
|  | @ -88,6 +87,7 @@ sqlite3_malloc; | ||||||
| sqlite3_mprintf; | sqlite3_mprintf; | ||||||
| sqlite3_open; | sqlite3_open; | ||||||
| sqlite3_open16; | sqlite3_open16; | ||||||
|  | sqlite3_open_v2; | ||||||
| sqlite3_overload_function; | sqlite3_overload_function; | ||||||
| sqlite3_prepare; | sqlite3_prepare; | ||||||
| sqlite3_prepare16; | sqlite3_prepare16; | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -71,6 +71,11 @@ CSRCS	+= unix_err.c | ||||||
| endif | endif | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | ifdef USE_SYSTEM_ZLIB | ||||||
|  | DEFINES += -DNSS_ENABLE_ZLIB | ||||||
|  | EXTRA_LIBS += $(ZLIB_LIBS) | ||||||
|  | endif | ||||||
|  | 
 | ||||||
| #######################################################################
 | #######################################################################
 | ||||||
| # (5) Execute "global" rules. (OPTIONAL)                              #
 | # (5) Execute "global" rules. (OPTIONAL)                              #
 | ||||||
| #######################################################################
 | #######################################################################
 | ||||||
|  |  | ||||||
|  | @ -43,6 +43,13 @@ ifdef NSS_SURVIVE_DOUBLE_BYPASS_FAILURE | ||||||
| DEFINES += -DNSS_SURVIVE_DOUBLE_BYPASS_FAILURE | DEFINES += -DNSS_SURVIVE_DOUBLE_BYPASS_FAILURE | ||||||
| endif | endif | ||||||
| 
 | 
 | ||||||
|  | # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 | ||||||
|  | CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) | ||||||
|  | 
 | ||||||
|  | EXTRA_LIBS += \
 | ||||||
|  | 	$(CRYPTOLIB) \
 | ||||||
|  | 	$(NULL) | ||||||
|  | 
 | ||||||
| ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ifeq (,$(filter-out WIN%,$(OS_TARGET))) | ||||||
| 
 | 
 | ||||||
| # don't want the 32 in the shared library name
 | # don't want the 32 in the shared library name
 | ||||||
|  | @ -73,23 +80,8 @@ EXTRA_SHARED_LIBS += \ | ||||||
| 	$(NULL) | 	$(NULL) | ||||||
| endif # NS_USE_GCC
 | endif # NS_USE_GCC
 | ||||||
| 
 | 
 | ||||||
| # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 |  | ||||||
| CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) |  | ||||||
| 
 |  | ||||||
| EXTRA_LIBS += \
 |  | ||||||
| 	$(CRYPTOLIB) \
 |  | ||||||
| 	$(NULL) |  | ||||||
| 
 |  | ||||||
| else | else | ||||||
| 
 | 
 | ||||||
| # $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
 |  | ||||||
| CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) |  | ||||||
| 
 |  | ||||||
| EXTRA_LIBS += \
 |  | ||||||
| 	$(CRYPTOLIB) \
 |  | ||||||
| 	$(NULL) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
 | # $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
 | ||||||
| # $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
 | # $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
 | ||||||
| EXTRA_SHARED_LIBS += \
 | EXTRA_SHARED_LIBS += \
 | ||||||
|  |  | ||||||
|  | @ -139,3 +139,14 @@ SSL_CanBypass; | ||||||
| ;+    local: | ;+    local: | ||||||
| ;+*; | ;+*; | ||||||
| ;+}; | ;+}; | ||||||
|  | ;+NSS_3.12.6 {      # NSS 3.12.6 release | ||||||
|  | ;+    global: | ||||||
|  | SSL_ConfigServerSessionIDCacheWithOpt; | ||||||
|  | SSL_GetNegotiatedHostInfo; | ||||||
|  | SSL_HandshakeNegotiatedExtension; | ||||||
|  | SSL_ReconfigFD; | ||||||
|  | SSL_SetTrustAnchors; | ||||||
|  | SSL_SNISocketConfigHook; | ||||||
|  | ;+    local: | ||||||
|  | ;+*; | ||||||
|  | ;+}; | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: ssl.h,v 1.28 2008/03/06 20:16:22 wtc%google.com Exp $ */ | /* $Id: ssl.h,v 1.35 2010/02/04 03:21:11 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #ifndef __ssl_h_ | #ifndef __ssl_h_ | ||||||
| #define __ssl_h_ | #define __ssl_h_ | ||||||
|  | @ -114,6 +114,14 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd); | ||||||
| #define SSL_NO_LOCKS                   17 /* Don't use locks for protection */ | #define SSL_NO_LOCKS                   17 /* Don't use locks for protection */ | ||||||
| #define SSL_ENABLE_SESSION_TICKETS     18 /* Enable TLS SessionTicket       */ | #define SSL_ENABLE_SESSION_TICKETS     18 /* Enable TLS SessionTicket       */ | ||||||
|                                           /* extension (off by default)     */ |                                           /* extension (off by default)     */ | ||||||
|  | #define SSL_ENABLE_DEFLATE             19 /* Enable TLS compression with    */ | ||||||
|  |                                           /* DEFLATE (off by default)       */ | ||||||
|  | #define SSL_ENABLE_RENEGOTIATION       20 /* Values below (default: never)  */ | ||||||
|  | #define SSL_REQUIRE_SAFE_NEGOTIATION   21 /* Peer must send Signalling      */ | ||||||
|  | 					  /* Cipher Suite Value (SCSV) or   */ | ||||||
|  |                                           /* Renegotiation  Info (RI)       */ | ||||||
|  | 					  /* extension in ALL handshakes.   */ | ||||||
|  |                                           /* default: off                   */ | ||||||
| 
 | 
 | ||||||
| #ifdef SSL_DEPRECATED_FUNCTION  | #ifdef SSL_DEPRECATED_FUNCTION  | ||||||
| /* Old deprecated function names */ | /* Old deprecated function names */ | ||||||
|  | @ -161,6 +169,19 @@ SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy); | ||||||
| #define SSL_REQUIRE_FIRST_HANDSHAKE ((PRBool)2) | #define SSL_REQUIRE_FIRST_HANDSHAKE ((PRBool)2) | ||||||
| #define SSL_REQUIRE_NO_ERROR        ((PRBool)3) | #define SSL_REQUIRE_NO_ERROR        ((PRBool)3) | ||||||
| 
 | 
 | ||||||
|  | /* Values for "on" with SSL_ENABLE_RENEGOTIATION */ | ||||||
|  | /* Never renegotiate at all.                                               */ | ||||||
|  | #define SSL_RENEGOTIATE_NEVER        ((PRBool)0) | ||||||
|  | /* Renegotiate without restriction, whether or not the peer's client hello */ | ||||||
|  | /* bears the renegotiation info extension.  Vulnerable, as in the past.    */ | ||||||
|  | #define SSL_RENEGOTIATE_UNRESTRICTED ((PRBool)1) | ||||||
|  | /* Only renegotiate if the peer's hello bears the TLS renegotiation_info   */ | ||||||
|  | /* extension. This is safe renegotiation.                                  */ | ||||||
|  | #define SSL_RENEGOTIATE_REQUIRES_XTN ((PRBool)2)  | ||||||
|  | /* Disallow all renegotiation in server sockets only, but allow clients    */ | ||||||
|  | /* to continue to renegotiate with vulnerable servers.                     */ | ||||||
|  | #define SSL_RENEGOTIATE_CLIENT_ONLY  ((PRBool)3) | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Reset the handshake state for fd. This will make the complete SSL | ** Reset the handshake state for fd. This will make the complete SSL | ||||||
| ** handshake protocol execute from the ground up on the next i/o | ** handshake protocol execute from the ground up on the next i/o | ||||||
|  | @ -252,6 +273,61 @@ SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, | ||||||
| 			                       SSLGetClientAuthData f, void *a); | 			                       SSLGetClientAuthData f, void *a); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  | ** SNI extension processing callback function. | ||||||
|  | ** It is called when SSL socket receives SNI extension in ClientHello message. | ||||||
|  | ** Upon this callback invocation, application is responsible to reconfigure the | ||||||
|  | ** socket with the data for a particular server name. | ||||||
|  | ** There are three potential outcomes of this function invocation: | ||||||
|  | **    * application does not recognize the name or the type and wants the | ||||||
|  | **    "unrecognized_name" alert be sent to the client. In this case the callback | ||||||
|  | **    function must return SSL_SNI_SEND_ALERT status. | ||||||
|  | **    * application does not recognize  the name, but wants to continue with | ||||||
|  | **    the handshake using the current socket configuration. In this case, | ||||||
|  | **    no socket reconfiguration is needed and the function should return | ||||||
|  | **    SSL_SNI_CURRENT_CONFIG_IS_USED. | ||||||
|  | **    * application recognizes the name and reconfigures the socket with | ||||||
|  | **    appropriate certs, key, etc. There are many ways to reconfigure. NSS | ||||||
|  | **    provides SSL_ReconfigFD function that can be used to update the socket | ||||||
|  | **    data from model socket. To continue with the rest of the handshake, the | ||||||
|  | **    implementation function should return an index of a name it has chosen. | ||||||
|  | ** LibSSL will ignore any SNI extension received in a ClientHello message | ||||||
|  | ** if application does not register a SSLSNISocketConfig callback. | ||||||
|  | ** Each type field of SECItem indicates the name type. | ||||||
|  | ** NOTE: currently RFC3546 defines only one name type: sni_host_name. | ||||||
|  | ** Client is allowed to send only one name per known type. LibSSL will | ||||||
|  | ** send an "unrecognized_name" alert if SNI extension name list contains more | ||||||
|  | ** then one name of a type. | ||||||
|  | */ | ||||||
|  | typedef PRInt32 (PR_CALLBACK *SSLSNISocketConfig)(PRFileDesc *fd, | ||||||
|  |                                             const SECItem *srvNameArr, | ||||||
|  |                                                   PRUint32 srvNameArrSize, | ||||||
|  |                                                   void *arg); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | ** SSLSNISocketConfig should return an index within 0 and srvNameArrSize-1 | ||||||
|  | ** when it has reconfigured the socket fd to use certs and keys, etc | ||||||
|  | ** for a specific name. There are two other allowed return values. One | ||||||
|  | ** tells libSSL to use the default cert and key.  The other tells libSSL | ||||||
|  | ** to send the "unrecognized_name" alert.  These values are: | ||||||
|  | **/ | ||||||
|  | #define SSL_SNI_CURRENT_CONFIG_IS_USED           -1 | ||||||
|  | #define SSL_SNI_SEND_ALERT                       -2 | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | ** Set application implemented SNISocketConfig callback. | ||||||
|  | */ | ||||||
|  | SSL_IMPORT SECStatus SSL_SNISocketConfigHook(PRFileDesc *fd,  | ||||||
|  |                                              SSLSNISocketConfig f, | ||||||
|  |                                              void *arg); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  | ** Reconfigure fd SSL socket with model socket parameters. Sets | ||||||
|  | ** server certs and keys, list of trust anchor, socket options | ||||||
|  | ** and all SSL socket call backs and parameters. | ||||||
|  | */ | ||||||
|  | SSL_IMPORT PRFileDesc *SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Set the client side argument for SSL to retrieve PKCS #11 pin. |  * Set the client side argument for SSL to retrieve PKCS #11 pin. | ||||||
|  *	fd - the file descriptor for the connection in question |  *	fd - the file descriptor for the connection in question | ||||||
|  | @ -269,7 +345,7 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f, | ||||||
| 				     void *arg); | 				     void *arg); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Configure ssl for running a secure server. Needs the | ** Configure SSL socket for running a secure server. Needs the | ||||||
| ** certificate for the server and the servers private key. The arguments | ** certificate for the server and the servers private key. The arguments | ||||||
| ** are copied. | ** are copied. | ||||||
| */ | */ | ||||||
|  | @ -278,7 +354,7 @@ SSL_IMPORT SECStatus SSL_ConfigSecureServer( | ||||||
| 				SECKEYPrivateKey *key, SSLKEAType kea); | 				SECKEYPrivateKey *key, SSLKEAType kea); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Configure a secure servers session-id cache. Define the maximum number | ** Configure a secure server's session-id cache. Define the maximum number | ||||||
| ** of entries in the cache, the longevity of the entires, and the directory | ** of entries in the cache, the longevity of the entires, and the directory | ||||||
| ** where the cache files will be placed.  These values can be zero, and  | ** where the cache files will be placed.  These values can be zero, and  | ||||||
| ** if so, the implementation will choose defaults. | ** if so, the implementation will choose defaults. | ||||||
|  | @ -289,6 +365,18 @@ SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCache(int      maxCacheEntries, | ||||||
| 					            PRUint32 timeout, | 					            PRUint32 timeout, | ||||||
| 					            PRUint32 ssl3_timeout, | 					            PRUint32 ssl3_timeout, | ||||||
| 				              const char *   directory); | 				              const char *   directory); | ||||||
|  | 
 | ||||||
|  | /* Configure a secure server's session-id cache. Depends on value of
 | ||||||
|  |  * enableMPCache, configures malti-proc or single proc cache. */ | ||||||
|  | SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCacheWithOpt( | ||||||
|  |                                                            PRUint32 timeout, | ||||||
|  |                                                        PRUint32 ssl3_timeout, | ||||||
|  |                                                      const char *   directory, | ||||||
|  |                                                           int maxCacheEntries, | ||||||
|  |                                                       int maxCertCacheEntries, | ||||||
|  |                                                     int maxSrvNameCacheEntries, | ||||||
|  |                                                            PRBool enableMPCache); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Like SSL_ConfigServerSessionIDCache, with one important difference. | ** Like SSL_ConfigServerSessionIDCache, with one important difference. | ||||||
| ** If the application will run multiple processes (as opposed to, or in  | ** If the application will run multiple processes (as opposed to, or in  | ||||||
|  | @ -364,10 +452,16 @@ SSL_IMPORT SECStatus SSL_RedoHandshake(PRFileDesc *fd); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Allow the application to pass a URL or hostname into the SSL library |  * Allow the application to pass a URL or hostname into the SSL library. | ||||||
|  */ |  */ | ||||||
| SSL_IMPORT SECStatus SSL_SetURL(PRFileDesc *fd, const char *url); | SSL_IMPORT SECStatus SSL_SetURL(PRFileDesc *fd, const char *url); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Allow an application to define a set of trust anchors for peer | ||||||
|  |  * cert validation. | ||||||
|  |  */ | ||||||
|  | SSL_IMPORT SECStatus SSL_SetTrustAnchors(PRFileDesc *fd, CERTCertList *list); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Return the number of bytes that SSL has waiting in internal buffers. | ** Return the number of bytes that SSL has waiting in internal buffers. | ||||||
| ** Return 0 if security is not enabled. | ** Return 0 if security is not enabled. | ||||||
|  | @ -398,7 +492,7 @@ SSL_IMPORT SECStatus SSL_ShutdownServerSessionIDCache(void); | ||||||
| ** Set peer information so we can correctly look up SSL session later. | ** Set peer information so we can correctly look up SSL session later. | ||||||
| ** You only have to do this if you're tunneling through a proxy. | ** You only have to do this if you're tunneling through a proxy. | ||||||
| */ | */ | ||||||
| SSL_IMPORT SECStatus SSL_SetSockPeerID(PRFileDesc *fd, char *peerID); | SSL_IMPORT SECStatus SSL_SetSockPeerID(PRFileDesc *fd, const char *peerID); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Reveal the security information for the peer.  | ** Reveal the security information for the peer.  | ||||||
|  | @ -407,7 +501,6 @@ SSL_IMPORT CERTCertificate * SSL_RevealCert(PRFileDesc * socket); | ||||||
| SSL_IMPORT void * SSL_RevealPinArg(PRFileDesc * socket); | SSL_IMPORT void * SSL_RevealPinArg(PRFileDesc * socket); | ||||||
| SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket); | SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| /* This callback may be passed to the SSL library via a call to
 | /* This callback may be passed to the SSL library via a call to
 | ||||||
|  * SSL_GetClientAuthDataHook() for each SSL client socket. |  * SSL_GetClientAuthDataHook() for each SSL client socket. | ||||||
|  * It will be invoked when SSL needs to know what certificate and private key |  * It will be invoked when SSL needs to know what certificate and private key | ||||||
|  | @ -470,6 +563,9 @@ SSL_IMPORT SECStatus SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, | ||||||
| SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,  | SSL_IMPORT SECStatus SSL_GetCipherSuiteInfo(PRUint16 cipherSuite,  | ||||||
|                                         SSLCipherSuiteInfo *info, PRUintn len); |                                         SSLCipherSuiteInfo *info, PRUintn len); | ||||||
| 
 | 
 | ||||||
|  | /* Returnes negotiated through SNI host info. */ | ||||||
|  | SSL_IMPORT SECItem *SSL_GetNegotiatedHostInfo(PRFileDesc *fd); | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
| ** Return a new reference to the certificate that was most recently sent | ** Return a new reference to the certificate that was most recently sent | ||||||
| ** to the peer on this SSL/TLS connection, or NULL if none has been sent. | ** to the peer on this SSL/TLS connection, or NULL if none has been sent. | ||||||
|  | @ -507,6 +603,14 @@ SSL_IMPORT SECStatus SSL_CanBypass(CERTCertificate *cert, | ||||||
| 				   PRUint16 *ciphers, int nciphers, | 				   PRUint16 *ciphers, int nciphers, | ||||||
|                                    PRBool *pcanbypass, void *pwArg); |                                    PRBool *pcanbypass, void *pwArg); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  | ** Did the handshake with the peer negotiate the given extension? | ||||||
|  | ** Output parameter valid only if function returns SECSuccess | ||||||
|  | */ | ||||||
|  | SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket, | ||||||
|  |                                                       SSLExtensionType extId, | ||||||
|  |                                                       PRBool *yes); | ||||||
|  | 
 | ||||||
| SEC_END_PROTOS | SEC_END_PROTOS | ||||||
| 
 | 
 | ||||||
| #endif /* __ssl_h_ */ | #endif /* __ssl_h_ */ | ||||||
|  |  | ||||||
|  | @ -71,8 +71,8 @@ | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| VS_VERSION_INFO VERSIONINFO | VS_VERSION_INFO VERSIONINFO | ||||||
|  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0 |  PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD | ||||||
|  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK |  FILEFLAGSMASK VS_FFI_FILEFLAGSMASK | ||||||
|  FILEFLAGS MY_FILEFLAGS_2 |  FILEFLAGS MY_FILEFLAGS_2 | ||||||
|  FILEOS MY_FILEOS |  FILEOS MY_FILEOS | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -40,7 +40,7 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| /* ECC code moved here from ssl3con.c */ | /* ECC code moved here from ssl3con.c */ | ||||||
| /* $Id: ssl3ecc.c,v 1.22 2008/03/10 00:01:28 wtc%google.com Exp $ */ | /* $Id: ssl3ecc.c,v 1.23 2010/01/28 16:14:25 kaie%kuix.de Exp $ */ | ||||||
| 
 | 
 | ||||||
| #include "nss.h" | #include "nss.h" | ||||||
| #include "cert.h" | #include "cert.h" | ||||||
|  | @ -1059,7 +1059,7 @@ ssl3_SendSupportedCurvesXtn( | ||||||
| 	if (!ss->sec.isServer) { | 	if (!ss->sec.isServer) { | ||||||
| 	    TLSExtensionData *xtnData = &ss->xtnData; | 	    TLSExtensionData *xtnData = &ss->xtnData; | ||||||
| 	    xtnData->advertised[xtnData->numAdvertised++] = | 	    xtnData->advertised[xtnData->numAdvertised++] = | ||||||
| 		elliptic_curves_xtn; | 		ssl_elliptic_curves_xtn; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|     return (sizeof EClist); |     return (sizeof EClist); | ||||||
|  | @ -1083,7 +1083,7 @@ ssl3_SendSupportedPointFormatsXtn( | ||||||
| 	if (!ss->sec.isServer) { | 	if (!ss->sec.isServer) { | ||||||
| 	    TLSExtensionData *xtnData = &ss->xtnData; | 	    TLSExtensionData *xtnData = &ss->xtnData; | ||||||
| 	    xtnData->advertised[xtnData->numAdvertised++] = | 	    xtnData->advertised[xtnData->numAdvertised++] = | ||||||
| 		ec_point_formats_xtn; | 		ssl_ec_point_formats_xtn; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|     return (sizeof ECPtFmt); |     return (sizeof ECPtFmt); | ||||||
|  |  | ||||||
|  | @ -41,11 +41,12 @@ | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| 
 | 
 | ||||||
| /* TLS extension code moved here from ssl3ecc.c */ | /* TLS extension code moved here from ssl3ecc.c */ | ||||||
| /* $Id: ssl3ext.c,v 1.3 2008/10/06 22:04:15 nelson%bolyard.com Exp $ */ | /* $Id: ssl3ext.c,v 1.11 2010/02/03 02:38:20 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #include "nssrenam.h" | #include "nssrenam.h" | ||||||
| #include "nss.h" | #include "nss.h" | ||||||
| #include "ssl.h" | #include "ssl.h" | ||||||
|  | #include "sslproto.h" | ||||||
| #include "sslimpl.h" | #include "sslimpl.h" | ||||||
| #include "pk11pub.h" | #include "pk11pub.h" | ||||||
| #include "blapi.h" | #include "blapi.h" | ||||||
|  | @ -61,8 +62,7 @@ static unsigned char  session_ticket_mac_key[SHA256_LENGTH]; | ||||||
| static PRBool         session_ticket_keys_initialized = PR_FALSE; | static PRBool         session_ticket_keys_initialized = PR_FALSE; | ||||||
| static PRCallOnceType generate_session_keys_once; | static PRCallOnceType generate_session_keys_once; | ||||||
| 
 | 
 | ||||||
| static PRInt32 ssl3_SendServerNameXtn(sslSocket * ss, | /* forward static function declarations */ | ||||||
|     PRBool append, PRUint32 maxBytes); |  | ||||||
| static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, | static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss, | ||||||
|     SECItem *data, EncryptedSessionTicket *enc_session_ticket); |     SECItem *data, EncryptedSessionTicket *enc_session_ticket); | ||||||
| static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, | static SECStatus ssl3_AppendToItem(SECItem *item, const unsigned char *buf, | ||||||
|  | @ -74,6 +74,10 @@ static SECStatus ssl3_GetSessionTicketKeysPKCS11(sslSocket *ss, | ||||||
| static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, | static SECStatus ssl3_GetSessionTicketKeys(const unsigned char **aes_key, | ||||||
|     PRUint32 *aes_key_length, const unsigned char **mac_key, |     PRUint32 *aes_key_length, const unsigned char **mac_key, | ||||||
|     PRUint32 *mac_key_length); |     PRUint32 *mac_key_length); | ||||||
|  | static PRInt32 ssl3_SendRenegotiationInfoXtn(sslSocket * ss, | ||||||
|  |     PRBool append, PRUint32 maxBytes); | ||||||
|  | static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss,  | ||||||
|  |     PRUint16 ex_type, SECItem *data); | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Write bytes.  Using this function means the SECItem structure |  * Write bytes.  Using this function means the SECItem structure | ||||||
|  | @ -222,39 +226,55 @@ ssl3_GetSessionTicketKeys(const unsigned char **aes_key, | ||||||
|  * In the second generation, this table will be dynamic, and functions |  * In the second generation, this table will be dynamic, and functions | ||||||
|  * will be registered here. |  * will be registered here. | ||||||
|  */ |  */ | ||||||
|  | /* This table is used by the server, to handle client hello extensions. */ | ||||||
| static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | static const ssl3HelloExtensionHandler clientHelloHandlers[] = { | ||||||
|     { server_name_xtn, &ssl3_HandleServerNameXtn }, |     { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn }, | ||||||
| #ifdef NSS_ENABLE_ECC | #ifdef NSS_ENABLE_ECC | ||||||
|     { elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn }, |     { ssl_elliptic_curves_xtn,    &ssl3_HandleSupportedCurvesXtn }, | ||||||
|     { ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, |     { ssl_ec_point_formats_xtn,   &ssl3_HandleSupportedPointFormatsXtn }, | ||||||
| #endif | #endif | ||||||
|     { session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |     { ssl_session_ticket_xtn,     &ssl3_ServerHandleSessionTicketXtn }, | ||||||
|  |     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | ||||||
|     { -1, NULL } |     { -1, NULL } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const ssl3HelloExtensionHandler serverHelloHandlers[] = { | /* These two tables are used by the client, to handle server hello
 | ||||||
|     { server_name_xtn, &ssl3_HandleServerNameXtn }, |  * extensions. */ | ||||||
|     /* TODO: add a handler for ec_point_formats_xtn */ | static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { | ||||||
|     { session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |     { ssl_server_name_xtn,        &ssl3_HandleServerNameXtn }, | ||||||
|  |     /* TODO: add a handler for ssl_ec_point_formats_xtn */ | ||||||
|  |     { ssl_session_ticket_xtn,     &ssl3_ClientHandleSessionTicketXtn }, | ||||||
|  |     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | ||||||
|     { -1, NULL } |     { -1, NULL } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /* Table of functions to format TLS hello extensions, one per extension.
 | static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = { | ||||||
|  * This static table is for the formatting of client hello extensions. |     { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | ||||||
|  |     { -1, NULL } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* Tables of functions to format TLS hello extensions, one function per
 | ||||||
|  |  * extension. | ||||||
|  |  * These static tables are for the formatting of client hello extensions. | ||||||
|  * The server's table of hello senders is dynamic, in the socket struct, |  * The server's table of hello senders is dynamic, in the socket struct, | ||||||
|  * and sender functions are registered there. |  * and sender functions are registered there. | ||||||
|  */ |  */ | ||||||
| static const  | static const  | ||||||
| ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSIONS] = { | ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { | ||||||
|     { server_name_xtn, &ssl3_SendServerNameXtn }, |     { ssl_server_name_xtn,        &ssl3_SendServerNameXtn        }, | ||||||
|  |     { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn }, | ||||||
| #ifdef NSS_ENABLE_ECC | #ifdef NSS_ENABLE_ECC | ||||||
|     { elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |     { ssl_elliptic_curves_xtn,    &ssl3_SendSupportedCurvesXtn }, | ||||||
|     { ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |     { ssl_ec_point_formats_xtn,   &ssl3_SendSupportedPointFormatsXtn }, | ||||||
| #else |  | ||||||
|     { -1, NULL }, |  | ||||||
|     { -1, NULL }, |  | ||||||
| #endif | #endif | ||||||
|     { session_ticket_xtn, ssl3_SendSessionTicketXtn } |     { ssl_session_ticket_xtn,     &ssl3_SendSessionTicketXtn } | ||||||
|  |     /* any extra entries will appear as { 0, NULL }    */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const  | ||||||
|  | ssl3HelloExtensionSender clientHelloSendersSSL3[SSL_MAX_EXTENSIONS] = { | ||||||
|  |     { ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn } | ||||||
|  |     /* any extra entries will appear as { 0, NULL }    */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static PRBool | static PRBool | ||||||
|  | @ -284,13 +304,14 @@ ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) { | ||||||
| 
 | 
 | ||||||
| /* Format an SNI extension, using the name from the socket's URL,
 | /* Format an SNI extension, using the name from the socket's URL,
 | ||||||
|  * unless that name is a dotted decimal string. |  * unless that name is a dotted decimal string. | ||||||
|  |  * Used by client and server. | ||||||
|  */ |  */ | ||||||
| static PRInt32  | PRInt32 | ||||||
| ssl3_SendServerNameXtn( | ssl3_SendServerNameXtn(sslSocket * ss, PRBool append, | ||||||
| 			sslSocket * ss, |  | ||||||
| 			PRBool      append, |  | ||||||
|                        PRUint32 maxBytes) |                        PRUint32 maxBytes) | ||||||
| { | { | ||||||
|  |     SECStatus rv; | ||||||
|  |     if (!ss->sec.isServer) { | ||||||
|         PRUint32 len; |         PRUint32 len; | ||||||
|         PRNetAddr netAddr; |         PRNetAddr netAddr; | ||||||
|          |          | ||||||
|  | @ -304,9 +325,8 @@ ssl3_SendServerNameXtn( | ||||||
|         } |         } | ||||||
|         len  = PORT_Strlen(ss->url); |         len  = PORT_Strlen(ss->url); | ||||||
|         if (append && maxBytes >= len + 9) { |         if (append && maxBytes >= len + 9) { | ||||||
| 	SECStatus rv; |  | ||||||
|             /* extension_type */ |             /* extension_type */ | ||||||
| 	rv = ssl3_AppendHandshakeNumber(ss, server_name_xtn, 2);  |             rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);  | ||||||
|             if (rv != SECSuccess) return -1; |             if (rv != SECSuccess) return -1; | ||||||
|             /* length of extension_data */ |             /* length of extension_data */ | ||||||
|             rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);  |             rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);  | ||||||
|  | @ -314,28 +334,127 @@ ssl3_SendServerNameXtn( | ||||||
|             /* length of server_name_list */ |             /* length of server_name_list */ | ||||||
|             rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); |             rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2); | ||||||
|             if (rv != SECSuccess) return -1; |             if (rv != SECSuccess) return -1; | ||||||
| 	/* Name Type (host_name) */ |             /* Name Type (sni_host_name) */ | ||||||
|             rv = ssl3_AppendHandshake(ss,       "\0",    1); |             rv = ssl3_AppendHandshake(ss,       "\0",    1); | ||||||
|             if (rv != SECSuccess) return -1; |             if (rv != SECSuccess) return -1; | ||||||
|             /* HostName (length and value) */ |             /* HostName (length and value) */ | ||||||
| 	rv = ssl3_AppendHandshakeVariable(ss, (unsigned char *)ss->url, len, 2); |             rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2); | ||||||
|             if (rv != SECSuccess) return -1; |             if (rv != SECSuccess) return -1; | ||||||
|             if (!ss->sec.isServer) { |             if (!ss->sec.isServer) { | ||||||
|                 TLSExtensionData *xtnData = &ss->xtnData; |                 TLSExtensionData *xtnData = &ss->xtnData; | ||||||
| 	    xtnData->advertised[xtnData->numAdvertised++] = server_name_xtn; |                 xtnData->advertised[xtnData->numAdvertised++] =  | ||||||
|  | 		    ssl_server_name_xtn; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return len + 9; |         return len + 9; | ||||||
|  |     } | ||||||
|  |     /* Server side */ | ||||||
|  |     if (append && maxBytes >= 4) { | ||||||
|  |         rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2); | ||||||
|  |         if (rv != SECSuccess)  return -1; | ||||||
|  |         /* length of extension_data */ | ||||||
|  |         rv = ssl3_AppendHandshakeNumber(ss, 0, 2); | ||||||
|  |         if (rv != SECSuccess) return -1; | ||||||
|  |     } | ||||||
|  |     return 4; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* handle an incoming SNI extension, by ignoring it. */ | /* handle an incoming SNI extension, by ignoring it. */ | ||||||
| SECStatus | SECStatus | ||||||
| ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) | ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data) | ||||||
| { | { | ||||||
|     /* TODO: if client, should verify extension_data is empty. */ |     SECItem *names = NULL; | ||||||
|     /* TODO: if server, should send empty extension_data. */ |     PRUint32 listCount = 0, namesPos = 0, i; | ||||||
|     /* For now, we ignore this, as if we didn't understand it. :-)  */ |     TLSExtensionData *xtnData = &ss->xtnData; | ||||||
|  |     SECItem  ldata; | ||||||
|  |     PRInt32  listLenBytes = 0; | ||||||
|  | 
 | ||||||
|  |     if (!ss->sec.isServer) { | ||||||
|  |         /* Verify extension_data is empty. */ | ||||||
|  |         if (data->data || data->len || | ||||||
|  |             !ssl3_ExtensionNegotiated(ss, ssl_server_name_xtn)) { | ||||||
|  |             /* malformed or was not initiated by the client.*/ | ||||||
|  |             return SECFailure; | ||||||
|  |         } | ||||||
|         return SECSuccess; |         return SECSuccess; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Server side - consume client data and register server sender. */ | ||||||
|  |     /* do not parse the data if don't have user extension handling function. */ | ||||||
|  |     if (!ss->sniSocketConfig) { | ||||||
|  |         return SECSuccess; | ||||||
|  |     } | ||||||
|  |     /* length of server_name_list */ | ||||||
|  |     listLenBytes = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);  | ||||||
|  |     if (listLenBytes == 0 || listLenBytes != data->len) { | ||||||
|  |         return SECFailure; | ||||||
|  |     } | ||||||
|  |     ldata = *data; | ||||||
|  |     /* Calculate the size of the array.*/ | ||||||
|  |     while (listLenBytes > 0) { | ||||||
|  |         SECItem litem; | ||||||
|  |         SECStatus rv; | ||||||
|  |         PRInt32  type; | ||||||
|  |         /* Name Type (sni_host_name) */ | ||||||
|  |         type = ssl3_ConsumeHandshakeNumber(ss, 1, &ldata.data, &ldata.len);  | ||||||
|  |         if (!ldata.len) { | ||||||
|  |             return SECFailure; | ||||||
|  |         } | ||||||
|  |         rv = ssl3_ConsumeHandshakeVariable(ss, &litem, 2, &ldata.data, &ldata.len); | ||||||
|  |         if (rv != SECSuccess) { | ||||||
|  |             return SECFailure; | ||||||
|  |         } | ||||||
|  |         /* Adjust total length for cunsumed item, item len and type.*/ | ||||||
|  |         listLenBytes -= litem.len + 3; | ||||||
|  |         if (listLenBytes > 0 && !ldata.len) { | ||||||
|  |             return SECFailure; | ||||||
|  |         } | ||||||
|  |         listCount += 1; | ||||||
|  |     } | ||||||
|  |     if (!listCount) { | ||||||
|  |         return SECFailure; | ||||||
|  |     } | ||||||
|  |     names = PORT_ZNewArray(SECItem, listCount); | ||||||
|  |     if (!names) { | ||||||
|  |         return SECFailure; | ||||||
|  |     } | ||||||
|  |     for (i = 0;i < listCount;i++) { | ||||||
|  |         int j; | ||||||
|  |         PRInt32  type; | ||||||
|  |         SECStatus rv; | ||||||
|  |         PRBool nametypePresent = PR_FALSE; | ||||||
|  |         /* Name Type (sni_host_name) */ | ||||||
|  |         type = ssl3_ConsumeHandshakeNumber(ss, 1, &data->data, &data->len);  | ||||||
|  |         /* Check if we have such type in the list */ | ||||||
|  |         for (j = 0;j < listCount && names[j].data;j++) { | ||||||
|  |             if (names[j].type == type) { | ||||||
|  |                 nametypePresent = PR_TRUE; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         /* HostName (length and value) */ | ||||||
|  |         rv = ssl3_ConsumeHandshakeVariable(ss, &names[namesPos], 2, | ||||||
|  |                                            &data->data, &data->len); | ||||||
|  |         if (rv != SECSuccess) { | ||||||
|  |             goto loser; | ||||||
|  |         } | ||||||
|  |         if (nametypePresent == PR_FALSE) { | ||||||
|  |             namesPos += 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     /* Free old and set the new data. */ | ||||||
|  |     if (xtnData->sniNameArr) { | ||||||
|  |         PORT_Free(ss->xtnData.sniNameArr); | ||||||
|  |     } | ||||||
|  |     xtnData->sniNameArr = names; | ||||||
|  |     xtnData->sniNameArrSize = namesPos; | ||||||
|  |     xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn; | ||||||
|  | 
 | ||||||
|  |     return SECSuccess; | ||||||
|  | 
 | ||||||
|  | loser: | ||||||
|  |     PORT_Free(names); | ||||||
|  |     return SECFailure; | ||||||
| } | } | ||||||
|          |          | ||||||
| /* Called by both clients and servers.
 | /* Called by both clients and servers.
 | ||||||
|  | @ -383,7 +502,7 @@ ssl3_SendSessionTicketXtn( | ||||||
|     if (append && maxBytes >= extension_length) { |     if (append && maxBytes >= extension_length) { | ||||||
| 	SECStatus rv; | 	SECStatus rv; | ||||||
| 	/* extension_type */ | 	/* extension_type */ | ||||||
|         rv = ssl3_AppendHandshakeNumber(ss, session_ticket_xtn, 2); |         rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2); | ||||||
|         if (rv != SECSuccess) |         if (rv != SECSuccess) | ||||||
| 	    goto loser; | 	    goto loser; | ||||||
| 	if (session_ticket && session_ticket->ticket.data && | 	if (session_ticket && session_ticket->ticket.data && | ||||||
|  | @ -399,7 +518,8 @@ ssl3_SendSessionTicketXtn( | ||||||
| 
 | 
 | ||||||
| 	if (!ss->sec.isServer) { | 	if (!ss->sec.isServer) { | ||||||
| 	    TLSExtensionData *xtnData = &ss->xtnData; | 	    TLSExtensionData *xtnData = &ss->xtnData; | ||||||
| 	    xtnData->advertised[xtnData->numAdvertised++] = session_ticket_xtn; | 	    xtnData->advertised[xtnData->numAdvertised++] =  | ||||||
|  | 		ssl_session_ticket_xtn; | ||||||
| 	} | 	} | ||||||
|     } else if (maxBytes < extension_length) { |     } else if (maxBytes < extension_length) { | ||||||
| 	PORT_Assert(0); | 	PORT_Assert(0); | ||||||
|  | @ -454,6 +574,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss) | ||||||
|     unsigned int         computed_mac_length; |     unsigned int         computed_mac_length; | ||||||
|     unsigned char        iv[AES_BLOCK_SIZE]; |     unsigned char        iv[AES_BLOCK_SIZE]; | ||||||
|     SECItem              ivItem; |     SECItem              ivItem; | ||||||
|  |     SECItem             *srvName = NULL; | ||||||
|  |     PRUint32             srvNameLen = 0; | ||||||
|     CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
 |     CK_MECHANISM_TYPE    msWrapMech = 0; /* dummy default value,
 | ||||||
|                                           * must be >= 0 */ |                                           * must be >= 0 */ | ||||||
| 
 | 
 | ||||||
|  | @ -514,6 +636,11 @@ ssl3_SendNewSessionTicket(sslSocket *ss) | ||||||
| 	} | 	} | ||||||
| 	ms_is_wrapped = PR_TRUE; | 	ms_is_wrapped = PR_TRUE; | ||||||
|     } |     } | ||||||
|  |     /* Prep to send negotiated name */ | ||||||
|  |     srvName = &ss->ssl3.pwSpec->srvVirtName; | ||||||
|  |     if (srvName->data && srvName->len) { | ||||||
|  |         srvNameLen = 2 + srvName->len; /* len bytes + name len */ | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     ciphertext_length =  |     ciphertext_length =  | ||||||
| 	sizeof(PRUint16)                     /* ticket_version */ | 	sizeof(PRUint16)                     /* ticket_version */ | ||||||
|  | @ -528,6 +655,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss) | ||||||
| 	+ ms_item.len                        /* master_secret */ | 	+ ms_item.len                        /* master_secret */ | ||||||
| 	+ 1                                  /* client_auth_type */ | 	+ 1                                  /* client_auth_type */ | ||||||
| 	+ cert_length                        /* cert */ | 	+ cert_length                        /* cert */ | ||||||
|  |         + 1                                  /* server name type */ | ||||||
|  |         + srvNameLen                         /* name len + length field */ | ||||||
| 	+ sizeof(ticket.ticket_lifetime_hint); | 	+ sizeof(ticket.ticket_lifetime_hint); | ||||||
|     padding_length =  AES_BLOCK_SIZE - |     padding_length =  AES_BLOCK_SIZE - | ||||||
| 	(ciphertext_length % AES_BLOCK_SIZE); | 	(ciphertext_length % AES_BLOCK_SIZE); | ||||||
|  | @ -610,6 +739,22 @@ ssl3_SendNewSessionTicket(sslSocket *ss) | ||||||
| 	sizeof(ticket.ticket_lifetime_hint)); | 	sizeof(ticket.ticket_lifetime_hint)); | ||||||
|     if (rv != SECSuccess) goto loser; |     if (rv != SECSuccess) goto loser; | ||||||
| 
 | 
 | ||||||
|  |     if (srvNameLen) { | ||||||
|  |         /* Name Type (sni_host_name) */ | ||||||
|  |         rv = ssl3_AppendNumberToItem(&plaintext, srvName->type, 1); | ||||||
|  |         if (rv != SECSuccess) goto loser; | ||||||
|  |         /* HostName (length and value) */ | ||||||
|  |         rv = ssl3_AppendNumberToItem(&plaintext, srvName->len, 2); | ||||||
|  |         if (rv != SECSuccess) goto loser; | ||||||
|  |         rv = ssl3_AppendToItem(&plaintext, srvName->data, srvName->len); | ||||||
|  |         if (rv != SECSuccess) goto loser; | ||||||
|  |     } else { | ||||||
|  |         /* No Name */ | ||||||
|  |         rv = ssl3_AppendNumberToItem(&plaintext, (char)TLS_STE_NO_SERVER_NAME, | ||||||
|  |                                      1); | ||||||
|  |         if (rv != SECSuccess) goto loser; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     PORT_Assert(plaintext.len == padding_length); |     PORT_Assert(plaintext.len == padding_length); | ||||||
|     for (i = 0; i < padding_length; i++) |     for (i = 0; i < padding_length; i++) | ||||||
| 	plaintext.data[i] = (unsigned char)padding_length; | 	plaintext.data[i] = (unsigned char)padding_length; | ||||||
|  | @ -782,6 +927,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, | ||||||
| 	unsigned int           buffer_len; | 	unsigned int           buffer_len; | ||||||
| 	PRInt32                temp; | 	PRInt32                temp; | ||||||
| 	SECItem                cert_item; | 	SECItem                cert_item; | ||||||
|  |         PRInt8                 nameType = TLS_STE_NO_SERVER_NAME; | ||||||
| 
 | 
 | ||||||
| 	/* Turn off stateless session resumption if the client sends a
 | 	/* Turn off stateless session resumption if the client sends a
 | ||||||
| 	 * SessionTicket extension, even if the extension turns out to be | 	 * SessionTicket extension, even if the extension turns out to be | ||||||
|  | @ -867,7 +1013,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, | ||||||
| 	    if (rv != SECSuccess) | 	    if (rv != SECSuccess) | ||||||
| 		goto no_ticket; | 		goto no_ticket; | ||||||
| 	} | 	} | ||||||
| 	if (PORT_Memcmp(computed_mac, enc_session_ticket.mac, | 	if (NSS_SecureMemcmp(computed_mac, enc_session_ticket.mac, | ||||||
| 		computed_mac_length) != 0) { | 		computed_mac_length) != 0) { | ||||||
| 	    SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.", | 	    SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.", | ||||||
| 			SSL_GETPID(), ss->fd)); | 			SSL_GETPID(), ss->fd)); | ||||||
|  | @ -963,7 +1109,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, | ||||||
| 	/* Read compression_method. */ | 	/* Read compression_method. */ | ||||||
| 	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); | 	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); | ||||||
| 	if (temp < 0) goto no_ticket; | 	if (temp < 0) goto no_ticket; | ||||||
| 	parsed_session_ticket->compression_method = (SSL3CompressionMethod)temp; | 	parsed_session_ticket->compression_method = (SSLCompressionMethod)temp; | ||||||
| 
 | 
 | ||||||
| 	/* Read cipher spec parameters. */ | 	/* Read cipher spec parameters. */ | ||||||
| 	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); | 	temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len); | ||||||
|  | @ -1034,6 +1180,20 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, | ||||||
| 	    goto no_ticket; | 	    goto no_ticket; | ||||||
| 	parsed_session_ticket->timestamp = (PRUint32)temp; | 	parsed_session_ticket->timestamp = (PRUint32)temp; | ||||||
| 
 | 
 | ||||||
|  |         /* Read server name */ | ||||||
|  |         nameType = | ||||||
|  |                 ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);  | ||||||
|  |         if (nameType != TLS_STE_NO_SERVER_NAME) { | ||||||
|  |             SECItem name_item; | ||||||
|  |             rv = ssl3_ConsumeHandshakeVariable(ss, &name_item, 2, &buffer, | ||||||
|  |                                                &buffer_len); | ||||||
|  |             if (rv != SECSuccess) goto no_ticket; | ||||||
|  |             rv = SECITEM_CopyItem(NULL, &parsed_session_ticket->srvName, | ||||||
|  |                                   &name_item); | ||||||
|  |             if (rv != SECSuccess) goto no_ticket; | ||||||
|  |             parsed_session_ticket->srvName.type = nameType; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
| 	/* Done parsing.  Check that all bytes have been consumed. */ | 	/* Done parsing.  Check that all bytes have been consumed. */ | ||||||
| 	if (buffer_len != padding_length) | 	if (buffer_len != padding_length) | ||||||
| 	    goto no_ticket; | 	    goto no_ticket; | ||||||
|  | @ -1090,6 +1250,9 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, | ||||||
| 		    goto loser; | 		    goto loser; | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
|  | 	    if (parsed_session_ticket->srvName.data != NULL) { | ||||||
|  |                 sid->u.ssl3.srvName = parsed_session_ticket->srvName; | ||||||
|  |             } | ||||||
| 	    ss->statelessResume = PR_TRUE; | 	    ss->statelessResume = PR_TRUE; | ||||||
| 	    ss->sec.ci.sid = sid; | 	    ss->sec.ci.sid = sid; | ||||||
| 	} | 	} | ||||||
|  | @ -1172,8 +1335,15 @@ ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data, | ||||||
| SECStatus  | SECStatus  | ||||||
| ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length) | ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length) | ||||||
| { | { | ||||||
|     const ssl3HelloExtensionHandler * handlers = |     const ssl3HelloExtensionHandler * handlers; | ||||||
| 	ss->sec.isServer ? clientHelloHandlers : serverHelloHandlers; | 
 | ||||||
|  |     if (ss->sec.isServer) { | ||||||
|  |         handlers = clientHelloHandlers; | ||||||
|  |     } else if (ss->version > SSL_LIBRARY_VERSION_3_0) { | ||||||
|  |         handlers = serverHelloHandlersTLS; | ||||||
|  |     } else { | ||||||
|  |         handlers = serverHelloHandlersSSL3; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     while (*length) { |     while (*length) { | ||||||
| 	const ssl3HelloExtensionHandler * handler; | 	const ssl3HelloExtensionHandler * handler; | ||||||
|  | @ -1226,7 +1396,7 @@ ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, | ||||||
|     int i; |     int i; | ||||||
|     ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0]; |     ssl3HelloExtensionSender *sender = &ss->xtnData.serverSenders[0]; | ||||||
| 
 | 
 | ||||||
|     for (i = 0; i < MAX_EXTENSIONS; ++i, ++sender) { |     for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { | ||||||
|         if (!sender->ex_sender) { |         if (!sender->ex_sender) { | ||||||
| 	    sender->ex_type   = ex_type; | 	    sender->ex_type   = ex_type; | ||||||
| 	    sender->ex_sender = cb; | 	    sender->ex_sender = cb; | ||||||
|  | @ -1239,7 +1409,7 @@ ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type, | ||||||
| 	    break; | 	    break; | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|     PORT_Assert(i < MAX_EXTENSIONS); /* table needs to grow */ |     PORT_Assert(i < SSL_MAX_EXTENSIONS); /* table needs to grow */ | ||||||
|     PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |     PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); | ||||||
|     return SECFailure; |     return SECFailure; | ||||||
| } | } | ||||||
|  | @ -1252,10 +1422,12 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, | ||||||
|     PRInt32 total_exten_len = 0; |     PRInt32 total_exten_len = 0; | ||||||
|     int i; |     int i; | ||||||
| 
 | 
 | ||||||
|     if (!sender) |     if (!sender) { | ||||||
|     	sender = &clientHelloSenders[0]; |     	sender = ss->version > SSL_LIBRARY_VERSION_3_0 ? | ||||||
|  |                  &clientHelloSendersTLS[0] : &clientHelloSendersSSL3[0]; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     for (i = 0; i < MAX_EXTENSIONS; ++i, ++sender) { |     for (i = 0; i < SSL_MAX_EXTENSIONS; ++i, ++sender) { | ||||||
| 	if (sender->ex_sender) { | 	if (sender->ex_sender) { | ||||||
| 	    PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); | 	    PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes); | ||||||
| 	    if (extLen < 0) | 	    if (extLen < 0) | ||||||
|  | @ -1266,3 +1438,82 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes, | ||||||
|     } |     } | ||||||
|     return total_exten_len; |     return total_exten_len; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* Extension format:
 | ||||||
|  |  * Extension number:   2 bytes | ||||||
|  |  * Extension length:   2 bytes | ||||||
|  |  * Verify Data Length: 1 byte | ||||||
|  |  * Verify Data (TLS): 12 bytes (client) or 24 bytes (server) | ||||||
|  |  * Verify Data (SSL): 36 bytes (client) or 72 bytes (server) | ||||||
|  |  */ | ||||||
|  | static PRInt32  | ||||||
|  | ssl3_SendRenegotiationInfoXtn( | ||||||
|  | 			sslSocket * ss, | ||||||
|  | 			PRBool      append, | ||||||
|  | 			PRUint32    maxBytes) | ||||||
|  | { | ||||||
|  |     PRInt32 len, needed; | ||||||
|  | 
 | ||||||
|  |     /* In draft-ietf-tls-renegotiation-03, it is NOT RECOMMENDED to send
 | ||||||
|  |      * both the SCSV and the empty RI, so when we send SCSV in  | ||||||
|  |      * the initial handshake, we don't also send RI. | ||||||
|  |      */ | ||||||
|  |     if (!ss || ss->ssl3.hs.sendingSCSV) | ||||||
|  |     	return 0; | ||||||
|  |     len = !ss->firstHsDone ? 0 :  | ||||||
|  | 	   (ss->sec.isServer ? ss->ssl3.hs.finishedBytes * 2  | ||||||
|  | 			     : ss->ssl3.hs.finishedBytes); | ||||||
|  |     needed = 5 + len; | ||||||
|  |     if (append && maxBytes >= needed) { | ||||||
|  | 	SECStatus rv; | ||||||
|  | 	/* extension_type */ | ||||||
|  | 	rv = ssl3_AppendHandshakeNumber(ss, ssl_renegotiation_info_xtn, 2);  | ||||||
|  | 	if (rv != SECSuccess) return -1; | ||||||
|  | 	/* length of extension_data */ | ||||||
|  | 	rv = ssl3_AppendHandshakeNumber(ss, len + 1, 2);  | ||||||
|  | 	if (rv != SECSuccess) return -1; | ||||||
|  | 	/* verify_Data from previous Finished message(s) */ | ||||||
|  | 	rv = ssl3_AppendHandshakeVariable(ss,  | ||||||
|  | 		  ss->ssl3.hs.finishedMsgs.data, len, 1); | ||||||
|  | 	if (rv != SECSuccess) return -1; | ||||||
|  | 	if (!ss->sec.isServer) { | ||||||
|  | 	    TLSExtensionData *xtnData = &ss->xtnData; | ||||||
|  | 	    xtnData->advertised[xtnData->numAdvertised++] =  | ||||||
|  | 	                                           ssl_renegotiation_info_xtn; | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |     return needed; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* This function runs in both the client and server.  */ | ||||||
|  | static SECStatus | ||||||
|  | ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) | ||||||
|  | { | ||||||
|  |     SECStatus rv = SECSuccess; | ||||||
|  |     PRUint32 len = 0; | ||||||
|  | 
 | ||||||
|  |     if (ss->firstHsDone) { | ||||||
|  | 	len = ss->sec.isServer ? ss->ssl3.hs.finishedBytes  | ||||||
|  | 	                       : ss->ssl3.hs.finishedBytes * 2; | ||||||
|  |     } | ||||||
|  |     if (data->len != 1 + len  || | ||||||
|  | 	data->data[0] != len  || (len &&  | ||||||
|  | 	NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, | ||||||
|  | 	                 data->data + 1, len))) { | ||||||
|  | 	/* Can we do this here? Or, must we arrange for the caller to do it? */ | ||||||
|  | 	(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); | ||||||
|  | 	PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE); | ||||||
|  | 	return SECFailure; | ||||||
|  |     } | ||||||
|  |     /* remember that we got this extension and it was correct. */ | ||||||
|  |     ss->peerRequestedProtection = 1; | ||||||
|  |     ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; | ||||||
|  |     if (ss->sec.isServer) { | ||||||
|  | 	/* prepare to send back the appropriate response */ | ||||||
|  | 	rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, | ||||||
|  | 					     ssl3_SendRenegotiationInfoXtn); | ||||||
|  |     } | ||||||
|  |     return rv; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -38,7 +38,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: ssl3prot.h,v 1.13 2008/03/06 20:16:22 wtc%google.com Exp $ */ | /* $Id: ssl3prot.h,v 1.18 2010/02/03 02:25:35 alexei.volkov.bugs%sun.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #ifndef __ssl3proto_h_ | #ifndef __ssl3proto_h_ | ||||||
| #define __ssl3proto_h_ | #define __ssl3proto_h_ | ||||||
|  | @ -173,15 +173,13 @@ typedef struct { | ||||||
|     uint8 length; |     uint8 length; | ||||||
| } SSL3SessionID; | } SSL3SessionID; | ||||||
|       |       | ||||||
| typedef enum { compression_null = 0 } SSL3CompressionMethod; |  | ||||||
|       |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     SSL3ProtocolVersion   client_version; |     SSL3ProtocolVersion   client_version; | ||||||
|     SSL3Random            random; |     SSL3Random            random; | ||||||
|     SSL3SessionID         session_id; |     SSL3SessionID         session_id; | ||||||
|     SECItem               cipher_suites; |     SECItem               cipher_suites; | ||||||
|     uint8                 cm_count; |     uint8                 cm_count; | ||||||
|     SSL3CompressionMethod compression_methods[MAX_COMPRESSION_METHODS]; |     SSLCompressionMethod  compression_methods[MAX_COMPRESSION_METHODS]; | ||||||
| } SSL3ClientHello; | } SSL3ClientHello; | ||||||
|       |       | ||||||
| typedef struct  { | typedef struct  { | ||||||
|  | @ -189,7 +187,7 @@ typedef struct  { | ||||||
|     SSL3Random            random; |     SSL3Random            random; | ||||||
|     SSL3SessionID         session_id; |     SSL3SessionID         session_id; | ||||||
|     ssl3CipherSuite       cipher_suite; |     ssl3CipherSuite       cipher_suite; | ||||||
|     SSL3CompressionMethod compression_method; |     SSLCompressionMethod  compression_method; | ||||||
| } SSL3ServerHello; | } SSL3ServerHello; | ||||||
|       |       | ||||||
| typedef struct { | typedef struct { | ||||||
|  | @ -345,19 +343,8 @@ typedef struct { | ||||||
|     unsigned char *mac; |     unsigned char *mac; | ||||||
| } EncryptedSessionTicket; | } EncryptedSessionTicket; | ||||||
| 
 | 
 | ||||||
| /* Supported extensions. */ |  | ||||||
| /* Update MAX_EXTENSIONS whenever a new extension type is added. */ |  | ||||||
| typedef enum { |  | ||||||
|     server_name_xtn              = 0, |  | ||||||
| #ifdef NSS_ENABLE_ECC |  | ||||||
|     elliptic_curves_xtn          = 10, |  | ||||||
|     ec_point_formats_xtn         = 11, |  | ||||||
| #endif |  | ||||||
|     session_ticket_xtn           = 35 |  | ||||||
| } ExtensionType; |  | ||||||
| 
 |  | ||||||
| #define MAX_EXTENSIONS             4 |  | ||||||
| 
 |  | ||||||
| #define TLS_EX_SESS_TICKET_MAC_LENGTH       32 | #define TLS_EX_SESS_TICKET_MAC_LENGTH       32 | ||||||
| 
 | 
 | ||||||
|  | #define TLS_STE_NO_SERVER_NAME        -1 | ||||||
|  | 
 | ||||||
| #endif /* __ssl3proto_h_ */ | #endif /* __ssl3proto_h_ */ | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: sslcon.c,v 1.36 2009/03/04 21:57:18 nelson%bolyard.com Exp $ */ | /* $Id: sslcon.c,v 1.39 2010/02/04 03:08:44 wtc%google.com Exp $ */ | ||||||
| 
 | 
 | ||||||
| #include "nssrenam.h" | #include "nssrenam.h" | ||||||
| #include "cert.h" | #include "cert.h" | ||||||
|  | @ -2731,7 +2731,8 @@ ssl2_HandleVerifyMessage(sslSocket *ss) | ||||||
|     DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |     DUMP_MSG(29, (ss, data, ss->gs.recordLen)); | ||||||
|     if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || |     if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || | ||||||
| 	(data[0] != SSL_MT_SERVER_VERIFY) || | 	(data[0] != SSL_MT_SERVER_VERIFY) || | ||||||
| 	PORT_Memcmp(data+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES)) { | 	NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge, | ||||||
|  | 	                 SSL_CHALLENGE_BYTES)) { | ||||||
| 	/* Bad server */ | 	/* Bad server */ | ||||||
| 	PORT_SetError(SSL_ERROR_BAD_SERVER); | 	PORT_SetError(SSL_ERROR_BAD_SERVER); | ||||||
| 	goto loser; | 	goto loser; | ||||||
|  | @ -3006,6 +3007,7 @@ ssl2_BeginClientHandshake(sslSocket *ss) | ||||||
|     unsigned int      i; |     unsigned int      i; | ||||||
|     int               sendLen, sidLen = 0; |     int               sendLen, sidLen = 0; | ||||||
|     SECStatus         rv; |     SECStatus         rv; | ||||||
|  |     TLSExtensionData  *xtnData; | ||||||
| 
 | 
 | ||||||
|     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |     PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); | ||||||
| 
 | 
 | ||||||
|  | @ -3150,7 +3152,8 @@ ssl2_BeginClientHandshake(sslSocket *ss) | ||||||
|     localCipherSpecs = ss->cipherSpecs; |     localCipherSpecs = ss->cipherSpecs; | ||||||
|     localCipherSize  = ss->sizeCipherSpecs; |     localCipherSize  = ss->sizeCipherSpecs; | ||||||
| 
 | 
 | ||||||
|     sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + sidLen + |     /* Add 3 for SCSV */ | ||||||
|  |     sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen + | ||||||
| 	SSL_CHALLENGE_BYTES; | 	SSL_CHALLENGE_BYTES; | ||||||
| 
 | 
 | ||||||
|     /* Generate challenge bytes for server */ |     /* Generate challenge bytes for server */ | ||||||
|  | @ -3175,8 +3178,9 @@ ssl2_BeginClientHandshake(sslSocket *ss) | ||||||
|      |      | ||||||
|     msg[1] = MSB(ss->clientHelloVersion); |     msg[1] = MSB(ss->clientHelloVersion); | ||||||
|     msg[2] = LSB(ss->clientHelloVersion); |     msg[2] = LSB(ss->clientHelloVersion); | ||||||
|     msg[3] = MSB(localCipherSize); |     /* Add 3 for SCSV */ | ||||||
|     msg[4] = LSB(localCipherSize); |     msg[3] = MSB(localCipherSize + 3); | ||||||
|  |     msg[4] = LSB(localCipherSize + 3); | ||||||
|     msg[5] = MSB(sidLen); |     msg[5] = MSB(sidLen); | ||||||
|     msg[6] = LSB(sidLen); |     msg[6] = LSB(sidLen); | ||||||
|     msg[7] = MSB(SSL_CHALLENGE_BYTES); |     msg[7] = MSB(SSL_CHALLENGE_BYTES); | ||||||
|  | @ -3184,6 +3188,16 @@ ssl2_BeginClientHandshake(sslSocket *ss) | ||||||
|     cp += SSL_HL_CLIENT_HELLO_HBYTES; |     cp += SSL_HL_CLIENT_HELLO_HBYTES; | ||||||
|     PORT_Memcpy(cp, localCipherSpecs, localCipherSize); |     PORT_Memcpy(cp, localCipherSpecs, localCipherSize); | ||||||
|     cp += localCipherSize; |     cp += localCipherSize; | ||||||
|  |     /*
 | ||||||
|  |      * Add SCSV.  SSL 2.0 cipher suites are listed before SSL 3.0 cipher | ||||||
|  |      * suites in localCipherSpecs for compatibility with SSL 2.0 servers. | ||||||
|  |      * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at | ||||||
|  |      * the beginning. | ||||||
|  |      */ | ||||||
|  |     cp[0] = 0x00; | ||||||
|  |     cp[1] = 0x00; | ||||||
|  |     cp[2] = 0xff; | ||||||
|  |     cp += 3; | ||||||
|     if (sidLen) { |     if (sidLen) { | ||||||
| 	PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); | 	PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); | ||||||
| 	cp += sidLen; | 	cp += sidLen; | ||||||
|  | @ -3206,6 +3220,14 @@ ssl2_BeginClientHandshake(sslSocket *ss) | ||||||
| 	goto loser; | 	goto loser; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /*
 | ||||||
|  |      * Since we sent the SCSV, pretend we sent empty RI extension.  We need | ||||||
|  |      * to record the extension has been advertised after ssl3_InitState has | ||||||
|  |      * been called, which ssl3_StartHandshakeHash took care for us above. | ||||||
|  |      */ | ||||||
|  |     xtnData = &ss->xtnData; | ||||||
|  |     xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; | ||||||
|  | 
 | ||||||
|     /* Setup to receive servers hello message */ |     /* Setup to receive servers hello message */ | ||||||
|     ssl_GetRecvBufLock(ss); |     ssl_GetRecvBufLock(ss); | ||||||
|     ss->gs.recordLen = 0; |     ss->gs.recordLen = 0; | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
|  * the terms of any one of the MPL, the GPL or the LGPL. |  * the terms of any one of the MPL, the GPL or the LGPL. | ||||||
|  * |  * | ||||||
|  * ***** END LICENSE BLOCK ***** */ |  * ***** END LICENSE BLOCK ***** */ | ||||||
| /* $Id: sslerr.h,v 1.6 2008/03/06 20:16:22 wtc%google.com Exp $ */ | /* $Id: sslerr.h,v 1.10 2010/02/03 03:44:29 wtc%google.com Exp $ */ | ||||||
| #ifndef __SSL_ERR_H_ | #ifndef __SSL_ERR_H_ | ||||||
| #define __SSL_ERR_H_ | #define __SSL_ERR_H_ | ||||||
| 
 | 
 | ||||||
|  | @ -195,6 +195,12 @@ SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT		= (SSL_ERROR_BASE + 108), | ||||||
| SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 109), | SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET = (SSL_ERROR_BASE + 109), | ||||||
| SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET  = (SSL_ERROR_BASE + 110), | SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET  = (SSL_ERROR_BASE + 110), | ||||||
| 
 | 
 | ||||||
|  | SSL_ERROR_DECOMPRESSION_FAILURE		= (SSL_ERROR_BASE + 111), | ||||||
|  | SSL_ERROR_RENEGOTIATION_NOT_ALLOWED     = (SSL_ERROR_BASE + 112), | ||||||
|  | SSL_ERROR_UNSAFE_NEGOTIATION            = (SSL_ERROR_BASE + 113), | ||||||
|  | 
 | ||||||
|  | SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD	= (SSL_ERROR_BASE + 114), | ||||||
|  | 
 | ||||||
| SSL_ERROR_END_OF_LIST	/* let the c compiler determine the value of this. */ | SSL_ERROR_END_OF_LIST	/* let the c compiler determine the value of this. */ | ||||||
| } SSLErrorCodes; | } SSLErrorCodes; | ||||||
| #endif /* NO_SECURITY_ERROR_ENUM */ | #endif /* NO_SECURITY_ERROR_ENUM */ | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue
	
	 Kai Engert
						Kai Engert