| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/origin_bound_cert_service.h" | 5 #include "net/base/origin_bound_cert_service.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "crypto/ec_private_key.h" | 12 #include "crypto/ec_private_key.h" |
| 13 #include "net/base/asn1_util.h" | 13 #include "net/base/asn1_util.h" |
| 14 #include "net/base/default_origin_bound_cert_store.h" | 14 #include "net/base/default_origin_bound_cert_store.h" |
| 15 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
| 16 #include "net/base/test_completion_callback.h" | 16 #include "net/base/test_completion_callback.h" |
| 17 #include "net/base/x509_certificate.h" | 17 #include "net/base/x509_certificate.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 19 |
| 20 namespace net { | 20 namespace net { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 void FailTest(int /* result */) { | 24 void FailTest(int /* result */) { |
| 25 FAIL(); | 25 FAIL(); |
| 26 } | 26 } |
| 27 | 27 |
| 28 TEST(OriginBoundCertServiceTest, GetDomainForHost) { | 28 TEST(ServerBoundCertServiceTest, GetDomainForHost) { |
| 29 EXPECT_EQ("google.com", | 29 EXPECT_EQ("google.com", |
| 30 OriginBoundCertService::GetDomainForHost("google.com")); | 30 ServerBoundCertService::GetDomainForHost("google.com")); |
| 31 EXPECT_EQ("google.com", | 31 EXPECT_EQ("google.com", |
| 32 OriginBoundCertService::GetDomainForHost("www.google.com")); | 32 ServerBoundCertService::GetDomainForHost("www.google.com")); |
| 33 // NOTE(rch): we would like to segregate cookies and certificates for | 33 // NOTE(rch): we would like to segregate cookies and certificates for |
| 34 // *.appspot.com, but currently we can not do that becaues we want to | 34 // *.appspot.com, but currently we can not do that becaues we want to |
| 35 // allow direct navigation to appspot.com. | 35 // allow direct navigation to appspot.com. |
| 36 EXPECT_EQ("appspot.com", | 36 EXPECT_EQ("appspot.com", |
| 37 OriginBoundCertService::GetDomainForHost("foo.appspot.com")); | 37 ServerBoundCertService::GetDomainForHost("foo.appspot.com")); |
| 38 EXPECT_EQ("google.com", | 38 EXPECT_EQ("google.com", |
| 39 OriginBoundCertService::GetDomainForHost("www.mail.google.com")); | 39 ServerBoundCertService::GetDomainForHost("www.mail.google.com")); |
| 40 EXPECT_EQ("goto", | 40 EXPECT_EQ("goto", |
| 41 OriginBoundCertService::GetDomainForHost("goto")); | 41 ServerBoundCertService::GetDomainForHost("goto")); |
| 42 EXPECT_EQ("127.0.0.1", | 42 EXPECT_EQ("127.0.0.1", |
| 43 OriginBoundCertService::GetDomainForHost("127.0.0.1")); | 43 ServerBoundCertService::GetDomainForHost("127.0.0.1")); |
| 44 } | 44 } |
| 45 | 45 |
| 46 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned. | 46 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned. |
| 47 #if !defined(USE_OPENSSL) | 47 #if !defined(USE_OPENSSL) |
| 48 | 48 |
| 49 TEST(OriginBoundCertServiceTest, CacheHit) { | 49 TEST(ServerBoundCertServiceTest, CacheHit) { |
| 50 scoped_ptr<OriginBoundCertService> service( | 50 scoped_ptr<ServerBoundCertService> service( |
| 51 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 51 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 52 std::string origin("https://encrypted.google.com:443"); | 52 std::string origin("https://encrypted.google.com:443"); |
| 53 | 53 |
| 54 int error; | 54 int error; |
| 55 std::vector<uint8> types; | 55 std::vector<uint8> types; |
| 56 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 56 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 57 TestCompletionCallback callback; | 57 TestCompletionCallback callback; |
| 58 OriginBoundCertService::RequestHandle request_handle; | 58 ServerBoundCertService::RequestHandle request_handle; |
| 59 | 59 |
| 60 // Asynchronous completion. | 60 // Asynchronous completion. |
| 61 SSLClientCertType type1; | 61 SSLClientCertType type1; |
| 62 std::string private_key_info1, der_cert1; | 62 std::string private_key_info1, der_cert1; |
| 63 EXPECT_EQ(0, service->cert_count()); | 63 EXPECT_EQ(0, service->cert_count()); |
| 64 error = service->GetOriginBoundCert( | 64 error = service->GetDomainBoundCert( |
| 65 origin, types, &type1, &private_key_info1, &der_cert1, | 65 origin, types, &type1, &private_key_info1, &der_cert1, |
| 66 callback.callback(), &request_handle); | 66 callback.callback(), &request_handle); |
| 67 EXPECT_EQ(ERR_IO_PENDING, error); | 67 EXPECT_EQ(ERR_IO_PENDING, error); |
| 68 EXPECT_TRUE(request_handle != NULL); | 68 EXPECT_TRUE(request_handle != NULL); |
| 69 error = callback.WaitForResult(); | 69 error = callback.WaitForResult(); |
| 70 EXPECT_EQ(OK, error); | 70 EXPECT_EQ(OK, error); |
| 71 EXPECT_EQ(1, service->cert_count()); | 71 EXPECT_EQ(1, service->cert_count()); |
| 72 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); | 72 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); |
| 73 EXPECT_FALSE(private_key_info1.empty()); | 73 EXPECT_FALSE(private_key_info1.empty()); |
| 74 EXPECT_FALSE(der_cert1.empty()); | 74 EXPECT_FALSE(der_cert1.empty()); |
| 75 | 75 |
| 76 // Synchronous completion. | 76 // Synchronous completion. |
| 77 SSLClientCertType type2; | 77 SSLClientCertType type2; |
| 78 std::string private_key_info2, der_cert2; | 78 std::string private_key_info2, der_cert2; |
| 79 error = service->GetOriginBoundCert( | 79 error = service->GetDomainBoundCert( |
| 80 origin, types, &type2, &private_key_info2, &der_cert2, | 80 origin, types, &type2, &private_key_info2, &der_cert2, |
| 81 callback.callback(), &request_handle); | 81 callback.callback(), &request_handle); |
| 82 EXPECT_TRUE(request_handle == NULL); | 82 EXPECT_TRUE(request_handle == NULL); |
| 83 EXPECT_EQ(OK, error); | 83 EXPECT_EQ(OK, error); |
| 84 EXPECT_EQ(1, service->cert_count()); | 84 EXPECT_EQ(1, service->cert_count()); |
| 85 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); | 85 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); |
| 86 EXPECT_EQ(private_key_info1, private_key_info2); | 86 EXPECT_EQ(private_key_info1, private_key_info2); |
| 87 EXPECT_EQ(der_cert1, der_cert2); | 87 EXPECT_EQ(der_cert1, der_cert2); |
| 88 | 88 |
| 89 EXPECT_EQ(2u, service->requests()); | 89 EXPECT_EQ(2u, service->requests()); |
| 90 EXPECT_EQ(1u, service->cert_store_hits()); | 90 EXPECT_EQ(1u, service->cert_store_hits()); |
| 91 EXPECT_EQ(0u, service->inflight_joins()); | 91 EXPECT_EQ(0u, service->inflight_joins()); |
| 92 } | 92 } |
| 93 | 93 |
| 94 TEST(OriginBoundCertServiceTest, UnsupportedTypes) { | 94 TEST(ServerBoundCertServiceTest, UnsupportedTypes) { |
| 95 scoped_ptr<OriginBoundCertService> service( | 95 scoped_ptr<ServerBoundCertService> service( |
| 96 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 96 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 97 std::string origin("https://encrypted.google.com:443"); | 97 std::string origin("https://encrypted.google.com:443"); |
| 98 | 98 |
| 99 int error; | 99 int error; |
| 100 std::vector<uint8> types; | 100 std::vector<uint8> types; |
| 101 TestCompletionCallback callback; | 101 TestCompletionCallback callback; |
| 102 OriginBoundCertService::RequestHandle request_handle; | 102 ServerBoundCertService::RequestHandle request_handle; |
| 103 | 103 |
| 104 // Empty requested_types. | 104 // Empty requested_types. |
| 105 SSLClientCertType type1; | 105 SSLClientCertType type1; |
| 106 std::string private_key_info1, der_cert1; | 106 std::string private_key_info1, der_cert1; |
| 107 error = service->GetOriginBoundCert( | 107 error = service->GetDomainBoundCert( |
| 108 origin, types, &type1, &private_key_info1, &der_cert1, | 108 origin, types, &type1, &private_key_info1, &der_cert1, |
| 109 callback.callback(), &request_handle); | 109 callback.callback(), &request_handle); |
| 110 EXPECT_EQ(ERR_INVALID_ARGUMENT, error); | 110 EXPECT_EQ(ERR_INVALID_ARGUMENT, error); |
| 111 EXPECT_TRUE(request_handle == NULL); | 111 EXPECT_TRUE(request_handle == NULL); |
| 112 | 112 |
| 113 // No supported types in requested_types. | 113 // No supported types in requested_types. |
| 114 types.push_back(CLIENT_CERT_RSA_SIGN); | 114 types.push_back(CLIENT_CERT_RSA_SIGN); |
| 115 types.push_back(2); | 115 types.push_back(2); |
| 116 types.push_back(3); | 116 types.push_back(3); |
| 117 error = service->GetOriginBoundCert( | 117 error = service->GetDomainBoundCert( |
| 118 origin, types, &type1, &private_key_info1, &der_cert1, | 118 origin, types, &type1, &private_key_info1, &der_cert1, |
| 119 callback.callback(), &request_handle); | 119 callback.callback(), &request_handle); |
| 120 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); | 120 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); |
| 121 EXPECT_TRUE(request_handle == NULL); | 121 EXPECT_TRUE(request_handle == NULL); |
| 122 | 122 |
| 123 // Supported types after unsupported ones in requested_types. | 123 // Supported types after unsupported ones in requested_types. |
| 124 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 124 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 125 // Asynchronous completion. | 125 // Asynchronous completion. |
| 126 EXPECT_EQ(0, service->cert_count()); | 126 EXPECT_EQ(0, service->cert_count()); |
| 127 error = service->GetOriginBoundCert( | 127 error = service->GetDomainBoundCert( |
| 128 origin, types, &type1, &private_key_info1, &der_cert1, | 128 origin, types, &type1, &private_key_info1, &der_cert1, |
| 129 callback.callback(), &request_handle); | 129 callback.callback(), &request_handle); |
| 130 EXPECT_EQ(ERR_IO_PENDING, error); | 130 EXPECT_EQ(ERR_IO_PENDING, error); |
| 131 EXPECT_TRUE(request_handle != NULL); | 131 EXPECT_TRUE(request_handle != NULL); |
| 132 error = callback.WaitForResult(); | 132 error = callback.WaitForResult(); |
| 133 EXPECT_EQ(OK, error); | 133 EXPECT_EQ(OK, error); |
| 134 EXPECT_EQ(1, service->cert_count()); | 134 EXPECT_EQ(1, service->cert_count()); |
| 135 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); | 135 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); |
| 136 EXPECT_FALSE(private_key_info1.empty()); | 136 EXPECT_FALSE(private_key_info1.empty()); |
| 137 EXPECT_FALSE(der_cert1.empty()); | 137 EXPECT_FALSE(der_cert1.empty()); |
| 138 | 138 |
| 139 // Now that the cert is created, doing requests for unsupported types | 139 // Now that the cert is created, doing requests for unsupported types |
| 140 // shouldn't affect the created cert. | 140 // shouldn't affect the created cert. |
| 141 // Empty requested_types. | 141 // Empty requested_types. |
| 142 types.clear(); | 142 types.clear(); |
| 143 SSLClientCertType type2; | 143 SSLClientCertType type2; |
| 144 std::string private_key_info2, der_cert2; | 144 std::string private_key_info2, der_cert2; |
| 145 error = service->GetOriginBoundCert( | 145 error = service->GetDomainBoundCert( |
| 146 origin, types, &type2, &private_key_info2, &der_cert2, | 146 origin, types, &type2, &private_key_info2, &der_cert2, |
| 147 callback.callback(), &request_handle); | 147 callback.callback(), &request_handle); |
| 148 EXPECT_EQ(ERR_INVALID_ARGUMENT, error); | 148 EXPECT_EQ(ERR_INVALID_ARGUMENT, error); |
| 149 EXPECT_TRUE(request_handle == NULL); | 149 EXPECT_TRUE(request_handle == NULL); |
| 150 | 150 |
| 151 // No supported types in requested_types. | 151 // No supported types in requested_types. |
| 152 types.push_back(CLIENT_CERT_RSA_SIGN); | 152 types.push_back(CLIENT_CERT_RSA_SIGN); |
| 153 types.push_back(2); | 153 types.push_back(2); |
| 154 types.push_back(3); | 154 types.push_back(3); |
| 155 error = service->GetOriginBoundCert( | 155 error = service->GetDomainBoundCert( |
| 156 origin, types, &type2, &private_key_info2, &der_cert2, | 156 origin, types, &type2, &private_key_info2, &der_cert2, |
| 157 callback.callback(), &request_handle); | 157 callback.callback(), &request_handle); |
| 158 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); | 158 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); |
| 159 EXPECT_TRUE(request_handle == NULL); | 159 EXPECT_TRUE(request_handle == NULL); |
| 160 | 160 |
| 161 // If we request EC, the cert we created before should still be there. | 161 // If we request EC, the cert we created before should still be there. |
| 162 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 162 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 163 error = service->GetOriginBoundCert( | 163 error = service->GetDomainBoundCert( |
| 164 origin, types, &type2, &private_key_info2, &der_cert2, | 164 origin, types, &type2, &private_key_info2, &der_cert2, |
| 165 callback.callback(), &request_handle); | 165 callback.callback(), &request_handle); |
| 166 EXPECT_TRUE(request_handle == NULL); | 166 EXPECT_TRUE(request_handle == NULL); |
| 167 EXPECT_EQ(OK, error); | 167 EXPECT_EQ(OK, error); |
| 168 EXPECT_EQ(1, service->cert_count()); | 168 EXPECT_EQ(1, service->cert_count()); |
| 169 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); | 169 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); |
| 170 EXPECT_EQ(private_key_info1, private_key_info2); | 170 EXPECT_EQ(private_key_info1, private_key_info2); |
| 171 EXPECT_EQ(der_cert1, der_cert2); | 171 EXPECT_EQ(der_cert1, der_cert2); |
| 172 } | 172 } |
| 173 | 173 |
| 174 TEST(OriginBoundCertServiceTest, StoreCerts) { | 174 TEST(ServerBoundCertServiceTest, StoreCerts) { |
| 175 scoped_ptr<OriginBoundCertService> service( | 175 scoped_ptr<ServerBoundCertService> service( |
| 176 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 176 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 177 int error; | 177 int error; |
| 178 std::vector<uint8> types; | 178 std::vector<uint8> types; |
| 179 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 179 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 180 TestCompletionCallback callback; | 180 TestCompletionCallback callback; |
| 181 OriginBoundCertService::RequestHandle request_handle; | 181 ServerBoundCertService::RequestHandle request_handle; |
| 182 | 182 |
| 183 std::string origin1("https://encrypted.google.com:443"); | 183 std::string origin1("https://encrypted.google.com:443"); |
| 184 SSLClientCertType type1; | 184 SSLClientCertType type1; |
| 185 std::string private_key_info1, der_cert1; | 185 std::string private_key_info1, der_cert1; |
| 186 EXPECT_EQ(0, service->cert_count()); | 186 EXPECT_EQ(0, service->cert_count()); |
| 187 error = service->GetOriginBoundCert( | 187 error = service->GetDomainBoundCert( |
| 188 origin1, types, &type1, &private_key_info1, &der_cert1, | 188 origin1, types, &type1, &private_key_info1, &der_cert1, |
| 189 callback.callback(), &request_handle); | 189 callback.callback(), &request_handle); |
| 190 EXPECT_EQ(ERR_IO_PENDING, error); | 190 EXPECT_EQ(ERR_IO_PENDING, error); |
| 191 EXPECT_TRUE(request_handle != NULL); | 191 EXPECT_TRUE(request_handle != NULL); |
| 192 error = callback.WaitForResult(); | 192 error = callback.WaitForResult(); |
| 193 EXPECT_EQ(OK, error); | 193 EXPECT_EQ(OK, error); |
| 194 EXPECT_EQ(1, service->cert_count()); | 194 EXPECT_EQ(1, service->cert_count()); |
| 195 | 195 |
| 196 std::string origin2("https://www.verisign.com:443"); | 196 std::string origin2("https://www.verisign.com:443"); |
| 197 SSLClientCertType type2; | 197 SSLClientCertType type2; |
| 198 std::string private_key_info2, der_cert2; | 198 std::string private_key_info2, der_cert2; |
| 199 error = service->GetOriginBoundCert( | 199 error = service->GetDomainBoundCert( |
| 200 origin2, types, &type2, &private_key_info2, &der_cert2, | 200 origin2, types, &type2, &private_key_info2, &der_cert2, |
| 201 callback.callback(), &request_handle); | 201 callback.callback(), &request_handle); |
| 202 EXPECT_EQ(ERR_IO_PENDING, error); | 202 EXPECT_EQ(ERR_IO_PENDING, error); |
| 203 EXPECT_TRUE(request_handle != NULL); | 203 EXPECT_TRUE(request_handle != NULL); |
| 204 error = callback.WaitForResult(); | 204 error = callback.WaitForResult(); |
| 205 EXPECT_EQ(OK, error); | 205 EXPECT_EQ(OK, error); |
| 206 EXPECT_EQ(2, service->cert_count()); | 206 EXPECT_EQ(2, service->cert_count()); |
| 207 | 207 |
| 208 std::string origin3("https://www.twitter.com:443"); | 208 std::string origin3("https://www.twitter.com:443"); |
| 209 SSLClientCertType type3; | 209 SSLClientCertType type3; |
| 210 std::string private_key_info3, der_cert3; | 210 std::string private_key_info3, der_cert3; |
| 211 error = service->GetOriginBoundCert( | 211 error = service->GetDomainBoundCert( |
| 212 origin3, types, &type3, &private_key_info3, &der_cert3, | 212 origin3, types, &type3, &private_key_info3, &der_cert3, |
| 213 callback.callback(), &request_handle); | 213 callback.callback(), &request_handle); |
| 214 EXPECT_EQ(ERR_IO_PENDING, error); | 214 EXPECT_EQ(ERR_IO_PENDING, error); |
| 215 EXPECT_TRUE(request_handle != NULL); | 215 EXPECT_TRUE(request_handle != NULL); |
| 216 error = callback.WaitForResult(); | 216 error = callback.WaitForResult(); |
| 217 EXPECT_EQ(OK, error); | 217 EXPECT_EQ(OK, error); |
| 218 EXPECT_EQ(3, service->cert_count()); | 218 EXPECT_EQ(3, service->cert_count()); |
| 219 | 219 |
| 220 EXPECT_NE(private_key_info1, private_key_info2); | 220 EXPECT_NE(private_key_info1, private_key_info2); |
| 221 EXPECT_NE(der_cert1, der_cert2); | 221 EXPECT_NE(der_cert1, der_cert2); |
| 222 EXPECT_NE(private_key_info1, private_key_info3); | 222 EXPECT_NE(private_key_info1, private_key_info3); |
| 223 EXPECT_NE(der_cert1, der_cert3); | 223 EXPECT_NE(der_cert1, der_cert3); |
| 224 EXPECT_NE(private_key_info2, private_key_info3); | 224 EXPECT_NE(private_key_info2, private_key_info3); |
| 225 EXPECT_NE(der_cert2, der_cert3); | 225 EXPECT_NE(der_cert2, der_cert3); |
| 226 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); | 226 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); |
| 227 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); | 227 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); |
| 228 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3); | 228 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3); |
| 229 } | 229 } |
| 230 | 230 |
| 231 // Tests an inflight join. | 231 // Tests an inflight join. |
| 232 TEST(OriginBoundCertServiceTest, InflightJoin) { | 232 TEST(ServerBoundCertServiceTest, InflightJoin) { |
| 233 scoped_ptr<OriginBoundCertService> service( | 233 scoped_ptr<ServerBoundCertService> service( |
| 234 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 234 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 235 std::string origin("https://encrypted.google.com:443"); | 235 std::string origin("https://encrypted.google.com:443"); |
| 236 int error; | 236 int error; |
| 237 std::vector<uint8> types; | 237 std::vector<uint8> types; |
| 238 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 238 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 239 | 239 |
| 240 SSLClientCertType type1; | 240 SSLClientCertType type1; |
| 241 std::string private_key_info1, der_cert1; | 241 std::string private_key_info1, der_cert1; |
| 242 TestCompletionCallback callback1; | 242 TestCompletionCallback callback1; |
| 243 OriginBoundCertService::RequestHandle request_handle1; | 243 ServerBoundCertService::RequestHandle request_handle1; |
| 244 | 244 |
| 245 SSLClientCertType type2; | 245 SSLClientCertType type2; |
| 246 std::string private_key_info2, der_cert2; | 246 std::string private_key_info2, der_cert2; |
| 247 TestCompletionCallback callback2; | 247 TestCompletionCallback callback2; |
| 248 OriginBoundCertService::RequestHandle request_handle2; | 248 ServerBoundCertService::RequestHandle request_handle2; |
| 249 | 249 |
| 250 error = service->GetOriginBoundCert( | 250 error = service->GetDomainBoundCert( |
| 251 origin, types, &type1, &private_key_info1, &der_cert1, | 251 origin, types, &type1, &private_key_info1, &der_cert1, |
| 252 callback1.callback(), &request_handle1); | 252 callback1.callback(), &request_handle1); |
| 253 EXPECT_EQ(ERR_IO_PENDING, error); | 253 EXPECT_EQ(ERR_IO_PENDING, error); |
| 254 EXPECT_TRUE(request_handle1 != NULL); | 254 EXPECT_TRUE(request_handle1 != NULL); |
| 255 // If we request RSA and EC in the 2nd request, should still join with the | 255 // If we request RSA and EC in the 2nd request, should still join with the |
| 256 // original request. | 256 // original request. |
| 257 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN); | 257 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN); |
| 258 error = service->GetOriginBoundCert( | 258 error = service->GetDomainBoundCert( |
| 259 origin, types, &type2, &private_key_info2, &der_cert2, | 259 origin, types, &type2, &private_key_info2, &der_cert2, |
| 260 callback2.callback(), &request_handle2); | 260 callback2.callback(), &request_handle2); |
| 261 EXPECT_EQ(ERR_IO_PENDING, error); | 261 EXPECT_EQ(ERR_IO_PENDING, error); |
| 262 EXPECT_TRUE(request_handle2 != NULL); | 262 EXPECT_TRUE(request_handle2 != NULL); |
| 263 | 263 |
| 264 error = callback1.WaitForResult(); | 264 error = callback1.WaitForResult(); |
| 265 EXPECT_EQ(OK, error); | 265 EXPECT_EQ(OK, error); |
| 266 error = callback2.WaitForResult(); | 266 error = callback2.WaitForResult(); |
| 267 EXPECT_EQ(OK, error); | 267 EXPECT_EQ(OK, error); |
| 268 | 268 |
| 269 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); | 269 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); |
| 270 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); | 270 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); |
| 271 EXPECT_EQ(2u, service->requests()); | 271 EXPECT_EQ(2u, service->requests()); |
| 272 EXPECT_EQ(0u, service->cert_store_hits()); | 272 EXPECT_EQ(0u, service->cert_store_hits()); |
| 273 EXPECT_EQ(1u, service->inflight_joins()); | 273 EXPECT_EQ(1u, service->inflight_joins()); |
| 274 } | 274 } |
| 275 | 275 |
| 276 TEST(OriginBoundCertServiceTest, ExtractValuesFromBytesEC) { | 276 TEST(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { |
| 277 scoped_ptr<OriginBoundCertService> service( | 277 scoped_ptr<ServerBoundCertService> service( |
| 278 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 278 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 279 std::string origin("https://encrypted.google.com:443"); | 279 std::string origin("https://encrypted.google.com:443"); |
| 280 SSLClientCertType type; | 280 SSLClientCertType type; |
| 281 std::string private_key_info, der_cert; | 281 std::string private_key_info, der_cert; |
| 282 int error; | 282 int error; |
| 283 std::vector<uint8> types; | 283 std::vector<uint8> types; |
| 284 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 284 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 285 TestCompletionCallback callback; | 285 TestCompletionCallback callback; |
| 286 OriginBoundCertService::RequestHandle request_handle; | 286 ServerBoundCertService::RequestHandle request_handle; |
| 287 | 287 |
| 288 error = service->GetOriginBoundCert( | 288 error = service->GetDomainBoundCert( |
| 289 origin, types, &type, &private_key_info, &der_cert, callback.callback(), | 289 origin, types, &type, &private_key_info, &der_cert, callback.callback(), |
| 290 &request_handle); | 290 &request_handle); |
| 291 EXPECT_EQ(ERR_IO_PENDING, error); | 291 EXPECT_EQ(ERR_IO_PENDING, error); |
| 292 EXPECT_TRUE(request_handle != NULL); | 292 EXPECT_TRUE(request_handle != NULL); |
| 293 error = callback.WaitForResult(); | 293 error = callback.WaitForResult(); |
| 294 EXPECT_EQ(OK, error); | 294 EXPECT_EQ(OK, error); |
| 295 | 295 |
| 296 base::StringPiece spki_piece; | 296 base::StringPiece spki_piece; |
| 297 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece)); | 297 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece)); |
| 298 std::vector<uint8> spki( | 298 std::vector<uint8> spki( |
| 299 spki_piece.data(), | 299 spki_piece.data(), |
| 300 spki_piece.data() + spki_piece.size()); | 300 spki_piece.data() + spki_piece.size()); |
| 301 | 301 |
| 302 // Check that we can retrieve the key from the bytes. | 302 // Check that we can retrieve the key from the bytes. |
| 303 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end()); | 303 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end()); |
| 304 scoped_ptr<crypto::ECPrivateKey> private_key( | 304 scoped_ptr<crypto::ECPrivateKey> private_key( |
| 305 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( | 305 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
| 306 OriginBoundCertService::kEPKIPassword, key_vec, spki)); | 306 ServerBoundCertService::kEPKIPassword, key_vec, spki)); |
| 307 EXPECT_TRUE(private_key != NULL); | 307 EXPECT_TRUE(private_key != NULL); |
| 308 | 308 |
| 309 // Check that we can retrieve the cert from the bytes. | 309 // Check that we can retrieve the cert from the bytes. |
| 310 scoped_refptr<X509Certificate> x509cert( | 310 scoped_refptr<X509Certificate> x509cert( |
| 311 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size())); | 311 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size())); |
| 312 EXPECT_TRUE(x509cert != NULL); | 312 EXPECT_TRUE(x509cert != NULL); |
| 313 } | 313 } |
| 314 | 314 |
| 315 // Tests that the callback of a canceled request is never made. | 315 // Tests that the callback of a canceled request is never made. |
| 316 TEST(OriginBoundCertServiceTest, CancelRequest) { | 316 TEST(ServerBoundCertServiceTest, CancelRequest) { |
| 317 scoped_ptr<OriginBoundCertService> service( | 317 scoped_ptr<ServerBoundCertService> service( |
| 318 new OriginBoundCertService(new DefaultOriginBoundCertStore(NULL))); | 318 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL))); |
| 319 std::string origin("https://encrypted.google.com:443"); | 319 std::string origin("https://encrypted.google.com:443"); |
| 320 SSLClientCertType type; | 320 SSLClientCertType type; |
| 321 std::string private_key_info, der_cert; | 321 std::string private_key_info, der_cert; |
| 322 int error; | 322 int error; |
| 323 std::vector<uint8> types; | 323 std::vector<uint8> types; |
| 324 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 324 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 325 OriginBoundCertService::RequestHandle request_handle; | 325 ServerBoundCertService::RequestHandle request_handle; |
| 326 | 326 |
| 327 error = service->GetOriginBoundCert(origin, | 327 error = service->GetDomainBoundCert(origin, |
| 328 types, | 328 types, |
| 329 &type, | 329 &type, |
| 330 &private_key_info, | 330 &private_key_info, |
| 331 &der_cert, | 331 &der_cert, |
| 332 base::Bind(&FailTest), | 332 base::Bind(&FailTest), |
| 333 &request_handle); | 333 &request_handle); |
| 334 EXPECT_EQ(ERR_IO_PENDING, error); | 334 EXPECT_EQ(ERR_IO_PENDING, error); |
| 335 EXPECT_TRUE(request_handle != NULL); | 335 EXPECT_TRUE(request_handle != NULL); |
| 336 service->CancelRequest(request_handle); | 336 service->CancelRequest(request_handle); |
| 337 | 337 |
| 338 // Issue a few more requests to the worker pool and wait for their | 338 // Issue a few more requests to the worker pool and wait for their |
| 339 // completion, so that the task of the canceled request (which runs on a | 339 // completion, so that the task of the canceled request (which runs on a |
| 340 // worker thread) is likely to complete by the end of this test. | 340 // worker thread) is likely to complete by the end of this test. |
| 341 TestCompletionCallback callback; | 341 TestCompletionCallback callback; |
| 342 for (int i = 0; i < 5; ++i) { | 342 for (int i = 0; i < 5; ++i) { |
| 343 error = service->GetOriginBoundCert( | 343 error = service->GetDomainBoundCert( |
| 344 "https://encrypted.google.com:" + std::string(1, (char) ('1' + i)), | 344 "https://foo" + std::string(1, (char) ('1' + i)), |
| 345 types, | 345 types, |
| 346 &type, | 346 &type, |
| 347 &private_key_info, | 347 &private_key_info, |
| 348 &der_cert, | 348 &der_cert, |
| 349 callback.callback(), | 349 callback.callback(), |
| 350 &request_handle); | 350 &request_handle); |
| 351 EXPECT_EQ(ERR_IO_PENDING, error); | 351 EXPECT_EQ(ERR_IO_PENDING, error); |
| 352 EXPECT_TRUE(request_handle != NULL); | 352 EXPECT_TRUE(request_handle != NULL); |
| 353 error = callback.WaitForResult(); | 353 error = callback.WaitForResult(); |
| 354 } | 354 } |
| 355 | 355 |
| 356 // Even though the original request was cancelled, the service will still | 356 // Even though the original request was cancelled, the service will still |
| 357 // store the result, it just doesn't call the callback. | 357 // store the result, it just doesn't call the callback. |
| 358 EXPECT_EQ(6, service->cert_count()); | 358 EXPECT_EQ(6, service->cert_count()); |
| 359 } | 359 } |
| 360 | 360 |
| 361 TEST(OriginBoundCertServiceTest, Expiration) { | 361 TEST(ServerBoundCertServiceTest, Expiration) { |
| 362 OriginBoundCertStore* store = new DefaultOriginBoundCertStore(NULL); | 362 ServerBoundCertStore* store = new DefaultServerBoundCertStore(NULL); |
| 363 base::Time now = base::Time::Now(); | 363 base::Time now = base::Time::Now(); |
| 364 store->SetOriginBoundCert("https://good", | 364 store->SetServerBoundCert("good", |
| 365 CLIENT_CERT_ECDSA_SIGN, | 365 CLIENT_CERT_ECDSA_SIGN, |
| 366 now, | 366 now, |
| 367 now + base::TimeDelta::FromDays(1), | 367 now + base::TimeDelta::FromDays(1), |
| 368 "a", | 368 "a", |
| 369 "b"); | 369 "b"); |
| 370 store->SetOriginBoundCert("https://expired", | 370 store->SetServerBoundCert("expired", |
| 371 CLIENT_CERT_ECDSA_SIGN, | 371 CLIENT_CERT_ECDSA_SIGN, |
| 372 now - base::TimeDelta::FromDays(2), | 372 now - base::TimeDelta::FromDays(2), |
| 373 now - base::TimeDelta::FromDays(1), | 373 now - base::TimeDelta::FromDays(1), |
| 374 "c", | 374 "c", |
| 375 "d"); | 375 "d"); |
| 376 OriginBoundCertService service(store); | 376 ServerBoundCertService service(store); |
| 377 EXPECT_EQ(2, service.cert_count()); | 377 EXPECT_EQ(2, service.cert_count()); |
| 378 | 378 |
| 379 int error; | 379 int error; |
| 380 std::vector<uint8> types; | 380 std::vector<uint8> types; |
| 381 types.push_back(CLIENT_CERT_ECDSA_SIGN); | 381 types.push_back(CLIENT_CERT_ECDSA_SIGN); |
| 382 TestCompletionCallback callback; | 382 TestCompletionCallback callback; |
| 383 OriginBoundCertService::RequestHandle request_handle; | 383 ServerBoundCertService::RequestHandle request_handle; |
| 384 | 384 |
| 385 // Cert still valid - synchronous completion. | 385 // Cert still valid - synchronous completion. |
| 386 SSLClientCertType type1; | 386 SSLClientCertType type1; |
| 387 std::string private_key_info1, der_cert1; | 387 std::string private_key_info1, der_cert1; |
| 388 error = service.GetOriginBoundCert( | 388 error = service.GetDomainBoundCert( |
| 389 "https://good", types, &type1, &private_key_info1, &der_cert1, | 389 "https://good", types, &type1, &private_key_info1, &der_cert1, |
| 390 callback.callback(), &request_handle); | 390 callback.callback(), &request_handle); |
| 391 EXPECT_EQ(OK, error); | 391 EXPECT_EQ(OK, error); |
| 392 EXPECT_TRUE(request_handle == NULL); | 392 EXPECT_TRUE(request_handle == NULL); |
| 393 EXPECT_EQ(2, service.cert_count()); | 393 EXPECT_EQ(2, service.cert_count()); |
| 394 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); | 394 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); |
| 395 EXPECT_STREQ("a", private_key_info1.c_str()); | 395 EXPECT_STREQ("a", private_key_info1.c_str()); |
| 396 EXPECT_STREQ("b", der_cert1.c_str()); | 396 EXPECT_STREQ("b", der_cert1.c_str()); |
| 397 | 397 |
| 398 // Cert expired - New cert will be generated, asynchronous completion. | 398 // Cert expired - New cert will be generated, asynchronous completion. |
| 399 SSLClientCertType type2; | 399 SSLClientCertType type2; |
| 400 std::string private_key_info2, der_cert2; | 400 std::string private_key_info2, der_cert2; |
| 401 error = service.GetOriginBoundCert( | 401 error = service.GetDomainBoundCert( |
| 402 "https://expired", types, &type2, &private_key_info2, &der_cert2, | 402 "https://expired", types, &type2, &private_key_info2, &der_cert2, |
| 403 callback.callback(), &request_handle); | 403 callback.callback(), &request_handle); |
| 404 EXPECT_EQ(ERR_IO_PENDING, error); | 404 EXPECT_EQ(ERR_IO_PENDING, error); |
| 405 EXPECT_TRUE(request_handle != NULL); | 405 EXPECT_TRUE(request_handle != NULL); |
| 406 error = callback.WaitForResult(); | 406 error = callback.WaitForResult(); |
| 407 EXPECT_EQ(OK, error); | 407 EXPECT_EQ(OK, error); |
| 408 EXPECT_EQ(2, service.cert_count()); | 408 EXPECT_EQ(2, service.cert_count()); |
| 409 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); | 409 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); |
| 410 EXPECT_LT(1U, private_key_info2.size()); | 410 EXPECT_LT(1U, private_key_info2.size()); |
| 411 EXPECT_LT(1U, der_cert2.size()); | 411 EXPECT_LT(1U, der_cert2.size()); |
| 412 } | 412 } |
| 413 | 413 |
| 414 #endif // !defined(USE_OPENSSL) | 414 #endif // !defined(USE_OPENSSL) |
| 415 | 415 |
| 416 } // namespace | 416 } // namespace |
| 417 | 417 |
| 418 } // namespace net | 418 } // namespace net |
| OLD | NEW |