--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
# Are you updating CLOBBER because you think it's needed for your WebIDL
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Bug 957865 - Non-clobbered ASAN builds were failing all mochitests after the clang upgrade
+Bug 989137 - /experiments needed clobber to build on OSX
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12408eb142739c7de87ab7ee0d0d2854d5c298f3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="15d69a6789c638709911507f74d25c0425963636">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="a9e08b91e9cd1f0930f16cfc49ec72f63575d5fe">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<!-- Stock Android things -->
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d11f524d00cacf5ba0dfbf25e4aa2158b1c3a036"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="12408eb142739c7de87ab7ee0d0d2854d5c298f3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
"git_revision": "",
"remote": "",
"branch": ""
},
- "revision": "6c593455e3d1292120a6f3d41ec5d06bc91019f1",
+ "revision": "f3575a1613e6c94fbc6b2ae01fd00130ee1b3f8a",
"repo_path": "/integration/gaia-central"
}
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -14,17 +14,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
<project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!-- B2G specific things. -->
<project name="platform_build" path="build" remote="b2g" revision="15d69a6789c638709911507f74d25c0425963636">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
- <project name="gaia" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
<project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
<!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="1ad48c4be51b279f7f63c1a13025b52fe087d231">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
- <project name="gaia.git" path="gaia" remote="mozillaorg" revision="eee8caa81a368f0feace718201ed15a423812c18"/>
+ <project name="gaia.git" path="gaia" remote="mozillaorg" revision="874fe42b82e8d819d592690e74db91c07179e68c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="5b93c7150acac5f657675b91889d828cc2b532e3"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89c5816399e71bda92a8959b5b771c04d6672ea3"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1357,16 +1357,18 @@ pref("social.sidebar.unload_timeout_ms",
pref("dom.identity.enabled", false);
// Turn on the CSP 1.0 parser for Content Security Policy headers
pref("security.csp.speccompliant", true);
// Block insecure active content on https pages
pref("security.mixed_content.block_active_content", true);
+pref("security.use_mozillapkix_verification", true);
+
// Override the Gecko-default value of false for Firefox.
pref("plain_text.wrap_long_lines", true);
// If this turns true, Moz*Gesture events are not called stopPropagation()
// before content.
pref("dom.debug.propagate_gesture_events_through_content", false);
// The request URL of the GeoLocation backend.
--- a/netwerk/base/public/security-prefs.js
+++ b/netwerk/base/public/security-prefs.js
@@ -49,8 +49,10 @@ pref("security.ssl3.rsa_seed_sha", false
pref("security.default_personal_cert", "Ask Every Time");
pref("security.remember_cert_checkbox_default_setting", true);
pref("security.ask_for_password", 0);
pref("security.password_lifetime", 30);
pref("security.OCSP.enabled", 1);
pref("security.OCSP.require", false);
pref("security.OCSP.GET.enabled", false);
+
+pref("security.use_mozillapkix_verification", false);
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -173,62 +173,66 @@ HttpChannelChild::AssociateApplicationCa
mLoadedFromApplicationCache = true;
mApplicationCache->InitAsHandle(groupID, clientID);
}
class StartRequestEvent : public ChannelEvent
{
public:
StartRequestEvent(HttpChannelChild* child,
+ const nsresult& channelStatus,
const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
const bool& cacheEntryAvailable,
const uint32_t& cacheExpirationTime,
const nsCString& cachedCharset,
const nsCString& securityInfoSerialization,
const NetAddr& selfAddr,
const NetAddr& peerAddr)
: mChild(child)
+ , mChannelStatus(channelStatus)
, mResponseHead(responseHead)
, mRequestHeaders(requestHeaders)
, mUseResponseHead(useResponseHead)
, mIsFromCache(isFromCache)
, mCacheEntryAvailable(cacheEntryAvailable)
, mCacheExpirationTime(cacheExpirationTime)
, mCachedCharset(cachedCharset)
, mSecurityInfoSerialization(securityInfoSerialization)
, mSelfAddr(selfAddr)
, mPeerAddr(peerAddr)
{}
void Run()
{
- mChild->OnStartRequest(mResponseHead, mUseResponseHead, mRequestHeaders,
- mIsFromCache, mCacheEntryAvailable,
+ mChild->OnStartRequest(mChannelStatus, mResponseHead, mUseResponseHead,
+ mRequestHeaders, mIsFromCache, mCacheEntryAvailable,
mCacheExpirationTime, mCachedCharset,
mSecurityInfoSerialization, mSelfAddr, mPeerAddr);
}
private:
HttpChannelChild* mChild;
+ nsresult mChannelStatus;
nsHttpResponseHead mResponseHead;
nsHttpHeaderArray mRequestHeaders;
bool mUseResponseHead;
bool mIsFromCache;
bool mCacheEntryAvailable;
uint32_t mCacheExpirationTime;
nsCString mCachedCharset;
nsCString mSecurityInfoSerialization;
NetAddr mSelfAddr;
NetAddr mPeerAddr;
};
bool
-HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
+HttpChannelChild::RecvOnStartRequest(const nsresult& channelStatus,
+ const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
const bool& cacheEntryAvailable,
const uint32_t& cacheExpirationTime,
const nsCString& cachedCharset,
const nsCString& securityInfoSerialization,
const NetAddr& selfAddr,
@@ -237,32 +241,34 @@ HttpChannelChild::RecvOnStartRequest(con
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
// stage, as they are set in the listener's OnStartRequest.
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"mFlushedForDiversion should be unset before OnStartRequest!");
MOZ_RELEASE_ASSERT(!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
if (mEventQ->ShouldEnqueue()) {
- mEventQ->Enqueue(new StartRequestEvent(this, responseHead, useResponseHead,
- requestHeaders, isFromCache,
- cacheEntryAvailable,
- cacheExpirationTime, cachedCharset,
- securityInfoSerialization, selfAddr,
- peerAddr));
+ mEventQ->Enqueue(new StartRequestEvent(this, channelStatus, responseHead,
+ useResponseHead, requestHeaders,
+ isFromCache, cacheEntryAvailable,
+ cacheExpirationTime, cachedCharset,
+ securityInfoSerialization, selfAddr,
+ peerAddr));
} else {
- OnStartRequest(responseHead, useResponseHead, requestHeaders, isFromCache,
- cacheEntryAvailable, cacheExpirationTime, cachedCharset,
- securityInfoSerialization, selfAddr, peerAddr);
+ OnStartRequest(channelStatus, responseHead, useResponseHead, requestHeaders,
+ isFromCache, cacheEntryAvailable, cacheExpirationTime,
+ cachedCharset, securityInfoSerialization, selfAddr,
+ peerAddr);
}
return true;
}
void
-HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
+HttpChannelChild::OnStartRequest(const nsresult& channelStatus,
+ const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
const bool& cacheEntryAvailable,
const uint32_t& cacheExpirationTime,
const nsCString& cachedCharset,
const nsCString& securityInfoSerialization,
const NetAddr& selfAddr,
@@ -272,16 +278,20 @@ HttpChannelChild::OnStartRequest(const n
// mFlushedForDiversion and mDivertingToParent should NEVER be set at this
// stage, as they are set in the listener's OnStartRequest.
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"mFlushedForDiversion should be unset before OnStartRequest!");
MOZ_RELEASE_ASSERT(!mDivertingToParent,
"mDivertingToParent should be unset before OnStartRequest!");
+ if (!mCanceled && NS_SUCCEEDED(mStatus)) {
+ mStatus = channelStatus;
+ }
+
if (useResponseHead && !mCanceled)
mResponseHead = new nsHttpResponseHead(responseHead);
if (!securityInfoSerialization.IsEmpty()) {
NS_DeserializeObject(securityInfoSerialization,
getter_AddRefs(mSecurityInfo));
}
@@ -326,76 +336,90 @@ HttpChannelChild::OnStartRequest(const n
mSelfAddr = selfAddr;
mPeerAddr = peerAddr;
}
class TransportAndDataEvent : public ChannelEvent
{
public:
TransportAndDataEvent(HttpChannelChild* child,
- const nsresult& status,
+ const nsresult& channelStatus,
+ const nsresult& transportStatus,
const uint64_t& progress,
const uint64_t& progressMax,
const nsCString& data,
const uint64_t& offset,
const uint32_t& count)
: mChild(child)
- , mStatus(status)
+ , mChannelStatus(channelStatus)
+ , mTransportStatus(transportStatus)
, mProgress(progress)
, mProgressMax(progressMax)
, mData(data)
, mOffset(offset)
, mCount(count) {}
- void Run() { mChild->OnTransportAndData(mStatus, mProgress, mProgressMax,
- mData, mOffset, mCount); }
+ void Run()
+ {
+ mChild->OnTransportAndData(mChannelStatus, mTransportStatus, mProgress,
+ mProgressMax, mData, mOffset, mCount);
+ }
private:
HttpChannelChild* mChild;
- nsresult mStatus;
+ nsresult mChannelStatus;
+ nsresult mTransportStatus;
uint64_t mProgress;
uint64_t mProgressMax;
nsCString mData;
uint64_t mOffset;
uint32_t mCount;
};
bool
-HttpChannelChild::RecvOnTransportAndData(const nsresult& status,
+HttpChannelChild::RecvOnTransportAndData(const nsresult& channelStatus,
+ const nsresult& transportStatus,
const uint64_t& progress,
const uint64_t& progressMax,
const nsCString& data,
const uint64_t& offset,
const uint32_t& count)
{
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
if (mEventQ->ShouldEnqueue()) {
- mEventQ->Enqueue(new TransportAndDataEvent(this, status, progress,
- progressMax, data, offset,
- count));
+ mEventQ->Enqueue(new TransportAndDataEvent(this, channelStatus,
+ transportStatus, progress,
+ progressMax, data, offset,
+ count));
} else {
MOZ_RELEASE_ASSERT(!mDivertingToParent,
"ShouldEnqueue when diverting to parent!");
- OnTransportAndData(status, progress, progressMax, data, offset, count);
+ OnTransportAndData(channelStatus, transportStatus, progress, progressMax,
+ data, offset, count);
}
return true;
}
void
-HttpChannelChild::OnTransportAndData(const nsresult& status,
+HttpChannelChild::OnTransportAndData(const nsresult& channelStatus,
+ const nsresult& transportStatus,
const uint64_t progress,
const uint64_t& progressMax,
const nsCString& data,
const uint64_t& offset,
const uint32_t& count)
{
LOG(("HttpChannelChild::OnTransportAndData [this=%p]\n", this));
+ if (!mCanceled && NS_SUCCEEDED(mStatus)) {
+ mStatus = channelStatus;
+ }
+
// For diversion to parent, just SendDivertOnDataAvailable.
if (mDivertingToParent) {
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
SendDivertOnDataAvailable(data, offset, count);
return;
}
@@ -416,22 +440,22 @@ HttpChannelChild::OnTransportAndData(con
// - JDUELL: may not need mStatus/mIsPending checks, given this is always called
// during OnDataAvailable, and we've already checked mCanceled. Code
// dupe'd from nsHttpChannel
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending &&
!(mLoadFlags & LOAD_BACKGROUND))
{
// OnStatus
//
- MOZ_ASSERT(status == NS_NET_STATUS_RECEIVING_FROM ||
- status == NS_NET_STATUS_READING);
+ MOZ_ASSERT(transportStatus == NS_NET_STATUS_RECEIVING_FROM ||
+ transportStatus == NS_NET_STATUS_READING);
nsAutoCString host;
mURI->GetHost(host);
- mProgressSink->OnStatus(this, nullptr, status,
+ mProgressSink->OnStatus(this, nullptr, transportStatus,
NS_ConvertUTF8toUTF16(host).get());
// OnProgress
//
if (progress > 0) {
MOZ_ASSERT(progress <= progressMax, "unexpected progress values");
mProgressSink->OnProgress(this, nullptr, progress, progressMax);
}
}
@@ -458,60 +482,61 @@ HttpChannelChild::OnTransportAndData(con
Cancel(rv);
}
}
class StopRequestEvent : public ChannelEvent
{
public:
StopRequestEvent(HttpChannelChild* child,
- const nsresult& statusCode)
+ const nsresult& channelStatus)
: mChild(child)
- , mStatusCode(statusCode) {}
+ , mChannelStatus(channelStatus) {}
- void Run() { mChild->OnStopRequest(mStatusCode); }
+ void Run() { mChild->OnStopRequest(mChannelStatus); }
private:
HttpChannelChild* mChild;
- nsresult mStatusCode;
+ nsresult mChannelStatus;
};
bool
-HttpChannelChild::RecvOnStopRequest(const nsresult& statusCode)
+HttpChannelChild::RecvOnStopRequest(const nsresult& channelStatus)
{
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be receiving any more callbacks from parent!");
if (mEventQ->ShouldEnqueue()) {
- mEventQ->Enqueue(new StopRequestEvent(this, statusCode));
+ mEventQ->Enqueue(new StopRequestEvent(this, channelStatus));
} else {
MOZ_ASSERT(!mDivertingToParent, "ShouldEnqueue when diverting to parent!");
- OnStopRequest(statusCode);
+ OnStopRequest(channelStatus);
}
return true;
}
void
-HttpChannelChild::OnStopRequest(const nsresult& statusCode)
+HttpChannelChild::OnStopRequest(const nsresult& channelStatus)
{
LOG(("HttpChannelChild::OnStopRequest [this=%p status=%x]\n",
- this, statusCode));
+ this, channelStatus));
if (mDivertingToParent) {
MOZ_RELEASE_ASSERT(!mFlushedForDiversion,
"Should not be processing any more callbacks from parent!");
- SendDivertOnStopRequest(statusCode);
+ SendDivertOnStopRequest(channelStatus);
return;
}
mIsPending = false;
- if (!mCanceled && NS_SUCCEEDED(mStatus))
- mStatus = statusCode;
+ if (!mCanceled && NS_SUCCEEDED(mStatus)) {
+ mStatus = channelStatus;
+ }
{ // We must flush the queue before we Send__delete__
// (although we really shouldn't receive any msgs after OnStop),
// so make sure this goes out of scope before then.
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
mListener->OnStopRequest(this, mListenerContext, mStatus);
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -91,27 +91,29 @@ public:
void AddIPDLReference();
void ReleaseIPDLReference();
bool IsSuspended();
void FlushedForDiversion();
protected:
- bool RecvOnStartRequest(const nsHttpResponseHead& responseHead,
+ bool RecvOnStartRequest(const nsresult& channelStatus,
+ const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
const bool& cacheEntryAvailable,
const uint32_t& cacheExpirationTime,
const nsCString& cachedCharset,
const nsCString& securityInfoSerialization,
const NetAddr& selfAddr,
const NetAddr& peerAddr) MOZ_OVERRIDE;
- bool RecvOnTransportAndData(const nsresult& status,
+ bool RecvOnTransportAndData(const nsresult& channelStatus,
+ const nsresult& status,
const uint64_t& progress,
const uint64_t& progressMax,
const nsCString& data,
const uint64_t& offset,
const uint32_t& count) MOZ_OVERRIDE;
bool RecvOnStopRequest(const nsresult& statusCode);
bool RecvOnProgress(const uint64_t& progress, const uint64_t& progressMax) MOZ_OVERRIDE;
bool RecvOnStatus(const nsresult& status) MOZ_OVERRIDE;
@@ -156,33 +158,35 @@ private:
// diverting callbacks to parent.
bool mSuspendSent;
// true after successful AsyncOpen until OnStopRequest completes.
bool RemoteChannelExists() { return mIPCOpen && !mKeptAlive; }
void AssociateApplicationCache(const nsCString &groupID,
const nsCString &clientID);
- void OnStartRequest(const nsHttpResponseHead& responseHead,
+ void OnStartRequest(const nsresult& channelStatus,
+ const nsHttpResponseHead& responseHead,
const bool& useResponseHead,
const nsHttpHeaderArray& requestHeaders,
const bool& isFromCache,
const bool& cacheEntryAvailable,
const uint32_t& cacheExpirationTime,
const nsCString& cachedCharset,
const nsCString& securityInfoSerialization,
const NetAddr& selfAddr,
const NetAddr& peerAddr);
- void OnTransportAndData(const nsresult& status,
+ void OnTransportAndData(const nsresult& channelStatus,
+ const nsresult& status,
const uint64_t progress,
const uint64_t& progressMax,
const nsCString& data,
const uint64_t& offset,
const uint32_t& count);
- void OnStopRequest(const nsresult& statusCode);
+ void OnStopRequest(const nsresult& channelStatus);
void OnProgress(const uint64_t& progress, const uint64_t& progressMax);
void OnStatus(const nsresult& status);
void FailedAsyncOpen(const nsresult& status);
void HandleAsyncAbort();
void Redirect1Begin(const uint32_t& newChannelId,
const URIParams& newUri,
const uint32_t& redirectFlags,
const nsHttpResponseHead& responseHead);
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -583,29 +583,32 @@ HttpChannelParent::OnStartRequest(nsIReq
encodedChannel->SetApplyConversion(false);
// Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
// It could be already released by nsHttpChannel at that time.
nsCOMPtr<nsISupports> cacheEntry;
chan->GetCacheToken(getter_AddRefs(cacheEntry));
mCacheEntry = do_QueryInterface(cacheEntry);
+ nsresult channelStatus = NS_OK;
+ chan->GetStatus(&channelStatus);
nsCString secInfoSerialization;
nsCOMPtr<nsISupports> secInfoSupp;
chan->GetSecurityInfo(getter_AddRefs(secInfoSupp));
if (secInfoSupp) {
mAssociatedContentSecurity = do_QueryInterface(secInfoSupp);
nsCOMPtr<nsISerializable> secInfoSer = do_QueryInterface(secInfoSupp);
if (secInfoSer)
NS_SerializeToString(secInfoSer, secInfoSerialization);
}
if (mIPCClosed ||
- !SendOnStartRequest(responseHead ? *responseHead : nsHttpResponseHead(),
+ !SendOnStartRequest(channelStatus,
+ responseHead ? *responseHead : nsHttpResponseHead(),
!!responseHead,
requestHead->Headers(),
isFromCache,
mCacheEntry ? true : false,
expirationTime, cachedCharset, secInfoSerialization,
mChannel->GetSelfAddr(), mChannel->GetPeerAddr()))
{
return NS_ERROR_UNEXPECTED;
@@ -645,23 +648,26 @@ HttpChannelParent::OnDataAvailable(nsIRe
MOZ_RELEASE_ASSERT(!mDivertingFromChild,
"Cannot call OnDataAvailable if diverting is set!");
nsCString data;
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
if (NS_FAILED(rv))
return rv;
+ nsresult channelStatus = NS_OK;
+ mChannel->GetStatus(&channelStatus);
+
// OnDataAvailable is always preceded by OnStatus/OnProgress calls that set
// mStoredStatus/mStoredProgress(Max) to appropriate values, unless
// LOAD_BACKGROUND set. In that case, they'll have garbage values, but
// child doesn't use them.
- if (mIPCClosed || !SendOnTransportAndData(mStoredStatus, mStoredProgress,
- mStoredProgressMax, data, aOffset,
- aCount)) {
+ if (mIPCClosed || !SendOnTransportAndData(channelStatus, mStoredStatus,
+ mStoredProgress, mStoredProgressMax,
+ data, aOffset, aCount)) {
return NS_ERROR_UNEXPECTED;
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// HttpChannelParent::nsIProgressEventSink
//-----------------------------------------------------------------------------
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -75,37 +75,39 @@ parent:
DivertOnStopRequest(nsresult statusCode);
// Child has no more events/messages to divert to the parent.
DivertComplete();
__delete__();
child:
- OnStartRequest(nsHttpResponseHead responseHead,
+ OnStartRequest(nsresult channelStatus,
+ nsHttpResponseHead responseHead,
bool useResponseHead,
nsHttpHeaderArray requestHeaders,
bool isFromCache,
bool cacheEntryAvailable,
uint32_t cacheExpirationTime,
nsCString cachedCharset,
nsCString securityInfoSerialization,
NetAddr selfAddr,
NetAddr peerAddr);
// Combines a single OnDataAvailable and its associated OnProgress &
// OnStatus calls into one IPDL message
- OnTransportAndData(nsresult status,
+ OnTransportAndData(nsresult channelStatus,
+ nsresult transportStatus,
uint64_t progress,
uint64_t progressMax,
nsCString data,
uint64_t offset,
uint32_t count);
- OnStopRequest(nsresult statusCode);
+ OnStopRequest(nsresult channelStatus);
OnProgress(uint64_t progress, uint64_t progressMax);
OnStatus(nsresult status);
// Used to cancel child channel if we hit errors during creating and
// AsyncOpen of nsHttpChannel on the parent.
FailedAsyncOpen(nsresult status);
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -29,16 +29,17 @@ const SEC_ERROR_REVOKED_CERTIFICATE
const SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13;
const SEC_ERROR_BAD_DATABASE = SEC_ERROR_BASE + 18;
const SEC_ERROR_UNTRUSTED_ISSUER = SEC_ERROR_BASE + 20; // -8172
const SEC_ERROR_UNTRUSTED_CERT = SEC_ERROR_BASE + 21; // -8171
const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = SEC_ERROR_BASE + 30; // -8162
const SEC_ERROR_EXTENSION_VALUE_INVALID = SEC_ERROR_BASE + 34; // -8158
const SEC_ERROR_EXTENSION_NOT_FOUND = SEC_ERROR_BASE + 35; // -8157
const SEC_ERROR_CA_CERT_INVALID = SEC_ERROR_BASE + 36;
+const SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = SEC_ERROR_BASE + 41;
const SEC_ERROR_INADEQUATE_KEY_USAGE = SEC_ERROR_BASE + 90; // -8102
const SEC_ERROR_INADEQUATE_CERT_TYPE = SEC_ERROR_BASE + 91; // -8101
const SEC_ERROR_CERT_NOT_IN_NAME_SPACE = SEC_ERROR_BASE + 112; // -8080
const SEC_ERROR_OCSP_MALFORMED_REQUEST = SEC_ERROR_BASE + 120;
const SEC_ERROR_OCSP_SERVER_ERROR = SEC_ERROR_BASE + 121;
const SEC_ERROR_OCSP_TRY_SERVER_LATER = SEC_ERROR_BASE + 122;
const SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = SEC_ERROR_BASE + 123;
const SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = SEC_ERROR_BASE + 124;
--- a/security/manager/ssl/tests/unit/test_ocsp_stapling.js
+++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js
@@ -38,16 +38,18 @@ function add_tests_in_mode(useMozillaPKI
add_ocsp_test("ocsp-stapling-needssig.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-unauthorized.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-unknown.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-good-other.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-none.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-expired.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com", Cr.NS_OK, false);
add_ocsp_test("ocsp-stapling-skip-responseBytes.example.com", Cr.NS_OK, false);
+ add_ocsp_test("ocsp-stapling-critical-extension.example.com", Cr.NS_OK, false);
+ add_ocsp_test("ocsp-stapling-noncritical-extension.example.com", Cr.NS_OK, false);
// Now test OCSP stapling
// The following error codes are defined in security/nss/lib/util/SECerrs.h
add_ocsp_test("ocsp-stapling-good.example.com", Cr.NS_OK, true);
add_ocsp_test("ocsp-stapling-revoked.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), true);
@@ -113,31 +115,38 @@ function add_tests_in_mode(useMozillaPKI
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true);
// TODO(bug 979070): NSS can't handle this yet.
if (useMozillaPKIX) {
add_ocsp_test("ocsp-stapling-skip-responseBytes.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true);
}
+ add_ocsp_test("ocsp-stapling-critical-extension.example.com",
+ useMozillaPKIX
+ ? getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION)
+ : Cr.NS_OK, // TODO(bug 987426): NSS doesn't handle unknown critical extensions
+ true);
+ add_ocsp_test("ocsp-stapling-noncritical-extension.example.com", Cr.NS_OK, true);
+
// ocsp-stapling-expired.example.com and
// ocsp-stapling-expired-fresh-ca.example.com are handled in
// test_ocsp_stapling_expired.js
}
function check_ocsp_stapling_telemetry() {
let histogram = Cc["@mozilla.org/base/telemetry;1"]
.getService(Ci.nsITelemetry)
.getHistogramById("SSL_OCSP_STAPLING")
.snapshot();
do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
- do_check_eq(histogram.counts[1], 2 * 1); // 1 connection with a good response
- do_check_eq(histogram.counts[2], 2 * 15); // 15 connections with no stapled resp.
+ do_check_eq(histogram.counts[1], 2 + 3); // 2 or 3 connections with a good response (bug 987426)
+ do_check_eq(histogram.counts[2], 2 * 17); // 17 connections with no stapled resp.
do_check_eq(histogram.counts[3], 2 * 0); // 0 connections with an expired response
- do_check_eq(histogram.counts[4], 12 + 11); // 12 or 11 connections with bad responses (bug 979070)
+ do_check_eq(histogram.counts[4], 13 + 11); // 13 or 11 connections with bad responses (bug 979070, bug 987426)
run_next_test();
}
function run_test() {
do_get_profile();
let certDB = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp
@@ -33,16 +33,18 @@ const OCSPHost sOCSPHosts[] =
{ "ocsp-stapling-malformed.example.com", ORTMalformed, nullptr },
{ "ocsp-stapling-srverr.example.com", ORTSrverr, nullptr },
{ "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr },
{ "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr },
{ "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr },
{ "ocsp-stapling-with-intermediate.example.com", ORTGood, "ocspEEWithIntermediate" },
{ "ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr },
{ "ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, nullptr },
+ { "ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, nullptr },
+ { "ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, nullptr },
{ nullptr, ORTNull, nullptr }
};
int32_t
DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
uint32_t aSrvNameArrSize, void *aArg)
{
const OCSPHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp
@@ -4,16 +4,17 @@
#include "OCSPCommon.h"
#include <stdio.h>
#include "ScopedNSSTypes.h"
#include "TLSServer.h"
#include "pkixtestutil.h"
+#include "secder.h"
#include "secerr.h"
using namespace mozilla;
using namespace mozilla::test;
using namespace mozilla::pkix::test;
SECItemArray *
@@ -94,16 +95,43 @@ GetOCSPResponseForType(OCSPResponseType
context.certStatus = 1;
}
if (aORT == ORTUnknown) {
context.certStatus = 2;
}
if (aORT == ORTBadSignature) {
context.badSignature = true;
}
+ OCSPResponseExtension extension;
+ if (aORT == ORTCriticalExtension || aORT == ORTNoncriticalExtension) {
+ SECItem oidItem = {
+ siBuffer,
+ nullptr,
+ 0
+ };
+ // 1.3.6.1.4.1.13769.666.666.666 is the root of Mozilla's testing OID space
+ static const char* testExtensionOID = "1.3.6.1.4.1.13769.666.666.666.1.500.9.2";
+ if (SEC_StringToOID(aArena, &oidItem, testExtensionOID,
+ PL_strlen(testExtensionOID)) != SECSuccess) {
+ return nullptr;
+ }
+ DERTemplate oidTemplate[2] = { { DER_OBJECT_ID, 0 }, { 0 } };
+ extension.id.data = nullptr;
+ extension.id.len = 0;
+ if (DER_Encode(aArena, &extension.id, oidTemplate, &oidItem)
+ != SECSuccess) {
+ return nullptr;
+ }
+ extension.critical = (aORT == ORTCriticalExtension);
+ static const uint8_t value[2] = { 0x05, 0x00 };
+ extension.value.data = const_cast<uint8_t*>(value);
+ extension.value.len = PR_ARRAY_SIZE(value);
+ extension.next = nullptr;
+ context.extensions = &extension;
+ }
if (!context.signerCert) {
context.signerCert = CERT_DupCertificate(context.issuerCert.get());
}
SECItem* response = CreateEncodedOCSPResponse(context);
if (!response) {
PrintPRError("CreateEncodedOCSPResponse failed");
--- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
+++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h
@@ -24,17 +24,19 @@ enum OCSPResponseType
ORTNone, // no stapled response
ORTEmpty, // an empty stapled response
ORTMalformed, // the response from the responder was malformed
ORTSrverr, // the response indicates there was a server error
ORTTryLater, // the responder replied with "try again later"
ORTNeedsSig, // the response needs a signature
ORTUnauthorized, // the responder is not authorized for this certificate
ORTBadSignature, // the response has a signature that does not verify
- ORTSkipResponseBytes // the response does not include responseBytes
+ ORTSkipResponseBytes, // the response does not include responseBytes
+ ORTCriticalExtension, // the response includes a critical extension
+ ORTNoncriticalExtension // the response includes an extension that is not critical
};
struct OCSPHost
{
const char *mHostName;
OCSPResponseType mORT;
const char *mAdditionalCertName; // useful for ORTGoodOtherCert, etc.
};
--- a/security/pkix/lib/pkixcheck.cpp
+++ b/security/pkix/lib/pkixcheck.cpp
@@ -183,17 +183,23 @@ DecodeBasicConstraints(const SECItem* en
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
if (der::ExpectTagAndIgnoreLength(input, der::SEQUENCE) != der::Success) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
bool isCA = false;
- if (der::OptionalBoolean(input, isCA) != der::Success) {
+ // TODO(bug 989518): cA is by default false. According to DER, default
+ // values must not be explicitly encoded in a SEQUENCE. So, if this
+ // value is present and false, it is an encoding error. However, Go Daddy
+ // has issued many certificates with this improper encoding, so we can't
+ // enforce this yet (hence passing true for allowInvalidExplicitEncoding
+ // to der::OptionalBoolean).
+ if (der::OptionalBoolean(input, true, isCA) != der::Success) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
}
basicConstraints.isCA = isCA;
if (input.Peek(der::INTEGER)) {
SECItem pathLenConstraintEncoded;
if (der::Integer(input, pathLenConstraintEncoded) != der::Success) {
return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID);
--- a/security/pkix/lib/pkixder.h
+++ b/security/pkix/lib/pkixder.h
@@ -369,25 +369,28 @@ Boolean(Input& input, /*out*/ bool& valu
default:
PR_SetError(SEC_ERROR_BAD_DER, 0);
return Failure;
}
}
// This is for any BOOLEAN DEFAULT FALSE.
// (If it is present and false, this is a bad encoding.)
+// TODO(bug 989518): For compatibility reasons, in some places we allow
+// invalid encodings with the explicit default value.
inline Result
-OptionalBoolean(Input& input, /*out*/ bool& value)
+OptionalBoolean(Input& input, bool allowInvalidExplicitEncoding,
+ /*out*/ bool& value)
{
value = false;
if (input.Peek(BOOLEAN)) {
if (Boolean(input, value) != Success) {
return Failure;
}
- if (!value) {
+ if (!allowInvalidExplicitEncoding && !value) {
return Fail(SEC_ERROR_BAD_DER);
}
}
return Success;
}
inline Result
Enumerated(Input& input, uint8_t& value)
--- a/security/pkix/lib/pkixocsp.cpp
+++ b/security/pkix/lib/pkixocsp.cpp
@@ -581,17 +581,18 @@ ResponseData(der::Input& input, Context&
// empty response makes things unnecessarily complicated.
if (der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
der::MustNotBeEmpty,
bind(SingleResponse, _1, ref(context))) != der::Success) {
return der::Failure;
}
if (!input.AtEnd()) {
- if (CheckExtensionsForCriticality(input) != der::Success) {
+ if (der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
+ CheckExtensionsForCriticality) != der::Success) {
return der::Failure;
}
}
return der::Success;
}
// SingleResponse ::= SEQUENCE {
@@ -703,19 +704,19 @@ SingleResponse(der::Input& input, Contex
if (context.time < SLOP) { // prevent underflow
return der::Fail(SEC_ERROR_INVALID_ARGS);
}
if (context.time - SLOP > notAfter) {
return der::Fail(SEC_ERROR_OCSP_OLD_RESPONSE);
}
-
if (!input.AtEnd()) {
- if (CheckExtensionsForCriticality(input) != der::Success) {
+ if (der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
+ CheckExtensionsForCriticality) != der::Success) {
return der::Failure;
}
}
if (context.thisUpdate) {
*context.thisUpdate = thisUpdate;
}
if (context.validThrough) {
@@ -855,17 +856,17 @@ CheckExtensionForCriticality(der::Input&
return der::Failure;
}
return input.Skip(toSkip);
}
static der::Result
CheckExtensionsForCriticality(der::Input& input)
{
- return der::NestedOf(input, der::SEQUENCE | 1, der::SEQUENCE,
+ return der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
der::MustNotBeEmpty, CheckExtensionForCriticality);
}
// 1. The certificate identified in a received response corresponds to
// the certificate that was identified in the corresponding request;
// 2. The signature on the response is valid;
// 3. The identity of the signer matches the intended recipient of the
// request;
--- a/security/pkix/test/lib/pkixtestutil.cpp
+++ b/security/pkix/test/lib/pkixtestutil.cpp
@@ -124,16 +124,17 @@ OCSPResponseContext::OCSPResponseContext
, thisUpdate(time)
, nextUpdate(time + 10 * PR_USEC_PER_SEC)
, includeNextUpdate(true)
, certIDHashAlg(SEC_OID_SHA1)
, certStatus(0)
, revocationTime(0)
, badSignature(false)
, responderIDType(ByKeyHash)
+ , extensions(nullptr)
{
}
static SECItem* ResponseBytes(OCSPResponseContext& context);
static SECItem* BasicOCSPResponse(OCSPResponseContext& context);
static SECItem* ResponseData(OCSPResponseContext& context);
static SECItem* ResponderID(OCSPResponseContext& context);
static SECItem* KeyHash(OCSPResponseContext& context);
@@ -394,16 +395,78 @@ BasicOCSPResponse(OCSPResponseContext& c
return nullptr;
}
if (output.Add(signatureNested) != der::Success) {
return nullptr;
}
return output.Squash(context.arena, der::SEQUENCE);
}
+// Extension ::= SEQUENCE {
+// id OBJECT IDENTIFIER,
+// critical BOOLEAN DEFAULT FALSE
+// value OCTET STRING
+// }
+static SECItem*
+OCSPExtension(OCSPResponseContext& context, OCSPResponseExtension* extension)
+{
+ Output output;
+ if (output.Add(&extension->id) != der::Success) {
+ return nullptr;
+ }
+ if (extension->critical) {
+ static const uint8_t trueEncoded[3] = { 0x01, 0x01, 0xFF };
+ SECItem critical = {
+ siBuffer,
+ const_cast<uint8_t*>(trueEncoded),
+ PR_ARRAY_SIZE(trueEncoded)
+ };
+ if (output.Add(&critical) != der::Success) {
+ return nullptr;
+ }
+ }
+ SECItem* value = EncodeNested(context.arena, der::OCTET_STRING,
+ &extension->value);
+ if (!value) {
+ return nullptr;
+ }
+ if (output.Add(value) != der::Success) {
+ return nullptr;
+ }
+ return output.Squash(context.arena, der::SEQUENCE);
+}
+
+// Extensions ::= [1] {
+// SEQUENCE OF Extension
+// }
+static SECItem*
+Extensions(OCSPResponseContext& context)
+{
+ Output output;
+ for (OCSPResponseExtension* extension = context.extensions;
+ extension; extension = extension->next) {
+ SECItem* extensionEncoded = OCSPExtension(context, extension);
+ if (!extensionEncoded) {
+ return nullptr;
+ }
+ if (output.Add(extensionEncoded) != der::Success) {
+ return nullptr;
+ }
+ }
+ SECItem* extensionsEncoded = output.Squash(context.arena, der::SEQUENCE);
+ if (!extensionsEncoded) {
+ return nullptr;
+ }
+ return EncodeNested(context.arena,
+ der::CONSTRUCTED |
+ der::CONTEXT_SPECIFIC |
+ 1,
+ extensionsEncoded);
+}
+
// ResponseData ::= SEQUENCE {
// version [0] EXPLICIT Version DEFAULT v1,
// responderID ResponderID,
// producedAt GeneralizedTime,
// responses SEQUENCE OF SingleResponse,
// responseExtensions [1] EXPLICIT Extensions OPTIONAL }
SECItem*
ResponseData(OCSPResponseContext& context)
@@ -421,27 +484,36 @@ ResponseData(OCSPResponseContext& contex
if (!responses) {
return nullptr;
}
SECItem* responsesNested = EncodeNested(context.arena, der::SEQUENCE,
responses);
if (!responsesNested) {
return nullptr;
}
+ SECItem* responseExtensions = nullptr;
+ if (context.extensions) {
+ responseExtensions = Extensions(context);
+ }
Output output;
if (output.Add(responderID) != der::Success) {
return nullptr;
}
if (output.Add(producedAtEncoded) != der::Success) {
return nullptr;
}
if (output.Add(responsesNested) != der::Success) {
return nullptr;
}
+ if (responseExtensions) {
+ if (output.Add(responseExtensions) != der::Success) {
+ return nullptr;
+ }
+ }
return output.Squash(context.arena, der::SEQUENCE);
}
// ResponderID ::= CHOICE {
// byName [1] Name,
// byKey [2] KeyHash }
// }
SECItem*
--- a/security/pkix/test/lib/pkixtestutil.h
+++ b/security/pkix/test/lib/pkixtestutil.h
@@ -19,16 +19,25 @@
#define mozilla_pkix_test__pkixtestutils_h
#include "pkix/ScopedPtr.h"
#include "pkix/pkixtypes.h"
#include "seccomon.h"
namespace mozilla { namespace pkix { namespace test {
+class OCSPResponseExtension
+{
+public:
+ SECItem id;
+ bool critical;
+ SECItem value;
+ OCSPResponseExtension* next;
+};
+
class OCSPResponseContext
{
public:
OCSPResponseContext(PLArenaPool* arena, CERTCertificate* cert, PRTime time);
PLArenaPool* arena;
// TODO(bug 980538): add a way to specify what certificates are included.
pkix::ScopedCERTCertificate cert; // The subject of the OCSP response
@@ -48,16 +57,18 @@ public:
PRTime revocationTime; // For certStatus == revoked
bool badSignature; // If true, alter the signature to fail verification
enum ResponderIDType {
ByName = 1,
ByKeyHash = 2
};
ResponderIDType responderIDType;
+
+ OCSPResponseExtension* extensions;
};
// The return value, if non-null, is owned by the arena in the context
// and MUST NOT be freed.
// This function does its best to respect the NSPR error code convention
// (that is, if it returns null, calling PR_GetError() will return the
// error of the failed operation). However, this is not guaranteed.
SECItem* CreateEncodedOCSPResponse(OCSPResponseContext& context);
--- a/testing/marionette/marionette-elements.js
+++ b/testing/marionette/marionette-elements.js
@@ -115,17 +115,18 @@ ElementManager.prototype = {
delete this.seenItems[id];
}
// use XPCNativeWrapper to compare elements; see bug 834266
let wrappedWin = XPCNativeWrapper(win);
if (!el ||
!(XPCNativeWrapper(el).ownerDocument == wrappedWin.document) ||
(XPCNativeWrapper(el).compareDocumentPosition(wrappedWin.document.documentElement) &
DOCUMENT_POSITION_DISCONNECTED)) {
- throw new ElementException("Stale element reference", 10, null);
+ throw new ElementException("The element reference is stale. Either the element " +
+ "is no longer attached to the DOM or the page has been refreshed.", 10, null);
}
return el;
},
/**
* Convert values to primitives that can be transported over the
* Marionette protocol.
*