зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
25809b66dc
Коммит
aad067a3a5
|
@ -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
|
||||
|
|
|
@ -46,7 +46,7 @@ LIBRARY_NAME = mozdbm_s
|
|||
LIB_IS_C_ONLY = 1
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
LIBRARY_NAME = dbm32
|
||||
LIBRARY_NAME = dbm$(MOZ_BITS)
|
||||
endif
|
||||
|
||||
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
|
||||
|
@ -58,7 +64,7 @@ MAKE_OBJ_TYPE=EXE
|
|||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBNAME=dbm32
|
||||
LIBNAME=dbm$(MOZ_BITS)
|
||||
PDBFILE=$(LIBNAME).pdb
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
|
|
|
@ -51,7 +51,7 @@ PROGRAM = lots$(BIN_SUFFIX)
|
|||
CSRCS = lots.c
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
EXTRA_DSO_LIBS = dbm32
|
||||
EXTRA_DSO_LIBS = dbm$(MOZ_BITS)
|
||||
else
|
||||
EXTRA_DSO_LIBS = mozdbm_s
|
||||
endif
|
||||
|
|
|
@ -71,9 +71,7 @@ OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -DBSD_OS -DBSDI -D
|
|||
ARCH = bsdos
|
||||
|
||||
DSO_CFLAGS = -fPIC -DPIC
|
||||
DSO_LDOPTS = -shared
|
||||
DSO_LDFLAGS =
|
||||
DSO_LDOPTS += -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
DSO_LDOPTS = -shared -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
|
||||
ifdef LIBRUNPATH
|
||||
DSO_LDOPTS += -Wl,-R$(LIBRUNPATH)
|
||||
|
|
|
@ -77,5 +77,3 @@ ARCH = beos
|
|||
|
||||
DSO_CFLAGS = -fPIC
|
||||
DSO_LDOPTS =
|
||||
DSO_LDFLAGS =
|
||||
|
||||
|
|
|
@ -121,8 +121,10 @@ endif
|
|||
ARCH = darwin
|
||||
|
||||
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.
|
||||
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)
|
||||
DLL_SUFFIX = dylib
|
||||
|
|
|
@ -42,11 +42,16 @@ CC = gcc
|
|||
CCC = g++
|
||||
RANLIB = ranlib
|
||||
|
||||
ifeq ($(OS_TEST),alpha)
|
||||
CPU_ARCH = alpha
|
||||
else
|
||||
CPU_ARCH = $(OS_TEST)
|
||||
ifeq ($(CPU_ARCH),i386)
|
||||
CPU_ARCH = x86
|
||||
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
|
||||
|
||||
|
|
|
@ -88,10 +88,9 @@ RPATH = +b '$$ORIGIN'
|
|||
ifneq ($(OS_TEST),ia64)
|
||||
# pa-risc
|
||||
ifndef USE_64
|
||||
RPATH =
|
||||
RPATH =
|
||||
endif
|
||||
endif
|
||||
DSO_LDFLAGS =
|
||||
|
||||
# +Z generates position independent code for use in shared libraries.
|
||||
DSO_CFLAGS = +Z
|
||||
|
|
|
@ -53,48 +53,41 @@ RANLIB = ranlib
|
|||
DEFAULT_COMPILER = gcc
|
||||
|
||||
ifeq ($(OS_TEST),ppc64)
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = ppc
|
||||
ifeq ($(USE_64),1)
|
||||
ARCHFLAG = -m64
|
||||
endif
|
||||
else
|
||||
ifeq ($(OS_TEST),alpha)
|
||||
OS_REL_CFLAGS = -D_ALPHA_ -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
OS_REL_CFLAGS = -D_ALPHA_
|
||||
CPU_ARCH = alpha
|
||||
else
|
||||
ifeq ($(OS_TEST),x86_64)
|
||||
ifeq ($(USE_64),1)
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = x86_64
|
||||
else
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -Di386 -D_XOPEN_SOURCE
|
||||
OS_REL_CFLAGS = -Di386
|
||||
CPU_ARCH = x86
|
||||
ARCHFLAG = -m32
|
||||
endif
|
||||
else
|
||||
ifeq ($(OS_TEST),sparc64)
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = sparc
|
||||
else
|
||||
ifeq (,$(filter-out arm% sa110,$(OS_TEST)))
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = arm
|
||||
else
|
||||
ifeq (,$(filter-out parisc%,$(OS_TEST)))
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = hppa
|
||||
else
|
||||
ifeq (,$(filter-out i%86,$(OS_TEST)))
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -Di386 -D_XOPEN_SOURCE
|
||||
OS_REL_CFLAGS = -Di386
|
||||
CPU_ARCH = x86
|
||||
else
|
||||
ifeq ($(OS_TEST),sh4a)
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = sh4
|
||||
else
|
||||
# $(OS_TEST) == m68k, ppc, ia64, sparc, s390, s390x, mips, sh3, sh4
|
||||
OS_REL_CFLAGS = -DLINUX1_2 -D_XOPEN_SOURCE
|
||||
CPU_ARCH = $(OS_TEST)
|
||||
endif
|
||||
endif
|
||||
|
@ -134,7 +127,12 @@ ifeq ($(USE_PTHREADS),1)
|
|||
OS_PTHREAD = -lpthread
|
||||
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
|
||||
|
||||
ifdef USE_PTHREADS
|
||||
|
@ -150,7 +148,6 @@ DSO_LDOPTS = -shared $(ARCHFLAG)
|
|||
# we don't use -z defs there.
|
||||
ZDEFS_FLAG = -Wl,-z,defs
|
||||
DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
|
||||
DSO_LDFLAGS =
|
||||
LDFLAGS += $(ARCHFLAG)
|
||||
|
||||
# INCLUDES += -I/usr/include -Y/usr/include/linux
|
||||
|
|
|
@ -46,5 +46,8 @@ endif
|
|||
PROCESS_MAP_FILE = grep -v ';-' $< | \
|
||||
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_LDOPTS = -shared
|
||||
DSO_LDFLAGS =
|
||||
ifeq ($(OBJECT_FMT),ELF)
|
||||
DSO_LDOPTS += -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
endif
|
||||
|
|
|
@ -66,7 +66,6 @@ ARCH = openbsd
|
|||
|
||||
DSO_CFLAGS = -fPIC -DPIC
|
||||
DSO_LDOPTS = -shared -fPIC -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
|
||||
DSO_LDFLAGS =
|
||||
|
||||
MKSHLIB = $(CC) $(DSO_LDOPTS)
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ PROCESS_MAP_FILE = cp $< $@
|
|||
BUILD_UNIX_PLUGINS = 1
|
||||
#DSO_LDOPTS += -b elf -G -z defs
|
||||
DSO_LDOPTS += -G
|
||||
DSO_LDFLAGS += -nostdlib -L/lib -L/usr/lib -lXm -lXt -lX11 -lgen
|
||||
|
||||
# Used for Java compiler
|
||||
EXPORT_FLAGS += -W l,-Bexport
|
||||
|
|
|
@ -69,4 +69,3 @@ ARCH = QNX
|
|||
|
||||
DSO_CFLAGS = -Wc,-fPIC
|
||||
DSO_LDOPTS = -shared
|
||||
DSO_LDFLAGS =
|
||||
|
|
|
@ -40,16 +40,15 @@ include $(CORE_DEPTH)/coreconf/UNIX.mk
|
|||
|
||||
LIB_SUFFIX = a
|
||||
DLL_SUFFIX = so
|
||||
AR = ar cr $@
|
||||
AR = ar cr $@
|
||||
LDOPTS += -L$(SOURCE_LIB_DIR)
|
||||
MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so)
|
||||
|
||||
OS_RELEASE =
|
||||
OS_TARGET = RISCOS
|
||||
OS_RELEASE =
|
||||
OS_TARGET = RISCOS
|
||||
|
||||
DSO_CFLAGS = -fPIC
|
||||
DSO_LDOPTS = -shared
|
||||
DSO_LDFLAGS =
|
||||
DSO_CFLAGS = -fPIC
|
||||
DSO_LDOPTS = -shared
|
||||
|
||||
ifdef BUILD_OPT
|
||||
OPTIMIZER = -O3
|
||||
|
|
|
@ -87,7 +87,6 @@ PROCESS_MAP_FILE = cp $< $@
|
|||
BUILD_UNIX_PLUGINS = 1
|
||||
#DSO_LDOPTS += -b elf -G -z defs
|
||||
DSO_LDOPTS += -b elf -G
|
||||
DSO_LDFLAGS += -nostdlib -L/lib -L/usr/lib -lXm -lXt -lX11 -lgen
|
||||
|
||||
# Used for Java compiler
|
||||
EXPORT_FLAGS += -W l,-Bexport
|
||||
|
|
|
@ -194,11 +194,6 @@ ifdef NSS_DISABLE_DBM
|
|||
DEFINES += -DNSS_DISABLE_DBM
|
||||
endif
|
||||
|
||||
ifdef NSS_NO_FORK_CHECK
|
||||
DEFINES += -DNO_FORK_CHECK
|
||||
DEFINES += -DNO_CHECK_FORK
|
||||
endif
|
||||
|
||||
# Avoid building object leak test code for optimized library
|
||||
ifndef BUILD_OPT
|
||||
ifdef PKIX_OBJECT_LEAK_TEST
|
||||
|
|
|
@ -42,4 +42,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -410,7 +410,8 @@ PWD := $(shell pwd)
|
|||
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
|
||||
@$(MAKE_OBJDIR)
|
||||
|
|
|
@ -243,6 +243,13 @@ ifeq ($(OS_ARCH),Linux)
|
|||
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=1
|
||||
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 WINCE
|
||||
|
|
|
@ -46,10 +46,6 @@ ifdef BUILD_LIBPKIX_TESTS
|
|||
DIRS += libpkix
|
||||
endif
|
||||
|
||||
ifndef USE_SYSTEM_ZLIB
|
||||
ZLIB_SRCDIR = zlib # Add the zlib directory to DIRS.
|
||||
endif
|
||||
|
||||
INCLUDES += \
|
||||
-I$(DIST)/../public/security \
|
||||
-I./include \
|
||||
|
|
|
@ -257,6 +257,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
|
|||
|
||||
/* Generate certificate request */
|
||||
cr = CERT_CreateCertificateRequest(subject, spki, NULL);
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
if (!cr) {
|
||||
SECU_PrintError(progName, "unable to make certificate request");
|
||||
return SECFailure;
|
||||
|
|
|
@ -56,47 +56,6 @@
|
|||
#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.
|
||||
* extHandle creaded by CERT_StartCRLEntryExtensions. entry
|
||||
* 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),
|
||||
"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
|
||||
|
||||
DIRS = lib \
|
||||
$(ZLIB_SRCDIR) \
|
||||
addbuiltin \
|
||||
atob \
|
||||
bltest \
|
||||
|
@ -56,6 +55,7 @@ DIRS = lib \
|
|||
digest \
|
||||
fipstest \
|
||||
makepqg \
|
||||
multinit \
|
||||
ocspclnt \
|
||||
oidcalc \
|
||||
p7content \
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
# 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
|
||||
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
|
||||
CRYPTOLIB=$(SOFTOKEN_LIB_DIR)/$(LIB_PREFIX)freebl.$(LIB_SUFFIX)
|
||||
|
||||
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)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)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 += \
|
||||
$(DIST)/lib/$(LIB_PREFIX)smime.$(LIB_SUFFIX) \
|
||||
|
@ -144,23 +145,6 @@ EXTRA_LIBS += \
|
|||
$(NULL)
|
||||
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 += \
|
||||
$(DIST)/lib/$(LIB_PREFIX)smime.$(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"
|
||||
" [-t threads] [-i pid_file] [-c ciphers] [-d dbdir] [-g numblocks]\n"
|
||||
" [-f password_file] [-L [seconds]] [-M maxProcs] [-P dbprefix]\n"
|
||||
" [-a sni_name]\n"
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
" [-C SSLCacheEntries] [-e ec_nickname]\n"
|
||||
#else
|
||||
|
@ -189,6 +190,8 @@ Usage(const char *progName)
|
|||
"-D means disable Nagle delays in TCP\n"
|
||||
"-E means disable export ciphersuites and SSL step down key gen\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"
|
||||
"-m means test the model-socket feature of SSL_ImportFD.\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"
|
||||
"-v means verbose output\n"
|
||||
"-x means use export policy.\n"
|
||||
"-z means enable compression.\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"
|
||||
"-N means do NOT use the server session cache. Incompatible with -M.\n"
|
||||
|
@ -387,11 +391,25 @@ printSecurityInfo(PRFileDesc *fd)
|
|||
suite.effectiveKeyBits, suite.symCipherName,
|
||||
suite.macBits, suite.macAlgorithmName);
|
||||
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.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)
|
||||
cert = SSL_PeerCertificate(fd);
|
||||
else
|
||||
|
@ -426,6 +444,71 @@ myBadCertHandler( void *arg, PRFileDesc *fd)
|
|||
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.
|
||||
**************************************************************************/
|
||||
|
@ -717,6 +800,9 @@ PRBool bypassPKCS11 = PR_FALSE;
|
|||
PRBool disableLocking = PR_FALSE;
|
||||
PRBool testbypass = 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 getCmd[] = { "GET " };
|
||||
|
@ -1520,12 +1606,26 @@ void initLoggingLayer(void)
|
|||
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
|
||||
server_main(
|
||||
PRFileDesc * listen_sock,
|
||||
int requestCert,
|
||||
SECKEYPrivateKey ** privKey,
|
||||
CERTCertificate ** cert)
|
||||
CERTCertificate ** cert,
|
||||
const char *expectedHostNameVal)
|
||||
{
|
||||
PRFileDesc *model_sock = NULL;
|
||||
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++) {
|
||||
if (cert[kea] != NULL) {
|
||||
secStatus = SSL_ConfigSecureServer(model_sock,
|
||||
|
@ -1631,6 +1744,10 @@ server_main(
|
|||
errExit("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5");
|
||||
}
|
||||
|
||||
if (expectedHostNameVal) {
|
||||
SSL_HandshakeCallback(model_sock, handshakeCallback,
|
||||
(void*)expectedHostNameVal);
|
||||
}
|
||||
|
||||
if (requestCert) {
|
||||
SSL_AuthCertificateHook(model_sock, mySSLAuthCertificate,
|
||||
|
@ -1818,7 +1935,9 @@ main(int argc, char **argv)
|
|||
SSL3Statistics *ssl3stats;
|
||||
PRUint32 i;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
|
||||
int virtServerNameIndex = 1;
|
||||
char *expectedHostNameVal = NULL;
|
||||
|
||||
tmp = strrchr(argv[0], '/');
|
||||
tmp = tmp ? tmp + 1 : argv[0];
|
||||
progName = strrchr(tmp, '\\');
|
||||
|
@ -1830,7 +1949,7 @@ main(int argc, char **argv)
|
|||
** numbers, then capital letters, then lower case, alphabetical.
|
||||
*/
|
||||
optstate = PL_CreateOptState(argc, argv,
|
||||
"2:3BC:DEL:M:NP:RSTbc:d:e:f: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) {
|
||||
++optionsFound;
|
||||
switch(optstate->option) {
|
||||
|
@ -1869,6 +1988,12 @@ main(int argc, char **argv)
|
|||
|
||||
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 'c': cipherString = PORT_Strdup(optstate->value); break;
|
||||
|
@ -1898,11 +2023,16 @@ main(int argc, char **argv)
|
|||
loggingLayer = PR_TRUE;
|
||||
break;
|
||||
|
||||
case 'k': expectedHostNameVal = PORT_Strdup(optstate->value);
|
||||
break;
|
||||
|
||||
case 'l': useLocalThreads = 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;
|
||||
|
||||
|
@ -1935,6 +2065,8 @@ main(int argc, char **argv)
|
|||
|
||||
case 'y': debugCache = PR_TRUE; break;
|
||||
|
||||
case 'z': enableCompression = PR_TRUE; break;
|
||||
|
||||
default:
|
||||
case '?':
|
||||
fprintf(stderr, "Unrecognized or bad option specified.\n");
|
||||
|
@ -2228,7 +2360,8 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
server_main(listen_sock, requestCert, privKey, cert);
|
||||
server_main(listen_sock, requestCert, privKey, cert,
|
||||
expectedHostNameVal);
|
||||
}
|
||||
|
||||
VLOG(("selfserv: server_thread: exiting"));
|
||||
|
@ -2240,6 +2373,10 @@ cleanup:
|
|||
fprintf(stderr, "selfserv: Experienced ticket parse failure(s)\n");
|
||||
exit(1);
|
||||
}
|
||||
if (failedToNegotiateName) {
|
||||
fprintf(stderr, "selfserv: Failed properly negotiate server name\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
@ -2251,15 +2388,20 @@ cleanup:
|
|||
SECKEY_DestroyPrivateKey(privKey[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0;virtServerNameArray[i];i++) {
|
||||
PORT_Free(virtServerNameArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (debugCache) {
|
||||
nss_DumpCertificateCacheInfo();
|
||||
}
|
||||
|
||||
if (nickName) {
|
||||
PORT_Free(nickName);
|
||||
}
|
||||
if (expectedHostNameVal) {
|
||||
PORT_Free(expectedHostNameVal);
|
||||
}
|
||||
if (passwd) {
|
||||
PORT_Free(passwd);
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@ WIN*)
|
|||
PATH=${ARG1}/lib:${ARG1}/bin:${ARG4}:${PATH}
|
||||
fi
|
||||
export PATH
|
||||
echo ${2}/shlibsign -v -i ${5}
|
||||
${2}/shlibsign -v -i ${5}
|
||||
echo "${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
|
||||
SHLIB_PATH=${1}/lib:${4}:$SHLIB_PATH
|
||||
export SHLIB_PATH
|
||||
|
@ -34,7 +34,7 @@ WIN*)
|
|||
export LIBRARY_PATH
|
||||
ADDON_PATH=${1}/lib:${4}:$ADDON_PATH
|
||||
export ADDON_PATH
|
||||
echo ${2}/shlibsign -v -i ${5}
|
||||
${2}/shlibsign -v -i ${5}
|
||||
echo "${2}"/shlibsign -v -i "${5}"
|
||||
"${2}"/shlibsign -v -i "${5}"
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -613,6 +613,9 @@ make_cert_request(char *subject, SECKEYPublicKey *pubk)
|
|||
exit (ERRX);
|
||||
}
|
||||
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
CERT_DestroyName(subj);
|
||||
|
||||
if (verbosity >= 0) {
|
||||
PR_fprintf(outputFD, "certificate request generated\n");
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
#include "cert.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;
|
||||
|
@ -365,6 +365,10 @@ const char * V2CipherString(int cs_int)
|
|||
case 0x000039: cs_str = "TLS/DHE-RSA/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 0x000042: cs_str = "TLS/DH-DSS/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 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 0x000073: cs_str = "TLS/DHE-DSS/AES128-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 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 0x00C002: cs_str = "TLS/ECDH-ECDSA/RC4-128/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 0x00C019: cs_str = "TLS/ECDH-anon/AES256-CBC/SHA"; break;
|
||||
|
||||
case 0x00feff: cs_str = "SSL3/RSA-FIPS/3DESEDE-CBC/SHA"; break;
|
||||
case 0x00fefe: cs_str = "SSL3/RSA-FIPS/DES-CBC/SHA"; break;
|
||||
case 0x00ffe1: cs_str = "SSL3/RSA-FIPS/DES56-CBC/SHA"; break;
|
||||
case 0x00ffe0: cs_str = "SSL3/RSA-FIPS/3DES192EDE-CBC/SHA";break;
|
||||
case 0x00C023: cs_str = "TLS/ECDHE-ECDSA/AES128-CBC/SHA256"; break;
|
||||
case 0x00C024: cs_str = "TLS/ECDHE-ECDSA/AES256-CBC/SHA384"; break;
|
||||
case 0x00C027: cs_str = "TLS/ECDHE-RSA/AES128-CBC/SHA256"; 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 */
|
||||
default: cs_str = "????" "/????????" "/?????????" "/???"; break;
|
||||
|
@ -458,6 +473,20 @@ const char * V2CipherString(int cs_int)
|
|||
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 *ex_name = NULL;
|
||||
|
@ -472,7 +501,9 @@ const char * helloExtensionNameString(int ex_num)
|
|||
case 5: ex_name = "status_request"; break;
|
||||
case 10: ex_name = "elliptic_curves"; break;
|
||||
case 11: ex_name = "ec_point_formats"; break;
|
||||
case 13: ex_name = "signature_algorithms"; 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;
|
||||
}
|
||||
|
||||
|
@ -554,10 +585,8 @@ void print_sslv2(DataBufferList *s, unsigned char *recordBuf, unsigned int recor
|
|||
(PRUint32)(GET_SHORT((chv2->rndlength))));
|
||||
PR_fprintf(PR_STDOUT," cipher-suites = { \n");
|
||||
for (p=0;p<GET_SHORT((chv2->cslength));p+=3) {
|
||||
const char *cs_str=NULL;
|
||||
PRUint32 cs_int=0;
|
||||
cs_int = GET_24((&chv2->csuites[p]));
|
||||
cs_str = V2CipherString(cs_int);
|
||||
PRUint32 cs_int = GET_24((&chv2->csuites[p]));
|
||||
const char *cs_str = V2CipherString(cs_int);
|
||||
|
||||
PR_fprintf(PR_STDOUT," (0x%06x) %s\n",
|
||||
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 = { ");
|
||||
len = GET_SHORT((shv2->cslength));
|
||||
for (p = 0; p < len; p += 3) {
|
||||
const char *cs_str=NULL;
|
||||
PRUint32 cs_int=0;
|
||||
cs_int = GET_24((pos+p));
|
||||
cs_str = V2CipherString(cs_int);
|
||||
PRUint32 cs_int = GET_24((pos+p));
|
||||
const char *cs_str = V2CipherString(cs_int);
|
||||
PR_fprintf(PR_STDOUT,"\n ");
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* 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,
|
||||
unsigned int recordLen,
|
||||
SSLRecord * sr,
|
||||
|
@ -757,10 +788,10 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
recordLen = s->msgBufOffset;
|
||||
recordBuf = s->msgBuf;
|
||||
}
|
||||
while (offset + 4 + s->hMACsize <= recordLen) {
|
||||
while (offset + 4 <= recordLen) {
|
||||
sslh.type = recordBuf[offset];
|
||||
sslh.length = GET_24(recordBuf+offset+1);
|
||||
if (offset + 4 + sslh.length + s->hMACsize > recordLen)
|
||||
if (offset + 4 + sslh.length > recordLen)
|
||||
break;
|
||||
/* finally have a complete message */
|
||||
if (sslhexparse)
|
||||
|
@ -816,17 +847,15 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
/* pretty print cipher suites */
|
||||
{
|
||||
int csuitelength = GET_SHORT((hsdata+pos));
|
||||
PR_fprintf(PR_STDOUT," cipher_suites[%d] = { \n",
|
||||
PR_fprintf(PR_STDOUT," cipher_suites[%d] = {\n",
|
||||
csuitelength/2);
|
||||
if (csuitelength % 2) {
|
||||
PR_fprintf(PR_STDOUT,
|
||||
"*error in protocol - csuitelength shouldn't be odd*\n");
|
||||
}
|
||||
for (w=0; w<csuitelength; w+=2) {
|
||||
const char *cs_str=NULL;
|
||||
PRUint32 cs_int=0;
|
||||
cs_int = GET_SHORT((hsdata+pos+2+w));
|
||||
cs_str = V2CipherString(cs_int);
|
||||
PRUint32 cs_int = GET_SHORT((hsdata+pos+2+w));
|
||||
const char *cs_str = V2CipherString(cs_int);
|
||||
PR_fprintf(PR_STDOUT,
|
||||
" (0x%04x) %s\n", cs_int, cs_str);
|
||||
}
|
||||
|
@ -837,13 +866,16 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
/* pretty print compression methods */
|
||||
{
|
||||
int complength = hsdata[pos];
|
||||
PR_fprintf(PR_STDOUT," compression[%d] = {",
|
||||
PR_fprintf(PR_STDOUT," compression[%d] = {\n",
|
||||
complength);
|
||||
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;
|
||||
PR_fprintf(PR_STDOUT," }\n");
|
||||
PR_fprintf(PR_STDOUT," }\n");
|
||||
}
|
||||
|
||||
/* pretty print extensions, if any */
|
||||
|
@ -887,8 +919,13 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
currentcipher = cs_int;
|
||||
pos += 2;
|
||||
}
|
||||
PR_fprintf(PR_STDOUT, " compression method = %02x\n",
|
||||
hsdata[pos++]);
|
||||
/* pretty print chosen compression method */
|
||||
{
|
||||
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 */
|
||||
pos = print_hello_extension(hsdata, sslh.length, pos);
|
||||
|
@ -1057,10 +1094,18 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
PR_fprintf(PR_STDOUT," }\n");
|
||||
|
||||
if (!isNULLmac(currentcipher) && !s->hMACsize) {
|
||||
/* To calculate the size of MAC, we subtract the number
|
||||
* of known bytes of message from the number of remaining
|
||||
* bytes in the record. */
|
||||
/* To calculate the size of MAC, we subtract the number of known
|
||||
* bytes of message from the number of remaining bytes in the
|
||||
* 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);
|
||||
sslh.length += s->hMACsize; /* skip over the MAC data */
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1075,8 +1120,8 @@ void print_ssl3_handshake(unsigned char *recordBuf,
|
|||
} /* end of switch sslh.type */
|
||||
offset += sslh.length + 4;
|
||||
} /* while */
|
||||
if (offset + s->hMACsize < recordLen) { /* stuff left over */
|
||||
int newMsgLen = recordLen - (offset + s->hMACsize);
|
||||
if (offset < recordLen) { /* stuff left over */
|
||||
int newMsgLen = recordLen - offset;
|
||||
if (!s->msgBuf) {
|
||||
s->msgBuf = PORT_Alloc(newMsgLen);
|
||||
if (!s->msgBuf) {
|
||||
|
|
|
@ -161,6 +161,7 @@ static PRBool bypassPKCS11 = PR_FALSE;
|
|||
static PRBool disableLocking = PR_FALSE;
|
||||
static PRBool ignoreErrors = PR_FALSE;
|
||||
static PRBool enableSessionTickets = PR_FALSE;
|
||||
static PRBool enableCompression = PR_FALSE;
|
||||
|
||||
PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
|
@ -179,8 +180,8 @@ Usage(const char *progName)
|
|||
fprintf(stderr,
|
||||
"Usage: %s [-n nickname] [-p port] [-d dbdir] [-c connections]\n"
|
||||
" [-23BDNTovqs] [-f filename] [-N | -P percentage]\n"
|
||||
" [-w dbpasswd] [-C cipher(s)] [-t threads] hostname\n"
|
||||
" [-W pwfile]\n"
|
||||
" [-w dbpasswd] [-C cipher(s)] [-t threads] [-W pwfile]\n"
|
||||
" [-a sniHostName] hostname\n"
|
||||
" where -v means verbose\n"
|
||||
" -o flag is interpreted as follows:\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"
|
||||
" -U means enable throttling up threads\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);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -312,9 +314,11 @@ printSecurityInfo(PRFileDesc *fd)
|
|||
suite.effectiveKeyBits, suite.symCipherName,
|
||||
suite.macBits, suite.macAlgorithmName);
|
||||
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.keaKeyBits, suite.keaTypeName);
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1074,7 +1078,8 @@ client_main(
|
|||
unsigned short port,
|
||||
int connections,
|
||||
cert_and_key* Cert_And_Key,
|
||||
const char * hostName)
|
||||
const char * hostName,
|
||||
const char * sniHostName)
|
||||
{
|
||||
PRFileDesc *model_sock = NULL;
|
||||
int i;
|
||||
|
@ -1233,6 +1238,12 @@ client_main(
|
|||
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_AuthCertificateHook(model_sock, mySSLAuthCertificate,
|
||||
|
@ -1241,6 +1252,9 @@ client_main(
|
|||
|
||||
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. */
|
||||
|
||||
/* end of ssl configuration. */
|
||||
|
@ -1326,8 +1340,9 @@ main(int argc, char **argv)
|
|||
SECStatus rv;
|
||||
PLOptState * optstate;
|
||||
PLOptStatus status;
|
||||
cert_and_key Cert_And_Key;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
cert_and_key Cert_And_Key;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
char * sniHostName = NULL;
|
||||
|
||||
/* Call the NSPR initialization routines */
|
||||
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
|
||||
|
@ -1338,7 +1353,8 @@ main(int argc, char **argv)
|
|||
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) {
|
||||
switch(optstate->option) {
|
||||
|
||||
|
@ -1360,6 +1376,8 @@ main(int argc, char **argv)
|
|||
|
||||
case 'U': ThrottleUp = PR_TRUE; break;
|
||||
|
||||
case 'a': sniHostName = PL_strdup(optstate->value); break;
|
||||
|
||||
case 'c': connections = PORT_Atoi(optstate->value); break;
|
||||
|
||||
case 'd': dir = optstate->value; break;
|
||||
|
@ -1398,6 +1416,8 @@ main(int argc, char **argv)
|
|||
pwdata.data = PL_strdup(optstate->value);
|
||||
break;
|
||||
|
||||
case 'z': enableCompression = PR_TRUE; break;
|
||||
|
||||
case 0: /* positional parameter */
|
||||
if (hostName) {
|
||||
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 */
|
||||
if (Cert_And_Key.cert) {
|
||||
|
@ -1482,6 +1503,9 @@ main(int argc, char **argv)
|
|||
if (Cert_And_Key.nickname) {
|
||||
PL_strfree(Cert_And_Key.nickname);
|
||||
}
|
||||
if (sniHostName) {
|
||||
PL_strfree(sniHostName);
|
||||
}
|
||||
|
||||
PL_strfree(hostName);
|
||||
|
||||
|
|
|
@ -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 = \
|
||||
baddbdir.c \
|
||||
conflict.c \
|
||||
dertimetest.c \
|
||||
nonspr10.c \
|
||||
remtest.c \
|
||||
$(NULL)
|
||||
|
|
|
@ -122,7 +122,8 @@ int ssl3CipherSuites[] = {
|
|||
|
||||
unsigned long __cmp_umuls;
|
||||
PRBool verbose;
|
||||
int renegotiate = 0;
|
||||
int renegotiationsToDo = 0;
|
||||
int renegotiationsDone = 0;
|
||||
|
||||
static char *progName;
|
||||
|
||||
|
@ -149,9 +150,11 @@ void printSecurityInfo(PRFileDesc *fd)
|
|||
suite.effectiveKeyBits, suite.symCipherName,
|
||||
suite.macBits, suite.macAlgorithmName);
|
||||
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.keaKeyBits, suite.keaTypeName);
|
||||
channel.keaKeyBits, suite.keaTypeName,
|
||||
channel.compressionMethodName);
|
||||
}
|
||||
}
|
||||
cert = SSL_RevealCert(fd);
|
||||
|
@ -179,18 +182,27 @@ void printSecurityInfo(PRFileDesc *fd)
|
|||
void
|
||||
handshakeCallback(PRFileDesc *fd, void *client_data)
|
||||
{
|
||||
const char *secondHandshakeName = (char *)client_data;
|
||||
if (secondHandshakeName) {
|
||||
SSL_SetURL(fd, secondHandshakeName);
|
||||
}
|
||||
printSecurityInfo(fd);
|
||||
if (renegotiate > 0) {
|
||||
renegotiate--;
|
||||
SSL_ReHandshake(fd, PR_FALSE);
|
||||
if (renegotiationsDone < renegotiationsToDo) {
|
||||
SSL_ReHandshake(fd, (renegotiationsToDo < 2));
|
||||
++renegotiationsDone;
|
||||
}
|
||||
}
|
||||
|
||||
static void Usage(const char *progName)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s -h host [-p port] [-d certdir] [-n nickname] [-23BTfosvxr] \n"
|
||||
" [-c ciphers] [-w passwd] [-W pwfile] [-q]\n", progName);
|
||||
"Usage: %s -h host [-a 1st_hs_name ] [-a 2nd_hs_name ] [-p port]\n"
|
||||
"[-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 Port number for SSL server\n", "-p port");
|
||||
fprintf(stderr,
|
||||
|
@ -210,8 +222,9 @@ static void Usage(const char *progName)
|
|||
fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
|
||||
fprintf(stderr, "%-20s Use export policy.\n", "-x");
|
||||
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 compression.\n", "-z");
|
||||
fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
|
||||
"-c ciphers");
|
||||
fprintf(stderr,
|
||||
|
@ -507,6 +520,7 @@ int main(int argc, char **argv)
|
|||
int disableLocking = 0;
|
||||
int useExportPolicy = 0;
|
||||
int enableSessionTickets = 0;
|
||||
int enableCompression = 0;
|
||||
PRSocketOptionData opt;
|
||||
PRNetAddr addr;
|
||||
PRPollDesc pollset[2];
|
||||
|
@ -517,6 +531,8 @@ int main(int argc, char **argv)
|
|||
int headerSeparatorPtrnId = 0;
|
||||
int error = 0;
|
||||
PRUint16 portno = 443;
|
||||
char * hs1SniHostName = NULL;
|
||||
char * hs2SniHostName = NULL;
|
||||
PLOptState *optstate;
|
||||
PLOptStatus optstatus;
|
||||
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) {
|
||||
switch (optstate->option) {
|
||||
case '?':
|
||||
|
@ -546,18 +563,27 @@ int main(int argc, char **argv)
|
|||
|
||||
case 'B': bypassPKCS11 = 1; break;
|
||||
|
||||
case 'S': skipProtoHeader = PR_TRUE; 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 'h': host = PORT_Strdup(optstate->value); break;
|
||||
|
||||
case 'f': clientSpeaksFirst = PR_TRUE; break;
|
||||
|
||||
case 'd': certDir = PORT_Strdup(optstate->value); break;
|
||||
|
||||
case 'f': clientSpeaksFirst = PR_TRUE; break;
|
||||
|
||||
case 'h': host = PORT_Strdup(optstate->value); break;
|
||||
|
||||
case 'm':
|
||||
multiplier = atoi(optstate->value);
|
||||
if (multiplier < 0)
|
||||
|
@ -578,7 +604,7 @@ int main(int argc, char **argv)
|
|||
|
||||
case 'v': verbose++; break;
|
||||
|
||||
case 'r': renegotiate = atoi(optstate->value); break;
|
||||
case 'r': renegotiationsToDo = atoi(optstate->value); break;
|
||||
|
||||
case 'w':
|
||||
pwdata.source = PW_PLAINTEXT;
|
||||
|
@ -591,6 +617,8 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'x': useExportPolicy = 1; break;
|
||||
|
||||
case 'z': enableCompression = 1; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -829,6 +857,13 @@ int main(int argc, char **argv)
|
|||
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_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);
|
||||
|
@ -836,8 +871,12 @@ int main(int argc, char **argv)
|
|||
SSL_BadCertHook(s, ownBadCertHandler, NULL);
|
||||
}
|
||||
SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
|
||||
SSL_HandshakeCallback(s, handshakeCallback, NULL);
|
||||
SSL_SetURL(s, host);
|
||||
SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName);
|
||||
if (hs1SniHostName) {
|
||||
SSL_SetURL(s, hs1SniHostName);
|
||||
} else {
|
||||
SSL_SetURL(s, host);
|
||||
}
|
||||
|
||||
/* Try to connect to the server */
|
||||
status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
|
||||
|
@ -1045,6 +1084,12 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
done:
|
||||
if (hs1SniHostName) {
|
||||
PORT_Free(hs1SniHostName);
|
||||
}
|
||||
if (hs2SniHostName) {
|
||||
PORT_Free(hs2SniHostName);
|
||||
}
|
||||
if (nickname) {
|
||||
PORT_Free(nickname);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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). #
|
||||
#######################################################################
|
||||
|
||||
ifeq ($(OS_TARGET), WINCE)
|
||||
DIRS := $(filter-out fortcrypt,$(DIRS))
|
||||
ifndef USE_SYSTEM_ZLIB
|
||||
ZLIB_SRCDIR = zlib # Add the zlib directory to DIRS.
|
||||
endif
|
||||
|
||||
ifndef MOZILLA_CLIENT
|
||||
ifndef NSS_USE_SYSTEM_SQLITE
|
||||
DIRS := sqlite $(DIRS)
|
||||
SQLITE_SRCDIR = sqlite # Add the sqlite directory to DIRS.
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*
|
||||
* 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_
|
||||
|
@ -1077,12 +1077,20 @@ extern CERTDistNames *CERT_GetSSLCACerts(CERTCertDBHandle *handle);
|
|||
|
||||
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
|
||||
*/
|
||||
extern CERTDistNames *CERT_DistNamesFromNicknames
|
||||
(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.
|
||||
*/
|
||||
|
|
|
@ -617,6 +617,54 @@ CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
|
|||
/*
|
||||
* 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 *
|
||||
CERT_GetSSLCACerts(CERTCertDBHandle *handle)
|
||||
{
|
||||
|
@ -678,6 +726,53 @@ loser:
|
|||
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 *
|
||||
CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,
|
||||
int nnames)
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
* Implementation of OCSP services, for both client and server.
|
||||
* (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"
|
||||
|
@ -150,6 +150,18 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
|
|||
void *pwArg,
|
||||
PRBool *certIDWasConsumed,
|
||||
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
|
||||
ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
||||
CERTOCSPResponse *response,
|
||||
|
@ -158,6 +170,9 @@ ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
|
|||
int64 time,
|
||||
CERTOCSPSingleResponse **pSingleResponse);
|
||||
|
||||
static SECStatus
|
||||
ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time);
|
||||
|
||||
#ifndef DEBUG
|
||||
#define OCSP_TRACE(msg)
|
||||
#define OCSP_TRACE_TIME(msg, time)
|
||||
|
@ -4284,6 +4299,33 @@ ocsp_TimeIsRecent(int64 checkTime)
|
|||
|
||||
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:
|
||||
* 1. The signer (represented by "signerCert") is authorized to give status
|
||||
|
@ -4365,13 +4407,10 @@ ocsp_VerifySingleResponse(CERTOCSPSingleResponse *single,
|
|||
return rv;
|
||||
|
||||
LL_ADD(tmp, tmp, nextUpdate);
|
||||
if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate)) {
|
||||
PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
|
||||
return SECFailure;
|
||||
}
|
||||
if (LL_CMP(tmp, <, now) || LL_CMP(producedAt, >, nextUpdate))
|
||||
return ocsp_HandleOldSingleResponse(single, now);
|
||||
} else if (ocsp_TimeIsRecent(thisUpdate) != PR_TRUE) {
|
||||
PORT_SetError(SEC_ERROR_OCSP_OLD_RESPONSE);
|
||||
return SECFailure;
|
||||
return ocsp_HandleOldSingleResponse(single, now);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
@ -4645,6 +4684,9 @@ ocsp_GetCachedOCSPResponseStatusIfFresh(CERTOCSPCertID *certID,
|
|||
/* having an arena means, we have a cached certStatus */
|
||||
if (cacheItem->certStatusArena) {
|
||||
*rvOcsp = ocsp_CertHasGoodStatus(&cacheItem->certStatus, time);
|
||||
if (*rvOcsp != SECSuccess) {
|
||||
*missingResponseError = PORT_GetError();
|
||||
}
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
/*
|
||||
|
@ -4766,6 +4808,77 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
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
|
||||
* return value.
|
||||
|
@ -4783,11 +4896,7 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
|
|||
PRBool locationIsDefault;
|
||||
SECItem *encodedResponse = NULL;
|
||||
CERTOCSPRequest *request = NULL;
|
||||
CERTOCSPResponse *response = NULL;
|
||||
CERTCertificate *signerCert = NULL;
|
||||
CERTCertificate *issuerCert = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
CERTOCSPSingleResponse *single = NULL;
|
||||
|
||||
if (!certIDWasConsumed || !rv_ocsp) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
@ -4849,6 +4958,75 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
|
|||
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);
|
||||
if (response == NULL) {
|
||||
goto loser;
|
||||
|
@ -4896,14 +5074,18 @@ ocsp_GetOCSPStatusFromNetwork(CERTCertDBHandle *handle,
|
|||
*rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time);
|
||||
|
||||
loser:
|
||||
PR_EnterMonitor(OCSP_Global.monitor);
|
||||
if (OCSP_Global.maxCacheEntries >= 0) {
|
||||
/* single == NULL means: remember response failure */
|
||||
ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
|
||||
certIDWasConsumed);
|
||||
/* ignore cache update failures */
|
||||
if (cacheNegative || *rv_ocsp == SECSuccess) {
|
||||
PR_EnterMonitor(OCSP_Global.monitor);
|
||||
if (OCSP_Global.maxCacheEntries >= 0) {
|
||||
/* single == NULL means: remember response failure */
|
||||
ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
|
||||
certIDWasConsumed);
|
||||
/* 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)
|
||||
CERT_DestroyCertificate(issuerCert);
|
||||
|
@ -4911,12 +5093,6 @@ loser:
|
|||
CERT_DestroyCertificate(signerCert);
|
||||
if (response != NULL)
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
/*
|
||||
* 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_
|
||||
|
@ -550,6 +550,42 @@ CERT_ParseURL(const char *url, char **pHostname, PRUint16 *pPort, char **pPath);
|
|||
extern SECStatus
|
||||
CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
|
||||
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
|
||||
* 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.
|
||||
#
|
||||
# ***** 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 $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
@ -49,7 +49,7 @@ EXTRA_LIBS = \
|
|||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
EXTRA_LIBS += \
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(NSPR_LIB_DIR) \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
|
@ -64,7 +64,7 @@ EXTRA_SHARED_LIBS += \
|
|||
endif # NS_USE_GCC
|
||||
else
|
||||
|
||||
EXTRA_LIBS += \
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(NSPR_LIB_DIR) \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
|
@ -78,25 +78,3 @@ include $(CORE_DEPTH)/coreconf/rules.mk
|
|||
# Generate certdata.c.
|
||||
generate:
|
||||
$(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.
|
||||
#
|
||||
# ***** 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 = ../../../..
|
||||
|
||||
|
@ -61,5 +61,3 @@ CSRCS = \
|
|||
REQUIRES = nspr
|
||||
|
||||
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.
|
||||
*
|
||||
* ***** 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_
|
||||
#define _CRYPTOHI_H_
|
||||
|
@ -114,7 +114,7 @@ extern SECStatus SGN_Begin(SGNContext *cx);
|
|||
** "input" the input data to sign
|
||||
** "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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -33,7 +33,9 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** 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_
|
||||
#define _KEY_H_
|
||||
|
|
|
@ -2014,10 +2014,10 @@ SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
|
|||
/* DER-encode the subjectpublickeyinfo */
|
||||
spkiDER = SEC_ASN1EncodeItem(NULL /*arena*/, NULL/*dest*/, spki,
|
||||
CERT_SubjectPublicKeyInfoTemplate);
|
||||
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
|
||||
finish:
|
||||
if (spki!=NULL) {
|
||||
SECKEY_DestroySubjectPublicKeyInfo(spki);
|
||||
}
|
||||
return spkiDER;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** 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 "cryptohi.h"
|
||||
|
@ -140,7 +140,7 @@ SGN_Begin(SGNContext *cx)
|
|||
}
|
||||
|
||||
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) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
|
|
|
@ -35,12 +35,10 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
#include "pkcs11.h"
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
|
|
|
@ -44,13 +44,9 @@
|
|||
#define CKHELPER_H
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
/* Some globals to keep from constantly redeclaring common cryptoki
|
||||
|
|
|
@ -44,13 +44,9 @@
|
|||
*/
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef NSSDEV_H
|
||||
#include "nssdev.h"
|
||||
#endif /* NSSDEV_H */
|
||||
|
|
|
@ -38,17 +38,13 @@
|
|||
#define DEVM_H
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef BASE_H
|
||||
#include "base.h"
|
||||
#endif /* BASE_H */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef DEV_H
|
||||
#include "dev.h"
|
||||
#endif /* DEV_H */
|
||||
|
|
|
@ -35,12 +35,10 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
#include "pkcs11.h"
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define DEVT_H
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
|
@ -59,10 +59,6 @@ static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.23 $ $
|
|||
#include "nssdevt.h"
|
||||
#endif /* NSSDEVT_H */
|
||||
|
||||
#ifndef NSSCKT_H
|
||||
#include "nssckt.h"
|
||||
#endif /* NSSCKT_H */
|
||||
|
||||
#ifndef BASET_H
|
||||
#include "baset.h"
|
||||
#endif /* BASET_H */
|
||||
|
|
|
@ -35,12 +35,10 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#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 */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
#include "nssckepv.h"
|
||||
#endif /* NSSCKEPV_H */
|
||||
#include "pkcs11.h"
|
||||
|
||||
#ifndef DEVM_H
|
||||
#include "devm.h"
|
||||
|
@ -431,6 +429,13 @@ find_objects_by_template (
|
|||
CK_OBJECT_CLASS objclass = (CK_OBJECT_CLASS)-1;
|
||||
nssCryptokiObject **objects = NULL;
|
||||
PRUint32 i;
|
||||
|
||||
if (!token) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN);
|
||||
if (statusOpt)
|
||||
*statusOpt = PR_FAILURE;
|
||||
return NULL;
|
||||
}
|
||||
for (i=0; i<otsize; i++) {
|
||||
if (obj_template[i].type == CKA_CLASS) {
|
||||
objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
|
||||
|
@ -491,6 +496,10 @@ nssToken_ImportCertificate (
|
|||
nssTokenSearchType searchType;
|
||||
nssCryptokiObject *rvObject = NULL;
|
||||
|
||||
if (!tok) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN);
|
||||
return NULL;
|
||||
}
|
||||
if (certType == NSSCertificateType_PKIX) {
|
||||
cert_type = CKC_X_509;
|
||||
} else {
|
||||
|
@ -842,6 +851,13 @@ nssToken_FindCertificateByIssuerAndSerialNumber (
|
|||
nssCryptokiObject **objects;
|
||||
nssCryptokiObject *rvObject = NULL;
|
||||
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 */
|
||||
if (searchType == nssTokenSearchType_SessionOnly) {
|
||||
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 += -DMPI_AMD64_ADD
|
||||
# comment the next two lines to turn off intel HW accelleration
|
||||
DEFINES += -DUSE_HW_AES
|
||||
ASFILES += intel-aes.s
|
||||
# DEFINES += -DUSE_HW_AES
|
||||
# ASFILES += intel-aes.s
|
||||
MPI_SRCS += mpi_amd64.c mp_comba.c
|
||||
endif
|
||||
ifeq ($(CPU_ARCH),x86)
|
||||
|
@ -410,8 +410,8 @@ else
|
|||
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
|
||||
DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
|
||||
# comment the next two lines to turn off intel HW accelleration
|
||||
DEFINES += -DUSE_HW_AES
|
||||
ASFILES += intel-aes.s
|
||||
# DEFINES += -DUSE_HW_AES
|
||||
# ASFILES += intel-aes.s
|
||||
MPI_SRCS += mpi_amd64.c
|
||||
else
|
||||
# Solaris x86
|
||||
|
|
|
@ -139,6 +139,20 @@ cleanup:
|
|||
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--------------------------------------------- */
|
||||
|
||||
/*
|
||||
|
@ -198,7 +212,7 @@ pkix_OcspChecker_CheckLocal(
|
|||
revStatus = PKIX_RevStatus_Success;
|
||||
resultCode = 0;
|
||||
} else {
|
||||
revStatus = PKIX_RevStatus_Revoked;
|
||||
revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,7 +340,7 @@ pkix_OcspChecker_CheckExternal(
|
|||
plContext),
|
||||
PKIX_OCSPRESPONSEGETSTATUSFORCERTFAILED);
|
||||
if (passed == PKIX_FALSE) {
|
||||
revStatus = PKIX_RevStatus_Revoked;
|
||||
revStatus = pkix_OcspChecker_MapResultCodeToRevStatus(resultCode);
|
||||
} else {
|
||||
revStatus = PKIX_RevStatus_Success;
|
||||
}
|
||||
|
|
|
@ -395,7 +395,10 @@ pkix_hash(
|
|||
PKIX_UInt32 hash;
|
||||
|
||||
PKIX_ENTER(OBJECT, "pkix_hash");
|
||||
PKIX_NULLCHECK_TWO(bytes, pHash);
|
||||
if (length != 0) {
|
||||
PKIX_NULLCHECK_ONE(bytes);
|
||||
}
|
||||
PKIX_NULLCHECK_ONE(pHash);
|
||||
|
||||
hash = 0;
|
||||
for (i = 0; i < length; i++) {
|
||||
|
|
|
@ -48,11 +48,11 @@ DEPTH = ../..
|
|||
# smime
|
||||
# ckfw (builtins module)
|
||||
# crmf jar (not dll's)
|
||||
DIRS = util freebl softoken \
|
||||
DIRS = util freebl $(SQLITE_SRCDIR) softoken \
|
||||
base dev pki pki1 \
|
||||
libpkix \
|
||||
certdb certhigh pk11wrap cryptohi nss \
|
||||
ssl \
|
||||
$(ZLIB_SRCDIR) ssl \
|
||||
pkcs12 pkcs7 smime \
|
||||
crmf jar \
|
||||
ckfw \
|
||||
|
|
|
@ -35,11 +35,6 @@
|
|||
#
|
||||
# ***** 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.
|
||||
ifeq (,$(filter-out WIN%,$(OS_TARGET)))
|
||||
|
||||
|
|
|
@ -979,3 +979,21 @@ SECMOD_OpenNewSlot;
|
|||
;+ 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.
|
||||
*
|
||||
* ***** 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_
|
||||
#define __nss_h_
|
||||
|
@ -60,22 +60,97 @@
|
|||
#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.
|
||||
*
|
||||
* 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_VMINOR 12
|
||||
#define NSS_VPATCH 4
|
||||
#define NSS_BETA PR_FALSE
|
||||
#define NSS_VPATCH 6
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_TRUE
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
|
||||
#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
|
||||
|
||||
/*
|
||||
|
@ -194,10 +269,19 @@ extern SECStatus NSS_InitReadWrite(const char *configdir);
|
|||
#define SECMOD_DB "secmod.db"
|
||||
#endif
|
||||
|
||||
typedef struct NSSInitContextStr NSSInitContext;
|
||||
|
||||
|
||||
extern SECStatus NSS_Initialize(const char *configdir,
|
||||
const char *certPrefix, const char *keyPrefix,
|
||||
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
|
||||
* old database in.
|
||||
|
@ -251,9 +335,9 @@ extern SECStatus NSS_Shutdown(void);
|
|||
/*
|
||||
* set the PKCS #11 strings for the internal token.
|
||||
*/
|
||||
void PK11_ConfigurePKCS11(const char *man, const char *libdes,
|
||||
const char *tokdes, const char *ptokdes, const char *slotdes,
|
||||
const char *pslotdes, const char *fslotdes, const char *fpslotdes,
|
||||
void PK11_ConfigurePKCS11(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, int pwRequired);
|
||||
|
||||
/*
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS MY_FILEFLAGS_2
|
||||
FILEOS MY_FILEOS
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** 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 <string.h>
|
||||
|
@ -46,8 +46,6 @@
|
|||
#include "prmem.h"
|
||||
#include "cert.h"
|
||||
#include "key.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
#include "secmod.h"
|
||||
#include "secoid.h"
|
||||
#include "nss.h"
|
||||
|
@ -128,6 +126,89 @@ nss_makeFlags(PRBool readOnly, PRBool noCertDB,
|
|||
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()
|
||||
* info.
|
||||
|
@ -141,85 +222,25 @@ static PRBool pk11_password_required = PR_FALSE;
|
|||
* the PKCS #11 internal token.
|
||||
*/
|
||||
void
|
||||
PK11_ConfigurePKCS11(const char *man, const char *libdes, const char *tokdes,
|
||||
const char *ptokdes, const char *slotdes, const char *pslotdes,
|
||||
const char *fslotdes, const char *fpslotdes, int minPwd, int pwRequired)
|
||||
PK11_ConfigurePKCS11(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,
|
||||
int pwRequired)
|
||||
{
|
||||
char *strings = NULL;
|
||||
char *newStrings;
|
||||
char * strings;
|
||||
|
||||
/* make sure the internationalization was done correctly... */
|
||||
strings = PR_smprintf("");
|
||||
if (strings == NULL) return;
|
||||
|
||||
if (man) {
|
||||
newStrings = PR_smprintf("%s manufacturerID='%s'",strings,man);
|
||||
PR_smprintf_free(strings);
|
||||
strings = newStrings;
|
||||
strings = nss_MkConfigString(man,libdesc,tokdesc,ptokdesc,slotdesc,
|
||||
pslotdesc,fslotdesc,fpslotdesc,minPwd);
|
||||
if (strings == NULL) {
|
||||
return;
|
||||
}
|
||||
if (strings == NULL) return;
|
||||
|
||||
if (libdes) {
|
||||
newStrings = PR_smprintf("%s libraryDescription='%s'",strings,libdes);
|
||||
PR_smprintf_free(strings);
|
||||
strings = newStrings;
|
||||
if (libdesc) {
|
||||
if (pk11_config_name != NULL) {
|
||||
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) {
|
||||
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
|
||||
* 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.
|
||||
* 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").
|
||||
* 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.
|
||||
* this function builds a moduleSpec string from the options and previously
|
||||
* set statics (from PKCS11_Configure, for instance), and uses it to kick off
|
||||
* the loading of the various PKCS #11 modules.
|
||||
*/
|
||||
|
||||
static PRBool nss_IsInitted = PR_FALSE;
|
||||
static void* plContext = NULL;
|
||||
|
||||
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,
|
||||
PRBool readOnly, PRBool noCertDB,
|
||||
PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
|
||||
PRBool optimizeSpace, PRBool noSingleThreadedModules,
|
||||
PRBool allowAlreadyInitializedModules,
|
||||
PRBool dontFinalizeModules)
|
||||
nss_InitModules(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, char *configName, char *configStrings,
|
||||
PRBool pwRequired, PRBool readOnly, PRBool noCertDB,
|
||||
PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace,
|
||||
PRBool isContextInit)
|
||||
{
|
||||
SECStatus rv = SECFailure;
|
||||
char *moduleSpec = NULL;
|
||||
char *flags = NULL;
|
||||
SECStatus rv = SECFailure;
|
||||
char *lconfigdir = NULL;
|
||||
char *lcertPrefix = NULL;
|
||||
char *lkeyPrefix = NULL;
|
||||
|
@ -438,88 +388,62 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
|||
char *lupdKeyPrefix = NULL;
|
||||
char *lupdateID = 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,
|
||||
pk11_password_required, optimizeSpace);
|
||||
pwRequired, optimizeSpace);
|
||||
if (flags == NULL) return rv;
|
||||
|
||||
/*
|
||||
* configdir is double nested, and Windows uses the same character
|
||||
* for file seps as we use for escapes! (sigh).
|
||||
*/
|
||||
lconfigdir = nss_doubleEscape(configdir);
|
||||
lconfigdir = secmod_DoubleEscape(configdir, '\'', '\"');
|
||||
if (lconfigdir == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lcertPrefix = nss_doubleEscape(certPrefix);
|
||||
lcertPrefix = secmod_DoubleEscape(certPrefix, '\'', '\"');
|
||||
if (lcertPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lkeyPrefix = nss_doubleEscape(keyPrefix);
|
||||
lkeyPrefix = secmod_DoubleEscape(keyPrefix, '\'', '\"');
|
||||
if (lkeyPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lsecmodName = nss_doubleEscape(secmodName);
|
||||
lsecmodName = secmod_DoubleEscape(secmodName, '\'', '\"');
|
||||
if (lsecmodName == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateDir = nss_doubleEscape(updateDir);
|
||||
lupdateDir = secmod_DoubleEscape(updateDir, '\'', '\"');
|
||||
if (lupdateDir == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdCertPrefix = nss_doubleEscape(updCertPrefix);
|
||||
lupdCertPrefix = secmod_DoubleEscape(updCertPrefix, '\'', '\"');
|
||||
if (lupdCertPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdKeyPrefix = nss_doubleEscape(updKeyPrefix);
|
||||
lupdKeyPrefix = secmod_DoubleEscape(updKeyPrefix, '\'', '\"');
|
||||
if (lupdKeyPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateID = nss_doubleEscape(updateID);
|
||||
lupdateID = secmod_DoubleEscape(updateID, '\'', '\"');
|
||||
if (lupdateID == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateName = nss_doubleEscape(updateName);
|
||||
lupdateName = secmod_DoubleEscape(updateName, '\'', '\"');
|
||||
if (lupdateName == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (noSingleThreadedModules || allowAlreadyInitializedModules ||
|
||||
dontFinalizeModules) {
|
||||
pk11_setGlobalOptions(noSingleThreadedModules,
|
||||
allowAlreadyInitializedModules,
|
||||
dontFinalizeModules);
|
||||
}
|
||||
|
||||
moduleSpec = PR_smprintf(
|
||||
"name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' "
|
||||
"secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' "
|
||||
"updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" "
|
||||
"NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
|
||||
pk11_config_name ? pk11_config_name : NSS_DEFAULT_MOD_NAME,
|
||||
"NSS=\"flags=internal,moduleDB,moduleDBOnly,critical%s\"",
|
||||
configName ? configName : NSS_DEFAULT_MOD_NAME,
|
||||
lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags,
|
||||
lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,
|
||||
lupdateName, pk11_config_strings ? pk11_config_strings : "");
|
||||
lupdateName, configStrings ? configStrings : "",
|
||||
isContextInit ? "" : ",defaultModDB,internalKeySlot");
|
||||
|
||||
loser:
|
||||
PORT_Free(flags);
|
||||
|
@ -541,65 +465,262 @@ loser:
|
|||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
return SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
if (nss_InitShutdownList() != SECSuccess) {
|
||||
return SECFailure;
|
||||
goto loser;
|
||||
}
|
||||
CERT_SetDefaultCertDB((CERTCertDBHandle *)
|
||||
STAN_GetDefaultTrustDomain());
|
||||
if ((!noModDB) && (!noCertDB) && (!noRootInit)) {
|
||||
if (!SECMOD_HasRootCerts()) {
|
||||
const char *dbpath = configdir;
|
||||
/* handle supported database modifiers */
|
||||
if (strncmp(dbpath, "sql:", 4) == 0) {
|
||||
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) {
|
||||
pkixError = PKIX_Initialize
|
||||
(PKIX_FALSE, PKIX_MAJOR_VERSION, PKIX_MINOR_VERSION,
|
||||
PKIX_MINOR_VERSION, &actualMinorVersion, &plContext);
|
||||
|
||||
if (pkixError != NULL) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
} else {
|
||||
char *ev = getenv("NSS_ENABLE_PKIX_VERIFY");
|
||||
if (ev && ev[0]) {
|
||||
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
|
||||
NSS_Init(const char *configdir)
|
||||
{
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
|
||||
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
|
||||
NULL, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
NSS_InitReadWrite(const char *configdir)
|
||||
{
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
|
||||
PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "", NULL,
|
||||
NULL, PR_FALSE, PR_FALSE, 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)
|
||||
{
|
||||
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
|
||||
"", "", "", "", "",
|
||||
"", "", "", "", "", NULL, NULL,
|
||||
((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
|
||||
((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
|
||||
((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));
|
||||
}
|
||||
|
||||
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
|
||||
NSS_InitWithMerge(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, const char *secmodName,
|
||||
|
@ -676,7 +818,8 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix,
|
|||
const char *updateName, PRUint32 flags)
|
||||
{
|
||||
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_NOCERTDB) == NSS_INIT_NOCERTDB),
|
||||
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
|
||||
|
@ -694,7 +837,7 @@ NSS_InitWithMerge(const char *configdir, const char *certPrefix,
|
|||
SECStatus
|
||||
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_FALSE,PR_FALSE,PR_FALSE);
|
||||
}
|
||||
|
@ -722,7 +865,7 @@ nss_GetShutdownEntry(NSS_ShutdownFunc sFunc, void *appData)
|
|||
{
|
||||
int count, i;
|
||||
count = nssShutdownList.peakFuncs;
|
||||
/* expect the list to be short, just do a linear search */
|
||||
|
||||
for (i=0; i < count; i++) {
|
||||
if ((nssShutdownList.funcs[i].func == sFunc) &&
|
||||
(nssShutdownList.funcs[i].appData == appData)){
|
||||
|
@ -740,8 +883,8 @@ NSS_RegisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!nss_IsInitted) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
if (!NSS_IsInitialized()) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
if (sFunc == NULL) {
|
||||
|
@ -794,8 +937,8 @@ SECStatus
|
|||
NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
|
||||
{
|
||||
int i;
|
||||
if (!nss_IsInitted) {
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
if (!NSS_IsInitialized()) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
@ -821,6 +964,9 @@ NSS_UnregisterShutdown(NSS_ShutdownFunc sFunc, void *appData)
|
|||
static SECStatus
|
||||
nss_InitShutdownList(void)
|
||||
{
|
||||
if (nssShutdownList.lock != NULL) {
|
||||
return SECSuccess;
|
||||
}
|
||||
nssShutdownList.lock = PZ_NewLock(nssILockOther);
|
||||
if (nssShutdownList.lock == NULL) {
|
||||
return SECFailure;
|
||||
|
@ -869,16 +1015,12 @@ nss_ShutdownShutdownList(void)
|
|||
extern const NSSError NSS_ERROR_BUSY;
|
||||
|
||||
SECStatus
|
||||
NSS_Shutdown(void)
|
||||
nss_Shutdown(void)
|
||||
{
|
||||
SECStatus shutdownRV = SECSuccess;
|
||||
SECStatus rv;
|
||||
PRStatus status;
|
||||
|
||||
if (!nss_IsInitted) {
|
||||
PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
|
||||
return SECFailure;
|
||||
}
|
||||
NSSInitContext *temp;
|
||||
|
||||
rv = nss_ShutdownShutdownList();
|
||||
if (rv != SECSuccess) {
|
||||
|
@ -891,6 +1033,7 @@ NSS_Shutdown(void)
|
|||
SECOID_Shutdown();
|
||||
status = STAN_Shutdown();
|
||||
cert_DestroySubjectKeyIDHashTable();
|
||||
pk11_SetInternalKeySlot(NULL);
|
||||
rv = SECMOD_Shutdown();
|
||||
if (rv != SECSuccess) {
|
||||
shutdownRV = SECFailure;
|
||||
|
@ -911,14 +1054,87 @@ NSS_Shutdown(void)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
* compatible with previous major releases. It is
|
||||
* 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;
|
||||
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';
|
||||
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) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (vmajor == NSS_VMAJOR && vminor == NSS_VMINOR &&
|
||||
vpatch == NSS_VPATCH && vbuild > NSS_VBUILD) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* Check dependent libraries */
|
||||
if (PR_VersionCheck(PR_VERSION) == PR_FALSE) {
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -1894,25 +1894,7 @@ PK11_ExportEncryptedPrivateKeyInfo(
|
|||
SECItem*
|
||||
PK11_DEREncodePublicKey(SECKEYPublicKey *pubk)
|
||||
{
|
||||
CERTSubjectPublicKeyInfo *spki=NULL;
|
||||
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;
|
||||
return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk);
|
||||
}
|
||||
|
||||
char *
|
||||
|
|
|
@ -854,6 +854,10 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
|||
nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
|
||||
|
||||
if (keyID == NULL) {
|
||||
goto loser; /* error code should be set already */
|
||||
}
|
||||
if (!token) {
|
||||
PORT_SetError(SEC_ERROR_NO_TOKEN);
|
||||
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 */
|
||||
nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
|
||||
if (!c->id.data) {
|
||||
|
@ -926,6 +919,18 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
|
|||
}
|
||||
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
|
||||
* CERTCertificate, and finish
|
||||
*/
|
||||
|
|
|
@ -37,8 +37,9 @@
|
|||
#define _PK11FUNC_H_
|
||||
|
||||
/*
|
||||
* the original pk11func.h had a mix of public and private functions.
|
||||
* continue to provide those for backward compatibility.
|
||||
* The original pk11func.h had a mix of public and private functions.
|
||||
* Continue to provide those for backward compatibility. New code should
|
||||
* include pk11pub.h instead of pk11func.h.
|
||||
*/
|
||||
#include "pk11pub.h"
|
||||
#include "pk11priv.h"
|
||||
|
|
|
@ -119,16 +119,122 @@ PRBool pk11_getFinalizeModulesOption(void)
|
|||
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
|
||||
*/
|
||||
SECStatus
|
||||
secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded)
|
||||
secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
|
||||
PRBool* alreadyLoaded)
|
||||
{
|
||||
CK_C_INITIALIZE_ARGS moduleArgs;
|
||||
CK_VOID_PTR pInitArgs;
|
||||
CK_RV crv;
|
||||
|
||||
if (reload) {
|
||||
*reload = NULL;
|
||||
}
|
||||
|
||||
if (!mod || !alreadyLoaded) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
|
@ -144,10 +250,36 @@ secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded)
|
|||
pInitArgs = &moduleArgs;
|
||||
}
|
||||
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
|
||||
if ((CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) &&
|
||||
(!enforceAlreadyInitializedError)) {
|
||||
*alreadyLoaded = PR_TRUE;
|
||||
return SECSuccess;
|
||||
if (CKR_CRYPTOKI_ALREADY_INITIALIZED == crv) {
|
||||
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;
|
||||
return SECSuccess;
|
||||
}
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
if (pInitArgs == NULL ||
|
||||
|
@ -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;
|
||||
static const char* softoken_default_name =
|
||||
static const char* softoken_shlib_name =
|
||||
SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
|
||||
static const PRCallOnceType pristineCallOnce;
|
||||
static PRCallOnceType loadSoftokenOnce;
|
||||
|
@ -231,22 +363,16 @@ static PRInt32 softokenLoadCount;
|
|||
#include <stdio.h>
|
||||
#include "prsystem.h"
|
||||
|
||||
#include "../freebl/genload.c"
|
||||
|
||||
/* This function must be run only once. */
|
||||
/* determine if hybrid platform, then actually load the DSO. */
|
||||
static PRStatus
|
||||
softoken_LoadDSO( void )
|
||||
{
|
||||
PRLibrary * handle;
|
||||
const char * name = softoken_default_name;
|
||||
|
||||
if (!name) {
|
||||
PR_SetError(PR_LOAD_LIBRARY_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
}
|
||||
|
||||
handle = loader_LoadLibrary(name);
|
||||
handle = PORT_LoadLibraryFromOrigin(my_shlib_name,
|
||||
(PRFuncPtr) &softoken_LoadDSO,
|
||||
softoken_shlib_name);
|
||||
if (handle) {
|
||||
softokenLib = handle;
|
||||
return PR_SUCCESS;
|
||||
|
@ -258,7 +384,7 @@ softoken_LoadDSO( void )
|
|||
* load a new module into our address space and initialize it.
|
||||
*/
|
||||
SECStatus
|
||||
SECMOD_LoadPKCS11Module(SECMODModule *mod) {
|
||||
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule) {
|
||||
PRLibrary *library = NULL;
|
||||
CK_C_GetFunctionList entry = NULL;
|
||||
char * full_name;
|
||||
|
@ -271,7 +397,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
|
|||
if (mod->loaded) return SECSuccess;
|
||||
|
||||
/* intenal modules get loaded from their internal list */
|
||||
if (mod->internal) {
|
||||
if (mod->internal && (mod->dllName == NULL)) {
|
||||
/*
|
||||
* Loads softoken as a dynamic library,
|
||||
* even though the rest of NSS assumes this as the "internal" module.
|
||||
|
@ -308,26 +434,14 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
|
|||
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);
|
||||
#endif
|
||||
|
||||
/* load the library. If this succeeds, then we have to remember to
|
||||
* unload the library if anything goes wrong from here on out...
|
||||
*/
|
||||
library = PR_LoadLibrary(full_name);
|
||||
mod->library = (void *)library;
|
||||
#ifdef notdef
|
||||
PR_FreeLibraryName(full_name);
|
||||
#else
|
||||
PORT_Free(full_name);
|
||||
#endif
|
||||
|
||||
if (library == NULL) {
|
||||
return SECFailure;
|
||||
|
@ -375,11 +489,18 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
|
|||
mod->isThreadSafe = PR_TRUE;
|
||||
|
||||
/* Now we initialize the module */
|
||||
rv = secmod_ModuleInit(mod, &alreadyLoaded);
|
||||
rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
|
||||
if (rv != SECSuccess) {
|
||||
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 */
|
||||
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK) goto fail2;
|
||||
if (info.cryptokiVersion.major != 2) goto fail2;
|
||||
|
@ -460,7 +581,9 @@ SECMOD_UnloadModule(SECMODModule *mod) {
|
|||
return SECFailure;
|
||||
}
|
||||
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->loaded = PR_FALSE;
|
||||
|
|
|
@ -681,7 +681,6 @@ pk11_IncrementNickname(char *nickname)
|
|||
{
|
||||
char *newNickname = NULL;
|
||||
int end;
|
||||
PRBool needCarry;
|
||||
int digit;
|
||||
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
|
||||
*/
|
||||
|
@ -137,15 +189,42 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
|
|||
if (slotParams) PORT_Free(slotParams);
|
||||
/* new field */
|
||||
mod->trustOrder = secmod_argReadLong("trustOrder",nssc,
|
||||
SECMOD_DEFAULT_TRUST_ORDER,NULL);
|
||||
SECMOD_DEFAULT_TRUST_ORDER,NULL);
|
||||
/* new field */
|
||||
mod->cipherOrder = secmod_argReadLong("cipherOrder",nssc,
|
||||
SECMOD_DEFAULT_CIPHER_ORDER,NULL);
|
||||
SECMOD_DEFAULT_CIPHER_ORDER,NULL);
|
||||
/* new field */
|
||||
mod->isModuleDB = secmod_argHasFlag("flags","moduleDB",nssc);
|
||||
mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc);
|
||||
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);
|
||||
secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers);
|
||||
if (ciphers) PORT_Free(ciphers);
|
||||
|
@ -155,6 +234,708 @@ SECMOD_CreateModule(const char *library, const char *moduleName,
|
|||
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 *
|
||||
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;
|
||||
SECStatus status;
|
||||
SECMODModule *module = NULL;
|
||||
SECMODModule *oldModule = NULL;
|
||||
SECStatus rv;
|
||||
|
||||
/* initialize the underlying module structures */
|
||||
|
@ -317,14 +1099,26 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
|
|||
}
|
||||
if (parent) {
|
||||
module->parent = SECMOD_ReferenceModule(parent);
|
||||
if (module->internal && secmod_IsInternalKeySlot(parent)) {
|
||||
module->internal = parent->internal;
|
||||
}
|
||||
}
|
||||
|
||||
/* load it */
|
||||
rv = SECMOD_LoadPKCS11Module(module);
|
||||
rv = secmod_LoadPKCS11Module(module, &oldModule);
|
||||
if (rv != SECSuccess) {
|
||||
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) {
|
||||
char ** moduleSpecList;
|
||||
PORT_SetError(0);
|
||||
|
@ -333,7 +1127,12 @@ SECMOD_LoadModule(char *modulespec,SECMODModule *parent, PRBool recurse)
|
|||
if (moduleSpecList) {
|
||||
char **index;
|
||||
|
||||
for (index = moduleSpecList; *index; index++) {
|
||||
index = moduleSpecList;
|
||||
if (*index && SECMOD_GetSkipFirstFlag(module)) {
|
||||
index++;
|
||||
}
|
||||
|
||||
for (; *index; index++) {
|
||||
SECMODModule *child;
|
||||
child = SECMOD_LoadModule(*index,module,PR_TRUE);
|
||||
if (!child) break;
|
||||
|
|
|
@ -291,18 +291,12 @@ PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
|
|||
CK_ATTRIBUTE theTemplate[20];
|
||||
int templateCount = 0;
|
||||
SECStatus rv = SECFailure;
|
||||
PRArenaPool *arena;
|
||||
CK_ATTRIBUTE *attrs;
|
||||
CK_ATTRIBUTE *signedattr = NULL;
|
||||
int signedcount = 0;
|
||||
CK_ATTRIBUTE *ap;
|
||||
SECItem *ck_id = NULL;
|
||||
|
||||
arena = PORT_NewArena(2048);
|
||||
if(!arena) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
attrs = theTemplate;
|
||||
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ SECStatus PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts);
|
|||
void PK11_InitSlot(SECMODModule *mod,CK_SLOT_ID slotID,PK11SlotInfo *slot);
|
||||
PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot);
|
||||
SECStatus PK11_ReadSlotCerts(PK11SlotInfo *slot);
|
||||
void pk11_SetInternalKeySlot(PK11SlotInfo *slot);
|
||||
|
||||
/*********************************************************************
|
||||
* Mechanism Mapping functions
|
||||
|
|
|
@ -574,6 +574,10 @@ SECKEYPrivateKey *PK11_UnwrapPrivKey(PK11SlotInfo *slot,
|
|||
SECStatus PK11_WrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
|
||||
SECKEYPrivateKey *privKey, CK_MECHANISM_TYPE wrapType,
|
||||
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);
|
||||
PK11SymKey* PK11_CopySymKeyForSigning(PK11SymKey *originalKey,
|
||||
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
|
||||
* 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,
|
||||
CK_ATTRIBUTE_TYPE attr, SECItem *item);
|
||||
|
|
|
@ -1129,6 +1129,8 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
|
|||
PR_TRUE : PR_FALSE);
|
||||
slot->readOnly = ((tokenInfo.flags & CKF_WRITE_PROTECTED) ?
|
||||
PR_TRUE : PR_FALSE);
|
||||
|
||||
|
||||
slot->hasRandom = ((tokenInfo.flags & CKF_RNG) ? PR_TRUE : PR_FALSE);
|
||||
slot->protectedAuthPath =
|
||||
((tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH)
|
||||
|
@ -1248,7 +1250,33 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
|
|||
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;
|
||||
}
|
||||
|
@ -1697,12 +1725,29 @@ PK11_NeedUserInit(PK11SlotInfo *slot)
|
|||
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
|
||||
* default slots */
|
||||
PK11SlotInfo *
|
||||
PK11_GetInternalKeySlot(void)
|
||||
{
|
||||
SECMODModule *mod = SECMOD_GetInternalModule();
|
||||
SECMODModule *mod;
|
||||
|
||||
if (pk11InternalKeySlot) {
|
||||
return PK11_ReferenceSlot(pk11InternalKeySlot);
|
||||
}
|
||||
|
||||
mod = SECMOD_GetInternalModule();
|
||||
PORT_Assert(mod != NULL);
|
||||
if (!mod) {
|
||||
PORT_SetError( SEC_ERROR_NO_MODULE );
|
||||
|
@ -1721,6 +1766,9 @@ PK11_GetInternalSlot(void)
|
|||
PORT_SetError( SEC_ERROR_NO_MODULE );
|
||||
return NULL;
|
||||
}
|
||||
if (mod->isFIPS) {
|
||||
return PK11_GetInternalKeySlot();
|
||||
}
|
||||
return PK11_ReferenceSlot(mod->slots[0]);
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,10 @@ SECMOD_AddModuleToList(SECMODModule *newModule)
|
|||
SECStatus
|
||||
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);
|
||||
}
|
||||
return secmod_AddModuleToList(&modulesDB,newModule);
|
||||
|
@ -281,6 +284,34 @@ SECMOD_FindModuleByID(SECMODModuleID id)
|
|||
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.
|
||||
*/
|
||||
|
@ -505,7 +536,7 @@ SECMOD_AddModule(SECMODModule *newModule)
|
|||
/* module already exists. */
|
||||
}
|
||||
|
||||
rv = SECMOD_LoadPKCS11Module(newModule);
|
||||
rv = secmod_LoadPKCS11Module(newModule, NULL);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1199,7 +1230,7 @@ SECMOD_CancelWait(SECMODModule *mod)
|
|||
* we intend to use it again */
|
||||
if (CKR_OK == crv) {
|
||||
PRBool alreadyLoaded;
|
||||
secmod_ModuleInit(mod, &alreadyLoaded);
|
||||
secmod_ModuleInit(mod, NULL, &alreadyLoaded);
|
||||
} else {
|
||||
/* Finalized failed for some reason, notify the application
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
@ -1409,7 +1388,7 @@ SECMOD_OpenNewSlot(SECMODModule *mod, const char *moduleSpec)
|
|||
}
|
||||
|
||||
/* we've found the slot, now build the moduleSpec */
|
||||
escSpec = nss_doubleEscape(moduleSpec);
|
||||
escSpec = secmod_DoubleEscape(moduleSpec, '>', ']');
|
||||
if (escSpec == NULL) {
|
||||
PK11_FreeSlot(slot);
|
||||
return NULL;
|
||||
|
|
|
@ -151,6 +151,10 @@ extern PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,const char *name);
|
|||
/* of modType has been installed */
|
||||
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
|
||||
* of Mechanism Flags and Cipher Enable Flags */
|
||||
extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags);
|
||||
|
|
|
@ -58,7 +58,8 @@ void nss_DumpModuleLog(void);
|
|||
extern int secmod_PrivateModuleCount;
|
||||
|
||||
extern void SECMOD_Init(void);
|
||||
SECStatus secmod_ModuleInit(SECMODModule *mod, PRBool* alreadyLoaded);
|
||||
SECStatus secmod_ModuleInit(SECMODModule *mod, SECMODModule **oldModule,
|
||||
PRBool* alreadyLoaded);
|
||||
|
||||
/* list managment */
|
||||
extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);
|
||||
|
@ -73,6 +74,7 @@ extern void SECMOD_ReleaseWriteLock(SECMODListLock *);
|
|||
|
||||
/* Operate on modules by name */
|
||||
extern SECMODModule *SECMOD_FindModuleByID(SECMODModuleID);
|
||||
extern SECMODModule *secmod_FindModuleByFuncPtr(void *funcPtr);
|
||||
|
||||
/* database/memory management */
|
||||
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);
|
||||
|
||||
/* Library functions */
|
||||
SECStatus SECMOD_LoadPKCS11Module(SECMODModule *);
|
||||
SECStatus secmod_LoadPKCS11Module(SECMODModule *, SECMODModule **oldModule);
|
||||
SECStatus SECMOD_UnloadModule(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);
|
||||
CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event,
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
|
@ -101,6 +101,11 @@ STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot)
|
|||
NSSToken *token;
|
||||
if (!td) {
|
||||
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);
|
||||
PK11Slot_SetNSSToken(slot, token);
|
||||
|
@ -118,6 +123,11 @@ STAN_ResetTokenInterator(NSSTrustDomain *td)
|
|||
{
|
||||
if (!td) {
|
||||
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);
|
||||
nssListIterator_Destroy(td->tokens);
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS MY_FILEFLAGS_2
|
||||
FILEOS MY_FILEOS
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
* The format of the version string should be
|
||||
* "<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_VMINOR 12
|
||||
#define SOFTOKEN_VPATCH 4
|
||||
|
|
|
@ -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
|
||||
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_VERSION = 3
|
||||
MAPFILE = $(OBJDIR)/sqlite.def
|
||||
DEFINES += -DTHREADSAFE=1
|
||||
DEFINES += -DSQLITE_THREADSAFE=1
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
|
|
@ -18,7 +18,6 @@ LIBRARY sqlite3 ;-
|
|||
EXPORTS ;-
|
||||
sqlite3_aggregate_context;
|
||||
sqlite3_aggregate_count;
|
||||
sqlite3_apis;
|
||||
sqlite3_auto_extension;
|
||||
sqlite3_bind_blob;
|
||||
sqlite3_bind_double;
|
||||
|
@ -88,6 +87,7 @@ sqlite3_malloc;
|
|||
sqlite3_mprintf;
|
||||
sqlite3_open;
|
||||
sqlite3_open16;
|
||||
sqlite3_open_v2;
|
||||
sqlite3_overload_function;
|
||||
sqlite3_prepare;
|
||||
sqlite3_prepare16;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -71,6 +71,11 @@ CSRCS += unix_err.c
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_SYSTEM_ZLIB
|
||||
DEFINES += -DNSS_ENABLE_ZLIB
|
||||
EXTRA_LIBS += $(ZLIB_LIBS)
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
|
|
@ -43,6 +43,13 @@ ifdef NSS_SURVIVE_DOUBLE_BYPASS_FAILURE
|
|||
DEFINES += -DNSS_SURVIVE_DOUBLE_BYPASS_FAILURE
|
||||
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)))
|
||||
|
||||
# don't want the 32 in the shared library name
|
||||
|
@ -73,23 +80,8 @@ EXTRA_SHARED_LIBS += \
|
|||
$(NULL)
|
||||
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
|
||||
|
||||
# $(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)
|
||||
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
|
||||
EXTRA_SHARED_LIBS += \
|
||||
|
|
|
@ -139,3 +139,14 @@ SSL_CanBypass;
|
|||
;+ 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.
|
||||
*
|
||||
* ***** 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_
|
||||
#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_ENABLE_SESSION_TICKETS 18 /* Enable TLS SessionTicket */
|
||||
/* 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
|
||||
/* 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_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
|
||||
** 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);
|
||||
|
||||
|
||||
/*
|
||||
** 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.
|
||||
* fd - the file descriptor for the connection in question
|
||||
|
@ -269,7 +345,7 @@ SSL_IMPORT SECStatus SSL_BadCertHook(PRFileDesc *fd, SSLBadCertHandler f,
|
|||
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
|
||||
** are copied.
|
||||
*/
|
||||
|
@ -278,7 +354,7 @@ SSL_IMPORT SECStatus SSL_ConfigSecureServer(
|
|||
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
|
||||
** where the cache files will be placed. These values can be zero, and
|
||||
** if so, the implementation will choose defaults.
|
||||
|
@ -289,6 +365,18 @@ SSL_IMPORT SECStatus SSL_ConfigServerSessionIDCache(int maxCacheEntries,
|
|||
PRUint32 timeout,
|
||||
PRUint32 ssl3_timeout,
|
||||
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.
|
||||
** If the application will run multiple processes (as opposed to, or in
|
||||
|
@ -364,10 +452,16 @@ SSL_IMPORT SECStatus SSL_RedoHandshake(PRFileDesc *fd);
|
|||
#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);
|
||||
|
||||
/*
|
||||
* 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 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.
|
||||
** 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.
|
||||
|
@ -407,7 +501,6 @@ SSL_IMPORT CERTCertificate * SSL_RevealCert(PRFileDesc * socket);
|
|||
SSL_IMPORT void * SSL_RevealPinArg(PRFileDesc * socket);
|
||||
SSL_IMPORT char * SSL_RevealURL(PRFileDesc * socket);
|
||||
|
||||
|
||||
/* This callback may be passed to the SSL library via a call to
|
||||
* SSL_GetClientAuthDataHook() for each SSL client socket.
|
||||
* 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,
|
||||
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
|
||||
** 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,
|
||||
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
|
||||
|
||||
#endif /* __ssl_h_ */
|
||||
|
|
|
@ -71,8 +71,8 @@
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,0
|
||||
FILEVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
PRODUCTVERSION NSS_VMAJOR,NSS_VMINOR,NSS_VPATCH,NSS_VBUILD
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS MY_FILEFLAGS_2
|
||||
FILEOS MY_FILEOS
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -40,7 +40,7 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* 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 "cert.h"
|
||||
|
@ -1059,7 +1059,7 @@ ssl3_SendSupportedCurvesXtn(
|
|||
if (!ss->sec.isServer) {
|
||||
TLSExtensionData *xtnData = &ss->xtnData;
|
||||
xtnData->advertised[xtnData->numAdvertised++] =
|
||||
elliptic_curves_xtn;
|
||||
ssl_elliptic_curves_xtn;
|
||||
}
|
||||
}
|
||||
return (sizeof EClist);
|
||||
|
@ -1083,7 +1083,7 @@ ssl3_SendSupportedPointFormatsXtn(
|
|||
if (!ss->sec.isServer) {
|
||||
TLSExtensionData *xtnData = &ss->xtnData;
|
||||
xtnData->advertised[xtnData->numAdvertised++] =
|
||||
ec_point_formats_xtn;
|
||||
ssl_ec_point_formats_xtn;
|
||||
}
|
||||
}
|
||||
return (sizeof ECPtFmt);
|
||||
|
|
|
@ -41,11 +41,12 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* 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 "nss.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
#include "sslimpl.h"
|
||||
#include "pk11pub.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 PRCallOnceType generate_session_keys_once;
|
||||
|
||||
static PRInt32 ssl3_SendServerNameXtn(sslSocket * ss,
|
||||
PRBool append, PRUint32 maxBytes);
|
||||
/* forward static function declarations */
|
||||
static SECStatus ssl3_ParseEncryptedSessionTicket(sslSocket *ss,
|
||||
SECItem *data, EncryptedSessionTicket *enc_session_ticket);
|
||||
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,
|
||||
PRUint32 *aes_key_length, const unsigned char **mac_key,
|
||||
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
|
||||
|
@ -222,39 +226,55 @@ ssl3_GetSessionTicketKeys(const unsigned char **aes_key,
|
|||
* In the second generation, this table will be dynamic, and functions
|
||||
* will be registered here.
|
||||
*/
|
||||
/* This table is used by the server, to handle client hello extensions. */
|
||||
static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
||||
{ server_name_xtn, &ssl3_HandleServerNameXtn },
|
||||
{ ssl_server_name_xtn, &ssl3_HandleServerNameXtn },
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
{ elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
|
||||
{ ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
|
||||
{ ssl_elliptic_curves_xtn, &ssl3_HandleSupportedCurvesXtn },
|
||||
{ ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn },
|
||||
#endif
|
||||
{ session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
||||
{ ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
||||
{ ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static const ssl3HelloExtensionHandler serverHelloHandlers[] = {
|
||||
{ server_name_xtn, &ssl3_HandleServerNameXtn },
|
||||
/* TODO: add a handler for ec_point_formats_xtn */
|
||||
{ session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
||||
/* These two tables are used by the client, to handle server hello
|
||||
* extensions. */
|
||||
static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
|
||||
{ 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 }
|
||||
};
|
||||
|
||||
/* Table of functions to format TLS hello extensions, one per extension.
|
||||
* This static table is for the formatting of client hello extensions.
|
||||
static const ssl3HelloExtensionHandler serverHelloHandlersSSL3[] = {
|
||||
{ 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,
|
||||
* and sender functions are registered there.
|
||||
*/
|
||||
static const
|
||||
ssl3HelloExtensionSender clientHelloSenders[MAX_EXTENSIONS] = {
|
||||
{ server_name_xtn, &ssl3_SendServerNameXtn },
|
||||
ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
|
||||
{ ssl_server_name_xtn, &ssl3_SendServerNameXtn },
|
||||
{ ssl_renegotiation_info_xtn, &ssl3_SendRenegotiationInfoXtn },
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
{ elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
||||
{ ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
||||
#else
|
||||
{ -1, NULL },
|
||||
{ -1, NULL },
|
||||
{ ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
||||
{ ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
||||
#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
|
||||
|
@ -284,60 +304,159 @@ ssl3_ClientExtensionAdvertised(sslSocket *ss, PRUint16 ex_type) {
|
|||
|
||||
/* Format an SNI extension, using the name from the socket's URL,
|
||||
* unless that name is a dotted decimal string.
|
||||
* Used by client and server.
|
||||
*/
|
||||
static PRInt32
|
||||
ssl3_SendServerNameXtn(
|
||||
sslSocket * ss,
|
||||
PRBool append,
|
||||
PRUint32 maxBytes)
|
||||
PRInt32
|
||||
ssl3_SendServerNameXtn(sslSocket * ss, PRBool append,
|
||||
PRUint32 maxBytes)
|
||||
{
|
||||
PRUint32 len;
|
||||
PRNetAddr netAddr;
|
||||
|
||||
/* must have a hostname */
|
||||
if (!ss || !ss->url || !ss->url[0])
|
||||
return 0;
|
||||
/* must not be an IPv4 or IPv6 address */
|
||||
if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
|
||||
/* is an IP address (v4 or v6) */
|
||||
return 0;
|
||||
SECStatus rv;
|
||||
if (!ss->sec.isServer) {
|
||||
PRUint32 len;
|
||||
PRNetAddr netAddr;
|
||||
|
||||
/* must have a hostname */
|
||||
if (!ss || !ss->url || !ss->url[0])
|
||||
return 0;
|
||||
/* must not be an IPv4 or IPv6 address */
|
||||
if (PR_SUCCESS == PR_StringToNetAddr(ss->url, &netAddr)) {
|
||||
/* is an IP address (v4 or v6) */
|
||||
return 0;
|
||||
}
|
||||
len = PORT_Strlen(ss->url);
|
||||
if (append && maxBytes >= len + 9) {
|
||||
/* extension_type */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ssl_server_name_xtn, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* length of extension_data */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* length of server_name_list */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* Name Type (sni_host_name) */
|
||||
rv = ssl3_AppendHandshake(ss, "\0", 1);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* HostName (length and value) */
|
||||
rv = ssl3_AppendHandshakeVariable(ss, (PRUint8 *)ss->url, len, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
if (!ss->sec.isServer) {
|
||||
TLSExtensionData *xtnData = &ss->xtnData;
|
||||
xtnData->advertised[xtnData->numAdvertised++] =
|
||||
ssl_server_name_xtn;
|
||||
}
|
||||
}
|
||||
return len + 9;
|
||||
}
|
||||
len = PORT_Strlen(ss->url);
|
||||
if (append && maxBytes >= len + 9) {
|
||||
SECStatus rv;
|
||||
/* extension_type */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, server_name_xtn, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* length of extension_data */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, len + 5, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* length of server_name_list */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, len + 3, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* Name Type (host_name) */
|
||||
rv = ssl3_AppendHandshake(ss, "\0", 1);
|
||||
if (rv != SECSuccess) return -1;
|
||||
/* HostName (length and value) */
|
||||
rv = ssl3_AppendHandshakeVariable(ss, (unsigned char *)ss->url, len, 2);
|
||||
if (rv != SECSuccess) return -1;
|
||||
if (!ss->sec.isServer) {
|
||||
TLSExtensionData *xtnData = &ss->xtnData;
|
||||
xtnData->advertised[xtnData->numAdvertised++] = server_name_xtn;
|
||||
}
|
||||
/* 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 len + 9;
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* handle an incoming SNI extension, by ignoring it. */
|
||||
SECStatus
|
||||
ssl3_HandleServerNameXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
||||
{
|
||||
/* TODO: if client, should verify extension_data is empty. */
|
||||
/* TODO: if server, should send empty extension_data. */
|
||||
/* For now, we ignore this, as if we didn't understand it. :-) */
|
||||
return SECSuccess;
|
||||
}
|
||||
SECItem *names = NULL;
|
||||
PRUint32 listCount = 0, namesPos = 0, i;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
* Clients sends a filled in session ticket if one is available, and otherwise
|
||||
* sends an empty ticket. Servers always send empty tickets.
|
||||
|
@ -383,7 +502,7 @@ ssl3_SendSessionTicketXtn(
|
|||
if (append && maxBytes >= extension_length) {
|
||||
SECStatus rv;
|
||||
/* extension_type */
|
||||
rv = ssl3_AppendHandshakeNumber(ss, session_ticket_xtn, 2);
|
||||
rv = ssl3_AppendHandshakeNumber(ss, ssl_session_ticket_xtn, 2);
|
||||
if (rv != SECSuccess)
|
||||
goto loser;
|
||||
if (session_ticket && session_ticket->ticket.data &&
|
||||
|
@ -399,7 +518,8 @@ ssl3_SendSessionTicketXtn(
|
|||
|
||||
if (!ss->sec.isServer) {
|
||||
TLSExtensionData *xtnData = &ss->xtnData;
|
||||
xtnData->advertised[xtnData->numAdvertised++] = session_ticket_xtn;
|
||||
xtnData->advertised[xtnData->numAdvertised++] =
|
||||
ssl_session_ticket_xtn;
|
||||
}
|
||||
} else if (maxBytes < extension_length) {
|
||||
PORT_Assert(0);
|
||||
|
@ -454,6 +574,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
unsigned int computed_mac_length;
|
||||
unsigned char iv[AES_BLOCK_SIZE];
|
||||
SECItem ivItem;
|
||||
SECItem *srvName = NULL;
|
||||
PRUint32 srvNameLen = 0;
|
||||
CK_MECHANISM_TYPE msWrapMech = 0; /* dummy default value,
|
||||
* must be >= 0 */
|
||||
|
||||
|
@ -514,6 +636,11 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
}
|
||||
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 =
|
||||
sizeof(PRUint16) /* ticket_version */
|
||||
|
@ -528,6 +655,8 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
+ ms_item.len /* master_secret */
|
||||
+ 1 /* client_auth_type */
|
||||
+ cert_length /* cert */
|
||||
+ 1 /* server name type */
|
||||
+ srvNameLen /* name len + length field */
|
||||
+ sizeof(ticket.ticket_lifetime_hint);
|
||||
padding_length = AES_BLOCK_SIZE -
|
||||
(ciphertext_length % AES_BLOCK_SIZE);
|
||||
|
@ -610,6 +739,22 @@ ssl3_SendNewSessionTicket(sslSocket *ss)
|
|||
sizeof(ticket.ticket_lifetime_hint));
|
||||
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);
|
||||
for (i = 0; i < padding_length; i++)
|
||||
plaintext.data[i] = (unsigned char)padding_length;
|
||||
|
@ -782,6 +927,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
unsigned int buffer_len;
|
||||
PRInt32 temp;
|
||||
SECItem cert_item;
|
||||
PRInt8 nameType = TLS_STE_NO_SERVER_NAME;
|
||||
|
||||
/* Turn off stateless session resumption if the client sends a
|
||||
* SessionTicket extension, even if the extension turns out to be
|
||||
|
@ -867,7 +1013,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
if (rv != SECSuccess)
|
||||
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) {
|
||||
SSL_DBG(("%d: SSL[%d]: Session ticket MAC mismatch.",
|
||||
SSL_GETPID(), ss->fd));
|
||||
|
@ -963,7 +1109,7 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
/* Read compression_method. */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
||||
if (temp < 0) goto no_ticket;
|
||||
parsed_session_ticket->compression_method = (SSL3CompressionMethod)temp;
|
||||
parsed_session_ticket->compression_method = (SSLCompressionMethod)temp;
|
||||
|
||||
/* Read cipher spec parameters. */
|
||||
temp = ssl3_ConsumeHandshakeNumber(ss, 1, &buffer, &buffer_len);
|
||||
|
@ -1034,6 +1180,20 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
goto no_ticket;
|
||||
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. */
|
||||
if (buffer_len != padding_length)
|
||||
goto no_ticket;
|
||||
|
@ -1090,6 +1250,9 @@ ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type,
|
|||
goto loser;
|
||||
}
|
||||
}
|
||||
if (parsed_session_ticket->srvName.data != NULL) {
|
||||
sid->u.ssl3.srvName = parsed_session_ticket->srvName;
|
||||
}
|
||||
ss->statelessResume = PR_TRUE;
|
||||
ss->sec.ci.sid = sid;
|
||||
}
|
||||
|
@ -1172,8 +1335,15 @@ ssl3_ParseEncryptedSessionTicket(sslSocket *ss, SECItem *data,
|
|||
SECStatus
|
||||
ssl3_HandleHelloExtensions(sslSocket *ss, SSL3Opaque **b, PRUint32 *length)
|
||||
{
|
||||
const ssl3HelloExtensionHandler * handlers =
|
||||
ss->sec.isServer ? clientHelloHandlers : serverHelloHandlers;
|
||||
const ssl3HelloExtensionHandler * handlers;
|
||||
|
||||
if (ss->sec.isServer) {
|
||||
handlers = clientHelloHandlers;
|
||||
} else if (ss->version > SSL_LIBRARY_VERSION_3_0) {
|
||||
handlers = serverHelloHandlersTLS;
|
||||
} else {
|
||||
handlers = serverHelloHandlersSSL3;
|
||||
}
|
||||
|
||||
while (*length) {
|
||||
const ssl3HelloExtensionHandler * handler;
|
||||
|
@ -1226,7 +1396,7 @@ ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
|
|||
int i;
|
||||
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) {
|
||||
sender->ex_type = ex_type;
|
||||
sender->ex_sender = cb;
|
||||
|
@ -1239,7 +1409,7 @@ ssl3_RegisterServerHelloExtensionSender(sslSocket *ss, PRUint16 ex_type,
|
|||
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);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -1252,10 +1422,12 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
|
|||
PRInt32 total_exten_len = 0;
|
||||
int i;
|
||||
|
||||
if (!sender)
|
||||
sender = &clientHelloSenders[0];
|
||||
if (!sender) {
|
||||
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) {
|
||||
PRInt32 extLen = (*sender->ex_sender)(ss, append, maxBytes);
|
||||
if (extLen < 0)
|
||||
|
@ -1266,3 +1438,82 @@ ssl3_CallHelloExtensionSenders(sslSocket *ss, PRBool append, PRUint32 maxBytes,
|
|||
}
|
||||
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.
|
||||
*
|
||||
* ***** 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_
|
||||
#define __ssl3proto_h_
|
||||
|
@ -173,15 +173,13 @@ typedef struct {
|
|||
uint8 length;
|
||||
} SSL3SessionID;
|
||||
|
||||
typedef enum { compression_null = 0 } SSL3CompressionMethod;
|
||||
|
||||
typedef struct {
|
||||
SSL3ProtocolVersion client_version;
|
||||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
SECItem cipher_suites;
|
||||
uint8 cm_count;
|
||||
SSL3CompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
|
||||
SSLCompressionMethod compression_methods[MAX_COMPRESSION_METHODS];
|
||||
} SSL3ClientHello;
|
||||
|
||||
typedef struct {
|
||||
|
@ -189,7 +187,7 @@ typedef struct {
|
|||
SSL3Random random;
|
||||
SSL3SessionID session_id;
|
||||
ssl3CipherSuite cipher_suite;
|
||||
SSL3CompressionMethod compression_method;
|
||||
SSLCompressionMethod compression_method;
|
||||
} SSL3ServerHello;
|
||||
|
||||
typedef struct {
|
||||
|
@ -345,19 +343,8 @@ typedef struct {
|
|||
unsigned char *mac;
|
||||
} 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_STE_NO_SERVER_NAME -1
|
||||
|
||||
#endif /* __ssl3proto_h_ */
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** 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 "cert.h"
|
||||
|
@ -2731,7 +2731,8 @@ ssl2_HandleVerifyMessage(sslSocket *ss)
|
|||
DUMP_MSG(29, (ss, data, ss->gs.recordLen));
|
||||
if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
|
||||
(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 */
|
||||
PORT_SetError(SSL_ERROR_BAD_SERVER);
|
||||
goto loser;
|
||||
|
@ -3006,6 +3007,7 @@ ssl2_BeginClientHandshake(sslSocket *ss)
|
|||
unsigned int i;
|
||||
int sendLen, sidLen = 0;
|
||||
SECStatus rv;
|
||||
TLSExtensionData *xtnData;
|
||||
|
||||
PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
|
||||
|
||||
|
@ -3150,7 +3152,8 @@ ssl2_BeginClientHandshake(sslSocket *ss)
|
|||
localCipherSpecs = ss->cipherSpecs;
|
||||
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;
|
||||
|
||||
/* Generate challenge bytes for server */
|
||||
|
@ -3175,8 +3178,9 @@ ssl2_BeginClientHandshake(sslSocket *ss)
|
|||
|
||||
msg[1] = MSB(ss->clientHelloVersion);
|
||||
msg[2] = LSB(ss->clientHelloVersion);
|
||||
msg[3] = MSB(localCipherSize);
|
||||
msg[4] = LSB(localCipherSize);
|
||||
/* Add 3 for SCSV */
|
||||
msg[3] = MSB(localCipherSize + 3);
|
||||
msg[4] = LSB(localCipherSize + 3);
|
||||
msg[5] = MSB(sidLen);
|
||||
msg[6] = LSB(sidLen);
|
||||
msg[7] = MSB(SSL_CHALLENGE_BYTES);
|
||||
|
@ -3184,6 +3188,16 @@ ssl2_BeginClientHandshake(sslSocket *ss)
|
|||
cp += SSL_HL_CLIENT_HELLO_HBYTES;
|
||||
PORT_Memcpy(cp, localCipherSpecs, 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) {
|
||||
PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
|
||||
cp += sidLen;
|
||||
|
@ -3206,6 +3220,14 @@ ssl2_BeginClientHandshake(sslSocket *ss)
|
|||
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 */
|
||||
ssl_GetRecvBufLock(ss);
|
||||
ss->gs.recordLen = 0;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** 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_
|
||||
#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_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. */
|
||||
} SSLErrorCodes;
|
||||
#endif /* NO_SECURITY_ERROR_ENUM */
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче