diff options
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, ¶ms, + 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 Binary files differnew file mode 100644 index 0000000..75c6922 --- /dev/null +++ b/nss/tests/smime/interop-openssl/Fran-ec.p12 diff --git a/nss/tests/smime/interop-openssl/Fran.p12 b/nss/tests/smime/interop-openssl/Fran.p12 Binary files differnew file mode 100644 index 0000000..65b1d4e --- /dev/null +++ b/nss/tests/smime/interop-openssl/Fran.p12 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 Binary files differnew file mode 100644 index 0000000..e3de11b --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env 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 Binary files differnew file mode 100644 index 0000000..6faabec --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env 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 Binary files differnew file mode 100644 index 0000000..4ec30c6 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env 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 Binary files differnew file mode 100644 index 0000000..113caa8 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env 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 Binary files differnew file mode 100644 index 0000000..2d797d0 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env Binary files differnew file mode 100644 index 0000000..0c35d4d --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-label_ossl.env 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 Binary files differnew file mode 100644 index 0000000..0871ccf --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-label_ossl.env 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 Binary files differnew file mode 100644 index 0000000..17b1a17 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash-sha256mgf_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env Binary files differnew file mode 100644 index 0000000..3fd8bd0 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256hash_ossl.env 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 Binary files differnew file mode 100644 index 0000000..c92f3c5 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf-label_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env Binary files differnew file mode 100644 index 0000000..875d4c2 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha256mgf_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env Binary files differnew file mode 100644 index 0000000..07d4743 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha384hash_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env Binary files differnew file mode 100644 index 0000000..61e80d3 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha384mgf_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env Binary files differnew file mode 100644 index 0000000..32120cf --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha512hash_ossl.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env Binary files differnew file mode 100644 index 0000000..ebc42c2 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep-sha512mgf_ossl.env 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 Binary files differnew file mode 100644 index 0000000..03f219c --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep_ossl-sha256hash-sha256mgf-label.env diff --git a/nss/tests/smime/interop-openssl/fran-oaep_ossl.env b/nss/tests/smime/interop-openssl/fran-oaep_ossl.env Binary files differnew file mode 100644 index 0000000..87a1237 --- /dev/null +++ b/nss/tests/smime/interop-openssl/fran-oaep_ossl.env 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" |