Check self-signed certificate names and signatures
Add unit tests for self-signed certificates with invalid name/sigs
BUG=607954
Review-Url: https://codereview.chromium.org/1988993002
Cr-Commit-Position: refs/heads/master@{#396548}
diff --git a/net/cert/x509_certificate_ios.cc b/net/cert/x509_certificate_ios.cc
index 553c63a..a92c5d16 100644
--- a/net/cert/x509_certificate_ios.cc
+++ b/net/cert/x509_certificate_ios.cc
@@ -466,9 +466,9 @@
crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert.get()));
if (!scoped_key)
return false;
-
- // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error.
- return X509_verify(cert.get(), scoped_key.get()) == 1;
+ if (!X509_verify(cert.get(), scoped_key.get()))
+ return false;
+ return X509_check_issued(cert.get(), cert.get()) == X509_V_OK;
}
} // namespace net
diff --git a/net/cert/x509_certificate_nss.cc b/net/cert/x509_certificate_nss.cc
index 4e63806..8681b3c 100644
--- a/net/cert/x509_certificate_nss.cc
+++ b/net/cert/x509_certificate_nss.cc
@@ -285,8 +285,12 @@
crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert_handle));
if (!public_key.get())
return false;
- return SECSuccess == CERT_VerifySignedDataWithPublicKey(
- &cert_handle->signatureWrap, public_key.get(), NULL);
+ if (SECSuccess != CERT_VerifySignedDataWithPublicKey(
+ &cert_handle->signatureWrap, public_key.get(), NULL)) {
+ return false;
+ }
+ return CERT_CompareName(&cert_handle->subject, &cert_handle->issuer) ==
+ SECEqual;
}
} // namespace net
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc
index dc1b4ee6..4809b45 100644
--- a/net/cert/x509_certificate_openssl.cc
+++ b/net/cert/x509_certificate_openssl.cc
@@ -456,9 +456,9 @@
crypto::ScopedEVP_PKEY scoped_key(X509_get_pubkey(cert_handle));
if (!scoped_key)
return false;
-
- // NOTE: X509_verify() returns 1 in case of success, 0 or -1 on error.
- return X509_verify(cert_handle, scoped_key.get()) == 1;
+ if (!X509_verify(cert_handle, scoped_key.get()))
+ return false;
+ return X509_check_issued(cert_handle, cert_handle) == X509_V_OK;
}
} // namespace net
diff --git a/net/cert/x509_certificate_unittest.cc b/net/cert/x509_certificate_unittest.cc
index 6e35cda..0b45df6 100644
--- a/net/cert/x509_certificate_unittest.cc
+++ b/net/cert/x509_certificate_unittest.cc
@@ -748,6 +748,16 @@
ImportCertFromFile(certs_dir, "aia-root.pem"));
ASSERT_NE(static_cast<X509Certificate*>(NULL), self_signed.get());
EXPECT_TRUE(X509Certificate::IsSelfSigned(self_signed->os_cert_handle()));
+
+ scoped_refptr<X509Certificate> bad_name(
+ ImportCertFromFile(certs_dir, "self-signed-invalid-name.pem"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), bad_name.get());
+ EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_name->os_cert_handle()));
+
+ scoped_refptr<X509Certificate> bad_sig(
+ ImportCertFromFile(certs_dir, "self-signed-invalid-sig.pem"));
+ ASSERT_NE(static_cast<X509Certificate*>(NULL), bad_sig.get());
+ EXPECT_FALSE(X509Certificate::IsSelfSigned(bad_sig->os_cert_handle()));
}
TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
diff --git a/net/cert/x509_certificate_win.cc b/net/cert/x509_certificate_win.cc
index 7d8e531..6edf6a9 100644
--- a/net/cert/x509_certificate_win.cc
+++ b/net/cert/x509_certificate_win.cc
@@ -464,15 +464,16 @@
// static
bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
- return !!CryptVerifyCertificateSignatureEx(
- NULL,
- X509_ASN_ENCODING,
- CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
+ bool valid_signature = !!CryptVerifyCertificateSignatureEx(
+ NULL, X509_ASN_ENCODING, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CERT,
reinterpret_cast<void*>(const_cast<PCERT_CONTEXT>(cert_handle)),
CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT,
- reinterpret_cast<void*>(const_cast<PCERT_CONTEXT>(cert_handle)),
- 0,
- NULL);
+ reinterpret_cast<void*>(const_cast<PCERT_CONTEXT>(cert_handle)), 0, NULL);
+ if (!valid_signature)
+ return false;
+ return !!CertCompareCertificateName(X509_ASN_ENCODING,
+ &cert_handle->pCertInfo->Subject,
+ &cert_handle->pCertInfo->Issuer);
}
} // namespace net
diff --git a/net/data/ssl/certificates/README b/net/data/ssl/certificates/README
index 3798af5c..761a8d2 100644
--- a/net/data/ssl/certificates/README
+++ b/net/data/ssl/certificates/README
@@ -279,3 +279,9 @@
containing the intermediate, which can be served via a URLRequestFilter.
aia-intermediate.der is stored in DER form for convenience, since that is
the form expected of certificates discovered via AIA.
+
+===== From net/data/ssl/scripts/generate-self-signed-certs.sh
+ - self-signed-invalid-name.pem
+ - self-signed-invalid-sig.pem
+ Two "self-signed" certificates with mismatched names or an invalid
+ signature, respectively.
diff --git a/net/data/ssl/certificates/self-signed-invalid-name.pem b/net/data/ssl/certificates/self-signed-invalid-name.pem
new file mode 100644
index 0000000..cbec017
--- /dev/null
+++ b/net/data/ssl/certificates/self-signed-invalid-name.pem
@@ -0,0 +1,69 @@
+Certificate:
+ Data:
+ Version: 1 (0x0)
+ Serial Number: 18181326976980170770 (0xfc510c8e88213812)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS A
+ Validity
+ Not Before: May 27 18:37:25 2016 GMT
+ Not After : May 25 18:37:25 2026 GMT
+ Subject: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS B
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b0:5a:83:9c:fe:1b:46:24:0b:d9:b0:0a:f2:f1:
+ 47:bf:05:f1:68:49:6b:d2:50:f7:29:f5:f1:59:a8:
+ 28:04:e2:7e:c9:d5:e0:86:b5:8f:2f:f9:45:a5:88:
+ 02:04:cb:9a:c3:19:56:68:c8:eb:fe:c3:46:1a:44:
+ be:e2:c5:e5:34:5a:18:66:1b:8e:d7:d9:19:f2:22:
+ 43:6d:4c:28:56:25:48:42:b5:76:e5:d9:c0:86:40:
+ f7:e7:87:0c:2d:07:e6:bd:84:9e:60:36:97:a8:d3:
+ de:8a:37:a6:70:68:de:f1:d3:0a:db:fe:11:e8:f9:
+ 0b:bc:56:47:d3:d4:5a:e5:ce:af:e6:d8:30:de:11:
+ a3:7a:4d:c7:b5:0a:9c:9a:f6:4d:df:a1:46:6c:91:
+ 03:e3:c6:be:61:38:b5:cb:1a:b5:82:6d:4d:d2:c6:
+ 8b:32:25:b3:6d:01:d7:e7:da:2e:fe:a0:95:cf:9c:
+ a1:e0:89:9e:2b:2b:f3:3a:98:7b:2e:b1:77:b3:88:
+ 12:71:63:53:bf:b1:df:1e:de:da:13:e8:bd:d4:30:
+ ec:c2:c4:e7:f9:0a:31:b2:b4:5e:36:9a:90:74:ef:
+ 6a:45:e5:77:f3:97:8b:68:81:43:05:bc:e5:07:a6:
+ 2f:9b:b1:c0:59:43:ac:28:bb:36:6c:98:02:72:c4:
+ 77:3b
+ Exponent: 65537 (0x10001)
+ Signature Algorithm: sha256WithRSAEncryption
+ 9d:33:a4:6d:41:ba:9c:83:24:92:be:82:61:d0:fd:d8:f6:3d:
+ 68:38:49:80:15:09:56:27:8b:ad:ef:7b:b4:43:1f:bf:9a:cd:
+ 72:da:6c:99:5c:c9:65:88:fd:8e:fa:65:df:27:80:22:ae:85:
+ 15:b8:ec:b4:e1:92:57:f0:19:7c:8a:79:d4:54:87:97:a8:4f:
+ 64:18:7c:89:0d:85:3b:6b:db:21:90:00:0c:17:32:19:11:a5:
+ 79:1f:ec:43:3e:3e:ce:96:53:d1:c1:eb:96:c6:05:3d:52:19:
+ 6c:a1:9f:a7:96:6e:a1:6f:d5:f9:37:04:89:99:a5:55:59:83:
+ 1a:6a:e7:08:5e:20:41:13:9c:86:0f:b6:ae:5c:9f:e9:5b:41:
+ ad:9e:af:96:1b:5c:37:d0:88:45:a0:35:d0:10:e7:9e:f6:38:
+ cc:c2:4f:65:70:e7:cb:73:ae:6b:e6:60:73:be:31:ef:d6:24:
+ 3f:12:e5:24:8f:2b:db:e2:b1:de:3d:b4:c5:8b:1b:88:2c:ac:
+ a3:e2:f3:34:15:df:ca:e5:25:8a:0c:96:a9:16:28:0a:a7:48:
+ 4a:95:00:3a:45:d1:0c:ad:58:10:71:0d:2a:77:99:78:4d:a0:
+ fb:ba:36:8b:62:54:53:7d:81:21:11:46:fc:46:a4:99:42:32:
+ c8:1f:ed:6f
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiACCQD8UQyOiCE4EjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITWljaGlnYW4xEjAQBgNVBAcMCUFubiBBcmJvcjEZMBcGA1UE
+CgwQVGVzdCBTZWxmLVNpZ25lZDENMAsGA1UEAwwEU1MgQTAeFw0xNjA1MjcxODM3
+MjVaFw0yNjA1MjUxODM3MjVaMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNaWNo
+aWdhbjESMBAGA1UEBwwJQW5uIEFyYm9yMRkwFwYDVQQKDBBUZXN0IFNlbGYtU2ln
+bmVkMQ0wCwYDVQQDDARTUyBCMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAsFqDnP4bRiQL2bAK8vFHvwXxaElr0lD3KfXxWagoBOJ+ydXghrWPL/lFpYgC
+BMuawxlWaMjr/sNGGkS+4sXlNFoYZhuO19kZ8iJDbUwoViVIQrV25dnAhkD354cM
+LQfmvYSeYDaXqNPeijemcGje8dMK2/4R6PkLvFZH09Ra5c6v5tgw3hGjek3HtQqc
+mvZN36FGbJED48a+YTi1yxq1gm1N0saLMiWzbQHX59ou/qCVz5yh4ImeKyvzOph7
+LrF3s4gScWNTv7HfHt7aE+i91DDswsTn+QoxsrReNpqQdO9qReV385eLaIFDBbzl
+B6Yvm7HAWUOsKLs2bJgCcsR3OwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCdM6Rt
+QbqcgySSvoJh0P3Y9j1oOEmAFQlWJ4ut73u0Qx+/ms1y2myZXMlliP2O+mXfJ4Ai
+roUVuOy04ZJX8Bl8innUVIeXqE9kGHyJDYU7a9shkAAMFzIZEaV5H+xDPj7OllPR
+weuWxgU9UhlsoZ+nlm6hb9X5NwSJmaVVWYMaaucIXiBBE5yGD7auXJ/pW0Gtnq+W
+G1w30IhFoDXQEOee9jjMwk9lcOfLc65r5mBzvjHv1iQ/EuUkjyvb4rHePbTFixuI
+LKyj4vM0Fd/K5SWKDJapFigKp0hKlQA6RdEMrVgQcQ0qd5l4TaD7ujaLYlRTfYEh
+EUb8RqSZQjLIH+1v
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/certificates/self-signed-invalid-sig.pem b/net/data/ssl/certificates/self-signed-invalid-sig.pem
new file mode 100644
index 0000000..fd9b5a9
--- /dev/null
+++ b/net/data/ssl/certificates/self-signed-invalid-sig.pem
@@ -0,0 +1,69 @@
+Certificate:
+ Data:
+ Version: 1 (0x0)
+ Serial Number: 14998008630224366850 (0xd023a162e6c42d02)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS A
+ Validity
+ Not Before: May 27 18:37:25 2016 GMT
+ Not After : May 25 18:37:25 2026 GMT
+ Subject: C=US, ST=Michigan, L=Ann Arbor, O=Test Self-Signed, CN=SS A
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (2048 bit)
+ Modulus:
+ 00:b0:5a:83:9c:fe:1b:46:24:0b:d9:b0:0a:f2:f1:
+ 47:bf:05:f1:68:49:6b:d2:50:f7:29:f5:f1:59:a8:
+ 28:04:e2:7e:c9:d5:e0:86:b5:8f:2f:f9:45:a5:88:
+ 02:04:cb:9a:c3:19:56:68:c8:eb:fe:c3:46:1a:44:
+ be:e2:c5:e5:34:5a:18:66:1b:8e:d7:d9:19:f2:22:
+ 43:6d:4c:28:56:25:48:42:b5:76:e5:d9:c0:86:40:
+ f7:e7:87:0c:2d:07:e6:bd:84:9e:60:36:97:a8:d3:
+ de:8a:37:a6:70:68:de:f1:d3:0a:db:fe:11:e8:f9:
+ 0b:bc:56:47:d3:d4:5a:e5:ce:af:e6:d8:30:de:11:
+ a3:7a:4d:c7:b5:0a:9c:9a:f6:4d:df:a1:46:6c:91:
+ 03:e3:c6:be:61:38:b5:cb:1a:b5:82:6d:4d:d2:c6:
+ 8b:32:25:b3:6d:01:d7:e7:da:2e:fe:a0:95:cf:9c:
+ a1:e0:89:9e:2b:2b:f3:3a:98:7b:2e:b1:77:b3:88:
+ 12:71:63:53:bf:b1:df:1e:de:da:13:e8:bd:d4:30:
+ ec:c2:c4:e7:f9:0a:31:b2:b4:5e:36:9a:90:74:ef:
+ 6a:45:e5:77:f3:97:8b:68:81:43:05:bc:e5:07:a6:
+ 2f:9b:b1:c0:59:43:ac:28:bb:36:6c:98:02:72:c4:
+ 77:3b
+ Exponent: 65537 (0x10001)
+ Signature Algorithm: sha256WithRSAEncryption
+ aa:73:51:c6:c4:9b:8e:2d:a1:04:08:19:f9:c5:58:62:58:55:
+ c8:71:9c:4b:af:01:cd:c6:34:6d:02:36:d8:34:0d:7b:6b:e6:
+ 41:f6:eb:6c:be:a5:42:85:a9:fd:38:ee:a3:21:ba:b0:97:e6:
+ f1:8e:2f:8e:68:ac:87:94:bb:90:8c:e5:b7:02:04:a2:75:35:
+ df:1b:ea:51:ec:df:85:fb:9f:46:a2:03:5b:f0:02:92:72:f0:
+ a6:d3:c7:d5:84:78:3a:c2:77:82:eb:ed:e0:59:37:c7:f6:6e:
+ 2c:34:3a:4e:3c:7a:f2:71:92:51:81:1b:77:0b:27:67:cd:33:
+ a6:59:a8:c8:c3:38:cd:ad:e3:48:bb:fd:e4:92:4a:e5:73:93:
+ 15:1a:c9:fd:94:eb:11:6b:cd:45:dd:04:92:da:bb:e8:53:1d:
+ 65:76:13:ea:a9:3a:e2:7b:f7:a6:66:f7:02:fb:d4:7a:ac:2f:
+ 72:32:66:0e:b5:97:a0:10:d2:0e:31:fc:e5:3a:74:79:bc:cc:
+ 97:85:31:85:f3:89:8f:f5:7a:66:53:eb:77:98:51:c3:3f:ed:
+ 29:b7:e6:bc:30:83:b2:aa:b0:82:98:50:32:a1:4c:da:1e:6f:
+ a8:c8:49:51:f5:6b:c4:15:18:e6:32:33:d6:31:f6:0d:62:f6:
+ d2:db:de:ad
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiACCQDQI6Fi5sQtAjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITWljaGlnYW4xEjAQBgNVBAcMCUFubiBBcmJvcjEZMBcGA1UE
+CgwQVGVzdCBTZWxmLVNpZ25lZDENMAsGA1UEAwwEU1MgQTAeFw0xNjA1MjcxODM3
+MjVaFw0yNjA1MjUxODM3MjVaMF4xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNaWNo
+aWdhbjESMBAGA1UEBwwJQW5uIEFyYm9yMRkwFwYDVQQKDBBUZXN0IFNlbGYtU2ln
+bmVkMQ0wCwYDVQQDDARTUyBBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEAsFqDnP4bRiQL2bAK8vFHvwXxaElr0lD3KfXxWagoBOJ+ydXghrWPL/lFpYgC
+BMuawxlWaMjr/sNGGkS+4sXlNFoYZhuO19kZ8iJDbUwoViVIQrV25dnAhkD354cM
+LQfmvYSeYDaXqNPeijemcGje8dMK2/4R6PkLvFZH09Ra5c6v5tgw3hGjek3HtQqc
+mvZN36FGbJED48a+YTi1yxq1gm1N0saLMiWzbQHX59ou/qCVz5yh4ImeKyvzOph7
+LrF3s4gScWNTv7HfHt7aE+i91DDswsTn+QoxsrReNpqQdO9qReV385eLaIFDBbzl
+B6Yvm7HAWUOsKLs2bJgCcsR3OwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCqc1HG
+xJuOLaEECBn5xVhiWFXIcZxLrwHNxjRtAjbYNA17a+ZB9utsvqVChan9OO6jIbqw
+l+bxji+OaKyHlLuQjOW3AgSidTXfG+pR7N+F+59GogNb8AKScvCm08fVhHg6wneC
+6+3gWTfH9m4sNDpOPHrycZJRgRt3CydnzTOmWajIwzjNreNIu/3kkkrlc5MVGsn9
+lOsRa81F3QSS2rvoUx1ldhPqqTrie/emZvcC+9R6rC9yMmYOtZegENIOMfzlOnR5
+vMyXhTGF84mP9XpmU+t3mFHDP+0pt+a8MIOyqrCCmFAyoUzaHm+oyElR9WvEFRjm
+MjPWMfYNYvbS296t
+-----END CERTIFICATE-----
diff --git a/net/data/ssl/scripts/ee.cnf b/net/data/ssl/scripts/ee.cnf
index 5bf4e46..6ccf83e 100644
--- a/net/data/ssl/scripts/ee.cnf
+++ b/net/data/ssl/scripts/ee.cnf
@@ -32,6 +32,20 @@
O = Test CA
CN = localhost
+[req_self_signed_a]
+C = US
+ST = Michigan
+L = Ann Arbor
+O = Test Self-Signed
+CN = SS A
+
+[req_self_signed_b]
+C = US
+ST = Michigan
+L = Ann Arbor
+O = Test Self-Signed
+CN = SS B
+
[req_punycode_dn]
CN = xn--wgv71a119e.com
diff --git a/net/data/ssl/scripts/generate-bad-self-signed.sh b/net/data/ssl/scripts/generate-bad-self-signed.sh
new file mode 100755
index 0000000..175553c
--- /dev/null
+++ b/net/data/ssl/scripts/generate-bad-self-signed.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+
+# Copyright 2016 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 script generates self-signed-invalid-name.pem and
+# self-signed-invalid-sig.pem, which are "self-signed" test certificates with
+# invalid names/signatures, respectively.
+set -e
+
+ rm -rf out
+ mkdir out
+
+openssl genrsa -out out/bad-self-signed.key 2048
+touch out/bad-self-signed-index.txt
+
+# Create two certificate requests with the same key, but different subjects
+SUBJECT_NAME="req_self_signed_a" \
+openssl req \
+ -new \
+ -key out/bad-self-signed.key \
+ -out out/ss-a.req \
+ -config ee.cnf
+
+SUBJECT_NAME="req_self_signed_b" \
+openssl req \
+ -new \
+ -key out/bad-self-signed.key \
+ -out out/ss-b.req \
+ -config ee.cnf
+
+# Create a normal self-signed certificate from one of these requests
+openssl x509 \
+ -req \
+ -in out/ss-a.req \
+ -out out/bad-self-signed-root-a.pem \
+ -signkey out/bad-self-signed.key \
+ -days 3650
+
+# To invalidate the signature without changing names, replace two bytes from the
+# end of the certificate with 0xdead.
+openssl x509 -in out/bad-self-signed-root-a.pem -outform DER \
+ | head -c -2 \
+ > out/bad-sig.der.1
+echo -n -e "\xde\xad" > out/bad-sig.der.2
+cat out/bad-sig.der.1 out/bad-sig.der.2 \
+ | openssl x509 \
+ -inform DER \
+ -outform PEM \
+ -out out/cert-self-signed-invalid-sig.pem
+
+openssl x509 \
+ -text \
+ -noout \
+ -in out/cert-self-signed-invalid-sig.pem \
+ > out/self-signed-invalid-sig.pem
+cat out/cert-self-signed-invalid-sig.pem >> out/self-signed-invalid-sig.pem
+
+# Make a "self-signed" certificate with mismatched names
+openssl x509 \
+ -req \
+ -in out/ss-b.req \
+ -out out/cert-self-signed-invalid-name.pem \
+ -days 3650 \
+ -CA out/bad-self-signed-root-a.pem \
+ -CAkey out/bad-self-signed.key \
+ -CAserial out/bad-self-signed-serial.txt \
+ -CAcreateserial
+
+openssl x509 \
+ -text \
+ -noout \
+ -in out/cert-self-signed-invalid-name.pem \
+ > out/self-signed-invalid-name.pem
+cat out/cert-self-signed-invalid-name.pem >> out/self-signed-invalid-name.pem
+
diff --git a/net/net.gypi b/net/net.gypi
index ae74414..25a1756 100644
--- a/net/net.gypi
+++ b/net/net.gypi
@@ -2122,6 +2122,8 @@
'data/ssl/certificates/reject_intranet_hosts.pem',
'data/ssl/certificates/root_ca_cert.pem',
'data/ssl/certificates/salesforce_com_test.pem',
+ 'data/ssl/certificates/self-signed-invalid-name.pem',
+ 'data/ssl/certificates/self-signed-invalid-sig.pem',
'data/ssl/certificates/sha1_2016.pem',
'data/ssl/certificates/sha1_dec_2015.pem',
'data/ssl/certificates/sha1_jan_2016.pem',