diff --git a/build/moz.configure/nss.configure b/build/moz.configure/nss.configure index 2765a6502d37..33ff47b3b118 100644 --- a/build/moz.configure/nss.configure +++ b/build/moz.configure/nss.configure @@ -9,7 +9,7 @@ system_lib_option("--with-system-nss", help="Use system NSS") imply_option("--with-system-nspr", True, when="--with-system-nss") nss_pkg = pkg_check_modules( - "NSS", "nss >= 3.99", when="--with-system-nss", config=False + "NSS", "nss >= 3.100", when="--with-system-nss", config=False ) set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss") diff --git a/security/nss/TAG-INFO b/security/nss/TAG-INFO index 13e8ce154772..408c7f0e47de 100644 --- a/security/nss/TAG-INFO +++ b/security/nss/TAG-INFO @@ -1 +1 @@ -NSS_3_99_RTM \ No newline at end of file +NSS_3_100_BETA1 \ No newline at end of file diff --git a/security/nss/automation/abi-check/expected-report-libnss3.so.txt b/security/nss/automation/abi-check/expected-report-libnss3.so.txt index 582afe387fa1..97f1a7cdd8e8 100644 --- a/security/nss/automation/abi-check/expected-report-libnss3.so.txt +++ b/security/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/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt index ed076df3002c..f0d77ef36925 100644 --- a/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt +++ b/security/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/security/nss/automation/abi-check/expected-report-libsmime3.so.txt b/security/nss/automation/abi-check/expected-report-libsmime3.so.txt index 69cd2ae3a9da..a42f62c39ade 100644 --- a/security/nss/automation/abi-check/expected-report-libsmime3.so.txt +++ b/security/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,36 +10,105 @@ 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/security/nss/automation/abi-check/previous-nss-release b/security/nss/automation/abi-check/previous-nss-release index 0dea1b7b74d9..335e901dad75 100644 --- a/security/nss/automation/abi-check/previous-nss-release +++ b/security/nss/automation/abi-check/previous-nss-release @@ -1 +1 @@ -NSS_3_98_BRANCH +NSS_3_99_BRANCH diff --git a/security/nss/build.sh b/security/nss/build.sh index ae8eeee8b0b2..73c6d77df376 100755 --- a/security/nss/build.sh +++ b/security/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/security/nss/cmd/certutil/certext.c b/security/nss/cmd/certutil/certext.c index 501608c850cb..0035d8c7fbdd 100644 --- a/security/nss/cmd/certutil/certext.c +++ b/security/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/security/nss/coreconf/config.gypi b/security/nss/coreconf/config.gypi index 13f857cacf5e..baf4256a8781 100644 --- a/security/nss/coreconf/config.gypi +++ b/security/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/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep index 590d1bfaeee3..5182f75552c8 100644 --- a/security/nss/coreconf/coreconf.dep +++ b/security/nss/coreconf/coreconf.dep @@ -10,4 +10,3 @@ */ #error "Do not include this header file." - diff --git a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc b/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc index 12adcc5de053..854460508d47 100644 --- a/security/nss/gtests/nss_bogo_shim/nss_bogo_shim.cc +++ b/security/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/security/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc b/security/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc index 01a02502c17d..44c6a7e142b0 100644 --- a/security/nss/gtests/ssl_gtest/ssl_certificate_compression_unittest.cc +++ b/security/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(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/security/nss/lib/base/base.h b/security/nss/lib/base/base.h index 140b5556aa4f..41ab86f6b0eb 100644 --- a/security/nss/lib/base/base.h +++ b/security/nss/lib/base/base.h @@ -1034,7 +1034,7 @@ extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED; * * Return value: * PR_SUCCESS - * PR_FAILURE + * PR_FAILRUE */ #ifdef DEBUG diff --git a/security/nss/lib/base/tracker.c b/security/nss/lib/base/tracker.c index eba95c1c8f8e..850add7c4bb8 100644 --- a/security/nss/lib/base/tracker.c +++ b/security/nss/lib/base/tracker.c @@ -338,7 +338,7 @@ nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer) * * Return value: * PR_SUCCESS - * PR_FAILURE + * PR_FAILRUE */ NSS_IMPLEMENT PRStatus diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h index f3608b581395..0326b93d5850 100644 --- a/security/nss/lib/nss/nss.h +++ b/security/nss/lib/nss/nss.h @@ -22,12 +22,12 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define NSS_VERSION "3.99" _NSS_CUSTOMIZED +#define NSS_VERSION "3.100" _NSS_CUSTOMIZED " Beta" #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 +#define NSS_BETA PR_TRUE #ifndef RC_INVOKED diff --git a/security/nss/lib/smime/cmsasn1.c b/security/nss/lib/smime/cmsasn1.c index 8ba95d044e69..47580069983d 100644 --- a/security/nss/lib/smime/cmsasn1.c +++ b/security/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/security/nss/lib/smime/cmslocal.h b/security/nss/lib/smime/cmslocal.h index ef7d50028073..3bf02d1cfaf5 100644 --- a/security/nss/lib/smime/cmslocal.h +++ b/security/nss/lib/smime/cmslocal.h @@ -166,13 +166,24 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid extern SECStatus NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, - SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg, + SECItem *encKey, SECItem *ukm, SECAlgorithmID *keyEncAlg, SECItem *originatorPubKey); extern PK11SymKey * NSS_CMSUtil_DecryptSymKey_ESDH(SECKEYPrivateKey *privkey, SECItem *encKey, SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, void *pwfn_arg); +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/security/nss/lib/smime/cmspubkey.c b/security/nss/lib/smime/cmspubkey.c index 8f18f60de1c7..be5a66b50a3e 100644 --- a/security/nss/lib/smime/cmspubkey.c +++ b/security/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,11 +108,410 @@ NSS_CMSUtil_DecryptSymKey_RSA(SECKEYPrivateKey *privkey, SECItem *encKey, SECOid return PK11_PubUnwrapSymKey(privkey, encKey, target, CKA_DECRYPT, 0); } +/* ====== 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 */ +}; + +SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) +SEC_ASN1_MKSUB(SEC_OctetStringTemplate) + +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_ESECDH(PLArenaPool *poolp, CERTCertificate *cert, + PK11SymKey *bulkkey, SECItem *encKey, + PRBool genUkm, SECItem *ukm, + SECAlgorithmID *keyEncAlg, SECItem *pubKey, + void *wincx) +{ + SECOidTag certalgtag; /* the certificate's encryption algorithm */ + SECStatus rv; + SECStatus err; + 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_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; + + ourPrivKey = SECKEY_CreateECPrivateKey(&publickey->u.ec.DEREncodedParams, + &ourPubKey, wincx); + if (!ourPrivKey || !ourPubKey) { + goto loser; + } + + rv = SECITEM_CopyItem(poolp, pubKey, &ourPubKey->u.ec.publicValue); + if (rv != SECSuccess) { + goto loser; + } + + /* 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; + + 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; + + 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 RFC5753 which we use + * to wrap the bulk encryption key. */ + 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; + + /* allocate space for the encrypted CEK (bulk key) */ + /* 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) { + PK11_FreeSymKey(kek); + goto loser; + } + + err = PK11_WrapSymKey(keyWrapMech, NULL, kek, bulkkey, encKey); + + PK11_FreeSymKey(kek); /* we do not need the KEK anymore */ + if (err != SECSuccess) { + goto loser; + } + + 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, keyEncAlgtag, keyEncAlg_params); + if (rv != SECSuccess) { + goto loser; + } + + return SECSuccess; + +loser: + if (publickey) { + SECKEY_DestroyPublicKey(publickey); + } + if (ourPubKey) { + SECKEY_DestroyPublicKey(ourPubKey); + } + if (ourPrivKey) { + SECKEY_DestroyPrivateKey(ourPrivKey); + } + 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_ECDH(SECKEYPrivateKey *privkey, SECItem *encKey, + SECAlgorithmID *keyEncAlg, SECOidTag bulkalgtag, + SECItem *ukm, NSSCMSOriginatorIdentifierOrKey *oiok, + void *wincx) +{ + 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; + } + + rv = SEC_ASN1DecodeItem(NULL, &keyWrapAlg, + SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), &(keyEncAlg->parameters)); + if (rv != SECSuccess) { + goto loser; + } + + 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: + SECOID_DestroyAlgorithmID(&keyWrapAlg, PR_FALSE); + return bulkkey; +} + /* ====== ESDH (Ephemeral-Static Diffie-Hellman) ==================================== */ SECStatus NSS_CMSUtil_EncryptSymKey_ESDH(PLArenaPool *poolp, CERTCertificate *cert, PK11SymKey *key, - SECItem *encKey, SECItem **ukm, SECAlgorithmID *keyEncAlg, + SECItem *encKey, SECItem *ukm, SECAlgorithmID *keyEncAlg, SECItem *pubKey) { #if 0 /* not yet done */ diff --git a/security/nss/lib/smime/cmsrecinfo.c b/security/nss/lib/smime/cmsrecinfo.c index 6cf2c68c31b9..2218c4d5f1de 100644 --- a/security/nss/lib/smime/cmsrecinfo.c +++ b/security/nss/lib/smime/cmsrecinfo.c @@ -158,6 +158,7 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, } 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 +167,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 @@ -275,6 +272,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 +454,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; @@ -499,6 +498,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 +510,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 +518,35 @@ 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_X942_DIFFIE_HELMAN_KEY: + rv = NSS_CMSUtil_EncryptSymKey_ESDH(poolp, cert, bulkkey, + &rek->encKey, + &ri->ri.keyAgreeRecipientInfo.ukm, + &ri->ri.keyAgreeRecipientInfo.keyEncAlg, + &oiok->id.originatorPublicKey.publicKey); + break; + 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 +566,10 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex, { PK11SymKey *bulkkey = NULL; SECOidTag encalgtag; - SECItem *enckey; + SECItem *enckey, *ukm; + NSSCMSOriginatorIdentifierOrKey *oiok; int error; + void *wincx = NULL; ri->cert = CERT_DupCertificate(cert); /* mark the recipientInfo so we can find it later */ @@ -567,7 +592,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_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; + case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* Diffie-Helman key exchange */ /* XXX not yet implemented */ diff --git a/security/nss/lib/smime/cmst.h b/security/nss/lib/smime/cmst.h index 3d888bc04177..1144f5571da8 100644 --- a/security/nss/lib/smime/cmst.h +++ b/security/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/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 768c7c26696c..915fa7e952c6 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/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/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h index ae4ebbe017fe..1471245665ea 100644 --- a/security/nss/lib/softoken/softkver.h +++ b/security/nss/lib/softoken/softkver.h @@ -17,11 +17,11 @@ * The format of the version string should be * ".[.[.]][ ][ ]" */ -#define SOFTOKEN_VERSION "3.99" SOFTOKEN_ECC_STRING +#define SOFTOKEN_VERSION "3.100" SOFTOKEN_ECC_STRING " Beta" #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 +#define SOFTOKEN_BETA PR_TRUE #endif /* _SOFTKVER_H_ */ diff --git a/security/nss/lib/ssl/tls13con.c b/security/nss/lib/ssl/tls13con.c index 2a3b8994a999..87f6d5bd7eea 100644 --- a/security/nss/lib/ssl/tls13con.c +++ b/security/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/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h index d49a6890c1e6..806506d1228a 100644 --- a/security/nss/lib/util/nssutil.h +++ b/security/nss/lib/util/nssutil.h @@ -19,12 +19,12 @@ * The format of the version string should be * ".[.[.]][ ]" */ -#define NSSUTIL_VERSION "3.99" +#define NSSUTIL_VERSION "3.100 Beta" #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 +#define NSSUTIL_BETA PR_TRUE SEC_BEGIN_PROTOS diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c index 05208eeffa77..a2dc5a6a6d23 100644 --- a/security/nss/lib/util/secoid.c +++ b/security/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/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h index f2618d62cb98..24fb880f78b6 100644 --- a/security/nss/lib/util/secoidt.h +++ b/security/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/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh index d7ec101fa775..67951f6e432e 100755 --- a/security/nss/tests/cert/cert.sh +++ b/security/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/security/nss/tests/smime/interop-openssl/Fran-ec.p12 b/security/nss/tests/smime/interop-openssl/Fran-ec.p12 new file mode 100644 index 000000000000..75c69220f927 Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/Fran-ec.p12 differ diff --git a/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env new file mode 100644 index 000000000000..e3de11b92678 Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha1.env differ diff --git a/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env new file mode 100644 index 000000000000..6faabecfb0cb Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha224.env differ diff --git a/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env new file mode 100644 index 000000000000..4ec30c677d2d Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes128-sha256.env differ diff --git a/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env new file mode 100644 index 000000000000..113caa87a404 Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes192-sha384.env differ diff --git a/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env new file mode 100644 index 000000000000..2d797d033064 Binary files /dev/null and b/security/nss/tests/smime/interop-openssl/fran-ec_ossl-aes256-sha512.env differ diff --git a/security/nss/tests/smime/smime.sh b/security/nss/tests/smime/smime.sh index 4cee298182af..551add3dbc1e 100755 --- a/security/nss/tests/smime/smime.sh +++ b/security/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,49 @@ smime_p7() done } +smime_enveloped_openssl_interop() { + echo "$SCRIPTNAME: OpenSSL interoperability --------------------------------" + + ${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-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 +570,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 +613,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 +628,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"