summaryrefslogtreecommitdiffstats
path: root/nss
diff options
context:
space:
mode:
Diffstat (limited to 'nss')
-rw-r--r--nss/.hg_archival.txt6
-rw-r--r--nss/automation/abi-check/expected-report-libnss3.so.txt17
-rw-r--r--nss/automation/abi-check/expected-report-libnssutil3.so.txt19
-rw-r--r--nss/automation/abi-check/expected-report-libsmime3.so.txt89
-rw-r--r--nss/automation/abi-check/previous-nss-release2
-rwxr-xr-xnss/build.sh2
-rw-r--r--nss/cmd/certutil/certext.c1
-rw-r--r--nss/coreconf/config.gypi11
-rw-r--r--nss/doc/rst/releases/index.rst28
-rw-r--r--nss/doc/rst/releases/nss_3_100.rst64
-rw-r--r--nss/gtests/nss_bogo_shim/nss_bogo_shim.cc13
-rw-r--r--nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc46
-rw-r--r--nss/lib/ckfw/Makefile25
-rw-r--r--nss/lib/ckfw/capi/Makefile82
-rw-r--r--nss/lib/ckfw/capi/README7
-rw-r--r--nss/lib/ckfw/capi/anchor.c17
-rw-r--r--nss/lib/ckfw/capi/cfind.c561
-rw-r--r--nss/lib/ckfw/capi/cinst.c97
-rw-r--r--nss/lib/ckfw/capi/ckcapi.h242
-rw-r--r--nss/lib/ckfw/capi/ckcapiver.c17
-rw-r--r--nss/lib/ckfw/capi/cobject.c2226
-rw-r--r--nss/lib/ckfw/capi/constants.c63
-rw-r--r--nss/lib/ckfw/capi/crsa.c687
-rw-r--r--nss/lib/ckfw/capi/csession.c87
-rw-r--r--nss/lib/ckfw/capi/cslot.c81
-rw-r--r--nss/lib/ckfw/capi/ctoken.c184
-rw-r--r--nss/lib/ckfw/capi/manifest.mn35
-rw-r--r--nss/lib/ckfw/capi/nsscapi.def26
-rw-r--r--nss/lib/ckfw/capi/nsscapi.h41
-rw-r--r--nss/lib/ckfw/capi/nsscapi.rc64
-rw-r--r--nss/lib/ckfw/capi/staticobj.c40
-rw-r--r--nss/lib/nss/nss.h4
-rw-r--r--nss/lib/pk11wrap/pk11skey.c8
-rw-r--r--nss/lib/pk11wrap/pk11slot.c9
-rw-r--r--nss/lib/smime/cmsasn1.c55
-rw-r--r--nss/lib/smime/cmslocal.h24
-rw-r--r--nss/lib/smime/cmspubkey.c624
-rw-r--r--nss/lib/smime/cmsrecinfo.c78
-rw-r--r--nss/lib/smime/cmst.h17
-rw-r--r--nss/lib/softoken/pkcs11.c6
-rw-r--r--nss/lib/softoken/softkver.h4
-rw-r--r--nss/lib/ssl/tls13con.c9
-rw-r--r--nss/lib/util/nssutil.h4
-rw-r--r--nss/lib/util/secoid.c45
-rw-r--r--nss/lib/util/secoidt.h11
-rwxr-xr-xnss/tests/cert/cert.sh33
-rw-r--r--nss/tests/smime/interop-openssl/Fran-ec.p12bin0 -> 1233 bytes
-rw-r--r--nss/tests/smime/interop-openssl/Fran.p12bin0 -> 2582 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.envbin0 -> 450 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.envbin0 -> 447 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.envbin0 -> 447 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.envbin0 -> 455 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.envbin0 -> 463 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-label_ossl.envbin0 -> 571 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha256hash-label_ossl.envbin0 -> 614 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha256hash-sha256mgf_ossl.envbin0 -> 589 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.envbin0 -> 589 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha256mgf-label_ossl.envbin0 -> 599 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.envbin0 -> 574 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.envbin0 -> 589 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.envbin0 -> 574 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.envbin0 -> 589 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.envbin0 -> 574 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep_ossl-sha256hash-sha256mgf-label.envbin0 -> 614 bytes
-rw-r--r--nss/tests/smime/interop-openssl/fran-oaep_ossl.envbin0 -> 529 bytes
-rwxr-xr-xnss/tests/smime/smime.sh150
66 files changed, 1096 insertions, 4865 deletions
diff --git a/nss/.hg_archival.txt b/nss/.hg_archival.txt
index eb85e3a..3181a55 100644
--- a/nss/.hg_archival.txt
+++ b/nss/.hg_archival.txt
@@ -1,4 +1,4 @@
repo: 9949429068caa6bb8827a8ceeaa7c605d722f47f
-node: 3594a1841f437338d44afa970a527714d86f36c7
-branch: NSS_3_99_BRANCH
-tag: NSS_3_99_RTM
+node: 09996a932d30c1318c690296c69c0caa25130d52
+branch: NSS_3_100_BRANCH
+tag: NSS_3_100_RTM
diff --git a/nss/automation/abi-check/expected-report-libnss3.so.txt b/nss/automation/abi-check/expected-report-libnss3.so.txt
index 582afe3..97f1a7c 100644
--- a/nss/automation/abi-check/expected-report-libnss3.so.txt
+++ b/nss/automation/abi-check/expected-report-libnss3.so.txt
@@ -5,11 +5,20 @@
parameter 2 of type 'typedef SECOidTag' has sub-type changes:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
- 2 enumerator insertions:
- '__anonymous_enum__::SEC_OID_ED25519_SIGNATURE' value '373'
- '__anonymous_enum__::SEC_OID_ED25519_PUBLIC_KEY' value '374'
+ 10 enumerator insertions:
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME' value '375'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME' value '376'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME' value '377'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME' value '378'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME' value '379'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME' value '380'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME' value '381'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME' value '382'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME' value '383'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME' value '384'
1 enumerator change:
- '__anonymous_enum__::SEC_OID_TOTAL' from value '373' to '375' at secoidt.h:34:1
+ '__anonymous_enum__::SEC_OID_TOTAL' from value '375' to '385' at secoidt.h:34:1
+
diff --git a/nss/automation/abi-check/expected-report-libnssutil3.so.txt b/nss/automation/abi-check/expected-report-libnssutil3.so.txt
index ed076df..f0d77ef 100644
--- a/nss/automation/abi-check/expected-report-libnssutil3.so.txt
+++ b/nss/automation/abi-check/expected-report-libnssutil3.so.txt
@@ -1,15 +1,24 @@
1 function with some indirect sub-type change:
- [C]'function SECStatus NSS_GetAlgorithmPolicy(SECOidTag, PRUint32*)' at secoid.c:2291:1 has some indirect sub-type changes:
+ [C]'function SECStatus NSS_GetAlgorithmPolicy(SECOidTag, PRUint32*)' at secoid.c:2336:1 has some indirect sub-type changes:
parameter 1 of type 'typedef SECOidTag' has sub-type changes:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
- 2 enumerator insertions:
- '__anonymous_enum__::SEC_OID_ED25519_SIGNATURE' value '373'
- '__anonymous_enum__::SEC_OID_ED25519_PUBLIC_KEY' value '374'
+ 10 enumerator insertions:
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME' value '375'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME' value '376'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME' value '377'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME' value '378'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME' value '379'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME' value '380'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME' value '381'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME' value '382'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME' value '383'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME' value '384'
1 enumerator change:
- '__anonymous_enum__::SEC_OID_TOTAL' from value '373' to '375' at secoidt.h:34:1
+ '__anonymous_enum__::SEC_OID_TOTAL' from value '375' to '385' at secoidt.h:34:1
+
diff --git a/nss/automation/abi-check/expected-report-libsmime3.so.txt b/nss/automation/abi-check/expected-report-libsmime3.so.txt
index 69cd2ae..a42f62c 100644
--- a/nss/automation/abi-check/expected-report-libsmime3.so.txt
+++ b/nss/automation/abi-check/expected-report-libsmime3.so.txt
@@ -1,8 +1,4 @@
-1 Added function:
-
- 'function PRBool NSS_CMSRecipient_IsSupported(CERTCertificate*)' {NSS_CMSRecipient_IsSupported@@NSS_3.99}
-
1 function with some indirect sub-type change:
[C]'function PK11SymKey* NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo*)' at cmscinfo.c:426:1 has some indirect sub-type changes:
@@ -14,34 +10,103 @@
type of 'NSSCMSContent NSSCMSContentInfoStr::content' changed:
underlying type 'union NSSCMSContentUnion' at cmst.h:113:1 changed:
type size hasn't changed
- 1 data member changes (3 filtered):
+ 2 data member changes (2 filtered):
type of 'NSSCMSEncryptedData* NSSCMSContentUnion::encryptedData' changed:
in pointed to type 'typedef NSSCMSEncryptedData' at cmst.h:65:1:
- underlying type 'struct NSSCMSEncryptedDataStr' at cmst.h:463:1 changed:
+ underlying type 'struct NSSCMSEncryptedDataStr' at cmst.h:470:1 changed:
type size hasn't changed
1 data member changes (1 filtered):
type of 'NSSCMSAttribute** NSSCMSEncryptedDataStr::unprotectedAttr' changed:
in pointed to type 'NSSCMSAttribute*':
in pointed to type 'typedef NSSCMSAttribute' at cmst.h:69:1:
- underlying type 'struct NSSCMSAttributeStr' at cmst.h:482:1 changed:
+ underlying type 'struct NSSCMSAttributeStr' at cmst.h:489:1 changed:
type size hasn't changed
1 data member change:
type of 'SECOidData* NSSCMSAttributeStr::typeTag' changed:
in pointed to type 'typedef SECOidData' at secoidt.h:16:1:
- underlying type 'struct SECOidDataStr' at secoidt.h:536:1 changed:
+ underlying type 'struct SECOidDataStr' at secoidt.h:547:1 changed:
type size hasn't changed
1 data member change:
type of 'SECOidTag SECOidDataStr::offset' changed:
underlying type 'enum __anonymous_enum__' at secoidt.h:34:1 changed:
type size hasn't changed
- 2 enumerator insertions:
- '__anonymous_enum__::SEC_OID_ED25519_SIGNATURE' value '373'
- '__anonymous_enum__::SEC_OID_ED25519_PUBLIC_KEY' value '374'
+ 10 enumerator insertions:
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME' value '375'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME' value '376'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME' value '377'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME' value '378'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME' value '379'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME' value '380'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME' value '381'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME' value '382'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME' value '383'
+ '__anonymous_enum__::SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME' value '384'
1 enumerator change:
- '__anonymous_enum__::SEC_OID_TOTAL' from value '373' to '375' at secoidt.h:34:1
+ '__anonymous_enum__::SEC_OID_TOTAL' from value '375' to '385' at secoidt.h:34:1
+
+
+
+
+
+ type of 'NSSCMSEnvelopedData* NSSCMSContentUnion::envelopedData' changed:
+ in pointed to type 'typedef NSSCMSEnvelopedData' at cmst.h:60:1:
+ underlying type 'struct NSSCMSEnvelopedDataStr' at cmst.h:257:1 changed:
+ type size hasn't changed
+ 1 data member changes (2 filtered):
+ type of 'NSSCMSRecipientInfo** NSSCMSEnvelopedDataStr::recipientInfos' changed:
+ in pointed to type 'NSSCMSRecipientInfo*':
+ in pointed to type 'typedef NSSCMSRecipientInfo' at cmst.h:62:1:
+ underlying type 'struct NSSCMSRecipientInfoStr' at cmst.h:439:1 changed:
+ type size changed from 1536 to 1664 bits
+ 3 data member changes:
+ type of '__anonymous_union__ NSSCMSRecipientInfoStr::ri' changed:
+ type size changed from 1344 to 1472 bits
+ 2 data member changes:
+ type of 'NSSCMSKEKRecipientInfo __anonymous_union__::kekRecipientInfo' changed:
+ underlying type 'struct NSSCMSKEKRecipientInfoStr' at cmst.h:397:1 changed:
+ type size hasn't changed
+ 1 data member change:
+ type of 'NSSCMSKEKIdentifier NSSCMSKEKRecipientInfoStr::kekIdentifier' changed:
+ underlying type 'struct NSSCMSKEKIdentifierStr' at cmst.h:390:1 changed:
+ type size hasn't changed
+ 1 data member change:
+ type of 'SECItem* NSSCMSKEKIdentifierStr::other' changed:
+ in pointed to type 'typedef SECItem' at cmst.h:347:1:
+ underlying type 'struct SECItemStr' at cmst.h:342:1 changed:
+ type name changed from 'SECItemStr' to 'NSSCMSOtherKeyAttributeStr'
+ type size changed from 192 to 384 bits
+ 2 data member deletions:
+ 'unsigned char* SECItemStr::data', at offset 64 (in bits) at seccomon.h:52:1
+
+ 'unsigned int SECItemStr::len', at offset 128 (in bits) at seccomon.h:53:1
+
+ 1 data member insertion:
+ 'SECItem NSSCMSOtherKeyAttributeStr::keyAttr', at offset 192 (in bits) at cmst.h:344:1
+ 1 data member change:
+ type of 'SECItemType SECItemStr::type' changed:
+ underlying type 'enum __anonymous_enum__' at seccomon.h:50:1 changed:
+ entity changed from 'enum __anonymous_enum__' to 'struct SECItemStr' at seccomon.h:50:1
+ type size changed from 32 to 192 bits
+ type alignment changed from 32 to 0 bits
+
+
+
+
+ type of 'NSSCMSKeyAgreeRecipientInfo __anonymous_union__::keyAgreeRecipientInfo' changed:
+ underlying type 'struct NSSCMSKeyAgreeRecipientInfoStr' at cmst.h:376:1 changed:
+ type size changed from 1344 to 1472 bits
+ 3 data member changes:
+ type of 'SECItem* NSSCMSKeyAgreeRecipientInfoStr::ukm' changed:
+ entity changed from 'SECItem*' to 'typedef SECItem' at seccomon.h:48:1
+ type size changed from 64 to 192 bits
+
+ 'SECAlgorithmID NSSCMSKeyAgreeRecipientInfoStr::keyEncAlg' offset changed from 896 to 1024 (in bits) (by +128 bits)
+ 'NSSCMSRecipientEncryptedKey** NSSCMSKeyAgreeRecipientInfoStr::recipientEncryptedKeys' offset changed from 1280 to 1408 (in bits) (by +128 bits)
+ 'NSSCMSMessage* NSSCMSRecipientInfoStr::cmsg' offset changed from 1408 to 1536 (in bits) (by +128 bits)
+ 'CERTCertificate* NSSCMSRecipientInfoStr::cert' offset changed from 1472 to 1600 (in bits) (by +128 bits)
diff --git a/nss/automation/abi-check/previous-nss-release b/nss/automation/abi-check/previous-nss-release
index 0dea1b7..335e901 100644
--- a/nss/automation/abi-check/previous-nss-release
+++ b/nss/automation/abi-check/previous-nss-release
@@ -1 +1 @@
-NSS_3_98_BRANCH
+NSS_3_99_BRANCH
diff --git a/nss/build.sh b/nss/build.sh
index ae8eeee..73c6d77 100755
--- a/nss/build.sh
+++ b/nss/build.sh
@@ -124,6 +124,8 @@ while [ $# -gt 0 ]; do
--system-nspr) set_nspr_path "/usr/include/nspr/:"; no_local_nspr=1 ;;
--system-sqlite) gyp_params+=(-Duse_system_sqlite=1) ;;
--enable-fips) gyp_params+=(-Ddisable_fips=0) ;;
+ --fips-module-id) gyp_params+=(-Dfips_module_id="$2"); shift ;;
+ --fips-module-id=?*) gyp_params+=(-Dfips_module_id="${1#*=}") ;;
--enable-libpkix) gyp_params+=(-Ddisable_libpkix=0) ;;
--mozpkix-only) gyp_params+=(-Dmozpkix_only=1 -Ddisable_tests=1 -Dsign_libs=0) ;;
--disable-keylog) sslkeylogfile=0 ;;
diff --git a/nss/cmd/certutil/certext.c b/nss/cmd/certutil/certext.c
index 501608c..0035d8c 100644
--- a/nss/cmd/certutil/certext.c
+++ b/nss/cmd/certutil/certext.c
@@ -1219,6 +1219,7 @@ AddCrlDistPoint(void *extHandle)
intValue = PORT_Atoi(buffer);
switch (intValue) {
case generalName:
+ PORT_SetError(0);
current->distPointType = intValue;
current->distPoint.fullName = CreateGeneralName(arena);
rv = PORT_GetError();
diff --git a/nss/coreconf/config.gypi b/nss/coreconf/config.gypi
index 13f857c..baf4256 100644
--- a/nss/coreconf/config.gypi
+++ b/nss/coreconf/config.gypi
@@ -136,6 +136,7 @@
'nss_include_dir%': '/usr/include/nss',
'only_dev_random%': 1,
'disable_fips%': 1,
+ 'fips_module_id%': '',
'mozpkix_only%': 0,
'mozilla_central%': 0,
'coverage%': 0,
@@ -165,12 +166,22 @@
'<(nss_include_dir)',
],
}],
+ [ 'disable_fips==0', {
+ 'defines': [
+ 'NSS_ENABLE_FIPS_INDICATORS',
+ ],
+ }],
[ 'disable_fips==1', {
'defines': [
'NSS_FIPS_DISABLED',
'NSS_NO_INIT_SUPPORT',
],
}],
+ [ 'fips_module_id!=""', {
+ 'defines': [
+ 'NSS_FIPS_MODULE_ID="<(fips_module_id)"'
+ ],
+ }],
[ 'OS!="android" and OS!="mac" and OS!="ios" and OS!="win"', {
'libraries': [
'-lpthread',
diff --git a/nss/doc/rst/releases/index.rst b/nss/doc/rst/releases/index.rst
index 865aad2..e0f3249 100644
--- a/nss/doc/rst/releases/index.rst
+++ b/nss/doc/rst/releases/index.rst
@@ -8,6 +8,7 @@ Releases
:glob:
:hidden:
+ nss_3_100.rst
nss_3_99.rst
nss_3_98.rst
nss_3_97.rst
@@ -64,23 +65,24 @@ Releases
.. note::
- **NSS 3.99** is the latest version of NSS.
- Complete release notes are available here: :ref:`mozilla_projects_nss_nss_3_99_release_notes`
+ **NSS 3.100** is the latest version of NSS.
+ Complete release notes are available here: :ref:`mozilla_projects_nss_nss_3_100_release_notes`
**NSS 3.90.2 (ESR)** is the latest version of NSS.
Complete release notes are available here: :ref:`mozilla_projects_nss_nss_3_90_2_release_notes`
.. container::
- Changes in 3.99 included in this release:
-
- - Bug 1325335 - Removing check for message len in ed25519
- - Bug 1884276 - add ed25519 to SECU_ecName2params.
- - Bug 1325335 - add EdDSA wycheproof tests.
- - Bug 1325335 - nss/lib layer code for EDDSA.
- - Bug 1325335 - Adding EdDSA implementation.
- - Bug 1881027 - Exporting Certificate Compression types
- - Bug 1880857 - Updating ACVP docker to rust 1.74
- - Bug 1325335 - Updating HACL* to 0f136f28935822579c244f287e1d2a1908a7e552
- - Bug 1877730 - Add NSS_CMSRecipient_IsSupported.
+ Changes in 3.100 included in this release:
+ - Bug 1893029 - merge pk11_kyberSlotList into pk11_ecSlotList for faster Xyber operations.
+ - Bug 1893752 - remove ckcapi.
+ - Bug 1893162 - avoid a potential PK11GenericObject memory leak.
+ - Bug 671060 - Remove incomplete ESDH code.
+ - Bug 215997 - Decrypt RSA OAEP encrypted messages.
+ - Bug 1887996 - Fix certutil CRLDP URI code.
+ - Bug 1890069 - Don't set CKA_DERIVE for CKK_EC_EDWARDS private keys.
+ - Bug 676118: Add ability to encrypt and decrypt CMS messages using ECDH.
+ - Bug 676100 - Correct Templates for key agreement in smime/cmsasn.c.
+ - Bug 1548723 - Moving the decodedCert allocation to NSS.
+ - Bug 1885404 - Allow developers to speed up repeated local execution of NSS tests that depend on certificates. \ No newline at end of file
diff --git a/nss/doc/rst/releases/nss_3_100.rst b/nss/doc/rst/releases/nss_3_100.rst
new file mode 100644
index 0000000..11362b3
--- /dev/null
+++ b/nss/doc/rst/releases/nss_3_100.rst
@@ -0,0 +1,64 @@
+.. _mozilla_projects_nss_nss_3_100_release_notes:
+
+NSS 3.100 release notes
+========================
+
+`Introduction <#introduction>`__
+--------------------------------
+
+.. container::
+
+ Network Security Services (NSS) 3.100 was released on *7th May 2024**.
+
+`Distribution Information <#distribution_information>`__
+--------------------------------------------------------
+
+.. container::
+
+ The HG tag is NSS_3_100_RTM. NSS 3.100 requires NSPR 4.35 or newer.
+
+ NSS 3.100 source distributions are available on ftp.mozilla.org for secure HTTPS download:
+
+ - Source tarballs:
+ https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_100_RTM/src/
+
+ Other releases are available :ref:`mozilla_projects_nss_releases`.
+
+.. _changes_in_nss_3.100:
+
+`Changes in NSS 3.100 <#changes_in_nss_3.100>`__
+------------------------------------------------------------------
+
+.. container::
+
+ - Bug 1893029 - merge pk11_kyberSlotList into pk11_ecSlotList for faster Xyber operations.
+ - Bug 1893752 - remove ckcapi.
+ - Bug 1893162 - avoid a potential PK11GenericObject memory leak.
+ - Bug 671060 - Remove incomplete ESDH code.
+ - Bug 215997 - Decrypt RSA OAEP encrypted messages.
+ - Bug 1887996 - Fix certutil CRLDP URI code.
+ - Bug 1890069 - Don't set CKA_DERIVE for CKK_EC_EDWARDS private keys.
+ - Bug 676118: Add ability to encrypt and decrypt CMS messages using ECDH.
+ - Bug 676100 - Correct Templates for key agreement in smime/cmsasn.c.
+ - Bug 1548723 - Moving the decodedCert allocation to NSS.
+ - Bug 1885404 - Allow developers to speed up repeated local execution of NSS tests that depend on certificates.
+
+`Compatibility <#compatibility>`__
+----------------------------------
+
+.. container::
+
+ NSS 3.100 shared libraries are backwards-compatible with all older NSS 3.x shared
+ libraries. A program linked with older NSS 3.x shared libraries will work with
+ this new version of the shared libraries without recompiling or
+ relinking. Furthermore, applications that restrict their use of NSS APIs to the
+ functions listed in NSS Public Functions will remain compatible with future
+ versions of the NSS shared libraries.
+
+`Feedback <#feedback>`__
+------------------------
+
+.. container::
+
+ Bugs discovered should be reported by filing a bug report on
+ `bugzilla.mozilla.org <https://bugzilla.mozilla.org/enter_bug.cgi?product=NSS>`__ (product NSS).
diff --git a/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc b/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
index 12adcc5..8544605 100644
--- a/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
+++ b/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc
@@ -657,8 +657,8 @@ class TestAgent {
return SECFailure;
}
- SECITEM_AllocItem(NULL, output, input->len + 2);
- if (output == NULL || output->data == NULL) {
+ if (output == NULL || output->data == NULL ||
+ output->len != input->len + 2) {
return SECFailure;
}
@@ -718,9 +718,8 @@ class TestAgent {
return SECFailure;
}
- SECITEM_AllocItem(NULL, output, input->len - 4);
-
- if (output == NULL || output->data == NULL) {
+ if (output == NULL || output->data == NULL ||
+ output->len != input->len - 4) {
return SECFailure;
}
@@ -785,9 +784,9 @@ class TestAgent {
std::cerr << "Certificate is too short. " << std::endl;
return SECFailure;
}
- SECITEM_AllocItem(NULL, output, input->len - 1);
- if (output == NULL || output->data == NULL) {
+ if (output == NULL || output->data == NULL ||
+ output->len != input->len - 1) {
return SECFailure;
}
diff --git a/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc b/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc
index 01a0250..44c6a7e 100644
--- a/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc
+++ b/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc
@@ -221,6 +221,7 @@ class TLSCertificateToEncodedCertificateChanger : public TlsRecordFilter {
static SECStatus SimpleXorCertCompEncode(const SECItem* input,
SECItem* output) {
SECITEM_CopyItem(NULL, output, input);
+ PORT_Memcpy(output->data, input->data, output->len);
for (size_t i = 0; i < output->len; i++) {
output->data[i] ^= 0x55;
}
@@ -230,7 +231,7 @@ static SECStatus SimpleXorCertCompEncode(const SECItem* input,
/* Test decoding function. */
static SECStatus SimpleXorCertCompDecode(const SECItem* input, SECItem* output,
size_t expectedLenDecodedCertificate) {
- SECITEM_CopyItem(NULL, output, input);
+ PORT_Memcpy(output->data, input->data, input->len);
for (size_t i = 0; i < output->len; i++) {
output->data[i] ^= 0x55;
}
@@ -251,7 +252,7 @@ static SECStatus SimpleXorWithDifferentValueEncode(const SECItem* input,
static SECStatus SimpleXorWithDifferentValueDecode(
const SECItem* input, SECItem* output,
size_t expectedLenDecodedCertificate) {
- SECITEM_CopyItem(NULL, output, input);
+ PORT_Memcpy(output->data, input->data, input->len);
for (size_t i = 0; i < output->len; i++) {
output->data[i] ^= 0x77;
}
@@ -1128,47 +1129,6 @@ TEST_F(TlsConnectStreamTls13, CertificateCompression_ReceivedWrongAlgorithm) {
SEC_ERROR_CERTIFICATE_COMPRESSION_ALGORITHM_NOT_SUPPORTED);
}
-static SECStatus SimpleXorCertCompDecode_length_smaller_than_given(
- const SECItem* input, SECItem* output,
- size_t expectedLenDecodedCertificate) {
- SECITEM_MakeItem(NULL, output, input->data, input->len - 1);
- return SECSuccess;
-}
-
-/*
- * The next test modifies the length of the received certificate
- * (uncompressed_length field of CompressedCertificate).
- */
-TEST_F(TlsConnectStreamTls13, CertificateCompression_ReceivedWrongLength) {
- EnsureTlsSetup();
- auto filterExtension =
- MakeTlsFilter<TLSCertificateCompressionCertificateModifier>(server_, 0x6,
- 0xff);
- SSLCertificateCompressionAlgorithm t = {
- 0xff01, "test function", SimpleXorCertCompEncode,
- SimpleXorCertCompDecode_length_smaller_than_given};
-
- EXPECT_EQ(SECSuccess,
- SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t));
- EXPECT_EQ(SECSuccess,
- SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t));
-
- ExpectAlert(client_, kTlsAlertBadCertificate);
- StartConnect();
-
- client_->SetServerKeyBits(server_->server_key_bits());
- client_->Handshake();
- server_->Handshake();
-
- ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING), 5000);
- ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state());
-
- client_->ExpectSendAlert(kTlsAlertCloseNotify);
- server_->ExpectReceiveAlert(kTlsAlertCloseNotify);
-
- client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE);
-}
-
/* The next test modifies the length of the encoded certificate
* (compressed_certificate_message len);
* the new length is compressed_certificate_message is equal to 0.
diff --git a/nss/lib/ckfw/Makefile b/nss/lib/ckfw/Makefile
index effa9ab..3f49eaa 100644
--- a/nss/lib/ckfw/Makefile
+++ b/nss/lib/ckfw/Makefile
@@ -11,29 +11,4 @@ ifdef BUILD_IDG
DEFINES += -DNSSDEBUG
endif
-ifdef NOTDEF # was ifdef MOZILLA_CLIENT
-NSS_BUILD_CAPI = 1
-endif
-
-# This'll need some help from a build person.
-
-# The generated files are checked in, and differ from what ckapi.perl
-# will produce. ckapi.perl is currently newer than the targets, so
-# these rules are invoked, causing the wrong files to be generated.
-# Turning off to fix builds.
-#
-# nssckepv.h: ck.api ckapi.perl
-# nssckft.h: ck.api ckapi.perl
-# nssckg.h: ck.api ckapi.perl
-# nssck.api: ck.api ckapi.perl
-# $(PERL) ckapi.perl ck.api
-
-
-# can't do this in manifest.mn because OS_TARGET isn't defined there.
-ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
-ifdef NSS_BUILD_CAPI
-DIRS += capi
-endif
-endif
-
include $(CORE_DEPTH)/coreconf/rules.mk
diff --git a/nss/lib/ckfw/capi/Makefile b/nss/lib/ckfw/capi/Makefile
deleted file mode 100644
index 3949d18..0000000
--- a/nss/lib/ckfw/capi/Makefile
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# 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 manifest.mn
-include $(CORE_DEPTH)/coreconf/config.mk
-
-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
-
-EXTRA_LIBS = \
- $(DIST)/lib/$(LIB_PREFIX)nssckfw.$(LIB_SUFFIX) \
- $(DIST)/lib/$(LIB_PREFIX)nssb.$(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 \
- -lcrypt32 \
- -ladvapi32 \
- -lrpcrt4 \
- $(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) | $$(@D)/d
- 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/nss/lib/ckfw/capi/README b/nss/lib/ckfw/capi/README
deleted file mode 100644
index 9fc5720..0000000
--- a/nss/lib/ckfw/capi/README
+++ /dev/null
@@ -1,7 +0,0 @@
-This Cryptoki module provides acces to certs and keys stored in
-Microsofts CAPI certificate store.
-
-It does not import or export CA Root trust from the CAPI.
-It does not import or export CRLs from the CAPI.
-It does not handle S/MIME objects (pkcs #7 in capi terms?).
-It does not yet handle it's own PIN. (CAPI does all the pin prompting).
diff --git a/nss/lib/ckfw/capi/anchor.c b/nss/lib/ckfw/capi/anchor.c
deleted file mode 100644
index 2d1523e..0000000
--- a/nss/lib/ckfw/capi/anchor.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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/. */
-
-/*
- * capi/canchor.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 "ckcapi.h"
-
-#define MODULE_NAME ckcapi
-#define INSTANCE_NAME (NSSCKMDInstance *)&nss_ckcapi_mdInstance
-#include "nssck.api"
diff --git a/nss/lib/ckfw/capi/cfind.c b/nss/lib/ckfw/capi/cfind.c
deleted file mode 100644
index 9c4d4f1..0000000
--- a/nss/lib/ckfw/capi/cfind.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/* 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/. */
-
-#ifndef CKCAPI_H
-#include "ckcapi.h"
-#endif /* CKCAPI_H */
-
-/*
- * ckcapi/cfind.c
- *
- * This file implements the NSSCKMDFindObjects object for the
- * "capi" cryptoki module.
- */
-
-struct ckcapiFOStr {
- NSSArena *arena;
- CK_ULONG n;
- CK_ULONG i;
- ckcapiInternalObject **objs;
-};
-
-static void
-ckcapi_mdFindObjects_Final(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
- NSSArena *arena = fo->arena;
- PRUint32 i;
-
- /* walk down an free the unused 'objs' */
- for (i = fo->i; i < fo->n; i++) {
- nss_ckcapi_DestroyInternalObject(fo->objs[i]);
- }
-
- nss_ZFreeIf(fo->objs);
- nss_ZFreeIf(fo);
- nss_ZFreeIf(mdFindObjects);
- if ((NSSArena *)NULL != arena) {
- NSSArena_Destroy(arena);
- }
-
- return;
-}
-
-static NSSCKMDObject *
-ckcapi_mdFindObjects_Next(
- NSSCKMDFindObjects *mdFindObjects,
- NSSCKFWFindObjects *fwFindObjects,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSArena *arena,
- CK_RV *pError)
-{
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)mdFindObjects->etc;
- ckcapiInternalObject *io;
-
- if (fo->i == fo->n) {
- *pError = CKR_OK;
- return (NSSCKMDObject *)NULL;
- }
-
- io = fo->objs[fo->i];
- fo->i++;
-
- return nss_ckcapi_CreateMDObject(arena, io, pError);
-}
-
-static CK_BBOOL
-ckcapi_attrmatch(
- CK_ATTRIBUTE_PTR a,
- ckcapiInternalObject *o)
-{
- PRBool prb;
- const NSSItem *b;
-
- b = nss_ckcapi_FetchAttribute(o, a->type);
- if (b == NULL) {
- return CK_FALSE;
- }
-
- if (a->ulValueLen != b->size) {
- /* match a decoded serial number */
- if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
- unsigned int len;
- unsigned char *data;
-
- data = nss_ckcapi_DERUnwrap(b->data, b->size, &len, NULL);
- if ((len == a->ulValueLen) &&
- nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
- return CK_TRUE;
- }
- }
- return CK_FALSE;
- }
-
- prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
-
- if (PR_TRUE == prb) {
- return CK_TRUE;
- } else {
- return CK_FALSE;
- }
-}
-
-static CK_BBOOL
-ckcapi_match(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject *o)
-{
- CK_ULONG i;
-
- for (i = 0; i < ulAttributeCount; i++) {
- if (CK_FALSE == ckcapi_attrmatch(&pTemplate[i], o)) {
- return CK_FALSE;
- }
- }
-
- /* Every attribute passed */
- return CK_TRUE;
-}
-
-#define CKAPI_ITEM_CHUNK 20
-
-#define PUT_Object(obj, err) \
- { \
- if (count >= size) { \
- *listp = *listp ? nss_ZREALLOCARRAY(*listp, ckcapiInternalObject *, \
- (size + \
- CKAPI_ITEM_CHUNK)) \
- : nss_ZNEWARRAY(NULL, ckcapiInternalObject *, \
- (size + \
- CKAPI_ITEM_CHUNK)); \
- if ((ckcapiInternalObject **)NULL == *listp) { \
- err = CKR_HOST_MEMORY; \
- goto loser; \
- } \
- size += CKAPI_ITEM_CHUNK; \
- } \
- (*listp)[count] = (obj); \
- count++; \
- }
-
-/*
- * pass parameters back through the callback.
- */
-typedef struct BareCollectParamsStr {
- CK_OBJECT_CLASS objClass;
- CK_ATTRIBUTE_PTR pTemplate;
- CK_ULONG ulAttributeCount;
- ckcapiInternalObject ***listp;
- PRUint32 size;
- PRUint32 count;
-} BareCollectParams;
-
-/* collect_bare's callback. Called for each object that
- * supposedly has a PROVINDER_INFO property */
-static BOOL WINAPI
-doBareCollect(
- const CRYPT_HASH_BLOB *msKeyID,
- DWORD flags,
- void *reserved,
- void *args,
- DWORD cProp,
- DWORD *propID,
- void **propData,
- DWORD *propSize)
-{
- BareCollectParams *bcp = (BareCollectParams *)args;
- PRUint32 size = bcp->size;
- PRUint32 count = bcp->count;
- ckcapiInternalObject ***listp = bcp->listp;
- ckcapiInternalObject *io = NULL;
- DWORD i;
- CRYPT_KEY_PROV_INFO *keyProvInfo = NULL;
- void *idData;
- CK_RV error;
-
- /* make sure there is a Key Provider Info property */
- for (i = 0; i < cProp; i++) {
- if (CERT_KEY_PROV_INFO_PROP_ID == propID[i]) {
- keyProvInfo = (CRYPT_KEY_PROV_INFO *)propData[i];
- break;
- }
- }
- if ((CRYPT_KEY_PROV_INFO *)NULL == keyProvInfo) {
- return 1;
- }
-
- /* copy the key ID */
- idData = nss_ZNEWARRAY(NULL, char, msKeyID->cbData);
- if ((void *)NULL == idData) {
- goto loser;
- }
- nsslibc_memcpy(idData, msKeyID->pbData, msKeyID->cbData);
-
- /* build a bare internal object */
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- goto loser;
- }
- io->type = ckcapiBareKey;
- io->objClass = bcp->objClass;
- io->u.key.provInfo = *keyProvInfo;
- io->u.key.provInfo.pwszContainerName =
- nss_ckcapi_WideDup(keyProvInfo->pwszContainerName);
- io->u.key.provInfo.pwszProvName =
- nss_ckcapi_WideDup(keyProvInfo->pwszProvName);
- io->u.key.provName = nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
- io->u.key.containerName =
- nss_ckcapi_WideToUTF8(keyProvInfo->pwszContainerName);
- io->u.key.hProv = 0;
- io->idData = idData;
- io->id.data = idData;
- io->id.size = msKeyID->cbData;
- idData = NULL;
-
- /* see if it matches */
- if (CK_FALSE == ckcapi_match(bcp->pTemplate, bcp->ulAttributeCount, io)) {
- goto loser;
- }
- PUT_Object(io, error);
- bcp->size = size;
- bcp->count = count;
- return 1;
-
-loser:
- if (io) {
- nss_ckcapi_DestroyInternalObject(io);
- }
- nss_ZFreeIf(idData);
- return 1;
-}
-
-/*
- * collect the bare keys running around
- */
-static PRUint32
-collect_bare(
- CK_OBJECT_CLASS objClass,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError)
-{
- BOOL rc;
- BareCollectParams bareCollectParams;
-
- bareCollectParams.objClass = objClass;
- bareCollectParams.pTemplate = pTemplate;
- bareCollectParams.ulAttributeCount = ulAttributeCount;
- bareCollectParams.listp = listp;
- bareCollectParams.size = *sizep;
- bareCollectParams.count = count;
-
- rc = CryptEnumKeyIdentifierProperties(NULL, CERT_KEY_PROV_INFO_PROP_ID, 0,
- NULL, NULL, &bareCollectParams, doBareCollect);
-
- *sizep = bareCollectParams.size;
- return bareCollectParams.count;
-}
-
-/* find all the certs that represent the appropriate object (cert, priv key, or
- * pub key) in the cert store.
- */
-static PRUint32
-collect_class(
- CK_OBJECT_CLASS objClass,
- LPCSTR storeStr,
- PRBool hasID,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError)
-{
- PRUint32 size = *sizep;
- ckcapiInternalObject *next = NULL;
- HCERTSTORE hStore;
- PCCERT_CONTEXT certContext = NULL;
- PRBool isKey =
- (objClass == CKO_PUBLIC_KEY) | (objClass == CKO_PRIVATE_KEY);
-
- hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
- if (NULL == hStore) {
- return count; /* none found does not imply an error */
- }
-
- /* FUTURE: use CertFindCertificateInStore to filter better -- so we don't
- * have to enumerate all the certificates */
- while ((PCERT_CONTEXT)NULL !=
- (certContext = CertEnumCertificatesInStore(hStore, certContext))) {
- /* first filter out non user certs if we are looking for keys */
- if (isKey) {
- /* make sure there is a Key Provider Info property */
- CRYPT_KEY_PROV_INFO *keyProvInfo;
- DWORD size = 0;
- BOOL rv;
- rv = CertGetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
- if (!rv) {
- int reason = GetLastError();
- /* we only care if it exists, we don't really need to fetch it yet */
- if (reason == CRYPT_E_NOT_FOUND) {
- continue;
- }
- }
- /* filter out the non-microsoft providers */
- keyProvInfo = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if (keyProvInfo) {
- rv = CertGetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID, keyProvInfo, &size);
- if (rv) {
- char *provName =
- nss_ckcapi_WideToUTF8(keyProvInfo->pwszProvName);
- nss_ZFreeIf(keyProvInfo);
-
- if (provName &&
- (strncmp(provName, "Microsoft", sizeof("Microsoft") - 1) != 0)) {
- continue;
- }
- } else {
- int reason =
- GetLastError();
- /* we only care if it exists, we don't really need to fetch it yet */
- nss_ZFreeIf(keyProvInfo);
- if (reason ==
- CRYPT_E_NOT_FOUND) {
- continue;
- }
- }
- }
- }
-
- if ((ckcapiInternalObject *)NULL == next) {
- next = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == next) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- }
- next->type = ckcapiCert;
- next->objClass = objClass;
- next->u.cert.certContext = certContext;
- next->u.cert.hasID = hasID;
- next->u.cert.certStore = storeStr;
- if (CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, next)) {
- /* clear cached values that may be dependent on our old certContext */
- memset(&next->u.cert, 0, sizeof(next->u.cert));
- /* get a 'permanent' context */
- next->u.cert.certContext = CertDuplicateCertificateContext(certContext);
- next->objClass = objClass;
- next->u.cert.certContext = certContext;
- next->u.cert.hasID = hasID;
- next->u.cert.certStore = storeStr;
- PUT_Object(next, *pError);
- next = NULL; /* need to allocate a new one now */
- } else {
- /* don't cache the values we just loaded */
- memset(&next->u.cert, 0, sizeof(next->u.cert));
- }
- }
-loser:
- CertCloseStore(hStore, 0);
- nss_ZFreeIf(next);
- *sizep = size;
- return count;
-}
-
-NSS_IMPLEMENT PRUint32
-nss_ckcapi_collect_all_certs(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError)
-{
- count = collect_class(CKO_CERTIFICATE, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- /*count = collect_class(CKO_CERTIFICATE, "AddressBook", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError); */
- count = collect_class(CKO_CERTIFICATE, "CA", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "Root", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "Trust", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "TrustedPeople", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- count = collect_class(CKO_CERTIFICATE, "AuthRoot", PR_FALSE, pTemplate,
- ulAttributeCount, listp, sizep, count, pError);
- return count;
-}
-
-CK_OBJECT_CLASS
-ckcapi_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,
- ckcapiInternalObject ***listp,
- CK_RV *pError)
-{
- PRUint32 i;
- PRUint32 count = 0;
- PRUint32 size = 0;
- CK_OBJECT_CLASS objClass;
-
- /*
- * first handle the static build in objects (if any)
- */
- for (i = 0; i < nss_ckcapi_nObjects; i++) {
- ckcapiInternalObject *o = (ckcapiInternalObject *)&nss_ckcapi_data[i];
-
- if (CK_TRUE == ckcapi_match(pTemplate, ulAttributeCount, o)) {
- PUT_Object(o, *pError);
- }
- }
-
- /*
- * now handle the various object types
- */
- objClass = ckcapi_GetObjectClass(pTemplate, ulAttributeCount);
- *pError = CKR_OK;
- switch (objClass) {
- case CKO_CERTIFICATE:
- count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PUBLIC_KEY:
- count = collect_class(objClass, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- case CKO_PRIVATE_KEY:
- count = collect_class(objClass, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(objClass, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- /* all of them */
- case CK_INVALID_HANDLE:
- count = nss_ckcapi_collect_all_certs(pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PUBLIC_KEY, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(CKO_PUBLIC_KEY, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- count = collect_class(CKO_PRIVATE_KEY, "My", PR_TRUE, pTemplate,
- ulAttributeCount, listp, &size, count, pError);
- count = collect_bare(CKO_PRIVATE_KEY, pTemplate, ulAttributeCount, listp,
- &size, count, pError);
- break;
- default:
- goto done; /* no other object types we understand in this module */
- }
- if (CKR_OK != *pError) {
- goto loser;
- }
-
-done:
- return count;
-loser:
- nss_ZFreeIf(*listp);
- return 0;
-}
-
-NSS_IMPLEMENT NSSCKMDFindObjects *
-nss_ckcapi_FindObjectsInit(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- /* This could be made more efficient. I'm rather rushed. */
- NSSArena *arena;
- NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
- struct ckcapiFOStr *fo = (struct ckcapiFOStr *)NULL;
- ckcapiInternalObject **temp = (ckcapiInternalObject **)NULL;
-
- 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 ckcapiFOStr);
- if ((struct ckcapiFOStr *)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 = ckcapi_mdFindObjects_Final;
- rv->Next = ckcapi_mdFindObjects_Next;
- rv->null = (void *)NULL;
-
- fo->n = collect_objects(pTemplate, ulAttributeCount, &temp, pError);
- if (*pError != CKR_OK) {
- goto loser;
- }
-
- fo->objs = nss_ZNEWARRAY(arena, ckcapiInternalObject *, fo->n);
- if ((ckcapiInternalObject **)NULL == fo->objs) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
-
- (void)nsslibc_memcpy(fo->objs, temp, sizeof(ckcapiInternalObject *) * fo->n);
- nss_ZFreeIf(temp);
- temp = (ckcapiInternalObject **)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/nss/lib/ckfw/capi/cinst.c b/nss/lib/ckfw/capi/cinst.c
deleted file mode 100644
index 937c289..0000000
--- a/nss/lib/ckfw/capi/cinst.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* 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 "ckcapi.h"
-
-/*
- * ckcapi/cinstance.c
- *
- * This file implements the NSSCKMDInstance object for the
- * "capi" cryptoki module.
- */
-
-/*
- * NSSCKMDInstance methods
- */
-
-static CK_ULONG
-ckcapi_mdInstance_GetNSlots(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (CK_ULONG)1;
-}
-
-static CK_VERSION
-ckcapi_mdInstance_GetCryptokiVersion(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_CryptokiVersion;
-}
-
-static NSSUTF8 *
-ckcapi_mdInstance_GetManufacturerID(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckcapi_mdInstance_GetLibraryDescription(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_LibraryDescription;
-}
-
-static CK_VERSION
-ckcapi_mdInstance_GetLibraryVersion(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_LibraryVersion;
-}
-
-static CK_RV
-ckcapi_mdInstance_GetSlots(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKMDSlot *slots[])
-{
- slots[0] = (NSSCKMDSlot *)&nss_ckcapi_mdSlot;
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckcapi_mdInstance_ModuleHandlesSessionObjects(
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- /* we don't want to allow any session object creation, at least
- * until we can investigate whether or not we can use those objects
- */
- return CK_TRUE;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDInstance
- nss_ckcapi_mdInstance = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Finalize */
- ckcapi_mdInstance_GetNSlots,
- ckcapi_mdInstance_GetCryptokiVersion,
- ckcapi_mdInstance_GetManufacturerID,
- ckcapi_mdInstance_GetLibraryDescription,
- ckcapi_mdInstance_GetLibraryVersion,
- ckcapi_mdInstance_ModuleHandlesSessionObjects,
- /*NULL, /* HandleSessionObjects */
- ckcapi_mdInstance_GetSlots,
- NULL, /* WaitForSlotEvent */
- (void *)NULL /* null terminator */
- };
diff --git a/nss/lib/ckfw/capi/ckcapi.h b/nss/lib/ckfw/capi/ckcapi.h
deleted file mode 100644
index 2c4b12a..0000000
--- a/nss/lib/ckfw/capi/ckcapi.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/* 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/. */
-
-#ifndef CKCAPI_H
-#define CKCAPI_H 1
-
-#include "nssckmdt.h"
-#include "nssckfw.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 */
-
-#include "wtypes.h"
-#include "wincrypt.h"
-
-/*
- * statically defined raw objects. Allows us to data description objects
- * to this PKCS #11 module.
- */
-struct ckcapiRawObjectStr {
- CK_ULONG n;
- const CK_ATTRIBUTE_TYPE *types;
- const NSSItem *items;
-};
-typedef struct ckcapiRawObjectStr ckcapiRawObject;
-
-/*
- * common values needed for both bare keys and cert referenced keys.
- */
-struct ckcapiKeyParamsStr {
- NSSItem modulus;
- NSSItem exponent;
- NSSItem privateExponent;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem coefficient;
- unsigned char publicExponentData[sizeof(CK_ULONG)];
- void *privateKey;
- void *pubKey;
-};
-typedef struct ckcapiKeyParamsStr ckcapiKeyParams;
-
-/*
- * 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 ckcapiKeyObjectStr {
- CRYPT_KEY_PROV_INFO provInfo;
- char *provName;
- char *containerName;
- HCRYPTPROV hProv;
- ckcapiKeyParams key;
-};
-typedef struct ckcapiKeyObjectStr ckcapiKeyObject;
-
-/*
- * Certificate and certificate referenced keys.
- */
-struct ckcapiCertObjectStr {
- PCCERT_CONTEXT certContext;
- PRBool hasID;
- const char *certStore;
- NSSItem label;
- NSSItem subject;
- NSSItem issuer;
- NSSItem serial;
- NSSItem derCert;
- ckcapiKeyParams key;
- unsigned char *labelData;
- /* static data: to do, make this dynamic like labelData */
- unsigned char derSerial[128];
-};
-typedef struct ckcapiCertObjectStr ckcapiCertObject;
-
-typedef enum {
- ckcapiRaw,
- ckcapiCert,
- ckcapiBareKey
-} ckcapiObjectType;
-
-/*
- * all the various types of objects are abstracted away in cobject and
- * cfind as ckcapiInternalObjects.
- */
-struct ckcapiInternalObjectStr {
- ckcapiObjectType type;
- union {
- ckcapiRawObject raw;
- ckcapiCertObject cert;
- ckcapiKeyObject key;
- } u;
- CK_OBJECT_CLASS objClass;
- NSSItem hashKey;
- NSSItem id;
- void *idData;
- unsigned char hashKeyData[128];
- NSSCKMDObject mdObject;
-};
-typedef struct ckcapiInternalObjectStr ckcapiInternalObject;
-
-/* our raw object data array */
-NSS_EXTERN_DATA ckcapiInternalObject nss_ckcapi_data[];
-NSS_EXTERN_DATA const PRUint32 nss_ckcapi_nObjects;
-
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_CryptokiVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_ManufacturerID;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_LibraryDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_LibraryVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_SlotDescription;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_HardwareVersion;
-NSS_EXTERN_DATA const CK_VERSION nss_ckcapi_FirmwareVersion;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_TokenLabel;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_TokenModel;
-NSS_EXTERN_DATA const NSSUTF8 *nss_ckcapi_TokenSerialNumber;
-
-NSS_EXTERN_DATA const NSSCKMDInstance nss_ckcapi_mdInstance;
-NSS_EXTERN_DATA const NSSCKMDSlot nss_ckcapi_mdSlot;
-NSS_EXTERN_DATA const NSSCKMDToken nss_ckcapi_mdToken;
-NSS_EXTERN_DATA const NSSCKMDMechanism nss_ckcapi_mdMechanismRSA;
-
-NSS_EXTERN NSSCKMDSession *
-nss_ckcapi_CreateSession(
- NSSCKFWSession *fwSession,
- CK_RV *pError);
-
-NSS_EXTERN NSSCKMDFindObjects *
-nss_ckcapi_FindObjectsInit(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError);
-
-/*
- * Object Utilities
- */
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateMDObject(
- NSSArena *arena,
- ckcapiInternalObject *io,
- CK_RV *pError);
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateObject(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError);
-
-NSS_EXTERN const NSSItem *
-nss_ckcapi_FetchAttribute(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type);
-
-NSS_EXTERN void
-nss_ckcapi_DestroyInternalObject(
- ckcapiInternalObject *io);
-
-NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey);
-
-/*
- * generic utilities
- */
-
-/*
- * So everyone else in the worlds stores their bignum data MSB first, but not
- * Microsoft, we need to byte swap everything coming into and out of CAPI.
- */
-void
-ckcapi_ReverseData(
- NSSItem *item);
-
-/*
- * unwrap a single DER value
- */
-unsigned char *
-nss_ckcapi_DERUnwrap(
- unsigned char *src,
- unsigned int size,
- unsigned int *outSize,
- unsigned char **next);
-
-/*
- * Return the size in bytes of a wide string
- */
-int
-nss_ckcapi_WideSize(
- LPCWSTR wide);
-
-/*
- * Covert a Unicode wide character string to a UTF8 string
- */
-char *
-nss_ckcapi_WideToUTF8(
- LPCWSTR wide);
-
-/*
- * Return a Wide String duplicated with nss allocated memory.
- */
-LPWSTR
-nss_ckcapi_WideDup(
- LPCWSTR wide);
-
-/*
- * Covert a UTF8 string to Unicode wide character
- */
-LPWSTR
-nss_ckcapi_UTF8ToWide(
- char *buf);
-
-NSS_EXTERN PRUint32
-nss_ckcapi_collect_all_certs(
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- ckcapiInternalObject ***listp,
- PRUint32 *sizep,
- PRUint32 count,
- CK_RV *pError);
-
-#define NSS_CKCAPI_ARRAY_SIZE(x) ((sizeof(x)) / (sizeof((x)[0])))
-
-#endif
diff --git a/nss/lib/ckfw/capi/ckcapiver.c b/nss/lib/ckfw/capi/ckcapiver.c
deleted file mode 100644
index 825b630..0000000
--- a/nss/lib/ckfw/capi/ckcapiver.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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/. */
-/* Library identity and versioning */
-
-#include "nsscapi.h"
-
-#if defined(DEBUG)
-#define _DEBUG_STRING " (debug)"
-#else
-#define _DEBUG_STRING ""
-#endif
-
-/*
- * Version information
- */
-const char __nss_ckcapi_version[] = "Version: NSS Access to Microsoft Certificate Store " NSS_CKCAPI_LIBRARY_VERSION _DEBUG_STRING;
diff --git a/nss/lib/ckfw/capi/cobject.c b/nss/lib/ckfw/capi/cobject.c
deleted file mode 100644
index c4b77d2..0000000
--- a/nss/lib/ckfw/capi/cobject.c
+++ /dev/null
@@ -1,2226 +0,0 @@
-/* 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 "ckcapi.h"
-#include "nssbase.h"
-
-/*
- * ckcapi/cobject.c
- *
- * This file implements the NSSCKMDObject object for the
- * "nss to capi objects" cryptoki module.
- */
-
-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_CKCAPI_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_CKCAPI_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_CKCAPI_ARRAY_SIZE(pubKeyAttrs);
-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 NSSItem ckcapi_trueItem = {
- (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL)
-};
-static const NSSItem ckcapi_falseItem = {
- (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL)
-};
-static const NSSItem ckcapi_x509Item = {
- (void *)&ckc_x509, (PRUint32)sizeof(CK_CERTIFICATE_TYPE)
-};
-static const NSSItem ckcapi_rsaItem = {
- (void *)&ckk_rsa, (PRUint32)sizeof(CK_KEY_TYPE)
-};
-static const NSSItem ckcapi_certClassItem = {
- (void *)&cko_certificate, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckcapi_privKeyClassItem = {
- (void *)&cko_private_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckcapi_pubKeyClassItem = {
- (void *)&cko_public_key, (PRUint32)sizeof(CK_OBJECT_CLASS)
-};
-static const NSSItem ckcapi_emptyItem = {
- (void *)&ck_true, 0
-};
-
-/*
- * these are utilities. The chould be moved to a new utilities file.
- */
-
-/*
- * unwrap a single DER value
- */
-unsigned char *
-nss_ckcapi_DERUnwrap(
- unsigned char *src,
- unsigned int size,
- unsigned int *outSize,
- unsigned char **next)
-{
- unsigned char *start = src;
- unsigned char *end = src + size;
- unsigned int len = 0;
-
- /* initialize error condition return values */
- *outSize = 0;
- if (next) {
- *next = src;
- }
-
- if (size < 2) {
- return start;
- }
- src++; /* skip the tag -- should check it against an expected value! */
- len = (unsigned)*src++;
- if (len & 0x80) {
- unsigned int count = len & 0x7f;
- len = 0;
-
- if (count + 2 > size) {
- return start;
- }
- while (count-- > 0) {
- len = (len << 8) | (unsigned)*src++;
- }
- }
- if (len + (src - start) > size) {
- return start;
- }
- if (next) {
- *next = src + len;
- }
- *outSize = len;
-
- return src;
-}
-
-/*
- * convert a PKCS #11 bytestrin into a CK_ULONG, the byte stream must be
- * less than sizeof (CK_ULONG).
- */
-CK_ULONG
-nss_ckcapi_DataToInt(
- NSSItem *data,
- CK_RV *pError)
-{
- CK_ULONG value = 0;
- unsigned long count = data->size;
- unsigned char *dataPtr = data->data;
- unsigned long size = 0;
-
- *pError = CKR_OK;
-
- while (count--) {
- value = value << 8;
- value = value + *dataPtr++;
- if (size || value) {
- size++;
- }
- }
- if (size > sizeof(CK_ULONG)) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
- return value;
-}
-
-/*
- * convert a CK_ULONG to a bytestream. Data is stored in the buffer 'buf'
- * and must be at least CK_ULONG. Caller must provide buf.
- */
-CK_ULONG
-nss_ckcapi_IntToData(
- CK_ULONG value,
- NSSItem *data,
- unsigned char *dataPtr,
- CK_RV *pError)
-{
- unsigned long count = 0;
- unsigned long i;
-#define SHIFT ((sizeof(CK_ULONG) - 1) * 8)
- PRBool first = 0;
-
- *pError = CKR_OK;
-
- data->data = dataPtr;
- for (i = 0; i < sizeof(CK_ULONG); i++) {
- unsigned char digit = (unsigned char)((value >> SHIFT) & 0xff);
-
- value = value << 8;
-
- /* drop leading zero bytes */
- if (first && (0 == digit)) {
- continue;
- }
- *dataPtr++ = digit;
- count++;
- }
- data->size = count;
- return count;
-}
-
-/*
- * get an attribute from a template. Value is returned in NSS item.
- * data for the item is owned by the template.
- */
-CK_RV
-nss_ckcapi_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
-nss_ckcapi_GetULongAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError)
-{
- NSSItem item;
-
- *pError = nss_ckcapi_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
-nss_ckcapi_GetBoolAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError)
-{
- NSSItem item;
-
- *pError = nss_ckcapi_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 an attribute which is type CK_BBOOL.
- */
-char *
-nss_ckcapi_GetStringAttribute(
- CK_ATTRIBUTE_TYPE type,
- CK_ATTRIBUTE *template,
- CK_ULONG templateSize,
- CK_RV *pError)
-{
- NSSItem item;
- char *str;
-
- /* get the attribute */
- *pError = nss_ckcapi_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;
-}
-
-/*
- * Return the size in bytes of a wide string, including the terminating null
- * character
- */
-int
-nss_ckcapi_WideSize(
- LPCWSTR wide)
-{
- DWORD size;
-
- if ((LPWSTR)NULL == wide) {
- return 0;
- }
- size = wcslen(wide) + 1;
- return size * sizeof(WCHAR);
-}
-
-/*
- * Covert a Unicode wide character string to a UTF8 string
- */
-char *
-nss_ckcapi_WideToUTF8(
- LPCWSTR wide)
-{
- DWORD size;
- char *buf;
-
- if ((LPWSTR)NULL == wide) {
- return (char *)NULL;
- }
-
- size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, NULL, 0, NULL, 0);
- if (size == 0) {
- return (char *)NULL;
- }
- buf = nss_ZNEWARRAY(NULL, char, size);
- size = WideCharToMultiByte(CP_UTF8, 0, wide, -1, buf, size, NULL, 0);
- if (size == 0) {
- nss_ZFreeIf(buf);
- return (char *)NULL;
- }
- return buf;
-}
-
-/*
- * Return a Wide String duplicated with nss allocated memory.
- */
-LPWSTR
-nss_ckcapi_WideDup(
- LPCWSTR wide)
-{
- DWORD len;
- LPWSTR buf;
-
- if ((LPWSTR)NULL == wide) {
- return (LPWSTR)NULL;
- }
-
- len = wcslen(wide) + 1;
-
- buf = nss_ZNEWARRAY(NULL, WCHAR, len);
- if ((LPWSTR)NULL == buf) {
- return buf;
- }
- nsslibc_memcpy(buf, wide, len * sizeof(WCHAR));
- return buf;
-}
-
-/*
- * Covert a UTF8 string to Unicode wide character
- */
-LPWSTR
-nss_ckcapi_UTF8ToWide(
- char *buf)
-{
- DWORD size;
- LPWSTR wide;
-
- if ((char *)NULL == buf) {
- return (LPWSTR)NULL;
- }
-
- size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, NULL, 0);
- if (size == 0) {
- return (LPWSTR)NULL;
- }
- wide = nss_ZNEWARRAY(NULL, WCHAR, size);
- size = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wide, size);
- if (size == 0) {
- nss_ZFreeIf(wide);
- return (LPWSTR)NULL;
- }
- return wide;
-}
-
-/*
- * keep all the knowlege of how the internalObject is laid out in this function
- *
- * nss_ckcapi_FetchKeyContainer
- *
- * fetches the Provider container and info as well as a key handle for a
- * private key. If something other than a private key is passed in,
- * this function fails with CKR_KEY_TYPE_INCONSISTENT
- */
-NSS_EXTERN CK_RV
-nss_ckcapi_FetchKeyContainer(
- ckcapiInternalObject *iKey,
- HCRYPTPROV *hProv,
- DWORD *keySpec,
- HCRYPTKEY *hKey)
-{
- ckcapiCertObject *co;
- ckcapiKeyObject *ko;
- BOOL rc, dummy;
- DWORD msError;
-
- switch (iKey->type) {
- default:
- case ckcapiRaw:
- /* can't have raw private keys */
- return CKR_KEY_TYPE_INCONSISTENT;
- case ckcapiCert:
- if (iKey->objClass != CKO_PRIVATE_KEY) {
- /* Only private keys have private key provider handles */
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- co = &iKey->u.cert;
-
- /* OK, get the Provider */
- rc = CryptAcquireCertificatePrivateKey(co->certContext,
- CRYPT_ACQUIRE_CACHE_FLAG |
- CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
- NULL, hProv,
- keySpec, &dummy);
- if (!rc) {
- goto loser;
- }
- break;
- case ckcapiBareKey:
- if (iKey->objClass != CKO_PRIVATE_KEY) {
- /* Only private keys have private key provider handles */
- return CKR_KEY_TYPE_INCONSISTENT;
- }
- ko = &iKey->u.key;
-
- /* OK, get the Provider */
- if (0 == ko->hProv) {
- rc =
- CryptAcquireContext(hProv,
- ko->containerName,
- ko->provName,
- ko->provInfo.dwProvType, 0);
- if (!rc) {
- goto loser;
- }
- } else {
- *hProv =
- ko->hProv;
- }
- *keySpec = ko->provInfo.dwKeySpec;
- break;
- }
-
- /* and get the crypto handle */
- rc = CryptGetUserKey(*hProv, *keySpec, hKey);
- if (!rc) {
- goto loser;
- }
- return CKR_OK;
-loser:
- /* map the microsoft error before leaving */
- msError = GetLastError();
- switch (msError) {
- case ERROR_INVALID_HANDLE:
- case ERROR_INVALID_PARAMETER:
- case NTE_BAD_KEY:
- case NTE_NO_KEY:
- case NTE_BAD_PUBLIC_KEY:
- case NTE_BAD_KEYSET:
- case NTE_KEYSET_NOT_DEF:
- return CKR_KEY_TYPE_INCONSISTENT;
- case NTE_BAD_UID:
- case NTE_KEYSET_ENTRY_BAD:
- return CKR_DEVICE_ERROR;
- }
- return CKR_GENERAL_ERROR;
-}
-
-/*
- * take a DER PUBLIC Key block and return the modulus and exponent
- */
-static void
-ckcapi_CertPopulateModulusExponent(
- ckcapiInternalObject *io)
-{
- ckcapiKeyParams *kp = &io->u.cert.key;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- unsigned char *pkData =
- certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData;
- unsigned int size =
- certContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData;
- unsigned int newSize;
- unsigned char *ptr, *newptr;
-
- /* find the start of the modulus -- this will not give good results if
- * the key isn't an rsa key! */
- ptr = nss_ckcapi_DERUnwrap(pkData, size, &newSize, NULL);
- kp->modulus.data = nss_ckcapi_DERUnwrap(ptr, newSize,
- &kp->modulus.size, &newptr);
- /* changed from signed to unsigned int */
- if (0 == *(char *)kp->modulus.data) {
- kp->modulus.data = ((char *)kp->modulus.data) + 1;
- kp->modulus.size = kp->modulus.size - 1;
- }
- /* changed from signed to unsigned int */
- kp->exponent.data = nss_ckcapi_DERUnwrap(newptr, (newptr - ptr) + newSize,
- &kp->exponent.size, NULL);
- if (0 == *(char *)kp->exponent.data) {
- kp->exponent.data = ((char *)kp->exponent.data) + 1;
- kp->exponent.size = kp->exponent.size - 1;
- }
- return;
-}
-
-typedef struct _CAPI_RSA_KEY_BLOB {
- PUBLICKEYSTRUC header;
- RSAPUBKEY rsa;
- char data[1];
-} CAPI_RSA_KEY_BLOB;
-
-#define CAPI_MODULUS_OFFSET(modSize) 0
-#define CAPI_PRIME_1_OFFSET(modSize) (modSize)
-#define CAPI_PRIME_2_OFFSET(modSize) ((modSize) + (modSize) / 2)
-#define CAPI_EXPONENT_1_OFFSET(modSize) ((modSize)*2)
-#define CAPI_EXPONENT_2_OFFSET(modSize) ((modSize)*2 + (modSize) / 2)
-#define CAPI_COEFFICIENT_OFFSET(modSize) ((modSize)*3)
-#define CAPI_PRIVATE_EXP_OFFSET(modSize) ((modSize)*3 + (modSize) / 2)
-
-void
-ckcapi_FetchPublicKey(
- ckcapiInternalObject *io)
-{
- ckcapiKeyParams *kp;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey = 0;
- CK_RV error;
- DWORD bufLen;
- BOOL rc;
- unsigned long modulus;
- char *buf = NULL;
- CAPI_RSA_KEY_BLOB *blob;
-
- error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
- if (CKR_OK != error) {
- goto loser;
- }
- kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
-
- rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- buf = nss_ZNEWARRAY(NULL, char, bufLen);
- rc = CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- /* validate the blob */
- blob = (CAPI_RSA_KEY_BLOB *)buf;
- if ((PUBLICKEYBLOB != blob->header.bType) ||
- (0x02 != blob->header.bVersion) ||
- (0x31415352 != blob->rsa.magic)) {
- goto loser;
- }
- modulus = blob->rsa.bitlen / 8;
- kp->pubKey = buf;
- buf = NULL;
-
- kp->modulus.data = &blob->data[CAPI_MODULUS_OFFSET(modulus)];
- kp->modulus.size = modulus;
- ckcapi_ReverseData(&kp->modulus);
- nss_ckcapi_IntToData(blob->rsa.pubexp, &kp->exponent,
- kp->publicExponentData, &error);
-
-loser:
- nss_ZFreeIf(buf);
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return;
-}
-
-void
-ckcapi_FetchPrivateKey(
- ckcapiInternalObject *io)
-{
- ckcapiKeyParams *kp;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey = 0;
- CK_RV error;
- DWORD bufLen;
- BOOL rc;
- unsigned long modulus;
- char *buf = NULL;
- CAPI_RSA_KEY_BLOB *blob;
-
- error = nss_ckcapi_FetchKeyContainer(io, &hProv, &keySpec, &hKey);
- if (CKR_OK != error) {
- goto loser;
- }
- kp = (ckcapiCert == io->type) ? &io->u.cert.key : &io->u.key.key;
-
- rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- buf = nss_ZNEWARRAY(NULL, char, bufLen);
- rc = CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, buf, &bufLen);
- if (!rc) {
- goto loser;
- }
- /* validate the blob */
- blob = (CAPI_RSA_KEY_BLOB *)buf;
- if ((PRIVATEKEYBLOB != blob->header.bType) ||
- (0x02 != blob->header.bVersion) ||
- (0x32415352 != blob->rsa.magic)) {
- goto loser;
- }
- modulus = blob->rsa.bitlen / 8;
- kp->privateKey = buf;
- buf = NULL;
-
- kp->privateExponent.data = &blob->data[CAPI_PRIVATE_EXP_OFFSET(modulus)];
- kp->privateExponent.size = modulus;
- ckcapi_ReverseData(&kp->privateExponent);
- kp->prime1.data = &blob->data[CAPI_PRIME_1_OFFSET(modulus)];
- kp->prime1.size = modulus / 2;
- ckcapi_ReverseData(&kp->prime1);
- kp->prime2.data = &blob->data[CAPI_PRIME_2_OFFSET(modulus)];
- kp->prime2.size = modulus / 2;
- ckcapi_ReverseData(&kp->prime2);
- kp->exponent1.data = &blob->data[CAPI_EXPONENT_1_OFFSET(modulus)];
- kp->exponent1.size = modulus / 2;
- ckcapi_ReverseData(&kp->exponent1);
- kp->exponent2.data = &blob->data[CAPI_EXPONENT_2_OFFSET(modulus)];
- kp->exponent2.size = modulus / 2;
- ckcapi_ReverseData(&kp->exponent2);
- kp->coefficient.data = &blob->data[CAPI_COEFFICIENT_OFFSET(modulus)];
- kp->coefficient.size = modulus / 2;
- ckcapi_ReverseData(&kp->coefficient);
-
-loser:
- nss_ZFreeIf(buf);
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return;
-}
-
-void
-ckcapi_PopulateModulusExponent(
- ckcapiInternalObject *io)
-{
- if (ckcapiCert == io->type) {
- ckcapi_CertPopulateModulusExponent(io);
- } else {
- ckcapi_FetchPublicKey(io);
- }
- return;
-}
-
-/*
- * fetch the friendly name attribute.
- * can only be called with ckcapiCert type objects!
- */
-void
-ckcapi_FetchLabel(
- ckcapiInternalObject *io)
-{
- ckcapiCertObject *co = &io->u.cert;
- char *label;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- char labelDataUTF16[128];
- DWORD size = sizeof(labelDataUTF16);
- DWORD size8 = sizeof(co->labelData);
- BOOL rv;
-
- rv = CertGetCertificateContextProperty(certContext,
- CERT_FRIENDLY_NAME_PROP_ID, labelDataUTF16, &size);
- if (rv) {
- co->labelData = nss_ckcapi_WideToUTF8((LPCWSTR)labelDataUTF16);
- if ((CHAR *)NULL == co->labelData) {
- rv = 0;
- } else {
- size = strlen(co->labelData);
- }
- }
- label = co->labelData;
- /* we are presuming a user cert, make sure it has a nickname, even if
- * Microsoft never gave it one */
- if (!rv && co->hasID) {
- DWORD mserror = GetLastError();
-#define DEFAULT_NICKNAME "no Microsoft nickname"
- label = DEFAULT_NICKNAME;
- size = sizeof(DEFAULT_NICKNAME);
- rv = 1;
- }
-
- if (rv) {
- co->label.data = label;
- co->label.size = size;
- }
- return;
-}
-
-void
-ckcapi_FetchSerial(
- ckcapiInternalObject *io)
-{
- ckcapiCertObject *co = &io->u.cert;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = sizeof(co->derSerial);
-
- BOOL rc = CryptEncodeObject(X509_ASN_ENCODING,
- X509_MULTI_BYTE_INTEGER,
- &certContext->pCertInfo->SerialNumber,
- co->derSerial,
- &size);
- if (rc) {
- co->serial.data = co->derSerial;
- co->serial.size = size;
- }
- return;
-}
-
-/*
- * fetch the key ID.
- */
-void
-ckcapi_FetchID(
- ckcapiInternalObject *io)
-{
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = 0;
- BOOL rc;
-
- rc = CertGetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size);
- if (!rc) {
- return;
- }
- io->idData = nss_ZNEWARRAY(NULL, char, size);
- if (io->idData == NULL) {
- return;
- }
-
- rc = CertGetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID, io->idData, &size);
- if (!rc) {
- nss_ZFreeIf(io->idData);
- io->idData = NULL;
- return;
- }
- io->id.data = io->idData;
- io->id.size = size;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_CertFetchHashKey(
- ckcapiInternalObject *io)
-{
- ckcapiCertObject *co = &io->u.cert;
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- DWORD size = certContext->cbCertEncoded;
- DWORD max = sizeof(io->hashKeyData) - 1;
- DWORD offset = 0;
-
- /* make sure we don't over flow. NOTE: cutting the top of a cert is
- * not a big issue because the signature for will be unique for the cert */
- if (size > max) {
- offset = size - max;
- size = max;
- }
-
- nsslibc_memcpy(io->hashKeyData, certContext->pbCertEncoded + offset, size);
- io->hashKeyData[size] = (char)(io->objClass & 0xff);
-
- io->hashKey.data = io->hashKeyData;
- io->hashKey.size = size + 1;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_KeyFetchHashKey(
- ckcapiInternalObject *io)
-{
- ckcapiKeyObject *ko = &io->u.key;
- DWORD size;
- DWORD max = sizeof(io->hashKeyData) - 2;
- DWORD offset = 0;
- DWORD provLen = strlen(ko->provName);
- DWORD containerLen = strlen(ko->containerName);
-
- size = provLen + containerLen;
-
- /* make sure we don't overflow, try to keep things unique */
- if (size > max) {
- DWORD diff = ((size - max) + 1) / 2;
- provLen -= diff;
- containerLen -= diff;
- size = provLen + containerLen;
- }
-
- nsslibc_memcpy(io->hashKeyData, ko->provName, provLen);
- nsslibc_memcpy(&io->hashKeyData[provLen],
- ko->containerName,
- containerLen);
- io->hashKeyData[size] = (char)(io->objClass & 0xff);
- io->hashKeyData[size + 1] = (char)(ko->provInfo.dwKeySpec & 0xff);
-
- io->hashKey.data = io->hashKeyData;
- io->hashKey.size = size + 2;
- return;
-}
-
-/*
- * fetch the hash key.
- */
-void
-ckcapi_FetchHashKey(
- ckcapiInternalObject *io)
-{
- if (ckcapiCert == io->type) {
- ckcapi_CertFetchHashKey(io);
- } else {
- ckcapi_KeyFetchHashKey(io);
- }
- return;
-}
-
-const NSSItem *
-ckcapi_FetchCertAttribute(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type)
-{
- PCCERT_CONTEXT certContext = io->u.cert.certContext;
- switch (type) {
- case CKA_CLASS:
- return &ckcapi_certClassItem;
- case CKA_TOKEN:
- return &ckcapi_trueItem;
- case CKA_MODIFIABLE:
- case CKA_PRIVATE:
- return &ckcapi_falseItem;
- case CKA_CERTIFICATE_TYPE:
- return &ckcapi_x509Item;
- case CKA_LABEL:
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (0 == io->u.cert.subject.size) {
- io->u.cert.subject.data =
- certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size =
- certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_ISSUER:
- if (0 == io->u.cert.issuer.size) {
- io->u.cert.issuer.data =
- certContext->pCertInfo->Issuer.pbData;
- io->u.cert.issuer.size =
- certContext->pCertInfo->Issuer.cbData;
- }
- return &io->u.cert.issuer;
- case CKA_SERIAL_NUMBER:
- if (0 == io->u.cert.serial.size) {
- /* not exactly right. This should be the encoded serial number, but
- * it's the decoded serial number! */
- ckcapi_FetchSerial(io);
- }
- return &io->u.cert.serial;
- case CKA_VALUE:
- if (0 == io->u.cert.derCert.size) {
- io->u.cert.derCert.data =
- io->u.cert.certContext->pbCertEncoded;
- io->u.cert.derCert.size =
- io->u.cert.certContext->cbCertEncoded;
- }
- return &io->u.cert.derCert;
- case CKA_ID:
- if (!io->u.cert.hasID) {
- return NULL;
- }
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckcapi_FetchPubKeyAttribute(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type)
-{
- PRBool isCertType = (ckcapiCert == io->type);
- ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-
- switch (type) {
- case CKA_CLASS:
- return &ckcapi_pubKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- case CKA_ENCRYPT:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- return &ckcapi_trueItem;
- case CKA_PRIVATE:
- case CKA_MODIFIABLE:
- case CKA_DERIVE:
- case CKA_WRAP:
- return &ckcapi_falseItem;
- case CKA_KEY_TYPE:
- return &ckcapi_rsaItem;
- case CKA_LABEL:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.subject.size) {
- PCCERT_CONTEXT certContext =
- io->u.cert.certContext;
- io->u.cert.subject.data =
- certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size =
- certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_MODULUS:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->modulus;
- case CKA_PUBLIC_EXPONENT:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->exponent;
- case CKA_ID:
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- break;
- }
- return NULL;
-}
-
-const NSSItem *
-ckcapi_FetchPrivKeyAttribute(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type)
-{
- PRBool isCertType = (ckcapiCert == io->type);
- ckcapiKeyParams *kp = isCertType ? &io->u.cert.key : &io->u.key.key;
-
- switch (type) {
- case CKA_CLASS:
- return &ckcapi_privKeyClassItem;
- case CKA_TOKEN:
- case CKA_LOCAL:
- case CKA_SIGN:
- case CKA_DECRYPT:
- case CKA_SIGN_RECOVER:
- return &ckcapi_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 &ckcapi_falseItem;
- case CKA_KEY_TYPE:
- return &ckcapi_rsaItem;
- case CKA_LABEL:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.label.size) {
- ckcapi_FetchLabel(io);
- }
- return &io->u.cert.label;
- case CKA_SUBJECT:
- if (!isCertType) {
- return &ckcapi_emptyItem;
- }
- if (0 == io->u.cert.subject.size) {
- PCCERT_CONTEXT certContext =
- io->u.cert.certContext;
- io->u.cert.subject.data =
- certContext->pCertInfo->Subject.pbData;
- io->u.cert.subject.size =
- certContext->pCertInfo->Subject.cbData;
- }
- return &io->u.cert.subject;
- case CKA_MODULUS:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->modulus;
- case CKA_PUBLIC_EXPONENT:
- if (0 == kp->modulus.size) {
- ckcapi_PopulateModulusExponent(io);
- }
- return &kp->exponent;
- case CKA_PRIVATE_EXPONENT:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->privateExponent;
- case CKA_PRIME_1:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->prime1;
- case CKA_PRIME_2:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->prime2;
- case CKA_EXPONENT_1:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->exponent1;
- case CKA_EXPONENT_2:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->exponent2;
- case CKA_COEFFICIENT:
- if (0 == kp->privateExponent.size) {
- ckcapi_FetchPrivateKey(io);
- }
- return &kp->coefficient;
- case CKA_ID:
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
- return &io->id;
- default:
- return NULL;
- }
-}
-
-const NSSItem *
-nss_ckcapi_FetchAttribute(
- ckcapiInternalObject *io,
- CK_ATTRIBUTE_TYPE type)
-{
- CK_ULONG i;
-
- if (io->type == ckcapiRaw) {
- 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 ckcapi_FetchCertAttribute(io, type);
- case CKO_PRIVATE_KEY:
- return ckcapi_FetchPrivKeyAttribute(io, type);
- case CKO_PUBLIC_KEY:
- return ckcapi_FetchPubKeyAttribute(io, type);
- }
- return NULL;
-}
-
-/*
- * check to see if the certificate already exists
- */
-static PRBool
-ckcapi_cert_exists(
- NSSItem *value,
- ckcapiInternalObject **io)
-{
- int count, i;
- PRUint32 size = 0;
- ckcapiInternalObject **listp = NULL;
- CK_ATTRIBUTE myTemplate[2];
- CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
- CK_ULONG templateCount = 2;
- CK_RV error;
- PRBool found = PR_FALSE;
-
- myTemplate[0].type = CKA_CLASS;
- myTemplate[0].pValue = &cert_class;
- myTemplate[0].ulValueLen = sizeof(cert_class);
- myTemplate[1].type = CKA_VALUE;
- myTemplate[1].pValue = value->data;
- myTemplate[1].ulValueLen = value->size;
-
- count = nss_ckcapi_collect_all_certs(myTemplate, templateCount, &listp,
- &size, 0, &error);
-
- /* free them */
- if (count > 1) {
- *io = listp[0];
- found = PR_TRUE;
- }
-
- for (i = 1; i < count; i++) {
- nss_ckcapi_DestroyInternalObject(listp[i]);
- }
- nss_ZFreeIf(listp);
- return found;
-}
-
-static PRBool
-ckcapi_cert_hasEmail(
- PCCERT_CONTEXT certContext)
-{
- int count;
-
- count = CertGetNameString(certContext, CERT_NAME_EMAIL_TYPE,
- 0, NULL, NULL, 0);
-
- return count > 1 ? PR_TRUE : PR_FALSE;
-}
-
-static PRBool
-ckcapi_cert_isRoot(
- PCCERT_CONTEXT certContext)
-{
- return CertCompareCertificateName(certContext->dwCertEncodingType,
- &certContext->pCertInfo->Issuer, &certContext->pCertInfo->Subject);
-}
-
-static PRBool
-ckcapi_cert_isCA(
- PCCERT_CONTEXT certContext)
-{
- PCERT_EXTENSION extension;
- CERT_BASIC_CONSTRAINTS2_INFO basicInfo;
- DWORD size = sizeof(basicInfo);
- BOOL rc;
-
- extension = CertFindExtension(szOID_BASIC_CONSTRAINTS,
- certContext->pCertInfo->cExtension,
- certContext->pCertInfo->rgExtension);
- if ((PCERT_EXTENSION)NULL == extension) {
- return PR_FALSE;
- }
- rc = CryptDecodeObject(X509_ASN_ENCODING, szOID_BASIC_CONSTRAINTS2,
- extension->Value.pbData, extension->Value.cbData,
- 0, &basicInfo, &size);
- if (!rc) {
- return PR_FALSE;
- }
- return (PRBool)basicInfo.fCA;
-}
-
-static CRYPT_KEY_PROV_INFO *
-ckcapi_cert_getPrivateKeyInfo(
- PCCERT_CONTEXT certContext,
- NSSItem *keyID)
-{
- BOOL rc;
- CRYPT_HASH_BLOB msKeyID;
- DWORD size = 0;
- CRYPT_KEY_PROV_INFO *prov = NULL;
-
- msKeyID.cbData = keyID->size;
- msKeyID.pbData = keyID->data;
-
- rc = CryptGetKeyIdentifierProperty(
- &msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, NULL, &size);
- if (!rc) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- rc = CryptGetKeyIdentifierProperty(
- &msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, prov, &size);
- if (!rc) {
- nss_ZFreeIf(prov);
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
-
- return prov;
-}
-
-static CRYPT_KEY_PROV_INFO *
-ckcapi_cert_getProvInfo(
- ckcapiInternalObject *io)
-{
- BOOL rc;
- DWORD size = 0;
- CRYPT_KEY_PROV_INFO *prov = NULL;
-
- rc = CertGetCertificateContextProperty(
- io->u.cert.certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- NULL, &size);
- if (!rc) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- prov = (CRYPT_KEY_PROV_INFO *)nss_ZAlloc(NULL, size);
- if ((CRYPT_KEY_PROV_INFO *)prov == NULL) {
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
- rc = CertGetCertificateContextProperty(
- io->u.cert.certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- prov, &size);
- if (!rc) {
- nss_ZFreeIf(prov);
- return (CRYPT_KEY_PROV_INFO *)NULL;
- }
-
- return prov;
-}
-
-/* forward declaration */
-static void
-ckcapi_removeObjectFromHash(
- ckcapiInternalObject *io);
-
-/*
- * Finalize - unneeded
- * Destroy
- * IsTokenObject - CK_TRUE
- * GetAttributeCount
- * GetAttributeTypes
- * GetAttributeSize
- * GetAttribute
- * SetAttribute
- * GetObjectSize
- */
-
-static CK_RV
-ckcapi_mdObject_Destroy(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_OBJECT_CLASS objClass;
- BOOL rc;
- DWORD provType;
- DWORD msError;
- PRBool isCertType = (PRBool)(ckcapiCert == io->type);
- HCERTSTORE hStore = 0;
-
- if (ckcapiRaw == io->type) {
- /* there is not 'object write protected' error, use the next best thing */
- return CKR_TOKEN_WRITE_PROTECTED;
- }
-
- objClass = io->objClass;
- if (CKO_CERTIFICATE == objClass) {
- PCCERT_CONTEXT certContext;
-
- /* get the store */
- hStore = CertOpenSystemStore(0, io->u.cert.certStore);
- if (0 == hStore) {
- rc = 0;
- goto loser;
- }
- certContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING, 0,
- CERT_FIND_EXISTING, io->u.cert.certContext, NULL);
- if ((PCCERT_CONTEXT)NULL == certContext) {
- rc = 0;
- goto loser;
- }
- rc = CertDeleteCertificateFromStore(certContext);
- } else {
- char *provName = NULL;
- char *containerName = NULL;
- HCRYPTPROV hProv;
- CRYPT_HASH_BLOB msKeyID;
-
- if (0 == io->id.size) {
- ckcapi_FetchID(io);
- }
-
- if (isCertType) {
- CRYPT_KEY_PROV_INFO *provInfo = ckcapi_cert_getProvInfo(io);
- provName = nss_ckcapi_WideToUTF8(provInfo->pwszProvName);
- containerName = nss_ckcapi_WideToUTF8(provInfo->pwszContainerName);
- provType = provInfo->dwProvType;
- nss_ZFreeIf(provInfo);
- } else {
- provName = io->u.key.provName;
- containerName = io->u.key.containerName;
- provType = io->u.key.provInfo.dwProvType;
- io->u.key.provName = NULL;
- io->u.key.containerName = NULL;
- }
- /* first remove the key id pointer */
- msKeyID.cbData = io->id.size;
- msKeyID.pbData = io->id.data;
- rc = CryptSetKeyIdentifierProperty(&msKeyID,
- CERT_KEY_PROV_INFO_PROP_ID, CRYPT_KEYID_DELETE_FLAG, NULL, NULL, NULL);
- if (rc) {
- rc = CryptAcquireContext(&hProv, containerName, provName, provType,
- CRYPT_DELETEKEYSET);
- }
- nss_ZFreeIf(provName);
- nss_ZFreeIf(containerName);
- }
-loser:
-
- if (hStore) {
- CertCloseStore(hStore, 0);
- }
- if (!rc) {
- msError = GetLastError();
- return CKR_GENERAL_ERROR;
- }
-
- /* remove it from the hash */
- ckcapi_removeObjectFromHash(io);
-
- /* free the puppy.. */
- nss_ckcapi_DestroyInternalObject(io);
- return CKR_OK;
-}
-
-static CK_BBOOL
-ckcapi_mdObject_IsTokenObject(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_TRUE;
-}
-
-static CK_ULONG
-ckcapi_mdObject_GetAttributeCount(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- if (ckcapiRaw == 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;
- default:
- break;
- }
- return 0;
-}
-
-static CK_RV
-ckcapi_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)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_ULONG i;
- CK_RV error = CKR_OK;
- const CK_ATTRIBUTE_TYPE *attrs = NULL;
- CK_ULONG size = ckcapi_mdObject_GetAttributeCount(
- mdObject, fwObject, mdSession, fwSession,
- mdToken, fwToken, mdInstance, fwInstance, &error);
-
- if (size != ulCount) {
- return CKR_BUFFER_TOO_SMALL;
- }
- if (io->type == ckcapiRaw) {
- 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
-ckcapi_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)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- const NSSItem *b;
-
- b = nss_ckcapi_FetchAttribute(io, attribute);
-
- if ((const NSSItem *)NULL == b) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- return 0;
- }
- return b->size;
-}
-
-static CK_RV
-ckcapi_mdObject_SetAttribute(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_TYPE attribute,
- NSSItem *value)
-{
- return CKR_OK;
-}
-
-static NSSCKFWItem
-ckcapi_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;
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
-
- mdItem.needsFreeing = PR_FALSE;
- mdItem.item = (NSSItem *)nss_ckcapi_FetchAttribute(io, attribute);
-
- if ((NSSItem *)NULL == mdItem.item) {
- *pError = CKR_ATTRIBUTE_TYPE_INVALID;
- }
-
- return mdItem;
-}
-
-static CK_ULONG
-ckcapi_mdObject_GetObjectSize(
- NSSCKMDObject *mdObject,
- NSSCKFWObject *fwObject,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- ckcapiInternalObject *io = (ckcapiInternalObject *)mdObject->etc;
- CK_ULONG rv = 1;
-
- /* size is irrelevant to this token */
- return rv;
-}
-
-static const NSSCKMDObject
- ckcapi_prototype_mdObject = {
- (void *)NULL, /* etc */
- NULL, /* Finalize */
- ckcapi_mdObject_Destroy,
- ckcapi_mdObject_IsTokenObject,
- ckcapi_mdObject_GetAttributeCount,
- ckcapi_mdObject_GetAttributeTypes,
- ckcapi_mdObject_GetAttributeSize,
- ckcapi_mdObject_GetAttribute,
- NULL, /* FreeAttribute */
- ckcapi_mdObject_SetAttribute,
- ckcapi_mdObject_GetObjectSize,
- (void *)NULL /* null terminator */
- };
-
-static nssHash *ckcapiInternalObjectHash = NULL;
-
-NSS_IMPLEMENT NSSCKMDObject *
-nss_ckcapi_CreateMDObject(
- NSSArena *arena,
- ckcapiInternalObject *io,
- CK_RV *pError)
-{
- if ((nssHash *)NULL == ckcapiInternalObjectHash) {
- ckcapiInternalObjectHash = nssHash_CreateItem(NULL, 10);
- }
- if (ckcapiCert == io->type) {
- /* the hash key, not a cryptographic key */
- NSSItem *key = &io->hashKey;
- ckcapiInternalObject *old_o = NULL;
-
- if (key->size == 0) {
- ckcapi_FetchHashKey(io);
- }
- old_o = (ckcapiInternalObject *)
- nssHash_Lookup(ckcapiInternalObjectHash, key);
- if (!old_o) {
- nssHash_Add(ckcapiInternalObjectHash, key, io);
- } else if (old_o != io) {
- nss_ckcapi_DestroyInternalObject(io);
- io = old_o;
- }
- }
-
- if ((void *)NULL == io->mdObject.etc) {
- (void)nsslibc_memcpy(&io->mdObject, &ckcapi_prototype_mdObject,
- sizeof(ckcapi_prototype_mdObject));
- io->mdObject.etc = (void *)io;
- }
- return &io->mdObject;
-}
-
-static void
-ckcapi_removeObjectFromHash(
- ckcapiInternalObject *io)
-{
- NSSItem *key = &io->hashKey;
-
- if ((nssHash *)NULL == ckcapiInternalObjectHash) {
- return;
- }
- if (key->size == 0) {
- ckcapi_FetchHashKey(io);
- }
- nssHash_Remove(ckcapiInternalObjectHash, key);
- return;
-}
-
-void
-nss_ckcapi_DestroyInternalObject(
- ckcapiInternalObject *io)
-{
- switch (io->type) {
- case ckcapiRaw:
- return;
- case ckcapiCert:
- CertFreeCertificateContext(io->u.cert.certContext);
- nss_ZFreeIf(io->u.cert.labelData);
- nss_ZFreeIf(io->u.cert.key.privateKey);
- nss_ZFreeIf(io->u.cert.key.pubKey);
- nss_ZFreeIf(io->idData);
- break;
- case ckcapiBareKey:
- nss_ZFreeIf(io->u.key.provInfo.pwszContainerName);
- nss_ZFreeIf(io->u.key.provInfo.pwszProvName);
- nss_ZFreeIf(io->u.key.provName);
- nss_ZFreeIf(io->u.key.containerName);
- nss_ZFreeIf(io->u.key.key.privateKey);
- nss_ZFreeIf(io->u.key.key.pubKey);
- if (0 != io->u.key.hProv) {
- CryptReleaseContext(io->u.key.hProv, 0);
- }
- nss_ZFreeIf(io->idData);
- break;
- }
- nss_ZFreeIf(io);
- return;
-}
-
-static ckcapiInternalObject *
-nss_ckcapi_CreateCertificate(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- NSSItem value;
- NSSItem keyID;
- char *storeStr;
- ckcapiInternalObject *io = NULL;
- PCCERT_CONTEXT certContext = NULL;
- PCCERT_CONTEXT storedCertContext = NULL;
- CRYPT_KEY_PROV_INFO *prov_info = NULL;
- char *nickname = NULL;
- HCERTSTORE hStore = 0;
- DWORD msError = 0;
- PRBool hasID;
- CK_RV dummy;
- BOOL rc;
-
- *pError = nss_ckcapi_GetAttribute(CKA_VALUE, pTemplate,
- ulAttributeCount, &value);
-
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
-
- *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
-
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
-
- if (ckcapi_cert_exists(&value, &io)) {
- return io;
- }
-
- /* OK, we are creating a new one, figure out what store it belongs to..
- * first get a certContext handle.. */
- certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
- value.data, value.size);
- if ((PCCERT_CONTEXT)NULL == certContext) {
- msError = GetLastError();
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
-
- /* do we have a private key laying around... */
- prov_info = ckcapi_cert_getPrivateKeyInfo(certContext, &keyID);
- if (prov_info) {
- CRYPT_DATA_BLOB msKeyID;
- storeStr = "My";
- hasID = PR_TRUE;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_KEY_PROV_INFO_PROP_ID,
- 0, prov_info);
- nss_ZFreeIf(prov_info);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
- msKeyID.cbData = keyID.size;
- msKeyID.pbData = keyID.data;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_KEY_IDENTIFIER_PROP_ID,
- 0, &msKeyID);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- /* does it look like a CA */
- } else if (ckcapi_cert_isCA(certContext)) {
- storeStr = ckcapi_cert_isRoot(certContext) ? "CA" : "Root";
- /* does it look like an S/MIME cert */
- } else if (ckcapi_cert_hasEmail(certContext)) {
- storeStr = "AddressBook";
- } else {
- /* just pick a store */
- storeStr = "CA";
- }
-
- /* get the nickname, not an error if we can't find it */
- nickname = nss_ckcapi_GetStringAttribute(CKA_LABEL, pTemplate,
- ulAttributeCount, &dummy);
- if (nickname) {
- LPWSTR nicknameUTF16 = NULL;
- CRYPT_DATA_BLOB nicknameBlob;
-
- nicknameUTF16 = nss_ckcapi_UTF8ToWide(nickname);
- nss_ZFreeIf(nickname);
- nickname = NULL;
- if ((LPWSTR)NULL == nicknameUTF16) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- nicknameBlob.cbData = nss_ckcapi_WideSize(nicknameUTF16);
- nicknameBlob.pbData = (BYTE *)nicknameUTF16;
- rc = CertSetCertificateContextProperty(certContext,
- CERT_FRIENDLY_NAME_PROP_ID, 0, &nicknameBlob);
- nss_ZFreeIf(nicknameUTF16);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
- }
-
- hStore = CertOpenSystemStore((HCRYPTPROV)NULL, storeStr);
- if (0 == hStore) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- rc = CertAddCertificateContextToStore(hStore, certContext,
- CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, &storedCertContext);
- CertFreeCertificateContext(certContext);
- certContext = NULL;
- CertCloseStore(hStore, 0);
- hStore = 0;
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- io->type = ckcapiCert;
- io->objClass = CKO_CERTIFICATE;
- io->u.cert.certContext = storedCertContext;
- io->u.cert.hasID = hasID;
- return io;
-
-loser:
- if (certContext) {
- CertFreeCertificateContext(certContext);
- certContext = NULL;
- }
- if (storedCertContext) {
- CertFreeCertificateContext(storedCertContext);
- storedCertContext = NULL;
- }
- if (0 != hStore) {
- CertCloseStore(hStore, 0);
- }
- return (ckcapiInternalObject *)NULL;
-}
-
-static char *
-ckcapi_getDefaultProvider(
- CK_RV *pError)
-{
- char *name = NULL;
- BOOL rc;
- DWORD nameLength = 0;
-
- rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, NULL,
- &nameLength);
- if (!rc) {
- return (char *)NULL;
- }
-
- name = nss_ZNEWARRAY(NULL, char, nameLength);
- if ((char *)NULL == name) {
- return (char *)NULL;
- }
- rc = CryptGetDefaultProvider(PROV_RSA_FULL, NULL, CRYPT_USER_DEFAULT, name,
- &nameLength);
- if (!rc) {
- nss_ZFreeIf(name);
- return (char *)NULL;
- }
-
- return name;
-}
-
-static char *
-ckcapi_getContainer(
- CK_RV *pError,
- NSSItem *id)
-{
- RPC_STATUS rstat;
- UUID uuid;
- char *uuidStr;
- char *container;
-
- rstat = UuidCreate(&uuid);
- rstat = UuidToString(&uuid, &uuidStr);
-
- /* convert it from rcp memory to our own */
- container = nssUTF8_Duplicate(uuidStr, NULL);
- RpcStringFree(&uuidStr);
-
- return container;
-}
-
-static CK_RV
-ckcapi_buildPrivateKeyBlob(
- NSSItem *keyBlob,
- NSSItem *modulus,
- NSSItem *publicExponent,
- NSSItem *privateExponent,
- NSSItem *prime1,
- NSSItem *prime2,
- NSSItem *exponent1,
- NSSItem *exponent2,
- NSSItem *coefficient,
- PRBool isKeyExchange)
-{
- CAPI_RSA_KEY_BLOB *keyBlobData = NULL;
- unsigned char *target;
- unsigned long modSize = modulus->size;
- unsigned long dataSize;
- CK_RV error = CKR_OK;
-
- /* validate extras */
- if (privateExponent->size != modSize) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (prime1->size != modSize / 2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (prime2->size != modSize / 2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (exponent1->size != modSize / 2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (exponent2->size != modSize / 2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- if (coefficient->size != modSize / 2) {
- error = CKR_ATTRIBUTE_VALUE_INVALID;
- goto loser;
- }
- dataSize = (modSize * 4) + (modSize / 2) + sizeof(CAPI_RSA_KEY_BLOB);
- keyBlobData = (CAPI_RSA_KEY_BLOB *)nss_ZAlloc(NULL, dataSize);
- if ((CAPI_RSA_KEY_BLOB *)NULL == keyBlobData) {
- error = CKR_HOST_MEMORY;
- goto loser;
- }
-
- keyBlobData->header.bType = PRIVATEKEYBLOB;
- keyBlobData->header.bVersion = 0x02;
- keyBlobData->header.reserved = 0x00;
- keyBlobData->header.aiKeyAlg = isKeyExchange ? CALG_RSA_KEYX : CALG_RSA_SIGN;
- keyBlobData->rsa.magic = 0x32415352;
- keyBlobData->rsa.bitlen = modSize * 8;
- keyBlobData->rsa.pubexp = nss_ckcapi_DataToInt(publicExponent, &error);
- if (CKR_OK != error) {
- goto loser;
- }
-
- target = &keyBlobData->data[CAPI_MODULUS_OFFSET(modSize)];
- nsslibc_memcpy(target, modulus->data, modulus->size);
- modulus->data = target;
- ckcapi_ReverseData(modulus);
-
- target = &keyBlobData->data[CAPI_PRIVATE_EXP_OFFSET(modSize)];
- nsslibc_memcpy(target, privateExponent->data, privateExponent->size);
- privateExponent->data = target;
- ckcapi_ReverseData(privateExponent);
-
- target = &keyBlobData->data[CAPI_PRIME_1_OFFSET(modSize)];
- nsslibc_memcpy(target, prime1->data, prime1->size);
- prime1->data = target;
- ckcapi_ReverseData(prime1);
-
- target = &keyBlobData->data[CAPI_PRIME_2_OFFSET(modSize)];
- nsslibc_memcpy(target, prime2->data, prime2->size);
- prime2->data = target;
- ckcapi_ReverseData(prime2);
-
- target = &keyBlobData->data[CAPI_EXPONENT_1_OFFSET(modSize)];
- nsslibc_memcpy(target, exponent1->data, exponent1->size);
- exponent1->data = target;
- ckcapi_ReverseData(exponent1);
-
- target = &keyBlobData->data[CAPI_EXPONENT_2_OFFSET(modSize)];
- nsslibc_memcpy(target, exponent2->data, exponent2->size);
- exponent2->data = target;
- ckcapi_ReverseData(exponent2);
-
- target = &keyBlobData->data[CAPI_COEFFICIENT_OFFSET(modSize)];
- nsslibc_memcpy(target, coefficient->data, coefficient->size);
- coefficient->data = target;
- ckcapi_ReverseData(coefficient);
-
- keyBlob->data = keyBlobData;
- keyBlob->size = dataSize;
-
- return CKR_OK;
-
-loser:
- nss_ZFreeIf(keyBlobData);
- return error;
-}
-
-static ckcapiInternalObject *
-nss_ckcapi_CreatePrivateKey(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- NSSItem modulus;
- NSSItem publicExponent;
- NSSItem privateExponent;
- NSSItem exponent1;
- NSSItem exponent2;
- NSSItem prime1;
- NSSItem prime2;
- NSSItem coefficient;
- NSSItem keyID;
- NSSItem keyBlob;
- ckcapiInternalObject *io = NULL;
- char *providerName = NULL;
- char *containerName = NULL;
- char *idData = NULL;
- CRYPT_KEY_PROV_INFO provInfo;
- CRYPT_HASH_BLOB msKeyID;
- CK_KEY_TYPE keyType;
- HCRYPTPROV hProv = 0;
- HCRYPTKEY hKey = 0;
- PRBool decrypt;
- DWORD keySpec;
- DWORD msError;
- BOOL rc;
-
- keyType = nss_ckcapi_GetULongAttribute(CKA_KEY_TYPE, pTemplate, ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- if (CKK_RSA != keyType) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (ckcapiInternalObject *)NULL;
- }
-
- decrypt = nss_ckcapi_GetBoolAttribute(CKA_DECRYPT,
- pTemplate, ulAttributeCount, pError);
- if (CKR_TEMPLATE_INCOMPLETE == *pError) {
- decrypt = PR_TRUE; /* default to true */
- }
- decrypt = decrypt || nss_ckcapi_GetBoolAttribute(CKA_UNWRAP,
- pTemplate, ulAttributeCount, pError);
- if (CKR_TEMPLATE_INCOMPLETE == *pError) {
- decrypt = PR_TRUE; /* default to true */
- }
- keySpec = decrypt ? AT_KEYEXCHANGE : AT_SIGNATURE;
-
- *pError = nss_ckcapi_GetAttribute(CKA_MODULUS, pTemplate,
- ulAttributeCount, &modulus);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PUBLIC_EXPONENT, pTemplate,
- ulAttributeCount, &publicExponent);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIVATE_EXPONENT, pTemplate,
- ulAttributeCount, &privateExponent);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIME_1, pTemplate,
- ulAttributeCount, &prime1);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_PRIME_2, pTemplate,
- ulAttributeCount, &prime2);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_1, pTemplate,
- ulAttributeCount, &exponent1);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_EXPONENT_2, pTemplate,
- ulAttributeCount, &exponent2);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_COEFFICIENT, pTemplate,
- ulAttributeCount, &coefficient);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- *pError = nss_ckcapi_GetAttribute(CKA_ID, pTemplate,
- ulAttributeCount, &keyID);
- if (CKR_OK != *pError) {
- return (ckcapiInternalObject *)NULL;
- }
- providerName = ckcapi_getDefaultProvider(pError);
- if ((char *)NULL == providerName) {
- return (ckcapiInternalObject *)NULL;
- }
- containerName = ckcapi_getContainer(pError, &keyID);
- if ((char *)NULL == containerName) {
- goto loser;
- }
- rc = CryptAcquireContext(&hProv, containerName, providerName,
- PROV_RSA_FULL, CRYPT_NEWKEYSET);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- *pError = ckcapi_buildPrivateKeyBlob(
- &keyBlob,
- &modulus,
- &publicExponent,
- &privateExponent,
- &prime1,
- &prime2,
- &exponent1,
- &exponent2,
- &coefficient,
- decrypt);
- if (CKR_OK != *pError) {
- goto loser;
- }
-
- rc = CryptImportKey(hProv, keyBlob.data, keyBlob.size,
- 0, CRYPT_EXPORTABLE, &hKey);
- if (!rc) {
- msError = GetLastError();
- *pError = CKR_DEVICE_ERROR;
- goto loser;
- }
-
- idData = nss_ZNEWARRAY(NULL, char, keyID.size);
- if ((void *)NULL == idData) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- nsslibc_memcpy(idData, keyID.data, keyID.size);
-
- provInfo.pwszContainerName = nss_ckcapi_UTF8ToWide(containerName);
- provInfo.pwszProvName = nss_ckcapi_UTF8ToWide(providerName);
- provInfo.dwProvType = PROV_RSA_FULL;
- provInfo.dwFlags = 0;
- provInfo.cProvParam = 0;
- provInfo.rgProvParam = NULL;
- provInfo.dwKeySpec = keySpec;
-
- msKeyID.cbData = keyID.size;
- msKeyID.pbData = keyID.data;
-
- rc = CryptSetKeyIdentifierProperty(&msKeyID, CERT_KEY_PROV_INFO_PROP_ID,
- 0, NULL, NULL, &provInfo);
- if (!rc) {
- goto loser;
- }
-
- /* handle error here */
- io = nss_ZNEW(NULL, ckcapiInternalObject);
- if ((ckcapiInternalObject *)NULL == io) {
- *pError = CKR_HOST_MEMORY;
- goto loser;
- }
- io->type = ckcapiBareKey;
- io->objClass = CKO_PRIVATE_KEY;
- io->u.key.provInfo = provInfo;
- io->u.key.provName = providerName;
- io->u.key.containerName = containerName;
- io->u.key.hProv = hProv; /* save the handle */
- io->idData = idData;
- io->id.data = idData;
- io->id.size = keyID.size;
- /* done with the key handle */
- CryptDestroyKey(hKey);
- return io;
-
-loser:
- nss_ZFreeIf(containerName);
- nss_ZFreeIf(providerName);
- nss_ZFreeIf(idData);
- if (0 != hProv) {
- CryptReleaseContext(hProv, 0);
- }
- if (0 != hKey) {
- CryptDestroyKey(hKey);
- }
- return (ckcapiInternalObject *)NULL;
-}
-
-NSS_EXTERN NSSCKMDObject *
-nss_ckcapi_CreateObject(
- NSSCKFWSession *fwSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- CK_OBJECT_CLASS objClass;
- ckcapiInternalObject *io = NULL;
- CK_BBOOL isToken;
-
- /*
- * only create token objects
- */
- isToken = nss_ckcapi_GetBoolAttribute(CKA_TOKEN, pTemplate,
- ulAttributeCount, pError);
- if (CKR_OK != *pError) {
- return (NSSCKMDObject *)NULL;
- }
- if (!isToken) {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- return (NSSCKMDObject *)NULL;
- }
-
- /*
- * only create keys and certs.
- */
- objClass = nss_ckcapi_GetULongAttribute(CKA_CLASS, 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
- if (objClass == CKO_CERTIFICATE) {
- io = nss_ckcapi_CreateCertificate(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else if (objClass == CKO_PRIVATE_KEY) {
- io = nss_ckcapi_CreatePrivateKey(fwSession, pTemplate,
- ulAttributeCount, pError);
- } else {
- *pError = CKR_ATTRIBUTE_VALUE_INVALID;
- }
-
- if ((ckcapiInternalObject *)NULL == io) {
- return (NSSCKMDObject *)NULL;
- }
- return nss_ckcapi_CreateMDObject(NULL, io, pError);
-}
diff --git a/nss/lib/ckfw/capi/constants.c b/nss/lib/ckfw/capi/constants.c
deleted file mode 100644
index 0d4b701..0000000
--- a/nss/lib/ckfw/capi/constants.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* 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/. */
-
-/*
- * ckcapi/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 NSSCAPI_H
-#include "nsscapi.h"
-#endif /* NSSCAPI_H */
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckcapi_CryptokiVersion = {
- NSS_CKCAPI_CRYPTOKI_VERSION_MAJOR,
- NSS_CKCAPI_CRYPTOKI_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_ManufacturerID = (NSSUTF8 *)"Mozilla Foundation";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_LibraryDescription = (NSSUTF8 *)"NSS Access to Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckcapi_LibraryVersion = {
- NSS_CKCAPI_LIBRARY_VERSION_MAJOR,
- NSS_CKCAPI_LIBRARY_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_SlotDescription = (NSSUTF8 *)"Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckcapi_HardwareVersion = {
- NSS_CKCAPI_HARDWARE_VERSION_MAJOR,
- NSS_CKCAPI_HARDWARE_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const CK_VERSION
- nss_ckcapi_FirmwareVersion = {
- NSS_CKCAPI_FIRMWARE_VERSION_MAJOR,
- NSS_CKCAPI_FIRMWARE_VERSION_MINOR
- };
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_TokenLabel = (NSSUTF8 *)"Microsoft Certificate Store";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_TokenModel = (NSSUTF8 *)"1";
-
-NSS_IMPLEMENT_DATA const NSSUTF8 *
- nss_ckcapi_TokenSerialNumber = (NSSUTF8 *)"1";
diff --git a/nss/lib/ckfw/capi/crsa.c b/nss/lib/ckfw/capi/crsa.c
deleted file mode 100644
index 62f90ac..0000000
--- a/nss/lib/ckfw/capi/crsa.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/* 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 "ckcapi.h"
-#include "secdert.h"
-
-#define SSL3_SHAMD5_HASH_SIZE 36 /* LEN_MD5 (16) + LEN_SHA1 (20) */
-
-/*
- * ckcapi/crsa.c
- *
- * This file implements the NSSCKMDMechnaism and NSSCKMDCryptoOperation objects
- * for the RSA operation on the CAPI cryptoki module.
- */
-
-/*
- * write a Decimal value to a string
- */
-
-static char *
-putDecimalString(char *cstr, unsigned long value)
-{
- unsigned long tenpower;
- int first = 1;
-
- for (tenpower = 10000000; tenpower; tenpower /= 10) {
- unsigned char digit = (unsigned char)(value / tenpower);
- value = value % tenpower;
-
- /* drop leading zeros */
- if (first && (0 == digit)) {
- continue;
- }
- first = 0;
- *cstr++ = digit + '0';
- }
-
- /* if value was zero, put one of them out */
- if (first) {
- *cstr++ = '0';
- }
- return cstr;
-}
-
-/*
- * Create a Capi OID string value from a DER OID
- */
-static char *
-nss_ckcapi_GetOidString(
- unsigned char *oidTag,
- unsigned int oidTagSize,
- CK_RV *pError)
-{
- unsigned char *oid;
- char *oidStr;
- char *cstr;
- unsigned long value;
- unsigned int oidSize;
-
- if (DER_OBJECT_ID != *oidTag) {
- /* wasn't an oid */
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
- oid = nss_ckcapi_DERUnwrap(oidTag, oidTagSize, &oidSize, NULL);
-
- if (oidSize < 2) {
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
-
- oidStr = nss_ZNEWARRAY(NULL, char, oidSize * 4);
- if ((char *)NULL == oidStr) {
- *pError = CKR_HOST_MEMORY;
- return NULL;
- }
- cstr = oidStr;
- cstr = putDecimalString(cstr, (*oid) / 40);
- *cstr++ = '.';
- cstr = putDecimalString(cstr, (*oid) % 40);
- oidSize--;
-
- value = 0;
- while (oidSize--) {
- oid++;
- value = (value << 7) + (*oid & 0x7f);
- if (0 == (*oid & 0x80)) {
- *cstr++ = '.';
- cstr = putDecimalString(cstr, value);
- value = 0;
- }
- }
-
- *cstr = 0; /* NULL terminate */
-
- if (value != 0) {
- nss_ZFreeIf(oidStr);
- *pError = CKR_DATA_INVALID;
- return NULL;
- }
- return oidStr;
-}
-
-/*
- * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
- * which includes the hash OID. CAPI expects to take a Hash Context. While
- * CAPI does have the capability of setting a raw hash value, it does not
- * have the ability to sign an arbitrary value. This function tries to
- * reduce the passed in data into something that CAPI could actually sign.
- */
-static CK_RV
-ckcapi_GetRawHash(
- const NSSItem *input,
- NSSItem *hash,
- ALG_ID *hashAlg)
-{
- unsigned char *current;
- unsigned char *algid;
- unsigned char *oid;
- unsigned char *hashData;
- char *oidStr;
- CK_RV error;
- unsigned int oidSize;
- unsigned int size;
- /*
- * there are 2 types of hashes NSS typically tries to sign, regular
- * RSA signature format (with encoded DER_OIDS), and SSL3 Signed hashes.
- * CAPI knows not to add any oids to SSL3_Signed hashes, so if we have any
- * random hash that is exactly the same size as an SSL3 hash, then we can
- * just pass the data through. CAPI has know way of knowing if the value
- * is really a combined hash or some other arbitrary data, so it's safe to
- * handle this case first.
- */
- if (SSL3_SHAMD5_HASH_SIZE == input->size) {
- hash->data = input->data;
- hash->size = input->size;
- *hashAlg = CALG_SSL3_SHAMD5;
- return CKR_OK;
- }
-
- current = (unsigned char *)input->data;
-
- /* make sure we have a sequence tag */
- if ((DER_SEQUENCE | DER_CONSTRUCTED) != *current) {
- return CKR_DATA_INVALID;
- }
-
- /* parse the input block to get 1) the hash oid, and 2) the raw hash value.
- * unfortunatly CAPI doesn't have a builtin function to do this work, so
- * we go ahead and do it by hand here.
- *
- * format is:
- * SEQUENCE {
- * SECQUENCE { // algid
- * OID {} // oid
- * ANY {} // optional params
- * }
- * OCTECT {} // hash
- */
-
- /* unwrap */
- algid = nss_ckcapi_DERUnwrap(current, input->size, &size, NULL);
-
- if (algid + size != current + input->size) {
- /* make sure there is not extra data at the end */
- return CKR_DATA_INVALID;
- }
-
- if ((DER_SEQUENCE | DER_CONSTRUCTED) != *algid) {
- /* wasn't an algid */
- return CKR_DATA_INVALID;
- }
- oid = nss_ckcapi_DERUnwrap(algid, size, &oidSize, &hashData);
-
- if (DER_OCTET_STRING != *hashData) {
- /* wasn't a hash */
- return CKR_DATA_INVALID;
- }
-
- /* get the real hash */
- current = hashData;
- size = size - (hashData - algid);
- hash->data = nss_ckcapi_DERUnwrap(current, size, &hash->size, NULL);
-
- /* get the real oid as a string. Again, Microsoft does not
- * export anything that does this for us */
- oidStr = nss_ckcapi_GetOidString(oid, oidSize, &error);
- if ((char *)NULL == oidStr) {
- return error;
- }
-
- /* look up the hash alg from the oid (fortunately CAPI does to this) */
- *hashAlg = CertOIDToAlgId(oidStr);
- nss_ZFreeIf(oidStr);
- if (0 == *hashAlg) {
- return CKR_HOST_MEMORY;
- }
-
- /* hash looks reasonably consistent, we should be able to sign it now */
- return CKR_OK;
-}
-
-/*
- * So everyone else in the worlds stores their bignum data MSB first, but not
- * Microsoft, we need to byte swap everything coming into and out of CAPI.
- */
-void
-ckcapi_ReverseData(NSSItem *item)
-{
- int end = (item->size) - 1;
- int middle = (item->size) / 2;
- unsigned char *buf = item->data;
- int i;
-
- for (i = 0; i < middle; i++) {
- unsigned char tmp = buf[i];
- buf[i] = buf[end - i];
- buf[end - i] = tmp;
- }
- return;
-}
-
-typedef struct ckcapiInternalCryptoOperationRSAPrivStr
- ckcapiInternalCryptoOperationRSAPriv;
-struct ckcapiInternalCryptoOperationRSAPrivStr {
- NSSCKMDCryptoOperation mdOperation;
- NSSCKMDMechanism *mdMechanism;
- ckcapiInternalObject *iKey;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey;
- NSSItem *buffer;
-};
-
-/*
- * ckcapi_mdCryptoOperationRSAPriv_Create
- */
-static NSSCKMDCryptoOperation *
-ckcapi_mdCryptoOperationRSAPriv_Create(
- const NSSCKMDCryptoOperation *proto,
- NSSCKMDMechanism *mdMechanism,
- NSSCKMDObject *mdKey,
- CK_RV *pError)
-{
- ckcapiInternalObject *iKey = (ckcapiInternalObject *)mdKey->etc;
- const NSSItem *classItem = nss_ckcapi_FetchAttribute(iKey, CKA_CLASS);
- const NSSItem *keyType = nss_ckcapi_FetchAttribute(iKey, CKA_KEY_TYPE);
- ckcapiInternalCryptoOperationRSAPriv *iOperation;
- CK_RV error;
- HCRYPTPROV hProv;
- DWORD keySpec;
- HCRYPTKEY hKey;
-
- /* 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;
- }
-
- error = nss_ckcapi_FetchKeyContainer(iKey, &hProv, &keySpec, &hKey);
- if (error != CKR_OK) {
- *pError = error;
- return (NSSCKMDCryptoOperation *)NULL;
- }
-
- iOperation = nss_ZNEW(NULL, ckcapiInternalCryptoOperationRSAPriv);
- if ((ckcapiInternalCryptoOperationRSAPriv *)NULL == iOperation) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDCryptoOperation *)NULL;
- }
- iOperation->mdMechanism = mdMechanism;
- iOperation->iKey = iKey;
- iOperation->hProv = hProv;
- iOperation->keySpec = keySpec;
- iOperation->hKey = hKey;
-
- nsslibc_memcpy(&iOperation->mdOperation,
- proto, sizeof(NSSCKMDCryptoOperation));
- iOperation->mdOperation.etc = iOperation;
-
- return &iOperation->mdOperation;
-}
-
-static CK_RV
-ckcapi_mdCryptoOperationRSAPriv_Destroy(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
-
- if (iOperation->hKey) {
- CryptDestroyKey(iOperation->hKey);
- }
- if (iOperation->buffer) {
- nssItem_Destroy(iOperation->buffer);
- }
- nss_ZFreeIf(iOperation);
- return CKR_OK;
-}
-
-static CK_ULONG
-ckcapi_mdCryptoOperationRSA_GetFinalLength(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- const NSSItem *modulus =
- nss_ckcapi_FetchAttribute(iOperation->iKey, CKA_MODULUS);
-
- return modulus->size;
-}
-
-/*
- * ckcapi_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
-ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- CK_RV *pError)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- BOOL rc;
-
- /* 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;
- }
- /* Sigh, reverse it */
- ckcapi_ReverseData(iOperation->buffer);
-
- rc = CryptDecrypt(iOperation->hKey, 0, TRUE, 0,
- iOperation->buffer->data, &iOperation->buffer->size);
- if (!rc) {
- DWORD msError = GetLastError();
- switch (msError) {
- case NTE_BAD_DATA:
- *pError =
- CKR_ENCRYPTED_DATA_INVALID;
- break;
- case NTE_FAIL:
- case NTE_BAD_UID:
- *pError =
- CKR_DEVICE_ERROR;
- break;
- default:
- *pError =
- CKR_GENERAL_ERROR;
- }
- return 0;
- }
-
- return iOperation->buffer->size;
-}
-
-/*
- * ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal
- *
- * NOTE: ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength is presumed to
- * have been called previously.
- */
-static CK_RV
-ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)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;
-}
-
-/*
- * ckcapi_mdCryptoOperationRSASign_UpdateFinal
- *
- */
-static CK_RV
-ckcapi_mdCryptoOperationRSASign_UpdateFinal(
- NSSCKMDCryptoOperation *mdOperation,
- NSSCKFWCryptoOperation *fwOperation,
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- const NSSItem *input,
- NSSItem *output)
-{
- ckcapiInternalCryptoOperationRSAPriv *iOperation =
- (ckcapiInternalCryptoOperationRSAPriv *)mdOperation->etc;
- CK_RV error = CKR_OK;
- DWORD msError;
- NSSItem hash;
- HCRYPTHASH hHash = 0;
- ALG_ID hashAlg;
- DWORD hashSize;
- DWORD len; /* temp length value we throw away */
- BOOL rc;
-
- /*
- * PKCS #11 sign for RSA expects to take a fully DER-encoded hash value,
- * which includes the hash OID. CAPI expects to take a Hash Context. While
- * CAPI does have the capability of setting a raw hash value, it does not
- * have the ability to sign an arbitrary value. This function tries to
- * reduce the passed in data into something that CAPI could actually sign.
- */
- error = ckcapi_GetRawHash(input, &hash, &hashAlg);
- if (CKR_OK != error) {
- goto loser;
- }
-
- rc = CryptCreateHash(iOperation->hProv, hashAlg, 0, 0, &hHash);
- if (!rc) {
- goto loser;
- }
-
- /* make sure the hash lens match before we set it */
- len = sizeof(DWORD);
- rc = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize, &len, 0);
- if (!rc) {
- goto loser;
- }
-
- if (hash.size != hashSize) {
- /* The input must have been bad for this to happen */
- error = CKR_DATA_INVALID;
- goto loser;
- }
-
- /* we have an explicit hash, set it, note that the length is
- * implicit by the hashAlg used in create */
- rc = CryptSetHashParam(hHash, HP_HASHVAL, hash.data, 0);
- if (!rc) {
- goto loser;
- }
-
- /* OK, we have the data in a hash structure, sign it! */
- rc = CryptSignHash(hHash, iOperation->keySpec, NULL, 0,
- output->data, &output->size);
- if (!rc) {
- goto loser;
- }
-
- /* Don't return a signature that might have been broken because of a cosmic
- * ray, or a broken processor, verify that it is valid... */
- rc = CryptVerifySignature(hHash, output->data, output->size,
- iOperation->hKey, NULL, 0);
- if (!rc) {
- goto loser;
- }
-
- /* OK, Microsoft likes to do things completely differently than anyone
- * else. We need to reverse the data we received here */
- ckcapi_ReverseData(output);
- CryptDestroyHash(hHash);
- return CKR_OK;
-
-loser:
- /* map the microsoft error */
- if (CKR_OK == error) {
- msError = GetLastError();
- switch (msError) {
- case ERROR_NOT_ENOUGH_MEMORY:
- error =
- CKR_HOST_MEMORY;
- break;
- case NTE_NO_MEMORY:
- error =
- CKR_DEVICE_MEMORY;
- break;
- case ERROR_MORE_DATA:
- return CKR_BUFFER_TOO_SMALL;
- case ERROR_INVALID_PARAMETER: /* these params were derived from the */
- case ERROR_INVALID_HANDLE: /* inputs, so if they are bad, the input */
- case NTE_BAD_ALGID: /* data is bad */
- case NTE_BAD_HASH:
- error =
- CKR_DATA_INVALID;
- break;
- case ERROR_BUSY:
- case NTE_FAIL:
- case NTE_BAD_UID:
- error =
- CKR_DEVICE_ERROR;
- break;
- default:
- error =
- CKR_GENERAL_ERROR;
- break;
- }
- }
- if (hHash) {
- CryptDestroyHash(hHash);
- }
- return error;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
- ckcapi_mdCryptoOperationRSADecrypt_proto = {
- NULL, /* etc */
- ckcapi_mdCryptoOperationRSAPriv_Destroy,
- NULL, /* GetFinalLengh - not needed for one shot Decrypt/Encrypt */
- ckcapi_mdCryptoOperationRSADecrypt_GetOperationLength,
- NULL, /* Final - not needed for one shot operation */
- NULL, /* Update - not needed for one shot operation */
- NULL, /* DigetUpdate - not needed for one shot operation */
- ckcapi_mdCryptoOperationRSADecrypt_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
- };
-
-NSS_IMPLEMENT_DATA const NSSCKMDCryptoOperation
- ckcapi_mdCryptoOperationRSASign_proto = {
- NULL, /* etc */
- ckcapi_mdCryptoOperationRSAPriv_Destroy,
- ckcapi_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, /* DigetUpdate - not needed for one shot operation */
- ckcapi_mdCryptoOperationRSASign_UpdateFinal,
- NULL, /* UpdateCombo - not needed for one shot operation */
- NULL, /* DigetKey - not needed for one shot operation */
- (void *)NULL /* null terminator */
- };
-
-/********** NSSCKMDMechansim functions ***********************/
-/*
- * ckcapi_mdMechanismRSA_Destroy
- */
-static void
-ckcapi_mdMechanismRSA_Destroy(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- nss_ZFreeIf(fwMechanism);
-}
-
-/*
- * ckcapi_mdMechanismRSA_GetMinKeySize
- */
-static CK_ULONG
-ckcapi_mdMechanismRSA_GetMinKeySize(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return 384;
-}
-
-/*
- * ckcapi_mdMechanismRSA_GetMaxKeySize
- */
-static CK_ULONG
-ckcapi_mdMechanismRSA_GetMaxKeySize(
- NSSCKMDMechanism *mdMechanism,
- NSSCKFWMechanism *fwMechanism,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return 16384;
-}
-
-/*
- * ckcapi_mdMechanismRSA_DecryptInit
- */
-static NSSCKMDCryptoOperation *
-ckcapi_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 ckcapi_mdCryptoOperationRSAPriv_Create(
- &ckcapi_mdCryptoOperationRSADecrypt_proto,
- mdMechanism, mdKey, pError);
-}
-
-/*
- * ckcapi_mdMechanismRSA_SignInit
- */
-static NSSCKMDCryptoOperation *
-ckcapi_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 ckcapi_mdCryptoOperationRSAPriv_Create(
- &ckcapi_mdCryptoOperationRSASign_proto,
- mdMechanism, mdKey, pError);
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDMechanism
- nss_ckcapi_mdMechanismRSA = {
- (void *)NULL, /* etc */
- ckcapi_mdMechanismRSA_Destroy,
- ckcapi_mdMechanismRSA_GetMinKeySize,
- ckcapi_mdMechanismRSA_GetMaxKeySize,
- NULL, /* GetInHardware - default false */
- NULL, /* EncryptInit - default errs */
- ckcapi_mdMechanismRSA_DecryptInit,
- NULL, /* DigestInit - default errs*/
- ckcapi_mdMechanismRSA_SignInit,
- NULL, /* VerifyInit - default errs */
- ckcapi_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/nss/lib/ckfw/capi/csession.c b/nss/lib/ckfw/capi/csession.c
deleted file mode 100644
index 5b268ea..0000000
--- a/nss/lib/ckfw/capi/csession.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/* 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 "ckcapi.h"
-
-/*
- * ckcapi/csession.c
- *
- * This file implements the NSSCKMDSession object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSCKMDFindObjects *
-ckcapi_mdSession_FindObjectsInit(
- NSSCKMDSession *mdSession,
- NSSCKFWSession *fwSession,
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_RV *pError)
-{
- return nss_ckcapi_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-static NSSCKMDObject *
-ckcapi_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)
-{
- return nss_ckcapi_CreateObject(fwSession, pTemplate, ulAttributeCount, pError);
-}
-
-NSS_IMPLEMENT NSSCKMDSession *
-nss_ckcapi_CreateSession(
- NSSCKFWSession *fwSession,
- CK_RV *pError)
-{
- NSSArena *arena;
- NSSCKMDSession *rv;
-
- 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 */
- /* rv->Logout */
- /* rv->InitPIN */
- /* rv->SetPIN */
- /* rv->GetOperationStateLen */
- /* rv->GetOperationState */
- /* rv->SetOperationState */
- rv->CreateObject = ckcapi_mdSession_CreateObject;
- /* rv->CopyObject */
- rv->FindObjectsInit = ckcapi_mdSession_FindObjectsInit;
- /* rv->SeedRandom */
- /* rv->GetRandom */
- /* rv->null */
-
- return rv;
-}
diff --git a/nss/lib/ckfw/capi/cslot.c b/nss/lib/ckfw/capi/cslot.c
deleted file mode 100644
index 8a39b78..0000000
--- a/nss/lib/ckfw/capi/cslot.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* 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 "ckcapi.h"
-
-/*
- * ckcapi/cslot.c
- *
- * This file implements the NSSCKMDSlot object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSUTF8 *
-ckcapi_mdSlot_GetSlotDescription(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_SlotDescription;
-}
-
-static NSSUTF8 *
-ckcapi_mdSlot_GetManufacturerID(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static CK_VERSION
-ckcapi_mdSlot_GetHardwareVersion(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_HardwareVersion;
-}
-
-static CK_VERSION
-ckcapi_mdSlot_GetFirmwareVersion(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_FirmwareVersion;
-}
-
-static NSSCKMDToken *
-ckcapi_mdSlot_GetToken(
- NSSCKMDSlot *mdSlot,
- NSSCKFWSlot *fwSlot,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSCKMDToken *)&nss_ckcapi_mdToken;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDSlot
- nss_ckcapi_mdSlot = {
- (void *)NULL, /* etc */
- NULL, /* Initialize */
- NULL, /* Destroy */
- ckcapi_mdSlot_GetSlotDescription,
- ckcapi_mdSlot_GetManufacturerID,
- NULL, /* GetTokenPresent -- defaults to true */
- NULL, /* GetRemovableDevice -- defaults to false */
- NULL, /* GetHardwareSlot -- defaults to false */
- ckcapi_mdSlot_GetHardwareVersion,
- ckcapi_mdSlot_GetFirmwareVersion,
- ckcapi_mdSlot_GetToken,
- (void *)NULL /* null terminator */
- };
diff --git a/nss/lib/ckfw/capi/ctoken.c b/nss/lib/ckfw/capi/ctoken.c
deleted file mode 100644
index cc95c17..0000000
--- a/nss/lib/ckfw/capi/ctoken.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* 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 "ckcapi.h"
-
-/*
- * ckcapi/ctoken.c
- *
- * This file implements the NSSCKMDToken object for the
- * "nss to capi" cryptoki module.
- */
-
-static NSSUTF8 *
-ckcapi_mdToken_GetLabel(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenLabel;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetManufacturerID(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_ManufacturerID;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetModel(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenModel;
-}
-
-static NSSUTF8 *
-ckcapi_mdToken_GetSerialNumber(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_RV *pError)
-{
- return (NSSUTF8 *)nss_ckcapi_TokenSerialNumber;
-}
-
-static CK_BBOOL
-ckcapi_mdToken_GetIsWriteProtected(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_FALSE;
-}
-
-/* fake out Mozilla so we don't try to initialize the token */
-static CK_BBOOL
-ckcapi_mdToken_GetUserPinInitialized(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return CK_TRUE;
-}
-
-static CK_VERSION
-ckcapi_mdToken_GetHardwareVersion(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_HardwareVersion;
-}
-
-static CK_VERSION
-ckcapi_mdToken_GetFirmwareVersion(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return nss_ckcapi_FirmwareVersion;
-}
-
-static NSSCKMDSession *
-ckcapi_mdToken_OpenSession(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- NSSCKFWSession *fwSession,
- CK_BBOOL rw,
- CK_RV *pError)
-{
- return nss_ckcapi_CreateSession(fwSession, pError);
-}
-
-static CK_ULONG
-ckcapi_mdToken_GetMechanismCount(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance)
-{
- return (CK_ULONG)1;
-}
-
-static CK_RV
-ckcapi_mdToken_GetMechanismTypes(
- NSSCKMDToken *mdToken,
- NSSCKFWToken *fwToken,
- NSSCKMDInstance *mdInstance,
- NSSCKFWInstance *fwInstance,
- CK_MECHANISM_TYPE types[])
-{
- types[0] = CKM_RSA_PKCS;
- return CKR_OK;
-}
-
-static NSSCKMDMechanism *
-ckcapi_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 *)&nss_ckcapi_mdMechanismRSA;
-}
-
-NSS_IMPLEMENT_DATA const NSSCKMDToken
- nss_ckcapi_mdToken = {
- (void *)NULL, /* etc */
- NULL, /* Setup */
- NULL, /* Invalidate */
- NULL, /* InitToken -- default errs */
- ckcapi_mdToken_GetLabel,
- ckcapi_mdToken_GetManufacturerID,
- ckcapi_mdToken_GetModel,
- ckcapi_mdToken_GetSerialNumber,
- NULL, /* GetHasRNG -- default is false */
- ckcapi_mdToken_GetIsWriteProtected,
- NULL, /* GetLoginRequired -- default is false */
- ckcapi_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 */
- ckcapi_mdToken_GetHardwareVersion,
- ckcapi_mdToken_GetFirmwareVersion,
- NULL, /* GetUTCTime -- no clock */
- ckcapi_mdToken_OpenSession,
- ckcapi_mdToken_GetMechanismCount,
- ckcapi_mdToken_GetMechanismTypes,
- ckcapi_mdToken_GetMechanism,
- (void *)NULL /* null terminator */
- };
diff --git a/nss/lib/ckfw/capi/manifest.mn b/nss/lib/ckfw/capi/manifest.mn
deleted file mode 100644
index c1003d0..0000000
--- a/nss/lib/ckfw/capi/manifest.mn
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# 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/.
-
-CORE_DEPTH = ../../../..
-
-MODULE = nss
-
-EXPORTS = \
- nsscapi.h \
- $(NULL)
-
-CSRCS = \
- anchor.c \
- constants.c \
- cfind.c \
- cinst.c \
- cobject.c \
- crsa.c \
- csession.c \
- cslot.c \
- ctoken.c \
- ckcapiver.c \
- staticobj.c \
- $(NULL)
-
-REQUIRES = nspr
-
-LIBRARY_NAME = nsscapi
-MAPFILE = $(OBJDIR)/$(LIBRARY_NAME).def
-LIBRARY = $(NULL)
-IMPORT_LIBRARY = $(NULL)
-
-#EXTRA_SHARED_LIBS = -L$(DIST)/lib -lnssckfw -lnssb -lplc4 -lplds4
diff --git a/nss/lib/ckfw/capi/nsscapi.def b/nss/lib/ckfw/capi/nsscapi.def
deleted file mode 100644
index d7e68c7..0000000
--- a/nss/lib/ckfw/capi/nsscapi.def
+++ /dev/null
@@ -1,26 +0,0 @@
-;+#
-;+# 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/.
-;+#
-;+# 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 nsscapi ;-
-EXPORTS ;-
-C_GetFunctionList;
-;+ local:
-;+*;
-;+};
diff --git a/nss/lib/ckfw/capi/nsscapi.h b/nss/lib/ckfw/capi/nsscapi.h
deleted file mode 100644
index 78bf38b..0000000
--- a/nss/lib/ckfw/capi/nsscapi.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 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/. */
-
-#ifndef NSSCAPI_H
-#define NSSCAPI_H
-
-/*
- * NSS CKCAPI 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_CKCAPI_CRYPTOKI_VERSION_MAJOR 2
-#define NSS_CKCAPI_CRYPTOKI_VERSION_MINOR 20
-
-/* These version numbers detail the changes
- * to the list of trusted certificates.
- *
- * NSS_CKCAPI_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_CKCAPI_LIBRARY_VERSION_MAJOR 1
-#define NSS_CKCAPI_LIBRARY_VERSION_MINOR 1
-#define NSS_CKCAPI_LIBRARY_VERSION "1.1"
-
-/* These version numbers detail the semantic changes to the ckfw engine. */
-#define NSS_CKCAPI_HARDWARE_VERSION_MAJOR 1
-#define NSS_CKCAPI_HARDWARE_VERSION_MINOR 0
-
-/* These version numbers detail the semantic changes to ckbi itself
- * (new PKCS #11 objects), etc. */
-#define NSS_CKCAPI_FIRMWARE_VERSION_MAJOR 1
-#define NSS_CKCAPI_FIRMWARE_VERSION_MINOR 0
-
-#endif /* NSSCKBI_H */
diff --git a/nss/lib/ckfw/capi/nsscapi.rc b/nss/lib/ckfw/capi/nsscapi.rc
deleted file mode 100644
index 2791200..0000000
--- a/nss/lib/ckfw/capi/nsscapi.rc
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 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 "nsscapi.h"
-#include <winver.h>
-
-#define MY_LIBNAME "nsscapi"
-#define MY_FILEDESCRIPTION "NSS Access to Microsoft CAPI"
-
-#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_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_LIBRARY_VERSION_MINOR,0,0
- PRODUCTVERSION NSS_CKCAPI_LIBRARY_VERSION_MAJOR,NSS_CKCAPI_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_CKCAPI_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_CKCAPI_LIBRARY_VERSION "\0"
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1200
- END
-END
diff --git a/nss/lib/ckfw/capi/staticobj.c b/nss/lib/ckfw/capi/staticobj.c
deleted file mode 100644
index 2d67a34..0000000
--- a/nss/lib/ckfw/capi/staticobj.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* 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/. */
-
-#ifndef CKCAPI_H
-#include "ckcapi.h"
-#endif /* CKCAPI_H */
-
-static const CK_TRUST ckt_netscape_valid = CKT_NETSCAPE_VALID;
-static const CK_OBJECT_CLASS cko_certificate = CKO_CERTIFICATE;
-static const CK_TRUST ckt_netscape_trusted_delegator = CKT_NETSCAPE_TRUSTED_DELEGATOR;
-static const CK_OBJECT_CLASS cko_netscape_trust = CKO_NETSCAPE_TRUST;
-static const CK_BBOOL ck_true = CK_TRUE;
-static const CK_OBJECT_CLASS cko_data = CKO_DATA;
-static const CK_CERTIFICATE_TYPE ckc_x_509 = CKC_X_509;
-static const CK_BBOOL ck_false = CK_FALSE;
-static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
-
-/* example of a static object */
-static const CK_ATTRIBUTE_TYPE nss_ckcapi_types_1[] = {
- CKA_CLASS, CKA_TOKEN, CKA_PRIVATE, CKA_MODIFIABLE, CKA_LABEL
-};
-
-static const NSSItem nss_ckcapi_items_1[] = {
- { (void *)&cko_data, (PRUint32)sizeof(CK_OBJECT_CLASS) },
- { (void *)&ck_true, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)&ck_false, (PRUint32)sizeof(CK_BBOOL) },
- { (void *)"Mozilla CAPI Access", (PRUint32)20 }
-};
-
-ckcapiInternalObject nss_ckcapi_data[] = {
- {
- ckcapiRaw,
- { 5, nss_ckcapi_types_1, nss_ckcapi_items_1 },
- },
-
-};
-
-const PRUint32 nss_ckcapi_nObjects = 1;
diff --git a/nss/lib/nss/nss.h b/nss/lib/nss/nss.h
index f3608b5..d88116f 100644
--- a/nss/lib/nss/nss.h
+++ b/nss/lib/nss/nss.h
@@ -22,9 +22,9 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define NSS_VERSION "3.99" _NSS_CUSTOMIZED
+#define NSS_VERSION "3.100" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
-#define NSS_VMINOR 99
+#define NSS_VMINOR 100
#define NSS_VPATCH 0
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
diff --git a/nss/lib/pk11wrap/pk11skey.c b/nss/lib/pk11wrap/pk11skey.c
index 02db85b..9e12646 100644
--- a/nss/lib/pk11wrap/pk11skey.c
+++ b/nss/lib/pk11wrap/pk11skey.c
@@ -526,16 +526,16 @@ PK11_ImportDataKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, PK11Origin origin
return NULL;
}
handle = PK11_GetObjectHandle(PK11_TypeGeneric, genObject, NULL);
- if (handle == CK_INVALID_HANDLE) {
- return NULL;
- }
/* A note about ownership of the PKCS #11 handle:
* PK11_CreateGenericObject() will not destroy the object it creates
* on Free, For that you want PK11_CreateManagedGenericObject().
* Below we import the handle into the symKey structure. We pass
* PR_TRUE as the owner so that the symKey will destroy the object
- * once it's freed. This is way it's safe to free now. */
+ * once it's freed. This is why it's safe to destroy genObject now. */
PK11_DestroyGenericObject(genObject);
+ if (handle == CK_INVALID_HANDLE) {
+ return NULL;
+ }
return PK11_SymKeyFromHandle(slot, NULL, origin, type, handle, PR_TRUE, wincx);
}
diff --git a/nss/lib/pk11wrap/pk11slot.c b/nss/lib/pk11wrap/pk11slot.c
index 90a429d..e4c7a73 100644
--- a/nss/lib/pk11wrap/pk11slot.c
+++ b/nss/lib/pk11wrap/pk11slot.c
@@ -94,8 +94,7 @@ static PK11SlotList
pk11_tlsSlotList,
pk11_randomSlotList,
pk11_sha256SlotList,
- pk11_sha512SlotList, /* slots do SHA512 and SHA384 */
- pk11_kyberSlotList;
+ pk11_sha512SlotList; /* slots do SHA512 and SHA384 */
/************************************************************
* Generic Slot List and Slot List element manipulations
@@ -850,7 +849,6 @@ PK11_InitSlotLists(void)
pk11_InitSlotListStatic(&pk11_randomSlotList);
pk11_InitSlotListStatic(&pk11_sha256SlotList);
pk11_InitSlotListStatic(&pk11_sha512SlotList);
- pk11_InitSlotListStatic(&pk11_kyberSlotList);
return SECSuccess;
}
@@ -877,7 +875,6 @@ PK11_DestroySlotLists(void)
pk11_FreeSlotListStatic(&pk11_randomSlotList);
pk11_FreeSlotListStatic(&pk11_sha256SlotList);
pk11_FreeSlotListStatic(&pk11_sha512SlotList);
- pk11_FreeSlotListStatic(&pk11_kyberSlotList);
return;
}
@@ -947,6 +944,8 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type)
case CKM_ECDSA_SHA1:
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
+ case CKM_NSS_KYBER_KEY_PAIR_GEN: /* Bug 1893029 */
+ case CKM_NSS_KYBER:
return &pk11_ecSlotList;
case CKM_SSL3_PRE_MASTER_KEY_GEN:
case CKM_SSL3_MASTER_KEY_DERIVE:
@@ -962,8 +961,6 @@ PK11_GetSlotList(CK_MECHANISM_TYPE type)
return &pk11_ideaSlotList;
case CKM_FAKE_RANDOM:
return &pk11_randomSlotList;
- case CKM_NSS_KYBER_KEY_PAIR_GEN:
- return &pk11_kyberSlotList;
}
return NULL;
}
diff --git a/nss/lib/smime/cmsasn1.c b/nss/lib/smime/cmsasn1.c
index 8ba95d0..4758006 100644
--- a/nss/lib/smime/cmsasn1.c
+++ b/nss/lib/smime/cmsasn1.c
@@ -23,6 +23,7 @@ SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
SEC_ASN1_MKSUB(SEC_BitStringTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
+SEC_ASN1_MKSUB(SEC_GeneralizedTimeTemplate)
SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate)
SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
@@ -269,27 +270,45 @@ static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
offsetof(NSSCMSOriginatorIdentifierOrKey, id.issuerAndSN),
SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
NSSCMSOriginatorIDOrKey_IssuerSN },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
- SEC_ASN1_XTRN | 1,
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
offsetof(NSSCMSOriginatorIdentifierOrKey, id.subjectKeyID),
- SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate),
NSSCMSOriginatorIDOrKey_SubjectKeyID },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(NSSCMSOriginatorIdentifierOrKey, id.originatorPublicKey),
NSSCMSOriginatorPublicKeyTemplate,
NSSCMSOriginatorIDOrKey_OriginatorPublicKey },
{ 0 }
};
+const SEC_ASN1Template NSSCMSOtherKeyAttributeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSOtherKeyAttribute) },
+ {
+ SEC_ASN1_OBJECT_ID,
+ offsetof(NSSCMSOtherKeyAttribute, keyAttrId),
+ },
+ {
+ SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
+ offsetof(NSSCMSOtherKeyAttribute, keyAttr),
+ },
+ {
+ 0,
+ }
+};
+
const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
- { SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier, subjectKeyIdentifier) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier, date) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSRecipientKeyIdentifier, other) },
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSRecipientKeyIdentifier, subjectKeyIdentifier),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSRecipientKeyIdentifier, date),
+ SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSRecipientKeyIdentifier, other),
+ NSSCMSOtherKeyAttributeTemplate },
{ 0 }
};
@@ -316,7 +335,7 @@ static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = {
NSSCMSKeyAgreeRecipientIdentifierTemplate },
{ SEC_ASN1_INLINE | SEC_ASN1_XTRN,
offsetof(NSSCMSRecipientEncryptedKey, encKey),
- SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
{ 0 }
};
@@ -350,10 +369,12 @@ static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = {
0, NULL, sizeof(NSSCMSKEKIdentifier) },
{ SEC_ASN1_OCTET_STRING,
offsetof(NSSCMSKEKIdentifier, keyIdentifier) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier, date) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
- offsetof(NSSCMSKEKIdentifier, other) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKEKIdentifier, date),
+ SEC_ASN1_SUB(SEC_GeneralizedTimeTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKEKIdentifier, other),
+ NSSCMSOtherKeyAttributeTemplate },
{ 0 }
};
@@ -380,11 +401,11 @@ const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
{ SEC_ASN1_CHOICE,
offsetof(NSSCMSRecipientInfo, recipientInfoType), NULL,
sizeof(NSSCMSRecipientInfo) },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
offsetof(NSSCMSRecipientInfo, ri.keyAgreeRecipientInfo),
NSSCMSKeyAgreeRecipientInfoTemplate,
NSSCMSRecipientInfoID_KeyAgree },
- { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
offsetof(NSSCMSRecipientInfo, ri.kekRecipientInfo),
NSSCMSKEKRecipientInfoTemplate,
NSSCMSRecipientInfoID_KEK },
diff --git a/nss/lib/smime/cmslocal.h b/nss/lib/smime/cmslocal.h
index ef7d500..2cc91ac 100644
--- a/nss/lib/smime/cmslocal.h
+++ b/nss/lib/smime/cmslocal.h
@@ -164,14 +164,24 @@ NSS_CMSUtil_EncryptSymKey_RSAPubKey(PLArenaPool *poolp,
extern PK11SymKey *
NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOidTag bulkalgtag);
-extern SECStatus
-NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *originatorPubKey);
-
+/*
+ * NSS_CMSUtil_DecryptSymKey_RSA_OAEP is the same as NSS_CMSUtil_DecryptSymKey_RSA, except that
+ * it works with a symmetric key that was wrapped using RSA with OAEP padding rather than PKCS #1
+ * Version 1.5 padding.
+ */
extern PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey,
- SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg);
+NSS_CMSUtil_DecryptSymKey_RSA_OAEP(SECKEYPrivateKey *privkey, SECItem *parameters, SECItem *encKey, SECOidTag bulkalgtag);
+
+extern SECStatus
+NSS_CMSUtil_EncryptSymKey_ESECDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
+ SECItem *encKey, PRBool genUkm, SECItem *ukm,
+ SECAlgorithmID *keyEncAlg, SECItem *originatorPubKey, void *wincx);
+
+PK11SymKey *
+NSS_CMSUtil_DecryptSymKey_ECDH(SECKEYPrivateKey *privkey, SECItem *encKey,
+ SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag,
+ SECItem *ukm, NSSCMSOriginatorIdentifierOrKey *oiok,
+ void *wincx);
/************************************************************************
* cmsreclist.c - recipient list stuff
diff --git a/nss/lib/smime/cmspubkey.c b/nss/lib/smime/cmspubkey.c
index 8f18f60..0c494c3 100644
--- a/nss/lib/smime/cmspubkey.c
+++ b/nss/lib/smime/cmspubkey.c
@@ -15,6 +15,8 @@
#include "secoid.h"
#include "pk11func.h"
#include "secerr.h"
+#include "secder.h"
+#include "prerr.h"
/* ====== RSA ======================================================================= */
@@ -106,180 +108,568 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid
return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0);
}
-/* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */
+typedef struct RSA_OAEP_CMS_paramsStr RSA_OAEP_CMS_params;
+struct RSA_OAEP_CMS_paramsStr {
+ SECAlgorithmID *hashFunc;
+ SECAlgorithmID *maskGenFunc;
+ SECAlgorithmID *pSourceFunc;
+};
+
+SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
+SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
+
+static const SEC_ASN1Template seckey_PointerToAlgorithmIDTemplate[] = {
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN, 0,
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }
+};
+
+static const SEC_ASN1Template RSA_OAEP_CMS_paramsTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(RSA_OAEP_CMS_params) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
+ SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(RSA_OAEP_CMS_params, hashFunc),
+ seckey_PointerToAlgorithmIDTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
+ SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(RSA_OAEP_CMS_params, maskGenFunc),
+ seckey_PointerToAlgorithmIDTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
+ SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ offsetof(RSA_OAEP_CMS_params, pSourceFunc),
+ seckey_PointerToAlgorithmIDTemplate },
+ { 0 }
+};
+/*
+ * NSS_CMSUtil_DecryptSymKey_RSA_OAEP - unwrap a RSA-wrapped symmetric key
+ *
+ * this function takes an RSA-OAEP-wrapped symmetric key and unwraps it, returning a symmetric
+ * key handle. Please note that the actual unwrapped key data may not be allowed to leave
+ * a hardware token...
+ */
+PK11SymKey *
+NSS_CMSUtil_DecryptSymKey_RSA_OAEP(SECKEYPrivateKey *privkey, SECItem *parameters, SECItem *encKey, SECOidTag bulkalgtag)
+{
+ CK_RSA_PKCS_OAEP_PARAMS oaep_params;
+ RSA_OAEP_CMS_params encoded_params;
+ SECAlgorithmID mgf1hashAlg;
+ SECOidTag mgfAlgtag, mgf1hashAlgtag, pSourcetag;
+ SECItem encoding_params, params;
+ PK11SymKey *bulkkey = NULL;
+ SECStatus rv;
+
+ CK_MECHANISM_TYPE target;
+ PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN);
+ target = PK11_AlgtagToMechanism(bulkalgtag);
+ if (bulkalgtag == SEC_OID_UNKNOWN || target == CKM_INVALID_MECHANISM) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return NULL;
+ }
+
+ PORT_Memset(&encoded_params, 0, sizeof(RSA_OAEP_CMS_params));
+ PORT_Memset(&mgf1hashAlg, 0, sizeof(SECAlgorithmID));
+ PORT_Memset(&encoding_params, 0, sizeof(SECItem));
+
+ /* Set default values for the OAEP parameters */
+ oaep_params.hashAlg = CKM_SHA_1;
+ oaep_params.mgf = CKG_MGF1_SHA1;
+ oaep_params.source = CKZ_DATA_SPECIFIED;
+ oaep_params.pSourceData = NULL;
+ oaep_params.ulSourceDataLen = 0;
+
+ if (parameters->len == 2) {
+ /* For some reason SEC_ASN1DecodeItem cannot process parameters if it is an emtpy SEQUENCE */
+ /* Just check that this is a properly encoded empty SEQUENCE */
+ if ((parameters->data[0] != 0x30) || (parameters->data[1] != 0)) {
+ return NULL;
+ }
+ } else {
+ rv = SEC_ASN1DecodeItem(NULL, &encoded_params, RSA_OAEP_CMS_paramsTemplate, parameters);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (encoded_params.hashFunc != NULL) {
+ oaep_params.hashAlg = PK11_AlgtagToMechanism(SECOID_GetAlgorithmTag(encoded_params.hashFunc));
+ }
+ if (encoded_params.maskGenFunc != NULL) {
+ mgfAlgtag = SECOID_GetAlgorithmTag(encoded_params.maskGenFunc);
+ if (mgfAlgtag != SEC_OID_PKCS1_MGF1) {
+ /* MGF1 is the only supported mask generation function */
+ goto loser;
+ }
+ /* The parameters field contains an AlgorithmIdentifier specifying the
+ * hash function to use with MGF1.
+ */
+ rv = SEC_ASN1DecodeItem(NULL, &mgf1hashAlg, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
+ &encoded_params.maskGenFunc->parameters);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ mgf1hashAlgtag = SECOID_GetAlgorithmTag(&mgf1hashAlg);
+ switch (mgf1hashAlgtag) {
+ case SEC_OID_SHA1:
+ oaep_params.mgf = CKG_MGF1_SHA1;
+ break;
+ case SEC_OID_SHA224:
+ oaep_params.mgf = CKG_MGF1_SHA224;
+ break;
+ case SEC_OID_SHA256:
+ oaep_params.mgf = CKG_MGF1_SHA256;
+ break;
+ case SEC_OID_SHA384:
+ oaep_params.mgf = CKG_MGF1_SHA384;
+ break;
+ case SEC_OID_SHA512:
+ oaep_params.mgf = CKG_MGF1_SHA512;
+ break;
+ case SEC_OID_SHA3_224:
+ oaep_params.mgf = CKG_MGF1_SHA3_224;
+ break;
+ case SEC_OID_SHA3_256:
+ oaep_params.mgf = CKG_MGF1_SHA3_256;
+ break;
+ case SEC_OID_SHA3_384:
+ oaep_params.mgf = CKG_MGF1_SHA3_384;
+ break;
+ case SEC_OID_SHA3_512:
+ oaep_params.mgf = CKG_MGF1_SHA3_512;
+ break;
+ default:
+ goto loser;
+ break;
+ }
+ }
+ if (encoded_params.pSourceFunc != NULL) {
+ pSourcetag = SECOID_GetAlgorithmTag(encoded_params.pSourceFunc);
+ if (pSourcetag != SEC_OID_PKCS1_PSPECIFIED) {
+ goto loser;
+ }
+ /* The encoding parameters (P) are provided as an OCTET STRING in the parameters field. */
+ if (encoded_params.pSourceFunc->parameters.len != 0) {
+ rv = SEC_ASN1DecodeItem(NULL, &encoding_params, SEC_ASN1_GET(SEC_OctetStringTemplate),
+ &encoded_params.pSourceFunc->parameters);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ oaep_params.ulSourceDataLen = encoding_params.len;
+ oaep_params.pSourceData = encoding_params.data;
+ }
+ }
+ }
+ params.type = siBuffer;
+ params.data = (unsigned char *)&oaep_params;
+ params.len = sizeof(CK_RSA_PKCS_OAEP_PARAMS);
+ bulkkey = PK11_PubUnwrapSymKeyWithMechanism(privkey, CKM_RSA_PKCS_OAEP, &params,
+ encKey, target, CKA_DECRYPT, 0);
+
+loser:
+ PORT_Free(oaep_params.pSourceData);
+ if (encoded_params.hashFunc) {
+ SECOID_DestroyAlgorithmID(encoded_params.hashFunc, PR_TRUE);
+ }
+ if (encoded_params.maskGenFunc) {
+ SECOID_DestroyAlgorithmID(encoded_params.maskGenFunc, PR_TRUE);
+ }
+ if (encoded_params.pSourceFunc) {
+ SECOID_DestroyAlgorithmID(encoded_params.pSourceFunc, PR_TRUE);
+ }
+ SECOID_DestroyAlgorithmID(&mgf1hashAlg, PR_FALSE);
+ return bulkkey;
+}
+
+/* ====== ESECDH (Ephemeral-Static Elliptic Curve Diffie-Hellman) =========== */
+
+typedef struct ECC_CMS_SharedInfoStr ECC_CMS_SharedInfo;
+struct ECC_CMS_SharedInfoStr {
+ SECAlgorithmID *keyInfo; /* key-encryption algorithm */
+ SECItem entityUInfo; /* ukm */
+ SECItem suppPubInfo; /* length of KEK in bits as 32-bit number */
+};
+
+static const SEC_ASN1Template ECC_CMS_SharedInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(ECC_CMS_SharedInfo) },
+ { SEC_ASN1_XTRN | SEC_ASN1_POINTER,
+ offsetof(ECC_CMS_SharedInfo, keyInfo),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(ECC_CMS_SharedInfo, entityUInfo),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED |
+ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
+ offsetof(ECC_CMS_SharedInfo, suppPubInfo),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
+ { 0 }
+};
+
+/* Inputs:
+ * keyInfo: key-encryption algorithm
+ * ukm: ukm field of KeyAgreeRecipientInfo
+ * KEKsize: length of KEK in bytes
+ *
+ * Output: DER encoded ECC-CMS-SharedInfo
+ */
+static SECItem *
+Create_ECC_CMS_SharedInfo(PLArenaPool *poolp,
+ SECAlgorithmID *keyInfo, SECItem *ukm, unsigned int KEKsize)
+{
+ ECC_CMS_SharedInfo SI;
+ unsigned char suppPubInfo[4] = { 0 };
+
+ SI.keyInfo = keyInfo;
+ SI.entityUInfo.type = ukm->type;
+ SI.entityUInfo.data = ukm->data;
+ SI.entityUInfo.len = ukm->len;
+
+ SI.suppPubInfo.type = siBuffer;
+ SI.suppPubInfo.data = suppPubInfo;
+ SI.suppPubInfo.len = sizeof(suppPubInfo);
+
+ if (KEKsize > 0x1FFFFFFF) { // ensure KEKsize * 8 fits in 4 bytes.
+ return NULL;
+ }
+ KEKsize *= 8;
+ suppPubInfo[0] = (KEKsize & 0xFF000000) >> 24;
+ suppPubInfo[1] = (KEKsize & 0xFF0000) >> 16;
+ suppPubInfo[2] = (KEKsize & 0xFF00) >> 8;
+ suppPubInfo[3] = KEKsize & 0xFF;
+
+ return SEC_ASN1EncodeItem(poolp, NULL, &SI, ECC_CMS_SharedInfoTemplate);
+}
+
+/* this will generate a key pair, compute the shared secret, */
+/* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */
+/* the keyEncAlg, set encKey, keyEncAlg, publicKey etc.
+ * The ukm is optional per RFC 5753. Pass a NULL value to request an empty ukm.
+ * Pass a SECItem with the size set to zero, to request allocating a random
+ * ukm of a default size. Or provide an explicit ukm that was defined by the caller.
+ */
SECStatus
-NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key,
- SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg,
- SECItem *pubKey)
+NSS_CMSUtil_EncryptSymKey_ESECDH(PLArenaPool *poolp, CERTCertificate *cert,
+ PK11SymKey *bulkkey, SECItem *encKey,
+ PRBool genUkm, SECItem *ukm,
+ SECAlgorithmID *keyEncAlg, SECItem *pubKey,
+ void *wincx)
{
-#if 0 /* not yet done */
- SECOidTag certalgtag; /* the certificate's encryption algorithm */
- SECOidTag encalgtag; /* the algorithm used for key exchange/agreement */
+ SECOidTag certalgtag; /* the certificate's encryption algorithm */
SECStatus rv;
- SECItem *params = NULL;
- int data_len;
SECStatus err;
- PK11SymKey *tek;
- CERTCertificate *ourCert;
- SECKEYPublicKey *ourPubKey;
- NSSCMSKEATemplateSelector whichKEA = NSSCMSKEAInvalid;
+ PK11SymKey *kek;
+ SECKEYPublicKey *publickey = NULL;
+ SECKEYPublicKey *ourPubKey = NULL;
+ SECKEYPrivateKey *ourPrivKey = NULL;
+ unsigned int bulkkey_size, kek_size;
+ SECAlgorithmID keyWrapAlg;
+ SECOidTag keyEncAlgtag;
+ SECItem keyWrapAlg_params, *keyEncAlg_params, *SharedInfo;
+ CK_MECHANISM_TYPE keyDerivationType, keyWrapMech;
+ CK_ULONG kdf;
+
+ if (genUkm && (ukm->len != 0 || ukm->data != NULL)) {
+ PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
+ return SECFailure;
+ }
certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
- PORT_Assert(certalgtag == SEC_OID_X942_DIFFIE_HELMAN_KEY);
-
- /* We really want to show our KEA tag as the key exchange algorithm tag. */
- encalgtag = SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN;
+ PORT_Assert(certalgtag == SEC_OID_ANSIX962_EC_PUBLIC_KEY);
+ if (certalgtag != SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
+ return SECFailure;
+ }
/* Get the public key of the recipient. */
publickey = CERT_ExtractPublicKey(cert);
- if (publickey == NULL) goto loser;
-
- /* XXXX generate a DH key pair on a PKCS11 module (XXX which parameters?) */
- /* XXXX */ourCert = PK11_FindBestKEAMatch(cert, wincx);
- if (ourCert == NULL) goto loser;
+ if (publickey == NULL)
+ goto loser;
- arena = PORT_NewArena(1024);
- if (arena == NULL) goto loser;
+ ourPrivKey = SECKEY_CreateECPrivateKey(&publickey->u.ec.DEREncodedParams,
+ &ourPubKey, wincx);
+ if (!ourPrivKey || !ourPubKey) {
+ goto loser;
+ }
- /* While we're here, extract the key pair's public key data and copy it into */
- /* the outgoing parameters. */
- /* XXXX */ourPubKey = CERT_ExtractPublicKey(ourCert);
- if (ourPubKey == NULL)
- {
+ rv = SECITEM_CopyItem(poolp, pubKey, &ourPubKey->u.ec.publicValue);
+ if (rv != SECSuccess) {
goto loser;
}
- SECITEM_CopyItem(arena, pubKey, /* XXX */&(ourPubKey->u.fortezza.KEAKey));
+
+ /* pubKey will be encoded as a BIT STRING, so pubKey->len must be length in bits
+ * rather than bytes */
+ pubKey->len = pubKey->len * 8;
+
SECKEY_DestroyPublicKey(ourPubKey); /* we only need the private key from now on */
ourPubKey = NULL;
- /* Extract our private key in order to derive the KEA key. */
- ourPrivKey = PK11_FindKeyByAnyCert(ourCert,wincx);
- CERT_DestroyCertificate(ourCert); /* we're done with this */
- if (!ourPrivKey) goto loser;
+ bulkkey_size = PK11_GetKeyLength(bulkkey);
+ if (bulkkey_size == 0) {
+ goto loser;
+ }
+
+ /* Parameters are supposed to be absent for AES key wrap algorithms.
+ * However, Microsoft Outlook cannot decrypt message unless
+ * parameters field is NULL. */
+ keyWrapAlg_params.len = 2;
+ keyWrapAlg_params.data = (unsigned char *)PORT_ArenaAlloc(poolp, keyWrapAlg_params.len);
+ if (keyWrapAlg_params.data == NULL)
+ goto loser;
- /* If ukm desired, prepare it - allocate enough space (filled with zeros). */
- if (ukm) {
- ukm->data = (unsigned char*)PORT_ArenaZAlloc(arena,/* XXXX */);
- ukm->len = /* XXXX */;
+ keyWrapAlg_params.data[0] = SEC_ASN1_NULL;
+ keyWrapAlg_params.data[1] = 0;
+
+ /* RFC5753 specifies id-aes128-wrap as the mandatory to support algorithm.
+ * So, use id-aes128-wrap unless bulkkey provides more than 128 bits of
+ * security. If bulkkey provides more than 128 bits of security, use
+ * the algorithms from KE Set 2 in RFC 6318. */
+
+ /* TODO: NIST Special Publication SP 800-56A requires the use of
+ * Cofactor ECDH. However, RFC 6318 specifies the use of
+ * dhSinglePass-stdDH-sha256kdf-scheme or dhSinglePass-stdDH-sha384kdf-scheme
+ * for Suite B. The reason for this is that all of the NIST recommended
+ * prime curves in FIPS 186-3 (including the Suite B curves) have a cofactor
+ * of 1, and so for these curves standard and cofactor ECDH are the same.
+ * This code should really look at the key's parameters and choose cofactor
+ * ECDH if the curve has a cofactor other than 1. */
+ if ((PK11_GetMechanism(bulkkey) == CKM_AES_CBC) && (bulkkey_size > 16)) {
+ rv = SECOID_SetAlgorithmID(poolp, &keyWrapAlg, SEC_OID_AES_256_KEY_WRAP, &keyWrapAlg_params);
+ kek_size = 32;
+ keyWrapMech = CKM_NSS_AES_KEY_WRAP;
+ kdf = CKD_SHA384_KDF;
+ keyEncAlgtag = SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME;
+ keyDerivationType = CKM_ECDH1_DERIVE;
+ } else {
+ rv = SECOID_SetAlgorithmID(poolp, &keyWrapAlg, SEC_OID_AES_128_KEY_WRAP, &keyWrapAlg_params);
+ kek_size = 16;
+ keyWrapMech = CKM_NSS_AES_KEY_WRAP;
+ kdf = CKD_SHA256_KDF;
+ keyEncAlgtag = SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME;
+ keyDerivationType = CKM_ECDH1_DERIVE;
+ }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ /* ukm is optional, but RFC 5753 says that originators SHOULD include the ukm.
+ * I made ukm 64 bytes, since RFC 2631 states that UserKeyingMaterial must
+ * contain 512 bits for Diffie-Hellman key agreement. */
+
+ if (genUkm) {
+ ukm->type = siBuffer;
+ ukm->len = 64;
+ ukm->data = (unsigned char *)PORT_ArenaAlloc(poolp, ukm->len);
+
+ if (ukm->data == NULL) {
+ goto loser;
+ }
+ rv = PK11_GenerateRandom(ukm->data, ukm->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ SharedInfo = Create_ECC_CMS_SharedInfo(poolp, &keyWrapAlg,
+ ukm,
+ kek_size);
+ if (!SharedInfo) {
+ goto loser;
}
- /* Generate the KEK (key exchange key) according to RFC2631 which we use
+ /* Generate the KEK (key exchange key) according to RFC5753 which we use
* to wrap the bulk encryption key. */
- kek = PK11_PubDerive(ourPrivKey, publickey, PR_TRUE,
- ukm, NULL,
- /* XXXX */CKM_KEA_KEY_DERIVE, /* XXXX */CKM_SKIPJACK_WRAP,
- CKA_WRAP, 0, wincx);
+ kek = PK11_PubDeriveWithKDF(ourPrivKey, publickey, PR_TRUE,
+ NULL, NULL,
+ keyDerivationType, keyWrapMech,
+ CKA_WRAP, kek_size, kdf, SharedInfo, NULL);
+ if (!kek) {
+ goto loser;
+ }
SECKEY_DestroyPublicKey(publickey);
SECKEY_DestroyPrivateKey(ourPrivKey);
publickey = NULL;
ourPrivKey = NULL;
- if (!kek)
- goto loser;
-
/* allocate space for the encrypted CEK (bulk key) */
- encKey->data = (unsigned char*)PORT_ArenaAlloc(poolp, SMIME_FORTEZZA_MAX_KEY_SIZE);
- encKey->len = SMIME_FORTEZZA_MAX_KEY_SIZE;
+ /* AES key wrap produces an output 64-bits longer than
+ * the input AES CEK (RFC 3565, Section 2.3.2) */
+ encKey->len = bulkkey_size + 8;
+ encKey->data = (unsigned char *)PORT_ArenaAlloc(poolp, encKey->len);
- if (encKey->data == NULL)
- {
+ if (encKey->data == NULL) {
PK11_FreeSymKey(kek);
goto loser;
}
+ err = PK11_WrapSymKey(keyWrapMech, NULL, kek, bulkkey, encKey);
- /* Wrap the bulk key using CMSRC2WRAP or CMS3DESWRAP, depending on the */
- /* bulk encryption algorithm */
- switch (/* XXXX */PK11_AlgtagToMechanism(enccinfo->encalg))
- {
- case /* XXXX */CKM_SKIPJACK_CFB8:
- err = PK11_WrapSymKey(/* XXXX */CKM_CMS3DES_WRAP, NULL, kek, bulkkey, encKey);
- whichKEA = NSSCMSKEAUsesSkipjack;
- break;
- case /* XXXX */CKM_SKIPJACK_CFB8:
- err = PK11_WrapSymKey(/* XXXX */CKM_CMSRC2_WRAP, NULL, kek, bulkkey, encKey);
- whichKEA = NSSCMSKEAUsesSkipjack;
- break;
- default:
- /* XXXX what do we do here? Neither RC2 nor 3DES... */
- err = SECFailure;
- /* set error */
- break;
- }
-
- PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
- if (err != SECSuccess)
+ PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
+ if (err != SECSuccess) {
goto loser;
+ }
- PORT_Assert(whichKEA != NSSCMSKEAInvalid);
-
- /* see RFC2630 12.3.1.1 "keyEncryptionAlgorithm must be ..." */
- /* params is the DER encoded key wrap algorithm (with parameters!) (XXX) */
- params = SEC_ASN1EncodeItem(arena, NULL, &keaParams, sec_pkcs7_get_kea_template(whichKEA));
- if (params == NULL)
+ keyEncAlg_params = SEC_ASN1EncodeItem(poolp, NULL, &keyWrapAlg, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
+ if (keyEncAlg_params == NULL)
goto loser;
+ keyEncAlg_params->type = siBuffer;
/* now set keyEncAlg */
- rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN, params);
- if (rv != SECSuccess)
+ rv = SECOID_SetAlgorithmID(poolp, keyEncAlg, keyEncAlgtag, keyEncAlg_params);
+ if (rv != SECSuccess) {
goto loser;
+ }
+
+ return SECSuccess;
- /* XXXXXXX this is not right yet */
loser:
- if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
- }
if (publickey) {
SECKEY_DestroyPublicKey(publickey);
}
+ if (ourPubKey) {
+ SECKEY_DestroyPublicKey(ourPubKey);
+ }
if (ourPrivKey) {
SECKEY_DestroyPrivateKey(ourPrivKey);
}
-#endif
return SECFailure;
}
+/* TODO: Move to pk11wrap and export? */
+static int
+cms_GetKekSizeFromKeyWrapAlgTag(SECOidTag keyWrapAlgtag)
+{
+ switch (keyWrapAlgtag) {
+ case SEC_OID_AES_128_KEY_WRAP:
+ return 16;
+ case SEC_OID_AES_192_KEY_WRAP:
+ return 24;
+ case SEC_OID_AES_256_KEY_WRAP:
+ return 32;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/* TODO: Move to smimeutil and export? */
+static CK_ULONG
+cms_GetKdfFromKeyEncAlgTag(SECOidTag keyEncAlgtag)
+{
+ switch (keyEncAlgtag) {
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME:
+ return CKD_SHA1_KDF;
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME:
+ return CKD_SHA224_KDF;
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME:
+ return CKD_SHA256_KDF;
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME:
+ return CKD_SHA384_KDF;
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME:
+ return CKD_SHA512_KDF;
+ default:
+ break;
+ }
+ return 0;
+}
+
PK11SymKey *
-NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey,
+NSS_CMSUtil_DecryptSymKey_ECDH(SECKEYPrivateKey *privkey, SECItem *encKey,
SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag,
- void *pwfn_arg)
+ SECItem *ukm, NSSCMSOriginatorIdentifierOrKey *oiok,
+ void *wincx)
{
-#if 0 /* not yet done */
- SECStatus err;
- CK_MECHANISM_TYPE bulkType;
- PK11SymKey *tek;
- SECKEYPublicKey *originatorPubKey;
- NSSCMSSMIMEKEAParameters keaParams;
-
- /* XXXX get originator's public key */
- originatorPubKey = PK11_MakeKEAPubKey(keaParams.originatorKEAKey.data,
- keaParams.originatorKEAKey.len);
- if (originatorPubKey == NULL)
- goto loser;
-
- /* Generate the TEK (token exchange key) which we use to unwrap the bulk encryption key.
- The Derive function generates a shared secret and combines it with the originatorRA
- data to come up with an unique session key */
- tek = PK11_PubDerive(privkey, originatorPubKey, PR_FALSE,
- &keaParams.originatorRA, NULL,
- CKM_KEA_KEY_DERIVE, CKM_SKIPJACK_WRAP,
- CKA_WRAP, 0, pwfn_arg);
- SECKEY_DestroyPublicKey(originatorPubKey); /* not needed anymore */
- if (tek == NULL)
+ SECAlgorithmID keyWrapAlg;
+ SECOidTag keyEncAlgtag, keyWrapAlgtag;
+ CK_MECHANISM_TYPE target, keyDerivationType, keyWrapMech;
+ CK_ULONG kdf;
+ PK11SymKey *kek = NULL, *bulkkey = NULL;
+ int kek_size;
+ SECKEYPublicKey originatorpublickey;
+ SECItem *oiok_publicKey, *SharedInfo = NULL;
+ SECStatus rv;
+
+ PORT_Memset(&keyWrapAlg, 0, sizeof(SECAlgorithmID));
+
+ PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN);
+ target = PK11_AlgtagToMechanism(bulkalgtag);
+ if (bulkalgtag == SEC_OID_UNKNOWN || target == CKM_INVALID_MECHANISM) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+
+ keyEncAlgtag = SECOID_GetAlgorithmTag(keyEncAlg);
+ keyDerivationType = PK11_AlgtagToMechanism(keyEncAlgtag);
+ if ((keyEncAlgtag == SEC_OID_UNKNOWN) ||
+ (keyDerivationType == CKM_INVALID_MECHANISM)) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
goto loser;
+ }
- /* Now that we have the TEK, unwrap the bulk key
- with which to decrypt the message. */
- /* Skipjack is being used as the bulk encryption algorithm.*/
- /* Unwrap the bulk key. */
- bulkkey = PK11_UnwrapSymKey(tek, CKM_SKIPJACK_WRAP, NULL,
- encKey, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
+ rv = SEC_ASN1DecodeItem(NULL, &keyWrapAlg,
+ SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), &(keyEncAlg->parameters));
+ if (rv != SECSuccess) {
+ goto loser;
+ }
- return bulkkey;
+ keyWrapAlgtag = SECOID_GetAlgorithmTag(&keyWrapAlg);
+ keyWrapMech = PK11_AlgtagToMechanism(keyWrapAlgtag);
+ if ((keyWrapAlgtag == SEC_OID_UNKNOWN) ||
+ (keyWrapMech == CKM_INVALID_MECHANISM)) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+
+ kek_size = cms_GetKekSizeFromKeyWrapAlgTag(keyWrapAlgtag);
+ if (!kek_size) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+ kdf = cms_GetKdfFromKeyEncAlgTag(keyEncAlgtag);
+ if (!kdf) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+
+ /* Get originator's public key */
+ /* TODO: Add support for static-static ECDH */
+ if (oiok->identifierType != NSSCMSOriginatorIDOrKey_OriginatorPublicKey) {
+ PORT_SetError(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE);
+ goto loser;
+ }
+
+ /* PK11_PubDeriveWithKDF only uses the keyType u.ec.publicValue.data
+ * and u.ec.publicValue.len from the originator's public key. */
+ oiok_publicKey = &(oiok->id.originatorPublicKey.publicKey);
+ originatorpublickey.keyType = ecKey;
+ originatorpublickey.u.ec.publicValue.data = oiok_publicKey->data;
+ originatorpublickey.u.ec.publicValue.len = oiok_publicKey->len / 8;
+
+ SharedInfo = Create_ECC_CMS_SharedInfo(NULL, &keyWrapAlg, ukm, kek_size);
+ if (!SharedInfo) {
+ goto loser;
+ }
+
+ /* Generate the KEK (key exchange key) according to RFC5753 which we use
+ * to wrap the bulk encryption key. */
+ kek = PK11_PubDeriveWithKDF(privkey, &originatorpublickey, PR_TRUE,
+ NULL, NULL,
+ keyDerivationType, keyWrapMech,
+ CKA_WRAP, kek_size, kdf, SharedInfo, wincx);
+
+ SECITEM_FreeItem(SharedInfo, PR_TRUE);
+
+ if (kek == NULL) {
+ goto loser;
+ }
+
+ bulkkey = PK11_UnwrapSymKey(kek, keyWrapMech, NULL, encKey, target, CKA_UNWRAP, 0);
+ PK11_FreeSymKey(kek); /* we do not need the KEK anymore */
loser:
-#endif
- return NULL;
+ SECOID_DestroyAlgorithmID(&keyWrapAlg, PR_FALSE);
+ return bulkkey;
}
diff --git a/nss/lib/smime/cmsrecinfo.c b/nss/lib/smime/cmsrecinfo.c
index 6cf2c68..e3b383b 100644
--- a/nss/lib/smime/cmsrecinfo.c
+++ b/nss/lib/smime/cmsrecinfo.c
@@ -157,7 +157,7 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
rv = SECFailure;
}
break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
PORT_Assert(type == NSSCMSRecipientID_IssuerSN);
if (type != NSSCMSRecipientID_IssuerSN) {
rv = SECFailure;
@@ -166,10 +166,6 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg,
/* a key agreement op */
ri->recipientInfoType = NSSCMSRecipientInfoID_KeyAgree;
- if (ri->ri.keyTransRecipientInfo.recipientIdentifier.id.issuerAndSN == NULL) {
- rv = SECFailure;
- break;
- }
/* we do not support the case where multiple recipients
* share the same KeyAgreeRecipientInfo and have multiple RecipientEncryptedKeys
* in this case, we would need to walk all the recipientInfos, take the
@@ -274,7 +270,7 @@ NSS_CMSRecipient_IsSupported(CERTCertificate *cert)
switch (certalgtag) {
case SEC_OID_PKCS1_RSA_ENCRYPTION:
- case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
return PR_TRUE;
default:
return PR_FALSE;
@@ -456,6 +452,7 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
PLArenaPool *poolp;
NSSCMSKeyTransRecipientInfoEx *extra = NULL;
PRBool usesSubjKeyID;
+ void *wincx = NULL;
poolp = ri->cmsg->poolp;
cert = ri->cert;
@@ -498,7 +495,7 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL);
break;
- case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0];
if (rek == NULL) {
rv = SECFailure;
@@ -510,7 +507,7 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
/* see RFC2630 12.3.1.1 */
if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier,
- SEC_OID_X942_DIFFIE_HELMAN_KEY, NULL) != SECSuccess) {
+ certalgtag, NULL) != SECSuccess) {
rv = SECFailure;
break;
}
@@ -518,12 +515,27 @@ NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey,
/* this will generate a key pair, compute the shared secret, */
/* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */
/* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */
- rv = NSS_CMSUtil_EncryptSymKey_ESDH(poolp, cert, bulkkey,
- &rek->encKey,
- &ri->ri.keyAgreeRecipientInfo.ukm,
- &ri->ri.keyAgreeRecipientInfo.keyEncAlg,
- &oiok->id.originatorPublicKey.publicKey);
+ switch (certalgtag) {
+ case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
+ if (ri->cmsg) {
+ wincx = ri->cmsg->pwfn_arg;
+ } else {
+ wincx = PK11_GetWindow(bulkkey);
+ }
+ rv = NSS_CMSUtil_EncryptSymKey_ESECDH(poolp, cert, bulkkey,
+ &rek->encKey,
+ PR_TRUE,
+ &ri->ri.keyAgreeRecipientInfo.ukm,
+ &ri->ri.keyAgreeRecipientInfo.keyEncAlg,
+ &oiok->id.originatorPublicKey.publicKey,
+ wincx);
+ break;
+ default:
+ /* Not reached. Added to silence enum warnings. */
+ PORT_Assert(0);
+ break;
+ }
break;
default:
/* other algorithms not supported yet */
@@ -543,8 +555,10 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
{
PK11SymKey *bulkkey = NULL;
SECOidTag encalgtag;
- SECItem *enckey;
+ SECItem *enckey, *ukm, *parameters;
+ NSSCMSOriginatorIdentifierOrKey *oiok;
int error;
+ void *wincx = NULL;
ri->cert = CERT_DupCertificate(cert);
/* mark the recipientInfo so we can find it later */
@@ -559,6 +573,12 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
/* get the symmetric (bulk) key by unwrapping it using our private key */
bulkkey = NSS_CMSUtil_DecryptSymKey_RSA(privkey, enckey, bulkalgtag);
break;
+ case SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION:
+ /* RSA OAEP encryption algorithm: */
+ /* get the symmetric (bulk) key by unwrapping it using our private key */
+ parameters = &(ri->ri.keyTransRecipientInfo.keyEncAlg.parameters);
+ bulkkey = NSS_CMSUtil_DecryptSymKey_RSA_OAEP(privkey, parameters, enckey, bulkalgtag);
+ break;
default:
error = SEC_ERROR_UNSUPPORTED_KEYALG;
goto loser;
@@ -567,19 +587,27 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
case NSSCMSRecipientInfoID_KeyAgree:
encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg));
enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey);
+ oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey);
+ ukm = &(ri->ri.keyAgreeRecipientInfo.ukm);
switch (encalgtag) {
- case SEC_OID_X942_DIFFIE_HELMAN_KEY:
- /* Diffie-Helman key exchange */
- /* XXX not yet implemented */
- /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */
- /* we support ephemeral-static DH only, so if the recipientinfo */
- /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */
- /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */
- /* content encryption key using a Unwrap op */
- /* the derive operation has to generate the key using the algorithm in RFC2631 */
- error = SEC_ERROR_UNSUPPORTED_KEYALG;
- goto loser;
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME:
+ case SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME:
+ if (ri->cmsg) {
+ wincx = ri->cmsg->pwfn_arg;
+ }
+ bulkkey = NSS_CMSUtil_DecryptSymKey_ECDH(privkey, enckey,
+ &(ri->ri.keyAgreeRecipientInfo.keyEncAlg),
+ bulkalgtag, ukm, oiok, wincx);
break;
+
default:
error = SEC_ERROR_UNSUPPORTED_KEYALG;
goto loser;
diff --git a/nss/lib/smime/cmst.h b/nss/lib/smime/cmst.h
index 3d888bc..1144f55 100644
--- a/nss/lib/smime/cmst.h
+++ b/nss/lib/smime/cmst.h
@@ -339,10 +339,17 @@ struct NSSCMSOriginatorIdentifierOrKeyStr {
};
typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey;
+struct NSSCMSOtherKeyAttributeStr {
+ SECItem keyAttrId;
+ SECItem keyAttr; /* optional */
+};
+
+typedef struct NSSCMSOtherKeyAttributeStr NSSCMSOtherKeyAttribute;
+
struct NSSCMSRecipientKeyIdentifierStr {
SECItem *subjectKeyIdentifier;
- SECItem *date; /* optional */
- SECItem *other; /* optional */
+ SECItem *date; /* optional */
+ NSSCMSOtherKeyAttribute *other; /* optional */
};
typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier;
@@ -369,7 +376,7 @@ typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey;
struct NSSCMSKeyAgreeRecipientInfoStr {
SECItem version;
NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey;
- SECItem *ukm; /* optional */
+ SECItem ukm; /* optional */
SECAlgorithmID keyEncAlg;
NSSCMSRecipientEncryptedKey **recipientEncryptedKeys;
};
@@ -382,8 +389,8 @@ typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo;
*/
struct NSSCMSKEKIdentifierStr {
SECItem keyIdentifier;
- SECItem *date; /* optional */
- SECItem *other; /* optional */
+ SECItem *date; /* optional */
+ NSSCMSOtherKeyAttribute *other; /* optional */
};
typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier;
diff --git a/nss/lib/softoken/pkcs11.c b/nss/lib/softoken/pkcs11.c
index 768c7c2..915fa7e 100644
--- a/nss/lib/softoken/pkcs11.c
+++ b/nss/lib/softoken/pkcs11.c
@@ -1088,7 +1088,7 @@ sftk_handlePublicKeyObject(SFTKSession *session, SFTKObject *object,
}
/* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
derive = (key_type == CKK_EC_EDWARDS) ? CK_FALSE : CK_TRUE; /* CK_TRUE for ECDH */
- verify = CK_TRUE; /* for ECDSA */
+ verify = CK_TRUE; /* for ECDSA and EDDSA */
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
@@ -1285,8 +1285,10 @@ sftk_handlePrivateKeyObject(SFTKSession *session, SFTKObject *object, CK_KEY_TYP
if (!sftk_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ /* for ECDSA and EDDSA. Change if the structure of any of them is modified. */
+ derive = (key_type == CKK_EC_EDWARDS) ? CK_FALSE : CK_TRUE; /* CK_TRUE for ECDH */
+ sign = CK_TRUE; /* for ECDSA and EDDSA */
encrypt = CK_FALSE;
- sign = CK_TRUE;
recover = CK_FALSE;
wrap = CK_FALSE;
break;
diff --git a/nss/lib/softoken/softkver.h b/nss/lib/softoken/softkver.h
index ae4ebbe..9538045 100644
--- a/nss/lib/softoken/softkver.h
+++ b/nss/lib/softoken/softkver.h
@@ -17,9 +17,9 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.99" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.100" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
-#define SOFTOKEN_VMINOR 99
+#define SOFTOKEN_VMINOR 100
#define SOFTOKEN_VPATCH 0
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
diff --git a/nss/lib/ssl/tls13con.c b/nss/lib/ssl/tls13con.c
index 2a3b899..87f6d5b 100644
--- a/nss/lib/ssl/tls13con.c
+++ b/nss/lib/ssl/tls13con.c
@@ -3977,12 +3977,13 @@ tls13_HandleCertificateDecode(sslSocket *ss, PRUint8 *b, PRUint32 length)
/* Decoding received certificate. */
SECItem decodedCertificate = { siBuffer, NULL, 0 };
+ if (!SECITEM_AllocItem(NULL, &decodedCertificate, decodedCertificateLen)) {
+ FATAL_ERROR(ss, SEC_ERROR_NO_MEMORY, internal_error);
+ return SECFailure;
+ }
- SECItem encodedCertAsSecItem;
- SECITEM_MakeItem(NULL, &encodedCertAsSecItem, b, compressedCertificateMessageLen);
-
+ SECItem encodedCertAsSecItem = { siBuffer, b, compressedCertificateMessageLen };
rv = certificateDecodingFunc(&encodedCertAsSecItem, &decodedCertificate, decodedCertificateLen);
- SECITEM_FreeItem(&encodedCertAsSecItem, PR_FALSE);
if (rv != SECSuccess) {
SSL_TRC(50, ("%d: TLS13[%d]: %s decoding of the certificate has failed",
diff --git a/nss/lib/util/nssutil.h b/nss/lib/util/nssutil.h
index d49a689..d9a0d6b 100644
--- a/nss/lib/util/nssutil.h
+++ b/nss/lib/util/nssutil.h
@@ -19,9 +19,9 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
-#define NSSUTIL_VERSION "3.99"
+#define NSSUTIL_VERSION "3.100"
#define NSSUTIL_VMAJOR 3
-#define NSSUTIL_VMINOR 99
+#define NSSUTIL_VMINOR 100
#define NSSUTIL_VPATCH 0
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE
diff --git a/nss/lib/util/secoid.c b/nss/lib/util/secoid.c
index 05208ee..a2dc5a6 100644
--- a/nss/lib/util/secoid.c
+++ b/nss/lib/util/secoid.c
@@ -159,6 +159,9 @@ const char __nss_util_version[] = "Version: NSS " NSSUTIL_VERSION _DEBUG_STRING;
#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04
#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03
+#define X9_63_SCHEME 0x2B, 0x81, 0x05, 0x10, 0x86, 0x48, 0x3F, 0x00
+#define SECG_SCHEME CERTICOM_OID, 0x01
+
/* for Camellia: iso(1) member-body(2) jisc(392)
* mitsubishi(200011) isl(61) security(1) algorithm(1)
*/
@@ -602,6 +605,18 @@ CONST_OID secgECsect409r1[] = { SECG_OID, 0x25 }; /* unsupported by freebl */
CONST_OID secgECsect571k1[] = { SECG_OID, 0x26 }; /* unsupported by freebl */
CONST_OID secgECsect571r1[] = { SECG_OID, 0x27 }; /* unsupported by freebl */
+/* Diffie-Hellman key agreement algorithms */
+CONST_OID dhSinglePassstdDHsha1kdfscheme[] = { X9_63_SCHEME, 0x02 };
+CONST_OID dhSinglePassstdDHsha224kdfscheme[] = { SECG_SCHEME, 0x0B, 0x00 };
+CONST_OID dhSinglePassstdDHsha256kdfscheme[] = { SECG_SCHEME, 0x0B, 0x01 };
+CONST_OID dhSinglePassstdDHsha384kdfscheme[] = { SECG_SCHEME, 0x0B, 0x02 };
+CONST_OID dhSinglePassstdDHsha512kdfscheme[] = { SECG_SCHEME, 0x0B, 0x03 };
+CONST_OID dhSinglePasscofactorDHsha1kdfscheme[] = { X9_63_SCHEME, 0x03 };
+CONST_OID dhSinglePasscofactorDHsha224kdfscheme[] = { SECG_SCHEME, 0x0E, 0x00 };
+CONST_OID dhSinglePasscofactorDHsha256kdfscheme[] = { SECG_SCHEME, 0x0E, 0x01 };
+CONST_OID dhSinglePasscofactorDHsha384kdfscheme[] = { SECG_SCHEME, 0x0E, 0x02 };
+CONST_OID dhSinglePasscofactorDHsha512kdfscheme[] = { SECG_SCHEME, 0x0E, 0x03 };
+
CONST_OID seed_CBC[] = { SEED_OID, 4 };
CONST_OID evIncorporationLocality[] = { EV_NAME_ATTRIBUTE, 1 };
@@ -1842,6 +1857,36 @@ const static SECOidData oids[SEC_OID_TOTAL] = {
OD(ed25519PublicKey, SEC_OID_ED25519_PUBLIC_KEY,
"X9.62 elliptic edwards curve public key", CKM_EC_EDWARDS_KEY_PAIR_GEN, INVALID_CERT_EXTENSION),
+ OD(dhSinglePassstdDHsha1kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Standard with SHA1 KDF", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePassstdDHsha224kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Standard with SHA224 KDF", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePassstdDHsha256kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Standard with SHA256 KDF", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePassstdDHsha384kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Standard with SHA384 KDF", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePassstdDHsha512kdfscheme, SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Standard with SHA512 KDF", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePasscofactorDHsha1kdfscheme, SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Cofactor with SHA1 KDF", CKM_ECDH1_COFACTOR_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePasscofactorDHsha224kdfscheme, SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Cofactor with SHA224 KDF", CKM_ECDH1_COFACTOR_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePasscofactorDHsha256kdfscheme, SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Cofactor with SHA256 KDF", CKM_ECDH1_COFACTOR_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePasscofactorDHsha384kdfscheme, SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Cofactor with SHA384 KDF", CKM_ECDH1_COFACTOR_DERIVE,
+ INVALID_CERT_EXTENSION),
+ OD(dhSinglePasscofactorDHsha512kdfscheme, SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME,
+ "Eliptic Curve Diffie-Hellman Single Pass Cofactor with SHA512 KDF", CKM_ECDH1_COFACTOR_DERIVE,
+ INVALID_CERT_EXTENSION),
};
/* PRIVATE EXTENDED SECOID Table
diff --git a/nss/lib/util/secoidt.h b/nss/lib/util/secoidt.h
index f2618d6..24fb880 100644
--- a/nss/lib/util/secoidt.h
+++ b/nss/lib/util/secoidt.h
@@ -517,6 +517,17 @@ typedef enum {
SEC_OID_ED25519_SIGNATURE = 373,
SEC_OID_ED25519_PUBLIC_KEY = 374,
+ SEC_OID_DHSINGLEPASS_STDDH_SHA1KDF_SCHEME = 375,
+ SEC_OID_DHSINGLEPASS_STDDH_SHA224KDF_SCHEME = 376,
+ SEC_OID_DHSINGLEPASS_STDDH_SHA256KDF_SCHEME = 377,
+ SEC_OID_DHSINGLEPASS_STDDH_SHA384KDF_SCHEME = 378,
+ SEC_OID_DHSINGLEPASS_STDDH_SHA512KDF_SCHEME = 379,
+ SEC_OID_DHSINGLEPASS_COFACTORDH_SHA1KDF_SCHEME = 380,
+ SEC_OID_DHSINGLEPASS_COFACTORDH_SHA224KDF_SCHEME = 381,
+ SEC_OID_DHSINGLEPASS_COFACTORDH_SHA256KDF_SCHEME = 382,
+ SEC_OID_DHSINGLEPASS_COFACTORDH_SHA384KDF_SCHEME = 383,
+ SEC_OID_DHSINGLEPASS_COFACTORDH_SHA512KDF_SCHEME = 384,
+
SEC_OID_TOTAL
} SECOidTag;
diff --git a/nss/tests/cert/cert.sh b/nss/tests/cert/cert.sh
index d7ec101..67951f6 100755
--- a/nss/tests/cert/cert.sh
+++ b/nss/tests/cert/cert.sh
@@ -2607,8 +2607,40 @@ cert_cleanup()
. common/cleanup.sh
}
+CERTCACHE=${TESTDIR}/${HOST}.${TEST_MODE}.cert.cache.tar.gz
+
+cert_make_cache()
+{
+ if [ -n "${NSS_USE_CERT_CACHE}" ] ; then
+ pushd ${HOSTDIR}
+ tar czf "${CERTCACHE}" .
+ popd
+ fi
+}
+
+cert_use_cache()
+{
+ if [ -n "${NSS_USE_CERT_CACHE}" ] ; then
+ pushd ${HOSTDIR}
+ if [ -r "${CERTCACHE}" ]; then
+ tar xzf "${CERTCACHE}"
+ return 1;
+ fi
+ popd
+ fi
+
+ rm "${CERTCACHE}"
+ return 0;
+}
+
################## main #################################################
+cert_use_cache
+USING_CACHE=$?
+if [[ $USING_CACHE -eq 1 ]]; then
+ return 0;
+fi
+
cert_init
cert_all_CA
cert_test_implicit_db_init
@@ -2648,3 +2680,4 @@ fi
cert_iopr_setup
cert_cleanup
+cert_make_cache
diff --git a/nss/tests/smime/interop-openssl/Fran-ec.p12 b/nss/tests/smime/interop-openssl/Fran-ec.p12
new file mode 100644
index 0000000..75c6922
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/Fran-ec.p12
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/Fran.p12 b/nss/tests/smime/interop-openssl/Fran.p12
new file mode 100644
index 0000000..65b1d4e
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/Fran.p12
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env
new file mode 100644
index 0000000..e3de11b
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env
new file mode 100644
index 0000000..6faabec
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env
new file mode 100644
index 0000000..4ec30c6
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env
new file mode 100644
index 0000000..113caa8
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env
new file mode 100644
index 0000000..2d797d0
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env
new file mode 100644
index 0000000..0c35d4d
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-label_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-label_ossl.env
new file mode 100644
index 0000000..0871ccf
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-label_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-sha256mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-sha256mgf_ossl.env
new file mode 100644
index 0000000..17b1a17
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-sha256mgf_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env
new file mode 100644
index 0000000..3fd8bd0
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf-label_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf-label_ossl.env
new file mode 100644
index 0000000..c92f3c5
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf-label_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env
new file mode 100644
index 0000000..875d4c2
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env
new file mode 100644
index 0000000..07d4743
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env
new file mode 100644
index 0000000..61e80d3
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env
new file mode 100644
index 0000000..32120cf
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env
new file mode 100644
index 0000000..ebc42c2
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep_ossl-sha256hash-sha256mgf-label.env b/nss/tests/smime/interop-openssl/fran-oaep_ossl-sha256hash-sha256mgf-label.env
new file mode 100644
index 0000000..03f219c
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep_ossl-sha256hash-sha256mgf-label.env
Binary files differ
diff --git a/nss/tests/smime/interop-openssl/fran-oaep_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep_ossl.env
new file mode 100644
index 0000000..87a1237
--- /dev/null
+++ b/nss/tests/smime/interop-openssl/fran-oaep_ossl.env
Binary files differ
diff --git a/nss/tests/smime/smime.sh b/nss/tests/smime/smime.sh
index 4cee298..940d7ad 100755
--- a/nss/tests/smime/smime.sh
+++ b/nss/tests/smime/smime.sh
@@ -76,6 +76,8 @@ smime_init()
cp ${QADIR}/smime/alice.txt ${SMIMEDIR}
mkdir tb
+ cp ${QADIR}/smime/interop-openssl/*.p12 ${SMIMEDIR}/tb
+ cp ${QADIR}/smime/interop-openssl/*.env ${SMIMEDIR}
make_multipart "------------ms030903020902020502030404"
multipart_start="$mp_start"
@@ -481,6 +483,134 @@ smime_p7()
done
}
+smime_enveloped_openssl_interop() {
+ echo "$SCRIPTNAME: OpenSSL interoperability --------------------------------"
+
+ ${BINDIR}/pk12util -d ${P_R_ALICEDIR} -i tb/Fran.p12 -W nss -K nss
+ ${BINDIR}/pk12util -d ${P_R_ALICEDIR} -i tb/Fran-ec.p12 -W nss -K nss
+
+ echo "This is a test message to Fran." > fran.txt
+
+ echo "cmsutil -D -i fran-oaep_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data1"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data1
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data1
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha256hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data2"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha256hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data2
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data2
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha384hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data3"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha384hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data3
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data3
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha512hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data4"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha512hash_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data4
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data4
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha256mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data5"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha256mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data5
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data5
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha384mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data6"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha384mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data6
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data6
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha512mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data7"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha512mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data7
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data7
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data8"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data8
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data8
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha256hash-sha256mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data9"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha256hash-sha256mgf_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data9
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data9
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha256hash-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data10"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha256hash-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data10
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data10
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep-sha256mgf-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data11"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep-sha256mgf-label_ossl.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data11
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data11
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-oaep_ossl-sha256hash-sha256mgf-label.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data12"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-oaep_ossl-sha256hash-sha256mgf-label.env -d ${P_R_ALICEDIR} -p nss -o fran-oaep.data12
+ html_msg $? 0 "Decode OpenSSL OAEP Enveloped Data Fran" "."
+
+ diff fran.txt fran-oaep.data12
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-ec_ossl-aes128-sha1.env -d ${P_R_ALICEDIR} -p nss -o fran.data1"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-ec_ossl-aes128-sha1.env -d ${P_R_ALICEDIR} -p nss -o fran.data1
+ html_msg $? 0 "Decode OpenSSL Enveloped Data Fran (ECDH, AES128 key wrap, SHA-1 KDF)" "."
+
+ diff fran.txt fran.data1
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-ec_ossl-aes128-sha224.env -d ${P_R_ALICEDIR} -p nss -o fran.data2"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-ec_ossl-aes128-sha224.env -d ${P_R_ALICEDIR} -p nss -o fran.data2
+ html_msg $? 0 "Decode OpenSSL Enveloped Data Fran (ECDH, AES128 key wrap, SHA-224 KDF)" "."
+
+ diff fran.txt fran.data2
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-ec_ossl-aes128-sha256.env -d ${P_R_ALICEDIR} -p nss -o fran.data3"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-ec_ossl-aes128-sha256.env -d ${P_R_ALICEDIR} -p nss -o fran.data3
+ html_msg $? 0 "Decode OpenSSL Enveloped Data Fran (ECDH, AES128 key wrap, SHA-256 KDF)" "."
+
+ diff fran.txt fran.data3
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-ec_ossl-aes192-sha384.env -d ${P_R_ALICEDIR} -p nss -o fran.data4"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-ec_ossl-aes192-sha384.env -d ${P_R_ALICEDIR} -p nss -o fran.data4
+ html_msg $? 0 "Decode OpenSSL Enveloped Data Fran (ECDH, AES192 key wrap, SHA-384 KDF)" "."
+
+ diff fran.txt fran.data4
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+
+ echo "cmsutil -D -i fran-ec_ossl-aes256-sha512.env -d ${P_R_ALICEDIR} -p nss -o fran.data5"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i fran-ec_ossl-aes256-sha512.env -d ${P_R_ALICEDIR} -p nss -o fran.data5
+ html_msg $? 0 "Decode OpenSSL Enveloped Data Fran (ECDH, AES256 key wrap, SHA-512 KDF)" "."
+
+ diff fran.txt fran.data5
+ html_msg $? 0 "Compare Decoded with OpenSSL enveloped" "."
+}
+
############################## smime_main ##############################
# local shell function to test basic signed and enveloped messages
# from 1 --> 2"
@@ -525,12 +655,26 @@ smime_main()
diff alice.txt alice.data1
html_msg $? 0 "Compare Decoded Enveloped Data and Original" "."
+ echo "$SCRIPTNAME: Enveloped Data Tests (ECDH) ------------------------------"
+ echo "cmsutil -E -r bob-ec@example.com -i alice.txt -d ${P_R_ALICEDIR} -p nss \\"
+ echo " -o alice-ec.env"
+ ${PROFTOOL} ${BINDIR}/cmsutil -E -r bob-ec@example.com -i alice.txt -d ${P_R_ALICEDIR} -p nss -o alice-ec.env
+ html_msg $? 0 "Create Enveloped Data with Alice (ECDH)" "."
+
+ echo "cmsutil -D -i alice-ec.env -d ${P_R_BOBDIR} -p nss -o alice.data1"
+ ${PROFTOOL} ${BINDIR}/cmsutil -D -i alice-ec.env -d ${P_R_BOBDIR} -p nss -o alice-ec.data1
+ html_msg $? 0 "Decode Enveloped Data Alice (ECDH)" "."
+
+ echo "diff alice.txt alice-ec.data1"
+ diff alice.txt alice-ec.data1
+ html_msg $? 0 "Compare Decoded Enveloped Data and Original (ECDH)" "."
+
# multiple recip
echo "$SCRIPTNAME: Testing multiple recipients ------------------------------"
echo "cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \\"
echo " -r bob@example.com,dave@example.com"
${PROFTOOL} ${BINDIR}/cmsutil -E -i alice.txt -d ${P_R_ALICEDIR} -o alicecc.env \
- -r bob@example.com,dave@example.com
+ -r bob@example.com,dave-ec@example.com
ret=$?
html_msg $ret 0 "Create Multiple Recipients Enveloped Data Alice" "."
if [ $ret != 0 ] ; then
@@ -554,7 +698,7 @@ smime_main()
echo "cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3"
${PROFTOOL} ${BINDIR}/cmsutil -D -i alicecc.env -d ${P_R_DAVEDIR} -p nss -o alice.data3
- html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Dave" "."
+ html_msg $? 0 "Decode Multiple Recipients Enveloped Data Alice by Dave (ECDH)" "."
echo "cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4"
${PROFTOOL} ${BINDIR}/cmsutil -D -i aliceve.env -d ${P_R_EVEDIR} -p nss -o alice.data4
@@ -569,6 +713,8 @@ smime_main()
diff alice.txt alice.data4
html_msg $? 0 "Compare Decoded with Multiple Email cert" "."
+ smime_enveloped_openssl_interop
+
echo "$SCRIPTNAME: Sending CERTS-ONLY Message ------------------------------"
echo "cmsutil -O -r \"Alice,bob@example.com,dave@example.com\" \\"
echo " -d ${P_R_ALICEDIR} > co.der"