0

Fix client certificate authentication on Mac and Linux introduced in r178732

When requesting client authentication, the SSL server may send a list of
acceptable CAs. When discovering matching client certificates, the Mac and
Linux implementations were not fully considering all intermediate certificates
when attempting to discover client certificates.

For example, if the client certficate chain was CC -> Intermediate -> Root, and
the server sent a list of acceptable CAs as Root, then on Mac and Linux, CC
would not be considered, whereas on Windows it would. Further, if the server
listed Intermediate as an acceptable CA, then it would work on all platforms.

BUG=224280, 224897
TEST=See https://docs.google.com/a/chromium.org/document/d/19V5_PBSm7OaFLXzTXdiCdSpt1r1yFYJhuH9X41O2oOs/edit?usp=sharing
R=wtc@chromium.org

Review URL: https://chromiumcodereview.appspot.com/13866049

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196535 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
rsleevi@chromium.org
2013-04-25 23:25:48 +00:00
parent cfa6f4e66a
commit b5c40cd46e
20 changed files with 673 additions and 517 deletions

@ -11,7 +11,6 @@ namespace base {
class Lock;
}
namespace crypto {
// The Mac OS X certificate and key management wrappers over CSSM are not

@ -279,9 +279,6 @@ class NET_EXPORT X509Certificate
// Does this certificate's usage allow SSL client authentication?
bool SupportsSSLClientAuth() const;
// Creates the chain of certs to use for this client identity cert.
CFArrayRef CreateClientCertificateChain() const;
// Returns a new CFArrayRef containing this certificate and its intermediate
// certificates in the form expected by Security.framework and Keychain
// Services, or NULL on failure.

@ -113,53 +113,6 @@ std::string GetCertSerialNumber(
serial_number.field()->Length);
}
// Gets the issuer for a given cert, starting with the cert itself and
// including the intermediate and finally root certificates (if any).
// This function calls SecTrust but doesn't actually pay attention to the trust
// result: it shouldn't be used to determine trust, just to traverse the chain.
// Caller is responsible for releasing the value stored into *out_cert_chain.
OSStatus CopyCertChain(SecCertificateRef cert_handle,
CFArrayRef* out_cert_chain) {
DCHECK(cert_handle);
DCHECK(out_cert_chain);
// Create an SSL policy ref configured for client cert evaluation.
SecPolicyRef ssl_policy;
OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy);
if (result)
return result;
ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
// Create a SecTrustRef.
ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
1, &kCFTypeArrayCallBacks));
SecTrustRef trust_ref = NULL;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustCreateWithCertificates(input_certs, ssl_policy,
&trust_ref);
}
if (result)
return result;
ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
// Evaluate trust, which creates the cert chain.
SecTrustResultType status;
CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustEvaluate(trust, &status);
}
if (result)
return result;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
}
return result;
}
// Returns true if |purpose| is listed as allowed in |usage|. This
// function also considers the "Any" purpose. If the attribute is
// present and empty, we return false.
@ -712,43 +665,6 @@ bool X509Certificate::SupportsSSLClientAuth() const {
return true;
}
CFArrayRef X509Certificate::CreateClientCertificateChain() const {
// Initialize the result array with just the IdentityRef of the receiver:
SecIdentityRef identity;
OSStatus result;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity);
}
if (result) {
OSSTATUS_LOG(ERROR, result) << "SecIdentityCreateWithCertificate error";
return NULL;
}
ScopedCFTypeRef<CFMutableArrayRef> chain(
CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
CFArrayAppendValue(chain, identity);
CFArrayRef cert_chain = NULL;
result = CopyCertChain(cert_handle_, &cert_chain);
ScopedCFTypeRef<CFArrayRef> scoped_cert_chain(cert_chain);
if (result) {
OSSTATUS_LOG(ERROR, result) << "CreateIdentityCertificateChain error";
return chain.release();
}
// Append the intermediate certs from SecTrust to the result array:
if (cert_chain) {
int chain_count = CFArrayGetCount(cert_chain);
if (chain_count > 1) {
CFArrayAppendArray(chain,
cert_chain,
CFRangeMake(1, chain_count - 1));
}
}
return chain.release();
}
CFArrayRef X509Certificate::CreateOSCertChainForCert() const {
CFMutableArrayRef cert_list =
CFArrayCreateMutable(kCFAllocatorDefault, 0,

@ -148,19 +148,19 @@ unit tests.
- client_1.pem
- client_1.key
- client_1_root.pem
- client_1_ca.pem
- client_2.pem
- client_2.key
- client_2_root.pem
This is a set of files used to unit test SSL client authentication.
Generated by net/data/ssl/scripts/generate-client-certificates.sh.
Unit test is in net/socket/ssl_client_socket_openssl_unittest.cc.
- client_1_root.pem and client_2_root.pem are the certificates of
- client_2_ca.pem
This is a set of files used to unit test SSL client certificate
authentication. These are generated by
net/data/ssl/scripts/generate-client-certificates.sh
- client_1_ca.pem and client_2_ca.pem are the certificates of
two distinct signing CAs.
- client_1.pem and client_1.key correspond to the certificate and
private key for a first certificate signed by client_1_root.pem.
private key for a first certificate signed by client_1_ca.pem.
- client_2.pem and client_2.key correspond to the certificate and
private key for a second certificate signed by client_2_root.pem.
private key for a second certificate signed by client_2_ca.pem.
- eku-test-root.pem
- non-crit-codeSigning-chain.pem

@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

@ -1,66 +1,72 @@
Certificate:
Data:
Version: 1 (0x0)
Version: 3 (0x2)
Serial Number: 236 (0xec)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Client Auth Test Root 1
Issuer: CN=B CA
Validity
Not Before: Feb 12 23:44:58 2013 GMT
Not After : Feb 10 23:44:58 2023 GMT
Subject: CN=Test Client
Not Before: Apr 22 21:58:52 2013 GMT
Not After : Apr 20 21:58:52 2023 GMT
Subject: CN=Client Cert A
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c1:8c:b0:6b:58:ac:cd:62:4a:f5:d3:03:c4:61:
b0:be:2c:7a:58:2c:58:d7:88:34:06:a0:14:d5:ae:
17:83:24:3a:e2:51:1d:73:0a:df:8b:a5:f2:fa:aa:
82:5d:78:dd:9d:d5:73:7c:04:55:a5:72:14:a6:ac:
ff:ce:e8:ef:92:bf:b8:98:31:13:c9:96:ad:10:d4:
f0:56:a9:09:7f:18:cd:bb:52:6c:00:58:b7:b4:e5:
c7:ec:8e:44:90:90:5c:a3:a6:bb:dd:8f:26:ad:7d:
33:67:e1:6a:ad:a1:bf:96:2c:84:9d:57:1b:b2:23:
ae:11:b8:f0:34:9a:5d:c7:b6:88:3f:ac:4f:ed:dc:
4e:94:f5:de:0a:27:92:52:8e:77:ac:9a:4f:8b:d1:
d6:ca:b1:6d:11:55:83:cc:2b:03:7f:e5:48:1f:44:
b2:30:dd:7a:a9:15:25:b4:c4:fc:1d:b4:1d:a0:31:
9f:05:f9:67:04:35:05:7f:5d:d0:69:44:87:fa:be:
5e:fb:5a:6a:aa:9a:32:f0:e7:8a:27:b0:8e:b7:be:
5e:a1:7d:5b:ab:35:2b:8e:9a:ec:0b:b0:2a:2a:b2:
63:c1:91:c9:b5:f9:0a:2a:d7:f6:c2:c9:cb:44:e6:
22:bd:aa:23:c4:cb:13:0f:57:8a:62:03:9f:7e:77:
29:99
00:bc:0f:a8:25:12:13:d8:e1:74:f4:fe:7e:0c:bf:
9f:e2:be:5d:f7:88:44:a2:e6:4f:8f:67:81:43:64:
b7:6d:bd:12:79:e6:0e:d8:07:ae:0f:f4:1f:76:00:
9c:86:b0:70:54:02:ba:a9:c5:05:2f:29:19:c9:4b:
06:bc:65:40:b6:1d:1e:c5:44:91:f0:d6:d2:86:c3:
f7:4e:73:b2:92:77:25:ca:4f:d5:9c:2b:a6:2c:f9:
f8:f7:fd:1e:1e:bc:d4:db:1e:99:c7:7c:52:cd:be:
7c:d3:ee:c7:39:b8:6a:88:d0:24:26:ea:0d:bb:ed:
c0:2e:fb:71:df:5d:12:55:1d:36:f8:74:55:2e:33:
1a:68:c3:26:fa:87:7b:d6:80:20:45:10:cd:ab:77:
f4:b2:3a:6b:2e:a1:7f:7c:a9:17:c1:47:51:b3:e6:
3d:67:68:90:df:d8:37:74:2d:02:11:d2:d0:64:96:
f4:06:85:23:07:14:55:50:7a:8b:32:26:0f:17:be:
9a:53:e1:03:c0:e8:27:ff:06:96:74:5d:29:0c:ab:
21:f5:ae:22:3c:2f:27:b8:3b:b6:c5:ba:41:58:8e:
e8:5f:ba:56:97:08:36:27:da:a6:f0:cc:27:11:52:
fb:9b:e5:92:aa:3d:f1:62:3e:ae:bb:b8:09:52:e6:
e5:d3
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
83:b6:a5:c8:3b:50:23:b5:71:6d:f2:03:62:74:df:3c:ad:ab:
34:76:e8:b4:c2:7c:3d:53:5e:82:95:b3:99:a1:4d:9f:8d:cd:
ad:13:d5:70:14:84:72:83:59:0f:d4:5e:44:85:a9:3d:d7:a9:
18:39:fe:da:42:54:27:be:ab:99:8f:f0:d2:f4:50:e2:06:eb:
53:e7:4a:a1:92:e5:65:50:60:e6:c4:5b:c1:21:83:55:a1:ae:
74:53:96:41:89:19:c0:98:98:be:44:a2:38:01:65:86:8a:82:
3d:7d:26:ad:82:0f:e6:cd:c4:1d:3a:ec:47:08:a9:0f:6c:92:
da:e1:14:33:22:f8:85:6f:91:e3:5d:c2:33:73:09:07:70:fc:
e5:ee:be:79:98:9c:65:5d:dc:d9:36:53:6a:21:3e:4a:58:b8:
c4:ac:b3:44:36:e3:90:5c:e4:91:b7:7a:cd:a8:57:64:c3:5c:
fe:7a:e0:4d:e7:c5:b6:86:84:6c:11:73:6b:31:66:62:9f:26:
d3:b6:00:df:66:ec:0e:6b:57:6e:39:9c:e9:a2:55:a9:74:f1:
75:b7:7c:f6:c1:f5:d3:26:bf:8a:9e:c5:bd:23:06:8e:b9:f7:
09:85:2f:62:14:cc:95:3a:5b:e4:06:26:07:b7:94:cd:fa:c8:
13:48:41:38
a5:ec:14:84:d5:27:71:38:e7:f1:5f:38:7f:96:0f:a7:5d:ad:
9d:bf:5d:f9:eb:66:d5:61:ea:5b:d5:c9:3e:73:a1:62:8a:a5:
25:60:8f:90:fb:9f:38:2d:1d:42:ec:e7:db:f5:34:fc:4a:57:
19:eb:29:83:ae:a4:8f:94:2c:9d:c0:dd:df:6c:29:d8:c9:9f:
ec:07:e7:18:80:8e:3b:92:0a:f1:2e:e7:1f:0b:d5:b7:b9:d9:
a9:39:cf:46:a3:7a:ec:95:7f:4d:0a:99:ba:e8:ca:a9:4e:ea:
48:b9:e3:21:ad:6e:20:8d:db:c5:7d:9d:94:69:f0:d0:8e:b3:
32:39:67:42:7c:22:e4:25:a5:d3:51:0e:65:89:52:90:63:b4:
bf:c5:8e:2c:79:cc:c5:b7:e5:00:98:5b:f8:f6:01:b1:83:cb:
ee:a2:cb:ba:4f:c4:a6:8b:1f:fa:fa:4f:43:b7:e9:75:54:43:
1b:e0:3d:d5:9b:15:6d:3d:c2:31:9f:42:10:be:9f:a1:67:0b:
f5:4b:ad:a4:8b:cb:ca:3f:be:ad:16:c8:6f:7a:42:33:71:39:
22:a1:ee:7b:d0:3f:fb:1c:c6:bf:90:17:18:0d:0f:00:18:15:
4f:2f:4f:7b:fb:26:05:05:e5:de:29:5e:ad:09:55:e6:d6:c5:
de:27:a6:6c
-----BEGIN CERTIFICATE-----
MIICrTCCAZUCAgDsMA0GCSqGSIb3DQEBBQUAMCIxIDAeBgNVBAMMF0NsaWVudCBB
dXRoIFRlc3QgUm9vdCAxMB4XDTEzMDIxMjIzNDQ1OFoXDTIzMDIxMDIzNDQ1OFow
FjEUMBIGA1UEAwwLVGVzdCBDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDBjLBrWKzNYkr10wPEYbC+LHpYLFjXiDQGoBTVrheDJDriUR1zCt+L
pfL6qoJdeN2d1XN8BFWlchSmrP/O6O+Sv7iYMRPJlq0Q1PBWqQl/GM27UmwAWLe0
5cfsjkSQkFyjprvdjyatfTNn4Wqtob+WLISdVxuyI64RuPA0ml3Htog/rE/t3E6U
9d4KJ5JSjnesmk+L0dbKsW0RVYPMKwN/5UgfRLIw3XqpFSW0xPwdtB2gMZ8F+WcE
NQV/XdBpRIf6vl77WmqqmjLw54onsI63vl6hfVurNSuOmuwLsCoqsmPBkcm1+Qoq
1/bCyctE5iK9qiPEyxMPV4piA59+dymZAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB
AIO2pcg7UCO1cW3yA2J03zytqzR26LTCfD1TXoKVs5mhTZ+Nza0T1XAUhHKDWQ/U
XkSFqT3XqRg5/tpCVCe+q5mP8NL0UOIG61PnSqGS5WVQYObEW8Ehg1WhrnRTlkGJ
GcCYmL5EojgBZYaKgj19Jq2CD+bNxB067EcIqQ9sktrhFDMi+IVvkeNdwjNzCQdw
/OXuvnmYnGVd3Nk2U2ohPkpYuMSss0Q245Bc5JG3es2oV2TDXP564E3nxbaGhGwR
c2sxZmKfJtO2AN9m7A5rV245nOmiVal08XW3fPbB9dMmv4qexb0jBo659wmFL2IU
zJU6W+QGJge3lM36yBNIQTg=
MIIC0jCCAbqgAwIBAgICAOwwDQYJKoZIhvcNAQEFBQAwDzENMAsGA1UEAwwEQiBD
QTAeFw0xMzA0MjIyMTU4NTJaFw0yMzA0MjAyMTU4NTJaMBgxFjAUBgNVBAMMDUNs
aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8D6gl
EhPY4XT0/n4Mv5/ivl33iESi5k+PZ4FDZLdtvRJ55g7YB64P9B92AJyGsHBUArqp
xQUvKRnJSwa8ZUC2HR7FRJHw1tKGw/dOc7KSdyXKT9WcK6Ys+fj3/R4evNTbHpnH
fFLNvnzT7sc5uGqI0CQm6g277cAu+3HfXRJVHTb4dFUuMxpowyb6h3vWgCBFEM2r
d/SyOmsuoX98qRfBR1Gz5j1naJDf2Dd0LQIR0tBklvQGhSMHFFVQeosyJg8XvppT
4QPA6Cf/BpZ0XSkMqyH1riI8Lye4O7bFukFYjuhfulaXCDYn2qbwzCcRUvub5ZKq
PfFiPq67uAlS5uXTAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQCl7BSE1SdxOOfx
Xzh/lg+nXa2dv13562bVYepb1ck+c6FiiqUlYI+Q+584LR1C7Ofb9TT8SlcZ6ymD
rqSPlCydwN3fbCnYyZ/sB+cYgI47kgrxLucfC9W3udmpOc9Go3rslX9NCpm66Mqp
TupIueMhrW4gjdvFfZ2UafDQjrMyOWdCfCLkJaXTUQ5liVKQY7S/xY4seczFt+UA
mFv49gGxg8vuosu6T8Smix/6+k9Dt+l1VEMb4D3VmxVtPcIxn0IQvp+hZwv1S62k
i8vKP76tFshvekIzcTkioe570D/7HMa/kBcYDQ8AGBVPL097+yYFBeXeKV6tCVXm
1sXeJ6Zs
-----END CERTIFICATE-----

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 236 (0xec)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=C Root CA
Validity
Not Before: Apr 22 21:58:52 2013 GMT
Not After : Apr 20 21:58:52 2023 GMT
Subject: CN=B CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ca:2b:37:8c:21:be:73:36:40:67:43:2a:89:9c:
3f:43:88:8b:34:8e:3e:34:cd:ee:32:5e:f2:a2:22:
f8:d9:7f:c6:96:b7:e1:52:7f:91:3e:81:4a:a9:35:
63:03:d7:3c:38:c5:0d:b8:a6:b0:be:b0:c5:b8:b9:
6c:34:fc:f2:9a:25:7c:37:cf:04:e6:c4:9b:00:5a:
b2:d3:9e:6c:85:97:92:0a:44:08:8d:32:2b:9b:50:
9a:e4:bd:61:db:49:d7:40:6b:72:15:6a:a3:75:52:
31:65:44:e0:bd:c1:bf:6e:b6:71:71:29:fd:98:67:
b9:62:62:d9:7b:a7:cb:4f:93:70:f9:1c:2c:83:42:
2a:dc:4b:e8:2d:51:3c:ef:f0:4b:a3:2b:db:7f:6d:
73:11:21:55:33:90:7c:94:29:2a:8c:3a:7b:22:b3:
9e:30:16:d1:41:64:7c:4d:83:79:5f:8f:c4:ec:21:
e4:0c:14:95:1e:ec:d7:d0:f7:d7:44:f5:93:48:01:
bf:e9:99:06:7e:2e:d4:e9:87:88:3f:46:f1:7c:c3:
07:5a:8b:b7:16:72:dc:35:d4:69:e3:33:68:45:79:
1a:35:26:37:08:4e:12:57:02:34:24:45:ec:2f:19:
ab:d5:7a:b6:20:db:93:0a:0d:f4:77:1d:27:15:37:
54:2b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha1WithRSAEncryption
93:c0:c7:af:77:e2:52:21:1f:59:b4:d1:df:d7:43:cc:31:73:
2b:76:3a:d9:ec:e0:ab:1d:e0:8d:7f:e4:16:2d:06:40:d1:c1:
97:be:65:d0:e6:4b:c3:a3:6a:e9:0c:5b:86:f6:49:eb:e2:f0:
07:95:ee:37:7f:10:df:ce:2f:5b:4e:70:24:5b:47:1f:f5:d8:
8e:0a:7c:4d:54:e2:e6:a7:0a:15:c6:16:a4:0f:79:03:22:a3:
76:23:6d:e6:1e:ce:81:84:39:ec:b8:f7:e8:0a:a2:1f:93:fa:
60:92:df:35:c2:23:0d:5c:74:70:74:46:fc:b4:47:83:81:ee:
a6:c7:03:90:26:78:84:1f:3d:c4:39:16:a1:f0:aa:13:9a:be:
6b:2d:ad:3f:5d:e2:57:45:60:6b:56:2a:e3:00:50:29:bb:41:
87:ba:c8:21:82:dd:57:68:4f:cd:ea:11:2a:9a:93:c7:c3:af:
2f:fb:0d:a5:40:59:2a:22:ac:df:98:3d:2a:ea:1e:c5:e8:03:
c6:0d:b4:2d:10:c6:a0:b5:e8:61:fd:b7:07:82:54:80:68:21:
05:db:d4:d7:1f:5f:62:93:21:a2:cd:b8:08:f0:06:86:04:93:
aa:b2:a3:64:4c:2f:47:78:0e:b1:a2:1c:b1:50:72:f4:86:cc:
07:2a:a6:cb
-----BEGIN CERTIFICATE-----
MIICwjCCAaqgAwIBAgICAOwwDQYJKoZIhvcNAQEFBQAwFDESMBAGA1UEAwwJQyBS
b290IENBMB4XDTEzMDQyMjIxNTg1MloXDTIzMDQyMDIxNTg1MlowDzENMAsGA1UE
AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMorN4whvnM2
QGdDKomcP0OIizSOPjTN7jJe8qIi+Nl/xpa34VJ/kT6BSqk1YwPXPDjFDbimsL6w
xbi5bDT88polfDfPBObEmwBastOebIWXkgpECI0yK5tQmuS9YdtJ10BrchVqo3VS
MWVE4L3Bv262cXEp/ZhnuWJi2Xuny0+TcPkcLINCKtxL6C1RPO/wS6Mr239tcxEh
VTOQfJQpKow6eyKznjAW0UFkfE2DeV+PxOwh5AwUlR7s19D310T1k0gBv+mZBn4u
1OmHiD9G8XzDB1qLtxZy3DXUaeMzaEV5GjUmNwhOElcCNCRF7C8Zq9V6tiDbkwoN
9HcdJxU3VCsCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwDQYJKoZIhvcNAQEFBQADggEBAJPAx6934lIhH1m00d/XQ8wxcyt2Otns4Ksd
4I1/5BYtBkDRwZe+ZdDmS8OjaukMW4b2Sevi8AeV7jd/EN/OL1tOcCRbRx/12I4K
fE1U4uanChXGFqQPeQMio3YjbeYezoGEOey49+gKoh+T+mCS3zXCIw1cdHB0Rvy0
R4OB7qbHA5AmeIQfPcQ5FqHwqhOavmstrT9d4ldFYGtWKuMAUCm7QYe6yCGC3Vdo
T83qESqak8fDry/7DaVAWSoirN+YPSrqHsXoA8YNtC0QxqC16GH9tweCVIBoIQXb
1NcfX2KTIaLNuAjwBoYEk6qyo2RML0d4DrGiHLFQcvSGzAcqpss=
-----END CERTIFICATE-----

@ -1,66 +0,0 @@
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 12799194924381938615 (0xb19fdff87ec4a3b7)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Client Auth Test Root 1
Validity
Not Before: Feb 12 23:44:58 2013 GMT
Not After : Feb 10 23:44:58 2023 GMT
Subject: CN=Client Auth Test Root 1
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d7:8f:ad:85:e4:36:c4:16:e2:59:65:e3:ba:9b:
60:da:8b:94:33:48:3a:5b:ab:80:00:92:20:08:26:
0d:4a:1f:d8:62:37:0d:42:8a:a5:ab:e6:c8:f6:5a:
83:42:62:0f:65:56:01:22:54:43:92:73:76:f8:18:
45:6d:a1:b0:80:a5:55:1e:75:c2:2c:1b:a0:68:3a:
43:57:88:e0:25:85:ff:42:a2:e0:61:17:23:fd:0d:
81:42:b9:43:21:65:66:de:42:73:eb:04:45:f3:64:
ce:f5:4c:e7:e6:a9:0c:ad:22:e6:03:20:e8:25:b6:
65:f9:b5:70:4a:10:98:db:38:d0:e9:1b:11:64:e0:
fa:71:46:c0:79:33:2a:81:5a:76:e7:4f:ca:14:79:
f6:a7:95:59:bd:c8:e0:85:79:95:59:bd:f0:38:bd:
f1:5a:d4:5c:f9:fb:46:73:aa:f8:51:51:0b:e1:3a:
23:93:21:80:85:fc:61:22:dc:ac:18:a1:e2:36:62:
41:ec:04:67:19:82:0f:8c:bb:a6:6c:43:6b:da:58:
16:76:dd:ec:89:4b:0e:ec:89:74:5d:2c:b2:b1:7f:
5b:57:d3:08:84:97:dc:d5:bd:0c:9e:8c:02:df:90:
21:e6:cf:02:ba:bc:fd:84:fc:77:8a:5a:a4:2c:91:
15:81
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
bf:8b:7e:39:b1:07:8e:95:47:59:e6:9e:04:5f:2b:e6:c0:c9:
73:a2:be:8f:f7:35:8f:bc:15:53:27:15:19:1d:a4:ca:e2:6c:
cc:33:fb:d5:21:a3:40:6f:22:79:1a:20:0f:e7:3a:ab:76:05:
cd:20:f1:9a:bc:a1:5e:0c:2a:63:20:5a:72:db:e8:62:ee:ba:
d4:2a:90:61:b5:57:5f:a9:43:b5:cd:71:69:c5:d6:40:40:43:
ff:b4:bf:8f:5b:b8:44:3d:c6:14:2a:17:f5:62:44:32:a0:99:
a4:92:94:5a:41:14:b2:ff:26:91:c2:9f:12:33:fc:f6:44:63:
c6:2f:dc:d6:0f:c5:c3:03:32:f9:8d:8a:49:8f:c0:27:d1:7c:
61:b7:2b:22:03:9d:8e:b5:45:f4:94:a3:8a:be:06:af:d3:1c:
1b:11:8e:e7:1b:38:89:70:5d:4a:1e:16:76:23:b4:d0:d1:ae:
76:62:14:31:99:32:7a:9f:ef:fa:26:05:19:bb:76:b9:92:7d:
2f:1f:f7:1f:19:6f:ad:42:c2:52:fb:3d:b5:4a:4e:15:d9:8a:
07:82:98:fe:5a:88:16:68:62:79:eb:48:27:aa:b6:0a:21:08:
d4:f6:85:9b:5e:8b:4b:34:c5:88:0c:a3:dd:d2:7d:d4:d5:0d:
a7:75:e2:77
-----BEGIN CERTIFICATE-----
MIICwDCCAagCCQCxn9/4fsSjtzANBgkqhkiG9w0BAQUFADAiMSAwHgYDVQQDDBdD
bGllbnQgQXV0aCBUZXN0IFJvb3QgMTAeFw0xMzAyMTIyMzQ0NThaFw0yMzAyMTAy
MzQ0NThaMCIxIDAeBgNVBAMMF0NsaWVudCBBdXRoIFRlc3QgUm9vdCAxMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA14+theQ2xBbiWWXjuptg2ouUM0g6
W6uAAJIgCCYNSh/YYjcNQoqlq+bI9lqDQmIPZVYBIlRDknN2+BhFbaGwgKVVHnXC
LBugaDpDV4jgJYX/QqLgYRcj/Q2BQrlDIWVm3kJz6wRF82TO9Uzn5qkMrSLmAyDo
JbZl+bVwShCY2zjQ6RsRZOD6cUbAeTMqgVp250/KFHn2p5VZvcjghXmVWb3wOL3x
WtRc+ftGc6r4UVEL4TojkyGAhfxhItysGKHiNmJB7ARnGYIPjLumbENr2lgWdt3s
iUsO7Il0XSyysX9bV9MIhJfc1b0MnowC35Ah5s8Curz9hPx3ilqkLJEVgQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4IBAQC/i345sQeOlUdZ5p4EXyvmwMlzor6P9zWPvBVT
JxUZHaTK4mzMM/vVIaNAbyJ5GiAP5zqrdgXNIPGavKFeDCpjIFpy2+hi7rrUKpBh
tVdfqUO1zXFpxdZAQEP/tL+PW7hEPcYUKhf1YkQyoJmkkpRaQRSy/yaRwp8SM/z2
RGPGL9zWD8XDAzL5jYpJj8An0XxhtysiA52OtUX0lKOKvgav0xwbEY7nGziJcF1K
HhZ2I7TQ0a52YhQxmTJ6n+/6JgUZu3a5kn0vH/cfGW+tQsJS+z21Sk4V2YoHgpj+
WogWaGJ560gnqrYKIQjU9oWbXotLNMWIDKPd0n3U1Q2ndeJ3
-----END CERTIFICATE-----

@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

@ -1,66 +1,72 @@
Certificate:
Data:
Version: 1 (0x0)
Version: 3 (0x2)
Serial Number: 236 (0xec)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Client Auth Test Root 2
Issuer: CN=E CA
Validity
Not Before: Feb 12 23:44:58 2013 GMT
Not After : Feb 10 23:44:58 2023 GMT
Subject: CN=Test Client
Not Before: Apr 22 21:58:52 2013 GMT
Not After : Apr 20 21:58:52 2023 GMT
Subject: CN=Client Cert D
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ee:f6:0f:20:45:c1:9b:3b:04:ab:14:82:cf:95:
a6:44:13:b3:f8:c7:d7:49:1b:68:70:11:e1:00:f1:
7a:b4:68:52:21:e2:ab:5e:15:fc:f7:95:18:1e:85:
88:c1:56:d1:9f:87:f1:68:c4:e0:f8:da:89:4a:7f:
70:cd:15:d2:e2:d3:12:cb:dd:5c:eb:48:02:90:cd:
4d:fd:bf:b1:61:62:be:5b:cf:bf:21:29:bb:8f:31:
20:92:92:90:55:fc:85:57:d3:cc:50:3f:1e:51:d3:
be:d6:48:31:97:a7:0d:e6:43:cb:5d:b8:eb:f5:bb:
0a:72:2c:88:37:fc:43:e3:2d:a4:c5:bc:05:bc:ef:
80:a6:b5:c1:47:fa:f4:d6:80:60:c3:3b:f6:f3:44:
31:83:8b:2e:58:32:66:32:74:85:e2:fa:dd:73:c3:
be:73:c9:61:c0:df:29:a7:15:ed:b0:16:0c:f1:4e:
b5:b6:62:a7:34:e0:4a:1f:e5:43:69:44:49:3c:8e:
48:31:aa:88:f0:5f:5d:bb:49:05:d9:a7:1b:77:c8:
9a:64:09:c2:5a:fe:bf:72:6a:fd:d7:a0:de:d7:09:
7f:d9:c1:95:02:8b:9c:30:e1:9a:69:95:15:59:0d:
09:bf:cf:5e:ee:54:76:1d:4e:d7:4b:8c:44:94:a1:
b3:21
00:bd:20:09:c4:a0:49:8b:69:a7:4a:a6:08:93:15:
4b:64:75:33:fd:60:e8:8a:02:6e:15:4f:79:0b:33:
a5:4f:7b:93:b5:a9:94:70:15:77:5a:3f:a3:f0:51:
4e:6e:fb:4e:c1:a1:aa:36:1c:c4:23:f0:75:94:be:
f9:34:c6:08:1c:0e:61:44:72:e0:20:73:23:da:b0:
d7:00:8a:d2:37:4f:f3:40:a6:9e:bc:09:18:e2:50:
ea:00:62:16:26:2a:6e:e9:1e:c8:99:77:9d:98:33:
02:19:1e:89:34:13:79:cc:5d:4a:b9:10:41:ae:53:
8a:c8:61:4c:30:6c:7f:fc:3e:8a:bc:49:ea:05:77:
46:11:10:03:b6:8d:6c:cc:19:63:2d:85:7f:97:d2:
92:06:28:d4:f7:4e:74:80:c3:a7:ca:49:1a:a6:17:
81:ed:ed:8e:95:97:73:af:c9:ef:04:2a:de:c4:9a:
62:e5:f7:d4:dc:02:4f:b7:2e:a8:44:e3:31:b9:9b:
e0:fc:3b:cd:ea:ff:cf:5a:c4:4c:fa:7f:32:1e:8c:
5e:83:8d:db:28:65:39:32:72:15:0f:82:3c:e8:fe:
90:d3:90:61:bf:39:ab:fd:aa:5e:1e:26:15:71:c5:
f4:10:77:6a:85:47:f9:e9:6d:90:a9:3b:a5:d8:c6:
9b:f5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
b0:63:fb:bd:38:67:07:1f:3c:f1:37:ba:e6:06:2c:d1:11:97:
34:e8:47:48:8e:23:df:3f:14:14:ad:b7:07:f2:88:ef:36:fc:
aa:56:af:ec:65:c1:6a:d8:1c:3f:d6:7d:25:ed:ab:2a:4f:cb:
72:21:94:a4:6c:30:f5:03:af:46:d7:ef:d1:fc:66:23:db:06:
e7:8c:4b:ce:50:7a:c6:e2:35:67:d3:f3:5a:83:19:4a:bf:f5:
a9:49:c8:d5:b4:0a:9a:fc:d4:c2:24:40:0e:d5:70:09:45:12:
5f:44:be:1c:e1:41:39:e7:d9:bb:a4:d9:2a:7f:08:22:7e:fc:
fd:b9:61:73:d0:7f:e7:e6:2b:15:15:fc:2a:46:2e:db:9f:9a:
56:b3:a8:d8:08:d6:ba:a8:ae:fb:1f:44:51:cd:a8:e8:4e:71:
fd:04:fe:50:32:fb:79:a2:d3:6b:8a:6c:41:c7:f8:b2:69:e0:
b0:86:e6:7c:be:a0:0e:44:7a:4d:e0:33:f3:9f:7d:e4:6f:eb:
54:2c:98:d8:81:3c:dd:74:5b:dd:5f:80:b5:c7:06:f4:62:ef:
a4:66:c8:cd:94:e6:a8:28:2a:31:50:2f:9d:6b:7a:17:2b:47:
13:f0:1b:66:66:50:d8:eb:08:6b:d9:53:39:16:48:8f:fb:9c:
03:e7:a9:58
05:33:9d:86:a9:81:49:a9:5c:57:41:67:30:2a:b3:92:d5:96:
f4:fc:4f:9a:ad:2a:18:f9:66:7e:e8:3a:ac:ef:6c:42:53:60:
1b:99:cc:aa:bd:78:ef:d7:d7:d1:52:04:3f:c6:d5:ea:ec:51:
d1:88:1f:ad:05:a7:16:12:2c:f9:7f:79:0f:10:70:de:a6:d1:
62:93:68:57:5d:a0:bd:95:0f:ba:82:37:66:77:d6:48:1f:ab:
10:aa:bd:1d:46:9c:23:d6:fa:2f:c2:3d:38:8e:84:7e:7a:62:
f5:6f:6d:c3:68:95:6f:4f:99:ec:2c:d6:6c:22:aa:a3:0a:d0:
09:d8:0f:19:5f:75:5d:65:6e:31:76:f9:b9:43:6b:f6:fa:22:
70:ff:c0:fa:03:f6:22:89:5c:69:9d:9b:fb:f8:a0:e8:76:66:
64:32:db:51:23:fb:58:e0:67:68:24:15:58:81:78:c3:80:7e:
79:d7:1e:5e:bf:9c:82:04:cf:c8:34:6a:c7:1e:75:92:0d:45:
d5:83:a3:5b:e7:3f:49:ed:7e:a0:f7:8b:6c:45:45:4d:f9:c0:
1a:5c:17:50:93:35:87:1e:7e:12:dc:41:fc:6b:2c:f7:ac:97:
6c:91:ba:47:22:91:99:36:45:74:14:f2:62:5b:e0:b1:59:ba:
53:f4:34:1c
-----BEGIN CERTIFICATE-----
MIICrTCCAZUCAgDsMA0GCSqGSIb3DQEBBQUAMCIxIDAeBgNVBAMMF0NsaWVudCBB
dXRoIFRlc3QgUm9vdCAyMB4XDTEzMDIxMjIzNDQ1OFoXDTIzMDIxMDIzNDQ1OFow
FjEUMBIGA1UEAwwLVGVzdCBDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQDu9g8gRcGbOwSrFILPlaZEE7P4x9dJG2hwEeEA8Xq0aFIh4qteFfz3
lRgehYjBVtGfh/FoxOD42olKf3DNFdLi0xLL3VzrSAKQzU39v7FhYr5bz78hKbuP
MSCSkpBV/IVX08xQPx5R077WSDGXpw3mQ8tduOv1uwpyLIg3/EPjLaTFvAW874Cm
tcFH+vTWgGDDO/bzRDGDiy5YMmYydIXi+t1zw75zyWHA3ymnFe2wFgzxTrW2Yqc0
4Eof5UNpREk8jkgxqojwX127SQXZpxt3yJpkCcJa/r9yav3XoN7XCX/ZwZUCi5ww
4ZpplRVZDQm/z17uVHYdTtdLjESUobMhAgMBAAEwDQYJKoZIhvcNAQEFBQADggEB
ALBj+704ZwcfPPE3uuYGLNERlzToR0iOI98/FBSttwfyiO82/KpWr+xlwWrYHD/W
fSXtqypPy3IhlKRsMPUDr0bX79H8ZiPbBueMS85QesbiNWfT81qDGUq/9alJyNW0
Cpr81MIkQA7VcAlFEl9EvhzhQTnn2buk2Sp/CCJ+/P25YXPQf+fmKxUV/CpGLtuf
mlazqNgI1rqorvsfRFHNqOhOcf0E/lAy+3mi02uKbEHH+LJp4LCG5ny+oA5Eek3g
M/OffeRv61QsmNiBPN10W91fgLXHBvRi76RmyM2U5qgoKjFQL51rehcrRxPwG2Zm
UNjrCGvZUzkWSI/7nAPnqVg=
MIIC0jCCAbqgAwIBAgICAOwwDQYJKoZIhvcNAQEFBQAwDzENMAsGA1UEAwwERSBD
QTAeFw0xMzA0MjIyMTU4NTJaFw0yMzA0MjAyMTU4NTJaMBgxFjAUBgNVBAMMDUNs
aWVudCBDZXJ0IEQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9IAnE
oEmLaadKpgiTFUtkdTP9YOiKAm4VT3kLM6VPe5O1qZRwFXdaP6PwUU5u+07Boao2
HMQj8HWUvvk0xggcDmFEcuAgcyPasNcAitI3T/NApp68CRjiUOoAYhYmKm7pHsiZ
d52YMwIZHok0E3nMXUq5EEGuU4rIYUwwbH/8Poq8SeoFd0YREAO2jWzMGWMthX+X
0pIGKNT3TnSAw6fKSRqmF4Ht7Y6Vl3Ovye8EKt7EmmLl99TcAk+3LqhE4zG5m+D8
O83q/89axEz6fzIejF6DjdsoZTkychUPgjzo/pDTkGG/Oav9ql4eJhVxxfQQd2qF
R/npbZCpO6XYxpv1AgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI
KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQAFM52GqYFJqVxX
QWcwKrOS1Zb0/E+arSoY+WZ+6Dqs72xCU2AbmcyqvXjv19fRUgQ/xtXq7FHRiB+t
BacWEiz5f3kPEHDeptFik2hXXaC9lQ+6gjdmd9ZIH6sQqr0dRpwj1vovwj04joR+
emL1b23DaJVvT5nsLNZsIqqjCtAJ2A8ZX3VdZW4xdvm5Q2v2+iJw/8D6A/YiiVxp
nZv7+KDodmZkMttRI/tY4GdoJBVYgXjDgH551x5ev5yCBM/INGrHHnWSDUXVg6Nb
5z9J7X6g94tsRUVN+cAaXBdQkzWHHn4S3EH8ayz3rJdskbpHIpGZNkV0FPJiW+Cx
WbpT9DQc
-----END CERTIFICATE-----

@ -0,0 +1,71 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 237 (0xed)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=C Root CA
Validity
Not Before: Apr 22 21:58:52 2013 GMT
Not After : Apr 20 21:58:52 2023 GMT
Subject: CN=E CA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e6:0b:39:56:df:1c:f7:69:44:73:00:91:ad:ef:
0a:31:1d:86:ca:67:b7:f5:bd:a8:34:d2:7d:af:3b:
46:61:98:d6:b6:ea:97:60:d8:1a:91:87:1e:b3:89:
f6:eb:8f:05:f4:7b:0b:77:3a:4c:7e:04:14:ce:60:
2f:f8:8c:c4:45:07:0b:86:ad:9e:97:58:20:90:4a:
16:90:f3:6e:7d:4e:92:f9:2b:bf:62:99:d6:86:38:
53:a4:33:79:df:7e:64:2b:8e:86:c0:c6:5a:87:73:
69:f5:5f:89:d5:3b:d7:f4:e4:1e:78:15:38:89:ff:
87:a9:7a:85:b9:4c:20:c6:44:7d:3a:d1:10:59:86:
7e:0f:d4:0c:a7:48:f8:42:7e:61:0a:bf:2b:4f:03:
3d:ac:f5:0f:01:5b:65:3b:fd:82:a1:8c:40:c7:8e:
24:e4:75:17:92:1c:76:e8:6c:f6:44:de:ee:90:d9:
cd:40:7c:70:50:91:23:a0:f5:c5:3c:9b:7e:5f:0d:
54:4d:b7:67:ce:1f:99:50:bf:da:a8:33:4f:6c:b3:
aa:4b:af:59:87:25:4a:8c:87:56:66:15:13:8a:58:
5a:9f:0a:fa:0e:34:8a:7a:cc:ac:9e:0e:c9:53:22:
b9:60:ae:32:b9:bc:5a:51:53:f9:f5:91:83:9e:df:
4b:77
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Certificate Sign, CRL Sign
Signature Algorithm: sha1WithRSAEncryption
46:32:41:a6:8c:f8:2e:56:59:6a:e6:c0:2e:85:1b:49:19:ba:
63:ee:5d:44:c1:91:f3:4b:1a:2c:e9:fd:d7:5f:0e:24:63:6a:
ea:5f:37:fd:ad:db:54:ad:a8:2b:10:f7:7c:86:98:39:62:ad:
50:bb:c4:f5:e1:4d:1f:12:30:83:cc:a9:cb:c7:5e:f9:d9:ee:
95:8f:d2:5a:f6:24:45:09:f6:66:44:76:79:e4:49:08:3b:ca:
c7:09:7c:f6:26:07:9c:01:70:38:cd:57:3f:16:ad:af:82:42:
4d:7e:e4:45:ed:0e:8d:83:a0:7a:56:8b:3f:21:52:db:6b:ca:
ab:bb:f0:17:10:e9:83:af:fd:4a:ea:32:61:ea:ec:fe:42:67:
fd:a2:2e:7a:3d:d7:9f:ff:f0:59:8b:a6:54:4d:77:f2:0c:4f:
c4:71:7e:8c:f0:3b:4b:72:6d:f7:28:35:0f:96:42:61:bf:28:
44:a2:7c:86:43:65:aa:3d:c1:6d:cf:41:f3:23:d3:96:ea:d4:
e0:72:78:04:d9:ff:7e:7c:fc:bf:88:f9:e2:64:80:47:52:97:
42:11:07:90:3c:31:35:c2:f9:83:88:e7:59:3f:f4:06:f4:b8:
07:35:14:56:1f:73:b9:a5:c3:95:47:20:4d:e0:8e:41:bd:c5:
7b:88:15:d6
-----BEGIN CERTIFICATE-----
MIICwjCCAaqgAwIBAgICAO0wDQYJKoZIhvcNAQEFBQAwFDESMBAGA1UEAwwJQyBS
b290IENBMB4XDTEzMDQyMjIxNTg1MloXDTIzMDQyMDIxNTg1MlowDzENMAsGA1UE
AwwERSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOYLOVbfHPdp
RHMAka3vCjEdhspnt/W9qDTSfa87RmGY1rbql2DYGpGHHrOJ9uuPBfR7C3c6TH4E
FM5gL/iMxEUHC4atnpdYIJBKFpDzbn1Okvkrv2KZ1oY4U6Qzed9+ZCuOhsDGWodz
afVfidU71/TkHngVOIn/h6l6hblMIMZEfTrREFmGfg/UDKdI+EJ+YQq/K08DPaz1
DwFbZTv9gqGMQMeOJOR1F5Icduhs9kTe7pDZzUB8cFCRI6D1xTybfl8NVE23Z84f
mVC/2qgzT2yzqkuvWYclSoyHVmYVE4pYWp8K+g40inrMrJ4OyVMiuWCuMrm8WlFT
+fWRg57fS3cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
AQYwDQYJKoZIhvcNAQEFBQADggEBAEYyQaaM+C5WWWrmwC6FG0kZumPuXUTBkfNL
Gizp/ddfDiRjaupfN/2t21StqCsQ93yGmDlirVC7xPXhTR8SMIPMqcvHXvnZ7pWP
0lr2JEUJ9mZEdnnkSQg7yscJfPYmB5wBcDjNVz8Wra+CQk1+5EXtDo2DoHpWiz8h
Uttryqu78BcQ6YOv/UrqMmHq7P5CZ/2iLno915//8FmLplRNd/IMT8RxfozwO0ty
bfcoNQ+WQmG/KESifIZDZao9wW3PQfMj05bq1OByeATZ/358/L+I+eJkgEdSl0IR
B5A8MTXC+YOI51k/9Ab0uAc1FFYfc7mlw5VHIE3gjkG9xXuIFdY=
-----END CERTIFICATE-----

@ -1,66 +0,0 @@
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 14502867099363826292 (0xc94488c99247da74)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=Client Auth Test Root 2
Validity
Not Before: Feb 12 23:44:58 2013 GMT
Not After : Feb 10 23:44:58 2023 GMT
Subject: CN=Client Auth Test Root 2
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:d5:75:ea:d8:1b:23:19:ad:a5:76:ce:bd:c0:54:
41:e4:e0:d1:f4:d1:3c:10:3d:8b:64:1c:0a:11:c3:
af:2b:4b:f4:28:41:a7:f9:f8:c3:4b:e1:4d:52:22:
ed:48:fa:5e:de:1d:6e:a4:93:92:76:a3:b4:41:cb:
e4:2d:ce:87:91:8e:50:c1:e0:fb:50:29:45:bb:d0:
b5:bc:0e:e4:47:d9:23:38:33:7a:24:a4:d3:b8:57:
21:89:f0:d8:45:da:72:11:9a:7a:62:96:28:29:2f:
b2:c6:d4:d0:3c:9e:d5:30:47:fe:a8:55:b6:be:80:
9a:fc:66:ed:ac:01:4b:45:e4:02:24:6d:81:ce:8a:
0a:02:b9:d7:5c:93:07:8e:9a:dc:3c:04:33:16:44:
e6:cd:26:e2:b6:40:d5:1c:2a:11:52:b8:02:f0:28:
14:67:f9:e9:e1:a1:e9:7b:a3:53:fb:b5:eb:e9:45:
7e:a9:b3:c3:ae:cc:76:ae:8b:53:4e:91:4c:12:58:
b5:00:8f:2d:2f:19:aa:bb:30:ca:e1:41:12:aa:3b:
76:ed:a5:b5:3f:d6:c7:b1:4f:33:c7:f4:14:23:08:
ab:39:dc:76:6b:86:0b:24:45:2b:70:d1:bf:00:0f:
50:93:5b:80:67:49:7e:01:89:9b:7c:1d:06:f3:11:
4f:45
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
20:0a:9a:fe:cb:fa:d5:49:b9:e5:83:c0:4f:fc:71:ea:99:82:
ef:9c:6c:ac:dd:7f:56:21:c9:9b:d6:01:95:29:27:4f:7b:51:
87:39:bf:62:8b:6a:af:54:83:d1:b3:3e:bc:35:4d:a0:e6:8a:
77:f8:b2:25:55:e9:ad:8b:95:33:19:d9:30:bd:77:93:7d:ac:
87:3c:fb:df:0f:73:69:74:25:6f:4e:eb:f1:4f:ff:76:29:7c:
aa:2f:ef:73:11:0f:43:00:cb:ad:65:4a:d1:1c:fc:e0:85:34:
cf:c4:20:8f:8f:ec:3d:4b:68:22:99:0c:a0:f2:dc:08:00:13:
3c:07:8a:eb:48:2a:21:64:81:84:a0:03:99:a4:d2:2e:6d:d5:
56:4e:b6:51:28:1c:d5:2d:39:d2:49:93:94:df:9a:cd:1c:33:
80:ca:a6:ce:8c:c6:d7:a6:24:49:6f:cf:b6:fe:22:ad:18:96:
82:06:a9:5b:41:aa:b6:04:86:1b:da:96:36:dc:53:89:71:1e:
5e:ab:63:19:54:34:e8:c5:f7:fc:a2:9f:f0:a1:7a:43:e9:b3:
ee:02:8f:a2:5b:8c:e4:4c:7d:45:fb:3f:e4:24:24:0f:f1:8e:
1c:8e:4d:2e:2b:8d:28:99:ff:5f:ff:12:cc:c7:a8:b8:d0:ab:
09:25:9d:03
-----BEGIN CERTIFICATE-----
MIICwDCCAagCCQDJRIjJkkfadDANBgkqhkiG9w0BAQUFADAiMSAwHgYDVQQDDBdD
bGllbnQgQXV0aCBUZXN0IFJvb3QgMjAeFw0xMzAyMTIyMzQ0NThaFw0yMzAyMTAy
MzQ0NThaMCIxIDAeBgNVBAMMF0NsaWVudCBBdXRoIFRlc3QgUm9vdCAyMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1XXq2BsjGa2lds69wFRB5ODR9NE8
ED2LZBwKEcOvK0v0KEGn+fjDS+FNUiLtSPpe3h1upJOSdqO0QcvkLc6HkY5QweD7
UClFu9C1vA7kR9kjODN6JKTTuFchifDYRdpyEZp6YpYoKS+yxtTQPJ7VMEf+qFW2
voCa/GbtrAFLReQCJG2BzooKArnXXJMHjprcPAQzFkTmzSbitkDVHCoRUrgC8CgU
Z/np4aHpe6NT+7Xr6UV+qbPDrsx2rotTTpFMEli1AI8tLxmquzDK4UESqjt27aW1
P9bHsU8zx/QUIwirOdx2a4YLJEUrcNG/AA9Qk1uAZ0l+AYmbfB0G8xFPRQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4IBAQAgCpr+y/rVSbnlg8BP/HHqmYLvnGys3X9WIcmb
1gGVKSdPe1GHOb9ii2qvVIPRsz68NU2g5op3+LIlVemti5UzGdkwvXeTfayHPPvf
D3NpdCVvTuvxT/92KXyqL+9zEQ9DAMutZUrRHPzghTTPxCCPj+w9S2gimQyg8twI
ABM8B4rrSCohZIGEoAOZpNIubdVWTrZRKBzVLTnSSZOU35rNHDOAyqbOjMbXpiRJ
b8+2/iKtGJaCBqlbQaq2BIYb2pY23FOJcR5eq2MZVDToxff8op/woXpD6bPuAo+i
W4zkTH1F+z/kJCQP8Y4cjk0uK40omf9f/xLMx6i40KsJJZ0D
-----END CERTIFICATE-----

@ -0,0 +1,51 @@
ID=1
CA_DIR=out
[ca]
default_ca = ca_settings
preserve = yes
[ca_settings]
dir = ${ENV::CA_DIR}
database = $dir/${ENV::ID}-index.txt
new_certs_dir = $dir
serial = $dir/${ENV::ID}-serial
certificate = $dir/${ENV::ID}.pem
private_key = $dir/${ENV::ID}.key
RANDFILE = $dir/rand
default_md = sha1
default_days = 3650
policy = policy_anything
unique_subject = no
copy_extensions = copy
[policy_anything]
# Default signing policy
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional
[req]
default_bits = 2048
default_md = sha1
string_mask = utf8only
prompt = no
encrypt_key = no
distinguished_name = req_env_dn
[user_cert]
# Extensions to add when signing a request for an EE cert
basicConstraints = critical, CA:false
extendedKeyUsage = serverAuth,clientAuth
[ca_cert]
# Extensions to add when signing a request for an intermediate/CA cert
basicConstraints = critical, CA:true
keyUsage = critical, keyCertSign, cRLSign
[req_env_dn]
CN = ${ENV::COMMON_NAME}

@ -1,35 +0,0 @@
ID=1
[req]
default_bits = 2048
default_md = sha1
string_mask = utf8only
prompt = no
encrypt_key = no
distinguished_name = ${ENV::DISTINGUISHED_NAME}
[ca]
default_ca = ca_settings
[ca_dn]
CN = Client Auth Test Root ${ENV::ID}
[client_dn]
CN = Test Client
[ca_settings]
database = out/${ENV::ID}-index.txt
new_certs_dir = out
default_md = sha1
policy = policy_anything
serial = out/${ENV::ID}-serial
default_days = 3650
[policy_anything]
# Default signing policy
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional

@ -4,77 +4,160 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This script generates certificates for the unittests in
# net/base/client_cert_store_unittest.cc. The output files are versioned in
# net/data/ssl/certificates (client_1.pem, client_2.pem).
# This script generates certificates that can be used to test SSL client
# authentication. Outputs for automated tests are stored in
# net/data/ssl/certificates, but may be re-generated for manual testing.
#
# This script generates two chains of test client certificates:
#
# 1. A (end-entity) -> B -> C (self-signed root)
# 2. D (end-entity) -> E -> C (self-signed root)
#
# In which A, B, C, D, and E all have distinct keypairs. Both client
# certificates share the same root, but are issued by different
# intermediates. The names of these intermediates are hardcoded within
# unit tests, and thus should not be changed.
try () {
echo "$@"
$@ || exit 1
}
# For each authority below a root ca certificate and one client certificate will
# be created.
authorities="1 2"
try rm -rf out
try mkdir out
for id in $authorities
echo Create the serial number files and indices.
serial = 100
for i in B C E
do
# Generate a private key for the root cert.
try openssl genrsa -out out/root_$id.key 2048
try echo $serial > out/$i-serial
serial=$(expr $serial + 1)
touch out/$i-index.txt
touch out/$i-index.txt.attr
done
# Create a certificate signing request for the root cert.
ID=$id \
DISTINGUISHED_NAME=ca_dn \
echo Generate the keys.
for i in A B C D E
do
try openssl genrsa -out out/$i.key 2048
done
echo Generate the C CSR
COMMON_NAME="C Root CA" \
CA_DIR=out \
ID=C \
try openssl req \
-new \
-key out/root_$id.key \
-out out/root_$id.csr \
-config client_authentication.cnf
-key out/C.key \
-out out/C.csr \
-config client-certs.cnf
# Sign the root cert.
ID=$id \
DISTINGUISHED_NAME=ca_dn \
echo C signs itself.
COMMON_NAME="C Root CA" \
CA_DIR=out \
ID=C \
try openssl x509 \
-req -days 3650 \
-in out/root_$id.csr \
-signkey out/root_$id.key \
-text \
-out out/root_$id.pem
-config client_authentication.cnf
-in out/C.csr \
-extensions ca_cert \
-signkey out/C.key \
-out out/C.pem
# Generate a private key for the client.
try openssl genrsa -out out/client_$id.key 2048
# Create a certificate signing request for the client cert.
ID=$id \
DISTINGUISHED_NAME=client_dn \
echo Generate the intermediates
COMMON_NAME="B CA" \
CA_DIR=out \
ID=B \
try openssl req \
-new \
-key out/client_$id.key \
-out out/client_$id.csr \
-config client_authentication.cnf
-key out/B.key \
-out out/B.csr \
-config client-certs.cnf
try touch out/$id-index.txt
try echo 1 > out/$id-serial
ID=$id \
DISTINGUISHED_NAME=client_dn \
COMMON_NAME="C CA" \
CA_DIR=out \
ID=C \
try openssl ca \
-batch \
-in out/client_$id.csr \
-cert out/root_$id.pem \
-keyfile out/root_$id.key \
-out out/client_$id.pem \
-config client_authentication.cnf
-extensions ca_cert \
-in out/B.csr \
-out out/B.pem \
-config client-certs.cnf
# Package the client cert and private key into a pkcs12 file.
try openssl pkcs12 \
-inkey out/client_$id.key \
-in out/client_$id.pem \
-out out/client_$id.p12 \
-export \
-passout pass:chrome
COMMON_NAME="E CA" \
CA_DIR=out \
ID=E \
try openssl req \
-new \
-key out/E.key \
-out out/E.csr \
-config client-certs.cnf
COMMON_NAME="C CA" \
CA_DIR=out \
ID=C \
try openssl ca \
-batch \
-extensions ca_cert \
-in out/E.csr \
-out out/E.pem \
-config client-certs.cnf
echo Generate the leaf certs
for id in A D
do
COMMON_NAME="Client Cert $id" \
ID=$id \
try openssl req \
-new \
-key out/$id.key \
-out out/$id.csr \
-config client-certs.cnf
done
echo B signs A
COMMON_NAME="B CA" \
CA_DIR=out \
ID=B \
try openssl ca \
-batch \
-extensions user_cert \
-in out/A.csr \
-out out/A.pem \
-config client-certs.cnf
echo E signs D
COMMON_NAME="E CA" \
CA_DIR=out \
ID=E \
try openssl ca \
-batch \
-extensions user_cert \
-in out/D.csr \
-out out/D.pem \
-config client-certs.cnf
echo Package the client certs and private keys into PKCS12 files
# This is done for easily importing all of the certs needed for clients.
cat out/A.pem out/A.key out/B.pem out/C.pem > out/A-chain.pem
cat out/D.pem out/D.key out/E.pem out/C.pem > out/D-chain.pem
try openssl pkcs12 \
-in out/A-chain.pem \
-out client_1.p12 \
-export \
-passout pass:chrome
try openssl pkcs12 \
-in out/D-chain.pem \
-out client_2.p12 \
-export \
-passout pass:chrome
echo Package the client certs for unit tests
cp out/A.pem client_1.pem
cp out/A.key client_1.key
cp out/B.pem client_1_ca.pem
cp out/D.pem client_2.pem
cp out/D.key client_2.key
cp out/E.pem client_2_ca.pem

@ -112,7 +112,10 @@
#include <Security/SecBase.h>
#include <Security/SecCertificate.h>
#include <Security/SecIdentity.h>
#include "base/mac/mac_logging.h"
#include "base/synchronization/lock.h"
#include "crypto/mac_security_services_lock.h"
#elif defined(USE_NSS)
#include <dlfcn.h>
#endif
@ -1397,29 +1400,31 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler(
OSStatus os_error = noErr;
SecIdentityRef identity = NULL;
SecKeyRef private_key = NULL;
CFArrayRef chain =
core->ssl_config_.client_cert->CreateClientCertificateChain();
if (chain) {
identity = reinterpret_cast<SecIdentityRef>(
const_cast<void*>(CFArrayGetValueAtIndex(chain, 0)));
X509Certificate::OSCertHandles chain;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
os_error = SecIdentityCreateWithCertificate(
NULL, core->ssl_config_.client_cert->os_cert_handle(), &identity);
}
if (identity)
if (os_error == noErr) {
os_error = SecIdentityCopyPrivateKey(identity, &private_key);
CFRelease(identity);
}
if (chain && identity && os_error == noErr) {
if (os_error == noErr) {
// TODO(rsleevi): Error checking for NSS allocation errors.
*result_certs = CERT_NewCertList();
*result_private_key = private_key;
for (CFIndex i = 0; i < CFArrayGetCount(chain); ++i) {
chain.push_back(core->ssl_config_.client_cert->os_cert_handle());
const X509Certificate::OSCertHandles& intermediates =
core->ssl_config_.client_cert->GetIntermediateCertificates();
if (!intermediates.empty())
chain.insert(chain.end(), intermediates.begin(), intermediates.end());
for (size_t i = 0, chain_count = chain.size(); i < chain_count; ++i) {
CSSM_DATA cert_data;
SecCertificateRef cert_ref;
if (i == 0) {
cert_ref = core->ssl_config_.client_cert->os_cert_handle();
} else {
cert_ref = reinterpret_cast<SecCertificateRef>(
const_cast<void*>(CFArrayGetValueAtIndex(chain, i)));
}
SecCertificateRef cert_ref = chain[i];
os_error = SecCertificateGetData(cert_ref, &cert_data);
if (os_error != noErr)
break;
@ -1431,23 +1436,20 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler(
CERTCertificate* nss_cert = CERT_NewTempCertificate(
CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
if (!nss_cert) {
// In the event of an NSS error we make up an OS error and reuse
// the error handling, below.
// In the event of an NSS error, make up an OS error and reuse
// the error handling below.
os_error = errSecCreateChainFailed;
break;
}
CERT_AddCertToListTail(*result_certs, nss_cert);
}
}
if (os_error == noErr) {
int cert_count = 0;
if (chain) {
cert_count = CFArrayGetCount(chain);
CFRelease(chain);
}
core->AddCertProvidedEvent(cert_count);
core->AddCertProvidedEvent(chain.size());
return SECSuccess;
}
OSSTATUS_LOG(WARNING, os_error)
<< "Client cert found, but could not be used";
if (*result_certs) {
@ -1458,8 +1460,6 @@ SECStatus SSLClientSocketNSS::Core::PlatformClientAuthHandler(
*result_private_key = NULL;
if (private_key)
CFRelease(private_key);
if (chain)
CFRelease(chain);
}
// Send no client certificate.

@ -219,7 +219,7 @@ TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendEmptyCert) {
TestServer::SSLOptions ssl_options;
ssl_options.request_client_certificate = true;
ssl_options.client_authorities.push_back(
GetTestClientCertsDirectory().AppendASCII("client_1_root.pem"));
GetTestClientCertsDirectory().AppendASCII("client_1_ca.pem"));
ASSERT_TRUE(ConnectToTestServer(ssl_options));
@ -241,7 +241,7 @@ TEST_F(SSLClientSocketOpenSSLClientAuthTest, SendGoodCert) {
TestServer::SSLOptions ssl_options;
ssl_options.request_client_certificate = true;
ssl_options.client_authorities.push_back(
GetTestClientCertsDirectory().AppendASCII("client_1_root.pem"));
GetTestClientCertsDirectory().AppendASCII("client_1_ca.pem"));
ASSERT_TRUE(ConnectToTestServer(ssl_options));

@ -21,6 +21,7 @@
#include "crypto/mac_security_services_lock.h"
#include "net/base/host_port_pair.h"
#include "net/cert/x509_util.h"
#include "net/cert/x509_util_mac.h"
using base::mac::ScopedCFTypeRef;
@ -28,9 +29,103 @@ namespace net {
namespace {
// Gets the issuer for a given cert, starting with the cert itself and
// including the intermediate and finally root certificates (if any).
// This function calls SecTrust but doesn't actually pay attention to the trust
// result: it shouldn't be used to determine trust, just to traverse the chain.
// Caller is responsible for releasing the value stored into *out_cert_chain.
OSStatus CopyCertChain(SecCertificateRef cert_handle,
CFArrayRef* out_cert_chain) {
DCHECK(cert_handle);
DCHECK(out_cert_chain);
// Create an SSL policy ref configured for client cert evaluation.
SecPolicyRef ssl_policy;
OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy);
if (result)
return result;
ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
// Create a SecTrustRef.
ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
1, &kCFTypeArrayCallBacks));
SecTrustRef trust_ref = NULL;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustCreateWithCertificates(input_certs, ssl_policy,
&trust_ref);
}
if (result)
return result;
ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
// Evaluate trust, which creates the cert chain.
SecTrustResultType status;
CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustEvaluate(trust, &status);
}
if (result)
return result;
{
base::AutoLock lock(crypto::GetMacSecurityServicesLock());
result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
}
return result;
}
// Returns true if |*cert| is issued by an authority in |valid_issuers|
// according to Keychain Services, rather than using |cert|'s intermediate
// certificates. If it is, |*cert| is updated to point to the completed
// certificate
bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers,
scoped_refptr<X509Certificate>* cert) {
DCHECK(cert);
DCHECK(*cert);
X509Certificate::OSCertHandle cert_handle = (*cert)->os_cert_handle();
CFArrayRef cert_chain = NULL;
OSStatus result = CopyCertChain(cert_handle, &cert_chain);
if (result) {
OSSTATUS_LOG(ERROR, result) << "CopyCertChain error";
return false;
}
if (!cert_chain)
return false;
X509Certificate::OSCertHandles intermediates;
for (CFIndex i = 1, chain_count = CFArrayGetCount(cert_chain);
i < chain_count; ++i) {
SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i)));
intermediates.push_back(cert);
}
scoped_refptr<X509Certificate> new_cert(X509Certificate::CreateFromHandle(
cert_handle, intermediates));
CFRelease(cert_chain); // Also frees |intermediates|.
if (!new_cert->IsIssuedByEncoded(valid_issuers))
return false;
cert->swap(new_cert);
return true;
}
// Examines the certificates in |preferred_cert| and |regular_certs| to find
// all certificates that match the client certificate request in |request|,
// storing the matching certificates in |selected_certs|.
// If |query_keychain| is true, Keychain Services will be queried to construct
// full certificate chains. If it is false, only the the certificates and their
// intermediates (available via X509Certificate::GetIntermediateCertificates())
// will be considered.
bool GetClientCertsImpl(const scoped_refptr<X509Certificate>& preferred_cert,
const CertificateList& regular_certs,
const SSLCertRequestInfo& request,
bool query_keychain,
CertificateList* selected_certs) {
CertificateList preliminary_list;
if (preferred_cert)
@ -55,11 +150,12 @@ bool GetClientCertsImpl(const scoped_refptr<X509Certificate>& preferred_cert,
continue;
// Check if the certificate issuer is allowed by the server.
if (!request.cert_authorities.empty() &&
!cert->IsIssuedByEncoded(request.cert_authorities)) {
continue;
if (request.cert_authorities.empty() ||
cert->IsIssuedByEncoded(request.cert_authorities) ||
(query_keychain &&
IsIssuedByInKeychain(request.cert_authorities, &cert))) {
selected_certs->push_back(cert);
}
selected_certs->push_back(cert);
}
// Preferred cert should appear first in the ui, so exclude it from the
@ -147,14 +243,14 @@ bool ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request,
return false;
}
return GetClientCertsImpl(preferred_cert, regular_certs, request,
return GetClientCertsImpl(preferred_cert, regular_certs, request, true,
selected_certs);
}
bool ClientCertStoreImpl::SelectClientCerts(const CertificateList& input_certs,
const SSLCertRequestInfo& request,
CertificateList* selected_certs) {
return GetClientCertsImpl(NULL, input_certs, request,
return GetClientCertsImpl(NULL, input_certs, request, false,
selected_certs);
}
@ -164,7 +260,7 @@ bool ClientCertStoreImpl::SelectClientCertsGivenPreferred(
const CertificateList& regular_certs,
const SSLCertRequestInfo& request,
CertificateList* selected_certs) {
return GetClientCertsImpl(preferred_cert, regular_certs, request,
return GetClientCertsImpl(preferred_cert, regular_certs, request, false,
selected_certs);
}
#endif

@ -14,13 +14,40 @@ namespace net {
namespace {
// Examines the certificates in |cert_list| to find all certificates that match
// the client certificate request in |request|, storing the matching
// certificates in |selected_certs|.
// If |query_nssdb| is true, NSS will be queried to construct full certificate
// chains. If it is false, only the certificate will be considered.
bool GetClientCertsImpl(CERTCertList* cert_list,
const SSLCertRequestInfo& request,
bool query_nssdb,
CertificateList* selected_certs) {
DCHECK(cert_list);
DCHECK(selected_certs);
selected_certs->clear();
// Create a "fake" CERTDistNames structure. No public API exists to create
// one from a list of issuers.
CERTDistNames ca_names;
ca_names.arena = NULL;
ca_names.nnames = 0;
ca_names.names = NULL;
ca_names.head = NULL;
std::vector<SECItem> ca_names_items(request.cert_authorities.size());
for (size_t i = 0; i < request.cert_authorities.size(); ++i) {
const std::string& authority = request.cert_authorities[i];
ca_names_items[i].type = siBuffer;
ca_names_items[i].data =
reinterpret_cast<unsigned char*>(const_cast<char*>(authority.data()));
ca_names_items[i].len = static_cast<unsigned int>(authority.size());
}
ca_names.nnames = static_cast<int>(ca_names_items.size());
if (!ca_names_items.empty())
ca_names.names = &ca_names_items[0];
for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(node, cert_list);
node = CERT_LIST_NEXT(node)) {
@ -34,11 +61,13 @@ bool GetClientCertsImpl(CERTCertList* cert_list,
node->cert, X509Certificate::OSCertHandles());
// Check if the certificate issuer is allowed by the server.
if (!request.cert_authorities.empty() &&
!cert->IsIssuedByEncoded(request.cert_authorities)) {
continue;
if (request.cert_authorities.empty() ||
(!query_nssdb &&
cert->IsIssuedByEncoded(request.cert_authorities)) ||
(query_nssdb &&
NSS_CmpCertChainWCANames(node->cert, &ca_names) == SECSuccess)) {
selected_certs->push_back(cert);
}
selected_certs->push_back(cert);
}
std::sort(selected_certs->begin(), selected_certs->end(),
@ -57,7 +86,7 @@ bool ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request,
if (!client_certs)
return true;
bool rv = GetClientCertsImpl(client_certs, request, selected_certs);
bool rv = GetClientCertsImpl(client_certs, request, true, selected_certs);
CERT_DestroyCertList(client_certs);
return rv;
}
@ -73,7 +102,7 @@ bool ClientCertStoreImpl::SelectClientCerts(const CertificateList& input_certs,
cert_list, CERT_DupCertificate(input_certs[i]->os_cert_handle()));
}
bool rv = GetClientCertsImpl(cert_list, request, selected_certs);
bool rv = GetClientCertsImpl(cert_list, request, false, selected_certs);
CERT_DestroyCertList(cert_list);
return rv;
}

@ -18,18 +18,16 @@ namespace net {
namespace {
// "CN=Client Auth Test Root 1" - DER encoded DN of the issuer of client_1.pem.
// "CN=B CA" - DER encoded DN of the issuer of client_1.pem
const unsigned char kAuthority1DN[] = {
0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x17, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68,
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x31
0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x04, 0x42, 0x20, 0x43, 0x41
};
// "CN=Client Auth Test Root 2" - DER encoded DN of the issuer of client_2.pem.
// "CN=E CA" - DER encoded DN of the issuer of client_2.pem
unsigned char kAuthority2DN[] = {
0x30, 0x22, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x17, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68,
0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x32
0x30, 0x0f, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
0x04, 0x45, 0x20, 0x43, 0x41
};
} // namespace