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:
Kai Engert 2010-02-07 12:54:28 +01:00
Родитель 25809b66dc
Коммит aad067a3a5
227 изменённых файлов: 91953 добавлений и 34207 удалений

Просмотреть файл

@ -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);
}

163
security/nss/coverage/cov.sh Executable file
Просмотреть файл

@ -0,0 +1,163 @@
#!/bin/bash
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Network Security Services
#
# The Initial Developer of the Original Code is Sun Microsystems, Inc.
# Portions created by the Initial Developer are Copyright (C) 2007-2009
# Sun Microsystems, Inc. All Rights Reserved.
#
# Contributor(s):
# Slavomir Katuscak <slavomir.katuscak@sun.com>, Sun Microsystems, Inc.
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
OS=`uname -s`
ARCH=`uname -p`
SCRIPT_DIR=`pwd`
DATE=`date +%Y%m%d`
if [ $# -ne 1 ]; then
echo "Usage: $0 [securitytip|securityjes5]"
exit 1
fi
BRANCH="$1"
if [ "${BRANCH}" != "securitytip" -a "${BRANCH}" != "securityjes5" ]; then
echo "Usage: $0 [securitytip|securityjes5]"
exit 1
fi
COV_DIR="/share/builds/mccrel3/security/coverage"
BRANCH_DIR="${COV_DIR}/${BRANCH}"
DATE_DIR="${BRANCH_DIR}/${DATE}-${ARCH}"
CVS_DIR="${DATE_DIR}/cvs_mozilla"
TCOV_DIR="${DATE_DIR}/tcov_mozilla"
CVS_CHECKOUT_BRANCH="cvs_checkout_${BRANCH}"
export HOST=`hostname`
export DOMSUF=red.iplanet.com
export NSS_ENABLE_ECC=1
export NSS_ECC_MORE_THAN_SUITE_B=1
export IOPR_HOSTADDR_LIST="dochinups.red.iplanet.com"
export NSS_AIA_PATH="/share/builds/mccrel3/security/aia_certs"
export NSS_AIA_HTTP="http://cindercone.red.iplanet.com/share/builds/mccrel3/security/aia_certs"
export USE_TCOV=1
export SUN_PROFDATA_DIR="${DATE_DIR}"
export SUN_PROFDATA="tcov_data"
if [ "${OS}" != "SunOS" ]; then
echo "OS not supported"
exit 1
fi
case "${ARCH}" in
"sparc")
export PATH="/usr/dist/share/sunstudio_sparc,v12.0/SUNWspro/prod/bin:/usr/sfw/bin:/usr/bin:/usr/ccs/bin:/usr/ucb:/tools/ns/bin:/usr/local/bin"
;;
"i386")
export PATH="/usr/dist/share/sunstudio_i386,v12.0/SUNWspro/bin:/usr/sfw/bin:/usr/bin:/usr/ccs/bin:/usr/ucb:/tools/ns/bin:/usr/local/bin"
;;
*)
echo "Platform not supported"
exit 1
;;
esac
cvs_checkout_securitytip()
{
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/nsprpub
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/dbm
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/dbm
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/coreconf
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/nss
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A mozilla/security/jss
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_1_RTM mozilla/security/nss/lib/freebl/ecl/ecl-curve.h
}
cvs_checkout_securityjes5()
{
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSPR_4_6_BRANCH mozilla/nsprpub
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/dbm
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/dbm
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/coreconf
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_BRANCH mozilla/security/nss
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r JSS_4_2_BRANCH mozilla/security/jss
cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co -A -r NSS_3_11_1_RTM mozilla/security/nss/lib/freebl/ecl/ecl-curve.h
}
cvs_checkout()
{
rm -rf "${DATE_DIR}"
mkdir -p "${CVS_DIR}"
cd "${CVS_DIR}"
${CVS_CHECKOUT_BRANCH}
}
run_build()
{
cd "${CVS_DIR}/mozilla/security/nss"
gmake nss_build_all
}
run_tests()
{
cd "${CVS_DIR}/mozilla/security/nss/tests"
./all.sh
}
process_results()
{
rm -rf "${TCOV_DIR}"
mkdir -p "${TCOV_DIR}"
cat "${SUN_PROFDATA_DIR}/${SUN_PROFDATA}/tcovd" | grep SRCFILE | grep "${CVS_DIR}/.*.c$" | sed "s:[^/]*\(.*\):\1:" | sort -u |
while read line
do
DIR=`echo "${line}" | sed "s:${CVS_DIR}/\(.*\)/.*:\1:"`
FILE=`echo "${line}" | sed "s:.*/\(.*\):\1:"`
mkdir -p "${TCOV_DIR}/${DIR}"
tcov -o "${TCOV_DIR}/${DIR}/$FILE" -x "${SUN_PROFDATA}" $line >/dev/null 2>&1
done
}
cvs_checkout
run_build
run_tests
process_results
cd "${SCRIPT_DIR}"
./report.sh "${BRANCH}" "${DATE}" "${ARCH}"
exit 0

238
security/nss/coverage/report.sh Executable file
Просмотреть файл

@ -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 */

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше