diff options
author | Will Drewry <drewry@google.com> | 2015-08-24 11:52:15 -0700 |
---|---|---|
committer | Will Drewry <drewry@google.com> | 2015-08-24 11:52:15 -0700 |
commit | e96e2217decd173041388dd2664b1985587b099f (patch) | |
tree | cc84b6e344438f3edda56caa5d8e33f0ff39667e | |
parent | 4a7dd9b16b350e4218dfefb9f82b030b01226248 (diff) | |
parent | ae396da167a9e43ce10c2db0956fb2e2b0d400ea (diff) | |
download | tlsdate-e96e2217decd173041388dd2664b1985587b099f.tar.gz |
Import upstream tlsdate with history
131 files changed, 19881 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7f4ca56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +*~ +*.gz +*.o +.deps/ +.libs/ +autom4te.cache/ +Makefile +Makefile.in +aclocal.m4 +config.guess +config.log +config.status +config.sub +configure +depcomp +install-sh +libtool +missing +stamp-h1 +config/ +src/.dirstamp +src/compat/.dirstamp +src/android/.dirstamp +src/configmake.h +src/tlsdate-helper.o +src/tlsdate-helper +src/tlsdate.o +src/tlsdate +m4 +*.swp +*.la +*.lo +src/proxy-bio_unittest +src/tlsdate-routeup +src/tlsdated +src/tlsdated_unittest +TAGS +tags +config.h +config.in diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..57e3045 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: c +before_script: ./autogen.sh +compiler: + - clang + - gcc +branches: + only: + - master +before_install: + - sudo apt-get update -qq + - sudo apt-get install -qq autotools-dev dh-apparmor hardening-wrapper libssl-dev autoconf automake pkg-config libtool +script: ./configure && make && make test @@ -0,0 +1,4 @@ +Jacob Appelbaum <jacob@appelbaum.net> +Christian Grothoff <christian@grothoff.org> +Elly Jones <elly@leptoquark.net> +Will Drewry <wad@chromium.org> diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..f6bbb45 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,168 @@ +0.0.13 Thu 28, May, 2015 + Update default host to google.com - www.ptb.de randomized timestamps +0.0.12 Sun 26, Oct, 2014 + Fix AppArmor for tlsdated: allow unprivileged helper to read the time. + Update tlsdated systemd service file. + Various little fixes and an early release to make the Debian Freeze! +0.0.11 Mon 20, Oct, 2014 + Fix routeup flushing when using stdout (Avery Pennarun). + Update AppArmor profile to support multiarch systems. + Instruct syslog to properly output tlsdated and pid information. + (This closes: https://github.com/ioerror/tlsdate/issues/144 ) + Fix -Wsizeof-pointer-memaccess in build of tlsdated unit test. + FreeBSD build improvements (Fabian Keil). + Update man pages. + Update AppArmor profile to remove unused stanzas. + Fix seccomp filter support on x86 systems (Will Drewry). + Refactor chatty tlsdated logging output to make it quiet. + Close syslog after tlsdated finishes using it. + Update systemd and init.d scripts for Debian. +0.0.10 Fri 26, Sep, 2014 + tlsdated removed from /usr/bin and now is only in /usr/sbin + This release is because 0.0.9 had two trivial bugs. Argh. +0.0.9 Fri 25, Sep, 2014 + Fix missing function prototype. + major libevent refactor by Will Drewry and Elly Fong-Jones of Google. + tlsdated should now function properly on ChromeOS and Debian GNU/Linux + Add ability to set COMPILE_DATE at configure/build time. + Add support for deterministic builds on Debian GNU/*. +0.0.8 Sun 14, Sep, 2014 + Add Debian GNU/Hurd and Debian GNU/kFreeBSD build support. + Fix build on FreeBSD 10 and 11. + Add FreeBSD (9.2 & 11-CURRENT) support for tlsdate and + tlsdate-helper. (Fabian Keil). + Update man pages (Kartik Mistry, Holger Levsen). + tlsdate will now abort if time fetch has a long delay (Avery Pennarun). + Updates for tlsdate related systemd service (Holger Levsen). + Check previously unchecked return codes (Brian Aker). + Update headers to reflect the correct location (Brian Aker). + Addition of various TODO items. + Update git tag to reference new GnuPG key + Key fingerprint = D2C6 7D20 E9C3 6C2A C5FE 74A2 D255 D3F5 C868 227F + Update tlsdate HTTPS user-agent to reflect proper version number +0.0.7 Sat 2 Nov, 2013 + Add tentative -plan9.[ch] versions of tlsdate-helper. + Add -x option to tlsdated to override source proxies. + Correctly check SANs against target host when using proxies. + Fix a race in tlsdate-dbus-announce that can cause signal drops. + Support -l argument to tlsdated. + Pass -l and -v arguments from tlsdated to tlsdate. + Log more verbosely at tlsdated startup. + Add FreeBSD support for tlsdate and tlsdate-helper. + Add Android build support with Android NDK for tlsdate. + Add NetBSD 6.0.1 support for tlsdate and tlsdate-helper. + Add OpenBSD 5.2 support for tldate and tlsdate-helper. + Add official support for Debian, Ubuntu, CentOS, Fedora, RHEL, OpenSUSE, + and Arch GNU/Linux distros. + Add Mac OS X 10.8.3 support + Extensive setup/install documentation is now present in INSTALL for most OSes + Add DragonFly BSD 3.3 support + Refactored subprocess watching. + Added integration tests. Run with ./run-tests + Refactored event loop. + Added suspend/resume RTC corruption detection. + Add -w option to get time from HTTPS header instead of from TLS ServerHello + Update AppArmor profile + Add simple systemd service file + Extra verbose output available with -vv; useful verbosity is -v +0.0.6 Mon 18 Feb, 2013 + Ensure that tlsdate compiles with g++ by explicit casting rather than + implicit casting by whatever compiler is compiling tlsdate. + Fix a logic bug in CN parsing caught by Ryan Sleevi of the Google Chrome Team + Further fixes by Thijs Alkemade + Add PolarSSL support (We no longer require OpenSSL to function!) + Thanks to Paul Bakker and the PolarSSL team! + Experimental Mac OS X (10.8.2) support + Thanks to Brian Aker and Ingy döt Net for pair programming time +0.0.5 Web 23 Jan, 2013 + Fix spelling error in tlsdate-helper + Update man pages formatting + Add Seccomp-BPF policies to be used with Minijail + Update CA cert file to remove TÃœRKTRUST + Support both CA certificate files or directories full of CA certs + Currently /etc/tlsdate/ca-roots/tlsdate-ca-roots.conf + Support announcing time updates over DBus with --enable-dbus + This introduces the 'tlsdate-dbus-announce' utility + Add support for lcov/gcov at build time + See ./configure --enable-code-coverage-checks and make lcov + Don't hardfail if DEFAULT_RTC_DEVICE cannot be opened, even if desired + Raspberry PI users rejoice (if the fix works) + Support -j to add jitter to tlsdated time checks. + Exponential backoff when TLS connections fail. + Add config file support (have a look at man/tlsdated.conf.5) + Support multiple hosts for time fetches + Add multiple hosts to your tlsdated.conf file today + Add simple AppArmor profile for /usr/bin/tlsdate-dbus-announce + Update AppArmor profile for tlsdated +0.0.4 Wed 7 Nov, 2012 + Fixup CHANGELOG and properly tag + Version Numbers Are Free! Hooray! + Update certificate data in ca-roots/ + tlsdate will now call tlsdate-helper with an absolute path + Pointed out ages ago by 0xabad1dea and others as a better execlp path + forward for execution. +0.0.3 Mon 5 Nov, 2012 + Add tlsdate-routeup man page + Update all man pages to reference other related man pages + Fix deb Makefile target + Update documentation + misc src changes (retab, formatting, includes, etc) + Update AppArmor profiles + Add HTTP/socks4a/socks5 proxy support and update man page documentation +0.0.2 Mon 29 Oct, 2012 + Released at the Metalab in Vienna during their third #CryptoParty + Add '-n' and '--dont-set-clock' option to fetch but not set time + Add '-V' and '--showtime' option to display remote time + Add '-t' and '--timewarp' option + If the local clock is before RECENT_COMPILE_DATE; we set the clock to the + RECENT_COMPILE_DATE. If the local clock is after RECENT_COMPILE_DATE, we + leave the clock alone. Clock setting is performed as the first operation + and will impact certificate verification. Specifically, this option is + helpful if on first boot, the local system clock is set back to the era + of Disco and Terrible Hair. This should ensure that + X509_V_ERR_CERT_NOT_YET_VALID or X509_V_ERR_CERT_HAS_EXPIRED are not + encountered because of a broken RTC or the lack of a local RTC; we assume + that tlsdate is recompiled yearly and that all certificates are otherwise + considered valid. + Add '-l' and '--leap' + Normally, the passing of time or time yet to come ensures that SSL verify + functions will fail to validate certificates. Commonly, + X509_V_ERR_CERT_NOT_YET_VALID and X509_V_ERR_CERT_HAS_EXPIRED are painfully + annoying but still very important error states. When the only issue with + the certificates in question is the timing information, this option allows + one to trust the remote system's time, as long as it is after + RECENT_COMPILE_DATE and before MAX_REASONABLE_TIME. The connection will + only be trusted if X509_V_ERR_CERT_NOT_YET_VALID and/or + X509_V_OKX509_V_ERR_CERT_HAS_EXPIRED are the only errors encountered. The + SSL verify function will not return X509_V_OK if there are any other + issues, such as self-signed certificates or if the user pins to a CA that + is not used by the remote server. This is useful if your RTC is broken on + boot and you are unable to use DNSSEC until you've at least had some kind + of leap of cryptographically assured data. + Update usage documentation + Move {*.c,h} into src/ + Move *.1 into man/ + Update TODO list to reflect desired changes + Update AppArmor profile to restrict {tlsdate,tlsdate-helper,tlsdated,tlsdate-routeup} + Update AUTHORS file to include a new email address + Update CHANGELOG + Added proper date for the 0.0.1 release + (Added all of the above items, obviously) + Print key bit length and key type information + Update Copyright headers to include the Great Christian Grothoff + Ensure key bit length and key type values are reasonable + Add CommonName and SAN checking + Add enumeration and printing of other x.509 extensions in SAN checking + Add SAN checking for iPAddress field per RFC2818 + Various small bug fixes + Fixed various tiny memory leaks + Added compat layer library for future multi-platform support by David Goulet + Compile output is now largely silent by default + Wildcard certificate verification per RFC 2595 + Add list of trusted CA certs to /etc/tlsdate/tlsdate-ca-roots.conf + Add Makefile target to update trusted CA certs from Mozilla's NSS trust root + Add tlsdated daemon + Add tlsdated documentation + +0.0.1 Fri Jul 13, 2012 + First git tagged release diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 0000000..b069e07 --- /dev/null +++ b/HACKING.md @@ -0,0 +1,108 @@ +Please feel free to contribute patches; here are the basic guidelines to hack +along with us! + +Please work from a git tree by cloning the repo: + + git clone https://github.com/ioerror/tlsdate.git + +Please file bugs on the tlsdate issue tracker: + + https://github.com/ioerror/tlsdate/issues + +Please use the github pull request feature when possible. + +The current build status is available as a handy image: + +[![Build Status](https://secure.travis-ci.org/ioerror/tlsdate.png?branch=master)](http://travis-ci.org/ioerror/tlsdate) + +Continuous integration is available for a number of platforms: + + https://jenkins.torproject.org/job/tlsdate-ci-linux/ + https://travis-ci.org/ioerror/tlsdate + http://build.chromium.org/p/chromiumos/waterfall + +White Space: + + Spaces only, no tabs; all tabs must die + No stray spaces at the end of lines + Generally try not to add excessive empty white space + +Documentation: + + Document all functions with doxygen style comments + +Ensuring Correctness: + + Test your patches and ensure: + + No compiler warnings or errors + No linker warnings or errors + + Test your improved copy of tlsdate extensively + +Security: + + tlsdate is security sensitive - please consider where you add code and in + what context it will run. When possible, run with the least privilege as is + possible. + +Proactively find bugs: + + Run your copy of tlsdate under valgrind + +Weird but meaningful conventions are prefered in tlsdate. We prefer attention +to detail: + + if ( NULL == foo (void) ) + { + bar (void); + } + +Over quick, hard to read and potentilly incorrect: + + if (foo(void)==NULL)) + bar(); + +Define magic numbers and explain their origin: + + // As taken from RFC 3.14 + #define MAGIC_NUMBER 23 // This goes in foo.h + ptr = malloc (MAGIC_NUMBER); + +Rather than just throwing them about in code: + + ptr = malloc (23); + +It is almost always prefered to use dynamically allocated memory: + + widget_ptr = malloc (WIDGET_SIZE); + +Try to avoid static allocations like the following: + + char widget[WIDGET_SIZE]; + +Try to use unsigned values unless an API requires signed values: + + uint32_t server_time_s; + +Please provide relevant CHANGELOG entries for all changes. +Please remove items from the TODO file as they are completed. +Please provide unittest cases. + +When submitting patches via email, please use `git format-patch` to format +patches: + + git format-patch 9a61fcba9bebc3fa2d91c9f79306bf316c59cbcc + +Email patches with a GnuPG signature whenever possible. + +When applying patches, please use `git am` to apply patches: + + git am -i 0001-add-TODO-item.patch + +If `git format-patch` is not possible, please send a unified diff. + +When in doubt, please consult the Tor HACKING guide: + + https://gitweb.torproject.org/tor.git/blob/HEAD:/doc/HACKING + diff --git a/HARDENING b/HARDENING new file mode 100644 index 0000000..e977395 --- /dev/null +++ b/HARDENING @@ -0,0 +1,76 @@ +Platforms offer varying security features; we'd like to support the best. + +This is a document that notes which security hardening we have implemented and +which things we'd like to see implemented for various platforms. We +specifically address exploitation mitigation and containment; security issues +such as x509 certification validation are not addressed here, yet. Patches, +suggestions and improvements are welcome! We always want the strongest set of +options by default on each supported platform. + +We attempt to use the C programming language correctly and in a standard way. +We do however use some compiler specific options such as defining integer +wrapping because we believe the practical benefit outweights the implied risks. +As such, we prefer to be explicit rather than implicit in our casting or other +possible ambiguity. + +We should treat all compiler and linker warnings as fatal errors. Currently, +consider autotools warnings to be an exception as we would like to support +platforms imperfectly rather than not at all. We generally wish to support +autotools bootstrapping on all of our supported platforms. This is not possible +on Plan 9. Currently autotools will complain on the BSD systems. + +On all platforms we attempt to support available compiler hardening and linking +options. Please do not disable these options. Additional compiler and linker +hardening options are welcome and the current options are implemented in the +following file: + + configure.ac + +On all platforms, we attempt to switch from the administrative user to an +unimportant role account which shares data with no other processes. If we start +as any user other than an administrative user, we will likely be unable to +switch to our normal unprivileged account. These users are defined at +`configure` time. It is most effective if such a user is not the traditional +'nobody' or group 'nogroup' as is often the tradition. + +In addition to the above hardening options, we have tried to extend our +hardening when the platform supports it. Each additional security measure that +we take is documented as well as planned or desired improvements. + +We do not currently support or set ulimits, we should do so where possible. + +On Debian Gnu/Linux platforms, we ship with a minimal AppArmor profile, see +the policy for details: + + apparmor-profile + +We'd like to have an SELinux policy specifically for tlsdate. +We'd like to support capability dropping with libcap or libcap-ng. +We'd like to support libseccomp2 filters. +Other kernel hardening suggestions are welcome. + +On ChromeOS we use minijail and seccomp filters, see the following policies for +details: + + tlsdate-seccomp-amd64.policy + tlsdate-seccomp-arm.policy + tlsdate-seccomp-x86.policy + +These are enabled by default in ChromeOS. + +On FreeBSD, we'd like to support jails, chroot, and Capsicum. + +On OpenBSD, we'd like to support chroot and systrace. + +On NetBSD, we'd like to chroot. + +On DragonFly BSD, we'd like to support chroot and jails. + +On Mac OS X, we'd like to support chroot and seatbelt. + +On Plan9, we'd like to chroot. + +On Windows, we do nothing beyond compile time hardening. We'd like to do more. + +On other platforms, we'll try to run correctly with the understanding that any +bug is likely a much more serious problem. @@ -0,0 +1,217 @@ +tlsdate should build and work on the following Operating Systems: + + Debian GNU/Linux squeeze, wheezy, jessie, sid + Ubuntu lucid, natty, oneiric, precise, quantal + CentOS 6.2, 6.3, 6.4 + Fedora 17, 18 + RedHat Enterprise Server 6.4 + OpenSUSE 11.2, 12.3 + FreeBSD 9.2, 10, 11 + Mac OS X 10.8.2, 10.8.3 + ChromeOS Release 25, 26, 27 and above + Android with the Android NDK (use Makefile.android) + Arch Linux (Don't forget to symlink to /dev/rtc to /dev/rtc0) + NetBSD 6.0.1 + OpenBSD 5.2 + Gentoo 20130413 + DragonFly BSD 3.3-DEVELOPMENT + Debian GNU/kFreeBSD 7.0 (8.2-1-amd64) + Debian GNU/Hurd + +tlsdate should build and might even work on the following Operating Systems: + + Win32 with Cygwin CYGWIN_NT-6.1 1.7.18(0.263/5/3 + Win32 with MinGW + Haiku r1alpha4 + +Please file a bug or email the tlsdate team if you have successfully built or +use tlsdate on a platform that is not listed. We are specifically looking for +ports of tlsdate or for tlsdate integration on the following Operating Systems: + + Windows native + OpenWRT + pfsense + OpenVMS + Irix + Minix + Any of the other classic unix systems + +Currently porting is in progress or partially documented for: + + Plan9 (with APE) + Debian GNU/Hurd 7.0 (GNU-Mach 1.3.99-486-dbg/Hurd-0.3) + Currently we report "server time 0 (difference is about 1367009757 s)" +Building and install of tlsdate on GNU/Linux and FreeBSD: + + ./autogen.sh + ./configure + make + make install + +Cleaning is the usual: + + make clean + +On Debian Gnu/Linux sid/unstable: + + apt-get install tlsdate + +On other versions of Debian GNU/Linux and with Debian backports, tlsdate may be +available: + + apt-get install tlsdate + +On recent Debian GNU/Linux and related systems, we provide a systemd service. +It will notice network changes and regularly invoke tlsdate to keep the clock +in sync. Start it like so: + + service tlsdated start + +On older Debian GNU/Linux and related systems, we provide an init.d script that +controls the tlsdated daemon. It will notice network changes and regularly +invoke tlsdate to keep the clock in sync. Start it like so: + + /etc/init.d/tlsdated start + +Debian GNU/Hurd does not yet support autotools bootstrapping and users must +bootstrap with `make dist` on another platform from the tlsdate git +repository. With such a release tar.gz it is the expected process: + + ./configure + make + make install + +Please note that setting time on GNU/Hurd has not yet been tested. + +On ChromeOS: + + tlsdated and tlsdate are included in the ChromeOS TCB; no install needed. They + run automatically and are the core ntp service for ChromeOS. + +On Gentoo: + + emerge net-misc/tlsdate + +On FreeBSD one may also use the ports system: + + cd /usr/ports/sysutils/tlsdate + make + make install + +On Mac OS X, we require that you have XCode installed. You may also need brew +for autoconf and automake packages: + + brew install autoconf automake libtool pkg-config + +It should also be possible to install tlsdate on OS X 10.8.x with brew directly: + + brew install tlsdate + +On Fedora: + + yum install tlsdate + +To run tlsdated as a service on Fedora: + + systemctl enable tlsdate.service + systemctl start tlsdate.service + +On Arch Linux there is a PKGBUILD in the Arch User Repository: + + https://aur.archlinux.org/packages/tlsdate + https://aur.archlinux.org/packages/tl/tlsdate/PKGBUILD + +Cygwin requires that the user installs openssl-dev, gcc, pkg-config, libtool, automake, autoconf: + + ./configure + make + +On Plan9 the start of building might look something like this: + + ip/ipconfig + ndb/dns -r + 9fs sources + /n/sources/contrib/fgb/root/rc/bin/contrib/install fgb/openssl + mk install + +On Haiku we must use gcc4: + + export CC=/boot/develop/abi/x86/gcc4/tools/gcc4.6.3-haiku-121101/bin/gcc + export LDFLAGS="$LDFLAGS -lbsd" + ./configure # This includes the above exports currently + make + +OpenBSD builds from source and is not yet in the port system: + + export AUTOCONF_VERSION=<your installed version> + export AUTOMAKE_VERSION=<your installed version> + ./autogen.sh + ./configure + make + make install + +If you wish to make a Debian package there are several other options. It is +expected that you are building for Sid and that you are familiar with how to +build Debian packages that are for upload into Debian directly. It is expected +that you should build in a chroot if you wish to have reliable and or +reproducible builds. + + # Prep your schroot + mysid=sid$RANDOM; + schroot -b -c sid -n $mysid; + dd-schroot-cmd -c $mysid apt-get update; + dd-schroot-cmd -c $mysid apt-get build-dep tlsdate; + # If build-dep is building an older tlsdate, you may need these tools too: + dd-schroot-cmd -c $mysid apt-get install git ca-certificates \ + lintian libevent-dev libseccomp-dev; + echo "Your chroot is called: $mysid"; + schroot -r -c $mysid + # Build tlsdate + git clone https://www.github.com/ioerror/tlsdate/ + cd tlsdate/ + git checkout debian-master + dpkg-buildpackage -B "-mMyName <MyEmail>" -uc + +Building without schroot should work with dpkg-buildpackage but the build +environment will have to be manually configured. + +To make a Debian package with git-buildpackage is the expected build process: + + # install dependencies + apt-get install git ca-certificates \ + lintian libevent-dev libseccomp-dev build-essential \ + autoconf dh-autoreconf dh-systemd automake autotools-dev \ + dh-apparmor libssl-dev libevent-dev libtool pkg-config \ + debhelper fakeroot hardening-wrapper git-buildpackage; + git clone https://www.github.com/ioerror/tlsdate/ + cd tlsdate/ + git checkout debian-master + git-buildpackage --git-upstream-branch=master \ + --git-debian-branch=debian-master \ + --git-upstream-tree=master \ + --git-ignore-new + +For Android: + +To cross compile tlsdate for Android (tested on Linux) you must have the +Android NDK (>=r8) installed somewhere on your system, and define the +environment variable NDK_BASE to be the path to the NDK's root dir. + + export NDK_BASE=/home/user/src/android-ndk-r8d + +The Android build also requires a cross-compiled OpenSSL. The Android Makefile +will attempt to build openssl, if you provide the path via the OPENSSL_ANDROID +env var. + + git clone https://github.com/guardianproject/openssl-android.git /path/to/android-openssl + export OPENSSL_ANDROID=/path/to/android-openssl + +Once NDK_BASE and OPENSSL_ANDROID are set properly, you can cross compile tlsdate with: + + make distclean # clean any previous builds + rm configure # distclean doesn't remove this file + make -f Makefile.android + +Android NDK: https://developer.android.com/tools/sdk/ndk/index.html +OpenSSL for Android: https://github.com/guardianproject/openssl-android + @@ -0,0 +1,51 @@ + This file contains the license for tlsdate, + a free software project to set your system clock securely. + + It also lists the licenses for other components used by tlsdate. + + For more information about tlsdate, see https://github.com/ioerror/tlsdate + + If you got this file as a part of a larger bundle, + there may be other license terms that you should be aware of. + +=============================================================================== +tlsdate is distributed under this license: + +Copyright (c) 2011-2012, Jacob Appelbaum <jacob@appelbaum.net> +Copyright (c) 2011-2012, The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=============================================================================== +If you got tlsdate as a static binary with OpenSSL included, then you should +know: + + "This product includes software developed by the OpenSSL Project for use in + the OpenSSL Toolkit (http://www.openssl.org/)" + +=============================================================================== diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..1573a7b --- /dev/null +++ b/Makefile.am @@ -0,0 +1,149 @@ +# vim:ft=automake + +AM_CFLAGS="-D__STDC_LIMIT_MACROS" + +BUILT_SOURCES= +doc_DATA= +EXTRA_DIST= +TESTS= +bin_PROGRAMS= +sbin_PROGRAMS= +check_PROGRAMS= +lib_LTLIBRARIES= +man_MANS= +noinst_HEADERS= +noinst_LTLIBRARIES= +noinst_PROGRAMS= + +if !TARGET_OSX +# GNU style is "make check", this will make check and test work +TESTS+= src/conf_unittest src/proxy-bio_unittest +if TARGET_LINUX +TESTS+= src/tlsdated_unittest +endif +test: check +endif + +ACLOCAL_AMFLAGS= -I m4 + +# Our Debian version +DEBIAN_VERSION := $(shell if [ -e debian/changelog ]; then cat debian/changelog|head -n1|cut -d\- -f2| head -c 1; else echo "unknown"; fi) + +doc_DATA+= AUTHORS +doc_DATA+= CHANGELOG +doc_DATA+= LICENSE +doc_DATA+= README +doc_DATA+= TODO + +EXTRA_DIST+= $(doc_DATA) +EXTRA_DIST+= apparmor-profile +EXTRA_DIST+= autogen.sh +EXTRA_DIST+= tlsdated.service + +include src/include.am + +# Cleanup individual files in order to preserve uninstall/etc order +maintainer-clean-local: + @rm -r -f autom4te.cache + @rm Makefile.in + @rm aclocal.m4 + @rm config.in + @rm config/config.guess + @rm config/config.sub + @rm config/depcomp + @rm config/install-sh + @rm config/ltmain.sh + @rm config/missing + @rm configure + @rmdir config + @rm dbus/org.torproject.tlsdate.conf + @rm m4/libtool.m4 + @rm m4/ltoptions.m4 + @rm m4/ltsugar.m4 + @rm m4/ltversion.m4 + @rm m4/lt~obsolete.m4 + @rm -f tlsdate-*.tar.gz + -rm src/configmake.h + -rm dbus/org.torproject.tlsdate.conf + @find ./ | $(GREP) \~$$ | xargs rm -f + +certdir = @TLSDATE_CA_ROOTS@ +cert_DATA = ca-roots/tlsdate-ca-roots.conf +EXTRA_DIST+= $(cert_DATA) + +confdir = @TLSDATE_CONF_DIR@ +if TARGET_LINUX +conf_DATA = etc/tlsdated.conf +EXTRA_DIST+= $(conf_DATA) +endif + +# Our documentation +man_MANS+= man/tlsdate.1 +man_MANS+= man/tlsdate-helper.1 + +if TARGET_LINUX +man_MANS+= man/tlsdated.8 +man_MANS+= man/tlsdated.conf.5 +endif + +EXTRA_DIST+= $(man_MANS) + +.PHONY: debian_orig git-tag git-push git-tag-debian deb really-clean valgrind_test +debian_orig: + $(MAKE) dist + mv tlsdate-$(VERSION).tar.gz ../tlsdate_$(VERSION).orig.tar.gz + +git-tag: + git tag -u 0x1801A819 -s tlsdate-$(VERSION) + +git-tag-debian: + git tag -u 0x1801A819 -s tlsdate-$(VERSION)-debian-${DEBIAN_VERSION} + +git-push: + git push --tags + git push + +deb: debian_orig + debuild -i'.*' -rfakeroot -uc -us -d + +# This generates code coverage data that is useful for continuous integration +lcov: +# ./configure --enable-code-coverage-checks && make && # ... run everything and then... + lcov --directory src -b . --capture --output-file tlsdate.lcov && genhtml -o lcov/ tlsdate.lcov + +valgrind_test: + TESTS_ENVIRONMENT="./libtool --mode=execute valgrind --trace-children=yes --leak-check=full" ./src/tlsdate -v -V -n -H encrypted.google.com + +# This allows us to parse the Mozilla NSS CA trusted root list and ensures we +# respect the trust bits as they are set - using them directly without the +# context is dangerous. This gives us a basic set of CA roots to trust for use +# with tlsdate without relying on any system CA list. +# You'll need agl's extract-nss-root-certs to recreate this file: +# https://github.com/agl/extract-nss-root-certs +update_ca_root_data: + curl https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt\?raw\=1 -o ca-roots/certdata.txt + go run ~/Documents/code/git/extract-nss-root-certs/convert_mozilla_certdata.go ca-roots/certdata.txt > ca-roots/tlsdate-ca-roots.conf + rm ca-roots/certdata.txt + +test_run: + ./src/tlsdate-helper google.com 443 tlsv1 racket verbose ca-roots/tlsdate-ca-roots.conf dont-set-clock showtime no-fun holdfast none + +BUILT_SOURCES+= src/configmake.h +noinst_HEADERS+= src/configmake.h +src/configmake.h: ${top_srcdir}/Makefile.in + @echo "Making $@" + @rm -f $@-t $@ + @{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ + echo '#define TLSDATE_CONFIG "$(sysconfdir)/ca-roots/"'; \ + echo '#define TLSDATE_CERTFILE "$(sysconfdir)/tlsdate/ca-roots/tlsdate-ca-roots.conf"'; \ + echo '#define TLSDATE_CONF_DIR "$(sysconfdir)/tlsdate/"'; \ + echo '#define TLSDATE_HELPER "$(bindir)/tlsdate-helper"'; \ + echo '#define TLSDATE "$(bindir)/tlsdate"'; \ + echo '#define TLSDATED "$(bindir)/tlsdated"'; \ + } | sed '/""/d' > $@-t + @if diff $@-t $@ >/dev/null 2>&1 ; then \ + rm @-t ; \ + else \ + mv $@-t $@ ; \ + fi + diff --git a/Makefile.android b/Makefile.android new file mode 100644 index 0000000..fba97ac --- /dev/null +++ b/Makefile.android @@ -0,0 +1,76 @@ +# +## Cross-compile env for Android +# Requires Android NDK >= r8 +# Requires the following env variables: +# +# NDK_BASE - path to your NDK's root directory +# e.g., /home/user/android-ndk +# OPENSSL_ANDROID - path to NDK built openssl +# e.g., /home/user/src/openssl-android +# + +# Android NDK setup +NDK_COMPILER_VERSION=4.6 +NDK_ABI=arm +NDK_BASE ?= /usr/local/android-ndk +#platform level >= 8 required for dladdr() +NDK_PLATFORM_LEVEL ?= 8 +NDK_SYSROOT=$(NDK_BASE)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-arm +NDK_UNAME=`uname -s | tr '[A-Z]' '[a-z]'` +NDK_TOOLCHAIN=$(NDK_BASE)/toolchains/$(NDK_ABI)-linux-androideabi-$(NDK_COMPILER_VERSION)/prebuilt/$(NDK_UNAME)-x86 + +# to use the real HOST tag, you need the latest libtool files: +# http://stackoverflow.com/questions/4594736/configure-does-not-recognize-androideabi +NDK_UNAME := `uname -s | tr '[A-Z]' '[a-z]'` +HOST := arm-linux-androideabi + +LOCAL_LDFLAGS = -L$(OPENSSL_ANDROID)/obj/local/armeabi/ -ldl -lcrypto -lssl -lz +LOCAL_LDFLAGS += -L$(NDK_TOOLCHAIN)/lib/gcc/arm-linux-androideabi/$($NDK_COMPILER_VERSION) -lgcc +CFLAGS = -I$(OPENSSL_ANDROID)/include +CC := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-gcc --sysroot=$(NDK_SYSROOT) +CXX := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-g++ +CPP := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-cpp +LD := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-ld +AR := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-ar +RANLIB := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-ranlib +STRIP := $(NDK_TOOLCHAIN)/bin/arm-linux-androideabi-strip \ + +all: $(OPENSSL_ANDROID)/libs/armeabi/libcrypto.so tlsdate-build + +$(OPENSSL_ANDROID)/libs/armeabi/libcrypto.so: + cd $(OPENSSL_ANDROID) && ndk-build -j4 + +openssl-clean: + -cd $(OPENSSL_ANDROID) && ndk-build clean + +openssl-distclean: + -cd $(OPENSSL_ANDROID) && ndk-build distclean + +configure: configure.ac + ./autogen.sh && \ + CFLAGS="$(CFLAGS)" ./configure \ + CC="$(CC)" \ + AR=$(AR) \ + RANLIB=$(RANLIB) \ + CFLAGS="$(CFLAGS)" \ + --disable-static \ + --disable-languages \ + --disable-dbus \ + --host=$(HOST) + #--prefix=$(prefix) \ + #--exec-prefix=$(prefix) + +tlsdate-build: configure + make -f Makefile CFLAGS="$(CFLAGS)" LDFLAGS="$(LOCAL_LDFLAGS)" + +tlsdate-clean: + -make -f Makefile clean + +tlsdate-distclean: + -make -f Makefile distclean && rm configure + + +clean: openssl-clean tlsdate-clean +distclean: openssl-distclean tlsdate-distclean + +.PHONY: clean openssl-clean tlsdate-clean @@ -0,0 +1,47 @@ +tlsdate: secure parasitic rdate replacement + + tlsdate sets the local clock by securely connecting with TLS to remote + servers and extracting the remote time out of the secure handshake. Unlike + ntpdate, tlsdate uses TCP, for instance connecting to a remote HTTPS or TLS + enabled service, and provides some protection against adversaries that try to + feed you malicious time information. + +On Debian GNU/Linux and related systems, we provide an init.d script that +controls the tlsdated daemon. It will notice network changes and regularly +invoke tlsdate to keep the clock in sync. Start it like so: + + /etc/init.d/tlsdate start + + +Here is an example an unprivileged user fetching the remote time: + + % tlsdate -V -n -H encrypted.google.com + Fri Apr 19 17:56:46 PDT 2013 + + +This is an example run - starting as root and dropping to nobody, setting the +clock and printing it: + + % sudo tlsdate -V + Fri Apr 19 17:57:49 PDT 2013 + + +Here is an example with a custom host and custom port without verification: + + % sudo tlsdate --skip-verification -p 80 -H rgnx.net + +Here is an example where a system may not have any kind of RTC at boot. Do the +time warp to restore sanity and do so with a leap of faith: + + % sudo tlsdate -V -l -t + Fri Apr 19 18:08:03 PDT 2013 + + +Some SSL/TLS services do not provide accurate time in their handshake process; +tlsdate may also be used to fetch time by processing the HTTP Date headers of +HTTP services: + + % sudo tlsdate -V -l -t -w + Wed Oct 30 18:08:46 CET 2013 + + diff --git a/TLSDATEPOOL b/TLSDATEPOOL new file mode 100644 index 0000000..2ca8015 --- /dev/null +++ b/TLSDATEPOOL @@ -0,0 +1,31 @@ +"Lets parasitically pool TLS resources into a single location!" + +ntp has pool.ntp.org which currently hosts around ~3000 machines. +tlsdate has only the wild internet's pool of TLS/SSL machines. + +It is believed that there are around ~185,000 reasonable SSL/TLS servers in the +genepool that is the internet. + +To discover the relevant systems in the genepool we will conduct scans and +collect data of SSL/TLS services for the entire internet. When a server is +discovered and it is confirmed to have a reasonably accurate clock, we will +store it in the genepool list. + +The genepool list will first be a text file included with tlsdate and tlsdate +will have an option to use the local genepool; it will randomly select an entry +from the list and use it for timing information. + +The genepool list will be in the following CSV format: + + hostname,port,last known IP address, protocol + +Currently, the default protocol is TLSv1 unless otherwise specified. Fields may +include sslv2, sslv3, tlsv1, tlsv1.1, tlsv1.2, xmpp, pop3, imap and other +STARTTLS enabled protocols. + +Eventually, we propose that a simple DNS query interface located at +genepool.tlsdate.net should return random entries from the genepool list. It +should only host records of machines that have correct timing information in +their SSL/TLS handshakes. The data returned will optionally be a TXT record +containing a line from a regularly updated genepool cache file or an A/AAAA +record for the host. @@ -0,0 +1,42 @@ + +Here is a nice list of things to do to improve tlsdate: + + + 1) hack the client handshake to not leak the clock to the server + set it to all zeros or something cute or something random + + 3) add HTTP GET request to avoid network fingerprinting + 6) skew the clock rather than slamming it +11) verification of remote certificate for Tor nodes +13) account for servers that do not send UTC (Microsoft sends local time) +14) port to bssl, nss, gnutls, yassl, and other libraries +15) starttls support (smtp, pop, imap, ftp, xmpp) +16) ensure that 32bit time isn't near wrapping time on 32bit systems +17) find others to audit it - we need more eyes! +20) Add verification of remote servers by DANE/CAA DNSSEC protected records +21) Integrate Chrome's CRL list into tlsdate +22) Block revoked or bad certs such as MD5 inc. and others. +24) Add OCSP check option +25) Block weak signature algorithms +26) Hard code block list of known horrible certs (extract from Chrome/FF) +28) Check that extended key usage is empty, or includes TLS Server Auth +29) extract the SubjectPublicKeyInfo from the certificates; match against + public keys +31) Confirm HTTP and TLS date is within a sane range +32) Integrate tack support https://github.com/tack/tackc +33) Implement checking of RFC 2818 style wildcards: + http://wiki.cacert.org/WildcardCertificates +35) seatbelt profile for Mac OS X +36) SELinux policy for GNU/Linux platforms +37) Port to some Windows operating system that anyone actually uses +42) Unit-test everything +47) Review cert validation and compare it with Chrome: + https://code.google.com/p/chromium/codesearch#chrome/src/net/base/x509_certificate.cc&l=500 +48) Complain when server uses very weak DH group parameters + example weak server: https://demo.cmrg.net/ +49) Add seccomp tlsdate and tlsdate-helper +50) Add AppArmor fixes for Tails +52) Port tlsdated to FreeBSD and other non GNU/Linux systems + +Patches welcome! + diff --git a/apparmor-profile b/apparmor-profile new file mode 100644 index 0000000..20451ed --- /dev/null +++ b/apparmor-profile @@ -0,0 +1,200 @@ +# +# AppArmor tlsdate profile for Debian GNU/Linux +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License published by the Free Software Foundation. +# + +#include <tunables/global> +#include <tunables/multiarch.d> +/usr/bin/tlsdate { + #include <abstractions/consoles> + #include <abstractions/ssl_certs> + + capability sys_time, + capability setgid, + capability setuid, + capability sys_chroot, + + # IPv4 TCP + network inet stream, + # IPv4 UDP for DNS resolution + network inet dgram, + # IPv6 TCP + network inet6 stream, + # IPv6 UDP + network inet6 dgram, + + # Required for gethostbyname + /etc/resolv.conf r, + /run/resolvconf/resolv.conf r, + /etc/nsswitch.conf r, + /etc/localtime r, + /etc/nsswitch.conf r, + /etc/hosts r, + /etc/host.conf r, + + # Allow reading public certs but not private keys + /etc/ssl/certs/* r, + /usr/share/ca-certificates/*/** r, + + # Allow reading of /etc/tlsdate/ + /etc/tlsdate/*/** r, + + # Required for getpwnam + /etc/passwd r, + /etc/group r, + /proc/sys/kernel/ngroups_max r, + + # Allow reading of libs and /tmp + /etc/ld.so.cache r, + + # Random number generation requires these two + /dev/random r, + /dev/urandom r, + + # Allow mapping of shared libraries + /lib{,32,64}/* rm, + /usr/lib/* rm, + /lib/@{multiarch}/* rm, + /usr/lib/@{multiarch}/* rm, + + # We'll allow tlsdate to write a new root to chroot into + /tmp/ r, + owner /tmp/tlsdate_*/ rw, + + # We'll allow tlsdate to exec tlsdate-helper + /usr/bin/tlsdate-helper ixm, + /usr/bin/tlsdate ixm, +} + +/usr/bin/tlsdate-helper { + #include <abstractions/consoles> + #include <abstractions/ssl_certs> + + capability sys_time, + capability setgid, + capability setuid, + capability sys_chroot, + + # IPv4 TCP + network inet stream, + # IPv4 UDP for DNS resolution + network inet dgram, + # IPv6 TCP + network inet6 stream, + # IPv6 UDP + network inet6 dgram, + + # Required for gethostbyname + /etc/resolv.conf r, + /run/resolvconf/resolv.conf r, + /etc/nsswitch.conf r, + /etc/localtime r, + /etc/nsswitch.conf r, + /etc/hosts r, + /etc/host.conf r, + + # Allow reading public certs but not private keys + /etc/ssl/certs/* r, + /usr/share/ca-certificates/*/** r, + + # Allow reading of /etc/tlsdate/ + /etc/tlsdate/*/** r, + + # Required for getpwnam + /etc/passwd r, + /etc/group r, + /proc/sys/kernel/ngroups_max r, + + # Allow reading of libs and /tmp + /etc/ld.so.cache r, + + # Random number generation requires these two + /dev/random r, + /dev/urandom r, + + # Allow mapping of shared libraries + /lib{,32,64}/* rm, + /usr/lib/* rm, + /lib/@{multiarch}/* rm, + /usr/lib/@{multiarch}/* rm, + + # We'll allow tlsdate to write a new root to chroot into + /tmp/ r, + owner /tmp/tlsdate_*/ rw, +} + +/usr/sbin/tlsdated { + #include <abstractions/consoles> + #include <abstractions/ssl_certs> + + capability sys_time, + capability setgid, + capability setuid, + capability sys_chroot, + + # IPv4 TCP + network inet stream, + # IPv4 UDP for DNS resolution + network inet dgram, + # IPv6 TCP + network inet6 stream, + # IPv6 UDP + network inet6 dgram, + + # Required for gethostbyname + /etc/resolv.conf r, + /etc/nsswitch.conf r, + /etc/localtime r, + /etc/nsswitch.conf r, + /etc/hosts r, + /etc/host.conf r, + + # Allow reading public certs but not private keys + /etc/ssl/certs/* r, + /usr/share/ca-certificates/*/** r, + + # Allow reading of /etc/tlsdate/ + /etc/tlsdate/*/** r, + /etc/tlsdate/tlsdated.conf r, + + # Required for getpwnam + /etc/passwd r, + /etc/group r, + /proc/sys/kernel/ngroups_max r, + + # tlsdated looks into proc for answers + /proc/meminfo r, + + # Allow reading of libs and /tmp + /etc/ld.so.cache r, + + # Random number generation requires these two + /dev/random r, + /dev/urandom r, + + # RTC + /dev/rtc0 rw, + /dev/rtc1 rw, + + # Allow mapping of shared libraries + /lib{,32,64}/* rm, + /usr/lib/* rm, + /lib/@{multiarch}/* rm, + /usr/lib/@{multiarch}/* rm, + + # We'll allow tlsdate to write a new root to chroot into + /tmp/ r, + owner /tmp/tlsdate_*/ rw, + + # We'll allow tlsdated to cache the time here + owner /var/cache/tlsdated/* rw, + # We'll allow the unprivileged helper to read the time + /var/cache/tlsdated/* r, + + # We'll allow tlsdated to exec tlsdate-helper + /usr/bin/tlsdate-helper ixm, + /usr/bin/tlsdate ixm, +} diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..efdcacc --- /dev/null +++ b/autogen.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# This generates our configure scripts and leads us onto the path of +# the great Makefile... +# + +set -e + +if [ ! -d config ]; +then + mkdir config; +fi + +if [ $(uname) != FreeBSD ]; +then + WARNINGS="all,error" + export WARNINGS +fi + +if [ $(uname) = NetBSD ] || [ $(uname) = DragonFly ]; +then + WARNINGS="" + export WARNINGS +fi + +if [ $(uname) = "CYGWIN_NT-6.1" ] || [ $(uname) = "MINGW32_NT-6.1" ]; +then + WARNINGS="" + export WARNINGS +fi + +autoreconf --install --verbose --force diff --git a/ca-roots/tlsdate-ca-roots.conf b/ca-roots/tlsdate-ca-roots.conf new file mode 100644 index 0000000..9122472 --- /dev/null +++ b/ca-roots/tlsdate-ca-roots.conf @@ -0,0 +1,4725 @@ +# 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/. + +# Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. +# Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. +# Label: "GTE CyberTrust Global Root" +# Serial: 421 +# MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db +# SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74 +# SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36 +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD +VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv +bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv +b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH +iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS +r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 +04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r +GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 +3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P +lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +# Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division +# Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division +# Label: "Thawte Server CA" +# Serial: 1 +# MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d +# SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c +# SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9 +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm +MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx +MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 +dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl +cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 +DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD +gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 +yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX +L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj +EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG +7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e +QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ +qdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +# Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division +# Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division +# Label: "Thawte Premium Server CA" +# Serial: 1 +# MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a +# SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a +# SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72 +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx +FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD +VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy +dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t +MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB +MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG +A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp +b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl +cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv +bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE +VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ +ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR +uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG +9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI +hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM +pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +# Issuer: O=Equifax OU=Equifax Secure Certificate Authority +# Subject: O=Equifax OU=Equifax Secure Certificate Authority +# Label: "Equifax Secure CA" +# Serial: 903804111 +# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 +# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a +# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy +dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 +MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx +dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f +BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A +cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm +aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw +ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj +IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y +7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh +1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 +-----END CERTIFICATE----- + +# Issuer: O=Digital Signature Trust Co. OU=DSTCA E1 +# Subject: O=Digital Signature Trust Co. OU=DSTCA E1 +# Label: "Digital Signature Trust Co. Global CA 1" +# Serial: 913315222 +# MD5 Fingerprint: 25:7a:ba:83:2e:b6:a2:0b:da:fe:f5:02:0f:08:d7:ad +# SHA1 Fingerprint: 81:96:8b:3a:ef:1c:dc:70:f5:fa:32:69:c2:92:a3:63:5b:d1:23:d3 +# SHA256 Fingerprint: 63:04:19:ae:c4:78:cb:b4:bb:80:83:de:9d:9c:f2:79:75:2f:03:9d:ef:16:e4:64:71:b6:79:ca:93:00:2d:b0 +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg +bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ +j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV +Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw +MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5 +fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i ++DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN +QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+ +gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl +-----END CERTIFICATE----- + +# Issuer: O=Digital Signature Trust Co. OU=DSTCA E2 +# Subject: O=Digital Signature Trust Co. OU=DSTCA E2 +# Label: "Digital Signature Trust Co. Global CA 3" +# Serial: 913232846 +# MD5 Fingerprint: 93:c2:8e:11:7b:d4:f3:03:19:bd:28:75:13:4a:45:4a +# SHA1 Fingerprint: ab:48:f3:33:db:04:ab:b9:c0:72:da:5b:0c:c1:d0:57:f0:36:9b:46 +# SHA256 Fingerprint: 8f:62:d7:73:6f:99:db:d3:3e:e0:0e:10:c7:e3:29:33:9c:98:8a:5b:47:ef:25:f4:08:29:3c:f2:42:6b:4d:44 +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV +UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL +EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ +BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x +ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/ +k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso +LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o +TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG +SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx +JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI +RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3 +MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C +TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5 +WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG +SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR +xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL +B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID +-----END CERTIFICATE----- + +# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority +# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority +# Label: "Verisign Class 3 Public Primary Certification Authority" +# Serial: 149843929435818692848040365716851702463 +# MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67 +# SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2 +# SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70 +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do +lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc +AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k +-----END CERTIFICATE----- + +# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network +# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network +# Label: "Verisign Class 3 Public Primary Certification Authority - G2" +# Serial: 167285380242319648451154478808036881606 +# MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9 +# SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f +# SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh +c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy +MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp +emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X +DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw +FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg +UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo +YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 +MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 +pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 +13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID +AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk +U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i +F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY +oJ2daZH9 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority +# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority +# Label: "ValiCert Class 1 VA" +# Serial: 1 +# MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb +# SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e +# SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04 +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy +NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y +LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ +TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y +TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 +LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW +I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw +nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI +-----END CERTIFICATE----- + +# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority +# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority +# Label: "ValiCert Class 2 VA" +# Serial: 1 +# MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87 +# SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6 +# SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy +NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY +dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 +WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS +v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v +UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu +IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC +W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd +-----END CERTIFICATE----- + +# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority +# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority +# Label: "RSA Root Certificate 1" +# Serial: 1 +# MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72 +# SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb +# SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 +IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz +BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y +aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG +9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy +NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y +azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw +Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl +cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD +cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs +2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY +JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE +Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ +n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A +PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 3 Public Primary Certification Authority - G3" +# Serial: 206684696279472310254277870180966723415 +# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 +# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 +# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 4 Public Primary Certification Authority - G3" +# Serial: 314531972711909413743075096039378935511 +# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df +# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d +# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 +GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ ++mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd +U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm +NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY +ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ +ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 +CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq +g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c +2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ +bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Secure Server CA" +# Serial: 927650371 +# MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee +# SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39 +# SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50 +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u +ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc +KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u +ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 +MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE +ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j +b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg +U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ +I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 +wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC +AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb +oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 +BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p +dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk +MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp +b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 +MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi +E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa +MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI +hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN +95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd +2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946059622 +# MD5 Fingerprint: ba:21:ea:20:d6:dd:db:8f:c1:57:8b:40:ad:a1:fc:fc +# SHA1 Fingerprint: 80:1d:62:d0:7b:44:9d:5c:5c:03:5c:98:ea:61:fa:44:3c:2a:58:fe +# SHA256 Fingerprint: d1:c3:39:ea:27:84:eb:87:0f:93:4f:c5:63:4e:4a:a9:ad:55:05:01:64:01:f2:64:65:d3:7a:57:46:63:35:9f +-----BEGIN CERTIFICATE----- +MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy +MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA +vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G +CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA +WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo +oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ +h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 +f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN +B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy +vUxFnmG6v4SBkgPR0ml8xQ== +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. +# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. +# Label: "Equifax Secure Global eBusiness CA" +# Serial: 1 +# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc +# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45 +# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07 +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT +ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw +MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj +dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l +c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC +UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc +58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ +o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr +aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA +A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA +Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv +8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +# Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. +# Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. +# Label: "Equifax Secure eBusiness CA 1" +# Serial: 4 +# MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d +# SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41 +# SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73 +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT +ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw +MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j +LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ +KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo +RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu +WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw +Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD +AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK +eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM +zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ +WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN +/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +# Issuer: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 +# Subject: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 +# Label: "Equifax Secure eBusiness CA 2" +# Serial: 930140085 +# MD5 Fingerprint: aa:bf:bf:64:97:da:98:1d:6f:c6:08:3a:95:70:33:ca +# SHA1 Fingerprint: 39:4f:f6:85:0b:06:be:52:e5:18:56:cc:10:e1:80:e8:82:b3:85:cc +# SHA256 Fingerprint: 2f:27:4e:48:ab:a4:ac:7b:76:59:33:10:17:75:50:6d:c3:0e:e3:8e:f6:ac:d5:c0:49:32:cf:e0:41:23:42:20 +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj +dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 +NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD +VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G +vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ +BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C +AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX +MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl +IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw +NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq +y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF +MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA +A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy +0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 +E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network +# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network +# Label: "AddTrust Low-Value Services Root" +# Serial: 1 +# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc +# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d +# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7 +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw +MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD +VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul +CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n +tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl +dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch +PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC ++Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O +BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl +MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk +ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X +7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz +43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl +pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA +WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Label: "AddTrust External Root" +# Serial: 1 +# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f +# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 +# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network +# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network +# Label: "AddTrust Public Services Root" +# Serial: 1 +# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f +# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5 +# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx +MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB +ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV +BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV +6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX +GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP +dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH +1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF +62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW +BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL +MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU +cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv +b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 +IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ +iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh +4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm +XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network +# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network +# Label: "AddTrust Qualified Certificates Root" +# Serial: 1 +# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb +# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf +# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16 +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 +b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 +MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK +EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh +BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq +xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G +87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i +2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U +WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 +0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G +A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr +pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL +ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm +aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv +hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm +hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 +P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y +iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no +xqE= +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3 +# Subject: O=RSA Security Inc OU=RSA Security 2048 V3 +# Label: "RSA Security 2048 v3" +# Serial: 13297492616345471454730593562152402946 +# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e +# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42 +# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 +MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp +dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX +BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy +MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp +eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg +/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl +wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh +AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 +PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu +AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR +MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc +HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ +Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ +f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO +rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch +6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 +7CAFYd4= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Global CA 2" +# Serial: 1 +# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9 +# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d +# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85 +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs +IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A +PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 +Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL +TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL +5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 +S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe +2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap +EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td +EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv +/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN +A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 +abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF +I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz +4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +# Issuer: CN=America Online Root Certification Authority 1 O=America Online Inc. +# Subject: CN=America Online Root Certification Authority 1 O=America Online Inc. +# Label: "America Online Root Certification Authority 1" +# Serial: 1 +# MD5 Fingerprint: 14:f1:08:ad:9d:fa:64:e2:89:e7:1c:cf:a8:ad:7d:5e +# SHA1 Fingerprint: 39:21:c1:15:c1:5d:0e:ca:5c:cb:5b:c4:f0:7d:21:d8:05:0b:56:6a +# SHA256 Fingerprint: 77:40:73:12:c6:3a:15:3d:5b:c0:0b:4e:51:75:9c:df:da:c2:37:dc:2a:33:b6:79:46:e9:8e:9b:fa:68:0a:e3 +-----BEGIN CERTIFICATE----- +MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP +bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 +MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft +ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk +hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym +1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW +OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb +2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko +O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU +AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF +Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb +LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir +oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C +MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds +sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 +-----END CERTIFICATE----- + +# Issuer: CN=America Online Root Certification Authority 2 O=America Online Inc. +# Subject: CN=America Online Root Certification Authority 2 O=America Online Inc. +# Label: "America Online Root Certification Authority 2" +# Serial: 1 +# MD5 Fingerprint: d6:ed:3c:ca:e2:66:0f:af:10:43:0d:77:9b:04:09:bf +# SHA1 Fingerprint: 85:b5:ff:67:9b:0c:79:96:1f:c8:6e:44:22:00:46:13:db:17:92:84 +# SHA256 Fingerprint: 7d:3b:46:5a:60:14:e5:26:c0:af:fc:ee:21:27:d2:31:17:27:ad:81:1c:26:84:2d:00:6a:f3:73:06:cc:80:bd +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc +MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP +bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 +MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft +ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC +206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci +KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 +JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 +BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e +Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B +PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 +Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq +Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ +o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 ++L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj +FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn +xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 +LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc +obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 +CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe +IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA +DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F +AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX +Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb +AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl +Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw +RY8mkaKO/qk= +-----END CERTIFICATE----- + +# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Label: "Visa eCommerce Root" +# Serial: 25952180776285836048024890241505565794 +# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 +# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 +# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum CA O=Unizeto Sp. z o.o. +# Subject: CN=Certum CA O=Unizeto Sp. z o.o. +# Label: "Certum Root CA" +# Serial: 65568 +# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9 +# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18 +# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24 +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM +MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD +QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E +jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo +ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI +ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu +Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg +AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 +HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA +uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa +TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg +xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q +CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x +O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs +6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=Secure Certificate Services O=Comodo CA Limited +# Subject: CN=Secure Certificate Services O=Comodo CA Limited +# Label: "Comodo Secure Services root" +# Serial: 1 +# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd +# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1 +# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8 +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp +ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow +fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV +BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM +cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S +HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 +CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk +3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz +6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV +HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud +EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv +Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw +Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww +DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 +5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI +gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ +aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl +izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= +-----END CERTIFICATE----- + +# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited +# Subject: CN=Trusted Certificate Services O=Comodo CA Limited +# Label: "Comodo Trusted Services root" +# Serial: 1 +# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27 +# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd +# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 +aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla +MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD +VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW +fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt +TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL +fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW +1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 +kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G +A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v +ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo +dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu +Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ +HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS +jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ +xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn +dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA" +# Serial: 10000010 +# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0 +# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04 +# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3 +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO +TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy +MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk +ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn +ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 +9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO +hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U +tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o +BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh +SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww +OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv +cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA +7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k +/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm +eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 +u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy +7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +# Issuer: O=TDC Internet OU=TDC Internet Root CA +# Subject: O=TDC Internet OU=TDC Internet Root CA +# Label: "TDC Internet Root CA" +# Serial: 986490188 +# MD5 Fingerprint: 91:f4:03:55:20:a1:f8:63:2c:62:de:ac:fb:61:1c:8e +# SHA1 Fingerprint: 21:fc:bd:8e:7f:6c:af:05:1b:d1:b3:43:ec:a8:e7:61:47:f2:0f:8a +# SHA256 Fingerprint: 48:98:c6:88:8c:0c:ff:b0:d3:e3:1a:ca:8a:37:d4:e3:51:5f:f7:46:d0:26:35:d8:66:46:cf:a0:a3:18:5a:e7 +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE +SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg +Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV +BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl +cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA +vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu +Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a +0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1 +4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN +eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD +R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG +A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu +dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME +Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3 +WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw +HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ +KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO +Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX +wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ +2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89 +9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0 +jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38 +aQNiuJkFBT1reBK9sG9l +-----END CERTIFICATE----- + +# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com +# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com +# Label: "UTN DATACorp SGC Root CA" +# Serial: 91374294542884689855167577680241077609 +# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06 +# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4 +# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48 +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB +kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw +IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG +EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD +VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu +dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 +E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ +D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK +4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq +lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW +bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB +o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT +MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js +LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr +BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB +AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj +j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH +KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv +2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 +mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- + +# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com +# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com +# Label: "UTN USERFirst Hardware Root CA" +# Serial: 91374294542884704022267039221184531197 +# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39 +# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7 +# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37 +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB +lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug +Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt +SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe +MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v +d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh +cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn +0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ +M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a +MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd +oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI +DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy +oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 +dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy +bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF +BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli +CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE +CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t +3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS +KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org +# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org +# Label: "Camerfirma Chambers of Commerce Root" +# Serial: 0 +# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84 +# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1 +# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3 +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg +b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa +MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB +ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw +IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B +AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb +unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d +BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq +7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 +0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX +roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG +A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j +aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p +26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA +BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud +EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN +BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB +AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd +p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi +1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc +XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 +eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu +tGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org +# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org +# Label: "Camerfirma Global Chambersign Root" +# Serial: 0 +# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19 +# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9 +# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn +MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL +ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo +YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 +MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy +NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G +A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA +A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 +Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s +QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV +eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 +B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh +z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T +AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i +ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w +TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH +MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD +VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE +VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B +AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM +bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi +ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG +VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c +ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ +AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Label: "NetLock Notary (Class A) Root" +# Serial: 259 +# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7 +# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6 +# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67 +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV +MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe +TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 +dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 +N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC +dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu +MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL +b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD +zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi +3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 +WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY +Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi +NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC +ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 +QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 +YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz +aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm +ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg +ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs +amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv +IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 +Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 +ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 +YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg +dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs +b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G +CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO +xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP +0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ +QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk +f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK +8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Subject: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Label: "NetLock Business (Class B) Root" +# Serial: 105 +# MD5 Fingerprint: 39:16:aa:b9:6a:41:e1:14:69:df:9e:6c:3b:72:dc:b6 +# SHA1 Fingerprint: 87:9f:4b:ee:05:df:98:58:3b:e3:60:d6:33:e7:0d:3f:fe:98:71:af +# SHA256 Fingerprint: 39:df:7b:68:2b:7b:93:8f:84:71:54:81:cc:de:8d:60:d8:f2:2e:c5:98:87:7d:0a:aa:c1:2b:59:18:2b:03:12 +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD +EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05 +OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G +A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh +Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l +dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG +SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK +gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX +iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc +Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E +BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G +SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu +b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh +bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv +Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln +aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0 +IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph +biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo +ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP +UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj +YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA +bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06 +sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa +n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS +NitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Subject: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok +# Label: "NetLock Express (Class C) Root" +# Serial: 104 +# MD5 Fingerprint: 4f:eb:f1:f0:70:c2:80:63:5d:58:9f:da:12:3c:a9:c4 +# SHA1 Fingerprint: e3:92:51:2f:0a:cf:f5:05:df:f6:de:06:7f:75:37:e1:65:ea:57:4b +# SHA256 Fingerprint: 0b:5e:ed:4e:84:64:03:cf:55:e0:65:84:84:40:ed:2a:82:75:8b:f5:b9:aa:1f:25:3d:46:13:cf:a0:80:ff:3f +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx +ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 +b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD +EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X +DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw +DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u +c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr +TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA +OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC +2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW +RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P +AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW +ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0 +YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz +b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO +ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB +IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs +b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s +YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg +a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g +SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0 +aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg +YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg +Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY +ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g +pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4 +Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing +# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing +# Label: "StartCom Certification Authority" +# Serial: 1 +# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16 +# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f +# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j +ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js +LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM +BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy +dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh +cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh +YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg +dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp +bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ +YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT +TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ +9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 +jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW +FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz +ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 +ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L +EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu +L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC +O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V +um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh +NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= +-----END CERTIFICATE----- + +# Issuer: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Firmaprofesional Root CA" +# Serial: 1 +# MD5 Fingerprint: 11:92:79:40:3c:b1:83:40:e5:ab:66:4a:67:92:80:df +# SHA1 Fingerprint: a9:62:8f:4b:98:a9:1b:48:35:ba:d2:c1:46:32:86:bb:66:64:6a:8c +# SHA256 Fingerprint: c1:cf:0b:52:09:64:35:e3:f1:b7:1d:aa:ec:45:5a:23:11:c8:40:4f:55:83:a9:e2:13:c6:9d:85:7d:94:33:05 +-----BEGIN CERTIFICATE----- +MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx +IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w +HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx +IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 +dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u +Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY +rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z +hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay +BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL +iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb +AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv +bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0 +MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E +FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n +VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq +u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m +hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl +ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp +QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5 +quGnM/b9Sh/22WA= +-----END CERTIFICATE----- + +# Issuer: CN=Wells Fargo Root Certificate Authority O=Wells Fargo OU=Wells Fargo Certification Authority +# Subject: CN=Wells Fargo Root Certificate Authority O=Wells Fargo OU=Wells Fargo Certification Authority +# Label: "Wells Fargo Root CA" +# Serial: 971282334 +# MD5 Fingerprint: 20:0b:4a:7a:88:a7:a9:42:86:8a:5f:74:56:7b:88:05 +# SHA1 Fingerprint: 93:e6:ab:22:03:03:b5:23:28:dc:da:56:9e:ba:e4:d1:d1:cc:fb:65 +# SHA256 Fingerprint: 03:45:8b:6a:be:ec:c2:14:95:3d:97:14:9a:f4:53:91:69:1d:e9:f9:cd:cc:26:47:86:3a:3d:67:c9:5c:24:3b +-----BEGIN CERTIFICATE----- +MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC +VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0 +MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww +KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G +A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13 +5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE +SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O +JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu +ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE +AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB +AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB +CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw +b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo +7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/ +0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7 +nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx +x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ +33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= +-----END CERTIFICATE----- + +# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services +# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services +# Label: "Swisscom Root CA 1" +# Serial: 122348795730808398873664200247279986742 +# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9 +# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51 +# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e +-----BEGIN CERTIFICATE----- +MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk +MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 +YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg +Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT +AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp +Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 +m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih +FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ +TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F +EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco +kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu +HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF +vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo +19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC +L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW +bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX +JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw +FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j +BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc +K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf +ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik +Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB +sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e +3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR +ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip +mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH +b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf +rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms +hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y +zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 +MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=Class 2 Primary CA O=Certplus +# Subject: CN=Class 2 Primary CA O=Certplus +# Label: "Certplus Class 2 Primary CA" +# Serial: 177770208045934040241468760488327595043 +# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b +# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb +# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES +# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES +# Label: "DST ACES CA X6" +# Serial: 17771143917277623872238992636097467865 +# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8 +# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d +# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40 +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx +ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w +MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD +VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx +FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu +ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 +gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH +fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a +ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT +ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk +c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto +dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt +aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI +hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk +QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ +h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR +rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 +9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=(c) 2005 TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=(c) 2005 TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Label: "TURKTRUST Certificate Services Provider Root 1" +# Serial: 1 +# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5 +# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9 +# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0 +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg +MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz +MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy +dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD +VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg +xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu +xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 +XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k +heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J +YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C +urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 +JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 +b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV +9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 +kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh +fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA +aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS +RGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- + +# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. (c) Kasım 2005 +# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. (c) Kasım 2005 +# Label: "TURKTRUST Certificate Services Provider Root 2" +# Serial: 1 +# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00 +# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7 +# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6 +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc +UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS +S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg +SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 +WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv +bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU +UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw +bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe +LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef +J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh +R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ +Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX +JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p +zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S +Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ +KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq +ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz +gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH +uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS +y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln +biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF +MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT +d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 +76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ +bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c +6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE +emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd +MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt +MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y +MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y +FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi +aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM +gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB +qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 +lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn +8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov +L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 +45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO +UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 +O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC +bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv +GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a +77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC +hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 +92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp +Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w +ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt +Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA +# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA +# Label: "WellsSecure Public Root Certificate Authority" +# Serial: 1 +# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36 +# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee +# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43 +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx +IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs +cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v +dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0 +MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl +bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD +DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r +WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU +Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs +HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj +z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf +SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl +AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG +KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P +AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j +BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC +VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX +ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB +ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd +/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB +A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn +k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9 +iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv +2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=IGC/A O=PM/SGDN OU=DCSSI +# Subject: CN=IGC/A O=PM/SGDN OU=DCSSI +# Label: "IGC/A" +# Serial: 245102874772 +# MD5 Fingerprint: 0c:7f:dd:6a:f4:2a:b9:c8:9b:bd:20:7e:a9:db:5c:37 +# SHA1 Fingerprint: 60:d6:89:74:b5:c2:65:9e:8a:0f:c1:88:7c:88:d2:46:69:1b:18:2c +# SHA256 Fingerprint: b9:be:a7:86:0a:96:2e:a3:61:1d:ab:97:ab:6d:a3:e2:1c:10:68:b9:7d:55:57:5e:d0:e1:12:79:c1:1c:89:32 +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT +AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ +TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG +9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw +MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM +BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO +MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2 +LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI +s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2 +xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4 +u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b +F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx +Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd +PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV +HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx +NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF +AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ +L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY +YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a +NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R +0982gaEbeC9xs/FZTEYYKKuF0mBWWg== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1 +# Label: "Security Communication EV RootCA1" +# Serial: 0 +# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3 +# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d +# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37 +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz +MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N +IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11 +bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE +RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO +zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5 +bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF +MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1 +VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC +OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G +CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW +tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ +q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb +EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+ +Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O +VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA +# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA +# Label: "Microsec e-Szigno Root CA" +# Serial: 272122594155480254301341951808045322001 +# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5 +# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d +# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0 +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw +cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy +b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z +ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4 +NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN +TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p +Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u +uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+ +LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA +vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770 +Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx +62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB +AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw +LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP +BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB +AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov +MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5 +ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT +AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh +ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo +AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa +AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln +bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p +Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP +PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv +Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB +EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu +w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj +cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV +HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI +VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS +BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS +b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS +8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds +ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl +7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR +hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/ +MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: CN=AC RaÃz Certicámara S.A. O=Sociedad Cameral de Certificación Digital - Certicámara S.A. +# Subject: CN=AC RaÃz Certicámara S.A. O=Sociedad Cameral de Certificación Digital - Certicámara S.A. +# Label: "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A." +# Serial: 38908203973182606954752843738508300 +# MD5 Fingerprint: 93:2a:3e:f6:fd:23:69:0d:71:20:d4:2b:47:99:2b:a6 +# SHA1 Fingerprint: cb:a1:c5:f8:b0:e3:5e:b8:b9:45:12:d3:f9:34:a2:e9:06:10:d3:36 +# SHA256 Fingerprint: a6:c5:1e:0d:a5:ca:0a:93:09:d2:e4:c0:e4:0c:2a:f9:10:7a:ae:82:03:85:7f:e1:98:e3:e7:69:e3:43:08:5c +-----BEGIN CERTIFICATE----- +MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx +CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp +ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa +QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw +NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft +ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu +QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG +qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL +fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ +Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4 +Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ +54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b +MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j +ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej +YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt +A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF +rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ +pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB +lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy +YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50 +7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs +YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6 +xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc +unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/ +Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp +ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42 +gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0 +jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+ +XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD +W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/ +RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r +MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk +BYn8eNZcLCZDqQ== +-----END CERTIFICATE----- + +# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA +# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA +# Label: "TC TrustCenter Class 2 CA II" +# Serial: 941389028203453866782103406992443 +# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23 +# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e +# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4 +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV +BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 +Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 +OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i +SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc +VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf +tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg +uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J +XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK +8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 +5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 +kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy +dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 +Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz +JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 +Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS +GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt +ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 +au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV +hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI +dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== +-----END CERTIFICATE----- + +# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA +# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA +# Label: "TC TrustCenter Class 3 CA II" +# Serial: 1506523511417715638772220530020799 +# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e +# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5 +# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV +BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 +Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 +OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i +SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc +VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW +Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q +Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 +1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq +ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 +Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX +XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy +dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 +Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz +JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 +Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN +irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 +TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 +g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB +95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj +S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== +-----END CERTIFICATE----- + +# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA +# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA +# Label: "TC TrustCenter Universal CA I" +# Serial: 601024842042189035295619584734726 +# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c +# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3 +# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV +BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 +c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx +MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg +R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD +VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR +JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T +fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu +jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z +wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ +fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD +VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G +CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 +7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn +8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs +ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT +ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ +2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY +-----END CERTIFICATE----- + +# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Label: "Deutsche Telekom Root CA 2" +# Serial: 38 +# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 +# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf +# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +# Issuer: CN=ComSign Secured CA O=ComSign +# Subject: CN=ComSign Secured CA O=ComSign +# Label: "ComSign Secured CA" +# Serial: 264725503855295744117309814499492384489 +# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5 +# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a +# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2 +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw +PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu +MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx +GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL +MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf +HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh +gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW +v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue +Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr +9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt +6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 +MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl +Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 +ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq +hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p +iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC +dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL +kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL +hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: CN=TÃœBÄ°TAK UEKAE Kök Sertifika Hizmet SaÄŸlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik AraÅŸtırma Kurumu - TÃœBÄ°TAK OU=Ulusal Elektronik ve Kriptoloji AraÅŸtırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi +# Subject: CN=TÃœBÄ°TAK UEKAE Kök Sertifika Hizmet SaÄŸlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik AraÅŸtırma Kurumu - TÃœBÄ°TAK OU=Ulusal Elektronik ve Kriptoloji AraÅŸtırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi +# Label: "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3" +# Serial: 17 +# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26 +# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96 +# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS +MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp +bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw +VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy +YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy +dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2 +ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe +Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx +GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls +aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU +QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh +xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0 +aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr +IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h +gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK +O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO +fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw +lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID +AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP +NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t +wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM +7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh +gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n +oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs +yZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327 +# Label: "Buypass Class 2 CA 1" +# Serial: 1 +# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23 +# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc +# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38 +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg +Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL +MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD +VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0 +ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX +l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB +HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B +5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3 +WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP +gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+ +DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu +BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs +h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk +LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 +# Label: "Buypass Class 3 CA 1" +# Serial: 2 +# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b +# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71 +# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24 +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg +Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL +MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD +VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg +isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z +NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI ++MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R +hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+ +mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP +Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s +EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2 +mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC +e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow +dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 +-----END CERTIFICATE----- + +# Issuer: CN=EBG Elektronik Sertifika Hizmet SaÄŸlayıcısı O=EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. +# Subject: CN=EBG Elektronik Sertifika Hizmet SaÄŸlayıcısı O=EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. +# Label: "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1" +# Serial: 5525761995591021570 +# MD5 Fingerprint: 2c:20:26:9d:cb:1a:4a:00:85:b5:b7:5a:ae:c2:01:37 +# SHA1 Fingerprint: 8c:96:ba:eb:dd:2b:07:07:48:ee:30:32:66:a0:f3:98:6e:7c:ae:58 +# SHA256 Fingerprint: 35:ae:5b:dd:d8:f7:ae:63:5c:ff:ba:56:82:a8:f0:0b:95:f4:84:62:c7:10:8e:e9:a0:e5:29:2b:07:4a:af:b2 +-----BEGIN CERTIFICATE----- +MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV +BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx +c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt +ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4 +MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl +a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h +4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk +tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s +tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL +dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4 +c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um +TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z ++kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O +Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW +OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW +fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2 +l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw +FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+ +8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI +6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO +TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME +wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY +Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn +xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q +DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q +Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t +hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4 +7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7 +QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=CNNIC ROOT O=CNNIC +# Subject: CN=CNNIC ROOT O=CNNIC +# Label: "CNNIC ROOT" +# Serial: 1228079105 +# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19 +# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f +# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7 +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD +TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2 +MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF +Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh +IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6 +dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO +V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC +GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN +v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB +AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB +Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO +76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK +OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH +ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi +yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL +buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj +2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE= +-----END CERTIFICATE----- + +# Issuer: O=Japanese Government OU=ApplicationCA +# Subject: O=Japanese Government OU=ApplicationCA +# Label: "ApplicationCA - Japanese Government" +# Serial: 49 +# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6 +# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74 +# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19 +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc +MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp +b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT +AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs +aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H +j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K +f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55 +IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw +FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht +QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm +/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ +k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ +MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC +seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ +hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+ +eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U +DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj +B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) FÅ‘tanúsÃtvány O=NetLock Kft. OU=TanúsÃtványkiadók (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) FÅ‘tanúsÃtvány O=NetLock Kft. OU=TanúsÃtványkiadók (Certification Services) +# Label: "NetLock Arany (Class Gold) FÅ‘tanúsÃtvány" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G2" +# Serial: 10000012 +# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a +# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 +# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig O=Disig a.s. +# Subject: CN=CA Disig O=Disig a.s. +# Label: "CA Disig" +# Serial: 1 +# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6 +# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41 +# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET +MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE +AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw +CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg +YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE +Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX +mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD +XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW +S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp +FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD +AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu +ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z +ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv +Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw +DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6 +yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq +EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB +EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN +PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +# Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus +# Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus +# Label: "Juur-SK" +# Serial: 999181308 +# MD5 Fingerprint: aa:8e:5d:d9:f8:db:0a:58:b7:8d:26:87:6c:82:35:55 +# SHA1 Fingerprint: 40:9d:4b:d9:17:b5:5c:27:b6:9b:64:cb:98:22:44:0d:cd:09:b8:89 +# SHA256 Fingerprint: ec:c3:e9:c3:40:75:03:be:e0:91:aa:95:2f:41:34:8f:f8:8b:aa:86:3b:22:64:be:fa:c8:07:90:15:74:e9:39 +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN +AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp +dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw +MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw +CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ +MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB +SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz +ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH +LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP +PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL +2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w +ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC +MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk +AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0 +AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz +AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz +AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f +BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY +P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi +CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g +kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95 +HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS +na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q +qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z +TbvGRNs2yyqcjg== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI +# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI +# Label: "ACEDICOM Root" +# Serial: 7029493972724711941 +# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6 +# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84 +# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a +-----BEGIN CERTIFICATE----- +MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE +AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x +CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW +MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF +RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC +AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7 +09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7 +XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P +Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK +t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb +X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28 +MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU +fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI +2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH +K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae +ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP +BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw +RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv +bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm +fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3 +gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe +I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i +5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi +ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn +MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ +o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6 +zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN +GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt +r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK +Z05phkOTOPu220+DkdRgfks+KzgHVZhepA== +-----END CERTIFICATE----- + +# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority +# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority +# Label: "Verisign Class 3 Public Primary Certification Authority" +# Serial: 80507572722862485515306429940691309246 +# MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4 +# SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b +# SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05 +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz +cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 +MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV +BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE +BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is +I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G +CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i +2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ +2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. +# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. +# Label: "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" +# Serial: 91184789765598910059173000485363494069 +# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b +# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34 +# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98 +-----BEGIN CERTIFICATE----- +MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp +Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp +a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx +MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg +R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg +U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU +MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT +L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H +5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC +90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1 +c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE +VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP +qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S +/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj +/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X +KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq +fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA +# Subject: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA +# Label: "TC TrustCenter Universal CA III" +# Serial: 2010889993983507346460533407902964 +# MD5 Fingerprint: 9f:dd:db:ab:ff:8e:ff:45:21:5f:f0:6c:9d:8f:fe:2b +# SHA1 Fingerprint: 96:56:cd:7b:57:96:98:95:d0:e1:41:46:68:06:fb:b8:c6:11:06:87 +# SHA256 Fingerprint: 30:9b:4a:87:f6:ca:56:c9:31:69:aa:a9:9c:6d:98:88:54:d7:89:2b:d5:43:7e:2d:07:b2:9c:be:da:55:d3:5d +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL +MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV +BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1 +c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy +MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl +ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm +BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF +5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv +DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v +zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT +yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj +dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh +MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI +4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz +dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY +aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G +DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV +CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH +LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Autorité Racine" +# Serial: 1 +# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a +# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3 +# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17 +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk +BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4 +Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl +cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0 +aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY +F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N +8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe +rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K +/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu +7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC +28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6 +lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E +nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB +0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09 +5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj +WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN +jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s +ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM +OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q +619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn +2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj +o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v +nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG +5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq +pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb +dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0 +BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA +# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA +# Label: "Root CA Generalitat Valenciana" +# Serial: 994436456 +# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2 +# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46 +# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF +UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ +R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN +MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw +JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+ +WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj +SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl +u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy +A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk +Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7 +MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr +aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC +IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A +cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA +YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA +bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA +bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA +aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA +ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA +YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA +ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA +LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6 +Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y +eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw +CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G +A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu +Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn +lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt +b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg +9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF +ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC +IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 +# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 +# Label: "A-Trust-nQual-03" +# Serial: 93214 +# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53 +# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2 +# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb +-----BEGIN CERTIFICATE----- +MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB +VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp +bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R +dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw +MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy +dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52 +ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM +EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj +lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ +znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH +2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1 +k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs +2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD +VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG +KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+ +8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R +FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS +mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE +DNuxUCAKGkq6ahq97BvIxYSazQ== +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing +# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing +# Label: "StartCom Certification Authority" +# Serial: 45 +# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16 +# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0 +# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11 +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg +Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk +pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf +OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C +Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT +Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi +HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM +Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w ++2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ +Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 +Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B +26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID +AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul +F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC +ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w +ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk +aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 +YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg +c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 +d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG +CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF +wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS +Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst +0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc +pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl +CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF +P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK +1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm +KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ +8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm +fyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd. +# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd. +# Label: "StartCom Certification Authority G2" +# Serial: 59 +# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64 +# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17 +# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95 +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW +MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 +OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG +A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ +JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD +vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo +D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ +Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW +RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK +HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN +nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM +0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i +UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 +Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg +TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL +BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX +UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl +6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK +9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ +HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI +wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY +XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l +IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo +hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr +so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..9fc9faf --- /dev/null +++ b/configure.ac @@ -0,0 +1,604 @@ +AC_INIT([tlsdate],[0.0.13],[jacob at appelbaum.net]) +AC_CONFIG_AUX_DIR([config]) +AC_CONFIG_MACRO_DIR([m4]) + +AC_CANONICAL_TARGET +AC_ARG_PROGRAM +AC_USE_SYSTEM_EXTENSIONS + +AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability subdir-objects foreign tar-ustar]) + +AC_PREREQ([2.63]) + +AC_CONFIG_HEADERS([config.h:config.in])dnl Keep filename to 8.3 for MS-DOS. + +PKG_PROG_PKG_CONFIG +LT_PREREQ([2.2]) +LT_INIT +LT_LANG([C]) +gl_VISIBILITY +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +CONFIG_EXTRA +AX_PLATFORM + +dnl Here we should build a small program to fetch the build system time in a portable +dnl manner. We have no Win32 users, we can fix this if we ever find one that +dnl cares. +dnl +dnl In Debian GNU/Linux and other Debian GNU/* systems, we wish to make this a +dnl deterministic build process. There is only one part of the build process that +dnl is entropic and that is this COMPILE_DATE value. We want to check to see if +dnl COMPILE_DATE is defined by the debian/rules file and if it is - we want to use +dnl the value provided by the environment. If it isn't we'll use one that we +dnl generate here. +dnl +echo "checking for \$COMPILE_DATE in the environment..." +if test "${COMPILE_DATE+set}" = set; then + echo "...we've found \$COMPILE_DATE in the environment." + echo "...\$COMPILE_DATE is set to: $COMPILE_DATE" +else + echo "...no \$COMPILE_DATE found in our build environment. Generating now..." + COMPILE_DATE=`date +%s` + echo "...\$COMPILE_DATE is set to: $COMPILE_DATE" +fi + +AC_SUBST([COMPILE_DATE]) +AC_DEFINE_UNQUOTED([RECENT_COMPILE_DATE], + [${COMPILE_DATE}L], + [Time in seconds since the Disco epoch at build time]) + +dnl Build up the directory we will use to install certs +TLSDATE_CA_ROOTS="${sysconfdir}/$PACKAGE_NAME/ca-roots" +AC_SUBST([TLSDATE_CA_ROOTS]) + +dnl Place we install our config file +TLSDATE_CONF_DIR="${sysconfdir}/$PACKAGE_NAME/" +AC_SUBST([TLSDATE_CONF_DIR]) + +dnl HTTPS User-agent +AC_ARG_WITH([https-user-agent], + [AS_HELP_STRING([--with-https-user-agent=AGENT], + [a User-Agent value to send when running in HTTPS mode])], + [], + [with_https_user_agent="TLSDate/$VERSION"]) +AC_DEFINE_UNQUOTED([HTTPS_USER_AGENT], + ["${with_https_user_agent}"], + [User-Agent value to send when running as an HTTPS client]) + +dnl check for PolarSSL +OPT_POLARSSL=yes + +AC_MSG_CHECKING([PolarSSL]) +AC_ARG_WITH([polarssl], + [AS_HELP_STRING([--with-polarssl=DIR], + [where to look for PolarSSL, DIR points to the installation root])]) + +AS_CASE([$with_polarssl], + [""|yes|no], [POLARSSL_DIR=""], + [*], [POLARSSL_DIR=$with_polarssl]) +OPT_POLARSSL=$with_polarssl + +SSL_FLAGS="" +SSL_LDFLAGS="" +SSL_LIBS="-lssl -lcrypto" + +AS_IF([test "x${OPT_POLARSSL}" != "xno"], [ + AS_IF([test -z "${POLARSSL_DIR}"], [ + dnl check for lib first without setting any new path + AC_CHECK_LIB(polarssl, ssl_init, + dnl libpolarssl found, set the variable + [ + AC_DEFINE(USE_POLARSSL, 1, [if PolarSSL is enabled]) + AC_SUBST(USE_POLARSSL, [1]) + POLARSSL_ENABLED=1 + USE_POLARSSL="yes" + ]) + ]) + + addld="" + addlib="" + addcflags="" + polarssllib="" + + AS_IF([test "x${USE_POLARSSL}" != "xyes"], [ + dnl add the path and test again + addld=-L${POLARSSL_DIR}/lib$libsuff + addcflags=-I${POLARSSL_DIR}/include + polarssllib=${POLARSSL_DIR}/lib$libsuff + + LDFLAGS="$LDFLAGS $addld" + AS_IF([test "$addcflags" != "-I/usr/include"], [ + AX_APPEND_COMPILE_FLAGS(["$addcflags"]) + CPPFLAGS="$CPPFLAGS $addcflags" + ]) + + AC_CHECK_LIB(polarssl, ssl_init, + [ + AC_DEFINE(USE_POLARSSL, 1, [if PolarSSL is enabled]) + AC_SUBST(USE_POLARSSL, [1]) + POLARSSL_ENABLED=1 + USE_POLARSSL="yes" + SSL_CFLAGS=$addcflags + SSL_LDFLAGS=$addld + ]) + ]) + + AS_IF([test "x${USE_POLARSSL}" = "xyes"], [ + AC_MSG_NOTICE([detected PolarSSL]) + SSL_LIBS="-lpolarssl" + + AS_IF([test -n "$polarssllib"], [ + dnl when shared libs were found in a path that the run-time + dnl linker doesn't search through, we need to add it to + dnl LD_LIBRARY_PATH to prevent further configure tests to fail + dnl due to this + AS_IF([test "x$cross_compiling" != "xyes"], [ + LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$polarssllib" + export LD_LIBRARY_PATH + AC_MSG_NOTICE([Added $polarssllib to LD_LIBRARY_PATH]) + ]) + ]) + ]) +]) +AC_SUBST(SSL_CFLAGS) +AC_SUBST(SSL_LDFLAGS) +AC_SUBST(SSL_LIBS) +AM_CONDITIONAL(POLARSSL, test "x${USE_POLARSSL}" = "xyes") + +dnl Required headers +AS_IF([test "x${USE_POLARSSL}" != "xyes"], [ + dnl First check to see if openssl is installed + AC_CHECK_HEADERS([openssl/ssl.h], ,[AC_MSG_ERROR([OpenSSL is not installed, openssl/sslh is missing])]) + AC_CHECK_HEADERS([openssl/bio.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) + AC_CHECK_HEADERS([openssl/err.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) + AC_CHECK_HEADERS([openssl/evp.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +]) + +AC_CHECK_HEADERS([arpa/inet.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([getopt.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([grp.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([pwd.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([stdint.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([stdio.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([stdlib.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([sys/mman.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([sys/socket.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([sys/time.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([sys/types.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([sys/wait.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([time.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) +AC_CHECK_HEADERS([unistd.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) + +AC_CHECK_HEADERS([linux/rtc.h]) +AC_CHECK_TYPES([struct rtc_time], [], [], [ +#ifdef HAVE_LINUX_RTC_H +#include <linux/rtc.h> +#endif +]) + +AC_CHECK_FUNCS([strchrnul]) +AM_CONDITIONAL(HAVE_STRCHRNUL, [test "x${ac_cv_func_strchrnul}" = xyes]) + +AC_CHECK_FUNCS([strnlen]) +AM_CONDITIONAL(HAVE_STRNLEN, [test "x${ac_cv_func_strnlen}" = xyes]) + +AC_CHECK_FUNCS_ONCE(m4_flatten([ + gettimeofday + prctl + preadv + pwritev + setresuid +])) + +AC_CHECK_FUNCS([fmemopen funopen]) +AM_CONDITIONAL(HAVE_FMEMOPEN, [test "x${ac_cv_func_fmemopen}" = xyes]) +AM_CONDITIONAL(HAVE_FUNOPEN, [test "x${ac_cv_func_funopen}" = xyes]) + +case "$host" in + *-darwin*) + dnl This is for Mac OS X (10.8.2) + AC_CHECK_HEADERS([mach/clock.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) + AC_CHECK_HEADERS([mach/mach.h], ,[AC_MSG_ERROR([Required headers missing; compilation will not succeed])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-freebsd*) + dnl This is for FreeBSD + dnl clock_gettime is either part of libc or unavailable. + AC_CHECK_FUNC([clock_gettime], , + [AC_MSG_ERROR([Your system lacks clock_gettime])]) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_WARN([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *kfreebsd*-gnu*) + dnl This is for Debian GNU/kFreeBSD + dnl clock_gettime is either part of libc or unavailable. + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_ERROR([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-netbsd*) + dnl This is for NetBSD + dnl clock_gettime is either part of libc or unavailable. + AC_CHECK_FUNC([clock_gettime], , + [AC_MSG_ERROR([Your system lacks clock_gettime])]) + if test "x${ac_cv_func_fmemopen}" != xyes; then + if test "x${ac_cv_func_funopen}" != xyes; then + AC_MSG_ERROR([We need fmemopen or funopen for unit tests.]) + fi + fi + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-openbsd*) + dnl This is for OpenBSD + dnl clock_gettime is either part of libc or unavailable. + AC_CHECK_FUNC([clock_gettime], , + [AC_MSG_ERROR([Your system lacks clock_gettime])]) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_WARN([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *dragonfly*) + dnl This is for DragonFly BSD + dnl clock_gettime is either part of libc or unavailable. + AC_CHECK_FUNC([clock_gettime], , + [AC_MSG_ERROR([Your system lacks clock_gettime])]) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_WARN([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-bsd*) + dnl This is a generic catch for BSD variants + dnl This likely needs to be tuned to catch all + dnl clock_gettime is either part of libc or unavailable. + AC_CHECK_FUNC([clock_gettime], , + [AC_MSG_ERROR([Your system lacks clock_gettime])]) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_ERROR([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nobody"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-linux*) + dnl This is for GNU/Linux + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + case "$host" in + *-linux-androideabi) + dnl This is for Android NDK as it is a special case of linux + AC_DEFINE(HAVE_ANDROID,1, [Defined if we are to build for an Android system]) + AC_SUBST(HAVE_ANDROID, [1]) + HAVE_ANDROID="yes" + ;; + esac + ;; + *-gnu0.*) + dnl This is a generic catch for GNU/Hurd variants + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + dnl If the autoconf goo picks up a compiler that runs in pre-POSIX mode, + dnl the fmemopen prototype is hidden causing the unit tests to segfault. + dnl This can happen if gcc is a symlink to gcc46 and is preferred to clang. + AC_CHECK_FUNC([fmemopen], , + [AC_MSG_ERROR([Missing fmemopen, unit tests are likely to segfault. Try CC=clang.])]) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nobody@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-cygwin*) + dnl This is for Cygwin + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-mingw32*) + dnl This is for MINGW32_NT + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; + *-beos*|*-haiku*) + dnl This is for BeOS and Haiku; we probably only support Haiku with gcc4 + dnl Check for clock_gettime. Some systems put it into -lc, while + dnl others use -lrt. Try the first and fallback to the latter. + dnl on Haiku we require the bsd library for strsep + RT_LIB= + AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) + AC_SUBST(RT_LIB) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + LDFLAGS="$LDFLAGS -lbsd" + CC="/boot/develop/abi/x86/gcc4/tools/gcc-4.6.3-haiku-121101/bin/gcc" + ;; + *) + AC_ARG_WITH([unpriv-group], + [AS_HELP_STRING([--with-unpriv-group=<group>], + [Group to drop privs to @<:@default: nogroup@:>@])]) + AS_CASE([$with_unpriv_group], + [""|yes|no], [UNPRIV_GROUP="nogroup"], + [*], [UNPRIV_GROUP=$with_unpriv_group]) + AC_DEFINE_UNQUOTED([UNPRIV_GROUP], ["${UNPRIV_GROUP}"], [Unprivileged group]) + ;; +esac + +dnl Android conditional +AM_CONDITIONAL(HAVE_ANDROID, test "x${HAVE_ANDROID}" = "xyes") + +AC_MSG_CHECKING([user/group to drop privs to]) + +AC_ARG_WITH([unpriv-user], + [AS_HELP_STRING([--with-unpriv-user=<user>], + [User to drop privs to @<:@default: nobody@:>@])]) +AS_CASE([$with_unpriv_user], + [""|yes|no], [UNPRIV_USER="nobody"], + [*], [UNPRIV_USER=$with_unpriv_user]) +AC_DEFINE_UNQUOTED([UNPRIV_USER], ["${UNPRIV_USER}"], [Unprivileged user]) +AC_SUBST([UNPRIV_USER]) + +AC_MSG_RESULT(${UNPRIV_USER}:${UNPRIV_GROUP}) + +AC_MSG_CHECKING([group to allow DBus calls from]) +AC_ARG_WITH([dbus-client-group], + [AS_HELP_STRING([--with-dbus-client-group=<group>], + [Allow dbus method calls from group @<:@default: root@:>@])]) +AS_CASE([$with_dbus_client_group], + [""|yes|no], [DBUS_CLIENT_GROUP="root"], + [*], [DBUS_CLIENT_GROUP=$with_dbus_client_group]) +AC_DEFINE_UNQUOTED([DBUS_CLIENT_GROUP], ["${DBUS_CLIENT_GROUP}"], [DBus client group]) +AC_MSG_RESULT(${DBUS_CLIENT_GROUP}) +AC_SUBST([DBUS_CLIENT_GROUP]) + +dnl Check for clock_gettime. Some systems put it into -lc, while +dnl others use -lrt. Try the first and fallback to the latter. +RT_LIB= +AC_CHECK_FUNC([clock_gettime], [:], + [AC_CHECK_LIB([rt], [clock_gettime], [RT_LIB="-lrt"], + [AC_MSG_ERROR([Your system lacks clock_gettime])])]) +AC_SUBST(RT_LIB) + +PKG_CHECK_MODULES([LIBEVENT], [libevent >= 2.0]) + +have_dbus=false +AC_ARG_ENABLE([dbus], + [AS_HELP_STRING([--disable-dbus], + [Disable automatically dbus support])]) +AS_IF([test "x$enable_dbus" = xyes], [ + PKG_CHECK_MODULES([DBUS], [dbus-1], [ + have_dbus=true + AC_DEFINE([HAVE_DBUS], [1], [dbus enabled]) + ], [ + AS_IF([test "x$enable_dbus" = xyes], + [AC_MSG_ERROR([dbus requested but not found])]) + ]) + ]) +AM_CONDITIONAL([HAVE_DBUS], ${have_dbus}) + +AC_SUBST(DBUS_CFLAGS) +AC_SUBST(DBUS_LIBS) +AC_SUBST(LIBEVENT_CFLAGS) +AC_SUBST(LIBEVENT_LIBS) + +have_seccomp_filter=false +AC_ARG_ENABLE([seccomp_filter], + [AS_HELP_STRING([--enable-seccomp-filter], + [Require seccomp filter])]) + +AC_MSG_CHECKING([kernel for seccomp_filter support]) +AS_IF([test "x$enable_seccomp_filter" = xyes], [ + dnl Force seccomp filter use + have_seccomp_filter=true + AC_MSG_RESULT([forced]) + ], [ + AS_IF([test "x$enable_seccomp_filter" = xno], [ + have_seccomp_filter=no + AC_MSG_RESULT([disabled]) + ], [ + dnl Detect seccomp filter support. + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include <errno.h> + #include <linux/audit.h> + #include <linux/filter.h> + #include <stdlib.h> + #include <sys/prctl.h> + #include "src/seccomp-compat.h" + ]], + [[ errno = 0; + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) + exit(1); + prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0); + exit(errno == EFAULT ? 0 : 1); ]])], + [ AC_MSG_RESULT([yes]) + have_seccomp_filter=true + ], [ + AC_MSG_RESULT([no]) + ], + [ AC_MSG_RESULT([cross-compiling, assuming yes]) + have_seccomp_filter=true + ] + ) +])]) + +AS_IF([${have_seccomp_filter}], [ + AC_DEFINE([HAVE_SECCOMP_FILTER], [1], [Enable seccomp filter]) + ]) +AM_CONDITIONAL([HAVE_SECCOMP_FILTER], ${have_seccomp_filter}) + + + +have_seccomp_debug=false +AC_ARG_ENABLE([seccomp_debugging], + [AS_HELP_STRING([--enable-seccomp-debugging], + [Enable seccomp filter debugging])]) +AS_IF([test "x$enable_seccomp_debugging" = xyes], [ + AC_DEFINE([SECCOMP_FILTER_DEBUG], [1], [Enable seccomp filter debugging]) + have_seccomp_debug=true + ]) +AM_CONDITIONAL([SECCOMP_FILTER_DEBUG], ${have_seccomp_debug}) + + +AC_MSG_CHECKING([for CrOS-specific platform wake event support]) +AC_ARG_ENABLE([cros], + [AS_HELP_STRING([--disable-cros], + [Disable CrOS platform support])]) + +AS_IF([test "x$enable_cros" = xyes -a "x$enable_dbus" != xyes ], [ + AC_MSG_ERROR([--enable-dbus is required for --enable-cros]) + ]) + +have_cros=false +AS_IF([test "x$enable_cros" = xyes], [ + have_cros=true + AC_DEFINE([HAVE_CROS], [1], [Enable CrOS support]) + AC_MSG_RESULT([yes]) + ], [ + AC_MSG_RESULT([no]) + ]) +AM_CONDITIONAL([HAVE_CROS], ${have_cros}) + +dnl Debug and hardening flags all in one shot +dnl Always do this at the end, otherwise you end up filtering system/other libraries +AC_ARG_ENABLE([hardened-checks], + [AS_HELP_STRING([--disable-hardened-checks], + [Disable automatically enabling hardened toolchain options])]) +AC_DEFUN([LOCAL_CHECK_FLAGS],[ + AC_REQUIRE([AX_CHECK_LINK_FLAG]) + AC_REQUIRE([AX_APPEND_COMPILE_FLAGS]) + AC_LANG_PUSH([C]) + AS_IF([test "x$enable_hardened_checks" != xno], [ + AX_APPEND_COMPILE_FLAGS([-g -O1]) + ], [ + AC_MSG_WARN([using hardened flags is HIGHLY RECOMMENDED and disabling them is a BAD IDEA]) + ]) + AX_APPEND_COMPILE_FLAGS([-Wall -fno-strict-aliasing]) + AS_IF([test "x$enable_hardened_checks" != xno], [ + AX_APPEND_COMPILE_FLAGS([-D_FORTIFY_SOURCE=2 -fstack-protector-all]) + AX_APPEND_COMPILE_FLAGS([-fwrapv -fPIE -Wstack-protector]) + AX_APPEND_COMPILE_FLAGS([--param=ssp-buffer-size=1]) + AX_CHECK_LINK_FLAG([-z relro -z now]) + AX_CHECK_LINK_FLAG([-pie]) + ]) + AC_LANG_POP + ]) +LOCAL_CHECK_FLAGS + +AC_ARG_ENABLE([code-coverage-checks], + [AS_HELP_STRING([--enable-code-coverage-checks], + [Enable gcov/lcov compile time options])], + [AX_APPEND_COMPILE_FLAGS([-ftest-coverage -fprofile-arcs])]) + +AC_CONFIG_FILES([dbus/org.torproject.tlsdate.conf]) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/dbus/org.torproject.tlsdate.conf.in b/dbus/org.torproject.tlsdate.conf.in new file mode 100644 index 0000000..80c83c1 --- /dev/null +++ b/dbus/org.torproject.tlsdate.conf.in @@ -0,0 +1,31 @@ +<!DOCTYPE busconfig PUBLIC + "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <!-- Only certain user can own the tlsdated service --> + <policy user="@UNPRIV_USER@"> + <allow own="org.torproject.tlsdate"/> + </policy> + + <!-- Allow anyone in the given group to invoke methods --> + <policy group="@DBUS_CLIENT_GROUP@"> + <allow send_destination="org.torproject.tlsdate" + send_interface="org.torproject.tlsdate" + send_member="LastSyncInfo"/> + <allow send_destination="org.torproject.tlsdate" + send_interface="org.torproject.tlsdate" + send_member="SetTime"/> + <allow send_destination="org.torproject.tlsdate" + send_interface="org.torproject.tlsdate" + send_member="CanSetTime"/> + </policy> + + <!-- Disallow anyone to invoke methods on tlsdated interface --> + <policy context="default"> + <deny send_interface="org.torproject.tlsdate" /> + <allow send_destination="org.torproject.tlsdate" + send_interface="org.torproject.tlsdate" + send_member="LastSyncInfo"/> + </policy> +</busconfig> diff --git a/dbus/org.torproject.tlsdate.service b/dbus/org.torproject.tlsdate.service new file mode 100644 index 0000000..36ee56d --- /dev/null +++ b/dbus/org.torproject.tlsdate.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.torproject.tlsdate +Exec=/usr/bin/tlsdated diff --git a/dbus/org.torproject.tlsdate.xml b/dbus/org.torproject.tlsdate.xml new file mode 100644 index 0000000..2023494 --- /dev/null +++ b/dbus/org.torproject.tlsdate.xml @@ -0,0 +1,42 @@ +<!DOCTYPE node PUBLIC +"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> +<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd"> + + <interface name="org.torproject.tlsdate"> + <method name="SetTime"> + <arg name="time" direction="in" type="x"> + <doc:doc><doc:summary>The requested time to set the system clock to. It may be tested + with: + dbus-send --print-reply --system --dest=org.torproject.tlsdate --type=method_call \ + /org/torproject/tlsdate org.torproject.tlsdate.SetTime int64:12345678 + </doc:summary></doc:doc> + </arg> + <arg name="code" direction="out" type="u"> + <doc:doc><doc:summary>Returns success or failure via an enum: + OK:0, Bad value:1, Not allowed:2, Bad call format:3 + </doc:summary></doc:doc> + </arg> + </method> + <method name="CanSetTime"> + <arg name="code" direction="out" type="b"> + <doc:doc><doc:summary>Returns TRUE is SetTime is allowed. + </doc:summary></doc:doc> + </arg> + </method> + <method name="LastSyncInfo"> + <arg name="network_synchronized" direction="out" type="b"> + <doc:doc><doc:summary>Whether the time is rooted in a network synchronization source since + fallback to "system-clock" happens at steady state intervals. + </doc:summary></doc:doc> + </arg> + <arg name="source" direction="out" type="s"> + <doc:doc><doc:summary>Name of the last source</doc:summary></doc:doc> + </arg> + <arg name="time" direction="out" type="x"> + <doc:doc><doc:summary>Last sync time</doc:summary></doc:doc> + </arg> + </method> + + </interface> +</node> diff --git a/etc/tlsdated.conf b/etc/tlsdated.conf new file mode 100644 index 0000000..ca42029 --- /dev/null +++ b/etc/tlsdated.conf @@ -0,0 +1,24 @@ +# tlsdated example config file +# for boolean options, "yes" enables them, any other value disables them. +# see tlsdated.conf(5) for details about the options + +base-path /var/cache/tlsdated +dry-run no +jitter 0 +max-tries 10 +min-steady-state-interval 86400 +should-load-disk yes +should-netlink yes +should-save-disk yes +should-sync-hwclock yes +steady-state-interval 86400 +subprocess-timeout 30 +verbose no +wait-between-tries 10 + +# Host configuration. +source + host google.com + port 443 + proxy none +end diff --git a/events.dot b/events.dot new file mode 100644 index 0000000..658240b --- /dev/null +++ b/events.dot @@ -0,0 +1,58 @@ +/* This DOT file represents the logical interaction between + * the events in the system and the "state" of tlsdated. + */ +digraph tlsdated { + graph[compound=true]; + + node[style=filled,color=lightblue]; + + subgraph cluster_states { + state_label[shape=box,style=dashed,label="States"]; + sleep -> wake; + wake -> sync; + sync -> save; + save -> sleep; + wake -> terminate; + sync -> terminate; + save -> terminate; + } + + subgraph cluster_wake { + color=purple; + style=filled; + wake_label[shape=box,style=dashed,label="Wake Events"]; + periodic_local_clock_check -> wake; + periodic_network_sync -> wake; + random_sigterm -> wake; + random_route_change -> wake; + } + + subgraph cluster_dbus { + dbus_label[shape=box,style=dashed,label="DBus Events"]; + dbus-> cros_shill_manager_change -> wake; + dbus-> cros_shill_service_change -> wake; + dbus -> cros_proxy_resolved -> {proxy_ok, proxy_failed}; + dbus -> cros_user_set_time -> save; + cros_user_set_time -> sync [style=dotted]; + get_proxy -> cros_resolve_proxy -> dbus; + announce -> dbus; + } + + subgraph cluster_sync { + sync_label[shape=box,style=dashed,label="Network Sync"]; + sync -> get_proxy -> {proxy_ok, proxy_failed, proxy_timed_out} -> tlsdate; + tlsdate -> tlsdate_ok -> save; + tlsdate -> tlsdate_fail; + tlsdate_fail -> tlsdate [label="retry",style=dotted]; + tlsdate_fail -> terminate; + }; + + subgraph cluster_save { + save_label[shape=box,style=dashed,label="Save to the system"]; + save -> { synchronize_rtc, synchronize_kernel, synchronize_disk } -> { save_ok, save_fail, save_bad_time }; + save_ok -> announce -> sleep; + save_fail -> terminate; + save_bad_time -> sleep; + } +} + diff --git a/init/tlsdated-cros.conf b/init/tlsdated-cros.conf new file mode 100644 index 0000000..f5b46a4 --- /dev/null +++ b/init/tlsdated-cros.conf @@ -0,0 +1,22 @@ +# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +description "Run the tlsdate daemon to set the system time" +author "chromium-os-dev@chromium.org" + +start on started system-services +stop on stopping system-services +respawn + +script + GOOGLE_CERTS=/usr/share/chromeos-ca-certificates + mkdir -m 755 -p /var/cache/tlsdated + # Make sure the timestamp file has the proper permissions. + chmod 0644 /var/cache/tlsdated/timestamp || true + # When it runs tlsdate, tlsdated stitches together an argument vector for it + # as follows: it begins with everything supplied to it after the --, then + # appends -H $host -p $port, and maybe -x $proxy if it has a proxy to use. + exec tlsdated -v -- /usr/bin/tlsdate -v -C "$GOOGLE_CERTS" -l \ + 2>&1 | logger -t tlsdate +end script diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 new file mode 100644 index 0000000..1f8e708 --- /dev/null +++ b/m4/ax_append_compile_flags.m4 @@ -0,0 +1,65 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the compiler works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. During the check the flag is always added to the +# current language's flags. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and +# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with +# AX_APPEND_LINK_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 3 + +AC_DEFUN([AX_APPEND_COMPILE_FLAGS], +[AC_REQUIRE([AX_CHECK_COMPILE_FLAG]) +AC_REQUIRE([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3]) +done +])dnl AX_APPEND_COMPILE_FLAGS diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..1d38b76 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,69 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_APPEND_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])dnl +AS_VAR_SET_IF(FLAGS, + [case " AS_VAR_GET(FLAGS) " in + *" $1 "*) + AC_RUN_LOG([: FLAGS already contains $1]) + ;; + *) + AC_RUN_LOG([: FLAGS="$FLAGS $1"]) + AS_VAR_SET(FLAGS, ["AS_VAR_GET(FLAGS) $1"]) + ;; + esac], + [AS_VAR_SET(FLAGS,["$1"])]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..c3a8d69 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,72 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..e2d0d36 --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM()], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_platform.m4 b/m4/ax_platform.m4 new file mode 100644 index 0000000..f3da57d --- /dev/null +++ b/m4/ax_platform.m4 @@ -0,0 +1,103 @@ +# =========================================================================== +# http:// +# =========================================================================== +# +# SYNOPSIS +# +# AX_PLATFORM +# +# DESCRIPTION +# +# Provide target and host defines. +# +# LICENSE +# +# Copyright (c) 2012 Brian Aker <brian@tangent.org> +# Copyleft (ↄ) 2013 Jacob Appelbaum <jacob@appelbaum.net> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + AC_DEFUN([AX_PLATFORM], + [AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_CANONICAL_TARGET]) + + AC_DEFINE_UNQUOTED([HOST_VENDOR],["$host_vendor"],[Vendor of Build System]) + AC_DEFINE_UNQUOTED([HOST_OS],["$host_os"], [OS of Build System]) + AC_DEFINE_UNQUOTED([HOST_CPU],["$host_cpu"], [CPU of Build System]) + + AC_DEFINE_UNQUOTED([TARGET_VENDOR],["$target_vendor"],[Vendor of Target System]) + AC_DEFINE_UNQUOTED([TARGET_OS],["$target_os"], [OS of Target System]) + AC_DEFINE_UNQUOTED([TARGET_CPU],["$target_cpu"], [CPU of Target System]) + + AS_CASE([$target_os], + [*mingw32*], + [TARGET_OS_WINDOWS="true" + AC_DEFINE([TARGET_OS_WINDOWS], [1], [Whether we are building for Windows]) + AC_DEFINE([WINVER], [WindowsXP], [Version of Windows]) + AC_DEFINE([_WIN32_WINNT], [0x0501], [Magical number to make things work]) + AC_DEFINE([EAI_SYSTEM], [11], [Another magical number]) + AH_BOTTOM([ +#ifndef HAVE_SYS_SOCKET_H +# define SHUT_RD SD_RECEIVE +# define SHUT_WR SD_SEND +# define SHUT_RDWR SD_BOTH +#endif + ])], + [*mingw*], + [TARGET_OS_MINGW="true" + AC_DEFINE([TARGET_OS_MINGW],[1],[Whether we build for MinGW])], + [*cygwin*], + [TARGET_OS_CYGWIN="true" + AC_DEFINE([TARGET_OS_CYGWIN],[1],[Whether we build for Cygwin])], + [*haiku*], + [TARGET_OS_HAIKU="true" + AC_DEFINE([TARGET_OS_HAIKU],[1],[Whether we build for Haiku])], + [*freebsd*], + [TARGET_OS_FREEBSD="true" + AC_DEFINE([TARGET_OS_FREEBSD],[1],[Whether we are building for FreeBSD])], + [*kfreebsd*-gnu], + [TARGET_OS_GNUKFREEBSD="true" + TARGET_OS_FREEBSD="true" + AC_DEFINE([TARGET_OS_FREEBSD],[1],[Whether we are building for FreeBSD]) + AC_DEFINE([TARGET_OS_GNUKFREEBSD],[1],[Whether we are building for GNU/kFreeBSD])], + [*netbsd*], + [TARGET_OS_NETBSD="true" + AC_DEFINE([TARGET_OS_NETBSD],[1],[Whether we are building for NetBSD])], + [*openbsd*], + [TARGET_OS_OPENBSD="true" + AC_DEFINE([TARGET_OS_OPENBSD],[1],[Whether we are building for OpenBSD])], + [*dragonfly*], + [TARGET_OS_DRAGONFLYBSD="true" + AC_DEFINE([TARGET_OS_DRAGONFLYBSD],[1],[Whether we are building for DragonFly BSD])], + [*bsd*], + [TARGET_OS_BSD="true" + AC_DEFINE([TARGET_OS_BSD],[1],[Whether we are building for some other *BSD])], + [*solaris*],[AC_DEFINE([TARGET_OS_SOLARIS],[1],[Whether we are building for Solaris])], + [*darwin*], + [TARGET_OS_OSX="true" + AC_DEFINE([TARGET_OS_OSX],[1],[Whether we build for OSX])], + [*linux*], + [TARGET_OS_LINUX="true" + AC_DEFINE([TARGET_OS_LINUX],[1],[Whether we build for Linux])], + [*gnu*], + [TARGET_OS_GNUHURD="true" + AC_DEFINE([TARGET_OS_GNUHURD],[1],[Whether we build for GNU/Hurd])]) + + AM_CONDITIONAL([TARGET_WIN32],[test "x${TARGET_OS_WINDOWS}" = "xtrue"]) + AM_CONDITIONAL([TARGET_MINGW],[test "x${TARGET_OS_MINGW}" = "xtrue"]) + AM_CONDITIONAL([TARGET_CYGWIN],[test "x${TARGET_OS_CYGWIN}" = "xtrue"]) + AM_CONDITIONAL([TARGET_HAIKU],[test "x${TARGET_OS_HAIKU}" = "xtrue"]) + AM_CONDITIONAL([TARGET_OSX],[test "x${TARGET_OS_OSX}" = "xtrue"]) + AM_CONDITIONAL([TARGET_GNUHURD],[test "x${TARGET_OS_GNUHURD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_LINUX],[test "x${TARGET_OS_LINUX}" = "xtrue"]) + AM_CONDITIONAL([TARGET_FREEBSD],[test "x${TARGET_OS_FREEBSD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_GNUKFREEBSD],[test "x${TARGET_OS_GNUKFREEBSD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_NETBSD],[test "x${TARGET_OS_NETBSD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_OPENBSD],[test "x${TARGET_OS_OPENBSD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_DRAGONFLYBSD],[test "x${TARGET_OS_DRAGONFLYBSD}" = "xtrue"]) + AM_CONDITIONAL([TARGET_BSD],[test "x${TARGET_OS_BSD}" = "xtrue"]) + ]) diff --git a/m4/bottom.m4 b/m4/bottom.m4 new file mode 100644 index 0000000..28e1c30 --- /dev/null +++ b/m4/bottom.m4 @@ -0,0 +1,12 @@ +AC_DEFUN([CONFIG_EXTRA],[ + + AH_TOP([ +#pragma once + +/* _SYS_FEATURE_TESTS_H is Solaris, _FEATURES_H is GCC */ +#if defined( _SYS_FEATURE_TESTS_H) || defined(_FEATURES_H) +#error "You should include config.h as your first include file" +#endif + + ]) + ]) diff --git a/m4/visibility.m4 b/m4/visibility.m4 new file mode 100644 index 0000000..75c34b6 --- /dev/null +++ b/m4/visibility.m4 @@ -0,0 +1,77 @@ +# visibility.m4 serial 4 (gettext-0.18.2) +dnl Copyright (C) 2005, 2008, 2010-2011 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl Tests whether the compiler supports the command-line option +dnl -fvisibility=hidden and the function and variable attributes +dnl __attribute__((__visibility__("hidden"))) and +dnl __attribute__((__visibility__("default"))). +dnl Does *not* test for __visibility__("protected") - which has tricky +dnl semantics (see the 'vismain' test in glibc) and does not exist e.g. on +dnl MacOS X. +dnl Does *not* test for __visibility__("internal") - which has processor +dnl dependent semantics. +dnl Does *not* test for #pragma GCC visibility push(hidden) - which is +dnl "really only recommended for legacy code". +dnl Set the variable CFLAG_VISIBILITY. +dnl Defines and sets the variable HAVE_VISIBILITY. + +AC_DEFUN([gl_VISIBILITY], +[ + AC_REQUIRE([AC_PROG_CC]) + CFLAG_VISIBILITY= + HAVE_VISIBILITY=0 + if test -n "$GCC"; then + dnl First, check whether -Werror can be added to the command line, or + dnl whether it leads to an error because of some other option that the + dnl user has put into $CC $CFLAGS $CPPFLAGS. + AC_MSG_CHECKING([whether the -Werror option is usable]) + AC_CACHE_VAL([gl_cv_cc_vis_werror], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [gl_cv_cc_vis_werror=yes], + [gl_cv_cc_vis_werror=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_vis_werror]) + dnl Now check whether visibility declarations are supported. + AC_MSG_CHECKING([for simple visibility declarations]) + AC_CACHE_VAL([gl_cv_cc_visibility], [ + gl_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fvisibility=hidden" + dnl We use the option -Werror and a function dummyfunc, because on some + dnl platforms (Cygwin 1.7) the use of -fvisibility triggers a warning + dnl "visibility attribute not supported in this configuration; ignored" + dnl at the first function definition in every compilation unit, and we + dnl don't want to use the option in this case. + if test $gl_cv_cc_vis_werror = yes; then + CFLAGS="$CFLAGS -Werror" + fi + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[extern __attribute__((__visibility__("hidden"))) int hiddenvar; + extern __attribute__((__visibility__("default"))) int exportedvar; + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + extern __attribute__((__visibility__("default"))) int exportedfunc (void); + void dummyfunc (void) {} + ]], + [[]])], + [gl_cv_cc_visibility=yes], + [gl_cv_cc_visibility=no]) + CFLAGS="$gl_save_CFLAGS"]) + AC_MSG_RESULT([$gl_cv_cc_visibility]) + if test $gl_cv_cc_visibility = yes; then + CFLAG_VISIBILITY="-fvisibility=hidden" + HAVE_VISIBILITY=1 + fi + fi + AC_SUBST([CFLAG_VISIBILITY]) + AC_SUBST([HAVE_VISIBILITY]) + AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], + [Define to 1 or 0, depending whether the compiler supports simple visibility declarations.]) +]) diff --git a/man/tlsdate-helper.1 b/man/tlsdate-helper.1 new file mode 100644 index 0000000..aedfe2b --- /dev/null +++ b/man/tlsdate-helper.1 @@ -0,0 +1,39 @@ +.\" Process this file with +.\" groff -man -Tascii foo.1 +.\" +.TH TLSDATE 1 "OCTOBER 2012" Linux "User Manuals" +.SH NAME +tlsdate-helper \- secure parasitic rdate replacement +.SH SYNOPSIS +.B tlsdate-helper host port protocol ca_racket verbose certdir setclock \ +showtime timewarp leapaway proxy-type://proxyhost:proxyport httpmode +.SH DESCRIPTION +.B tlsdate-helper +is a tool for setting the system clock by hand or by communication +with the network. It does not set the Real Time Clock. It is designed to be as +secure as TLS (RFC 2246) but of course the security of TLS is often reduced to +whichever CA racket you believe is trustworthy. By default, tlsdate-helper +trusts your local CA root store - so any of these companies could assist in a +MITM attack against you and you'd be screwed. + +The proxy argument expects HTTP, SOCKS4A or SOCKS5 formatted as followed: + + http://127.0.0.1:8118 + socks4a://127.0.0.1:9050 + socks5://127.0.0.1:9050 + +This tool is designed to be run by hand or as a system daemon. It must be +run as root or otherwise have the proper caps; it will not be able to set +the system time without running as root or another privileged user. +.SH BUGS +It's likely! Let us know by contacting jacob@appelbaum.net + +Note that +.B tlsdate(1) +is in Beta, and may not work as expected. +.SH AUTHOR +Jacob Appelbaum <jacob at appelbaum dot net> +.SH "SEE ALSO" +.B tlsdate(1), +.B tlsdated(8), +.B tlsdated.conf(5) diff --git a/man/tlsdate.1 b/man/tlsdate.1 new file mode 100644 index 0000000..b052e48 --- /dev/null +++ b/man/tlsdate.1 @@ -0,0 +1,95 @@ +.\" Process this file with +.\" groff -man -Tascii foo.1 +.\" +.TH TLSDATE 1 "OCTOBER 2012" Linux "User Manuals" +.SH NAME +tlsdate \- secure parasitic rdate replacement +.SH SYNOPSIS +.B tlsdate [\-hnvVstlw] [\-H [hostname]] [\-p [port]] [\-P [sslv23|sslv3|tlsv1]] \ +[\-\-certdir [dirname]] [\-x [\-\-proxy] proxy\-type://proxyhost:proxyport] +.SH DESCRIPTION +.B tlsdate +is a tool for setting the system clock by hand or by communication +with the network. It does not set the Real Time Clock. It is designed to be as +secure as TLS (RFC 2246) but of course the security of TLS is often reduced to +whichever CA racket you believe is trustworthy. By default, tlsdate trusts your +local CA root store - so any of these companies could assist in a MITM attack +against you and you'd be screwed. + +This tool is designed to be run by hand or as a system daemon. It must be +run as root or otherwise have the proper caps; it will not be able to set +the system time without running as root or another privileged user. +.SH OPTIONS +.IP "\-h | \-\-help" +Print the help message +.IP "\-s | \-\-skip\-verification" +Skip certificate verification +.IP "\-H | \-\-host [hostname|ip]" +Set remote hostname (default: 'google.com') +.IP "\-n | \-\-dont\-set\-clock" +Do not set the system clock to the time of the remote server +.IP "\-p | \-\-port [port]" +Set remote port (default: '443') +.IP "\-P | \-\-protocol [sslv23|sslv3|tlsv1]" +Set protocol to use when communicating with server (default: 'tlsv1') +.IP "\-C | \-\-certdir [dirname]" +Set the local directory where certificates are located +(default: '/etc/ssl/certs') +This allows for certificate or certificate authority (CA) pinning. To ensure +that signatures are only valid if they are signed by a specific CA or +certificate, set the path to a directory containing only the desired +certificates. +.IP "\-x | \-\-proxy [proxy\-type://proxyhost:proxyport]" +The proxy argument expects HTTP, SOCKS4A or SOCKS5 formatted as followed: + + http://127.0.0.1:8118 + socks4a://127.0.0.1:9050 + socks5://127.0.0.1:9050 + +The proxy support should not leak DNS requests and is suitable for use with Tor. +.IP "\-v | \-\-verbose" +Provide verbose output +.IP "\-V | \-\-showtime [human|raw]" +Show the time retrieved from the remote server in a human-readable format or as +a raw time_t. +.IP "\-t | \-\-timewarp" +If the local clock is before RECENT_COMPILE_DATE; we set the clock to the +RECENT_COMPILE_DATE. If the local clock is after RECENT_COMPILE_DATE, we leave +the clock alone. Clock setting is performed as the first operation and will +impact certificate verification. Specifically, this option is helpful if on +first boot, the local system clock is set back to the era of Disco and Terrible +Hair. This should ensure that X509_V_ERR_CERT_NOT_YET_VALID or +X509_V_ERR_CERT_HAS_EXPIRED are not encountered because of a broken RTC or the +lack of a local RTC; we assume that tlsdate is recompiled yearly and that all +certificates are otherwise considered valid. +.IP "\-l | \-\-leap" +Normally, the passing of time or time yet to come ensures that SSL verify +functions will fail to validate certificates. Commonly, +X509_V_ERR_CERT_NOT_YET_VALID and X509_V_ERR_CERT_HAS_EXPIRED are painfully +annoying but still very important error states. When the only issue with the +certificates in question is the timing information, this option allows you to +trust the remote system's time, as long as it is after RECENT_COMPILE_DATE and +before MAX_REASONABLE_TIME. The connection will only be trusted if +X509_V_ERR_CERT_NOT_YET_VALID and/or X509_V_OKX509_V_ERR_CERT_HAS_EXPIRED are +the only errors encountered. The SSL verify function will not return X509_V_OK +if there are any other issues, such as self-signed certificates or if the user +pins to a CA that is not used by the remote server. This is useful if your RTC +is broken on boot and you are unable to use DNSEC until you've at least had +some kind of leap of cryptographically assured data. +.IP "\-w | \-\-http" +Run in web mode: look for the time in an HTTP "Date" header inside an +HTTPS connection, rather than in the TLS connection itself. The provided +hostname and port must support HTTPS. +.SH BUGS +It's likely! Let us know by contacting jacob@appelbaum.net + +Note that +.B tlsdate(1) +is in Beta, and may not work as expected. +.SH AUTHOR +Jacob Appelbaum <jacob at appelbaum dot net> +.SH "SEE ALSO" +.B tlsdate(1), +.B tlsdate-helper(1), +.B tlsdated(8), +.B tlsdated.conf(5) diff --git a/man/tlsdated.8 b/man/tlsdated.8 new file mode 100644 index 0000000..24f79fb --- /dev/null +++ b/man/tlsdated.8 @@ -0,0 +1,73 @@ +.\" Process this file with +.\" groff -man -Tascii foo.1 +.\" +.TH TLSDATED 8 "OCTOBER 2012" Linux "User Manuals" +.SH NAME +tlsdated \- secure parasitic rdate replacement daemon +.SH SYNOPSIS +.B tlsdated [\-wprlsvh] \ +[\-t <n>] \ +[\-d <n>] \ +[\-T <n>] \ +[\-D <n>] \ +[\-c /path/to ] \ +[\-a seconds ] \ +[\-\-] \ +[commands to be passed to tlsdate] +.SH DESCRIPTION +.B tlsdated +is a daemon that runs tlsdate. It must be run as root or otherwise have the +proper caps; it will not be able to set the system time without running as root +or another privileged user. +.SH OPTIONS +.IP "\-w" +don't set hwclock +.IP "\-p" +dry run (don't really set time) +.IP "\-r" +use stdin instead of netlink for routes +.IP "\-t [n]" +try up to n times if unsuccessful to synchronize the time +.IP "\-d [n]" +delay n seconds between tries +.IP "\-T [n]" +give subprocess n chances to exit +.IP "\-D [n]" +delay n seconds between wait attempts +.IP "\-c [/path/to/cache/directory/]" +set the cache directory +.IP "\-a [n]" +run at most every n seconds in steady state +.IP "\-l" +don't load disk timestamps +.IP "\-s" +don't save disk timestamp +.IP "\-j [n]" +add up to n seconds of jitter to steady-state fetches +.IP "\-v" +be verbose +.IP "\-b" +be extra verbose (debugging) +.IP "\-U" +do not use DBus if supported +.IP "\-h" +print help message +.IP "\-f [/path/to/config/file]" +use alternate config file +.IP "\-x [proxy]" +override the proxy supplied to sources in the config file +.IP "[tlsdate command arguments]" +arguments to be passed to tlsdate at launch time + +.SH BUGS +It's likely! Let us know by contacting jacob@appelbaum.net + +Note that +.B tlsdate(8) +is in Beta, and may not work as expected. +.SH AUTHOR +Jacob Appelbaum <jacob at appelbaum dot net> +.SH "SEE ALSO" +.B tlsdate(1), +.B tlsdate-helper(1), +.B tlsdated.conf(5) diff --git a/man/tlsdated.conf.5 b/man/tlsdated.conf.5 new file mode 100644 index 0000000..d4f763d --- /dev/null +++ b/man/tlsdated.conf.5 @@ -0,0 +1,75 @@ +.\" Process this file with +.\" groff -man -Tascii foo.1 +.\" +.TH TLSDATED 5 "JANUARY 2013" "File Formats and Conversions" +.SH NAME +tlsdated.conf \- tlsdated config file +.SH SYNTAX +\fBtlsdated.conf\fR is the configuration file for the \fBtlsdated(8)\fR daemon. +The config file is formatted as a list of key-value pairs, one per line, +separated by whitespace. Whitespace inside values is preserved, so +.RS +foo bar baz quxx +.RE +represents the key \fBfoo\fR mapping to the value \fBbar baz quxx\fR. Empty +lines and lines beginning with \fB#\fR are ignored; leading whitespace on lines +is stripped. For boolean options, the value \fByes\fR or no value at all +indicates that the option should be switched on, and all other values indicate +that the option should be switched off. \fINote that trailing whitespace is +preserved in values.\fR +.SH OPTIONS +.IP "base-path [string]" +Sets the path to tlsdated's cache directory. +.IP "dry-run [bool]" +If enabled, don't actually adjust the system time. +.IP "jitter [int]" +Add or subtract up to this many seconds from the steady-state interval when +checking. This helps prevent correlation between sequential checks and smooth +load on time hosts. +.IP "max-tries [int]" +How many times to try running the tlsdate subprocess. +.IP "min-steady-state-interval [int]" +Do not check more than once this many seconds when in steady state. +.IP "should-load-disk [bool]" +If enabled, try loading the current timestamp out of the cache directory. +.IP "should-netlink [bool]" +If enabled, use a netlink socket to get network events; otherwise, read network +events from stdin. +.IP "should-save-disk [bool]" +If enabled, save the current timestamp to the cache directory every so often and +at exit. +.IP "should-sync-hwclock [bool]" +If enabled, set the hwclock to the fetched time. +.IP "steady-state-interval [int]" +Check at least once this many seconds when in steady state. +.IP "subprocess-timeout [int]" +How many seconds to wait for the subprocess to exit. +.IP "verbose [bool]" +If enabled, tlsdated will be annoyingly verbose in syslog and on stdout. +.IP "wait-between-tries [int]" +How long to wait between runs of the subprocess. +.SH SOURCES +You can list one or more sources to fetch time from. The format of these is: +.RS 4 +source +.RS 4 +host www.example.com +.br +port 443 +.br +proxy socks5://127.0.0.1:9050 +.RE +end +.RE +.SH BUGS +It's likely! Let us know by contacting jacob@appelbaum.net + +Note that +.B tlsdated(8) +is in Beta, and may not work as expected. +.SH AUTHOR +Jacob Appelbaum <jacob at appelbaum dot net> +.SH "SEE ALSO" +.B tlsdate(1), +.B tlsdate-helper(1), +.B tlsdated(8), @@ -0,0 +1,12 @@ +</$objtype/mkfile + +#src/tlsdate: src/tlsdate.c +# $CC -I. $prereq + +src/tlsdatehelper: config.h + $CC -I. ./src/util-plan9.c ./src/proxy-bio-plan9.c ./src/tlsdate-helper-plan9.c /$objtype/lib/ape/libssl.a /$objtype/lib/ape/libcrypto.a + +config.h: + touch config.h + +CC=pcc -DHAVE_TIME_H -D_PLAN9_SOURCE -D_REENTRANT_SOURCE -D_BSD_EXTENSION -D_SUSV2_SOURCE -D_POSIX_SOURCE diff --git a/run-tests b/run-tests new file mode 100755 index 0000000..1e43b05 --- /dev/null +++ b/run-tests @@ -0,0 +1,48 @@ +#!/bin/sh + +run_test() { + # Clear the last results + rm -f "$1"/result + [ -x "$1"/setup ] && "$1"/setup + if [ -r "$1"/tlsdated-flags ]; then + flags=$(cat "$1"/tlsdated-flags | sed "s/@TESTDIR@/$1/g") + elif [ -r "$1"/test.conf ]; then + flags="-U -w -p -r -l -s -b -f $1/test.conf -v" + else + flags="-U -w -p -r -l -s -b -f test.conf -v" + fi + # flags are deliberately unquoted here so that they'll be interpolated + (test -x "$1"/input.sh && "$1"/input.sh) | + timeout 8 src/tlsdated $flags -- "$1"/subproc.sh \ + >"$1"/run-output 2>"$1"/run-err + [ -x "$1"/teardown ] && "$1"/teardown +} + +test_passed() { + f="$t"/result + test -f "$f" && grep -q ok "$f" +} + +total=0 +passed=0 + +if ! test -x src/test/emit; then + echo "Make sure src/test/emit has been built (make check)!" + exit 1 +fi +for t in tests/*; do + [ ! -d "$t" ] && continue + name="$(basename "$t")" + echo -n "$name: " + run_test "$t" + if test_passed "$t"; then + echo "ok" + passed=$((passed + 1)) + else + echo "failed" + fi + total=$((total + 1)) +done +echo "Passed: $passed/$total" +[ $passed != $total ] +exit $? diff --git a/src/common/android.c b/src/common/android.c new file mode 100644 index 0000000..655eb0b --- /dev/null +++ b/src/common/android.c @@ -0,0 +1,18 @@ +#include "android.h" + +#include <string.h> + +char *strchrnul(const char *s, int c) +{ + char * matched_char = strchr(s, c); + if (matched_char == NULL) { + matched_char = (char*) s + strlen(s); + } + return matched_char; +} + +int MIN(int a, int b) { + return a < b ? a : b; +} + + diff --git a/src/common/android.h b/src/common/android.h new file mode 100644 index 0000000..f2908c2 --- /dev/null +++ b/src/common/android.h @@ -0,0 +1,25 @@ +/* + * Android's libc lacks fmemopen, so here is our implementation. + */ + +#include <stdio.h> + +/** + * fmemopen expects this function + * defined in android.c + */ +int MIN(int a, int b); + + +/* + * Android's libc does not provide strchrnul, so here + * is our own implementation. strchrnul behaves like + * strchr except instead of returning NULL if c is not + * in s, strchrnul returns a pointer to the \0 byte at + * the end of s. + * defined in android.c + */ +char *strchrnul(const char *s, int c); + +/* defined in fmemopen.c */ +FILE *fmemopen(void *buf, size_t size, const char *mode); diff --git a/src/common/fmemopen-funopen.c b/src/common/fmemopen-funopen.c new file mode 100644 index 0000000..87c8675 --- /dev/null +++ b/src/common/fmemopen-funopen.c @@ -0,0 +1,158 @@ +/* + * POSIX 2008 fmemopen(3) implemented in terms of BSD funopen(3) + */ + +/* + * Copyright (c) 2013 Taylor R. Campbell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define _BSD_SOURCE +#define _NETBSD_SOURCE + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fmemopen.h" + +struct fmem_cookie { + void *fmc_buffer; + size_t fmc_index; + size_t fmc_limit; +}; + +static int +fmem_read(void *cookie, char *buffer, int n) +{ + struct fmem_cookie *const fmc = cookie; + + if (n < 0) { /* paranoia */ + errno = EINVAL; + return -1; + } + + if (n > (fmc->fmc_limit - fmc->fmc_index)) + n = (fmc->fmc_limit - fmc->fmc_index); + + (void)memcpy(buffer, (char *)fmc->fmc_buffer + fmc->fmc_index, n); + fmc->fmc_index += n; + return n; +} + +static int +fmem_write(void *cookie, const char *buffer, int n) +{ + struct fmem_cookie *const fmc = cookie; + + if (n < 0) { /* paranoia */ + errno = EINVAL; + return -1; + } + + if (n > (fmc->fmc_limit - fmc->fmc_index)) + n = (fmc->fmc_limit - fmc->fmc_index); + + (void)memcpy((char *)fmc->fmc_buffer + fmc->fmc_index, buffer, n); + fmc->fmc_index += n; + return n; +} + +static fpos_t +fmem_seek(void *cookie, fpos_t offset, int cmd) +{ + struct fmem_cookie *const fmc = cookie; + + switch (cmd) { + case SEEK_SET: + if ((offset < 0) || (fmc->fmc_limit < offset)) + goto einval; + fmc->fmc_index = offset; + return 0; + + case SEEK_CUR: + if (offset < 0) { + /* Assume two's-complement arithmetic. */ + if ((offset == ~(fpos_t)0) || (-offset > fmc->fmc_index)) + goto einval; + } else { + if (offset > (fmc->fmc_limit - fmc->fmc_index)) + goto einval; + } + fmc->fmc_index += offset; + return 0; + + case SEEK_END: + /* Assume two's-complement arithmetic. */ + if ((offset >= 0) || (offset == ~(fpos_t)0) || (fmc->fmc_limit < -offset)) + goto einval; + fmc->fmc_index = (fmc->fmc_limit + offset); + return 0; + + default: + goto einval; + } + +einval: + errno = EINVAL; + return -1; +} + +static int +fmem_close(void *cookie) +{ + struct fmem_cookie *const fmc = cookie; + + free(fmc); + + return 0; +} + +FILE * +fmemopen(void *buffer, size_t len, const char *mode) +{ + struct fmem_cookie *fmc; + FILE *file; + + fmc = malloc(sizeof(*fmc)); + if (fmc == NULL) + goto fail0; + + (void)memset(fmc, 0, sizeof(*fmc)); + fmc->fmc_buffer = buffer; + fmc->fmc_index = 0; + fmc->fmc_limit = len; + + file = funopen(fmc, &fmem_read, &fmem_write, &fmem_seek, &fmem_close); + if (file == NULL) + goto fail1; + + return file; + +fail1: + free(fmc); +fail0: + return NULL; +} diff --git a/src/common/fmemopen.c b/src/common/fmemopen.c new file mode 100644 index 0000000..d42fc30 --- /dev/null +++ b/src/common/fmemopen.c @@ -0,0 +1,225 @@ +/* + This file was retrieved from + http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/lib/libc/stdio/fmemopen.c + on 26/04/2013 by Abel Luck for inclusion in tlsdate for the Android port. +*/ +#include "android.h" +/* $NetBSD: fmemopen.c,v 1.4 2010/09/27 16:50:13 tnozaki Exp $ */ + +/*- + * Copyright (c)2007, 2010 Takehiko NOZAKI, + * Copyright (c) 2012, Venkatesh Srinivas <vsrinivas@dragonflybsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> + +//#include "local.h" +//#include "priv_stdio.h" + +struct fmemopen_cookie { + char *head, *tail, *cur, *eob; +}; + +static int +fmemopen_read(void *cookie, char *buf, int nbytes) +{ + struct fmemopen_cookie *p; + char *s; + int len; + + assert(cookie != NULL); + assert(buf != NULL && nbytes > 0); + + p = cookie; + s = p->cur; + len = MIN(p->tail - p->cur, nbytes); + bcopy(p->cur, buf, len); + p->cur += len; + + return (int)(p->cur - s); +} + +static int +fmemopen_write(void *cookie, const char *buf, int nbytes) +{ + struct fmemopen_cookie *p; + char *s; + int len; + + assert(cookie != NULL); + assert(buf != NULL && nbytes > 0); + + p = cookie; + if (p->cur >= p->tail) + return 0; + s = p->cur; + + len = MIN(p->tail - p->cur, nbytes); + + bcopy(buf, p->cur, len); + + p->cur += len - 1; + if (p->cur == p->tail - 1) { + *p->cur = '\0'; + if (buf[len - 1] == '\0') + p->cur++; + } else { + *++p->cur = '\0'; + } + + if (p->cur > p->eob) + p->eob = p->cur; + + return (int)(p->cur - s); +} + +static fpos_t +fmemopen_seek(void *cookie, fpos_t offset, int whence) +{ + struct fmemopen_cookie *p; + + assert(cookie != NULL); + + p = (struct fmemopen_cookie *)cookie; + switch (whence) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += p->cur - p->head; + break; + case SEEK_END: + offset += p->eob - p->head; + break; + default: + errno = EINVAL; + goto error; + } + if (offset >= (fpos_t)0 && offset <= p->tail - p->head) { + p->cur = p->head + (ptrdiff_t)offset; + return (fpos_t)(p->cur - p->head); + } +error: + return (fpos_t)-1; +} + +static int +fmemopen_close0(void *cookie) +{ + assert(cookie != NULL); + + free(cookie); + + return 0; +} + +static int +fmemopen_close1(void *cookie) +{ + struct fmemopen_cookie *p; + + assert(cookie != NULL); + + p = cookie; + free(p->head); + free(p); + + return 0; +} + + +FILE * +fmemopen(void * __restrict buf, size_t size, const char * __restrict mode) +{ + int flags, oflags; + FILE *fp; + struct fmemopen_cookie *cookie; + + if (size < (size_t)1) + goto invalid; + + flags = __sflags(mode, &oflags); + if (flags == 0) + return NULL; + + if ((oflags & O_RDWR) == 0 && buf == NULL) + goto invalid; + + fp = __sfp(); + if (fp == NULL) + return NULL; + + cookie = malloc(sizeof(*cookie)); + if (cookie == NULL) + goto release; + + if (buf == NULL) { + cookie->head = malloc(size); + if (cookie->head == NULL) { + free(cookie); + goto release; + } + *cookie->head = '\0'; + fp->_close = &fmemopen_close1; + } else { + cookie->head = (char *)buf; + if (oflags & O_TRUNC) + *cookie->head = '\0'; + fp->_close = &fmemopen_close0; + } + + cookie->tail = cookie->head + size; + cookie->eob = cookie->head; + do { + if (*cookie->eob == '\0') + break; + ++cookie->eob; + } while (--size > 0); + + cookie->cur = (oflags & O_APPEND) ? cookie->eob : cookie->head; + + // fp->pub._flags = flags; + fp->_write = (flags & __SRD) ? NULL : &fmemopen_write; + fp->_read = (flags & __SWR) ? NULL : &fmemopen_read; + fp->_seek = &fmemopen_seek; + fp->_cookie = (void *)cookie; + + return fp; + +invalid: + errno = EINVAL; + return NULL; + +release: + //fp->pub._flags = 0; + return NULL; +} + + diff --git a/src/common/fmemopen.h b/src/common/fmemopen.h new file mode 100644 index 0000000..28a2500 --- /dev/null +++ b/src/common/fmemopen.h @@ -0,0 +1,8 @@ +#ifndef TLSDATE_FMEMOPEN_H +#define TLSDATE_FMEMOPEN_H + +#include <stdio.h> + +FILE *fmemopen(void *, size_t, const char *); + +#endif /* TLSDATE_FMEMOPEN_H */ diff --git a/src/common/strnlen.c b/src/common/strnlen.c new file mode 100644 index 0000000..38e56e1 --- /dev/null +++ b/src/common/strnlen.c @@ -0,0 +1,19 @@ +/* + * Trivial strnlen(3) implementation + */ + +#include <stddef.h> + +#include "strnlen.h" + +size_t +strnlen(const char *s, size_t limit) +{ + size_t len; + + for (len = 0; len < limit; len++) + if (*s++ == '\0') + break; + + return len; +} diff --git a/src/common/strnlen.h b/src/common/strnlen.h new file mode 100644 index 0000000..945c0d4 --- /dev/null +++ b/src/common/strnlen.h @@ -0,0 +1,8 @@ +#ifndef TLSDATE_STRNLEN_H +#define TLSDATE_STRNLEN_H + +#include <stddef.h> + +size_t strnlen(const char *, size_t); + +#endif /* TLSDATE_STRNLEN_H */ diff --git a/src/compat/clock-darwin.c b/src/compat/clock-darwin.c new file mode 100644 index 0000000..13cc82a --- /dev/null +++ b/src/compat/clock-darwin.c @@ -0,0 +1,110 @@ +/* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net> + * Jacob Appelbaum <jacob@torproject.org> + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file clock-darwin.c + * \brief Contains clock primitives for Mac OS X (Tested on 10.8.2) + **/ + +#include "config.h" +#include "clock.h" +#include <stdio.h> +#include <sys/time.h> +#include <time.h> + +#ifdef __APPLE__ +#include <mach/clock.h> +#include <mach/clock_priv.h> +#include <mach/mach.h> +#include <mach/clock_types.h> +#include <mach/mach_traps.h> +#include <mach/clock_reply.h> +#include <mach/mach_time.h> +#include <mach/mach_error.h> +#endif + +#include <assert.h> + +/** + * Get current real time value and store it into time. + * + * @param time where the current time is stored + * @return clock_gettime syscall return value + */ +int clock_get_real_time(struct tlsdate_time *time) +{ + /* Safety net */ + assert(time); + + kern_return_t r; + clock_serv_t cclock; + mach_timespec_t mts; + + r = host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + if (r != KERN_SUCCESS) + { + fprintf(stderr, "host_get_clock_service failed!\n"); + return -1; + } + + r = clock_get_time(cclock, &mts); + if (r != KERN_SUCCESS) + { + fprintf(stderr, "clock_get_time failed!\n"); + return -1; + } + + r = mach_port_deallocate(mach_task_self(), cclock); + if (r != KERN_SUCCESS) + { + fprintf(stderr, "mach_port_deallocate failed!\n"); + return -1; + } + + time->tp.tv_sec = mts.tv_sec; + time->tp.tv_nsec = mts.tv_nsec; + return r; +} + +/** + * Set current real time clock using time. + * + * @param time where the current time to set is stored + * @return clock_settime syscall return value + */ +int clock_set_real_time(const struct tlsdate_time *time) +{ + /* Safety net */ + assert(time); + + //printf ("V: server time %u\n", (unsigned int) time->tp.tv_sec); + int r; + struct timeval tv = {time->tp.tv_sec, 0}; + + r = settimeofday(&tv, NULL); + if (r != 0) + { + fprintf(stderr, "setimeofday failed!\n"); + return -1; + } + + return r; +} + +/** + * Init a tlsdate_time structure. + * + * @param sec is the seconds + * @param nsec is the nanoseconds + */ +void clock_init_time(struct tlsdate_time *time, time_t sec, + long nsec) +{ + /* Safety net */ + assert(time); + + time->tp.tv_sec = sec; + time->tp.tv_nsec = nsec; +} diff --git a/src/compat/clock-hurd.c b/src/compat/clock-hurd.c new file mode 100644 index 0000000..3d62068 --- /dev/null +++ b/src/compat/clock-hurd.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net> + * Jacob Appelbaum + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file clock-linux.c + * \brief Contains clock primitives for GNU/Linux OS + **/ + +#include "config.h" + +#include <assert.h> + +#include "src/compat/clock.h" + +/** + * Get current real time value and store it into time. + * + * @param time where the current time is stored + * @return clock_gettime syscall return value + */ +int clock_get_real_time(struct tlsdate_time *time) +{ + /* Safety net */ + assert(time); + + return clock_gettime(CLOCK_REALTIME, &time->tp); +} + +/** + * Set current real time clock using time. + * + * @param time where the current time to set is stored + * @return clock_settime syscall return value + */ +int clock_set_real_time(const struct tlsdate_time *time) +{ + /* Safety net */ + assert(time); + + return clock_settime(CLOCK_REALTIME, &time->tp); +} + +/** + * Init a tlsdate_time structure. + * + * @param sec is the seconds + * @param nsec is the nanoseconds + */ +void clock_init_time(struct tlsdate_time *time, time_t sec, + long nsec) +{ + /* Safety net */ + assert(time); + + time->tp.tv_sec = sec; + time->tp.tv_nsec = nsec; +} diff --git a/src/compat/clock-linux.c b/src/compat/clock-linux.c new file mode 100644 index 0000000..84bc934 --- /dev/null +++ b/src/compat/clock-linux.c @@ -0,0 +1,56 @@ +/* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net> + * Jacob Appelbaum + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file clock-linux.c + * \brief Contains clock primitives for GNU/Linux OS + **/ + +#include "config.h" + +#include <assert.h> + +#include "src/compat/clock.h" + +/** + * Get current real time value and store it into time. + * + * @param time where the current time is stored + * @return clock_gettime syscall return value + */ +int clock_get_real_time(struct tlsdate_time *time) +{ + /* Safety net */ + assert (time); + return clock_gettime (CLOCK_REALTIME, &time->tp); +} + +/** + * Set current real time clock using time. + * + * @param time where the current time to set is stored + * @return clock_settime syscall return value + */ +int clock_set_real_time(const struct tlsdate_time *time) +{ + /* Safety net */ + assert (time); + return clock_settime (CLOCK_REALTIME, &time->tp); +} + +/** + * Init a tlsdate_time structure. + * + * @param sec is the seconds + * @param nsec is the nanoseconds + */ +void clock_init_time(struct tlsdate_time *time, time_t sec, + long nsec) +{ + /* Safety net */ + assert (time); + time->tp.tv_sec = sec; + time->tp.tv_nsec = nsec; +} diff --git a/src/compat/clock.h b/src/compat/clock.h new file mode 100644 index 0000000..15f3223 --- /dev/null +++ b/src/compat/clock.h @@ -0,0 +1,74 @@ +/* Copyright (c) 2012, David Goulet <dgoulet@ev0ke.net> + * Jacob Appelbaum <jacob@torproject.org> + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file clock.h + * \brief Header file for the clock primitives. + **/ + +#pragma once +#ifndef CLOCK_HEADER_GUARD +#define CLOCK_HEADER_GUARD 1 + +#include <src/visibility.h> + +#ifdef HAVE_TIME_H +#include <time.h> +#endif + +#ifdef TARGET_OS_OPENBSD +#include <sys/time.h> +#endif + +#ifdef HAVE_MACH_CLOCK_H +#include <mach/clock.h> +#endif +#ifdef HAVE_MACH_MACH_H +#include <mach/mach.h> +#endif + +struct tlsdate_time { +#if defined(__linux__) || defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__DragonFly__) + struct timespec tp; +#elif defined(__APPLE__) + mach_timespec_t tp; +#elif _WIN32 + void *tp; +#elif TARGET_OS_HAIKU + struct timespec tp; +#elif TARGET_OS_CYGWIN + struct timespec tp; +#elif TARGET_OS_MINGW + struct timespec tp; +#elif TARGET_OS_GNUHURD + struct timespec tp; +#else + struct timespec tp; +#endif +}; + +TLSDATE_API +int clock_get_real_time(struct tlsdate_time *time); + +TLSDATE_API +int clock_set_real_time(const struct tlsdate_time *time); + +TLSDATE_API +void clock_init_time(struct tlsdate_time *time, time_t sec, long nsec); + +/* Helper macros to access time values */ +#define CLOCK_SEC(time) ((time)->tp.tv_sec) +#define CLOCK_MSEC(time) ((time)->tp.tv_nsec / 1000000) +#define CLOCK_USEC(time) ((time)->tp.tv_nsec / 1000) +#define CLOCK_NSEC(time) ((time)->tp.tv_nsec) + +/* Helper macros to access time values. TODO: Complete them */ +/* +#define CLOCK_SEC(time) +#define CLOCK_MSEC(time) +#define CLOCK_USEC(time) +#define CLOCK_NSEC(time) +*/ +#endif // CLOCK_HEADER_GUARD diff --git a/src/compat/include.am b/src/compat/include.am new file mode 100644 index 0000000..f499c70 --- /dev/null +++ b/src/compat/include.am @@ -0,0 +1,59 @@ +# vim:ft=automake + +noinst_LTLIBRARIES+= src/compat/libtlsdate_compat.la + +noinst_HEADERS+= src/compat/clock.h + +src_compat_libtlsdate_compat_la_SOURCES = +src_compat_libtlsdate_compat_la_CFLAGS = -DBUILDING_TLSDATE +src_compat_libtlsdate_compat_la_LIBADD = + +if TARGET_OSX +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-darwin.c +endif + +if TARGET_LINUX +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_FREEBSD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_NETBSD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_OPENBSD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_DRAGONFLYBSD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_BSD +if !TARGET_NETBSD +if !TARGET_FREEBSD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif +endif +endif + +if TARGET_GNUHURD +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-hurd.c +endif + +if TARGET_CYGWIN +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_MINGW +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +if TARGET_HAIKU +src_compat_libtlsdate_compat_la_SOURCES+= src/compat/clock-linux.c +endif + +src_compat_libtlsdate_compat_la_LIBADD+= @RT_LIB@ diff --git a/src/conf-unittest.c b/src/conf-unittest.c new file mode 100644 index 0000000..0cc7a56 --- /dev/null +++ b/src/conf-unittest.c @@ -0,0 +1,95 @@ +/* + * conf-unittest.c - config parser unit tests + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "src/conf.h" +#include "src/test_harness.h" + +#ifdef HAVE_ANDROID_SYSTEM +#include "src/common/fmemopen.h" +#endif + +#ifndef HAVE_FMEMOPEN +#include "src/common/fmemopen.h" +#endif + +FILE *fopenstr (const char *str) +{ + /* strlen(str) instead of strlen(str) + 1 because files shouldn't appear + * null-terminated. Cast away constness because we're in read mode, but the + * fmemopen prototype has no way to express that. */ + return fmemopen ( (char *) str, strlen (str), "r"); +} + +TEST (parse_empty) +{ + /* can't do a truly empty file - fmemopen() combusts */ + FILE *f = fopenstr ("\n"); + ASSERT_NE (NULL, f); + struct conf_entry *e = conf_parse (f); + EXPECT_NULL (e); + conf_free (e); +} + +TEST (parse_basic) +{ + FILE *f = fopenstr ("foo bar\nbaz quxx\n"); + ASSERT_NE (NULL, f); + struct conf_entry *e = conf_parse (f); + ASSERT_NE (NULL, e); + EXPECT_STREQ (e->key, "foo"); + EXPECT_STREQ (e->value, "bar"); + ASSERT_NE (NULL, e->next); + EXPECT_STREQ (e->next->key, "baz"); + EXPECT_STREQ (e->next->value, "quxx"); + ASSERT_NULL (e->next->next); + conf_free (e); +} + +TEST (parse_novalue) +{ + FILE *f = fopenstr ("abcdef\n"); + ASSERT_NE (NULL, f); + struct conf_entry *e = conf_parse (f); + ASSERT_NE (NULL, e); + EXPECT_STREQ (e->key, "abcdef"); + EXPECT_NULL (e->value); + EXPECT_NULL (e->next); + conf_free (e); +} + +TEST (parse_whitespace) +{ + FILE *f = fopenstr (" fribble grotz \n"); + ASSERT_NE (NULL, f); + struct conf_entry *e = conf_parse (f); + ASSERT_NE (NULL, e); + EXPECT_STREQ (e->key, "fribble"); + EXPECT_STREQ (e->value, "grotz "); + EXPECT_NULL (e->next); + conf_free (e); +} + +TEST (parse_comment) +{ + FILE *f = fopenstr ("#foo bar\nbaz quxx\n"); + ASSERT_NE (NULL, f); + struct conf_entry *e = conf_parse (f); + ASSERT_NE (NULL, e); + EXPECT_STREQ (e->key, "baz"); + EXPECT_STREQ (e->value, "quxx"); + EXPECT_NULL (e->next); + conf_free (e); +} + +TEST_HARNESS_MAIN diff --git a/src/conf.c b/src/conf.c new file mode 100644 index 0000000..abb1b92 --- /dev/null +++ b/src/conf.c @@ -0,0 +1,119 @@ +/* conf.c - config file parser */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE /* strchrnul */ +#endif +#include "config.h" +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "src/conf.h" + +#ifdef TARGET_OS_NETBSD +#include "src/common/android.h" // XXX: Dirty hack - make this more generic later +#endif + +#ifdef TARGET_OS_OPENBSD +#include "src/common/android.h" // XXX: Dirty hack - make this more generic later +#endif + +#ifdef TARGET_OS_DRAGONFLYBSD +#include "src/common/android.h" // XXX: Dirty hack - make this more generic later +#endif + +#ifdef TARGET_OS_HAIKU +#include "src/common/android.h" // XXX: Dirty hack - make this more generic later +#endif + +#ifdef TARGET_OS_FREEBSD +#ifndef HAVE_STRCHRNUL +#include "src/common/android.h" // XXX: Dirty hack - make this more generic later +#endif +#endif + +#ifdef HAVE_ANDROID +#include "src/common/android.h" +#endif + +void strip_newlines (char *line) +{ + *strchrnul (line, '\n') = '\0'; + *strchrnul (line, '\r') = '\0'; +} + +char *eat_whitespace (char *line) +{ + while (isspace ((int)(unsigned char)*line)) + line++; + return line; +} + +int is_ignored_line (char *line) +{ + return !*line || *line == '#'; +} + +struct conf_entry *conf_parse (FILE *f) +{ + struct conf_entry *head = NULL; + struct conf_entry *tail = NULL; + char buf[CONF_MAX_LINE]; + + while (fgets (buf, sizeof (buf), f)) + { + struct conf_entry *e; + char *start = buf; + char *key; + char *val; + strip_newlines (start); + start = eat_whitespace (start); + if (is_ignored_line (start)) + continue; + key = strtok (start, " \t"); + val = strtok (NULL, ""); + if (val) + val = eat_whitespace (val); + e = malloc (sizeof *e); + if (!e) + goto fail; + e->next = NULL; + e->key = strdup (key); + e->value = val ? strdup (val) : NULL; + if (!e->key || (val && !e->value)) + { + free (e->key); + free (e->value); + goto fail; + } + if (!head) + { + head = e; + tail = e; + } + else + { + tail->next = e; + tail = e; + } + } + + return head; +fail: + conf_free (head); + return NULL; +} + +void conf_free (struct conf_entry *e) +{ + struct conf_entry *n; + while (e) + { + n = e->next; + free (e->key); + free (e->value); + free (e); + e = n; + } +} diff --git a/src/conf.h b/src/conf.h new file mode 100644 index 0000000..d01290b --- /dev/null +++ b/src/conf.h @@ -0,0 +1,20 @@ +/* conf.h - config file parser */ + +#ifndef CONF_H +#define CONF_H + +#include <stdio.h> + +#define CONF_MAX_LINE 16384 + +struct conf_entry +{ + struct conf_entry *next; + char *key; + char *value; +}; + +struct conf_entry *conf_parse (FILE *f); +void conf_free (struct conf_entry *e); + +#endif /* !CONF_H */ diff --git a/src/dbus.c b/src/dbus.c new file mode 100644 index 0000000..b83e9ef --- /dev/null +++ b/src/dbus.c @@ -0,0 +1,578 @@ +/* + * dbus.c - event loop dbus integration + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "config.h" + +#include <errno.h> +#include <stdio.h> +#include <stdint.h> +#include <time.h> +#include <unistd.h> + +#include <dbus/dbus.h> +#include <event2/event.h> +#include "src/dbus.h" +#include "src/tlsdate.h" +#include "src/util.h" + +/* Pointers are needed so that we don't have to deal with array-to-pointer + * weirdness with DBus argument passing. + */ +static const char kServiceInterfaceData[] = "org.torproject.tlsdate"; +static const char *kServiceInterface = kServiceInterfaceData; +static const char kServicePathData[] = "/org/torproject/tlsdate"; +static const char *kServicePath = kServicePathData; +static const char kServiceSetTimeData[] = "SetTime"; +static const char *kServiceSetTime = kServiceSetTimeData; +static const char kServiceCanSetTimeData[] = "CanSetTime"; +static const char *kServiceCanSetTime = kServiceCanSetTimeData; +static const char kServiceLastSyncInfoData[] = "LastSyncInfo"; +static const char *kServiceLastSyncInfo = kServiceLastSyncInfoData; + +static const char kTimeUpdatedData[] = "TimeUpdated"; +static const char *kTimeUpdated = kTimeUpdatedData; + +static +short +dbus_to_event (unsigned int flags) +{ + short events = 0; + if (flags & DBUS_WATCH_READABLE) + events |= EV_READ; + if (flags & DBUS_WATCH_WRITABLE) + events |= EV_WRITE; + return events; +} + +static +unsigned int +event_to_dbus (short events) +{ + unsigned int flags = 0; + if (events & EV_READ) + flags |= DBUS_WATCH_READABLE; + if (events & EV_WRITE) + flags |= DBUS_WATCH_WRITABLE; + return flags; +} + +static +void +watch_handler (evutil_socket_t fd, short what, void *arg) +{ + DBusWatch *watch = arg; + struct dbus_event_data *data = dbus_watch_get_data (watch); + unsigned int flags = event_to_dbus (what); + dbus_connection_ref (data->state->conn); + while (!dbus_watch_handle (watch, flags)) + { + info ("dbus_watch_handle waiting for memory . . ."); + /* TODO(wad) this seems like a bad idea. */ + sleep (1); + } + while (dbus_connection_dispatch (data->state->conn) == + DBUS_DISPATCH_DATA_REMAINS); + dbus_connection_unref (data->state->conn); +} + +static +dbus_bool_t +add_watch (DBusWatch *watch, void *user_data) +{ + struct state *tlsdate_state = user_data; + struct dbus_state *state = tlsdate_state->dbus; + struct dbus_event_data *data; + /* Don't add anything if it isn't active. */ + data = dbus_malloc0 (sizeof (struct dbus_event_data)); + if (!data) + return FALSE; + data->state = state; + data->event = event_new (tlsdate_state->base, + dbus_watch_get_unix_fd (watch), + EV_PERSIST|dbus_to_event (dbus_watch_get_flags (watch)), + watch_handler, + watch); + if (!data->event) + { + dbus_free (data); + return FALSE; + } + event_priority_set (data->event, PRI_WAKE); + + dbus_watch_set_data (watch, data, dbus_free); + if (!dbus_watch_get_enabled (watch)) + return TRUE; + /* Only add the event if it is enabled. */ + if (event_add (data->event, NULL)) + { + error ("Could not add a new watch!"); + event_free (data->event); + dbus_free (data); + return FALSE; + } + return TRUE; +} + +static +void +remove_watch (DBusWatch *watch, void *user_data) +{ + struct dbus_event_data *data = dbus_watch_get_data (watch); + /* TODO(wad) should this just be in a free_function? */ + if (data && data->event) + { + event_del (data->event); + event_free (data->event); + } +} + +static +void +toggle_watch (DBusWatch *watch, void *user_data) +{ + struct dbus_event_data *data = dbus_watch_get_data (watch); + if (!data || !data->event) /* should not be possible */ + return; + /* If the event is pending, then we have to remove it to + * disable it or remove it before re-enabling it. + */ + if (event_pending (data->event, + dbus_to_event (dbus_watch_get_flags (watch)), NULL)) + event_del (data->event); + if (dbus_watch_get_enabled (watch)) + { + event_add (data->event, NULL); + } +} + +static +void +timeout_handler (evutil_socket_t fd, short what, void *arg) +{ + DBusTimeout *t = arg; + struct dbus_event_data *data = dbus_timeout_get_data (t); + dbus_connection_ref (data->state->conn); + dbus_timeout_handle (t); + dbus_connection_unref (data->state->conn); +} + +static +dbus_bool_t +add_timeout (DBusTimeout *t, void *user_data) +{ + struct state *tlsdate_state = user_data; + struct dbus_state *state = tlsdate_state->dbus; + struct dbus_event_data *data; + int ms = dbus_timeout_get_interval (t); + struct timeval interval; + data = dbus_malloc0 (sizeof (struct dbus_event_data)); + if (!data) + return FALSE; + interval.tv_sec = ms / 1000; + interval.tv_usec = (ms % 1000) * 1000; + data->state = state; + data->event = event_new (tlsdate_state->base, + -1, + EV_TIMEOUT|EV_PERSIST, + timeout_handler, + t); + if (!data->event) + { + dbus_free (data); + return FALSE; + } + event_priority_set (data->event, PRI_WAKE); + dbus_timeout_set_data (t, data, dbus_free); + /* Only add it to the queue if it is enabled. */ + if (!dbus_timeout_get_enabled (t)) + return TRUE; + if (event_add (data->event, &interval)) + { + error ("Could not add a new timeout!"); + event_free (data->event); + dbus_free (data); + return FALSE; + } + return TRUE; +} + +static +void +remove_timeout (DBusTimeout *t, void *user_data) +{ + struct dbus_event_data *data = dbus_timeout_get_data (t); + if (data && data->event) + { + event_del (data->event); + event_free (data->event); + } +} + +static +void +toggle_timeout (DBusTimeout *t, void *user_data) +{ + struct dbus_event_data *data = dbus_timeout_get_data (t); + int ms = dbus_timeout_get_interval (t); + struct timeval interval; + /* If the event is pending, then we have to remove it to + * disable it or remove it before re-enabling it. + */ + if (evtimer_pending (data->event, NULL)) + event_del (data->event); + if (dbus_timeout_get_enabled (t)) + { + interval.tv_sec = ms / 1000; + interval.tv_usec = (ms % 1000) * 1000; + event_add (data->event, &interval); + } +} + +void +dbus_announce (struct state *global_state) +{ + struct dbus_state *state = global_state->dbus; + DBusConnection *conn; + DBusMessage *msg; + uint32_t ignored; + const char *sync_type = sync_type_str (global_state->last_sync_type); + +#ifndef TLSDATED_MAIN + /* Return early if we're not linked to tlsdated. */ + return; +#endif + + conn = state->conn; + msg = dbus_message_new_signal (kServicePath, kServiceInterface, kTimeUpdated); + if (!msg) + { + error ("[dbus] could not allocate new announce signal"); + return; + } + if (!dbus_message_append_args (msg, + DBUS_TYPE_STRING, &sync_type, + DBUS_TYPE_INVALID)) + { + error ("[dbus] could not allocate new announce args"); + return; + } + if (!dbus_connection_send (conn, msg, &ignored)) + { + error ("[dbus] could not send announce signal"); + return; + } +} + +static +DBusHandlerResult +send_time_reply (DBusConnection *connection, + DBusMessage *message, + dbus_uint32_t code) +{ + DBusMessage *reply; + DBusMessageIter args; + dbus_uint32_t serial = dbus_message_get_serial (message); + + reply = dbus_message_new_method_return (message); + if (!reply) + { + error ("[dbus] no memory to reply to SetTime"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_message_set_reply_serial (reply, serial)) + { + error ("[dbus] no memory to set serial for reply to SetTime"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + dbus_message_iter_init_append (reply, &args); + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_UINT32, &code)) + { + error ("[dbus] no memory to add reply args to SetTime"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_connection_send (connection, reply, &serial)) + { + error ("[dbus] unable to send SetTime reply"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + dbus_connection_flush (connection); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +DBusHandlerResult +send_can_reply (DBusConnection *connection, + DBusMessage *message, + dbus_bool_t allowed) +{ + DBusMessage *reply; + DBusMessageIter args; + dbus_uint32_t serial = dbus_message_get_serial (message); + + reply = dbus_message_new_method_return (message); + if (!reply) + { + error ("[dbus] no memory to reply to CanSetTime"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_message_set_reply_serial (reply, serial)) + { + error ("[dbus] no memory to set serial for reply to CanSetTime"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + dbus_message_iter_init_append (reply, &args); + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_BOOLEAN, &allowed)) + { + error ("[dbus] no memory to add reply args to CanSetTime"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_connection_send (connection, reply, &serial)) + { + error ("[dbus] unable to send CanSetTime reply"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + dbus_connection_flush (connection); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +/* Returns 0 if time cannot be set, and 1 otherwise. */ +static +int +can_set_time (struct state *state) +{ + time_t delta = state->clock_delta; + /* Force a synchronization check. */ + if (check_continuity (&delta) > 0) + { + info ("[event:%s] clock delta desync detected (%ld != %ld)", + __func__, state->clock_delta, delta); + delta = state->clock_delta = 0; + invalidate_time (state); + } + /* Only use the time if we're not synchronized. */ + return !state->clock_delta; +} + +static +DBusHandlerResult +handle_set_time (DBusConnection *connection, + DBusMessage *message, + struct state *state) +{ + DBusMessageIter iter; + DBusError error; + dbus_int64_t requested_time = 0; + verb_debug ("[event:%s]: fired", __func__); + dbus_error_init (&error); + + /* Expects DBUS_TYPE_INT64:<time_t> */ + if (!dbus_message_iter_init (message, &iter)) + return send_time_reply (connection, message, SET_TIME_BAD_CALL); + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INT64) + return send_time_reply (connection, message, SET_TIME_BAD_CALL); + dbus_message_iter_get_basic (&iter, &requested_time); + if (!is_sane_time ((time_t) requested_time)) + { + error ("event:%s] invalid time from user: %ld", __func__, + (time_t) requested_time); + return send_time_reply (connection, message, SET_TIME_INVALID); + } + if (!can_set_time (state)) + { + info ("[event:%s]: time is already synchronized.", __func__); + return send_time_reply (connection, message, SET_TIME_NOT_ALLOWED); + } + + state->last_time = requested_time; + state->last_sync_type = SYNC_TYPE_PLATFORM; + trigger_event (state, E_SAVE, -1); + /* Kick off a network sync for good measure. */ + action_kickoff_time_sync (-1, EV_TIMEOUT, state); + + return send_time_reply (connection, message, SET_TIME_OK); +} + +static +DBusHandlerResult +handle_can_set_time (DBusConnection *connection, + DBusMessage *message, + struct state *state) +{ + verb_debug ("[event:%s]: fired", __func__); + return send_can_reply (connection, message, can_set_time (state)); +} + +static +DBusHandlerResult +handle_last_sync_info (DBusConnection *connection, + DBusMessage *message, + struct state *state) +{ + DBusMessage *reply; + DBusMessageIter args; + dbus_uint32_t serial = dbus_message_get_serial (message); + dbus_bool_t net_synced = !!state->clock_delta; + const char *sync = sync_type_str (state->last_sync_type); + int64_t t = state->last_time; + + verb_debug ("[dbus]: handler fired"); + reply = dbus_message_new_method_return (message); + if (!reply) + { + error ("[dbus] no memory to reply to LastSyncInfo"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_message_set_reply_serial (reply, serial)) + { + error ("[dbus] no memory to set serial for reply to LastSyncInfo"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + dbus_message_iter_init_append (reply, &args); + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_BOOLEAN, &net_synced)) + { + error ("[dbus] no memory to add reply args to LastSyncInfo"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &sync)) + { + error ("[dbus] no memory to add reply args to LastSyncInfo"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_INT64, &t)) + { + error ("[dbus] no memory to add reply args to LastSyncInfo"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!dbus_connection_send (connection, reply, &serial)) + { + error ("[dbus] unable to send LastSyncInfo reply"); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + dbus_connection_flush (connection); + dbus_message_unref (reply); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +void +unregister_service (DBusConnection *conn, void *data) +{ + info ("dbus service has been unregistered"); +} + +static +DBusHandlerResult +service_dispatch (DBusConnection *conn, DBusMessage *msg, void *data) +{ + struct state *state = data; + const char *interface; + const char *method; + + verb_debug ("[dbus] service dispatcher called"); + if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_METHOD_CALL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + interface = dbus_message_get_interface (msg); + method = dbus_message_get_member (msg); + if (!interface || !method) + { + verb_debug ("[dbus] service request fired with bogus data"); + /* Consume it */ + return DBUS_HANDLER_RESULT_HANDLED; + } + if (strcmp (interface, kServiceInterface)) + { + verb_debug ("[dbus] invalid interface supplied"); + return DBUS_HANDLER_RESULT_HANDLED; + } + if (!strcmp (method, kServiceSetTime)) + return handle_set_time (conn, msg, state); + else if (!strcmp (method, kServiceCanSetTime)) + return handle_can_set_time (conn, msg, state); + else if (!strcmp (method, kServiceLastSyncInfo)) + return handle_last_sync_info (conn, msg, state); + verb_debug ("[dbus] invalid method supplied"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusObjectPathVTable service_vtable = { + .unregister_function = unregister_service, + .message_function = service_dispatch, +}; + +int +init_dbus (struct state *tlsdate_state) +{ + DBusError error; + dbus_error_init (&error); + struct dbus_state *state = calloc (1, sizeof (struct dbus_state)); + if (!state) + return 1; + tlsdate_state->dbus = state; + state->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (state->conn == NULL || dbus_error_is_set (&error)) + { + error ("[dbus] error when connecting to the bus: %s", + error.message); + goto err; + } + if (!dbus_connection_set_timeout_functions (state->conn, add_timeout, + remove_timeout, toggle_timeout, tlsdate_state, dbus_free)) + { + error ("[dbus] dbus_connection_set_timeout_functions failed"); + /* TODO(wad) disconnect from DBus */ + goto err; + } + if (!dbus_connection_set_watch_functions (state->conn, add_watch, + remove_watch, toggle_watch, tlsdate_state, dbus_free)) + { + error ("[dbus] dbus_connection_set_watch_functions failed"); + goto err; + } + if (!dbus_bus_request_name (state->conn, kServiceInterface, 0, &error) || + dbus_error_is_set (&error)) + { + error ("[dbus] failed to get name: %s", error.message); + goto err; + } + + /* Setup the vtable for dispatching incoming messages. */ + if (dbus_connection_register_object_path ( + state->conn, kServicePath, &service_vtable, tlsdate_state) == FALSE) + { + error ("[dbus] failed to register object path: %s", kServicePath); + goto err; + } + + verb_debug ("[dbus] initialized"); + return 0; +err: + tlsdate_state->dbus = NULL; + free (state); + return 1; +} diff --git a/src/dbus.h b/src/dbus.h new file mode 100644 index 0000000..296ba86 --- /dev/null +++ b/src/dbus.h @@ -0,0 +1,47 @@ +/* + * dbus.h - event loop dbus integration + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef DBUS_H_ +#define DBUS_H_ + +#include "config.h" + +#ifdef HAVE_DBUS +#include <dbus/dbus.h> + +#define SET_TIME_OK 0 +#define SET_TIME_INVALID 1 +#define SET_TIME_NOT_ALLOWED 2 +#define SET_TIME_BAD_CALL 3 + +struct state; +int init_dbus (struct state *state); + +struct dbus_state +{ + DBusConnection *conn; +}; + +struct dbus_event_data +{ + struct dbus_state *state; + struct event *event; +}; + +void dbus_announce (struct state *); + +#else /* !HAVE_DBUS */ +struct state; +static inline int init_dbus (struct state *state) +{ + return 0; +} +static inline void dbus_announce (struct state *global_state) +{ +} +#endif + +#endif /* DBUS_H_ */ diff --git a/src/events/check_continuity.c b/src/events/check_continuity.c new file mode 100644 index 0000000..9340fa1 --- /dev/null +++ b/src/events/check_continuity.c @@ -0,0 +1,77 @@ +/* + * check_continuity.c - periodically check local clock deltas + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <time.h> +#include <event2/event.h> + +#include "src/conf.h" +#include "src/tlsdate.h" +#include "src/util.h" + + +/* Returns < 0 on error, + * 0 on sync'd, + * and > 0 on desync'd. + * Old delta is in |delta|. |delta| is overwritten + * if >= 0 is returned. + * + * This event catches any sort of real-time clock jump. A jump is observed + * when settimeofday() or adjtimex() is called, or if the RTC misbehaves on + * return from suspend. If a jump is detected between a cycle-oriented clock + * (MONOTONIC_RAW) and a potentially RTC managed clock (REALTIME), then a + * network resynchronization will be required. To avoid requiring this on + * every resume-from-suspend, a larger delta represents the largest time jump + * allowed before needing a resync. + * + * Note, CLOCK_BOOTTIME does not resolve this on platforms without a persistent + * clock because the RTC still determines the time considered "suspend time". + */ +int +check_continuity (time_t *delta) +{ + time_t new_delta; + struct timespec monotonic, real; + if (clock_gettime (CLOCK_REALTIME, &real) < 0) + return -1; + if (clock_gettime (CLOCK_MONOTONIC_RAW, &monotonic) < 0) + return -1; + new_delta = real.tv_sec - monotonic.tv_sec; + if (*delta) + { + /* The allowed delta matches the interval for now. */ + static const time_t kDelta = CONTINUITY_INTERVAL; + if (new_delta < *delta - kDelta || new_delta > *delta + kDelta) + { + *delta = new_delta; + return 1; + } + } + /* First delta after de-sync. */ + *delta = new_delta; + return 0; +} + +/* Sets up a wake event just in case there has not been a wake event + * recently enough to catch clock desynchronization. This does not + * invalidate the time like the action_invalidate_time event. + */ +int setup_event_timer_continuity (struct state *state) +{ + struct event *event; + struct timeval interval = { state->opts.continuity_interval, 0 }; + event = event_new (state->base, -1, EV_TIMEOUT|EV_PERSIST, + action_kickoff_time_sync, state); + if (!event) + { + error ("Failed to create interval event"); + return 1; + } + event_priority_set (event, PRI_WAKE); + return event_add (event, &interval); +} diff --git a/src/events/kickoff_time_sync.c b/src/events/kickoff_time_sync.c new file mode 100644 index 0000000..2ed2b0b --- /dev/null +++ b/src/events/kickoff_time_sync.c @@ -0,0 +1,170 @@ +/* + * kickoff_time_sync.c - network time synchronization + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#ifdef USE_POLARSSL +#include <polarssl/entropy.h> +#include <polarssl/ctr_drbg.h> +#else +#include <openssl/rand.h> +#endif +#include <stdlib.h> +#include <time.h> +#include <unistd.h> +#include <event2/event.h> + +#include "src/conf.h" +#include "src/util.h" +#include "src/tlsdate.h" + +#ifdef USE_POLARSSL +static int random_init = 0; +static entropy_context entropy; +static ctr_drbg_context ctr_drbg; +static char *pers = "tlsdated"; +#endif + +int +add_jitter (int base, int jitter) +{ + int n = 0; + if (!jitter) + return base; +#ifdef USE_POLARSSL + if (0 == random_init) + { + entropy_init(&entropy); + if (0 > ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, + (unsigned char *) pers, strlen(pers))) + { + pfatal ("Failed to initialize random source"); + } + random_init = 1; + } + if (0 != ctr_drbg_random(&ctr_drbg, (unsigned char *)&n, sizeof(n))) + fatal ("ctr_drbg_random() failed"); +#else + if (RAND_bytes ( (unsigned char *) &n, sizeof (n)) != 1) + fatal ("RAND_bytes() failed"); +#endif + return base + (abs (n) % (2 * jitter)) - jitter; +} + +void +invalidate_time (struct state *state) +{ + state->last_sync_type = SYNC_TYPE_RTC; + state->last_time = time (NULL); + /* Note(!) this does not invalidate the clock_delta implicitly. + * This allows forced invalidation to not lose synchronization + * data. + */ +} + +void +action_invalidate_time (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + verb_debug ("[event:%s] fired", __func__); + /* If time is already invalid and being acquired, do nothing. */ + if (state->last_sync_type == SYNC_TYPE_RTC && + event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL)) + return; + /* Time out our trust in network synchronization but don't persist + * the change to disk or notify the system. Let a network sync + * failure or success do that. + */ + invalidate_time (state); + /* Then trigger a network sync if possible. */ + action_kickoff_time_sync (-1, EV_TIMEOUT, arg); +} + +int +setup_event_timer_sync (struct state *state) +{ + int wait_time = add_jitter (state->opts.steady_state_interval, + state->opts.jitter); + struct timeval interval = { wait_time, 0 }; + state->events[E_STEADYSTATE] = event_new (state->base, -1, + EV_TIMEOUT|EV_PERSIST, + action_invalidate_time, state); + if (!state->events[E_STEADYSTATE]) + { + error ("Failed to create interval event"); + return 1; + } + event_priority_set (state->events[E_STEADYSTATE], PRI_ANY); + return event_add (state->events[E_STEADYSTATE], &interval); +} + +/* Begins a network synchronization attempt. If the local clocks + * are synchronized, then make sure that the _current_ synchronization + * source is set to the real-time clock and note that the clock_delta + * is unreliable. If the clock was in sync and the last synchronization + * source was the network, then this action does nothing. + * + * In the case of desynchronization, the clock_delta value is used as a + * guard to indicate that even if the synchronization source isn't the + * network, the source is still tracking the clock delta that was + * established from a network source. + * TODO(wad) Change the name of clock_delta to indicate that it is the local + * clock delta after the last network sync. + */ +void action_kickoff_time_sync (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + verb_debug ("[event:%s] fired", __func__); + time_t delta = state->clock_delta; + int jitter = 0; + if (check_continuity (&delta) > 0) + { + info ("[event:%s] clock delta desync detected (%d != %d)", __func__, + state->clock_delta, delta); + /* Add jitter iff we had network synchronization once before. */ + if (state->clock_delta) + jitter = add_jitter (30, 30); /* TODO(wad) make configurable */ + /* Forget the old delta until we have time again. */ + state->clock_delta = 0; + invalidate_time (state); + } + if (state->last_sync_type == SYNC_TYPE_NET) + { + verb_debug ("[event:%s] time in sync. skipping", __func__); + return; + } + /* Keep parity with run_tlsdate: for every wake, allow it to retry again. */ + if (state->tries > 0) + { + state->tries -= 1; + /* Don't bother re-triggering tlsdate */ + verb_debug ("[event:%s] called while tries are in progress", __func__); + return; + } + /* Don't over-schedule if the first attempt hasn't fired. If a wake event + * impacts the result of a proxy resolution, then the updated value can be + * acquired on the next run. If the wake comes in after E_TLSDATE is + * serviced, then the tries count will be decremented. + */ + if (event_pending (state->events[E_TLSDATE], EV_TIMEOUT, NULL)) + { + verb_debug ("[event:%s] called while tlsdate is pending", __func__); + return; + } + if (!state->events[E_RESOLVER]) + { + trigger_event (state, E_TLSDATE, jitter); + return; + } + /* If the resolver relies on an external response, then make sure that a + * tlsdate event is waiting in the wings if the resolver is too slow. Even + * if this fires, it won't stop eventual handling of the resolver since it + * doesn't event_del() E_RESOLVER. + */ + trigger_event (state, E_TLSDATE, jitter + RESOLVER_TIMEOUT); + trigger_event (state, E_RESOLVER, jitter); +} diff --git a/src/events/route_up.c b/src/events/route_up.c new file mode 100644 index 0000000..0691cc7 --- /dev/null +++ b/src/events/route_up.c @@ -0,0 +1,93 @@ +/* + * route_up.c - wake events for route changes + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/routeup.h" +#include "src/tlsdate.h" +#include "src/util.h" + +void action_stdin_wakeup (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + char buf[1]; + verb_debug ("[event:%s] fired", __func__); + if (what != EV_READ) + return; + if (IGNORE_EINTR (read (fd, buf, sizeof (buf))) != sizeof (buf)) + { + error ("[event:%s] unregistering stdin handler - it's broken!", + __func__); + event_del (state->events[E_ROUTEUP]); + return; + } + action_kickoff_time_sync (-1, EV_TIMEOUT, arg); +} + +void action_netlink_ready (evutil_socket_t fd, short what, void *arg) +{ + struct routeup routeup_cfg; + verb_debug ("[event:%s] fired", __func__); + routeup_cfg.netlinkfd = fd; + if (what & EV_READ) + { + if (routeup_process (&routeup_cfg) == 0) + { + verb_debug ("[event:%s] routes changed", __func__); + /* Fire off a proxy resolution attempt and a new sync request */ + action_kickoff_time_sync (-1, EV_TIMEOUT, arg); + } + } +} + +int setup_event_route_up (struct state *state) +{ + event_callback_fn handler; + int fd = -1; + struct routeup routeup_cfg; + if (state->opts.should_netlink) + { + if (routeup_setup (&routeup_cfg)) + { + error ("routeup_setup() failed"); + return 1; + } + fd = routeup_cfg.netlinkfd; + handler = action_netlink_ready; + } + else /* Listen for cues from stdin */ + { + fd = STDIN_FILENO; + if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) + { + perror ("stdin fcntl(O_NONBLOCK) failed"); + return 1; + } + handler = action_stdin_wakeup; + } + state->events[E_ROUTEUP] = event_new (state->base, fd, + EV_READ|EV_PERSIST, handler, state); + if (!state->events[E_ROUTEUP]) + { + if (state->opts.should_netlink) + { + routeup_teardown (&routeup_cfg); + } + return 1; + } + event_priority_set (state->events[E_ROUTEUP], PRI_WAKE); + event_add (state->events[E_ROUTEUP], NULL); + return 0; +} diff --git a/src/events/run_tlsdate.c b/src/events/run_tlsdate.c new file mode 100644 index 0000000..544eb45 --- /dev/null +++ b/src/events/run_tlsdate.c @@ -0,0 +1,77 @@ +/* + * run_tlsdate.c - events for running tlsdate + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/dbus.h" +#include "src/util.h" +#include "src/tlsdate.h" + +/* TODO(wad) split out backoff logic to make this testable */ +void action_run_tlsdate (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + verb_debug ("[event:%s] fired", __func__); + if (state->last_sync_type == SYNC_TYPE_NET) + { + verb ("[event:%s] called, but network time isn't needed", + __func__); + return; + } + state->resolving = 0; + if (state->running) + { + /* It's possible that a network or proxy change occurred during a call. If + * the call succeeded, it doesn't matter. If the call fails, reissuing + * the attempt with the new configuration has a chance of succeeding. To + * avoid missing a retry, we decrement the try count and reset the + * backoff. + */ + if (state->tries > 0) + { + state->tries--; + /* TODO(wad) Make a shorter retry constant for this. */ + state->backoff = state->opts.wait_between_tries; + } + info ("[event:%s] requested re-run of tlsdate while tlsdate is running", + __func__); + return; + } + /* Enforce maximum retries here instead of in sigchld.c */ + if (state->tries < state->opts.max_tries) + { + state->tries++; + } + else + { + state->tries = 0; + state->backoff = state->opts.wait_between_tries; + error ("[event:%s] tlsdate tried and failed to get the time", __func__); + return; + } + state->running = 1; + verb ("[event:%s] attempt %d backoff %d", __func__, + state->tries, state->backoff); + /* Setup a timeout before killing tlsdate */ + trigger_event (state, E_TLSDATE_TIMEOUT, + state->opts.subprocess_wait_between_tries); + /* Add the response listener event */ + trigger_event (state, E_TLSDATE_STATUS, -1); + /* Fire off the child process now! */ + if (tlsdate (state)) + { + /* TODO(wad) Should this be fatal? */ + error ("[event:%s] tlsdate failed to launch!", __func__); + state->running = 0; + state->tries = 0; + event_del (state->events[E_TLSDATE_TIMEOUT]); + return; + } +} diff --git a/src/events/save.c b/src/events/save.c new file mode 100644 index 0000000..8fa733e --- /dev/null +++ b/src/events/save.c @@ -0,0 +1,63 @@ +/* + * save.c - send new time to the time setter + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <string.h> +#include <sys/time.h> +#include <unistd.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/util.h" +#include "src/tlsdate.h" + +void action_sync_and_save (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + time_t t = state->last_time; + ssize_t bytes; + verb_debug ("[event:%s] fired", __func__); + /* For all non-net sources, don't write to disk by + * flagging the time negative. We don't use negative + * times and this won't effect shutdown (0) writes. + */ + if (state->last_sync_type != SYNC_TYPE_NET) + t = -t; + if (what & EV_READ) + { + /* EPIPE/EBADF notification */ + error ("[event:%s] time setter is gone!", __func__); + /* SIGCHLD will handle teardown. */ + return; + } + bytes = IGNORE_EINTR (write (fd, &t, sizeof (t))); + if (bytes == -1) + { + if (errno == EPIPE) + { + error ("[event:%s] time setter is gone! (EPIPE)", __func__); + return; + } + if (errno == EAGAIN) + return; /* Get notified again. */ + error ("[event:%s] Unexpected errno %d", __func__, errno); + } + if (bytes != sizeof (t)) + pfatal ("[event:%s] unexpected write to time setter (%d)", + __func__, bytes); + /* If we're going down and we wrote the time, send a shutdown message. */ + if (state->exitting && t) + { + state->last_time = 0; + action_sync_and_save (fd, what, arg); + /* TODO(wad) platform->pgrp_kill() ? */ + } + return; +} diff --git a/src/events/sigchld.c b/src/events/sigchld.c new file mode 100644 index 0000000..66d2fe0 --- /dev/null +++ b/src/events/sigchld.c @@ -0,0 +1,141 @@ +/* + * sigchld.c - event for SIGCHLD + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <event2/event.h> +#include <sys/wait.h> +#include <sys/types.h> + +#include "src/conf.h" +#include "src/util.h" +#include "src/tlsdate.h" + +/* Returns 1 if a death was handled, otherwise 0. */ +int +handle_child_death (struct state *state) +{ + siginfo_t info; + int ret; + info.si_pid = 0; + ret = waitid (P_ALL, -1, &info, WEXITED|WNOHANG); + if (ret == -1) + { + if (errno == ECHILD) + return 0; + perror ("[event:%s] waitid() failed after SIGCHLD", __func__); + return 0; + } + if (info.si_pid == 0) + { + return 0; + } + if (info.si_pid == state->setter_pid) + { + report_setter_error (&info); + event_base_loopbreak (state->base); + return 1; + } + if (info.si_pid != state->tlsdate_pid) + { + error ("[event:%s] SIGCHLD for an unknown process -- " + "pid:%d uid:%d status:%d code:%d", __func__, + info.si_pid, info.si_uid, info.si_status, info.si_code); + return 1; + } + verb ("[event:%s] tlsdate reaped => " + "pid:%d uid:%d status:%d code:%d", __func__, + info.si_pid, info.si_uid, info.si_status, info.si_code); + + /* If it was still active, remove it. */ + event_del (state->events[E_TLSDATE_TIMEOUT]); + state->running = 0; + state->tlsdate_pid = 0; + /* Clean exit - don't rerun! */ + if (info.si_status == 0) + return 1; + verb_debug ("[event:%s] scheduling a retry", __func__); + /* Rerun a failed tlsdate */ + if (state->backoff < MAX_SANE_BACKOFF) + state->backoff *= 2; + /* If there is no resolver, call tlsdate directly. */ + if (!state->events[E_RESOLVER]) + { + trigger_event (state, E_TLSDATE, state->backoff); + return 1; + } + /* Run tlsdate even if the resolver doesn't come back. */ + trigger_event (state, E_TLSDATE, RESOLVER_TIMEOUT + state->backoff); + /* Schedule the resolver. This is always done after tlsdate in case there + * is no resolver. + */ + trigger_event (state, E_RESOLVER, state->backoff); + return 1; +} + +/* Returns 1 if a death was handled, otherwise 0. */ +int +handle_child_stop (struct state *state) +{ + /* Handle unexpected external interactions */ + siginfo_t info; + int ret; + info.si_pid = 0; + ret = waitid (P_ALL, -1, &info, WSTOPPED|WCONTINUED|WNOHANG); + if (ret == -1) + { + if (errno == ECHILD) + return 0; + perror ("[event:%s] waitid() failed after SIGCHLD", __func__); + return 0; + } + if (info.si_pid == 0) + return 0; + info ("[event:%s] a child has been STOPPED or CONTINUED. Killing it.", + __func__); + /* Kill it then catch the next SIGCHLD. */ + if (kill (info.si_pid, SIGKILL)) + { + if (errno == EPERM) + fatal ("[event:%s] cannot terminate STOPPED privileged child", + __func__); + if (errno == ESRCH) + info ("[event:%s] child gone before we could kill it", + __func__); + } + return 1; +} + +void +action_sigchld (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + verb_debug ("[event:%s] a child process has SIGCHLD'd!", __func__); + /* Process SIGCHLDs in two steps: death and stopped until all + * pending children are sorted. + */ + if (!handle_child_death (state) && !handle_child_stop (state)) + verb ("[event:%s] SIGCHLD fired but no children ready!", __func__); + while (handle_child_death (state) || handle_child_stop (state)); +} + +int +setup_sigchld_event (struct state *state, int persist) +{ + state->events[E_SIGCHLD] = event_new (state->base, SIGCHLD, + EV_SIGNAL| (persist ? EV_PERSIST : 0), + action_sigchld, state); + if (!state->events[E_SIGCHLD]) + return 1; + /* Make sure this is lower than SAVE so we get any error + * messages back from the time setter. + */ + event_priority_set (state->events[E_SIGCHLD], PRI_NET); + event_add (state->events[E_SIGCHLD], NULL); + return 0; +} diff --git a/src/events/sigterm.c b/src/events/sigterm.c new file mode 100644 index 0000000..ff09ab8 --- /dev/null +++ b/src/events/sigterm.c @@ -0,0 +1,33 @@ +/* + * sigterm.c - handler for SIGTERM + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <sys/time.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/util.h" +#include "src/tlsdate.h" + +/* On sigterm, grab the system clock and write it before terminating */ +void action_sigterm (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + struct timeval tv; + info ("[event:%s] starting graceful shutdown . . .", __func__); + state->exitting = 1; + if (platform->time_get (&tv)) + { + pfatal ("[event:%s] couldn't gettimeofday to exit gracefully", __func__); + } + /* Don't change the last sync_type */ + state->last_time = tv.tv_sec; + /* Immediately save and exit. */ + trigger_event (state, E_SAVE, -1); +} diff --git a/src/events/time_set.c b/src/events/time_set.c new file mode 100644 index 0000000..edc30c9 --- /dev/null +++ b/src/events/time_set.c @@ -0,0 +1,174 @@ +/* + * time_set.c - time setting functions + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/dbus.h" +#include "src/tlsdate.h" +#include "src/util.h" + +void +handle_time_setter (struct state *state, int status) +{ + switch (status) + { + case SETTER_BAD_TIME: + info ("[event:%s] time setter received bad time", __func__); + /* This is the leaf node. Failure means that our source + * tried to walk back in time. + */ + state->last_sync_type = SYNC_TYPE_RTC; + state->last_time = time (NULL); + break; + case SETTER_TIME_SET: + info ("[event:%s] time set from the %s (%ld)", + __func__, sync_type_str (state->last_sync_type), state->last_time); + if (state->last_sync_type == SYNC_TYPE_NET) + { + /* Update the delta so it doesn't fire again immediately. */ + state->clock_delta = 0; + check_continuity (&state->clock_delta); + /* Reset the sources list! */ + state->opts.cur_source = NULL; + } + /* Share our success. */ + if (state->opts.should_dbus) + dbus_announce (state); + break; + case SETTER_NO_SBOX: + error ("[event:%s] time setter failed to sandbox", __func__); + break; + case SETTER_EXIT: + error ("[event:%s] time setter exited gracefully", __func__); + break; + case SETTER_SET_ERR: + error ("[event:%s] time setter could not settimeofday()", __func__); + break; + case SETTER_NO_RTC: + error ("[event:%s] time setter could sync rtc", __func__); + break; + case SETTER_NO_SAVE: + error ("[event:%s] time setter could not open save file", __func__); + break; + case SETTER_READ_ERR: + error ("[event:%s] time setter could not read time", __func__); + break; + default: + error ("[event:%s] received bogus status from time setter: %d", + __func__, status); + exit (status); + } +} + +void +action_time_set (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + int status = -1; + ssize_t bytes = 0; + verb_debug ("[event:%s] fired", __func__); + bytes = IGNORE_EINTR (read (fd, &status, sizeof (status))); + if (bytes == -1 && errno == EAGAIN) + return; /* Catch next wake up */ + /* Catch the rest of the errnos and any truncation. */ + if (bytes != sizeof (status)) + { + /* Truncation of an int over a pipe shouldn't happen except in + * terminal cases. + */ + perror ("[event:%s] time setter pipe truncated! (%d)", __func__, + bytes); + /* Let SIGCHLD do the teardown. */ + close (fd); + return; + } + handle_time_setter (state, status); +} + +int +setup_time_setter (struct state *state) +{ + struct event *event; + int to_fds[2]; + int from_fds[2]; + if (pipe (to_fds) < 0) + { + perror ("pipe failed"); + return 1; + } + if (pipe (from_fds) < 0) + { + perror ("pipe failed"); + close (to_fds[0]); + close (to_fds[1]); + return 1; + } + /* The fd that tlsdated will write to */ + state->setter_save_fd = to_fds[1]; + state->setter_notify_fd = from_fds[0]; + /* Make the notifications fd non-blocking. */ + if (fcntl (from_fds[0], F_SETFL, O_NONBLOCK) < 0) + { + perror ("notifier_fd fcntl(O_NONBLOCK) failed"); + goto close_and_fail; + } + /* Make writes non-blocking */ + if (fcntl (to_fds[1], F_SETFL, O_NONBLOCK) < 0) + { + perror ("save_fd fcntl(O_NONBLOCK) failed"); + goto close_and_fail; + } + event = event_new (state->base, from_fds[0], EV_READ|EV_PERSIST, + action_time_set, state); + if (!event) + { + error ("Failed to allocate tlsdate setter event"); + goto close_and_fail; + } + event_priority_set (event, PRI_NET); + event_add (event, NULL); + /* fork */ + state->setter_pid = fork(); + if (state->setter_pid < 0) + { + perror ("fork()ing the time setter failed"); + goto close_and_fail; + } + if (state->setter_pid == 0) + { + close (to_fds[1]); + close (from_fds[0]); + time_setter_coprocess (to_fds[0], from_fds[1], state); + _exit (1); + } + close (from_fds[1]); + close (to_fds[0]); + return 0; + +close_and_fail: + close (to_fds[0]); + close (to_fds[1]); + close (from_fds[0]); + close (from_fds[1]); + return 1; +} diff --git a/src/events/tlsdate_status.c b/src/events/tlsdate_status.c new file mode 100644 index 0000000..9c6a6a9 --- /dev/null +++ b/src/events/tlsdate_status.c @@ -0,0 +1,148 @@ +/* + * tlsdate_status.c - handles tlsdate-monitor responses + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/util.h" +#include "src/tlsdate.h" + +/* Returns < 0 on error, > 0 on eagain, and 0 on success */ +int +read_tlsdate_response (int fd, time_t *t) +{ + /* TLS passes time as a 32-bit value. */ + uint32_t server_time = 0; + ssize_t ret = IGNORE_EINTR (read (fd, &server_time, sizeof (server_time))); + if (ret == -1 && errno == EAGAIN) + { + /* Full response isn't ready yet. */ + return 1; + } + if (ret != sizeof (server_time)) + { + /* End of pipe (0) or truncated: death probable. */ + error ("[event:(%s)] invalid time read from tlsdate (rd:%d,ret:%zd).", + __func__, server_time, ret); + return -1; + } + /* uint32_t moves to signed long so there is room for silliness. */ + *t = server_time; + return 0; +} + +void +action_tlsdate_timeout (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + info ("[event:%s] tlsdate timed out", __func__); + /* Force kill it and let action_sigchld rerun. */ + if (state->tlsdate_pid) + kill (state->tlsdate_pid, SIGKILL); +} + +void +action_tlsdate_status (evutil_socket_t fd, short what, void *arg) +{ + struct state *state = arg; + time_t t = 0; + int ret = read_tlsdate_response (fd, &t); + verb_debug ("[event:%s] fired", __func__); + if (ret < 0) + { + verb_debug ("[event:%s] forcibly timing out tlsdate", __func__); + trigger_event (state, E_TLSDATE_TIMEOUT, 0); + return; + } + if (ret) + { + /* EAGAIN'd: wait for the rest. */ + trigger_event (state, E_TLSDATE_STATUS, -1); + return; + } + if (is_sane_time (t)) + { + /* Note that last_time is from an online source */ + state->last_sync_type = SYNC_TYPE_NET; + state->last_time = t; + trigger_event (state, E_SAVE, -1); + } + else + { + error ("[event:%s] invalid time received from tlsdate: %ld", + __func__, t); + } + /* Restore the backoff and tries count on success, insane or not. + * On failure, the event handler does it. + */ + state->tries = 0; + state->backoff = state->opts.wait_between_tries; + return; +} + +/* Returns 0 on success and populates |fds| */ +int +new_tlsdate_monitor_pipe (int fds[2]) +{ + if (pipe (fds) < 0) + { + perror ("pipe failed"); + return -1; + } + /* TODO(wad): CLOEXEC, Don't leak these into tlsdate proper. */ + return 0; +} + +/* Create a fd pair that the tlsdate runner will communicate over */ +int +setup_tlsdate_status (struct state *state) +{ + int fds[2] = { -1, -1 }; + /* One pair of pipes are reused along with the event. */ + if (new_tlsdate_monitor_pipe (fds)) + { + return -1; + } + verb_debug ("[%s] monitor fd pair (%d, %d)", __func__, fds[0], fds[1]); + /* The fd that the monitor process will write to */ + state->tlsdate_monitor_fd = fds[1]; + /* Make the reader fd non-blocking and not leak into tlsdate. */ + if (fcntl (fds[0], F_SETFL, O_NONBLOCK|O_CLOEXEC) < 0) + { + perror ("pipe[0] fcntl(O_NONBLOCK) failed"); + return 1; + } + state->events[E_TLSDATE_STATUS] = event_new (state->base, fds[0], + EV_READ, + action_tlsdate_status, state); + if (!state->events[E_TLSDATE_STATUS]) + { + error ("Failed to allocate tlsdate status event"); + return 1; + } + event_priority_set (state->events[E_TLSDATE_STATUS], PRI_NET); + state->events[E_TLSDATE_TIMEOUT] = event_new (state->base, -1, + EV_TIMEOUT, + action_tlsdate_timeout, state); + if (!state->events[E_TLSDATE_TIMEOUT]) + { + error ("Failed to allocate tlsdate timeout event"); + return 1; + } + event_priority_set (state->events[E_TLSDATE_TIMEOUT], PRI_SAVE); + return 0; +} diff --git a/src/include.am b/src/include.am new file mode 100644 index 0000000..ec091e5 --- /dev/null +++ b/src/include.am @@ -0,0 +1,489 @@ +# vim:ft=automake + +src_tlsdate_SOURCES= +src_tlsdate_LDADD= + +src_tlsdate_helper_CFLAGS= +src_tlsdate_helper_SOURCES= +src_tlsdate_helper_LDADD= + +include src/compat/include.am + +# Our main program +if TARGET_LINUX +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +if HAVE_SECCOMP_FILTER +src_tlsdate_helper_SOURCES+= src/seccomp.c +endif + +sbin_PROGRAMS+= src/tlsdated + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c + +if HAVE_ANDROID +src_conf_unittest_SOURCES+= src/common/android.c src/common/fmemopen.c +endif + +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif # TARGET_LINUX + +if TARGET_GNUKFREEBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +if !HAVE_STRCHRNUL +src_conf_unittest_SOURCES+= src/common/android.c +endif +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_FREEBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +if !HAVE_STRCHRNUL +src_conf_unittest_SOURCES+= src/common/android.c +endif +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_NETBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c + +# XXX This conditional should apply for any system where we're building +# conf_unittest, but I don't know how to tell that to automake. +if !HAVE_FMEMOPEN +if HAVE_FUNOPEN +src_conf_unittest_SOURCES+= src/common/fmemopen-funopen.c +endif +endif + +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_OPENBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +src_conf_unittest_SOURCES+= src/common/fmemopen.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_DRAGONFLYBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_BSD +if !TARGET_FREEBSD +if !TARGET_NETBSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif +endif +endif + +if TARGET_GNUHURD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_CYGWIN +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_MINGW +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_HAIKU +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif + +if TARGET_OSX +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper +endif + +src_tlsdate_SOURCES+= src/tlsdate.c +src_tlsdate_CFLAGS = -DBUILDING_TLSDATE + +src_tlsdate_helper_CFLAGS+= @SSL_CFLAGS@ +src_tlsdate_helper_LDADD+= @SSL_LIBS@ +src_tlsdate_helper_LDADD+= src/compat/libtlsdate_compat.la +src_tlsdate_helper_SOURCES+= src/tlsdate-helper.c + +if POLARSSL +src_tlsdate_helper_SOURCES+= src/proxy-polarssl.c +else +# OpenSSL is our default if we're not using PolarSSL +src_tlsdate_helper_SOURCES+= src/proxy-bio.c +endif +src_tlsdate_helper_SOURCES+= src/util.c + +if !HAVE_STRNLEN +src_tlsdate_helper_SOURCES+= src/common/strnlen.c +endif + +# This doesn't work on Mac OS X +if TARGET_LINUX + +src_tlsdated_CFLAGS = $(DBUS_CFLAGS) $(LIBEVENT_CFLAGS) @SSL_CFLAGS@ +src_tlsdated_CPPFLAGS = -DTLSDATED_MAIN -DWITH_EVENTS +if SECCOMP_FILTER_DEBUG +src_tlsdated_CPPFLAGS += -DSECCOMP_FILTER_DEBUG=1 +endif +src_tlsdated_LDADD = @SSL_LIBS@ $(RT_LIB) $(DBUS_LIBS) $(LIBEVENT_LIBS) +src_tlsdated_SOURCES = src/conf.c + +if HAVE_ANDROID +src_tlsdated_SOURCES+= src/common/android.c +endif + +# This doesn't work on Mac OS X or FreeBSD +if TARGET_LINUX +src_tlsdated_SOURCES+= src/routeup.c +endif + +if HAVE_DBUS +src_tlsdated_SOURCES+= src/dbus.c +endif +if HAVE_CROS +src_tlsdated_SOURCES+= src/platform-cros.c +endif +if HAVE_SECCOMP_FILTER +src_tlsdated_SOURCES+= src/seccomp.c +endif +src_tlsdated_SOURCES+= src/tlsdate-monitor.c +src_tlsdated_SOURCES+= src/tlsdate-setter.c +src_tlsdated_SOURCES+= src/tlsdated.c +src_tlsdated_SOURCES+= src/util.c +src_tlsdated_SOURCES+= src/events/check_continuity.c +src_tlsdated_SOURCES+= src/events/kickoff_time_sync.c +src_tlsdated_SOURCES+= src/events/route_up.c +src_tlsdated_SOURCES+= src/events/run_tlsdate.c +src_tlsdated_SOURCES+= src/events/sigterm.c +src_tlsdated_SOURCES+= src/events/sigchld.c +src_tlsdated_SOURCES+= src/events/save.c +src_tlsdated_SOURCES+= src/events/time_set.c +src_tlsdated_SOURCES+= src/events/tlsdate_status.c + +src_tlsdated_unittest_CFLAGS = $(DBUS_CFLAGS) $(LIBEVENT_CFLAGS) +src_tlsdated_unittest_CPPFLAGS = -DWITH_EVENTS +if SECCOMP_FILTER_DEBUG +src_tlsdated_unittest_CPPFLAGS += -DSECCOMP_FILTER_DEBUG=1 +endif +src_tlsdated_unittest_LDADD = @SSL_LIBS@ $(RT_LIB) $(DBUS_LIBS) $(LIBEVENT_LIBS) +src_tlsdated_unittest_SOURCES = src/tlsdated-unittest.c +src_tlsdated_unittest_SOURCES+= $(src_tlsdated_SOURCES) + +check_PROGRAMS+= src/tlsdated_unittest +noinst_PROGRAMS+= src/tlsdated_unittest +endif + +# This doesn't work on Mac OS X +if TARGET_LINUX +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +if HAVE_SECCOMP_FILTER +src_proxy_bio_unittest_SOURCES+= src/seccomp.c +endif +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_FREEBSD +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +if !HAVE_STRCHRNUL +src_proxy_bio_unittest_SOURCES+= src/common/android.c +endif +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +# XXX This conditional should apply for any system where we're building +# conf_unittest, but I don't know how to tell that to automake. +if !HAVE_FMEMOPEN +if HAVE_FUNOPEN +src_conf_unittest_SOURCES+= src/common/fmemopen-funopen.c +endif +endif +endif + +if TARGET_NETBSD +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c + +# XXX This conditional should apply for any system where we're building +# proxy_bio_unittest, but I don't know how to tell that to automake. +if !HAVE_STRNLEN +src_proxy_bio_unittest_SOURCES+= src/common/strnlen.c +endif + +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_OPENBSD +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +src_proxy_bio_unittest_SOURCES+= src/common/fmemopen.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_DRAGONFLYBSD +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_BSD +if !POLARSSL +if !TARGET_FREEBSD +if !TARGET_NETBSD +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif +endif +endif + +if TARGET_GNUHURD +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_CYGWIN +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_MINGW +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +if TARGET_HAIKU +if !POLARSSL +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest +endif +endif + +# We're not shipping headers +noinst_HEADERS+= src/routeup.h +noinst_HEADERS+= src/test_harness.h +noinst_HEADERS+= src/tlsdate-helper.h +noinst_HEADERS+= src/seccomp.h +noinst_HEADERS+= src/seccomp-compat.h +noinst_HEADERS+= src/tlsdate.h +noinst_HEADERS+= src/util.h +noinst_HEADERS+= src/visibility.h +noinst_HEADERS+= src/proxy-bio.h +noinst_HEADERS+= src/proxy-polarssl.h +noinst_HEADERS+= src/test-bio.h +noinst_HEADERS+= src/conf.h +noinst_HEADERS+= src/dbus.h +noinst_HEADERS+= src/platform.h + +if HAVE_ANDROID +noinst_HEADERS+= src/common/android.h +endif + +# This is our explicit target list +# We do not attempt to build with PolarSSL +if !POLARSSL +if !TARGET_LINUX +if !TARGET_OSX +if !TARGET_OPENBSD +if !TARGET_NETBSD +if !TARGET_FREEBSD +if !TARGET_DRAGONFLYBSD +if !TARGET_HAIKU +if !TARGET_GNUHURD +if !TARGET_CYGWIN +if !TARGET_MINGW +if !TARGET_BSD +bin_PROGRAMS+= src/tlsdate +bin_PROGRAMS+= src/tlsdate-helper + +src_conf_unittest_SOURCES = src/conf.c +src_conf_unittest_SOURCES+= src/conf-unittest.c +src_conf_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/conf_unittest +noinst_PROGRAMS+= src/conf_unittest +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif + +if !POLARSSL +if !TARGET_LINUX +if !TARGET_OSX +if !TARGET_OPENBSD +if !TARGET_NETBSD +if !TARGET_FREEBSD +if !TARGET_GNUKFREEBSD +if !TARGET_DRAGONFLYBSD +if !TARGET_HAIKU +if !TARGET_GNUHURD +if !TARGET_CYGWIN +if !TARGET_MINGW +if !TARGET_BSD +src_proxy_bio_unittest_LDADD = @SSL_LIBS@ +src_proxy_bio_unittest_SOURCES = src/proxy-bio.c +src_proxy_bio_unittest_SOURCES+= src/proxy-bio-unittest.c +src_proxy_bio_unittest_SOURCES+= src/test-bio.c +src_proxy_bio_unittest_SOURCES+= src/util.c +src_proxy_bio_unittest_SOURCES+= src/common/android.c +check_PROGRAMS+= src/proxy-bio_unittest +noinst_PROGRAMS+= src/proxy-bio_unittest + +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif +endif + + +check_PROGRAMS+= src/test/proxy-override src/test/check-host-1 \ + src/test/check-host-2 src/test/sleep-wrap \ + src/test/return-argc src/test/emit diff --git a/src/platform-cros.c b/src/platform-cros.c new file mode 100644 index 0000000..5a9d7ab --- /dev/null +++ b/src/platform-cros.c @@ -0,0 +1,613 @@ +/* + * platform-cros.c - CrOS platform DBus integration + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "config.h" + +#include <ctype.h> +#include <dbus/dbus.h> +#include <errno.h> +#include <signal.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <time.h> + +#include <event2/event.h> + +#include "src/dbus.h" +#include "src/platform.h" +#include "src/tlsdate.h" +#include "src/util.h" + +static const char kMatchFormatData[] = "interface='%s',member='%s',arg0='%s'"; +static const char *kMatchFormat = kMatchFormatData; +static const char kMatchNoArgFormatData[] = "interface='%s',member='%s'"; +static const char *kMatchNoArgFormat = kMatchNoArgFormatData; + +static const char kLibCrosDestData[] = "org.chromium.LibCrosService"; +static const char *kLibCrosDest = kLibCrosDestData; +static const char kLibCrosInterfaceData[] = "org.chromium.LibCrosServiceInterface"; +static const char *kLibCrosInterface = kLibCrosInterfaceData; +static const char kLibCrosPathData[] = "/org/chromium/LibCrosService"; +static const char *kLibCrosPath = kLibCrosPathData; +static const char kResolveNetworkProxyData[] = "ResolveNetworkProxy"; +static const char *kResolveNetworkProxy = kResolveNetworkProxyData; + +static const char kDBusInterfaceData[] = "org.freedesktop.DBus"; +static const char *kDBusInterface = kDBusInterfaceData; +static const char kNameOwnerChangedData[] = "NameOwnerChanged"; +static const char *kNameOwnerChanged = kNameOwnerChangedData; +static const char kNameAcquiredData[] = "NameAcquired"; +static const char *kNameAcquired = kNameAcquiredData; + +static const char kManagerInterfaceData[] = "org.chromium.flimflam.Manager"; +static const char *kManagerInterface = kManagerInterfaceData; + +static const char kServiceInterfaceData[] = "org.chromium.flimflam.Service"; +static const char *kServiceInterface = kServiceInterfaceData; +static const char kMemberData[] = "PropertyChanged"; +static const char *kMember = kMemberData; + +static const char kProxyConfigData[] = "ProxyConfig"; +static const char *kProxyConfig = kProxyConfigData; +static const char kDefaultServiceData[] = "DefaultService"; +static const char *kDefaultService = kDefaultServiceData; + +static const char kResolveInterfaceData[] = "org.torproject.tlsdate.Resolver"; +static const char *kResolveInterface = kResolveInterfaceData; +static const char kResolveMemberData[] = "ProxyChange"; +static const char *kResolveMember = kResolveMemberData; + +/* TODO(wad) Integrate with cros_system_api/dbus/service_constants.h */ +static const char kPowerManagerInterfaceData[] = "org.chromium.PowerManager"; +static const char *kPowerManagerInterface = kPowerManagerInterfaceData; +static const char kSuspendDoneData[] = "SuspendDone"; +static const char *kSuspendDone = kSuspendDoneData; + +static const char kErrorServiceUnknownData[] = "org.freedesktop.DBus.Error.ServiceUnknown"; +static const char *kErrorServiceUnknown = kErrorServiceUnknownData; + +struct platform_state +{ + struct event_base *base; + struct state *state; + DBusMessage **resolve_msg; + int resolve_msg_count; + uint32_t resolve_network_proxy_serial; +}; + +static +bool +get_valid_hostport (const char *hostport, char *out, size_t len) +{ + bool host = true; + const char *end = hostport + strlen (hostport); + const char *c; + *out = '\0'; + /* Hosts begin with alphanumeric only. */ + if (!isalnum (*hostport)) + { + info ("Host does not start with alnum"); + return false; + } + *out++ = *hostport; + for (c = hostport + 1; c < end && len > 0; ++c, ++out, --len) + { + *out = *c; + if (host) + { + if (isalnum (*c) || *c == '-' || *c == '.') + { + continue; + } + if (*c == ':') + { + host = false; + continue; + } + } + else + { + if (isdigit (*c)) + continue; + } + *out = '\0'; + return false; + } + *out = '\0'; + return true; +} + +/* Convert PAC return format to tlsdated url format */ +/* TODO(wad) support multiple proxies when Chromium does: + * PROXY x.x.x.x:yyyy; PROXY z.z.z.z:aaaaa + */ +static +void +canonicalize_pac (const char *pac_fmt, char *proxy_url, size_t len) +{ + size_t type_len; + size_t copied = 0; + const char *space; + /* host[255]:port[6]\0 */ + char hostport[6 + 255 + 2]; + proxy_url[0] = '\0'; + if (len < 1) + return; + if (!strcmp (pac_fmt, "DIRECT")) + { + return; + } + /* Find type */ + space = strchr (pac_fmt, ' '); + if (!space) + return; + type_len = space - pac_fmt; + if (!get_valid_hostport (space + 1, hostport, sizeof (hostport))) + { + error ("invalid host:port: %s", space + 1); + return; + } + proxy_url[0] = '\0'; + if (!strncmp (pac_fmt, "PROXY", type_len)) + { + copied = snprintf (proxy_url, len, "http://%s", hostport); + } + else if (!strncmp (pac_fmt, "SOCKS", type_len)) + { + copied = snprintf (proxy_url, len, "socks4://%s", hostport); + } + else if (!strncmp (pac_fmt, "SOCKS5", type_len)) + { + copied = snprintf (proxy_url, len, "socks5://%s", hostport); + } + else if (!strncmp (pac_fmt, "HTTPS", type_len)) + { + copied = snprintf (proxy_url, len, "https://%s", hostport); + } + else + { + error ("pac_fmt unmatched: '%s' %zu", pac_fmt, type_len); + } + if (copied >= len) + { + error ("canonicalize_pac: truncation '%s'", proxy_url); + proxy_url[0] = '\0'; + return; + } +} + +static +DBusHandlerResult +handle_service_change (DBusConnection *connection, + DBusMessage *message, + struct platform_state *ctx) +{ + DBusMessageIter iter, subiter; + DBusError error; + const char *pname; + const char *pval; + const char *service; + dbus_error_init (&error); + verb_debug ("[event:cros:%s]: fired", __func__); + /* TODO(wad) Track the current DefaultService only fire when it changes */ + service = dbus_message_get_path (message); + if (!service) + return DBUS_HANDLER_RESULT_HANDLED; + /* Shill emits string:ProxyConfig variant string:"..." */ + if (!dbus_message_iter_init (message, &iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&iter, &pname); + /* Make sure we are only firing on a ProxyConfig property change. */ + if (strcmp (pname, kProxyConfig)) + return DBUS_HANDLER_RESULT_HANDLED; + if (!dbus_message_iter_next (&iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_recurse (&iter, &subiter); + if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&subiter, &pval); + /* Right now, nothing is done with the Shill proxy value because + * Chromium handles .pac resolution. This may be more useful for + * ignoring incomplete proxy values sent while a user is typing. + */ + action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +DBusHandlerResult +handle_manager_change (DBusConnection *connection, + DBusMessage *message, + struct platform_state *ctx) +{ + DBusMessageIter iter, subiter; + DBusError error; + const char *pname; + const char *pval; + verb_debug ("[event:cros:%s]: fired", __func__); + dbus_error_init (&error); + if (!dbus_message_iter_init (message, &iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&iter, &pname); + /* Make sure we caught the right property. */ + if (strcmp (pname, kDefaultService)) + return DBUS_HANDLER_RESULT_HANDLED; + if (!dbus_message_iter_next (&iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_recurse (&iter, &subiter); + if (dbus_message_iter_get_arg_type (&subiter) != DBUS_TYPE_OBJECT_PATH) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&subiter, &pval); + /* TODO(wad) Filter on the currently active service in pval. */ + verb_debug ("[event:cros:%s] service change on path %s", + __func__, pval); + action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +DBusHandlerResult +handle_suspend_done (DBusConnection *connection, + DBusMessage *message, + struct platform_state *ctx) +{ + DBusMessageIter iter; + DBusError error; + const char *pname; + verb_debug ("[event:cros:%s]: fired", __func__); + /* Coming back from resume, trigger a continuity and time + * check just in case none of the other events happen. + */ + action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +DBusHandlerResult +handle_proxy_change (DBusConnection *connection, + DBusMessage *message, + struct platform_state *ctx) +{ + DBusMessageIter iter; + DBusError error; + const char *pname; + const char *pval; + char time_host[MAX_PROXY_URL]; + int url_len = 0; + struct source *src = ctx->state->opts.sources; + verb_debug ("[event:cros:%s]: fired", __func__); + if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next) + src = ctx->state->opts.cur_source->next; + if (!ctx->state->resolving) + { + info ("[event:cros:%s] Unexpected ResolveNetworkProxy signal seen", + __func__); + return DBUS_HANDLER_RESULT_HANDLED; + } + dbus_error_init (&error); + /* Shill emits string:ProxyConfig variant string:"..." */ + if (!dbus_message_iter_init (message, &iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&iter, &pname); + /* Make sure this was the resolution we asked for */ + url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s", + src->host, src->port); + if (url_len >= sizeof (time_host)) + { + error ("[event:cros:%s]: current source url is too long", + __func__); + } + if (strcmp (pname, time_host)) + { + error ("[event:cros:%s]: resolved host mismatch: %s v %s", + __func__, pname, time_host); + return DBUS_HANDLER_RESULT_HANDLED; + } + if (!dbus_message_iter_next (&iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&iter, &pval); + ctx->state->resolving = 0; + canonicalize_pac (pval, ctx->state->dynamic_proxy, sizeof (ctx->state->dynamic_proxy)); + trigger_event (ctx->state, E_TLSDATE, 1); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +DBusHandlerResult +handle_dbus_change (DBusConnection *connection, + DBusMessage *message, + struct platform_state *ctx) +{ + DBusMessageIter iter; + DBusError error; + const char *pname; + verb_debug ("[event:cros:%s]: fired", __func__); + dbus_error_init (&error); + if (!dbus_message_iter_init (message, &iter)) + return DBUS_HANDLER_RESULT_HANDLED; + if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) + return DBUS_HANDLER_RESULT_HANDLED; + dbus_message_iter_get_basic (&iter, &pname); + /* Make sure we caught the right property. */ + if (strcmp (pname, kLibCrosDest)) + return DBUS_HANDLER_RESULT_HANDLED; + action_kickoff_time_sync (-1, EV_TIMEOUT, ctx->state); + return DBUS_HANDLER_RESULT_HANDLED; +} + +static +void +action_resolve_proxy (evutil_socket_t fd, short what, void *arg) +{ + struct platform_state *ctx = arg; + struct dbus_state *dbus_state = ctx->state->dbus; + DBusConnection *conn = dbus_state->conn; + struct source *src = ctx->state->opts.sources; + verb_debug ("[event:%s] fired", __func__); + /* Emulate tlsdate-monitor.c:build_argv and choose the next source */ + if (ctx->state->opts.cur_source && ctx->state->opts.cur_source->next) + src = ctx->state->opts.cur_source->next; + if (ctx->state->resolving || ctx->resolve_network_proxy_serial) + { + /* Note, this is not the same as the response signal. It just avoids + * multiple requests in a single dispatch window. + */ + info ("[event:%s] no resolve_proxy sent; pending method_reply", + __func__); + return; + } + ctx->state->dynamic_proxy[0] = '\0'; + if (ctx->resolve_msg[src->id] == NULL) + { + info ("[event:%s] no dynamic proxy for %s:%s", __func__, + src->host, src->port); + trigger_event (ctx->state, E_TLSDATE, 1); + return; + } + info ("[event:%s] resolving proxy for %s:%s", __func__, + src->host, src->port); + ctx->state->resolving = 1; + if (!dbus_connection_send (conn, + ctx->resolve_msg[src->id], + &ctx->resolve_network_proxy_serial)) + { + error ("[event:%s] cannot send ResolveNetworkProxy query!", __func__); + return; + } +} + +static +DBusHandlerResult +dbus_filter (DBusConnection *connection, DBusMessage *message, void *data) +{ + struct platform_state *state = data; + /* Terminate gracefully if DBus goes away. */ + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) + { + error ("[cros] DBus system bus has become inaccessible. Terminating."); + /* Trigger a graceful teardown. */ + kill (getpid(), SIGINT); + return DBUS_HANDLER_RESULT_HANDLED; + } + /* Hand it over to the service dispatcher. */ + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + /* Handle explicitly defined signals only. */ + if (dbus_message_is_signal (message, kDBusInterface, kNameAcquired)) + { + info ("[cros] DBus name acquired successfully"); + return DBUS_HANDLER_RESULT_HANDLED; + } + if (dbus_message_is_signal (message, kServiceInterface, kMember)) + return handle_service_change (connection, message, state); + if (dbus_message_is_signal (message, kManagerInterface, kMember)) + return handle_manager_change (connection, message, state); + if (dbus_message_is_signal (message, kResolveInterface, kResolveMember)) + return handle_proxy_change (connection, message, state); + if (dbus_message_is_signal (message, kDBusInterface, kNameOwnerChanged)) + return handle_dbus_change (connection, message, state); + if (dbus_message_is_signal (message, kPowerManagerInterface, kSuspendDone)) + return handle_suspend_done (connection, message, state); + if (dbus_message_is_error (message, kErrorServiceUnknown)) + { + info ("[cros] org.chromium.LibCrosService.ResolveNetworkProxy is missing"); + info ("[cros] skipping proxy resolution for now"); + /* Fire off tlsdate rather than letting it fail silently. */ + state->resolve_network_proxy_serial = 0; + state->state->resolving = 0; + trigger_event (state->state, E_TLSDATE, 1); + return DBUS_HANDLER_RESULT_HANDLED; + } + /* Indicates a successful resolve request was issued. */ + if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN) + { + uint32_t serial = dbus_message_get_reply_serial (message); + if (serial == state->resolve_network_proxy_serial) + { + state->resolve_network_proxy_serial = 0; + return DBUS_HANDLER_RESULT_HANDLED; + } + info ("[cros] unknown DBus METHOD_RETURN seen: %u", serial); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + verb_debug ("[cros] unknown message received: " + "type=%s dest=%s interface=%s member=%s path=%s sig=%s error_name=%s", + dbus_message_type_to_string (dbus_message_get_type (message)), + dbus_message_get_destination (message), + dbus_message_get_interface (message), + dbus_message_get_member (message), + dbus_message_get_path (message), + dbus_message_get_signature (message), + dbus_message_get_error_name (message)); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int +add_match (DBusConnection *conn, const char *interface, const char *member, + const char *arg0) +{ + char match[1024]; + DBusError error; + int len; + dbus_error_init (&error); + if (arg0) + { + len = snprintf (match, sizeof (match), kMatchFormat, + interface, member, arg0); + } + else + { + len = snprintf (match, sizeof (match), kMatchNoArgFormat, + interface, member); + } + if (len >= sizeof (match) || len < 0) + { + error ("[dbus] match truncated for '%s,%s'", interface, member); + return 1; + } + dbus_bus_add_match (conn, match, &error); + if (dbus_error_is_set (&error)) + { + error ("[dbus] failed to add_match for '%s,%s'; error: %s, %s", + interface, member, error.name, error.message); + dbus_error_free (&error); + return 1; + } + return 0; +} + +DBusMessage * +new_resolver_message(const struct source *src) +{ + char time_host[MAX_PROXY_URL]; + void *time_host_ptr = &time_host; + int url_len; + DBusMessage *res; + DBusMessageIter args; + if (!src->proxy || strcmp (src->proxy, "dynamic")) + { + return NULL; + } + res = dbus_message_new_method_call (kLibCrosDest, kLibCrosPath, + kLibCrosInterface, kResolveNetworkProxy); + if (!res) + { + error ("[cros] could not setup dynamic proxy for source %d", src->id); + return NULL; + } + /* Build the time_host */ + url_len = snprintf (time_host, sizeof (time_host), "https://%s:%s", + src->host, src->port); + if (url_len >= sizeof (time_host)) + { + fatal ("[cros] source %d url is too long! (%d)", src->id, url_len); + } + /* Finish the message */ + dbus_message_iter_init_append (res, &args); + if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &time_host_ptr) || + !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveInterface) || + !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &kResolveMember)) + { + fatal ("[cros could not append arguments for resolver message"); + } + return res; +} + +int +platform_init_cros (struct state *state) +{ + /* Watch for per-service ProxyConfig property changes */ + struct event_base *base = state->base; + struct dbus_state *dbus_state = state->dbus; + struct source *src = NULL; + int sources = 0; + DBusConnection *conn = dbus_state->conn; + DBusError error; + struct platform_state *platform_state = + calloc (1, sizeof (struct platform_state)); + if (!platform_state) + { + error ("[cros] could not allocate platform_state"); + return -1; + } + /* TODO(wad) Follow up with dbus_error_free() where needed. */ + dbus_error_init (&error); + /* Add watches for: proxy changes, default service changes, proxy resolution, + * LibCrosService ownership, and power state changes. + */ + if (add_match (conn, kServiceInterface, kMember, kProxyConfig) || + add_match (conn, kManagerInterface, kMember, kDefaultService) || + add_match (conn, kResolveInterface, kResolveMember, NULL) || + add_match (conn, kDBusInterface, kNameOwnerChanged, kLibCrosDest) || + add_match (conn, kPowerManagerInterface, kSuspendDone, NULL)) + return 1; + + /* Allocate one per source */ + for (src = state->opts.sources; src; src = src->next, ++sources); + platform_state->resolve_msg_count = sources; + platform_state->resolve_msg = calloc (sources, sizeof (DBusMessage *)); + if (!platform_state->resolve_msg) + { + error ("[cros] cannot allocate resolver messages"); + free (platform_state); + return -1; + } + for (src = state->opts.sources; src; src = src->next) + { + if (src->id >= sources) + fatal ("Source ID is greater than available sources!"); + platform_state->resolve_msg[src->id] = new_resolver_message (src); + if (platform_state->resolve_msg[src->id]) + src->proxy = state->dynamic_proxy; + } + state->dynamic_proxy[0] = '\0'; + if (state->opts.proxy && !strcmp (state->opts.proxy, "dynamic")) + { + info ("[cros] default dynamic proxy support"); + state->opts.proxy = state->dynamic_proxy; + } + platform_state->base = base; + platform_state->state = state; + /* Add the dynamic resolver if tlsdate doesn't already have one. */ + if (!state->events[E_RESOLVER]) + { + state->events[E_RESOLVER] = event_new (base, -1, EV_TIMEOUT, + action_resolve_proxy, + platform_state); + if (!state->events[E_RESOLVER]) + /* Let's not clean up DBus. */ + fatal ("Could not allocated resolver event"); + /* Wake up as a NET event since it'll self-block until DBus has a chance + * to send it. + */ + event_priority_set (state->events[E_RESOLVER], PRI_NET); + } + /* Each platform can attach their own filter, but the filter func needs to be + * willing to DBUS_HANDLER_RESULT_NOT_YET_HANDLED on unexpected events. + */ + /* TODO(wad) add the clean up function as the callback. */ + if (!dbus_connection_add_filter (conn, + dbus_filter, platform_state, NULL)) + { + error ("Failed to register signal handler callback"); + return 1; + } + return 0; +} diff --git a/src/platform.h b/src/platform.h new file mode 100644 index 0000000..f17efa2 --- /dev/null +++ b/src/platform.h @@ -0,0 +1,21 @@ +/* + * platform.h - platform handlers for event loops + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef PLATFORM_H_ +#define PLATFORM_H_ +#include "config.h" + +struct state; + +#ifdef HAVE_CROS +int platform_init_cros (struct state *state); +#else +static inline int platform_init_cros (struct state *state) +{ + return 0; +} +#endif /* HAVE_CROS */ +#endif /* PLATFORM_H_ */ diff --git a/src/proxy-bio-plan9.c b/src/proxy-bio-plan9.c new file mode 100644 index 0000000..98d3f97 --- /dev/null +++ b/src/proxy-bio-plan9.c @@ -0,0 +1,449 @@ +/* + * proxy-bio.c - BIO layer for SOCKS4a/5 proxy connections + * + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file implements a SOCKS4a/SOCKS5 "filter" BIO. In SSL terminology, a BIO + * is a stackable IO filter, kind of like sysv streams. These filters are + * inserted into a stream to cause it to run SOCKS over whatever transport is + * being used. Most commonly, this would be: + * SSL BIO (filter) -> SOCKS BIO (filter) -> connect BIO (source/sink) + * This configuration represents doing an SSL connection through a SOCKS proxy, + * which is itself connected to in plaintext. You might also do: + * SSL BIO -> SOCKS BIO -> SSL BIO -> connect BIO + * This is an SSL connection through a SOCKS proxy which is itself reached over + * SSL. + */ + +#include <arpa/inet.h> +#include <assert.h> +#ifndef __USE_MISC +#define __USE_MISC +#endif +#ifndef __USE_POSIX +#define __USE_POSIX +#endif + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX (255) +#endif + +#include <netdb.h> + +#include <inttypes.h> + +#include "src/proxy-bio-plan9.h" + +int socks4a_connect(BIO *b); +int socks5_connect(BIO *b); +int http_connect(BIO *b); + +int proxy_new(BIO *b) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) malloc(sizeof *ctx); + if (!ctx) + return 0; + ctx->connected = 0; + ctx->connect = NULL; + ctx->host = NULL; + ctx->port = 0; + b->init = 1; + b->flags = 0; + b->ptr = ctx; + return 1; +} + +int proxy_free(BIO *b) +{ + struct proxy_ctx *c; + if (!b || !b->ptr) + return 1; + c = (struct proxy_ctx *) b->ptr; + if (c->host) + free(c->host); + c->host = NULL; + b->ptr = NULL; + free(c); + return 1; +} + +int socks4a_connect(BIO *b) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + int r; + unsigned char buf[NI_MAXHOST + 16]; + uint16_t port_n = htons(ctx->port); + size_t sz = 0; + + verb("V: proxy4: connecting %s:%d", ctx->host, ctx->port); + + /* + * Packet layout: + * 1b: Version (must be 0x04) + * 1b: command (0x01 is connect) + * 2b: port number, big-endian + * 4b: 0x00, 0x00, 0x00, 0x01 (bogus IPv4 addr) + * 1b: 0x00 (empty 'userid' field) + * nb: hostname, null-terminated + */ + buf[0] = 0x04; + buf[1] = 0x01; + sz += 2; + + memcpy(buf + 2, &port_n, sizeof(port_n)); + sz += sizeof(port_n); + + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x01; + sz += 4; + + buf[8] = 0x00; + sz += 1; + + memcpy(buf + sz, ctx->host, strlen(ctx->host) + 1); + sz += strlen(ctx->host) + 1; + + r = BIO_write(b->next_bio, buf, sz); + if ( -1 == r ) + return -1; + if ( (size_t) r != sz) + return 0; + + /* server reply: 1 + 1 + 2 + 4 */ + r = BIO_read(b->next_bio, buf, 8); + if ( -1 == r ) + return -1; + if ( (size_t) r != 8) + return 0; + if (buf[1] == 0x5a) { + verb("V: proxy4: connected"); + ctx->connected = 1; + return 1; + } + return 0; +} + +int socks5_connect(BIO *b) +{ + unsigned char buf[NI_MAXHOST + 16]; + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + uint16_t port_n = htons(ctx->port); + size_t sz = 0; + + /* the length for SOCKS addresses is only one byte. */ + if (strlen(ctx->host) == UINT8_MAX + 1) + return 0; + + verb("V: proxy5: connecting %s:%d", ctx->host, ctx->port); + + /* + * Hello packet layout: + * 1b: Version + * 1b: auth methods + * nb: method types + * + * We support only one method (no auth, 0x00). Others listed in RFC + * 1928. + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + + r = BIO_write(b->next_bio, buf, 3); + if (r != 3) + return 0; + + r = BIO_read(b->next_bio, buf, 2); + if (r != 2) + return 0; + + if (buf[0] != 0x05 || buf[1] != 0x00) { + verb("V: proxy5: auth error %02x %02x", buf[0], buf[1]); + return 0; + } + + /* + * Connect packet layout: + * 1b: version + * 1b: command (0x01 is connect) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = 0x03; + buf[4] = strlen(ctx->host); + sz += 5; + memcpy(buf + 5, ctx->host, strlen(ctx->host)); + sz += strlen(ctx->host); + memcpy(buf + sz, &port_n, sizeof(port_n)); + sz += sizeof(port_n); + + r = BIO_write(b->next_bio, buf, sz); + if ( -1 == r ) + return -1; + if ( (size_t) r != sz) + return 0; + + /* + * Server's response: + * 1b: version + * 1b: status (0x00 is okay) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name, 0x01 ipv4) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + + /* grab up through the addr type */ + r = BIO_read(b->next_bio, buf, 4); + if ( -1 == r ) + return -1; + if (r != 4) + return 0; + + if (buf[0] != 0x05 || buf[1] != 0x00) { + verb("V: proxy5: connect error %02x %02x", buf[0], buf[1]); + return 0; + } + + if (buf[3] == 0x03) { + unsigned int len; + r = BIO_read(b->next_bio, buf + 4, 1); + if (r != 1) + return 0; + /* host (buf[4] bytes) + port (2 bytes) */ + len = buf[4] + 2; + while (len) { + r = BIO_read(b->next_bio, buf + 5, min(len, sizeof(buf))); + if (r <= 0) + return 0; + len -= min(len, r); + } + } else if (buf[3] == 0x01) { + /* 4 bytes ipv4 addr, 2 bytes port */ + r = BIO_read(b->next_bio, buf + 4, 6); + if (r != 6) + return 0; + } + + verb("V: proxy5: connected"); + ctx->connected = 1; + return 1; +} + +/* SSL socket BIOs don't support BIO_gets, so... */ +int sock_gets(BIO *b, char *buf, size_t sz) +{ + char c; + while (BIO_read(b, &c, 1) > 0 && sz > 1) { + *buf++ = c; + sz--; + if (c == '\n') { + *buf = '\0'; + return 0; + } + } + return 1; +} + +int http_connect(BIO *b) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + char buf[4096]; + int retcode; + + snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n", + ctx->host, ctx->port); + r = BIO_write(b->next_bio, buf, strlen(buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + /* required by RFC 2616 14.23 */ + snprintf(buf, sizeof(buf), "Host: %s:%d\r\n", ctx->host, ctx->port); + r = BIO_write(b->next_bio, buf, strlen(buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + strcpy(buf, "\r\n"); + r = BIO_write(b->next_bio, buf, strlen(buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + + r = sock_gets(b->next_bio, buf, sizeof(buf)); + if (r) + return 0; + /* use %*s to ignore the version */ + if (sscanf(buf, "HTTP/%*s %d", &retcode) != 1) + return 0; + + if (retcode < 200 || retcode > 299) + return 0; + while (!(r = sock_gets(b->next_bio, buf, sizeof(buf)))) { + if (!strcmp(buf, "\r\n")) { + /* Done with the header */ + ctx->connected = 1; + return 1; + } + } + return 0; +} + +int proxy_write(BIO *b, const char *buf, int sz) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + + assert(buf); + + if (sz <= 0) + return 0; + + if (!b->next_bio) + return 0; + + if (!ctx->connected) { + assert(ctx->connect); + if (!ctx->connect(b)) + return 0; + } + + r = BIO_write(b->next_bio, buf, sz); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return r; +} + +int proxy_read(BIO *b, char *buf, int sz) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + + assert(buf); + + if (!b->next_bio) + return 0; + + if (!ctx->connected) { + assert(ctx->connect); + if (!ctx->connect(b)) + return 0; + } + + r = BIO_read(b->next_bio, buf, sz); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return r; +} + +long proxy_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + struct proxy_ctx *ctx; + if (!b->next_bio) + return 0; + ctx = (struct proxy_ctx *) b->ptr; + assert(ctx); + + switch (cmd) { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_DUP: + ret = 0; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + return ret; +} + +int proxy_gets(BIO *b, char *buf, int size) +{ + return BIO_gets(b->next_bio, buf, size); +} + +int proxy_puts(BIO *b, const char *str) +{ + return BIO_puts(b->next_bio, str); +} + +long proxy_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + if (!b->next_bio) + return 0; + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +BIO_METHOD proxy_methods = { + BIO_TYPE_MEM, + "proxy", + proxy_write, + proxy_read, + proxy_puts, + proxy_gets, + proxy_ctrl, + proxy_new, + proxy_free, + proxy_callback_ctrl, +}; + +BIO_METHOD *BIO_f_proxy() +{ + return &proxy_methods; +} + +/* API starts here */ + +BIO API *BIO_new_proxy() +{ + return BIO_new(BIO_f_proxy()); +} + +int API BIO_proxy_set_type(BIO *b, const char *type) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + if (!strcmp(type, "socks5")) + ctx->connect = socks5_connect; + else if (!strcmp(type, "socks4a")) + ctx->connect = socks4a_connect; + else if (!strcmp(type, "http")) + ctx->connect = http_connect; + else + return 1; + return 0; +} + +int API BIO_proxy_set_host(BIO *b, const char *host) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + if (strlen(host) == NI_MAXHOST) + return 1; + ctx->host = strdup(host); + return 0; +} + +void API BIO_proxy_set_port(BIO *b, uint16_t port) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + ctx->port = port; +} diff --git a/src/proxy-bio-plan9.h b/src/proxy-bio-plan9.h new file mode 100644 index 0000000..3e8e74b --- /dev/null +++ b/src/proxy-bio-plan9.h @@ -0,0 +1,32 @@ +/* + * proxy-bio.h - BIO layer for transparent proxy connections + * + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef PROXY_BIO_H +#define PROXY_BIO_H + +#include <inttypes.h> + +#include <openssl/bio.h> + +#include "util-plan9.h" + +struct proxy_ctx { + char *host; + uint16_t port; + int connected; + int (*connect)(BIO *b); +}; + +BIO *BIO_new_proxy(); + +/* These do not take ownership of their string arguments. */ +int BIO_proxy_set_type(BIO *b, const char *type); +int BIO_proxy_set_host(BIO *b, const char *host); +void BIO_proxy_set_port(BIO *b, uint16_t port); + +#endif /* !PROXY_BIO_H */ diff --git a/src/proxy-bio-unittest.c b/src/proxy-bio-unittest.c new file mode 100644 index 0000000..8b9ae8b --- /dev/null +++ b/src/proxy-bio-unittest.c @@ -0,0 +1,292 @@ +/* + * proxy-bio-unittest.c - proxy-bio unit tests + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#if defined(__linux__) +#include <alloca.h> +#endif + +#include "src/proxy-bio.h" +#include "src/test-bio.h" +#include "src/test_harness.h" +#include "src/tlsdate.h" + +FIXTURE (test_bio) +{ + BIO *test; +}; + +FIXTURE_SETUP (test_bio) +{ + self->test = BIO_new_test(); + ASSERT_NE (NULL, self->test); +} + +FIXTURE_TEARDOWN (test_bio) +{ + BIO_free (self->test); +} + +BIO *proxy_bio (BIO *test, const char *type) +{ + BIO *proxy = BIO_new_proxy(); + BIO_proxy_set_type (proxy, type); + BIO_proxy_set_host (proxy, kTestHost); + BIO_proxy_set_port (proxy, TEST_PORT); + BIO_push (proxy, test); + return proxy; +} + +int need_out_bytes (BIO *test, const unsigned char *out, size_t sz) +{ + unsigned char *buf = malloc (sz); + size_t i; + int result; + if (!buf) + return 1; + if (BIO_test_output_left (test) < sz) + { + fprintf (TH_LOG_STREAM, "not enough output: %d < %d\n", + (int) BIO_test_output_left (test), (int) sz); + free (buf); + return 2; + } + if (BIO_test_get_output (test, buf, sz) != sz) + { + free (buf); + return 3; + } + if (memcmp (buf, out, sz)) + { + for (i = 0; i < sz; i++) + { + if (buf[i] != out[i]) + fprintf (TH_LOG_STREAM, + "mismatch %d %02x %02x\n", (int) i, + buf[i], out[i]); + } + } + result = memcmp (buf, out, sz); + free (buf); + return result; +} + +int need_out_byte (BIO *test, unsigned char out) +{ + unsigned char c; + if (BIO_test_output_left (test) < 1) + return 1; + if (BIO_test_get_output (test, &c, 1) != 1) + return 2; + return c != out; +} + +int get_bytes (BIO *test, unsigned char *buf, size_t sz) +{ + return BIO_test_get_output (test, buf, sz); +} + +void put_bytes (BIO *test, const unsigned char *buf, size_t sz) +{ + BIO_test_add_input (test, buf, sz); +} + +void put_byte (BIO *test, char c) +{ + BIO_test_add_input (test, (unsigned char *) &c, 1); +} + +unsigned const char kSocks4ARequest[] = +{ + 0x04, /* socks4 */ + 0x01, /* tcp stream */ + (TEST_PORT & 0xff00) >> 8, + TEST_PORT & 0xff, + 0x00, 0x00, 0x00, 0x01, /* bogus IP */ + 0x00, /* userid */ + TEST_HOST, 0x00 /* null-terminated host */ +}; + +TEST_F (test_bio, socks4a_success) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + unsigned const char kReply[] = + { + 0x00, /* null byte */ + 0x5a, /* success */ + (TEST_PORT & 0xff00) >> 8, /* port high */ + TEST_PORT & 0xff, /* port low */ + 0x00, 0x00, 0x00, 0x00 /* bogus IP */ + }; + BIO *proxy = proxy_bio (self->test, "socks4a"); + put_bytes (self->test, kReply, sizeof (kReply)); + EXPECT_EQ (4, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks4ARequest, + sizeof (kSocks4ARequest))); + EXPECT_EQ (0, need_out_bytes (self->test, kTestInput, + sizeof (kTestInput))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_F (test_bio, socks4a_fail) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + unsigned const char kReply[] = + { + 0x00, /* null byte */ + 0x5b, /* fail */ + (TEST_PORT & 0xff00) >> 8, /* port high */ + TEST_PORT & 0xff, /* port low */ + 0x00, 0x00, 0x00, 0x00 /* bogus IP */ + }; + BIO *proxy = proxy_bio (self->test, "socks4a"); + put_bytes (self->test, kReply, sizeof (kReply)); + EXPECT_EQ (0, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks4ARequest, + sizeof (kSocks4ARequest))); + /* We shouldn't have written any payload */ + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +unsigned const char kSocks5AuthRequest[] = +{ + 0x05, /* socks5 */ + 0x01, /* one auth method */ + 0x00 /* no auth */ +}; + +unsigned const char kSocks5AuthReply[] = +{ + 0x05, /* socks5 */ + 0x00, /* no auth */ +}; + +unsigned const char kSocks5ConnectRequest[] = +{ + 0x05, /* socks5 */ + 0x01, /* tcp stream */ + 0x00, /* reserved 0x00 */ + 0x03, /* domain name */ + TEST_HOST_SIZE, /* hostname with length prefix */ + TEST_HOST, + (TEST_PORT & 0xff00) >> 8, + TEST_PORT & 0xff +}; + +unsigned const char kSocks5ConnectReply[] = +{ + 0x05, /* socks5 */ + 0x00, /* success */ + 0x00, /* reserved 0x00 */ + 0x03, /* domain name */ + TEST_HOST_SIZE, /* hostname with length prefix */ + TEST_HOST, + (TEST_PORT & 0xff00) >> 8, + TEST_PORT & 0xff +}; + +TEST_F (test_bio, socks5_success) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + BIO *proxy = proxy_bio (self->test, "socks5"); + put_bytes (self->test, kSocks5AuthReply, sizeof (kSocks5AuthReply)); + put_bytes (self->test, kSocks5ConnectReply, sizeof (kSocks5ConnectReply)); + EXPECT_EQ (4, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks5AuthRequest, + sizeof (kSocks5AuthRequest))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks5ConnectRequest, + sizeof (kSocks5ConnectRequest))); + EXPECT_EQ (0, need_out_bytes (self->test, kTestInput, + sizeof (kTestInput))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_F (test_bio, socks5_auth_fail) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + unsigned const char kAuthFail[] = + { + 0x05, + 0xff, + }; + BIO *proxy = proxy_bio (self->test, "socks5"); + put_bytes (self->test, kAuthFail, sizeof (kAuthFail)); + EXPECT_EQ (0, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks5AuthRequest, + sizeof (kSocks5AuthRequest))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_F (test_bio, socks5_connect_fail) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + unsigned const char kConnectFail[] = + { + 0x05, + 0x01, + 0x00, + 0x03, + TEST_HOST_SIZE, + TEST_HOST, + (TEST_PORT & 0xff00) >> 8, + TEST_PORT & 0xff + }; + BIO *proxy = proxy_bio (self->test, "socks5"); + put_bytes (self->test, kSocks5AuthReply, sizeof (kSocks5AuthReply)); + put_bytes (self->test, kConnectFail, sizeof (kConnectFail)); + EXPECT_EQ (0, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks5AuthRequest, + sizeof (kSocks5AuthRequest))); + EXPECT_EQ (0, need_out_bytes (self->test, kSocks5ConnectRequest, + sizeof (kSocks5ConnectRequest))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_F (test_bio, http_success) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + BIO *proxy = proxy_bio (self->test, "http"); + char kConnectRequest[1024]; + char kConnectResponse[] = "HTTP/1.0 200 OK\r\n" + "Uninteresting-Header: foobar\r\n" + "Another-Header: lol\r\n" + "\r\n"; + snprintf (kConnectRequest, sizeof (kConnectRequest), + "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", + kTestHost, TEST_PORT, kTestHost, TEST_PORT); + put_bytes (self->test, (unsigned char *) kConnectResponse, + strlen (kConnectResponse)); + EXPECT_EQ (4, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, + (unsigned char *) kConnectRequest, + strlen (kConnectRequest))); + EXPECT_EQ (0, need_out_bytes (self->test, kTestInput, + sizeof (kTestInput))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_F (test_bio, http_error) +{ + unsigned const char kTestInput[] = { 0xde, 0xad, 0xbe, 0xef }; + BIO *proxy = proxy_bio (self->test, "http"); + char kConnectRequest[1024]; + char kConnectResponse[] = "HTTP/1.0 403 NO U\r\n" + "Uninteresting-Header: foobar\r\n" + "Another-Header: lol\r\n" + "\r\n"; + snprintf (kConnectRequest, sizeof (kConnectRequest), + "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", + kTestHost, TEST_PORT, kTestHost, TEST_PORT); + put_bytes (self->test, (unsigned char *) kConnectResponse, + strlen (kConnectResponse)); + EXPECT_EQ (0, BIO_write (proxy, kTestInput, sizeof (kTestInput))); + EXPECT_EQ (0, need_out_bytes (self->test, + (unsigned char *) kConnectRequest, + strlen (kConnectRequest))); + EXPECT_EQ (0, BIO_test_output_left (self->test)); +} + +TEST_HARNESS_MAIN diff --git a/src/proxy-bio.c b/src/proxy-bio.c new file mode 100644 index 0000000..2576112 --- /dev/null +++ b/src/proxy-bio.c @@ -0,0 +1,430 @@ +/* + * proxy-bio.c - BIO layer for SOCKS4a/5 proxy connections + * + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file implements a SOCKS4a/SOCKS5 "filter" BIO. In SSL terminology, a BIO + * is a stackable IO filter, kind of like sysv streams. These filters are + * inserted into a stream to cause it to run SOCKS over whatever transport is + * being used. Most commonly, this would be: + * SSL BIO (filter) -> SOCKS BIO (filter) -> connect BIO (source/sink) + * This configuration represents doing an SSL connection through a SOCKS proxy, + * which is itself connected to in plaintext. You might also do: + * SSL BIO -> SOCKS BIO -> SSL BIO -> connect BIO + * This is an SSL connection through a SOCKS proxy which is itself reached over + * SSL. + */ + +#include "config.h" + +#include <arpa/inet.h> +#include <assert.h> +#ifndef __USE_MISC +#define __USE_MISC +#endif +#ifndef __USE_POSIX +#define __USE_POSIX +#endif +#include <netdb.h> + +#include <stdint.h> + +#ifndef HAVE_STRNLEN +#include "src/common/strnlen.h" +#endif + +#include "src/proxy-bio.h" + +int socks4a_connect (BIO *b); +int socks5_connect (BIO *b); +int http_connect (BIO *b); + +int proxy_new (BIO *b) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) malloc (sizeof *ctx); + if (!ctx) + return 0; + ctx->connected = 0; + ctx->connect = NULL; + ctx->host = NULL; + ctx->port = 0; + b->init = 1; + b->flags = 0; + b->ptr = ctx; + return 1; +} + +int proxy_free (BIO *b) +{ + struct proxy_ctx *c; + if (!b || !b->ptr) + return 1; + c = (struct proxy_ctx *) b->ptr; + if (c->host) + free (c->host); + c->host = NULL; + b->ptr = NULL; + free (c); + return 1; +} + +int socks4a_connect (BIO *b) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + int r; + unsigned char buf[NI_MAXHOST + 16]; + uint16_t port_n = htons (ctx->port); + size_t sz = 0; + verb ("V: proxy4: connecting %s:%d", ctx->host, ctx->port); + /* + * Packet layout: + * 1b: Version (must be 0x04) + * 1b: command (0x01 is connect) + * 2b: port number, big-endian + * 4b: 0x00, 0x00, 0x00, 0x01 (bogus IPv4 addr) + * 1b: 0x00 (empty 'userid' field) + * nb: hostname, null-terminated + */ + buf[0] = 0x04; + buf[1] = 0x01; + sz += 2; + memcpy (buf + 2, &port_n, sizeof (port_n)); + sz += sizeof (port_n); + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x01; + sz += 4; + buf[8] = 0x00; + sz += 1; + + memcpy (buf + sz, ctx->host, strlen (ctx->host) + 1); + sz += strlen (ctx->host) + 1; + r = BIO_write (b->next_bio, buf, sz); + if ( -1 == r ) + return -1; + if ( (size_t) r != sz) + return 0; + /* server reply: 1 + 1 + 2 + 4 */ + r = BIO_read (b->next_bio, buf, 8); + if ( -1 == r ) + return -1; + if ( (size_t) r != 8) + return 0; + if (buf[1] == 0x5a) + { + verb ("V: proxy4: connected"); + ctx->connected = 1; + return 1; + } + return 0; +} + +int socks5_connect (BIO *b) +{ + unsigned char buf[NI_MAXHOST + 16]; + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + uint16_t port_n = htons (ctx->port); + size_t sz = 0; + /* the length for SOCKS addresses is only one byte. */ + if (strnlen (ctx->host, UINT8_MAX + 1) == UINT8_MAX + 1) + return 0; + verb ("V: proxy5: connecting %s:%d", ctx->host, ctx->port); + /* + * Hello packet layout: + * 1b: Version + * 1b: auth methods + * nb: method types + * + * We support only one method (no auth, 0x00). Others listed in RFC + * 1928. + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + r = BIO_write (b->next_bio, buf, 3); + if (r != 3) + return 0; + r = BIO_read (b->next_bio, buf, 2); + if (r != 2) + return 0; + if (buf[0] != 0x05 || buf[1] != 0x00) + { + verb ("V: proxy5: auth error %02x %02x", buf[0], buf[1]); + return 0; + } + /* + * Connect packet layout: + * 1b: version + * 1b: command (0x01 is connect) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = 0x03; + buf[4] = strlen (ctx->host); + sz += 5; + memcpy (buf + 5, ctx->host, strlen (ctx->host)); + sz += strlen (ctx->host); + memcpy (buf + sz, &port_n, sizeof (port_n)); + sz += sizeof (port_n); + r = BIO_write (b->next_bio, buf, sz); + if ( -1 == r ) + return -1; + if ( (size_t) r != sz) + return 0; + /* + * Server's response: + * 1b: version + * 1b: status (0x00 is okay) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name, 0x01 ipv4) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + /* grab up through the addr type */ + r = BIO_read (b->next_bio, buf, 4); + if ( -1 == r ) + return -1; + if (r != 4) + return 0; + if (buf[0] != 0x05 || buf[1] != 0x00) + { + verb ("V: proxy5: connect error %02x %02x", buf[0], buf[1]); + return 0; + } + if (buf[3] == 0x03) + { + unsigned int len; + r = BIO_read (b->next_bio, buf + 4, 1); + if (r != 1) + return 0; + /* host (buf[4] bytes) + port (2 bytes) */ + len = buf[4] + 2; + while (len) + { + r = BIO_read (b->next_bio, buf + 5, min (len, sizeof (buf))); + if (r <= 0) + return 0; + len -= min (len, r); + } + } + else if (buf[3] == 0x01) + { + /* 4 bytes ipv4 addr, 2 bytes port */ + r = BIO_read (b->next_bio, buf + 4, 6); + if (r != 6) + return 0; + } + verb ("V: proxy5: connected"); + ctx->connected = 1; + return 1; +} + +/* SSL socket BIOs don't support BIO_gets, so... */ +int sock_gets (BIO *b, char *buf, size_t sz) +{ + char c; + while (BIO_read (b, &c, 1) > 0 && sz > 1) + { + *buf++ = c; + sz--; + if (c == '\n') + { + *buf = '\0'; + return 0; + } + } + return 1; +} + +int http_connect (BIO *b) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + char buf[4096]; + int retcode; + snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.1\r\n", + ctx->host, ctx->port); + r = BIO_write (b->next_bio, buf, strlen (buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + /* required by RFC 2616 14.23 */ + snprintf (buf, sizeof (buf), "Host: %s:%d\r\n", ctx->host, ctx->port); + r = BIO_write (b->next_bio, buf, strlen (buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + strcpy (buf, "\r\n"); + r = BIO_write (b->next_bio, buf, strlen (buf)); + if ( -1 == r ) + return -1; + if ( (size_t) r != strlen(buf)) + return 0; + r = sock_gets (b->next_bio, buf, sizeof (buf)); + if (r) + return 0; + /* use %*s to ignore the version */ + if (sscanf (buf, "HTTP/%*s %d", &retcode) != 1) + return 0; + if (retcode < 200 || retcode > 299) + return 0; + while (! (r = sock_gets (b->next_bio, buf, sizeof (buf)))) + { + if (!strcmp (buf, "\r\n")) + { + /* Done with the header */ + ctx->connected = 1; + return 1; + } + } + return 0; +} + +int proxy_write (BIO *b, const char *buf, int sz) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + + assert (buf); + if (sz <= 0) + return 0; + if (!b->next_bio) + return 0; + if (!ctx->connected) + { + assert (ctx->connect); + if (!ctx->connect (b)) + return 0; + } + r = BIO_write (b->next_bio, buf, sz); + BIO_clear_retry_flags (b); + BIO_copy_next_retry (b); + return r; +} + +int proxy_read (BIO *b, char *buf, int sz) +{ + int r; + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + + assert (buf); + if (!b->next_bio) + return 0; + if (!ctx->connected) + { + assert (ctx->connect); + if (!ctx->connect (b)) + return 0; + } + r = BIO_read (b->next_bio, buf, sz); + BIO_clear_retry_flags (b); + BIO_copy_next_retry (b); + return r; +} + +long proxy_ctrl (BIO *b, int cmd, long num, void *ptr) +{ + long ret; + struct proxy_ctx *ctx; + if (!b->next_bio) + return 0; + ctx = (struct proxy_ctx *) b->ptr; + assert (ctx); + switch (cmd) + { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags (b); + ret = BIO_ctrl (b->next_bio, cmd, num, ptr); + BIO_copy_next_retry (b); + break; + case BIO_CTRL_DUP: + ret = 0; + break; + default: + ret = BIO_ctrl (b->next_bio, cmd, num, ptr); + } + return ret; +} + +int proxy_gets (BIO *b, char *buf, int size) +{ + return BIO_gets (b->next_bio, buf, size); +} + +int proxy_puts (BIO *b, const char *str) +{ + return BIO_puts (b->next_bio, str); +} + +long proxy_callback_ctrl (BIO *b, int cmd, bio_info_cb *fp) +{ + if (!b->next_bio) + return 0; + return BIO_callback_ctrl (b->next_bio, cmd, fp); +} + +BIO_METHOD proxy_methods = +{ + BIO_TYPE_MEM, + "proxy", + proxy_write, + proxy_read, + proxy_puts, + proxy_gets, + proxy_ctrl, + proxy_new, + proxy_free, + proxy_callback_ctrl, +}; + +BIO_METHOD *BIO_f_proxy() +{ + return &proxy_methods; +} + +/* API starts here */ + +BIO API *BIO_new_proxy() +{ + return BIO_new (BIO_f_proxy()); +} + +int API BIO_proxy_set_type (BIO *b, const char *type) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + if (!strcmp (type, "socks5")) + ctx->connect = socks5_connect; + else if (!strcmp (type, "socks4a")) + ctx->connect = socks4a_connect; + else if (!strcmp (type, "http")) + ctx->connect = http_connect; + else + return 1; + return 0; +} + +int API BIO_proxy_set_host (BIO *b, const char *host) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + if (strnlen (host, NI_MAXHOST) == NI_MAXHOST) + return 1; + ctx->host = strdup (host); + return 0; +} + +void API BIO_proxy_set_port (BIO *b, uint16_t port) +{ + struct proxy_ctx *ctx = (struct proxy_ctx *) b->ptr; + ctx->port = port; +} diff --git a/src/proxy-bio.h b/src/proxy-bio.h new file mode 100644 index 0000000..3a68153 --- /dev/null +++ b/src/proxy-bio.h @@ -0,0 +1,32 @@ +/* + * proxy-bio.h - BIO layer for transparent proxy connections + * + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef PROXY_BIO_H +#define PROXY_BIO_H + +#include <stdint.h> + +#include <openssl/bio.h> + +#include "util.h" + +struct proxy_ctx { + char *host; + uint16_t port; + int connected; + int (*connect)(BIO *b); +}; + +BIO *BIO_new_proxy(); + +/* These do not take ownership of their string arguments. */ +int BIO_proxy_set_type (BIO *b, const char *type); +int BIO_proxy_set_host (BIO *b, const char *host); +void BIO_proxy_set_port (BIO *b, uint16_t port); + +#endif /* !PROXY_BIO_H */ diff --git a/src/proxy-polarssl.c b/src/proxy-polarssl.c new file mode 100644 index 0000000..04f7f6d --- /dev/null +++ b/src/proxy-polarssl.c @@ -0,0 +1,360 @@ +/* + * proxy-polarssl.c - Net stack layer for SOCKS4a/5 proxy connections + * + * Based on proxy-bio.c - Original copyright (c) 2012 The Chromium OS Authors. + * + * This file was adapted by Paul Bakker <p.j.bakker@offspark.com> + * All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This file implements a SOCKS4a/SOCKS5 net layer as used by PolarSSL. + */ + +#include "config.h" + +#include <arpa/inet.h> +#include <assert.h> +#ifndef __USE_MISC +#define __USE_MISC +#endif +#ifndef __USE_POSIX +#define __USE_POSIX +#endif +#include <netdb.h> +#include <stdint.h> +#include <stdio.h> + +#ifndef HAVE_STRNLEN +#include "src/common/strnlen.h" +#endif + +#include "src/proxy-polarssl.h" +#include "src/util.h" + +int socks4a_connect(proxy_polarssl_ctx *ctx) +{ + int r; + unsigned char buf[NI_MAXHOST + 16]; + uint16_t port_n; + size_t sz = 0; + + if (!ctx) + return 0; + + verb("V: proxy4: connecting %s:%d", ctx->host, ctx->port); + + port_n = htons(ctx->port); + + /* + * Packet layout: + * 1b: Version (must be 0x04) + * 1b: command (0x01 is connect) + * 2b: port number, big-endian + * 4b: 0x00, 0x00, 0x00, 0x01 (bogus IPv4 addr) + * 1b: 0x00 (empty 'userid' field) + * nb: hostname, null-terminated + */ + buf[0] = 0x04; + buf[1] = 0x01; + sz += 2; + + memcpy(buf + 2, &port_n, sizeof(port_n)); + sz += sizeof(port_n); + + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x01; + sz += 4; + + buf[8] = 0x00; + sz += 1; + + memcpy(buf + sz, ctx->host, strlen(ctx->host) + 1); + sz += strlen(ctx->host) + 1; + + r = ctx->f_send(ctx->p_send, buf, sz); + if (r != sz) + return 0; + + /* server reply: 1 + 1 + 2 + 4 */ + r = ctx->f_recv(ctx->p_recv, buf, 8); + if (r != 8) + return 0; + + if (buf[1] == 0x5a) { + verb("V: proxy4: connected"); + ctx->connected = 1; + return 1; + } + return 0; +} + +int socks5_connect(proxy_polarssl_ctx *ctx) +{ + unsigned char buf[NI_MAXHOST + 16]; + int r; + uint16_t port_n; + size_t sz = 0; + + if (!ctx) + return 0; + + /* the length for SOCKS addresses is only one byte. */ + if (strnlen(ctx->host, UINT8_MAX + 1) == UINT8_MAX + 1) + return 0; + + verb("V: proxy5: connecting %s:%d", ctx->host, ctx->port); + + port_n = htons(ctx->port); + + /* + * Hello packet layout: + * 1b: Version + * 1b: auth methods + * nb: method types + * + * We support only one method (no auth, 0x00). Others listed in RFC + * 1928. + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + + r = ctx->f_send(ctx->p_send, buf, 3); + if (r != 3) + return 0; + + r = ctx->f_recv(ctx->p_recv, buf, 2); + if (r != 2) + return 0; + + if (buf[0] != 0x05 || buf[1] != 0x00) { + verb("V: proxy5: auth error %02x %02x", buf[0], buf[1]); + return 0; + } + + /* + * Connect packet layout: + * 1b: version + * 1b: command (0x01 is connect) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + buf[0] = 0x05; + buf[1] = 0x01; + buf[2] = 0x00; + buf[3] = 0x03; + buf[4] = strlen(ctx->host); + sz += 5; + memcpy(buf + 5, ctx->host, strlen(ctx->host)); + sz += strlen(ctx->host); + memcpy(buf + sz, &port_n, sizeof(port_n)); + sz += sizeof(port_n); + + r = ctx->f_send(ctx->p_send, buf, sz); + if (r != sz) + return 0; + + /* + * Server's response: + * 1b: version + * 1b: status (0x00 is okay) + * 1b: reserved, 0x00 + * 1b: addr type (0x03 is domain name, 0x01 ipv4) + * nb: addr len (1b) + addr bytes, no null termination + * 2b: port, network byte order + */ + + /* grab up through the addr type */ + r = ctx->f_recv(ctx->p_recv, buf, 4); + if (r != 4) + return 0; + + if (buf[0] != 0x05 || buf[1] != 0x00) { + verb("V: proxy5: connect error %02x %02x", buf[0], buf[1]); + return 0; + } + + if (buf[3] == 0x03) { + unsigned int len; + r = ctx->f_recv(ctx->p_recv, buf + 4, 1); + if (r != 1) + return 0; + /* host (buf[4] bytes) + port (2 bytes) */ + len = buf[4] + 2; + while (len) { + r = ctx->f_recv(ctx->p_recv, buf + 5, min(len, sizeof(buf))); + if (r <= 0) + return 0; + len -= min(len, r); + } + } else if (buf[3] == 0x01) { + /* 4 bytes ipv4 addr, 2 bytes port */ + r = ctx->f_recv(ctx->p_recv, buf + 4, 6); + if (r != 6) + return 0; + } + + verb("V: proxy5: connected"); + ctx->connected = 1; + return 1; +} + +/* SSL socket BIOs don't support BIO_gets, so... */ +int sock_gets(proxy_polarssl_ctx *ctx, char *buf, size_t sz) +{ + unsigned char c; + while (ctx->f_recv(ctx->p_recv, &c, 1) > 0 && sz > 1) { + *buf++ = c; + sz--; + if (c == '\n') { + *buf = '\0'; + return 0; + } + } + return 1; +} + +int http_connect(proxy_polarssl_ctx *ctx) +{ + int r; + char buf[4096]; + int retcode; + + snprintf(buf, sizeof(buf), "CONNECT %s:%d HTTP/1.1\r\n", + ctx->host, ctx->port); + r = ctx->f_send(ctx->p_send, (unsigned char *) buf, strlen(buf)); + if (r != strlen(buf)) + return 0; + /* required by RFC 2616 14.23 */ + snprintf(buf, sizeof(buf), "Host: %s:%d\r\n", ctx->host, ctx->port); + r = ctx->f_send(ctx->p_send, (unsigned char *) buf, strlen(buf)); + if (r != strlen(buf)) + return 0; + strcpy(buf, "\r\n"); + r = ctx->f_send(ctx->p_send, (unsigned char *) buf, strlen(buf)); + if (r != strlen(buf)) + return 0; + + r = sock_gets(ctx, buf, sizeof(buf)); + if (r) + return 0; + /* use %*s to ignore the version */ + if (sscanf(buf, "HTTP/%*s %d", &retcode) != 1) + return 0; + + if (retcode < 200 || retcode > 299) + return 0; + while (!(r = sock_gets(ctx, buf, sizeof(buf)))) { + if (!strcmp(buf, "\r\n")) { + /* Done with the header */ + ctx->connected = 1; + return 1; + } + } + return 0; +} + +int API proxy_polarssl_init(proxy_polarssl_ctx *ctx) +{ + if (!ctx) + return 0; + + memset(ctx, 0, sizeof(proxy_polarssl_ctx)); + return 1; +} + +void API proxy_polarssl_set_bio(proxy_polarssl_ctx *ctx, + int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, + int (*f_send)(void *, const unsigned char *, size_t), void *p_send) +{ + if (!ctx) + return; + + ctx->f_recv = f_recv; + ctx->p_recv = p_recv; + ctx->f_send = f_send; + ctx->p_send = p_send; +} + +int API proxy_polarssl_free(proxy_polarssl_ctx *ctx) +{ + if (!ctx) + return 0; + + if (ctx->host) + { + free(ctx->host); + ctx->host = NULL; + } + + return 1; +} + +int API proxy_polarssl_set_scheme(proxy_polarssl_ctx *ctx, const char *scheme) +{ + if (!strcmp(scheme, "socks5")) + ctx->f_connect = socks5_connect; + else if (!strcmp(scheme, "socks4")) + ctx->f_connect = socks4a_connect; + else if (!strcmp(scheme, "http")) + ctx->f_connect = http_connect; + else + return 1; + return 0; +} + +int API proxy_polarssl_set_host(proxy_polarssl_ctx *ctx, const char *host) +{ + if (strnlen(host, NI_MAXHOST) == NI_MAXHOST) + return 1; + ctx->host = strdup(host); + return 0; +} + +void API proxy_polarssl_set_port(proxy_polarssl_ctx *ctx, uint16_t port) +{ + ctx->port = port; +} + +int API proxy_polarssl_recv(void *ctx, unsigned char *data, size_t len) +{ + proxy_polarssl_ctx *proxy = (proxy_polarssl_ctx *) ctx; + int r; + + if (!ctx) + return -1; + + if (!proxy->connected) + { + r = proxy->f_connect(ctx); + if (r) + return (r); + } + + return proxy->f_recv(proxy->p_recv, data, len); +} + + +int API proxy_polarssl_send(void *ctx, const unsigned char *data, size_t len) +{ + proxy_polarssl_ctx *proxy = (proxy_polarssl_ctx *) ctx; + int r; + + if (!ctx) + return -1; + + if (!proxy->connected) + { + r = proxy->f_connect(ctx); + if (r) + return (r); + } + + return proxy->f_send(proxy->p_send, data, len); +} diff --git a/src/proxy-polarssl.h b/src/proxy-polarssl.h new file mode 100644 index 0000000..144ba20 --- /dev/null +++ b/src/proxy-polarssl.h @@ -0,0 +1,46 @@ +/* + * proxy-polarssl.h - PolarSSL layer for transparent proxy connections + * + * Based on proxy-bio.c - Original copyright (c) 2012 The Chromium OS Authors. + * + * This file was adapted by Paul Bakker <p.j.bakker@offspark.com> + * All rights reserved. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef PROXY_POLARSSL_H +#define PROXY_POLARSSL_H + +#include <stdint.h> + +typedef struct _proxy_polarssl_ctx proxy_polarssl_ctx; + +struct _proxy_polarssl_ctx { + char *host; + uint16_t port; + int connected; + + int (*f_recv)(void *, unsigned char *, size_t); + int (*f_send)(void *, const unsigned char *, size_t); + int (*f_connect)(proxy_polarssl_ctx *); + + void *p_recv; /*!< context for reading operations */ + void *p_send; /*!< context for writing operations */ +}; + +int proxy_polarssl_init(proxy_polarssl_ctx *proxy); +int proxy_polarssl_free(proxy_polarssl_ctx *ctx); + +void proxy_polarssl_set_bio(proxy_polarssl_ctx *ctx, + int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, + int (*f_send)(void *, const unsigned char *, size_t), void *p_send); +int proxy_polarssl_set_scheme(proxy_polarssl_ctx *ctx, const char *scheme); +int proxy_polarssl_set_host(proxy_polarssl_ctx *ctx, const char *host); +void proxy_polarssl_set_port(proxy_polarssl_ctx *ctx, uint16_t port); + +int proxy_polarssl_recv(void *ctx, unsigned char *data, size_t len); +int proxy_polarssl_send(void *ctx, const unsigned char *data, size_t len); + +#endif /* !PROXY_POLARSSL_H */ diff --git a/src/routeup.c b/src/routeup.c new file mode 100644 index 0000000..a5925d5 --- /dev/null +++ b/src/routeup.c @@ -0,0 +1,158 @@ +/* + * routeup.c - listens for routes coming up, tells stdout + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * We emit 'n' for a route coming up. + */ + +#include "config.h" + +#ifdef linux +#include <asm/types.h> +#endif + +#include <sys/socket.h> /* needed for linux/if.h for struct sockaddr */ +#include <errno.h> +#include <fcntl.h> +#include <linux/if.h> +#include <linux/netlink.h> +#include <linux/rtnetlink.h> +#include <linux/sockios.h> +#include <stdio.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/select.h> +#include <unistd.h> + +#include "src/util.h" +#include "src/routeup.h" + +int verbose; +int verbose_debug; + +/* + * Set up the supplied context by creating and binding its netlink socket. + * Returns 0 for success, 1 for failure. + */ +int API +routeup_setup (struct routeup *rtc) +{ + struct sockaddr_nl sa; + memset (&sa, 0, sizeof (sa)); + sa.nl_family = AF_NETLINK; + sa.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; + rtc->netlinkfd = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (rtc->netlinkfd < 0) + { + perror ("netlink socket() failed"); + return 1; + } + if (bind (rtc->netlinkfd, (struct sockaddr *) &sa, sizeof (sa)) < 0) + { + perror ("netlink bind() failed"); + close (rtc->netlinkfd); + return 1; + } + if (fcntl (rtc->netlinkfd, F_SETFL, O_NONBLOCK) < 0) + { + perror ("netlink fcntl(O_NONBLOCK) failed"); + close (rtc->netlinkfd); + return 1; + } + return 0; +} + +/* + * Handle a single netlink message. + * Returns 0 if there was a route status change, 1 if there + * were no valid nlmsghdrs, and -1 if there was a read error. + */ +int API +routeup_process (struct routeup *rtc) +{ + char buf[4096]; + ssize_t sz; + struct nlmsghdr *nh; + if ( (sz = read (rtc->netlinkfd, buf, sizeof (buf))) < 0) + return -1; + for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, sz); + nh = NLMSG_NEXT (nh, sz)) + { + /* + * Unpack the netlink message into a bunch of... well... + * netlink messages. The terminology is overloaded. Walk + * through the message until we find a header of type + * NLMSG_DONE. + */ + if (nh->nlmsg_type == NLMSG_DONE) + break; + if (nh->nlmsg_type != RTM_NEWROUTE) + continue; + /* + * Clear out the socket so we don't keep old messages + * queued up and eventually overflow the receive buffer. + */ + while (read (rtc->netlinkfd, buf, sizeof (buf)) > 0) + /* loop through receive queue */; + if (errno != EAGAIN) return -1; + return 0; + } + return 1; +} + + +/* + * Blocks until we get a route status change message then calls + * route_process(). Returns 0 if there was a route state change, 1 if there + * was a timeout, and -1 if there was a read error. + */ +int API +routeup_once (struct routeup *rtc, unsigned int timeout) +{ + int ret; + struct timeval remaining; + struct timeval *rp = timeout ? &remaining : NULL; + fd_set fds; + remaining.tv_sec = timeout; + remaining.tv_usec = 0; + FD_ZERO (&fds); + FD_SET (rtc->netlinkfd, &fds); + while (select (rtc->netlinkfd + 1, &fds, NULL, NULL, rp) >= 0) + { + FD_ZERO (&fds); + FD_SET (rtc->netlinkfd, &fds); + if (timeout && !remaining.tv_sec && !remaining.tv_usec) + return 1; + ret = routeup_process (rtc); + if (ret == 1) + continue; + return ret; + } + return -1; +} + +/* Tear down the supplied context by closing its netlink socket. */ +void API +routeup_teardown (struct routeup *rtc) +{ + close (rtc->netlinkfd); +} + +#ifdef ROUTEUP_MAIN +int API +main () +{ + struct routeup rtc; + if (routeup_setup (&rtc)) + return 1; + while (!routeup_once (&rtc, 0)) + { + printf ("n\n"); + fflush (stdout); + } + routeup_teardown (&rtc); + return 0; +} +#endif /* ROUTEUP_MAIN */ diff --git a/src/routeup.h b/src/routeup.h new file mode 100644 index 0000000..29d87e2 --- /dev/null +++ b/src/routeup.h @@ -0,0 +1,44 @@ +/* + * routeup.h - routeup library interface + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Call routeup_setup() to initialize a routeup context, then call + * routeup_once() until it returns nonzero (indicating an error) or until + * you're no longer interested in route changes. Call routeup_teardown() + * when you're done with an routeup context. + */ + +#ifndef ROUTEUP_H +#define ROUTEUP_H + +struct routeup +{ + int netlinkfd; /* AF_NETLINK event socket */ +}; + +#ifdef TARGET_OS_LINUX +int routeup_setup (struct routeup *ifc); +int routeup_once (struct routeup *ifc, unsigned int timeout); +int routeup_process (struct routeup *rtc); +void routeup_teardown (struct routeup *ifc); +#else +static inline int routeup_setup (struct routeup *ifc) +{ + return 1; /* Fail for platforms without support. */ +} +static inline int routeup_once (struct routeup *ifc, unsigned int timeout) +{ + return -1; +} +static inline int routeup_process (struct routeup *rtc) +{ + return -1; +} +static inline void routeup_teardown (struct routeup *ifc) +{ +} +#endif + +#endif /* !ROUTEUP_H */ diff --git a/src/rtc.h b/src/rtc.h new file mode 100644 index 0000000..2017e96 --- /dev/null +++ b/src/rtc.h @@ -0,0 +1,9 @@ +#ifndef RTC_H +#define RTC_H + +struct rtc_handle +{ + int fd; +}; + +#endif /* RTC_H */ diff --git a/src/seccomp-compat.h b/src/seccomp-compat.h new file mode 100644 index 0000000..9f1da87 --- /dev/null +++ b/src/seccomp-compat.h @@ -0,0 +1,32 @@ +/* + * seccomp-compat.h - seccomp defines for bad headers + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SECCOMP_COMPAT_H +#define SECCOMP_COMPAT_H + +#include <stdint.h> + +#ifndef PR_SET_NO_NEW_PRIVS +# define PR_SET_NO_NEW_PRIVS 38 +#endif + +#ifndef SECCOMP_MODE_FILTER +#define SECCOMP_MODE_FILTER 2 /* uses user-supplied filter. */ +#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ +#define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ +#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ +#define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ + +struct seccomp_data +{ + int nr; + uint32_t arch; + uint64_t instruction_pointer; + uint64_t args[6]; +}; +#endif /* !SECCOMP_MODE_FILTER */ + +#endif diff --git a/src/seccomp.c b/src/seccomp.c new file mode 100644 index 0000000..fbc5a33 --- /dev/null +++ b/src/seccomp.c @@ -0,0 +1,117 @@ +/* + * seccomp.c - seccomp utility functions + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <asm/unistd.h> +#include <elf.h> +#include <errno.h> +#include <sys/prctl.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <sys/syscall.h> +#include <unistd.h> + +#include <linux/audit.h> +#include <linux/filter.h> + +#include "src/seccomp.h" + +/* Linux seccomp_filter sandbox */ +#define SECCOMP_FILTER_FAIL SECCOMP_RET_KILL + +/* Use a signal handler to emit violations when debugging */ +#ifdef SECCOMP_FILTER_DEBUG +# undef SECCOMP_FILTER_FAIL +# define SECCOMP_FILTER_FAIL SECCOMP_RET_TRAP +#endif /* SANDBOX_SECCOMP_FILTER_DEBUG */ + +/* Simple helpers to avoid manual errors (but larger BPF programs). */ +#define SC_DENY(_nr, _errno) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno)) +#define SC_ALLOW(_nr) \ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_ ## _nr, 0, 1), \ + BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW) + +#if defined(__i386__) +# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386 +#elif defined(__x86_64__) +# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64 +#elif defined(__arm__) +# ifndef EM_ARM +# define EM_ARM 40 +# endif +# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_ARM +#else +# error "Platform does not support seccomp filter yet" +#endif + +/* Returns 0 if the the sandbox is enabled using + * the time setter policy. + */ +int +enable_setter_seccomp (void) +{ + static const struct sock_filter insns[] = + { + /* Ensure the syscall arch convention is as expected. */ + BPF_STMT (BPF_LD+BPF_W+BPF_ABS, + offsetof (struct seccomp_data, arch)), + BPF_JUMP (BPF_JMP+BPF_JEQ+BPF_K, SECCOMP_AUDIT_ARCH, 1, 0), + BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), + /* Load the syscall number for checking. */ + BPF_STMT (BPF_LD+BPF_W+BPF_ABS, + offsetof (struct seccomp_data, nr)), + + /* Process ALLOWs as quickly as possible */ + SC_ALLOW (read), + SC_ALLOW (write), + SC_ALLOW (pwritev), + + SC_ALLOW (settimeofday), + SC_ALLOW (ioctl), /* TODO(wad) filter for fd and RTC_SET_TIME */ +#ifdef __NR_time /* This is required for x86 systems */ + SC_ALLOW (time), +#endif + + SC_ALLOW (lseek), + SC_ALLOW (close), + SC_ALLOW (munmap), + + SC_ALLOW (exit_group), + SC_ALLOW (exit), + + SC_DENY (open, EINVAL), + SC_DENY (fcntl, EINVAL), + SC_DENY (fstat, EINVAL), +#ifdef __NR_mmap + SC_DENY (mmap, EINVAL), +#endif +#ifdef __NR_mmap2 + SC_DENY (mmap2, EINVAL), +#endif +#ifdef __NR_sendto + SC_DENY (sendto, EINVAL), +#endif +#ifdef __NR_socket + SC_DENY (socket, EINVAL), +#endif +#ifdef __NR_socketcall + SC_DENY (socketcall, EINVAL), +#endif + BPF_STMT (BPF_RET+BPF_K, SECCOMP_FILTER_FAIL), + }; + static const struct sock_fprog prog = + { + .len = (unsigned short) (sizeof (insns) /sizeof (insns[0])), + .filter = (struct sock_filter *) insns, + }; + return (prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || + prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)); +} diff --git a/src/seccomp.h b/src/seccomp.h new file mode 100644 index 0000000..5f4a5f3 --- /dev/null +++ b/src/seccomp.h @@ -0,0 +1,24 @@ +/* + * seccomp.h - seccomp functions + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef SECCOMP_H +#define SECCOMP_H + +#include "config.h" + +#include "src/seccomp-compat.h" + +#ifdef HAVE_SECCOMP_FILTER +int enable_setter_seccomp (void); +#else /* HAVE_SECCOMP_FILTER */ +static +inline int enable_setter_seccomp (void) +{ + return 0; +} +#endif /* !HAVE_SECCOMP_FILTER */ + +#endif diff --git a/src/test-bio.c b/src/test-bio.c new file mode 100644 index 0000000..de8dd37 --- /dev/null +++ b/src/test-bio.c @@ -0,0 +1,156 @@ +/* + * test-bio.c - BIO layer for testing + * + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a 'source/sink' BIO which supports synthetic inputs and outputs, and + * can be used to drive filter BIOs through a state machine. It buffers all + * output sent to it, which can be retrieved with BIO_test_get_output(), and + * input sent to it, which is handed back in response to BIO_read() by the + * filter BIO. + */ + +#include <assert.h> +#include <string.h> + +#include "src/test-bio.h" +#include "src/util.h" + +int verbose; +int verbose_debug; + +static const unsigned int kMagic = 0x5f8d3f15; + +struct test_ctx +{ + unsigned int magic; + unsigned char *out; + size_t outsz; + unsigned char *in; + size_t insz; +}; + +static struct test_ctx *bio_ctx (BIO *b) +{ + struct test_ctx *ctx = b->ptr; + assert (ctx->magic == kMagic); + return ctx; +} + +static size_t buf_drain (unsigned char **buf, size_t *bufsz, + unsigned char *out, size_t outsz) +{ + if (*bufsz < outsz) + outsz = *bufsz; + memcpy (out, *buf, outsz); + if (*bufsz > outsz) + memmove (*buf, *buf + outsz, *bufsz - outsz); + *bufsz -= outsz; + *buf = realloc (*buf, *bufsz); + return outsz; +} + +static void buf_fill (unsigned char **buf, size_t *bufsz, + const unsigned char *in, size_t insz) +{ + *buf = realloc (*buf, *bufsz + insz); + memcpy (*buf + *bufsz, in, insz); + *bufsz += insz; +} + +int test_new (BIO *b) +{ + struct test_ctx *ctx = malloc (sizeof *ctx); + if (!ctx) + return 0; + ctx->magic = kMagic; + ctx->in = NULL; + ctx->insz = 0; + ctx->out = NULL; + ctx->outsz = 0; + b->init = 1; + b->flags = 0; + b->ptr = ctx; + return 1; +} + +int test_free (BIO *b) +{ + struct test_ctx *ctx; + if (!b || !b->ptr) + return 1; + ctx = bio_ctx (b); + free (ctx->in); + free (ctx->out); + return 1; +} + +int test_write (BIO *b, const char *buf, int sz) +{ + struct test_ctx *ctx = bio_ctx (b); + if (sz <= 0) + return 0; + buf_fill (&ctx->out, &ctx->outsz, (unsigned char *) buf, sz); + return sz; +} + +int test_read (BIO *b, char *buf, int sz) +{ + struct test_ctx *ctx = bio_ctx (b); + if (sz <= 0) + return 0; + return buf_drain (&ctx->in, &ctx->insz, (unsigned char *) buf, sz); +} + +long test_ctrl (BIO *b, int cmd, long num, void *ptr) +{ + return 0; +} + +long test_callback_ctrl (BIO *b, int cmd, bio_info_cb *fp) +{ + return 0; +} + +BIO_METHOD test_methods = +{ + BIO_TYPE_SOCKET, + "test", + test_write, + test_read, + NULL, + NULL, + test_ctrl, + test_new, + test_free, + test_callback_ctrl, +}; + +BIO_METHOD *BIO_s_test() +{ + return &test_methods; +} + +BIO API *BIO_new_test() +{ + return BIO_new (BIO_s_test()); +} + +size_t API BIO_test_output_left (BIO *b) +{ + return bio_ctx (b)->outsz; +} + +size_t API BIO_test_get_output (BIO *b, unsigned char *buf, size_t bufsz) +{ + struct test_ctx *c = bio_ctx (b); + return buf_drain (&c->out, &c->outsz, buf, bufsz); +} + +void API BIO_test_add_input (BIO *b, const unsigned char *buf, size_t bufsz) +{ + struct test_ctx *c = bio_ctx (b); + return buf_fill (&c->in, &c->insz, buf, bufsz); +} diff --git a/src/test-bio.h b/src/test-bio.h new file mode 100644 index 0000000..dcf1721 --- /dev/null +++ b/src/test-bio.h @@ -0,0 +1,20 @@ +/* + * test-bio.h - test BIO that stores reads/writes + * + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef TEST_BIO_H +#define TEST_BIO_H + +#include <openssl/bio.h> + +BIO *BIO_new_test(); + +size_t BIO_test_output_left (BIO *b); +size_t BIO_test_get_output (BIO *b, unsigned char *buf, size_t bufsz); +void BIO_test_add_input (BIO *b, const unsigned char *buf, size_t bufsz); + +#endif /* !TEST_BIO_H */ diff --git a/src/test/check-host-1.c b/src/test/check-host-1.c new file mode 100644 index 0000000..33f745a --- /dev/null +++ b/src/test/check-host-1.c @@ -0,0 +1,27 @@ +/* test returns a "sane" time if the host, port, and proxy + * are passed in properly on the commandline. The test + * is invoked by tlsdated instead of tlsdate. + * This expects host1, port1, proxy1. + * + * Paired with check-host-2.c, it allows for source rotation + * testing. + */ +#include "config.h" + +#include <string.h> +#include <stdio.h> + +int main (int argc, char *argv[]) +{ + unsigned int t = RECENT_COMPILE_DATE + 1; + if (argc < 7) + return 3; + if (!strcmp (argv[2], "host1") + && !strcmp (argv[4], "port1") + && !strcmp (argv[6], "proxy1")) + { + fwrite (&t, sizeof (t), 1, stdout); + return 0; + } + return 1; +} diff --git a/src/test/check-host-2.c b/src/test/check-host-2.c new file mode 100644 index 0000000..869a865 --- /dev/null +++ b/src/test/check-host-2.c @@ -0,0 +1,26 @@ +/* test returns a "sane" time if the host, port, and proxy + * are passed in properly on the commandline. The test + * is invoked by tlsdated instead of tlsdate. + * This expects host2, port2, proxy2. + * + * Paired with check-host-2.c, it allows for source rotation + * testing. + */ +#include "config.h" +#include <string.h> +#include <stdio.h> + +int main (int argc, char *argv[]) +{ + unsigned int t = RECENT_COMPILE_DATE + 1; + if (argc < 7) + return 3; + if (!strcmp (argv[2], "host2") + && !strcmp (argv[4], "port2") + && !strcmp (argv[6], "proxy2")) + { + fwrite (&t, sizeof (t), 1, stdout); + return 0; + } + return 1; +} diff --git a/src/test/emit.c b/src/test/emit.c new file mode 100644 index 0000000..2c9d8e7 --- /dev/null +++ b/src/test/emit.c @@ -0,0 +1,18 @@ +/* Integration test helper which will print out + * the given time in seconds as an unsigned int. + */ +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int main (int argc, char *argv[]) +{ + /* Unsigned int to match what tlsdate -Vraw returns, not time_t */ + unsigned int t = argc > 1 ? (unsigned int) atoi(argv[1]) : + RECENT_COMPILE_DATE + 1; + fwrite (&t, sizeof (t), 1, stdout); + fflush(stdout); + return 0; +} diff --git a/src/test/proxy-override.c b/src/test/proxy-override.c new file mode 100644 index 0000000..39abdc6 --- /dev/null +++ b/src/test/proxy-override.c @@ -0,0 +1,32 @@ +/* This test is called in lieu of tlsdate by tlsdated + * and it returns a timestamp that matches the proxy + * ordering - global, dynamic, etc. + * For use, see tlsdated-unittests.c + */ +#include "config.h" + +#include <string.h> +#include <stdio.h> + +int main (int argc, char *argv[]) +{ + /* Unsigned int to match what tlsdate -Vraw returns, not time_t */ + /* TODO(wad) move tlsdated -Vraw to emitting time_t */ + unsigned int t = RECENT_COMPILE_DATE + 1; + int saw_good_proxy = 0; + while (argc--) + { + if (!strcmp (argv[0], "socks5://good.proxy")) + saw_good_proxy = 1; + if (!strcmp (argv[0], "socks5://bad.proxy")) + { + t = RECENT_COMPILE_DATE + 3; + break; + } + argv++; + } + if (saw_good_proxy) + t = RECENT_COMPILE_DATE + 2; + fwrite (&t, sizeof (t), 1, stdout); + return 0; +} diff --git a/src/test/return-argc.c b/src/test/return-argc.c new file mode 100644 index 0000000..3bcface --- /dev/null +++ b/src/test/return-argc.c @@ -0,0 +1,3 @@ +/* return-argc.c - returns argc */ + +int main(int argc, char *argv[]) { return argc; } diff --git a/src/test/sleep-wrap.c b/src/test/sleep-wrap.c new file mode 100644 index 0000000..d45d92f --- /dev/null +++ b/src/test/sleep-wrap.c @@ -0,0 +1,20 @@ +/* Test invoked by tlsdated instead of tlsdate to + * show allow arbitrary delays before returning a + * "sane" time. This makes for easy timeout testing. + */ +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +int main (int argc, char *argv[]) +{ + /* Unsigned int to match what tlsdate -Vraw returns, not time_t */ + unsigned int t = RECENT_COMPILE_DATE + 1; + if (argc < 2) + return 1; + sleep (atoi (argv[1])); + fwrite (&t, sizeof (t), 1, stdout); + return 0; +} diff --git a/src/test_harness.h b/src/test_harness.h new file mode 100644 index 0000000..3fd118a --- /dev/null +++ b/src/test_harness.h @@ -0,0 +1,451 @@ +/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * test_harness.h: simple C unit test helper. + * + * Usage: + * #include "test_harness.h" + * TEST(standalone_test) { + * do_some_stuff; + * EXPECT_GT(10, stuff) { + * stuff_state_t state; + * enumerate_stuff_state(&state); + * TH_LOG("expectation failed with state: %s", state.msg); + * } + * more_stuff; + * ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!"); + * last_stuff; + * EXPECT_EQ(0, last_stuff); + * } + * + * FIXTURE(my_fixture) { + * mytype_t *data; + * int awesomeness_level; + * }; + * FIXTURE_SETUP(my_fixture) { + * self->data = mytype_new(); + * ASSERT_NE(NULL, self->data); + * } + * FIXTURE_TEARDOWN(my_fixture) { + * mytype_free(self->data); + * } + * TEST_F(my_fixture, data_is_good) { + * EXPECT_EQ(1, is_my_data_good(self->data)); + * } + * + * TEST_HARNESS_MAIN + * + * API inspired by code.google.com/p/googletest + */ +#ifndef TEST_HARNESS_H_ +#define TEST_HARNESS_H_ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +/* All exported functionality should be declared through this macro. */ +#define TEST_API(x) _##x + +/* + * Exported APIs + */ + +/* TEST(name) { implementation } + * Defines a test by name. + * Names must be unique and tests must not be run in parallel. The + * implementation containing block is a function and scoping should be treated + * as such. Returning early may be performed with a bare "return;" statement. + * + * EXPECT_* and ASSERT_* are valid in a TEST() { } context. + */ +#define TEST TEST_API(TEST) + +/* FIXTURE(datatype name) { + * type property1; + * ... + * }; + * Defines the data provided to TEST_F()-defined tests as |self|. It should be + * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN. + */ +#define FIXTURE TEST_API(FIXTURE) + +/* FIXTURE_DATA(datatype name) + * This call may be used when the type of the fixture data + * is needed. In general, this should not be needed unless + * the |self| is being passed to a helper directly. + */ +#define FIXTURE_DATA TEST_API(FIXTURE_DATA) + +/* FIXTURE_SETUP(fixture name) { implementation } + * Populates the required "setup" function for a fixture. An instance of the + * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * implementation. + * + * ASSERT_* are valid for use in this context and will prempt the execution + * of any dependent fixture tests. + * + * A bare "return;" statement may be used to return early. + */ +#define FIXTURE_SETUP TEST_API(FIXTURE_SETUP) + +/* FIXTURE_TEARDOWN(fixture name) { implementation } + * Populates the required "teardown" function for a fixture. An instance of the + * datatype defined with _FIXTURE_DATA will be exposed as |self| for the + * implementation to clean up. + * + * A bare "return;" statement may be used to return early. + */ +#define FIXTURE_TEARDOWN TEST_API(FIXTURE_TEARDOWN) + +/* TEST_F(fixture, name) { implementation } + * Defines a test that depends on a fixture (e.g., is part of a test case). + * Very similar to TEST() except that |self| is the setup instance of fixture's + * datatype exposed for use by the implementation. + */ +#define TEST_F TEST_API(TEST_F) + +/* Use once to append a main() to the test file. E.g., + * TEST_HARNESS_MAIN + */ +#define TEST_HARNESS_MAIN TEST_API(TEST_HARNESS_MAIN) + +/* + * Operators for use in TEST and TEST_F. + * ASSERT_* calls will stop test execution immediately. + * EXPECT_* calls will emit a failure warning, note it, and continue. + */ + +/* ASSERT_EQ(expected, measured): expected == measured */ +#define ASSERT_EQ TEST_API(ASSERT_EQ) +/* ASSERT_NE(expected, measured): expected != measured */ +#define ASSERT_NE TEST_API(ASSERT_NE) +/* ASSERT_LT(expected, measured): expected < measured */ +#define ASSERT_LT TEST_API(ASSERT_LT) +/* ASSERT_LE(expected, measured): expected <= measured */ +#define ASSERT_LE TEST_API(ASSERT_LE) +/* ASSERT_GT(expected, measured): expected > measured */ +#define ASSERT_GT TEST_API(ASSERT_GT) +/* ASSERT_GE(expected, measured): expected >= measured */ +#define ASSERT_GE TEST_API(ASSERT_GE) +/* ASSERT_NULL(measured): NULL == measured */ +#define ASSERT_NULL TEST_API(ASSERT_NULL) +/* ASSERT_TRUE(measured): measured != 0 */ +#define ASSERT_TRUE TEST_API(ASSERT_TRUE) +/* ASSERT_FALSE(measured): measured == 0 */ +#define ASSERT_FALSE TEST_API(ASSERT_FALSE) +/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define ASSERT_STREQ TEST_API(ASSERT_STREQ) +/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */ +#define ASSERT_STRNE TEST_API(ASSERT_STRNE) +/* EXPECT_EQ(expected, measured): expected == measured */ +#define EXPECT_EQ TEST_API(EXPECT_EQ) +/* EXPECT_NE(expected, measured): expected != measured */ +#define EXPECT_NE TEST_API(EXPECT_NE) +/* EXPECT_LT(expected, measured): expected < measured */ +#define EXPECT_LT TEST_API(EXPECT_LT) +/* EXPECT_LE(expected, measured): expected <= measured */ +#define EXPECT_LE TEST_API(EXPECT_LE) +/* EXPECT_GT(expected, measured): expected > measured */ +#define EXPECT_GT TEST_API(EXPECT_GT) +/* EXPECT_GE(expected, measured): expected >= measured */ +#define EXPECT_GE TEST_API(EXPECT_GE) +/* EXPECT_NULL(measured): NULL == measured */ +#define EXPECT_NULL TEST_API(EXPECT_NULL) +/* EXPECT_TRUE(measured): 0 != measured */ +#define EXPECT_TRUE TEST_API(EXPECT_TRUE) +/* EXPECT_FALSE(measured): 0 == measured */ +#define EXPECT_FALSE TEST_API(EXPECT_FALSE) +/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */ +#define EXPECT_STREQ TEST_API(EXPECT_STREQ) +/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */ +#define EXPECT_STRNE TEST_API(EXPECT_STRNE) + +/* TH_LOG(format, ...) + * Optional debug logging function available for use in tests. + * Logging may be enabled or disabled by defining TH_LOG_ENABLED. + * E.g., #define TH_LOG_ENABLED 1 + * If no definition is provided, logging is enabled by default. + */ +#define TH_LOG TEST_API(TH_LOG) + +/* + * Internal implementation. + * + */ + +/* Utilities exposed to the test definitions */ +#ifndef TH_LOG_STREAM +# define TH_LOG_STREAM stderr +#endif + +#ifndef TH_LOG_ENABLED +# define TH_LOG_ENABLED 1 +#endif + +#define _TH_LOG(fmt, ...) do { \ + if (TH_LOG_ENABLED) \ + __TH_LOG(fmt, ##__VA_ARGS__); \ +} while (0) + +/* Unconditional logger for internal use. */ +#define __TH_LOG(fmt, ...) \ + fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ + __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) + +/* Defines the test function and creates the registration stub. */ +#define _TEST(test_name) \ + static void test_name(struct __test_metadata *_metadata); \ + static struct __test_metadata _##test_name##_object = \ + { name: "global." #test_name, fn: &test_name }; \ + static void __attribute__((constructor)) _register_##test_name(void) { \ + __register_test(&_##test_name##_object); \ + } \ + static void test_name( \ + struct __test_metadata __attribute__((unused)) *_metadata) + +/* Wraps the struct name so we have one less argument to pass around. */ +#define _FIXTURE_DATA(fixture_name) struct _test_data_##fixture_name + +/* Called once per fixture to setup the data and register. */ +#define _FIXTURE(fixture_name) \ + static void __attribute__((constructor)) \ + _register_##fixture_name##_data(void) { \ + __fixture_count++; \ + } \ + _FIXTURE_DATA(fixture_name) + +/* Prepares the setup function for the fixture. |_metadata| is included + * so that ASSERT_* work as a convenience. + */ +#define _FIXTURE_SETUP(fixture_name) \ + void fixture_name##_setup( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) +#define _FIXTURE_TEARDOWN(fixture_name) \ + void fixture_name##_teardown( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) + +/* Emits test registration and helpers for fixture-based test + * cases. + * TODO(wad) register fixtures on dedicated test lists. + */ +#define _TEST_F(fixture_name, test_name) \ + static void fixture_name##_##test_name( \ + struct __test_metadata *_metadata, \ + _FIXTURE_DATA(fixture_name) *self); \ + static inline void wrapper_##fixture_name##_##test_name( \ + struct __test_metadata *_metadata) { \ + /* fixture data is allocated, setup, and torn down per call. */ \ + _FIXTURE_DATA(fixture_name) self; \ + memset(&self, 0, sizeof(_FIXTURE_DATA(fixture_name))); \ + fixture_name##_setup(_metadata, &self); \ + /* Let setup failure terminate early. */ \ + if (!_metadata->passed) return; \ + fixture_name##_##test_name(_metadata, &self); \ + fixture_name##_teardown(_metadata, &self); \ + } \ + static struct __test_metadata _##fixture_name##_##test_name##_object = { \ + name: #fixture_name "." #test_name, \ + fn: &wrapper_##fixture_name##_##test_name, \ + }; \ + static void __attribute__((constructor)) \ + _register_##fixture_name##_##test_name(void) { \ + __register_test(&_##fixture_name##_##test_name##_object); \ + } \ + static void fixture_name##_##test_name( \ + struct __test_metadata __attribute__((unused)) *_metadata, \ + _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) + +/* Exports a simple wrapper to run the test harness. */ +#define _TEST_HARNESS_MAIN \ + int main(int argc, char **argv) { return test_harness_run(argc, argv); } + +#define _ASSERT_EQ(_expected, _seen) \ + __EXPECT(_expected, _seen, ==, 1) +#define _ASSERT_NE(_expected, _seen) \ + __EXPECT(_expected, _seen, !=, 1) +#define _ASSERT_LT(_expected, _seen) \ + __EXPECT(_expected, _seen, <, 1) +#define _ASSERT_LE(_expected, _seen) \ + __EXPECT(_expected, _seen, <=, 1) +#define _ASSERT_GT(_expected, _seen) \ + __EXPECT(_expected, _seen, >, 1) +#define _ASSERT_GE(_expected, _seen) \ + __EXPECT(_expected, _seen, >=, 1) +#define _ASSERT_NULL(_seen) \ + __EXPECT(NULL, _seen, ==, 1) + +#define _ASSERT_TRUE(_seen) \ + _ASSERT_NE(0, _seen) +#define _ASSERT_FALSE(_seen) \ + _ASSERT_EQ(0, _seen) +#define _ASSERT_STREQ(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, ==, 1) +#define _ASSERT_STRNE(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, !=, 1) + +#define _EXPECT_EQ(_expected, _seen) \ + __EXPECT(_expected, _seen, ==, 0) +#define _EXPECT_NE(_expected, _seen) \ + __EXPECT(_expected, _seen, !=, 0) +#define _EXPECT_LT(_expected, _seen) \ + __EXPECT(_expected, _seen, <, 0) +#define _EXPECT_LE(_expected, _seen) \ + __EXPECT(_expected, _seen, <=, 0) +#define _EXPECT_GT(_expected, _seen) \ + __EXPECT(_expected, _seen, >, 0) +#define _EXPECT_GE(_expected, _seen) \ + __EXPECT(_expected, _seen, >=, 0) + +#define _EXPECT_NULL(_seen) \ + __EXPECT(NULL, _seen, ==, 0) +#define _EXPECT_TRUE(_seen) \ + _EXPECT_NE(0, _seen) +#define _EXPECT_FALSE(_seen) \ + _EXPECT_EQ(0, _seen) + +#define _EXPECT_STREQ(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, ==, 0) +#define _EXPECT_STRNE(_expected, _seen) \ + __EXPECT_STR(_expected, _seen, !=, 0) + +/* Support an optional handler after and ASSERT_* or EXPECT_*. The approach is + * not thread-safe, but it should be fine in most sane test scenarios. + * + * Using __bail(), which optionally abort()s, is the easiest way to early + * return while still providing an optional block to the API consumer. + */ +#define OPTIONAL_HANDLER(_assert) \ + for (; _metadata->trigger; _metadata->trigger = __bail(_assert)) + +#define __EXPECT(_expected, _seen, _t, _assert) do { \ + /* Avoid multiple evaluation of the cases */ \ + __typeof__(_expected) __exp = (_expected); \ + __typeof__(_seen) __seen = (_seen); \ + if (!(__exp _t __seen)) { \ + unsigned long long __exp_print = 0; \ + unsigned long long __seen_print = 0; \ + /* Avoid casting complaints the scariest way we can. */ \ + memcpy(&__exp_print, &__exp, sizeof(__exp)); \ + memcpy(&__seen_print, &__seen, sizeof(__seen)); \ + __TH_LOG("Expected %s (%llu) %s %s (%llu)", \ + #_expected, __exp_print, #_t, \ + #_seen, __seen_print); \ + _metadata->passed = 0; \ + /* Ensure the optional handler is triggered */ \ + _metadata->trigger = 1; \ + } \ +} while (0); OPTIONAL_HANDLER(_assert) + +#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \ + const char *__exp = (_expected); \ + const char *__seen = (_seen); \ + if (!(strcmp(__exp, __seen) _t 0)) { \ + __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \ + _metadata->passed = 0; \ + _metadata->trigger = 1; \ + } \ +} while (0); OPTIONAL_HANDLER(_assert) + +/* Contains all the information for test execution and status checking. */ +struct __test_metadata +{ + const char *name; + void (*fn) (struct __test_metadata *); + int passed; + int trigger; /* extra handler after the evaluation */ + struct __test_metadata *prev, *next; +}; + +/* Storage for the (global) tests to be run. */ +static struct __test_metadata *__test_list = NULL; +static unsigned int __test_count = 0; +static unsigned int __fixture_count = 0; + +static inline void __register_test (struct __test_metadata *t) +{ + __test_count++; + /* Circular linked list where only prev is circular. */ + if (__test_list == NULL) + { + __test_list = t; + t->next = NULL; + t->prev = t; + return; + } + t->next = NULL; + t->prev = __test_list->prev; + t->prev->next = t; + __test_list->prev = t; +} + +static inline int __bail (int for_realz) +{ + if (for_realz) + abort(); + return 0; +} + +static int test_harness_run (int __attribute__ ( (unused)) argc, + char __attribute__ ( (unused)) **argv) +{ + struct __test_metadata *t; + int ret = 0; + unsigned int count = 0; + /* TODO(wad) add optional arguments similar to gtest. */ + printf ("[==========] Running %u tests from %u test cases.\n", + __test_count, __fixture_count + 1); + for (t = __test_list; t; t = t->next) + { + pid_t child_pid; + int status; + count++; + t->passed = 1; + t->trigger = 0; + printf ("[ RUN ] %s\n", t->name); + child_pid = fork(); + if (child_pid < 0) + { + printf ("ERROR SPAWNING TEST CHILD\n"); + t->passed = 0; + } + else if (child_pid == 0) + { + t->fn (t); + _exit (t->passed); + } + else + { + /* TODO(wad) add timeout support. */ + waitpid (child_pid, &status, 0); + if (WIFEXITED (status)) + t->passed = WEXITSTATUS (status); + if (WIFSIGNALED (status)) + { + t->passed = 0; + fprintf (TH_LOG_STREAM, + "%s: Test terminated unexpectedly by signal %d\n", + t->name, + WTERMSIG (status)); + } + } + printf ("[ %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name); + if (!t->passed) + ret = 1; + } + /* TODO(wad) organize by fixtures since ordering is not guaranteed now. */ + printf ("[==========] %u tests ran.\n", count); + printf ("[ %s ]\n", (ret ? "FAILED" : "PASSED")); + return ret; +} + +#endif /* TEST_HARNESS_H_ */ diff --git a/src/tlsdate-helper-plan9.c b/src/tlsdate-helper-plan9.c new file mode 100644 index 0000000..3c532aa --- /dev/null +++ b/src/tlsdate-helper-plan9.c @@ -0,0 +1,1250 @@ +/* Copyright (c) 2012, Jacob Appelbaum. + * Copyright (c) 2012, The Tor Project, Inc. + * Copyright (c) 2012, Christian Grothoff. */ +/* See LICENSE for licensing information */ +/* + This file contains the license for tlsdate, + a free software project to set your system clock securely. + + It also lists the licenses for other components used by tlsdate. + + For more information about tlsdate, see https://github.com/ioerror/tlsdate + + If you got this file as a part of a larger bundle, + there may be other license terms that you should be aware of. + +=============================================================================== +tlsdate is distributed under this license: + +Copyright (c) 2011-2012, Jacob Appelbaum <jacob@appelbaum.net> +Copyright (c) 2011-2012, The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=============================================================================== +If you got tlsdate as a static binary with OpenSSL included, then you should +know: + + "This product includes software developed by the OpenSSL Project for use in + the OpenSSL Toolkit (http://www.openssl.org/)" + +=============================================================================== +*/ + +/** + * \file tlsdate-helper.c + * \brief Helper program that does the actual work of setting the system clock. + **/ + +/* + * tlsdate is a tool for setting the system clock by hand or by communication + * with the network. It does not set the RTC. It is designed to be as secure as + * TLS (RFC 2246) but of course the security of TLS is often reduced to + * whichever CA racket you believe is trustworthy. By default, tlsdate trusts + * your local CA root store - so any of these companies could assist in a MITM + * attack against you and you'd be screwed. + + * This tool is designed to be run by hand or as a system daemon. It must be + * run as root or otherwise have the proper caps; it will not be able to set + * the system time without running as root or another privileged user. + */ + +#include "config.h" +#include "src/tlsdate-helper-plan9.h" + +#ifndef USE_POLARSSL +#include "src/proxy-bio-plan9.h" +#else +#include "src/proxy-polarssl.h" +#endif + +#include "src/compat/clock-plan9.h" + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +#ifdef USE_POLARSSL +#include "polarssl/entropy.h" +#include "polarssl/ctr_drbg.h" +#include "polarssl/ssl.h" +#endif + +static void +validate_proxy_scheme(const char *scheme) +{ + if (!strcmp(scheme, "http")) + return; + if (!strcmp(scheme, "socks4")) + return; + if (!strcmp(scheme, "socks5")) + return; + die("invalid proxy scheme\n"); +} + +static void +validate_proxy_host(const char *host) +{ + const char *kValid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + ".-"; + if (strspn(host, kValid) != strlen(host)) + die("invalid char in host\n"); +} + +static void +validate_proxy_port(const char *port) +{ + while (*port) + if (!isdigit(*port++)) + die("invalid char in port\n"); +} + +static void +parse_proxy_uri(char *proxy, char **scheme, char **host, char **port) +{ + /* Expecting a URI, so: <scheme> '://' <host> ':' <port> */ + *scheme = proxy; + proxy = strstr(proxy, "://"); + if (!proxy) + die("malformed proxy URI\n"); + *proxy = '\0'; /* terminate scheme string */ + proxy += strlen("://"); + + *host = proxy; + proxy = strchr(proxy, ':'); + if (!proxy) + die("malformed proxy URI\n"); + *proxy++ = '\0'; + + *port = proxy; + + validate_proxy_scheme(*scheme); + validate_proxy_host(*host); + validate_proxy_port(*port); +} + +#ifndef USE_POLARSSL +static void +setup_proxy(BIO *ssl) +{ + BIO *bio; + char *scheme; + char *proxy_host; + char *proxy_port; + + if (!proxy) + return; + /* + * grab the proxy's host and port out of the URI we have for it. We want the + * underlying connect BIO to connect to this, not the target host and port, so + * we squirrel away the target host and port in the proxy BIO (as the proxy + * target) and swap out the connect BIO's target host and port so it'll + * connect to the proxy instead. + */ + parse_proxy_uri(proxy, &scheme, &proxy_host, &proxy_port); + bio = BIO_new_proxy(); + BIO_proxy_set_type(bio, scheme); + BIO_proxy_set_host(bio, host); + BIO_proxy_set_port(bio, atoi(port)); + host = proxy_host; + port = proxy_port; + BIO_push(ssl, bio); +} + +static BIO * +make_ssl_bio(SSL_CTX *ctx) +{ + BIO *con = NULL; + BIO *ssl = NULL; + + if (!(con = BIO_new(BIO_s_connect()))) + die("BIO_s_connect failed\n"); + if (!(ssl = BIO_new_ssl(ctx, 1))) + die("BIO_new_ssl failed\n"); + setup_proxy(ssl); + BIO_push(ssl, con); + return ssl; +} + +/** helper function for 'malloc' */ +static void * +xmalloc (size_t size) +{ + void *ptr; + + if (0 == size) + die("xmalloc: zero size\n"); + + ptr = malloc(size); + if (NULL == ptr) + die("xmalloc: out of memory (allocating %zu bytes)\n", size); + + return ptr; +} + + +/** helper function for 'free' */ +static void +xfree (void *ptr) +{ + if (NULL == ptr) + die("xfree: NULL pointer given as argument\n"); + + free(ptr); +} + +void +openssl_time_callback (const SSL* ssl, int where, int ret) +{ + if (where == SSL_CB_CONNECT_LOOP && + (ssl->state == SSL3_ST_CR_SRVR_HELLO_A || ssl->state == SSL3_ST_CR_SRVR_HELLO_B)) + { + /* + // XXX TODO: If we want to trust the remote system for time, + // can we just read that time out of the remote system and if the + // cert verifies, decide that the time is reasonable? + // Such a process seems to indicate that a once valid cert would be + // forever valid - we stopgap that by ensuring it isn't less than + // the latest compiled_time and isn't above max_reasonable_time... + // XXX TODO: Solve eternal question about the Chicken and the Egg... + */ + uint32_t compiled_time = RECENT_COMPILE_DATE; + uint32_t max_reasonable_time = MAX_REASONABLE_TIME; + uint32_t server_time; + verb("V: freezing time for x509 verification\n"); + memcpy(&server_time, ssl->s3->server_random, sizeof(uint32_t)); + if (compiled_time < ntohl(server_time) + && + ntohl(server_time) < max_reasonable_time) + { + verb("V: remote peer provided: %d, preferred over compile time: %d\n", + ntohl(server_time), compiled_time); + verb("V: freezing time with X509_VERIFY_PARAM_set_time\n"); + X509_VERIFY_PARAM_set_time(ssl->ctx->cert_store->param, + (time_t) ntohl(server_time) + 86400); + } else { + die("V: the remote server is a false ticker! server: %d compile: %d\n", + ntohl(server_time), compiled_time); + } + } +} + +uint32_t +get_certificate_keybits (EVP_PKEY *public_key) +{ + /* + In theory, we could use check_bitlen_dsa() and check_bitlen_rsa() + */ + uint32_t key_bits; + switch (public_key->type) + { + case EVP_PKEY_RSA: + verb("V: key type: EVP_PKEY_RSA\n"); + key_bits = BN_num_bits(public_key->pkey.rsa->n); + break; + case EVP_PKEY_RSA2: + verb("V: key type: EVP_PKEY_RSA2\n"); + key_bits = BN_num_bits(public_key->pkey.rsa->n); + break; + case EVP_PKEY_DSA: + verb("V: key type: EVP_PKEY_DSA\n"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA1: + verb("V: key type: EVP_PKEY_DSA1\n"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA2: + verb("V: key type: EVP_PKEY_DSA2\n"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA3: + verb("V: key type: EVP_PKEY_DSA3\n"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA4: + verb("V: key type: EVP_PKEY_DSA4\n"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DH: + verb("V: key type: EVP_PKEY_DH\n"); + key_bits = BN_num_bits(public_key->pkey.dh->pub_key); + break; + case EVP_PKEY_EC: + verb("V: key type: EVP_PKEY_EC\n"); + key_bits = EVP_PKEY_bits(public_key); + break; + // Should we also care about EVP_PKEY_HMAC and EVP_PKEY_CMAC? + default: + key_bits = 0; + die ("unknown public key type\n"); + break; + } + verb ("V: keybits: %d\n", key_bits); + return key_bits; +} + +uint32_t +dns_label_count(char *label, char *delim) +{ + char *label_tmp; + char *saveptr; + char *saveptr_tmp; + uint32_t label_count; + + label_tmp = strdup(label); + label_count = 0; + saveptr = NULL; + saveptr_tmp = NULL; + saveptr = strtok_r(label_tmp, delim, &saveptr); + if (NULL != saveptr) + { + // Did we find our first label? + if (saveptr[0] != delim[0]) + { + label_count++; + verb ("V: label found; total label count: %d\n", label_count); + } + do + { + // Find all subsequent labels + label_count++; + saveptr_tmp = strtok_r(NULL, delim, &saveptr); + verb ("V: label found; total label count: %d\n", label_count); + } while (NULL != saveptr_tmp); + } + free(label_tmp); + return label_count; +} + +// first we split strings on '.' +// then we call each split string a 'label' +// Do not allow '*' for the top level domain label; eg never allow *.*.com +// Do not allow '*' for subsequent subdomains; eg never allow *.foo.example.com +// Do allow *.example.com +uint32_t +check_wildcard_match_rfc2595 (const char *orig_hostname, + const char *orig_cert_wild_card) +{ + char *hostname; + char *hostname_to_free; + char *cert_wild_card; + char *cert_wild_card_to_free; + char *expected_label; + char *wildcard_label; + char *delim; + char *wildchar; + uint32_t ok; + uint32_t wildcard_encountered; + uint32_t label_count; + + // First we copy the original strings + hostname = strdup(orig_hostname); + cert_wild_card = strdup(orig_cert_wild_card); + hostname_to_free = hostname; + cert_wild_card_to_free = cert_wild_card; + delim = strdup("."); + wildchar = strdup("*"); + + verb ("V: Inspecting '%s' for possible wildcard match against '%s'\n", + hostname, cert_wild_card); + + // By default we have not processed any labels + label_count = dns_label_count(cert_wild_card, delim); + + // By default we have no match + ok = 0; + wildcard_encountered = 0; + // First - do we have labels? If not, we refuse to even try to match + if ((NULL != strpbrk(cert_wild_card, delim)) && + (NULL != strpbrk(hostname, delim)) && + (label_count <= ((uint32_t)RFC2595_MIN_LABEL_COUNT))) + { + if (wildchar[0] == cert_wild_card[0]) + { + verb ("V: Found wildcard in at start of provided certificate name\n"); + do + { + // Skip over the bytes between the first char and until the next label + wildcard_label = strtok(cert_wild_card, delim); + expected_label = strtok(hostname, delim); + if (NULL != wildcard_label && + NULL != expected_label && + NULL != hostname && + NULL != cert_wild_card) + { + // Now we only consider this wildcard valid if the rest of the + // hostnames match verbatim + verb ("V: Attempting match of '%s' against '%s'\n", + expected_label, wildcard_label); + // This is the case where we have a label that begins with wildcard + // Furthermore, we only allow this for the first label + if (wildcard_label[0] == wildchar[0] && + 0 == wildcard_encountered && 0 == ok) + { + verb ("V: Forced match of '%s' against '%s'\n", expected_label, wildcard_label); + wildcard_encountered = 1; + } else { + verb ("V: Attempting match of '%s' against '%s'\n", + hostname, cert_wild_card); + if (0 == strcasecmp (expected_label, wildcard_label) && + label_count >= ((uint32_t)RFC2595_MIN_LABEL_COUNT)) + { + ok = 1; + verb ("V: remaining labels match!\n"); + break; + } else { + ok = 0; + verb ("V: remaining labels do not match!\n"); + break; + } + } + } else { + // We hit this case when we have a mismatched number of labels + verb("V: NULL label; no wildcard here\n"); + break; + } + } while (0 != wildcard_encountered && label_count <= RFC2595_MIN_LABEL_COUNT); + } else { + verb ("V: Not a RFC 2595 wildcard\n"); + } + } else { + verb ("V: Not a valid wildcard certificate\n"); + ok = 0; + } + // Free our copies + free(wildchar); + free(delim); + free(hostname_to_free); + free(cert_wild_card_to_free); + if (wildcard_encountered & ok && label_count >= RFC2595_MIN_LABEL_COUNT) + { + verb ("V: wildcard match of %s against %s\n", + orig_hostname, orig_cert_wild_card); + return (wildcard_encountered & ok); + } else { + verb ("V: wildcard match failure of %s against %s\n", + orig_hostname, orig_cert_wild_card); + return 0; + } +} +#endif + +#ifndef USE_POLARSSL +/** + This extracts the first commonName and checks it against hostname. +*/ +uint32_t +check_cn (SSL *ssl, const char *hostname) +{ + int ok = 0; + int ret; + char *cn_buf; + X509 *certificate; + X509_NAME *xname; + + // We cast this to cast away g++ complaining about the following: + // error: invalid conversion from ‘void*’ to ‘char*’ + cn_buf = (char *) xmalloc(TLSDATE_HOST_NAME_MAX + 1); + + certificate = SSL_get_peer_certificate(ssl); + if (NULL == certificate) + { + die ("Unable to extract certificate\n"); + } + + memset(cn_buf, '\0', (TLSDATE_HOST_NAME_MAX + 1)); + xname = X509_get_subject_name(certificate); + ret = X509_NAME_get_text_by_NID(xname, NID_commonName, + cn_buf, TLSDATE_HOST_NAME_MAX); + + if (-1 == ret || ret != (int) strlen(cn_buf)) + { + die ("Unable to extract commonName\n"); + } + if (strcasecmp(cn_buf, hostname)) + { + verb ("V: commonName mismatch! Expected: %s - received: %s\n", + hostname, cn_buf); + } else { + verb ("V: commonName matched: %s\n", cn_buf); + ok = 1; + } + + X509_NAME_free(xname); + X509_free(certificate); + xfree(cn_buf); + + return ok; +} + +/** + Search for a hostname match in the SubjectAlternativeNames. +*/ +uint32_t +check_san (SSL *ssl, const char *hostname) +{ + X509 *cert; + int extcount, ok = 0; + /* What an OpenSSL mess ... */ + if (NULL == (cert = SSL_get_peer_certificate(ssl))) + { + die ("Getting certificate failed\n"); + } + + if ((extcount = X509_get_ext_count(cert)) > 0) + { + int i; + for (i = 0; i < extcount; ++i) + { + const char *extstr; + X509_EXTENSION *ext; + ext = X509_get_ext(cert, i); + extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); + + if (!strcmp(extstr, "subjectAltName")) + { + + int j; + void *extvalstr; + const unsigned char *tmp; + + STACK_OF(CONF_VALUE) *val; + CONF_VALUE *nval; +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + const +#endif + X509V3_EXT_METHOD *method; + + if (!(method = X509V3_EXT_get(ext))) + { + break; + } + + tmp = ext->value->data; + if (method->it) + { + extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length, + ASN1_ITEM_ptr(method->it)); + } else { + extvalstr = method->d2i(NULL, &tmp, ext->value->length); + } + + if (!extvalstr) + { + break; + } + + if (method->i2v) + { + val = method->i2v(method, extvalstr, NULL); + for (j = 0; j < sk_CONF_VALUE_num(val); ++j) + { + nval = sk_CONF_VALUE_value(val, j); + if ((!strcasecmp(nval->name, "DNS") && + !strcasecmp(nval->value, hostname) ) || + (!strcasecmp(nval->name, "iPAddress") && + !strcasecmp(nval->value, hostname))) + { + verb ("V: subjectAltName matched: %s, type: %s\n", nval->value, nval->name); /* We matched this; so it's safe to print */ + ok = 1; + break; + } + // Attempt to match subjectAltName DNS names + if (!strcasecmp(nval->name, "DNS")) + { + ok = check_wildcard_match_rfc2595(hostname, nval->value); + if (ok) + { + break; + } + } + verb ("V: subjectAltName found but not matched: %s, type: %s\n", nval->value, nval->name); // XXX: Clean this string! + } + } + } else { + verb ("V: found non subjectAltName extension\n"); + } + if (ok) + { + break; + } + } + } else { + verb ("V: no X509_EXTENSION field(s) found\n"); + } + X509_free(cert); + return ok; +} + +uint32_t +check_name (SSL *ssl, const char *hostname) +{ + uint32_t ret; + ret = check_cn(ssl, hostname); + ret += check_san(ssl, hostname); + if (0 != ret && 0 < ret) + { + verb ("V: hostname verification passed\n"); + } else { + die ("hostname verification failed for host %s!\n", host); + } + return ret; +} +#endif + +#ifdef USE_POLARSSL +uint32_t +verify_signature (ssl_context *ssl, const char *hostname) +{ + int ssl_verify_result; + + ssl_verify_result = ssl_get_verify_result (ssl); + if (ssl_verify_result & BADCERT_EXPIRED) + { + die ("certificate has expired\n"); + } + if (ssl_verify_result & BADCERT_REVOKED) + { + die ("certificate has been revoked\n"); + } + if (ssl_verify_result & BADCERT_CN_MISMATCH) + { + die ("CN and subject AltName mismatch for certificate\n"); + } + if (ssl_verify_result & BADCERT_NOT_TRUSTED) + { + die ("certificate is self-signed or not signed by a trusted CA\n"); + } + + if (0 == ssl_verify_result) + { + verb ("V: verify success\n"); + } + else + { + die ("certificate verification error: -0x%04x\n", -ssl_verify_result); + } + return 0; +} +#else +uint32_t +verify_signature (SSL *ssl, const char *hostname) +{ + long ssl_verify_result; + X509 *certificate; + + certificate = SSL_get_peer_certificate(ssl); + if (NULL == certificate) + { + die ("Getting certificate failed\n"); + } + // In theory, we verify that the cert is valid + ssl_verify_result = SSL_get_verify_result(ssl); + switch (ssl_verify_result) + { + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + die ("certificate is self signed\n"); + case X509_V_OK: + verb ("V: certificate verification passed\n"); + break; + default: + die ("certification verification error: %ld\n", + ssl_verify_result); + } + return 0; +} +#endif + +#ifdef USE_POLARSSL +void +check_key_length (ssl_context *ssl) +{ + uint32_t key_bits; + const x509_cert *certificate; + const rsa_context *public_key; + char buf[1024]; + + certificate = ssl_get_peer_cert (ssl); + if (NULL == certificate) + { + die ("Getting certificate failed\n"); + } + + x509parse_dn_gets(buf, 1024, &certificate->subject); + verb ("V: Certificate for subject '%s'\n", buf); + + public_key = &certificate->rsa; + if (NULL == public_key) + { + die ("public key extraction failure\n"); + } else { + verb ("V: public key is ready for inspection\n"); + } + key_bits = mpi_msb (&public_key->N); + if (MIN_PUB_KEY_LEN >= key_bits) + { + die ("Unsafe public key size: %d bits\n", key_bits); + } else { + verb ("V: key length appears safe\n"); + } +} +#else +void +check_key_length (SSL *ssl) +{ + uint32_t key_bits; + X509 *certificate; + EVP_PKEY *public_key; + certificate = SSL_get_peer_certificate (ssl); + if (NULL == certificate) + { + die ("Getting certificate failed\n"); + } + public_key = X509_get_pubkey (certificate); + if (NULL == public_key) + { + die ("public key extraction failure\n"); + } else { + verb ("V: public key is ready for inspection\n"); + } + + key_bits = get_certificate_keybits (public_key); + if (MIN_PUB_KEY_LEN >= key_bits && public_key->type != EVP_PKEY_EC) + { + die ("Unsafe public key size: %d bits\n", key_bits); + } else { + if (public_key->type == EVP_PKEY_EC) + if(key_bits >= MIN_ECC_PUB_KEY_LEN + && key_bits <= MAX_ECC_PUB_KEY_LEN) + { + verb ("V: ECC key length appears safe\n"); + } else { + die ("Unsafe ECC key size: %d bits\n", key_bits); + } else { + verb ("V: key length appears safe\n"); + } + } + EVP_PKEY_free (public_key); +} +#endif + +#ifdef USE_POLARSSL +void +inspect_key (ssl_context *ssl, const char *hostname) +{ + verify_signature (ssl, hostname); + + // ssl_get_verify_result() already checks for CN / subjectAltName match + // and reports the mismatch as error. So check_name() is not called +} +#else +void +inspect_key (SSL *ssl, const char *hostname) +{ + + verify_signature (ssl, hostname); + check_name (ssl, hostname); +} +#endif + +#ifdef USE_POLARSSL +void +check_timestamp (uint32_t server_time) +{ + uint32_t compiled_time = RECENT_COMPILE_DATE; + uint32_t max_reasonable_time = MAX_REASONABLE_TIME; + if (compiled_time < server_time + && + server_time < max_reasonable_time) + { + verb("V: remote peer provided: %d, preferred over compile time: %d\n", + server_time, compiled_time); + } else { + die("V: the remote server is a false ticker! server: %d compile: %d\n", + server_time, compiled_time); + } +} + +static int ssl_do_handshake_part(ssl_context *ssl) +{ + int ret = 0; + + /* Only do steps till ServerHello is received */ + while (ssl->state != SSL_SERVER_HELLO) + { + ret = ssl_handshake_step (ssl); + if (0 != ret) + { + die("SSL handshake failed\n"); + } + } + /* Do ServerHello so we can skim the timestamp */ + ret = ssl_handshake_step (ssl); + if (0 != ret) + { + die("SSL handshake failed\n"); + } + + return 0; +} + +/** + * Run SSL handshake and store the resulting time value in the + * 'time_map'. + * + * @param time_map where to store the current time + */ +static void +run_ssl (uint32_t *time_map, int time_is_an_illusion) +{ + entropy_context entropy; + ctr_drbg_context ctr_drbg; + ssl_context ssl; + proxy_polarssl_ctx proxy_ctx; + x509_cert cacert; + struct stat statbuf; + int ret = 0, server_fd = 0; + char *pers = "tlsdate-helper"; + + memset (&ssl, 0, sizeof(ssl_context)); + memset (&cacert, 0, sizeof(x509_cert)); + + verb("V: Using PolarSSL for SSL\n"); + if (ca_racket) + { + if (-1 == stat (ca_cert_container, &statbuf)) + { + die("Unable to stat CA certficate container %s\n", ca_cert_container); + } + else + { + switch (statbuf.st_mode & S_IFMT) + { + case S_IFREG: + if (0 > x509parse_crtfile(&cacert, ca_cert_container)) + fprintf(stderr, "x509parse_crtfile failed\n"); + break; + case S_IFDIR: + if (0 > x509parse_crtpath(&cacert, ca_cert_container)) + fprintf(stderr, "x509parse_crtpath failed\n"); + break; + default: + die("Unable to load CA certficate container %s\n", ca_cert_container); + } + } + } + + entropy_init (&entropy); + if (0 != ctr_drbg_init (&ctr_drbg, entropy_func, &entropy, + (unsigned char *) pers, strlen(pers))) + { + die("Failed to initialize CTR_DRBG\n"); + } + + if (0 != ssl_init (&ssl)) + { + die("SSL initialization failed\n"); + } + ssl_set_endpoint (&ssl, SSL_IS_CLIENT); + ssl_set_rng (&ssl, ctr_drbg_random, &ctr_drbg); + ssl_set_ca_chain (&ssl, &cacert, NULL, hostname_to_verify); + if (ca_racket) + { + // You can do SSL_VERIFY_REQUIRED here, but then the check in + // inspect_key() never happens as the ssl_handshake() will fail. + ssl_set_authmode (&ssl, SSL_VERIFY_OPTIONAL); + } + + if (proxy) + { + char *scheme; + char *proxy_host; + char *proxy_port; + + parse_proxy_uri (proxy, &scheme, &proxy_host, &proxy_port); + + verb("V: opening socket to proxy %s:%s\n", proxy_host, proxy_port); + if (0 != net_connect (&server_fd, proxy_host, atoi(proxy_port))) + { + die ("SSL connection failed\n"); + } + + proxy_polarssl_init (&proxy_ctx); + proxy_polarssl_set_bio (&proxy_ctx, net_recv, &server_fd, net_send, &server_fd); + proxy_polarssl_set_host (&proxy_ctx, host); + proxy_polarssl_set_port (&proxy_ctx, atoi(port)); + proxy_polarssl_set_scheme (&proxy_ctx, scheme); + + ssl_set_bio (&ssl, proxy_polarssl_recv, &proxy_ctx, proxy_polarssl_send, &proxy_ctx); + + verb("V: Handle proxy connection\n"); + if (0 == proxy_ctx.f_connect (&proxy_ctx)) + die("Proxy connection failed\n"); + } + else + { + verb("V: opening socket to %s:%s\n", host, port); + if (0 != net_connect (&server_fd, host, atoi(port))) + { + die ("SSL connection failed\n"); + } + + ssl_set_bio (&ssl, net_recv, &server_fd, net_send, &server_fd); + } + + verb("V: starting handshake\n"); + if (0 != ssl_do_handshake_part (&ssl)) + die("SSL handshake first part failed\n"); + + uint32_t timestamp = ( (uint32_t) ssl.in_msg[6] << 24 ) + | ( (uint32_t) ssl.in_msg[7] << 16 ) + | ( (uint32_t) ssl.in_msg[8] << 8 ) + | ( (uint32_t) ssl.in_msg[9] ); + check_timestamp (timestamp); + + verb("V: continuing handshake\n"); + /* Continue with handshake */ + while (0 != (ret = ssl_handshake (&ssl))) + { + if (POLARSSL_ERR_NET_WANT_READ != ret && + POLARSSL_ERR_NET_WANT_WRITE != ret) + { + die("SSL handshake failed\n"); + } + } + + // Verify the peer certificate against the CA certs on the local system + if (ca_racket) { + inspect_key (&ssl, hostname_to_verify); + } else { + verb ("V: Certificate verification skipped!\n"); + } + check_key_length (&ssl); + + memcpy (time_map, ×tamp, sizeof(uint32_t)); + proxy_polarssl_free (&proxy_ctx); + ssl_free (&ssl); + x509_free (&cacert); +} +#else /* USE_POLARSSL */ +/** + * Run SSL handshake and store the resulting time value in the + * 'time_map'. + * + * @param time_map where to store the current time + */ +static void +run_ssl (uint32_t *time_map, int time_is_an_illusion) +{ + BIO *s_bio; + SSL_CTX *ctx; + SSL *ssl; + struct stat statbuf; + + SSL_load_error_strings(); + SSL_library_init(); + + ctx = NULL; + if (0 == strcmp("sslv23", protocol)) + { + verb ("V: using SSLv23_client_method()\n"); + ctx = SSL_CTX_new(SSLv23_client_method()); + } else if (0 == strcmp("sslv3", protocol)) + { + verb ("V: using SSLv3_client_method()\n"); + ctx = SSL_CTX_new(SSLv3_client_method()); + } else if (0 == strcmp("tlsv1", protocol)) + { + verb ("V: using TLSv1_client_method()\n"); + ctx = SSL_CTX_new(TLSv1_client_method()); + } else + die("Unsupported protocol `%s'\n", protocol); + + if (ctx == NULL) + die("OpenSSL failed to support protocol `%s'\n", protocol); + + verb("V: Using OpenSSL for SSL\n"); + if (ca_racket) + { + if (-1 == stat(ca_cert_container, &statbuf)) + { + die("Unable to stat CA certficate container %s\n", ca_cert_container); + } else + { + switch (statbuf.st_mode & S_IFMT) + { + case S_IFREG: + if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) + fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); + break; + case S_IFDIR: + if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) + fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); + break; + default: + if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) + { + fprintf(stderr, "SSL_CTX_load_verify_locations failed\n"); + die("Unable to load CA certficate container %s\n", ca_cert_container); + } + } + } + } + + if (NULL == (s_bio = make_ssl_bio(ctx))) + die ("SSL BIO setup failed\n"); + BIO_get_ssl(s_bio, &ssl); + if (NULL == ssl) + die ("SSL setup failed\n"); + + if (time_is_an_illusion) + { + SSL_set_info_callback(ssl, openssl_time_callback); + } + + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + verb("V: opening socket to %s:%s\n", host, port); + if ( (1 != BIO_set_conn_hostname(s_bio, host)) || + (1 != BIO_set_conn_port(s_bio, port)) ) + die ("Failed to initialize connection to `%s:%s'\n", host, port); + + if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) + die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); + + // This should run in seccomp + // eg: prctl(PR_SET_SECCOMP, 1); + if (1 != BIO_do_connect(s_bio)) /* XXX TODO: BIO_should_retry() later? */ + die ("SSL connection failed\n"); + if (1 != BIO_do_handshake(s_bio)) + die ("SSL handshake failed\n"); + + // Verify the peer certificate against the CA certs on the local system + if (ca_racket) { + inspect_key (ssl, hostname_to_verify); + } else { + verb ("V: Certificate verification skipped!\n"); + } + check_key_length(ssl); + // from /usr/include/openssl/ssl3.h + // ssl->s3->server_random is an unsigned char of 32 bits + memcpy(time_map, ssl->s3->server_random, sizeof (uint32_t)); + SSL_free(ssl); + SSL_CTX_free(ctx); +} +#endif /* USE_POLARSSL */ +/** drop root rights and become 'nobody' */ + +int +main(int argc, char **argv) +{ + uint32_t *time_map; + struct tlsdate_time start_time, end_time, warp_time; + int status; + pid_t ssl_child; + long long rt_time_ms; + uint32_t server_time_s; + int setclock; + int showtime; + int timewarp; + int leap; + + if (argc != 12) + return 1; + host = argv[1]; + hostname_to_verify = argv[1]; + port = argv[2]; + protocol = argv[3]; + ca_cert_container = argv[6]; + ca_racket = (0 != strcmp ("unchecked", argv[4])); + verbose = (0 != strcmp ("quiet", argv[5])); + setclock = (0 == strcmp ("setclock", argv[7])); + showtime = (0 == strcmp ("showtime", argv[8])); + timewarp = (0 == strcmp ("timewarp", argv[9])); + leap = (0 == strcmp ("leapaway", argv[10])); + proxy = (0 == strcmp ("none", argv[11]) ? NULL : argv[11]); + + if (timewarp) + { + + verb ("V: RECENT_COMPILE_DATE is %lu.%06lu\n", + (unsigned long) CLOCK_SEC(&warp_time), + (unsigned long) CLOCK_USEC(&warp_time)); + + if (1 == setclock) { + clock_init_time(&warp_time, RECENT_COMPILE_DATE, 0); + } else { + verb ("V: we'll do the time warp another time - we're not setting clock\n"); + } + } + + /* We are not going to set the clock, thus no need to stay root */ + if (0 == setclock && 0 == timewarp) + { + drop_privs_to (UNPRIV_USER, UNPRIV_GROUP); + } +/* + XXX: KILL ME + // We cast the mmap value to remove this error when compiling with g++: + // src/tlsdate-helper.c: In function ‘int main(int, char**)’: + // src/tlsdate-helper.c:822:41: error: invalid conversion from ‘void*’ to ‘uint32_t + time_map = (uint32_t *) mmap (NULL, sizeof (uint32_t), + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (MAP_FAILED == time_map) + { + fprintf (stderr, "mmap failed: %s\n", + strerror (errno)); + return 1; + } +*/ + /* Get the current time from the system clock. */ + if (0 != clock_get_real_time(&start_time)) + { + die ("Failed to read current time of day: %s\n", strerror (errno)); + } + + verb ("V: time is currently %lu.%06lu\n", + (unsigned long) CLOCK_SEC(&start_time), + (unsigned long) CLOCK_NSEC(&start_time)); + + if (((unsigned long) CLOCK_SEC(&start_time)) < ((unsigned long) CLOCK_SEC(&warp_time))) + { + verb ("V: local clock time is less than RECENT_COMPILE_DATE\n"); + if (timewarp) + { + verb ("V: Attempting to warp local clock into the future\n"); + if (0 != clock_set_real_time(&warp_time)) + { + die ("setting time failed: %s (Attempted to set clock to %lu.%06lu)\n", + strerror (errno), + (unsigned long) CLOCK_SEC(&warp_time), + (unsigned long) CLOCK_SEC(&warp_time)); + } + if (0 != clock_get_real_time(&start_time)) + { + die ("Failed to read current time of day: %s\n", strerror (errno)); + } + verb ("V: time is currently %lu.%06lu\n", + (unsigned long) CLOCK_SEC(&start_time), + (unsigned long) CLOCK_NSEC(&start_time)); + verb ("V: It's just a step to the left...\n"); + } + } else { + verb ("V: time is greater than RECENT_COMPILE_DATE\n"); + } + + /* initialize to bogus value, just to be on the safe side */ + *time_map = 0; + + /* Run SSL interaction in separate process (and not as 'root') */ + ssl_child = fork (); + if (-1 == ssl_child) + die ("fork failed: %s\n", strerror (errno)); + if (0 == ssl_child) + { + drop_privs_to (UNPRIV_USER, UNPRIV_GROUP); + run_ssl (time_map, leap); + /* + XXX: should be a pipe close + (void) munmap (time_map, sizeof (uint32_t)); + */ + _exit (0); + } + if (ssl_child != waitpid (ssl_child, &status, 0)) + die ("waitpid failed: %s\n", strerror (errno)); + if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)) )) + die ("child process failed in SSL handshake\n"); + + if (0 != clock_get_real_time(&end_time)) + die ("Failed to read current time of day: %s\n", strerror (errno)); + + /* calculate RTT */ + rt_time_ms = (CLOCK_SEC(&end_time) - CLOCK_SEC(&start_time)) * 1000 + (CLOCK_USEC(&end_time) - CLOCK_USEC(&start_time)) / 1000; + if (rt_time_ms < 0) + rt_time_ms = 0; /* non-linear time... */ +#ifdef USE_POLARSSL + server_time_s = *time_map; +#else + server_time_s = ntohl (*time_map); +#endif + /* + XXX: should be a pipe close + munmap (time_map, sizeof (uint32_t)); + */ + verb ("V: server time %u (difference is about %d s) was fetched in %lld ms\n", + (unsigned int) server_time_s, + CLOCK_SEC(&start_time) - server_time_s, + rt_time_ms); + + /* warning if the handshake took too long */ + if (rt_time_ms > TLS_RTT_THRESHOLD) { + verb ("V: the TLS handshake took more than %d msecs - consider using a different " \ + "server or run it again\n", TLS_RTT_THRESHOLD); + } + + if (showtime) + { + struct tm ltm; + time_t tim = server_time_s; + char buf[256]; + + localtime_r(&tim, <m); + if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", <m)) + { + die ("strftime returned 0\n"); + } + fprintf(stdout, "%s\n", buf); + } + + /* finally, actually set the time */ + if (setclock) + { + struct tlsdate_time server_time; + + clock_init_time(&server_time, server_time_s + (rt_time_ms / 2 / 1000), + (rt_time_ms / 2) % 1000); + + // We should never receive a time that is before the time we were last + // compiled; we subscribe to the linear theory of time for this program + // and this program alone! + if (CLOCK_SEC(&server_time) >= MAX_REASONABLE_TIME) + die("remote server is a false ticker from the future!\n"); + if (CLOCK_SEC(&server_time) <= RECENT_COMPILE_DATE) + die ("remote server is a false ticker!\n"); + if (0 != clock_set_real_time(&server_time)) + die ("setting time failed: %s (Difference from server is about %d s)\n", + strerror (errno), + CLOCK_SEC(&start_time) - server_time_s); + verb ("V: setting time succeeded\n"); + } + return 0; +} diff --git a/src/tlsdate-helper-plan9.h b/src/tlsdate-helper-plan9.h new file mode 100644 index 0000000..4838ed6 --- /dev/null +++ b/src/tlsdate-helper-plan9.h @@ -0,0 +1,118 @@ +/* Copyright (c) 2012, Jacob Appelbaum + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file tlsdate-helper.h + * \brief The secondary header for our clock helper. + **/ + +#ifndef TLSDATEHELPER_H +#define TLSDATEHELPER_H + +#include <stdarg.h> +#include <inttypes.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <time.h> +#include <pwd.h> +#include <grp.h> +#include <arpa/inet.h> +#include <ctype.h> + +#ifndef USE_POLARSSL +#include <openssl/bio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/conf.h> +#include <openssl/x509v3.h> +#endif + +int verbose; + +#include "src/util.h" + +/** Name of user that we feel safe to run SSL handshake with. */ +#ifndef UNPRIV_USER +#define UNPRIV_USER "nobody" +#endif +#ifndef UNPRIV_GROUP +#define UNPRIV_GROUP "nogroup" +#endif + +// We should never accept a time before we were compiled +// We measure in seconds since the epoch - eg: echo `date '+%s'` +// We set this manually to ensure others can reproduce a build; +// automation of this will make every build different! +#ifndef RECENT_COMPILE_DATE +#define RECENT_COMPILE_DATE (uint32_t) 1342323666 +#endif + +#ifndef MAX_REASONABLE_TIME +#define MAX_REASONABLE_TIME (uint32_t) 1999991337 +#endif + +#ifndef MIN_PUB_KEY_LEN +#define MIN_PUB_KEY_LEN (uint32_t) 1023 +#endif + +#ifndef MIN_ECC_PUB_KEY_LEN +#define MIN_ECC_PUB_KEY_LEN (uint32_t) 160 +#endif + +#ifndef MAX_ECC_PUB_KEY_LEN +#define MAX_ECC_PUB_KEY_LEN (uint32_t) 521 +#endif +// After the duration of the TLS handshake exceeds this threshold +// (in msec), a warning is printed. +#define TLS_RTT_THRESHOLD 2000 + +// RFC 5280 says... +// ub-common-name-length INTEGER ::= 64 +#define MAX_CN_NAME_LENGTH 64 + +// RFC 1034 and posix say... +#define TLSDATE_HOST_NAME_MAX 255 + +// To support our RFC 2595 wildcard verification +#define RFC2595_MIN_LABEL_COUNT 3 + +static int ca_racket; + +static const char *host; + +static const char *hostname_to_verify; + +static const char *port; + +static const char *protocol; + +static char *proxy; + +static const char *ca_cert_container; +#ifndef USE_POLARSSL +void openssl_time_callback (const SSL* ssl, int where, int ret); +uint32_t get_certificate_keybits (EVP_PKEY *public_key); +uint32_t check_cn (SSL *ssl, const char *hostname); +uint32_t check_san (SSL *ssl, const char *hostname); +long openssl_check_against_host_and_verify (SSL *ssl); +uint32_t check_name (SSL *ssl, const char *hostname); +uint32_t verify_signature (SSL *ssl, const char *hostname); +void check_key_length (SSL *ssl); +void inspect_key (SSL *ssl, const char *hostname); +void check_key_length (SSL *ssl); +void inspect_key (SSL *ssl, const char *hostname); +#endif +uint32_t dns_label_count (char *label, char *delim); +uint32_t check_wildcard_match_rfc2595 (const char *orig_hostname, + const char *orig_cert_wild_card); +static void run_ssl (uint32_t *time_map, int time_is_an_illusion); + +#endif diff --git a/src/tlsdate-helper.c b/src/tlsdate-helper.c new file mode 100644 index 0000000..877c67e --- /dev/null +++ b/src/tlsdate-helper.c @@ -0,0 +1,1439 @@ +/* Copyright (c) 2012, Jacob Appelbaum. + * Copyright (c) 2012, The Tor Project, Inc. + * Copyright (c) 2012, Christian Grothoff. */ +/* See LICENSE for licensing information */ +/* + This file contains the license for tlsdate, + a free software project to set your system clock securely. + + It also lists the licenses for other components used by tlsdate. + + For more information about tlsdate, see https://github.com/ioerror/tlsdate + + If you got this file as a part of a larger bundle, + there may be other license terms that you should be aware of. + +=============================================================================== +tlsdate is distributed under this license: + +Copyright (c) 2011-2012, Jacob Appelbaum <jacob@appelbaum.net> +Copyright (c) 2011-2012, The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=============================================================================== +If you got tlsdate as a static binary with OpenSSL included, then you should +know: + + "This product includes software developed by the OpenSSL Project for use in + the OpenSSL Toolkit (http://www.openssl.org/)" + +=============================================================================== +*/ + +/** + * \file tlsdate-helper.c + * \brief Helper program that does the actual work of setting the system clock. + **/ + +/* + * tlsdate is a tool for setting the system clock by hand or by communication + * with the network. It does not set the RTC. It is designed to be as secure as + * TLS (RFC 2246) but of course the security of TLS is often reduced to + * whichever CA racket you believe is trustworthy. By default, tlsdate trusts + * your local CA root store - so any of these companies could assist in a MITM + * attack against you and you'd be screwed. + + * This tool is designed to be run by hand or as a system daemon. It must be + * run as root or otherwise have the proper caps; it will not be able to set + * the system time without running as root or another privileged user. + */ + +#include "config.h" +#include "src/tlsdate-helper.h" +#include "src/util.h" + +#ifndef USE_POLARSSL +#include "src/proxy-bio.h" +#else +#include "src/proxy-polarssl.h" +#endif + +#include "src/compat/clock.h" + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +#ifdef USE_POLARSSL +#include "polarssl/entropy.h" +#include "polarssl/ctr_drbg.h" +#include "polarssl/ssl.h" +#endif + +static void +validate_proxy_scheme(const char *scheme) +{ + if (!strcmp(scheme, "http")) + return; + if (!strcmp(scheme, "socks4")) + return; + if (!strcmp(scheme, "socks5")) + return; + die("invalid proxy scheme"); +} + +static void +validate_proxy_host(const char *host) +{ + const char *kValid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + ".-"; + if (strspn(host, kValid) != strlen(host)) + die("invalid char in host"); +} + +static void +validate_proxy_port(const char *port) +{ + while (*port) + if (!isdigit((int)(unsigned char)*port++)) + die("invalid char in port"); +} + +static void +parse_proxy_uri(char *proxy, char **scheme, char **host, char **port) +{ + /* Expecting a URI, so: <scheme> '://' <host> ':' <port> */ + *scheme = proxy; + proxy = strstr(proxy, "://"); + if (!proxy) + die("malformed proxy URI"); + *proxy = '\0'; /* terminate scheme string */ + proxy += strlen("://"); + + *host = proxy; + proxy = strchr(proxy, ':'); + if (!proxy) + die("malformed proxy URI"); + *proxy++ = '\0'; + + *port = proxy; + + validate_proxy_scheme(*scheme); + validate_proxy_host(*host); + validate_proxy_port(*port); +} + +#ifndef USE_POLARSSL +static void +setup_proxy(BIO *ssl) +{ + BIO *bio; + char *scheme; + char *proxy_host; + char *proxy_port; + + if (!proxy) + return; + /* + * grab the proxy's host and port out of the URI we have for it. We want the + * underlying connect BIO to connect to this, not the target host and port, so + * we squirrel away the target host and port in the proxy BIO (as the proxy + * target) and swap out the connect BIO's target host and port so it'll + * connect to the proxy instead. + */ + parse_proxy_uri(proxy, &scheme, &proxy_host, &proxy_port); + bio = BIO_new_proxy(); + BIO_proxy_set_type(bio, scheme); + BIO_proxy_set_host(bio, host); + BIO_proxy_set_port(bio, atoi(port)); + host = proxy_host; + port = proxy_port; + BIO_push(ssl, bio); +} + +static BIO * +make_ssl_bio(SSL_CTX *ctx) +{ + BIO *con = NULL; + BIO *ssl = NULL; + + if (!(con = BIO_new(BIO_s_connect()))) + die("BIO_s_connect failed"); + if (!(ssl = BIO_new_ssl(ctx, 1))) + die("BIO_new_ssl failed"); + setup_proxy(ssl); + BIO_push(ssl, con); + return ssl; +} + + +static int +write_all_to_bio(BIO *bio, const char *string) +{ + int n = (int) strlen(string); + int r; + + while (n) { + r = BIO_write(bio, string, n); + if (r > 0) { + if (r > n) + return -1; + n -= r; + string += r; + } else { + return 0; + } + } + + return 1; +} + +/* If the string is all nice clean ascii that it's safe to log, return + * it. Otherwise return a placeholder "This is junk" string. */ +static const char * +sanitize_string(const char *s) +{ + const unsigned char *cp; + for (cp = (const unsigned char *)s; *cp; cp++) { + if (*cp < 32 || *cp >= 127) + return "string with invalid characters"; + } + return s; +} + +static int +handle_date_line(const char *dateline, uint32_t *result) +{ + int year,mon,day,hour,min,sec; + char month[4]; + struct tm tm; + int i; + time_t t; + /* We recognize the three formats in RFC2616, section 3.3.1. Month + names are always in English. The formats are: + + Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 + Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 + Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format + + Note that the first is preferred. + */ + + static const char *MONTHS[] = + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; + + if (strncmp("\r\nDate: ", dateline, 8)) + return 0; + + dateline += 8; + if (strlen(dateline) > MAX_DATE_LINE_LEN) { + verb("V: The date line was impossibly long."); + return -1; + } + verb("V: The alleged date is <%s>", sanitize_string(dateline)); + + while (*dateline == ' ') + ++dateline; + while (*dateline && *dateline != ' ') + ++dateline; + while (*dateline == ' ') + ++dateline; + /* We just skipped over the day of the week. Now we have:*/ + if (sscanf(dateline, "%d %3s %d %d:%d:%d", + &day, month, &year, &hour, &min, &sec) == 6 || + sscanf(dateline, "%d-%3s-%d %d:%d:%d", + &day, month, &year, &hour, &min, &sec) == 6 || + sscanf(dateline, "%3s %d %d:%d:%d %d", + month, &day, &hour, &min, &sec, &year) == 6) { + + /* Two digit dates are defined to be relative to 1900; all other dates + * are supposed to be represented as four digits. */ + if (year < 100) + year += 1900; + + verb("V: Parsed the date: %04d-%s-%02d %02d:%02d:%02d", + year, month, day, hour, min, sec); + } else { + verb("V: Couldn't parse date."); + return -1; + } + + for (i = 0; ; ++i) { + if (!MONTHS[i]) + return -2; + if (!strcmp(month, MONTHS[i])) { + mon = i; + break; + } + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = year - 1900; + tm.tm_mon = mon; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + t = timegm(&tm); + if (t > 0xffffffff || t < 0) + return -1; + + *result = (uint32_t) t; + + return 1; +} + +static int +read_http_date_from_bio(BIO *bio, uint32_t *result) +{ + int n; + char buf[MAX_HTTP_HEADERS_SIZE]; + int buf_len=0; + char *dateline, *endofline; + + while (buf_len < sizeof(buf)-1) { + n = BIO_read(bio, buf+buf_len, sizeof(buf)-buf_len-1); + if (n <= 0) + return 0; + buf_len += n; + buf[buf_len] = 0; + verb_debug ("V: read %d bytes.", n, buf); + + dateline = memmem(buf, buf_len, "\r\nDate: ", 8); + if (NULL == dateline) + continue; + + endofline = memmem(dateline+2, buf_len - (dateline-buf+2), "\r\n", 2); + if (NULL == endofline) + continue; + + *endofline = 0; + return handle_date_line(dateline, result); + } + return -2; +} + +/** helper function for 'malloc' */ +static void * +xmalloc (size_t size) +{ + void *ptr; + + if (0 == size) + die("xmalloc: zero size"); + + ptr = malloc(size); + if (NULL == ptr) + die("xmalloc: out of memory (allocating %zu bytes)", size); + + return ptr; +} + + +/** helper function for 'free' */ +static void +xfree (void *ptr) +{ + if (NULL == ptr) + die("xfree: NULL pointer given as argument"); + + free(ptr); +} + +void +openssl_time_callback (const SSL* ssl, int where, int ret) +{ + if (where == SSL_CB_CONNECT_LOOP && + (ssl->state == SSL3_ST_CR_SRVR_HELLO_A || ssl->state == SSL3_ST_CR_SRVR_HELLO_B)) + { + // XXX TODO: If we want to trust the remote system for time, + // can we just read that time out of the remote system and if the + // cert verifies, decide that the time is reasonable? + // Such a process seems to indicate that a once valid cert would be + // forever valid - we stopgap that by ensuring it isn't less than + // the latest compiled_time and isn't above max_reasonable_time... + // XXX TODO: Solve eternal question about the Chicken and the Egg... + uint32_t compiled_time = RECENT_COMPILE_DATE; + uint32_t max_reasonable_time = MAX_REASONABLE_TIME; + uint32_t server_time; + verb("V: freezing time for x509 verification"); + memcpy(&server_time, ssl->s3->server_random, sizeof(uint32_t)); + if (compiled_time < ntohl(server_time) + && + ntohl(server_time) < max_reasonable_time) + { + verb("V: remote peer provided: %d, preferred over compile time: %d", + ntohl(server_time), compiled_time); + verb("V: freezing time with X509_VERIFY_PARAM_set_time"); + X509_VERIFY_PARAM_set_time(ssl->ctx->cert_store->param, + (time_t) ntohl(server_time) + 86400); + } else { + die("V: the remote server is a false ticker! server: %d compile: %d", + ntohl(server_time), compiled_time); + } + } +} + +uint32_t +get_certificate_keybits (EVP_PKEY *public_key) +{ + /* + In theory, we could use check_bitlen_dsa() and check_bitlen_rsa() + */ + uint32_t key_bits; + switch (public_key->type) + { + case EVP_PKEY_RSA: + verb("V: key type: EVP_PKEY_RSA"); + key_bits = BN_num_bits(public_key->pkey.rsa->n); + break; + case EVP_PKEY_RSA2: + verb("V: key type: EVP_PKEY_RSA2"); + key_bits = BN_num_bits(public_key->pkey.rsa->n); + break; + case EVP_PKEY_DSA: + verb("V: key type: EVP_PKEY_DSA"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA1: + verb("V: key type: EVP_PKEY_DSA1"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA2: + verb("V: key type: EVP_PKEY_DSA2"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA3: + verb("V: key type: EVP_PKEY_DSA3"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DSA4: + verb("V: key type: EVP_PKEY_DSA4"); + key_bits = BN_num_bits(public_key->pkey.dsa->p); + break; + case EVP_PKEY_DH: + verb("V: key type: EVP_PKEY_DH"); + key_bits = BN_num_bits(public_key->pkey.dh->pub_key); + break; + case EVP_PKEY_EC: + verb("V: key type: EVP_PKEY_EC"); + key_bits = EVP_PKEY_bits(public_key); + break; + // Should we also care about EVP_PKEY_HMAC and EVP_PKEY_CMAC? + default: + key_bits = 0; + die ("unknown public key type"); + break; + } + verb ("V: keybits: %d", key_bits); + return key_bits; +} + +uint32_t +dns_label_count(char *label, char *delim) +{ + char *label_tmp; + char *saveptr; + char *saveptr_tmp; + uint32_t label_count; + + label_tmp = strdup(label); + label_count = 0; + saveptr = NULL; + saveptr_tmp = NULL; + saveptr = strtok_r(label_tmp, delim, &saveptr); + if (NULL != saveptr) + { + // Did we find our first label? + if (saveptr[0] != delim[0]) + { + label_count++; + } + do + { + // Find all subsequent labels + label_count++; + saveptr_tmp = strtok_r(NULL, delim, &saveptr); + } while (NULL != saveptr_tmp); + } + verb_debug ("V: label found; total label count: %d", label_count); + free(label_tmp); + return label_count; +} + +// first we split strings on '.' +// then we call each split string a 'label' +// Do not allow '*' for the top level domain label; eg never allow *.*.com +// Do not allow '*' for subsequent subdomains; eg never allow *.foo.example.com +// Do allow *.example.com +uint32_t +check_wildcard_match_rfc2595 (const char *orig_hostname, + const char *orig_cert_wild_card) +{ + char *hostname; + char *hostname_to_free; + char *cert_wild_card; + char *cert_wild_card_to_free; + char *expected_label; + char *wildcard_label; + char *delim; + char *wildchar; + uint32_t ok; + uint32_t wildcard_encountered; + uint32_t label_count; + + // First we copy the original strings + hostname = strndup(orig_hostname, strlen(orig_hostname)); + cert_wild_card = strndup(orig_cert_wild_card, strlen(orig_cert_wild_card)); + hostname_to_free = hostname; + cert_wild_card_to_free = cert_wild_card; + delim = strdup("."); + wildchar = strdup("*"); + + verb_debug ("V: Inspecting '%s' for possible wildcard match against '%s'", + hostname, cert_wild_card); + + // By default we have not processed any labels + label_count = dns_label_count(cert_wild_card, delim); + + // By default we have no match + ok = 0; + wildcard_encountered = 0; + // First - do we have labels? If not, we refuse to even try to match + if ((NULL != strpbrk(cert_wild_card, delim)) && + (NULL != strpbrk(hostname, delim)) && + (label_count <= ((uint32_t)RFC2595_MIN_LABEL_COUNT))) + { + if (wildchar[0] == cert_wild_card[0]) + { + verb_debug ("V: Found wildcard in at start of provided certificate name"); + do + { + // Skip over the bytes between the first char and until the next label + wildcard_label = strsep(&cert_wild_card, delim); + expected_label = strsep(&hostname, delim); + if (NULL != wildcard_label && + NULL != expected_label && + NULL != hostname && + NULL != cert_wild_card) + { + // Now we only consider this wildcard valid if the rest of the + // hostnames match verbatim + verb_debug ("V: Attempting match of '%s' against '%s'", + expected_label, wildcard_label); + // This is the case where we have a label that begins with wildcard + // Furthermore, we only allow this for the first label + if (wildcard_label[0] == wildchar[0] && + 0 == wildcard_encountered && 0 == ok) + { + verb ("V: Forced match of '%s' against '%s'", expected_label, wildcard_label); + wildcard_encountered = 1; + } else { + verb_debug ("V: Attempting match of '%s' against '%s'", + hostname, cert_wild_card); + if (0 == strcasecmp (expected_label, wildcard_label) && + label_count >= ((uint32_t)RFC2595_MIN_LABEL_COUNT)) + { + ok = 1; + verb_debug ("V: remaining labels match!"); + break; + } else { + ok = 0; + verb_debug ("V: remaining labels do not match!"); + break; + } + } + } else { + // We hit this case when we have a mismatched number of labels + verb_debug ("V: NULL label; no wildcard here"); + break; + } + } while (0 != wildcard_encountered && label_count <= RFC2595_MIN_LABEL_COUNT); + } else { + verb_debug ("V: Not a RFC 2595 wildcard"); + } + } else { + verb_debug ("V: Not a valid wildcard certificate"); + ok = 0; + } + // Free our copies + free(wildchar); + free(delim); + free(hostname_to_free); + free(cert_wild_card_to_free); + if (wildcard_encountered & ok && label_count >= RFC2595_MIN_LABEL_COUNT) + { + verb_debug ("V: wildcard match of %s against %s", + orig_hostname, orig_cert_wild_card); + return (wildcard_encountered & ok); + } else { + verb_debug ("V: wildcard match failure of %s against %s", + orig_hostname, orig_cert_wild_card); + return 0; + } +} +#endif + +#ifndef USE_POLARSSL +/** + This extracts the first commonName and checks it against hostname. +*/ +uint32_t +check_cn (SSL *ssl, const char *hostname) +{ + int ok = 0; + int ret; + char *cn_buf; + X509 *certificate; + X509_NAME *xname; + + // We cast this to cast away g++ complaining about the following: + // error: invalid conversion from ‘void*’ to ‘char*’ + cn_buf = (char *) xmalloc(TLSDATE_HOST_NAME_MAX + 1); + + certificate = SSL_get_peer_certificate(ssl); + if (NULL == certificate) + { + die ("Unable to extract certificate"); + } + + memset(cn_buf, '\0', (TLSDATE_HOST_NAME_MAX + 1)); + xname = X509_get_subject_name(certificate); + ret = X509_NAME_get_text_by_NID(xname, NID_commonName, + cn_buf, TLSDATE_HOST_NAME_MAX); + + if (-1 == ret || ret != (int) strlen(cn_buf)) + { + die ("Unable to extract commonName"); + } + if (strcasecmp(cn_buf, hostname)) + { + verb ("V: commonName mismatch! Expected: %s - received: %s", + hostname, cn_buf); + } else { + verb ("V: commonName matched: %s", cn_buf); + ok = 1; + } + + X509_NAME_free(xname); + X509_free(certificate); + xfree(cn_buf); + + return ok; +} + +/** + Search for a hostname match in the SubjectAlternativeNames. +*/ +uint32_t +check_san (SSL *ssl, const char *hostname) +{ + X509 *cert; + int extcount, ok = 0; + /* What an OpenSSL mess ... */ + if (NULL == (cert = SSL_get_peer_certificate(ssl))) + { + die ("Getting certificate failed"); + } + + if ((extcount = X509_get_ext_count(cert)) > 0) + { + int i; + for (i = 0; i < extcount; ++i) + { + const char *extstr; + X509_EXTENSION *ext; + ext = X509_get_ext(cert, i); + extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); + + if (!strcmp(extstr, "subjectAltName")) + { + + int j; + void *extvalstr; + const unsigned char *tmp; + + STACK_OF(CONF_VALUE) *val; + CONF_VALUE *nval; +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + const +#endif + X509V3_EXT_METHOD *method; + + if (!(method = X509V3_EXT_get(ext))) + { + break; + } + + tmp = ext->value->data; + if (method->it) + { + extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length, + ASN1_ITEM_ptr(method->it)); + } else { + extvalstr = method->d2i(NULL, &tmp, ext->value->length); + } + + if (!extvalstr) + { + break; + } + + if (method->i2v) + { + val = method->i2v(method, extvalstr, NULL); + for (j = 0; j < sk_CONF_VALUE_num(val); ++j) + { + nval = sk_CONF_VALUE_value(val, j); + if ((!strcasecmp(nval->name, "DNS") && + !strcasecmp(nval->value, hostname) ) || + (!strcasecmp(nval->name, "iPAddress") && + !strcasecmp(nval->value, hostname))) + { + verb ("V: subjectAltName matched: %s, type: %s", nval->value, nval->name); // We matched this; so it's safe to print + ok = 1; + break; + } + // Attempt to match subjectAltName DNS names + if (!strcasecmp(nval->name, "DNS")) + { + ok = check_wildcard_match_rfc2595(hostname, nval->value); + if (ok) + { + break; + } + } + verb_debug ("V: subjectAltName found but not matched: %s, type: %s", + nval->value, sanitize_string(nval->name)); + } + } + } else { + verb_debug ("V: found non subjectAltName extension"); + } + if (ok) + { + break; + } + } + } else { + verb_debug ("V: no X509_EXTENSION field(s) found"); + } + X509_free(cert); + return ok; +} + +uint32_t +check_name (SSL *ssl, const char *hostname) +{ + uint32_t ret; + ret = check_cn(ssl, hostname); + ret += check_san(ssl, hostname); + if (0 != ret && 0 < ret) + { + verb ("V: hostname verification passed"); + } else { + die ("hostname verification failed for host %s!", host); + } + return ret; +} +#endif + +#ifdef USE_POLARSSL +uint32_t +verify_signature (ssl_context *ssl, const char *hostname) +{ + int ssl_verify_result; + + ssl_verify_result = ssl_get_verify_result (ssl); + if (ssl_verify_result & BADCERT_EXPIRED) + { + die ("certificate has expired"); + } + if (ssl_verify_result & BADCERT_REVOKED) + { + die ("certificate has been revoked"); + } + if (ssl_verify_result & BADCERT_CN_MISMATCH) + { + die ("CN and subject AltName mismatch for certificate"); + } + if (ssl_verify_result & BADCERT_NOT_TRUSTED) + { + die ("certificate is self-signed or not signed by a trusted CA"); + } + + if (0 == ssl_verify_result) + { + verb ("V: verify success"); + } + else + { + die ("certificate verification error: -0x%04x", -ssl_verify_result); + } + return 0; +} +#else +uint32_t +verify_signature (SSL *ssl, const char *hostname) +{ + long ssl_verify_result; + X509 *certificate; + + certificate = SSL_get_peer_certificate(ssl); + if (NULL == certificate) + { + die ("Getting certificate failed"); + } + // In theory, we verify that the cert is valid + ssl_verify_result = SSL_get_verify_result(ssl); + switch (ssl_verify_result) + { + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + die ("certificate is self signed"); + case X509_V_OK: + verb ("V: certificate verification passed"); + break; + default: + die ("certification verification error: %ld", + ssl_verify_result); + } + return 0; +} +#endif + +#ifdef USE_POLARSSL +void +check_key_length (ssl_context *ssl) +{ + uint32_t key_bits; + const x509_cert *certificate; + const rsa_context *public_key; + char buf[1024]; + + certificate = ssl_get_peer_cert (ssl); + if (NULL == certificate) + { + die ("Getting certificate failed"); + } + + x509parse_dn_gets(buf, 1024, &certificate->subject); + verb_debug ("V: Certificate for subject '%s'", buf); + + public_key = &certificate->rsa; + if (NULL == public_key) + { + die ("public key extraction failure"); + } else { + verb_debug ("V: public key is ready for inspection"); + } + key_bits = mpi_msb (&public_key->N); + if (MIN_PUB_KEY_LEN >= key_bits) + { + die ("Unsafe public key size: %d bits", key_bits); + } else { + verb_debug ("V: key length appears safe"); + } +} +#else +void +check_key_length (SSL *ssl) +{ + uint32_t key_bits; + X509 *certificate; + EVP_PKEY *public_key; + certificate = SSL_get_peer_certificate (ssl); + if (NULL == certificate) + { + die ("Getting certificate failed"); + } + public_key = X509_get_pubkey (certificate); + if (NULL == public_key) + { + die ("public key extraction failure"); + } else { + verb_debug ("V: public key is ready for inspection"); + } + + key_bits = get_certificate_keybits (public_key); + if (MIN_PUB_KEY_LEN >= key_bits && public_key->type != EVP_PKEY_EC) + { + die ("Unsafe public key size: %d bits", key_bits); + } else { + if (public_key->type == EVP_PKEY_EC) + if(key_bits >= MIN_ECC_PUB_KEY_LEN + && key_bits <= MAX_ECC_PUB_KEY_LEN) + { + verb_debug ("V: ECC key length appears safe"); + } else { + die ("Unsafe ECC key size: %d bits", key_bits); + } else { + verb_debug ("V: key length appears safe"); + } + } + EVP_PKEY_free (public_key); +} +#endif + +#ifdef USE_POLARSSL +void +inspect_key (ssl_context *ssl, const char *hostname) +{ + verify_signature (ssl, hostname); + + // ssl_get_verify_result() already checks for CN / subjectAltName match + // and reports the mismatch as error. So check_name() is not called +} +#else +void +inspect_key (SSL *ssl, const char *hostname) +{ + + verify_signature (ssl, hostname); + check_name (ssl, hostname); +} +#endif + +#ifdef USE_POLARSSL +void +check_timestamp (uint32_t server_time) +{ + uint32_t compiled_time = RECENT_COMPILE_DATE; + uint32_t max_reasonable_time = MAX_REASONABLE_TIME; + if (compiled_time < server_time + && + server_time < max_reasonable_time) + { + verb("V: remote peer provided: %d, preferred over compile time: %d", + server_time, compiled_time); + } else { + die("V: the remote server is a false ticker! server: %d compile: %d", + server_time, compiled_time); + } +} + +static int ssl_do_handshake_part(ssl_context *ssl) +{ + int ret = 0; + + /* Only do steps till ServerHello is received */ + while (ssl->state != SSL_SERVER_HELLO) + { + ret = ssl_handshake_step (ssl); + if (0 != ret) + { + die("SSL handshake failed"); + } + } + /* Do ServerHello so we can skim the timestamp */ + ret = ssl_handshake_step (ssl); + if (0 != ret) + { + die("SSL handshake failed"); + } + + return 0; +} + +/** + * Run SSL handshake and store the resulting time value in the + * 'time_map'. + * + * @param time_map where to store the current time + * @param time_is_an_illusion + * @param http whether to do an http request and take the date from that + * instead. + */ +static void +run_ssl (uint32_t *time_map, int time_is_an_illusion, int http) +{ + entropy_context entropy; + ctr_drbg_context ctr_drbg; + ssl_context ssl; + proxy_polarssl_ctx proxy_ctx; + x509_cert cacert; + struct stat statbuf; + int ret = 0, server_fd = 0; + char *pers = "tlsdate-helper"; + + memset (&ssl, 0, sizeof(ssl_context)); + memset (&cacert, 0, sizeof(x509_cert)); + + verb("V: Using PolarSSL for SSL"); + if (ca_racket) + { + if (-1 == stat (ca_cert_container, &statbuf)) + { + die("Unable to stat CA certficate container %s", ca_cert_container); + } + else + { + switch (statbuf.st_mode & S_IFMT) + { + case S_IFREG: + if (0 > x509parse_crtfile(&cacert, ca_cert_container)) + fprintf(stderr, "x509parse_crtfile failed"); + break; + case S_IFDIR: + if (0 > x509parse_crtpath(&cacert, ca_cert_container)) + fprintf(stderr, "x509parse_crtpath failed"); + break; + default: + die("Unable to load CA certficate container %s", ca_cert_container); + } + } + } + + entropy_init (&entropy); + if (0 != ctr_drbg_init (&ctr_drbg, entropy_func, &entropy, + (unsigned char *) pers, strlen(pers))) + { + die("Failed to initialize CTR_DRBG"); + } + + if (0 != ssl_init (&ssl)) + { + die("SSL initialization failed"); + } + ssl_set_endpoint (&ssl, SSL_IS_CLIENT); + ssl_set_rng (&ssl, ctr_drbg_random, &ctr_drbg); + ssl_set_ca_chain (&ssl, &cacert, NULL, hostname_to_verify); + if (ca_racket) + { + // You can do SSL_VERIFY_REQUIRED here, but then the check in + // inspect_key() never happens as the ssl_handshake() will fail. + ssl_set_authmode (&ssl, SSL_VERIFY_OPTIONAL); + } + + if (proxy) + { + char *scheme; + char *proxy_host; + char *proxy_port; + + parse_proxy_uri (proxy, &scheme, &proxy_host, &proxy_port); + + verb("V: opening socket to proxy %s:%s", proxy_host, proxy_port); + if (0 != net_connect (&server_fd, proxy_host, atoi(proxy_port))) + { + die ("SSL connection failed"); + } + + proxy_polarssl_init (&proxy_ctx); + proxy_polarssl_set_bio (&proxy_ctx, net_recv, &server_fd, net_send, &server_fd); + proxy_polarssl_set_host (&proxy_ctx, host); + proxy_polarssl_set_port (&proxy_ctx, atoi(port)); + proxy_polarssl_set_scheme (&proxy_ctx, scheme); + + ssl_set_bio (&ssl, proxy_polarssl_recv, &proxy_ctx, proxy_polarssl_send, &proxy_ctx); + + verb("V: Handle proxy connection"); + if (0 == proxy_ctx.f_connect (&proxy_ctx)) + die("Proxy connection failed"); + } + else + { + verb("V: opening socket to %s:%s", host, port); + if (0 != net_connect (&server_fd, host, atoi(port))) + { + die ("SSL connection failed"); + } + + ssl_set_bio (&ssl, net_recv, &server_fd, net_send, &server_fd); + } + + verb("V: starting handshake"); + if (0 != ssl_do_handshake_part (&ssl)) + die("SSL handshake first part failed"); + + uint32_t timestamp = ( (uint32_t) ssl.in_msg[6] << 24 ) + | ( (uint32_t) ssl.in_msg[7] << 16 ) + | ( (uint32_t) ssl.in_msg[8] << 8 ) + | ( (uint32_t) ssl.in_msg[9] ); + check_timestamp (timestamp); + + verb("V: continuing handshake"); + /* Continue with handshake */ + while (0 != (ret = ssl_handshake (&ssl))) + { + if (POLARSSL_ERR_NET_WANT_READ != ret && + POLARSSL_ERR_NET_WANT_WRITE != ret) + { + die("SSL handshake failed"); + } + } + + // Verify the peer certificate against the CA certs on the local system + if (ca_racket) { + inspect_key (&ssl, hostname_to_verify); + } else { + verb ("V: Certificate verification skipped!"); + } + check_key_length (&ssl); + + memcpy (time_map, ×tamp, sizeof(uint32_t)); + proxy_polarssl_free (&proxy_ctx); + ssl_free (&ssl); + x509_free (&cacert); +} +#else /* USE_POLARSSL */ +/** + * Run SSL handshake and store the resulting time value in the + * 'time_map'. + * + * @param time_map where to store the current time + * @param time_is_an_illusion + * @param http whether to do an http request and take the date from that + * instead. + */ +static void +run_ssl (uint32_t *time_map, int time_is_an_illusion, int http) +{ + BIO *s_bio; + SSL_CTX *ctx; + SSL *ssl; + struct stat statbuf; + uint32_t result_time; + + SSL_load_error_strings(); + SSL_library_init(); + + ctx = NULL; + if (0 == strcmp("sslv23", protocol)) + { + verb ("V: using SSLv23_client_method()"); + ctx = SSL_CTX_new(SSLv23_client_method()); + } else if (0 == strcmp("sslv3", protocol)) + { + verb ("V: using SSLv3_client_method()"); + ctx = SSL_CTX_new(SSLv3_client_method()); + } else if (0 == strcmp("tlsv1", protocol)) + { + verb ("V: using TLSv1_client_method()"); + ctx = SSL_CTX_new(TLSv1_client_method()); + } else + die("Unsupported protocol `%s'", protocol); + + if (ctx == NULL) + die("OpenSSL failed to support protocol `%s'", protocol); + + verb("V: Using OpenSSL for SSL"); + if (ca_racket) + { + if (-1 == stat(ca_cert_container, &statbuf)) + { + die("Unable to stat CA certficate container %s", ca_cert_container); + } else + { + switch (statbuf.st_mode & S_IFMT) + { + case S_IFREG: + if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL)) + fprintf(stderr, "SSL_CTX_load_verify_locations failed"); + break; + case S_IFDIR: + if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) + fprintf(stderr, "SSL_CTX_load_verify_locations failed"); + break; + default: + if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container)) + { + fprintf(stderr, "SSL_CTX_load_verify_locations failed"); + die("Unable to load CA certficate container %s", ca_cert_container); + } + } + } + } + + if (NULL == (s_bio = make_ssl_bio(ctx))) + die ("SSL BIO setup failed"); + BIO_get_ssl(s_bio, &ssl); + if (NULL == ssl) + die ("SSL setup failed"); + + if (time_is_an_illusion) + { + SSL_set_info_callback(ssl, openssl_time_callback); + } + + SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); + verb("V: opening socket to %s:%s", host, port); + if ( (1 != BIO_set_conn_hostname(s_bio, host)) || + (1 != BIO_set_conn_port(s_bio, port)) ) + die ("Failed to initialize connection to `%s:%s'", host, port); + + if (NULL == BIO_new_fp(stdout, BIO_NOCLOSE)) + die ("BIO_new_fp returned error, possibly: %s", strerror(errno)); + + // This should run in seccomp + // eg: prctl(PR_SET_SECCOMP, 1); + if (1 != BIO_do_connect(s_bio)) // XXX TODO: BIO_should_retry() later? + die ("SSL connection failed"); + if (1 != BIO_do_handshake(s_bio)) + die ("SSL handshake failed"); + + // from /usr/include/openssl/ssl3.h + // ssl->s3->server_random is an unsigned char of 32 bits + memcpy(&result_time, ssl->s3->server_random, sizeof (uint32_t)); + verb("V: In TLS response, T=%lu", (unsigned long)ntohl(result_time)); + + if (http) { + char buf[1024]; + verb_debug ("V: Starting HTTP"); + if (snprintf(buf, sizeof(buf), + HTTP_REQUEST, HTTPS_USER_AGENT, hostname_to_verify) >= 1024) + die("hostname too long"); + buf[1023]='\0'; /* Unneeded. */ + verb_debug ("V: Writing HTTP request"); + if (1 != write_all_to_bio(s_bio, buf)) + die ("write all to bio failed."); + verb_debug ("V: Reading HTTP response"); + if (1 != read_http_date_from_bio(s_bio, &result_time)) + die ("read all from bio failed."); + verb ("V: Received HTTP response. T=%lu", (unsigned long)result_time); + + result_time = htonl(result_time); + } + + // Verify the peer certificate against the CA certs on the local system + if (ca_racket) { + inspect_key (ssl, hostname_to_verify); + } else { + verb ("V: Certificate verification skipped!"); + } + check_key_length(ssl); + + memcpy(time_map, &result_time, sizeof (uint32_t)); + + SSL_free(ssl); + SSL_CTX_free(ctx); +} +#endif /* USE_POLARSSL */ +/** drop root rights and become 'nobody' */ + +int +main(int argc, char **argv) +{ + uint32_t *time_map; + struct tlsdate_time start_time, end_time, warp_time; + int status; + pid_t ssl_child; + long long rt_time_ms; + uint32_t server_time_s; + int setclock; + int showtime; + int showtime_raw; + int timewarp; + int leap; + int http; + + if (argc != 13) + return 1; + host = argv[1]; + hostname_to_verify = argv[1]; + port = argv[2]; + protocol = argv[3]; + ca_cert_container = argv[6]; + ca_racket = (0 != strcmp ("unchecked", argv[4])); + verbose = (0 != strcmp ("quiet", argv[5])); + verbose_debug = (0 != strcmp ("verbose", argv[5])); + setclock = (0 == strcmp ("setclock", argv[7])); + showtime = (0 == strcmp ("showtime", argv[8])); + showtime_raw = (0 == strcmp ("showtime=raw", argv[8])); + timewarp = (0 == strcmp ("timewarp", argv[9])); + leap = (0 == strcmp ("leapaway", argv[10])); + proxy = (0 == strcmp ("none", argv[11]) ? NULL : argv[11]); + http = (0 == (strcmp("http", argv[12]))); + + /* Initalize warp_time with RECENT_COMPILE_DATE */ + clock_init_time(&warp_time, RECENT_COMPILE_DATE, 0); + + verb ("V: RECENT_COMPILE_DATE is %lu.%06lu", + (unsigned long) CLOCK_SEC(&warp_time), + (unsigned long) CLOCK_USEC(&warp_time)); + + if (1 != timewarp) + { + verb ("V: we'll do the time warp another time - we're not setting clock"); + } + + /* We are not going to set the clock, thus no need to stay root */ + if (0 == setclock && 0 == timewarp) + { + verb ("V: attemping to drop administrator privileges"); + drop_privs_to (UNPRIV_USER, UNPRIV_GROUP); + } + + // We cast the mmap value to remove this error when compiling with g++: + // src/tlsdate-helper.c: In function ‘int main(int, char**)’: + // src/tlsdate-helper.c:822:41: error: invalid conversion from ‘void*’ to ‘uint32_t + time_map = (uint32_t *) mmap (NULL, sizeof (uint32_t), + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (MAP_FAILED == time_map) + { + fprintf (stderr, "mmap failed: %s", + strerror (errno)); + return 1; + } + + /* Get the current time from the system clock. */ + if (0 != clock_get_real_time(&start_time)) + { + die ("Failed to read current time of day: %s", strerror (errno)); + } + + verb ("V: time is currently %lu.%06lu", + (unsigned long) CLOCK_SEC(&start_time), + (unsigned long) CLOCK_NSEC(&start_time)); + + if (((unsigned long) CLOCK_SEC(&start_time)) < ((unsigned long) CLOCK_SEC(&warp_time))) + { + verb ("V: local clock time is less than RECENT_COMPILE_DATE"); + if (timewarp) + { + verb ("V: Attempting to warp local clock into the future"); + if (0 != clock_set_real_time(&warp_time)) + { + die ("setting time failed: %s (Attempted to set clock to %lu.%06lu)", + strerror (errno), + (unsigned long) CLOCK_SEC(&warp_time), + (unsigned long) CLOCK_SEC(&warp_time)); + } + if (0 != clock_get_real_time(&start_time)) + { + die ("Failed to read current time of day: %s", strerror (errno)); + } + verb ("V: time is currently %lu.%06lu", + (unsigned long) CLOCK_SEC(&start_time), + (unsigned long) CLOCK_NSEC(&start_time)); + verb ("V: It's just a step to the left..."); + } + } else { + verb ("V: time is greater than RECENT_COMPILE_DATE"); + } + + /* initialize to bogus value, just to be on the safe side */ + *time_map = 0; + + /* Run SSL interaction in separate process (and not as 'root') */ + ssl_child = fork (); + if (-1 == ssl_child) + die ("fork failed: %s", strerror (errno)); + if (0 == ssl_child) + { + drop_privs_to (UNPRIV_USER, UNPRIV_GROUP); + run_ssl (time_map, leap, http); + (void) munmap (time_map, sizeof (uint32_t)); + _exit (0); + } + if (ssl_child != platform->process_wait (ssl_child, &status, 1)) + die ("waitpid failed: %s", strerror (errno)); + if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)) )) + die ("child process failed in SSL handshake"); + + if (0 != clock_get_real_time(&end_time)) + die ("Failed to read current time of day: %s", strerror (errno)); + + /* calculate RTT */ + rt_time_ms = (CLOCK_SEC(&end_time) - CLOCK_SEC(&start_time)) * 1000 + (CLOCK_USEC(&end_time) - CLOCK_USEC(&start_time)) / 1000; + if (rt_time_ms < 0) + rt_time_ms = 0; /* non-linear time... */ +#ifdef USE_POLARSSL + server_time_s = *time_map; +#else + server_time_s = ntohl (*time_map); +#endif + // We should never have a time_map of zero here; + // It either stayed zero or we have a false ticker. + if ( 0 == server_time_s ) + die ("child process failed to update time map; weird platform issues?"); + munmap (time_map, sizeof (uint32_t)); + + verb ("V: server time %u (difference is about %d s) was fetched in %lld ms", + (unsigned int) server_time_s, + CLOCK_SEC(&start_time) - server_time_s, + rt_time_ms); + + /* warning if the handshake took too long */ + if (rt_time_ms > TLS_RTT_UNREASONABLE) { + die ("the TLS handshake took more than %d msecs - consider using a different " \ + "server or run it again", TLS_RTT_UNREASONABLE); + } + if (rt_time_ms > TLS_RTT_THRESHOLD) { + verb ("V: the TLS handshake took more than %d msecs - consider using a different " \ + "server or run it again", TLS_RTT_THRESHOLD); + } + + if (showtime_raw) + { + fwrite(&server_time_s, sizeof(server_time_s), 1, stdout); + } + + if (showtime) + { + struct tm ltm; + time_t tim = server_time_s; + char buf[256]; + + localtime_r(&tim, <m); + if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", <m)) + { + die ("strftime returned 0"); + } + fprintf(stdout, "%s\n", buf); + } + + /* finally, actually set the time */ + if (setclock) + { + struct tlsdate_time server_time; + + clock_init_time(&server_time, server_time_s + (rt_time_ms / 2 / 1000), + (rt_time_ms / 2) % 1000); + + // We should never receive a time that is before the time we were last + // compiled; we subscribe to the linear theory of time for this program + // and this program alone! + if (CLOCK_SEC(&server_time) >= MAX_REASONABLE_TIME) + die("remote server is a false ticker from the future!"); + if (CLOCK_SEC(&server_time) <= RECENT_COMPILE_DATE) + die ("remote server is a false ticker!"); + if (0 != clock_set_real_time(&server_time)) + die ("setting time failed: %s (Difference from server is about %d s)", + strerror (errno), + CLOCK_SEC(&start_time) - server_time_s); + verb ("V: setting time succeeded"); + } + return 0; +} diff --git a/src/tlsdate-helper.h b/src/tlsdate-helper.h new file mode 100644 index 0000000..64e4092 --- /dev/null +++ b/src/tlsdate-helper.h @@ -0,0 +1,144 @@ +/* Copyright (c) 2012, Jacob Appelbaum + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file tlsdate-helper.h + * \brief The secondary header for our clock helper. + **/ + +#ifndef TLSDATEHELPER_H +#define TLSDATEHELPER_H + +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#ifdef TARGET_OS_HAIKU +#include <posix/string.h> +#include <bsd/string.h> +#endif +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/mman.h> +#include <time.h> +#include <pwd.h> +#include <grp.h> +#include <arpa/inet.h> +#include <ctype.h> +#ifdef HAVE_PRCTL +#include <sys/prctl.h> +#endif + +#ifndef USE_POLARSSL +#include <openssl/bio.h> +#include <openssl/ssl.h> +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/x509.h> +#include <openssl/conf.h> +#include <openssl/x509v3.h> +#endif + +int verbose; +int verbose_debug; + +#include "src/util.h" + +/** Name of user that we feel safe to run SSL handshake with. */ +#ifndef UNPRIV_USER +#define UNPRIV_USER "nobody" +#endif +#ifndef UNPRIV_GROUP +#define UNPRIV_GROUP "nogroup" +#endif + +// We should never accept a time before we were compiled +// We measure in seconds since the epoch - eg: echo `date '+%s'` +// We set this manually to ensure others can reproduce a build; +// automation of this will make every build different! +#ifndef RECENT_COMPILE_DATE +#define RECENT_COMPILE_DATE 1342323666L +#endif + +#ifndef MAX_REASONABLE_TIME +#define MAX_REASONABLE_TIME 1999991337L +#endif + +#ifndef MIN_PUB_KEY_LEN +#define MIN_PUB_KEY_LEN (uint32_t) 1023 +#endif + +#ifndef MIN_ECC_PUB_KEY_LEN +#define MIN_ECC_PUB_KEY_LEN (uint32_t) 160 +#endif + +#ifndef MAX_ECC_PUB_KEY_LEN +#define MAX_ECC_PUB_KEY_LEN (uint32_t) 521 +#endif +// After the duration of the TLS handshake exceeds this threshold +// (in msec), a warning is printed. +#define TLS_RTT_THRESHOLD 2000 + +// After the duration of the TLS handshake exceeds this threshold +// (in msec), we consider the operation to have failed. +#define TLS_RTT_UNREASONABLE 30000 + +// RFC 5280 says... +// ub-common-name-length INTEGER ::= 64 +#define MAX_CN_NAME_LENGTH 64 + +// RFC 1034 and posix say... +#define TLSDATE_HOST_NAME_MAX 255 + +// To support our RFC 2595 wildcard verification +#define RFC2595_MIN_LABEL_COUNT 3 + +// Define a max length for the HTTP Date: header +#define MAX_DATE_LINE_LEN 32 + +// Define a max length for HTTP headers +#define MAX_HTTP_HEADERS_SIZE 8192 + +// Define our basic HTTP request +#define HTTP_REQUEST \ + "HEAD / HTTP/1.1\r\n" \ + "User-Agent: %s\r\n" \ + "Host: %s\r\n" \ + "\r\n" + +static int ca_racket; + +static const char *host; + +static const char *hostname_to_verify; + +static const char *port; + +static const char *protocol; + +static char *proxy; + +static const char *ca_cert_container; +#ifndef USE_POLARSSL +void openssl_time_callback (const SSL* ssl, int where, int ret); +uint32_t get_certificate_keybits (EVP_PKEY *public_key); +uint32_t check_cn (SSL *ssl, const char *hostname); +uint32_t check_san (SSL *ssl, const char *hostname); +long openssl_check_against_host_and_verify (SSL *ssl); +uint32_t check_name (SSL *ssl, const char *hostname); +uint32_t verify_signature (SSL *ssl, const char *hostname); +void check_key_length (SSL *ssl); +void inspect_key (SSL *ssl, const char *hostname); +void check_key_length (SSL *ssl); +void inspect_key (SSL *ssl, const char *hostname); +#endif +uint32_t dns_label_count (char *label, char *delim); +uint32_t check_wildcard_match_rfc2595 (const char *orig_hostname, + const char *orig_cert_wild_card); +static void run_ssl (uint32_t *time_map, int time_is_an_illusion, int http); + +#endif diff --git a/src/tlsdate-monitor.c b/src/tlsdate-monitor.c new file mode 100644 index 0000000..5169a09 --- /dev/null +++ b/src/tlsdate-monitor.c @@ -0,0 +1,99 @@ +/* + * tlsdate-monitor.c - tlsdated monitor for tlsdate. + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <time.h> +#include <unistd.h> + +#include "src/util.h" +#include "src/tlsdate.h" + +static +char ** +build_argv (struct opts *opts) +{ + int argc; + char **new_argv; + assert (opts->sources); + /* choose the next source in the list; if we're at the end, start over. */ + if (!opts->cur_source || !opts->cur_source->next) + opts->cur_source = opts->sources; + else + opts->cur_source = opts->cur_source->next; + for (argc = 0; opts->base_argv[argc]; argc++) + ; + /* Put an arbitrary limit on the number of args. */ + if (argc > 1024) + return NULL; + argc++; /* uncounted null terminator */ + argc += 9; /* -H host -p port -x proxy -Vraw -n -l */ + new_argv = malloc (argc * sizeof (char *)); + if (!new_argv) + return NULL; + for (argc = 0; opts->base_argv[argc]; argc++) + new_argv[argc] = opts->base_argv[argc]; + new_argv[argc++] = "-H"; + new_argv[argc++] = opts->cur_source->host; + new_argv[argc++] = "-p"; + new_argv[argc++] = opts->cur_source->port; + if (opts->cur_source->proxy || opts->proxy) + { + char *proxy = opts->proxy ? opts->proxy : opts->cur_source->proxy; + if (strcmp (proxy, "")) + { + new_argv[argc++] = (char *) "-x"; + new_argv[argc++] = proxy; + } + } + new_argv[argc++] = "-Vraw"; + new_argv[argc++] = "-n"; + if (opts->leap) + new_argv[argc++] = "-l"; + new_argv[argc++] = NULL; + return new_argv; +} + +/* Run tlsdate and redirects stdout to the monitor_fd */ +int +tlsdate (struct state *state) +{ + char **new_argv; + pid_t pid; + switch ((pid = fork())) + { + case 0: /* child! */ + break; + case -1: + perror ("fork() failed!"); + return -1; + default: + verb_debug ("[tlsdate-monitor] spawned tlsdate: %d", pid); + state->tlsdate_pid = pid; + return 0; + } + if (!(new_argv = build_argv (&state->opts))) + fatal ("out of memory building argv"); + /* Replace stdout with the pipe back to tlsdated */ + if (dup2 (state->tlsdate_monitor_fd, STDOUT_FILENO) < 0) + { + perror ("dup2 failed"); + _exit (2); + } + execve (new_argv[0], new_argv, state->envp); + perror ("[tlsdate-monitor] execve() failed"); + _exit (1); +} diff --git a/src/tlsdate-setter.c b/src/tlsdate-setter.c new file mode 100644 index 0000000..a40f67e --- /dev/null +++ b/src/tlsdate-setter.c @@ -0,0 +1,178 @@ +/* + * tlsdate-setter.c - privileged time setter for tlsdated + * Copyright (c) 2013 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/prctl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/dbus.h" +#include "src/seccomp.h" +#include "src/tlsdate.h" +#include "src/util.h" + +/* Atomically writes the timestamp to the specified fd. */ +int +save_timestamp_to_fd (int fd, time_t t) +{ + return platform->file_write(fd, &t, sizeof (t)); +} + +void +report_setter_error (siginfo_t *info) +{ + const char *code; + int killit = 0; + switch (info->si_code) + { + case CLD_EXITED: + code = "EXITED"; + break; + case CLD_KILLED: + code = "KILLED"; + break; + case CLD_DUMPED: + code = "DUMPED"; + break; + case CLD_STOPPED: + code = "STOPPED"; + killit = 1; + break; + case CLD_TRAPPED: + code = "TRAPPED"; + killit = 1; + break; + case CLD_CONTINUED: + code = "CONTINUED"; + killit = 1; + break; + default: + code = "???"; + killit = 1; + } + info ("tlsdate-setter exitting: code:%s status:%d pid:%d uid:%d", + code, info->si_status, info->si_pid, info->si_uid); + if (killit) + kill (info->si_pid, SIGKILL); +} + +void +time_setter_coprocess (int time_fd, int notify_fd, struct state *state) +{ + int save_fd = -1; + int status; + prctl (PR_SET_NAME, "tlsdated-setter"); + if (state->opts.should_save_disk && !state->opts.dry_run) + { + /* TODO(wad) platform->file_open */ + if ( (save_fd = open (state->timestamp_path, + O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) + { + /* Attempt to unlink the path on the way out. */ + unlink (state->timestamp_path); + status = SETTER_NO_SAVE; + goto notify_and_die; + } + } + /* XXX: Drop all privs but CAP_SYS_TIME */ +#ifdef HAVE_SECCOMP_FILTER + if (enable_setter_seccomp()) + { + status = SETTER_NO_SBOX; + goto notify_and_die; + } +#endif + while (1) + { + struct timeval tv = { 0, 0 }; + /* The wire protocol is a time_t, but the caller should + * always be the unprivileged tlsdated process which spawned this + * helper. + * There are two special messages: + * (time_t) 0: requests a clean shutdown + * (time_t) < 0: indicates not to write to disk + * On Linux, time_t is a signed long. Expanding the protocol + * is easy, but writing one long only is ideal. + */ + ssize_t bytes = read (time_fd, &tv.tv_sec, sizeof (tv.tv_sec)); + int save = 1; + if (bytes == -1) + { + if (errno == EINTR) + continue; + status = SETTER_READ_ERR; + goto notify_and_die; + } + if (bytes == 0) + { + /* End of pipe */ + status = SETTER_READ_ERR; + goto notify_and_die; + } + if (bytes != sizeof (tv.tv_sec)) + continue; + if (tv.tv_sec < 0) + { + /* Don't write to disk */ + tv.tv_sec = -tv.tv_sec; + save = 0; + } + if (tv.tv_sec == 0) + { + status = SETTER_EXIT; + goto notify_and_die; + } + if (is_sane_time (tv.tv_sec)) + { + /* It would be nice if time was only allowed to move forward, but + * if a single time source is wrong, then it could make it impossible + * to recover from once the time is written to disk. + */ + status = SETTER_BAD_TIME; + if (!state->opts.dry_run) + { + if (settimeofday (&tv, NULL) < 0) + { + status = SETTER_SET_ERR; + goto notify_and_die; + } + if (state->opts.should_sync_hwclock && + platform->rtc_write(&state->hwclock, &tv)) + { + status = SETTER_NO_RTC; + goto notify_and_die; + } + if (save && save_fd != -1 && + save_timestamp_to_fd (save_fd, tv.tv_sec)) + { + status = SETTER_NO_SAVE; + goto notify_and_die; + } + } + status = SETTER_TIME_SET; + } + /* TODO(wad) platform->file_write */ + IGNORE_EINTR (write (notify_fd, &status, sizeof(status))); + } +notify_and_die: + IGNORE_EINTR (write (notify_fd, &status, sizeof(status))); + close (notify_fd); + close (save_fd); + _exit (status); +} diff --git a/src/tlsdate.c b/src/tlsdate.c new file mode 100644 index 0000000..dd7f993 --- /dev/null +++ b/src/tlsdate.c @@ -0,0 +1,235 @@ +/* Copyright (c) 2012, Jacob Appelbaum. + * Copyright (c) 2012, The Tor Project, Inc. + * Copyright (c) 2012, Christian Grothoff. */ +/* See LICENSE for licensing information */ +/* + This file contains the license for tlsdate, + a free software project to set your system clock securely. + + It also lists the licenses for other components used by tlsdate. + + For more information about tlsdate, see https://github.com/ioerror/tlsdate + + If you got this file as a part of a larger bundle, + there may be other license terms that you should be aware of. + +=============================================================================== +tlsdate is distributed under this license: + +Copyright (c) 2011-2012, Jacob Appelbaum <jacob@appelbaum.net> +Copyright (c) 2011-2012, The Tor Project, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * Neither the names of the copyright owners nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=============================================================================== +If you got tlsdate as a static binary with OpenSSL included, then you should +know: + + "This product includes software developed by the OpenSSL Project for use in + the OpenSSL Toolkit (http://www.openssl.org/)" + +=============================================================================== +*/ + +/** + * \file tlsdate.c + * \brief The main program to assist in setting the system clock. + **/ + +/* + * tlsdate is a tool for setting the system clock by hand or by communication + * with the network. It does not set the RTC. It is designed to be as secure as + * TLS (RFC 2246) but of course the security of TLS is often reduced to + * whichever CA racket you believe is trustworthy. By default, tlsdate trusts + * your local CA root store - so any of these companies could assist in a MITM + * attack against you and you'd be screwed. + + * This tool is designed to be run by hand or as a system daemon. It must be + * run as root or otherwise have the proper caps; it will not be able to set + * the system time without running as root or another privileged user. + */ + +#include "config.h" +#include "src/tlsdate.h" + + +/** Return the proper commandline switches when the user needs information. */ +static void +usage (void) +{ + fprintf (stderr, "tlsdate usage:\n" + " [-h|--help]\n" + " [-s|--skip-verification]\n" + " [-n|--dont-set-clock]\n" + " [-H|--host] [hostname|ip]\n" + " [-p|--port] [port number]\n" + " [-P|--protocol] [sslv23|sslv3|tlsv1]\n" + " [-C|--certcontainer] [dirname|filename]\n" + " [-v|--verbose]\n" + " [-V|--showtime] [human|raw]\n" + " [-t|--timewarp]\n" + " [-l|--leap]\n" + " [-x|--proxy] [url]\n" + " [-w|--http]\n"); +} + + +int +main (int argc, char **argv) +{ + int verbose; + int ca_racket; + int showtime; + int setclock; + const char *host; + const char *port; + const char *protocol; + const char *ca_cert_container; + int timewarp; + int leap; + const char *proxy; + int http; + + host = DEFAULT_HOST; + port = DEFAULT_PORT; + protocol = DEFAULT_PROTOCOL; + ca_cert_container = DEFAULT_CERTFILE; + verbose = 0; + ca_racket = 1; + showtime = 0; + setclock = 1; + timewarp = 0; + leap = 0; + proxy = NULL; + http = 0; + + while (1) + { + int option_index = 0; + int c; + static struct option long_options[] = + { + {"verbose", 0, 0, 'v'}, + {"showtime", 2, 0, 'V'}, + {"skip-verification", 0, 0, 's'}, + {"help", 0, 0, 'h'}, + {"host", 0, 0, 'H'}, + {"port", 0, 0, 'p'}, + {"protocol", 0, 0, 'P'}, + {"dont-set-clock", 0, 0, 'n'}, + {"certcontainer", 0, 0, 'C'}, + {"timewarp", 0, 0, 't'}, + {"leap", 0, 0, 'l'}, + {"proxy", 0, 0, 'x'}, + {"http", 0, 0, 'w'}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "vV::shH:p:P:nC:tlx:w", + long_options, &option_index); + if (c == -1) + break; + switch (c) + { + case 'v': + verbose = 1; + break; + case 'V': + showtime = (optarg && 0 == strcmp ("raw", optarg) ? 2:1); + break; + case 's': + ca_racket = 0; + break; + case 'h': + usage(); + exit (1); + break; + case 'H': + host = optarg; + break; + case 'p': + port = optarg; + break; + case 'P': + protocol = optarg; + break; + case 'n': + setclock = 0; + break; + case 'C': + ca_cert_container = optarg; + break; + case 't': + timewarp = 1; + break; + case 'l': + leap = 1; + break; + case 'x': + proxy = optarg; + break; + case 'w': + http = 1; + break; + case '?': + break; + default : + fprintf (stderr, "Unknown option!\n"); + usage(); + exit (1); + } + } + if (1 == verbose) { + fprintf(stderr, + "V: tlsdate version %s\n" + "V: We were called with the following arguments:\n" + "V: %s host = %s:%s\n", + PACKAGE_VERSION, + ca_racket ? "validate SSL certificates" : "disable SSL certificate check", + host, port); + if (0 == ca_racket) + fprintf(stderr, "WARNING: Skipping certificate verification!\n"); + } + execlp (TLSDATE_HELPER, + "tlsdate", + host, + port, + protocol, + (ca_racket ? "racket" : "unchecked"), + (verbose ? "verbose" : "quiet"), + ca_cert_container, + (setclock ? "setclock" : "dont-set-clock"), + (showtime ? (showtime == 2 ? "showtime=raw" : "showtime") : "no-showtime"), + (timewarp ? "timewarp" : "no-fun"), + (leap ? "leapaway" : "holdfast"), + (proxy ? proxy : "none"), + (http ? "http" : "tls"), + NULL); + perror ("Failed to run tlsdate-helper"); + return 1; +} diff --git a/src/tlsdate.h b/src/tlsdate.h new file mode 100644 index 0000000..52305eb --- /dev/null +++ b/src/tlsdate.h @@ -0,0 +1,245 @@ +/* Copyright (c) 2013, Jacob Appelbaum + * Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file tlsdate.h + * \brief The main header for our clock helper. + **/ + +#ifndef TLSDATE_H +#define TLSDATE_H + +#include "src/configmake.h" +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <limits.h> +#include <signal.h> +#include <time.h> +#include <unistd.h> + +#include "src/rtc.h" + +#define DEFAULT_HOST "google.com" +#define DEFAULT_PORT "443" +#define DEFAULT_PROXY "none" +#define DEFAULT_PROTOCOL "tlsv1" +#define DEFAULT_CERTDIR "/etc/ssl/certs" +#define DEFAULT_CERTFILE TLSDATE_CERTFILE +#define DEFAULT_DAEMON_CACHEDIR "/var/cache/tlsdated" +#define DEFAULT_DAEMON_TMPSUFFIX ".new" +#define DEFAULT_TLSDATE TLSDATE +#define DEFAULT_RTC_DEVICE "/dev/rtc" +#define DEFAULT_CONF_FILE TLSDATE_CONF_DIR "tlsdated.conf" + +/* tlsdated magic numbers */ +#define MAX_TRIES 10 +#define WAIT_BETWEEN_TRIES 10 +#define SUBPROCESS_TRIES 10 +#define SUBPROCESS_WAIT_BETWEEN_TRIES 10 +#define RESOLVER_TIMEOUT 30 +/* Invalidate the network sync once per day. */ +#define STEADY_STATE_INTERVAL (60*60*24) +/* Check if the clock has jumped every four hours. */ +#define CONTINUITY_INTERVAL (60*60*4) +#define DEFAULT_SYNC_HWCLOCK 1 +#define DEFAULT_LOAD_FROM_DISK 1 +#define DEFAULT_SAVE_TO_DISK 1 +#define DEFAULT_USE_NETLINK 1 +#define DEFAULT_DRY_RUN 0 +#define MAX_SANE_BACKOFF (10*60) /* exponential backoff should only go this far */ + +#ifndef TLSDATED_MAX_DATE +#define TLSDATED_MAX_DATE 1999991337L /* this'll be a great bug some day */ +#endif + +#define MAX_EVENT_PRIORITIES 2 +#define PRI_SAVE 0 +#define PRI_NET 1 +#define PRI_WAKE 1 +#define PRI_ANY 1 + +/* Sync sources in order of "reliability" */ +#define SYNC_TYPE_NONE (0) +#define SYNC_TYPE_BUILD (1 << 0) +#define SYNC_TYPE_DISK (1 << 1) +#define SYNC_TYPE_RTC (1 << 2) +#define SYNC_TYPE_PLATFORM (1 << 3) +#define SYNC_TYPE_NET (1 << 4) + +/* Simple time setter<>tlsdated protocol */ +#define SETTER_EXIT 0 +#define SETTER_BAD_TIME 1 +#define SETTER_NO_SAVE 2 +#define SETTER_READ_ERR 3 +#define SETTER_TIME_SET 4 +#define SETTER_SET_ERR 5 +#define SETTER_NO_SBOX 6 +#define SETTER_NO_RTC 7 + +#define TEST_HOST 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', \ + 'c', 'o', 'm' +#define TEST_HOST_SIZE 14 +static const char kTestHost[] = { TEST_HOST, 0 }; +#define TEST_PORT 80 + +/** The current version of tlsdate. */ +#define tlsdate_version VERSION + +/** GNU/Hurd support requires that we declare this ourselves: */ +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif +#ifndef MAXPATHLEN +#define MAXPATHLEN PATH_MAX +#endif + +struct source +{ + struct source *next; + char *host; + char *port; + char *proxy; + int id; +}; + +struct opts +{ + const char *user; + const char *group; + int max_tries; + int min_steady_state_interval; + int wait_between_tries; + int subprocess_tries; + int subprocess_wait_between_tries; + int steady_state_interval; + int continuity_interval; + const char *base_path; + char **base_argv; + char **argv; + int should_sync_hwclock; + int should_load_disk; + int should_save_disk; + int should_netlink; + int dry_run; + int jitter; + char *conf_file; + struct source *sources; + struct source *cur_source; + char *proxy; + int leap; + int should_dbus; +}; + +#define MAX_FQDN_LEN 255 +#define MAX_SCHEME_LEN 9 +#define MAX_PORT_LEN 6 /* incl. : */ +#define MAX_PROXY_URL (MAX_FQDN_LEN + MAX_SCHEME_LEN + MAX_PORT_LEN + 1) + +enum event_id_t +{ + E_RESOLVER = 0, + E_TLSDATE, + E_TLSDATE_STATUS, + E_TLSDATE_TIMEOUT, + E_SAVE, + E_SIGCHLD, + E_SIGTERM, + E_STEADYSTATE, + E_ROUTEUP, + E_MAX +}; + +struct event_base; + +/* This struct is used for passing tlsdated runtime state between + * events/ in its event loop. + */ +struct state +{ + struct opts opts; + struct event_base *base; + void *dbus; + char **envp; + + time_t clock_delta; + int last_sync_type; + time_t last_time; + + char timestamp_path[PATH_MAX]; + struct rtc_handle hwclock; + char dynamic_proxy[MAX_PROXY_URL]; + /* Event triggered events */ + + struct event *events[E_MAX]; + int tlsdate_monitor_fd; + pid_t tlsdate_pid; + pid_t setter_pid; + int setter_save_fd; + int setter_notify_fd; + uint32_t backoff; + int tries; + int resolving; + int running; /* tlsdate itself */ + int exitting; +}; + +char timestamp_path[PATH_MAX]; + +int is_sane_time (time_t ts); +int load_disk_timestamp (const char *path, time_t * t); +void save_disk_timestamp (const char *path, time_t t); +int add_jitter (int base, int jitter); +void time_setter_coprocess (int time_fd, int notify_fd, struct state *state); +int tlsdate (struct state *state); + +int save_timestamp_to_fd (int fd, time_t t); +void set_conf_defaults (struct opts *opts); +int new_tlsdate_monitor_pipe (int fds[2]); +int read_tlsdate_response (int fd, time_t *t); + +void invalidate_time (struct state *state); +int check_continuity (time_t *delta); + +void action_check_continuity (int fd, short what, void *arg); +void action_kickoff_time_sync (int fd, short what, void *arg); +void action_invalidate_time (int fd, short what, void *arg); +void action_stdin_wakeup (int fd, short what, void *arg); +void action_netlink_ready (int fd, short what, void *arg); +void action_run_tlsdate (int fd, short what, void *arg); +void action_sigterm (int fd, short what, void *arg); +void action_sync_and_save (int fd, short what, void *arg); +void action_time_set (int fd, short what, void *arg); +void action_tlsdate_status (int fd, short what, void *arg); + +int setup_event_timer_continuity (struct state *state); +int setup_event_timer_sync (struct state *state); +int setup_event_route_up (struct state *state); +int setup_time_setter (struct state *state); +int setup_tlsdate_status (struct state *state); +int setup_sigchld_event (struct state *state, int persist); + +void report_setter_error (siginfo_t *info); + +void sync_and_save (void *hwclock_handle, int should_save); + +/** This is where we store parsed commandline options. */ +typedef struct +{ + int verbose; + int verbose_debug; + int ca_racket; + int help; + int showtime; + int setclock; + time_t manual_time; + char *host; + char *port; + char *protocol; +} tlsdate_options_t; + +#endif /* TLSDATE_H */ diff --git a/src/tlsdated-unittest.c b/src/tlsdated-unittest.c new file mode 100644 index 0000000..c82a85c --- /dev/null +++ b/src/tlsdated-unittest.c @@ -0,0 +1,328 @@ +/* + * tlsdated-unittest.c - tlsdated unit tests + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include "src/test_harness.h" +#include "src/tlsdate.h" +#include "src/util.h" + +#include <event2/event.h> +#include <fcntl.h> +#include <limits.h> +#include <stdlib.h> +#include <sys/time.h> +#include <unistd.h> + +FIXTURE (tempdir) +{ + char path[PATH_MAX]; +}; + +FIXTURE_SETUP (tempdir) +{ + char *p; + strncpy (self->path, "/tmp/tlsdated-unit-XXXXXX", sizeof (self->path)); + p = mkdtemp (self->path); + ASSERT_NE (NULL, p); +} + +FIXTURE_TEARDOWN(tempdir) { + char buf[256]; + snprintf(buf, sizeof(buf), "%s/load", self->path); + unlink(buf); + snprintf(buf, sizeof(buf), "%s/save", self->path); + unlink(buf); + ASSERT_EQ(0, rmdir(self->path)); +} + +int write_time (const char *path, time_t time) +{ + int fd = open (path, O_WRONLY | O_TRUNC | O_CREAT, 0600); + if (fd == -1) + return 1; + if (save_timestamp_to_fd (fd, time)) + return 1; + if (write (fd, &time, sizeof (time)) != sizeof (time)) + { + close (fd); + return 1; + } + return close (fd); +} + +int read_time (const char *path, time_t* time) +{ + int fd = open (path, O_RDONLY); + if (fd == -1) + return 1; + if (read (fd, time, sizeof (*time)) != sizeof (*time)) + { + close (fd); + return 1; + } + return close (fd); +} + +TEST (sane_time) +{ + ASSERT_EQ (0, is_sane_time (0)); + ASSERT_EQ (0, is_sane_time (INT_MAX)); +} + +TEST (sane_host_time) +{ + ASSERT_EQ (1, is_sane_time (time (NULL))); +} + +TEST_F (tempdir, load_time) +{ + char buf[PATH_MAX]; + time_t tm = 3; + time_t now = time (NULL); + snprintf (buf, sizeof (buf), "%s/load", self->path); + ASSERT_EQ (0, write_time (buf, 0)); + ASSERT_EQ (-1, load_disk_timestamp (buf, &tm)); + ASSERT_EQ (3, tm); + ASSERT_EQ (0, write_time (buf, INT_MAX)); + ASSERT_EQ (-1, load_disk_timestamp (buf, &tm)); + ASSERT_EQ (3, tm); + ASSERT_EQ (0, write_time (buf, now)); + ASSERT_EQ (0, truncate (buf, 2)); + ASSERT_EQ (-1, load_disk_timestamp (buf, &tm)); + ASSERT_EQ (3, tm); + ASSERT_EQ (0, unlink (buf)); + ASSERT_EQ (-1, load_disk_timestamp (buf, &tm)); + ASSERT_EQ (3, tm); + ASSERT_EQ (0, write_time (buf, now)); + ASSERT_EQ (0, load_disk_timestamp (buf, &tm)); + ASSERT_EQ (now, tm); +} + + +TEST_F (tempdir, save_time) +{ + char buf[PATH_MAX]; + time_t now = time (NULL); + time_t tm; + snprintf (buf, sizeof (buf), "%s/save", self->path); + ASSERT_EQ (0, write_time (buf, now)); + ASSERT_EQ (0, read_time (buf, &tm)); + EXPECT_EQ (now, tm); +} + +FIXTURE (tlsdate) +{ + struct state state; + struct timeval timeout; +}; + + +FIXTURE_SETUP (tlsdate) +{ + memset (self, 0, sizeof (*self)); + /* TODO(wad) make this use the same function tlsdated uses. */ + self->state.base = event_base_new(); + set_conf_defaults (&self->state.opts); + ASSERT_NE (NULL, self->state.base); + event_base_priority_init (self->state.base, MAX_EVENT_PRIORITIES); + ASSERT_EQ (0, setup_sigchld_event (&self->state, 1)); + self->state.events[E_TLSDATE] = event_new (self->state.base, -1, EV_TIMEOUT, + action_run_tlsdate, &self->state); + ASSERT_NE (NULL, self->state.events[E_TLSDATE]); + event_priority_set (self->state.events[E_TLSDATE], PRI_NET); + /* The timeout and fd will be filled in per-call. */ + ASSERT_EQ (0, setup_tlsdate_status (&self->state)); + self->timeout.tv_sec = 1; +} + +FIXTURE_TEARDOWN (tlsdate) +{ + int i; + for (i = 0; i < E_MAX; ++i) + { + struct event *e = self->state.events[i]; + if (e) + { + int fd = event_get_fd (e); + if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL)) + close (fd); + event_free (e); + self->state.events[i] = NULL; + } + } + /* The other half was closed above. */ + close (self->state.tlsdate_monitor_fd); + if (self->state.tlsdate_pid) + { + kill (self->state.tlsdate_pid, SIGKILL); + waitpid (self->state.tlsdate_pid, NULL, WNOHANG); + } + if (self->state.base) + event_base_free (self->state.base); +} + +static int +runner (FIXTURE_DATA (tlsdate) *self, time_t *newtime) +{ + if (newtime) + *newtime = 0; + trigger_event (&self->state, E_TLSDATE, 0); + event_base_loopexit (self->state.base, &self->timeout); + if (event_base_dispatch (self->state.base)) + return -1; + if (self->state.last_time) + { + if (newtime) + *newtime = self->state.last_time; + return 0; + } + return 1; +} + +TEST_F (tlsdate, runner_multi) +{ + struct source source = + { + .next = NULL, + .host = "host1", + .port = "port1", + .proxy = "proxy1" + }; + char *args[] = { "/nonexistent", NULL, NULL }; + extern char **environ; + self->state.opts.sources = &source; + self->state.opts.base_argv = args; + self->state.opts.subprocess_tries = 2; + self->state.opts.subprocess_wait_between_tries = 1; + self->state.opts.max_tries = 3; + self->state.envp = environ; + EXPECT_EQ (1, runner (self, NULL)); + args[0] = "/bin/false"; + self->state.tries = 0; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (1, runner (self, NULL)); + args[0] = "src/test/check-host-1"; + self->state.tries = 0; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); + args[0] = "src/test/sleep-wrap"; + args[1] = "3"; + self->state.tries = 0; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); +} + +TEST (jitter) +{ + int i = 0; + int r; + const int kBase = 100; + const int kJitter = 25; + int nonequal = 0; + for (i = 0; i < 1000; i++) + { + r = add_jitter (kBase, kJitter); + EXPECT_GE (r, kBase - kJitter); + EXPECT_LE (r, kBase + kJitter); + if (r != kBase) + nonequal++; + } + EXPECT_NE (nonequal, 0); +} + +TEST_F (tlsdate, rotate_hosts) +{ + struct source s2 = + { + .next = NULL, + .host = "host2", + .port = "port2", + .proxy = "proxy2" + }; + struct source s1 = + { + .next = &s2, + .host = "host1", + .port = "port1", + .proxy = "proxy1" + }; + char *args[] = { "src/test/check-host-1", NULL }; + extern char **environ; + self->state.envp = environ; + self->state.opts.sources = &s1; + self->state.opts.base_argv = args; + self->state.opts.subprocess_tries = 2; + self->state.opts.subprocess_wait_between_tries = 1; + self->state.opts.max_tries = 5; + self->timeout.tv_sec = 2; + EXPECT_EQ (0, runner (self, NULL)); + self->state.tries = 0; + args[0] = "src/test/check-host-2"; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); + self->state.tries = 0; + args[0] = "src/test/check-host-1"; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); + self->state.tries = 0; + args[0] = "src/test/check-host-2"; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); +} + +TEST_F (tlsdate, proxy_override) +{ + struct source s1 = + { + .next = NULL, + .host = "host", + .port = "port", + .proxy = NULL, + }; + char *args[] = { "src/test/proxy-override", NULL }; + extern char **environ; + self->state.envp = environ; + self->state.opts.sources = &s1; + self->state.opts.base_argv = args; + self->state.opts.subprocess_tries = 2; + self->state.opts.subprocess_wait_between_tries = 1; + EXPECT_EQ (0, runner (self, NULL)); + EXPECT_EQ (RECENT_COMPILE_DATE + 1, self->state.last_time); + s1.proxy = "socks5://bad.proxy"; + self->state.tries = 0; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); + EXPECT_EQ (RECENT_COMPILE_DATE + 3, self->state.last_time); + self->state.opts.proxy = "socks5://good.proxy"; + self->state.tries = 0; + self->state.last_sync_type = SYNC_TYPE_NONE; + EXPECT_EQ (0, runner (self, NULL)); + EXPECT_EQ (RECENT_COMPILE_DATE + 2, self->state.last_time); +} + +FIXTURE(mock_platform) { + struct platform platform; + struct platform *old_platform; +}; + +FIXTURE_SETUP(mock_platform) { + self->old_platform = platform; + self->platform.rtc_open = NULL; + self->platform.rtc_write = NULL; + self->platform.rtc_read = NULL; + self->platform.rtc_close = NULL; + platform = &self->platform; +} + +FIXTURE_TEARDOWN(mock_platform) { + platform = self->old_platform; +} + +/* TODO: leap_tests, time_setter tests. */ + +TEST_HARNESS_MAIN diff --git a/src/tlsdated.c b/src/tlsdated.c new file mode 100644 index 0000000..0165b58 --- /dev/null +++ b/src/tlsdated.c @@ -0,0 +1,602 @@ +/* + * tlsdated.c - invoke tlsdate when necessary. + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * We invoke tlsdate once at system startup, then we start trying to invoke + * tlsdate when a new network route appears. We try a few times after each route + * comes up. As soon as we get a successful tlsdate run, we save that timestamp + * to disk, then linger to wait for system shutdown. At system shutdown + * (indicated by us getting SIGTERM), we save our timestamp to disk. + */ + +#include "config.h" + +#include <assert.h> +#include <errno.h> +#include <grp.h> /* setgroups */ +#include <fcntl.h> +#include <limits.h> +#include <linux/rtc.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/wait.h> +#include <time.h> +#include <unistd.h> + + +#include <event2/event.h> + +#include "src/conf.h" +#include "src/routeup.h" +#include "src/util.h" +#include "src/tlsdate.h" +#include "src/dbus.h" +#include "src/platform.h" + +const char *kCacheDir = DEFAULT_DAEMON_CACHEDIR; + +int +is_sane_time (time_t ts) +{ + return ts > RECENT_COMPILE_DATE && ts < TLSDATED_MAX_DATE; +} + +/* + * Load a time value out of the file named by path. Returns 0 if successful, + * -1 if not. The file contains the time in seconds since epoch in host byte + * order. + */ +int +load_disk_timestamp (const char *path, time_t * t) +{ + int fd = platform->file_open (path, 0 /* RDONLY */, 1 /* CLOEXEC */); + time_t tmpt = 0; + if (fd < 0) + { + perror ("Can't open %s for reading", path); + return -1; + } + if (platform->file_read(fd, &tmpt, sizeof(tmpt))) + { + perror ("Can't read seconds from %s", path); + platform->file_close (fd); + return -1; + } + platform->file_close (fd); + if (!is_sane_time (tmpt)) + { + error ("Disk timestamp is not sane: %ld", tmpt); + return -1; + } + *t = tmpt; + return 0; +} + + +void +usage (const char *progn) +{ + printf ("Usage: %s [flags...] [--] [tlsdate command...]\n", progn); + printf (" -w don't set hwclock\n"); + printf (" -p dry run (don't really set time)\n"); + printf (" -r use stdin instead of netlink for routes\n"); + printf (" -t <n> try n times to synchronize the time\n"); + printf (" -d <n> delay n seconds between tries\n"); + printf (" -T <n> give subprocess n chances to exit\n"); + printf (" -D <n> delay n seconds between wait attempts\n"); + printf (" -c <path> set the cache directory\n"); + printf (" -a <n> run at most every n seconds in steady state\n"); + printf (" -m <n> run at most once every n seconds in steady state\n"); + printf (" -j <n> add up to n seconds jitter to steady state checks\n"); + printf (" -l don't load disk timestamps\n"); + printf (" -s don't save disk timestamps\n"); + printf (" -U don't use DBus if supported\n"); + printf (" -u <user> user to change to\n"); + printf (" -g <grp> group to change to\n"); + printf (" -v be verbose\n"); + printf (" -b use verbose debugging\n"); + printf (" -x <h> set proxy for subprocs to h\n"); + printf (" -h this\n"); +} + +void +set_conf_defaults (struct opts *opts) +{ + static char *kDefaultArgv[] = + { + (char *) DEFAULT_TLSDATE, (char *) "-H", (char *) DEFAULT_HOST, NULL + }; + opts->user = UNPRIV_USER; + opts->group = UNPRIV_GROUP; + opts->max_tries = MAX_TRIES; + opts->min_steady_state_interval = STEADY_STATE_INTERVAL; + opts->wait_between_tries = WAIT_BETWEEN_TRIES; + opts->subprocess_tries = SUBPROCESS_TRIES; + opts->subprocess_wait_between_tries = SUBPROCESS_WAIT_BETWEEN_TRIES; + opts->steady_state_interval = STEADY_STATE_INTERVAL; + opts->continuity_interval = CONTINUITY_INTERVAL; + opts->base_path = kCacheDir; + opts->base_argv = kDefaultArgv; + opts->argv = NULL; + opts->should_dbus = 1; + opts->should_sync_hwclock = DEFAULT_SYNC_HWCLOCK; + opts->should_load_disk = DEFAULT_LOAD_FROM_DISK; + opts->should_save_disk = DEFAULT_SAVE_TO_DISK; + opts->should_netlink = DEFAULT_USE_NETLINK; + opts->dry_run = DEFAULT_DRY_RUN; + opts->jitter = 0; + opts->conf_file = NULL; + opts->sources = NULL; + opts->cur_source = NULL; + opts->proxy = NULL; + opts->leap = 0; +} + +void +parse_argv (struct opts *opts, int argc, char *argv[]) +{ + int opt; + while ((opt = getopt (argc, argv, "hwrpt:d:T:D:c:a:lsvbm:j:f:x:Uu:g:")) != -1) + { + switch (opt) + { + case 'w': + opts->should_sync_hwclock = 0; + break; + case 'r': + opts->should_netlink = 0; + break; + case 'U': + opts->should_dbus = 0; + break; + case 'p': + opts->dry_run = 1; + break; + case 't': + opts->max_tries = atoi (optarg); + break; + case 'd': + opts->wait_between_tries = atoi (optarg); + break; + case 'T': + opts->subprocess_tries = atoi (optarg); + break; + case 'D': + opts->subprocess_wait_between_tries = atoi (optarg); + break; + case 'c': + opts->base_path = optarg; + break; + case 'a': + opts->steady_state_interval = atoi (optarg); + break; + case 'l': + opts->should_load_disk = 0; + break; + case 's': + opts->should_save_disk = 0; + break; + case 'v': + verbose = 1; + break; + case 'b': + verbose_debug = 1; + break; + case 'm': + opts->min_steady_state_interval = atoi (optarg); + break; + case 'j': + opts->jitter = atoi (optarg); + break; + case 'f': + opts->conf_file = optarg; + break; + case 'x': + opts->proxy = optarg; + break; + case 'u': + opts->user = optarg; + break; + case 'g': + opts->group = optarg; + break; + case 'h': + default: + usage (argv[0]); + exit (1); + } + } + if (optind < argc) + opts->base_argv = argv + optind; + /* Validate arguments */ +} + +static +void add_source_to_conf (struct opts *opts, char *host, char *port, char *proxy) +{ + struct source *s; + struct source *source = (struct source *) calloc (1, sizeof *source); + if (!source) + fatal ("out of memory for source"); + source->host = strdup (host); + if (!source->host) + fatal ("out of memory for host"); + source->port = strdup (port); + if (!source->port) + fatal ("out of memory for port"); + if (proxy) + { + source->proxy = strdup (proxy); + if (!source->proxy) + fatal ("out of memory for proxy"); + } + if (!opts->sources) + { + opts->sources = source; + source->id = 0; + } + else + { + for (s = opts->sources; s->next; s = s->next) + ; + source->id = s->id + 1; + s->next = source; + } +} + +static struct conf_entry * +parse_source (struct opts *opts, struct conf_entry *conf) +{ + char *host = NULL; + char *port = NULL; + char *proxy = NULL; + /* a source entry: + * source + * host <host> + * port <port> + * [proxy <proxy>] + * end + */ + assert (!strcmp (conf->key, "source")); + conf = conf->next; + while (conf && strcmp (conf->key, "end")) + { + if (!strcmp (conf->key, "host")) + host = conf->value; + else if (!strcmp (conf->key, "port")) + port = conf->value; + else if (!strcmp (conf->key, "proxy")) + proxy = conf->value; + else + fatal ("malformed config: '%s' in source stanza", conf->key); + conf = conf->next; + } + if (!conf) + fatal ("unclosed source stanza"); + if (!host || !port) + fatal ("incomplete source stanza (needs host, port)"); + add_source_to_conf (opts, host, port, proxy); + return conf; +} + +void +load_conf (struct opts *opts) +{ + FILE *f; + struct conf_entry *conf, *e; + char *conf_file = opts->conf_file; + if (!opts->conf_file) + conf_file = (char *) DEFAULT_CONF_FILE; + f = fopen (conf_file, "r"); + if (!f) + { + if (opts->conf_file) + { + pfatal ("can't open conf file '%s'", opts->conf_file); + } + else + { + pinfo ("can't open conf file '%s'", conf_file); + return; + } + } + conf = conf_parse (f); + if (!conf) + pfatal ("can't parse config file"); + + for (e = conf; e; e = e->next) + { + if (!strcmp (e->key, "max-tries") && e->value) + { + opts->max_tries = atoi (e->value); + } + else if (!strcmp (e->key, "min-steady-state-interval") && e->value) + { + opts->min_steady_state_interval = atoi (e->value); + } + else if (!strcmp (e->key, "wait-between-tries") && e->value) + { + opts->wait_between_tries = atoi (e->value); + } + else if (!strcmp (e->key, "subprocess-tries") && e->value) + { + opts->subprocess_tries = atoi (e->value); + } + else if (!strcmp (e->key, "subprocess-wait-between-tries") && e->value) + { + opts->subprocess_wait_between_tries = atoi (e->value); + } + else if (!strcmp (e->key, "steady-state-interval") && e->value) + { + opts->steady_state_interval = atoi (e->value); + } + else if (!strcmp (e->key, "base-path") && e->value) + { + opts->base_path = strdup (e->value); + if (!opts->base_path) + fatal ("out of memory for base path"); + } + else if (!strcmp (e->key, "should-sync-hwclock")) + { + opts->should_sync_hwclock = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "should-load-disk")) + { + opts->should_load_disk = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "should-save-disk")) + { + opts->should_save_disk = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "should-netlink")) + { + opts->should_netlink = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "dry-run")) + { + opts->dry_run = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "jitter") && e->value) + { + opts->jitter = atoi (e->value); + } + else if (!strcmp (e->key, "verbose")) + { + verbose = e->value ? !strcmp (e->value, "yes") : 1; + } + else if (!strcmp (e->key, "source")) + { + e = parse_source (opts, e); + } + else if (!strcmp (e->key, "leap")) + { + opts->leap = e->value ? !strcmp (e->value, "yes") : 1; + } + } +} + +void +check_conf (struct state *state) +{ + struct opts *opts = &state->opts; + if (!opts->max_tries) + fatal ("-t argument must be nonzero"); + if (!opts->wait_between_tries) + fatal ("-d argument must be nonzero"); + if (!opts->steady_state_interval) + fatal ("-a argument must be nonzero"); + if (snprintf (state->timestamp_path, sizeof (state->timestamp_path), + "%s/timestamp", opts->base_path) >= sizeof (state->timestamp_path)) + fatal ("supplied base path is too long: '%s'", opts->base_path); + if (opts->jitter >= opts->steady_state_interval) + fatal ("jitter must be less than steady state interval (%d >= %d)", + opts->jitter, opts->steady_state_interval); +} + +int +cleanup_main (struct state *state) +{ + int i; + for (i = 0; i < E_MAX; ++i) + { + struct event *e = state->events[i]; + if (e) + { + int fd = event_get_fd (e); + if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL)) + close (fd); + event_free (e); + } + } + /* The other half was closed above. */ + platform->file_close (state->tlsdate_monitor_fd); + if (state->tlsdate_pid) + { + platform->process_signal (state->tlsdate_pid, SIGKILL); + platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */); + } + /* Best effort to tear it down if it is still alive. */ + close(state->setter_notify_fd); + close(state->setter_save_fd); + if (state->setter_pid) + { + platform->process_signal (state->setter_pid, SIGKILL); + platform->process_wait (state->setter_pid, NULL, 0 /* !forever */); + } + /* TODO(wad) Add dbus_cleanup() */ + if (state->base) + event_base_free (state->base); + memset(state, 0, sizeof(*state)); + info ("tlsdated clean up finished; exiting!"); + terminate_syslog (); + return 0; +} + +#ifdef TLSDATED_MAIN +int API +main (int argc, char *argv[], char *envp[]) +{ + initalize_syslog (); + struct state state; + /* TODO(wad) EVENT_BASE_FLAG_PRECISE_TIMER | EVENT_BASE_FLAG_PRECISE_TIMER */ + struct event_base *base = event_base_new(); + if (!base) + { + fatal ("could not allocated new event base"); + } + /* Add three priority levels: + * 0 - time saving. Must be done before any other events are handled. + * 1 - network synchronization events + * 2 - any other events (wake, platform, etc) + */ + event_base_priority_init (base, MAX_EVENT_PRIORITIES); + memset (&state, 0, sizeof (state)); + set_conf_defaults (&state.opts); + parse_argv (&state.opts, argc, argv); + check_conf (&state); + load_conf (&state.opts); + check_conf (&state); + if (!state.opts.sources) + add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY); + state.base = base; + state.envp = envp; + state.backoff = state.opts.wait_between_tries; + /* TODO(wad) move this into setup_time_setter */ + /* grab a handle to /dev/rtc for time-setter. */ + if (state.opts.should_sync_hwclock && + platform->rtc_open(&state.hwclock)) + { + pinfo ("can't open hwclock fd"); + state.opts.should_sync_hwclock = 0; + } + /* install the SIGCHLD handler for the setter and tlsdate */ + if (setup_sigchld_event (&state, 1)) + { + error ("Failed to setup SIGCHLD event"); + goto out; + } + /* fork off the privileged helper */ + verb ("spawning time setting helper . . ."); + if (setup_time_setter (&state)) + { + error ("could not fork privileged coprocess"); + goto out; + } + /* release the hwclock now that the time-setter is running. */ + if (state.opts.should_sync_hwclock) + { + platform->rtc_close (&state.hwclock); + } + /* drop privileges before touching any untrusted data */ + drop_privs_to (state.opts.user, state.opts.group); + /* register a signal handler to save time at shutdown */ + if (state.opts.should_save_disk) + { + struct event *event = event_new (base, SIGTERM, EV_SIGNAL|EV_PERSIST, + action_sigterm, &state); + if (!event) + fatal ("Failed to create SIGTERM event"); + event_priority_set (event, PRI_SAVE); + event_add (event, NULL); + } + if (state.opts.should_dbus && init_dbus (&state)) + { + error ("Failed to initialize DBus"); + goto out; + } + /* Register the tlsdate event before any listeners could show up. */ + state.events[E_TLSDATE] = event_new (base, -1, EV_TIMEOUT, + action_run_tlsdate, &state); + if (!state.events[E_TLSDATE]) + { + error ("Failed to create tlsdate event"); + goto out; + } + event_priority_set (state.events[E_TLSDATE], PRI_NET); + /* The timeout and fd will be filled in per-call. */ + if (setup_tlsdate_status (&state)) + { + error ("Failed to create tlsdate status event"); + goto out; + } + /* TODO(wad) Could use a timeout on this to catch setter death? */ + /* EV_READ is for truncation/EPIPE notification */ + state.events[E_SAVE] = event_new (base, state.setter_save_fd, + EV_READ|EV_WRITE, action_sync_and_save, + &state); + if (!state.events[E_SAVE]) + { + error ("Failed to create sync & save event"); + goto out; + } + event_priority_set (state.events[E_SAVE], PRI_SAVE); + /* Start by grabbing the system time. */ + state.last_sync_type = SYNC_TYPE_RTC; + state.last_time = time (NULL); + /* If possible, grab disk time and check the two. */ + if (state.opts.should_load_disk) + { + time_t disk_time = state.last_time; + if (!load_disk_timestamp (state.timestamp_path, &disk_time)) + { + verb ("disk timestamp available: yes"); + if (!is_sane_time (state.last_time) || + state.last_time < disk_time) + { + state.last_sync_type = SYNC_TYPE_DISK; + state.last_time = disk_time; + } + } + else + { + verb ("disk timestamp available: no"); + } + } + if (!is_sane_time (state.last_time)) + { + state.last_sync_type = SYNC_TYPE_BUILD; + state.last_time = RECENT_COMPILE_DATE + 1; + } + /* Save and announce the initial time source. */ + trigger_event (&state, E_SAVE, -1); + verb ("tlsdated parasitic time synchronization initialized"); + info ("initial time sync type: %s", sync_type_str (state.last_sync_type)); + /* Initialize platform specific loop behavior */ + if (platform_init_cros (&state)) + { + error ("Failed to initialize platform code"); + goto out; + } + if (setup_event_route_up (&state)) + { + error ("Failed to setup route up monitoring"); + goto out; + } + if (setup_event_timer_sync (&state)) + { + error ("Failed to setup a timer event"); + goto out; + } + if (setup_event_timer_continuity (&state)) + { + error ("Failed to setup continuity timer"); + goto out; + } + /* Add a forced sync event to the event list. */ + action_kickoff_time_sync (-1, EV_TIMEOUT, &state); + verb ("Entering dispatch . . ."); + event_base_dispatch (base); + verb ("tlsdated event dispatch terminating gracefully"); +out: + return cleanup_main (&state); +} +#endif /* !TLSDATED_MAIN */ diff --git a/src/util-plan9.c b/src/util-plan9.c new file mode 100644 index 0000000..77d2077 --- /dev/null +++ b/src/util-plan9.c @@ -0,0 +1,112 @@ +/* + * util.c - routeup/tlsdated utility functions + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" + +#include <grp.h> +#include <pwd.h> +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#if !_PLAN9_SOURCE +#include <syslog.h> +#endif +#include <unistd.h> + +#include "src/util.h" + +/** helper function to print message and die */ +void +die (const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +/** helper function for 'verbose' output */ +void +verb (const char *fmt, ...) +{ + va_list ap; + + if (! verbose) return; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + +#if !_PLAN9_SOURCE +void API logat(int isverbose, const char *fmt, ...) +{ + if (isverbose && !verbose) + return; + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + va_start(ap, fmt); + vsyslog(LOG_INFO, fmt, ap); + va_end(ap); +} +#endif + + +void +drop_privs_to (const char *user, const char *group) +{ +#if !_PLAN9_SOURCE + + uid_t uid; + gid_t gid; + struct passwd *pw; + struct group *gr; + + if (0 != getuid ()) + return; /* not running as root to begin with; should (!) be harmless to continue + without dropping to 'nobody' (setting time will fail in the end) */ + pw = getpwnam(user); + gr = getgrnam(group); + if (NULL == pw) + die ("Failed to obtain UID for `%s'\n", user); + if (NULL == gr) + die ("Failed to obtain GID for `%s'\n", group); + uid = pw->pw_uid; + if (0 == uid) + die ("UID for `%s' is 0, refusing to run SSL\n", user); + gid = pw->pw_gid; + if (0 == gid || 0 == gr->gr_gid) + die ("GID for `%s' is 0, refusing to run SSL\n", user); + if (pw->pw_gid != gr->gr_gid) + die ("GID for `%s' is not `%s' as expected, refusing to run SSL\n", + user, group); + + if (0 != initgroups((const char *)user, gr->gr_gid)) + die ("Unable to initgroups for `%s' in group `%s' as expected\n", + user, group); + +#ifdef HAVE_SETRESGID + if (0 != setresgid (gid, gid, gid)) + die ("Failed to setresgid: %s\n", strerror (errno)); +#else + if (0 != (setgid (gid) | setegid (gid))) + die ("Failed to setgid: %s\n", strerror (errno)); +#endif +#ifdef HAVE_SETRESUID + if (0 != setresuid (uid, uid, uid)) + die ("Failed to setresuid: %s\n", strerror (errno)); +#else + if (0 != (setuid (uid) | seteuid (uid))) + die ("Failed to setuid: %s\n", strerror (errno)); +#endif +#endif /* !_PLAN9_SOURCE */ +} + diff --git a/src/util-plan9.h b/src/util-plan9.h new file mode 100644 index 0000000..7453235 --- /dev/null +++ b/src/util-plan9.h @@ -0,0 +1,41 @@ +/* + * util.h - routeup/tlsdated utility functions + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef UTIL_H +#define UTIL_H + +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#if _PLAN9_SOURCE +#define API +#else +#define API __attribute__((visibility("default"))) +#endif + +extern int verbose; +extern int verbose_debug; +void die (const char *fmt, ...); +void verb (const char *fmt, ...); +extern void logat(int isverbose, const char *fmt, ...); + +#define info(fmt, ...) logat(1, fmt, ## __VA_ARGS__) +#define pinfo(fmt, ...) logat(1, fmt ": %s", ## __VA_ARGS__, strerror(errno)) +#define error(fmt, ...) logat(0, fmt, ## __VA_ARGS__) +#define perror(fmt, ...) logat(0, fmt ": %s", ## __VA_ARGS__, strerror(errno)) +#define fatal(fmt, ...) do { logat(0, fmt, ## __VA_ARGS__); exit(1); } while (0) +#define pfatal(fmt, ...) do { \ + logat(0, fmt ": %s", ## __VA_ARGS__, strerror(errno)); \ + exit(1); \ +} while (0) + +static inline int min(int x, int y) { return x < y ? x : y; } + +void drop_privs_to (const char *user, const char *group); + +#endif /* !UTIL_H */ diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..6bb279c --- /dev/null +++ b/src/util.c @@ -0,0 +1,439 @@ +/* + * util.c - routeup/tlsdated utility functions + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "config.h" +#include "tlsdate.h" + +#include <fcntl.h> +#include <grp.h> +#include <limits.h> +#ifdef HAVE_LINUX_RTC_H +#include <linux/rtc.h> +#endif +#include <pwd.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <sys/wait.h> +#include <syslog.h> +#include <time.h> +#include <unistd.h> + +#ifdef WITH_EVENTS +#include <event2/event.h> +#endif + +#include "src/tlsdate.h" +#include "src/util.h" + +#ifdef HAVE_SECCOMP_FILTER +#include "src/seccomp.h" +#endif + +#if defined(HAVE_STRUCT_RTC_TIME) && defined(RTC_SET_TIME) && defined(RTC_RD_TIME) +#define ENABLE_RTC +#endif + +const char *kTempSuffix = DEFAULT_DAEMON_TMPSUFFIX; + +/** helper function to print message and die */ +void +die (const char *fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + fprintf (stderr, "\n"); + va_end (ap); + exit (1); +} + +/* Initalize syslog */ +void initalize_syslog (void) +{ + openlog ("tlsdated", LOG_PID, LOG_DAEMON); +} + +/* Signal to syslog that we're finished logging */ +void terminate_syslog (void) +{ + closelog (); +} + +/** helper function for 'verbose' output without syslog support */ +void +verb_no_syslog (const char *fmt, ...) +{ + va_list ap; + + if (! verbose ) return; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf (stderr, "\n"); + va_end(ap); +} + +/** helper function for 'verbose' output */ +void +verb (const char *fmt, ...) +{ + va_list ap; + + if (! verbose ) return; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf (stderr, "\n"); + va_end(ap); + va_start(ap, fmt); + vsyslog (LOG_DEBUG, fmt, ap); + va_end(ap); +} + +void API logat (int isverbose, const char *fmt, ...) +{ + va_list ap; + if (isverbose && !verbose) + return; + va_start (ap, fmt); + vfprintf (stderr, fmt, ap); + fprintf (stderr, "\n"); + va_end (ap); + va_start (ap, fmt); + vsyslog (LOG_INFO, fmt, ap); + va_end (ap); +} + +void no_new_privs(void) +{ +#ifdef TARGET_OS_LINUX +#ifdef HAVE_PRCTL // XXX: Make this specific to PR_SET_NO_NEW_PRIVS + // Check to see if we're already set PR_SET_NO_NEW_PRIVS + // This happens in tlsdated earlier than when tlsdate-helper drops + // privileges. + if (0 == prctl (PR_GET_NO_NEW_PRIVS)) { + // Remove the ability to regain privilegess + if (0 != prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); + die ("Failed to PR_SET_NO_NEW_PRIVS"); + } else { + verb ("V: Parent process has already set PR_SET_NO_NEW_PRIVS"); + } +#else + verb ("V: we are unwilling to set PR_SET_NO_NEW_PRIVS"); +#endif +#endif +} + +void enable_seccomp(void) +{ +#ifdef HAVE_SECCOMP_FILTER + int status; + prctl (PR_SET_NAME, "tlsdate seccomp"); + verb ("V: seccomp support is enabled"); + if (enable_setter_seccomp()) + { + status = SETTER_NO_SBOX; + _exit (status); + } +#else + verb ("V: seccomp support is disabled"); +#endif +} + +void +drop_privs_to (const char *user, const char *group) +{ + uid_t uid; + gid_t gid; + struct passwd *pw; + struct group *gr; + + if (0 != getuid ()) + return; /* not running as root to begin with; should (!) be harmless to continue + without dropping to 'nobody' (setting time will fail in the end) */ + pw = getpwnam (user); + gr = getgrnam (group); + if (NULL == pw) + die ("Failed to obtain UID for `%s'\n", user); + if (NULL == gr) + die ("Failed to obtain GID for `%s'\n", group); + uid = pw->pw_uid; + if (0 == uid) + die ("UID for `%s' is 0, refusing to run SSL\n", user); + gid = pw->pw_gid; + if (0 == gid || 0 == gr->gr_gid) + die ("GID for `%s' is 0, refusing to run SSL\n", user); + if (pw->pw_gid != gr->gr_gid) + die ("GID for `%s' is not `%s' as expected, refusing to run SSL\n", + user, group); + if (0 != initgroups ( (const char *) user, gr->gr_gid)) + die ("Unable to initgroups for `%s' in group `%s' as expected\n", + user, group); +#ifdef HAVE_SETRESGID + if (0 != setresgid (gid, gid, gid)) + die ("Failed to setresgid: %s\n", strerror (errno)); +#else + if (0 != (setgid (gid) | setegid (gid))) + die ("Failed to setgid: %s\n", strerror (errno)); +#endif +#ifdef HAVE_SETRESUID + if (0 != setresuid (uid, uid, uid)) + die ("Failed to setresuid: %s\n", strerror (errno)); +#else + if (0 != (setuid (uid) | seteuid (uid))) + die ("Failed to setuid: %s\n", strerror (errno)); +#endif +} + +#ifdef ENABLE_RTC +int rtc_open(struct rtc_handle *h) +{ + if (!h) + return -1; + h->fd = -1; + /* TODO: Use platform->file_open but drop NOFOLLOW? */ + h->fd = open(DEFAULT_RTC_DEVICE, O_RDONLY); + if (h->fd < 0) + { + pinfo("can't open rtc"); + return -1; + } + return 0; +} + +/* + * Set the hardware clock referred to by fd (which should be a descriptor to + * some device that implements the interface documented in rtc(4)) to the system + * time. See hwclock(8) for details of why this is important. If we fail, we + * just return - there's nothing the caller can really do about a failure of + * this function except try later. + */ +int rtc_write(struct rtc_handle *handle, const struct timeval *tv) +{ + struct tm tmr; + struct tm *tm; + struct rtc_time rtctm; + int fd = handle->fd; + + tm = gmtime_r (&tv->tv_sec, &tmr); + + /* these structs are identical, but separately defined */ + rtctm.tm_sec = tm->tm_sec; + rtctm.tm_min = tm->tm_min; + rtctm.tm_hour = tm->tm_hour; + rtctm.tm_mday = tm->tm_mday; + rtctm.tm_mon = tm->tm_mon; + rtctm.tm_year = tm->tm_year; + rtctm.tm_wday = tm->tm_wday; + rtctm.tm_yday = tm->tm_yday; + rtctm.tm_isdst = tm->tm_isdst; + + if (ioctl (fd, RTC_SET_TIME, &rtctm)) + { + pinfo ("ioctl(%d, RTC_SET_TIME, ...) failed", fd); + return 1; + } + + info ("synced rtc to sysclock"); + return 0; +} + +int rtc_read(struct rtc_handle *handle, struct timeval *tv) +{ + struct tm tm; + struct rtc_time rtctm; + int fd = handle->fd; + + if (ioctl (fd, RTC_RD_TIME, &rtctm)) + { + pinfo ("ioctl(%d, RTC_RD_TIME, ...) failed", fd); + return 1; + } + + tm.tm_sec = rtctm.tm_sec; + tm.tm_min = rtctm.tm_min; + tm.tm_hour = rtctm.tm_hour; + tm.tm_mday = rtctm.tm_mday; + tm.tm_mon = rtctm.tm_mon; + tm.tm_year = rtctm.tm_year; + tm.tm_wday = rtctm.tm_wday; + tm.tm_yday = rtctm.tm_yday; + tm.tm_isdst = rtctm.tm_isdst; + + tv->tv_sec = mktime(&tm); + tv->tv_usec = 0; + + return 0; +} + +int rtc_close(struct rtc_handle *handle) +{ + struct rtc_handle *h = handle; + platform->file_close(h->fd); + h->fd = -1; + return 0; +} +#endif + +int file_write(int fd, void *buf, size_t sz) +{ + struct iovec iov[1]; + ssize_t ret; + iov[0].iov_base = buf; + iov[0].iov_len = sz; + ret = IGNORE_EINTR (pwritev (fd, iov, 1, 0)); + if (ret != sz) + { + return -1; + } + return 0; +} + +int file_open(const char *path, int write, int cloexec) +{ + int fd; + int oflags = cloexec ? O_CLOEXEC : 0; + if (write) + { + int perms = S_IRUSR | S_IWUSR; + oflags |= O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC; + /* Rely on atomic write calls rather than rename() calls. */ + fd = open(path, oflags, perms); + } + else + { + oflags |= O_RDONLY | O_NOFOLLOW; + fd = open(path, oflags); + } + if (fd < 0) + { + pinfo("open(%s) failed", path); + return -1; + } + return fd; +} + +int file_close(int fd) +{ + return close(fd); +} + +int file_read(int fd, void *buf, size_t sz) +{ + struct iovec iov[1]; + iov[0].iov_base = buf; + iov[0].iov_len = sz; + if (preadv (fd, iov, 1, 0) != sz) + { + /* Returns -1 on read failure */ + return -1; + } + /* Returns 0 on a successful buffer fill. */ + return 0; +} + +int time_get(struct timeval *tv) +{ + return gettimeofday(tv, NULL); +} + +int pgrp_enter(void) +{ + return setpgid(0, 0); +} + +int pgrp_kill(void) +{ + pid_t grp = getpgrp(); + return kill(-grp, SIGKILL); +} + +int process_signal(pid_t pid, int signal) +{ + return kill (pid, signal); +} + +pid_t process_wait(pid_t pid, int *status, int forever) +{ + int flag = forever ? 0 : WNOHANG; + return waitpid (pid, status, flag); +} + +static struct platform default_platform = { +#ifdef ENABLE_RTC + .rtc_open = rtc_open, + .rtc_write = rtc_write, + .rtc_read = rtc_read, + .rtc_close = rtc_close, +#endif + + .file_open = file_open, + .file_close = file_close, + .file_write = file_write, + .file_read = file_read, + + .time_get = time_get, + + .pgrp_enter = pgrp_enter, + .pgrp_kill = pgrp_kill, + + .process_signal = process_signal, + .process_wait = process_wait +}; + +struct platform *platform = &default_platform; + +/* TODO(wad) rename to schedule_event */ +void +trigger_event (struct state *state, enum event_id_t id, int sec) +{ +#ifdef WITH_EVENTS + struct event *e = state->events[id]; + struct timeval delay = { sec, 0 }; + /* Fallthrough to tlsdate if there is no resolver. */ + if (!e && id == E_RESOLVER) + e = state->events[E_TLSDATE]; + if (!e) + { + info ("trigger_event with NULL |e|. I hope this is a test!"); + return; + } + if (event_pending (e, EV_READ|EV_WRITE|EV_TIMEOUT|EV_SIGNAL, NULL)) + event_del (e); + if (sec >= 0) + event_add (e, &delay); + else /* Note! This will not fire a TIMEOUT event. */ + event_add (e, NULL); +#endif +} + +const char * +sync_type_str (int sync_type) +{ + switch (sync_type) + { + case SYNC_TYPE_NONE: + return "none"; + case SYNC_TYPE_BUILD: + return "build-timestamp"; + case SYNC_TYPE_DISK: + return "disk-timestamp"; + case SYNC_TYPE_RTC: + return "system-clock"; + case SYNC_TYPE_PLATFORM: + return "platform-feature"; + case SYNC_TYPE_NET: + return "network"; + default: + return "error"; + } +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..eaceeeb --- /dev/null +++ b/src/util.h @@ -0,0 +1,97 @@ +/* + * util.h - routeup/tlsdated utility functions + * Copyright (c) 2012 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef UTIL_H +#define UTIL_H + +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> + +#ifdef HAVE_PRCTL +#include <sys/prctl.h> +#ifndef PR_SET_NO_NEW_PRIVS +# define PR_SET_NO_NEW_PRIVS 38 +#endif +#ifndef PR_GET_NO_NEW_PRIVS +# define PR_GET_NO_NEW_PRIVS 39 +#endif +#endif + +#include "src/rtc.h" + +#ifdef TARGET_OS_HAIKU +#include <stdarg.h> +#endif + +#define API __attribute__((visibility("default"))) + +extern const char *kTempSuffix; +#define IGNORE_EINTR(expr) ({ \ + typeof(expr) _r; \ + while ((_r = (expr)) == -1 && errno == EINTR); \ + _r; \ +}) + +extern int verbose; +extern int verbose_debug; +void initalize_syslog (void); +void terminate_syslog (void); +void die (const char *fmt, ...); +void verb (const char *fmt, ...); +extern void logat (int isverbose, const char *fmt, ...); + +#define verb_debug debug +#define debug(fmt, ...) if (verbose_debug) logat(1, fmt, ## __VA_ARGS__) +#define info(fmt, ...) logat(0, fmt, ## __VA_ARGS__) +#define pinfo(fmt, ...) logat(1, fmt ": %s", ## __VA_ARGS__, strerror(errno)) +#define error(fmt, ...) logat(0, fmt, ## __VA_ARGS__) +#define perror(fmt, ...) logat(0, fmt ": %s", ## __VA_ARGS__, strerror(errno)) +#define fatal(fmt, ...) do { logat(0, fmt, ## __VA_ARGS__); exit(1); } while (0) +#define pfatal(fmt, ...) do { \ + logat(0, fmt ": %s", ## __VA_ARGS__, strerror(errno)); \ + exit(1); \ +} while (0) + +static inline int min (int x, int y) +{ + return x < y ? x : y; +} + +void drop_privs_to (const char *user, const char *group); +void no_new_privs (void); +const char *sync_type_str (int sync_type); + +struct state; +enum event_id_t; +void trigger_event (struct state *state, enum event_id_t e, int sec); + +struct platform { + int (*rtc_open)(struct rtc_handle *); + int (*rtc_write)(struct rtc_handle *, const struct timeval *tv); + int (*rtc_read)(struct rtc_handle *, struct timeval *tv); + int (*rtc_close)(struct rtc_handle *); + + int (*file_open)(const char *path, int write, int cloexec); + int (*file_close)(int fd); + /* Atomic file write and read */ + int (*file_write)(int fd, void *buf, size_t sz); + int (*file_read)(int fd, void *buf, size_t sz); + + int (*time_get)(struct timeval *tv); + + int (*pgrp_enter)(void); + int (*pgrp_kill)(void); + + int (*process_signal)(pid_t pid, int sig); + int (*process_wait)(pid_t pid, int *status, int timeout); +}; + +extern struct platform *platform; + +#endif /* !UTIL_H */ diff --git a/src/visibility.h b/src/visibility.h new file mode 100644 index 0000000..b9452f1 --- /dev/null +++ b/src/visibility.h @@ -0,0 +1,75 @@ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Copyright (C) 2012 Brian Aker, brian@tangent.org + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#pragma once + +#if defined(BUILDING_TLSDATE) +# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY +# define TLSDATE_API __attribute__ ((visibility("default"))) +# define TLSDATE_LOCAL __attribute__ ((visibility("default"))) +# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# define TLSDATE_API __global +# define TLSDATE_LOCAL __global +# elif defined(_MSC_VER) +# define TLSDATE_API extern __declspec(dllexport) +# define TLSDATE_LOCAL extern __declspec(dllexport) +# else +# define TLSDATE_API +# define TLSDATE_LOCAL +# endif +#else +# if defined(BUILDING_TLSDATE) +# if defined(HAVE_VISIBILITY) && HAVE_VISIBILITY +# define TLSDATE_API __attribute__ ((visibility("default"))) +# define TLSDATE_LOCAL __attribute__ ((visibility("hidden"))) +# elif defined (__SUNPRO_C) && (__SUNPRO_C >= 0x550) +# define TLSDATE_API __global +# define TLSDATE_LOCAL __hidden +# elif defined(_MSC_VER) +# define TLSDATE_API extern __declspec(dllexport) +# define TLSDATE_LOCAL +# else +# define TLSDATE_API +# define TLSDATE_LOCAL +# endif /* defined(HAVE_VISIBILITY) */ +# else /* defined(BUILDING_TLSDATE) */ +# if defined(_MSC_VER) +# define TLSDATE_API extern __declspec(dllimport) +# define TLSDATE_LOCAL +# else +# define TLSDATE_API +# define TLSDATE_LOCAL +# endif /* defined(_MSC_VER) */ +# endif /* defined(BUILDING_TLSDATE) */ +#endif /* defined(BUILDING_TLSDATEINTERNAL) */ diff --git a/systemd/tlsdated.service b/systemd/tlsdated.service new file mode 100644 index 0000000..5515a8e --- /dev/null +++ b/systemd/tlsdated.service @@ -0,0 +1,10 @@ +[Unit] +Description=Secure parasitic time daemon +After=network.target + +[Service] +Type=simple +EnvironmentFile=/etc/default/tlsdated +ExecStart=/usr/sbin/tlsdated ${DAEMON_OPTS} +ExecReload=/bin/kill -HUP ${MAINPID} +ExecStop=/bin/kill -INT ${MAINPID} diff --git a/test.conf b/test.conf new file mode 100644 index 0000000..96827ef --- /dev/null +++ b/test.conf @@ -0,0 +1,2 @@ +min-steady-state-interval 0 +wait-between-tries 1 diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..e0c0e00 --- /dev/null +++ b/tests/README @@ -0,0 +1 @@ +Integration tests for tlsdate/tlsdated. diff --git a/tests/common.sh b/tests/common.sh new file mode 100644 index 0000000..9e488db --- /dev/null +++ b/tests/common.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +kill_tlsdated() { + kill -TERM $PPID +} + +result_passed() { + res=$(cat "$(mydir)"/"result") + if [ $res = "ok" ]; then + return 0 + fi + return 1 +} + +check_err() { + grep -q "$1" "$(mydir)"/"run-err" +} + +passed_if_timed_out() { + echo "ok" > "$(mydir)"/"result" +} + +passed() { + echo "ok" > "$(mydir)"/"result" + kill_tlsdated +} + +failed() { + echo "failed" > "$(mydir)"/"result" + kill_tlsdated +} + +mydir() { + echo "$(dirname "$0")" +} + +counter() { + cat "$(mydir)"/"$1" +} + +inc_counter() { + c=$(counter "$1") + echo $((c + 1)) >"$(mydir)"/"$1" +} + +reset_counter() { + echo 0 > "$(mydir)"/"$1" +} + +reset_time() { + date +%s > "$(mydir)"/"$1" +} + +emit_time() { + src/test/emit `cat "$(mydir)"/"$1"` +} diff --git a/tests/run-idle/output b/tests/run-idle/output new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tests/run-idle/output @@ -0,0 +1 @@ +ok diff --git a/tests/run-idle/setup b/tests/run-idle/setup new file mode 100755 index 0000000..bd12ed6 --- /dev/null +++ b/tests/run-idle/setup @@ -0,0 +1,5 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_time "timestamp" +reset_counter "runs" diff --git a/tests/run-idle/subproc.sh b/tests/run-idle/subproc.sh new file mode 100755 index 0000000..f01a814 --- /dev/null +++ b/tests/run-idle/subproc.sh @@ -0,0 +1,12 @@ +#!/bin/sh +. "$(dirname $0)"/../common.sh + +inc_counter "runs" +c=$(counter "runs") +[ $c -eq 3 ] && passed + +# Bump it three seconds to overcome the steady state interval. +inc_counter "timestamp" +inc_counter "timestamp" +inc_counter "timestamp" +emit_time "timestamp" diff --git a/tests/run-idle/teardown b/tests/run-idle/teardown new file mode 100644 index 0000000..b153b10 --- /dev/null +++ b/tests/run-idle/teardown @@ -0,0 +1,15 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_counter "runs" +# If the run count passed, then make sure the +# time was being set and it wasn't error calls. +if result_passed; then + if check_err 'time set from the network'; then + passed + else + failed + fi +fi + + diff --git a/tests/run-idle/test.conf b/tests/run-idle/test.conf new file mode 100644 index 0000000..c97ac9b --- /dev/null +++ b/tests/run-idle/test.conf @@ -0,0 +1,4 @@ +min-steady-state-interval 0 +steady-state-interval 1 +subprocess-tries 1 +subprocess-wait-between-tries 2 diff --git a/tests/run-once/output b/tests/run-once/output new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tests/run-once/output @@ -0,0 +1 @@ +ok diff --git a/tests/run-once/run-error b/tests/run-once/run-error new file mode 100644 index 0000000..f84e1cf --- /dev/null +++ b/tests/run-once/run-error @@ -0,0 +1 @@ +Killed diff --git a/tests/run-once/subproc.sh b/tests/run-once/subproc.sh new file mode 100755 index 0000000..5bf92e1 --- /dev/null +++ b/tests/run-once/subproc.sh @@ -0,0 +1,3 @@ +#!/bin/sh +. "$(dirname $0)"/../common.sh +passed diff --git a/tests/run-routeup/input.sh b/tests/run-routeup/input.sh new file mode 100755 index 0000000..fd33215 --- /dev/null +++ b/tests/run-routeup/input.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# Wake up from stdin twice. +c=0 +while [ $c -lt 120 ]; do + echo + sleep 0.2 + c=$((c+1)) +done diff --git a/tests/run-routeup/output b/tests/run-routeup/output new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tests/run-routeup/output @@ -0,0 +1 @@ +ok diff --git a/tests/run-routeup/setup b/tests/run-routeup/setup new file mode 100755 index 0000000..c4afd68 --- /dev/null +++ b/tests/run-routeup/setup @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_counter "runs" diff --git a/tests/run-routeup/subproc.sh b/tests/run-routeup/subproc.sh new file mode 100755 index 0000000..18bb5c9 --- /dev/null +++ b/tests/run-routeup/subproc.sh @@ -0,0 +1,9 @@ +#!/bin/sh +. "$(dirname $0)"/../common.sh + +inc_counter "runs" +c=$(counter "runs") +[ $c -eq 2 ] && passed + +# Always emit a bogus time so that stdin retriggers. +src/test/emit "0" diff --git a/tests/run-routeup/teardown b/tests/run-routeup/teardown new file mode 100644 index 0000000..c4afd68 --- /dev/null +++ b/tests/run-routeup/teardown @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_counter "runs" diff --git a/tests/run-routeup/test.conf b/tests/run-routeup/test.conf new file mode 100644 index 0000000..14a7747 --- /dev/null +++ b/tests/run-routeup/test.conf @@ -0,0 +1,4 @@ +# Don't let steady state trigger the next call. +min-steady-state-interval 10 +steady-state-interval 30 +wait-between-tries 1 diff --git a/tests/subproc-retry/output b/tests/subproc-retry/output new file mode 100644 index 0000000..0dae225 --- /dev/null +++ b/tests/subproc-retry/output @@ -0,0 +1,3 @@ +dying +dying +ok diff --git a/tests/subproc-retry/setup b/tests/subproc-retry/setup new file mode 100755 index 0000000..c4afd68 --- /dev/null +++ b/tests/subproc-retry/setup @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_counter "runs" diff --git a/tests/subproc-retry/subproc.sh b/tests/subproc-retry/subproc.sh new file mode 100755 index 0000000..b3fded7 --- /dev/null +++ b/tests/subproc-retry/subproc.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Die on the first three attempts. +. "$(dirname $0)"/../common.sh + +inc_counter "runs" +if [ $(counter "runs") -lt 3 ]; then + exit 1 +fi +passed diff --git a/tests/subproc-retry/teardown b/tests/subproc-retry/teardown new file mode 100644 index 0000000..c4afd68 --- /dev/null +++ b/tests/subproc-retry/teardown @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_counter "runs" diff --git a/tests/wait-idle/output b/tests/wait-idle/output new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/wait-idle/output diff --git a/tests/wait-idle/setup b/tests/wait-idle/setup new file mode 100755 index 0000000..bd12ed6 --- /dev/null +++ b/tests/wait-idle/setup @@ -0,0 +1,5 @@ +#!/bin/sh +. "$(dirname "$0")"/../common.sh + +reset_time "timestamp" +reset_counter "runs" diff --git a/tests/wait-idle/subproc.sh b/tests/wait-idle/subproc.sh new file mode 100755 index 0000000..2994a5c --- /dev/null +++ b/tests/wait-idle/subproc.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Make sure that a longer steady state after a successful run +# doesn't call again too soon. +. "$(dirname $0)"/../common.sh + +emit_time "timestamp" +# This one expects a timeout to end it. +passed_if_timed_out + +inc_counter "runs" +c=$(counter "runs") +[ $c -eq 2 ] && failed + diff --git a/tlsdate-brew-formula.rb b/tlsdate-brew-formula.rb new file mode 100644 index 0000000..5ed9bf3 --- /dev/null +++ b/tlsdate-brew-formula.rb @@ -0,0 +1,27 @@ +require 'formula' + +class Tlsdate < Formula + homepage 'https://www.github.com/ioerror/tlsdate/' + url 'https://nodeload.github.com/ioerror/tlsdate/tar.gz/master' + # This hash will never be correct until we put a tagged version into master + # update accordingly until we do a proper release that supports OS X + sha1 '2e818eb327af74c6a6c86a8c8b3911e20be9bc0f' + version '0.0.6' + + depends_on 'autoconf' => :build + depends_on 'automake' => :build + depends_on 'libtool' => :build + depends_on 'pkg-config' => :build + + def install + system "./autogen.sh" + system "./configure", "--disable-debug", "--disable-dependency-tracking", + "--prefix=#{prefix}" + system "make" + system "make install" + end + + def test + system "tlsdate -v -n" + end +end diff --git a/tlsdate-seccomp-amd64.policy b/tlsdate-seccomp-amd64.policy new file mode 100644 index 0000000..d22afdc --- /dev/null +++ b/tlsdate-seccomp-amd64.policy @@ -0,0 +1,48 @@ +mmap: 1 +open: 1 +read: 1 +close: 1 +fstat: 1 +mprotect: 1 +munmap: 1 +stat: 1 +write: 1 +lseek: 1 +brk: 1 +fcntl: 1 +execve: 1 +sendto: 1 +# Allow domain == PF_FILE || domain == PF_INET || domain == PF_NETLINK +socket: arg0 == 1 || arg0 == 2 || arg0 == 16 +connect: 1 +poll: 1 +access: 1 +arch_prctl: 1 +wait4: 1 +rt_sigaction: 1 +exit_group: 1 +rt_sigprocmask: 1 +clone: 1 +# Allow request == RTC_SET_TIME || request == FIONREAD +ioctl: arg1 == 0x4024700a || arg1 == 0x541b +getuid: 1 +exit: 1 +rt_sigreturn: 1 +rename: 1 +select: 1 +setgid: 1 +settimeofday: 1 +restart_syscall: 1 +setresgid: 1 +setgroups: 1 +setsockopt: 1 +bind: 1 +recvfrom: 1 +setresuid: 1 +nanosleep: 1 +clock_gettime: 1 +clock_settime: 1 +futex: 1 +getrlimit: 1 +set_robust_list: 1 +set_tid_address: 1 diff --git a/tlsdate-seccomp-arm.policy b/tlsdate-seccomp-arm.policy new file mode 100644 index 0000000..2d31d89 --- /dev/null +++ b/tlsdate-seccomp-arm.policy @@ -0,0 +1,50 @@ +open: 1 +read: 1 +mmap2: 1 +stat64: 1 +close: 1 +fstat64: 1 +_newselect: 1 +mprotect: 1 +munmap: 1 +gettimeofday: 1 +_llseek: 1 +write: 1 +rt_sigprocmask: 1 +brk: 1 +execve: 1 +fcntl64: 1 +rt_sigaction: 1 +send: 1 +poll: 1 +# Allow domain == PF_FILE || domain == PF_INET || domain == PF_NETLINK +socket: arg0 == 1 || arg0 == 2 || arg0 == 16 +uname: 1 +connect: 1 +access: 1 +ARM_set_tls: 1 +wait4: 1 +exit_group: 1 +getuid32: 1 +clone: 1 +# Allow request == RTC_SET_TIME || request == FIONREAD +ioctl: arg1 == 0x4024700a || arg1 == 0x541b +setgid32: 1 +recvfrom: 1 +setresuid32: 1 +setgroups32: 1 +settimeofday: 1 +restart_syscall: 1 +setsockopt: 1 +setresgid32: 1 +nanosleep: 1 +exit: 1 +rt_sigreturn: 1 +rename: 1 +bind: 1 +clock_gettime: 1 +clock_settime: 1 +futex: 1 +ugetrlimit: 1 +set_robust_list: 1 +set_tid_address: 1 diff --git a/tlsdate-seccomp-x86.policy b/tlsdate-seccomp-x86.policy new file mode 100644 index 0000000..da790c9 --- /dev/null +++ b/tlsdate-seccomp-x86.policy @@ -0,0 +1,47 @@ +open: 1 +mmap2: 1 +read: 1 +close: 1 +fstat64: 1 +stat64: 1 +munmap: 1 +mprotect: 1 +time: 1 +socketcall: 1 +_llseek: 1 +brk: 1 +write: 1 +execve: 1 +fcntl64: 1 +gettimeofday: 1 +poll: 1 +access: 1 +set_thread_area: 1 +waitpid: 1 +exit_group: 1 +rt_sigprocmask: 1 +getuid32: 1 +clone: 1 +rt_sigaction: 1 +# Allow request == RTC_SET_TIME || request == FIONREAD +ioctl: arg1 == 0x4024700a || arg1 == 0x541b +setgid32: 1 +setgroups32: 1 +setresuid32: 1 +settimeofday: 1 +restart_syscall: 1 +setresgid32: 1 +nanosleep: 1 +exit: 1 +rt_sigreturn: 1 +rename: 1 +select: 1 +_newselect: 1 +clock_gettime: 1 +clock_settime: 1 +futex: 1 +getrlimit: 1 +ugetrlimit: 1 +set_robust_list: 1 +set_tid_address: 1 +uname: 1 |