summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdownload.lst2
-rw-r--r--external/nss/ExternalPackage_nss.mk17
-rw-r--r--external/nss/ExternalProject_nss.mk2
-rw-r--r--external/nss/Module_nss.mk2
-rw-r--r--external/nss/README64
-rw-r--r--external/nss/UnpackedTarball_nss.mk12
-rw-r--r--external/nss/asan.patch.112
-rw-r--r--external/nss/clang-cl.patch.074
-rw-r--r--external/nss/nss-pem.patch6376
-rw-r--r--external/nss/nss-winXP-sdk.patch.15
-rw-r--r--[-rwxr-xr-x]external/nss/nss.cygwin64.in32bit.patch0
-rw-r--r--external/nss/nss.nowerror.patch8
-rw-r--r--external/nss/nss.patch26
-rw-r--r--external/nss/nss.utf8bom.patch.130
-rw-r--r--[-rwxr-xr-x]external/nss/nss.vs2015.patch0
-rw-r--r--[-rwxr-xr-x]external/nss/nss.vs2015.pdb.patch0
-rw-r--r--external/nss/nss.windowbuild.patch.055
-rw-r--r--external/nss/nss.windows.patch6
-rw-r--r--external/nss/nss_macosx.patch10
-rw-r--r--external/nss/ubsan-alignment.patch.040
-rw-r--r--external/nss/ubsan.patch.034
21 files changed, 278 insertions, 6497 deletions
diff --git a/download.lst b/download.lst
index 882cc98ed477..53fc12297f5b 100755
--- a/download.lst
+++ b/download.lst
@@ -107,7 +107,7 @@ export MWAW_TARBALL := libmwaw-0.3.$(MWAW_VERSION_MICRO).tar.bz2
export MYSQLCPPCONN_TARBALL := 7239a4430efd4d0189c4f24df67f08e5-mysql-connector-c++-1.1.4.tar.gz
export MYTHES_TARBALL := a8c2c5b8f09e7ede322d5c602ff6a4b6-mythes-1.2.4.tar.gz
export NEON_TARBALL := 231adebe5c2f78fded3e3df6e958878e-neon-0.30.1.tar.gz
-export NSS_TARBALL := 6b254cf2f8cb4b27a3f0b8b7b9966ea7-nss-3.22.2-with-nspr-4.12.tar.gz
+export NSS_TARBALL := 0e3eee39402386cf16fd7aaa7399ebef-nss-3.27-with-nspr-4.13.tar.gz
export ODFGEN_MD5SUM := 32572ea48d9021bbd6fa317ddb697abc
export ODFGEN_VERSION_MICRO := 6
export ODFGEN_TARBALL := libodfgen-0.1.$(ODFGEN_VERSION_MICRO).tar.bz2
diff --git a/external/nss/ExternalPackage_nss.mk b/external/nss/ExternalPackage_nss.mk
index c6d8953fd23b..6d568b7edfee 100644
--- a/external/nss/ExternalPackage_nss.mk
+++ b/external/nss/ExternalPackage_nss.mk
@@ -58,23 +58,10 @@ $(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
dist/out/lib/libsqlite3.so \
))
endif
-
-ifeq ($(SYSTEM_CURL),)
-ifeq ($(OS),IOS)
-# nothing
-else ifeq ($(OS),MACOSX)
-$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
- dist/out/lib/libnsspem.dylib \
-))
-else ifeq ($(OS),WNT)
+ifeq ($(OS),LINUX)
$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
- dist/out/lib/nsspem.dll \
+ dist/out/lib/libfreeblpriv3.so \
))
-else # OS!=WNT/MACOSX
-$(eval $(call gb_ExternalPackage_add_files,nss,$(LIBO_LIB_FOLDER),\
- dist/out/lib/libnsspem.so \
-))
-endif
endif
# vim: set noet sw=4 ts=4:
diff --git a/external/nss/ExternalProject_nss.mk b/external/nss/ExternalProject_nss.mk
index bd649716a6c1..07cc472b9fb2 100644
--- a/external/nss/ExternalProject_nss.mk
+++ b/external/nss/ExternalProject_nss.mk
@@ -67,6 +67,7 @@ $(call gb_ExternalProject_get_state_target,nss,build): $(call gb_ExternalProject
$(if $(filter MACOSX,$(OS)),\
$(if $(filter-out POWERPC,$(CPUNAME)),MACOS_SDK_DIR=$(MACOSX_SDK_PATH)) \
NSS_USE_SYSTEM_SQLITE=1) \
+ $(if $(filter LINUX,$(OS)),$(if $(ENABLE_DBGUTIL),,BUILD_OPT=1)) \
$(if $(filter SOLARIS,$(OS)),NS_USE_GCC=1) \
$(if $(CROSS_COMPILING),\
$(if $(filter MACOSXPOWERPC,$(OS)$(CPUNAME)),CPU_ARCH=ppc) \
@@ -88,7 +89,6 @@ $(call gb_ExternalProject_get_state_target,nss,build): $(call gb_ExternalProject
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libnss3.dylib \
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libnssckbi.dylib \
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libnssdbm3.dylib \
- $(gb_Package_SOURCEDIR_nss)/dist/out/lib/libnsspem.dylib \
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libnssutil3.dylib \
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libplc4.dylib \
$(gb_Package_SOURCEDIR_nss)/dist/out/lib/libplds4.dylib \
diff --git a/external/nss/Module_nss.mk b/external/nss/Module_nss.mk
index c1e1ab2bc074..69b39f59ee5d 100644
--- a/external/nss/Module_nss.mk
+++ b/external/nss/Module_nss.mk
@@ -9,7 +9,6 @@
$(eval $(call gb_Module_Module,nss))
-ifeq ($(SYSTEM_NSS),)
ifeq ($(filter ANDROID,$(OS)),)
$(eval $(call gb_Module_add_targets,nss,\
UnpackedTarball_nss \
@@ -17,6 +16,5 @@ $(eval $(call gb_Module_add_targets,nss,\
ExternalProject_nss \
))
endif
-endif
# vim: set noet sw=4 ts=4:
diff --git a/external/nss/README b/external/nss/README
index 0c5adf808ce4..d4fbd68bd193 100644
--- a/external/nss/README
+++ b/external/nss/README
@@ -1,32 +1,9 @@
-Contains the security libraries which are also part of [[moz]]. However nss is meant to be more current.
-
-== Relation between nss, moz, moz_prebuilt ==
-
-nss contains the security libraries which are also part of moz. However nss is
-meant to be more current, that is it to be updated more often. This should be
-easier than doing this with moz.
-
-If nss is built depends on an environment variable (SYSTEM_NSS=NO) which
-is per default set to YES. In this case nss is build before moz. The nss
-libraries/lib files/headers built in moz are then not delivered. Otherwise they
-would overwrite those from nss. That is, the nss libraries build in moz are
-removed from mozruntime.zip (build in moz/solver/bin), they are removed from the
-lib directory (for example moz/unxlngi6.pro/lib), and the nss and nspr headers
-are also removed (inc/nss and inc/nspr). The nss libraries from the nss module
-are then added to mozruntime.zip.
-
-This also applies for moz_prebuilt. Therefore moz and moz_prebuilt must be build
-again after changes have been made to the libraries in the nss module.
-
-Also when moz was updated to use a newer version of mozilla, then one must make
-sure that new files which also belong to nss are not delivered and are removed
-from mozruntime.zip.
-
+Contains the Network Security Services (NSS) libraries from Mozilla
== Fips 140 and signed libraries ==
Fips 140 mode is not supported. That is, the *.chk files containing the
-checksums for the cryptographic module are not delivered into solver and will
+checksums for the cryptographic module are not delivered into instdir and will
not be part of the OOo installation sets.
Signing has been turned off because
@@ -34,48 +11,15 @@ Signing has been turned off because
(Mac)
- sqlite conflicts with the system sqlite when signing which breaks the build
-
-== libfreebl3 ==
-
-Porting to other platforms may require to deliver other variants of
-libfreebl*. The library name varies according to the platform. Changes need to
-be made to
-ooo/moz/extractfiles.mk
-ooo/moz/zipped/makefile.mk
-sun/moz_prebuilt/zipped/makefile.mk
-
See also
-[http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn6.html]
-
-
-== Windows builds of nss ==
-
-To build mozilla on windows you'll need the mozilla build tools
-
-Build requirements containing the link to the build tools:
-[https://developer.mozilla.org/en/Windows_Build_Prerequisites#ss2.2]
-
-The direct link:
-[http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-1.3.exe]
-
+[https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/NSS_Tech_Notes/nss_tech_note6]
== libsqlite3 ==
-The system sqlite in Mac OS X versions older than 10.6 is incompatible
-with the softokn3 in nss which requires a later version of sqlite.
-With SDK 10.6 (and more current SDK) we use
+With all supported Mac OS X SDK we use
NSS_USE_SYSTEM_SQLITE=1
to build using the system sqlite.
-The problem described here was found on Mac with OS 10.6
-We cannot deliver sqlite in the lib directory of the solver. This directory is
-used by tools of the build environment. Using the sqlite from NSS breaks the
-tools if they use system libraries which are linked with the system
-sqlite. Therefore we deliver it into lib/sqlite on unix systems.
-
-See also issue:
-[https://bz.apache.org/ooo/show_bug.cgi?id=106132]
-
== system NSS on Linux ==
Note that different Linux distributions use different SONAMEs for the
diff --git a/external/nss/UnpackedTarball_nss.mk b/external/nss/UnpackedTarball_nss.mk
index 7fc3f4cd054b..a0ac57173fd1 100644
--- a/external/nss/UnpackedTarball_nss.mk
+++ b/external/nss/UnpackedTarball_nss.mk
@@ -24,6 +24,8 @@ $(eval $(call gb_UnpackedTarball_add_patches,nss,\
external/nss/nss-3.13.3-build.patch.3 \
external/nss/nss.mingw.patch.3) \
external/nss/ubsan.patch.0 \
+ external/nss/clang-cl.patch.0 \
+ external/nss/nss.windowbuild.patch.0 \
$(if $(filter IOS,$(OS)), \
external/nss/nss-chromium-nss-static.patch \
external/nss/nss-more-static.patch \
@@ -34,19 +36,15 @@ $(eval $(call gb_UnpackedTarball_add_patches,nss,\
external/nss/nss.vs2015.pdb.patch) \
$(if $(findstring 120_70,$(VCVER)_$(WINDOWS_SDK_VERSION)), \
external/nss/nss-winXP-sdk.patch.1) \
+ $(if $(filter WNTMSC,$(OS)$(COM)), \
+ external/nss/nss.utf8bom.patch.1) \
))
-# nss-pem is only needed for internal curl to read the NSS CA database
-ifeq ($(SYSTEM_CURL),)
-$(eval $(call gb_UnpackedTarball_add_patches,nss,\
- external/nss/nss-pem.patch \
-))
-endif
-
ifeq ($(COM_IS_CLANG),TRUE)
ifneq ($(filter -fsanitize=%,$(CC)),)
$(eval $(call gb_UnpackedTarball_add_patches,nss,\
external/nss/asan.patch.1 \
+ external/nss/ubsan-alignment.patch.0 \
))
endif
endif
diff --git a/external/nss/asan.patch.1 b/external/nss/asan.patch.1
index 3b64aa6f3045..0685adb1dc4b 100644
--- a/external/nss/asan.patch.1
+++ b/external/nss/asan.patch.1
@@ -1,12 +1,12 @@
diff -ur nss.org/nss/coreconf/Linux.mk nss/nss/coreconf/Linux.mk
--- nss.org/nss/coreconf/Linux.mk 2014-05-06 04:36:01.817838877 +0200
+++ nss/nss/coreconf/Linux.mk 2014-05-06 04:37:25.387835456 +0200
-@@ -145,7 +145,7 @@
- # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
- # incorrectly reports undefined references in the libraries we link with, so
+@@ -158,7 +158,7 @@
# we don't use -z defs there.
+ # Also, -z defs conflicts with Address Sanitizer, which emits relocations
+ # against the libsanitizer runtime built into the main executable.
-ZDEFS_FLAG = -Wl,-z,defs
+ZDEFS_FLAG =
- DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) -Wl,-z,origin '-Wl,-rpath,$$ORIGIN'
- LDFLAGS += $(ARCHFLAG)
-
+ ifneq ($(USE_ASAN),1)
+ DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) -Wl,-z,origin '-Wl,-rpath,$$ORIGIN'
+ endif
diff --git a/external/nss/clang-cl.patch.0 b/external/nss/clang-cl.patch.0
new file mode 100644
index 000000000000..98786d49971c
--- /dev/null
+++ b/external/nss/clang-cl.patch.0
@@ -0,0 +1,74 @@
+# "#pragma deprecated" and "#pragma intrinsic" not (yet?) handled in the "if
+# (LangOpts.MicrosoftExt)" block in Preprocessor::RegisterBuiltinPragmas in
+# Clang's lib/Lex/Pragma.cpp:
+--- nspr/pr/include/pratom.h
++++ nspr/pr/include/pratom.h
+@@ -83,7 +83,7 @@
+
+ #include <intrin.h>
+
+-#ifdef _MSC_VER
++#if defined _WIN32 && !defined __clang__
+ #pragma intrinsic(_InterlockedIncrement)
+ #pragma intrinsic(_InterlockedDecrement)
+ #pragma intrinsic(_InterlockedExchange)
+--- nspr/pr/include/prbit.h
++++ nspr/pr/include/prbit.h
+@@ -14,7 +14,7 @@
+ ** functions.
+ */
+ #if defined(_WIN32) && (_MSC_VER >= 1300) && \
+- (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM))
++ (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM)) && !defined __clang__
+ # include <intrin.h>
+ # pragma intrinsic(_BitScanForward,_BitScanReverse)
+ __forceinline static int __prBitScanForward32(unsigned int val)
+@@ -32,7 +32,7 @@
+ # define pr_bitscan_ctz32(val) __prBitScanForward32(val)
+ # define pr_bitscan_clz32(val) __prBitScanReverse32(val)
+ # define PR_HAVE_BUILTIN_BITSCAN32
+-#elif ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \
++#elif defined __GNUC__ && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && \
+ (defined(__i386__) || defined(__x86_64__) || defined(__arm__))
+ # define pr_bitscan_ctz32(val) __builtin_ctz(val)
+ # define pr_bitscan_clz32(val) __builtin_clz(val)
+@@ -136,7 +136,7 @@
+ */
+
+ #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || \
+- defined(_M_X64) || defined(_M_ARM))
++ defined(_M_X64) || defined(_M_ARM)) && !defined __clang__
+ #include <stdlib.h>
+ #pragma intrinsic(_rotl, _rotr)
+ #define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits)
+--- nss/lib/certdb/certdb.h
++++ nss/lib/certdb/certdb.h
+@@ -21,7 +21,7 @@
+ /* On Windows, Mac, and Linux (and other gcc platforms), we can give compile
+ * time deprecation warnings when applications use the old CERTDB_VALID_PEER
+ * define */
+-#if __GNUC__ > 3
++#if defined __GNUC__ && __GNUC__ > 3
+ #if (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
+ typedef unsigned int __CERTDB_VALID_PEER __attribute__((deprecated));
+ #else
+@@ -30,7 +30,7 @@
+ #endif
+ #define CERTDB_VALID_PEER ((__CERTDB_VALID_PEER)CERTDB_TERMINAL_RECORD)
+ #else
+-#ifdef _WIN32
++#if defined _WIN32 && !defined __clang__
+ #pragma deprecated(CERTDB_VALID_PEER)
+ #endif
+ #define CERTDB_VALID_PEER CERTDB_TERMINAL_RECORD
+--- nss/lib/util/pkcs11n.h
++++ nss/lib/util/pkcs11n.h
+@@ -426,7 +426,7 @@
+ /* keep the old value for compatibility reasons*/
+ #define CKT_NSS_MUST_VERIFY ((__CKT_NSS_MUST_VERIFY)(CKT_NSS + 4))
+ #else
+-#ifdef _WIN32
++#if defined _WIN32 && !defined __clang__
+ /* This magic gets the windows compiler to give us a deprecation
+ * warning */
+ #pragma deprecated(CKT_NSS_UNTRUSTED, CKT_NSS_MUST_VERIFY, CKT_NSS_VALID)
diff --git a/external/nss/nss-pem.patch b/external/nss/nss-pem.patch
deleted file mode 100644
index d41809d3ecaf..000000000000
--- a/external/nss/nss-pem.patch
+++ /dev/null
@@ -1,6376 +0,0 @@
-diff --git a/a/nss/lib/ckfw/manifest.mn b/b/nss/lib/ckfw/manifest.mn
-index 20bebeb..4f10563 100644
---- a/a/nss/lib/ckfw/manifest.mn
-+++ b/b/nss/lib/ckfw/manifest.mn
-@@ -5,7 +5,7 @@
-
- CORE_DEPTH = ../..
-
--DIRS = builtins
-+DIRS = builtins pem
-
- PRIVATE_EXPORTS = \
- ck.h \
-diff --git a/a/nss/lib/ckfw/pem/Makefile b/b/nss/lib/ckfw/pem/Makefile
-new file mode 100644
-index 0000000..aec3bbd
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/Makefile
-@@ -0,0 +1,107 @@
-+#
-+# ***** 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 *****
-+MAKEFILE_CVS_ID = "@(#) $RCSfile: Makefile,v $ $Revision: 1.5 $ $Date: 2007/05/09 00:09:37 $"
-+
-+include manifest.mn
-+include $(CORE_DEPTH)/coreconf/config.mk
-+include config.mk
-+
-+EXTRA_LIBS = \
-+ $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
-+ $(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
-+ $(DIST)/lib/$(LIB_PREFIX)freebl.$(LIB_SUFFIX) \
-+ $(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \
-+ $(NULL)
-+
-+# can't do this in manifest.mn because OS_TARGET isn't defined there.
-+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-+
-+ifdef NS_USE_GCC
-+EXTRA_LIBS += \
-+ -L$(NSPR_LIB_DIR) \
-+ -lplc4 \
-+ -lplds4 \
-+ -lnspr4 \
-+ $(NULL)
-+else
-+EXTRA_SHARED_LIBS += \
-+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
-+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
-+ $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)nspr4.lib \
-+ crypt32.lib \
-+ advapi32.lib \
-+ rpcrt4.lib \
-+ $(NULL)
-+endif # NS_USE_GCC
-+else
-+
-+EXTRA_LIBS += \
-+ -L$(NSPR_LIB_DIR) \
-+ -lplc4 \
-+ -lplds4 \
-+ -lnspr4 \
-+ $(NULL)
-+endif
-+
-+
-+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
-+
-+
-diff --git a/a/nss/lib/ckfw/pem/anchor.c b/b/nss/lib/ckfw/pem/anchor.c
-new file mode 100644
-index 0000000..621f919
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/anchor.c
-@@ -0,0 +1,50 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 ***** */
-+
-+/*
-+ * anchor.c
-+ *
-+ * This file "anchors" the actual cryptoki entry points in this module's
-+ * shared library, which is required for dynamic loading. See the
-+ * comments in nssck.api for more information.
-+ */
-+
-+#include "ckpem.h"
-+
-+#define MODULE_NAME pem
-+#define INSTANCE_NAME (NSSCKMDInstance *)&pem_mdInstance
-+#include "nssck.api"
-diff --git a/a/nss/lib/ckfw/pem/ckpem.h b/b/nss/lib/ckfw/pem/ckpem.h
-new file mode 100644
-index 0000000..9712ccd
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/ckpem.h
-@@ -0,0 +1,263 @@
-+#ifndef CKPEM_H
-+#define CKPEM_H
-+
-+#include "nssckmdt.h"
-+#include "nssckfw.h"
-+#include "ckfwtm.h"
-+#include "ckfw.h"
-+#include "secder.h"
-+#include "secoid.h"
-+#include "secasn1.h"
-+#include "blapit.h"
-+#include "softoken.h"
-+
-+/*
-+ * I'm including this for access to the arena functions.
-+ * Looks like we should publish that API.
-+ */
-+#ifndef BASE_H
-+#include "base.h"
-+#endif /* BASE_H */
-+
-+/*
-+ * This is where the Netscape extensions live, at least for now.
-+ */
-+#ifndef CKT_H
-+#include "ckt.h"
-+#endif /* CKT_H */
-+
-+#define NUM_SLOTS 8
-+
-+/*
-+ * statically defined raw objects. Allows us to data description objects
-+ * to this PKCS #11 module.
-+ */
-+struct pemRawObjectStr {
-+ CK_ULONG n;
-+ const CK_ATTRIBUTE_TYPE *types;
-+ const NSSItem *items;
-+};
-+typedef struct pemRawObjectStr pemRawObject;
-+
-+/*
-+ * common values needed for both bare keys and cert referenced keys.
-+ */
-+struct pemKeyParamsStr {
-+ NSSItem modulus;
-+ NSSItem exponent;
-+ NSSItem privateExponent;
-+ NSSItem prime1;
-+ NSSItem prime2;
-+ NSSItem exponent1;
-+ NSSItem exponent2;
-+ NSSItem coefficient;
-+ unsigned char publicExponentData[sizeof(CK_ULONG)];
-+ SECItem *privateKey;
-+ SECItem *privateKeyOrig; /* deep copy of privateKey until decrypted */
-+ void *pubKey;
-+};
-+typedef struct pemKeyParamsStr pemKeyParams;
-+/*
-+ * Key objects. Handles bare keys which do not yet have certs associated
-+ * with them. These are usually short lived, but may exist for several days
-+ * while the CA is issuing the certificate.
-+ */
-+struct pemKeyObjectStr {
-+ char *provName;
-+ char *containerName;
-+ pemKeyParams key;
-+ char *ivstring;
-+ int cipher;
-+};
-+typedef struct pemKeyObjectStr pemKeyObject;
-+
-+/*
-+ * Certificate and certificate referenced keys.
-+ */
-+struct pemCertObjectStr {
-+ const char *certStore;
-+ NSSItem label;
-+ NSSItem subject;
-+ NSSItem issuer;
-+ NSSItem serial;
-+ NSSItem derCert;
-+ unsigned char sha1_hash[SHA1_LENGTH];
-+ unsigned char md5_hash[MD5_LENGTH];
-+ pemKeyParams key;
-+ unsigned char *labelData;
-+ /* static data: to do, make this dynamic like labelData */
-+ unsigned char derSerial[128];
-+};
-+typedef struct pemCertObjectStr pemCertObject;
-+
-+/*
-+ * Trust
-+ */
-+struct pemTrustObjectStr {
-+ char *nickname;
-+};
-+typedef struct pemTrustObjectStr pemTrustObject;
-+
-+typedef enum {
-+ pemAll = -1, /* matches all types */
-+ pemRaw,
-+ pemCert,
-+ pemBareKey,
-+ pemTrust
-+} pemObjectType;
-+
-+typedef struct pemInternalObjectStr pemInternalObject;
-+typedef struct pemObjectListItemStr pemObjectListItem;
-+
-+/*
-+ * singly-linked list of internal objects
-+ */
-+struct pemObjectListItemStr {
-+ pemInternalObject *io;
-+ pemObjectListItem *next;
-+};
-+
-+/*
-+ * all the various types of objects are abstracted away in cobject and
-+ * cfind as pemInternalObjects.
-+ */
-+struct pemInternalObjectStr {
-+ pemObjectType type;
-+ union {
-+ pemRawObject raw;
-+ pemCertObject cert;
-+ pemKeyObject key;
-+ pemTrustObject trust;
-+ } u;
-+ CK_OBJECT_CLASS objClass;
-+ NSSItem hashKey;
-+ NSSItem id;
-+ unsigned char hashKeyData[128];
-+ SECItem *derCert;
-+ char *nickname;
-+ NSSCKMDObject mdObject;
-+ CK_SLOT_ID slotID;
-+ CK_ULONG gobjIndex;
-+ int refCount;
-+
-+ /* used by pem_mdFindObjects_Next */
-+ CK_BBOOL extRef;
-+
-+ /* If list != NULL, the object contains no useful data except of the list
-+ * of slave objects */
-+ pemObjectListItem *list;
-+};
-+
-+struct pemTokenStr {
-+ PRBool logged_in;
-+};
-+typedef struct pemTokenStr pemToken;
-+
-+/* our raw object data array */
-+NSS_EXTERN_DATA pemInternalObject nss_pem_data[];
-+NSS_EXTERN_DATA const PRUint32 nss_pem_nObjects;
-+
-+/* our raw object data array */
-+NSS_EXTERN_DATA pemInternalObject nss_pem_data[];
-+NSS_EXTERN_DATA const PRUint32 nss_pem_nObjects;
-+
-+NSS_EXTERN_DATA pemInternalObject pem_data[];
-+NSS_EXTERN_DATA const PRUint32 pem_nObjects;
-+
-+NSS_EXTERN_DATA const CK_VERSION pem_CryptokiVersion;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_ManufacturerID;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_LibraryDescription;
-+NSS_EXTERN_DATA const CK_VERSION pem_LibraryVersion;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_SlotDescription;
-+NSS_EXTERN_DATA const CK_VERSION pem_HardwareVersion;
-+NSS_EXTERN_DATA const CK_VERSION pem_FirmwareVersion;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_TokenLabel;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_TokenModel;
-+NSS_EXTERN_DATA const NSSUTF8 * pem_TokenSerialNumber;
-+
-+NSS_EXTERN_DATA const NSSCKMDInstance pem_mdInstance;
-+NSS_EXTERN_DATA const NSSCKMDSlot pem_mdSlot;
-+NSS_EXTERN_DATA const NSSCKMDToken pem_mdToken;
-+NSS_EXTERN_DATA const NSSCKMDMechanism pem_mdMechanismRSA;
-+
-+NSS_EXTERN NSSCKMDSession *
-+pem_CreateSession
-+(
-+ NSSCKFWSession *fwSession,
-+ CK_RV *pError
-+);
-+
-+NSS_EXTERN NSSCKMDFindObjects *
-+pem_FindObjectsInit
-+(
-+ NSSCKFWSession *fwSession,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV *pError
-+);
-+
-+NSS_EXTERN NSSCKMDObject *
-+pem_CreateMDObject
-+(
-+ NSSArena *arena,
-+ pemInternalObject *io,
-+ CK_RV *pError
-+);
-+
-+#define NSS_PEM_ARRAY_SIZE(x) ((sizeof (x))/(sizeof ((x)[0])))
-+
-+typedef enum {
-+ pemLOWKEYNullKey = 0,
-+ pemLOWKEYRSAKey = 1,
-+ pemLOWKEYDSAKey = 2,
-+ pemLOWKEYDHKey = 4,
-+ pemLOWKEYECKey = 5
-+} pemLOWKEYType;
-+
-+/*
-+** Low Level private key object
-+** This is only used by the raw Crypto engines (crypto), keydb (keydb),
-+** and PKCS #11. Everyone else uses the high level key structure.
-+*/
-+struct pemLOWKEYPrivateKeyStr {
-+ PLArenaPool *arena;
-+ pemLOWKEYType keyType;
-+ union {
-+ RSAPrivateKey rsa;
-+ DSAPrivateKey dsa;
-+ DHPrivateKey dh;
-+ ECPrivateKey ec;
-+ } u;
-+};
-+typedef struct pemLOWKEYPrivateKeyStr pemLOWKEYPrivateKey;
-+
-+SECStatus ReadDERFromFile(SECItem ***derlist, char *filename, PRBool ascii, int *cipher, char **ivstring, PRBool certsonly);
-+const NSSItem * pem_FetchAttribute ( pemInternalObject *io, CK_ATTRIBUTE_TYPE type);
-+void pem_PopulateModulusExponent(pemInternalObject *io);
-+NSSCKMDObject * pem_CreateObject(NSSCKFWInstance *fwInstance, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_RV *pError);
-+NSSCKMDSlot *pem_NewSlot( NSSCKFWInstance *fwInstance, CK_RV *pError);
-+
-+
-+PRBool pem_ParseString(const char* inputstring, const char delimiter,
-+ PRInt32* numStrings, char*** returnedstrings);
-+PRBool pem_FreeParsedStrings(PRInt32 numStrings, char** instrings);
-+
-+pemInternalObject *
-+AddObjectIfNeeded(CK_OBJECT_CLASS objClass, pemObjectType type,
-+ SECItem *certDER, SECItem *keyDER, char *filename, int objid,
-+ CK_SLOT_ID slotID, PRBool *pAdded);
-+
-+void pem_DestroyInternalObject (pemInternalObject *io);
-+
-+
-+/* prsa.c */
-+unsigned int pem_PrivateModulusLen(pemLOWKEYPrivateKey *privk);
-+
-+/* ptoken.c */
-+NSSCKMDToken * pem_NewToken(NSSCKFWInstance *fwInstance, CK_RV *pError);
-+
-+/* util.c */
-+void open_log();
-+void plog(const char *fmt, ...);
-+
-+#endif /* CKPEM_H */
-diff --git a/a/nss/lib/ckfw/pem/ckpemver.c b/b/nss/lib/ckfw/pem/ckpemver.c
-new file mode 100644
-index 0000000..76ab5df
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/ckpemver.c
-@@ -0,0 +1,59 @@
-+/* ***** 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.
-+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
-+ *
-+ * Contributor(s):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 ***** */
-+/* Library identity and versioning */
-+
-+#include "nsspem.h"
-+
-+#if defined(DEBUG)
-+#define _DEBUG_STRING " (debug)"
-+#else
-+#define _DEBUG_STRING ""
-+#endif
-+
-+/*
-+ * Version information for the 'ident' and 'what commands
-+ *
-+ * NOTE: the first component of the concatenated rcsid string
-+ * must not end in a '$' to prevent rcs keyword substitution.
-+ */
-+const char __nss_ckpem_rcsid[] = "$Header: NSS Access to Flat Files in PEM format"
-+ NSS_CKPEM_LIBRARY_VERSION _DEBUG_STRING
-+ " " __DATE__ " " __TIME__ " $";
-+const char __nss_ckcapi_sccsid[] = "@(#)NSS Access to Flag Files in PEM format "
-+ NSS_CKPEM_LIBRARY_VERSION _DEBUG_STRING
-+ " " __DATE__ " " __TIME__;
-diff --git a/a/nss/lib/ckfw/pem/config.mk b/b/nss/lib/ckfw/pem/config.mk
-new file mode 100644
-index 0000000..ff6cd9a
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/config.mk
-@@ -0,0 +1,71 @@
-+#
-+# ***** 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 *****
-+CONFIG_CVS_ID = "@(#) $RCSfile: config.mk,v $ $Revision: 1.11 $ $Date: 2005/01/20 02:25:46 $"
-+
-+#
-+# Override TARGETS variable so that only shared libraries
-+# are specified as dependencies within rules.mk.
-+#
-+
-+TARGETS = $(SHARED_LIBRARY)
-+LIBRARY =
-+IMPORT_LIBRARY =
-+PROGRAM =
-+
-+ifeq (,$(filter-out WIN%,$(OS_TARGET)))
-+ SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
-+ RES = $(OBJDIR)/$(LIBRARY_NAME).res
-+ RESNAME = $(LIBRARY_NAME).rc
-+endif
-+
-+ifdef BUILD_IDG
-+ DEFINES += -DNSSDEBUG
-+endif
-+
-+#
-+# To create a loadable module on Darwin, we must use -bundle.
-+#
-+ifeq ($(OS_TARGET),Darwin)
-+DSO_LDOPTS = -bundle
-+endif
-+
-+ifeq ($(OS_TARGET),SunOS)
-+# The -R '$ORIGIN' linker option instructs this library to search for its
-+# dependencies in the same directory where it resides.
-+MKSHLIB += -R '$$ORIGIN'
-+endif
-+
-diff --git a/a/nss/lib/ckfw/pem/constants.c b/b/nss/lib/ckfw/pem/constants.c
-new file mode 100644
-index 0000000..0ceb443
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/constants.c
-@@ -0,0 +1,77 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 ***** */
-+/*
-+ * constants.c
-+ *
-+ * Identification and other constants, all collected here in one place.
-+ */
-+
-+#ifndef NSSBASET_H
-+#include "nssbaset.h"
-+#endif /* NSSBASET_H */
-+
-+#ifndef NSSCKT_H
-+#include "nssckt.h"
-+#endif /* NSSCKT_H */
-+
-+#ifndef NSSCKBI_H
-+#include "../builtins/nssckbi.h"
-+#endif /* NSSCKBI_H */
-+
-+NSS_IMPLEMENT_DATA const CK_VERSION
-+pem_CryptokiVersion = { 2, 1 };
-+
-+NSS_IMPLEMENT_DATA const NSSUTF8 *
-+pem_ManufacturerID = (NSSUTF8 *) "Red Hat, Inc.";
-+
-+NSS_IMPLEMENT_DATA const NSSUTF8 *
-+pem_LibraryDescription = (NSSUTF8 *) "PEM Reader Cryptoki Module";
-+
-+NSS_IMPLEMENT_DATA const CK_VERSION
-+pem_LibraryVersion = { 1, 0 };
-+
-+NSS_IMPLEMENT_DATA const CK_VERSION
-+pem_HardwareVersion = { 1, 0 };
-+
-+NSS_IMPLEMENT_DATA const CK_VERSION
-+pem_FirmwareVersion = { 1, 0 };
-+
-+NSS_IMPLEMENT_DATA const NSSUTF8 *
-+pem_TokenModel = (NSSUTF8 *) "1";
-+
-+NSS_IMPLEMENT_DATA const NSSUTF8 *
-+pem_TokenSerialNumber = (NSSUTF8 *) "1";
-diff --git a/a/nss/lib/ckfw/pem/manifest.mn b/b/nss/lib/ckfw/pem/manifest.mn
-new file mode 100644
-index 0000000..8de27d1
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/manifest.mn
-@@ -0,0 +1,68 @@
-+#
-+# ***** 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 *****
-+MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.1 $ $Date: 2005/11/04 02:05:04 $"
-+
-+CORE_DEPTH = ../../..
-+
-+MODULE = nss
-+MAPFILE = $(OBJDIR)/nsspem.def
-+
-+EXPORTS = \
-+ nsspem.h \
-+ $(NULL)
-+
-+CSRCS = \
-+ anchor.c \
-+ constants.c \
-+ pargs.c \
-+ pfind.c \
-+ pinst.c \
-+ pobject.c \
-+ prsa.c \
-+ psession.c \
-+ pslot.c \
-+ ptoken.c \
-+ ckpemver.c \
-+ rsawrapr.c \
-+ util.c \
-+ $(NULL)
-+
-+REQUIRES = nspr
-+
-+LIBRARY_NAME = nsspem
-+
-+#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
-diff --git a/a/nss/lib/ckfw/pem/nsspem.def b/b/nss/lib/ckfw/pem/nsspem.def
-new file mode 100644
-index 0000000..4978252
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/nsspem.def
-@@ -0,0 +1,58 @@
-+;+#
-+;+# ***** 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) 2003
-+;+# 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 *****
-+;+#
-+;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
-+;+# 1. For all unix platforms, the string ";-" means "remove this line"
-+;+# 2. For all unix platforms, the string " DATA " will be removed from any
-+;+# line on which it occurs.
-+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
-+;+# On AIX, lines containing ";+" will be removed.
-+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
-+;+# 5. For all unix platforms, after the above processing has taken place,
-+;+# all characters after the first ";" on the line will be removed.
-+;+# And for AIX, the first ";" will also be removed.
-+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
-+;+# directives are hidden behind ";", ";+", and ";-"
-+;+
-+;+NSS_3.1 { # NSS 3.1 release
-+;+ global:
-+LIBRARY nsspem ;-
-+EXPORTS ;-
-+C_GetFunctionList;
-+;+ local:
-+;+*;
-+;+};
-diff --git a/a/nss/lib/ckfw/pem/nsspem.h b/b/nss/lib/ckfw/pem/nsspem.h
-new file mode 100644
-index 0000000..1547bf4
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/nsspem.h
-@@ -0,0 +1,75 @@
-+/* ***** 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.
-+ * Portions created by Red Hat, Inc, are Copyright (C) 2005
-+ *
-+ * Contributor(s):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+
-+#ifndef NSSPEM_H
-+#define NSSPEM_H
-+
-+/*
-+ * NSS CKPEM Version numbers.
-+ *
-+ * These are the version numbers for the capi module packaged with
-+ * this release on NSS. To determine the version numbers of the builtin
-+ * module you are using, use the appropriate PKCS #11 calls.
-+ *
-+ * These version numbers detail changes to the PKCS #11 interface. They map
-+ * to the PKCS #11 spec versions.
-+ */
-+#define NSS_CKPEM_CRYPTOKI_VERSION_MAJOR 2
-+#define NSS_CKPEM_CRYPTOKI_VERSION_MINOR 20
-+
-+/* These version numbers detail the changes
-+ * to the list of trusted certificates.
-+ *
-+ * NSS_CKPEM_LIBRARY_VERSION_MINOR is a CK_BYTE. It's not clear
-+ * whether we may use its full range (0-255) or only 0-99 because
-+ * of the comment in the CK_VERSION type definition.
-+ */
-+#define NSS_CKPEM_LIBRARY_VERSION_MAJOR 1
-+#define NSS_CKPEM_LIBRARY_VERSION_MINOR 1
-+#define NSS_CKPEM_LIBRARY_VERSION "1.1"
-+
-+/* These version numbers detail the semantic changes to the ckfw engine. */
-+#define NSS_CKPEM_HARDWARE_VERSION_MAJOR 1
-+#define NSS_CKPEM_HARDWARE_VERSION_MINOR 0
-+
-+/* These version numbers detail the semantic changes to ckbi itself
-+ * (new PKCS #11 objects), etc. */
-+#define NSS_CKPEM_FIRMWARE_VERSION_MAJOR 1
-+#define NSS_CKPEM_FIRMWARE_VERSION_MINOR 0
-+
-+#endif /* NSSCKBI_H */
-diff --git a/a/nss/lib/ckfw/pem/nsspem.rc b/b/nss/lib/ckfw/pem/nsspem.rc
-new file mode 100644
-index 0000000..eb208d6
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/nsspem.rc
-@@ -0,0 +1,64 @@
-+/* This Source Code Form is subject to the terms of the Mozilla Public
-+ * License, v. 2.0. If a copy of the MPL was not distributed with this
-+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-+
-+#include "nsspem.h"
-+#include <winver.h>
-+
-+#define MY_LIBNAME "nsspem"
-+#define MY_FILEDESCRIPTION "NSS PEM support"
-+
-+#ifdef _DEBUG
-+#define MY_DEBUG_STR " (debug)"
-+#define MY_FILEFLAGS_1 VS_FF_DEBUG
-+#else
-+#define MY_DEBUG_STR ""
-+#define MY_FILEFLAGS_1 0x0L
-+#endif
-+#if NSS_BETA
-+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
-+#else
-+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
-+#endif
-+
-+#ifdef WINNT
-+#define MY_FILEOS VOS_NT_WINDOWS32
-+#else
-+#define MY_FILEOS VOS__WINDOWS32
-+#endif
-+
-+#define MY_INTERNAL_NAME MY_LIBNAME
-+
-+/////////////////////////////////////////////////////////////////////////////
-+//
-+// Version-information resource
-+//
-+
-+VS_VERSION_INFO VERSIONINFO
-+ FILEVERSION NSS_CKPEM_LIBRARY_VERSION_MAJOR,NSS_CKPEM_LIBRARY_VERSION_MINOR,0,0
-+ PRODUCTVERSION NSS_CKPEM_LIBRARY_VERSION_MAJOR,NSS_CKPEM_LIBRARY_VERSION_MINOR,0,0
-+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
-+ FILEFLAGS MY_FILEFLAGS_2
-+ FILEOS MY_FILEOS
-+ FILETYPE VFT_DLL
-+ FILESUBTYPE 0x0L // not used
-+
-+BEGIN
-+ BLOCK "StringFileInfo"
-+ BEGIN
-+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
-+ BEGIN
-+ VALUE "CompanyName", "Mozilla Foundation\0"
-+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
-+ VALUE "FileVersion", NSS_CKPEM_LIBRARY_VERSION "\0"
-+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
-+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
-+ VALUE "ProductName", "Network Security Services\0"
-+ VALUE "ProductVersion", NSS_CKPEM_LIBRARY_VERSION "\0"
-+ END
-+ END
-+ BLOCK "VarFileInfo"
-+ BEGIN
-+ VALUE "Translation", 0x409, 1200
-+ END
-+END
-diff --git a/a/nss/lib/ckfw/pem/pargs.c b/b/nss/lib/ckfw/pem/pargs.c
-new file mode 100644
-index 0000000..21291a8
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/pargs.c
-@@ -0,0 +1,164 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 <string.h>
-+#include <nspr.h>
-+
-+void *pem_Malloc(const PRInt32 sz)
-+{
-+ return PR_Malloc(sz);
-+}
-+
-+char *pem_StrNdup(const char *instr, PRInt32 inlen)
-+{
-+ size_t len = inlen;
-+ char *buffer;
-+ if (!instr) {
-+ return NULL;
-+ }
-+
-+ if (!len) {
-+ return NULL;
-+ }
-+ buffer = (char *) pem_Malloc(len + 1);
-+ if (!buffer) {
-+ return NULL;
-+ }
-+ memcpy(buffer, instr, len);
-+ buffer[len] = 0; /* NULL termination */
-+ return buffer;
-+}
-+
-+char *pem_Strdup(const char *instr)
-+{
-+ size_t len;
-+ if (!instr) {
-+ return NULL;
-+ }
-+
-+ len = strlen(instr);
-+ return pem_StrNdup(instr, len);
-+}
-+
-+void pem_Free(char *instr)
-+{
-+ if (!instr) {
-+ PR_ASSERT(0);
-+ }
-+ PR_Free(instr);
-+}
-+
-+void
-+addString(char ***returnedstrings, char *newstring, PRInt32 stringcount)
-+{
-+ char **stringarray = NULL;
-+ if (!returnedstrings || !newstring) {
-+ return;
-+ }
-+ if (!stringcount) {
-+ /* first string to be added, allocate buffer */
-+ *returnedstrings =
-+ (char **) PR_Malloc(sizeof(char *) * (stringcount + 1));
-+ stringarray = *returnedstrings;
-+ } else {
-+ stringarray = (char **) PR_Realloc(*returnedstrings,
-+ sizeof(char *) * (stringcount + 1));
-+ if (stringarray) {
-+ *returnedstrings = stringarray;
-+ }
-+ }
-+ if (stringarray) {
-+ stringarray[stringcount] = newstring;
-+ }
-+}
-+
-+PRBool
-+pem_ParseString(const char *inputstring, const char delimiter,
-+ PRInt32 * numStrings, char ***returnedstrings)
-+{
-+ char nextchar;
-+ char *instring = (char *) inputstring;
-+ if (!inputstring || !delimiter || !numStrings || !returnedstrings) {
-+ /* we need a string and a non-zero delimiter, as well as
-+ * a valid place to return the strings and count
-+ */
-+ return PR_FALSE;
-+ }
-+ *numStrings = 0;
-+ *returnedstrings = NULL;
-+
-+ while ((nextchar = *instring)) {
-+ unsigned long len = 0;
-+ char *next = (char *) strchr(instring, delimiter);
-+ if (next) {
-+ /* current string string */
-+ len = next - instring;
-+ } else {
-+ /* last string length */
-+ len = strlen(instring);
-+ }
-+
-+ if (len > 0) {
-+ char *newstring = pem_StrNdup(instring, len);
-+
-+ addString(returnedstrings, newstring, (*numStrings)++);
-+
-+ instring += len;
-+ }
-+
-+ if (delimiter == *instring) {
-+ instring++; /* skip past next delimiter */
-+ }
-+ }
-+ return PR_TRUE;
-+}
-+
-+PRBool pem_FreeParsedStrings(PRInt32 numStrings, char **instrings)
-+{
-+ PRInt32 counter;
-+ if (!numStrings || !instrings) {
-+ return PR_FALSE;
-+ }
-+ for (counter = 0; counter < numStrings; counter++) {
-+ char *astring = instrings[counter];
-+ if (astring) {
-+ pem_Free(astring);
-+ }
-+ }
-+ PR_Free((void *) instrings);
-+ return PR_TRUE;
-+}
-diff --git a/a/nss/lib/ckfw/pem/pfind.c b/b/nss/lib/ckfw/pem/pfind.c
-new file mode 100644
-index 0000000..30b1174
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/pfind.c
-@@ -0,0 +1,435 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+
-+/*
-+ * pfind.c
-+ *
-+ * This file implements the NSSCKMDFindObjects object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+NSS_EXTERN_DATA pemInternalObject **gobj;
-+NSS_EXTERN_DATA int pem_nobjs;
-+
-+struct pemFOStr {
-+ NSSArena *arena;
-+ CK_ULONG n;
-+ CK_ULONG i;
-+ pemInternalObject **objs;
-+};
-+
-+#define PEM_ITEM_CHUNK 512
-+
-+#define PUT_Object(obj,err) \
-+ { \
-+ if (count >= size) { \
-+ *listp = *listp ? \
-+ nss_ZREALLOCARRAY(*listp, pemInternalObject *, \
-+ (size+PEM_ITEM_CHUNK) ) : \
-+ nss_ZNEWARRAY(NULL, pemInternalObject *, \
-+ (size+PEM_ITEM_CHUNK) ) ; \
-+ if ((pemInternalObject **)NULL == *listp) { \
-+ err = CKR_HOST_MEMORY; \
-+ goto loser; \
-+ } \
-+ size += PEM_ITEM_CHUNK; \
-+ } \
-+ (*listp)[ count ] = (obj); \
-+ count++; \
-+ }
-+
-+static void
-+pem_mdFindObjects_Final
-+(
-+ NSSCKMDFindObjects * mdFindObjects,
-+ NSSCKFWFindObjects * fwFindObjects,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ struct pemFOStr *fo = (struct pemFOStr *) mdFindObjects->etc;
-+ NSSArena *arena = fo->arena;
-+
-+ nss_ZFreeIf(fo->objs);
-+ nss_ZFreeIf(fo);
-+ nss_ZFreeIf(mdFindObjects);
-+ if ((NSSArena *) NULL != arena) {
-+ NSSArena_Destroy(arena);
-+ }
-+
-+ return;
-+}
-+
-+static NSSCKMDObject *
-+pem_mdFindObjects_Next
-+(
-+ NSSCKMDFindObjects * mdFindObjects,
-+ NSSCKFWFindObjects * fwFindObjects,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSArena * arena,
-+ CK_RV * pError
-+)
-+{
-+ struct pemFOStr *fo = (struct pemFOStr *) mdFindObjects->etc;
-+ pemInternalObject *io;
-+
-+ plog("pem_FindObjects_Next: ");
-+
-+ if (fo->i == fo->n) {
-+ plog("Done creating objects\n");
-+ *pError = CKR_OK;
-+ return (NSSCKMDObject *) NULL;
-+ }
-+
-+ io = fo->objs[fo->i];
-+ fo->i++;
-+
-+ plog("Creating object for type %d\n", io->type);
-+
-+ if (!io->extRef) {
-+ /* increase reference count only once as ckfw will free the found
-+ * object only once */
-+ io->extRef = CK_TRUE;
-+ io->refCount ++;
-+ }
-+
-+ return pem_CreateMDObject(arena, io, pError);
-+}
-+
-+#if 0
-+static int
-+pem_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
-+{
-+ unsigned char *start = src;
-+ int len = 0;
-+
-+ if (*src++ != 2) {
-+ return 0;
-+ }
-+ len = *src++;
-+ if (len & 0x80) {
-+ int count = len & 0x7f;
-+ len = 0;
-+
-+ if (count + 2 > size) {
-+ return 0;
-+ }
-+ while (count-- > 0) {
-+ len = (len << 8) | *src++;
-+ }
-+ }
-+ if (len + (src - start) != size) {
-+ return 0;
-+ }
-+ *dest = src;
-+ return len;
-+}
-+#endif
-+
-+static char * pem_attr_name(CK_ATTRIBUTE_TYPE type) {
-+ switch(type) {
-+ case CKA_CLASS:
-+ return "CKA_CLASS";
-+ case CKA_TOKEN:
-+ return "CKA_TOKEN";
-+ case CKA_PRIVATE:
-+ return "CKA_PRIVATE";
-+ case CKA_LABEL:
-+ return "CKA_LABEL";
-+ case CKA_APPLICATION:
-+ return "CKA_APPLICATION";
-+ case CKA_VALUE:
-+ return "CKA_VALUE";
-+ case CKA_OBJECT_ID:
-+ return "CKA_OBJECT_ID";
-+ case CKA_CERTIFICATE_TYPE:
-+ return "CKA_CERTIFICATE_TYPE";
-+ case CKA_ISSUER:
-+ return "CKA_ISSUER";
-+ case CKA_SERIAL_NUMBER:
-+ return "CKA_SERIAL_NUMBER";
-+ case CKA_ID:
-+ return "CKA_ID";
-+ default:
-+ return "unknown";
-+ }
-+}
-+
-+static CK_BBOOL
-+pem_attrmatch(CK_ATTRIBUTE_PTR a, pemInternalObject * o) {
-+ PRBool prb;
-+ const NSSItem *b;
-+
-+ b = pem_FetchAttribute(o, a->type);
-+ if (b == NULL) {
-+ plog("pem_attrmatch %s %08x: CK_FALSE attr not found\n", pem_attr_name(a->type), a->type);
-+ return CK_FALSE;
-+ }
-+
-+ if (a->ulValueLen != b->size) {
-+ plog("pem_attrmatch %s %08x: CK_FALSE size mismatch %d vs %d\n", pem_attr_name(a->type), a->type, a->ulValueLen, b->size);
-+ return CK_FALSE;
-+ }
-+
-+ prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *) NULL);
-+
-+ if (PR_TRUE == prb) {
-+ plog("pem_attrmatch %s %08x: CK_TRUE\n", pem_attr_name(a->type), a->type);
-+ return CK_TRUE;
-+ } else {
-+ plog("pem_attrmatch %s %08x: CK_FALSE\n", pem_attr_name(a->type), a->type);
-+ plog("type: %08x, label: %s a->pValue %08x, b->data %08x\n", o->objClass, o->u.cert.label.data, a->pValue, b->data);
-+ return CK_FALSE;
-+ }
-+}
-+
-+static CK_BBOOL
-+pem_match
-+(
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ pemInternalObject * o
-+)
-+{
-+ CK_ULONG i;
-+
-+ for (i = 0; i < ulAttributeCount; i++) {
-+ if (CK_FALSE == pem_attrmatch(&pTemplate[i], o)) {
-+ plog("pem_match: CK_FALSE\n");
-+ return CK_FALSE;
-+ }
-+ }
-+
-+ /* Every attribute passed */
-+ plog("pem_match: CK_TRUE\n");
-+ return CK_TRUE;
-+}
-+
-+CK_OBJECT_CLASS
-+pem_GetObjectClass(CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount)
-+{
-+ CK_ULONG i;
-+
-+ for (i = 0; i < ulAttributeCount; i++) {
-+ if (pTemplate[i].type == CKA_CLASS) {
-+ return *(CK_OBJECT_CLASS *) pTemplate[i].pValue;
-+ }
-+ }
-+ /* need to return a value that says 'fetch them all' */
-+ return CK_INVALID_HANDLE;
-+}
-+
-+static PRUint32
-+collect_objects(CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ pemInternalObject *** listp,
-+ CK_RV * pError, CK_SLOT_ID slotID)
-+{
-+ PRUint32 i;
-+ PRUint32 count = 0;
-+ PRUint32 size = 0;
-+ pemObjectType type = pemRaw;
-+ CK_OBJECT_CLASS objClass = pem_GetObjectClass(pTemplate, ulAttributeCount);
-+
-+ *pError = CKR_OK;
-+
-+ plog("collect_objects slot #%ld, ", slotID);
-+ plog("%d attributes, ", ulAttributeCount);
-+ plog("%d objects to look through.\n", pem_nobjs);
-+ plog("Looking for: ");
-+ /*
-+ * now determine type of the object
-+ */
-+ switch (objClass) {
-+ case CKO_CERTIFICATE:
-+ plog("CKO_CERTIFICATE\n");
-+ type = pemCert;
-+ break;
-+ case CKO_PUBLIC_KEY:
-+ plog("CKO_PUBLIC_KEY\n");
-+ type = pemBareKey;
-+ break;
-+ case CKO_PRIVATE_KEY:
-+ type = pemBareKey;
-+ plog("CKO_PRIVATE_KEY\n");
-+ break;
-+ case CKO_NETSCAPE_TRUST:
-+ type = pemTrust;
-+ plog("CKO_NETSCAPE_TRUST\n");
-+ break;
-+ case CKO_NETSCAPE_CRL:
-+ plog("CKO_NETSCAPE_CRL\n");
-+ goto done;
-+ case CKO_NETSCAPE_SMIME:
-+ plog("CKO_NETSCAPE_SMIME\n");
-+ goto done;
-+ case CKO_NETSCAPE_BUILTIN_ROOT_LIST:
-+ plog("CKO_NETSCAPE_BUILTIN_ROOT_LIST\n");
-+ goto done;
-+ case CK_INVALID_HANDLE:
-+ type = pemAll; /* look through all objectclasses - ignore the type field */
-+ plog("CK_INVALID_HANDLE\n");
-+ break;
-+ default:
-+ plog("no other object types %08x\n", objClass);
-+ goto done; /* no other object types we understand in this module */
-+ }
-+
-+ /* find objects */
-+ for (i = 0; i < pem_nobjs; i++) {
-+ int match = 1; /* matches type if type not specified */
-+ if (NULL == gobj[i])
-+ continue;
-+
-+ plog(" %d type = %d\n", i, gobj[i]->type);
-+ if (type != pemAll) {
-+ /* type specified - must match given type */
-+ match = (type == gobj[i]->type);
-+ }
-+ if (match) {
-+ match = (slotID == gobj[i]->slotID) &&
-+ (CK_TRUE == pem_match(pTemplate, ulAttributeCount, gobj[i]));
-+ }
-+ if (match) {
-+ pemInternalObject *o = gobj[i];
-+ PUT_Object(o, *pError);
-+ }
-+ }
-+
-+ if (CKR_OK != *pError) {
-+ goto loser;
-+ }
-+
-+ done:
-+ plog("collect_objects: Found %d\n", count);
-+ return count;
-+ loser:
-+ nss_ZFreeIf(*listp);
-+ return 0;
-+
-+}
-+
-+NSS_IMPLEMENT NSSCKMDFindObjects *
-+pem_FindObjectsInit
-+(
-+ NSSCKFWSession * fwSession,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV * pError
-+)
-+{
-+ NSSArena *arena = NULL;
-+ NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *) NULL;
-+ struct pemFOStr *fo = (struct pemFOStr *) NULL;
-+ pemInternalObject **temp = (pemInternalObject **) NULL;
-+ NSSCKFWSlot *fwSlot;
-+ CK_SLOT_ID slotID;
-+
-+ plog("pem_FindObjectsInit\n");
-+ fwSlot = nssCKFWSession_GetFWSlot(fwSession);
-+ if ((NSSCKFWSlot *) NULL == fwSlot) {
-+ goto loser;
-+ }
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ arena = NSSArena_Create();
-+ if ((NSSArena *) NULL == arena) {
-+ goto loser;
-+ }
-+
-+ rv = nss_ZNEW(arena, NSSCKMDFindObjects);
-+ if ((NSSCKMDFindObjects *) NULL == rv) {
-+ *pError = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ fo = nss_ZNEW(arena, struct pemFOStr);
-+ if ((struct pemFOStr *) NULL == fo) {
-+ *pError = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ fo->arena = arena;
-+ /* fo->n and fo->i are already zero */
-+
-+ rv->etc = (void *) fo;
-+ rv->Final = pem_mdFindObjects_Final;
-+ rv->Next = pem_mdFindObjects_Next;
-+ rv->null = (void *) NULL;
-+
-+ fo->n =
-+ collect_objects(pTemplate, ulAttributeCount, &temp, pError,
-+ slotID);
-+ if (*pError != CKR_OK) {
-+ goto loser;
-+ }
-+
-+ fo->objs = nss_ZNEWARRAY(arena, pemInternalObject *, fo->n);
-+ if ((pemInternalObject **) NULL == fo->objs) {
-+ *pError = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ (void) nsslibc_memcpy(fo->objs, temp,
-+ sizeof(pemInternalObject *) * fo->n);
-+
-+ nss_ZFreeIf(temp);
-+ temp = (pemInternalObject **) NULL;
-+
-+ return rv;
-+
-+ loser:
-+ nss_ZFreeIf(temp);
-+ nss_ZFreeIf(fo);
-+ nss_ZFreeIf(rv);
-+ if ((NSSArena *) NULL != arena) {
-+ NSSArena_Destroy(arena);
-+ }
-+ return (NSSCKMDFindObjects *) NULL;
-+}
-diff --git a/a/nss/lib/ckfw/pem/pinst.c b/b/nss/lib/ckfw/pem/pinst.c
-new file mode 100644
-index 0000000..9c98e89
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/pinst.c
-@@ -0,0 +1,768 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 <stdlib.h>
-+#include "ckpem.h"
-+#include "blapi.h"
-+#include "prprf.h"
-+
-+/*
-+ * pinstance.c
-+ *
-+ * This file implements the NSSCKMDInstance object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+static PRBool pemInitialized = PR_FALSE;
-+
-+pemInternalObject **gobj;
-+int pem_nobjs = 0;
-+int token_needsLogin[NUM_SLOTS];
-+
-+PRInt32 size = 0;
-+PRInt32 count = 0;
-+
-+#define PEM_ITEM_CHUNK 512
-+
-+/*
-+ * simple cert decoder to avoid the cost of asn1 engine
-+ */
-+static unsigned char *
-+dataStart(unsigned char *buf, unsigned int length,
-+ unsigned int *data_length,
-+ PRBool includeTag, unsigned char *rettag)
-+{
-+ unsigned char tag;
-+ unsigned int used_length = 0;
-+ if (!length)
-+ return NULL;
-+
-+ tag = buf[used_length++];
-+
-+ if (rettag) {
-+ *rettag = tag;
-+ }
-+
-+ /* blow out when we come to the end */
-+ if (tag == 0 || length <= used_length) {
-+ return NULL;
-+ }
-+
-+ *data_length = buf[used_length++];
-+
-+ if (*data_length & 0x80) {
-+ int len_count = *data_length & 0x7f;
-+
-+ *data_length = 0;
-+
-+ while (len_count-- > 0) {
-+ if (length <= used_length)
-+ return NULL;
-+
-+ *data_length = (*data_length << 8) | buf[used_length++];
-+ }
-+ }
-+
-+ if (*data_length > (length - used_length)) {
-+ *data_length = length - used_length;
-+ return NULL;
-+ }
-+ if (includeTag)
-+ *data_length += used_length;
-+
-+ return (buf + (includeTag ? 0 : used_length));
-+}
-+
-+static int
-+GetCertFields(unsigned char *cert, int cert_length,
-+ SECItem * issuer, SECItem * serial, SECItem * derSN,
-+ SECItem * subject, SECItem * valid, SECItem * subjkey)
-+{
-+ unsigned char *buf;
-+ unsigned int buf_length;
-+ unsigned char *dummy;
-+ unsigned int dummylen;
-+
-+ /* get past the signature wrap */
-+ buf = dataStart(cert, cert_length, &buf_length, PR_FALSE, NULL);
-+ if (buf == NULL)
-+ return SECFailure;
-+ /* get into the raw cert data */
-+ buf = dataStart(buf, buf_length, &buf_length, PR_FALSE, NULL);
-+ if (buf == NULL)
-+ return SECFailure;
-+ /* skip past any optional version number */
-+ if ((buf[0] & 0xa0) == 0xa0) {
-+ dummy = dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
-+ if (dummy == NULL)
-+ return SECFailure;
-+ buf_length -= (dummy - buf) + dummylen;
-+ buf = dummy + dummylen;
-+ }
-+ /* serial number */
-+ if (derSN) {
-+ derSN->data =
-+ dataStart(buf, buf_length, &derSN->len, PR_TRUE, NULL);
-+ }
-+ serial->data =
-+ dataStart(buf, buf_length, &serial->len, PR_FALSE, NULL);
-+ if (serial->data == NULL)
-+ return SECFailure;
-+ buf_length -= (serial->data - buf) + serial->len;
-+ buf = serial->data + serial->len;
-+ /* skip the OID */
-+ dummy = dataStart(buf, buf_length, &dummylen, PR_FALSE, NULL);
-+ if (dummy == NULL)
-+ return SECFailure;
-+ buf_length -= (dummy - buf) + dummylen;
-+ buf = dummy + dummylen;
-+ /* issuer */
-+ issuer->data = dataStart(buf, buf_length, &issuer->len, PR_TRUE, NULL);
-+ if (issuer->data == NULL)
-+ return SECFailure;
-+ buf_length -= (issuer->data - buf) + issuer->len;
-+ buf = issuer->data + issuer->len;
-+
-+ /* only wanted issuer/SN */
-+ if (subject == NULL || valid == NULL || subjkey == NULL) {
-+ return SECSuccess;
-+ }
-+ /* validity */
-+ valid->data = dataStart(buf, buf_length, &valid->len, PR_FALSE, NULL);
-+ if (valid->data == NULL)
-+ return SECFailure;
-+ buf_length -= (valid->data - buf) + valid->len;
-+ buf = valid->data + valid->len;
-+ /*subject */
-+ subject->data =
-+ dataStart(buf, buf_length, &subject->len, PR_TRUE, NULL);
-+ if (subject->data == NULL)
-+ return SECFailure;
-+ buf_length -= (subject->data - buf) + subject->len;
-+ buf = subject->data + subject->len;
-+ /* subject key info */
-+ subjkey->data =
-+ dataStart(buf, buf_length, &subjkey->len, PR_TRUE, NULL);
-+ if (subjkey->data == NULL)
-+ return SECFailure;
-+ buf_length -= (subjkey->data - buf) + subjkey->len;
-+ buf = subjkey->data + subjkey->len;
-+ return SECSuccess;
-+}
-+
-+static CK_RV
-+assignObjectID(pemInternalObject *o, int objid)
-+{
-+ char id[16];
-+ int len;
-+
-+ sprintf(id, "%d", objid);
-+ len = strlen(id) + 1; /* zero terminate */
-+ o->id.size = len;
-+ o->id.data = nss_ZAlloc(NULL, len);
-+ if (o->id.data == NULL)
-+ return CKR_HOST_MEMORY;
-+
-+ nsslibc_memcpy(o->id.data, id, len);
-+ return CKR_OK;
-+}
-+
-+static pemInternalObject *
-+CreateObject(CK_OBJECT_CLASS objClass,
-+ pemObjectType type, SECItem * certDER,
-+ SECItem * keyDER, char *filename,
-+ int objid, CK_SLOT_ID slotID)
-+{
-+ pemInternalObject *o;
-+ SECItem subject;
-+ SECItem issuer;
-+ SECItem serial;
-+ SECItem derSN;
-+ SECItem valid;
-+ SECItem subjkey;
-+ char *nickname;
-+
-+ o = nss_ZNEW(NULL, pemInternalObject);
-+ if ((pemInternalObject *) NULL == o) {
-+ return NULL;
-+ }
-+
-+ nickname = strrchr(filename, '/');
-+ if (nickname)
-+ nickname++;
-+ else
-+ nickname = filename;
-+
-+ switch (objClass) {
-+ case CKO_CERTIFICATE:
-+ plog("Creating cert nick %s id %d in slot %ld\n", nickname, objid, slotID);
-+ memset(&o->u.cert, 0, sizeof(o->u.cert));
-+ break;
-+ case CKO_PRIVATE_KEY:
-+ plog("Creating key id %d in slot %ld\n", objid, slotID);
-+ memset(&o->u.key, 0, sizeof(o->u.key));
-+ nickname = filename;
-+ break;
-+ case CKO_NETSCAPE_TRUST:
-+ plog("Creating trust nick %s id %d in slot %ld\n", nickname, objid, slotID);
-+ memset(&o->u.trust, 0, sizeof(o->u.trust));
-+ break;
-+ }
-+
-+ o->nickname = (char *) nss_ZAlloc(NULL, strlen(nickname) + 1);
-+ if (o->nickname == NULL)
-+ goto fail;
-+ strcpy(o->nickname, nickname);
-+
-+ if (CKR_OK != assignObjectID(o, objid))
-+ goto fail;
-+
-+ o->objClass = objClass;
-+ o->type = type;
-+ o->slotID = slotID;
-+
-+ o->derCert = nss_ZNEW(NULL, SECItem);
-+ if (o->derCert == NULL)
-+ goto fail;
-+ o->derCert->data = (void *) nss_ZAlloc(NULL, certDER->len);
-+ if (o->derCert->data == NULL)
-+ goto fail;
-+ o->derCert->len = certDER->len;
-+ nsslibc_memcpy(o->derCert->data, certDER->data, certDER->len);
-+
-+ switch (objClass) {
-+ case CKO_CERTIFICATE:
-+ case CKO_NETSCAPE_TRUST:
-+ if (SECSuccess != GetCertFields(o->derCert->data, o->derCert->len,
-+ &issuer, &serial, &derSN, &subject,
-+ &valid, &subjkey))
-+ goto fail;
-+
-+ o->u.cert.subject.data = (void *) nss_ZAlloc(NULL, subject.len);
-+ if (o->u.cert.subject.data == NULL)
-+ goto fail;
-+ o->u.cert.subject.size = subject.len;
-+ nsslibc_memcpy(o->u.cert.subject.data, subject.data, subject.len);
-+
-+ o->u.cert.issuer.data = (void *) nss_ZAlloc(NULL, issuer.len);
-+ if (o->u.cert.issuer.data == NULL) {
-+ nss_ZFreeIf(o->u.cert.subject.data);
-+ goto fail;
-+ }
-+ o->u.cert.issuer.size = issuer.len;
-+ nsslibc_memcpy(o->u.cert.issuer.data, issuer.data, issuer.len);
-+
-+ o->u.cert.serial.data = (void *) nss_ZAlloc(NULL, serial.len);
-+ if (o->u.cert.serial.data == NULL) {
-+ nss_ZFreeIf(o->u.cert.issuer.data);
-+ nss_ZFreeIf(o->u.cert.subject.data);
-+ goto fail;
-+ }
-+ o->u.cert.serial.size = serial.len;
-+ nsslibc_memcpy(o->u.cert.serial.data, serial.data, serial.len);
-+ break;
-+ case CKO_PRIVATE_KEY:
-+ o->u.key.key.privateKey = nss_ZNEW(NULL, SECItem);
-+ if (o->u.key.key.privateKey == NULL)
-+ goto fail;
-+ o->u.key.key.privateKey->data =
-+ (void *) nss_ZAlloc(NULL, keyDER->len);
-+ if (o->u.key.key.privateKey->data == NULL) {
-+ nss_ZFreeIf(o->u.key.key.privateKey);
-+ goto fail;
-+ }
-+
-+ /* store deep copy of original key DER so we can compare it later on */
-+ o->u.key.key.privateKeyOrig = SECITEM_DupItem(keyDER);
-+ if (o->u.key.key.privateKeyOrig == NULL) {
-+ nss_ZFreeIf(o->u.key.key.privateKey->data);
-+ nss_ZFreeIf(o->u.key.key.privateKey);
-+ goto fail;
-+ }
-+
-+ o->u.key.key.privateKey->len = keyDER->len;
-+ nsslibc_memcpy(o->u.key.key.privateKey->data, keyDER->data,
-+ keyDER->len);
-+ }
-+
-+
-+ return o;
-+
-+fail:
-+ if (o) {
-+ if (o->derCert) {
-+ nss_ZFreeIf(o->derCert->data);
-+ nss_ZFreeIf(o->derCert);
-+ }
-+ nss_ZFreeIf(o->id.data);
-+ nss_ZFreeIf(o->nickname);
-+ nss_ZFreeIf(o);
-+ }
-+ return NULL;
-+}
-+
-+/* Compare the DER encoding of the internal object against those
-+ * of the provided certDER or keyDER according to its objClass.
-+ */
-+static PRBool
-+derEncodingsMatch(CK_OBJECT_CLASS objClass, pemInternalObject * obj,
-+ SECItem * certDER, SECItem * keyDER)
-+{
-+ SECComparison result;
-+
-+ switch (objClass) {
-+ case CKO_CERTIFICATE:
-+ case CKO_NETSCAPE_TRUST:
-+ result = SECITEM_CompareItem(obj->derCert, certDER);
-+ break;
-+
-+ case CKO_PRIVATE_KEY:
-+ result = SECITEM_CompareItem(obj->u.key.key.privateKeyOrig, keyDER);
-+ break;
-+
-+ default:
-+ /* unhandled object class */
-+ return PR_FALSE;
-+ }
-+
-+ return SECEqual == result;
-+}
-+
-+static CK_RV
-+LinkSharedKeyObject(int oldKeyIdx, int newKeyIdx)
-+{
-+ int i;
-+ for (i = 0; i < pem_nobjs; i++) {
-+ CK_RV rv;
-+ pemInternalObject *obj = gobj[i];
-+ if (NULL == obj)
-+ continue;
-+
-+ if (atoi(obj->id.data) != oldKeyIdx)
-+ continue;
-+
-+ nss_ZFreeIf(obj->id.data);
-+ rv = assignObjectID(obj, newKeyIdx);
-+ if (CKR_OK != rv)
-+ return rv;
-+ }
-+
-+ return CKR_OK;
-+}
-+
-+pemInternalObject *
-+AddObjectIfNeeded(CK_OBJECT_CLASS objClass,
-+ pemObjectType type, SECItem * certDER,
-+ SECItem * keyDER, char *filename,
-+ int objid, CK_SLOT_ID slotID, PRBool *pAdded)
-+{
-+ int i;
-+ pemInternalObject *io;
-+
-+ /* FIXME: copy-pasted from CreateObject */
-+ const char *nickname = strrchr(filename, '/');
-+ if (nickname && CKO_PRIVATE_KEY != objClass)
-+ nickname++;
-+ else
-+ nickname = filename;
-+
-+ if (pAdded)
-+ *pAdded = PR_FALSE;
-+
-+ /* first look for the object in gobj, it might be already there */
-+ for (i = 0; i < pem_nobjs; i++) {
-+ if (NULL == gobj[i])
-+ continue;
-+
-+ /* Comparing DER encodings is dependable and frees the PEM module
-+ * from having to require clients to provide unique nicknames.
-+ */
-+ if ((gobj[i]->objClass == objClass)
-+ && (gobj[i]->type == type)
-+ && (gobj[i]->slotID == slotID)
-+ && derEncodingsMatch(objClass, gobj[i], certDER, keyDER)) {
-+
-+ /* While adding a client certificate we (wrongly?) assumed that the
-+ * key object will follow right after the cert object. However, if
-+ * the key object is shared by multiple client certificates, such
-+ * an assumption does not hold. We have to update the references.
-+ */
-+ LinkSharedKeyObject(pem_nobjs, i);
-+
-+ plog("AddObjectIfNeeded: re-using internal object #%i\n", i);
-+ gobj[i]->refCount ++;
-+ return gobj[i];
-+ }
-+ }
-+
-+ /* object not found, we need to create it */
-+ io = CreateObject(objClass, type, certDER, keyDER,
-+ filename, objid, slotID);
-+ if (io == NULL)
-+ return NULL;
-+
-+ /* initialize pointers to functions */
-+ pem_CreateMDObject(NULL, io, NULL);
-+
-+ io->gobjIndex = count;
-+
-+ /* add object to global array */
-+ if (count >= size) {
-+ gobj = gobj ?
-+ nss_ZREALLOCARRAY(gobj, pemInternalObject *,
-+ (size+PEM_ITEM_CHUNK) ) :
-+ nss_ZNEWARRAY(NULL, pemInternalObject *,
-+ (size+PEM_ITEM_CHUNK) ) ;
-+
-+ if ((pemInternalObject **)NULL == gobj)
-+ return NULL;
-+ size += PEM_ITEM_CHUNK;
-+ }
-+ gobj[count] = io;
-+ count++;
-+ pem_nobjs++;
-+
-+ if (pAdded)
-+ *pAdded = PR_TRUE;
-+
-+ io->refCount ++;
-+ return io;
-+}
-+
-+CK_RV
-+AddCertificate(char *certfile, char *keyfile, PRBool cacert,
-+ CK_SLOT_ID slotID)
-+{
-+ pemInternalObject *o;
-+ CK_RV error = 0;
-+ int objid, i;
-+ int nobjs = 0;
-+ SECItem **objs = NULL;
-+ char *ivstring = NULL;
-+ int cipher;
-+
-+ nobjs = ReadDERFromFile(&objs, certfile, PR_TRUE, &cipher, &ivstring, PR_TRUE /* certs only */);
-+ if (nobjs <= 0) {
-+ nss_ZFreeIf(objs);
-+ return CKR_GENERAL_ERROR;
-+ }
-+
-+ /* For now load as many certs as are in the file for CAs only */
-+ if (cacert) {
-+ for (i = 0; i < nobjs; i++) {
-+ char nickname[1024];
-+ objid = pem_nobjs + 1;
-+
-+ PR_snprintf(nickname, 1024, "%s - %d", certfile, i);
-+
-+ o = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert, objs[i], NULL,
-+ nickname, 0, slotID, NULL);
-+ if (o == NULL) {
-+ error = CKR_GENERAL_ERROR;
-+ goto loser;
-+ }
-+
-+ /* Add the CA trust object */
-+ o = AddObjectIfNeeded(CKO_NETSCAPE_TRUST, pemTrust, objs[i], NULL,
-+ nickname, 0, slotID, NULL);
-+ if (o == NULL) {
-+ error = CKR_GENERAL_ERROR;
-+ goto loser;
-+ }
-+ } /* for */
-+ } else {
-+ objid = pem_nobjs + 1;
-+ o = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert, objs[0], NULL, certfile,
-+ objid, slotID, NULL);
-+ if (o == NULL) {
-+ error = CKR_GENERAL_ERROR;
-+ goto loser;
-+ }
-+
-+ o = NULL;
-+
-+ if (keyfile) { /* add the private key */
-+ SECItem **keyobjs = NULL;
-+ int kobjs = 0;
-+ kobjs =
-+ ReadDERFromFile(&keyobjs, keyfile, PR_TRUE, &cipher,
-+ &ivstring, PR_FALSE);
-+ if (kobjs < 1) {
-+ error = CKR_GENERAL_ERROR;
-+ goto loser;
-+ }
-+ o = AddObjectIfNeeded(CKO_PRIVATE_KEY, pemBareKey, objs[0],
-+ keyobjs[0], certfile, objid, slotID, NULL);
-+ if (o == NULL) {
-+ error = CKR_GENERAL_ERROR;
-+ goto loser;
-+ }
-+ }
-+ }
-+
-+ nss_ZFreeIf(objs);
-+ return CKR_OK;
-+
-+ loser:
-+ nss_ZFreeIf(objs);
-+ nss_ZFreeIf(o);
-+ return error;
-+}
-+
-+CK_RV
-+pem_Initialize
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSUTF8 * configurationData
-+)
-+{
-+ CK_RV rv;
-+ /* parse the initialization string */
-+ char **certstrings = NULL;
-+ char *modparms = NULL;
-+ PRInt32 numcerts = 0;
-+ PRBool status, error = PR_FALSE;
-+ int i;
-+ CK_C_INITIALIZE_ARGS_PTR modArgs = NULL;
-+
-+ if (!fwInstance) return CKR_ARGUMENTS_BAD;
-+
-+ modArgs = NSSCKFWInstance_GetInitArgs(fwInstance);
-+ if (modArgs &&
-+ ((modArgs->flags & CKF_OS_LOCKING_OK) || (modArgs->CreateMutex != 0))) {
-+ return CKR_CANT_LOCK;
-+ }
-+
-+ if (pemInitialized) {
-+ return CKR_OK;
-+ }
-+
-+ RNG_RNGInit();
-+
-+ open_log();
-+
-+ plog("pem_Initialize\n");
-+
-+ if (!modArgs || !modArgs->LibraryParameters) {
-+ goto done;
-+ }
-+ modparms = (char *) modArgs->LibraryParameters;
-+ plog("Initialized with %s\n", modparms);
-+
-+ /*
-+ * The initialization string format is a space-delimited file of
-+ * pairs of paths which are delimited by a semi-colon. The first
-+ * entry of the pair is the path to the certificate file. The
-+ * second is the path to the key file.
-+ *
-+ * CA certificates do not need the semi-colon.
-+ *
-+ * Example:
-+ * /etc/certs/server.pem;/etc/certs/server.key /etc/certs/ca.pem
-+ *
-+ */
-+ status =
-+ pem_ParseString(modparms, ' ', &numcerts,
-+ &certstrings);
-+ if (status == PR_FALSE) {
-+ return CKR_ARGUMENTS_BAD;
-+ }
-+
-+ for (i = 0; i < numcerts && error != PR_TRUE; i++) {
-+ char *cert = certstrings[i];
-+ PRInt32 attrcount = 0;
-+ char **certattrs = NULL;
-+ status = pem_ParseString(cert, ';', &attrcount, &certattrs);
-+ if (status == PR_FALSE) {
-+ error = PR_TRUE;
-+ break;
-+ }
-+
-+ if (error == PR_FALSE) {
-+ if (attrcount == 1) /* CA certificate */
-+ rv = AddCertificate(certattrs[0], NULL, PR_TRUE, 0);
-+ else
-+ rv = AddCertificate(certattrs[0], certattrs[1], PR_FALSE,
-+ 0);
-+
-+ if (rv != CKR_OK) {
-+ error = PR_TRUE;
-+ status = PR_FALSE;
-+ }
-+ }
-+ pem_FreeParsedStrings(attrcount, certattrs);
-+ }
-+ pem_FreeParsedStrings(numcerts, certstrings);
-+
-+ if (status == PR_FALSE) {
-+ return CKR_ARGUMENTS_BAD;
-+ }
-+
-+ for (i = 0; i < NUM_SLOTS; i++)
-+ token_needsLogin[i] = PR_FALSE;
-+
-+ done:
-+
-+ PR_AtomicSet(&pemInitialized, PR_TRUE);
-+
-+ return CKR_OK;
-+}
-+
-+void
-+pem_Finalize
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ plog("pem_Finalize\n");
-+ if (!pemInitialized)
-+ return;
-+
-+ nss_ZFreeIf(gobj);
-+ gobj = NULL;
-+
-+ pem_nobjs = 0;
-+ size = 0;
-+ count = 0;
-+
-+ PR_AtomicSet(&pemInitialized, PR_FALSE);
-+
-+ return;
-+}
-+
-+/*
-+ * NSSCKMDInstance methods
-+ */
-+
-+static CK_ULONG
-+pem_mdInstance_GetNSlots
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (CK_ULONG) NUM_SLOTS;
-+}
-+
-+static CK_VERSION
-+pem_mdInstance_GetCryptokiVersion
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_CryptokiVersion;
-+}
-+
-+static NSSUTF8 *
-+pem_mdInstance_GetManufacturerID
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_ManufacturerID;
-+}
-+
-+static NSSUTF8 *
-+pem_mdInstance_GetLibraryDescription
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_LibraryDescription;
-+}
-+
-+static CK_VERSION
-+pem_mdInstance_GetLibraryVersion
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_LibraryVersion;
-+}
-+
-+static CK_RV
-+pem_mdInstance_GetSlots
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKMDSlot * slots[]
-+)
-+{
-+ int i;
-+ CK_RV pError;
-+
-+ for (i = 0; i < NUM_SLOTS; i++) {
-+ slots[i] = (NSSCKMDSlot *) pem_NewSlot(fwInstance, &pError);
-+ if (pError != CKR_OK)
-+ return pError;
-+ }
-+ return CKR_OK;
-+}
-+
-+CK_BBOOL
-+pem_mdInstance_ModuleHandlesSessionObjects
-+(
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return CK_TRUE;
-+}
-+
-+NSS_IMPLEMENT_DATA const NSSCKMDInstance
-+pem_mdInstance = {
-+ (void *) NULL, /* etc */
-+ pem_Initialize, /* Initialize */
-+ pem_Finalize, /* Finalize */
-+ pem_mdInstance_GetNSlots,
-+ pem_mdInstance_GetCryptokiVersion,
-+ pem_mdInstance_GetManufacturerID,
-+ pem_mdInstance_GetLibraryDescription,
-+ pem_mdInstance_GetLibraryVersion,
-+ pem_mdInstance_ModuleHandlesSessionObjects,
-+ pem_mdInstance_GetSlots,
-+ NULL, /* WaitForSlotEvent */
-+ (void *) NULL /* null terminator */
-+};
-diff --git a/a/nss/lib/ckfw/pem/pobject.c b/b/nss/lib/ckfw/pem/pobject.c
-new file mode 100644
-index 0000000..a13e531
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/pobject.c
-@@ -0,0 +1,1240 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+#include "secasn1.h"
-+#include "certt.h"
-+#include "prprf.h"
-+#include "pk11pub.h"
-+
-+/*
-+ * pobject.c
-+ *
-+ * This file implements the NSSCKMDObject object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+NSS_EXTERN_DATA pemInternalObject **gobj;
-+NSS_EXTERN_DATA int pem_nobjs;
-+NSS_EXTERN_DATA int token_needsLogin[NUM_SLOTS];
-+
-+#define APPEND_LIST_ITEM(item) do { \
-+ item->next = nss_ZNEW(NULL, pemObjectListItem); \
-+ if (NULL == item->next) \
-+ goto loser; \
-+ item = item->next; \
-+} while (0)
-+
-+const CK_ATTRIBUTE_TYPE certAttrs[] = {
-+ CKA_CLASS,
-+ CKA_TOKEN,
-+ CKA_PRIVATE,
-+ CKA_MODIFIABLE,
-+ CKA_LABEL,
-+ CKA_CERTIFICATE_TYPE,
-+ CKA_SUBJECT,
-+ CKA_ISSUER,
-+ CKA_SERIAL_NUMBER,
-+ CKA_VALUE
-+};
-+const PRUint32 certAttrsCount = NSS_PEM_ARRAY_SIZE(certAttrs);
-+
-+/* private keys, for now only support RSA */
-+const CK_ATTRIBUTE_TYPE privKeyAttrs[] = {
-+ CKA_CLASS,
-+ CKA_TOKEN,
-+ CKA_PRIVATE,
-+ CKA_MODIFIABLE,
-+ CKA_LABEL,
-+ CKA_KEY_TYPE,
-+ CKA_DERIVE,
-+ CKA_LOCAL,
-+ CKA_SUBJECT,
-+ CKA_SENSITIVE,
-+ CKA_DECRYPT,
-+ CKA_SIGN,
-+ CKA_SIGN_RECOVER,
-+ CKA_UNWRAP,
-+ CKA_EXTRACTABLE,
-+ CKA_ALWAYS_SENSITIVE,
-+ CKA_NEVER_EXTRACTABLE,
-+ CKA_MODULUS,
-+ CKA_PUBLIC_EXPONENT,
-+};
-+const PRUint32 privKeyAttrsCount = NSS_PEM_ARRAY_SIZE(privKeyAttrs);
-+
-+/* public keys, for now only support RSA */
-+const CK_ATTRIBUTE_TYPE pubKeyAttrs[] = {
-+ CKA_CLASS,
-+ CKA_TOKEN,
-+ CKA_PRIVATE,
-+ CKA_MODIFIABLE,
-+ CKA_LABEL,
-+ CKA_KEY_TYPE,
-+ CKA_DERIVE,
-+ CKA_LOCAL,
-+ CKA_SUBJECT,
-+ CKA_ENCRYPT,
-+ CKA_VERIFY,
-+ CKA_VERIFY_RECOVER,
-+ CKA_WRAP,
-+ CKA_MODULUS,
-+ CKA_PUBLIC_EXPONENT,
-+};
-+const PRUint32 pubKeyAttrsCount = NSS_PEM_ARRAY_SIZE(pubKeyAttrs);
-+
-+/* Trust */
-+const CK_ATTRIBUTE_TYPE trustAttrs[] = {
-+ CKA_CLASS,
-+ CKA_TOKEN,
-+ CKA_LABEL,
-+ CKA_CERT_SHA1_HASH,
-+ CKA_CERT_MD5_HASH,
-+ CKA_ISSUER,
-+ CKA_SUBJECT,
-+ CKA_TRUST_SERVER_AUTH,
-+ CKA_TRUST_CLIENT_AUTH,
-+ CKA_TRUST_EMAIL_PROTECTION,
-+ CKA_TRUST_CODE_SIGNING
-+};
-+const PRUint32 trustAttrsCount = NSS_PEM_ARRAY_SIZE(trustAttrs);
-+
-+static const CK_BBOOL ck_true = CK_TRUE;
-+static const CK_BBOOL ck_false = CK_FALSE;
-+static const CK_CERTIFICATE_TYPE ckc_x509 = CKC_X_509;
-+static const CK_KEY_TYPE ckk_rsa = CKK_RSA;
-+static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-+static const CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
-+static const CK_OBJECT_CLASS cko_public_key = CKO_PUBLIC_KEY;
-+static const CK_OBJECT_CLASS cko_trust = CKO_NETSCAPE_TRUST;
-+static const CK_TRUST ckt_netscape_trusted = CKT_NETSCAPE_TRUSTED_DELEGATOR;
-+static const NSSItem pem_trueItem = {
-+ (void *) &ck_true, (PRUint32) sizeof(CK_BBOOL)
-+};
-+static const NSSItem pem_falseItem = {
-+ (void *) &ck_false, (PRUint32) sizeof(CK_BBOOL)
-+};
-+static const NSSItem pem_x509Item = {
-+ (void *) &ckc_x509, (PRUint32) sizeof(CK_ULONG)
-+};
-+static const NSSItem pem_rsaItem = {
-+ (void *) &ckk_rsa, (PRUint32) sizeof(CK_KEY_TYPE)
-+};
-+static const NSSItem pem_certClassItem = {
-+ (void *) &cko_certificate, (PRUint32) sizeof(CK_OBJECT_CLASS)
-+};
-+static const NSSItem pem_privKeyClassItem = {
-+ (void *) &cko_private_key, (PRUint32) sizeof(CK_OBJECT_CLASS)
-+};
-+static const NSSItem pem_pubKeyClassItem = {
-+ (void *) &cko_public_key, (PRUint32) sizeof(CK_OBJECT_CLASS)
-+};
-+static const NSSItem pem_trustClassItem = {
-+ (void *) &cko_trust, (PRUint32) sizeof(CK_OBJECT_CLASS)
-+};
-+static const NSSItem pem_emptyItem = {
-+ (void *) &ck_true, 0
-+};
-+static const NSSItem pem_trusted = {
-+ (void *) &ckt_netscape_trusted, (PRUint32) sizeof(CK_TRUST)
-+};
-+
-+/* SEC_SkipTemplate is already defined and exported by libnssutil */
-+#ifdef SEC_SKIP_TEMPLATE
-+/*
-+ * Template for skipping a subitem.
-+ *
-+ * Note that it only makes sense to use this for decoding (when you want
-+ * to decode something where you are only interested in one or two of
-+ * the fields); you cannot encode a SKIP!
-+ */
-+const SEC_ASN1Template SEC_SkipTemplate[] = {
-+ {SEC_ASN1_SKIP}
-+};
-+#endif
-+
-+/*
-+ * Find the subjectName in a DER encoded certificate
-+ */
-+const SEC_ASN1Template SEC_CertSubjectTemplate[] = {
-+ {SEC_ASN1_SEQUENCE,
-+ 0, NULL, sizeof(SECItem)} ,
-+ {SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
-+ SEC_ASN1_CONTEXT_SPECIFIC | 0,
-+ 0, SEC_SkipTemplate} , /* version */
-+ {SEC_ASN1_SKIP}, /* serial number */
-+ {SEC_ASN1_SKIP}, /* signature algorithm */
-+ {SEC_ASN1_SKIP}, /* issuer */
-+ {SEC_ASN1_SKIP}, /* validity */
-+ {SEC_ASN1_ANY, 0, NULL}, /* subject */
-+ {SEC_ASN1_SKIP_REST},
-+ {0}
-+};
-+
-+void
-+pem_FetchLabel
-+(
-+ pemInternalObject * io
-+)
-+{
-+ pemCertObject *co = &io->u.cert;
-+
-+ co->label.data = io->nickname;
-+ co->label.size = strlen(io->nickname);
-+}
-+
-+const NSSItem
-+*pem_FetchCertAttribute
-+(
-+ pemInternalObject * io,
-+ CK_ATTRIBUTE_TYPE type
-+)
-+{
-+ switch (type) {
-+ case CKA_CLASS:
-+ plog(" fetch cert CKA_CLASS\n");
-+ return &pem_certClassItem;
-+ case CKA_TOKEN:
-+ plog(" fetch cert CKA_TOKEN\n");
-+ return &pem_trueItem;
-+ case CKA_PRIVATE:
-+ return &pem_falseItem;
-+ case CKA_CERTIFICATE_TYPE:
-+ plog(" fetch cert CKA_CERTIFICATE_TYPE\n");
-+ return &pem_x509Item;
-+ case CKA_LABEL:
-+ if (0 == io->u.cert.label.size) {
-+ pem_FetchLabel(io);
-+ }
-+ plog(" fetch cert CKA_LABEL %s\n", io->u.cert.label.data);
-+ return &io->u.cert.label;
-+ case CKA_SUBJECT:
-+ plog(" fetch cert CKA_SUBJECT size %d\n", io->u.cert.subject.size);
-+ return &io->u.cert.subject;
-+ case CKA_ISSUER:
-+ plog(" fetch cert CKA_ISSUER size %d\n", io->u.cert.issuer.size);
-+ return &io->u.cert.issuer;
-+ case CKA_SERIAL_NUMBER:
-+ plog(" fetch cert CKA_SERIAL_NUMBER size %d value %08x\n", io->u.cert.serial.size, io->u.cert.serial.data);
-+ return &io->u.cert.serial;
-+ case CKA_VALUE:
-+ if (0 == io->u.cert.derCert.size) {
-+ io->u.cert.derCert.data = io->derCert->data;
-+ io->u.cert.derCert.size = io->derCert->len;
-+ }
-+ plog(" fetch cert CKA_VALUE\n");
-+ return &io->u.cert.derCert;
-+ case CKA_ID:
-+ plog(" fetch cert CKA_ID val=%s size=%d\n", (char *) io->id.data,
-+ io->id.size);
-+ return &io->id;
-+ case CKA_TRUSTED:
-+ plog(" fetch cert CKA_TRUSTED: returning NULL\n");
-+ return NULL;
-+ default:
-+ plog(" fetching cert unknown type %d\n", type);
-+ break;
-+ }
-+ return NULL;
-+}
-+
-+const NSSItem *
-+pem_FetchPrivKeyAttribute
-+(
-+ pemInternalObject * io,
-+ CK_ATTRIBUTE_TYPE type
-+)
-+{
-+ PRBool isCertType = (pemCert == io->type);
-+ pemKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-+
-+ switch (type) {
-+ case CKA_CLASS:
-+ return &pem_privKeyClassItem;
-+ case CKA_TOKEN:
-+ case CKA_LOCAL:
-+ case CKA_SIGN:
-+ case CKA_DECRYPT:
-+ case CKA_SIGN_RECOVER:
-+ return &pem_trueItem;
-+ case CKA_SENSITIVE:
-+ case CKA_PRIVATE: /* should move in the future */
-+ case CKA_MODIFIABLE:
-+ case CKA_DERIVE:
-+ case CKA_UNWRAP:
-+ case CKA_EXTRACTABLE: /* will probably move in the future */
-+ case CKA_ALWAYS_SENSITIVE:
-+ case CKA_NEVER_EXTRACTABLE:
-+ return &pem_falseItem;
-+ case CKA_KEY_TYPE:
-+ return &pem_rsaItem;
-+ case CKA_LABEL:
-+ if (!isCertType) {
-+ return &pem_emptyItem;
-+ }
-+ if (0 == io->u.cert.label.size) {
-+ pem_FetchLabel(io);
-+ }
-+ plog(" fetch key CKA_LABEL %s\n", io->u.cert.label.data);
-+ return &io->u.cert.label;
-+ case CKA_SUBJECT:
-+ if (!isCertType) {
-+ return &pem_emptyItem;
-+ }
-+ plog(" fetch key CKA_SUBJECT %s\n", io->u.cert.label.data);
-+ return &io->u.cert.subject;
-+ case CKA_MODULUS:
-+ if (0 == kp->modulus.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_MODULUS\n");
-+ return &kp->modulus;
-+ case CKA_PUBLIC_EXPONENT:
-+ if (0 == kp->modulus.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_PUBLIC_EXPONENT\n");
-+ return &kp->exponent;
-+ case CKA_PRIVATE_EXPONENT:
-+ if (0 == kp->privateExponent.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_PRIVATE_EXPONENT\n");
-+ return &kp->privateExponent;
-+ case CKA_PRIME_1:
-+ if (0 == kp->prime1.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_PRIME_1\n");
-+ return &kp->prime1;
-+ case CKA_PRIME_2:
-+ if (0 == kp->prime2.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_PRIME_2\n");
-+ return &kp->prime2;
-+ case CKA_EXPONENT_1:
-+ if (0 == kp->exponent1.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_EXPONENT_1\n");
-+ return &kp->exponent1;
-+ case CKA_EXPONENT_2:
-+ if (0 == kp->exponent2.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_EXPONENT_2\n");
-+ return &kp->exponent2;
-+ case CKA_COEFFICIENT:
-+ if (0 == kp->coefficient.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ plog(" fetch key CKA_COEFFICIENT_2\n");
-+ return &kp->coefficient;
-+ case CKA_ID:
-+ plog(" fetch key CKA_ID val=%s size=%d\n", (char *) io->id.data,
-+ io->id.size);
-+ return &io->id;
-+ default:
-+ return NULL;
-+ }
-+}
-+
-+const NSSItem *
-+pem_FetchPubKeyAttribute
-+(
-+ pemInternalObject * io,
-+ CK_ATTRIBUTE_TYPE type
-+)
-+{
-+ PRBool isCertType = (pemCert == io->type);
-+ pemKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-+
-+ switch (type) {
-+ case CKA_CLASS:
-+ return &pem_pubKeyClassItem;
-+ case CKA_TOKEN:
-+ case CKA_LOCAL:
-+ case CKA_ENCRYPT:
-+ case CKA_VERIFY:
-+ case CKA_VERIFY_RECOVER:
-+ return &pem_trueItem;
-+ case CKA_PRIVATE:
-+ case CKA_MODIFIABLE:
-+ case CKA_DERIVE:
-+ case CKA_WRAP:
-+ return &pem_falseItem;
-+ case CKA_KEY_TYPE:
-+ return &pem_rsaItem;
-+ case CKA_LABEL:
-+ if (!isCertType) {
-+ return &pem_emptyItem;
-+ }
-+ if (0 == io->u.cert.label.size) {
-+ pem_FetchLabel(io);
-+ }
-+ return &io->u.cert.label;
-+ case CKA_SUBJECT:
-+ if (!isCertType) {
-+ return &pem_emptyItem;
-+ }
-+ return &io->u.cert.subject;
-+ case CKA_MODULUS:
-+ if (0 == kp->modulus.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ return &kp->modulus;
-+ case CKA_PUBLIC_EXPONENT:
-+ if (0 == kp->modulus.size) {
-+ pem_PopulateModulusExponent(io);
-+ }
-+ return &kp->exponent;
-+ case CKA_ID:
-+ return &io->id;
-+ default:
-+ break;
-+ }
-+ return NULL;
-+}
-+
-+const NSSItem *
-+pem_FetchTrustAttribute
-+(
-+ pemInternalObject * io,
-+ CK_ATTRIBUTE_TYPE type
-+)
-+{
-+ static NSSItem hash;
-+ SECStatus rv;
-+
-+ switch (type) {
-+ case CKA_CLASS:
-+ return &pem_trustClassItem;
-+ case CKA_TOKEN:
-+ return &pem_trueItem;
-+ case CKA_PRIVATE:
-+ return &pem_falseItem;
-+ case CKA_CERTIFICATE_TYPE:
-+ return &pem_x509Item;
-+ case CKA_LABEL:
-+ if (0 == io->u.cert.label.size) {
-+ pem_FetchLabel(io);
-+ }
-+ plog(" fetch trust CKA_LABEL %s\n", io->u.cert.label.data);
-+ return &io->u.cert.label;
-+ case CKA_SUBJECT:
-+ plog(" fetch trust CKA_SUBJECT\n");
-+ return NULL;
-+ case CKA_ISSUER:
-+ plog(" fetch trust CKA_ISSUER\n");
-+ return &io->u.cert.issuer;
-+ case CKA_SERIAL_NUMBER:
-+ plog(" fetch trust CKA_SERIAL_NUMBER size %d value %08x\n", io->u.cert.serial.size, io->u.cert.serial.data);
-+ return &io->u.cert.serial;
-+ case CKA_VALUE:
-+ return &pem_trueItem;
-+ case CKA_ID:
-+ plog(" fetch trust CKA_ID val=%s size=%d\n", (char *) io->id.data,
-+ io->id.size);
-+ return &io->id;
-+ case CKA_TRUSTED:
-+ return &pem_trusted;
-+ case CKA_TRUST_SERVER_AUTH:
-+ return &pem_trusted;
-+ case CKA_TRUST_CLIENT_AUTH:
-+ return &pem_trusted;
-+ case CKA_TRUST_CODE_SIGNING:
-+ return &pem_trusted;
-+ case CKA_TRUST_EMAIL_PROTECTION:
-+ return &pem_trusted;
-+ case CKA_TRUST_IPSEC_END_SYSTEM:
-+ return &pem_trusted;
-+ case CKA_TRUST_IPSEC_TUNNEL:
-+ return &pem_trusted;
-+ case CKA_TRUST_IPSEC_USER:
-+ return &pem_trusted;
-+ case CKA_TRUST_TIME_STAMPING:
-+ return &pem_trusted;
-+ case CKA_TRUST_STEP_UP_APPROVED:
-+ return &pem_falseItem;
-+ case CKA_CERT_SHA1_HASH:
-+ hash.size = 0;
-+ hash.data = NULL;
-+ nsslibc_memset(io->u.cert.sha1_hash, 0, SHA1_LENGTH);
-+ rv = SHA1_HashBuf(io->u.cert.sha1_hash, io->derCert->data,
-+ io->derCert->len);
-+ if (rv == SECSuccess) {
-+ hash.data = io->u.cert.sha1_hash;
-+ hash.size = sizeof(io->u.cert.sha1_hash);
-+ }
-+ return &hash;
-+ case CKA_CERT_MD5_HASH:
-+ hash.size = 0;
-+ hash.data = NULL;
-+ nsslibc_memset(io->u.cert.sha1_hash, 0, MD5_LENGTH);
-+ rv = MD5_HashBuf(io->u.cert.sha1_hash, io->derCert->data,
-+ io->derCert->len);
-+ if (rv == SECSuccess) {
-+ hash.data = io->u.cert.sha1_hash;
-+ hash.size = sizeof(io->u.cert.sha1_hash);
-+ }
-+ return &hash;
-+ default:
-+ return &pem_trusted;
-+ break;
-+ }
-+ return NULL;
-+}
-+
-+const NSSItem *
-+pem_FetchAttribute
-+(
-+ pemInternalObject * io,
-+ CK_ATTRIBUTE_TYPE type
-+)
-+{
-+ CK_ULONG i;
-+
-+ if (io->type == pemRaw) {
-+ for (i = 0; i < io->u.raw.n; i++) {
-+ if (type == io->u.raw.types[i]) {
-+ return &io->u.raw.items[i];
-+ }
-+ }
-+ return NULL;
-+ }
-+ /* deal with the common attributes */
-+ switch (io->objClass) {
-+ case CKO_CERTIFICATE:
-+ return pem_FetchCertAttribute(io, type);
-+ case CKO_PRIVATE_KEY:
-+ return pem_FetchPrivKeyAttribute(io, type);
-+ case CKO_NETSCAPE_TRUST:
-+ return pem_FetchTrustAttribute(io, type);
-+ case CKO_PUBLIC_KEY:
-+ return pem_FetchPubKeyAttribute(io, type);
-+ }
-+ return NULL;
-+}
-+
-+/*
-+ * Destroy internal object or list object if refCount becomes zero (after
-+ * decrement). Safe to call with NULL argument.
-+ */
-+void
-+pem_DestroyInternalObject
-+(
-+ pemInternalObject * io
-+)
-+{
-+ if (NULL == io)
-+ /* nothing to destroy */
-+ return;
-+
-+ if (NULL != io->list) {
-+ /* destroy list object */
-+ pemObjectListItem *item = io->list;
-+ while (item) {
-+ pemObjectListItem *next = item->next;
-+
-+ /* recursion of maximal depth 1 */
-+ pem_DestroyInternalObject(item->io);
-+
-+ nss_ZFreeIf(item);
-+ item = next;
-+ }
-+ nss_ZFreeIf(io);
-+ return;
-+ }
-+
-+ io->refCount --;
-+ if (0 < io->refCount)
-+ return;
-+
-+ /* destroy internal object */
-+ switch (io->type) {
-+ case pemRaw:
-+ return;
-+ case pemCert:
-+ nss_ZFreeIf(io->u.cert.labelData);
-+ nss_ZFreeIf(io->u.cert.key.privateKey);
-+ nss_ZFreeIf(io->u.cert.key.pubKey);
-+ /* go through */
-+ case pemTrust:
-+ nss_ZFreeIf(io->id.data);
-+ nss_ZFreeIf(io->nickname);
-+ nss_ZFreeIf(io->derCert->data);
-+ nss_ZFreeIf(io->derCert);
-+ if (io->u.cert.subject.size > 0) {
-+ nss_ZFreeIf(io->u.cert.subject.data);
-+ }
-+ if (io->u.cert.issuer.size > 0) {
-+ nss_ZFreeIf(io->u.cert.issuer.data);
-+ }
-+ if (io->u.cert.serial.size > 0) {
-+ nss_ZFreeIf(io->u.cert.serial.data);
-+ }
-+ break;
-+ case pemBareKey:
-+ SECITEM_FreeItem(io->u.key.key.privateKeyOrig, PR_TRUE);
-+ nss_ZFreeIf(io->u.key.key.coefficient.data);
-+ nss_ZFreeIf(io->u.key.key.exponent2.data);
-+ nss_ZFreeIf(io->u.key.key.exponent1.data);
-+ nss_ZFreeIf(io->u.key.key.prime2.data);
-+ nss_ZFreeIf(io->u.key.key.prime1.data);
-+ nss_ZFreeIf(io->u.key.key.privateExponent.data);
-+ nss_ZFreeIf(io->u.key.key.exponent.data);
-+ nss_ZFreeIf(io->u.key.key.modulus.data);
-+ nss_ZFreeIf(io->u.key.key.privateKey->data);
-+ nss_ZFreeIf(io->u.key.key.privateKey);
-+ nss_ZFreeIf(io->u.key.key.pubKey);
-+ nss_ZFreeIf(io->id.data);
-+ nss_ZFreeIf(io->nickname);
-+ nss_ZFreeIf(io->derCert->data);
-+ nss_ZFreeIf(io->derCert);
-+
-+ /* strdup'd in ReadDERFromFile */
-+ if (io->u.key.ivstring)
-+ free(io->u.key.ivstring);
-+ break;
-+ }
-+
-+ if (NULL != gobj)
-+ /* remove reference to self from the global array */
-+ gobj[io->gobjIndex] = NULL;
-+
-+ nss_ZFreeIf(io);
-+ return;
-+}
-+
-+/*
-+ * Finalize - needed
-+ * Destroy - CKR_SESSION_READ_ONLY
-+ * IsTokenObject - CK_TRUE
-+ * GetAttributeCount
-+ * GetAttributeTypes
-+ * GetAttributeSize
-+ * GetAttribute
-+ * SetAttribute - unneeded
-+ * GetObjectSize - unneeded
-+ */
-+
-+static void
-+pem_mdObject_Finalize
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ pem_DestroyInternalObject((pemInternalObject *) mdObject->etc);
-+}
-+
-+static CK_RV
-+pem_mdObject_Destroy
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ pemInternalObject *io = (pemInternalObject *) mdObject->etc;
-+
-+ pem_DestroyInternalObject(io);
-+ return CKR_OK;
-+}
-+
-+static CK_BBOOL
-+pem_mdObject_IsTokenObject
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return CK_TRUE;
-+}
-+
-+static CK_ULONG
-+pem_mdObject_GetAttributeCount
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ pemInternalObject *io = (pemInternalObject *) mdObject->etc;
-+
-+ if (NULL != io->list) {
-+ /* list object --> use the first item in the list */
-+ NSSCKMDObject *md = &(io->list->io->mdObject);
-+ return md->GetAttributeCount(md, fwObject, mdSession, fwSession,
-+ mdToken, fwToken, mdInstance, fwInstance,
-+ pError);
-+ }
-+
-+ if (pemRaw == io->type) {
-+ return io->u.raw.n;
-+ }
-+ switch (io->objClass) {
-+ case CKO_CERTIFICATE:
-+ return certAttrsCount;
-+ case CKO_PUBLIC_KEY:
-+ return pubKeyAttrsCount;
-+ case CKO_PRIVATE_KEY:
-+ return privKeyAttrsCount;
-+ case CKO_NETSCAPE_TRUST:
-+ return trustAttrsCount;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static CK_RV
-+pem_mdObject_GetAttributeTypes
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_ATTRIBUTE_TYPE_PTR typeArray,
-+ CK_ULONG ulCount
-+)
-+{
-+ pemInternalObject *io = (pemInternalObject *) mdObject->etc;
-+ CK_ULONG i;
-+ CK_RV error = CKR_OK;
-+ const CK_ATTRIBUTE_TYPE *attrs = NULL;
-+ CK_ULONG size;
-+
-+ if (NULL != io->list) {
-+ /* list object --> use the first item in the list */
-+ NSSCKMDObject *md = &(io->list->io->mdObject);
-+ return md->GetAttributeTypes(md, fwObject, mdSession, fwSession,
-+ mdToken, fwToken, mdInstance, fwInstance,
-+ typeArray, ulCount);
-+ }
-+
-+ size = pem_mdObject_GetAttributeCount(mdObject, fwObject, mdSession,
-+ fwSession, mdToken, fwToken, mdInstance,
-+ fwInstance, &error);
-+
-+ if (size != ulCount) {
-+ return CKR_BUFFER_TOO_SMALL;
-+ }
-+ if (io->type == pemRaw) {
-+ attrs = io->u.raw.types;
-+ } else
-+ switch (io->objClass) {
-+ case CKO_CERTIFICATE:
-+ attrs = certAttrs;
-+ break;
-+ case CKO_PUBLIC_KEY:
-+ attrs = pubKeyAttrs;
-+ break;
-+ case CKO_PRIVATE_KEY:
-+ attrs = privKeyAttrs;
-+ break;
-+ default:
-+ return CKR_OK;
-+ }
-+
-+ for (i = 0; i < size; i++) {
-+ typeArray[i] = attrs[i];
-+ }
-+
-+ return CKR_OK;
-+}
-+
-+static CK_ULONG
-+pem_mdObject_GetAttributeSize
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_ATTRIBUTE_TYPE attribute,
-+ CK_RV * pError
-+)
-+{
-+ pemInternalObject *io = (pemInternalObject *) mdObject->etc;
-+ const NSSItem *b;
-+
-+ if (NULL != io->list) {
-+ /* list object --> use the first item in the list */
-+ NSSCKMDObject *md = &(io->list->io->mdObject);
-+ return md->GetAttributeSize(md, fwObject, mdSession, fwSession,
-+ mdToken, fwToken, mdInstance, fwInstance,
-+ attribute, pError);
-+ }
-+
-+ b = pem_FetchAttribute(io, attribute);
-+
-+ if ((const NSSItem *) NULL == b) {
-+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
-+ return 0;
-+ }
-+ return b->size;
-+}
-+
-+static NSSCKFWItem
-+pem_mdObject_GetAttribute
-+(
-+ NSSCKMDObject * mdObject,
-+ NSSCKFWObject * fwObject,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_ATTRIBUTE_TYPE attribute,
-+ CK_RV * pError
-+)
-+{
-+ NSSCKFWItem mdItem;
-+ pemInternalObject *io = (pemInternalObject *) mdObject->etc;
-+
-+ if (NULL != io->list) {
-+ /* list object --> use the first item in the list */
-+ NSSCKMDObject *md = &(io->list->io->mdObject);
-+ return md->GetAttribute(md, fwObject, mdSession, fwSession,
-+ mdToken, fwToken, mdInstance, fwInstance,
-+ attribute, pError);
-+ }
-+
-+ mdItem.needsFreeing = PR_FALSE;
-+ mdItem.item = (NSSItem *) pem_FetchAttribute(io, attribute);
-+
-+ if ((NSSItem *) NULL == mdItem.item) {
-+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
-+ }
-+
-+ return mdItem;
-+}
-+
-+/*
-+ * get an attribute from a template. Value is returned in NSS item.
-+ * data for the item is owned by the template.
-+ */
-+CK_RV
-+pem_GetAttribute
-+(
-+ CK_ATTRIBUTE_TYPE type,
-+ CK_ATTRIBUTE * template,
-+ CK_ULONG templateSize,
-+ NSSItem * item
-+)
-+{
-+ CK_ULONG i;
-+
-+ for (i = 0; i < templateSize; i++) {
-+ if (template[i].type == type) {
-+ item->data = template[i].pValue;
-+ item->size = template[i].ulValueLen;
-+ return CKR_OK;
-+ }
-+ }
-+ return CKR_TEMPLATE_INCOMPLETE;
-+}
-+
-+/*
-+ * get an attribute which is type CK_ULONG.
-+ */
-+CK_ULONG
-+pem_GetULongAttribute
-+(
-+ CK_ATTRIBUTE_TYPE type,
-+ CK_ATTRIBUTE * template,
-+ CK_ULONG templateSize,
-+ CK_RV * pError
-+)
-+{
-+ NSSItem item;
-+
-+ *pError = pem_GetAttribute(type, template, templateSize, &item);
-+ if (CKR_OK != *pError) {
-+ return (CK_ULONG) 0;
-+ }
-+ if (item.size != sizeof(CK_ULONG)) {
-+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
-+ return (CK_ULONG) 0;
-+ }
-+ return *(CK_ULONG *) item.data;
-+}
-+
-+/*
-+ * get an attribute which is type CK_BBOOL.
-+ */
-+CK_BBOOL
-+pem_GetBoolAttribute
-+(
-+ CK_ATTRIBUTE_TYPE type,
-+ CK_ATTRIBUTE * template,
-+ CK_ULONG templateSize,
-+ CK_RV * pError
-+)
-+{
-+ NSSItem item;
-+
-+ *pError = pem_GetAttribute(type, template, templateSize, &item);
-+ if (CKR_OK != *pError) {
-+ return (CK_BBOOL) 0;
-+ }
-+ if (item.size != sizeof(CK_BBOOL)) {
-+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
-+ return (CK_BBOOL) 0;
-+ }
-+ return *(CK_BBOOL *) item.data;
-+}
-+
-+/*
-+ * Get a string attribute. Caller needs to free this.
-+ */
-+char *
-+pem_GetStringAttribute
-+(
-+ CK_ATTRIBUTE_TYPE type,
-+ CK_ATTRIBUTE * template,
-+ CK_ULONG templateSize,
-+ CK_RV * pError
-+)
-+{
-+ NSSItem item;
-+ char *str;
-+
-+ /* get the attribute */
-+ *pError = pem_GetAttribute(type, template, templateSize, &item);
-+ if (CKR_OK != *pError) {
-+ return (char *) NULL;
-+ }
-+ /* make sure it is null terminated */
-+ str = nss_ZNEWARRAY(NULL, char, item.size + 1);
-+ if ((char *) NULL == str) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (char *) NULL;
-+ }
-+
-+ nsslibc_memcpy(str, item.data, item.size);
-+ str[item.size] = 0;
-+
-+ return str;
-+}
-+
-+static const NSSCKMDObject
-+pem_prototype_mdObject = {
-+ (void *) NULL, /* etc */
-+ pem_mdObject_Finalize,
-+ pem_mdObject_Destroy,
-+ pem_mdObject_IsTokenObject,
-+ pem_mdObject_GetAttributeCount,
-+ pem_mdObject_GetAttributeTypes,
-+ pem_mdObject_GetAttributeSize,
-+ pem_mdObject_GetAttribute,
-+ NULL, /* FreeAttribute */
-+ NULL, /* SetAttribute */
-+ NULL, /* GetObjectSize */
-+ (void *) NULL /* null terminator */
-+};
-+
-+NSS_IMPLEMENT NSSCKMDObject *
-+pem_CreateMDObject
-+(
-+ NSSArena * arena,
-+ pemInternalObject * io,
-+ CK_RV * pError
-+)
-+{
-+ if ((void *) NULL == io->mdObject.etc) {
-+ (void) nsslibc_memcpy(&io->mdObject, &pem_prototype_mdObject,
-+ sizeof(pem_prototype_mdObject));
-+ io->mdObject.etc = (void *) io;
-+ }
-+
-+ return &io->mdObject;
-+}
-+
-+/*
-+ * Each object has an identifier. For a certificate and key pair this id
-+ * needs to be the same so we use the right combination. If the target object
-+ * is a key we first look to see if its certificate was already added and if
-+ * so, use that id. The same thing is done when a key is added.
-+ */
-+NSS_EXTERN NSSCKMDObject *
-+pem_CreateObject
-+(
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV * pError
-+)
-+{
-+ CK_OBJECT_CLASS objClass;
-+ CK_BBOOL isToken;
-+ NSSCKFWSlot *fwSlot;
-+ CK_SLOT_ID slotID;
-+ CK_BBOOL cacert;
-+ char *filename;
-+ SECItem **derlist = NULL;
-+ int nobjs = 0;
-+ int i;
-+ int objid;
-+ pemToken *token;
-+ int cipher;
-+ char *ivstring = NULL;
-+ pemInternalObject *listObj = NULL;
-+ pemObjectListItem *listItem = NULL;
-+
-+ /*
-+ * only create token objects
-+ */
-+ isToken = pem_GetBoolAttribute(CKA_TOKEN, pTemplate,
-+ ulAttributeCount, pError);
-+ if (CKR_OK != *pError) {
-+ return (NSSCKMDObject *) NULL;
-+ }
-+ if (!isToken) {
-+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
-+ return (NSSCKMDObject *) NULL;
-+ }
-+
-+ /* What slot are we adding the object to? */
-+ fwSlot = nssCKFWSession_GetFWSlot(fwSession);
-+ if ((NSSCKFWSlot *) NULL == fwSlot) {
-+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
-+ *pError = CKR_GENERAL_ERROR;
-+ return (NSSCKMDObject *) NULL;
-+
-+ }
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ token = (pemToken *) mdToken->etc;
-+
-+ /*
-+ * only create keys and certs.
-+ */
-+ objClass = pem_GetULongAttribute(CKA_CLASS, pTemplate,
-+ ulAttributeCount, pError);
-+ if (CKR_OK != *pError) {
-+ return (NSSCKMDObject *) NULL;
-+ }
-+
-+ cacert = pem_GetBoolAttribute(CKA_TRUST, pTemplate,
-+ ulAttributeCount, pError);
-+
-+ filename = pem_GetStringAttribute(CKA_LABEL, pTemplate,
-+ ulAttributeCount, pError);
-+ if (CKR_OK != *pError) {
-+ return (NSSCKMDObject *) NULL;
-+ }
-+
-+#ifdef notdef
-+ if (objClass == CKO_PUBLIC_KEY) {
-+ return CKR_OK; /* fake public key creation, happens as a side effect of
-+ * private key creation */
-+ }
-+#endif
-+
-+ listObj = nss_ZNEW(NULL, pemInternalObject);
-+ if (NULL == listObj) {
-+ nss_ZFreeIf(filename);
-+ return NULL;
-+ }
-+
-+ listItem = listObj->list = nss_ZNEW(NULL, pemObjectListItem);
-+ if (NULL == listItem) {
-+ nss_ZFreeIf(listObj);
-+ nss_ZFreeIf(filename);
-+ return NULL;
-+ }
-+
-+ if (objClass == CKO_CERTIFICATE) {
-+ nobjs = ReadDERFromFile(&derlist, filename, PR_TRUE, &cipher, &ivstring, PR_TRUE /* certs only */);
-+ if (nobjs < 1)
-+ goto loser;
-+
-+ /* We're just adding a cert, we'll assume the key is next */
-+ objid = pem_nobjs + 1;
-+
-+ if (cacert) {
-+ /* Add the certificate. There may be more than one */
-+ int c;
-+ for (c = 0; c < nobjs; c++) {
-+ char nickname[1024];
-+ objid = pem_nobjs + 1;
-+
-+ PR_snprintf(nickname, 1024, "%s - %d", filename, c);
-+
-+ if (c)
-+ APPEND_LIST_ITEM(listItem);
-+ listItem->io = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert,
-+ derlist[c], NULL, nickname, 0,
-+ slotID, NULL);
-+ if (listItem->io == NULL)
-+ goto loser;
-+
-+ /* Add the trust object */
-+ APPEND_LIST_ITEM(listItem);
-+ listItem->io = AddObjectIfNeeded(CKO_NETSCAPE_TRUST, pemTrust,
-+ derlist[c], NULL, nickname, 0,
-+ slotID, NULL);
-+ if (listItem->io == NULL)
-+ goto loser;
-+ }
-+ } else {
-+ listItem->io = AddObjectIfNeeded(CKO_CERTIFICATE, pemCert,
-+ derlist[0], NULL, filename, objid,
-+ slotID, NULL);
-+ if (listItem->io == NULL)
-+ goto loser;
-+ }
-+ } else if (objClass == CKO_PRIVATE_KEY) {
-+ /* Brute force: find the id of the certificate, if any, in this slot */
-+ int i;
-+ SECItem certDER;
-+ CK_SESSION_HANDLE hSession;
-+ PRBool added;
-+
-+ nobjs = ReadDERFromFile(&derlist, filename, PR_TRUE, &cipher, &ivstring, PR_FALSE /* keys only */);
-+ if (nobjs < 1)
-+ goto loser;
-+
-+ certDER.len = 0; /* in case there is no equivalent cert */
-+ certDER.data = NULL;
-+
-+ objid = -1;
-+ for (i = 0; i < pem_nobjs; i++) {
-+ if (NULL == gobj[i])
-+ continue;
-+
-+ if ((slotID == gobj[i]->slotID) && (gobj[i]->type == pemCert)) {
-+ objid = atoi(gobj[i]->id.data);
-+ certDER.data =
-+ (void *) nss_ZAlloc(NULL, gobj[i]->derCert->len);
-+
-+ if (certDER.data == NULL)
-+ goto loser;
-+
-+ certDER.len = gobj[i]->derCert->len;
-+ nsslibc_memcpy(certDER.data, gobj[i]->derCert->data,
-+ gobj[i]->derCert->len);
-+ }
-+ }
-+
-+ /* We're just adding a key, we'll assume the cert is next */
-+ if (objid == -1)
-+ objid = pem_nobjs + 1;
-+
-+ listItem->io = AddObjectIfNeeded(CKO_PRIVATE_KEY, pemBareKey, &certDER,
-+ derlist[0], filename, objid, slotID,
-+ &added);
-+ if (listItem->io == NULL)
-+ goto loser;
-+
-+ listItem->io->u.key.ivstring = ivstring;
-+ listItem->io->u.key.cipher = cipher;
-+ nss_ZFreeIf(certDER.data);
-+
-+ /* If the key was encrypted then free the session to make it appear that
-+ * the token was removed so we can force a login.
-+ */
-+ if (cipher && added) {
-+ /* FIXME: Why 1.0s? Is it enough? Isn't it too much?
-+ * What about e.g. 3.14s? */
-+ PRIntervalTime onesec = PR_SecondsToInterval(1);
-+ token_needsLogin[slotID - 1] = PR_TRUE;
-+
-+ /* We have to sleep so that NSS will notice that the token was
-+ * removed.
-+ */
-+ PR_Sleep(onesec);
-+ hSession =
-+ nssCKFWInstance_FindSessionHandle(fwInstance, fwSession);
-+ nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
-+ } else {
-+ *pError = CKR_KEY_UNEXTRACTABLE;
-+ }
-+ } else {
-+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
-+ }
-+
-+ loser:
-+
-+ for (i = 0; i < nobjs; i++) {
-+ free(derlist[i]->data);
-+ free(derlist[i]);
-+ }
-+ nss_ZFreeIf(filename);
-+ nss_ZFreeIf(derlist);
-+ if ((pemInternalObject *) NULL == listItem->io) {
-+ pem_DestroyInternalObject(listObj);
-+ return (NSSCKMDObject *) NULL;
-+ }
-+ return pem_CreateMDObject(NULL, listObj, pError);
-+}
-diff --git a/a/nss/lib/ckfw/pem/prsa.c b/b/nss/lib/ckfw/pem/prsa.c
-new file mode 100644
-index 0000000..d42e9f7
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/prsa.c
-@@ -0,0 +1,702 @@
-+/* ***** BEGIN LICENSE BLOCK *****
-+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
-+ *
-+ * The contents of this file are subject to the Mozilla Public License Version
-+ * 1.1 (the "License"); you may not use this file except in compliance with
-+ * the License. You may obtain a copy of the License at
-+ * http://www.mozilla.org/MPL/
-+ *
-+ * Software distributed under the License is distributed on an "AS IS" basis,
-+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-+ * for the specific language governing rights and limitations under the
-+ * License.
-+ *
-+ * The Original Code is the Netscape security libraries.
-+ *
-+ * The Initial Developer of the Original Code is
-+ * Netscape Communications Corporation.
-+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
-+ * the Initial Developer. All Rights Reserved.
-+ *
-+ * Contributor(s):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+#include "secdert.h"
-+#include "secoid.h"
-+#include "nssckmdt.h"
-+
-+#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
-+
-+SEC_ASN1_MKSUB(SEC_AnyTemplate)
-+SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
-+
-+/*
-+ * prsa.c
-+ *
-+ * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects
-+ * for the RSA operation.
-+ */
-+
-+const SEC_ASN1Template pem_RSAPrivateKeyTemplate[] = {
-+ {SEC_ASN1_SEQUENCE, 0, NULL, sizeof(pemLOWKEYPrivateKey)} ,
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.version)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.modulus)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.publicExponent)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.privateExponent)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.prime1)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.prime2)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.exponent1)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.exponent2)},
-+ {SEC_ASN1_INTEGER, offsetof(pemLOWKEYPrivateKey, u.rsa.coefficient)},
-+ {0}
-+};
-+
-+static const SEC_ASN1Template pem_AttributeTemplate[] = {
-+ { SEC_ASN1_SEQUENCE,
-+ 0, NULL, sizeof(NSSLOWKEYAttribute) },
-+ { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
-+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
-+ SEC_ASN1_SUB(SEC_AnyTemplate) },
-+ { 0 }
-+};
-+
-+static const SEC_ASN1Template pem_SetOfAttributeTemplate[] = {
-+ { SEC_ASN1_SET_OF, 0, pem_AttributeTemplate },
-+};
-+
-+const SEC_ASN1Template pem_PrivateKeyInfoTemplate[] = {
-+ { SEC_ASN1_SEQUENCE,
-+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
-+ { SEC_ASN1_INTEGER,
-+ offsetof(NSSLOWKEYPrivateKeyInfo,version) },
-+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
-+ offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
-+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
-+ { SEC_ASN1_OCTET_STRING,
-+ offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
-+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
-+ offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
-+ pem_SetOfAttributeTemplate },
-+ { 0 }
-+};
-+
-+/* Declarations */
-+SECStatus pem_RSA_Sign(pemLOWKEYPrivateKey * key, unsigned char *output,
-+ unsigned int *outputLen, unsigned int maxOutputLen,
-+ unsigned char *input, unsigned int inputLen);
-+SECStatus pem_RSA_DecryptBlock(pemLOWKEYPrivateKey * key,
-+ unsigned char *output, unsigned int *outputLen,
-+ unsigned int maxOutputLen, unsigned char *input,
-+ unsigned int inputLen);
-+
-+void prepare_low_rsa_priv_key_for_asn1(pemLOWKEYPrivateKey * key)
-+{
-+ key->u.rsa.modulus.type = siUnsignedInteger;
-+ key->u.rsa.publicExponent.type = siUnsignedInteger;
-+ key->u.rsa.privateExponent.type = siUnsignedInteger;
-+ key->u.rsa.prime1.type = siUnsignedInteger;
-+ key->u.rsa.prime2.type = siUnsignedInteger;
-+ key->u.rsa.exponent1.type = siUnsignedInteger;
-+ key->u.rsa.exponent2.type = siUnsignedInteger;
-+ key->u.rsa.coefficient.type = siUnsignedInteger;
-+}
-+
-+unsigned int
-+pem_PrivateModulusLen(pemLOWKEYPrivateKey * privk)
-+{
-+
-+ unsigned char b0;
-+
-+ switch (privk->keyType) {
-+ case pemLOWKEYRSAKey:
-+ b0 = privk->u.rsa.modulus.data[0];
-+ return b0 ? privk->u.rsa.modulus.len : privk->u.rsa.modulus.len -
-+ 1;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+struct SFTKHashSignInfoStr {
-+ SECOidTag hashOid;
-+ pemLOWKEYPrivateKey *key;
-+};
-+typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
-+
-+void
-+pem_DestroyPrivateKey(pemLOWKEYPrivateKey * privk)
-+{
-+ if (privk && privk->arena) {
-+ PORT_FreeArena(privk->arena, PR_TRUE);
-+ }
-+ nss_ZFreeIf(privk);
-+}
-+
-+/* decode and parse the rawkey into the lpk structure */
-+static pemLOWKEYPrivateKey *
-+pem_getPrivateKey(PLArenaPool *arena, SECItem *rawkey, CK_RV * pError, NSSItem *modulus)
-+{
-+ pemLOWKEYPrivateKey *lpk = NULL;
-+ SECStatus rv = SECFailure;
-+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
-+ SECItem *keysrc = NULL;
-+
-+ /* make sure SECOID is initialized - not sure why we have to do this outside of nss_Init */
-+ if (SECSuccess != (rv = SECOID_Init())) {
-+ *pError = CKR_GENERAL_ERROR;
-+ return NULL; /* wha???? */
-+ }
-+
-+ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
-+ sizeof(NSSLOWKEYPrivateKeyInfo));
-+ if(!pki) {
-+ *pError = CKR_HOST_MEMORY;
-+ goto done;
-+ }
-+
-+ /* let's first see if this is a "raw" RSA private key or an RSA private key in PKCS#8 format */
-+ rv = SEC_ASN1DecodeItem(arena, pki, pem_PrivateKeyInfoTemplate, rawkey);
-+ if (rv != SECSuccess) {
-+ /* not PKCS#8 - assume it's a "raw" RSA private key */
-+ keysrc = rawkey;
-+ } else if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_ENCRYPTION) {
-+ keysrc = &pki->privateKey;
-+ } else { /* unsupported */
-+ *pError = CKR_FUNCTION_NOT_SUPPORTED;
-+ goto done;
-+ }
-+
-+ lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
-+ sizeof(pemLOWKEYPrivateKey));
-+ if (lpk == NULL) {
-+ *pError = CKR_HOST_MEMORY;
-+ goto done;
-+ }
-+
-+ lpk->arena = arena;
-+ lpk->keyType = pemLOWKEYRSAKey;
-+ prepare_low_rsa_priv_key_for_asn1(lpk);
-+
-+ /* I don't know what this is supposed to accomplish. We free the old
-+ modulus data and set it again, making a copy of the new data.
-+ But we just allocated a new empty key structure above with
-+ nss_ZAlloc. So lpk->u.rsa.modulus.data is NULL and
-+ lpk->u.rsa.modulus.len. If the intention is to free the old
-+ modulus data, why not just set it to NULL after freeing? Why
-+ go through this unnecessary and confusing copying code?
-+ */
-+ if (modulus) {
-+ nss_ZFreeIf(modulus->data);
-+ modulus->data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
-+ modulus->size = lpk->u.rsa.modulus.len;
-+ nsslibc_memcpy(modulus->data, lpk->u.rsa.modulus.data,
-+ lpk->u.rsa.modulus.len);
-+ }
-+
-+ /* decode the private key and any algorithm parameters */
-+ rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
-+ keysrc);
-+
-+ if (rv != SECSuccess) {
-+ goto done;
-+ }
-+
-+done:
-+ return lpk;
-+}
-+
-+void
-+pem_PopulateModulusExponent(pemInternalObject * io)
-+{
-+ const NSSItem *classItem = pem_FetchAttribute(io, CKA_CLASS);
-+ const NSSItem *keyType = pem_FetchAttribute(io, CKA_KEY_TYPE);
-+ pemLOWKEYPrivateKey *lpk = NULL;
-+ PLArenaPool *arena;
-+ CK_RV pError = 0;
-+
-+ /* make sure we have the right objects */
-+ if (((const NSSItem *) NULL == classItem) ||
-+ (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
-+ (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *) classItem->data) ||
-+ ((const NSSItem *) NULL == keyType) ||
-+ (sizeof(CK_KEY_TYPE) != keyType->size) ||
-+ (CKK_RSA != *(CK_KEY_TYPE *) keyType->data)) {
-+ return;
-+ }
-+
-+ arena = PORT_NewArena(2048);
-+ if (!arena) {
-+ return;
-+ }
-+
-+ lpk = pem_getPrivateKey(arena, io->u.key.key.privateKey, &pError, NULL);
-+ if (lpk == NULL) {
-+ PORT_FreeArena(arena, PR_FALSE);
-+ return;
-+ }
-+
-+ nss_ZFreeIf(io->u.key.key.modulus.data);
-+ io->u.key.key.modulus.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
-+ io->u.key.key.modulus.size = lpk->u.rsa.modulus.len;
-+ nsslibc_memcpy(io->u.key.key.modulus.data, lpk->u.rsa.modulus.data,
-+ lpk->u.rsa.modulus.len);
-+
-+ nss_ZFreeIf(io->u.key.key.exponent.data);
-+ io->u.key.key.exponent.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.publicExponent.len);
-+ io->u.key.key.exponent.size = lpk->u.rsa.publicExponent.len;
-+ nsslibc_memcpy(io->u.key.key.exponent.data,
-+ lpk->u.rsa.publicExponent.data,
-+ lpk->u.rsa.publicExponent.len);
-+
-+ nss_ZFreeIf(io->u.key.key.privateExponent.data);
-+ io->u.key.key.privateExponent.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.privateExponent.len);
-+ io->u.key.key.privateExponent.size = lpk->u.rsa.privateExponent.len;
-+ nsslibc_memcpy(io->u.key.key.privateExponent.data,
-+ lpk->u.rsa.privateExponent.data,
-+ lpk->u.rsa.privateExponent.len);
-+
-+ nss_ZFreeIf(io->u.key.key.prime1.data);
-+ io->u.key.key.prime1.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.prime1.len);
-+ io->u.key.key.prime1.size = lpk->u.rsa.prime1.len;
-+ nsslibc_memcpy(io->u.key.key.prime1.data, lpk->u.rsa.prime1.data,
-+ lpk->u.rsa.prime1.len);
-+
-+ nss_ZFreeIf(io->u.key.key.prime2.data);
-+ io->u.key.key.prime2.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.prime2.len);
-+ io->u.key.key.prime2.size = lpk->u.rsa.prime2.len;
-+ nsslibc_memcpy(io->u.key.key.prime2.data, lpk->u.rsa.prime2.data,
-+ lpk->u.rsa.prime2.len);
-+
-+ nss_ZFreeIf(io->u.key.key.exponent1.data);
-+ io->u.key.key.exponent1.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.exponent1.len);
-+ io->u.key.key.exponent1.size = lpk->u.rsa.exponent1.len;
-+ nsslibc_memcpy(io->u.key.key.exponent1.data, lpk->u.rsa.exponent1.data,
-+ lpk->u.rsa.exponent1.len);
-+
-+ nss_ZFreeIf(io->u.key.key.exponent2.data);
-+ io->u.key.key.exponent2.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.exponent2.len);
-+ io->u.key.key.exponent2.size = lpk->u.rsa.exponent2.len;
-+ nsslibc_memcpy(io->u.key.key.exponent2.data, lpk->u.rsa.exponent2.data,
-+ lpk->u.rsa.exponent2.len);
-+
-+ nss_ZFreeIf(io->u.key.key.coefficient.data);
-+ io->u.key.key.coefficient.data =
-+ (void *) nss_ZAlloc(NULL, lpk->u.rsa.coefficient.len);
-+ io->u.key.key.coefficient.size = lpk->u.rsa.coefficient.len;
-+ nsslibc_memcpy(io->u.key.key.coefficient.data,
-+ lpk->u.rsa.coefficient.data,
-+ lpk->u.rsa.coefficient.len);
-+
-+ pem_DestroyPrivateKey(lpk);
-+ return;
-+}
-+
-+typedef struct pemInternalCryptoOperationRSAPrivStr
-+ pemInternalCryptoOperationRSAPriv;
-+struct pemInternalCryptoOperationRSAPrivStr
-+{
-+ NSSCKMDCryptoOperation mdOperation;
-+ NSSCKMDMechanism *mdMechanism;
-+ pemInternalObject *iKey;
-+ pemLOWKEYPrivateKey *lpk;
-+ NSSItem *buffer;
-+};
-+
-+/*
-+ * pem_mdCryptoOperationRSAPriv_Create
-+ */
-+static NSSCKMDCryptoOperation *
-+pem_mdCryptoOperationRSAPriv_Create
-+(
-+ const NSSCKMDCryptoOperation * proto,
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKMDObject * mdKey,
-+ CK_RV * pError
-+)
-+{
-+ pemInternalObject *iKey = (pemInternalObject *) mdKey->etc;
-+ const NSSItem *classItem = pem_FetchAttribute(iKey, CKA_CLASS);
-+ const NSSItem *keyType = pem_FetchAttribute(iKey, CKA_KEY_TYPE);
-+ pemInternalCryptoOperationRSAPriv *iOperation;
-+ pemLOWKEYPrivateKey *lpk = NULL;
-+ PLArenaPool *arena;
-+
-+ /* make sure we have the right objects */
-+ if (((const NSSItem *) NULL == classItem) ||
-+ (sizeof(CK_OBJECT_CLASS) != classItem->size) ||
-+ (CKO_PRIVATE_KEY != *(CK_OBJECT_CLASS *) classItem->data) ||
-+ ((const NSSItem *) NULL == keyType) ||
-+ (sizeof(CK_KEY_TYPE) != keyType->size) ||
-+ (CKK_RSA != *(CK_KEY_TYPE *) keyType->data)) {
-+ *pError = CKR_KEY_TYPE_INCONSISTENT;
-+ return (NSSCKMDCryptoOperation *) NULL;
-+ }
-+
-+ arena = PORT_NewArena(2048);
-+ if (!arena) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDCryptoOperation *) NULL;
-+ }
-+
-+ lpk = pem_getPrivateKey(arena, iKey->u.key.key.privateKey, pError, &iKey->u.key.key.modulus);
-+ if (lpk == NULL) {
-+ PORT_FreeArena(arena, PR_FALSE);
-+ return (NSSCKMDCryptoOperation *) NULL;
-+ }
-+
-+ iOperation = nss_ZNEW(NULL, pemInternalCryptoOperationRSAPriv);
-+ if ((pemInternalCryptoOperationRSAPriv *) NULL == iOperation) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDCryptoOperation *) NULL;
-+ }
-+ iOperation->mdMechanism = mdMechanism;
-+ iOperation->iKey = iKey;
-+ iOperation->lpk = lpk;
-+
-+ nsslibc_memcpy(&iOperation->mdOperation,
-+ proto, sizeof(NSSCKMDCryptoOperation));
-+ iOperation->mdOperation.etc = iOperation;
-+
-+ return &iOperation->mdOperation;
-+}
-+
-+static void
-+pem_mdCryptoOperationRSAPriv_Destroy
-+(
-+ NSSCKMDCryptoOperation * mdOperation,
-+ NSSCKFWCryptoOperation * fwOperation,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ pemInternalCryptoOperationRSAPriv *iOperation =
-+ (pemInternalCryptoOperationRSAPriv *) mdOperation->etc;
-+
-+ if (iOperation->buffer) {
-+ nssItem_Destroy(iOperation->buffer);
-+ iOperation->buffer = NULL;
-+ }
-+ pem_DestroyPrivateKey(iOperation->lpk);
-+ iOperation->lpk = NULL;
-+ nss_ZFreeIf(iOperation);
-+}
-+
-+static CK_ULONG
-+pem_mdCryptoOperationRSA_GetFinalLength
-+(
-+ NSSCKMDCryptoOperation * mdOperation,
-+ NSSCKFWCryptoOperation * fwOperation,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ pemInternalCryptoOperationRSAPriv *iOperation =
-+ (pemInternalCryptoOperationRSAPriv *) mdOperation->etc;
-+ const NSSItem *modulus =
-+ pem_FetchAttribute(iOperation->iKey, CKA_MODULUS);
-+
-+ if (NULL == modulus) {
-+ *pError = CKR_FUNCTION_FAILED;
-+ return 0;
-+ }
-+
-+ return modulus->size;
-+}
-+
-+
-+/*
-+ * pem_mdCryptoOperationRSADecrypt_GetOperationLength
-+ * we won't know the length until we actually decrypt the
-+ * input block. Since we go to all the work to decrypt the
-+ * the block, we'll save if for when the block is asked for
-+ */
-+static CK_ULONG
-+pem_mdCryptoOperationRSADecrypt_GetOperationLength
-+(
-+ NSSCKMDCryptoOperation * mdOperation,
-+ NSSCKFWCryptoOperation * fwOperation,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ const NSSItem * input,
-+ CK_RV * pError
-+)
-+{
-+ pemInternalCryptoOperationRSAPriv *iOperation =
-+ (pemInternalCryptoOperationRSAPriv *) mdOperation->etc;
-+ SECStatus rv;
-+
-+ /* FIXME: Just because Microsoft is broken doesn't mean I have to be.
-+ * but this is faster to do for now */
-+
-+ /* Microsoft's Decrypt operation works in place. Since we don't want
-+ * to trash our input buffer, we make a copy of it */
-+ iOperation->buffer = nssItem_Duplicate((NSSItem *) input, NULL, NULL);
-+ if ((NSSItem *) NULL == iOperation->buffer) {
-+ *pError = CKR_HOST_MEMORY;
-+ return 0;
-+ }
-+
-+ rv = pem_RSA_DecryptBlock(iOperation->lpk, iOperation->buffer->data,
-+ &iOperation->buffer->size,
-+ iOperation->buffer->size, input->data,
-+ input->size);
-+
-+ if (rv != SECSuccess) {
-+ return 0;
-+ }
-+
-+ return iOperation->buffer->size;
-+}
-+
-+/*
-+ * pem_mdCryptoOperationRSADecrypt_UpdateFinal
-+ *
-+ * NOTE: pem_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
-+ * have been called previously.
-+ */
-+static CK_RV
-+pem_mdCryptoOperationRSADecrypt_UpdateFinal
-+(
-+ NSSCKMDCryptoOperation * mdOperation,
-+ NSSCKFWCryptoOperation * fwOperation,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ const NSSItem * input,
-+ NSSItem * output
-+)
-+{
-+ pemInternalCryptoOperationRSAPriv *iOperation =
-+ (pemInternalCryptoOperationRSAPriv *) mdOperation->etc;
-+ NSSItem *buffer = iOperation->buffer;
-+
-+ if ((NSSItem *) NULL == buffer) {
-+ return CKR_GENERAL_ERROR;
-+ }
-+ nsslibc_memcpy(output->data, buffer->data, buffer->size);
-+ output->size = buffer->size;
-+ return CKR_OK;
-+}
-+
-+/*
-+ * pem_mdCryptoOperationRSASign_UpdateFinal
-+ *
-+ */
-+static CK_RV
-+pem_mdCryptoOperationRSASign_UpdateFinal
-+(
-+ NSSCKMDCryptoOperation * mdOperation,
-+ NSSCKFWCryptoOperation * fwOperation,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ const NSSItem * input,
-+ NSSItem * output
-+)
-+{
-+ pemInternalCryptoOperationRSAPriv *iOperation =
-+ (pemInternalCryptoOperationRSAPriv *) mdOperation->etc;
-+ CK_RV error = CKR_OK;
-+ SECStatus rv = SECSuccess;
-+
-+ rv = pem_RSA_Sign(iOperation->lpk, output->data, &output->size,
-+ output->size, input->data, input->size);
-+
-+ if (rv != SECSuccess) {
-+ error = CKR_GENERAL_ERROR;
-+ }
-+
-+ return error;
-+}
-+
-+NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-+pem_mdCryptoOperationRSADecrypt_proto = {
-+ NULL, /* etc */
-+ pem_mdCryptoOperationRSAPriv_Destroy,
-+ NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
-+ pem_mdCryptoOperationRSADecrypt_GetOperationLength,
-+ NULL, /* Final - not needed for one shot operation */
-+ NULL, /* Update - not needed for one shot operation */
-+ NULL, /* DigestUpdate - not needed for one shot operation */
-+ pem_mdCryptoOperationRSADecrypt_UpdateFinal,
-+ NULL, /* UpdateCombo - not needed for one shot operation */
-+ NULL, /* DigestKey - not needed for one shot operation */
-+ (void *) NULL /* null terminator */
-+};
-+
-+NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
-+pem_mdCryptoOperationRSASign_proto = {
-+ NULL, /* etc */
-+ pem_mdCryptoOperationRSAPriv_Destroy,
-+ pem_mdCryptoOperationRSA_GetFinalLength,
-+ NULL, /* GetOperationLengh - not needed for one shot Sign/Verify */
-+ NULL, /* Final - not needed for one shot operation */
-+ NULL, /* Update - not needed for one shot operation */
-+ NULL, /* DigestUpdate - not needed for one shot operation */
-+ pem_mdCryptoOperationRSASign_UpdateFinal,
-+ NULL, /* UpdateCombo - not needed for one shot operation */
-+ NULL, /* DigestKey - not needed for one shot operation */
-+ (void *) NULL /* null terminator */
-+};
-+
-+/********** NSSCKMDMechansim functions ***********************/
-+/*
-+ * pem_mdMechanismRSA_Destroy
-+ */
-+static void
-+pem_mdMechanismRSA_Destroy
-+(
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKFWMechanism * fwMechanism,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ nss_ZFreeIf(fwMechanism);
-+}
-+
-+/*
-+ * pem_mdMechanismRSA_GetMinKeySize
-+ */
-+static CK_ULONG
-+pem_mdMechanismRSA_GetMinKeySize
-+(
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKFWMechanism * fwMechanism,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return 384;
-+}
-+
-+/*
-+ * pem_mdMechanismRSA_GetMaxKeySize
-+ */
-+static CK_ULONG
-+pem_mdMechanismRSA_GetMaxKeySize
-+(
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKFWMechanism * fwMechanism,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return 16384;
-+}
-+
-+/*
-+ * pem_mdMechanismRSA_DecryptInit
-+ */
-+static NSSCKMDCryptoOperation *
-+pem_mdMechanismRSA_DecryptInit
-+(
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKFWMechanism * fwMechanism,
-+ CK_MECHANISM * pMechanism,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKMDObject * mdKey,
-+ NSSCKFWObject * fwKey,
-+ CK_RV * pError
-+)
-+{
-+ return pem_mdCryptoOperationRSAPriv_Create
-+ (&pem_mdCryptoOperationRSADecrypt_proto, mdMechanism, mdKey,
-+ pError);
-+}
-+
-+/*
-+ * pem_mdMechanismRSA_SignInit
-+ */
-+static NSSCKMDCryptoOperation *
-+pem_mdMechanismRSA_SignInit
-+(
-+ NSSCKMDMechanism * mdMechanism,
-+ NSSCKFWMechanism * fwMechanism,
-+ CK_MECHANISM * pMechanism,
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKMDObject * mdKey,
-+ NSSCKFWObject * fwKey,
-+ CK_RV * pError
-+)
-+{
-+ return pem_mdCryptoOperationRSAPriv_Create
-+ (&pem_mdCryptoOperationRSASign_proto, mdMechanism, mdKey, pError);
-+}
-+
-+NSS_IMPLEMENT_DATA const NSSCKMDMechanism
-+pem_mdMechanismRSA = {
-+ (void *) NULL, /* etc */
-+ pem_mdMechanismRSA_Destroy,
-+ pem_mdMechanismRSA_GetMinKeySize,
-+ pem_mdMechanismRSA_GetMaxKeySize,
-+ NULL, /* GetInHardware - default false */
-+ NULL, /* EncryptInit - default errs */
-+ pem_mdMechanismRSA_DecryptInit,
-+ NULL, /* DigestInit - default errs */
-+ pem_mdMechanismRSA_SignInit,
-+ NULL, /* VerifyInit - default errs */
-+ pem_mdMechanismRSA_SignInit, /* SignRecoverInit */
-+ NULL, /* VerifyRecoverInit - default errs */
-+ NULL, /* GenerateKey - default errs */
-+ NULL, /* GenerateKeyPair - default errs */
-+ NULL, /* GetWrapKeyLength - default errs */
-+ NULL, /* WrapKey - default errs */
-+ NULL, /* UnwrapKey - default errs */
-+ NULL, /* DeriveKey - default errs */
-+ (void *) NULL /* null terminator */
-+};
-diff --git a/a/nss/lib/ckfw/pem/psession.c b/b/nss/lib/ckfw/pem/psession.c
-new file mode 100644
-index 0000000..70c5407
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/psession.c
-@@ -0,0 +1,388 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+#include "secmodt.h"
-+#include "pk11pub.h"
-+#include "base64.h"
-+#include "blapi.h"
-+
-+/*
-+ * psession.c
-+ *
-+ * This file implements the NSSCKMDSession object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+NSS_EXTERN_DATA pemInternalObject **gobj;
-+NSS_EXTERN_DATA int pem_nobjs;
-+NSS_EXTERN_DATA int token_needsLogin[NUM_SLOTS];
-+NSS_EXTERN_DATA const SEC_ASN1Template pem_RSAPrivateKeyTemplate[];
-+
-+void prepare_low_rsa_priv_key_for_asn1(NSSLOWKEYPrivateKey * key);
-+void pem_DestroyPrivateKey(NSSLOWKEYPrivateKey * privk);
-+
-+/*
-+ * Convert a hex string into bytes.
-+ */
-+static unsigned char *convert_iv(char *src, int num)
-+{
-+ int i;
-+ char conv[3];
-+ unsigned char *c;
-+
-+ c = (unsigned char *) malloc((num) + 1);
-+ if (c == NULL)
-+ return NULL;
-+
-+ conv[2] = '\0';
-+ memset(c, 0, num);
-+ for (i = 0; i < num; i++) {
-+ conv[0] = src[(i * 2)];
-+ conv[1] = src[(i * 2) + 1];
-+ c[i] = strtol(conv, NULL, 16);
-+ }
-+ return c;
-+}
-+
-+/*
-+ * The key is a 24-bit hash. The first 16 bits are the MD5 hash of the
-+ * password and the IV (salt). This has is then re-hashed with the
-+ * password and IV again and the first 8 bytes of that are the remaining
-+ * bytes of the 24-bit key.
-+ */
-+static int
-+make_key(const unsigned char *salt, const unsigned char *data, int len,
-+ unsigned char *key)
-+{
-+ int nkey = 0;
-+ MD5Context *Md5Ctx = MD5_NewContext();
-+ unsigned int digestLen;
-+ int count, i;
-+ unsigned char H[25];
-+
-+ nkey = 24;
-+ count = 0;
-+
-+ while (nkey > 0) {
-+ MD5_Begin(Md5Ctx);
-+ if (count)
-+ MD5_Update(Md5Ctx, (const unsigned char *) H, digestLen);
-+ MD5_Update(Md5Ctx, (const unsigned char *) data, len);
-+ MD5_Update(Md5Ctx, (const unsigned char *) salt, 8);
-+ MD5_End(Md5Ctx, (unsigned char *) H, &digestLen, sizeof(H));
-+
-+ i = 0;
-+ while (nkey && (i != digestLen)) {
-+ *(key++) = H[i];
-+ nkey--;
-+ i++;
-+ }
-+ count++;
-+ }
-+ MD5_DestroyContext(Md5Ctx, PR_TRUE);
-+
-+ return 24;
-+}
-+
-+static NSSCKMDFindObjects *
-+pem_mdSession_FindObjectsInit
-+(
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV * pError
-+)
-+{
-+ plog("mdSession_FindObjectsInit\n");
-+ return pem_FindObjectsInit(fwSession, pTemplate, ulAttributeCount,
-+ pError);
-+}
-+
-+static NSSCKMDObject *
-+pem_mdSession_CreateObject
-+(
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSArena * arena,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV * pError
-+)
-+{
-+ plog("mdSession_CreateObject\n");
-+ return pem_CreateObject(fwInstance, fwSession, mdToken, pTemplate,
-+ ulAttributeCount, pError);
-+}
-+
-+/*
-+ * increase refCount of internal object(s)
-+ */
-+NSSCKMDObject *
-+pem_mdSession_CopyObject
-+(
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKMDObject * mdOldObject,
-+ NSSCKFWObject * fwOldObject,
-+ NSSArena * arena,
-+ CK_ATTRIBUTE_PTR pTemplate,
-+ CK_ULONG ulAttributeCount,
-+ CK_RV * pError
-+)
-+{
-+ NSSCKMDObject *rvmdObject = NULL;
-+ pemInternalObject *io = (pemInternalObject *) mdOldObject->etc;
-+
-+ /* make a new mdObject */
-+ rvmdObject = nss_ZNEW(arena, NSSCKMDObject);
-+ if ((NSSCKMDObject *) NULL == rvmdObject) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDObject *) NULL;
-+ }
-+
-+ if (NULL == io->list) {
-+ io->refCount ++;
-+ } else {
-+ /* go through list of objects */
-+ pemObjectListItem *item = io->list;
-+ while (item) {
-+ item->io->refCount ++;
-+ item = item->next;
-+ }
-+ }
-+ /* struct (shallow) copy the old one */
-+ *rvmdObject = *mdOldObject;
-+
-+ return rvmdObject;
-+}
-+
-+CK_RV
-+pem_mdSession_Login
-+(
-+ NSSCKMDSession * mdSession,
-+ NSSCKFWSession * fwSession,
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_USER_TYPE userType,
-+ NSSItem * pin,
-+ CK_STATE oldState,
-+ CK_STATE newState
-+)
-+{
-+ NSSCKFWSlot *fwSlot;
-+ CK_SLOT_ID slotID;
-+ pemInternalObject *io = NULL;
-+ unsigned char *iv = 0;
-+ unsigned char mykey[32];
-+ unsigned char *output = NULL;
-+ DESContext *cx = NULL;
-+ SECStatus rv;
-+ unsigned int len = 0;
-+ NSSLOWKEYPrivateKey *lpk = NULL;
-+ PLArenaPool *arena;
-+ SECItem plain;
-+ int i;
-+
-+ fwSlot = NSSCKFWToken_GetFWSlot(fwToken);
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ arena = PORT_NewArena(2048);
-+ if (!arena) {
-+ return CKR_HOST_MEMORY;
-+ }
-+
-+ plog("pem_mdSession_Login '%s'\n", (char *) pin->data);
-+
-+ token_needsLogin[slotID - 1] = PR_FALSE;
-+
-+ /* Find the right key object */
-+ for (i = 0; i < pem_nobjs; i++) {
-+ if (NULL == gobj[i])
-+ continue;
-+
-+ if ((slotID == gobj[i]->slotID) && (gobj[i]->type == pemBareKey)) {
-+ io = gobj[i];
-+ break;
-+ }
-+ }
-+
-+ if (NULL == io) {
-+ rv = CKR_SLOT_ID_INVALID;
-+ goto loser;
-+ }
-+
-+ /* Convert the IV from hex into an array of bytes */
-+ iv = convert_iv(io->u.key.ivstring, 8);
-+
-+ /* Convert the PIN and IV into a DES key */
-+ make_key(iv, pin->data, pin->size, mykey);
-+
-+ output =
-+ (unsigned char *) nss_ZAlloc(NULL,
-+ (io->u.key.key.privateKey->len + 1));
-+ if (!output) {
-+ rv = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ cx = DES_CreateContext((const unsigned char *) mykey, iv,
-+ io->u.key.cipher, PR_FALSE);
-+ if (!cx) {
-+ rv = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ rv = DES_Decrypt(cx, output, &len, io->u.key.key.privateKey->len,
-+ io->u.key.key.privateKey->data,
-+ io->u.key.key.privateKey->len);
-+ DES_DestroyContext(cx, PR_TRUE);
-+
-+ if (iv) {
-+ free(iv);
-+ iv = NULL;
-+ }
-+ if (rv != SECSuccess) {
-+ rv = CKR_PIN_INCORRECT;
-+ goto loser;
-+ }
-+
-+ lpk = (NSSLOWKEYPrivateKey *) nss_ZAlloc(NULL,
-+ sizeof (NSSLOWKEYPrivateKey));
-+ if (lpk == NULL) {
-+ rv = CKR_HOST_MEMORY;
-+ goto loser;
-+ }
-+
-+ lpk->arena = arena;
-+ lpk->keyType = NSSLOWKEYRSAKey;
-+ prepare_low_rsa_priv_key_for_asn1(lpk);
-+
-+
-+ /* Decode the resulting blob and see if it is a decodable DER that fits
-+ * our private key template. If so we declare success and move on. If not
-+ * then we return an error.
-+ */
-+ memset(&plain, 0, sizeof(plain));
-+ plain.data = output;
-+ plain.len = len - output[len - 1];
-+ rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
-+ &plain);
-+ pem_DestroyPrivateKey(lpk);
-+ arena = NULL;
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ nss_ZFreeIf(io->u.key.key.privateKey->data);
-+ io->u.key.key.privateKey->len = len - output[len - 1];
-+ io->u.key.key.privateKey->data =
-+ (void *) nss_ZAlloc(NULL, io->u.key.key.privateKey->len);
-+ memcpy(io->u.key.key.privateKey->data, output, len - output[len - 1]);
-+
-+ rv = CKR_OK;
-+
-+ loser:
-+ if (arena)
-+ PORT_FreeArena(arena, PR_FALSE);
-+ if (iv)
-+ free(iv);
-+ nss_ZFreeIf(output);
-+
-+ return rv;
-+}
-+
-+NSS_IMPLEMENT NSSCKMDSession *
-+pem_CreateSession
-+(
-+ NSSCKFWSession * fwSession,
-+ CK_RV * pError
-+)
-+{
-+ NSSArena *arena;
-+ NSSCKMDSession *rv;
-+
-+ plog("pem_CreateSession returning new session\n");
-+ arena = NSSCKFWSession_GetArena(fwSession, pError);
-+ if ((NSSArena *) NULL == arena) {
-+ return (NSSCKMDSession *) NULL;
-+ }
-+
-+ rv = nss_ZNEW(arena, NSSCKMDSession);
-+ if ((NSSCKMDSession *) NULL == rv) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDSession *) NULL;
-+ }
-+
-+ /*
-+ * rv was zeroed when allocated, so we only
-+ * need to set the non-zero members.
-+ */
-+
-+ rv->etc = (void *) fwSession;
-+ /* rv->Close */
-+ /* rv->GetDeviceError */
-+ rv->Login = pem_mdSession_Login;
-+ /* rv->Logout */
-+ /* rv->InitPIN */
-+ /* rv->SetPIN */
-+ /* rv->GetOperationStateLen */
-+ /* rv->GetOperationState */
-+ /* rv->SetOperationState */
-+ rv->CreateObject = pem_mdSession_CreateObject;
-+ rv->CopyObject = pem_mdSession_CopyObject;
-+ rv->FindObjectsInit = pem_mdSession_FindObjectsInit;
-+ /* rv->SeedRandom */
-+ /* rv->GetRandom */
-+ /* rv->null */
-+
-+ return rv;
-+}
-diff --git a/a/nss/lib/ckfw/pem/pslot.c b/b/nss/lib/ckfw/pem/pslot.c
-new file mode 100644
-index 0000000..2f9901b
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/pslot.c
-@@ -0,0 +1,183 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+#include "prprf.h"
-+
-+/*
-+ * pslot.c
-+ *
-+ * This file implements the NSSCKMDSlot object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+static NSSUTF8 *
-+pem_mdSlot_GetSlotDescription
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ CK_SLOT_ID slotID;
-+ NSSArena *arena;
-+ char *slotid;
-+
-+ arena = NSSCKFWInstance_GetArena(fwInstance, pError);
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ slotid = (char *) nss_ZAlloc(arena, 256);
-+ PR_snprintf(slotid, 256, "PEM Slot #%ld", slotID);
-+
-+ return (NSSUTF8 *) slotid;
-+}
-+
-+static NSSUTF8 *
-+pem_mdSlot_GetManufacturerID
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_ManufacturerID;
-+}
-+
-+static CK_VERSION
-+pem_mdSlot_GetHardwareVersion
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_HardwareVersion;
-+}
-+
-+static CK_VERSION
-+pem_mdSlot_GetFirmwareVersion
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_FirmwareVersion;
-+}
-+
-+static NSSCKMDToken *
-+pem_mdSlot_GetToken
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSCKMDToken *) mdSlot->etc;
-+}
-+
-+CK_BBOOL
-+pem_mdSlot_GetRemovableDevice
-+(
-+ NSSCKMDSlot * mdSlot,
-+ NSSCKFWSlot * fwSlot,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return CK_TRUE;
-+}
-+
-+NSSCKMDSlot *
-+pem_NewSlot
-+(
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ NSSArena *arena;
-+ NSSCKMDSlot *mdSlot;
-+
-+ plog("pem_NewSlot\n");
-+ arena = NSSCKFWInstance_GetArena(fwInstance, pError);
-+ if ((NSSArena *) NULL == arena) {
-+ if (CKR_OK == *pError) {
-+ *pError = CKR_GENERAL_ERROR;
-+ }
-+ }
-+
-+ mdSlot = nss_ZNEW(arena, NSSCKMDSlot);
-+ if ((NSSCKMDSlot *) NULL == mdSlot) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDSlot *) NULL;
-+ }
-+
-+ mdSlot->etc = pem_NewToken(fwInstance, pError);
-+
-+ mdSlot->GetSlotDescription = pem_mdSlot_GetSlotDescription;
-+ mdSlot->GetManufacturerID = pem_mdSlot_GetManufacturerID;
-+ mdSlot->GetHardwareVersion = pem_mdSlot_GetHardwareVersion;
-+ mdSlot->GetFirmwareVersion = pem_mdSlot_GetFirmwareVersion;
-+ mdSlot->GetRemovableDevice = pem_mdSlot_GetRemovableDevice;
-+ mdSlot->GetToken = pem_mdSlot_GetToken;
-+
-+ return mdSlot;
-+}
-+
-+NSS_IMPLEMENT_DATA const NSSCKMDSlot
-+pem_mdSlot = {
-+ (void *) NULL, /* etc */
-+ NULL, /* Initialize */
-+ NULL, /* Destroy */
-+ pem_mdSlot_GetSlotDescription,
-+ pem_mdSlot_GetManufacturerID,
-+ NULL, /* GetTokenPresent -- defaults to true */
-+ pem_mdSlot_GetRemovableDevice,
-+ NULL, /* GetHardwareSlot -- defaults to false */
-+ pem_mdSlot_GetHardwareVersion,
-+ pem_mdSlot_GetFirmwareVersion,
-+ pem_mdSlot_GetToken,
-+ (void *) NULL /* null terminator */
-+};
-diff --git a/a/nss/lib/ckfw/pem/ptoken.c b/b/nss/lib/ckfw/pem/ptoken.c
-new file mode 100644
-index 0000000..6c35b21
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/ptoken.c
-@@ -0,0 +1,334 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 "ckpem.h"
-+#include "prprf.h"
-+
-+/*
-+ * ptoken.c
-+ *
-+ * This file implements the NSSCKMDToken object for the
-+ * "PEM objects" cryptoki module.
-+ */
-+
-+NSS_EXTERN_DATA int token_needsLogin[NUM_SLOTS];
-+
-+static NSSUTF8 *
-+pem_mdToken_GetLabel
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ NSSCKFWSlot *fwSlot;
-+ CK_SLOT_ID slotID;
-+ NSSArena *arena;
-+ char *tokenid;
-+
-+ arena = NSSCKFWInstance_GetArena(fwInstance, pError);
-+ fwSlot = NSSCKFWToken_GetFWSlot(fwToken);
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ tokenid = (char *) nss_ZAlloc(arena, 256);
-+ PR_snprintf(tokenid, 256, "PEM Token #%ld", slotID);
-+
-+ return (NSSUTF8 *) tokenid;
-+}
-+
-+static NSSUTF8 *
-+pem_mdToken_GetManufacturerID
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_ManufacturerID;
-+}
-+
-+static NSSUTF8 *
-+pem_mdToken_GetModel
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_TokenModel;
-+}
-+
-+static NSSUTF8 *
-+pem_mdToken_GetSerialNumber
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ return (NSSUTF8 *) pem_TokenSerialNumber;
-+}
-+
-+static CK_BBOOL
-+pem_mdToken_GetIsWriteProtected
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return CK_TRUE;
-+}
-+
-+static CK_VERSION
-+pem_mdToken_GetHardwareVersion
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_HardwareVersion;
-+}
-+
-+static CK_VERSION
-+pem_mdToken_GetFirmwareVersion
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return pem_FirmwareVersion;
-+}
-+
-+static NSSCKMDSession *pem_mdToken_OpenSession
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ NSSCKFWSession * fwSession,
-+ CK_BBOOL rw,
-+ CK_RV * pError
-+)
-+{
-+ plog("pem_mdToken_OpenSession\n");
-+ return pem_CreateSession(fwSession, pError);
-+}
-+
-+static CK_ULONG
-+pem_mdToken_GetMechanismCount
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ return (CK_ULONG) 1;
-+}
-+
-+static CK_RV
-+pem_mdToken_GetMechanismTypes
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_MECHANISM_TYPE types[]
-+)
-+{
-+ types[0] = CKM_RSA_PKCS;
-+ return CKR_OK;
-+}
-+
-+static NSSCKMDMechanism *
-+pem_mdToken_GetMechanism
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance,
-+ CK_MECHANISM_TYPE which,
-+ CK_RV * pError
-+)
-+{
-+ if (which != CKM_RSA_PKCS) {
-+ *pError = CKR_MECHANISM_INVALID;
-+ return (NSSCKMDMechanism *) NULL;
-+ }
-+ return (NSSCKMDMechanism *) & pem_mdMechanismRSA;
-+}
-+
-+static CK_BBOOL
-+pem_mdToken_GetUserPinInitialized
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ plog("pem_mdToken_GetUserPinInitialized: always TRUE\n");
-+ return CK_TRUE;
-+}
-+
-+static CK_BBOOL
-+pem_mdToken_GetLoginRequired
-+(
-+ NSSCKMDToken * mdToken,
-+ NSSCKFWToken * fwToken,
-+ NSSCKMDInstance * mdInstance,
-+ NSSCKFWInstance * fwInstance
-+)
-+{
-+ char *label;
-+ CK_RV pError;
-+ NSSCKFWSlot *fwSlot;
-+ CK_SLOT_ID slotID;
-+
-+ fwSlot = NSSCKFWToken_GetFWSlot(fwToken);
-+ slotID = nssCKFWSlot_GetSlotID(fwSlot);
-+
-+ label = pem_mdToken_GetLabel(mdToken, fwToken, mdInstance, fwInstance,
-+ &pError);
-+
-+ plog("pem_mdToken_GetLoginRequired %s: %d\n", label,
-+ token_needsLogin[slotID - 1]);
-+
-+ if (token_needsLogin[slotID - 1] == PR_TRUE)
-+ return CK_TRUE;
-+ else
-+ return CK_FALSE;
-+}
-+
-+NSSCKMDToken *
-+pem_NewToken
-+(
-+ NSSCKFWInstance * fwInstance,
-+ CK_RV * pError
-+)
-+{
-+ NSSArena *arena;
-+ NSSCKMDToken *mdToken;
-+ pemToken *token;
-+
-+ arena = NSSCKFWInstance_GetArena(fwInstance, pError);
-+ if ((NSSArena *) NULL == arena) {
-+ if (CKR_OK == *pError) {
-+ *pError = CKR_GENERAL_ERROR;
-+ }
-+ }
-+
-+ mdToken = nss_ZNEW(arena, NSSCKMDToken);
-+ if ((NSSCKMDToken *) NULL == mdToken) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDToken *) NULL;
-+ }
-+
-+ token = nss_ZNEW(arena, struct pemTokenStr);
-+ if ((struct pemTokenStr *) NULL == token) {
-+ *pError = CKR_HOST_MEMORY;
-+ return (NSSCKMDToken *) NULL;
-+ }
-+
-+ mdToken->etc = (void *) token;
-+ mdToken->GetLabel = pem_mdToken_GetLabel;
-+ mdToken->GetManufacturerID = pem_mdToken_GetManufacturerID;
-+ mdToken->GetModel = pem_mdToken_GetModel;
-+ mdToken->GetSerialNumber = pem_mdToken_GetSerialNumber;
-+ mdToken->GetIsWriteProtected = pem_mdToken_GetIsWriteProtected;
-+ mdToken->GetLoginRequired = pem_mdToken_GetLoginRequired;
-+ mdToken->GetUserPinInitialized = pem_mdToken_GetUserPinInitialized;
-+ mdToken->GetHardwareVersion = pem_mdToken_GetHardwareVersion;
-+ mdToken->GetFirmwareVersion = pem_mdToken_GetFirmwareVersion;
-+ mdToken->OpenSession = pem_mdToken_OpenSession;
-+ mdToken->GetMechanismCount = pem_mdToken_GetMechanismCount;
-+ mdToken->GetMechanismTypes = pem_mdToken_GetMechanismTypes;
-+ mdToken->GetMechanism = pem_mdToken_GetMechanism;
-+
-+ return mdToken;
-+}
-+
-+#if 0
-+NSS_IMPLEMENT_DATA const NSSCKMDToken pem_mdToken = {
-+ (void *) NULL, /* etc */
-+ NULL, /* Setup */
-+ NULL, /* Invalidate */
-+ NULL, /* InitToken -- default errs */
-+ pem_mdToken_GetLabel,
-+ pem_mdToken_GetManufacturerID,
-+ pem_mdToken_GetModel,
-+ pem_mdToken_GetSerialNumber,
-+ NULL, /* GetHasRNG -- default is false */
-+ pem_mdToken_GetIsWriteProtected,
-+ pem_mdToken_GetLoginRequired,
-+ pem_mdToken_GetUserPinInitialized,
-+ NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
-+ NULL, /* GetHasClockOnToken -- default is false */
-+ NULL, /* GetHasProtectedAuthenticationPath -- default is false */
-+ NULL, /* GetSupportsDualCryptoOperations -- default is false */
-+ NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
-+ NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
-+ NULL, /* GetMaxPinLen -- irrelevant */
-+ NULL, /* GetMinPinLen -- irrelevant */
-+ NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
-+ NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
-+ NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
-+ NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
-+ pem_mdToken_GetHardwareVersion,
-+ pem_mdToken_GetFirmwareVersion,
-+ NULL, /* GetUTCTime -- no clock */
-+ pem_mdToken_OpenSession,
-+ pem_mdToken_GetMechanismCount,
-+ pem_mdToken_GetMechanismTypes,
-+ pem_mdToken_GetMechanism,
-+ (void *) NULL /* null terminator */
-+};
-+#endif
-diff --git a/a/nss/lib/ckfw/pem/rsawrapr.c b/b/nss/lib/ckfw/pem/rsawrapr.c
-new file mode 100644
-index 0000000..1179f2a
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/rsawrapr.c
-@@ -0,0 +1,823 @@
-+/*
-+ * PKCS#1 encoding and decoding functions.
-+ * This file is believed to contain no code licensed from other parties.
-+ *
-+ * ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * Alternatively, the contents of this file may be used under the terms of
-+ * either the GNU General Public License Version 2 or later (the "GPL"), or
-+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-+ * in which case the provisions of the GPL or the LGPL are applicable instead
-+ * of those above. If you wish to allow use of your version of this file only
-+ * under the terms of either the GPL or the LGPL, and not to allow others to
-+ * use your version of this file under the terms of the MPL, indicate your
-+ * decision by deleting the provisions above and replace them with the notice
-+ * and other provisions required by the GPL or the LGPL. If you do not delete
-+ * the provisions above, a recipient may use your version of this file under
-+ * the terms of any one of the MPL, the GPL or the LGPL.
-+ *
-+ * ***** END LICENSE BLOCK ***** */
-+/* $Id: $ */
-+
-+#include "ckpem.h"
-+#include "blapi.h"
-+#include "softoken.h"
-+#include "sechash.h"
-+#include "base.h"
-+
-+#include "secerr.h"
-+
-+#define RSA_BLOCK_MIN_PAD_LEN 8
-+#define RSA_BLOCK_FIRST_OCTET 0x00
-+#define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
-+#define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
-+#define RSA_BLOCK_AFTER_PAD_OCTET 0x00
-+
-+#define OAEP_SALT_LEN 8
-+#define OAEP_PAD_LEN 8
-+#define OAEP_PAD_OCTET 0x00
-+
-+#define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */
-+
-+unsigned
-+pem_PublicModulusLen(NSSLOWKEYPublicKey *pubk)
-+{
-+ unsigned char b0;
-+
-+ /* interpret modulus length as key strength... in
-+ * fortezza that's the public key length */
-+
-+ switch (pubk->keyType) {
-+ case pemLOWKEYRSAKey:
-+ b0 = pubk->u.rsa.modulus.data[0];
-+ return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static SHA1Context *SHA1_CloneContext(SHA1Context * original)
-+{
-+ SHA1Context *clone = NULL;
-+ unsigned char *pBuf;
-+ int sha1ContextSize = SHA1_FlattenSize(original);
-+ SECStatus frv;
-+ unsigned char buf[FLAT_BUFSIZE];
-+
-+ PORT_Assert(sizeof buf >= sha1ContextSize);
-+ if (sizeof buf >= sha1ContextSize) {
-+ pBuf = buf;
-+ } else {
-+ pBuf = nss_ZAlloc(NULL, sha1ContextSize);
-+ if (!pBuf)
-+ goto done;
-+ }
-+
-+ frv = SHA1_Flatten(original, pBuf);
-+ if (frv == SECSuccess) {
-+ clone = SHA1_Resurrect(pBuf, NULL);
-+ memset(pBuf, 0, sha1ContextSize);
-+ }
-+ done:
-+ if (pBuf != buf)
-+ nss_ZFreeIf(pBuf);
-+ return clone;
-+}
-+
-+/*
-+ * Modify data by XORing it with a special hash of salt.
-+ */
-+static SECStatus
-+oaep_xor_with_h1(unsigned char *data, unsigned int datalen,
-+ unsigned char *salt, unsigned int saltlen)
-+{
-+ SHA1Context *sha1cx;
-+ unsigned char *dp, *dataend;
-+ unsigned char end_octet;
-+
-+ sha1cx = SHA1_NewContext();
-+ if (sha1cx == NULL) {
-+ return SECFailure;
-+ }
-+
-+ /*
-+ * Get a hash of salt started; we will use it several times,
-+ * adding in a different end octet (x00, x01, x02, ...).
-+ */
-+ SHA1_Begin(sha1cx);
-+ SHA1_Update(sha1cx, salt, saltlen);
-+ end_octet = 0;
-+
-+ dp = data;
-+ dataend = data + datalen;
-+
-+ while (dp < dataend) {
-+ SHA1Context *sha1cx_h1;
-+ unsigned int sha1len, sha1off;
-+ unsigned char sha1[SHA1_LENGTH];
-+
-+ /*
-+ * Create hash of (salt || end_octet)
-+ */
-+ sha1cx_h1 = SHA1_CloneContext(sha1cx);
-+ SHA1_Update(sha1cx_h1, &end_octet, 1);
-+ SHA1_End(sha1cx_h1, sha1, &sha1len, sizeof(sha1));
-+ SHA1_DestroyContext(sha1cx_h1, PR_TRUE);
-+ PORT_Assert(sha1len == SHA1_LENGTH);
-+
-+ /*
-+ * XOR that hash with the data.
-+ * When we have fewer than SHA1_LENGTH octets of data
-+ * left to xor, use just the low-order ones of the hash.
-+ */
-+ sha1off = 0;
-+ if ((dataend - dp) < SHA1_LENGTH)
-+ sha1off = SHA1_LENGTH - (dataend - dp);
-+ while (sha1off < SHA1_LENGTH)
-+ *dp++ ^= sha1[sha1off++];
-+
-+ /*
-+ * Bump for next hash chunk.
-+ */
-+ end_octet++;
-+ }
-+
-+ SHA1_DestroyContext(sha1cx, PR_TRUE);
-+ return SECSuccess;
-+}
-+
-+/*
-+ * Modify salt by XORing it with a special hash of data.
-+ */
-+static SECStatus
-+oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen,
-+ unsigned char *data, unsigned int datalen)
-+{
-+ unsigned char sha1[SHA1_LENGTH];
-+ unsigned char *psalt, *psha1, *saltend;
-+ SECStatus rv;
-+
-+ /*
-+ * Create a hash of data.
-+ */
-+ rv = SHA1_HashBuf(sha1, data, datalen);
-+ if (rv != SECSuccess) {
-+ return rv;
-+ }
-+
-+ /*
-+ * XOR the low-order octets of that hash with salt.
-+ */
-+ PORT_Assert(saltlen <= SHA1_LENGTH);
-+ saltend = salt + saltlen;
-+ psalt = salt;
-+ psha1 = sha1 + SHA1_LENGTH - saltlen;
-+ while (psalt < saltend) {
-+ *psalt++ ^= *psha1++;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+/*
-+ * RSA block types
-+ *
-+ * The actual values are important -- they are fixed, *not* arbitrary.
-+ * The explicit value assignments are not needed (because C would give
-+ * us those same values anyway) but are included as a reminder...
-+ */
-+typedef enum {
-+ RSA_BlockPrivate0 = 0, /* unused, really */
-+ RSA_BlockPrivate = 1, /* pad for a private-key operation */
-+ RSA_BlockPublic = 2, /* pad for a public-key operation */
-+ RSA_BlockRaw = 4, /* simply justify the block appropriately */
-+ RSA_BlockTotal
-+} RSA_BlockType;
-+
-+/*
-+ * Format one block of data for public/private key encryption using
-+ * the rules defined in PKCS #1.
-+ */
-+static unsigned char *rsa_FormatOneBlock(unsigned modulusLen,
-+ RSA_BlockType blockType,
-+ SECItem * data)
-+{
-+ unsigned char *block;
-+ unsigned char *bp;
-+ int padLen;
-+ int i;
-+ SECStatus rv;
-+
-+ block = (unsigned char *) nss_ZAlloc(NULL, modulusLen);
-+ if (block == NULL)
-+ return NULL;
-+
-+ bp = block;
-+
-+ /*
-+ * All RSA blocks start with two octets:
-+ * 0x00 || BlockType
-+ */
-+ *bp++ = RSA_BLOCK_FIRST_OCTET;
-+ *bp++ = (unsigned char) blockType;
-+
-+ switch (blockType) {
-+
-+ /*
-+ * Blocks intended for private-key operation.
-+ */
-+ case RSA_BlockPrivate: /* preferred method */
-+ /*
-+ * 0x00 || BT || Pad || 0x00 || ActualData
-+ * 1 1 padLen 1 data->len
-+ * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
-+ */
-+ padLen = modulusLen - data->len - 3;
-+ PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
-+ if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
-+ nss_ZFreeIf(block);
-+ return NULL;
-+ }
-+ nsslibc_memset(bp, RSA_BLOCK_PRIVATE_PAD_OCTET, padLen);
-+ bp += padLen;
-+ *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
-+ nsslibc_memcpy(bp, data->data, data->len);
-+ break;
-+
-+ /*
-+ * Blocks intended for public-key operation.
-+ */
-+ case RSA_BlockPublic:
-+
-+ /*
-+ * 0x00 || BT || Pad || 0x00 || ActualData
-+ * 1 1 padLen 1 data->len
-+ * Pad is all non-zero random bytes.
-+ */
-+ padLen = modulusLen - data->len - 3;
-+ PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
-+ if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
-+ nss_ZFreeIf(block);
-+ return NULL;
-+ }
-+ for (i = 0; i < padLen; i++) {
-+ /* Pad with non-zero random data. */
-+ do {
-+ rv = RNG_GenerateGlobalRandomBytes(bp + i, 1);
-+ } while (rv == SECSuccess
-+ && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
-+ if (rv != SECSuccess) {
-+ nss_ZFreeIf(block);
-+ return NULL;
-+ }
-+ }
-+ bp += padLen;
-+ *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
-+ nsslibc_memcpy(bp, data->data, data->len);
-+
-+ break;
-+
-+ default:
-+ PORT_Assert(0);
-+ nss_ZFreeIf(block);
-+ return NULL;
-+ }
-+
-+ return block;
-+}
-+
-+static SECStatus
-+rsa_FormatBlock(SECItem * result, unsigned modulusLen,
-+ RSA_BlockType blockType, SECItem * data)
-+{
-+ /*
-+ * XXX For now assume that the data length fits in a single
-+ * XXX encryption block; the ASSERTs below force this.
-+ * XXX To fix it, each case will have to loop over chunks whose
-+ * XXX lengths satisfy the assertions, until all data is handled.
-+ * XXX (Unless RSA has more to say about how to handle data
-+ * XXX which does not fit in a single encryption block?)
-+ * XXX And I do not know what the result is supposed to be,
-+ * XXX so the interface to this function may need to change
-+ * XXX to allow for returning multiple blocks, if they are
-+ * XXX not wanted simply concatenated one after the other.
-+ */
-+
-+ switch (blockType) {
-+ case RSA_BlockPrivate:
-+ case RSA_BlockPublic:
-+ /*
-+ * 0x00 || BT || Pad || 0x00 || ActualData
-+ *
-+ * The "3" below is the first octet + the second octet + the 0x00
-+ * octet that always comes just before the ActualData.
-+ */
-+ PORT_Assert(data->len <=
-+ (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
-+
-+ result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
-+ if (result->data == NULL) {
-+ result->len = 0;
-+ return SECFailure;
-+ }
-+ result->len = modulusLen;
-+
-+ break;
-+
-+ case RSA_BlockRaw:
-+ /*
-+ * Pad || ActualData
-+ * Pad is zeros. The application is responsible for recovering
-+ * the actual data.
-+ */
-+ if (data->len > modulusLen) {
-+ return SECFailure;
-+ }
-+ result->data = (unsigned char *) nss_ZAlloc(NULL, modulusLen);
-+ result->len = modulusLen;
-+ nsslibc_memcpy(result->data + (modulusLen - data->len), data->data,
-+ data->len);
-+ break;
-+
-+ default:
-+ PORT_Assert(0);
-+ result->data = NULL;
-+ result->len = 0;
-+ return SECFailure;
-+ }
-+
-+ return SECSuccess;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+pem_RSA_Sign(pemLOWKEYPrivateKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int maxOutputLen,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv = SECSuccess;
-+ unsigned int modulus_len = pem_PrivateModulusLen(key);
-+ SECItem formatted;
-+ SECItem unformatted;
-+
-+ if (maxOutputLen < modulus_len)
-+ return SECFailure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ return SECFailure;
-+
-+ unformatted.len = input_len;
-+ unformatted.data = input;
-+ formatted.data = NULL;
-+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
-+ &unformatted);
-+ if (rv != SECSuccess)
-+ goto done;
-+
-+ rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output,
-+ formatted.data);
-+ *output_len = modulus_len;
-+
-+ goto done;
-+
-+ done:
-+ if (formatted.data != NULL)
-+ nss_ZFreeIf(formatted.data);
-+ return rv;
-+}
-+
-+#if 0
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_CheckSign(NSSLOWKEYPublicKey * key,
-+ unsigned char *sign,
-+ unsigned int sign_len,
-+ unsigned char *hash, unsigned int hash_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+ unsigned int i;
-+ unsigned char *buffer;
-+
-+ modulus_len = pem_PublicModulusLen(key);
-+ if (sign_len != modulus_len)
-+ goto failure;
-+ /*
-+ * 0x00 || BT || Pad || 0x00 || ActualData
-+ *
-+ * The "3" below is the first octet + the second octet + the 0x00
-+ * octet that always comes just before the ActualData.
-+ */
-+ if (hash_len > modulus_len - (3 + RSA_BLOCK_MIN_PAD_LEN))
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ buffer = (unsigned char *) nss_ZAlloc(NULL, modulus_len + 1);
-+ if (!buffer)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ /*
-+ * check the padding that was used
-+ */
-+ if (buffer[0] != 0 || buffer[1] != 1)
-+ goto loser;
-+ for (i = 2; i < modulus_len - hash_len - 1; i++) {
-+ if (buffer[i] != 0xff)
-+ goto loser;
-+ }
-+ if (buffer[i] != 0)
-+ goto loser;
-+
-+ /*
-+ * make sure we get the same results
-+ */
-+ if (memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
-+ goto loser;
-+
-+ nss_ZFreeIf(buffer);
-+ return SECSuccess;
-+
-+ loser:
-+ nss_ZFreeIf(buffer);
-+ failure:
-+ return SECFailure;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_CheckSignRecover(NSSLOWKEYPublicKey * key,
-+ unsigned char *data,
-+ unsigned int *data_len,
-+ unsigned int max_output_len,
-+ unsigned char *sign, unsigned int sign_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+ unsigned int i;
-+ unsigned char *buffer;
-+
-+ if (sign_len != modulus_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ buffer = (unsigned char *) nss_ZAlloc(NULL, modulus_len + 1);
-+ if (!buffer)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
-+ if (rv != SECSuccess)
-+ goto loser;
-+ *data_len = 0;
-+
-+ /*
-+ * check the padding that was used
-+ */
-+ if (buffer[0] != 0 || buffer[1] != 1)
-+ goto loser;
-+ for (i = 2; i < modulus_len; i++) {
-+ if (buffer[i] == 0) {
-+ *data_len = modulus_len - i - 1;
-+ break;
-+ }
-+ if (buffer[i] != 0xff)
-+ goto loser;
-+ }
-+ if (*data_len == 0)
-+ goto loser;
-+ if (*data_len > max_output_len)
-+ goto loser;
-+
-+ /*
-+ * make sure we get the same results
-+ */
-+ nsslibc_memcpy(data, buffer + modulus_len - *data_len, *data_len);
-+
-+ nss_ZFreeIf(buffer);
-+ return SECSuccess;
-+
-+ loser:
-+ nss_ZFreeIf(buffer);
-+ failure:
-+ return SECFailure;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_EncryptBlock(NSSLOWKEYPublicKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int max_output_len,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+ SECItem formatted;
-+ SECItem unformatted;
-+
-+ formatted.data = NULL;
-+ if (max_output_len < modulus_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ unformatted.len = input_len;
-+ unformatted.data = input;
-+ formatted.data = NULL;
-+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
-+ &unformatted);
-+ if (rv != SECSuccess)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
-+ if (rv != SECSuccess)
-+ goto failure;
-+
-+ nss_ZFreeIf(formatted.data);
-+ *output_len = modulus_len;
-+ return SECSuccess;
-+
-+ failure:
-+ if (formatted.data != NULL)
-+ nss_ZFreeIf(formatted.data);
-+ return SECFailure;
-+}
-+#endif
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+pem_RSA_DecryptBlock(pemLOWKEYPrivateKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int max_output_len,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PrivateModulusLen(key);
-+ unsigned int i;
-+ unsigned char *buffer;
-+
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+ if (input_len != modulus_len)
-+ goto failure;
-+
-+ buffer = (unsigned char *) nss_ZAlloc(NULL, modulus_len + 1);
-+ if (!buffer)
-+ goto failure;
-+
-+ rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
-+ if (rv != SECSuccess) {
-+ goto loser;
-+ }
-+
-+ if (buffer[0] != 0 || buffer[1] != 2)
-+ goto loser;
-+ *output_len = 0;
-+ for (i = 2; i < modulus_len; i++) {
-+ if (buffer[i] == 0) {
-+ *output_len = modulus_len - i - 1;
-+ break;
-+ }
-+ }
-+ if (*output_len == 0)
-+ goto loser;
-+ if (*output_len > max_output_len)
-+ goto loser;
-+
-+ nsslibc_memcpy(output, buffer + modulus_len - *output_len, *output_len);
-+
-+ nss_ZFreeIf(buffer);
-+ return SECSuccess;
-+
-+ loser:
-+ nss_ZFreeIf(buffer);
-+ failure:
-+ return SECFailure;
-+}
-+
-+#if 0
-+/* XXX Doesn't set error code */
-+/*
-+ * added to make pkcs #11 happy
-+ * RAW is RSA_X_509
-+ */
-+SECStatus
-+pem_RSA_SignRaw(pemLOWKEYPrivateKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int maxOutputLen,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv = SECSuccess;
-+ unsigned int modulus_len = pem_PrivateModulusLen(key);
-+ SECItem formatted;
-+ SECItem unformatted;
-+
-+ if (maxOutputLen < modulus_len)
-+ return SECFailure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ return SECFailure;
-+
-+ unformatted.len = input_len;
-+ unformatted.data = input;
-+ formatted.data = NULL;
-+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw,
-+ &unformatted);
-+ if (rv != SECSuccess)
-+ goto done;
-+
-+ rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, output,
-+ formatted.data);
-+ *output_len = modulus_len;
-+
-+ done:
-+ if (formatted.data != NULL)
-+ nss_ZFreeIf(formatted.data);
-+ return rv;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_CheckSignRaw(NSSLOWKEYPublicKey * key,
-+ unsigned char *sign,
-+ unsigned int sign_len,
-+ unsigned char *hash, unsigned int hash_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+ unsigned char *buffer;
-+
-+ if (sign_len != modulus_len)
-+ goto failure;
-+ if (hash_len > modulus_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ buffer = (unsigned char *) nss_ZAlloc(NULL, modulus_len + 1);
-+ if (!buffer)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
-+ if (rv != SECSuccess)
-+ goto loser;
-+
-+ /*
-+ * make sure we get the same results
-+ */
-+ /* NOTE: should we verify the leading zeros? */
-+ if (memcmp(buffer + (modulus_len - hash_len), hash, hash_len) !=
-+ 0)
-+ goto loser;
-+
-+ nss_ZFreeIf(buffer);
-+ return SECSuccess;
-+
-+ loser:
-+ nss_ZFreeIf(buffer);
-+ failure:
-+ return SECFailure;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_CheckSignRecoverRaw(NSSLOWKEYPublicKey * key,
-+ unsigned char *data,
-+ unsigned int *data_len,
-+ unsigned int max_output_len,
-+ unsigned char *sign, unsigned int sign_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+
-+ if (sign_len != modulus_len)
-+ goto failure;
-+ if (max_output_len < modulus_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
-+ if (rv != SECSuccess)
-+ goto failure;
-+
-+ *data_len = modulus_len;
-+ return SECSuccess;
-+
-+ failure:
-+ return SECFailure;
-+}
-+
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+RSA_EncryptRaw(NSSLOWKEYPublicKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int max_output_len,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PublicModulusLen(key);
-+ SECItem formatted;
-+ SECItem unformatted;
-+
-+ formatted.data = NULL;
-+ if (max_output_len < modulus_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+
-+ unformatted.len = input_len;
-+ unformatted.data = input;
-+ formatted.data = NULL;
-+ rv = rsa_FormatBlock(&formatted, modulus_len, RSA_BlockRaw,
-+ &unformatted);
-+ if (rv != SECSuccess)
-+ goto failure;
-+
-+ rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
-+ if (rv != SECSuccess)
-+ goto failure;
-+
-+ nss_ZFreeIf(formatted.data);
-+ *output_len = modulus_len;
-+ return SECSuccess;
-+
-+ failure:
-+ if (formatted.data != NULL)
-+ nss_ZFreeIf(formatted.data);
-+ return SECFailure;
-+}
-+
-+/* XXX Doesn't set error code */
-+SECStatus
-+pem_RSA_DecryptRaw(pemLOWKEYPrivateKey * key,
-+ unsigned char *output,
-+ unsigned int *output_len,
-+ unsigned int max_output_len,
-+ unsigned char *input, unsigned int input_len)
-+{
-+ SECStatus rv;
-+ unsigned int modulus_len = pem_PrivateModulusLen(key);
-+
-+ if (modulus_len <= 0)
-+ goto failure;
-+ if (modulus_len > max_output_len)
-+ goto failure;
-+ PORT_Assert(key->keyType == pemLOWKEYRSAKey);
-+ if (key->keyType != pemLOWKEYRSAKey)
-+ goto failure;
-+ if (input_len != modulus_len)
-+ goto failure;
-+
-+ rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
-+ if (rv != SECSuccess) {
-+ goto failure;
-+ }
-+
-+ *output_len = modulus_len;
-+ return SECSuccess;
-+
-+ failure:
-+ return SECFailure;
-+}
-+#endif
-diff --git a/a/nss/lib/ckfw/pem/util.c b/b/nss/lib/ckfw/pem/util.c
-new file mode 100644
-index 0000000..e5fb4da
---- /dev/null
-+++ b/b/nss/lib/ckfw/pem/util.c
-@@ -0,0 +1,314 @@
-+/* ***** 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):
-+ * Rob Crittenden (rcritten@redhat.com)
-+ *
-+ * 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 ***** */
-+
-+/* cribbed from secutil.c */
-+
-+#include "prtypes.h"
-+#include "prtime.h"
-+#include "prlong.h"
-+#include "prerror.h"
-+#include "prlog.h"
-+#include "prprf.h"
-+#include "plgetopt.h"
-+#include "plstr.h"
-+#include "prenv.h"
-+#include "prnetdb.h"
-+#include "base.h"
-+#include "base64.h"
-+
-+#include "cryptohi.h"
-+#include "secpkcs7.h"
-+#include "secerr.h"
-+
-+#include "ckpem.h"
-+
-+#include <stdarg.h>
-+
-+#define CHUNK_SIZE 512
-+#define PUT_Object(obj,err) \
-+ { \
-+ if (count >= size) { \
-+ *derlist = *derlist ? \
-+ nss_ZREALLOCARRAY(*derlist, SECItem *, \
-+ (size+CHUNK_SIZE) ) : \
-+ nss_ZNEWARRAY(NULL, SECItem *, \
-+ (size+CHUNK_SIZE) ) ; \
-+ if ((SECItem **)NULL == *derlist) { \
-+ err = CKR_HOST_MEMORY; \
-+ goto loser; \
-+ } \
-+ size += CHUNK_SIZE; \
-+ } \
-+ (*derlist)[ count ] = (obj); \
-+ count++; \
-+ }
-+
-+/* Read certificates from a flat file */
-+
-+static SECItem *AllocItem(SECItem * item, unsigned int len)
-+{
-+ SECItem *result = NULL;
-+
-+ if (item == NULL) {
-+ result = nss_ZAlloc(NULL, sizeof(SECItem));
-+ if (result == NULL) {
-+ goto loser;
-+ }
-+ } else {
-+ PORT_Assert(item->data == NULL);
-+ result = item;
-+ }
-+
-+ result->len = len;
-+ if (len) {
-+ result->data = nss_ZAlloc(NULL, len);
-+ }
-+
-+ return (result);
-+
-+ loser:
-+ return (NULL);
-+}
-+
-+static SECStatus FileToItem(SECItem * dst, PRFileDesc * src)
-+{
-+ PRFileInfo info;
-+ PRInt32 numBytes;
-+ PRStatus prStatus;
-+
-+ prStatus = PR_GetOpenFileInfo(src, &info);
-+
-+ if (prStatus != PR_SUCCESS || info.type == PR_FILE_DIRECTORY) {
-+ return SECFailure;
-+ }
-+
-+ /* XXX workaround for 3.1, not all utils zero dst before sending */
-+ dst->data = 0;
-+ if (!AllocItem(dst, info.size+1))
-+ goto loser;
-+
-+ numBytes = PR_Read(src, dst->data, info.size);
-+ if (numBytes != info.size) {
-+ goto loser;
-+ }
-+
-+ return SECSuccess;
-+ loser:
-+ nss_ZFreeIf(dst->data);
-+ return SECFailure;
-+}
-+
-+int
-+ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii,
-+ int *cipher, char **ivstring, PRBool certsonly)
-+{
-+ SECStatus rv;
-+ PRFileDesc *inFile;
-+ int count = 0, size = 0;
-+ SECItem *der = NULL;
-+ int error;
-+ SECItem filedata;
-+ char *c, *iv;
-+
-+ inFile = PR_Open(filename, PR_RDONLY, 0);
-+ if (!inFile)
-+ return -1;
-+
-+ if (ascii) {
-+ /* First convert ascii to binary */
-+ char *asc, *body;
-+
-+ /* Read in ascii data */
-+ rv = FileToItem(&filedata, inFile);
-+ if (rv != SECSuccess) {
-+ PR_Close(inFile);
-+ return -1;
-+ }
-+ asc = (char *) filedata.data;
-+ if (!asc) {
-+ PR_Close(inFile);
-+ return -1;
-+ }
-+
-+ /* check for headers and trailers and remove them */
-+ if (strstr(asc, "-----BEGIN") != NULL) {
-+ int key = 0;
-+ while ((asc) && ((body = strstr(asc, "-----BEGIN")) != NULL)) {
-+ char *trailer;
-+ key = 0;
-+ if ((strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) ||
-+ (strncmp(body, "-----BEGIN PRIVATE KEY", 21) == 0)) {
-+ key = 1;
-+ c = body;
-+ body = strchr(body, '\n');
-+ if (NULL == body)
-+ goto loser;
-+ body++;
-+ if (strncmp(body, "Proc-Type: 4,ENCRYPTED", 22) == 0) {
-+ body = strchr(body, '\n');
-+ if (NULL == body)
-+ goto loser;
-+ body++;
-+ if (strncmp(body, "DEK-Info: ", 10) == 0) {
-+ body += 10;
-+ c = body;
-+ body = strchr(body, ',');
-+ if (body == NULL)
-+ goto loser;
-+ *body = '\0';
-+ if (!PL_strcasecmp(c, "DES-EDE3-CBC"))
-+ *cipher = NSS_DES_EDE3_CBC;
-+ else if (!PL_strcasecmp(c, "DES-CBC"))
-+ *cipher = NSS_DES_CBC;
-+ else {
-+ *cipher = -1;
-+ goto loser;
-+ }
-+ body++;
-+ iv = body;
-+ body = strchr(body, '\n');
-+ if (body == NULL)
-+ goto loser;
-+ *body = '\0';
-+ body++;
-+ *ivstring = strdup(iv);
-+ }
-+ } else { /* Else the private key is not encrypted */
-+ *cipher = 0;
-+ body = c;
-+ }
-+ }
-+ der = (SECItem *) malloc(sizeof(SECItem));
-+ if (der == NULL)
-+ goto loser;
-+
-+ trailer = NULL;
-+ asc = body;
-+ body = strchr(body, '\n');
-+ if (!body)
-+ body = strchr(asc, '\r'); /* maybe this is a MAC file */
-+ if (body) {
-+ trailer = strstr(++body, "-----END");
-+ }
-+ if (trailer != NULL) {
-+ asc = trailer + 1;
-+ *trailer = '\0';
-+ } else {
-+ free(der);
-+ goto loser;
-+ }
-+
-+ /* Convert to binary */
-+ rv = ATOB_ConvertAsciiToItem(der, body);
-+ if (rv) {
-+ free(der);
-+ goto loser;
-+ }
-+ if ((certsonly && !key) || (!certsonly && key)) {
-+ PUT_Object(der, error);
-+ } else {
-+ free(der->data);
-+ free(der);
-+ }
-+ } /* while */
-+ } else { /* No headers and footers, translate the blob */
-+ der = (SECItem *) malloc(sizeof(SECItem));
-+ if (der == NULL)
-+ goto loser;
-+
-+ rv = ATOB_ConvertAsciiToItem(der, asc);
-+ if (rv) {
-+ free(der);
-+ goto loser;
-+ }
-+
-+ /* NOTE: This code path has never been tested. */
-+ PUT_Object(der, error);
-+ }
-+
-+ nss_ZFreeIf(filedata.data);
-+ filedata.data = 0;
-+ filedata.len = 0;
-+ } else {
-+ /* Read in binary der */
-+ rv = FileToItem(der, inFile);
-+ if (rv != SECSuccess) {
-+ PR_Close(inFile);
-+ return -1;
-+ }
-+ }
-+ PR_Close(inFile);
-+ return count;
-+
-+ loser:
-+ if (filedata.len > 0)
-+ nss_ZFreeIf(filedata.data);
-+ PR_Close(inFile);
-+ return -1;
-+}
-+
-+#ifdef DEBUG
-+#define LOGGING_BUFFER_SIZE 400
-+#define PEM_DEFAULT_LOG_FILE "/tmp/pkcs11.log"
-+static const char *pemLogModuleName = "PEM";
-+static PRLogModuleInfo* pemLogModule;
-+#endif
-+
-+void open_log()
-+{
-+#ifdef DEBUG
-+ const char *nsprLogFile = PR_GetEnv("NSPR_LOG_FILE");
-+
-+ pemLogModule = PR_NewLogModule(pemLogModuleName);
-+
-+ (void) PR_SetLogFile(nsprLogFile ? nsprLogFile : PEM_DEFAULT_LOG_FILE);
-+ /* If false, the log file will remain what it was before */
-+#endif
-+}
-+
-+void plog(const char *fmt, ...)
-+{
-+#ifdef DEBUG
-+ char buf[LOGGING_BUFFER_SIZE];
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ PR_vsnprintf(buf, sizeof(buf), fmt, ap);
-+ va_end(ap);
-+ PR_LOG(pemLogModule, PR_LOG_DEBUG, ("%s", buf));
-+#endif
-+}
diff --git a/external/nss/nss-winXP-sdk.patch.1 b/external/nss/nss-winXP-sdk.patch.1
index 2c8189215083..5273e71705b6 100644
--- a/external/nss/nss-winXP-sdk.patch.1
+++ b/external/nss/nss-winXP-sdk.patch.1
@@ -1,9 +1,12 @@
diff -ur nss.org/nss/coreconf/config.mk nss/nss/coreconf/config.mk
--- nss.org/nss/coreconf/config.mk 2016-03-15 14:52:19.706093300 +0100
+++ nss/nss/coreconf/config.mk 2016-03-15 14:56:51.549914800 +0100
-@@ -188,3 +188,5 @@
+@@ -203,6 +203,8 @@
# Hide old, deprecated, TLS cipher suite names when building NSS
DEFINES += -DSSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES
+# build with 7.1A SDK for winXP compatibility
+DEFINES += -D_USING_V110_SDK71_
+
+ # Mozilla's mozilla/modules/zlib/src/zconf.h adds the MOZ_Z_ prefix to zlib
+ # exported symbols, which causes problem when NSS is built as part of Mozilla.
diff --git a/external/nss/nss.cygwin64.in32bit.patch b/external/nss/nss.cygwin64.in32bit.patch
index b00761a0e85b..b00761a0e85b 100755..100644
--- a/external/nss/nss.cygwin64.in32bit.patch
+++ b/external/nss/nss.cygwin64.in32bit.patch
diff --git a/external/nss/nss.nowerror.patch b/external/nss/nss.nowerror.patch
index ca5f17ccbf66..ff81a9b33539 100644
--- a/external/nss/nss.nowerror.patch
+++ b/external/nss/nss.nowerror.patch
@@ -1,14 +1,12 @@
diff -ur nss.org/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk
--- a/nss.org/nss/coreconf/WIN32.mk 2016-04-13 11:33:09.322294523 +0200
+++ b/nss/nss/coreconf/WIN32.mk 2016-04-13 11:33:27.744323969 +0200
-@@ -126,9 +126,9 @@
- OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \
- -D_CRT_NONSTDC_NO_WARNINGS
+@@ -127,7 +127,7 @@
+ -D_CRT_NONSTDC_NO_WARNINGS
OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS
ifndef NSS_ENABLE_WERROR
- NSS_ENABLE_WERROR = 1
+ NSS_ENABLE_WERROR = 0
endif
ifeq ($(NSS_ENABLE_WERROR),1)
- OS_CFLAGS += -WX
- endif
+ WARNING_CFLAGS += -WX
diff --git a/external/nss/nss.patch b/external/nss/nss.patch
index 548363578789..771ebf59baed 100644
--- a/external/nss/nss.patch
+++ b/external/nss/nss.patch
@@ -110,16 +110,16 @@ diff -ru a/nss/coreconf/Linux.mk b/nss/coreconf/Linux.mk
RANLIB = ranlib
DEFAULT_COMPILER = gcc
-@@ -145,7 +148,7 @@
- # incorrectly reports undefined references in the libraries we link with, so
- # we don't use -z defs there.
+@@ -157,7 +160,7 @@
+ # against the libsanitizer runtime built into the main executable.
ZDEFS_FLAG = -Wl,-z,defs
+ ifneq ($(USE_ASAN),1)
-DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
-+DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) -Wl,-z,origin '-Wl,-rpath,$$ORIGIN'
++DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) -Wl,-z,origin '-Wl,-rpath,$$ORIGIN'
+ endif
LDFLAGS += $(ARCHFLAG)
- # On Maemo, we need to use the -rpath-link flag for even the standard system
-@@ -176,8 +179,13 @@
+@@ -189,8 +192,13 @@
endif
endif
@@ -175,13 +175,13 @@ diff -ru a/nss/Makefile b/nss/Makefile
diff -ru nss.orig/nss/coreconf/Werror.mk nss/nss/coreconf/Werror.mk
--- a/nss.orig/nss/coreconf/Werror.mk 2016-02-12 15:36:18.000000000 +0100
+++ b/nss/nss/coreconf/Werror.mk 2016-02-23 23:58:15.119584046 +0100
-@@ -60,7 +60,8 @@
- endif #ndef NSS_ENABLE_WERROR
+@@ -94,7 +94,8 @@
+ endif #ndef NSS_ENABLE_WERROR
- ifeq ($(NSS_ENABLE_WERROR),1)
-- WARNING_CFLAGS += -Werror
+ ifeq ($(NSS_ENABLE_WERROR),1)
+- WARNING_CFLAGS += -Werror
+# We do not treat warnings as errors.
+# WARNING_CFLAGS += -Werror
- else
- # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
- # Use this to disable use of that #pragma and the warnings it suppresses.
+ else
+ # Old versions of gcc (< 4.8) don't support #pragma diagnostic in functions.
+ # Use this to disable use of that #pragma and the warnings it suppresses.
diff --git a/external/nss/nss.utf8bom.patch.1 b/external/nss/nss.utf8bom.patch.1
new file mode 100644
index 000000000000..bc37f184ce64
--- /dev/null
+++ b/external/nss/nss.utf8bom.patch.1
@@ -0,0 +1,30 @@
+diff -ur nss.org/nss/external_tests/google_test/gtest/include/gtest/internal/gtest-internal.h nss/nss/external_tests/google_test/gtest/include/gtest/internal/gtest-internal.h
+--- nss.org/nss/external_tests/google_test/gtest/include/gtest/internal/gtest-internal.h 2016-03-31 18:26:06.763009800 +0800
++++ nss/nss/external_tests/google_test/gtest/include/gtest/internal/gtest-internal.h 2016-03-31 19:17:11.724452000 +0800
+@@ -1,4 +1,4 @@
+-// Copyright 2005, Google Inc.
++// Copyright 2005, Google Inc.
+ // All rights reserved.
+ //
+ // Redistribution and use in source and binary forms, with or without
+diff -ur nss.org/nss/lib/ckfw/builtins/certdata.perl nss/nss/lib/ckfw/builtins/certdata.perl
+--- nss.org/nss/lib/ckfw/builtins/certdata.perl 2016-03-31 18:26:07.890190900 +0800
++++ nss/nss/lib/ckfw/builtins/certdata.perl 2016-03-31 19:16:16.727269600 +0800
+@@ -110,6 +110,9 @@
+ sub doprint {
+ my $i;
+
++print chr(0xEF);
++print chr(0xBB);
++print chr(0xBF);
+ print <<EOD
+ /* THIS IS A GENERATED FILE */
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+@@ -119,6 +122,7 @@
+ #ifndef BUILTINS_H
+ #include "builtins.h"
+ #endif /* BUILTINS_H */
++#pragma execution_character_set("utf-8")
+
+ EOD
+ ;
diff --git a/external/nss/nss.vs2015.patch b/external/nss/nss.vs2015.patch
index de4f8762fd5b..de4f8762fd5b 100755..100644
--- a/external/nss/nss.vs2015.patch
+++ b/external/nss/nss.vs2015.patch
diff --git a/external/nss/nss.vs2015.pdb.patch b/external/nss/nss.vs2015.pdb.patch
index dc4f4638b476..dc4f4638b476 100755..100644
--- a/external/nss/nss.vs2015.pdb.patch
+++ b/external/nss/nss.vs2015.pdb.patch
diff --git a/external/nss/nss.windowbuild.patch.0 b/external/nss/nss.windowbuild.patch.0
new file mode 100644
index 000000000000..04b13a7bea27
--- /dev/null
+++ b/external/nss/nss.windowbuild.patch.0
@@ -0,0 +1,55 @@
+--- ./nss/external_tests/ssl_gtest/tls_connect.cc
++++ ./nss/external_tests/ssl_gtest/tls_connect.cc
+@@ -375,6 +375,12 @@
+ }
+ }
+
++// A simple value of "a", "b". Note that the preferred value of "a" is placed
++// at the end, because the NSS API follows the now defunct NPN specification,
++// which places the preferred (and default) entry at the end of the list.
++// NSS will move this final entry to the front when used with ALPN.
++const uint8_t alpn_dummy_val_[4] = { 0x01, 0x62, 0x01, 0x61 };
++
+ void TlsConnectTestBase::EnableAlpn() {
+ client_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
+ server_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
+--- ./nss/external_tests/ssl_gtest/tls_connect.h
++++ ./nss/external_tests/ssl_gtest/tls_connect.h
+@@ -113,12 +113,6 @@
+ SessionResumptionMode expected_resumption_mode_;
+ std::vector<std::vector<uint8_t>> session_ids_;
+
+- // A simple value of "a", "b". Note that the preferred value of "a" is placed
+- // at the end, because the NSS API follows the now defunct NPN specification,
+- // which places the preferred (and default) entry at the end of the list.
+- // NSS will move this final entry to the front when used with ALPN.
+- const uint8_t alpn_dummy_val_[4] = {0x01, 0x62, 0x01, 0x61};
+-
+ private:
+ void CheckResumption(SessionResumptionMode expected);
+ void CheckExtendedMasterSecret();
+--- ./nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
++++ ./nss/external_tests/ssl_gtest/ssl_loopback_unittest.cc
+@@ -51,6 +51,12 @@
+ CheckAlpn("a");
+ }
+
++// A simple value of "a", "b". Note that the preferred value of "a" is placed
++// at the end, because the NSS API follows the now defunct NPN specification,
++// which places the preferred (and default) entry at the end of the list.
++// NSS will move this final entry to the front when used with ALPN.
++const uint8_t alpn_dummy_val_[4] = { 0x01, 0x62, 0x01, 0x61 };
++
+ TEST_P(TlsConnectGeneric, ConnectAlpnClone) {
+ EnsureModelSockets();
+ client_model_->EnableAlpn(alpn_dummy_val_, sizeof(alpn_dummy_val_));
+--- ./nss/external_tests/ssl_gtest/databuffer.h
++++ ./nss/external_tests/ssl_gtest/databuffer.h
+@@ -10,6 +10,7 @@
+ #include <algorithm>
+ #include <cassert>
+ #include <cstring>
++#include <cstdint>
+ #include <iomanip>
+ #include <iostream>
+ #if defined(WIN32) || defined(WIN64)
diff --git a/external/nss/nss.windows.patch b/external/nss/nss.windows.patch
index 9464bb1ce090..9dbeaa946520 100644
--- a/external/nss/nss.windows.patch
+++ b/external/nss/nss.windows.patch
@@ -11,12 +11,12 @@
$(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp
--- a/a/nss/coreconf/rules.mk 2008-12-03 00:24:39.000000000 +0100
+++ b/b/nss/coreconf/rules.mk 2009-11-27 13:36:22.662753328 +0100
-@@ -411,7 +411,7 @@
+@@ -386,7 +386,7 @@
endif
# The quotes allow absolute paths to contain spaces.
--core_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))"
-+core_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(shell cygpath -m $(1))),$(1),$(shell cygpath -m $(PWD)/$(1))))"
+-core_abspath = '$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))'
++core_abspath = '$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(shell cygpath -m $(1))),$(1),$(shell cygpath -m $(PWD)/$(1))))'
$(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c
@$(MAKE_OBJDIR)
diff --git a/external/nss/nss_macosx.patch b/external/nss/nss_macosx.patch
index 40d02c955160..dfbad1a36f32 100644
--- a/external/nss/nss_macosx.patch
+++ b/external/nss/nss_macosx.patch
@@ -13,7 +13,7 @@ diff -ru a/nspr/configure b/nspr/configure
diff -ru a/nss/coreconf/Darwin.mk b/nss/coreconf/Darwin.mk
--- a/a/nss/coreconf/Darwin.mk 2014-09-29 16:50:22.992304799 +0100
+++ b/b/nss/coreconf/Darwin.mk 2014-09-29 16:51:59.214931953 +0100
-@@ -7,8 +7,12 @@
+@@ -8,8 +8,12 @@
DEFAULT_COMPILER = gcc
@@ -28,23 +28,25 @@ diff -ru a/nss/coreconf/Darwin.mk b/nss/coreconf/Darwin.mk
RANLIB = ranlib
ifndef CPU_ARCH
-@@ -19,11 +23,15 @@
+@@ -20,13 +24,17 @@
ifeq (,$(filter-out i%86,$(CPU_ARCH)))
ifdef USE_64
+ifeq (,$(findstring -arch ,$(CC)))
CC += -arch x86_64
+ CCC += -arch x86_64
+endif
override CPU_ARCH = x86_64
else
OS_REL_CFLAGS = -Di386
+ifeq (,$(findstring -arch ,$(CC)))
CC += -arch i386
+ CCC += -arch i386
+endif
override CPU_ARCH = x86
endif
else
-@@ -31,12 +39,16 @@
+@@ -40,12 +48,16 @@
endif
ifneq (,$(MACOS_SDK_DIR))
@@ -62,7 +64,7 @@ diff -ru a/nss/coreconf/Darwin.mk b/nss/coreconf/Darwin.mk
# GCC <= 3
DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks
ifneq (,$(shell find $(MACOS_SDK_DIR)/Library/Frameworks -maxdepth 0))
-@@ -104,7 +115,7 @@
+@@ -108,7 +120,7 @@
# 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.
diff --git a/external/nss/ubsan-alignment.patch.0 b/external/nss/ubsan-alignment.patch.0
new file mode 100644
index 000000000000..651939f7bc88
--- /dev/null
+++ b/external/nss/ubsan-alignment.patch.0
@@ -0,0 +1,40 @@
+--- nss/lib/freebl/md5.c
++++ nss/lib/freebl/md5.c
+@@ -445,7 +445,7 @@
+ /* Iterate over 64-byte chunks of the message. */
+ while (inputLen >= MD5_BUFFER_SIZE) {
+ #ifdef IS_LITTLE_ENDIAN
+-#ifdef NSS_X86_OR_X64
++#if 0
+ /* x86 can handle arithmetic on non-word-aligned buffers */
+ wBuf = (PRUint32 *)input;
+ #else
+--- nss/lib/freebl/sha_fast.c
++++ nss/lib/freebl/sha_fast.c
+@@ -16,7 +16,7 @@
+ #include "ssltrace.h"
+ #endif
+
+-static void shaCompress(volatile SHA_HW_t *X, const PRUint32 *datain);
++static void shaCompress(volatile SHA_HW_t *X, const unsigned char *datain);
+
+ #define W u.w
+ #define B u.b
+@@ -241,7 +241,7 @@
+ * code on AMD64.
+ */
+ static void
+-shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
++shaCompress(volatile SHA_HW_t *X, const unsigned char *inbuf)
+ {
+ register SHA_HW_t A, B, C, D, E;
+
+@@ -277,7 +277,7 @@
+ a = SHA_ROTL(b, 5) + SHA_F4(c, d, e) + a + XW(n) + K3; \
+ c = SHA_ROTL(c, 30)
+
+-#define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
++#define LOAD(n) XW(n) = (((PRUint32)inbuf[4*n])<<24)|(((PRUint32)inbuf[4*n+1])<<16)|(((PRUint32)inbuf[4*n+2])<<8)|((PRUint32)inbuf[4*n+3])
+
+ A = XH(0);
+ B = XH(1);
diff --git a/external/nss/ubsan.patch.0 b/external/nss/ubsan.patch.0
index ccf04b92b023..1254afd0c4ad 100644
--- a/external/nss/ubsan.patch.0
+++ b/external/nss/ubsan.patch.0
@@ -1,6 +1,5 @@
-diff -ru nss.orig/nss/lib/certdb/crl.c nss/nss/lib/certdb/crl.c
---- nss/lib/certdb/crl.c 2016-02-12 15:36:18.000000000 +0100
-+++ nss/lib/certdb/crl.c 2016-02-23 20:57:17.067924598 +0100
+--- nss/lib/certdb/crl.c
++++ nss/lib/certdb/crl.c
@@ -1982,7 +1982,7 @@
return SECSuccess;
}
@@ -10,3 +9,32 @@ diff -ru nss.orig/nss/lib/certdb/crl.c nss/nss/lib/certdb/crl.c
if (cache->ncrls) {
/* pick the newest CRL */
+--- nss/lib/softoken/legacydb/pk11db.c
++++ nss/lib/softoken/legacydb/pk11db.c
+@@ -65,7 +65,7 @@
+ unsigned char isModuleDBOnly;
+ unsigned char isCritical;
+ unsigned char reserved[4];
+- unsigned char names[6]; /* enough space for the length fields */
++ unsigned char names[1]; /* +5: enough space for the length fields */
+ };
+
+ struct lgdbSlotDataStr {
+@@ -148,7 +148,7 @@
+ goto loser;
+ }
+
+- dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
++ dataLen = sizeof(lgdbData)+5 + len + len2 + len3 + sizeof(unsigned short) +
+ count * sizeof(lgdbSlotData);
+
+ data->data = (unsigned char *)PORT_ZAlloc(dataLen);
+@@ -327,7 +327,7 @@
+ }
+ if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR) &&
+ (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR)) {
+- CHECK_SIZE(sizeof(lgdbData));
++ CHECK_SIZE(sizeof(lgdbData)+5);
+ trustOrder = LGDB_GETLONG(encoded->trustOrder);
+ cipherOrder = LGDB_GETLONG(encoded->cipherOrder);
+ isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE : PR_FALSE;