tbb-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2014
- 2 participants
- 108 discussions

[tor-browser-bundle/master] Merge remote-tracking branch 'tjr/tjr-64bit'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 912a8305b26ce0b1cbc80c4014b4de3ada898991
Merge: af7bd8e f1f4a2a
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed Oct 29 15:14:09 2014 -0700
Merge remote-tracking branch 'tjr/tjr-64bit'
Conflicts:
gitian/descriptors/mac/gitian-pluggable-transports.yml
Bundle-Data/mac-tor.sh | 1 -
gitian/descriptors/mac/gitian-bundle.yml | 9 +++-----
gitian/descriptors/mac/gitian-firefox.yml | 3 ---
.../mac/gitian-pluggable-transports.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-tor.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-utils.yml | 16 +++++++------
gitian/mkbundle-mac.sh | 24 ++++++++++----------
7 files changed, 40 insertions(+), 45 deletions(-)
diff --cc gitian/descriptors/mac/gitian-pluggable-transports.yml
index 4c25f07,17aef86..6201230
--- a/gitian/descriptors/mac/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/mac/gitian-pluggable-transports.yml
@@@ -48,10 -42,8 +48,10 @@@ files
- "apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb"
- "multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz"
- "dzip.sh"
- - "gmp-mac32-utils.zip"
- - "openssl-mac32-utils.zip"
+- "go.crypto.tar.bz2"
+- "go.net.tar.bz2"
+ - "gmp-mac64-utils.zip"
+ - "openssl-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@@ -253,53 -245,7 +253,53 @@@
cp -a README doc/*.1 $TBDIR/Docs/meek
cd ..
+ # Building go ed25519
+ cd ed25519
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/agl/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/agl/ed25519"
+ go install github.com/agl/ed25519/extra25519
+ cd ..
+
+ # Building go siphash
+ cd siphash
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/dchest/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/dchest/siphash"
+ go install github.com/dchest/siphash
+ cd ..
+
+ # Building go.crypto
+ tar xjf go.crypto.tar.bz2
+ cd go.crypto
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.crypto"
+ go install code.google.com/p/go.crypto/curve25519
+ go install code.google.com/p/go.crypto/hkdf
+ go install code.google.com/p/go.crypto/nacl/secretbox
+ cd ..
+
+ # Building go.net
+ tar xjf go.net.tar.bz2
+ cd go.net
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.net"
+ go install code.google.com/p/go.net/proxy
+ cd ..
+
+ # Building obfs4proxy
+ cd obfs4
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/git.torproject.org/pluggable-transports"
+ ln -sf "$PWD" "$GOPATH/src/git.torproject.org/pluggable-transports/obfs4.git"
+ cd obfs4proxy
+ go build -ldflags '-s'
+ cp -a obfs4proxy $PTDIR
+ cd ../..
+
# Grabbing the result
cd $INSTDIR
- ~/build/dzip.sh pluggable-transports-mac$GBUILD_BITS-gbuilt.zip TorBrowserBundle.app
- cp pluggable-transports-mac$GBUILD_BITS-gbuilt.zip $OUTDIR/
+ ~/build/dzip.sh pluggable-transports-mac64-gbuilt.zip TorBrowserBundle.app
+ cp pluggable-transports-mac64-gbuilt.zip $OUTDIR/
1
0

[tor-browser-bundle/master] Merge remote-tracking branch 'origin/master'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit ab8da1c4a840f30f37873132258edc3f9711554b
Merge: 912a830 9f0cacb
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 13:47:37 2014 -0700
Merge remote-tracking branch 'origin/master'
gitian/versions.alpha | 3 +++
1 file changed, 3 insertions(+)
1
0

[tor-browser-bundle/master] Bump obfs4 related tags/commits for 4.5-alpha.
by gk@torproject.org 30 Oct '14
by gk@torproject.org 30 Oct '14
30 Oct '14
commit 9f0cacb1cf6a075e91e4da1a4f56d31cd30b33cf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Oct 30 13:56:04 2014 +0000
Bump obfs4 related tags/commits for 4.5-alpha.
---
gitian/versions.alpha | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index 6c49137..c4b65c3 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -27,6 +27,9 @@ TXSOCKSX_TAG=216eb0894a1755872f4789f9458aa6cf543b8433 # unsigned habnabit/1.13.0
GOPTLIB_TAG=0.2
MEEK_TAG=0.11
FAKETIME_TAG=70aa6b394d9341522dffe8a5a5cf5929e82cc6b9 # unsigned v0.9.6
+GOED25519_TAG=c4161f4c7483313562781c61b9a20aba73daf9de
+GOSIPHASH_TAG=42ba037e748c9062a75e0924705c43b893edefcd
+OBFS4_TAG=0.0.3
GITIAN_TAG=tor-browser-builder-3.x-7
1
0

[torbutton/master] Bug #5926: Allow spoofing of javascript locale to en-US.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit da3286e36773c5ed7e0519dbc4956ef15ee407ff
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Fri Oct 10 15:41:19 2014 -0700
Bug #5926: Allow spoofing of javascript locale to en-US.
---
src/chrome/content/torbutton.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 44020ec..7fddf07 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -2030,6 +2030,7 @@ function torbutton_update_fingerprinting_prefs() {
m_tb_prefs.setCharPref("intl.accept_languages", "en-us, en");
m_tb_prefs.setCharPref("intl.accept_charsets", "iso-8859-1,*,utf-8");
m_tb_prefs.setCharPref("intl.charsetmenu.browser.cache", "UTF-8");
+ m_tb_prefs.setCharPref("javascript.default_locale", "en-US");
} else {
if(m_tb_prefs.prefHasUserValue("intl.accept_languages"))
m_tb_prefs.clearUserPref("intl.accept_languages");
@@ -2037,6 +2038,8 @@ function torbutton_update_fingerprinting_prefs() {
m_tb_prefs.clearUserPref("intl.charsetmenu.browser.cache");
if(m_tb_prefs.prefHasUserValue("intl.accept_charsets"))
m_tb_prefs.clearUserPref("intl.accept_charsets");
+ if(m_tb_prefs.prefHasUserValue("javascript.default_locale"))
+ m_tb_prefs.clearUserPref("javascript.default_locale");
}
} else {
m_tb_prefs.setIntPref("browser.display.max_font_attempts",-1);
1
0

[tor-browser/tor-browser-31.2.0esr-4.5-1] Bug #11955 Backport certificate pinning
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit cd9887977227df33462e755200ac6f6ade351bea
Author: Camilo Viecco <cviecco(a)mozilla.com>
Date: Thu Jun 20 10:35:43 2013 -0700
Bug #11955 Backport certificate pinning
Includes the following Mozilla patches, some modified for Tor Browser:
Bug 744204 - Allow Key pining part 1 - Built-in Pinning Service. r=keeler
Bug 744204 - Allow Certificate key pinning Part 2 - Certverifier Interface. r=keeler
--HG--
extra : rebase_source : 2f9748ba0b241c697e22b7ff72f2f5a0fad4a2ca
Bug 998057: Add test pinset to the pin generator (r=cviecco)
--HG--
rename : security/manager/ssl/tests/unit/tlsserver/default-ee.der => security/manager/boot/src/default-ee.der
Bug 998057: Add tests for certificate pinning (r=cviecco,dkeeler)
Bug 1002696 - Minimum set of changes to make genHPKPStaticPins.js productionizable. r=cviecco, dkeeler
--HG--
rename : security/manager/boot/src/PreloadedHPKPins.json => security/manager/tools/PreloadedHPKPins.json
rename : security/manager/boot/src/genHPKPStaticPins.js => security/manager/tools/genHPKPStaticPins.js
Bug 951315 - Add telemetry to PK pinning. r=dkeeler
Bug 1006107 - Disable pining by default, setup pinning for *.addons.mozilla.org. r=dkeeler
Tor project: only patching two files:
security/manager/ssl/src/nsNSSComponent.cpp
netwerk/base/public/security-prefs.js
--HG--
extra : rebase_source : 93b1dbd5dc31490424060729a3941deffa8ee1d5
Bug 772756: Implement sha1 support, import Chrome's pinsets wholesale, add test mode (r=cviecco,keeler)
Tor project, we only patch:
security/manager/ssl/tests/unit/test_pinning.js
security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
security/manager/ssl/tests/unit/tlsserver/default-ee.der
security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
security/manager/ssl/tests/unit/tlsserver/other-test-ca.der
security/manager/ssl/tests/unit/tlsserver/test-ca.der
Bug 1009720: Telemetry for CERT_PINNING_TEST_RESULTS (r=keeler)
Bug 1007844: Implement per-host telemetry for pin violations for AMO and aus4 (r=keeler)
Only patching toolkit/components/telemetry/Histograms.json
Bug 1011269: Add CertVerifier::pinningEnforceTestMode (r=keeler)
Tor project, only commit:
security/certverifier/CertVerifier.cpp
security/certverifier/CertVerifier.h
security/manager/ssl/src/nsNSSComponent.cpp
Bug 1012882: Restrict pinning to desktop (r=keeler)
Tor Bug #11955: Backport certificate pinning
Bring the following files up to date:
security/manager/boot/src/PublicKeyPinningService.cpp
security/manager/boot/src/PublicKeyPinningService.h
security/manager/boot/src/StaticHPKPins.h
security/manager/ssl/tests/unit/test_pinning.js
security/manager/tools/PreloadedHPKPins.json
security/manager/tools/genHPKPStaticPins.js
security/pkix/include/pkix/Time.h
security/pkix/lib/pkixtime.cpp
---
.gitignore | 2 +-
browser/app/profile/firefox.js | 3 +
modules/libpref/src/init/all.js | 3 +
security/apps/AppTrustDomain.h | 2 +
security/certverifier/CertVerifier.cpp | 225 +++-
security/certverifier/CertVerifier.h | 17 +-
security/certverifier/NSSCertDBTrustDomain.cpp | 35 +-
security/certverifier/NSSCertDBTrustDomain.h | 6 +-
security/certverifier/moz.build | 1 +
.../manager/boot/src/PublicKeyPinningService.cpp | 306 ++++++
.../boot/src/PublicKeyPinningService.cpp.rej | 11 +
.../manager/boot/src/PublicKeyPinningService.h | 35 +
security/manager/boot/src/StaticHPKPins.h | 1095 ++++++++++++++++++++
security/manager/boot/src/moz.build | 6 +
.../manager/ssl/src/SSLServerCertVerification.cpp | 5 +-
security/manager/ssl/src/SharedCertVerifier.h | 6 +-
security/manager/ssl/src/nsCMS.cpp | 5 +-
security/manager/ssl/src/nsNSSCertificate.cpp | 13 +-
security/manager/ssl/src/nsNSSCertificateDB.cpp | 19 +-
security/manager/ssl/src/nsNSSComponent.cpp | 12 +-
security/manager/ssl/src/nsUsageArrayHelper.cpp | 5 +-
security/manager/ssl/tests/unit/head_psm.js | 1 +
.../manager/ssl/tests/unit/test_cert_overrides.js | 2 +-
security/manager/ssl/tests/unit/test_pinning.js | 182 ++++
security/manager/ssl/tests/unit/tlsserver/cert8.db | Bin 65536 -> 65536 bytes
.../ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp | 11 +
.../ssl/tests/unit/tlsserver/default-ee.der | Bin 527 -> 639 bytes
.../ssl/tests/unit/tlsserver/generate_certs.sh | 17 +-
security/manager/ssl/tests/unit/tlsserver/key3.db | Bin 49152 -> 57344 bytes
.../ssl/tests/unit/tlsserver/other-test-ca.der | Bin 452 -> 452 bytes
.../manager/ssl/tests/unit/tlsserver/secmod.db | Bin 16384 -> 16384 bytes
.../manager/ssl/tests/unit/tlsserver/test-ca.der | Bin 440 -> 440 bytes
security/manager/ssl/tests/unit/xpcshell.ini | 4 +
security/manager/tools/PreloadedHPKPins.json | 247 +++++
security/manager/tools/genHPKPStaticPins.js | 576 ++++++++++
security/pkix/include/pkix/Result.h | 174 ++++
security/pkix/include/pkix/Time.h | 126 +++
security/pkix/include/pkix/pkixtypes.h | 5 +
security/pkix/lib/pkixbuild.cpp | 24 +
security/pkix/lib/pkixtime.cpp | 70 ++
toolkit/components/telemetry/Histograms.json | 32 +
41 files changed, 3198 insertions(+), 85 deletions(-)
diff --git a/.gitignore b/.gitignore
index 8df1754..6d17511 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,7 @@ ID
.*.sw[a-z]
# User files that may appear at the root
-/.mozconfig*
+#/.mozconfig*
/mozconfig
/configure
/config.cache
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index 2ec7f9a..b61756d 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1484,6 +1484,9 @@ pref("security.csp.speccompliant", true);
// Block insecure active content on https pages
pref("security.mixed_content.block_active_content", true);
+// 1 = allow MITM for certificate pinning checks.
+pref("security.cert_pinning.enforcement_level", 1);
+
// Override the Gecko-default value of false for Firefox.
pref("plain_text.wrap_long_lines", true);
diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js
index 8efad8f..8a389e3 100644
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1566,6 +1566,9 @@ pref("security.csp.experimentalEnabled", false);
pref("security.mixed_content.block_active_content", false);
pref("security.mixed_content.block_display_content", false);
+// Disable pinning checks by default.
+pref("security.cert_pinning.enforcement_level", 0);
+
// Modifier key prefs: default to Windows settings,
// menu access key = alt, accelerator key = control.
// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 91 for Win, 0 for none. Mac settings in macprefs.js
diff --git a/security/apps/AppTrustDomain.h b/security/apps/AppTrustDomain.h
index 875c1db..d7e4734 100644
--- a/security/apps/AppTrustDomain.h
+++ b/security/apps/AppTrustDomain.h
@@ -35,6 +35,8 @@ public:
/*const*/ CERTCertificate* issuerCertToDup,
PRTime time,
/*optional*/ const SECItem* stapledOCSPresponse);
+ SECStatus IsChainValid(const CERTCertList* certChain) { return SECSuccess; }
+
private:
void* mPinArg; // non-owning!
mozilla::pkix::ScopedCERTCertificate mTrustedRoot;
diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp
index b8b84d7..b2db9fc 100644
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -11,9 +11,11 @@
#include "pkix/pkix.h"
#include "ExtendedValidation.h"
#include "NSSCertDBTrustDomain.h"
+#include "PublicKeyPinningService.h"
#include "cert.h"
#include "ocsp.h"
#include "secerr.h"
+#include "pk11pub.h"
#include "prerror.h"
#include "sslerr.h"
@@ -38,7 +40,8 @@ CertVerifier::CertVerifier(implementation_config ic,
#endif
ocsp_download_config odc,
ocsp_strict_config osc,
- ocsp_get_config ogc)
+ ocsp_get_config ogc,
+ pinning_enforcement_config pel)
: mImplementation(ic)
#ifndef NSS_NO_LIBPKIX
, mMissingCertDownloadEnabled(mcdc == missing_cert_download_on)
@@ -47,6 +50,7 @@ CertVerifier::CertVerifier(implementation_config ic,
, mOCSPDownloadEnabled(odc == ocsp_on)
, mOCSPStrict(osc == ocsp_strict)
, mOCSPGETEnabled(ogc == ocsp_get_enabled)
+ , mPinningEnforcementLevel(pel)
{
}
@@ -64,7 +68,6 @@ InitCertVerifierLog()
#endif
}
-#if 0
// Once we migrate to mozilla::pkix or change the overridable error
// logic this will become unnecesary.
static SECStatus
@@ -95,23 +98,102 @@ insertErrorIntoVerifyLog(CERTCertificate* cert, const PRErrorCode err,
return SECSuccess;
}
-#endif
+
+SECStatus
+IsCertBuiltInRoot(CERTCertificate* cert, bool& result) {
+ result = false;
+ ScopedPtr<PK11SlotList, PK11_FreeSlotList> slots;
+ slots = PK11_GetAllSlotsForCert(cert, nullptr);
+ if (!slots) {
+ if (PORT_GetError() == SEC_ERROR_NO_TOKEN) {
+ // no list
+ return SECSuccess;
+ }
+ return SECFailure;
+ }
+ for (PK11SlotListElement* le = slots->head; le; le = le->next) {
+ char* token = PK11_GetTokenName(le->slot);
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("BuiltInRoot? subject=%s token=%s",cert->subjectName, token));
+ if (strcmp("Builtin Object Token", token) == 0) {
+ result = true;
+ return SECSuccess;
+ }
+ }
+ return SECSuccess;
+}
+
+struct ChainValidationCallbackState
+{
+ const char* hostname;
+ const CertVerifier::pinning_enforcement_config pinningEnforcementLevel;
+ const SECCertificateUsage usage;
+ const PRTime time;
+};
SECStatus chainValidationCallback(void* state, const CERTCertList* certList,
PRBool* chainOK)
{
+ ChainValidationCallbackState* callbackState =
+ reinterpret_cast<ChainValidationCallbackState*>(state);
+
*chainOK = PR_FALSE;
- PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("verifycert: Inside the Callback \n"));
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("verifycert: Inside the Callback \n"));
// On sanity failure we fail closed.
if (!certList) {
- PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("verifycert: Short circuit, callback, "
- "sanity check failed \n"));
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("verifycert: Short circuit, callback, sanity check failed \n"));
+ PR_SetError(PR_INVALID_STATE_ERROR, 0);
+ return SECFailure;
+ }
+ if (!callbackState) {
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("verifycert: Short circuit, callback, no state! \n"));
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return SECFailure;
}
- *chainOK = PR_TRUE;
+
+ if (callbackState->usage != certificateUsageSSLServer ||
+ callbackState->pinningEnforcementLevel == CertVerifier::pinningDisabled) {
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("verifycert: Callback shortcut pel=%d \n",
+ callbackState->pinningEnforcementLevel));
+ *chainOK = PR_TRUE;
+ return SECSuccess;
+ }
+
+ for (CERTCertListNode* node = CERT_LIST_HEAD(certList);
+ !CERT_LIST_END(node, certList);
+ node = CERT_LIST_NEXT(node)) {
+ CERTCertificate* currentCert = node->cert;
+ if (CERT_LIST_END(CERT_LIST_NEXT(node), certList)) {
+ bool isBuiltInRoot = false;
+ SECStatus srv = IsCertBuiltInRoot(currentCert, isBuiltInRoot);
+ if (srv != SECSuccess) {
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("Is BuiltInRoot failure"));
+ return srv;
+ }
+ // If desired, the user can enable "allow user CA MITM mode", in which
+ // case key pinning is not enforced for certificates that chain to trust
+ // anchors that are not in Mozilla's root program
+ if (!isBuiltInRoot &&
+ (callbackState->pinningEnforcementLevel ==
+ CertVerifier::pinningAllowUserCAMITM)) {
+ *chainOK = PR_TRUE;
+ return SECSuccess;
+ }
+ }
+ }
+
+ const bool enforceTestMode = (callbackState->pinningEnforcementLevel ==
+ CertVerifier::pinningEnforceTestMode);
+ *chainOK = PublicKeyPinningService::
+ ChainHasValidPins(certList, callbackState->hostname, callbackState->time,
+ enforceTestMode);
+
return SECSuccess;
}
@@ -120,42 +202,41 @@ ClassicVerifyCert(CERTCertificate* cert,
const SECCertificateUsage usage,
const PRTime time,
void* pinArg,
+ ChainValidationCallbackState* callbackState,
/*optional out*/ ScopedCERTCertList* validationChain,
/*optional out*/ CERTVerifyLog* verifyLog)
{
SECStatus rv;
SECCertUsage enumUsage;
- if (validationChain) {
- switch(usage){
- case certificateUsageSSLClient:
- enumUsage = certUsageSSLClient;
- break;
- case certificateUsageSSLServer:
- enumUsage = certUsageSSLServer;
- break;
- case certificateUsageSSLCA:
- enumUsage = certUsageSSLCA;
- break;
- case certificateUsageEmailSigner:
- enumUsage = certUsageEmailSigner;
- break;
- case certificateUsageEmailRecipient:
- enumUsage = certUsageEmailRecipient;
- break;
- case certificateUsageObjectSigner:
- enumUsage = certUsageObjectSigner;
- break;
- case certificateUsageVerifyCA:
- enumUsage = certUsageVerifyCA;
- break;
- case certificateUsageStatusResponder:
- enumUsage = certUsageStatusResponder;
- break;
- default:
- PR_NOT_REACHED("unexpected usage");
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
+ switch (usage) {
+ case certificateUsageSSLClient:
+ enumUsage = certUsageSSLClient;
+ break;
+ case certificateUsageSSLServer:
+ enumUsage = certUsageSSLServer;
+ break;
+ case certificateUsageSSLCA:
+ enumUsage = certUsageSSLCA;
+ break;
+ case certificateUsageEmailSigner:
+ enumUsage = certUsageEmailSigner;
+ break;
+ case certificateUsageEmailRecipient:
+ enumUsage = certUsageEmailRecipient;
+ break;
+ case certificateUsageObjectSigner:
+ enumUsage = certUsageObjectSigner;
+ break;
+ case certificateUsageVerifyCA:
+ enumUsage = certUsageVerifyCA;
+ break;
+ case certificateUsageStatusResponder:
+ enumUsage = certUsageStatusResponder;
+ break;
+ default:
+ PR_NOT_REACHED("unexpected usage");
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
}
if (usage == certificateUsageSSLServer) {
// SSL server cert verification has always used CERT_VerifyCert, so we
@@ -168,13 +249,38 @@ ClassicVerifyCert(CERTCertificate* cert,
rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), cert, true,
usage, time, pinArg, verifyLog, nullptr);
}
- if (rv == SECSuccess && validationChain) {
- PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("VerifyCert: getting chain in 'classic' \n"));
- *validationChain = CERT_GetCertChainFromCert(cert, time, enumUsage);
- if (!*validationChain) {
- rv = SECFailure;
+
+ if (rv == SECSuccess &&
+ (validationChain || usage == certificateUsageSSLServer)) {
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("VerifyCert: getting chain in 'classic' \n"));
+ ScopedCERTCertList certChain(CERT_GetCertChainFromCert(cert, time,
+ enumUsage));
+ if (!certChain) {
+ return SECFailure;
+ }
+ if (usage == certificateUsageSSLServer) {
+ PRBool chainOK = PR_FALSE;
+ SECStatus srv = chainValidationCallback(callbackState, certChain.get(),
+ &chainOK);
+ if (srv != SECSuccess) {
+ return srv;
+ }
+ if (chainOK != PR_TRUE) {
+ if (verifyLog) {
+ insertErrorIntoVerifyLog(cert,
+ SEC_ERROR_APPLICATION_CALLBACK_ERROR,
+ verifyLog);
+ }
+ PR_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR, 0); // same as libpkix
+ return SECFailure;
+ }
+ }
+ if (rv == SECSuccess && validationChain) {
+ *validationChain = certChain.release();
}
}
+
return rv;
}
@@ -227,6 +333,7 @@ CertVerifier::MozillaPKIXVerifyCert(
const PRTime time,
void* pinArg,
const Flags flags,
+ ChainValidationCallbackState* callbackState,
/*optional*/ const SECItem* stapledOCSPResponse,
/*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain,
/*optional out*/ SECOidTag* evOidPolicy)
@@ -249,6 +356,10 @@ CertVerifier::MozillaPKIXVerifyCert(
return SECFailure;
}
+ CERTChainVerifyCallback callbackContainer;
+ callbackContainer.isChainValid = chainValidationCallback;
+ callbackContainer.isChainValidArg = callbackState;
+
NSSCertDBTrustDomain::OCSPFetching ocspFetching
= !mOCSPDownloadEnabled ||
(flags & FLAG_LOCAL_ONLY) ? NSSCertDBTrustDomain::NeverFetchOCSP
@@ -295,7 +406,7 @@ CertVerifier::MozillaPKIXVerifyCert(
ocspFetching == NSSCertDBTrustDomain::NeverFetchOCSP
? NSSCertDBTrustDomain::LocalOnlyOCSPForEV
: NSSCertDBTrustDomain::FetchOCSPForEV,
- mOCSPCache, pinArg);
+ mOCSPCache, pinArg, &callbackContainer);
rv = BuildCertChainForOneKeyUsage(trustDomain, cert, time,
KeyUsage::digitalSignature, // ECDHE/DHE
KeyUsage::keyEncipherment, // RSA
@@ -321,7 +432,7 @@ CertVerifier::MozillaPKIXVerifyCert(
// Now try non-EV.
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
- pinArg);
+ pinArg, &callbackContainer);
rv = BuildCertChainForOneKeyUsage(trustDomain, cert, time,
KeyUsage::digitalSignature, // (EC)DHE
KeyUsage::keyEncipherment, // RSA
@@ -443,19 +554,25 @@ CertVerifier::MozillaPKIXVerifyCert(
SECStatus
CertVerifier::VerifyCert(CERTCertificate* cert,
- /*optional*/ const SECItem* stapledOCSPResponse,
const SECCertificateUsage usage,
const PRTime time,
void* pinArg,
+ const char* hostname,
const Flags flags,
+ /*optional in*/ const SECItem* stapledOCSPResponse,
/*optional out*/ ScopedCERTCertList* validationChain,
/*optional out*/ SECOidTag* evOidPolicy,
/*optional out*/ CERTVerifyLog* verifyLog)
{
+ ChainValidationCallbackState callbackState = { hostname,
+ mPinningEnforcementLevel,
+ usage,
+ time };
+
if (mImplementation == mozillapkix) {
return MozillaPKIXVerifyCert(cert, usage, time, pinArg, flags,
- stapledOCSPResponse, validationChain,
- evOidPolicy);
+ &callbackState, stapledOCSPResponse,
+ validationChain, evOidPolicy);
}
if (!cert)
@@ -581,7 +698,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert,
CERTChainVerifyCallback callbackContainer;
if (usage == certificateUsageSSLServer) {
callbackContainer.isChainValid = chainValidationCallback;
- callbackContainer.isChainValidArg = nullptr;
+ callbackContainer.isChainValidArg = &callbackState;
cvin[i].type = cert_pi_chainVerifyCallback;
cvin[i].value.pointer.chainVerifyCallback = &callbackContainer;
++i;
@@ -685,8 +802,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert,
if (mImplementation == classic) {
// XXX: we do not care about the localOnly flag (currently) as the
// caller that wants localOnly should disable and reenable the fetching.
- return ClassicVerifyCert(cert, usage, time, pinArg, validationChain,
- verifyLog);
+ return ClassicVerifyCert(cert, usage, time, pinArg, &callbackState,
+ validationChain, verifyLog);
}
#ifdef NSS_NO_LIBPKIX
@@ -826,9 +943,9 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
// CreateCertErrorRunnable assumes that CERT_VerifyCertName is only called
// if VerifyCert succeeded.
ScopedCERTCertList validationChain;
- SECStatus rv = VerifyCert(peerCert, stapledOCSPResponse,
- certificateUsageSSLServer, time,
- pinarg, 0, &validationChain, evOidPolicy);
+ SECStatus rv = VerifyCert(peerCert, certificateUsageSSLServer, time, pinarg,
+ hostname, 0, stapledOCSPResponse, &validationChain,
+ evOidPolicy, nullptr);
if (rv != SECSuccess) {
return rv;
}
diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h
index 09ed4b0..270e9a1 100644
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -12,6 +12,8 @@
namespace mozilla { namespace psm {
+struct ChainValidationCallbackState;
+
class CertVerifier
{
public:
@@ -24,11 +26,12 @@ public:
// *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV
// Only one usage per verification is supported.
SECStatus VerifyCert(CERTCertificate* cert,
- /*optional*/ const SECItem* stapledOCSPResponse,
const SECCertificateUsage usage,
const PRTime time,
void* pinArg,
+ const char* hostname,
const Flags flags = 0,
+ /*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
/*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain = nullptr,
/*optional out*/ SECOidTag* evOidPolicy = nullptr ,
/*optional out*/ CERTVerifyLog* verifyLog = nullptr);
@@ -52,6 +55,13 @@ public:
mozillapkix = 2
};
+ enum pinning_enforcement_config {
+ pinningDisabled = 0,
+ pinningAllowUserCAMITM = 1,
+ pinningStrict = 2,
+ pinningEnforceTestMode = 3
+ };
+
enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on };
enum crl_download_config { crl_local_only = 0, crl_download_allowed };
enum ocsp_download_config { ocsp_off = 0, ocsp_on };
@@ -65,7 +75,8 @@ public:
missing_cert_download_config ac, crl_download_config cdc,
#endif
ocsp_download_config odc, ocsp_strict_config osc,
- ocsp_get_config ogc);
+ ocsp_get_config ogc,
+ pinning_enforcement_config pinningEnforcementLevel);
~CertVerifier();
void ClearOCSPCache() { mOCSPCache.Clear(); }
@@ -78,6 +89,7 @@ public:
const bool mOCSPDownloadEnabled;
const bool mOCSPStrict;
const bool mOCSPGETEnabled;
+ const pinning_enforcement_config mPinningEnforcementLevel;
private:
SECStatus MozillaPKIXVerifyCert(CERTCertificate* cert,
@@ -85,6 +97,7 @@ private:
const PRTime time,
void* pinArg,
const Flags flags,
+ ChainValidationCallbackState* callbackState,
/*optional*/ const SECItem* stapledOCSPResponse,
/*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain,
/*optional out*/ SECOidTag* evOidPolicy);
diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverifier/NSSCertDBTrustDomain.cpp
index 9bed2ce..fd2e363 100644
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -43,11 +43,13 @@ typedef ScopedPtr<SECMODModule, SECMOD_DestroyModule> ScopedSECMODModule;
NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
OCSPFetching ocspFetching,
OCSPCache& ocspCache,
- void* pinArg)
+ void* pinArg,
+ CERTChainVerifyCallback* checkChainCallback)
: mCertDBTrustType(certDBTrustType)
, mOCSPFetching(ocspFetching)
, mOCSPCache(ocspCache)
, mPinArg(pinArg)
+ , mCheckChainCallback(checkChainCallback)
{
}
@@ -475,6 +477,37 @@ NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse(
return rv;
}
+SECStatus
+NSSCertDBTrustDomain::IsChainValid(const CERTCertList* certChain) {
+ SECStatus rv = SECFailure;
+
+ PR_LOG(gCertVerifierLog, PR_LOG_DEBUG,
+ ("NSSCertDBTrustDomain: Top of IsChainValid mCheckCallback=%p",
+ mCheckChainCallback));
+
+ if (!mCheckChainCallback) {
+ return SECSuccess;
+ }
+ if (!mCheckChainCallback->isChainValid) {
+ PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
+ return SECFailure;
+ }
+ PRBool chainOK;
+ rv = (mCheckChainCallback->isChainValid)(mCheckChainCallback->isChainValidArg,
+ certChain, &chainOK);
+ if (rv != SECSuccess) {
+ return rv;
+ }
+ // rv = SECSuccess only implies successful call, now is time
+ // to check the chain check status
+ // we should only return success if the chain is valid
+ if (chainOK) {
+ return SECSuccess;
+ }
+ PR_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR, 0);
+ return SECFailure;
+}
+
namespace {
static char*
diff --git a/security/certverifier/NSSCertDBTrustDomain.h b/security/certverifier/NSSCertDBTrustDomain.h
index 979c3e2..c2f211d 100644
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -57,7 +57,8 @@ public:
LocalOnlyOCSPForEV = 4,
};
NSSCertDBTrustDomain(SECTrustType certDBTrustType, OCSPFetching ocspFetching,
- OCSPCache& ocspCache, void* pinArg);
+ OCSPCache& ocspCache, void* pinArg,
+ CERTChainVerifyCallback* checkChainCallback = nullptr);
virtual SECStatus FindPotentialIssuers(
const SECItem* encodedIssuerName,
@@ -78,6 +79,8 @@ public:
PRTime time,
/*optional*/ const SECItem* stapledOCSPResponse);
+ virtual SECStatus IsChainValid(const CERTCertList* certChain);
+
private:
enum EncodedResponseSource {
ResponseIsFromNetwork = 1,
@@ -93,6 +96,7 @@ private:
const OCSPFetching mOCSPFetching;
OCSPCache& mOCSPCache; // non-owning!
void* mPinArg; // non-owning!
+ CERTChainVerifyCallback* mCheckChainCallback; // non-owning!
};
} } // namespace mozilla::psm
diff --git a/security/certverifier/moz.build b/security/certverifier/moz.build
index 5e99b12..434c3cc 100644
--- a/security/certverifier/moz.build
+++ b/security/certverifier/moz.build
@@ -17,6 +17,7 @@ if not CONFIG['NSS_NO_EV_CERTS']:
]
LOCAL_INCLUDES += [
+ '../manager/boot/src',
'../manager/ssl/src',
'../pkix/include',
]
diff --git a/security/manager/boot/src/PublicKeyPinningService.cpp b/security/manager/boot/src/PublicKeyPinningService.cpp
new file mode 100644
index 0000000..82abaaf
--- /dev/null
+++ b/security/manager/boot/src/PublicKeyPinningService.cpp
@@ -0,0 +1,306 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PublicKeyPinningService.h"
+#include "pkix/nullptr.h"
+#include "StaticHPKPins.h" // autogenerated by genHPKPStaticpins.js
+
+#include "cert.h"
+#include "mozilla/Base64.h"
+#include "mozilla/Telemetry.h"
+#include "nsString.h"
+#include "nssb64.h"
+#include "pkix/pkixtypes.h"
+#include "prlog.h"
+#include "ScopedNSSTypes.h"
+#include "seccomon.h"
+#include "sechash.h"
+
+using namespace mozilla;
+using namespace mozilla::pkix;
+using namespace mozilla::psm;
+
+#if defined(PR_LOGGING)
+PRLogModuleInfo* gPublicKeyPinningLog =
+ PR_NewLogModule("PublicKeyPinningService");
+#endif
+
+/**
+ Computes in the location specified by base64Out the SHA256 digest
+ of the DER Encoded subject Public Key Info for the given cert
+*/
+static SECStatus
+GetBase64HashSPKI(const CERTCertificate* cert, SECOidTag hashType,
+ nsACString& hashSPKIDigest)
+{
+ hashSPKIDigest.Truncate();
+ Digest digest;
+ nsresult rv = digest.DigestBuf(hashType, cert->derPublicKey.data,
+ cert->derPublicKey.len);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return SECFailure;
+ }
+ rv = Base64Encode(nsDependentCSubstring(
+ reinterpret_cast<const char*>(digest.get().data),
+ digest.get().len),
+ hashSPKIDigest);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/*
+ * Returns true if a given cert matches any hashType fingerprints from the
+ * given pinset, false otherwise.
+ */
+static bool
+EvalCertWithHashType(const CERTCertificate* cert, SECOidTag hashType,
+ const StaticFingerprints* fingerprints)
+{
+ if (!fingerprints) {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: No hashes found for hash type: %d\n", hashType));
+ return false;
+ }
+
+ nsAutoCString base64Out;
+ SECStatus srv = GetBase64HashSPKI(cert, hashType, base64Out);
+ if (srv != SECSuccess) {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: GetBase64HashSPKI failed!\n"));
+ return false;
+ }
+
+ for (size_t i = 0; i < fingerprints->size; i++) {
+ if (base64Out.Equals(fingerprints->data[i])) {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: found pin base_64 ='%s'\n", base64Out.get()));
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ * Returns true if a given chain matches any hashType fingerprints from the
+ * given pinset, false otherwise.
+ */
+static bool
+EvalChainWithHashType(const CERTCertList* certList, SECOidTag hashType,
+ const StaticPinset* pinset)
+{
+ CERTCertificate* currentCert;
+
+ const StaticFingerprints* fingerprints = nullptr;
+ if (hashType == SEC_OID_SHA256) {
+ fingerprints = pinset->sha256;
+ } else if (hashType == SEC_OID_SHA1) {
+ fingerprints = pinset->sha1;
+ }
+ if (!fingerprints) {
+ return false;
+ }
+
+ CERTCertListNode* node;
+ for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
+ node = CERT_LIST_NEXT(node)) {
+ currentCert = node->cert;
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: certArray subject: '%s'\n",
+ currentCert->subjectName));
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: certArray common_name: '%s'\n",
+ CERT_GetCommonName(&(currentCert->issuer))));
+ if (EvalCertWithHashType(currentCert, hashType, fingerprints)) {
+ return true;
+ }
+ }
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG, ("pkpin: no matches found\n"));
+ return false;
+}
+
+/**
+ * Given a pinset and certlist, return true if one of the certificates on
+ * the list matches a fingerprint in the pinset, false otherwise.
+ */
+static bool
+EvalChainWithPinset(const CERTCertList* certList,
+ const StaticPinset* pinset) {
+ // SHA256 is more trustworthy, try that first.
+ if (EvalChainWithHashType(certList, SEC_OID_SHA256, pinset)) {
+ return true;
+ }
+ return EvalChainWithHashType(certList, SEC_OID_SHA1, pinset);
+}
+
+/**
+ Comparator for the is public key pinned host.
+*/
+static int
+TransportSecurityPreloadCompare(const void *key, const void *entry) {
+ const char *keyStr = reinterpret_cast<const char *>(key);
+ const TransportSecurityPreload *preloadEntry =
+ reinterpret_cast<const TransportSecurityPreload *>(entry);
+
+ return strcmp(keyStr, preloadEntry->mHost);
+}
+
+/**
+ * Check PKPins on the given certlist against the specified hostname
+ */
+static bool
+CheckPinsForHostname(const CERTCertList *certList, const char *hostname,
+ bool enforceTestMode)
+{
+ if (!certList) {
+ return false;
+ }
+ if (!hostname || hostname[0] == 0) {
+ return false;
+ }
+
+ TransportSecurityPreload *foundEntry = nullptr;
+ char *evalHost = const_cast<char*>(hostname);
+ char *evalPart;
+ // Notice how the (xx = strchr) prevents pins for unqualified domain names.
+ while (!foundEntry && (evalPart = strchr(evalHost, '.'))) {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: Querying pinsets for host: '%s'\n", evalHost));
+ foundEntry = (TransportSecurityPreload *)bsearch(evalHost,
+ kPublicKeyPinningPreloadList,
+ sizeof(kPublicKeyPinningPreloadList) / sizeof(TransportSecurityPreload),
+ sizeof(TransportSecurityPreload),
+ TransportSecurityPreloadCompare);
+ if (foundEntry) {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: Found pinset for host: '%s'\n", evalHost));
+ if (evalHost != hostname) {
+ if (!foundEntry->mIncludeSubdomains) {
+ // Does not apply to this host, continue iterating
+ foundEntry = nullptr;
+ }
+ }
+ } else {
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: Didn't find pinset for host: '%s'\n", evalHost));
+ }
+ // Add one for '.'
+ evalHost = evalPart + 1;
+ }
+
+ if (foundEntry && foundEntry->pinset) {
+ bool result = EvalChainWithPinset(certList, foundEntry->pinset);
+ bool retval = result;
+ Telemetry::ID histogram = foundEntry->mIsMoz
+ ? Telemetry::CERT_PINNING_MOZ_RESULTS
+ : Telemetry::CERT_PINNING_RESULTS;
+ if (foundEntry->mTestMode) {
+ histogram = foundEntry->mIsMoz
+ ? Telemetry::CERT_PINNING_MOZ_TEST_RESULTS
+ : Telemetry::CERT_PINNING_TEST_RESULTS;
+ if (!enforceTestMode) {
+ retval = true;
+ }
+ }
+ // We can collect per-host pinning violations for this host because it is
+ // operationally critical to Firefox.
+ if (foundEntry->mId != kUnknownId) {
+ int32_t bucket = foundEntry->mId * 2 + (result ? 1 : 0);
+ histogram = foundEntry->mTestMode
+ ? Telemetry::CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST
+ : Telemetry::CERT_PINNING_MOZ_RESULTS_BY_HOST;
+ Telemetry::Accumulate(histogram, bucket);
+ } else {
+ Telemetry::Accumulate(histogram, result ? 1 : 0);
+ }
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: Pin check %s for %s host '%s' (mode=%s)\n",
+ result ? "passed" : "failed",
+ foundEntry->mIsMoz ? "mozilla" : "non-mozilla",
+ hostname, foundEntry->mTestMode ? "test" : "production"));
+ return retval;
+ }
+ return true; // No pinning information for this hostname
+}
+
+/**
+ * Extract all the DNS names for a host (including CN) and evaluate the
+ * certifiate pins against all of them (Currently is an OR so we stop
+ * evaluating at the first OK pin).
+ */
+static bool
+CheckChainAgainstAllNames(const CERTCertList* certList, bool enforceTestMode)
+{
+ PR_LOG(gPublicKeyPinningLog, PR_LOG_DEBUG,
+ ("pkpin: top of checkChainAgainstAllNames"));
+ CERTCertListNode* node = CERT_LIST_HEAD(certList);
+ if (!node) {
+ return false;
+ }
+ CERTCertificate* cert = node->cert;
+ if (!cert) {
+ return false;
+ }
+
+ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
+ if (!arena) {
+ return false;
+ }
+
+ bool hasValidPins = false;
+ CERTGeneralName* nameList;
+ CERTGeneralName* currentName;
+ nameList = CERT_GetConstrainedCertificateNames(cert, arena.get(), PR_TRUE);
+ if (!nameList) {
+ return false;
+ }
+
+ currentName = nameList;
+ do {
+ if (currentName->type == certDNSName
+ && currentName->name.other.data[0] != 0) {
+ // no need to cleaup, as the arena cleanup will do
+ char *hostName = (char *)PORT_ArenaAlloc(arena.get(),
+ currentName->name.other.len + 1);
+ if (!hostName) {
+ break;
+ }
+ // We use a temporary buffer as the hostname as returned might not be
+ // null terminated.
+ hostName[currentName->name.other.len] = 0;
+ memcpy(hostName, currentName->name.other.data,
+ currentName->name.other.len);
+ if (!hostName[0]) {
+ // cannot call CheckPinsForHostname on empty or null hostname
+ break;
+ }
+ if (CheckPinsForHostname(certList, hostName, enforceTestMode)) {
+ hasValidPins = true;
+ break;
+ }
+ }
+ currentName = CERT_GetNextGeneralName(currentName);
+ } while (currentName != nameList);
+
+ return hasValidPins;
+}
+
+bool
+PublicKeyPinningService::ChainHasValidPins(const CERTCertList* certList,
+ const char* hostname,
+ const PRTime time,
+ bool enforceTestMode)
+{
+ if (!certList) {
+ return false;
+ }
+ if (time > kPreloadPKPinsExpirationTime) {
+ return true;
+ }
+ if (!hostname || hostname[0] == 0) {
+ return CheckChainAgainstAllNames(certList, enforceTestMode);
+ }
+ return CheckPinsForHostname(certList, hostname, enforceTestMode);
+}
diff --git a/security/manager/boot/src/PublicKeyPinningService.cpp.rej b/security/manager/boot/src/PublicKeyPinningService.cpp.rej
new file mode 100644
index 0000000..e88f91b
--- /dev/null
+++ b/security/manager/boot/src/PublicKeyPinningService.cpp.rej
@@ -0,0 +1,11 @@
+diff a/security/manager/boot/src/PublicKeyPinningService.cpp b/security/manager/boot/src/PublicKeyPinningService.cpp (rejected hunks)
+@@ -296,7 +296,8 @@ PublicKeyPinningService::ChainHasValidPins(const CERTCertList* certList,
+ if (!certList) {
+ return false;
+ }
+- if (time > TimeFromElapsedSecondsAD(kPreloadPKPinsExpirationTime)) {
++ if (time > TimeFromEpochInSeconds(kPreloadPKPinsExpirationTime /
++ PR_USEC_PER_SEC)) {
+ return true;
+ }
+ if (!hostname || hostname[0] == 0) {
diff --git a/security/manager/boot/src/PublicKeyPinningService.h b/security/manager/boot/src/PublicKeyPinningService.h
new file mode 100644
index 0000000..978c5ec
--- /dev/null
+++ b/security/manager/boot/src/PublicKeyPinningService.h
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef PublicKeyPinningService_h
+#define PublicKeyPinningService_h
+
+#include "cert.h"
+
+namespace mozilla {
+namespace psm {
+
+class PublicKeyPinningService
+{
+public:
+ /**
+ * Returns true if the given (host, certList) passes pinning checks,
+ * false otherwise. If the host is pinned, return true if one of the keys in
+ * the given certificate chain matches the pin set specified by the
+ * hostname. If the hostname is null or empty evaluate against all the
+ * possible names for the EE cert (Common Name (CN) plus all DNS Name:
+ * subject Alt Name entries). The certList's head is the EE cert and the
+ * tail is the trust anchor.
+ * Note: if an alt name is a wildcard, it won't necessarily find a pinset
+ * that would otherwise be valid for it
+ */
+ static bool ChainHasValidPins(const CERTCertList* certList,
+ const char* hostname,
+ const PRTime,
+ bool enforceTestMode);
+};
+
+}} // namespace mozilla::psm
+
+#endif // PublicKeyPinningServiceService_h
diff --git a/security/manager/boot/src/StaticHPKPins.h b/security/manager/boot/src/StaticHPKPins.h
new file mode 100644
index 0000000..4506489
--- /dev/null
+++ b/security/manager/boot/src/StaticHPKPins.h
@@ -0,0 +1,1095 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*****************************************************************************/
+/* This is an automatically generated file. If you're not */
+/* PublicKeyPinningService.cpp, you shouldn't be #including it. */
+/*****************************************************************************/
+#include <stdint.h>
+/* AddTrust External Root */
+static const char kAddTrust_External_RootFingerprint[] =
+ "lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=";
+
+/* AddTrust Low-Value Services Root */
+static const char kAddTrust_Low_Value_Services_RootFingerprint[] =
+ "BStocQfshOhzA4JFLsKidFF0XXSFpX1vRk4Np6G2ryo=";
+
+/* AddTrust Public Services Root */
+static const char kAddTrust_Public_Services_RootFingerprint[] =
+ "OGHXtpYfzbISBFb/b8LrdwSxp0G0vZM6g3b14ZFcppg=";
+
+/* AddTrust Qualified Certificates Root */
+static const char kAddTrust_Qualified_Certificates_RootFingerprint[] =
+ "xzr8Lrp3DQy8HuQfJStS6Kk9ErctzOwDHY2DnL+Bink=";
+
+/* AffirmTrust Commercial */
+static const char kAffirmTrust_CommercialFingerprint[] =
+ "bEZLmlsjOl6HTadlwm8EUBDS3c/0V5TwtMfkqvpQFJU=";
+
+/* AffirmTrust Networking */
+static const char kAffirmTrust_NetworkingFingerprint[] =
+ "lAcq0/WPcPkwmOWl9sBMlscQvYSdgxhJGa6Q64kK5AA=";
+
+/* AffirmTrust Premium */
+static const char kAffirmTrust_PremiumFingerprint[] =
+ "x/Q7TPW3FWgpT4IrU3YmBfbd0Vyt7Oc56eLDy6YenWc=";
+
+/* AffirmTrust Premium ECC */
+static const char kAffirmTrust_Premium_ECCFingerprint[] =
+ "MhmwkRT/SVo+tusAwu/qs0ACrl8KVsdnnqCHo/oDfk8=";
+
+/* America Online Root Certification Authority 1 */
+static const char kAmerica_Online_Root_Certification_Authority_1Fingerprint[] =
+ "I4SdCUkj1EpIgbY6sYXpvhWqyO8sMETZNLx/JuLSzWk=";
+
+/* America Online Root Certification Authority 2 */
+static const char kAmerica_Online_Root_Certification_Authority_2Fingerprint[] =
+ "/PfamDYD6IhiAw2WE32OEwMbrftNVsH9TKzDOfa9uyo=";
+
+/* Baltimore CyberTrust Root */
+static const char kBaltimore_CyberTrust_RootFingerprint[] =
+ "Y9mvm0exBk1JoQ57f9Vm28jKo5lFm/woKcVxrYxu80o=";
+
+/* COMODO Certification Authority */
+static const char kCOMODO_Certification_AuthorityFingerprint[] =
+ "AG1751Vd2CAmRCxPGieoDomhmJy4ezREjtIZTBgZbV4=";
+
+/* COMODO ECC Certification Authority */
+static const char kCOMODO_ECC_Certification_AuthorityFingerprint[] =
+ "58qRu/uxh4gFezqAcERupSkRYBlBAvfcw7mEjGPLnNU=";
+
+/* Comodo AAA Services root */
+static const char kComodo_AAA_Services_rootFingerprint[] =
+ "vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM=";
+
+/* Comodo Secure Services root */
+static const char kComodo_Secure_Services_rootFingerprint[] =
+ "RpHL/ehKa2BS3b4VK7DCFq4lqG5XR4E9vA8UfzOFcL4=";
+
+/* Comodo Trusted Services root */
+static const char kComodo_Trusted_Services_rootFingerprint[] =
+ "4tiR77c4ZpEF1TDeXtcuKyrD9KZweLU0mz/ayklvXrg=";
+
+/* Cybertrust Global Root */
+static const char kCybertrust_Global_RootFingerprint[] =
+ "foeCwVDOOVL4AuY2AjpdPpW7XWjjPoWtsroXgSXOvxU=";
+
+/* DigiCert Assured ID Root CA */
+static const char kDigiCert_Assured_ID_Root_CAFingerprint[] =
+ "I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=";
+
+/* DigiCert ECC Secure Server CA */
+static const char kDigiCert_ECC_Secure_Server_CAFingerprint[] =
+ "PZXN3lRAy+8tBKk2Ox6F7jIlnzr2Yzmwqc3JnyfXoCw=";
+
+/* DigiCert Global Root CA */
+static const char kDigiCert_Global_Root_CAFingerprint[] =
+ "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=";
+
+/* DigiCert High Assurance EV Root CA */
+static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[] =
+ "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
+
+/* End Entity Test Cert */
+static const char kEnd_Entity_Test_CertFingerprint[] =
+ "pVVgLk2kFI2WWRPwDMIX6YmzFhEW4DXQV/U5gP+feGA=";
+
+/* Entrust Root Certification Authority */
+static const char kEntrust_Root_Certification_AuthorityFingerprint[] =
+ "bb+uANN7nNc/j7R95lkXrwDg3d9C286sIMF8AnXuIJU=";
+
+/* Entrust.net Premium 2048 Secure Server CA */
+static const char kEntrust_net_Premium_2048_Secure_Server_CAFingerprint[] =
+ "HqPF5D7WbC2imDpCpKebHpBnhs6fG1hiFBmgBGOofTg=";
+
+/* Equifax Secure CA */
+static const char kEquifax_Secure_CAFingerprint[] =
+ "/1aAzXOlcD2gSBegdf1GJQanNQbEuBoVg+9UlHjSZHY=";
+
+/* Equifax Secure Global eBusiness CA */
+static const char kEquifax_Secure_Global_eBusiness_CAFingerprint[] =
+ "pvH5v4oKndwID7SbHvw9GhwsMtwOE2pbAMlzFvKj3BE=";
+
+/* Equifax Secure eBusiness CA 1 */
+static const char kEquifax_Secure_eBusiness_CA_1Fingerprint[] =
+ "JsGNxu6m9jL2drzrodjCtINS8pwtX82oeOCdy4Mt1uU=";
+
+/* GOOGLE_PIN_AlphaSSL_G2 */
+static const char kGOOGLE_PIN_AlphaSSL_G2Fingerprint[] =
+ "yxgiWGK++SFB9ySwt3M3qpn5HO0ZLFY5D+h+G/vcT/c=";
+
+/* GOOGLE_PIN_CryptoCat1 */
+static const char kGOOGLE_PIN_CryptoCat1Fingerprint[] =
+ "vKaqtTLWmVuXPVJE+0OqN5sRc4VCcSQHI/W3XTDVR24=";
+
+/* GOOGLE_PIN_EntrustRootEC1 */
+static const char kGOOGLE_PIN_EntrustRootEC1Fingerprint[] =
+ "/qK31kX7pz11PB7Jp4cMQOH3sMVh6Se5hb9xGGbjbyI=";
+
+/* GOOGLE_PIN_Entrust_G2 */
+static const char kGOOGLE_PIN_Entrust_G2Fingerprint[] =
+ "du6FkDdMcVQ3u8prumAo6t3i3G27uMP2EOhR8R0at/U=";
+
+/* GOOGLE_PIN_Entrust_SSL */
+static const char kGOOGLE_PIN_Entrust_SSLFingerprint[] =
+ "nsxRNo6G40YPZsKV5JQt1TCA8nseQQr/LRqp1Oa8fnw=";
+
+/* GOOGLE_PIN_GoDaddySecure */
+static const char kGOOGLE_PIN_GoDaddySecureFingerprint[] =
+ "MrZLZnJ6IGPkBm87lYywqu5Xal7O/ZUzmbuIdHMdlYc=";
+
+/* GOOGLE_PIN_Libertylavabitcom */
+static const char kGOOGLE_PIN_LibertylavabitcomFingerprint[] =
+ "WnKzsDXgqPtS1KvtImrhQPqcxfpmfssuI2cSJt4LMks=";
+
+/* GOOGLE_PIN_RapidSSL */
+static const char kGOOGLE_PIN_RapidSSLFingerprint[] =
+ "lT09gPUeQfbYrlxRtpsHrjDblj9Rpz+u7ajfCrg4qDM=";
+
+/* GOOGLE_PIN_Tor2web */
+static const char kGOOGLE_PIN_Tor2webFingerprint[] =
+ "99ogQzjMuUTBkG1ZP7FME0K4kvBEti8Buzu4nZjRItM=";
+
+/* GTE CyberTrust Global Root */
+static const char kGTE_CyberTrust_Global_RootFingerprint[] =
+ "EGn6R6CqT4z3ERscrqNl7q7RC//zJmDe9uBhS/rnCHU=";
+
+/* GeoTrust Global CA */
+static const char kGeoTrust_Global_CAFingerprint[] =
+ "h6801m+z8v3zbgkRHpq6L29Esgfzhj89C1SyUCOQmqU=";
+
+/* GeoTrust Global CA 2 */
+static const char kGeoTrust_Global_CA_2Fingerprint[] =
+ "F3VaXClfPS1y5vAxofB/QAxYi55YKyLxfq4xoVkNEYU=";
+
+/* GeoTrust Primary Certification Authority */
+static const char kGeoTrust_Primary_Certification_AuthorityFingerprint[] =
+ "SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=";
+
+/* GeoTrust Primary Certification Authority - G2 */
+static const char kGeoTrust_Primary_Certification_Authority___G2Fingerprint[] =
+ "vPtEqrmtAhAVcGtBIep2HIHJ6IlnWQ9vlK50TciLePs=";
+
+/* GeoTrust Primary Certification Authority - G3 */
+static const char kGeoTrust_Primary_Certification_Authority___G3Fingerprint[] =
+ "q5hJUnat8eyv8o81xTBIeB5cFxjaucjmelBPT2pRMo8=";
+
+/* GeoTrust Universal CA */
+static const char kGeoTrust_Universal_CAFingerprint[] =
+ "lpkiXF3lLlbN0y3y6W0c/qWqPKC7Us2JM8I7XCdEOCA=";
+
+/* GeoTrust Universal CA 2 */
+static const char kGeoTrust_Universal_CA_2Fingerprint[] =
+ "fKoDRlEkWQxgHlZ+UhSOlSwM/+iQAFMP4NlbbVDqrkE=";
+
+/* GlobalSign Root CA */
+static const char kGlobalSign_Root_CAFingerprint[] =
+ "K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=";
+
+/* GlobalSign Root CA - R2 */
+static const char kGlobalSign_Root_CA___R2Fingerprint[] =
+ "iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0=";
+
+/* GlobalSign Root CA - R3 */
+static const char kGlobalSign_Root_CA___R3Fingerprint[] =
+ "cGuxAXyFXFkWm61cF4HPWX8S0srS9j0aSqN0k4AP+4A=";
+
+/* Go Daddy Class 2 CA */
+static const char kGo_Daddy_Class_2_CAFingerprint[] =
+ "VjLZe/p3W/PJnd6lL8JVNBCGQBZynFLdZSTIqcO0SJ8=";
+
+/* Go Daddy Root Certificate Authority - G2 */
+static const char kGo_Daddy_Root_Certificate_Authority___G2Fingerprint[] =
+ "Ko8tivDrEjiY90yGasP6ZpBU4jwXvHqVvQI0GS3GNdA=";
+
+/* GoogleBackup2048 */
+static const char kGoogleBackup2048Fingerprint[] =
+ "vq7OyjSnqOco9nyMCDGdy77eijM=";
+
+/* GoogleG2 */
+static const char kGoogleG2Fingerprint[] =
+ "Q9rWMO5T+KmAym79hfRqo3mQ4Oo=";
+
+/* Network Solutions Certificate Authority */
+static const char kNetwork_Solutions_Certificate_AuthorityFingerprint[] =
+ "MtGA7THJNVieydu7ciEjuIO1/C3BD5/KOpXXfhv8tTQ=";
+
+/* Starfield Class 2 CA */
+static const char kStarfield_Class_2_CAFingerprint[] =
+ "FfFKxFycfaIz00eRZOgTf+Ne4POK6FgYPwhBDqgqxLQ=";
+
+/* Starfield Root Certificate Authority - G2 */
+static const char kStarfield_Root_Certificate_Authority___G2Fingerprint[] =
+ "gI1os/q0iEpflxrOfRBVDXqVoWN3Tz7Dav/7IT++THQ=";
+
+/* Starfield Services Root Certificate Authority - G2 */
+static const char kStarfield_Services_Root_Certificate_Authority___G2Fingerprint[] =
+ "KwccWaCgrnaw6tsrrSO61FgLacNgG2MMLq8GE6+oP5I=";
+
+/* StartCom Certification Authority */
+static const char kStartCom_Certification_AuthorityFingerprint[] =
+ "5C8kvU039KouVrl52D0eZSGf4Onjo4Khs8tmyTlV3nU=";
+
+/* StartCom Certification Authority G2 */
+static const char kStartCom_Certification_Authority_G2Fingerprint[] =
+ "FSg5faISiQqDCwuVpZlozvI0dzd531GBzxD6ZHU0u2U=";
+
+/* TC TrustCenter Class 2 CA II */
+static const char kTC_TrustCenter_Class_2_CA_IIFingerprint[] =
+ "rPZeHWLLWKK6/W/6tA+4hpnEc5fPXLSD1C1pytNM1Is=";
+
+/* TC TrustCenter Class 3 CA II */
+static const char kTC_TrustCenter_Class_3_CA_IIFingerprint[] =
+ "k5KuIUmSSt435kXbof9L3dzaKykbYJdmnSr6XHo3Jhk=";
+
+/* TC TrustCenter Universal CA I */
+static const char kTC_TrustCenter_Universal_CA_IFingerprint[] =
+ "st71NirT+s0EvSkEekOET3ZwNOpIkvgOVr7mkCQ+JQI=";
+
+/* TC TrustCenter Universal CA III */
+static const char kTC_TrustCenter_Universal_CA_IIIFingerprint[] =
+ "q1zbM1Y5c1bW5pGXPCW4YYtl12qQSG6nqKXBd2f0Zzo=";
+
+/* TestSPKI */
+static const char kTestSPKIFingerprint[] =
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAA=";
+
+/* Thawte Premium Server CA */
+static const char kThawte_Premium_Server_CAFingerprint[] =
+ "9TwiBZgX3Zb0AGUWOdL4V+IQcKWavtkHlADZ9pVQaQA=";
+
+/* Thawte Server CA */
+static const char kThawte_Server_CAFingerprint[] =
+ "nG9qEjy6pO402+zu4kyX1ziHjLQj88InOQNCT10fbdU=";
+
+/* Tor1 */
+static const char kTor1Fingerprint[] =
+ "juNxSTv9UANmpC9kF5GKpmWNx3Y=";
+
+/* Tor2 */
+static const char kTor2Fingerprint[] =
+ "lia43lPolzSPVIq34Dw57uYcLD8=";
+
+/* Tor3 */
+static const char kTor3Fingerprint[] =
+ "rzEyQIKOh77j87n5bjWUNguXF8Y=";
+
+/* Twitter1 */
+static const char kTwitter1Fingerprint[] =
+ "Vv7zwhR9TtOIN/29MFI4cgHld40=";
+
+/* UTN DATACorp SGC Root CA */
+static const char kUTN_DATACorp_SGC_Root_CAFingerprint[] =
+ "QAL80xHQczFWfnG82XHkYEjI3OjRZZcRdTs9qiommvo=";
+
+/* UTN USERFirst Email Root CA */
+static const char kUTN_USERFirst_Email_Root_CAFingerprint[] =
+ "Laj56jRU0hFGRko/nQKNxMf7tXscUsc8KwVyovWZotM=";
+
+/* UTN USERFirst Hardware Root CA */
+static const char kUTN_USERFirst_Hardware_Root_CAFingerprint[] =
+ "TUDnr0MEoJ3of7+YliBMBVFB4/gJsv5zO7IxD9+YoWI=";
+
+/* UTN USERFirst Object Root CA */
+static const char kUTN_USERFirst_Object_Root_CAFingerprint[] =
+ "D+FMJksXu28NZT56cOs2Pb9UvhWAOe3a5cJXEd9IwQM=";
+
+/* VeriSign Class 3 Public Primary Certification Authority - G4 */
+static const char kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint[] =
+ "UZJDjsNp1+4M5x9cbbdflB779y5YRBcV6Z6rBMLIrO4=";
+
+/* VeriSign Class 3 Public Primary Certification Authority - G5 */
+static const char kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint[] =
+ "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg=";
+
+/* VeriSign Universal Root Certification Authority */
+static const char kVeriSign_Universal_Root_Certification_AuthorityFingerprint[] =
+ "lnsM2T/O9/J84sJFdnrpsFp3awZJ+ZZbYpCWhGloaHI=";
+
+/* Verisign Class 1 Public Primary Certification Authority */
+static const char kVerisign_Class_1_Public_Primary_Certification_AuthorityFingerprint[] =
+ "LclHC+Y+9KzxvYKGCUArt7h72ZY4pkOTTohoLRvowwg=";
+
+/* Verisign Class 1 Public Primary Certification Authority - G3 */
+static const char kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint[] =
+ "IgduWu9Eu5pBaii30cRDItcFn2D+/6XK9sW+hEeJEwM=";
+
+/* Verisign Class 2 Public Primary Certification Authority - G2 */
+static const char kVerisign_Class_2_Public_Primary_Certification_Authority___G2Fingerprint[] =
+ "2oALgLKofTmeZvoZ1y/fSZg7R9jPMix8eVA6DH4o/q8=";
+
+/* Verisign Class 2 Public Primary Certification Authority - G3 */
+static const char kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint[] =
+ "cAajgxHlj7GTSEIzIYIQxmEloOSoJq7VOaxWHfv72QM=";
+
+/* Verisign Class 3 Public Primary Certification Authority */
+static const char kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint[] =
+ "sRJBQqWhpaKIGcc1NA7/jJ4vgWj+47oYfyU7waOS1+I=";
+
+/* Verisign Class 3 Public Primary Certification Authority - G2 */
+static const char kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint[] =
+ "AjyBzOjnxk+pQtPBUEhwfTXZu1uH9PVExb8bxWQ68vo=";
+
+/* Verisign Class 3 Public Primary Certification Authority - G3 */
+static const char kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint[] =
+ "SVqWumuteCQHvVIaALrOZXuzVVVeS7f4FGxxu6V+es4=";
+
+/* Verisign Class 4 Public Primary Certification Authority - G3 */
+static const char kVerisign_Class_4_Public_Primary_Certification_Authority___G3Fingerprint[] =
+ "VnuCEf0g09KD7gzXzgZyy52ZvFtIeljJ1U7Gf3fUqPU=";
+
+/* XRamp Global CA Root */
+static const char kXRamp_Global_CA_RootFingerprint[] =
+ "BRz5+pXkDpuD7a7aaWH2Fox4ecRmAXJHnN1RqwPOpis=";
+
+/* thawte Primary Root CA */
+static const char kthawte_Primary_Root_CAFingerprint[] =
+ "HXXQgxueCIU5TTLHob/bPbwcKOKw6DkfsTWYHbxbqTY=";
+
+/* thawte Primary Root CA - G2 */
+static const char kthawte_Primary_Root_CA___G2Fingerprint[] =
+ "Z9xPMvoQ59AaeaBzqgyeAhLsL/w9d54Kp/nA8OHCyJM=";
+
+/* thawte Primary Root CA - G3 */
+static const char kthawte_Primary_Root_CA___G3Fingerprint[] =
+ "GQbGEk27Q4V40A4GbVBUxsN/D6YCjAVUXgmU7drshik=";
+
+/* Pinsets are each an ordered list by the actual value of the fingerprint */
+struct StaticFingerprints {
+ const size_t size;
+ const char* const* data;
+};
+
+struct StaticPinset {
+ const StaticFingerprints* sha1;
+ const StaticFingerprints* sha256;
+};
+
+/* PreloadedHPKPins.json pinsets */
+static const char* kPinset_facebook_sha256_Data[] = {
+ kDigiCert_ECC_Secure_Server_CAFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+};
+static const StaticFingerprints kPinset_facebook_sha256 = {
+ sizeof(kPinset_facebook_sha256_Data) / sizeof(const char*),
+ kPinset_facebook_sha256_Data
+};
+
+static const StaticPinset kPinset_facebook = {
+ nullptr,
+ &kPinset_facebook_sha256
+};
+
+static const char* kPinset_google_root_pems_sha256_Data[] = {
+ kEquifax_Secure_CAFingerprint,
+ kAmerica_Online_Root_Certification_Authority_2Fingerprint,
+ kComodo_Trusted_Services_rootFingerprint,
+ kCOMODO_ECC_Certification_AuthorityFingerprint,
+ kStartCom_Certification_AuthorityFingerprint,
+ kStartCom_Certification_AuthorityFingerprint,
+ kThawte_Premium_Server_CAFingerprint,
+ kCOMODO_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint,
+ kXRamp_Global_CA_RootFingerprint,
+ kAddTrust_Low_Value_Services_RootFingerprint,
+ kGeoTrust_Global_CA_2Fingerprint,
+ kStartCom_Certification_Authority_G2Fingerprint,
+ kStarfield_Class_2_CAFingerprint,
+ kthawte_Primary_Root_CA___G3Fingerprint,
+ kthawte_Primary_Root_CAFingerprint,
+ kEntrust_net_Premium_2048_Secure_Server_CAFingerprint,
+ kDigiCert_Assured_ID_Root_CAFingerprint,
+ kAmerica_Online_Root_Certification_Authority_1Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint,
+ kEquifax_Secure_eBusiness_CA_1Fingerprint,
+ kGlobalSign_Root_CAFingerprint,
+ kGo_Daddy_Root_Certificate_Authority___G2Fingerprint,
+ kStarfield_Services_Root_Certificate_Authority___G2Fingerprint,
+ kAffirmTrust_Premium_ECCFingerprint,
+ kNetwork_Solutions_Certificate_AuthorityFingerprint,
+ kAddTrust_Public_Services_RootFingerprint,
+ kUTN_DATACorp_SGC_Root_CAFingerprint,
+ kComodo_Secure_Services_rootFingerprint,
+ kGeoTrust_Primary_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
+ kUTN_USERFirst_Hardware_Root_CAFingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint,
+ kGo_Daddy_Class_2_CAFingerprint,
+ kVerisign_Class_4_Public_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kBaltimore_CyberTrust_RootFingerprint,
+ kthawte_Primary_Root_CA___G2Fingerprint,
+ kAffirmTrust_CommercialFingerprint,
+ kEntrust_Root_Certification_AuthorityFingerprint,
+ kGlobalSign_Root_CA___R3Fingerprint,
+ kGeoTrust_Universal_CA_2Fingerprint,
+ kCybertrust_Global_RootFingerprint,
+ kStarfield_Root_Certificate_Authority___G2Fingerprint,
+ kGeoTrust_Global_CAFingerprint,
+ kGlobalSign_Root_CA___R2Fingerprint,
+ kTC_TrustCenter_Class_3_CA_IIFingerprint,
+ kAffirmTrust_NetworkingFingerprint,
+ kAddTrust_External_RootFingerprint,
+ kVeriSign_Universal_Root_Certification_AuthorityFingerprint,
+ kGeoTrust_Universal_CAFingerprint,
+ kThawte_Server_CAFingerprint,
+ kEquifax_Secure_Global_eBusiness_CAFingerprint,
+ kTC_TrustCenter_Universal_CA_IIIFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_Global_Root_CAFingerprint,
+ kTC_TrustCenter_Class_2_CA_IIFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
+ kTC_TrustCenter_Universal_CA_IFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
+ kComodo_AAA_Services_rootFingerprint,
+ kAffirmTrust_PremiumFingerprint,
+ kAddTrust_Qualified_Certificates_RootFingerprint,
+};
+static const StaticFingerprints kPinset_google_root_pems_sha256 = {
+ sizeof(kPinset_google_root_pems_sha256_Data) / sizeof(const char*),
+ kPinset_google_root_pems_sha256_Data
+};
+
+static const StaticPinset kPinset_google_root_pems = {
+ nullptr,
+ &kPinset_google_root_pems_sha256
+};
+
+static const char* kPinset_mozilla_sha256_Data[] = {
+ kGeoTrust_Global_CA_2Fingerprint,
+ kthawte_Primary_Root_CA___G3Fingerprint,
+ kthawte_Primary_Root_CAFingerprint,
+ kDigiCert_Assured_ID_Root_CAFingerprint,
+ kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint,
+ kGeoTrust_Primary_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint,
+ kVerisign_Class_4_Public_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kBaltimore_CyberTrust_RootFingerprint,
+ kthawte_Primary_Root_CA___G2Fingerprint,
+ kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint,
+ kGeoTrust_Universal_CA_2Fingerprint,
+ kGeoTrust_Global_CAFingerprint,
+ kVeriSign_Universal_Root_Certification_AuthorityFingerprint,
+ kGeoTrust_Universal_CAFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_Global_Root_CAFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
+};
+static const StaticFingerprints kPinset_mozilla_sha256 = {
+ sizeof(kPinset_mozilla_sha256_Data) / sizeof(const char*),
+ kPinset_mozilla_sha256_Data
+};
+
+static const StaticPinset kPinset_mozilla = {
+ nullptr,
+ &kPinset_mozilla_sha256
+};
+
+static const char* kPinset_mozilla_services_sha256_Data[] = {
+ kDigiCert_Global_Root_CAFingerprint,
+};
+static const StaticFingerprints kPinset_mozilla_services_sha256 = {
+ sizeof(kPinset_mozilla_services_sha256_Data) / sizeof(const char*),
+ kPinset_mozilla_services_sha256_Data
+};
+
+static const StaticPinset kPinset_mozilla_services = {
+ nullptr,
+ &kPinset_mozilla_services_sha256
+};
+
+static const char* kPinset_mozilla_test_sha256_Data[] = {
+ kEnd_Entity_Test_CertFingerprint,
+};
+static const StaticFingerprints kPinset_mozilla_test_sha256 = {
+ sizeof(kPinset_mozilla_test_sha256_Data) / sizeof(const char*),
+ kPinset_mozilla_test_sha256_Data
+};
+
+static const StaticPinset kPinset_mozilla_test = {
+ nullptr,
+ &kPinset_mozilla_test_sha256
+};
+
+/* Chrome static pinsets */
+static const char* kPinset_test_sha1_Data[] = {
+ kTestSPKIFingerprint,
+};
+static const StaticFingerprints kPinset_test_sha1 = {
+ sizeof(kPinset_test_sha1_Data) / sizeof(const char*),
+ kPinset_test_sha1_Data
+};
+
+static const StaticPinset kPinset_test = {
+ &kPinset_test_sha1,
+ nullptr
+};
+
+static const char* kPinset_google_sha1_Data[] = {
+ kGoogleG2Fingerprint,
+ kGoogleBackup2048Fingerprint,
+};
+static const StaticFingerprints kPinset_google_sha1 = {
+ sizeof(kPinset_google_sha1_Data) / sizeof(const char*),
+ kPinset_google_sha1_Data
+};
+
+static const StaticPinset kPinset_google = {
+ &kPinset_google_sha1,
+ nullptr
+};
+
+static const char* kPinset_tor_sha1_Data[] = {
+ kTor1Fingerprint,
+ kTor2Fingerprint,
+ kTor3Fingerprint,
+};
+static const StaticFingerprints kPinset_tor_sha1 = {
+ sizeof(kPinset_tor_sha1_Data) / sizeof(const char*),
+ kPinset_tor_sha1_Data
+};
+
+static const char* kPinset_tor_sha256_Data[] = {
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kGOOGLE_PIN_RapidSSLFingerprint,
+};
+static const StaticFingerprints kPinset_tor_sha256 = {
+ sizeof(kPinset_tor_sha256_Data) / sizeof(const char*),
+ kPinset_tor_sha256_Data
+};
+
+static const StaticPinset kPinset_tor = {
+ &kPinset_tor_sha1,
+ &kPinset_tor_sha256
+};
+
+static const char* kPinset_twitterCom_sha1_Data[] = {
+ kTwitter1Fingerprint,
+};
+static const StaticFingerprints kPinset_twitterCom_sha1 = {
+ sizeof(kPinset_twitterCom_sha1_Data) / sizeof(const char*),
+ kPinset_twitterCom_sha1_Data
+};
+
+static const char* kPinset_twitterCom_sha256_Data[] = {
+ kVerisign_Class_2_Public_Primary_Certification_Authority___G2Fingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint,
+ kGeoTrust_Global_CA_2Fingerprint,
+ kDigiCert_Assured_ID_Root_CAFingerprint,
+ kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint,
+ kVerisign_Class_1_Public_Primary_Certification_AuthorityFingerprint,
+ kGeoTrust_Primary_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint,
+ kVerisign_Class_4_Public_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint,
+ kGeoTrust_Universal_CA_2Fingerprint,
+ kGeoTrust_Global_CAFingerprint,
+ kVeriSign_Universal_Root_Certification_AuthorityFingerprint,
+ kGeoTrust_Universal_CAFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_Global_Root_CAFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
+};
+static const StaticFingerprints kPinset_twitterCom_sha256 = {
+ sizeof(kPinset_twitterCom_sha256_Data) / sizeof(const char*),
+ kPinset_twitterCom_sha256_Data
+};
+
+static const StaticPinset kPinset_twitterCom = {
+ &kPinset_twitterCom_sha1,
+ &kPinset_twitterCom_sha256
+};
+
+static const char* kPinset_twitterCDN_sha1_Data[] = {
+ kTwitter1Fingerprint,
+};
+static const StaticFingerprints kPinset_twitterCDN_sha1 = {
+ sizeof(kPinset_twitterCDN_sha1_Data) / sizeof(const char*),
+ kPinset_twitterCDN_sha1_Data
+};
+
+static const char* kPinset_twitterCDN_sha256_Data[] = {
+ kVerisign_Class_2_Public_Primary_Certification_Authority___G2Fingerprint,
+ kComodo_Trusted_Services_rootFingerprint,
+ kCOMODO_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G2Fingerprint,
+ kAddTrust_Low_Value_Services_RootFingerprint,
+ kUTN_USERFirst_Object_Root_CAFingerprint,
+ kGTE_CyberTrust_Global_RootFingerprint,
+ kGeoTrust_Global_CA_2Fingerprint,
+ kEntrust_net_Premium_2048_Secure_Server_CAFingerprint,
+ kDigiCert_Assured_ID_Root_CAFingerprint,
+ kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G5Fingerprint,
+ kGlobalSign_Root_CAFingerprint,
+ kUTN_USERFirst_Email_Root_CAFingerprint,
+ kVerisign_Class_1_Public_Primary_Certification_AuthorityFingerprint,
+ kAddTrust_Public_Services_RootFingerprint,
+ kUTN_DATACorp_SGC_Root_CAFingerprint,
+ kComodo_Secure_Services_rootFingerprint,
+ kGeoTrust_Primary_Certification_AuthorityFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_Authority___G3Fingerprint,
+ kUTN_USERFirst_Hardware_Root_CAFingerprint,
+ kVeriSign_Class_3_Public_Primary_Certification_Authority___G4Fingerprint,
+ kVerisign_Class_4_Public_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kBaltimore_CyberTrust_RootFingerprint,
+ kEntrust_Root_Certification_AuthorityFingerprint,
+ kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint,
+ kGlobalSign_Root_CA___R3Fingerprint,
+ kGOOGLE_PIN_Entrust_G2Fingerprint,
+ kGeoTrust_Universal_CA_2Fingerprint,
+ kGeoTrust_Global_CAFingerprint,
+ kGlobalSign_Root_CA___R2Fingerprint,
+ kAddTrust_External_RootFingerprint,
+ kVeriSign_Universal_Root_Certification_AuthorityFingerprint,
+ kGeoTrust_Universal_CAFingerprint,
+ kGOOGLE_PIN_Entrust_SSLFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_Global_Root_CAFingerprint,
+ kVerisign_Class_3_Public_Primary_Certification_AuthorityFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
+ kComodo_AAA_Services_rootFingerprint,
+ kAddTrust_Qualified_Certificates_RootFingerprint,
+};
+static const StaticFingerprints kPinset_twitterCDN_sha256 = {
+ sizeof(kPinset_twitterCDN_sha256_Data) / sizeof(const char*),
+ kPinset_twitterCDN_sha256_Data
+};
+
+static const StaticPinset kPinset_twitterCDN = {
+ &kPinset_twitterCDN_sha1,
+ &kPinset_twitterCDN_sha256
+};
+
+static const char* kPinset_tor2web_sha256_Data[] = {
+ kGOOGLE_PIN_Tor2webFingerprint,
+ kGOOGLE_PIN_AlphaSSL_G2Fingerprint,
+};
+static const StaticFingerprints kPinset_tor2web_sha256 = {
+ sizeof(kPinset_tor2web_sha256_Data) / sizeof(const char*),
+ kPinset_tor2web_sha256_Data
+};
+
+static const StaticPinset kPinset_tor2web = {
+ nullptr,
+ &kPinset_tor2web_sha256
+};
+
+static const char* kPinset_cryptoCat_sha256_Data[] = {
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kGOOGLE_PIN_CryptoCat1Fingerprint,
+};
+static const StaticFingerprints kPinset_cryptoCat_sha256 = {
+ sizeof(kPinset_cryptoCat_sha256_Data) / sizeof(const char*),
+ kPinset_cryptoCat_sha256_Data
+};
+
+static const StaticPinset kPinset_cryptoCat = {
+ nullptr,
+ &kPinset_cryptoCat_sha256
+};
+
+static const char* kPinset_lavabit_sha256_Data[] = {
+ kGOOGLE_PIN_LibertylavabitcomFingerprint,
+};
+static const StaticFingerprints kPinset_lavabit_sha256 = {
+ sizeof(kPinset_lavabit_sha256_Data) / sizeof(const char*),
+ kPinset_lavabit_sha256_Data
+};
+
+static const StaticPinset kPinset_lavabit = {
+ nullptr,
+ &kPinset_lavabit_sha256
+};
+
+static const char* kPinset_dropbox_sha256_Data[] = {
+ kGOOGLE_PIN_EntrustRootEC1Fingerprint,
+ kThawte_Premium_Server_CAFingerprint,
+ kthawte_Primary_Root_CA___G3Fingerprint,
+ kthawte_Primary_Root_CAFingerprint,
+ kEntrust_net_Premium_2048_Secure_Server_CAFingerprint,
+ kDigiCert_Assured_ID_Root_CAFingerprint,
+ kGo_Daddy_Root_Certificate_Authority___G2Fingerprint,
+ kGOOGLE_PIN_GoDaddySecureFingerprint,
+ kGeoTrust_Primary_Certification_AuthorityFingerprint,
+ kGo_Daddy_Class_2_CAFingerprint,
+ kDigiCert_High_Assurance_EV_Root_CAFingerprint,
+ kthawte_Primary_Root_CA___G2Fingerprint,
+ kEntrust_Root_Certification_AuthorityFingerprint,
+ kGOOGLE_PIN_Entrust_G2Fingerprint,
+ kGeoTrust_Global_CAFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G3Fingerprint,
+ kDigiCert_Global_Root_CAFingerprint,
+ kGeoTrust_Primary_Certification_Authority___G2Fingerprint,
+};
+static const StaticFingerprints kPinset_dropbox_sha256 = {
+ sizeof(kPinset_dropbox_sha256_Data) / sizeof(const char*),
+ kPinset_dropbox_sha256_Data
+};
+
+static const StaticPinset kPinset_dropbox = {
+ nullptr,
+ &kPinset_dropbox_sha256
+};
+
+/* Domainlist */
+struct TransportSecurityPreload {
+ const char* mHost;
+ const bool mIncludeSubdomains;
+ const bool mTestMode;
+ const bool mIsMoz;
+ const int32_t mId;
+ const StaticPinset *pinset;
+};
+
+/* Sort hostnames for binary search. */
+static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
+ { "2mdn.net", true, false, false, -1, &kPinset_google_root_pems },
+ { "accounts.firefox.com", true, false, false, 4, &kPinset_mozilla_services },
+ { "accounts.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "addons.mozilla.net", true, false, true, 2, &kPinset_mozilla },
+ { "addons.mozilla.org", true, false, true, 1, &kPinset_mozilla },
+ { "admin.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "android.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "api.accounts.firefox.com", true, false, false, 5, &kPinset_mozilla_services },
+ { "api.twitter.com", true, false, false, -1, &kPinset_twitterCDN },
+ { "apis.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "appengine.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "aus4.mozilla.org", true, true, true, 3, &kPinset_mozilla },
+ { "blog.torproject.org", true, false, false, -1, &kPinset_tor },
+ { "business.twitter.com", true, false, false, -1, &kPinset_twitterCom },
+ { "cdn.mozilla.net", true, false, true, -1, &kPinset_mozilla },
+ { "cdn.mozilla.org", true, false, true, -1, &kPinset_mozilla },
+ { "chart.apis.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "check.torproject.org", true, false, false, -1, &kPinset_tor },
+ { "checkout.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "chrome-devtools-frontend.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "chrome.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "chromiumcodereview.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "cloud.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "code.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "codereview.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "codereview.chromium.org", true, false, false, -1, &kPinset_google_root_pems },
+ { "crypto.cat", false, true, false, -1, &kPinset_cryptoCat },
+ { "dev.twitter.com", true, false, false, -1, &kPinset_twitterCom },
+ { "dist.torproject.org", true, false, false, -1, &kPinset_tor },
+ { "dl.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "docs.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "domains.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "doubleclick.net", true, false, false, -1, &kPinset_google_root_pems },
+ { "drive.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "dropbox.com", false, false, false, -1, &kPinset_dropbox },
+ { "encrypted.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "exclude-subdomains.pinning.example.com", false, false, false, 0, &kPinset_mozilla_test },
+ { "facebook.com", true, true, false, -1, &kPinset_facebook },
+ { "g.co", true, false, false, -1, &kPinset_google_root_pems },
+ { "glass.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "gmail.com", false, false, false, -1, &kPinset_google_root_pems },
+ { "goo.gl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google-analytics.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ac", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ad", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ae", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.af", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ag", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.am", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.as", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.at", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.az", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ba", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.be", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.bf", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.bg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.bi", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.bj", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.bs", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.by", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ca", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cat", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cc", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cd", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cf", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ch", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ci", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ao", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.bw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ck", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.cr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.hu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.id", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.il", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.im", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.in", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.je", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.jp", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ke", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.kr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ls", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ma", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.mz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.nz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.th", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.tz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ug", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.uk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.uz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.ve", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.vi", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.za", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.zm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.co.zw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.af", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ag", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ai", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ar", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.au", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.bd", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.bh", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.bn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.bo", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.br", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.by", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.bz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.cn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.co", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.cu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.cy", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.do", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ec", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.eg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.et", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.fj", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ge", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.gh", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.gi", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.gr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.gt", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.hk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.iq", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.jm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.jo", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.kh", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.kw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.lb", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ly", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.mt", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.mx", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.my", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.na", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.nf", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ng", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ni", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.np", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.nr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.om", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.pa", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.pe", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ph", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.pk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.pl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.pr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.py", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.qa", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ru", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.sa", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.sb", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.sg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.sl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.sv", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.tj", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.tn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.tr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.tw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ua", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.uy", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.vc", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.ve", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.com.vn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cv", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.cz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.de", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.dj", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.dk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.dm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.dz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ee", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.es", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.fi", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.fm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.fr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ga", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ge", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gp", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.gy", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.hk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.hn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.hr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ht", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.hu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ie", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.im", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.info", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.iq", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.is", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.it", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.it.ao", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.je", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.jo", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.jobs", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.jp", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.kg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ki", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.kz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.la", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.li", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.lk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.lt", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.lu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.lv", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.md", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.me", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ml", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ms", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mv", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.mw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ne", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ne.jp", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.net", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.nl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.no", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.nr", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.nu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.off.ai", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.pk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.pl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.pn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ps", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.pt", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ro", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.rs", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ru", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.rw", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.sc", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.se", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.sh", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.si", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.sk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.sm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.sn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.so", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.st", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.td", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tk", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tl", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tm", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tn", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.to", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.tt", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.us", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.uz", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.vg", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.vu", true, false, false, -1, &kPinset_google_root_pems },
+ { "google.ws", true, false, false, -1, &kPinset_google_root_pems },
+ { "googleadservices.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googleapis.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googlecode.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googlecommerce.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googlegroups.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googlemail.com", false, false, false, -1, &kPinset_google_root_pems },
+ { "googleplex.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googlesyndication.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googletagmanager.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googletagservices.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "googleusercontent.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "goto.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "groups.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "gstatic.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "history.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "hostedtalkgadget.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "include-subdomains.pinning.example.com", true, false, false, -1, &kPinset_mozilla_test },
+ { "liberty.lavabit.com", true, true, false, -1, &kPinset_lavabit },
+ { "login.corp.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "mail.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "market.android.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "media.mozilla.com", true, false, true, -1, &kPinset_mozilla },
+ { "mobile.twitter.com", true, false, false, -1, &kPinset_twitterCom },
+ { "oauth.twitter.com", true, false, false, -1, &kPinset_twitterCom },
+ { "pinningtest.appspot.com", true, false, false, -1, &kPinset_test },
+ { "platform.twitter.com", true, false, false, -1, &kPinset_twitterCDN },
+ { "play.google.com", false, false, false, -1, &kPinset_google_root_pems },
+ { "plus.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "plus.sandbox.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "profiles.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "script.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "security.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "services.mozilla.com", true, true, false, -1, &kPinset_mozilla_services },
+ { "sites.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "spreadsheets.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "ssl.google-analytics.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "talk.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "talkgadget.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "test-mode.pinning.example.com", true, true, false, -1, &kPinset_mozilla_test },
+ { "tor2web.org", true, true, false, -1, &kPinset_tor2web },
+ { "torproject.org", false, false, false, -1, &kPinset_tor },
+ { "translate.googleapis.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "twimg.com", true, false, false, -1, &kPinset_twitterCDN },
+ { "twitter.com", true, false, false, -1, &kPinset_twitterCDN },
+ { "urchin.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "w-spotlight.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wallet.google.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "webfilings-eu-mirror.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "webfilings-eu.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "webfilings-mirror-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "webfilings.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-bigsky-master.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-demo-eu.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-demo-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-dogfood-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-pentest.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-staging-hr.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-training-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-training-master.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "wf-trial-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "www.dropbox.com", true, false, false, -1, &kPinset_dropbox },
+ { "www.gmail.com", false, false, false, -1, &kPinset_google_root_pems },
+ { "www.googlemail.com", false, false, false, -1, &kPinset_google_root_pems },
+ { "www.torproject.org", true, false, false, -1, &kPinset_tor },
+ { "www.twitter.com", true, false, false, -1, &kPinset_twitterCom },
+ { "xbrlsuccess.appspot.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "youtu.be", true, false, false, -1, &kPinset_google_root_pems },
+ { "youtube-nocookie.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "youtube.com", true, false, false, -1, &kPinset_google_root_pems },
+ { "ytimg.com", true, false, false, -1, &kPinset_google_root_pems },
+};
+
+// Pinning Preload List Length = 331;
+
+static const int32_t kUnknownId = -1;
+
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1419674828470000);
diff --git a/security/manager/boot/src/moz.build b/security/manager/boot/src/moz.build
index b3d2127..50a345b 100644
--- a/security/manager/boot/src/moz.build
+++ b/security/manager/boot/src/moz.build
@@ -10,6 +10,7 @@ UNIFIED_SOURCES += [
'nsSecurityHeaderParser.cpp',
'nsSecurityWarningDialogs.cpp',
'nsSiteSecurityService.cpp',
+ 'PublicKeyPinningService.cpp',
]
# nsSecureBrowserUIImpl.cpp cannot be built in unified mode because it forces NSPR logging.
@@ -17,6 +18,11 @@ SOURCES += [
'nsSecureBrowserUIImpl.cpp',
]
+
+LOCAL_INCLUDES += [
+ '../../../pkix/include',
+]
+
FAIL_ON_WARNINGS = True
MSVC_ENABLE_PGO = True
diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp
index cf15586..18d9f55 100644
--- a/security/manager/ssl/src/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/src/SSLServerCertVerification.cpp
@@ -637,8 +637,9 @@ NSSDetermineCertOverrideErrors(CertVerifier& certVerifier,
// possible failure.
// XXX TODO: convert to VerifySSLServerCert
// XXX TODO: get rid of error log
- certVerifier.VerifyCert(cert, stapledOCSPResponse, certificateUsageSSLServer,
- now, infoObject, 0, nullptr, nullptr, verify_log);
+ certVerifier.VerifyCert(cert, certificateUsageSSLServer,
+ now, infoObject, infoObject->GetHostNameRaw(),
+ 0, stapledOCSPResponse, nullptr, nullptr, verify_log);
// Check the name field against the desired hostname.
if (CERT_VerifyCertName(cert, infoObject->GetHostNameRaw()) != SECSuccess) {
diff --git a/security/manager/ssl/src/SharedCertVerifier.h b/security/manager/ssl/src/SharedCertVerifier.h
index 32a92a3..c7c1936 100644
--- a/security/manager/ssl/src/SharedCertVerifier.h
+++ b/security/manager/ssl/src/SharedCertVerifier.h
@@ -24,12 +24,14 @@ public:
missing_cert_download_config ac, crl_download_config cdc,
#endif
ocsp_download_config odc, ocsp_strict_config osc,
- ocsp_get_config ogc)
+ ocsp_get_config ogc,
+ pinning_enforcement_config pinningEnforcementLevel)
: mozilla::psm::CertVerifier(ic,
#ifndef NSS_NO_LIBPKIX
ac, cdc,
#endif
- odc, osc, ogc)
+ odc, osc, ogc,
+ pinningEnforcementLevel)
{
}
};
diff --git a/security/manager/ssl/src/nsCMS.cpp b/security/manager/ssl/src/nsCMS.cpp
index 70a3c49..ee76c07 100644
--- a/security/manager/ssl/src/nsCMS.cpp
+++ b/security/manager/ssl/src/nsCMS.cpp
@@ -264,9 +264,10 @@ nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_
NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
{
- SECStatus srv = certVerifier->VerifyCert(si->cert, nullptr,
+ SECStatus srv = certVerifier->VerifyCert(si->cert,
certificateUsageEmailSigner,
- PR_Now(), nullptr /*XXX pinarg*/);
+ PR_Now(), nullptr /*XXX pinarg*/,
+ nullptr /*hostname*/);
if (srv != SECSuccess) {
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp
index 88fb8ed..70b9c89 100644
--- a/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -829,10 +829,12 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain)
// We want to test all usages, but we start with server because most of the
// time Firefox users care about server certs.
- certVerifier->VerifyCert(mCert.get(), nullptr,
+ certVerifier->VerifyCert(mCert.get(),
certificateUsageSSLServer, PR_Now(),
nullptr, /*XXX fixme*/
+ nullptr, /* hostname */
CertVerifier::FLAG_LOCAL_ONLY,
+ nullptr, /* stapledOCSPResponse */
&nssChain);
// This is the whitelist of all non-SSLServer usages that are supported by
// verifycert.
@@ -851,10 +853,12 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain)
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
("pipnss: PKIX attempting chain(%d) for '%s'\n",
usage, mCert->nickname));
- certVerifier->VerifyCert(mCert.get(), nullptr,
+ certVerifier->VerifyCert(mCert.get(),
usage, PR_Now(),
nullptr, /*XXX fixme*/
+ nullptr, /*hostname*/
CertVerifier::FLAG_LOCAL_ONLY,
+ nullptr, /* stapledOCSPResponse */
&nssChain);
}
@@ -1467,10 +1471,11 @@ nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV)
uint32_t flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY |
mozilla::psm::CertVerifier::FLAG_MUST_BE_EV;
- SECStatus rv = certVerifier->VerifyCert(mCert.get(), nullptr,
+ SECStatus rv = certVerifier->VerifyCert(mCert.get(),
certificateUsageSSLServer, PR_Now(),
nullptr /* XXX pinarg */,
- flags, nullptr, &resultOidTag);
+ nullptr /* hostname */,
+ flags, nullptr /* stapledOCSPResponse */ , nullptr, &resultOidTag);
if (rv != SECSuccess) {
resultOidTag = SEC_OID_UNKNOWN;
diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp
index 40b03c1..c9fd8ba 100644
--- a/security/manager/ssl/src/nsNSSCertificateDB.cpp
+++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp
@@ -634,9 +634,10 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
mozilla::pkix::ScopedCERTCertList certChain;
- SECStatus rv = certVerifier->VerifyCert(node->cert, nullptr,
+ SECStatus rv = certVerifier->VerifyCert(node->cert,
certificateUsageEmailRecipient,
- now, ctx, 0, &certChain);
+ now, ctx, nullptr, 0,
+ nullptr, &certChain);
if (rv != SECSuccess) {
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
@@ -801,9 +802,10 @@ nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfac
!CERT_LIST_END(node,certList);
node = CERT_LIST_NEXT(node)) {
mozilla::pkix::ScopedCERTCertList certChain;
- SECStatus rv = certVerifier->VerifyCert(node->cert, nullptr,
+ SECStatus rv = certVerifier->VerifyCert(node->cert,
certificateUsageVerifyCA,
- PR_Now(), ctx, 0, &certChain);
+ PR_Now(), ctx, nullptr, 0, nullptr,
+ &certChain);
if (rv != SECSuccess) {
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow, proofOfLock);
@@ -1381,9 +1383,10 @@ nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEma
!CERT_LIST_END(node, certlist);
node = CERT_LIST_NEXT(node)) {
- SECStatus srv = certVerifier->VerifyCert(node->cert, nullptr,
+ SECStatus srv = certVerifier->VerifyCert(node->cert,
certificateUsageEmailRecipient,
- PR_Now(), nullptr /*XXX pinarg*/);
+ PR_Now(), nullptr /*XXX pinarg*/,
+ nullptr /*hostname*/);
if (srv == SECSuccess) {
break;
}
@@ -1772,10 +1775,12 @@ nsNSSCertificateDB::VerifyCertNow(nsIX509Cert* aCert,
SECOidTag evOidPolicy;
SECStatus srv;
- srv = certVerifier->VerifyCert(nssCert, nullptr,
+ srv = certVerifier->VerifyCert(nssCert,
aUsage, PR_Now(),
nullptr, // Assume no context
+ nullptr, // hostname
aFlags,
+ nullptr, // stapledOCSPResponse
&resultChain,
&evOidPolicy);
diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp
index 44b3808..c4bd566 100644
--- a/security/manager/ssl/src/nsNSSComponent.cpp
+++ b/security/manager/ssl/src/nsNSSComponent.cpp
@@ -996,6 +996,13 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
}
}
+ // Default pinning enforcement level is disabled.
+ CertVerifier::pinning_enforcement_config
+ pinningEnforcementLevel =
+ static_cast<CertVerifier::pinning_enforcement_config>
+ (Preferences::GetInt("security.cert_pinning.enforcement_level",
+ CertVerifier::pinningDisabled));
+
CertVerifier::ocsp_download_config odc;
CertVerifier::ocsp_strict_config osc;
CertVerifier::ocsp_get_config ogc;
@@ -1009,7 +1016,7 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
crlDownloading ?
CertVerifier::crl_download_allowed : CertVerifier::crl_local_only,
#endif
- odc, osc, ogc);
+ odc, osc, ogc, pinningEnforcementLevel);
// mozilla::pkix has its own OCSP cache, so disable the NSS cache
// if appropriate.
@@ -1644,7 +1651,8 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
|| prefName.Equals("security.OCSP.GET.enabled")
|| prefName.Equals("security.ssl.enable_ocsp_stapling")
|| prefName.Equals("security.use_mozillapkix_verification")
- || prefName.Equals("security.use_libpkix_verification")) {
+ || prefName.Equals("security.use_libpkix_verification")
+ || prefName.Equals("security.cert_pinning.enforcement_level")) {
MutexAutoLock lock(mutex);
setValidationOptions(false, lock);
} else if (prefName.Equals("network.ntlm.send-lm-response")) {
diff --git a/security/manager/ssl/src/nsUsageArrayHelper.cpp b/security/manager/ssl/src/nsUsageArrayHelper.cpp
index 7f7249f..dd65ae5 100644
--- a/security/manager/ssl/src/nsUsageArrayHelper.cpp
+++ b/security/manager/ssl/src/nsUsageArrayHelper.cpp
@@ -105,8 +105,9 @@ nsUsageArrayHelper::check(uint32_t previousCheckResult,
MOZ_CRASH("unknown cert usage passed to check()");
}
- SECStatus rv = certVerifier->VerifyCert(mCert, nullptr, aCertUsage,
- time, nullptr /*XXX:wincx*/, flags);
+ SECStatus rv = certVerifier->VerifyCert(mCert, aCertUsage, time,
+ nullptr /*XXX:wincx*/,
+ nullptr /*hostname*/, flags);
if (rv == SECSuccess) {
typestr.Append(suffix);
diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js
index 58e838b..ae25ea9e 100644
--- a/security/manager/ssl/tests/unit/head_psm.js
+++ b/security/manager/ssl/tests/unit/head_psm.js
@@ -52,6 +52,7 @@ const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144;
const SEC_ERROR_POLICY_VALIDATION_FAILED = SEC_ERROR_BASE + 160; // -8032
const SEC_ERROR_OCSP_BAD_SIGNATURE = SEC_ERROR_BASE + 157;
const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176;
+const SEC_ERROR_APPLICATION_CALLBACK_ERROR = SEC_ERROR_BASE + 178;
const SSL_ERROR_BAD_CERT_DOMAIN = SSL_ERROR_BASE + 12;
diff --git a/security/manager/ssl/tests/unit/test_cert_overrides.js b/security/manager/ssl/tests/unit/test_cert_overrides.js
index 11e14f3b..91fc77eb 100644
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js
+++ b/security/manager/ssl/tests/unit/test_cert_overrides.js
@@ -232,7 +232,7 @@ function add_distrust_override_test(certFileName, hostName,
let certToDistrust = constructCertFromFile(certFileName);
add_test(function () {
- // "pu" means the cert is actively distrusted.
+ // Add an entry to the NSS certDB that says to distrust the cert
setCertTrust(certToDistrust, "pu,,");
clearSessionCache();
run_next_test();
diff --git a/security/manager/ssl/tests/unit/test_pinning.js b/security/manager/ssl/tests/unit/test_pinning.js
new file mode 100644
index 0000000..dc779dd
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_pinning.js
@@ -0,0 +1,182 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+//
+// For all cases, the acceptable pinset includes only certificates pinned to
+// Test End Entity Cert (signed by issuer testCA). Other certificates
+// are issued by otherCA, which is never in the pinset but is a user-specified
+// trust anchor. This test covers multiple cases:
+//
+// Pinned domain include-subdomains.pinning.example.com includes subdomains
+// - PASS: include-subdomains.pinning.example.com serves a correct cert
+// - PASS: good.include-subdomains.pinning.example.com serves a correct cert
+// - FAIL (strict): bad.include-subdomains.pinning.example.com serves a cert
+// not in the pinset
+// - PASS (mitm): bad.include-subdomains.pinning.example.com serves a cert not
+// in the pinset, but issued by a user-specified trust domain
+//
+// Pinned domain exclude-subdomains.pinning.example.com excludes subdomains
+// - PASS: exclude-subdomains.pinning.example.com serves a correct cert
+// - FAIL: exclude-subdomains.pinning.example.com services an incorrect cert
+// (TODO: test using verifyCertnow)
+// - PASS: sub.exclude-subdomains.pinning.example.com serves an incorrect cert
+
+"use strict";
+
+do_get_profile(); // must be called before getting nsIX509CertDB
+const certdb = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+
+function test_strict() {
+ // In strict mode, we always evaluate pinning data, regardless of whether the
+ // issuer is a built-in trust anchor. We only enforce pins that are not in
+ // test mode.
+ add_test(function() {
+ Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
+ run_next_test();
+ });
+
+ // If a host should be pinned but other errors (particularly overridable
+ // errors) like 'unknown issuer' are encountered, the pinning error takes
+ // precedence. This prevents overrides for such hosts.
+ add_connection_test("unknownissuer.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE));
+
+ // Issued by otherCA, which is not in the pinset for pinning.example.com.
+ add_connection_test("bad.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE));
+
+ // These domains serve certs that match the pinset.
+ add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
+
+ // This domain serves a cert that doesn't match the pinset, but subdomains
+ // are excluded.
+ add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
+
+ // This domain's pinset is exactly the same as
+ // include-subdomains.pinning.example.com, serves the same cert as
+ // bad.include-subdomains.pinning.example.com, but it should pass because
+ // it's in test_mode.
+ add_connection_test("test-mode.pinning.example.com", Cr.NS_OK);
+}
+
+function test_mitm() {
+ // In MITM mode, we allow pinning to pass if the chain resolves to any
+ // user-specified trust anchor, even if it is not in the pinset.
+ add_test(function() {
+ Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1);
+ run_next_test();
+ });
+
+ add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
+
+ add_connection_test("unknownissuer.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER));
+
+ // In this case, even though otherCA is not in the pinset, it is a
+ // user-specified trust anchor and the pinning check succeeds.
+ add_connection_test("bad.include-subdomains.pinning.example.com", Cr.NS_OK);
+
+ add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("test-mode.pinning.example.com", Cr.NS_OK);
+};
+
+function test_disabled() {
+ // Disable pinning.
+ add_test(function() {
+ Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 0);
+ run_next_test();
+ });
+
+ add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("bad.include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("test-mode.pinning.example.com", Cr.NS_OK);
+
+ add_connection_test("unknownissuer.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER));
+}
+
+function test_enforce_test_mode() {
+ // In enforce test mode, we always enforce all pins, even test pins.
+ add_test(function() {
+ Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 3);
+ run_next_test();
+ });
+
+ add_connection_test("unknownissuer.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE));
+
+ // Issued by otherCA, which is not in the pinset for pinning.example.com.
+ add_connection_test("bad.include-subdomains.pinning.example.com",
+ getXPCOMStatusFromNSS(MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE));
+
+ // These domains serve certs that match the pinset.
+ add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
+ add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
+
+ // This domain serves a cert that doesn't match the pinset, but subdomains
+ // are excluded.
+ add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
+
+ // This domain's pinset is exactly the same as
+ // include-subdomains.pinning.example.com, serves the same cert as
+ // bad.include-subdomains.pinning.example.com, is in test-mode, but we are
+ // enforcing test mode pins.
+ add_connection_test("test-mode.pinning.example.com",
+ getXPCOMStatusFromNSS(MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE));
+}
+
+function check_pinning_telemetry() {
+ let service = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry);
+ let prod_histogram = service.getHistogramById("CERT_PINNING_RESULTS")
+ .snapshot();
+ let test_histogram = service.getHistogramById("CERT_PINNING_TEST_RESULTS")
+ .snapshot();
+ // Because all of our test domains are pinned to user-specified trust
+ // anchors, effectively only strict mode and enforce test-mode get evaluated
+ do_check_eq(prod_histogram.counts[0], 4); // Failure count
+ do_check_eq(prod_histogram.counts[1], 4); // Success count
+ do_check_eq(test_histogram.counts[0], 2); // Failure count
+ do_check_eq(test_histogram.counts[1], 0); // Success count
+
+ let moz_prod_histogram = service.getHistogramById("CERT_PINNING_MOZ_RESULTS")
+ .snapshot();
+ let moz_test_histogram =
+ service.getHistogramById("CERT_PINNING_MOZ_TEST_RESULTS").snapshot();
+ do_check_eq(moz_prod_histogram.counts[0], 0); // Failure count
+ do_check_eq(moz_prod_histogram.counts[1], 0); // Success count
+ do_check_eq(moz_test_histogram.counts[0], 0); // Failure count
+ do_check_eq(moz_test_histogram.counts[1], 0); // Success count
+
+ let per_host_histogram =
+ service.getHistogramById("CERT_PINNING_MOZ_RESULTS_BY_HOST").snapshot();
+ do_check_eq(per_host_histogram.counts[0], 0); // Failure count
+ do_check_eq(per_host_histogram.counts[1], 2); // Success count
+ run_next_test();
+}
+
+function run_test() {
+ add_tls_server_setup("BadCertServer");
+
+ // Add a user-specified trust anchor.
+ addCertFromFile(certdb, "tlsserver/other-test-ca.der", "CTu,u,u");
+
+ test_strict();
+ test_mitm();
+ test_disabled();
+ test_enforce_test_mode();
+
+ add_test(function () {
+ check_pinning_telemetry();
+ });
+ run_next_test();
+}
diff --git a/security/manager/ssl/tests/unit/tlsserver/cert8.db b/security/manager/ssl/tests/unit/tlsserver/cert8.db
index 13c101f..7da5d7f 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/cert8.db and b/security/manager/ssl/tests/unit/tlsserver/cert8.db differ
diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
index a4c59a4..5df134a 100644
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
+++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp
@@ -24,6 +24,7 @@ struct BadCertHost
const char *mCertName;
};
+// Hostname, cert nickname pairs.
const BadCertHost sBadCertHosts[] =
{
{ "expired.example.com", "expired" },
@@ -42,6 +43,16 @@ const BadCertHost sBadCertHosts[] =
{ "inadequatekeyusage.example.com", "inadequatekeyusage" },
{ "selfsigned-inadequateEKU.example.com", "selfsigned-inadequateEKU" },
{ "self-signed-end-entity-with-cA-true.example.com", "self-signed-EE-with-cA-true" },
+ // All of include-subdomains.pinning.example.com is pinned to End Entity
+ // Test Cert with nick localhostAndExampleCom. Any other nick will only
+ // pass pinning when security.cert_pinning.enforcement.level != strict and
+ // otherCA is added as a user-specified trust anchor. See StaticHPKPins.h.
+ { "include-subdomains.pinning.example.com", "localhostAndExampleCom" },
+ { "good.include-subdomains.pinning.example.com", "localhostAndExampleCom" },
+ { "bad.include-subdomains.pinning.example.com", "otherIssuerEE" },
+ { "exclude-subdomains.pinning.example.com", "localhostAndExampleCom" },
+ { "sub.exclude-subdomains.pinning.example.com", "otherIssuerEE" },
+ { "test-mode.pinning.example.com", "otherIssuerEE" },
{ nullptr, nullptr }
};
diff --git a/security/manager/ssl/tests/unit/tlsserver/default-ee.der b/security/manager/ssl/tests/unit/tlsserver/default-ee.der
index ac98037..9b2359d 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/default-ee.der and b/security/manager/ssl/tests/unit/tlsserver/default-ee.der differ
diff --git a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
index ef388bb..6075a5c 100755
--- a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
+++ b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh
@@ -12,7 +12,10 @@
#
# NB: This will cause the following files to be overwritten if they are in
# the output directory:
-# cert8.db, key3.db, secmod.db, ocsp-ca.der, ocsp-other-ca.der
+# cert8.db, key3.db, secmod.db, ocsp-ca.der, ocsp-other-ca.der, default-ee.der
+# NB: You must run genHPKPStaticPins.js after running this file, since its
+# output (StaticHPKPins.h) depends on default-ee.der
+
set -x
set -e
@@ -25,11 +28,13 @@ OBJDIR=${1}
OUTPUT_DIR=${2}
RUN_MOZILLA="$OBJDIR/dist/bin/run-mozilla.sh"
CERTUTIL="$OBJDIR/dist/bin/certutil"
+# On BSD, mktemp requires either a template or a prefix.
+MKTEMP="mktemp temp.XXXX"
-NOISE_FILE=`mktemp`
+NOISE_FILE=`$MKTEMP`
# Make a good effort at putting something unique in the noise file.
date +%s%N > "$NOISE_FILE"
-PASSWORD_FILE=`mktemp`
+PASSWORD_FILE=`$MKTEMP`
function cleanup {
rm -f "$NOISE_FILE" "$PASSWORD_FILE"
@@ -134,7 +139,11 @@ function make_delegated {
make_CA testCA 'CN=Test CA' test-ca.der
make_CA otherCA 'CN=Other test CA' other-test-ca.der
-make_EE localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example.com"
+
+make_EE localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.…"
+# Make an EE cert issued by otherCA
+make_EE otherIssuerEE 'CN=Wrong CA Pin Test End-Entity' otherCA "*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com,*.pinning.example.com"
+
$RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -L -n localhostAndExampleCom -r > $OUTPUT_DIR/default-ee.der
# A cert that is like localhostAndExampleCom, but with a different serial number for
# testing the "OCSP response is from the right issuer, but it is for the wrong cert"
diff --git a/security/manager/ssl/tests/unit/tlsserver/key3.db b/security/manager/ssl/tests/unit/tlsserver/key3.db
index 283e8fb..2d4dd29 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/key3.db and b/security/manager/ssl/tests/unit/tlsserver/key3.db differ
diff --git a/security/manager/ssl/tests/unit/tlsserver/other-test-ca.der b/security/manager/ssl/tests/unit/tlsserver/other-test-ca.der
index 794fb9c..742bb86 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/other-test-ca.der and b/security/manager/ssl/tests/unit/tlsserver/other-test-ca.der differ
diff --git a/security/manager/ssl/tests/unit/tlsserver/secmod.db b/security/manager/ssl/tests/unit/tlsserver/secmod.db
index a5f2f60..7a0e2b5 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/secmod.db and b/security/manager/ssl/tests/unit/tlsserver/secmod.db differ
diff --git a/security/manager/ssl/tests/unit/tlsserver/test-ca.der b/security/manager/ssl/tests/unit/tlsserver/test-ca.der
index f4c4863..356de5b 100644
Binary files a/security/manager/ssl/tests/unit/tlsserver/test-ca.der and b/security/manager/ssl/tests/unit/tlsserver/test-ca.der differ
diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini
index 7935c2d..24b0ffc 100644
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -78,3 +78,7 @@ requesttimeoutfactor = 4
run-sequentially = hardcoded ports
# Bug 676972: this test times out on Android and B2G
skip-if = os == "android" || buildapp == "b2g"
+[test_pinning.js]
+run-sequentially = hardcoded ports
+# Bug 676972: test fails consistently on Android and B2G
+fail-if = os == "android" || buildapp == "b2g"
\ No newline at end of file
diff --git a/security/manager/tools/PreloadedHPKPins.json b/security/manager/tools/PreloadedHPKPins.json
new file mode 100644
index 0000000..ed3b9b7
--- /dev/null
+++ b/security/manager/tools/PreloadedHPKPins.json
@@ -0,0 +1,247 @@
+// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// The top-level element is a dictionary with two keys: "pinsets" maps details
+// of certificate pinning to a name and "entries" contains the HPKP details for
+// each host.
+//
+// "pinsets" is a list of objects. Each object has the following members:
+// name: (string) the name of the pinset
+// sha256_hashes: (list of strings) the set of allowed SPKIs hashes
+//
+// For a given pinset, a certificate is accepted if at least one of the
+// Subject Public Key Infos (SPKIs) is found in the chain. SPKIs are specified
+// as names, which must match up with the name given in the Mozilla root store.
+//
+// "entries" is a list of objects. Each object has the following members:
+// name: (string) the DNS name of the host in question
+// include_subdomains: (optional bool) whether subdomains of |name| are also covered
+// pins: (string) the |name| member of an object in |pinsets|
+//
+// "extra_certs" is a list of base64-encoded certificates. These are used in
+// pinsets that reference certificates not in our root program (for example,
+// Facebook).
+
+// equifax -> aus3
+// Geotrust Primary -> www.mozilla.org
+// Geotrust Global -> *. addons.mozilla.org
+{
+ "chromium_data" : {
+ "cert_file_url": "https://src.chromium.org/chrome/trunk/src/net/http/transport_security_state…",
+ "json_file_url": "https://src.chromium.org/chrome/trunk/src/net/http/transport_security_state…",
+ "substitute_pinsets": {
+ // Use the larger google_root_pems pinset instead of google
+ "google": "google_root_pems"
+ },
+ "production_pinsets": [
+ "google_root_pems"
+ ],
+ "production_domains": [
+ // Chrome's test domain.
+ "pinningtest.appspot.com",
+ // Dropbox
+ "dropbox.com",
+ "www.dropbox.com",
+ // Twitter
+ "api.twitter.com",
+ "business.twitter.com",
+ "dev.twitter.com",
+ "mobile.twitter.com",
+ "oauth.twitter.com",
+ "platform.twitter.com",
+ "twimg.com",
+ "www.twitter.com",
+ // Tor
+ "torproject.org",
+ "blog.torproject.org",
+ "check.torproject.org",
+ "dist.torproject.org",
+ "www.torproject.org"
+ ],
+ "exclude_domains" : [
+ // Chrome's entry for twitter.com doesn't include subdomains, so replace
+ // it with our own entry below which also uses an expanded pinset.
+ "twitter.com"
+ ]
+ },
+ "pinsets": [
+ {
+ // From bug 772756, mozilla uses GeoTrust, Digicert and Thawte. Our
+ // cdn sites use Verisign and Baltimore. We exclude 1024-bit root certs
+ // from all providers. geotrust ca info:
+ // http://www.geotrust.com/resources/root-certificates/index.html
+ "name": "mozilla",
+ "sha256_hashes": [
+ "Baltimore CyberTrust Root",
+ "DigiCert Assured ID Root CA",
+ "DigiCert Global Root CA",
+ "DigiCert High Assurance EV Root CA",
+ "GeoTrust Global CA",
+ "GeoTrust Global CA 2",
+ "GeoTrust Primary Certification Authority",
+ "GeoTrust Primary Certification Authority - G2",
+ "GeoTrust Primary Certification Authority - G3",
+ "GeoTrust Universal CA",
+ "GeoTrust Universal CA 2",
+ "thawte Primary Root CA",
+ "thawte Primary Root CA - G2",
+ "thawte Primary Root CA - G3",
+ "Verisign Class 1 Public Primary Certification Authority - G3",
+ "Verisign Class 2 Public Primary Certification Authority - G3",
+ "Verisign Class 3 Public Primary Certification Authority - G3",
+ "VeriSign Class 3 Public Primary Certification Authority - G4",
+ "VeriSign Class 3 Public Primary Certification Authority - G5",
+ "Verisign Class 4 Public Primary Certification Authority - G3",
+ "VeriSign Universal Root Certification Authority"
+ ]
+ },
+ {
+ "name": "mozilla_services",
+ "sha256_hashes": [
+ "DigiCert Global Root CA"
+ ]
+ },
+ // For pinning tests on pinning.example.com, the certificate must be 'End
+ // Entity Test Cert'
+ {
+ "name": "mozilla_test",
+ "sha256_hashes": [
+ "End Entity Test Cert"
+ ]
+ },
+ // Google's root PEMs. Chrome pins only to their intermediate certs, but
+ // they'd like us to be more liberal. For the initial list, we are using
+ // the certs from http://pki.google.com/roots.pem.
+ // We have no built-in for commented out CAs.
+ {
+ "name": "google_root_pems",
+ "sha256_hashes": [
+ "AddTrust External Root",
+ "AddTrust Low-Value Services Root",
+ "AddTrust Public Services Root",
+ "AddTrust Qualified Certificates Root",
+ "AffirmTrust Commercial",
+ "AffirmTrust Networking",
+ "AffirmTrust Premium",
+ "AffirmTrust Premium ECC",
+ "America Online Root Certification Authority 1",
+ "America Online Root Certification Authority 2",
+ "Baltimore CyberTrust Root",
+ "Comodo AAA Services root",
+ "COMODO Certification Authority",
+ "COMODO ECC Certification Authority",
+ "Comodo Secure Services root",
+ "Comodo Trusted Services root",
+ "Cybertrust Global Root",
+ "DigiCert Assured ID Root CA",
+ "DigiCert Global Root CA",
+ "DigiCert High Assurance EV Root CA",
+ "Entrust.net Premium 2048 Secure Server CA",
+ // "Entrust.net Secure Server CA",
+ "Entrust Root Certification Authority",
+ "Equifax Secure CA",
+ "Equifax Secure eBusiness CA 1",
+ // "Equifax Secure eBusiness CA 2",
+ "Equifax Secure Global eBusiness CA",
+ "GeoTrust Global CA",
+ "GeoTrust Global CA 2",
+ "GeoTrust Primary Certification Authority",
+ "GeoTrust Primary Certification Authority - G2",
+ "GeoTrust Primary Certification Authority - G3",
+ "GeoTrust Universal CA",
+ "GeoTrust Universal CA 2",
+ "GlobalSign Root CA",
+ "GlobalSign Root CA - R2",
+ "GlobalSign Root CA - R3",
+ "Go Daddy Class 2 CA",
+ "Go Daddy Root Certificate Authority - G2",
+ // "GTE CyberTrust Global Root",
+ "Network Solutions Certificate Authority",
+ // "RSA Root Certificate 1",
+ "Starfield Class 2 CA",
+ "Starfield Root Certificate Authority - G2",
+ "Starfield Services Root Certificate Authority - G2",
+ "StartCom Certification Authority",
+ "StartCom Certification Authority",
+ "StartCom Certification Authority G2",
+ "TC TrustCenter Class 2 CA II",
+ "TC TrustCenter Class 3 CA II",
+ "TC TrustCenter Universal CA I",
+ "TC TrustCenter Universal CA III",
+ "Thawte Premium Server CA",
+ "thawte Primary Root CA",
+ "thawte Primary Root CA - G2",
+ "thawte Primary Root CA - G3",
+ "Thawte Server CA",
+ "UTN DATACorp SGC Root CA",
+ "UTN USERFirst Hardware Root CA",
+ // "ValiCert Class 1 VA",
+ // "ValiCert Class 2 VA",
+ "Verisign Class 3 Public Primary Certification Authority",
+ "Verisign Class 3 Public Primary Certification Authority",
+ "Verisign Class 3 Public Primary Certification Authority - G2",
+ "Verisign Class 3 Public Primary Certification Authority - G3",
+ "VeriSign Class 3 Public Primary Certification Authority - G4",
+ "VeriSign Class 3 Public Primary Certification Authority - G5",
+ "Verisign Class 4 Public Primary Certification Authority - G3",
+ "VeriSign Universal Root Certification Authority",
+ "XRamp Global CA Root"
+ ]
+ },
+ {
+ "name": "facebook",
+ "sha256_hashes": [
+ "Verisign Class 3 Public Primary Certification Authority - G3",
+ "DigiCert High Assurance EV Root CA",
+ "DigiCert ECC Secure Server CA"
+ ]
+ }
+ ],
+
+ "entries": [
+ // Only domains that are operationally crucial to Firefox can have per-host
+ // telemetry reporting (the "id") field
+ { "name": "addons.mozilla.org", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": false, "id": 1 },
+ { "name": "addons.mozilla.net", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": false, "id": 2 },
+ { "name": "aus4.mozilla.org", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": true, "id": 3 },
+ { "name": "accounts.firefox.com", "include_subdomains": true,
+ "pins": "mozilla_services", "test_mode": false, "id": 4 },
+ { "name": "api.accounts.firefox.com", "include_subdomains": true,
+ "pins": "mozilla_services", "test_mode": false, "id": 5 },
+ { "name": "cdn.mozilla.net", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": false },
+ { "name": "cdn.mozilla.org", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": false },
+ { "name": "media.mozilla.com", "include_subdomains": true,
+ "pins": "mozilla", "test_mode": false },
+ { "name": "services.mozilla.com", "include_subdomains": true,
+ "pins": "mozilla_services", "test_mode": true },
+ { "name": "include-subdomains.pinning.example.com",
+ "include_subdomains": true, "pins": "mozilla_test",
+ "test_mode": false },
+ // Example domain to collect per-host stats for telemetry tests.
+ { "name": "exclude-subdomains.pinning.example.com",
+ "include_subdomains": false, "pins": "mozilla_test",
+ "test_mode": false, "id": 0 },
+ { "name": "test-mode.pinning.example.com", "include_subdomains": true,
+ "pins": "mozilla_test", "test_mode": true },
+ // Expand twitter's pinset to include all of *.twitter.com and use
+ // twitterCDN. More specific rules take precedence because we search for
+ // exact domain name first.
+ { "name": "twitter.com", "include_subdomains": true,
+ "pins": "twitterCDN", "test_mode": false },
+ // Facebook (not pinned by Chrome)
+ { "name": "facebook.com", "include_subdomains": true,
+ "pins": "facebook", "test_mode": true }
+ ],
+
+ "extra_certificates": [
+ // DigiCert ECC Secure Server CA (for Facebook)
+ "MIIDrDCCApSgAwIBAgIQCssoukZe5TkIdnRw883GEjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJjAkBgNVBAMTHURpZ2lDZXJ0IEVDQyBTZWN1cmUgU2VydmVyIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ghC6nfYJN6gLGSkE85AnCNyqQIKDjc/ITa4jVMU9tWRlUvzlgKNcR7E2Munn17voOZ/WpIRllNv68DLP679Wz9HJOeaBy6Wvqgvu1cYr3GkvXg6HuhbPGtkESvMNCuMo4IBITCCAR0wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdENBLmNybDA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAdBgNVHQ4EFgQUo53mH/naOU/AbuiRy5Wl2jHiCp8wHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEMBQADggEBAMeKoENL7HTJxavVHzA1Nm6YVntIrAVjrnuaVyRXzG/63qttnMe2uuzO58pzZNvfBDcKAEmzP58
mrZGMIOgfiA4q+2Y3yDDo0sIkp0VILeoBUEoxlBPfjV/aKrtJPGHzecicZpIalir0ezZYoyxBEHQa0+1IttK7igZFcTMQMHp6mCHdJLnsnLWSB62DxsRq+HfmNb4TDydkskO/g+l3VtsIh5RHFPVfKK+jaEyDj2D3loB5hWp2Jp2VDCADjT7ueihlZGak2YPqmXTNbk19HOuNssWvFhtOyPNV6og4ETQdEa8/B6hPatJ0ES8q/HO3X8IVQwVs1n3aAr0im0/T+Xc="
+ ]
+}
diff --git a/security/manager/tools/genHPKPStaticPins.js b/security/manager/tools/genHPKPStaticPins.js
new file mode 100644
index 0000000..d16d017
--- /dev/null
+++ b/security/manager/tools/genHPKPStaticPins.js
@@ -0,0 +1,576 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// How to run this file:
+// 1. [obtain firefox source code]
+// 2. [build/obtain firefox binaries]
+// 3. run `[path to]/run-mozilla.sh [path to]/xpcshell \
+// [path to]/genHPKPStaticpins.js \
+// [absolute path to]/PreloadedHPKPins.json \
+// [absolute path to]/default-ee.der \
+// [absolute path to]/StaticHPKPins.h
+
+if (arguments.length != 3) {
+ throw "Usage: genHPKPStaticPins.js " +
+ "<absolute path to PreloadedHPKPins.json> " +
+ "<absolute path to default-ee.der> " +
+ "<absolute path to StaticHPKPins.h>";
+}
+
+const { 'classes': Cc, 'interfaces': Ci, 'utils': Cu, 'results': Cr } = Components;
+
+let { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
+let { FileUtils } = Cu.import("resource://gre/modules/FileUtils.jsm", {});
+let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
+let gCertDB = Cc["@mozilla.org/security/x509certdb;1"]
+ .getService(Ci.nsIX509CertDB);
+
+const BUILT_IN_NICK_PREFIX = "Builtin Object Token:";
+const SHA1_PREFIX = "sha1/";
+const SHA256_PREFIX = "sha256/";
+const GOOGLE_PIN_PREFIX = "GOOGLE_PIN_";
+
+// Pins expire in 14 weeks (6 weeks on Beta + 8 weeks on stable)
+const PINNING_MINIMUM_REQUIRED_MAX_AGE = 60 * 60 * 24 * 7 * 14;
+
+const FILE_HEADER = "/* This Source Code Form is subject to the terms of the Mozilla Public\n" +
+" * License, v. 2.0. If a copy of the MPL was not distributed with this\n" +
+" * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n" +
+"\n" +
+"/*****************************************************************************/\n" +
+"/* This is an automatically generated file. If you're not */\n" +
+"/* PublicKeyPinningService.cpp, you shouldn't be #including it. */\n" +
+"/*****************************************************************************/\n" +
+"#include <stdint.h>" +
+"\n";
+
+const DOMAINHEADER = "/* Domainlist */\n" +
+ "struct TransportSecurityPreload {\n" +
+ " const char* mHost;\n" +
+ " const bool mIncludeSubdomains;\n" +
+ " const bool mTestMode;\n" +
+ " const bool mIsMoz;\n" +
+ " const int32_t mId;\n" +
+ " const StaticPinset *pinset;\n" +
+ "};\n\n";
+
+const PINSETDEF = "/* Pinsets are each an ordered list by the actual value of the fingerprint */\n" +
+ "struct StaticFingerprints {\n" +
+ " const size_t size;\n" +
+ " const char* const* data;\n" +
+ "};\n\n" +
+ "struct StaticPinset {\n" +
+ " const StaticFingerprints* sha1;\n" +
+ " const StaticFingerprints* sha256;\n" +
+ "};\n\n";
+
+// Command-line arguments
+var gStaticPins = parseJson(arguments[0]);
+var gTestCertFile = arguments[1];
+
+// Open the output file.
+let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+file.initWithPath(arguments[2]);
+let gFileOutputStream = FileUtils.openSafeFileOutputStream(file);
+
+function writeString(string) {
+ gFileOutputStream.write(string, string.length);
+}
+
+function readFileToString(filename) {
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(filename);
+ let stream = Cc["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Ci.nsIFileInputStream);
+ stream.init(file, -1, 0, 0);
+ let buf = NetUtil.readInputStreamToString(stream, stream.available());
+ return buf;
+}
+
+function stripComments(buf) {
+ var lines = buf.split("\n");
+ let entryRegex = /^\s*\/\//;
+ let data = "";
+ for (let i = 0; i < lines.length; ++i) {
+ let match = entryRegex.exec(lines[i]);
+ if (!match) {
+ data = data + lines[i];
+ }
+ }
+ return data;
+}
+
+function isBuiltinToken(tokenName) {
+ return tokenName == "Builtin Object Token";
+}
+
+function isCertBuiltIn(cert) {
+ let tokenNames = cert.getAllTokenNames({});
+ if (!tokenNames) {
+ return false;
+ }
+ if (tokenNames.some(isBuiltinToken)) {
+ return true;
+ }
+ return false;
+}
+
+function download(filename) {
+ var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Ci.nsIXMLHttpRequest);
+ req.open("GET", filename, false); // doing the request synchronously
+ try {
+ req.send();
+ }
+ catch (e) {
+ throw "ERROR: problem downloading '" + filename + "': " + e;
+ }
+
+ if (req.status != 200) {
+ throw("ERROR: problem downloading '" + filename + "': status " +
+ req.status);
+ }
+ return req.responseText;
+}
+
+function downloadAsJson(filename) {
+ // we have to filter out '//' comments
+ var result = download(filename).replace(/\/\/[^\n]*\n/g, "");
+ var data = null;
+ try {
+ data = JSON.parse(result);
+ }
+ catch (e) {
+ throw "ERROR: could not parse data from '" + filename + "': " + e;
+ }
+ return data;
+}
+
+// Returns a Subject Public Key Digest from the given pem, if it exists.
+function getSKDFromPem(pem) {
+ let cert = gCertDB.constructX509FromBase64(pem, pem.length);
+ return cert.sha256SubjectPublicKeyInfoDigest;
+}
+
+// Downloads the static certs file and tries to map Google Chrome nicknames
+// to Mozilla nicknames, as well as storing any hashes for pins for which we
+// don't have root PEMs. Each entry consists of a line containing the name of
+// the pin followed either by a hash in the format "sha1/" + base64(hash), or
+// a PEM encoded certificate. For certificates that we have in our database,
+// return a map of Google's nickname to ours. For ones that aren't return a
+// map of Google's nickname to sha1 values. This code is modeled after agl's
+// https://github.com/agl/transport-security-state-generate, which doesn't
+// live in the Chromium repo because go is not an official language in
+// Chromium.
+// For all of the entries in this file:
+// - If the entry has a hash format, find the Mozilla pin name (cert nickname)
+// and stick the hash into certSKDToName
+// - If the entry has a PEM format, parse the PEM, find the Mozilla pin name
+// and stick the hash in certSKDToName
+// We MUST be able to find a corresponding cert nickname for the Chrome names,
+// otherwise we skip all pinsets referring to that Chrome name.
+function downloadAndParseChromeCerts(filename, certSKDToName) {
+ // Prefixes that we care about.
+ const BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
+ const END_CERT = "-----END CERTIFICATE-----";
+
+ // Parsing states.
+ const PRE_NAME = 0;
+ const POST_NAME = 1;
+ const IN_CERT = 2;
+ let state = PRE_NAME;
+
+ let lines = download(filename).split("\n");
+ let name = "";
+ let pemCert = "";
+ let hash = "";
+ let chromeNameToHash = {};
+ let chromeNameToMozName = {}
+ for (let i = 0; i < lines.length; ++i) {
+ let line = lines[i];
+ // Skip comments and newlines.
+ if (line.length == 0 || line[0] == '#') {
+ continue;
+ }
+ switch(state) {
+ case PRE_NAME:
+ chromeName = line;
+ state = POST_NAME;
+ break;
+ case POST_NAME:
+ if (line.startsWith(SHA1_PREFIX) ||
+ line.startsWith(SHA256_PREFIX)) {
+ if (line.startsWith(SHA1_PREFIX)) {
+ hash = line.substring(SHA1_PREFIX.length);
+ } else if (line.startsWith(SHA256_PREFIX)) {
+ hash = line.substring(SHA256_PREFIX);
+ }
+ // Store the entire prefixed hash, so we can disambiguate sha1 from
+ // sha256 later.
+ chromeNameToHash[chromeName] = line;
+ certNameToSKD[chromeName] = hash;
+ certSKDToName[hash] = chromeName;
+ state = PRE_NAME;
+ } else if (line.startsWith(BEGIN_CERT)) {
+ state = IN_CERT;
+ } else {
+ throw "ERROR: couldn't parse Chrome certificate file " + line;
+ }
+ break;
+ case IN_CERT:
+ if (line.startsWith(END_CERT)) {
+ state = PRE_NAME;
+ hash = getSKDFromPem(pemCert);
+ pemCert = "";
+ if (hash in certSKDToName) {
+ mozName = certSKDToName[hash];
+ } else {
+ // Not one of our built-in certs. Prefix the name with
+ // GOOGLE_PIN_.
+ mozName = GOOGLE_PIN_PREFIX + chromeName;
+ dump("Can't find hash in builtin certs for Chrome nickname " +
+ chromeName + ", inserting " + mozName + "\n");
+ certSKDToName[hash] = mozName;
+ certNameToSKD[mozName] = hash;
+ }
+ chromeNameToMozName[chromeName] = mozName;
+ } else {
+ pemCert += line;
+ }
+ break;
+ default:
+ throw "ERROR: couldn't parse Chrome certificate file " + line;
+ }
+ }
+ return [ chromeNameToHash, chromeNameToMozName ];
+}
+
+// We can only import pinsets from chrome if for every name in the pinset:
+// - We have a hash from Chrome's static certificate file
+// - We have a builtin cert
+// If the pinset meets these requirements, we store a map array of pinset
+// objects:
+// {
+// pinset_name : {
+// // Array of names with entries in certNameToSKD
+// sha1_hashes: [],
+// sha256_hashes: []
+// }
+// }
+// and an array of imported pinset entries:
+// { name: string, include_subdomains: boolean, test_mode: boolean,
+// pins: pinset_name }
+function downloadAndParseChromePins(filename,
+ chromeNameToHash,
+ chromeNameToMozName,
+ certNameToSKD,
+ certSKDToName) {
+ let chromePreloads = downloadAsJson(filename);
+ let chromePins = chromePreloads.pinsets;
+ let chromeImportedPinsets = {};
+ let chromeImportedEntries = [];
+
+ chromePins.forEach(function(pin) {
+ let valid = true;
+ let pinset = { name: pin.name, sha1_hashes: [], sha256_hashes: [] };
+ // Translate the Chrome pinset format to ours
+ pin.static_spki_hashes.forEach(function(name) {
+ if (name in chromeNameToHash) {
+ let hash = chromeNameToHash[name];
+ if (hash.startsWith(SHA1_PREFIX)) {
+ hash = hash.substring(SHA1_PREFIX.length);
+ pinset.sha1_hashes.push(certSKDToName[hash]);
+ } else if (hash.startsWith(SHA256_PREFIX)) {
+ hash = hash.substring(SHA256_PREFIX.length);
+ pinset.sha256_hashes.push(certSKDToName[hash]);
+ } else {
+ throw("Unsupported hash type: " + chromeNameToHash[name]);
+ }
+ // We should have already added hashes for all of these when we
+ // imported the certificate file.
+ if (!certNameToSKD[name]) {
+ throw("No hash for name: " + name);
+ }
+ } else if (name in chromeNameToMozName) {
+ pinset.sha256_hashes.push(chromeNameToMozName[name]);
+ } else {
+ dump("Skipping Chrome pinset " + pinset.name + ", couldn't find " +
+ "builtin " + name + " from cert file\n");
+ valid = false;
+ }
+ });
+ if (valid) {
+ chromeImportedPinsets[pinset.name] = pinset;
+ }
+ });
+
+ // Grab the domain entry lists. Chrome's entry format is similar to
+ // ours, except theirs includes a HSTS mode.
+ const cData = gStaticPins.chromium_data;
+ let entries = chromePreloads.entries;
+ entries.forEach(function(entry) {
+ let pinsetName = cData.substitute_pinsets[entry.pins];
+ if (!pinsetName) {
+ pinsetName = entry.pins;
+ }
+ let isProductionDomain =
+ (cData.production_domains.indexOf(entry.name) != -1);
+ let isProductionPinset =
+ (cData.production_pinsets.indexOf(pinsetName) != -1);
+ let excludeDomain =
+ (cData.exclude_domains.indexOf(entry.name) != -1);
+ let isTestMode = !isProductionPinset && !isProductionDomain;
+ if (entry.pins && !excludeDomain && chromeImportedPinsets[entry.pins]) {
+ chromeImportedEntries.push({
+ name: entry.name,
+ include_subdomains: entry.include_subdomains,
+ test_mode: isTestMode,
+ is_moz: false,
+ pins: pinsetName });
+ }
+ });
+ return [ chromeImportedPinsets, chromeImportedEntries ];
+}
+
+// Returns a pair of maps [certNameToSKD, certSKDToName] between cert
+// nicknames and digests of the SPKInfo for the mozilla trust store
+function loadNSSCertinfo(derTestFile, extraCertificates) {
+ let allCerts = gCertDB.getCerts();
+ let enumerator = allCerts.getEnumerator();
+ let certNameToSKD = {};
+ let certSKDToName = {};
+ while (enumerator.hasMoreElements()) {
+ let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
+ if (!isCertBuiltIn(cert)) {
+ continue;
+ }
+ let name = cert.nickname.substr(BUILT_IN_NICK_PREFIX.length);
+ let SKD = cert.sha256SubjectPublicKeyInfoDigest;
+ certNameToSKD[name] = SKD;
+ certSKDToName[SKD] = name;
+ }
+
+ for (let cert of extraCertificates) {
+ let name = cert.commonName;
+ let SKD = cert.sha256SubjectPublicKeyInfoDigest;
+ certNameToSKD[name] = SKD;
+ certSKDToName[SKD] = name;
+ }
+
+ {
+ // A certificate for *.example.com.
+ let der = readFileToString(derTestFile);
+ let testCert = gCertDB.constructX509(der, der.length);
+ // We can't include this cert in the previous loop, because it skips
+ // non-builtin certs and the nickname is not built-in to the cert.
+ let name = "End Entity Test Cert";
+ let SKD = testCert.sha256SubjectPublicKeyInfoDigest;
+ certNameToSKD[name] = SKD;
+ certSKDToName[SKD] = name;
+ }
+ return [certNameToSKD, certSKDToName];
+}
+
+function parseJson(filename) {
+ let json = stripComments(readFileToString(filename));
+ return JSON.parse(json);
+}
+
+function nameToAlias(certName) {
+ // change the name to a string valid as a c identifier
+ // remove non-ascii characters
+ certName = certName.replace( /[^[:ascii:]]/g, "_");
+ // replace non word characters
+ certName = certName.replace(/[^A-Za-z0-9]/g ,"_");
+
+ return "k" + certName + "Fingerprint";
+}
+
+function compareByName (a, b) {
+ return a.name.localeCompare(b.name);
+}
+
+function genExpirationTime() {
+ let now = new Date();
+ let nowMillis = now.getTime();
+ let expirationMillis = nowMillis + (PINNING_MINIMUM_REQUIRED_MAX_AGE * 1000);
+ let expirationMicros = expirationMillis * 1000;
+ return "static const PRTime kPreloadPKPinsExpirationTime = INT64_C(" +
+ expirationMicros +");\n";
+}
+
+function writeFullPinset(certNameToSKD, certSKDToName, pinset) {
+ // We aren't guaranteed to have sha1 hashes in our own imported pins.
+ let prefix = "kPinset_" + pinset.name;
+ let sha1Name = "nullptr";
+ let sha256Name = "nullptr";
+ if (pinset.sha1_hashes && pinset.sha1_hashes.length > 0) {
+ writeFingerprints(certNameToSKD, certSKDToName, pinset.name,
+ pinset.sha1_hashes, "sha1");
+ sha1Name = "&" + prefix + "_sha1";
+ }
+ if (pinset.sha256_hashes && pinset.sha256_hashes.length > 0) {
+ writeFingerprints(certNameToSKD, certSKDToName, pinset.name,
+ pinset.sha256_hashes, "sha256");
+ sha256Name = "&" + prefix + "_sha256";
+ }
+ writeString("static const StaticPinset " + prefix + " = {\n" +
+ " " + sha1Name + ",\n " + sha256Name + "\n};\n\n");
+}
+
+function writeFingerprints(certNameToSKD, certSKDToName, name, hashes, type) {
+ let varPrefix = "kPinset_" + name + "_" + type;
+ writeString("static const char* " + varPrefix + "_Data[] = {\n");
+ let SKDList = [];
+ for (let certName of hashes) {
+ if (!(certName in certNameToSKD)) {
+ throw "Can't find " + certName + " in certNameToSKD";
+ }
+ SKDList.push(certNameToSKD[certName]);
+ }
+ for (let skd of SKDList.sort()) {
+ writeString(" " + nameToAlias(certSKDToName[skd]) + ",\n");
+ }
+ if (hashes.length == 0) {
+ // ANSI C requires that an initialiser list be non-empty.
+ writeString(" 0\n");
+ }
+ writeString("};\n");
+ writeString("static const StaticFingerprints " + varPrefix + " = {\n " +
+ "sizeof(" + varPrefix + "_Data) / sizeof(const char*),\n " + varPrefix +
+ "_Data\n};\n\n");
+}
+
+function writeEntry(entry) {
+ let printVal = " { \"" + entry.name + "\",\ ";
+ if (entry.include_subdomains) {
+ printVal += "true, ";
+ } else {
+ printVal += "false, ";
+ }
+ // Default to test mode if not specified.
+ let testMode = true;
+ if (entry.hasOwnProperty("test_mode")) {
+ testMode = entry.test_mode;
+ }
+ if (testMode) {
+ printVal += "true, ";
+ } else {
+ printVal += "false, ";
+ }
+ if (entry.is_moz || (entry.pins == "mozilla")) {
+ printVal += "true, ";
+ } else {
+ printVal += "false, ";
+ }
+ if (entry.id >= 256) {
+ throw("Not enough buckets in histogram");
+ }
+ if (entry.id >= 0) {
+ printVal += entry.id + ", ";
+ } else {
+ printVal += "-1, ";
+ }
+ printVal += "&kPinset_" + entry.pins;
+ printVal += " },\n";
+ writeString(printVal);
+}
+
+function writeDomainList(chromeImportedEntries) {
+ writeString("/* Sort hostnames for binary search. */\n");
+ writeString("static const TransportSecurityPreload " +
+ "kPublicKeyPinningPreloadList[] = {\n");
+ let count = 0;
+ let sortedEntries = gStaticPins.entries;
+ sortedEntries.push.apply(sortedEntries, chromeImportedEntries);
+ for (let entry of sortedEntries.sort(compareByName)) {
+ count++;
+ writeEntry(entry);
+ }
+ writeString("};\n");
+
+ writeString("\n// Pinning Preload List Length = " + count + ";\n");
+ writeString("\nstatic const int32_t kUnknownId = -1;\n");
+}
+
+function writeFile(certNameToSKD, certSKDToName,
+ chromeImportedPinsets, chromeImportedEntries) {
+ // Compute used pins from both Chrome's and our pinsets, so we can output
+ // them later.
+ usedFingerprints = {};
+ gStaticPins.pinsets.forEach(function(pinset) {
+ // We aren't guaranteed to have sha1_hashes in our own JSON.
+ if (pinset.sha1_hashes) {
+ pinset.sha1_hashes.forEach(function(name) {
+ usedFingerprints[name] = true;
+ });
+ }
+ if (pinset.sha256_hashes) {
+ pinset.sha256_hashes.forEach(function(name) {
+ usedFingerprints[name] = true;
+ });
+ }
+ });
+ for (let key in chromeImportedPinsets) {
+ let pinset = chromeImportedPinsets[key];
+ pinset.sha1_hashes.forEach(function(name) {
+ usedFingerprints[name] = true;
+ });
+ pinset.sha256_hashes.forEach(function(name) {
+ usedFingerprints[name] = true;
+ });
+ }
+
+ writeString(FILE_HEADER);
+
+ // Write actual fingerprints.
+ Object.keys(usedFingerprints).sort().forEach(function(certName) {
+ if (certName) {
+ writeString("/* " + certName + " */\n");
+ writeString("static const char " + nameToAlias(certName) + "[] =\n");
+ writeString(" \"" + certNameToSKD[certName] + "\";\n");
+ writeString("\n");
+ }
+ });
+
+ // Write the pinsets
+ writeString(PINSETDEF);
+ writeString("/* PreloadedHPKPins.json pinsets */\n");
+ gStaticPins.pinsets.sort(compareByName).forEach(function(pinset) {
+ writeFullPinset(certNameToSKD, certSKDToName, pinset);
+ });
+ writeString("/* Chrome static pinsets */\n");
+ for (let key in chromeImportedPinsets) {
+ writeFullPinset(certNameToSKD, certSKDToName, chromeImportedPinsets[key]);
+ }
+
+ // Write the domainlist entries.
+ writeString(DOMAINHEADER);
+ writeDomainList(chromeImportedEntries);
+ writeString("\n");
+ writeString(genExpirationTime());
+}
+
+function loadExtraCertificates(certStringList) {
+ let constructedCerts = [];
+ for (let certString of certStringList) {
+ constructedCerts.push(gCertDB.constructX509FromBase64(certString));
+ }
+ return constructedCerts;
+}
+
+let extraCertificates = loadExtraCertificates(gStaticPins.extra_certificates);
+let [ certNameToSKD, certSKDToName ] = loadNSSCertinfo(gTestCertFile,
+ extraCertificates);
+let [ chromeNameToHash, chromeNameToMozName ] = downloadAndParseChromeCerts(
+ gStaticPins.chromium_data.cert_file_url, certSKDToName);
+let [ chromeImportedPinsets, chromeImportedEntries ] =
+ downloadAndParseChromePins(gStaticPins.chromium_data.json_file_url,
+ chromeNameToHash, chromeNameToMozName, certNameToSKD, certSKDToName);
+
+writeFile(certNameToSKD, certSKDToName, chromeImportedPinsets,
+ chromeImportedEntries);
+
+FileUtils.closeSafeFileOutputStream(gFileOutputStream);
diff --git a/security/pkix/include/pkix/Result.h b/security/pkix/include/pkix/Result.h
new file mode 100644
index 0000000..e82e6428
--- /dev/null
+++ b/security/pkix/include/pkix/Result.h
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This code is made available to you under your choice of the following sets
+ * of licensing terms:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/* Copyright 2013 Mozilla Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef mozilla_pkix__Result_h
+#define mozilla_pkix__Result_h
+
+#include <cassert>
+
+#include "pkix/enumclass.h"
+
+namespace mozilla { namespace pkix {
+
+static const unsigned int FATAL_ERROR_FLAG = 0x800;
+
+// The first argument to MOZILLA_PKIX_MAP() is used for building the mapping
+// from error code to error name in MapResultToName.
+//
+// The second argument is for defining the value for the enum literal in the
+// Result enum class.
+//
+// The third argument to MOZILLA_PKIX_MAP() is used, along with the first
+// argument, for maintaining the mapping of mozilla::pkix error codes to
+// NSS/NSPR error codes in pkixnss.cpp.
+#define MOZILLA_PKIX_MAP_LIST \
+ MOZILLA_PKIX_MAP(Success, 0, 0) \
+ MOZILLA_PKIX_MAP(ERROR_BAD_DER, 1, \
+ SEC_ERROR_BAD_DER) \
+ MOZILLA_PKIX_MAP(ERROR_CA_CERT_INVALID, 2, \
+ SEC_ERROR_CA_CERT_INVALID) \
+ MOZILLA_PKIX_MAP(ERROR_BAD_SIGNATURE, 3, \
+ SEC_ERROR_BAD_SIGNATURE) \
+ MOZILLA_PKIX_MAP(ERROR_CERT_BAD_ACCESS_LOCATION, 4, \
+ SEC_ERROR_CERT_BAD_ACCESS_LOCATION) \
+ MOZILLA_PKIX_MAP(ERROR_CERT_NOT_IN_NAME_SPACE, 5, \
+ SEC_ERROR_CERT_NOT_IN_NAME_SPACE) \
+ MOZILLA_PKIX_MAP(ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED, 6, \
+ SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED) \
+ MOZILLA_PKIX_MAP(ERROR_CONNECT_REFUSED, 7, \
+ PR_CONNECT_REFUSED_ERROR) \
+ MOZILLA_PKIX_MAP(ERROR_EXPIRED_CERTIFICATE, 8, \
+ SEC_ERROR_EXPIRED_CERTIFICATE) \
+ MOZILLA_PKIX_MAP(ERROR_EXTENSION_VALUE_INVALID, 9, \
+ SEC_ERROR_EXTENSION_VALUE_INVALID) \
+ MOZILLA_PKIX_MAP(ERROR_INADEQUATE_CERT_TYPE, 10, \
+ SEC_ERROR_INADEQUATE_CERT_TYPE) \
+ MOZILLA_PKIX_MAP(ERROR_INADEQUATE_KEY_USAGE, 11, \
+ SEC_ERROR_INADEQUATE_KEY_USAGE) \
+ MOZILLA_PKIX_MAP(ERROR_INVALID_ALGORITHM, 12, \
+ SEC_ERROR_INVALID_ALGORITHM) \
+ MOZILLA_PKIX_MAP(ERROR_INVALID_TIME, 13, \
+ SEC_ERROR_INVALID_TIME) \
+ MOZILLA_PKIX_MAP(ERROR_KEY_PINNING_FAILURE, 14, \
+ MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE) \
+ MOZILLA_PKIX_MAP(ERROR_PATH_LEN_CONSTRAINT_INVALID, 15, \
+ SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID) \
+ MOZILLA_PKIX_MAP(ERROR_POLICY_VALIDATION_FAILED, 16, \
+ SEC_ERROR_POLICY_VALIDATION_FAILED) \
+ MOZILLA_PKIX_MAP(ERROR_REVOKED_CERTIFICATE, 17, \
+ SEC_ERROR_REVOKED_CERTIFICATE) \
+ MOZILLA_PKIX_MAP(ERROR_UNKNOWN_CRITICAL_EXTENSION, 18, \
+ SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION) \
+ MOZILLA_PKIX_MAP(ERROR_UNKNOWN_ERROR, 19, \
+ PR_UNKNOWN_ERROR) \
+ MOZILLA_PKIX_MAP(ERROR_UNKNOWN_ISSUER, 20, \
+ SEC_ERROR_UNKNOWN_ISSUER) \
+ MOZILLA_PKIX_MAP(ERROR_UNTRUSTED_CERT, 21, \
+ SEC_ERROR_UNTRUSTED_CERT) \
+ MOZILLA_PKIX_MAP(ERROR_UNTRUSTED_ISSUER, 22, \
+ SEC_ERROR_UNTRUSTED_ISSUER) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_BAD_SIGNATURE, 23, \
+ SEC_ERROR_OCSP_BAD_SIGNATURE) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_INVALID_SIGNING_CERT, 24, \
+ SEC_ERROR_OCSP_INVALID_SIGNING_CERT) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_MALFORMED_REQUEST, 25, \
+ SEC_ERROR_OCSP_MALFORMED_REQUEST) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_MALFORMED_RESPONSE, 26, \
+ SEC_ERROR_OCSP_MALFORMED_RESPONSE) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_OLD_RESPONSE, 27, \
+ SEC_ERROR_OCSP_OLD_RESPONSE) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_REQUEST_NEEDS_SIG, 28, \
+ SEC_ERROR_OCSP_REQUEST_NEEDS_SIG) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_RESPONDER_CERT_INVALID, 29, \
+ SEC_ERROR_OCSP_RESPONDER_CERT_INVALID) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_SERVER_ERROR, 30, \
+ SEC_ERROR_OCSP_SERVER_ERROR) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_TRY_SERVER_LATER, 31, \
+ SEC_ERROR_OCSP_TRY_SERVER_LATER) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_UNAUTHORIZED_REQUEST, 32, \
+ SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, 33, \
+ SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_UNKNOWN_CERT, 34, \
+ SEC_ERROR_OCSP_UNKNOWN_CERT) \
+ MOZILLA_PKIX_MAP(ERROR_OCSP_FUTURE_RESPONSE, 35, \
+ SEC_ERROR_OCSP_FUTURE_RESPONSE) \
+ MOZILLA_PKIX_MAP(ERROR_INVALID_KEY, 36, \
+ SEC_ERROR_INVALID_KEY) \
+ MOZILLA_PKIX_MAP(ERROR_UNSUPPORTED_KEYALG, 37, \
+ SEC_ERROR_UNSUPPORTED_KEYALG) \
+ MOZILLA_PKIX_MAP(ERROR_EXPIRED_ISSUER_CERTIFICATE, 38, \
+ SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE) \
+ MOZILLA_PKIX_MAP(ERROR_CA_CERT_USED_AS_END_ENTITY, 39, \
+ MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY) \
+ MOZILLA_PKIX_MAP(ERROR_INADEQUATE_KEY_SIZE, 40, \
+ MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE) \
+ MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_ARGS, FATAL_ERROR_FLAG | 1, \
+ SEC_ERROR_INVALID_ARGS) \
+ MOZILLA_PKIX_MAP(FATAL_ERROR_INVALID_STATE, FATAL_ERROR_FLAG | 2, \
+ PR_INVALID_STATE_ERROR) \
+ MOZILLA_PKIX_MAP(FATAL_ERROR_LIBRARY_FAILURE, FATAL_ERROR_FLAG | 3, \
+ SEC_ERROR_LIBRARY_FAILURE) \
+ MOZILLA_PKIX_MAP(FATAL_ERROR_NO_MEMORY, FATAL_ERROR_FLAG | 4, \
+ SEC_ERROR_NO_MEMORY) \
+ /* nothing here */
+
+MOZILLA_PKIX_ENUM_CLASS Result
+{
+#define MOZILLA_PKIX_MAP(name, value, nss_name) name = value,
+ MOZILLA_PKIX_MAP_LIST
+#undef MOZILLA_PKIX_MAP
+};
+
+// Returns the stringified name of the given result, e.g. "Result::Success",
+// or nullptr if result is unknown (invalid).
+const char* MapResultToName(Result result);
+
+// We write many comparisons as (x != Success), and this shortened name makes
+// those comparisons clearer, especially because the shortened name often
+// results in less line wrapping.
+//
+// Visual Studio before VS2013 does not support "enum class," so
+// Result::Success will already be visible in this scope, and compilation will
+// fail if we try to define a variable with that name here.
+#if !defined(_MSC_VER) || (_MSC_VER >= 1700)
+static const Result Success = Result::Success;
+#endif
+
+inline bool
+IsFatalError(Result rv)
+{
+ return (static_cast<unsigned int>(rv) & FATAL_ERROR_FLAG) != 0;
+}
+
+inline Result
+NotReached(const char* /*explanation*/, Result result)
+{
+ assert(false);
+ return result;
+}
+
+} } // namespace mozilla::pkix
+
+#endif // mozilla_pkix__Result_h
diff --git a/security/pkix/include/pkix/Time.h b/security/pkix/include/pkix/Time.h
new file mode 100644
index 0000000..b8d6ee9
--- /dev/null
+++ b/security/pkix/include/pkix/Time.h
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This code is made available to you under your choice of the following sets
+ * of licensing terms:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/* Copyright 2014 Mozilla Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef mozilla_pkix__Time_h
+#define mozilla_pkix__Time_h
+
+#include <ctime>
+#include <limits>
+#include <stdint.h>
+
+#include "pkix/Result.h"
+
+namespace mozilla { namespace pkix {
+
+// Time with a range from the first second of year 0 (AD) through at least the
+// last second of year 9999, which is the range of legal times in X.509 and
+// OCSP. This type has second-level precision. The time zone is always UTC.
+//
+// Pass by value, not by reference.
+class Time
+{
+public:
+ // Construct an uninitilized instance.
+ //
+ // This will fail to compile because there is no default constructor:
+ // Time x;
+ //
+ // This will succeed, leaving the time uninitialized:
+ // Time x(Time::uninitialized);
+ enum Uninitialized { uninitialized };
+ explicit Time(Uninitialized) { }
+
+ bool operator==(const Time& other) const
+ {
+ return elapsedSecondsAD == other.elapsedSecondsAD;
+ }
+ bool operator>(const Time& other) const
+ {
+ return elapsedSecondsAD > other.elapsedSecondsAD;
+ }
+ bool operator>=(const Time& other) const
+ {
+ return elapsedSecondsAD >= other.elapsedSecondsAD;
+ }
+ bool operator<(const Time& other) const
+ {
+ return elapsedSecondsAD < other.elapsedSecondsAD;
+ }
+ bool operator<=(const Time& other) const
+ {
+ return elapsedSecondsAD <= other.elapsedSecondsAD;
+ }
+
+ Result AddSeconds(uint64_t seconds)
+ {
+ if (std::numeric_limits<uint64_t>::max() - elapsedSecondsAD
+ < seconds) {
+ return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
+ }
+ elapsedSecondsAD += seconds;
+ return Success;
+ }
+
+ Result SubtractSeconds(uint64_t seconds)
+ {
+ if (seconds > elapsedSecondsAD) {
+ return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
+ }
+ elapsedSecondsAD -= seconds;
+ return Success;
+ }
+
+ static const uint64_t ONE_DAY_IN_SECONDS
+ = UINT64_C(24) * UINT64_C(60) * UINT64_C(60);
+
+private:
+ // This constructor is hidden to prevent accidents like this:
+ //
+ // Time foo(time_t t)
+ // {
+ // // WRONG! 1970-01-01-00:00:00 == time_t(0), but not Time(0)!
+ // return Time(t);
+ // }
+ explicit Time(uint64_t elapsedSecondsAD)
+ : elapsedSecondsAD(elapsedSecondsAD)
+ {
+ }
+ friend Time TimeFromElapsedSecondsAD(uint64_t);
+
+ uint64_t elapsedSecondsAD;
+};
+
+inline Time TimeFromElapsedSecondsAD(uint64_t elapsedSecondsAD)
+{
+ return Time(elapsedSecondsAD);
+}
+
+Time Now();
+
+// Note the epoch is the unix epoch (ie 00:00:00 UTC, 1 January 1970)
+Time TimeFromEpochInSeconds(uint64_t secondsSinceEpoch);
+
+} } // namespace mozilla::pkix
+
+#endif // mozilla_pkix__Time_h
diff --git a/security/pkix/include/pkix/pkixtypes.h b/security/pkix/include/pkix/pkixtypes.h
index 0a64b9d..d38603b 100644
--- a/security/pkix/include/pkix/pkixtypes.h
+++ b/security/pkix/include/pkix/pkixtypes.h
@@ -120,6 +120,11 @@ public:
PRTime time,
/*optional*/ const SECItem* stapledOCSPresponse) = 0;
+ // Called as soon as we think we have a valid chain but before revocation
+ // checks are done. Called to compute additional chain level checks, by the
+ // TrustDomain.
+ virtual SECStatus IsChainValid(const CERTCertList* certChain) = 0;
+
protected:
TrustDomain() { }
diff --git a/security/pkix/lib/pkixbuild.cpp b/security/pkix/lib/pkixbuild.cpp
index 22e3f61..c078eda 100644
--- a/security/pkix/lib/pkixbuild.cpp
+++ b/security/pkix/lib/pkixbuild.cpp
@@ -225,6 +225,30 @@ BuildForward(TrustDomain& trustDomain,
}
if (trustLevel == TrustDomain::TrustAnchor) {
+ ScopedCERTCertList certChain(CERT_NewCertList());
+ if (!certChain) {
+ PR_SetError(SEC_ERROR_NO_MEMORY, 0);
+ return MapSECStatus(SECFailure);
+ }
+
+ rv = subject.PrependNSSCertToList(certChain.get());
+ if (rv != Success) {
+ return rv;
+ }
+ BackCert* child = subject.childCert;
+ while (child) {
+ rv = child->PrependNSSCertToList(certChain.get());
+ if (rv != Success) {
+ return rv;
+ }
+ child = child->childCert;
+ }
+
+ SECStatus srv = trustDomain.IsChainValid(certChain.get());
+ if (srv != SECSuccess) {
+ return MapSECStatus(srv);
+ }
+
// End of the recursion. Create the result list and add the trust anchor to
// it.
results = CERT_NewCertList();
diff --git a/security/pkix/lib/pkixtime.cpp b/security/pkix/lib/pkixtime.cpp
new file mode 100644
index 0000000..499784e
--- /dev/null
+++ b/security/pkix/lib/pkixtime.cpp
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This code is made available to you under your choice of the following sets
+ * of licensing terms:
+ */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/* Copyright 2014 Mozilla Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pkix/Time.h"
+#include "pkixutil.h"
+#ifdef WIN32
+#include "windows.h"
+#else
+#include "sys/time.h"
+#endif
+
+namespace mozilla { namespace pkix {
+
+Time
+Now()
+{
+ uint64_t seconds;
+
+#ifdef WIN32
+ // "Contains a 64-bit value representing the number of 100-nanosecond
+ // intervals since January 1, 1601 (UTC)."
+ // - http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).a…
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft);
+ uint64_t ft64 = (static_cast<uint64_t>(ft.dwHighDateTime) << 32) |
+ ft.dwLowDateTime;
+ seconds = (DaysBeforeYear(1601) * Time::ONE_DAY_IN_SECONDS) +
+ ft64 / (1000u * 1000u * 1000u / 100u);
+#else
+ // "The gettimeofday() function shall obtain the current time, expressed as
+ // seconds and microseconds since the Epoch."
+ // - http://pubs.opengroup.org/onlinepubs/009695399/functions/gettimeofday.html
+ timeval tv;
+ (void) gettimeofday(&tv, nullptr);
+ seconds = (DaysBeforeYear(1970) * Time::ONE_DAY_IN_SECONDS) + tv.tv_sec;
+#endif
+
+ return TimeFromElapsedSecondsAD(seconds);
+}
+
+Time
+TimeFromEpochInSeconds(uint64_t secondsSinceEpoch)
+{
+ uint64_t seconds = (DaysBeforeYear(1970) * Time::ONE_DAY_IN_SECONDS) +
+ secondsSinceEpoch;
+ return TimeFromElapsedSecondsAD(seconds);
+}
+
+} } // namespace mozilla::pkix
diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json
index 01a27a1..bf96ccd 100644
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -5929,5 +5929,37 @@
"high": "5000",
"n_buckets": 10,
"extended_statistics_ok": true
+ },
+ "CERT_PINNING_RESULTS": {
+ "expires_in_version": "never",
+ "kind": "boolean",
+ "description": "Certificate pinning results (0 = failure, 1 = success)"
+ },
+ "CERT_PINNING_TEST_RESULTS": {
+ "expires_in_version": "never",
+ "kind": "boolean",
+ "description": "Certificate pinning test results (0 = failure, 1 = success)"
+ },
+ "CERT_PINNING_MOZ_RESULTS": {
+ "expires_in_version": "never",
+ "kind": "boolean",
+ "description": "Certificate pinning results for Mozilla sites (0 = failure, 1 = success)"
+ },
+ "CERT_PINNING_MOZ_TEST_RESULTS": {
+ "expires_in_version": "never",
+ "kind": "boolean",
+ "description": "Certificate pinning test results for Mozilla sites (0 = failure, 1 = success)"
+ },
+ "CERT_PINNING_MOZ_RESULTS_BY_HOST": {
+ "expires_in_version": "never",
+ "kind": "enumerated",
+ "n_values": 512,
+ "description": "Certificate pinning results by host for Mozilla operational sites"
+ },
+ "CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST": {
+ "expires_in_version": "never",
+ "kind": "enumerated",
+ "n_values": 512,
+ "description": "Certificate pinning test results by host for Mozilla operational sites"
}
}
1
0

[tor-browser/tor-browser-31.2.0esr-4.5-1] fixup! TB3: Tor Browser's official .mozconfigs.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 672d66cc8b67815fb506ab78c231468098f8462c
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed Oct 29 15:19:19 2014 -0700
fixup! TB3: Tor Browser's official .mozconfigs.
Re-enable ICU.
---
.mozconfig-mac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.mozconfig-mac b/.mozconfig-mac
index 4abcc7c..9a38951 100644
--- a/.mozconfig-mac
+++ b/.mozconfig-mac
@@ -42,7 +42,7 @@ ac_add_options --enable-update-packaging
ac_add_options --disable-verify-mar
# ICU seems still to have cross-compiling issues:
-ac_add_options --without-intl-api
+#ac_add_options --without-intl-api
ac_add_options --disable-crashreporter
ac_add_options --disable-maintenance-service
ac_add_options --disable-webrtc
1
0
commit af7bd8eba8f6c442a3a628c0a957ec089409a464
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue Oct 28 17:54:15 2014 -0700
Remove old patches.
---
gitian/patches/bug10297.patch | 55 ----
gitian/patches/bug11069.patch | 209 --------------
gitian/patches/bug11156.patch | 275 -------------------
gitian/patches/bug11200-hang-0.2.5.patch | 81 ------
gitian/patches/bug11200.patch | 39 ---
gitian/patches/bug5018.patch | 225 ---------------
gitian/patches/bug8402.patch | 437 ------------------------------
gitian/patches/bug9665.patch | 108 --------
8 files changed, 1429 deletions(-)
diff --git a/gitian/patches/bug10297.patch b/gitian/patches/bug10297.patch
deleted file mode 100644
index 58dfdc2..0000000
--- a/gitian/patches/bug10297.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From ad47e1a52072c2a4528e421a6a3bf9c7029f4501 Mon Sep 17 00:00:00 2001
-From: David Fifield <david(a)bamsoftware.com>
-Date: Thu, 5 Dec 2013 04:56:28 +0000
-Subject: [PATCH] Set CREATE_NO_WINDOW in tor_spawn_background.
-
-This flag prevents the creation of a console window popup on Windows. We
-need it for pluggable transport executables--otherwise you get blank
-console windows when you launch the 3.x browser bundle with transports
-enabled.
-
-http://msdn.microsoft.com/en-us/library/ms684863.aspx#CREATE_NO_WINDOW
-
-The browser bundles that used Vidalia used to set this flag when
-launching tor itself; it was apparently inherited by the pluggable
-transports launched by tor. In the 3.x bundles, tor is launched by some
-JavaScript code, which doesn't have the ability to set CREATE_NO_WINDOW.
-tor itself is now being compiled with the -mwindows option, so that it
-is a GUI application, not a console application, and doesn't show a
-console window in any case. This workaround doesn't work for pluggable
-transports, because they need to be able to write control messages to
-stdout.
-
-https://trac.torproject.org/projects/tor/ticket/9444#comment:30
----
- changes/bug10297 | 4 ++++
- src/common/util.c | 2 +-
- 2 files changed, 5 insertions(+), 1 deletion(-)
- create mode 100644 changes/bug10297
-
-diff --git a/changes/bug10297 b/changes/bug10297
-new file mode 100644
-index 0000000..4cdd80f
---- /dev/null
-+++ b/changes/bug10297
-@@ -0,0 +1,4 @@
-+ o Minor features:
-+ - Spawn background processes using the CREATE_NO_WINDOW flag on
-+ Windows, in order to prevent a console window from appearing.
-+ Resolves ticket 10297.
-diff --git a/src/common/util.c b/src/common/util.c
-index 5eb0f9a..252f6af 100644
---- a/src/common/util.c
-+++ b/src/common/util.c
-@@ -3685,7 +3685,7 @@ tor_spawn_background(const char *const filename, const char **argv,
- TRUE, // handles are inherited
- /*(TODO: set CREATE_NEW CONSOLE/PROCESS_GROUP to make GetExitCodeProcess()
- * work?) */
-- 0, // creation flags
-+ CREATE_NO_WINDOW, // creation flags
- (env==NULL) ? NULL : env->windows_environment_block,
- NULL, // use parent's current directory
- &siStartInfo, // STARTUPINFO pointer
---
-1.7.9.5
-
diff --git a/gitian/patches/bug11069.patch b/gitian/patches/bug11069.patch
deleted file mode 100644
index b6032e9..0000000
--- a/gitian/patches/bug11069.patch
+++ /dev/null
@@ -1,209 +0,0 @@
-From 67c70b2566fc9bef4527fb8a0c24ce7d8c4d0647 Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Mon, 10 Mar 2014 22:52:07 +0000
-Subject: [PATCH] Throw control port warning if we failed to connect to all our
- bridges.
-
-Conflicts:
- src/or/connection.c
- src/or/control.c
- src/or/control.h
- src/test/test_extorport.c
----
- changes/bug11069 | 4 ++++
- src/or/connection.c | 25 +++++++++++++++++++++++++
- src/or/connection.h | 2 ++
- src/or/connection_or.c | 8 +++++---
- src/or/control.c | 13 ++++++++-----
- src/or/control.h | 3 ++-
- src/or/entrynodes.c | 21 ---------------------
- src/or/entrynodes.h | 1 -
- 8 files changed, 46 insertions(+), 31 deletions(-)
- create mode 100644 changes/bug11069
-
-diff --git a/changes/bug11069 b/changes/bug11069
-new file mode 100644
-index 0000000..5aa3085
---- /dev/null
-+++ b/changes/bug11069
-@@ -0,0 +1,4 @@
-+ o Minor bugfixes (clients):
-+ - Fix tor so that it raises a control port warning when we fail to
-+ connect to all of our bridges. Fixes bug 11069; bugfix on
-+ tor-0.2.1.2-alpha.
-diff --git a/src/or/connection.c b/src/or/connection.c
-index 4f74a1d..ba28d81 100644
---- a/src/or/connection.c
-+++ b/src/or/connection.c
-@@ -3846,6 +3846,31 @@ connection_get_by_type_purpose(int type, int purpose)
- return NULL;
- }
-
-+/** Return 1 if there are any active OR connections apart from
-+ * <b>this_conn</b>.
-+ *
-+ * We use this to guess if we should tell the controller that we
-+ * didn't manage to connect to any of our bridges. */
-+int
-+any_other_active_or_conns(const or_connection_t *this_conn)
-+{
-+ smartlist_t *conns = get_connection_array();
-+ SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
-+ if (conn == TO_CONN(this_conn)) { /* don't consider this conn */
-+ continue;
-+ }
-+
-+ if (conn->type == CONN_TYPE_OR &&
-+ !conn->marked_for_close) {
-+ log_debug(LD_DIR, "%s: Found an OR connection: %s",
-+ __func__, conn->address);
-+ return 1;
-+ }
-+ } SMARTLIST_FOREACH_END(conn);
-+
-+ return 0;
-+}
-+
- /** Return 1 if <b>conn</b> is a listener conn, else return 0. */
- int
- connection_is_listener(connection_t *conn)
-diff --git a/src/or/connection.h b/src/or/connection.h
-index c78fe6e..9bd5f88 100644
---- a/src/or/connection.h
-+++ b/src/or/connection.h
-@@ -180,6 +180,8 @@ connection_t *connection_get_by_type_state_rendquery(int type, int state,
- dir_connection_t *connection_dir_get_by_purpose_and_resource(
- int state, const char *resource);
-
-+int any_other_active_or_conns(const or_connection_t *this_conn);
-+
- #define connection_speaks_cells(conn) ((conn)->type == CONN_TYPE_OR)
- int connection_is_listener(connection_t *conn);
- int connection_state_is_open(connection_t *conn);
-diff --git a/src/or/connection_or.c b/src/or/connection_or.c
-index 8e7cd9e..8684f18 100644
---- a/src/or/connection_or.c
-+++ b/src/or/connection_or.c
-@@ -645,7 +645,8 @@ connection_or_about_to_close(or_connection_t *or_conn)
- reason);
- if (!authdir_mode_tests_reachability(options))
- control_event_bootstrap_problem(
-- orconn_end_reason_to_control_string(reason), reason);
-+ orconn_end_reason_to_control_string(reason),
-+ reason, or_conn);
- }
- }
- } else if (conn->hold_open_until_flushed) {
-@@ -1008,7 +1009,7 @@ connection_or_connect_failed(or_connection_t *conn,
- {
- control_event_or_conn_status(conn, OR_CONN_EVENT_FAILED, reason);
- if (!authdir_mode_tests_reachability(get_options()))
-- control_event_bootstrap_problem(msg, reason);
-+ control_event_bootstrap_problem(msg, reason, conn);
- }
-
- /** <b>conn</b> got an error in connection_handle_read_impl() or
-@@ -1638,7 +1639,8 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
- if (!authdir_mode_tests_reachability(options))
- control_event_bootstrap_problem(
- "Unexpected identity in router certificate",
-- END_OR_CONN_REASON_OR_IDENTITY);
-+ END_OR_CONN_REASON_OR_IDENTITY,
-+ conn);
- return -1;
- }
- if (authdir_mode_tests_reachability(options)) {
-diff --git a/src/or/control.c b/src/or/control.c
-index a88de12..cd2c55c 100644
---- a/src/or/control.c
-+++ b/src/or/control.c
-@@ -4696,10 +4696,12 @@ control_event_bootstrap(bootstrap_status_t status, int progress)
-
- /** Called when Tor has failed to make bootstrapping progress in a way
- * that indicates a problem. <b>warn</b> gives a hint as to why, and
-- * <b>reason</b> provides an "or_conn_end_reason" tag.
-+ * <b>reason</b> provides an "or_conn_end_reason" tag. <b>or_conn</b>
-+ * is the connection that caused this problem.
- */
- void
--control_event_bootstrap_problem(const char *warn, int reason)
-+control_event_bootstrap_problem(const char *warn, int reason,
-+ const or_connection_t *or_conn)
- {
- int status = bootstrap_percent;
- const char *tag, *summary;
-@@ -4721,9 +4723,10 @@ control_event_bootstrap_problem(const char *warn, int reason)
- if (reason == END_OR_CONN_REASON_NO_ROUTE)
- recommendation = "warn";
-
-- if (get_options()->UseBridges &&
-- !any_bridge_descriptors_known() &&
-- !any_pending_bridge_descriptor_fetches())
-+ /* If we are using bridges and all our OR connections are now
-+ closed, it means that we totally failed to connect to our
-+ bridges. Throw a warning. */
-+ if (get_options()->UseBridges && !any_other_active_or_conns(or_conn))
- recommendation = "warn";
-
- if (we_are_hibernating())
-diff --git a/src/or/control.h b/src/or/control.h
-index 61062da..1d90a90 100644
---- a/src/or/control.h
-+++ b/src/or/control.h
-@@ -85,7 +85,8 @@ void enable_control_logging(void);
- void monitor_owning_controller_process(const char *process_spec);
-
- void control_event_bootstrap(bootstrap_status_t status, int progress);
--void control_event_bootstrap_problem(const char *warn, int reason);
-+void control_event_bootstrap_problem(const char *warn, int reason,
-+ const or_connection_t *or_conn);
-
- void control_event_clients_seen(const char *controller_str);
-
-diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
-index 2aa063c..b145c94 100644
---- a/src/or/entrynodes.c
-+++ b/src/or/entrynodes.c
-@@ -2134,27 +2134,6 @@ any_bridge_descriptors_known(void)
- return choose_random_entry(NULL) != NULL;
- }
-
--/** Return 1 if there are any directory conns fetching bridge descriptors
-- * that aren't marked for close. We use this to guess if we should tell
-- * the controller that we have a problem. */
--int
--any_pending_bridge_descriptor_fetches(void)
--{
-- smartlist_t *conns = get_connection_array();
-- SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
-- if (conn->type == CONN_TYPE_DIR &&
-- conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
-- TO_DIR_CONN(conn)->router_purpose == ROUTER_PURPOSE_BRIDGE &&
-- !conn->marked_for_close &&
-- conn->linked &&
-- conn->linked_conn && !conn->linked_conn->marked_for_close) {
-- log_debug(LD_DIR, "found one: %s", conn->address);
-- return 1;
-- }
-- } SMARTLIST_FOREACH_END(conn);
-- return 0;
--}
--
- /** Return 1 if we have at least one descriptor for an entry guard
- * (bridge or member of EntryNodes) and all descriptors we know are
- * down. Else return 0. If <b>act</b> is 1, then mark the down guards
-diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
-index 52b8dc0..f6c07d9 100644
---- a/src/or/entrynodes.h
-+++ b/src/or/entrynodes.h
-@@ -104,7 +104,6 @@ void retry_bridge_descriptor_fetch_directly(const char *digest);
- void fetch_bridge_descriptors(const or_options_t *options, time_t now);
- void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
- int any_bridge_descriptors_known(void);
--int any_pending_bridge_descriptor_fetches(void);
- int entries_known_but_down(const or_options_t *options);
- void entries_retry_all(const or_options_t *options);
-
---
-1.8.1.2
-
diff --git a/gitian/patches/bug11156.patch b/gitian/patches/bug11156.patch
deleted file mode 100644
index d9f8e7a..0000000
--- a/gitian/patches/bug11156.patch
+++ /dev/null
@@ -1,275 +0,0 @@
-From af42f9b9125fb3f50f7383e63fb02bab1df82db9 Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Wed, 12 Mar 2014 20:25:05 -0700
-Subject: [PATCH] Don't do directory fetches before all PTs have been
- configured.
-
----
- src/or/microdesc.c | 2 +-
- src/or/networkstatus.c | 36 ++++++++++++++++++++++++++++++------
- src/or/networkstatus.h | 2 +-
- src/or/nodelist.c | 8 ++++----
- src/or/routerlist.c | 6 +++---
- 5 files changed, 39 insertions(+), 15 deletions(-)
-
-diff --git a/src/or/microdesc.c b/src/or/microdesc.c
-index 90ac0ac..1f12347 100644
---- a/src/or/microdesc.c
-+++ b/src/or/microdesc.c
-@@ -725,7 +725,7 @@ update_microdesc_downloads(time_t now)
- smartlist_t *missing;
- digestmap_t *pending;
-
-- if (should_delay_dir_fetches(options))
-+ if (should_delay_dir_fetches(options, NULL))
- return;
- if (directory_too_idle_to_fetch_descriptors(options, now))
- return;
-diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
-index 1b5c6db..bcadc52 100644
---- a/src/or/networkstatus.c
-+++ b/src/or/networkstatus.c
-@@ -31,6 +31,7 @@
- #include "router.h"
- #include "routerlist.h"
- #include "routerparse.h"
-+#include "transports.h"
-
- /* For tracking v2 networkstatus documents. Only caches do this now. */
-
-@@ -1380,14 +1381,37 @@ update_consensus_networkstatus_fetch_time(time_t now)
-
- /** Return 1 if there's a reason we shouldn't try any directory
- * fetches yet (e.g. we demand bridges and none are yet known).
-- * Else return 0. */
-+ * Else return 0.
-+
-+ * If we return 1 and <b>msg_out</b> is provided, set <b>msg_out</b>
-+ * to an explanation of why directory fetches are delayed. (If we
-+ * return 0, we set msg_out to NULL.)
-+ */
- int
--should_delay_dir_fetches(const or_options_t *options)
-+should_delay_dir_fetches(const or_options_t *options, const char **msg_out)
- {
-- if (options->UseBridges && !any_bridge_descriptors_known()) {
-- log_info(LD_DIR, "delaying dir fetches (no running bridges known)");
-- return 1;
-+ if (msg_out) {
-+ *msg_out = NULL;
- }
-+
-+ if (options->UseBridges) {
-+ if (!any_bridge_descriptors_known()) {
-+ if (msg_out) {
-+ *msg_out = "No running bridges";
-+ }
-+ log_info(LD_DIR, "Delaying dir fetches (no running bridges known)");
-+ return 1;
-+ }
-+
-+ if (pt_proxies_configuration_pending()) {
-+ if (msg_out) {
-+ *msg_out = "Pluggable transport proxies still configuring";
-+ }
-+ log_info(LD_DIR, "Delaying dir fetches (pt proxies still configuring)");
-+ return 1;
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -1397,7 +1421,7 @@ void
- update_networkstatus_downloads(time_t now)
- {
- const or_options_t *options = get_options();
-- if (should_delay_dir_fetches(options))
-+ if (should_delay_dir_fetches(options, NULL))
- return;
- if (authdir_mode_any_main(options) || options->FetchV2Networkstatus)
- update_v2_networkstatus_cache_downloads(now);
-diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
-index 761f8e7..f50f6f1 100644
---- a/src/or/networkstatus.h
-+++ b/src/or/networkstatus.h
-@@ -69,7 +69,7 @@ int networkstatus_nickname_is_unnamed(const char *nickname);
- void networkstatus_consensus_download_failed(int status_code,
- const char *flavname);
- void update_consensus_networkstatus_fetch_time(time_t now);
--int should_delay_dir_fetches(const or_options_t *options);
-+int should_delay_dir_fetches(const or_options_t *options,const char **msg_out);
- void update_networkstatus_downloads(time_t now);
- void update_certificate_downloads(time_t now);
- int consensus_is_waiting_for_certs(void);
-diff --git a/src/or/nodelist.c b/src/or/nodelist.c
-index 178f084..600a1fd 100644
---- a/src/or/nodelist.c
-+++ b/src/or/nodelist.c
-@@ -1439,6 +1439,7 @@ update_router_have_minimum_dir_info(void)
- const networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now,usable_consensus_flavor());
- int using_md;
-+ const char *delay_fetches_msg = NULL;
-
- if (!consensus) {
- if (!networkstatus_get_latest_consensus())
-@@ -1451,10 +1452,9 @@ update_router_have_minimum_dir_info(void)
- goto done;
- }
-
-- if (should_delay_dir_fetches(get_options())) {
-- log_notice(LD_DIR, "no known bridge descriptors running yet; stalling");
-- strlcpy(dir_info_status, "No live bridge descriptors.",
-- sizeof(dir_info_status));
-+ if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) {
-+ log_notice(LD_DIR, "Delaying dir fetches: %s", delay_fetches_msg);
-+ strlcpy(dir_info_status, "%s", sizeof(dir_info_status));
- res = 0;
- goto done;
- }
-diff --git a/src/or/routerlist.c b/src/or/routerlist.c
-index cb39729..d78c7bb 100644
---- a/src/or/routerlist.c
-+++ b/src/or/routerlist.c
-@@ -684,7 +684,7 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
- char id_digest_str[2*DIGEST_LEN+1];
- char sk_digest_str[2*DIGEST_LEN+1];
-
-- if (should_delay_dir_fetches(get_options()))
-+ if (should_delay_dir_fetches(get_options(), NULL))
- return;
-
- pending_cert = fp_pair_map_new();
-@@ -4901,7 +4901,7 @@ void
- update_router_descriptor_downloads(time_t now)
- {
- const or_options_t *options = get_options();
-- if (should_delay_dir_fetches(options))
-+ if (should_delay_dir_fetches(options, NULL))
- return;
- if (!we_fetch_router_descriptors(options))
- return;
-@@ -4925,7 +4925,7 @@ update_extrainfo_downloads(time_t now)
- int n_no_ei = 0, n_pending = 0, n_have = 0, n_delay = 0;
- if (! options->DownloadExtraInfo)
- return;
-- if (should_delay_dir_fetches(options))
-+ if (should_delay_dir_fetches(options, NULL))
- return;
- if (!router_have_minimum_dir_info())
- return;
---
-1.8.1.2
-
-From 1a3eb5c72dd0feb43a542ca465c57dd0801ff7cc Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Tue, 8 Apr 2014 16:59:46 +0100
-Subject: [PATCH 1/4] Don't halt bootstrap to figure out if we should restart
- PT proxies.
-
-Instead, figure out if we should restart PT proxies _immediately_ after
-we re-read the config file.
----
- changes/bug11156 | 5 +++++
- src/or/config.c | 6 ++++++
- src/or/transports.c | 3 +--
- 3 files changed, 12 insertions(+), 2 deletions(-)
- create mode 100644 changes/bug11156
-
-diff --git a/changes/bug11156 b/changes/bug11156
-new file mode 100644
-index 0000000..bb20ed1e
---- /dev/null
-+++ b/changes/bug11156
-@@ -0,0 +1,5 @@
-+ o Minor bugfixes (clients):
-+ - Fix a bug where a client-side Tor with pluggable transports
-+ would take 60 seconds to bootstrap if a config re-read was
-+ triggered at just the right timing during bootstrap. Refixes bug
-+ 11156; bugfix on 0.2.5.3-alpha.
-\ No newline at end of file
-diff --git a/src/or/config.c b/src/or/config.c
-index dbf643c..c2d6545 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -1433,6 +1433,12 @@ options_act(const or_options_t *old_options)
- sweep_transport_list();
- sweep_proxy_list();
-
-+ /* Start the PT proxy configuration. By doing this configuration
-+ here, we also figure out which proxies need to be restarted and
-+ which not. */
-+ if (pt_proxies_configuration_pending())
-+ pt_configure_remaining_proxies();
-+
- /* Bail out at this point if we're not going to be a client or server:
- * we want to not fork, and to log stuff to stderr. */
- if (!running_tor)
-diff --git a/src/or/transports.c b/src/or/transports.c
-index 7e496fe..e1876d6 100644
---- a/src/or/transports.c
-+++ b/src/or/transports.c
-@@ -534,8 +534,7 @@ launch_managed_proxy(managed_proxy_t *mp)
- }
-
- /** Check if any of the managed proxies we are currently trying to
-- * configure have anything new to say. This is called from
-- * run_scheduled_events(). */
-+ * configure has anything new to say. */
- void
- pt_configure_remaining_proxies(void)
- {
---
-1.8.1.2
-
-From 4719a2f5248b8cf6d70daef91fd1cf9fd65628f4 Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Mon, 21 Apr 2014 14:17:35 +0300
-Subject: [PATCH 4/4] fixup! Don't halt bootstrap to figure out if we should
- restart PT proxies.
-
----
- src/or/config.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/or/config.c b/src/or/config.c
-index c2d6545..551b09f 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -1436,7 +1436,7 @@ options_act(const or_options_t *old_options)
- /* Start the PT proxy configuration. By doing this configuration
- here, we also figure out which proxies need to be restarted and
- which not. */
-- if (pt_proxies_configuration_pending())
-+ if (pt_proxies_configuration_pending() && !net_is_disabled())
- pt_configure_remaining_proxies();
-
- /* Bail out at this point if we're not going to be a client or server:
---
-1.8.1.2
-
-From dfcbc4500aad07a641e9e856d442c848d86d2c7e Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Thu, 1 May 2014 17:32:29 +0100
-Subject: [PATCH] fixup! Fix a misuse of strlcpy() introduced by the #11156
- patch.
-
----
- changes/bug11654 | 4 ++++
- 1 file changed, 4 insertions(+)
- create mode 100644 changes/bug11654
-
-diff --git a/changes/bug11654 b/changes/bug11654
-new file mode 100644
-index 0000000..97c70b2
---- /dev/null
-+++ b/changes/bug11654
-@@ -0,0 +1,4 @@
-+ o Minor bugfixes:
-+ - Fix a broken log message about delayed directory fetches that
-+ was caused by a misuse of strlcpy(). Fixes bug 11654; bugfix on
-+ 0.2.5.3-alpha.
---
-1.9.1
-
diff --git a/gitian/patches/bug11200-hang-0.2.5.patch b/gitian/patches/bug11200-hang-0.2.5.patch
deleted file mode 100644
index 76cd159..0000000
--- a/gitian/patches/bug11200-hang-0.2.5.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From fcac4b4467427e8f6ad948e8c8e6f34a0131e716 Mon Sep 17 00:00:00 2001
-From: Roger Dingledine <arma(a)torproject.org>
-Date: Tue, 5 Aug 2014 16:54:46 -0400
-Subject: [PATCH] Build circuits more readily when DisableNetwork goes to 0
-
-When Tor starts with DisabledNetwork set, it would correctly
-conclude that it shouldn't try making circuits, but it would
-mistakenly cache this conclusion and continue believing it even
-when DisableNetwork is set to 0. Fixes the bug introduced by the
-fix for bug 11200; bugfix on 0.2.5.4-alpha.
----
- changes/bug11200-caching | 7 +++++++
- src/or/nodelist.c | 21 ++++++++++++---------
- 2 files changed, 19 insertions(+), 9 deletions(-)
- create mode 100644 changes/bug11200-caching
-
-diff --git a/changes/bug11200-caching b/changes/bug11200-caching
-new file mode 100644
-index 0000000..e3fbaec
---- /dev/null
-+++ b/changes/bug11200-caching
-@@ -0,0 +1,7 @@
-+ o Major bugfixes:
-+ - When Tor starts with DisabledNetwork set, it would correctly
-+ conclude that it shouldn't try making circuits, but it would
-+ mistakenly cache this conclusion and continue believing it even
-+ when DisableNetwork is set to 0. Fixes the bug introduced by the
-+ fix for bug 11200; bugfix on 0.2.5.4-alpha.
-+
-diff --git a/src/or/nodelist.c b/src/or/nodelist.c
-index 8f87081..7b1f338 100644
---- a/src/or/nodelist.c
-+++ b/src/or/nodelist.c
-@@ -1275,10 +1275,21 @@ static char dir_info_status[256] = "";
- int
- router_have_minimum_dir_info(void)
- {
-+ static int logged_delay=0;
-+ const char *delay_fetches_msg = NULL;
-+ if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) {
-+ if (!logged_delay)
-+ log_notice(LD_DIR, "Delaying directory fetches: %s", delay_fetches_msg);
-+ logged_delay=1;
-+ strlcpy(dir_info_status, delay_fetches_msg, sizeof(dir_info_status));
-+ return 0;
-+ }
-+ logged_delay = 0; /* reset it if we get this far */
-+
- if (PREDICT_UNLIKELY(need_to_update_have_min_dir_info)) {
- update_router_have_minimum_dir_info();
-- need_to_update_have_min_dir_info = 0;
- }
-+
- return have_min_dir_info;
- }
-
-@@ -1498,7 +1509,6 @@ update_router_have_minimum_dir_info(void)
- const networkstatus_t *consensus =
- networkstatus_get_reasonably_live_consensus(now,usable_consensus_flavor());
- int using_md;
-- const char *delay_fetches_msg = NULL;
-
- if (!consensus) {
- if (!networkstatus_get_latest_consensus())
-@@ -1511,13 +1521,6 @@ update_router_have_minimum_dir_info(void)
- goto done;
- }
-
-- if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) {
-- log_notice(LD_DIR, "Delaying directory fetches: %s", delay_fetches_msg);
-- strlcpy(dir_info_status, delay_fetches_msg, sizeof(dir_info_status));
-- res = 0;
-- goto done;
-- }
--
- using_md = consensus->flavor == FLAV_MICRODESC;
-
- {
---
-1.9.1
-
diff --git a/gitian/patches/bug11200.patch b/gitian/patches/bug11200.patch
deleted file mode 100644
index 040309a..0000000
--- a/gitian/patches/bug11200.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 6770153d4ced726e54305ad38d14ea82df0d639e Mon Sep 17 00:00:00 2001
-From: Nick Mathewson <nickm(a)torproject.org>
-Date: Sat, 29 Mar 2014 21:49:32 -0700
-Subject: [PATCH] should_disable_dir_fetches() now returns 1 if
- DisableNetwork==1
-
-This change prevents LD_BUG warnings and bootstrap failure messages
-when we try to do directory fetches when starting with
-DisableNetwork == 1, a consensus present, but no descriptors (or
-insufficient descriptors) yet.
-
-Fixes bug 11200 and bug 10405. It's a bugfix on 0.2.3.9-alpha.
-Thanks to mcs for walking me through the repro instructions!
----
- src/or/networkstatus.c | 8 ++++++++
- 1 file changed, 8 insertions(+)
-
-diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
-index bcadc52..9a1824b 100644
---- a/src/or/networkstatus.c
-+++ b/src/or/networkstatus.c
-@@ -1394,6 +1394,14 @@ should_delay_dir_fetches(const or_options_t *options, const char **msg_out)
- *msg_out = NULL;
- }
-
-+ if (options->DisableNetwork) {
-+ if (msg_out) {
-+ *msg_out = "DisableNetwork is set.";
-+ }
-+ log_info(LD_DIR, "Delaying dir fetches (DisableNetwork is set)");
-+ return 1;
-+ }
-+
- if (options->UseBridges) {
- if (!any_bridge_descriptors_known()) {
- if (msg_out) {
---
-1.8.1.2
-
diff --git a/gitian/patches/bug5018.patch b/gitian/patches/bug5018.patch
deleted file mode 100644
index b0ac8e6..0000000
--- a/gitian/patches/bug5018.patch
+++ /dev/null
@@ -1,225 +0,0 @@
-From 3394daa34842a397561e65002a33c13355df651d Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Thu, 28 Feb 2013 18:58:36 +0200
-Subject: [PATCH 1/4] Only launch transport proxies that provide useful
- transports.
-
----
- changes/bug5018 | 3 +++
- src/or/config.c | 20 ++++++++++++++++----
- src/or/entrynodes.c | 23 +++++++++++++++++++++++
- src/or/entrynodes.h | 1 +
- 4 files changed, 43 insertions(+), 4 deletions(-)
- create mode 100644 changes/bug5018
-
-diff --git a/changes/bug5018 b/changes/bug5018
-new file mode 100644
-index 0000000..c5c12ef
---- /dev/null
-+++ b/changes/bug5018
-@@ -0,0 +1,3 @@
-+ o Minor features:
-+ - Don't launch pluggable transport proxies that contribute
-+ transports we don't need. Resolves ticket 5018.
-diff --git a/src/or/config.c b/src/or/config.c
-index ef02946..47510c5 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -4242,7 +4242,8 @@ parse_client_transport_line(const char *line, int validate_only)
- int is_managed=0;
- char **proxy_argv=NULL;
- char **tmp=NULL;
-- int proxy_argc,i;
-+ int proxy_argc, i;
-+ int is_useless_proxy=1;
-
- int line_length;
-
-@@ -4264,11 +4265,16 @@ parse_client_transport_line(const char *line, int validate_only)
- smartlist_split_string(transport_list, transports, ",",
- SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
- SMARTLIST_FOREACH_BEGIN(transport_list, const char *, transport_name) {
-+ /* validate transport names */
- if (!string_is_C_identifier(transport_name)) {
- log_warn(LD_CONFIG, "Transport name is not a C identifier (%s).",
- transport_name);
- goto err;
- }
-+
-+ /* see if we actually need the transports provided by this proxy */
-+ if (!validate_only && transport_is_needed(transport_name))
-+ is_useless_proxy = 0;
- } SMARTLIST_FOREACH_END(transport_name);
-
- /* field2 is either a SOCKS version or "exec" */
-@@ -4287,9 +4293,15 @@ parse_client_transport_line(const char *line, int validate_only)
- }
-
- if (is_managed) { /* managed */
-- if (!validate_only) { /* if we are not just validating, use the
-- rest of the line as the argv of the proxy
-- to be launched */
-+ if (!validate_only && is_useless_proxy) {
-+ log_warn(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
-+ "any needed transports and will not be launched.", line);
-+ }
-+
-+ /* If we are not just validating, use the rest of the line as the
-+ argv of the proxy to be launched. Also, make sure that we are
-+ only launching proxies that contribute useful transports. */
-+ if (!validate_only && !is_useless_proxy) {
- proxy_argc = line_length-2;
- tor_assert(proxy_argc > 0);
- proxy_argv = tor_malloc_zero(sizeof(char*)*(proxy_argc+1));
-diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
-index 2aa063c..4062cee 100644
---- a/src/or/entrynodes.c
-+++ b/src/or/entrynodes.c
-@@ -1773,6 +1773,29 @@ bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
- } SMARTLIST_FOREACH_END(bridge);
- }
-
-+/** Return True if we have a bridge that uses a transport with name
-+ * <b>transport_name</b>. */
-+int
-+transport_is_needed(const char *transport_name)
-+{
-+ int retval;
-+ smartlist_t *needed_transports = NULL;
-+
-+ if (!bridge_list)
-+ return 0;
-+
-+ needed_transports = smartlist_new();
-+
-+ SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) {
-+ if (bridge->transport_name)
-+ smartlist_add(needed_transports, bridge->transport_name);
-+ } SMARTLIST_FOREACH_END(bridge);
-+
-+ retval = smartlist_string_isin(needed_transports, transport_name);
-+ smartlist_free(needed_transports);
-+ return retval;
-+}
-+
- /** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
- * is set, it tells us the identity key too. If we already had the
- * bridge in our list, unmark it, and don't actually add anything new.
-diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
-index 52b8dc0..b02cd48 100644
---- a/src/or/entrynodes.h
-+++ b/src/or/entrynodes.h
-@@ -118,6 +118,7 @@ struct transport_t;
- int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
- const struct transport_t **transport);
-
-+int transport_is_needed(const char *transport_name);
- int validate_pluggable_transports_config(void);
-
- double pathbias_get_close_success_count(entry_guard_t *guard);
---
-1.8.1.2
-
-From 54f75531a9613ee7b964be93b0051bc75322e7e3 Mon Sep 17 00:00:00 2001
-From: David Fifield <david(a)bamsoftware.com>
-Date: Sat, 26 Oct 2013 14:34:48 -0700
-Subject: [PATCH 2/4] Simplify transport_is_needed.
-
-By Roger at
-https://trac.torproject.org/projects/tor/ticket/5018#comment:11.
----
- src/or/entrynodes.c | 14 ++++----------
- 1 file changed, 4 insertions(+), 10 deletions(-)
-
-diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
-index 4062cee..98a01c5 100644
---- a/src/or/entrynodes.c
-+++ b/src/or/entrynodes.c
-@@ -1778,22 +1778,16 @@ bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
- int
- transport_is_needed(const char *transport_name)
- {
-- int retval;
-- smartlist_t *needed_transports = NULL;
--
- if (!bridge_list)
- return 0;
-
-- needed_transports = smartlist_new();
--
- SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) {
-- if (bridge->transport_name)
-- smartlist_add(needed_transports, bridge->transport_name);
-+ if (bridge->transport_name &&
-+ !strcmp(bridge->transport_name, transport_name))
-+ return 1;
- } SMARTLIST_FOREACH_END(bridge);
-
-- retval = smartlist_string_isin(needed_transports, transport_name);
-- smartlist_free(needed_transports);
-- return retval;
-+ return 0;
- }
-
- /** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
---
-1.8.1.2
-
-From 936ff64974b00a898fa0e77e3fd6f9b2df57f448 Mon Sep 17 00:00:00 2001
-From: David Fifield <david(a)bamsoftware.com>
-Date: Sat, 26 Oct 2013 14:37:50 -0700
-Subject: [PATCH 3/4] Document that unneeded transports are ignored.
-
-Suggested by Roger in
-https://trac.torproject.org/projects/tor/ticket/5018#comment:11.
----
- src/or/config.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/or/config.c b/src/or/config.c
-index 47510c5..435d981 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -4220,7 +4220,8 @@ parse_bridge_line(const char *line, int validate_only)
- * <b>line</b>. Return 0 if the line is well-formed, and -1 if it
- * isn't.
- *
-- * If <b>validate_only</b> is 0, and the line is well-formed:
-+ * If <b>validate_only</b> is 0, the line is well-formed, and the
-+ * transport is needed by some bridge:
- * - If it's an external proxy line, add the transport described in the line to
- * our internal transport list.
- * - If it's a managed proxy line, launch the managed proxy. */
---
-1.8.1.2
-
-From a4cf8514af1d2dbfd15857af83076577b7dcc4ee Mon Sep 17 00:00:00 2001
-From: George Kadianakis <desnacked(a)riseup.net>
-Date: Mon, 10 Mar 2014 22:05:31 +0000
-Subject: [PATCH 4/4] Tone down the log message for when we don't need a PT
- proxy.
-
-Conflicts:
- changes/bug5018
----
- src/or/config.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/or/config.c b/src/or/config.c
-index 435d981..914c3de 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -4295,8 +4295,8 @@ parse_client_transport_line(const char *line, int validate_only)
-
- if (is_managed) { /* managed */
- if (!validate_only && is_useless_proxy) {
-- log_warn(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
-- "any needed transports and will not be launched.", line);
-+ log_notice(LD_GENERAL, "Pluggable transport proxy (%s) does not provide "
-+ "any needed transports and will not be launched.", line);
- }
-
- /* If we are not just validating, use the rest of the line as the
---
-1.8.1.2
-
diff --git a/gitian/patches/bug8402.patch b/gitian/patches/bug8402.patch
deleted file mode 100644
index 2aa74c6..0000000
--- a/gitian/patches/bug8402.patch
+++ /dev/null
@@ -1,437 +0,0 @@
-From 88ddabbce1e15627f51b1bd6aef06f1b3515dd15 Mon Sep 17 00:00:00 2001
-From: Yawning Angel <yawning(a)schwanenlied.me>
-Date: Thu, 1 May 2014 03:57:29 +0000
-Subject: [PATCH 1/2] Allow ClientTransportPlugins to use proxies
-
-This change allows using Socks4Proxy, Socks5Proxy and HTTPSProxy with
-ClientTransportPlugins via the TOR_PT_PROXY extension to the
-pluggable transport specification.
-
-This fixes bug #8402.
-
-WARNING:
-
-This is a backport to tor-0.2.4.x of a unmerged patch. Differences
-at the time of writing from my real branch are:
- * Unit tests.
- * get_proxy_type() is removed in the backport, 0.2.5.x uses the
- routine elsewhere, so it is left intact (with modifications).
----
- src/or/config.c | 24 +++++++----
- src/or/connection.c | 55 ++++++++++---------------
- src/or/transports.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++--
- src/or/transports.h | 3 ++
- 4 files changed, 152 insertions(+), 44 deletions(-)
-
-diff --git a/src/or/config.c b/src/or/config.c
-index 09fdc0c..3fe5b73 100644
---- a/src/or/config.c
-+++ b/src/or/config.c
-@@ -490,7 +490,9 @@ static int options_transition_affects_descriptor(
- static int check_nickname_list(const char *lst, const char *name, char **msg);
-
- static int parse_bridge_line(const char *line, int validate_only);
--static int parse_client_transport_line(const char *line, int validate_only);
-+static int parse_client_transport_line(const or_options_t *options,
-+ const char *line,
-+ int validate_only);
-
- static int parse_server_transport_line(const char *line, int validate_only);
- static char *get_bindaddr_from_transport_listen_line(const char *line,
-@@ -1337,7 +1339,7 @@ options_act(const or_options_t *old_options)
- pt_prepare_proxy_list_for_config_read();
- if (options->ClientTransportPlugin) {
- for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
-- if (parse_client_transport_line(cl->value, 0)<0) {
-+ if (parse_client_transport_line(options, cl->value, 0)<0) {
- log_warn(LD_BUG,
- "Previously validated ClientTransportPlugin line "
- "could not be added!");
-@@ -2954,11 +2956,11 @@ options_validate(or_options_t *old_options, or_options_t *options,
- }
- }
-
-- /* Check if more than one proxy type has been enabled. */
-+ /* Check if more than one exclusive proxy type has been enabled. */
- if (!!options->Socks4Proxy + !!options->Socks5Proxy +
-- !!options->HTTPSProxy + !!options->ClientTransportPlugin > 1)
-+ !!options->HTTPSProxy > 1)
- REJECT("You have configured more than one proxy type. "
-- "(Socks4Proxy|Socks5Proxy|HTTPSProxy|ClientTransportPlugin)");
-+ "(Socks4Proxy|Socks5Proxy|HTTPSProxy)");
-
- /* Check if the proxies will give surprising behavior. */
- if (options->HTTPProxy && !(options->Socks4Proxy ||
-@@ -3073,7 +3075,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
- }
-
- for (cl = options->ClientTransportPlugin; cl; cl = cl->next) {
-- if (parse_client_transport_line(cl->value, 1)<0)
-+ if (parse_client_transport_line(options, cl->value, 1)<0)
- REJECT("Transport line did not parse. See logs for details.");
- }
-
-@@ -4229,7 +4231,8 @@ parse_bridge_line(const char *line, int validate_only)
- * our internal transport list.
- * - If it's a managed proxy line, launch the managed proxy. */
- static int
--parse_client_transport_line(const char *line, int validate_only)
-+parse_client_transport_line(const or_options_t *options, const char *line,
-+ int validate_only)
- {
- smartlist_t *items = NULL;
- int r;
-@@ -4308,6 +4311,13 @@ parse_client_transport_line(const char *line, int validate_only)
- pt_kickstart_client_proxy(transport_list, proxy_argv);
- }
- } else { /* external */
-+ /* ClientTransportPlugins connecting through a proxy is managed only. */
-+ if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
-+ log_warn(LD_CONFIG, "You have configured an external proxy with another "
-+ "proxy type. (Socks4Proxy|Socks5Proxy|HTTPSProxy)");
-+ goto err;
-+ }
-+
- if (smartlist_len(transport_list) != 1) {
- log_warn(LD_CONFIG, "You can't have an external proxy with "
- "more than one transports.");
-diff --git a/src/or/connection.c b/src/or/connection.c
-index 4f74a1d..683cf46 100644
---- a/src/or/connection.c
-+++ b/src/or/connection.c
-@@ -81,7 +81,6 @@ static const char *connection_proxy_state_to_string(int state);
- static int connection_read_https_proxy_response(connection_t *conn);
- static void connection_send_socks5_connect(connection_t *conn);
- static const char *proxy_type_to_string(int proxy_type);
--static int get_proxy_type(void);
-
- /** The last addresses that our network interface seemed to have been
- * binding to. We use this as one way to detect when our IP changes.
-@@ -4390,6 +4389,27 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
- {
- const or_options_t *options = get_options();
-
-+ /* Client Transport Plugins can use another proxy, but that should be hidden
-+ * from the rest of tor (as the plugin is responsible for dealing with the
-+ * proxy), check it first, then check the rest of the proxy types to allow
-+ * the config to have unused ClientTransportPlugin entries.
-+ */
-+ if (options->ClientTransportPlugin) {
-+ const transport_t *transport = NULL;
-+ int r;
-+ r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
-+ if (r<0)
-+ return -1;
-+ if (transport) { /* transport found */
-+ tor_addr_copy(addr, &transport->addr);
-+ *port = transport->port;
-+ *proxy_type = transport->socks_version;
-+ return 0;
-+ }
-+
-+ /* Unused ClientTransportPlugin. */
-+ }
-+
- if (options->HTTPSProxy) {
- tor_addr_copy(addr, &options->HTTPSProxyAddr);
- *port = options->HTTPSProxyPort;
-@@ -4405,43 +4425,12 @@ get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
- *port = options->Socks5ProxyPort;
- *proxy_type = PROXY_SOCKS5;
- return 0;
-- } else if (options->ClientTransportPlugin ||
-- options->Bridges) {
-- const transport_t *transport = NULL;
-- int r;
-- r = find_transport_by_bridge_addrport(&conn->addr, conn->port, &transport);
-- if (r<0)
-- return -1;
-- if (transport) { /* transport found */
-- tor_addr_copy(addr, &transport->addr);
-- *port = transport->port;
-- *proxy_type = transport->socks_version;
-- return 0;
-- }
- }
-
- *proxy_type = PROXY_NONE;
- return 0;
- }
-
--/** Returns the global proxy type used by tor. */
--static int
--get_proxy_type(void)
--{
-- const or_options_t *options = get_options();
--
-- if (options->HTTPSProxy)
-- return PROXY_CONNECT;
-- else if (options->Socks4Proxy)
-- return PROXY_SOCKS4;
-- else if (options->Socks5Proxy)
-- return PROXY_SOCKS5;
-- else if (options->ClientTransportPlugin)
-- return PROXY_PLUGGABLE;
-- else
-- return PROXY_NONE;
--}
--
- /** Log a failed connection to a proxy server.
- * <b>conn</b> is the connection we use the proxy server for. */
- void
-@@ -4457,7 +4446,7 @@ log_failed_proxy_connection(connection_t *conn)
- log_warn(LD_NET,
- "The connection to the %s proxy server at %s just failed. "
- "Make sure that the proxy server is up and running.",
-- proxy_type_to_string(get_proxy_type()),
-+ proxy_type_to_string(proxy_type),
- fmt_addrport(&proxy_addr, proxy_port));
- }
-
-diff --git a/src/or/transports.c b/src/or/transports.c
-index 3749d6b..cae1f31 100644
---- a/src/or/transports.c
-+++ b/src/or/transports.c
-@@ -103,6 +103,8 @@ static INLINE int proxy_configuration_finished(const managed_proxy_t *mp);
-
- static void managed_proxy_destroy(managed_proxy_t *mp,
- int also_terminate_process);
-+static char* get_pt_proxy_uri(void);
-+static void parse_proxy_error(const char *line);
-
- static void handle_finished_proxy(managed_proxy_t *mp);
- static int configure_proxy(managed_proxy_t *mp);
-@@ -123,6 +125,8 @@ static INLINE void free_execve_args(char **arg);
- #define PROTO_SMETHOD_ERROR "SMETHOD-ERROR"
- #define PROTO_CMETHODS_DONE "CMETHODS DONE"
- #define PROTO_SMETHODS_DONE "SMETHODS DONE"
-+#define PROTO_PROXY_DONE "PROXY DONE"
-+#define PROTO_PROXY_ERROR "PROXY-ERROR"
-
- /** The first and only supported - at the moment - configuration
- protocol version. */
-@@ -434,6 +438,17 @@ add_transport_to_proxy(const char *transport, managed_proxy_t *mp)
- static int
- proxy_needs_restart(const managed_proxy_t *mp)
- {
-+ int ret = 1;
-+ char* proxy_uri;
-+
-+ /* If the PT proxy config has changed, then all existing pluggable transports
-+ * should be restarted.
-+ */
-+
-+ proxy_uri = get_pt_proxy_uri();
-+ if (strcmp_opt(proxy_uri, mp->proxy_uri) != 0)
-+ goto needs_restart;
-+
- /* mp->transport_to_launch is populated with the names of the
- transports that must be launched *after* the SIGHUP.
- mp->transports is populated with the transports that were
-@@ -454,10 +469,10 @@ proxy_needs_restart(const managed_proxy_t *mp)
-
- } SMARTLIST_FOREACH_END(t);
-
-- return 0;
--
-- needs_restart:
-- return 1;
-+ ret = 0;
-+needs_restart:
-+ tor_free(proxy_uri);
-+ return ret;
- }
-
- /** Managed proxy <b>mp</b> must be restarted. Do all the necessary
-@@ -488,6 +503,11 @@ proxy_prepare_for_restart(managed_proxy_t *mp)
- SMARTLIST_FOREACH(mp->transports, transport_t *, t, transport_free(t));
- smartlist_clear(mp->transports);
-
-+ /* Reset the proxy's HTTPS/SOCKS proxy */
-+ tor_free(mp->proxy_uri);
-+ mp->proxy_uri = get_pt_proxy_uri();
-+ mp->proxy_supported = 0;
-+
- /* flag it as an infant proxy so that it gets launched on next tick */
- mp->conf_state = PT_PROTO_INFANT;
- unconfigured_proxies_n++;
-@@ -718,12 +738,52 @@ managed_proxy_destroy(managed_proxy_t *mp,
- /* free the argv */
- free_execve_args(mp->argv);
-
-+ /* free the outgoing proxy URI */
-+ tor_free(mp->proxy_uri);
-+
- tor_process_handle_destroy(mp->process_handle, also_terminate_process);
- mp->process_handle = NULL;
-
- tor_free(mp);
- }
-
-+/** Convert the tor proxy options to a URI suitable for TOR_PT_PROXY. */
-+static char *
-+get_pt_proxy_uri(void)
-+{
-+ const or_options_t *options = get_options();
-+ char *uri = NULL;
-+
-+ if (options->Socks4Proxy || options->Socks5Proxy || options->HTTPSProxy) {
-+ char addr[TOR_ADDR_BUF_LEN+1];
-+
-+ if (options->Socks4Proxy) {
-+ tor_addr_to_str(addr, &options->Socks4ProxyAddr, sizeof(addr), 1);
-+ tor_asprintf(&uri, "socks4a://%s:%d", addr, options->Socks4ProxyPort);
-+ } else if (options->Socks5Proxy) {
-+ tor_addr_to_str(addr, &options->Socks5ProxyAddr, sizeof(addr), 1);
-+ if (!options->Socks5ProxyUsername && !options->Socks5ProxyPassword) {
-+ tor_asprintf(&uri, "socks5://%s:%d", addr, options->Socks5ProxyPort);
-+ } else {
-+ tor_asprintf(&uri, "socks5://%s:%s@%s:%d",
-+ options->Socks5ProxyUsername,
-+ options->Socks5ProxyPassword,
-+ addr, options->Socks5ProxyPort);
-+ }
-+ } else if (options->HTTPSProxy) {
-+ tor_addr_to_str(addr, &options->HTTPSProxyAddr, sizeof(addr), 1);
-+ if (!options->HTTPSProxyAuthenticator) {
-+ tor_asprintf(&uri, "http://%s:%d", addr, options->HTTPSProxyPort);
-+ } else {
-+ tor_asprintf(&uri, "http://%s@%s:%d", options->HTTPSProxyAuthenticator,
-+ addr, options->HTTPSProxyPort);
-+ }
-+ }
-+ }
-+
-+ return uri;
-+}
-+
- /** Handle a configured or broken managed proxy <b>mp</b>. */
- static void
- handle_finished_proxy(managed_proxy_t *mp)
-@@ -736,6 +796,12 @@ handle_finished_proxy(managed_proxy_t *mp)
- managed_proxy_destroy(mp, 0); /* destroy it but don't terminate */
- break;
- case PT_PROTO_CONFIGURED: /* if configured correctly: */
-+ if (mp->proxy_uri && !mp->proxy_supported) {
-+ log_warn(LD_CONFIG, "Managed proxy '%s' did not configure the "
-+ "specified outgoing proxy.", mp->argv[0]);
-+ managed_proxy_destroy(mp, 1); /* annihilate it. */
-+ break;
-+ }
- register_proxy(mp); /* register its transports */
- mp->conf_state = PT_PROTO_COMPLETED; /* and mark it as completed. */
- break;
-@@ -854,6 +920,22 @@ handle_proxy_line(const char *line, managed_proxy_t *mp)
- goto err;
-
- return;
-+ } else if (!strcmpstart(line, PROTO_PROXY_DONE)) {
-+ if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
-+ goto err;
-+
-+ if (mp->proxy_uri) {
-+ mp->proxy_supported = 1;
-+ return;
-+ }
-+
-+ /* No proxy was configured, this should log */
-+ } else if (!strcmpstart(line, PROTO_PROXY_ERROR)) {
-+ if (mp->conf_state != PT_PROTO_ACCEPTING_METHODS)
-+ goto err;
-+
-+ parse_proxy_error(line);
-+ goto err;
- } else if (!strcmpstart(line, SPAWN_ERROR_MESSAGE)) {
- /* managed proxy launch failed: parse error message to learn why. */
- int retval, child_state, saved_errno;
-@@ -1105,6 +1187,21 @@ parse_cmethod_line(const char *line, managed_proxy_t *mp)
- return r;
- }
-
-+/** Parses an PROXY-ERROR <b>line</b> and warns the user accordingly. */
-+static void
-+parse_proxy_error(const char *line)
-+{
-+ /* (Length of the protocol string) plus (a space) and (the first char of
-+ the error message) */
-+ if (strlen(line) < (strlen(PROTO_PROXY_ERROR) + 2))
-+ log_notice(LD_CONFIG, "Managed proxy sent us an %s without an error "
-+ "message.", PROTO_PROXY_ERROR);
-+
-+ log_warn(LD_CONFIG, "Managed proxy failed to configure the "
-+ "pluggable transport's outgoing proxy. (%s)",
-+ line+strlen(PROTO_PROXY_ERROR)+1);
-+}
-+
- /** Return the string that tor should place in TOR_PT_SERVER_BINDADDR
- * while configuring the server managed proxy in <b>mp</b>. The
- * string is stored in the heap, and it's the the responsibility of
-@@ -1193,6 +1290,14 @@ create_managed_proxy_environment(const managed_proxy_t *mp)
- * variable in Tor's environment and crash PTs that try to parse
- * it even when not run in server mode.) */
- smartlist_add(envs, tor_strdup("TOR_PT_EXTENDED_SERVER_PORT="));
-+ } else {
-+ /* If ClientTransportPlugin has a HTTPS/SOCKS proxy configured, set the
-+ * TOR_PT_PROXY line.
-+ */
-+
-+ if (mp->proxy_uri) {
-+ smartlist_add_asprintf(envs, "TOR_PT_PROXY=%s", mp->proxy_uri);
-+ }
- }
-
- SMARTLIST_FOREACH_BEGIN(envs, const char *, env_var) {
-@@ -1225,6 +1330,7 @@ managed_proxy_create(const smartlist_t *transport_list,
- mp->is_server = is_server;
- mp->argv = proxy_argv;
- mp->transports = smartlist_new();
-+ mp->proxy_uri = get_pt_proxy_uri();
-
- mp->transports_to_launch = smartlist_new();
- SMARTLIST_FOREACH(transport_list, const char *, transport,
-diff --git a/src/or/transports.h b/src/or/transports.h
-index 6ee82f4..f13de5d 100644
---- a/src/or/transports.h
-+++ b/src/or/transports.h
-@@ -74,6 +74,9 @@ typedef struct {
- char **argv; /* the cli arguments of this proxy */
- int conf_protocol; /* the configuration protocol version used */
-
-+ char *proxy_uri; /* the outgoing proxy in TOR_PT_PROXY URI format */
-+ int proxy_supported : 1; /* the proxy claims to honor TOR_PT_PROXY */
-+
- int is_server; /* is it a server proxy? */
-
- /* A pointer to the process handle of this managed proxy. */
---
-1.8.1.2
-
-From 34004139ee9380c5c468d28037520d02681dd7cf Mon Sep 17 00:00:00 2001
-From: Yawning Angel <yawning(a)schwanenlied.me>
-Date: Thu, 1 May 2014 19:01:34 +0000
-Subject: [PATCH 2/2] Improve the log message when a transport doesn't support
- proxies.
-
-Per feedback, explicltly note that the transport will be killed when it
-does not acknowledge the configured outgoing proxy.
----
- src/or/transports.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/or/transports.c b/src/or/transports.c
-index cae1f31..917d12a 100644
---- a/src/or/transports.c
-+++ b/src/or/transports.c
-@@ -798,7 +798,8 @@ handle_finished_proxy(managed_proxy_t *mp)
- case PT_PROTO_CONFIGURED: /* if configured correctly: */
- if (mp->proxy_uri && !mp->proxy_supported) {
- log_warn(LD_CONFIG, "Managed proxy '%s' did not configure the "
-- "specified outgoing proxy.", mp->argv[0]);
-+ "specified outgoing proxy and will be terminated.",
-+ mp->argv[0]);
- managed_proxy_destroy(mp, 1); /* annihilate it. */
- break;
- }
---
-1.8.1.2
-
diff --git a/gitian/patches/bug9665.patch b/gitian/patches/bug9665.patch
deleted file mode 100644
index aeab37b..0000000
--- a/gitian/patches/bug9665.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 08ae53e400ff6fa2d8147aad440c38173c106cae Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?F=C3=A1bio=20J=2E=20Bertinatto?= <fabiojrb(a)gmail.com>
-Date: Tue, 5 Nov 2013 00:50:16 -0200
-Subject: [PATCH 1/3] Fix bug9665
-
----
- src/or/connection_or.c | 5 +++++
- 1 file changed, 5 insertions(+)
-
-diff --git a/src/or/connection_or.c b/src/or/connection_or.c
-index 04ad2cc..ba3ac00 100644
---- a/src/or/connection_or.c
-+++ b/src/or/connection_or.c
-@@ -1195,6 +1195,11 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
- "your pluggable transport proxy stopped running.",
- fmt_addrport(&TO_CONN(conn)->addr, TO_CONN(conn)->port),
- transport_name, transport_name);
-+
-+ control_event_bootstrap_problem(
-+ "Can't connect to bridge",
-+ END_OR_CONN_REASON_NO_ROUTE);
-+
- } else {
- log_warn(LD_GENERAL, "Tried to connect to '%s' through a proxy, but "
- "the proxy address could not be found.",
---
-1.8.1.2
-
-From 754a50592c412d95d2eb48038784d0ef725a7dc2 Mon Sep 17 00:00:00 2001
-From: Nick Mathewson <nickm(a)torproject.org>
-Date: Mon, 7 Apr 2014 13:41:07 -0400
-Subject: [PATCH 2/3] Forward-port bug9665 fix to work with our fix for 11069
-
----
- src/or/connection_or.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/src/or/connection_or.c b/src/or/connection_or.c
-index ba3ac00..01ff4dc 100644
---- a/src/or/connection_or.c
-+++ b/src/or/connection_or.c
-@@ -1198,7 +1198,8 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
-
- control_event_bootstrap_problem(
- "Can't connect to bridge",
-- END_OR_CONN_REASON_NO_ROUTE);
-+ END_OR_CONN_REASON_NO_ROUTE,
-+ conn);
-
- } else {
- log_warn(LD_GENERAL, "Tried to connect to '%s' through a proxy, but "
---
-1.8.1.2
-
-From 90341b4852bf88f1fdf9fd150fa2f5c47f88b2cb Mon Sep 17 00:00:00 2001
-From: Nick Mathewson <nickm(a)torproject.org>
-Date: Mon, 7 Apr 2014 13:44:22 -0400
-Subject: [PATCH 3/3] For missing transport, say "PT_MISSING" not "NO_ROUTE"
-
----
- src/or/connection_or.c | 2 +-
- src/or/or.h | 3 ++-
- src/or/reasons.c | 2 ++
- 3 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/or/connection_or.c b/src/or/connection_or.c
-index 01ff4dc..6572a91 100644
---- a/src/or/connection_or.c
-+++ b/src/or/connection_or.c
-@@ -1198,7 +1198,7 @@ connection_or_connect(const tor_addr_t *_addr, uint16_t port,
-
- control_event_bootstrap_problem(
- "Can't connect to bridge",
-- END_OR_CONN_REASON_NO_ROUTE,
-+ END_OR_CONN_REASON_PT_MISSING,
- conn);
-
- } else {
-diff --git a/src/or/or.h b/src/or/or.h
-index 38ab176..1b35c1f 100644
---- a/src/or/or.h
-+++ b/src/or/or.h
-@@ -604,7 +604,8 @@ typedef enum {
- #define END_OR_CONN_REASON_NO_ROUTE 6 /* no route to host/net */
- #define END_OR_CONN_REASON_IO_ERROR 7 /* read/write error */
- #define END_OR_CONN_REASON_RESOURCE_LIMIT 8 /* sockets, buffers, etc */
--#define END_OR_CONN_REASON_MISC 9
-+#define END_OR_CONN_REASON_PT_MISSING 9 /* PT failed or not available */
-+#define END_OR_CONN_REASON_MISC 10
-
- /* Reasons why we (or a remote OR) might close a stream. See tor-spec.txt for
- * documentation of these. The values must match. */
-diff --git a/src/or/reasons.c b/src/or/reasons.c
-index 0674474..750e89b 100644
---- a/src/or/reasons.c
-+++ b/src/or/reasons.c
-@@ -231,6 +231,8 @@ orconn_end_reason_to_control_string(int r)
- return "RESOURCELIMIT";
- case END_OR_CONN_REASON_MISC:
- return "MISC";
-+ case END_OR_CONN_REASON_PT_MISSING:
-+ return "PT_MISSING";
- case 0:
- return "";
- default:
---
-1.8.1.2
-
1
0

[tor-browser-bundle/master] Bug 8405: Add Tor patch for domain isolation.
by mikeperry@torproject.org 29 Oct '14
by mikeperry@torproject.org 29 Oct '14
29 Oct '14
commit 1eeb621e9a20afc065518f34e6a6c87c35109fa3
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue Oct 28 17:50:47 2014 -0700
Bug 8405: Add Tor patch for domain isolation.
Also clean up our patch application.
---
gitian/descriptors/linux/gitian-tor.yml | 20 ++-----
gitian/descriptors/mac/gitian-tor.yml | 20 ++-----
gitian/descriptors/windows/gitian-tor.yml | 20 ++-----
gitian/patches/bug8405.patch | 84 +++++++++++++++++++++++++++++
4 files changed, 99 insertions(+), 45 deletions(-)
diff --git a/gitian/descriptors/linux/gitian-tor.yml b/gitian/descriptors/linux/gitian-tor.yml
index e678203..68a5bae 100644
--- a/gitian/descriptors/linux/gitian-tor.yml
+++ b/gitian/descriptors/linux/gitian-tor.yml
@@ -27,6 +27,7 @@ files:
- "bug9665.patch"
- "bug8402.patch"
- "bug8402-master.patch"
+- "bug8405.patch"
- "dzip.sh"
- "openssl-linux32-utils.zip"
- "openssl-linux64-utils.zip"
@@ -82,23 +83,12 @@ script: |
export GIT_COMMITTER_NAME="nobody"
export GIT_COMMITTER_EMAIL="nobody@localhost"
export GIT_COMMITTER_DATE="$REFERENCE_DATETIME"
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
+ if [ ${TOR_TAG::9} == "tor-0.2.5" ];
then
- git am ~/build/bug10297.patch
- fi
- if [ $BUILD_PT_BUNDLES ]; then
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
- then
- git am ~/build/bug5018.patch
- git am ~/build/bug11069.patch
- git am ~/build/bug11156.patch
- git am ~/build/bug9665.patch
- git am ~/build/bug11200.patch
- git am ~/build/bug8402.patch
- elif [ ${TOR_TAG::9} == "tor-0.2.5" ];
- then
+ git am ~/build/bug8405.patch
git am ~/build/bug8402-master.patch
- fi
+ else # 0.2.6 and master
+ git am ~/build/bug8405.patch
fi
mkdir -p $OUTDIR/src
#git archive HEAD | tar -x -C $OUTDIR/src
diff --git a/gitian/descriptors/mac/gitian-tor.yml b/gitian/descriptors/mac/gitian-tor.yml
index 6022c0b..36b5b0f 100644
--- a/gitian/descriptors/mac/gitian-tor.yml
+++ b/gitian/descriptors/mac/gitian-tor.yml
@@ -23,6 +23,7 @@ files:
- "bug9665.patch"
- "bug8402.patch"
- "bug8402-master.patch"
+- "bug8405.patch"
- "apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb"
- "multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz"
- "dzip.sh"
@@ -60,23 +61,12 @@ script: |
export GIT_COMMITTER_NAME="nobody"
export GIT_COMMITTER_EMAIL="nobody@localhost"
export GIT_COMMITTER_DATE="$REFERENCE_DATETIME"
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
+ if [ ${TOR_TAG::9} == "tor-0.2.5" ];
then
- git am ~/build/bug10297.patch
- fi
- if [ $BUILD_PT_BUNDLES ]; then
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
- then
- git am ~/build/bug5018.patch
- git am ~/build/bug11069.patch
- git am ~/build/bug11156.patch
- git am ~/build/bug9665.patch
- git am ~/build/bug11200.patch
- git am ~/build/bug8402.patch
- elif [ ${TOR_TAG::9} == "tor-0.2.5" ];
- then
+ git am ~/build/bug8405.patch
git am ~/build/bug8402-master.patch
- fi
+ else # 0.2.6 and master
+ git am ~/build/bug8405.patch
fi
mkdir -p $OUTDIR/src
#git archive HEAD | tar -x -C $OUTDIR/src
diff --git a/gitian/descriptors/windows/gitian-tor.yml b/gitian/descriptors/windows/gitian-tor.yml
index 0ac603c..6be93b5 100644
--- a/gitian/descriptors/windows/gitian-tor.yml
+++ b/gitian/descriptors/windows/gitian-tor.yml
@@ -23,6 +23,7 @@ files:
- "bug9665.patch"
- "bug8402.patch"
- "bug8402-master.patch"
+- "bug8405.patch"
- "binutils.tar.bz2"
- "dzip.sh"
- "mingw-w64-win32-utils.zip"
@@ -60,23 +61,12 @@ script: |
export GIT_COMMITTER_NAME="nobody"
export GIT_COMMITTER_EMAIL="nobody@localhost"
export GIT_COMMITTER_DATE="$REFERENCE_DATETIME"
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
+ if [ ${TOR_TAG::9} == "tor-0.2.5" ];
then
- git am ~/build/bug10297.patch
- fi
- if [ $BUILD_PT_BUNDLES ]; then
- if [ ${TOR_TAG::9} == "tor-0.2.4" ];
- then
- git am ~/build/bug5018.patch
- git am ~/build/bug11069.patch
- git am ~/build/bug11156.patch
- git am ~/build/bug9665.patch
- git am ~/build/bug11200.patch
- git am ~/build/bug8402.patch
- elif [ ${TOR_TAG::9} == "tor-0.2.5" ];
- then
+ git am ~/build/bug8405.patch
git am ~/build/bug8402-master.patch
- fi
+ else # 0.2.6 and master
+ git am ~/build/bug8405.patch
fi
mkdir -p $OUTDIR/src
#git archive HEAD | tar -x -C $OUTDIR/src
diff --git a/gitian/patches/bug8405.patch b/gitian/patches/bug8405.patch
new file mode 100644
index 0000000..3c40632
--- /dev/null
+++ b/gitian/patches/bug8405.patch
@@ -0,0 +1,84 @@
+From a298c77f7eba232154ff08ca1119b05ccd9eee9e Mon Sep 17 00:00:00 2001
+From: Arthur Edelstein <arthuredelstein(a)gmail.com>
+Date: Tue, 15 Jul 2014 21:27:59 -0700
+Subject: [PATCH] Bug #8405: Report SOCKS username/password in CIRC status
+ events
+
+Introduces two new circuit status name-value parameters: SOCKS_USERNAME
+and SOCKS_PASSWORD. Values are enclosing in quotes and unusual characters
+are escaped.
+
+Example:
+
+ 650 CIRC 5 EXTENDED [...] SOCKS_USERNAME="my_username" SOCKS_PASSWORD="my_password"
+---
+ src/common/util.c | 14 ++++++++++++++
+ src/common/util.h | 1 +
+ src/or/control.c | 14 ++++++++++++++
+ 3 files changed, 29 insertions(+)
+
+diff --git a/src/common/util.c b/src/common/util.c
+index 8589344..64cee56 100644
+--- a/src/common/util.c
++++ b/src/common/util.c
+@@ -1222,6 +1222,20 @@ esc_for_log(const char *s)
+ return result;
+ }
+
++/** Similar to esc_for_log. Allocate and return a new string representing
++ * the first n characters in <b>chars</b>, surround by quotes and using
++ * standard C escapes. If a NUL character is encountered in <b>chars</b>,
++ * the resulting string will be terminated there.
++ */
++char *
++esc_for_log_len(const char *chars, size_t n)
++{
++ char *string = tor_strndup(chars, n);
++ char *string_escaped = esc_for_log(string);
++ tor_free(string);
++ return string_escaped;
++}
++
+ /** Allocate and return a new string representing the contents of <b>s</b>,
+ * surrounded by quotes and using standard C escapes.
+ *
+diff --git a/src/common/util.h b/src/common/util.h
+index 97367a9..50c5a3d 100644
+--- a/src/common/util.h
++++ b/src/common/util.h
+@@ -229,6 +229,7 @@ int tor_mem_is_zero(const char *mem, size_t len);
+ int tor_digest_is_zero(const char *digest);
+ int tor_digest256_is_zero(const char *digest);
+ char *esc_for_log(const char *string) ATTR_MALLOC;
++char *esc_for_log_len(const char *chars, size_t n) ATTR_MALLOC;
+ const char *escaped(const char *string);
+
+ char *tor_escape_str_for_pt_args(const char *string,
+diff --git a/src/or/control.c b/src/or/control.c
+index 9285fc5..aa46df6 100644
+--- a/src/or/control.c
++++ b/src/or/control.c
+@@ -1862,6 +1862,20 @@ circuit_describe_status_for_controller(origin_circuit_t *circ)
+ smartlist_add_asprintf(descparts, "TIME_CREATED=%s", tbuf);
+ }
+
++ // Show username and/or password if available.
++ if (circ->socks_username_len > 0) {
++ char* socks_username_escaped = esc_for_log_len(circ->socks_username,
++ (size_t) circ->socks_username_len);
++ smartlist_add_asprintf(descparts, "SOCKS_USERNAME=%s", socks_username_escaped);
++ tor_free(socks_username_escaped);
++ }
++ if (circ->socks_password_len > 0) {
++ char* socks_password_escaped = esc_for_log_len(circ->socks_password,
++ (size_t) circ->socks_password_len);
++ smartlist_add_asprintf(descparts, "SOCKS_PASSWORD=%s", socks_password_escaped);
++ tor_free(socks_password_escaped);
++ }
++
+ rv = smartlist_join_strings(descparts, " ", 0, NULL);
+
+ SMARTLIST_FOREACH(descparts, char *, cp, tor_free(cp));
+--
+1.8.3.4 (Apple Git-47)
+
1
0

[tor-browser-bundle/master] Switch nightlies and alpha to new Tor Browser branch.
by mikeperry@torproject.org 28 Oct '14
by mikeperry@torproject.org 28 Oct '14
28 Oct '14
commit 42d1b7373a8dbb9f6359c1c1a3589af392878d7b
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue Oct 28 16:15:39 2014 -0700
Switch nightlies and alpha to new Tor Browser branch.
---
gitian/versions.alpha | 2 +-
gitian/versions.nightly | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index 0fb2bd0..6c49137 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -8,7 +8,7 @@ FIREFOX_VERSION=31.2.0esr
TORBROWSER_UPDATE_CHANNEL=alpha
-TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.x-1-build3
+TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.5-1-build1
TOR_TAG=tor-0.2.5.10
TORLAUNCHER_TAG=0.2.7.0.1
TORBUTTON_TAG=1.7.0.1
diff --git a/gitian/versions.nightly b/gitian/versions.nightly
index dc545ae..e6ea2a1 100755
--- a/gitian/versions.nightly
+++ b/gitian/versions.nightly
@@ -8,7 +8,7 @@ FIREFOX_VERSION=31.2.0esr
TORBROWSER_UPDATE_CHANNEL=default
-TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.x-1
+TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.5-1
TOR_TAG=master
TORLAUNCHER_TAG=master
TORBUTTON_TAG=master
1
0

[tor-browser-bundle/master] Bug 12903: Integrate obfs4proxy into Tor Browser.
by mikeperry@torproject.org 28 Oct '14
by mikeperry@torproject.org 28 Oct '14
28 Oct '14
commit bb6389fbe7aa9539c4dce2aba0659e61ae8a376a
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Oct 13 11:42:46 2014 +0000
Bug 12903: Integrate obfs4proxy into Tor Browser.
We start shipping obfs4proxy in Tor Browser nightlies and the alpha
series.
---
.../Docs/Licenses/PluggableTransports/LICENSE | 77 +++++++++++++++++---
Bundle-Data/PTConfigs/bridge_prefs.js | 4 +
.../PTConfigs/linux/torrc-defaults-appendix | 6 +-
Bundle-Data/PTConfigs/mac/torrc-defaults-appendix | 5 +-
.../PTConfigs/windows/torrc-defaults-appendix | 5 +-
.../linux/gitian-pluggable-transports.yml | 54 ++++++++++++++
.../mac/gitian-pluggable-transports.yml | 54 ++++++++++++++
.../windows/gitian-pluggable-transports.yml | 54 ++++++++++++++
gitian/fetch-inputs.sh | 17 ++++-
gitian/gpg/obfs4proxy.gpg | Bin 0 -> 34128 bytes
gitian/mkbundle-linux.sh | 3 +-
gitian/mkbundle-mac.sh | 3 +-
gitian/mkbundle-windows.sh | 3 +-
gitian/verify-tags.sh | 5 +-
gitian/versions.alpha | 9 +++
gitian/versions.nightly | 9 +++
16 files changed, 291 insertions(+), 17 deletions(-)
diff --git a/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE b/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
index 749986b..c6efd2c 100644
--- a/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
+++ b/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
@@ -13,15 +13,6 @@ file LICENSE.PYTHON.
===============================================================================
-Go
-
-Some pluggable transports are written in Go and the binary packages include
-parts of the Go runtime library. A copy of the Go license (which itself
-includes the licenses of some of Go's components) is included in the file
-LICENSE.GO.
-
-===============================================================================
-
OpenSSL
(From http://openssl.org/source/license.html.)
@@ -447,3 +438,71 @@ To the extent possible under law, the authors have dedicated all
copyright and related and neighboring rights to this software to the
public domain worldwide. This software is distributed without any
warranty. See LICENSE.CC0.
+
+===============================================================================
+
+obfs4
+
+Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+===============================================================================
+
+go.net
+
+Copyright 2009 The Go Authors. All rights reserved.
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file.
+
+For details about the Go License, please see LICENSE.GO.
+
+===============================================================================
+
+go.crypto
+
+Copyright 2009 The Go Authors. All rights reserved.
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file.
+
+For details about the Go License, please see LICENSE.GO.
+
+===============================================================================
+
+agl/ed25519
+
+Copyright 2013 The Go Authors. All rights reserved.
+Use of this source code is governed by a BSD-style
+license that can be found in the LICENSE file.
+
+For details about the Go License, please see LICENSE.GO.
+
+===============================================================================
+
+dchest/siphash
+
+To the extent possible under law, the authors have dedicated all
+copyright and related and neighboring rights to this software to the
+public domain worldwide. This software is distributed without any
+warranty. See LICENSE.CC0.
diff --git a/Bundle-Data/PTConfigs/bridge_prefs.js b/Bundle-Data/PTConfigs/bridge_prefs.js
index d9c2049..7684fec 100644
--- a/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -30,6 +30,10 @@ pref("extensions.torlauncher.default_bridge.scramblesuit.1", "scramblesuit 188.4
pref("extensions.torlauncher.default_bridge.scramblesuit.2", "scramblesuit 188.226.213.208:54278 AA5A86C1490296EF4FACA946CC5A182FCD1C5B1E password=MD2VRP7WXAMSG7MKIGMHI4CB4BMSNO7T");
pref("extensions.torlauncher.default_bridge.scramblesuit.3", "scramblesuit 83.212.101.3:443 A09D536DD1752D542E1FBB3C9CE4449D51298239 password=XTCXLG2JAMJKZW2POLBAOWOQETQSMASH");
+pref("extensions.torlauncher.default_bridge.obfs4.1", "obfs4 178.209.52.110:443 67E72FF33D7D41BF11C569646A0A7B4B188340DF cert=Z+cv8z19Qb8RxWlkagp7SxiDQN++b7D2Tntowhf+j4D15/kLuj3EoSSGvuREGPc3h60Ofw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 83.212.101.3:41213 A09D536DD1752D542E1FBB3C9CE4449D51298239 cert=lPRQ/MXdD1t5SRZ9MquYQNT9m5DV757jtdXdlePmRCudUU9CFUOX1Tm7/meFSyPOsud7Cw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.3", "obfs4 104.131.108.182:56880 EF577C30B9F788B0E1801CF7E433B3B77792B77A cert=0SFhfDQrKjUJP8Qq6wrwSICEPf3Vl/nJRsYxWbg3QRoSqhl2EB78MPS2lQxbXY4EW1wwXA iat-mode=0");
+
pref("extensions.torlauncher.default_bridge.meek-google.1", "meek 0.0.2.0:1 url=https://meek-reflect.appspot.com/ front=www.google.com");
pref("extensions.torlauncher.default_bridge.meek-amazon.1", "meek 0.0.2.0:2 url=https://d2zfqthxsdq309.cloudfront.net/ front=a0.awsstatic.com");
pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek 0.0.2.0:3 url=https://az668014.vo.msecnd.net/ front=ajax.aspnetcdn.com");
diff --git a/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix b/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
index d019d19..50e03fd 100644
--- a/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
+++ b/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
@@ -2,7 +2,11 @@
ClientTransportPlugin fte exec ./TorBrowser/Tor/PluggableTransports/fteproxy.bin --managed
## obfsproxy configuration
-ClientTransportPlugin obfs2,obfs3,scramblesuit exec ./TorBrowser/Tor/PluggableTransports/obfsproxy.bin managed
+ClientTransportPlugin scramblesuit exec ./TorBrowser/Tor/PluggableTransports/obfsproxy.bin managed
+
+## obfs4proxy configuration
+ClientTransportPlugin obfs2,obfs3,obfs4 exec ./TorBrowser/Tor/PluggableTransports/obfs4proxy
+
## flash proxy configuration
#
# Change the second number here (9000) to the number of a port that can
diff --git a/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix b/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
index d6ec189..604098f 100644
--- a/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
+++ b/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
@@ -2,7 +2,10 @@
ClientTransportPlugin fte exec PluggableTransports/fteproxy.bin --managed
## obfsproxy configuration
-ClientTransportPlugin obfs2,obfs3,scramblesuit exec PluggableTransports/obfsproxy.bin managed
+ClientTransportPlugin scramblesuit exec PluggableTransports/obfsproxy.bin managed
+
+## obfs4proxy configuration
+ClientTransportPlugin obfs2,obfs3,obfs4 exec PluggableTransports/obfs4proxy
## flash proxy configuration
#
diff --git a/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix b/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
index f1b103d..d92d201 100644
--- a/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
+++ b/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
@@ -2,7 +2,10 @@
ClientTransportPlugin fte exec TorBrowser\Tor\PluggableTransports\fteproxy --managed
## obfsproxy configuration
-ClientTransportPlugin obfs2,obfs3,scramblesuit exec TorBrowser\Tor\PluggableTransports\obfsproxy managed
+ClientTransportPlugin scramblesuit exec TorBrowser\Tor\PluggableTransports\obfsproxy managed
+
+## obfs4proxy configuration
+ClientTransportPlugin obfs2,obfs3,obfs4 exec TorBrowser\Tor\PluggableTransports\obfs4proxy
## flash proxy configuration
#
diff --git a/gitian/descriptors/linux/gitian-pluggable-transports.yml b/gitian/descriptors/linux/gitian-pluggable-transports.yml
index 7e23ec5..daa1225 100644
--- a/gitian/descriptors/linux/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/linux/gitian-pluggable-transports.yml
@@ -32,6 +32,12 @@ remotes:
"dir": "goptlib"
- "url": "https://git.torproject.org/pluggable-transports/meek.git"
"dir": "meek"
+- "url": "https://github.com/agl/ed25519.git"
+ "dir": "ed25519"
+- "url": "https://github.com/dchest/siphash.git"
+ "dir": "siphash"
+- "url": "https://git.torproject.org/pluggable-transports/obfs4.git"
+ "dir": "obfs4"
files:
- "pycrypto.tar.gz"
- "argparse.tar.gz"
@@ -46,6 +52,8 @@ files:
- "gmp-linux64-utils.zip"
- "openssl-linux32-utils.zip"
- "openssl-linux64-utils.zip"
+- "go.crypto.tar.bz2"
+- "go.net.tar.bz2"
script: |
INSTDIR="$HOME/install"
PTDIR="$INSTDIR/Tor/PluggableTransports"
@@ -217,6 +225,52 @@ script: |
cp -a README doc/*.1 $INSTDIR/Docs/meek
cd ..
+ # Building go ed25519
+ cd ed25519
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/agl/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/agl/ed25519"
+ go install github.com/agl/ed25519/extra25519
+ cd ..
+
+ # Building go siphash
+ cd siphash
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/dchest/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/dchest/siphash"
+ go install github.com/dchest/siphash
+ cd ..
+
+ # Building go.crypto
+ tar xjf go.crypto.tar.bz2
+ cd go.crypto
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.crypto"
+ go install code.google.com/p/go.crypto/curve25519
+ go install code.google.com/p/go.crypto/hkdf
+ go install code.google.com/p/go.crypto/nacl/secretbox
+ cd ..
+
+ # Building go.net
+ tar xjf go.net.tar.bz2
+ cd go.net
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.net"
+ go install code.google.com/p/go.net/proxy
+ cd ..
+
+ # Building obfs4proxy
+ cd obfs4
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/git.torproject.org/pluggable-transports"
+ ln -sf "$PWD" "$GOPATH/src/git.torproject.org/pluggable-transports/obfs4.git"
+ cd obfs4proxy
+ go build -ldflags '-s'
+ cp -a obfs4proxy $PTDIR
+ cd ../..
+
# Grabbing the results
cd $INSTDIR
~/build/dzip.sh pluggable-transports-linux$GBUILD_BITS-gbuilt.zip Tor/ Docs/
diff --git a/gitian/descriptors/mac/gitian-pluggable-transports.yml b/gitian/descriptors/mac/gitian-pluggable-transports.yml
index 33df49f..4c25f07 100644
--- a/gitian/descriptors/mac/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/mac/gitian-pluggable-transports.yml
@@ -30,6 +30,12 @@ remotes:
"dir": "goptlib"
- "url": "https://git.torproject.org/pluggable-transports/meek.git"
"dir": "meek"
+- "url": "https://github.com/agl/ed25519.git"
+ "dir": "ed25519"
+- "url": "https://github.com/dchest/siphash.git"
+ "dir": "siphash"
+- "url": "https://git.torproject.org/pluggable-transports/obfs4.git"
+ "dir": "obfs4"
files:
- "pycrypto.tar.gz"
- "argparse.tar.gz"
@@ -44,6 +50,8 @@ files:
- "dzip.sh"
- "gmp-mac32-utils.zip"
- "openssl-mac32-utils.zip"
+- "go.crypto.tar.bz2"
+- "go.net.tar.bz2"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@ -245,6 +253,52 @@ script: |
cp -a README doc/*.1 $TBDIR/Docs/meek
cd ..
+ # Building go ed25519
+ cd ed25519
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/agl/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/agl/ed25519"
+ go install github.com/agl/ed25519/extra25519
+ cd ..
+
+ # Building go siphash
+ cd siphash
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/dchest/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/dchest/siphash"
+ go install github.com/dchest/siphash
+ cd ..
+
+ # Building go.crypto
+ tar xjf go.crypto.tar.bz2
+ cd go.crypto
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.crypto"
+ go install code.google.com/p/go.crypto/curve25519
+ go install code.google.com/p/go.crypto/hkdf
+ go install code.google.com/p/go.crypto/nacl/secretbox
+ cd ..
+
+ # Building go.net
+ tar xjf go.net.tar.bz2
+ cd go.net
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.net"
+ go install code.google.com/p/go.net/proxy
+ cd ..
+
+ # Building obfs4proxy
+ cd obfs4
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/git.torproject.org/pluggable-transports"
+ ln -sf "$PWD" "$GOPATH/src/git.torproject.org/pluggable-transports/obfs4.git"
+ cd obfs4proxy
+ go build -ldflags '-s'
+ cp -a obfs4proxy $PTDIR
+ cd ../..
+
# Grabbing the result
cd $INSTDIR
~/build/dzip.sh pluggable-transports-mac$GBUILD_BITS-gbuilt.zip TorBrowserBundle.app
diff --git a/gitian/descriptors/windows/gitian-pluggable-transports.yml b/gitian/descriptors/windows/gitian-pluggable-transports.yml
index 6a6301d..bd3189b 100644
--- a/gitian/descriptors/windows/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/windows/gitian-pluggable-transports.yml
@@ -29,6 +29,12 @@ remotes:
"dir": "goptlib"
- "url": "https://git.torproject.org/pluggable-transports/meek.git"
"dir": "meek"
+- "url": "https://github.com/agl/ed25519.git"
+ "dir": "ed25519"
+- "url": "https://github.com/dchest/siphash.git"
+ "dir": "siphash"
+- "url": "https://git.torproject.org/pluggable-transports/obfs4.git"
+ "dir": "obfs4"
files:
- "setuptools.tar.gz"
- "pycrypto.tar.gz"
@@ -49,6 +55,8 @@ files:
- "openssl-win32-utils.zip"
- "gmp-win32-utils.zip"
- "gcclibs-win32-utils.zip"
+- "go.crypto.tar.bz2"
+- "go.net.tar.bz2"
script: |
# Set the timestamp on every .pyc file in a zip file, and re-dzip the zip file.
function py2exe_zip_timestomp {
@@ -323,6 +331,52 @@ script: |
cp -a README doc/*.1.txt $INSTDIR/Docs/meek
cd ..
+ # Building go ed25519
+ cd ed25519
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/agl/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/agl/ed25519"
+ go install github.com/agl/ed25519/extra25519
+ cd ..
+
+ # Building go siphash
+ cd siphash
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/dchest/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/dchest/siphash"
+ go install github.com/dchest/siphash
+ cd ..
+
+ # Building go.crypto
+ tar xjf go.crypto.tar.bz2
+ cd go.crypto
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.crypto"
+ go install code.google.com/p/go.crypto/curve25519
+ go install code.google.com/p/go.crypto/hkdf
+ go install code.google.com/p/go.crypto/nacl/secretbox
+ cd ..
+
+ # Building go.net
+ tar xjf go.net.tar.bz2
+ cd go.net
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.net"
+ go install code.google.com/p/go.net/proxy
+ cd ..
+
+ # Building obfs4proxy
+ cd obfs4
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/git.torproject.org/pluggable-transports"
+ ln -sf "$PWD" "$GOPATH/src/git.torproject.org/pluggable-transports/obfs4.git"
+ cd obfs4proxy
+ go build -ldflags '-s'
+ cp -a obfs4proxy.exe $PTDIR
+ cd ../..
+
# http://bugs.winehq.org/show_bug.cgi?id=3591
cp -a $INSTDIR/python/python27.dll $PTDIR/
diff --git a/gitian/fetch-inputs.sh b/gitian/fetch-inputs.sh
index ef4dbf7..049824a 100755
--- a/gitian/fetch-inputs.sh
+++ b/gitian/fetch-inputs.sh
@@ -6,6 +6,7 @@
MIRROR_URL=https://people.torproject.org/~mikeperry/mirrors/sources/
MIRROR_URL_DCF=https://people.torproject.org/~dcf/mirrors/sources/
MIRROR_URL_ASN=https://people.torproject.org/~asn/mirrors/sources/
+MIRROR_URL_YAWNING=https://people.torproject.org/~yawning/mirrors/sources/
set -e
set -u
umask 0022
@@ -179,6 +180,15 @@ do
get "${!PACKAGE}" "${!URL}"
done
+# XXX/Yawning. As far as I can tell, this gitian thing doesn't support
+# fetching from hg repositories.
+for i in GOCRYPTO GONET
+do
+ PACKAGE="${i}_PACKAGE"
+ URL="${MIRROR_URL_YAWNING}${!PACKAGE}"
+ get "${!PACKAGE}" "${MIRROR_URL_YAWNING}${!PACKAGE}"
+done
+
# Verify packages with weak or no signatures via multipath downloads
# (OpenSSL is signed with MD5, and OSXSDK is not signed at all)
# XXX: Google won't allow wget -N.. We need to re-download the whole
@@ -208,7 +218,7 @@ wget -U "" -N ${HTTPSE_URL}
# Verify packages with weak or no signatures via direct sha256 check
# (OpenSSL is signed with MD5, and OSXSDK is not signed at all)
-for i in OSXSDK TOOLCHAIN4 TOOLCHAIN4_OLD NOSCRIPT HTTPSE MSVCR100 PYCRYPTO ARGPARSE PYYAML ZOPEINTERFACE TWISTED M2CRYPTO SETUPTOOLS OPENSSL GMP PARSLEY GO GCC
+for i in OSXSDK TOOLCHAIN4 TOOLCHAIN4_OLD NOSCRIPT HTTPSE MSVCR100 PYCRYPTO ARGPARSE PYYAML ZOPEINTERFACE TWISTED M2CRYPTO SETUPTOOLS OPENSSL GMP PARSLEY GO GCC GOCRYPTO GONET
do
PACKAGE="${i}_PACKAGE"
HASH="${i}_HASH"
@@ -262,6 +272,8 @@ ln -sf "$GMP_PACKAGE" gmp.tar.bz2
ln -sf "$LXML_PACKAGE" lxml.tar.gz
ln -sf "$PARSLEY_PACKAGE" parsley.tar.gz
ln -sf "$GO_PACKAGE" go.tar.gz
+ln -sf "$GONET_PACKAGE" go.net.tar.bz2
+ln -sf "$GOCRYPTO_PACKAGE" go.crypto.tar.bz2
# Fetch latest gitian-builder itself
# XXX - this is broken if a non-standard inputs dir is selected using the command line flag.
@@ -295,6 +307,9 @@ txsocksx https://github.com/habnabit/txsocksx.git $TXSOCKSX_TAG
goptlib https://git.torproject.org/pluggable-transports/goptlib.git $GOPTLIB_TAG
meek https://git.torproject.org/pluggable-transports/meek.git $MEEK_TAG
faketime https://github.com/wolfcw/libfaketime $FAKETIME_TAG
+ed25519 https://github.com/agl/ed25519.git $GOED25519_TAG
+siphash https://github.com/dchest/siphash.git $GOSIPHASH_TAG
+obfs4 https://git.torproject.org/pluggable-transports/obfs4.git $OBFS4_TAG
EOF
exit 0
diff --git a/gitian/gpg/obfs4proxy.gpg b/gitian/gpg/obfs4proxy.gpg
new file mode 100644
index 0000000..b9c490a
Binary files /dev/null and b/gitian/gpg/obfs4proxy.gpg differ
diff --git a/gitian/mkbundle-linux.sh b/gitian/mkbundle-linux.sh
index 8321ffe..45f4f9b 100755
--- a/gitian/mkbundle-linux.sh
+++ b/gitian/mkbundle-linux.sh
@@ -94,6 +94,7 @@ then
PYPTLIB_TAG=refs/tags/$PYPTLIB_TAG
OBFSPROXY_TAG=refs/tags/$OBFSPROXY_TAG
FLASHPROXY_TAG=refs/tags/$FLASHPROXY_TAG
+ OBFS4_TAG=refs/tags/$OBFS4_TAG
fi
cd $GITIAN_DIR
@@ -221,7 +222,7 @@ then
echo "****** Starting Pluggable Transports Component of Linux Bundle (4/5 for Linux) ******"
echo
- ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG $DESCRIPTOR_DIR/linux/gitian-pluggable-transports.yml
+ ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG,ed25519=$GOED25519_TAG,siphash=$GOSIPHASH_TAG,obfs4=$OBFS4_TAG $DESCRIPTOR_DIR/linux/gitian-pluggable-transports.yml
if [ $? -ne 0 ];
then
#mv var/build.log ./pluggable-transports-fail-linux.log.`date +%Y%m%d%H%M%S`
diff --git a/gitian/mkbundle-mac.sh b/gitian/mkbundle-mac.sh
index 9c5d99b..807319b 100755
--- a/gitian/mkbundle-mac.sh
+++ b/gitian/mkbundle-mac.sh
@@ -99,6 +99,7 @@ then
PYPTLIB_TAG=refs/tags/$PYPTLIB_TAG
OBFSPROXY_TAG=refs/tags/$OBFSPROXY_TAG
FLASHPROXY_TAG=refs/tags/$FLASHPROXY_TAG
+ OBFS4_TAG=refs/tags/$OBFS4_TAG
fi
cd $GITIAN_DIR
@@ -187,7 +188,7 @@ then
echo "****** Starting Pluggable Transports Component of Mac Bundle (4/5 for Mac) ******"
echo
- ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG $DESCRIPTOR_DIR/mac/gitian-pluggable-transports.yml
+ ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG,ed25519=$GOED25519_TAG,siphash=$GOSIPHASH_TAG,obfs4=$OBFS4_TAG $DESCRIPTOR_DIR/mac/gitian-pluggable-transports.yml
if [ $? -ne 0 ];
then
#mv var/build.log ./firefox-fail-mac.log.`date +%Y%m%d%H%M%S`
diff --git a/gitian/mkbundle-windows.sh b/gitian/mkbundle-windows.sh
index 7600e07..38d1eff 100755
--- a/gitian/mkbundle-windows.sh
+++ b/gitian/mkbundle-windows.sh
@@ -92,6 +92,7 @@ then
PYPTLIB_TAG=refs/tags/$PYPTLIB_TAG
OBFSPROXY_TAG=refs/tags/$OBFSPROXY_TAG
FLASHPROXY_TAG=refs/tags/$FLASHPROXY_TAG
+ OBFS4_TAG=refs/tags/$OBFS4_TAG
fi
cd $GITIAN_DIR
@@ -190,7 +191,7 @@ then
echo "****** Starting Pluggable Transports Component of Windows Bundle (4/5 for Windows) ******"
echo
- ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG $DESCRIPTOR_DIR/windows/gitian-pluggable-transports.yml
+ ./bin/gbuild -j $NUM_PROCS -m $VM_MEMORY --commit pyptlib=$PYPTLIB_TAG,obfsproxy=$OBFSPROXY_TAG,flashproxy=$FLASHPROXY_TAG,libfte=$LIBFTE_TAG,fteproxy=$FTEPROXY_TAG,txsocksx=$TXSOCKSX_TAG,goptlib=$GOPTLIB_TAG,meek=$MEEK_TAG,ed25519=$GOED25519_TAG,siphash=$GOSIPHASH_TAG,obfs4=$OBFS4_TAG $DESCRIPTOR_DIR/windows/gitian-pluggable-transports.yml
if [ $? -ne 0 ];
then
#mv var/build.log ./pluggable-transports-fail-win32.log.`date +%Y%m%d%H%M%S`
diff --git a/gitian/verify-tags.sh b/gitian/verify-tags.sh
index b7a89f1..09454bb 100755
--- a/gitian/verify-tags.sh
+++ b/gitian/verify-tags.sh
@@ -101,6 +101,7 @@ obfsproxy obfsproxy.gpg $OBFSPROXY_TAG
flashproxy flashproxy.gpg $FLASHPROXY_TAG
goptlib goptlib.gpg $GOPTLIB_TAG
meek meek.gpg $MEEK_TAG
+obfs4 obfs4proxy.gpg $OBFS4_TAG
EOF
#https-everywhere https-everywhere.gpg $HTTPSE_TAG
@@ -113,6 +114,8 @@ libfte $LIBFTE_TAG
fteproxy $FTEPROXY_TAG
txsocksx $TXSOCKSX_TAG
faketime $FAKETIME_TAG
+ed25519 $GOED25519_TAG
+siphash $GOSIPHASH_TAG
EOF
# Verify signatures on signed packages
@@ -136,7 +139,7 @@ done
# Verify packages with weak or no signatures via direct sha256 check
# (OpenSSL is signed with MD5, and OSXSDK is not signed at all)
-for i in OSXSDK TOOLCHAIN4 TOOLCHAIN4_OLD NOSCRIPT HTTPSE MSVCR100 PYCRYPTO ARGPARSE PYYAML ZOPEINTERFACE TWISTED M2CRYPTO SETUPTOOLS OPENSSL GMP PARSLEY GO GCC
+for i in OSXSDK TOOLCHAIN4 TOOLCHAIN4_OLD NOSCRIPT HTTPSE MSVCR100 PYCRYPTO ARGPARSE PYYAML ZOPEINTERFACE TWISTED M2CRYPTO SETUPTOOLS OPENSSL GMP PARSLEY GO GCC GOCRYPTO GONET
do
PACKAGE="${i}_PACKAGE"
HASH="${i}_HASH"
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index e17b071..0912b5d 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -27,6 +27,9 @@ TXSOCKSX_TAG=216eb0894a1755872f4789f9458aa6cf543b8433 # unsigned habnabit/1.13.0
GOPTLIB_TAG=0.2
MEEK_TAG=0.11
FAKETIME_TAG=70aa6b394d9341522dffe8a5a5cf5929e82cc6b9 # unsigned v0.9.6
+GOED25519_TAG=c4161f4c7483313562781c61b9a20aba73daf9de
+GOSIPHASH_TAG=42ba037e748c9062a75e0924705c43b893edefcd
+OBFS4_TAG=obfs4proxy-0.0.3
GITIAN_TAG=tor-browser-builder-3.x-7
@@ -74,6 +77,8 @@ SETUPTOOLS_PACKAGE=setuptools-${SETUPTOOLS_VER}.tar.gz
LXML_PACKAGE=lxml-${LXML_VER}.tar.gz
PARSLEY_PACKAGE=Parsley-${PARSLEY_VER}.tar.gz
GO_PACKAGE=go${GO_VER}.src.tar.gz
+GOCRYPTO_PACKAGE=go.crypto-5478be1963aa.tar.bz2
+GONET_PACKAGE=go.net-9c0f9daaa74b.tar.bz2
# Hashes for packages with weak sigs or no sigs
OPENSSL_HASH=3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7
@@ -94,6 +99,8 @@ PY2EXE_HASH=610a8800de3d973ed5ed4ac505ab42ad058add18a68609ac09e6cf3598ef056c
SETUPTOOLS_HASH=75d288687066ed124311d6ca5f40ffa92a0e81adcd7fff318c6e84082713cf39
PARSLEY_HASH=50d30cee70770fd44db7cea421cb2fb75af247c3a1cd54885c06b30a7c85dd23
GO_HASH=1bb6fde89cfe8b9756a875af55d994cce0994861227b5dc0f268c143d91cd5ff
+GOCRYPTO_HASH=a8e301714f5724999321f0397b867a5670a5e5c4f808ba157bdd93ee0d028827
+GONET_HASH=1812fec55256e1a6fe546111cc658520b80972f38826c94ec11ef24315d32353
## Non-git package URLs
OPENSSL_URL=https://www.openssl.org/source/${OPENSSL_PACKAGE}
@@ -119,3 +126,5 @@ SETUPTOOLS_URL=https://pypi.python.org/packages/source/s/setuptools/${SETUP…
LXML_URL=https://pypi.python.org/packages/source/l/lxml/${LXML_PACKAGE}
PARSLEY_URL=https://pypi.python.org/packages/source/P/Parsley/${PARSLEY_PAC…
GO_URL=http://golang.org/dl/${GO_PACKAGE}
+GOCRYPTO_URL=https://people.torproject.org/~yawning/mirrors/sources/${GOCRYPTO_PACKAGE}
+GONET_URL=https://people.torproject.org/~yawning/mirrors/sources/${GONET_PACKAGE}
diff --git a/gitian/versions.nightly b/gitian/versions.nightly
index 5541ded..3867629 100755
--- a/gitian/versions.nightly
+++ b/gitian/versions.nightly
@@ -28,6 +28,9 @@ TXSOCKSX_TAG=216eb0894a1755872f4789f9458aa6cf543b8433 # unsigned habnabit/1.13.0
GOPTLIB_TAG=master
MEEK_TAG=master
FAKETIME_TAG=70aa6b394d9341522dffe8a5a5cf5929e82cc6b9 # unsigned v0.9.6
+GOED25519_TAG=c4161f4c7483313562781c61b9a20aba73daf9de
+GOSIPHASH_TAG=42ba037e748c9062a75e0924705c43b893edefcd
+OBFS4_TAG=master
GITIAN_TAG=tor-browser-builder-3.x-7
@@ -75,6 +78,8 @@ SETUPTOOLS_PACKAGE=setuptools-${SETUPTOOLS_VER}.tar.gz
LXML_PACKAGE=lxml-${LXML_VER}.tar.gz
PARSLEY_PACKAGE=Parsley-${PARSLEY_VER}.tar.gz
GO_PACKAGE=go${GO_VER}.src.tar.gz
+GOCRYPTO_PACKAGE=go.crypto-5478be1963aa.tar.bz2
+GONET_PACKAGE=go.net-9c0f9daaa74b.tar.bz2
# Hashes for packages with weak sigs or no sigs
OPENSSL_HASH=3c179f46ca77069a6a0bac70212a9b3b838b2f66129cb52d568837fc79d8fcc7
@@ -95,6 +100,8 @@ PY2EXE_HASH=610a8800de3d973ed5ed4ac505ab42ad058add18a68609ac09e6cf3598ef056c
SETUPTOOLS_HASH=75d288687066ed124311d6ca5f40ffa92a0e81adcd7fff318c6e84082713cf39
PARSLEY_HASH=50d30cee70770fd44db7cea421cb2fb75af247c3a1cd54885c06b30a7c85dd23
GO_HASH=1bb6fde89cfe8b9756a875af55d994cce0994861227b5dc0f268c143d91cd5ff
+GOCRYPTO_HASH=a8e301714f5724999321f0397b867a5670a5e5c4f808ba157bdd93ee0d028827
+GONET_HASH=1812fec55256e1a6fe546111cc658520b80972f38826c94ec11ef24315d32353
## Non-git package URLs
OPENSSL_URL=https://www.openssl.org/source/${OPENSSL_PACKAGE}
@@ -120,3 +127,5 @@ SETUPTOOLS_URL=https://pypi.python.org/packages/source/s/setuptools/${SETUP…
LXML_URL=https://pypi.python.org/packages/source/l/lxml/${LXML_PACKAGE}
PARSLEY_URL=https://pypi.python.org/packages/source/P/Parsley/${PARSLEY_PAC…
GO_URL=http://golang.org/dl/${GO_PACKAGE}
+GOCRYPTO_URL=https://people.torproject.org/~yawning/mirrors/sources/${GOCRYPTO_PACKAGE}
+GONET_URL=https://people.torproject.org/~yawning/mirrors/sources/${GONET_PACKAGE}
1
0