tbb-commits
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- 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
- 1 participants
- 20078 discussions
[tor-browser-bundle/master] 64 bit build on Mac for all components. Tor-Browser requires an additional patch, and versions.alpa was not updated to point at the correct tag
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit f1f4a2a85da44820e148c47486363befc1a4bb16
Author: Tom Ritter <tom(a)ritter.vg>
Date: Tue Sep 16 21:46:00 2014 -0500
64 bit build on Mac for all components. Tor-Browser requires an additional patch, and versions.alpa was not updated to point at the correct tag
---
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 --git a/Bundle-Data/mac-tor.sh b/Bundle-Data/mac-tor.sh
index 9a22096..03d6f9d 100755
--- a/Bundle-Data/mac-tor.sh
+++ b/Bundle-Data/mac-tor.sh
@@ -1,7 +1,6 @@
#!/bin/sh
# Compiled Python modules require a compatible Python, which means 32-bit 2.6.
export VERSIONER_PYTHON_VERSION=2.6
-export VERSIONER_PYTHON_PREFER_32_BIT=yes
export DYLD_LIBRARY_PATH=.:$DYLD_LIBRARY_PATH
# Set the current working directory to the directory containing this executable,
# so that pluggable transport executables can be given with relative paths. This
diff --git a/gitian/descriptors/mac/gitian-bundle.yml b/gitian/descriptors/mac/gitian-bundle.yml
index 82b6595..1cf75e9 100644
--- a/gitian/descriptors/mac/gitian-bundle.yml
+++ b/gitian/descriptors/mac/gitian-bundle.yml
@@ -30,9 +30,9 @@ remotes:
"dir": "meek"
files:
# TODO: Can we use an env for this file+version??
-- "tor-browser-mac32-gbuilt.zip"
-- "tor-mac32-gbuilt.zip"
-- "pluggable-transports-mac32-gbuilt.zip"
+- "tor-browser-mac64-gbuilt.zip"
+- "tor-mac64-gbuilt.zip"
+- "pluggable-transports-mac64-gbuilt.zip"
- "torrc-defaults-appendix-mac"
- "bridge_prefs.js"
- "meek-http-helper-user.js"
@@ -75,9 +75,6 @@ script: |
unzip -d ~/build ~/build/mar-tools-mac$GBUILD_BITS.zip
MARTOOLS=~/build/mar-tools
#
- # XXX: Find a better way to tell that we are having a 32bit build
- GBUILD_BITS=32
- #
mkdir -p $OUTDIR/
mkdir -p $TORBROWSER_NAME.app/TorBrowser/Data/Browser/profile.default/extensions/https-everywhere(a)eff.org
mkdir -p $TORBROWSER_NAME.app/TorBrowser/Data/Browser/profile.meek-http-helper/extensions
diff --git a/gitian/descriptors/mac/gitian-firefox.yml b/gitian/descriptors/mac/gitian-firefox.yml
index fc36472..9126f03 100644
--- a/gitian/descriptors/mac/gitian-firefox.yml
+++ b/gitian/descriptors/mac/gitian-firefox.yml
@@ -95,9 +95,6 @@ script: |
zip -r mar-tools-mac${GBUILD_BITS}.zip mar-tools
cp -p mar-tools-mac${GBUILD_BITS}.zip $OUTDIR/
#
- # XXX: Find a better way to tell that we are having a 32bit build
- GBUILD_BITS=32
- #
cd $INSTDIR
# Adjust the Info.plist file
INFO_PLIST=TorBrowser.app/Contents/Info.plist
diff --git a/gitian/descriptors/mac/gitian-pluggable-transports.yml b/gitian/descriptors/mac/gitian-pluggable-transports.yml
index 33df49f..17aef86 100644
--- a/gitian/descriptors/mac/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/mac/gitian-pluggable-transports.yml
@@ -42,8 +42,8 @@ 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"
+- "gmp-mac64-utils.zip"
+- "openssl-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@ -61,8 +61,8 @@ script: |
sudo dpkg -i *.deb
tar xaf multiarch-darwin*tar.xz
export PATH="$PATH:$HOME/build/apple-osx/bin/"
- unzip -d $INSTDIR gmp-mac32-utils.zip
- unzip -d $INSTDIR openssl-mac32-utils.zip
+ unzip -d $INSTDIR gmp-mac64-utils.zip
+ unzip -d $INSTDIR openssl-mac64-utils.zip
cp $INSTDIR/gmp/lib/*dylib* $TBDIR/Tor/
#
@@ -72,8 +72,8 @@ script: |
# http://bugs.python.org/issue9437
export LDSHARED="$CC -pthread -shared"
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
- export CXXFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
+ export CXXFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5"
# Building go
@@ -247,5 +247,5 @@ script: |
# 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/
diff --git a/gitian/descriptors/mac/gitian-tor.yml b/gitian/descriptors/mac/gitian-tor.yml
index 6022c0b..555440f 100644
--- a/gitian/descriptors/mac/gitian-tor.yml
+++ b/gitian/descriptors/mac/gitian-tor.yml
@@ -26,8 +26,8 @@ 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"
-- "openssl-mac32-utils.zip"
-- "libevent-mac32-utils.zip"
+- "openssl-mac64-utils.zip"
+- "libevent-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@ -46,15 +46,15 @@ script: |
sudo dpkg -i *.deb
tar xaf multiarch-darwin*tar.xz
export PATH="$PATH:$HOME/build/apple-osx/bin/"
- unzip -d $INSTDIR openssl-mac32-utils.zip
- unzip -d $INSTDIR libevent-mac32-utils.zip
+ unzip -d $INSTDIR openssl-mac64-utils.zip
+ unzip -d $INSTDIR libevent-mac64-utils.zip
cp $INSTDIR/libevent/lib/libevent-*.dylib $TBDIR/Tor/
LIBEVENT_FILE=`basename $INSTDIR/libevent/lib/libevent-*.dylib`
# Building tor
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
- export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export LDFLAGS="-m64 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
cd tor
git update-index --refresh -q
export GIT_COMMITTER_NAME="nobody"
@@ -94,5 +94,5 @@ script: |
# Grabbing the result
cd $INSTDIR
- ~/build/dzip.sh tor-mac32-gbuilt.zip TorBrowserBundle.app
- cp tor-mac32-gbuilt.zip $OUTDIR/
+ ~/build/dzip.sh tor-mac64-gbuilt.zip TorBrowserBundle.app
+ cp tor-mac64-gbuilt.zip $OUTDIR/
diff --git a/gitian/descriptors/mac/gitian-utils.yml b/gitian/descriptors/mac/gitian-utils.yml
index 785d88c..f96b5ec 100644
--- a/gitian/descriptors/mac/gitian-utils.yml
+++ b/gitian/descriptors/mac/gitian-utils.yml
@@ -34,10 +34,12 @@ script: |
export PATH="$PATH:$HOME/build/apple-osx/bin/"
# For OpenSSL
ln -s ~/build/apple-osx/bin/apple-osx-gcc ~/build/apple-osx/bin/i686-apple-darwin11-cc
+ #For gmp, need to trick it so it knows we're doing a 64 bit build
+ for i in ~/build/apple-osx/bin/i686-apple-darwin11-*; do j=`echo $i | sed 's/i686/x86_64/'`; ln -s $i $j; done;
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
- export CXXFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -mmacosx-version-min=10.5"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export CXXFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -mmacosx-version-min=10.5"
export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
# Building Libevent
@@ -54,7 +56,7 @@ script: |
cd openssl-*
find -type f | xargs touch --date="$REFERENCE_DATETIME"
# TODO: Add enable-ec_nistp_64_gcc_128 for 64bit OS X.
- ./Configure --cross-compile-prefix=i686-apple-darwin11- $CFLAGS darwin-i386-cc --prefix=$INSTDIR/openssl
+ ./Configure --cross-compile-prefix=i686-apple-darwin11- $CFLAGS darwin64-x86_64-cc --prefix=$INSTDIR/openssl enable-ec_nistp_64_gcc_128
# Using $MAKEOPTS breaks the build. Might be the issue mentioned on
# http://cblfs.cross-lfs.org/index.php/OpenSSL.
make
@@ -65,15 +67,15 @@ script: |
tar xjf gmp.tar.bz2
cd gmp-*
find -type f | xargs touch --date="$REFERENCE_DATETIME"
- ./configure --host=i686-apple-darwin11 --prefix=$INSTDIR/gmp --disable-static --enable-shared --enable-cxx
+ ./configure --host=x86_64-apple-darwin11 --prefix=$INSTDIR/gmp --disable-static --enable-shared --enable-cxx
make
make install
cd ..
# Grabbing the results
cd $INSTDIR
- ~/build/dzip.sh openssl-$OPENSSL_VER-mac32-utils.zip openssl
- ~/build/dzip.sh libevent-${LIBEVENT_TAG#release-}-mac32-utils.zip libevent
- ~/build/dzip.sh gmp-$GMP_VER-mac32-utils.zip gmp
+ ~/build/dzip.sh openssl-$OPENSSL_VER-mac64-utils.zip openssl
+ ~/build/dzip.sh libevent-${LIBEVENT_TAG#release-}-mac64-utils.zip libevent
+ ~/build/dzip.sh gmp-$GMP_VER-mac64-utils.zip gmp
cp *utils.zip $OUTDIR/
diff --git a/gitian/mkbundle-mac.sh b/gitian/mkbundle-mac.sh
index 9c5d99b..c8830af 100755
--- a/gitian/mkbundle-mac.sh
+++ b/gitian/mkbundle-mac.sh
@@ -103,9 +103,9 @@ fi
cd $GITIAN_DIR
-if [ ! -f inputs/openssl-$OPENSSL_VER-mac32-utils.zip -o \
- ! -f inputs/libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip -o \
- ! -f inputs/gmp-$GMP_VER-mac32-utils.zip ];
+if [ ! -f inputs/openssl-$OPENSSL_VER-mac64-utils.zip -o \
+ ! -f inputs/libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip -o \
+ ! -f inputs/gmp-$GMP_VER-mac64-utils.zip ];
then
echo
echo "****** Starting Utilities Component of Mac Bundle (1/5 for Mac) ******"
@@ -119,9 +119,9 @@ then
cd inputs
cp -a ../build/out/*-utils.zip .
- ln -sf openssl-$OPENSSL_VER-mac32-utils.zip openssl-mac32-utils.zip
- ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip libevent-mac32-utils.zip
- ln -sf gmp-$GMP_VER-mac32-utils.zip gmp-mac32-utils.zip
+ ln -sf openssl-$OPENSSL_VER-mac64-utils.zip openssl-mac64-utils.zip
+ ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip libevent-mac64-utils.zip
+ ln -sf gmp-$GMP_VER-mac64-utils.zip gmp-mac64-utils.zip
cd ..
#cp -a result/utils-mac-res.yml inputs/
else
@@ -132,13 +132,13 @@ else
# We might have built the utilities in the past but maybe the links are
# pointing to the wrong version. Refresh them.
cd inputs
- ln -sf openssl-$OPENSSL_VER-mac32-utils.zip openssl-mac32-utils.zip
- ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip libevent-mac32-utils.zip
- ln -sf gmp-$GMP_VER-mac32-utils.zip gmp-mac32-utils.zip
+ ln -sf openssl-$OPENSSL_VER-mac64-utils.zip openssl-mac64-utils.zip
+ ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip libevent-mac64-utils.zip
+ ln -sf gmp-$GMP_VER-mac64-utils.zip gmp-mac64-utils.zip
cd ..
fi
-if [ ! -f inputs/tor-mac32-gbuilt.zip ];
+if [ ! -f inputs/tor-mac64-gbuilt.zip ];
then
echo
echo "****** Starting Tor Component of Mac Bundle (2/5 for Mac) ******"
@@ -159,7 +159,7 @@ else
echo
fi
-if [ ! -f inputs/tor-browser-mac32-gbuilt.zip ];
+if [ ! -f inputs/tor-browser-mac64-gbuilt.zip ];
then
echo
echo "****** Starting TorBrowser Component of Mac Bundle (3/5 for Mac) ******"
@@ -181,7 +181,7 @@ else
echo
fi
-if [ ! -f inputs/pluggable-transports-mac32-gbuilt.zip ];
+if [ ! -f inputs/pluggable-transports-mac64-gbuilt.zip ];
then
echo
echo "****** Starting Pluggable Transports Component of Mac Bundle (4/5 for Mac) ******"
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 0a916fb562dcc744e4f3ce7b491669bcfd41b64c
Merge: 3fd3351 bb6389f
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Oct 13 15:27:00 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 --cc gitian/versions.nightly
index 9dc6f3f,3867629..5bd9d63
--- a/gitian/versions.nightly
+++ b/gitian/versions.nightly
@@@ -95,7 -100,8 +100,9 @@@ PY2EXE_HASH=610a8800de3d973ed5ed4ac505a
SETUPTOOLS_HASH=75d288687066ed124311d6ca5f40ffa92a0e81adcd7fff318c6e84082713cf39
PARSLEY_HASH=50d30cee70770fd44db7cea421cb2fb75af247c3a1cd54885c06b30a7c85dd23
GO_HASH=1bb6fde89cfe8b9756a875af55d994cce0994861227b5dc0f268c143d91cd5ff
+GCC_HASH=d334781a124ada6f38e63b545e2a3b8c2183049515a1abab6d513f109f1d717e
+ GOCRYPTO_HASH=a8e301714f5724999321f0397b867a5670a5e5c4f808ba157bdd93ee0d028827
+ GONET_HASH=1812fec55256e1a6fe546111cc658520b80972f38826c94ec11ef24315d32353
## Non-git package URLs
OPENSSL_URL=https://www.openssl.org/source/${OPENSSL_PACKAGE}
1
0
[tor-browser-bundle/master] Merge remote-tracking branch 'gk/bug_12903_squashed_v3'
by mikeperry@torproject.org 28 Oct '14
by mikeperry@torproject.org 28 Oct '14
28 Oct '14
commit 104bd981bfb47563d3eb8c28069a1d87deea03ed
Merge: 875f231 0a916fb
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue Oct 28 15:40:50 2014 -0700
Merge remote-tracking branch 'gk/bug_12903_squashed_v3'
.../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(-)
1
0