diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-24 14:53:22 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-24 14:53:22 +0000 |
commit | 478df839eb3260d4b2602c7e6a8f5d6294213eef (patch) | |
tree | 05b56a1b1aebc91c6669e261c4336079cfd57e1c | |
parent | dd2608624a1674faf2530e291dd3441bb83e04f7 (diff) | |
download | chromium_src-478df839eb3260d4b2602c7e6a8f5d6294213eef.zip chromium_src-478df839eb3260d4b2602c7e6a8f5d6294213eef.tar.gz chromium_src-478df839eb3260d4b2602c7e6a8f5d6294213eef.tar.bz2 |
Revert "nss: revert encrypted and origin bound certificates support."
Screwed up git branches in that change.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138795 0039d316-1c4b-4281-b951-d872f2087c98
27 files changed, 956 insertions, 271 deletions
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 2602c11..127a2a1 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc @@ -1878,38 +1878,6 @@ TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) { // we should also test that preferences are preserved. } -#if defined(OS_POSIX) -TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) { - FilePath source_data_dir = data_dir_. - AppendASCII("unpacked"). - AppendASCII("symlinks_allowed"); - - // Paths to test data files. - FilePath source_manifest = source_data_dir.AppendASCII("manifest.json"); - ASSERT_TRUE(file_util::PathExists(source_manifest)); - FilePath source_icon = source_data_dir.AppendASCII("icon.png"); - ASSERT_TRUE(file_util::PathExists(source_icon)); - - // Set up the temporary extension directory. - ScopedTempDir temp; - ASSERT_TRUE(temp.CreateUniqueTempDir()); - FilePath extension_path = temp.path(); - FilePath manifest = extension_path.Append(Extension::kManifestFilename); - FilePath icon_symlink = extension_path.AppendASCII("icon.png"); - file_util::CopyFile(source_manifest, manifest); - file_util::CreateSymbolicLink(source_icon, icon_symlink); - - // Load extension. - InitializeEmptyExtensionService(); - extensions::UnpackedInstaller::Create(service_)->Load(extension_path); - loop_.RunAllPending(); - - EXPECT_TRUE(GetErrors().empty()); - ASSERT_EQ(1u, loaded_.size()); - EXPECT_EQ(1u, service_->extensions()->size()); -} -#endif - TEST_F(ExtensionServiceTest, InstallLocalizedTheme) { InitializeEmptyExtensionService(); FilePath theme_path = data_dir_ diff --git a/chrome/browser/extensions/unpacked_installer.cc b/chrome/browser/extensions/unpacked_installer.cc index 3bfb522..39e5513 100644 --- a/chrome/browser/extensions/unpacked_installer.cc +++ b/chrome/browser/extensions/unpacked_installer.cc @@ -132,7 +132,7 @@ void UnpackedInstaller::LoadFromCommandLine(const FilePath& path_in) { scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( extension_path_, Extension::LOAD, - flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, + flags, &error)); if (!extension) { @@ -195,7 +195,7 @@ void UnpackedInstaller::LoadWithFileAccess(bool allow_file_access) { scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( extension_path_, Extension::LOAD, - flags | Extension::FOLLOW_SYMLINKS_ANYWHERE, + flags, &error)); if (!extension) { diff --git a/chrome/test/data/extensions/unpacked/symlinks_allowed/icon.png b/chrome/test/data/extensions/unpacked/symlinks_allowed/icon.png Binary files differdeleted file mode 100644 index 84c4be3..0000000 --- a/chrome/test/data/extensions/unpacked/symlinks_allowed/icon.png +++ /dev/null diff --git a/chrome/test/data/extensions/unpacked/symlinks_allowed/manifest.json b/chrome/test/data/extensions/unpacked/symlinks_allowed/manifest.json deleted file mode 100644 index 7210509..0000000 --- a/chrome/test/data/extensions/unpacked/symlinks_allowed/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "Test for symlinked content in unpacked extension", - "description": "This is an extension used to test that file symlinks are allowed within unpacked extensions", - "version": "1", - "manifest_version": 2, - "browser_action": { - "default_icon": "icon.png" - } -} diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc index 6d4e050..e5dad26 100644 --- a/content/browser/fileapi/fileapi_message_filter.cc +++ b/content/browser/fileapi/fileapi_message_filter.cc @@ -172,6 +172,11 @@ void FileAPIMessageFilter::UnregisterOperation(int request_id) { FileAPIMessageFilter::~FileAPIMessageFilter() {} +void FileAPIMessageFilter::BadMessageReceived() { + content::RecordAction(UserMetricsAction("BadMessageTerminate_FAMF")); + BrowserMessageFilter::BadMessageReceived(); +} + void FileAPIMessageFilter::OnOpen( int request_id, const GURL& origin_url, fileapi::FileSystemType type, int64 requested_size, bool create) { @@ -463,12 +468,20 @@ void FileAPIMessageFilter::OnAppendBlobDataItem( OnRemoveBlob(url); return; } + if (item.length == 0) { + BadMessageReceived(); + return; + } blob_storage_context_->controller()->AppendBlobDataItem(url, item); } void FileAPIMessageFilter::OnAppendSharedMemory( const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) { DCHECK(base::SharedMemory::IsHandleValid(handle)); + if (!buffer_size) { + BadMessageReceived(); + return; + } #if defined(OS_WIN) base::SharedMemory shared_memory(handle, true, peer_handle()); #else @@ -693,3 +706,4 @@ FileSystemOperationInterface* FileAPIMessageFilter::GetNewOperation( operations_.AddWithID(operation, request_id); return operation; } + diff --git a/content/browser/fileapi/fileapi_message_filter.h b/content/browser/fileapi/fileapi_message_filter.h index c6d94ed9..88b8197 100644 --- a/content/browser/fileapi/fileapi_message_filter.h +++ b/content/browser/fileapi/fileapi_message_filter.h @@ -68,6 +68,8 @@ class FileAPIMessageFilter : public content::BrowserMessageFilter { protected: virtual ~FileAPIMessageFilter(); + virtual void BadMessageReceived() OVERRIDE; + private: void OnOpen(int request_id, const GURL& origin_url, diff --git a/content/common/fileapi/webblobregistry_impl.cc b/content/common/fileapi/webblobregistry_impl.cc index 924e919..9a80fb9 100644 --- a/content/common/fileapi/webblobregistry_impl.cc +++ b/content/common/fileapi/webblobregistry_impl.cc @@ -39,6 +39,8 @@ void WebBlobRegistryImpl::registerBlobURL( case WebBlobData::Item::TypeData: { // WebBlobData does not allow partial data items. DCHECK(!data_item.offset && data_item.length == -1); + if (data_item.data.size() == 0) + break; if (data_item.data.size() < kLargeThresholdBytes) { item.SetToData(data_item.data.data(), data_item.data.size()); child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item)); @@ -64,12 +66,14 @@ void WebBlobRegistryImpl::registerBlobURL( break; } case WebBlobData::Item::TypeFile: - item.SetToFile( - webkit_glue::WebStringToFilePath(data_item.filePath), - static_cast<uint64>(data_item.offset), - static_cast<uint64>(data_item.length), - base::Time::FromDoubleT(data_item.expectedModificationTime)); - child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item)); + if (data_item.length) { + item.SetToFile( + webkit_glue::WebStringToFilePath(data_item.filePath), + static_cast<uint64>(data_item.offset), + static_cast<uint64>(data_item.length), + base::Time::FromDoubleT(data_item.expectedModificationTime)); + child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item)); + } break; case WebBlobData::Item::TypeBlob: if (data_item.length) { @@ -77,8 +81,8 @@ void WebBlobRegistryImpl::registerBlobURL( data_item.blobURL, static_cast<uint64>(data_item.offset), static_cast<uint64>(data_item.length)); + child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item)); } - child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item)); break; default: NOTREACHED(); diff --git a/net/base/transport_security_state.cc b/net/base/transport_security_state.cc index 034182b..9e23cc8 100644 --- a/net/base/transport_security_state.cc +++ b/net/base/transport_security_state.cc @@ -564,8 +564,6 @@ enum SecondLevelDomainName { DOMAIN_AKAMAIHD_NET, - DOMAIN_TOR2WEB_ORG, - // Boundary value for UMA_HISTOGRAM_ENUMERATION: DOMAIN_NUM_EVENTS }; diff --git a/net/base/transport_security_state_static.certs b/net/base/transport_security_state_static.certs index 20a4901..0857bfb 100644 --- a/net/base/transport_security_state_static.certs +++ b/net/base/transport_security_state_static.certs @@ -1105,59 +1105,3 @@ GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ -----END CERTIFICATE----- - -Tor2web ------BEGIN CERTIFICATE----- -MIIEgjCCA2qgAwIBAgISESHiIwbyj8tbXjvCF3lADzOxMA0GCSqGSIb3DQEBBQUA -MC4xETAPBgNVBAoTCEFscGhhU1NMMRkwFwYDVQQDExBBbHBoYVNTTCBDQSAtIEcy -MB4XDTExMTIwNTEyMzYzMVoXDTE2MTIwNTA0NTk1OFowSDELMAkGA1UEBhMCREUx -ITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEWMBQGA1UEAxQNKi50 -b3Iyd2ViLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJZ/olAy -7o+W0soGoxD5xWXGVKa3cQdv/daqwDyFhGINhVgsm3GS3Oo2XLAYvyvlUFceuy2v -fRecb431lh7xtLhPpr5nZL/T0cjUxffstxSt5HI5BQ5Q/TFLA4iJQDzJgiNld0DJ -RYd8gGADwh5cVBjvAtRouUbFw75b1/4hR3kJnQsHutvglLjWHmZtf/ZoZ39CbR1a -LBJpEPoWkVqJ9LrvgA+aJ1wmi+oKLfSYQkDEn30DBeVxBZBp6tRc93eGqK1skzpG -2Sof9cmlRNIXp8plYBvtsV3LKrFlBXvQRr+hhpjrqGNib02ynyJdRij7tOCLHfqW -UitjVQVOWoGs49MCAwEAAaOCAX4wggF6MA4GA1UdDwEB/wQEAwIFoDBNBgNVHSAE -RjBEMEIGCisGAQQBoDIBCgowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xv -YmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wJQYDVR0RBB4wHIINKi50b3Iyd2ViLm9y -Z4ILdG9yMndlYi5vcmcwCQYDVR0TBAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYI -KwYBBQUHAwIwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDIuYWxwaGFzc2wu -Y29tL2dzL2dzYWxwaGFnMi5jcmwwTAYIKwYBBQUHAQEEQDA+MDwGCCsGAQUFBzAC -hjBodHRwOi8vc2VjdXJlMi5hbHBoYXNzbC5jb20vY2FjZXJ0L2dzYWxwaGFnMi5j -cnQwHQYDVR0OBBYEFLE3Bo2XTl90LORxYwgr2pPD06tSMB8GA1UdIwQYMBaAFBTq -GVXwDg0yxh90M7eOZhpMEjEeMA0GCSqGSIb3DQEBBQUAA4IBAQAyOUFr9R7EKzPP -B8UsWT5ckA/TNlOqbdo6fvqshQfH/FHUQja28IbYcpBiC2XsMov+r7WNiH3lh1CF -WKT1SwfO6a0I/58CL36pL/asWv/onlDYgAsCwr1j7qcSiROZlpLD+tehiCE70afa -+3VlyoGsbKVZ2A7MrXnxIaYhmhe4Y+238PwyBT74fpBvwoFIcbccwWEST8J2y2YW -4+SWm4pJtcJxJH/uJ8qzvZLwjzcgFKQbBLVtl+SRAblFSj64YuO9Xu97+nta1HuL -fmLvlwIO/yvONapjePASH6prPdmWvj3Clqz381mkU1pLpxTgHQqeoP87DYi8z084 -+maO9AY4 ------END CERTIFICATE----- - -AlphaSSL_G2 ------BEGIN CERTIFICATE----- -MIIELzCCAxegAwIBAgILBAAAAAABL07hNwIwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw -MDBaFw0yMjA0MTMxMDAwMDBaMC4xETAPBgNVBAoTCEFscGhhU1NMMRkwFwYDVQQD -ExBBbHBoYVNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAw/BliN8b3caChy/JC7pUxmM/RnWsSxQfmHKLHBD/CalSbi9l32WEP1+Bstjx -T9fwWrvJr9Ax3SZGKpme2KmjtrgHxMlx95WE79LqH1Sg5b7kQSFWMRBkfR5jjpxx -XDygLt5n3MiaIPB1yLC2J4Hrlw3uIkWlwi80J+zgWRJRsx4F5Tgg0mlZelkXvhpL -OQgSeTObZGj+WIHdiAxqulm0ryRPYeDK/Bda0jxyq6dMt7nqLeP0P5miTcgdWPh/ -UzWO1yKIt2F2CBMTaWawV1kTMQpwgiuT1/biQBXQHQFyxxNYalrsGYkWPODIjYYq -+jfwNTLd7OX+gI73BWe0i0J1NQIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEG -MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFBTqGVXwDg0yxh90M7eOZhpM -EjEeMEUGA1UdIAQ+MDwwOgYEVR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3 -dy5hbHBoYXNzbC5jb20vcmVwb3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0 -cDovL2NybC5nbG9iYWxzaWduLm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8w -LQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAf -BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUFAAOC -AQEABjBCm89JAn6J6fWDWj0C87yyRt5KUO65mpBz2qBcJsqCrA6ts5T6KC6y5kk/ -UHcOlS9o82U8nxTyaGCStvwEDfakGKFpYA3jnWhbvJ4LOFmNIdoj+pmKCbkfpy61 -VWxH50Hs5uJ/r1VEOeCsdO5l0/qrUUgw8T53be3kD0CY7kd/jbZYJ82Sb2AjzAKb -WSh4olGd0Eqc5ZNemI/L7z/K/uCvpMlbbkBYpZItvV1lVcW/fARB2aS1gOmUYAIQ -OGoICNdTHC2Tr8kTe9RsxDrE+4CsuzpOVHrNTrM+7fH8EU6f9fMUvLmxMc72qi+l -+MPpZqmyIJ3E+LgDYqeF0RhjWw== ------END CERTIFICATE----- diff --git a/net/base/transport_security_state_static.h b/net/base/transport_security_state_static.h index 3ff0a18..743d146 100644 --- a/net/base/transport_security_state_static.h +++ b/net/base/transport_security_state_static.h @@ -1243,68 +1243,6 @@ lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ static const char kSPKIHash_GTECyberTrustGlobalRoot[] = "sha1/WXkS3mF11m/EI7d3E3THlt5viHI="; -#if 0 ------BEGIN CERTIFICATE----- -MIIEgjCCA2qgAwIBAgISESHiIwbyj8tbXjvCF3lADzOxMA0GCSqGSIb3DQEBBQUA -MC4xETAPBgNVBAoTCEFscGhhU1NMMRkwFwYDVQQDExBBbHBoYVNTTCBDQSAtIEcy -MB4XDTExMTIwNTEyMzYzMVoXDTE2MTIwNTA0NTk1OFowSDELMAkGA1UEBhMCREUx -ITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEWMBQGA1UEAxQNKi50 -b3Iyd2ViLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJZ/olAy -7o+W0soGoxD5xWXGVKa3cQdv/daqwDyFhGINhVgsm3GS3Oo2XLAYvyvlUFceuy2v -fRecb431lh7xtLhPpr5nZL/T0cjUxffstxSt5HI5BQ5Q/TFLA4iJQDzJgiNld0DJ -RYd8gGADwh5cVBjvAtRouUbFw75b1/4hR3kJnQsHutvglLjWHmZtf/ZoZ39CbR1a -LBJpEPoWkVqJ9LrvgA+aJ1wmi+oKLfSYQkDEn30DBeVxBZBp6tRc93eGqK1skzpG -2Sof9cmlRNIXp8plYBvtsV3LKrFlBXvQRr+hhpjrqGNib02ynyJdRij7tOCLHfqW -UitjVQVOWoGs49MCAwEAAaOCAX4wggF6MA4GA1UdDwEB/wQEAwIFoDBNBgNVHSAE -RjBEMEIGCisGAQQBoDIBCgowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xv -YmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wJQYDVR0RBB4wHIINKi50b3Iyd2ViLm9y -Z4ILdG9yMndlYi5vcmcwCQYDVR0TBAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYI -KwYBBQUHAwIwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDIuYWxwaGFzc2wu -Y29tL2dzL2dzYWxwaGFnMi5jcmwwTAYIKwYBBQUHAQEEQDA+MDwGCCsGAQUFBzAC -hjBodHRwOi8vc2VjdXJlMi5hbHBoYXNzbC5jb20vY2FjZXJ0L2dzYWxwaGFnMi5j -cnQwHQYDVR0OBBYEFLE3Bo2XTl90LORxYwgr2pPD06tSMB8GA1UdIwQYMBaAFBTq -GVXwDg0yxh90M7eOZhpMEjEeMA0GCSqGSIb3DQEBBQUAA4IBAQAyOUFr9R7EKzPP -B8UsWT5ckA/TNlOqbdo6fvqshQfH/FHUQja28IbYcpBiC2XsMov+r7WNiH3lh1CF -WKT1SwfO6a0I/58CL36pL/asWv/onlDYgAsCwr1j7qcSiROZlpLD+tehiCE70afa -+3VlyoGsbKVZ2A7MrXnxIaYhmhe4Y+238PwyBT74fpBvwoFIcbccwWEST8J2y2YW -4+SWm4pJtcJxJH/uJ8qzvZLwjzcgFKQbBLVtl+SRAblFSj64YuO9Xu97+nta1HuL -fmLvlwIO/yvONapjePASH6prPdmWvj3Clqz381mkU1pLpxTgHQqeoP87DYi8z084 -+maO9AY4 ------END CERTIFICATE----- -#endif -static const char kSPKIHash_Tor2web[] = - "sha1/GeW1hxvUgy7I9ZSX/sZe+0jjM7E="; - -#if 0 ------BEGIN CERTIFICATE----- -MIIELzCCAxegAwIBAgILBAAAAAABL07hNwIwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw -MDBaFw0yMjA0MTMxMDAwMDBaMC4xETAPBgNVBAoTCEFscGhhU1NMMRkwFwYDVQQD -ExBBbHBoYVNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAw/BliN8b3caChy/JC7pUxmM/RnWsSxQfmHKLHBD/CalSbi9l32WEP1+Bstjx -T9fwWrvJr9Ax3SZGKpme2KmjtrgHxMlx95WE79LqH1Sg5b7kQSFWMRBkfR5jjpxx -XDygLt5n3MiaIPB1yLC2J4Hrlw3uIkWlwi80J+zgWRJRsx4F5Tgg0mlZelkXvhpL -OQgSeTObZGj+WIHdiAxqulm0ryRPYeDK/Bda0jxyq6dMt7nqLeP0P5miTcgdWPh/ -UzWO1yKIt2F2CBMTaWawV1kTMQpwgiuT1/biQBXQHQFyxxNYalrsGYkWPODIjYYq -+jfwNTLd7OX+gI73BWe0i0J1NQIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEG -MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFBTqGVXwDg0yxh90M7eOZhpM -EjEeMEUGA1UdIAQ+MDwwOgYEVR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3 -dy5hbHBoYXNzbC5jb20vcmVwb3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0 -cDovL2NybC5nbG9iYWxzaWduLm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8w -LQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAf -BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUFAAOC -AQEABjBCm89JAn6J6fWDWj0C87yyRt5KUO65mpBz2qBcJsqCrA6ts5T6KC6y5kk/ -UHcOlS9o82U8nxTyaGCStvwEDfakGKFpYA3jnWhbvJ4LOFmNIdoj+pmKCbkfpy61 -VWxH50Hs5uJ/r1VEOeCsdO5l0/qrUUgw8T53be3kD0CY7kd/jbZYJ82Sb2AjzAKb -WSh4olGd0Eqc5ZNemI/L7z/K/uCvpMlbbkBYpZItvV1lVcW/fARB2aS1gOmUYAIQ -OGoICNdTHC2Tr8kTe9RsxDrE+4CsuzpOVHrNTrM+7fH8EU6f9fMUvLmxMc72qi+l -+MPpZqmyIJ3E+LgDYqeF0RhjWw== ------END CERTIFICATE----- -#endif -static const char kSPKIHash_AlphaSSL_G2[] = - "sha1/5STpjjF9yPytkFN8kecNpHCTkF8="; - // The following is static data describing the hosts that are hardcoded with // certificate pins or HSTS information. @@ -1426,16 +1364,6 @@ static const char* const kTwitterCDNAcceptableCerts[] = { kNoRejectedPublicKeys, \ } -static const char* const kTor2webAcceptableCerts[] = { - kSPKIHash_AlphaSSL_G2, - kSPKIHash_Tor2web, - NULL, -}; -#define kTor2webPins { \ - kTor2webAcceptableCerts, \ - kNoRejectedPublicKeys, \ -} - #define kNoPins {\ NULL, NULL, \ } @@ -1554,8 +1482,6 @@ static const struct HSTSPreload kPreloadedSTS[] = { {22, true, "\020braintreegateway\003com", true, kNoPins, DOMAIN_NOT_PINNED }, {23, false, "\021braintreepayments\003com", true, kNoPins, DOMAIN_NOT_PINNED }, {27, false, "\003www\021braintreepayments\003com", true, kNoPins, DOMAIN_NOT_PINNED }, - {24, false, "\022emailprivacytester\003com", true, kNoPins, DOMAIN_NOT_PINNED }, - {13, true, "\007tor2web\003org", false, kTor2webPins, DOMAIN_TOR2WEB_ORG }, }; static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS); diff --git a/net/base/transport_security_state_static.json b/net/base/transport_security_state_static.json index 9efd38a..c387ceb 100644 --- a/net/base/transport_security_state_static.json +++ b/net/base/transport_security_state_static.json @@ -123,13 +123,6 @@ "UTNUSERFirstObject", "GTECyberTrustGlobalRoot" ] - }, - { - "name": "tor2web", - "static_spki_hashes": [ - "AlphaSSL_G2", - "Tor2web" - ] } ], @@ -266,7 +259,6 @@ { "name": "braintreepayments.com", "mode": "force-https" }, { "name": "www.braintreepayments.com", "mode": "force-https" }, { "name": "emailprivacytester.com", "mode": "force-https" }, - { "name": "tor2web.org", "include_subdomains": true, "pins": "tor2web" }, // Entries that are only valid if the client supports SNI. { "name": "gmail.com", "mode": "force-https", "pins": "google", "snionly": true }, diff --git a/net/base/transport_security_state_static_generate.go b/net/base/transport_security_state_static_generate.go index 9b119e8..03694f9 100644 --- a/net/base/transport_security_state_static_generate.go +++ b/net/base/transport_security_state_static_generate.go @@ -38,7 +38,7 @@ type pin struct { name string cert *x509.Certificate spkiHash []byte - spkiHashFunc string // i.e. "sha1" + spkiHashFunc string // i.e. "sha1" } // preloaded represents the information contained in the @@ -59,7 +59,7 @@ type pinset struct { type hsts struct { Name string `json:"name"` Subdomains bool `json:"include_subdomains"` - Mode string `json:"mode"` + Mode string `json:"mode"` Pins string `json:"pins"` SNIOnly bool `json:"snionly"` } @@ -283,21 +283,13 @@ func matchNames(name, v string) error { if strings.HasSuffix(firstWord, ",") { firstWord = firstWord[:len(firstWord)-1] } - if strings.HasPrefix(firstWord, "*.") { - firstWord = firstWord[2:] - } if pos := strings.Index(firstWord, "."); pos != -1 { firstWord = firstWord[:pos] } if pos := strings.Index(firstWord, "-"); pos != -1 { firstWord = firstWord[:pos] } - if len(firstWord) == 0 { - return errors.New("first word of certificate name is empty") - } - firstWord = strings.ToLower(firstWord) - lowerV := strings.ToLower(v) - if !strings.HasPrefix(lowerV, firstWord) { + if !strings.HasPrefix(v, firstWord) { return errors.New("the first word of the certificate name isn't a prefix of the variable name") } @@ -464,7 +456,7 @@ func toDNS(s string) (string, int) { name += label l += len(label) + 1 } - l += 1 // For the length of the root label. + l += 1 // For the length of the root label. return name, l } diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index ed99bbf..cf15d5e 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -2083,9 +2083,12 @@ SECStatus SSLClientSocketNSS::OwnAuthCertHandler(void* arg, // static bool SSLClientSocketNSS::DomainBoundCertNegotiated(PRFileDesc* socket) { - // TODO(wtc,mattm): this is temporary while DBC support is changed into - // Channel ID. - return false; + PRBool xtn_negotiated = PR_FALSE; + SECStatus rv = SSL_HandshakeNegotiatedExtension( + socket, ssl_ob_cert_xtn, &xtn_negotiated); + DCHECK_EQ(SECSuccess, rv); + + return xtn_negotiated ? true : false; } SECStatus SSLClientSocketNSS::DomainBoundClientAuthHandler( diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index 3f14a7a..5e80af8 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -40,6 +40,11 @@ Patches: patches/didhandshakeresume.patch https://bugzilla.mozilla.org/show_bug.cgi?id=731798 + * Support origin bound certificates. + http://balfanz.github.com/tls-obc-spec/draft-balfanz-tls-obc-00.txt + https://bugzilla.mozilla.org/show_bug.cgi?id=680292 + patches/origin_bound_certs.patch + * Add a function to restart a handshake after a client certificate request. patches/restartclientauth.patch @@ -48,6 +53,10 @@ Patches: https://bugzilla.mozilla.org/show_bug.cgi?id=681839 patches/negotiatedextension.patch + * Support the encrypted client certificates extension. + https://bugzilla.mozilla.org/show_bug.cgi?id=692154 + patches/encryptedclientcerts.patch + * Add function to retrieve TLS client cert types requested by server. https://bugzilla.mozilla.org/show_bug.cgi?id=51413 patches/getrequestedclientcerttypes.patch diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh index b713a46..55167bf 100755 --- a/net/third_party/nss/patches/applypatches.sh +++ b/net/third_party/nss/patches/applypatches.sh @@ -24,12 +24,16 @@ patch -p6 < $patches_dir/clientauth.patch patch -p6 < $patches_dir/didhandshakeresume.patch +patch -p6 < $patches_dir/origin_bound_certs.patch + patch -p6 < $patches_dir/negotiatedextension.patch patch -p6 < $patches_dir/getrequestedclientcerttypes.patch patch -p6 < $patches_dir/restartclientauth.patch +patch -p6 < $patches_dir/encryptedclientcerts.patch + patch -p4 < $patches_dir/dtls.patch patch -p5 < $patches_dir/falsestartnpn.patch diff --git a/net/third_party/nss/patches/encryptedclientcerts.patch b/net/third_party/nss/patches/encryptedclientcerts.patch new file mode 100644 index 0000000..35ea585 --- /dev/null +++ b/net/third_party/nss/patches/encryptedclientcerts.patch @@ -0,0 +1,390 @@ +diff -pu -r a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-03-19 13:49:12.517522610 -0700 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-03-19 13:49:29.507749795 -0700 +@@ -186,6 +186,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi + #define SSL_CBC_RANDOM_IV 23 + #define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ + #define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ ++#define SSL_ENCRYPT_CLIENT_CERTS 26 /* Enable encrypted client certs. */ + + #ifdef SSL_DEPRECATED_FUNCTION + /* Old deprecated function names */ +diff -pu -r a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-03-19 13:49:12.557523144 -0700 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-03-19 13:49:29.507749795 -0700 +@@ -350,6 +350,7 @@ typedef struct sslOptionsStr { + unsigned int cbcRandomIV : 1; /* 24 */ + unsigned int enableOCSPStapling : 1; /* 25 */ + unsigned int enableOBCerts : 1; /* 26 */ ++ unsigned int encryptClientCerts : 1; /* 27 */ + } sslOptions; + + typedef enum { sslHandshakingUndetermined = 0, +diff -pu -r a/src/net/third_party/nss/ssl/ssl3con.c b/src/net/third_party/nss/ssl/ssl3con.c +--- a/src/net/third_party/nss/ssl/ssl3con.c 2012-03-19 13:49:12.527522744 -0700 ++++ b/src/net/third_party/nss/ssl/ssl3con.c 2012-03-19 13:49:29.507749795 -0700 +@@ -2882,7 +2882,14 @@ ssl3_HandleChangeCipherSpecs(sslSocket * + + ss->ssl3.prSpec = ss->ssl3.crSpec; + ss->ssl3.crSpec = prSpec; +- ss->ssl3.hs.ws = wait_finished; ++ ++ if (ss->sec.isServer && ++ ss->opt.requestCertificate && ++ ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ ss->ssl3.hs.ws = wait_client_cert; ++ } else { ++ ss->ssl3.hs.ws = wait_finished; ++ } + + SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", + SSL_GETPID(), ss->fd )); +@@ -4898,10 +4905,11 @@ loser: + static SECStatus + ssl3_SendCertificateVerify(sslSocket *ss) + { +- SECStatus rv = SECFailure; +- PRBool isTLS; +- SECItem buf = {siBuffer, NULL, 0}; +- SSL3Hashes hashes; ++ SECStatus rv = SECFailure; ++ PRBool isTLS; ++ SECItem buf = {siBuffer, NULL, 0}; ++ SSL3Hashes hashes; ++ ssl3CipherSpec *spec; + + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); +@@ -4910,13 +4918,17 @@ ssl3_SendCertificateVerify(sslSocket *ss + SSL_GETPID(), ss->fd)); + + ssl_GetSpecReadLock(ss); +- rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); ++ spec = ss->ssl3.pwSpec; ++ if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ spec = ss->ssl3.cwSpec; ++ } ++ rv = ssl3_ComputeHandshakeHashes(ss, spec, &hashes, 0); + ssl_ReleaseSpecReadLock(ss); + if (rv != SECSuccess) { + goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ + } + +- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); ++ isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0); + if (ss->ssl3.platformClientKey) { + #ifdef NSS_PLATFORM_CLIENT_AUTH + rv = ssl3_PlatformSignHashes(&hashes, ss->ssl3.platformClientKey, +@@ -5924,6 +5936,10 @@ ssl3_SendClientSecondRound(sslSocket *ss + { + SECStatus rv; + PRBool sendClientCert; ++ PRBool sendEmptyCert; ++ int n = 0, i; ++ typedef SECStatus (*SendFunction)(sslSocket*); ++ SendFunction send_funcs[5]; + + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); +@@ -5970,35 +5986,40 @@ ssl3_SendClientSecondRound(sslSocket *ss + + ssl_GetXmitBufLock(ss); /*******************************/ + +- if (ss->ssl3.sendEmptyCert) { +- ss->ssl3.sendEmptyCert = PR_FALSE; +- rv = ssl3_SendEmptyCertificate(ss); +- /* Don't send verify */ +- if (rv != SECSuccess) { +- goto loser; /* error code is set. */ +- } +- } else if (sendClientCert) { +- rv = ssl3_SendCertificate(ss); +- if (rv != SECSuccess) { +- goto loser; /* error code is set. */ +- } +- } ++ sendEmptyCert = ss->ssl3.sendEmptyCert; ++ ss->ssl3.sendEmptyCert = PR_FALSE; + +- rv = ssl3_SendClientKeyExchange(ss); +- if (rv != SECSuccess) { +- goto loser; /* err is set. */ ++ if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ send_funcs[n++] = ssl3_SendClientKeyExchange; ++ send_funcs[n++] = ssl3_SendChangeCipherSpecs; ++ if (sendEmptyCert) { ++ send_funcs[n++] = ssl3_SendEmptyCertificate; ++ } ++ if (sendClientCert) { ++ send_funcs[n++] = ssl3_SendCertificate; ++ send_funcs[n++] = ssl3_SendCertificateVerify; ++ } ++ } else { ++ if (sendEmptyCert) { ++ send_funcs[n++] = ssl3_SendEmptyCertificate; ++ } ++ if (sendClientCert) { ++ send_funcs[n++] = ssl3_SendCertificate; ++ } ++ send_funcs[n++] = ssl3_SendClientKeyExchange; ++ if (sendClientCert) { ++ send_funcs[n++] = ssl3_SendCertificateVerify; ++ } ++ send_funcs[n++] = ssl3_SendChangeCipherSpecs; + } + +- if (sendClientCert) { +- rv = ssl3_SendCertificateVerify(ss); +- if (rv != SECSuccess) { +- goto loser; /* err is set. */ +- } +- } ++ PORT_Assert(n <= sizeof(send_funcs)/sizeof(send_funcs[0])); + +- rv = ssl3_SendChangeCipherSpecs(ss); +- if (rv != SECSuccess) { +- goto loser; /* err code was set. */ ++ for (i = 0; i < n; i++) { ++ rv = send_funcs[i](ss); ++ if (rv != SECSuccess) { ++ goto loser; /* err code was set. */ ++ } + } + + /* XXX: If the server's certificate hasn't been authenticated by this +@@ -6213,8 +6234,13 @@ ssl3_SendServerHelloSequence(sslSocket * + return rv; /* err code is set. */ + } + +- ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert +- : wait_client_key; ++ if (ss->opt.requestCertificate && ++ !ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ ss->ssl3.hs.ws = wait_client_cert; ++ } else { ++ ss->ssl3.hs.ws = wait_client_key; ++ } ++ + return SECSuccess; + } + +@@ -7458,7 +7484,11 @@ ssl3_HandleCertificateVerify(sslSocket * + desc = isTLS ? decode_error : illegal_parameter; + goto alert_loser; /* malformed */ + } +- ss->ssl3.hs.ws = wait_change_cipher; ++ if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ ss->ssl3.hs.ws = wait_finished; ++ } else { ++ ss->ssl3.hs.ws = wait_change_cipher; ++ } + return SECSuccess; + + alert_loser: +@@ -8358,7 +8388,11 @@ ssl3_HandleCertificate(sslSocket *ss, SS + } + } else { + server_no_cert: +- ss->ssl3.hs.ws = wait_client_key; ++ if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ ss->ssl3.hs.ws = wait_cert_verify; ++ } else { ++ ss->ssl3.hs.ws = wait_client_key; ++ } + } + + PORT_Assert(rv == SECSuccess); +@@ -8968,6 +9002,8 @@ ssl3_HandleHandshakeMessage(sslSocket *s + if (type == finished) { + sender = ss->sec.isServer ? sender_client : sender_server; + rSpec = ss->ssl3.crSpec; ++ } else if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { ++ rSpec = ss->ssl3.crSpec; + } + rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); + } +diff -pu -r a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-03-19 12:50:32.610015524 -0700 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-03-19 13:49:29.507749795 -0700 +@@ -84,6 +84,12 @@ static SECStatus ssl3_ServerHandleNextPr + PRUint16 ex_type, SECItem *data); + static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); ++static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); ++static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); ++static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, ++ PRBool append, PRUint32 maxBytes); + + /* + * Write bytes. Using this function means the SECItem structure +@@ -240,6 +246,7 @@ static const ssl3HelloExtensionHandler c + { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, + #endif + { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, + { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, +@@ -252,6 +259,7 @@ static const ssl3HelloExtensionHandler s + { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, + /* TODO: add a handler for ssl_ec_point_formats_xtn */ + { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, +@@ -279,6 +287,7 @@ ssl3HelloExtensionSender clientHelloSend + { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, + #endif + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, ++ { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } +@@ -1082,6 +1091,18 @@ ssl3_ClientHandleSessionTicketXtn(sslSoc + return SECSuccess; + } + ++static SECStatus ++ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ if (data->len != 0) ++ return SECFailure; ++ ++ /* Keep track of negotiated extensions. */ ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ return SECSuccess; ++} ++ + SECStatus + ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +@@ -1495,6 +1516,24 @@ loser: + return rv; + } + ++static SECStatus ++ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ SECStatus rv = SECSuccess; ++ ++ if (data->len != 0) ++ return SECFailure; ++ ++ if (ss->opt.encryptClientCerts) { ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ rv = ssl3_RegisterServerHelloExtensionSender( ++ ss, ex_type, ssl3_SendEncryptedClientCertsXtn); ++ } ++ ++ return rv; ++} ++ + /* + * Read bytes. Using this function means the SECItem structure + * cannot be freed. The caller is expected to call this function +@@ -1694,6 +1733,33 @@ ssl3_SendRenegotiationInfoXtn( + return needed; + } + ++static PRInt32 ++ssl3_SendEncryptedClientCertsXtn( ++ sslSocket * ss, ++ PRBool append, ++ PRUint32 maxBytes) ++{ ++ PRInt32 needed; ++ ++ if (!ss->opt.encryptClientCerts) ++ return 0; ++ ++ needed = 4; /* two bytes of type and two of length. */ ++ if (append && maxBytes >= needed) { ++ SECStatus rv; ++ rv = ssl3_AppendHandshakeNumber(ss, ssl_encrypted_client_certs, 2); ++ if (rv != SECSuccess) ++ return -1; ++ rv = ssl3_AppendHandshakeNumber(ss, 0 /* length */, 2); ++ if (rv != SECSuccess) ++ return -1; ++ ss->xtnData.advertised[ss->xtnData.numAdvertised++] = ++ ssl_encrypted_client_certs; ++ } ++ ++ return needed; ++} ++ + /* This function runs in both the client and server. */ + static SECStatus + ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) +diff -pu -r a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-03-19 12:59:07.586991902 -0700 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-03-19 13:49:29.517749929 -0700 +@@ -188,6 +188,7 @@ static sslOptions ssl_defaults = { + PR_TRUE, /* cbcRandomIV */ + PR_FALSE, /* enableOCSPStapling */ + PR_FALSE, /* enableOBCerts */ ++ PR_FALSE, /* encryptClientCerts */ + }; + + /* +@@ -826,6 +827,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + ss->opt.enableOBCerts = on; + break; + ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ ss->opt.encryptClientCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +@@ -897,6 +902,8 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; + case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; + case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ on = ss->opt.encryptClientCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -959,6 +966,8 @@ SSL_OptionGetDefault(PRInt32 which, PRBo + on = ssl_defaults.enableOCSPStapling; + break; + case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ on = ssl_defaults.encryptClientCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -1126,6 +1135,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo + ssl_defaults.enableOBCerts = on; + break; + ++ case SSL_ENCRYPT_CLIENT_CERTS: ++ ssl_defaults.encryptClientCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +diff -pu -r a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h +--- a/src/net/third_party/nss/ssl/sslt.h 2012-03-19 12:50:32.610015524 -0700 ++++ b/src/net/third_party/nss/ssl/sslt.h 2012-03-19 13:49:29.517749929 -0700 +@@ -214,10 +214,11 @@ typedef enum { + #endif + ssl_session_ticket_xtn = 35, + ssl_next_proto_nego_xtn = 13172, ++ ssl_encrypted_client_certs = 13180, /* not IANA assigned. */ + ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ + ssl_ob_cert_xtn = 13175 /* experimental number */ + } SSLExtensionType; + +-#define SSL_MAX_EXTENSIONS 8 ++#define SSL_MAX_EXTENSIONS 9 + + #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/patches/origin_bound_certs.patch b/net/third_party/nss/patches/origin_bound_certs.patch new file mode 100644 index 0000000..18d60ad --- /dev/null +++ b/net/third_party/nss/patches/origin_bound_certs.patch @@ -0,0 +1,219 @@ +diff -up a/src/net/third_party/nss/ssl/ssl.h b/src/net/third_party/nss/ssl/ssl.h +--- a/src/net/third_party/nss/ssl/ssl.h 2012-02-29 14:41:25.755295547 -0800 ++++ b/src/net/third_party/nss/ssl/ssl.h 2012-02-29 16:45:47.368569394 -0800 +@@ -168,6 +168,7 @@ SSL_IMPORT PRFileDesc *SSL_ImportFD(PRFi + */ + #define SSL_CBC_RANDOM_IV 23 + #define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ ++#define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ + + #ifdef SSL_DEPRECATED_FUNCTION + /* Old deprecated function names */ +diff -up a/src/net/third_party/nss/ssl/ssl3ext.c b/src/net/third_party/nss/ssl/ssl3ext.c +--- a/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/ssl3ext.c 2012-02-29 17:05:21.684414824 -0800 +@@ -242,6 +242,7 @@ static const ssl3HelloExtensionHandler c + { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, ++ { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, + { -1, NULL } + }; + +@@ -254,6 +255,7 @@ static const ssl3HelloExtensionHandler s + { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, + { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, ++ { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, + { -1, NULL } + }; + +@@ -278,7 +280,8 @@ ssl3HelloExtensionSender clientHelloSend + #endif + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, + { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, +- { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } ++ { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, ++ { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } + /* any extra entries will appear as { 0, NULL } */ + }; + +@@ -1723,3 +1726,80 @@ ssl3_HandleRenegotiationInfoXtn(sslSocke + return rv; + } + ++/* This sender is used by both the client and server. */ ++PRInt32 ++ssl3_SendOBCertXtn(sslSocket * ss, PRBool append, ++ PRUint32 maxBytes) ++{ ++ SECStatus rv; ++ PRUint32 extension_length; ++ ++ if (!ss) ++ return 0; ++ ++ if (!ss->opt.enableOBCerts) ++ return 0; ++ ++ /* extension length = extension_type (2-bytes) + ++ * length(extension_data) (2-bytes) + ++ */ ++ ++ extension_length = 4; ++ ++ if (append && maxBytes >= extension_length) { ++ /* extension_type */ ++ rv = ssl3_AppendHandshakeNumber(ss, ssl_ob_cert_xtn, 2); ++ if (rv != SECSuccess) return -1; ++ /* length of extension_data */ ++ rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); ++ if (rv != SECSuccess) return -1; ++ ++ if (!ss->sec.isServer) { ++ TLSExtensionData *xtnData = &ss->xtnData; ++ xtnData->advertised[xtnData->numAdvertised++] = ssl_ob_cert_xtn; ++ } ++ } ++ ++ return extension_length; ++} ++ ++SECStatus ++ssl3_ServerHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ SECStatus rv; ++ ++ /* Ignore the OBCert extension if it is disabled. */ ++ if (!ss->opt.enableOBCerts) ++ return SECSuccess; ++ ++ /* The echoed extension must be empty. */ ++ if (data->len != 0) ++ return SECFailure; ++ ++ /* Keep track of negotiated extensions. */ ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ ++ rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, ++ ssl3_SendOBCertXtn); ++ ++ return SECSuccess; ++} ++ ++SECStatus ++ssl3_ClientHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, ++ SECItem *data) ++{ ++ /* If we didn't request this extension, then the server may not echo it. */ ++ if (!ss->opt.enableOBCerts) ++ return SECFailure; ++ ++ /* The echoed extension must be empty. */ ++ if (data->len != 0) ++ return SECFailure; ++ ++ /* Keep track of negotiated extensions. */ ++ ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; ++ ++ return SECSuccess; ++} +diff -up a/src/net/third_party/nss/ssl/sslimpl.h b/src/net/third_party/nss/ssl/sslimpl.h +--- a/src/net/third_party/nss/ssl/sslimpl.h 2012-02-28 20:34:50.114663722 -0800 ++++ b/src/net/third_party/nss/ssl/sslimpl.h 2012-02-29 16:57:21.097919853 -0800 +@@ -349,6 +349,7 @@ typedef struct sslOptionsStr { + unsigned int enableFalseStart : 1; /* 23 */ + unsigned int cbcRandomIV : 1; /* 24 */ + unsigned int enableOCSPStapling : 1; /* 25 */ ++ unsigned int enableOBCerts : 1; /* 26 */ + } sslOptions; + + typedef enum { sslHandshakingUndetermined = 0, +@@ -1563,8 +1564,12 @@ extern SECStatus ssl3_ClientHandleSessio + PRUint16 ex_type, SECItem *data); + extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); ++extern SECStatus ssl3_ClientHandleOBCertXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); + extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); ++extern SECStatus ssl3_ServerHandleOBCertXtn(sslSocket *ss, ++ PRUint16 ex_type, SECItem *data); + + /* ClientHello and ServerHello extension senders. + * Note that not all extension senders are exposed here; only those that +@@ -1580,6 +1585,8 @@ extern PRInt32 ssl3_ClientSendStatusRequ + */ + extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); ++extern PRInt32 ssl3_SendOBCertXtn(sslSocket *ss, PRBool append, ++ PRUint32 maxBytes); + + /* Assigns new cert, cert chain and keys to ss->serverCerts + * struct. If certChain is NULL, tries to find one. Aborts if +diff -up a/src/net/third_party/nss/ssl/sslsock.c b/src/net/third_party/nss/ssl/sslsock.c +--- a/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 14:41:25.755295547 -0800 ++++ b/src/net/third_party/nss/ssl/sslsock.c 2012-02-29 17:03:16.272715683 -0800 +@@ -187,6 +187,7 @@ static sslOptions ssl_defaults = { + PR_FALSE, /* enableFalseStart */ + PR_TRUE, /* cbcRandomIV */ + PR_FALSE, /* enableOCSPStapling */ ++ PR_FALSE, /* enableOBCerts */ + }; + + sslSessionIDLookupFunc ssl_sid_lookup; +@@ -750,6 +751,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh + ss->opt.enableOCSPStapling = on; + break; + ++ case SSL_ENABLE_OB_CERTS: ++ ss->opt.enableOBCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + rv = SECFailure; +@@ -816,6 +821,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh + case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; + case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; + case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; ++ case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -873,6 +879,7 @@ SSL_OptionGetDefault(PRInt32 which, PRBo + case SSL_ENABLE_OCSP_STAPLING: + on = ssl_defaults.enableOCSPStapling; + break; ++ case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); +@@ -1036,6 +1043,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo + ssl_defaults.enableOCSPStapling = on; + break; + ++ case SSL_ENABLE_OB_CERTS: ++ ssl_defaults.enableOBCerts = on; ++ break; ++ + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; +diff -up a/src/net/third_party/nss/ssl/sslt.h b/src/net/third_party/nss/ssl/sslt.h +--- a/src/net/third_party/nss/ssl/sslt.h 2012-02-28 19:26:04.057351342 -0800 ++++ b/src/net/third_party/nss/ssl/sslt.h 2012-02-29 17:05:03.744171015 -0800 +@@ -205,9 +205,10 @@ typedef enum { + #endif + ssl_session_ticket_xtn = 35, + ssl_next_proto_nego_xtn = 13172, +- ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ ++ ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ ++ ssl_ob_cert_xtn = 13175 /* experimental number */ + } SSLExtensionType; + +-#define SSL_MAX_EXTENSIONS 7 ++#define SSL_MAX_EXTENSIONS 8 + + #endif /* __sslt_h_ */ diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h index 1368e2f..8885575 100644 --- a/net/third_party/nss/ssl/ssl.h +++ b/net/third_party/nss/ssl/ssl.h @@ -191,6 +191,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd); */ #define SSL_CBC_RANDOM_IV 23 #define SSL_ENABLE_OCSP_STAPLING 24 /* Request OCSP stapling (client) */ +#define SSL_ENABLE_OB_CERTS 25 /* Enable origin bound certs. */ +#define SSL_ENCRYPT_CLIENT_CERTS 26 /* Enable encrypted client certs. */ #ifdef SSL_DEPRECATED_FUNCTION /* Old deprecated function names */ diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index db9fad3..55e4901 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -2991,7 +2991,14 @@ ssl3_HandleChangeCipherSpecs(sslSocket *ss, sslBuffer *buf) ss->ssl3.prSpec = ss->ssl3.crSpec; ss->ssl3.crSpec = prSpec; - ss->ssl3.hs.ws = wait_finished; + + if (ss->sec.isServer && + ss->opt.requestCertificate && + ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_client_cert; + } else { + ss->ssl3.hs.ws = wait_finished; + } SSL_TRC(3, ("%d: SSL3[%d] Set Current Read Cipher Suite to Pending", SSL_GETPID(), ss->fd )); @@ -5080,10 +5087,11 @@ loser: static SECStatus ssl3_SendCertificateVerify(sslSocket *ss) { - SECStatus rv = SECFailure; - PRBool isTLS; - SECItem buf = {siBuffer, NULL, 0}; - SSL3Hashes hashes; + SECStatus rv = SECFailure; + PRBool isTLS; + SECItem buf = {siBuffer, NULL, 0}; + SSL3Hashes hashes; + ssl3CipherSpec *spec; PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); @@ -5092,13 +5100,17 @@ ssl3_SendCertificateVerify(sslSocket *ss) SSL_GETPID(), ss->fd)); ssl_GetSpecReadLock(ss); - rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); + spec = ss->ssl3.pwSpec; + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + spec = ss->ssl3.cwSpec; + } + rv = ssl3_ComputeHandshakeHashes(ss, spec, &hashes, 0); ssl_ReleaseSpecReadLock(ss); if (rv != SECSuccess) { goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ } - isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); + isTLS = (PRBool)(spec->version > SSL_LIBRARY_VERSION_3_0); if (ss->ssl3.platformClientKey) { #ifdef NSS_PLATFORM_CLIENT_AUTH rv = ssl3_PlatformSignHashes(&hashes, ss->ssl3.platformClientKey, @@ -6153,6 +6165,10 @@ ssl3_SendClientSecondRound(sslSocket *ss) { SECStatus rv; PRBool sendClientCert; + PRBool sendEmptyCert; + int n = 0, i; + typedef SECStatus (*SendFunction)(sslSocket*); + SendFunction send_funcs[5]; PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); @@ -6199,35 +6215,40 @@ ssl3_SendClientSecondRound(sslSocket *ss) ssl_GetXmitBufLock(ss); /*******************************/ - if (ss->ssl3.sendEmptyCert) { - ss->ssl3.sendEmptyCert = PR_FALSE; - rv = ssl3_SendEmptyCertificate(ss); - /* Don't send verify */ - if (rv != SECSuccess) { - goto loser; /* error code is set. */ - } - } else if (sendClientCert) { - rv = ssl3_SendCertificate(ss); - if (rv != SECSuccess) { - goto loser; /* error code is set. */ - } - } + sendEmptyCert = ss->ssl3.sendEmptyCert; + ss->ssl3.sendEmptyCert = PR_FALSE; - rv = ssl3_SendClientKeyExchange(ss); - if (rv != SECSuccess) { - goto loser; /* err is set. */ + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + send_funcs[n++] = ssl3_SendClientKeyExchange; + send_funcs[n++] = ssl3_SendChangeCipherSpecs; + if (sendEmptyCert) { + send_funcs[n++] = ssl3_SendEmptyCertificate; + } + if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificate; + send_funcs[n++] = ssl3_SendCertificateVerify; + } + } else { + if (sendEmptyCert) { + send_funcs[n++] = ssl3_SendEmptyCertificate; + } + if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificate; + } + send_funcs[n++] = ssl3_SendClientKeyExchange; + if (sendClientCert) { + send_funcs[n++] = ssl3_SendCertificateVerify; + } + send_funcs[n++] = ssl3_SendChangeCipherSpecs; } - if (sendClientCert) { - rv = ssl3_SendCertificateVerify(ss); - if (rv != SECSuccess) { - goto loser; /* err is set. */ - } - } + PORT_Assert(n <= sizeof(send_funcs)/sizeof(send_funcs[0])); - rv = ssl3_SendChangeCipherSpecs(ss); - if (rv != SECSuccess) { - goto loser; /* err code was set. */ + for (i = 0; i < n; i++) { + rv = send_funcs[i](ss); + if (rv != SECSuccess) { + goto loser; /* err code was set. */ + } } /* XXX: If the server's certificate hasn't been authenticated by this @@ -6442,8 +6463,13 @@ ssl3_SendServerHelloSequence(sslSocket *ss) return rv; /* err code is set. */ } - ss->ssl3.hs.ws = (ss->opt.requestCertificate) ? wait_client_cert - : wait_client_key; + if (ss->opt.requestCertificate && + !ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_client_cert; + } else { + ss->ssl3.hs.ws = wait_client_key; + } + return SECSuccess; } @@ -7740,7 +7766,11 @@ ssl3_HandleCertificateVerify(sslSocket *ss, SSL3Opaque *b, PRUint32 length, desc = isTLS ? decode_error : illegal_parameter; goto alert_loser; /* malformed */ } - ss->ssl3.hs.ws = wait_change_cipher; + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_finished; + } else { + ss->ssl3.hs.ws = wait_change_cipher; + } return SECSuccess; alert_loser: @@ -8653,7 +8683,11 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length) } } else { server_no_cert: - ss->ssl3.hs.ws = wait_client_key; + if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + ss->ssl3.hs.ws = wait_cert_verify; + } else { + ss->ssl3.hs.ws = wait_client_key; + } } PORT_Assert(rv == SECSuccess); @@ -9268,6 +9302,8 @@ ssl3_HandleHandshakeMessage(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (type == finished) { sender = ss->sec.isServer ? sender_client : sender_server; rSpec = ss->ssl3.crSpec; + } else if (ssl3_ExtensionNegotiated(ss, ssl_encrypted_client_certs)) { + rSpec = ss->ssl3.crSpec; } rv = ssl3_ComputeHandshakeHashes(ss, rSpec, &hashes, sender); } diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext.c index b9fd6e7..6d5866b 100644 --- a/net/third_party/nss/ssl/ssl3ext.c +++ b/net/third_party/nss/ssl/ssl3ext.c @@ -84,6 +84,12 @@ static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); +static SECStatus ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); +static SECStatus ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); +static PRInt32 ssl3_SendEncryptedClientCertsXtn(sslSocket *ss, + PRBool append, PRUint32 maxBytes); /* * Write bytes. Using this function means the SECItem structure @@ -240,8 +246,10 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { { ssl_ec_point_formats_xtn, &ssl3_HandleSupportedPointFormatsXtn }, #endif { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, + { ssl_encrypted_client_certs, &ssl3_ServerHandleEncryptedClientCertsXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, + { ssl_ob_cert_xtn, &ssl3_ServerHandleOBCertXtn }, { -1, NULL } }; @@ -251,9 +259,11 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = { { ssl_server_name_xtn, &ssl3_HandleServerNameXtn }, /* TODO: add a handler for ssl_ec_point_formats_xtn */ { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, + { ssl_encrypted_client_certs, &ssl3_ClientHandleEncryptedClientCertsXtn }, { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, { ssl_next_proto_nego_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, { ssl_cert_status_xtn, &ssl3_ClientHandleStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_ClientHandleOBCertXtn }, { -1, NULL } }; @@ -277,8 +287,10 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = { { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, #endif { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, + { ssl_encrypted_client_certs, &ssl3_SendEncryptedClientCertsXtn }, { ssl_next_proto_nego_xtn, &ssl3_ClientSendNextProtoNegoXtn }, - { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn } + { ssl_cert_status_xtn, &ssl3_ClientSendStatusRequestXtn }, + { ssl_ob_cert_xtn, &ssl3_SendOBCertXtn } /* any extra entries will appear as { 0, NULL } */ }; @@ -1087,6 +1099,18 @@ ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, return SECSuccess; } +static SECStatus +ssl3_ClientHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +{ + if (data->len != 0) + return SECFailure; + + /* Keep track of negotiated extensions. */ + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + return SECSuccess; +} + SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) @@ -1500,6 +1524,24 @@ loser: return rv; } +static SECStatus +ssl3_ServerHandleEncryptedClientCertsXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +{ + SECStatus rv = SECSuccess; + + if (data->len != 0) + return SECFailure; + + if (ss->opt.encryptClientCerts) { + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + rv = ssl3_RegisterServerHelloExtensionSender( + ss, ex_type, ssl3_SendEncryptedClientCertsXtn); + } + + return rv; +} + /* * Read bytes. Using this function means the SECItem structure * cannot be freed. The caller is expected to call this function @@ -1699,6 +1741,33 @@ ssl3_SendRenegotiationInfoXtn( return needed; } +static PRInt32 +ssl3_SendEncryptedClientCertsXtn( + sslSocket * ss, + PRBool append, + PRUint32 maxBytes) +{ + PRInt32 needed; + + if (!ss->opt.encryptClientCerts) + return 0; + + needed = 4; /* two bytes of type and two of length. */ + if (append && maxBytes >= needed) { + SECStatus rv; + rv = ssl3_AppendHandshakeNumber(ss, ssl_encrypted_client_certs, 2); + if (rv != SECSuccess) + return -1; + rv = ssl3_AppendHandshakeNumber(ss, 0 /* length */, 2); + if (rv != SECSuccess) + return -1; + ss->xtnData.advertised[ss->xtnData.numAdvertised++] = + ssl_encrypted_client_certs; + } + + return needed; +} + /* This function runs in both the client and server. */ static SECStatus ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) @@ -1730,3 +1799,80 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) return rv; } +/* This sender is used by both the client and server. */ +PRInt32 +ssl3_SendOBCertXtn(sslSocket * ss, PRBool append, + PRUint32 maxBytes) +{ + SECStatus rv; + PRUint32 extension_length; + + if (!ss) + return 0; + + if (!ss->opt.enableOBCerts) + return 0; + + /* extension length = extension_type (2-bytes) + + * length(extension_data) (2-bytes) + + */ + + extension_length = 4; + + if (append && maxBytes >= extension_length) { + /* extension_type */ + rv = ssl3_AppendHandshakeNumber(ss, ssl_ob_cert_xtn, 2); + if (rv != SECSuccess) return -1; + /* length of extension_data */ + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); + if (rv != SECSuccess) return -1; + + if (!ss->sec.isServer) { + TLSExtensionData *xtnData = &ss->xtnData; + xtnData->advertised[xtnData->numAdvertised++] = ssl_ob_cert_xtn; + } + } + + return extension_length; +} + +SECStatus +ssl3_ServerHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +{ + SECStatus rv; + + /* Ignore the OBCert extension if it is disabled. */ + if (!ss->opt.enableOBCerts) + return SECSuccess; + + /* The echoed extension must be empty. */ + if (data->len != 0) + return SECFailure; + + /* Keep track of negotiated extensions. */ + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + + rv = ssl3_RegisterServerHelloExtensionSender(ss, ex_type, + ssl3_SendOBCertXtn); + + return SECSuccess; +} + +SECStatus +ssl3_ClientHandleOBCertXtn(sslSocket *ss, PRUint16 ex_type, + SECItem *data) +{ + /* If we didn't request this extension, then the server may not echo it. */ + if (!ss->opt.enableOBCerts) + return SECFailure; + + /* The echoed extension must be empty. */ + if (data->len != 0) + return SECFailure; + + /* Keep track of negotiated extensions. */ + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; + + return SECSuccess; +} diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h index 8ab865a..4991aca 100644 --- a/net/third_party/nss/ssl/sslimpl.h +++ b/net/third_party/nss/ssl/sslimpl.h @@ -356,6 +356,8 @@ typedef struct sslOptionsStr { unsigned int enableFalseStart : 1; /* 23 */ unsigned int cbcRandomIV : 1; /* 24 */ unsigned int enableOCSPStapling : 1; /* 25 */ + unsigned int enableOBCerts : 1; /* 26 */ + unsigned int encryptClientCerts : 1; /* 27 */ } sslOptions; typedef enum { sslHandshakingUndetermined = 0, @@ -1700,8 +1702,12 @@ extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ClientHandleStatusRequestXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); +extern SECStatus ssl3_ClientHandleOBCertXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data); +extern SECStatus ssl3_ServerHandleOBCertXtn(sslSocket *ss, + PRUint16 ex_type, SECItem *data); /* ClientHello and ServerHello extension senders. * Note that not all extension senders are exposed here; only those that @@ -1717,6 +1723,8 @@ extern PRInt32 ssl3_ClientSendStatusRequestXtn(sslSocket *ss, PRBool append, */ extern PRInt32 ssl3_SendServerNameXtn(sslSocket *ss, PRBool append, PRUint32 maxBytes); +extern PRInt32 ssl3_SendOBCertXtn(sslSocket *ss, PRBool append, + PRUint32 maxBytes); /* Assigns new cert, cert chain and keys to ss->serverCerts * struct. If certChain is NULL, tries to find one. Aborts if diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c index ebc245a..3364902 100644 --- a/net/third_party/nss/ssl/sslsock.c +++ b/net/third_party/nss/ssl/sslsock.c @@ -187,6 +187,8 @@ static sslOptions ssl_defaults = { PR_FALSE, /* enableFalseStart */ PR_TRUE, /* cbcRandomIV */ PR_FALSE, /* enableOCSPStapling */ + PR_FALSE, /* enableOBCerts */ + PR_FALSE, /* encryptClientCerts */ }; /* @@ -864,6 +866,14 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 which, PRBool on) ss->opt.enableOCSPStapling = on; break; + case SSL_ENABLE_OB_CERTS: + ss->opt.enableOBCerts = on; + break; + + case SSL_ENCRYPT_CLIENT_CERTS: + ss->opt.encryptClientCerts = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); rv = SECFailure; @@ -934,6 +944,9 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 which, PRBool *pOn) case SSL_ENABLE_FALSE_START: on = ss->opt.enableFalseStart; break; case SSL_CBC_RANDOM_IV: on = ss->opt.cbcRandomIV; break; case SSL_ENABLE_OCSP_STAPLING: on = ss->opt.enableOCSPStapling; break; + case SSL_ENABLE_OB_CERTS: on = ss->opt.enableOBCerts; break; + case SSL_ENCRYPT_CLIENT_CERTS: + on = ss->opt.encryptClientCerts; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -995,6 +1008,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBool *pOn) case SSL_ENABLE_OCSP_STAPLING: on = ssl_defaults.enableOCSPStapling; break; + case SSL_ENABLE_OB_CERTS: on = ssl_defaults.enableOBCerts; break; + case SSL_ENCRYPT_CLIENT_CERTS: + on = ssl_defaults.encryptClientCerts; break; default: PORT_SetError(SEC_ERROR_INVALID_ARGS); @@ -1158,6 +1174,14 @@ SSL_OptionSetDefault(PRInt32 which, PRBool on) ssl_defaults.enableOCSPStapling = on; break; + case SSL_ENABLE_OB_CERTS: + ssl_defaults.enableOBCerts = on; + break; + + case SSL_ENCRYPT_CLIENT_CERTS: + ssl_defaults.encryptClientCerts = on; + break; + default: PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; diff --git a/net/third_party/nss/ssl/sslt.h b/net/third_party/nss/ssl/sslt.h index 0636570..eddfffd 100644 --- a/net/third_party/nss/ssl/sslt.h +++ b/net/third_party/nss/ssl/sslt.h @@ -215,9 +215,11 @@ typedef enum { #endif ssl_session_ticket_xtn = 35, ssl_next_proto_nego_xtn = 13172, - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ + ssl_encrypted_client_certs = 13180, /* not IANA assigned. */ + ssl_renegotiation_info_xtn = 0xff01, /* experimental number */ + ssl_ob_cert_xtn = 13175 /* experimental number */ } SSLExtensionType; -#define SSL_MAX_EXTENSIONS 7 +#define SSL_MAX_EXTENSIONS 9 #endif /* __sslt_h_ */ diff --git a/webkit/blob/blob_data.cc b/webkit/blob/blob_data.cc index 57d9bc2..33ee36b 100644 --- a/webkit/blob/blob_data.cc +++ b/webkit/blob/blob_data.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -86,4 +86,35 @@ BlobData::BlobData(const WebBlobData& data) { BlobData::~BlobData() {} +void BlobData::AppendData(const char* data, size_t length) { + DCHECK(length > 0); + items_.push_back(Item()); + items_.back().SetToData(data, length); +} + +void BlobData::AppendFile(const FilePath& file_path, uint64 offset, + uint64 length, + const base::Time& expected_modification_time) { + DCHECK(length > 0); + items_.push_back(Item()); + items_.back().SetToFile(file_path, offset, length, + expected_modification_time); +} + +void BlobData::AppendBlob(const GURL& blob_url, uint64 offset, uint64 length) { + DCHECK(length > 0); + items_.push_back(Item()); + items_.back().SetToBlob(blob_url, offset, length); +} + +int64 BlobData::GetMemoryUsage() const { + int64 memory = 0; + for (std::vector<Item>::const_iterator iter = items_.begin(); + iter != items_.end(); ++iter) { + if (iter->type == TYPE_DATA) + memory += iter->data.size(); + } + return memory; +} + } // namespace webkit_blob diff --git a/webkit/blob/blob_data.h b/webkit/blob/blob_data.h index c1296a3..3d276f0 100644 --- a/webkit/blob/blob_data.h +++ b/webkit/blob/blob_data.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -85,24 +85,12 @@ class BLOB_EXPORT BlobData : public base::RefCounted<BlobData> { AppendData(data.c_str(), data.size()); } - void AppendData(const char* data, size_t length) { - if (length > 0) { - items_.push_back(Item()); - items_.back().SetToData(data, length); - } - } + void AppendData(const char* data, size_t length); void AppendFile(const FilePath& file_path, uint64 offset, uint64 length, - const base::Time& expected_modification_time) { - items_.push_back(Item()); - items_.back().SetToFile(file_path, offset, length, - expected_modification_time); - } + const base::Time& expected_modification_time); - void AppendBlob(const GURL& blob_url, uint64 offset, uint64 length) { - items_.push_back(Item()); - items_.back().SetToBlob(blob_url, offset, length); - } + void AppendBlob(const GURL& blob_url, uint64 offset, uint64 length); void AttachShareableFileReference(ShareableFileReference* reference) { shareable_files_.push_back(reference); @@ -122,15 +110,7 @@ class BLOB_EXPORT BlobData : public base::RefCounted<BlobData> { content_disposition_ = content_disposition; } - int64 GetMemoryUsage() const { - int64 memory = 0; - for (std::vector<Item>::const_iterator iter = items_.begin(); - iter != items_.end(); ++iter) { - if (iter->type == TYPE_DATA) - memory += iter->data.size(); - } - return memory; - } + int64 GetMemoryUsage() const; private: friend class base::RefCounted<BlobData>; diff --git a/webkit/blob/blob_storage_controller.cc b/webkit/blob/blob_storage_controller.cc index ed617e6..9dcbc33 100644 --- a/webkit/blob/blob_storage_controller.cc +++ b/webkit/blob/blob_storage_controller.cc @@ -68,6 +68,7 @@ void BlobStorageController::AppendBlobDataItem( // All the Blob items in the passing blob data are resolved and expanded into // a set of Data and File items. + DCHECK(item.length > 0); switch (item.type) { case BlobData::TYPE_DATA: // WebBlobData does not allow partial data. diff --git a/webkit/fileapi/file_system_operation_write_unittest.cc b/webkit/fileapi/file_system_operation_write_unittest.cc index 2b3fec8..2288c82 100644 --- a/webkit/fileapi/file_system_operation_write_unittest.cc +++ b/webkit/fileapi/file_system_operation_write_unittest.cc @@ -234,7 +234,6 @@ TEST_F(FileSystemOperationWriteTest, TestWriteSuccess) { TEST_F(FileSystemOperationWriteTest, TestWriteZero) { GURL blob_url("blob:zero"); scoped_refptr<webkit_blob::BlobData> blob_data(new webkit_blob::BlobData()); - blob_data->AppendData(""); TestURLRequestContext url_request_context; url_request_context.blob_storage_controller()->AddFinishedBlob( |