diff options
author | Andras Timar <andras.timar@collabora.com> | 2017-03-22 12:13:09 +0100 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-03-22 12:25:15 +0100 |
commit | ada771b1d8d166db336f5ca1ba7671cc528189e9 (patch) | |
tree | 11fd4f4e2fb20c247e96c8d95c07b18acf0eefaa /external | |
parent | 02a74897398a2506f75a971fe1ac2124cdfd268c (diff) |
upgrade nss to version 3.27
Change-Id: I5042457f73204867fd401f3bc6691eda15c32320
Diffstat (limited to 'external')
-rw-r--r-- | external/nss/ExternalPackage_nss.mk | 17 | ||||
-rw-r--r-- | external/nss/ExternalProject_nss.mk | 2 | ||||
-rw-r--r-- | external/nss/Module_nss.mk | 2 | ||||
-rw-r--r-- | external/nss/README | 64 | ||||
-rw-r--r-- | external/nss/UnpackedTarball_nss.mk | 20 | ||||
-rw-r--r-- | external/nss/asan.patch.1 | 12 | ||||
-rw-r--r-- | external/nss/clang-cl.patch.0 | 74 | ||||
-rw-r--r-- | external/nss/nss-pem.patch | 6376 | ||||
-rw-r--r-- | external/nss/nss-winXP-sdk.patch.1 | 5 | ||||
-rw-r--r--[-rwxr-xr-x] | external/nss/nss.cygwin64.in32bit.patch | 0 | ||||
-rw-r--r-- | external/nss/nss.nowerror.patch | 12 | ||||
-rw-r--r-- | external/nss/nss.patch | 26 | ||||
-rw-r--r-- | external/nss/nss.utf8bom.patch.1 | 30 | ||||
-rw-r--r-- | external/nss/nss.vs2015.patch | 12 | ||||
-rw-r--r-- | external/nss/nss.vs2015.pdb.patch | 22 | ||||
-rw-r--r-- | external/nss/nss.windowbuild.patch.0 | 55 | ||||
-rw-r--r-- | external/nss/nss.windows.patch | 6 | ||||
-rw-r--r-- | external/nss/nss_macosx.patch | 10 | ||||
-rw-r--r-- | external/nss/ubsan-alignment.patch.0 | 40 | ||||
-rw-r--r-- | external/nss/ubsan.patch.0 | 34 |
20 files changed, 326 insertions, 6493 deletions
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 f7409e1bb1b5..a0ac57173fd1 100644 --- a/external/nss/UnpackedTarball_nss.mk +++ b/external/nss/UnpackedTarball_nss.mk @@ -17,32 +17,34 @@ $(eval $(call gb_UnpackedTarball_add_patches,nss,\ external/nss/nss-3.13.5-zlib-werror.patch \ external/nss/nss_macosx.patch \ external/nss/nss-win32-make.patch.1 \ - $(if $(filter WNTMSC,$(OS)$(COM)),external/nss/nss.windows.patch) \ + $(if $(filter WNTMSC,$(OS)$(COM)),external/nss/nss.windows.patch \ + external/nss/nss.nowerror.patch \ + external/nss/nss.vs2015.patch) \ $(if $(filter WNTGCC,$(OS)$(COM)),external/nss/nspr-4.9-build.patch.3 \ 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 \ external/nss/nss-ios.patch) \ $(if $(filter MSC-INTEL,$(COM)-$(CPUNAME)), \ external/nss/nss.cygwin64.in32bit.patch) \ + $(if $(filter WNTMSC,$(OS)$(COM)), \ + 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_GCC_IS_CLANG),TRUE) +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 c3f28bc74a6d..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 specifed 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 new file mode 100644 index 000000000000..ff81a9b33539 --- /dev/null +++ b/external/nss/nss.nowerror.patch @@ -0,0 +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 +@@ -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) + 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 new file mode 100644 index 000000000000..de4f8762fd5b --- /dev/null +++ b/external/nss/nss.vs2015.patch @@ -0,0 +1,12 @@ +diff -ru nss.org/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk +--- a/nss.org/nss/coreconf/WIN32.mk 2016-02-12 15:36:18.000000000 +0100 ++++ b/nss/nss/coreconf/WIN32.mk 2016-02-26 00:42:43.170809600 +0100 +@@ -199,7 +199,7 @@ + # Disable C4244: conversion from 'type1' to 'type2', possible loss of data + # Disable C4018: 'expression' : signed/unsigned mismatch + # Disable C4312: 'type cast': conversion from 'type1' to 'type2' of greater size +- OS_CFLAGS += -w44267 -w44244 -w44018 -w44312 ++ OS_CFLAGS += -w44267 -w44244 -w44018 -w44312 -wd4996 -wd4554 + ifeq ($(_MSC_VER_GE_12),1) + OS_CFLAGS += -FS + endif diff --git a/external/nss/nss.vs2015.pdb.patch b/external/nss/nss.vs2015.pdb.patch new file mode 100644 index 000000000000..dc4f4638b476 --- /dev/null +++ b/external/nss/nss.vs2015.pdb.patch @@ -0,0 +1,22 @@ +diff -ru nss.orig/nss/coreconf/WIN32.mk nss/nss/coreconf/WIN32.mk +--- a/nss.orig/nss/coreconf/WIN32.mk 2016-03-04 08:30:16.306639400 +0100 ++++ b/nss/nss/coreconf/WIN32.mk 2016-03-04 08:31:17.987233200 +0100 +@@ -169,15 +169,15 @@ + DLLFLAGS += -OUT:$@ + ifdef MOZ_DEBUG_SYMBOLS + ifdef MOZ_DEBUG_FLAGS +- OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd$(OBJDIR)/ ++ OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd./ + else +- OPTIMIZER += -Zi -Fd$(OBJDIR)/ ++ OPTIMIZER += -Zi -Fd./ + endif + DLLFLAGS += -DEBUG -OPT:REF + LDFLAGS += -DEBUG -OPT:REF + endif + else +- OPTIMIZER += -Zi -Fd$(OBJDIR)/ -Od ++ OPTIMIZER += -Zi -Fd./ -Od + NULLSTRING := + SPACE := $(NULLSTRING) # end of the line + USERNAME := $(subst $(SPACE),_,$(USERNAME)) 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; |