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/socket/ssl_client_socket.h" | 5 #include "net/socket/ssl_client_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <string.h> | 8 #include <string.h> |
9 | 9 |
10 #include <openssl/bio.h> | 10 #include <openssl/bio.h> |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 namespace net { | 48 namespace net { |
49 | 49 |
50 namespace { | 50 namespace { |
51 | 51 |
52 // These client auth tests are currently dependent on OpenSSL's struct X509. | 52 // These client auth tests are currently dependent on OpenSSL's struct X509. |
53 #if defined(USE_OPENSSL_CERTS) | 53 #if defined(USE_OPENSSL_CERTS) |
54 typedef OpenSSLClientKeyStore::ScopedEVP_PKEY ScopedEVP_PKEY; | 54 typedef OpenSSLClientKeyStore::ScopedEVP_PKEY ScopedEVP_PKEY; |
55 | 55 |
56 // BIO_free is a macro, it can't be used as a template parameter. | 56 // BIO_free is a macro, it can't be used as a template parameter. |
57 void BIO_free_func(BIO* bio) { | 57 void BIO_free_func(BIO* bio) { |
58 BIO_free(bio); | 58 BIO_free(bio); |
59 } | 59 } |
60 | 60 |
61 typedef crypto::ScopedOpenSSL<BIO, BIO_free_func> ScopedBIO; | 61 typedef crypto::ScopedOpenSSL<BIO, BIO_free_func> ScopedBIO; |
62 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA; | 62 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA; |
63 typedef crypto::ScopedOpenSSL<BIGNUM, BN_free> ScopedBIGNUM; | 63 typedef crypto::ScopedOpenSSL<BIGNUM, BN_free> ScopedBIGNUM; |
64 | 64 |
65 const SSLConfig kDefaultSSLConfig; | 65 const SSLConfig kDefaultSSLConfig; |
66 | 66 |
67 // A ServerBoundCertStore that always returns an error when asked for a | 67 // A ServerBoundCertStore that always returns an error when asked for a |
68 // certificate. | 68 // certificate. |
69 class FailingServerBoundCertStore : public ServerBoundCertStore { | 69 class FailingServerBoundCertStore : public ServerBoundCertStore { |
70 virtual int GetServerBoundCert(const std::string& server_identifier, | 70 virtual int GetServerBoundCert(const std::string& server_identifier, |
71 base::Time* expiration_time, | 71 base::Time* expiration_time, |
72 std::string* private_key_result, | 72 std::string* private_key_result, |
73 std::string* cert_result, | 73 std::string* cert_result, |
74 const GetCertCallback& callback) OVERRIDE { | 74 const GetCertCallback& callback) OVERRIDE { |
75 return ERR_UNEXPECTED; | 75 return ERR_UNEXPECTED; |
76 } | 76 } |
77 virtual void SetServerBoundCert(const std::string& server_identifier, | 77 virtual void SetServerBoundCert(const std::string& server_identifier, |
78 base::Time creation_time, | 78 base::Time creation_time, |
79 base::Time expiration_time, | 79 base::Time expiration_time, |
80 const std::string& private_key, | 80 const std::string& private_key, |
81 const std::string& cert) OVERRIDE {} | 81 const std::string& cert) OVERRIDE {} |
82 virtual void DeleteServerBoundCert(const std::string& server_identifier, | 82 virtual void DeleteServerBoundCert( |
83 const base::Closure& completion_callback) | 83 const std::string& server_identifier, |
84 OVERRIDE {} | 84 const base::Closure& completion_callback) OVERRIDE {} |
85 virtual void DeleteAllCreatedBetween(base::Time delete_begin, | 85 virtual void DeleteAllCreatedBetween( |
86 base::Time delete_end, | 86 base::Time delete_begin, |
87 const base::Closure& completion_callback) | 87 base::Time delete_end, |
88 OVERRIDE {} | 88 const base::Closure& completion_callback) OVERRIDE {} |
89 virtual void DeleteAll(const base::Closure& completion_callback) OVERRIDE {} | 89 virtual void DeleteAll(const base::Closure& completion_callback) OVERRIDE {} |
90 virtual void GetAllServerBoundCerts(const GetCertListCallback& callback) | 90 virtual void GetAllServerBoundCerts( |
91 OVERRIDE {} | 91 const GetCertListCallback& callback) OVERRIDE {} |
92 virtual int GetCertCount() OVERRIDE { return 0; } | 92 virtual int GetCertCount() OVERRIDE { return 0; } |
93 virtual void SetForceKeepSessionState() OVERRIDE {} | 93 virtual void SetForceKeepSessionState() OVERRIDE {} |
94 }; | 94 }; |
95 | 95 |
96 // Loads a PEM-encoded private key file into a scoped EVP_PKEY object. | 96 // Loads a PEM-encoded private key file into a scoped EVP_PKEY object. |
97 // |filepath| is the private key file path. | 97 // |filepath| is the private key file path. |
98 // |*pkey| is reset to the new EVP_PKEY on success, untouched otherwise. | 98 // |*pkey| is reset to the new EVP_PKEY on success, untouched otherwise. |
99 // Returns true on success, false on failure. | 99 // Returns true on success, false on failure. |
100 bool LoadPrivateKeyOpenSSL( | 100 bool LoadPrivateKeyOpenSSL(const base::FilePath& filepath, |
101 const base::FilePath& filepath, | 101 OpenSSLClientKeyStore::ScopedEVP_PKEY* pkey) { |
102 OpenSSLClientKeyStore::ScopedEVP_PKEY* pkey) { | |
103 std::string data; | 102 std::string data; |
104 if (!base::ReadFileToString(filepath, &data)) { | 103 if (!base::ReadFileToString(filepath, &data)) { |
105 LOG(ERROR) << "Could not read private key file: " | 104 LOG(ERROR) << "Could not read private key file: " << filepath.value() |
106 << filepath.value() << ": " << strerror(errno); | 105 << ": " << strerror(errno); |
107 return false; | 106 return false; |
108 } | 107 } |
109 ScopedBIO bio( | 108 ScopedBIO bio(BIO_new_mem_buf( |
110 BIO_new_mem_buf( | 109 const_cast<char*>(reinterpret_cast<const char*>(data.data())), |
111 const_cast<char*>(reinterpret_cast<const char*>(data.data())), | 110 static_cast<int>(data.size()))); |
112 static_cast<int>(data.size()))); | |
113 if (!bio.get()) { | 111 if (!bio.get()) { |
114 LOG(ERROR) << "Could not allocate BIO for buffer?"; | 112 LOG(ERROR) << "Could not allocate BIO for buffer?"; |
115 return false; | 113 return false; |
116 } | 114 } |
117 EVP_PKEY* result = PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL); | 115 EVP_PKEY* result = PEM_read_bio_PrivateKey(bio.get(), NULL, NULL, NULL); |
118 if (result == NULL) { | 116 if (result == NULL) { |
119 LOG(ERROR) << "Could not decode private key file: " | 117 LOG(ERROR) << "Could not decode private key file: " << filepath.value(); |
120 << filepath.value(); | |
121 return false; | 118 return false; |
122 } | 119 } |
123 pkey->reset(result); | 120 pkey->reset(result); |
124 return true; | 121 return true; |
125 } | 122 } |
126 | 123 |
127 class SSLClientSocketOpenSSLClientAuthTest : public PlatformTest { | 124 class SSLClientSocketOpenSSLClientAuthTest : public PlatformTest { |
128 public: | 125 public: |
129 SSLClientSocketOpenSSLClientAuthTest() | 126 SSLClientSocketOpenSSLClientAuthTest() |
130 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()), | 127 : socket_factory_(net::ClientSocketFactory::GetDefaultFactory()), |
131 cert_verifier_(new net::MockCertVerifier), | 128 cert_verifier_(new net::MockCertVerifier), |
132 transport_security_state_(new net::TransportSecurityState) { | 129 transport_security_state_(new net::TransportSecurityState) { |
133 cert_verifier_->set_default_result(net::OK); | 130 cert_verifier_->set_default_result(net::OK); |
134 context_.cert_verifier = cert_verifier_.get(); | 131 context_.cert_verifier = cert_verifier_.get(); |
135 context_.transport_security_state = transport_security_state_.get(); | 132 context_.transport_security_state = transport_security_state_.get(); |
136 key_store_ = net::OpenSSLClientKeyStore::GetInstance(); | 133 key_store_ = net::OpenSSLClientKeyStore::GetInstance(); |
137 } | 134 } |
138 | 135 |
139 virtual ~SSLClientSocketOpenSSLClientAuthTest() { | 136 virtual ~SSLClientSocketOpenSSLClientAuthTest() { key_store_->Flush(); } |
140 key_store_->Flush(); | |
141 } | |
142 | 137 |
143 protected: | 138 protected: |
144 void EnabledChannelID() { | 139 void EnabledChannelID() { |
145 cert_service_.reset( | 140 cert_service_.reset( |
146 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL), | 141 new ServerBoundCertService(new DefaultServerBoundCertStore(NULL), |
147 base::MessageLoopProxy::current())); | 142 base::MessageLoopProxy::current())); |
148 context_.server_bound_cert_service = cert_service_.get(); | 143 context_.server_bound_cert_service = cert_service_.get(); |
149 } | 144 } |
150 | 145 |
151 void EnabledFailingChannelID() { | 146 void EnabledFailingChannelID() { |
152 cert_service_.reset( | 147 cert_service_.reset(new ServerBoundCertService( |
153 new ServerBoundCertService(new FailingServerBoundCertStore(), | 148 new FailingServerBoundCertStore(), base::MessageLoopProxy::current())); |
154 base::MessageLoopProxy::current())); | |
155 context_.server_bound_cert_service = cert_service_.get(); | 149 context_.server_bound_cert_service = cert_service_.get(); |
156 } | 150 } |
157 | 151 |
158 scoped_ptr<SSLClientSocket> CreateSSLClientSocket( | 152 scoped_ptr<SSLClientSocket> CreateSSLClientSocket( |
159 scoped_ptr<StreamSocket> transport_socket, | 153 scoped_ptr<StreamSocket> transport_socket, |
160 const HostPortPair& host_and_port, | 154 const HostPortPair& host_and_port, |
161 const SSLConfig& ssl_config) { | 155 const SSLConfig& ssl_config) { |
162 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); | 156 scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); |
163 connection->SetSocket(transport_socket.Pass()); | 157 connection->SetSocket(transport_socket.Pass()); |
164 return socket_factory_->CreateSSLClientSocket(connection.Pass(), | 158 return socket_factory_->CreateSSLClientSocket( |
165 host_and_port, | 159 connection.Pass(), host_and_port, ssl_config, context_); |
166 ssl_config, | |
167 context_); | |
168 } | 160 } |
169 | 161 |
170 // Connect to a HTTPS test server. | 162 // Connect to a HTTPS test server. |
171 bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) { | 163 bool ConnectToTestServer(SpawnedTestServer::SSLOptions& ssl_options) { |
172 test_server_.reset(new SpawnedTestServer(SpawnedTestServer::TYPE_HTTPS, | 164 test_server_.reset(new SpawnedTestServer( |
173 ssl_options, | 165 SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); |
174 base::FilePath())); | |
175 if (!test_server_->Start()) { | 166 if (!test_server_->Start()) { |
176 LOG(ERROR) << "Could not start SpawnedTestServer"; | 167 LOG(ERROR) << "Could not start SpawnedTestServer"; |
177 return false; | 168 return false; |
178 } | 169 } |
179 | 170 |
180 if (!test_server_->GetAddressList(&addr_)) { | 171 if (!test_server_->GetAddressList(&addr_)) { |
181 LOG(ERROR) << "Could not get SpawnedTestServer address list"; | 172 LOG(ERROR) << "Could not get SpawnedTestServer address list"; |
182 return false; | 173 return false; |
183 } | 174 } |
184 | 175 |
185 transport_.reset(new TCPClientSocket( | 176 transport_.reset(new TCPClientSocket(addr_, &log_, NetLog::Source())); |
186 addr_, &log_, NetLog::Source())); | 177 int rv = callback_.GetResult(transport_->Connect(callback_.callback())); |
187 int rv = callback_.GetResult( | |
188 transport_->Connect(callback_.callback())); | |
189 if (rv != OK) { | 178 if (rv != OK) { |
190 LOG(ERROR) << "Could not connect to SpawnedTestServer"; | 179 LOG(ERROR) << "Could not connect to SpawnedTestServer"; |
191 return false; | 180 return false; |
192 } | 181 } |
193 return true; | 182 return true; |
194 } | 183 } |
195 | 184 |
196 // Record a certificate's private key to ensure it can be used | 185 // Record a certificate's private key to ensure it can be used |
197 // by the OpenSSL-based SSLClientSocket implementation. | 186 // by the OpenSSL-based SSLClientSocket implementation. |
198 // |ssl_config| provides a client certificate. | 187 // |ssl_config| provides a client certificate. |
199 // |private_key| must be an EVP_PKEY for the corresponding private key. | 188 // |private_key| must be an EVP_PKEY for the corresponding private key. |
200 // Returns true on success, false on failure. | 189 // Returns true on success, false on failure. |
201 bool RecordPrivateKey(SSLConfig& ssl_config, | 190 bool RecordPrivateKey(SSLConfig& ssl_config, EVP_PKEY* private_key) { |
202 EVP_PKEY* private_key) { | 191 return key_store_->RecordClientCertPrivateKey(ssl_config.client_cert.get(), |
203 return key_store_->RecordClientCertPrivateKey( | 192 private_key); |
204 ssl_config.client_cert.get(), private_key); | |
205 } | 193 } |
206 | 194 |
207 // Create an SSLClientSocket object and use it to connect to a test | 195 // Create an SSLClientSocket object and use it to connect to a test |
208 // server, then wait for connection results. This must be called after | 196 // server, then wait for connection results. This must be called after |
209 // a succesful ConnectToTestServer() call. | 197 // a succesful ConnectToTestServer() call. |
210 // |ssl_config| the SSL configuration to use. | 198 // |ssl_config| the SSL configuration to use. |
211 // |result| will retrieve the ::Connect() result value. | 199 // |result| will retrieve the ::Connect() result value. |
212 // Returns true on succes, false otherwise. Success means that the socket | 200 // Returns true on succes, false otherwise. Success means that the socket |
213 // could be created and its Connect() was called, not that the connection | 201 // could be created and its Connect() was called, not that the connection |
214 // itself was a success. | 202 // itself was a success. |
215 bool CreateAndConnectSSLClientSocket(SSLConfig& ssl_config, | 203 bool CreateAndConnectSSLClientSocket(SSLConfig& ssl_config, int* result) { |
216 int* result) { | 204 sock_ = CreateSSLClientSocket( |
217 sock_ = CreateSSLClientSocket(transport_.Pass(), | 205 transport_.Pass(), test_server_->host_port_pair(), ssl_config); |
218 test_server_->host_port_pair(), | |
219 ssl_config); | |
220 | 206 |
221 if (sock_->IsConnected()) { | 207 if (sock_->IsConnected()) { |
222 LOG(ERROR) << "SSL Socket prematurely connected"; | 208 LOG(ERROR) << "SSL Socket prematurely connected"; |
223 return false; | 209 return false; |
224 } | 210 } |
225 | 211 |
226 *result = callback_.GetResult(sock_->Connect(callback_.callback())); | 212 *result = callback_.GetResult(sock_->Connect(callback_.callback())); |
227 return true; | 213 return true; |
228 } | 214 } |
229 | 215 |
230 | |
231 // Check that the client certificate was sent. | 216 // Check that the client certificate was sent. |
232 // Returns true on success. | 217 // Returns true on success. |
233 bool CheckSSLClientSocketSentCert() { | 218 bool CheckSSLClientSocketSentCert() { |
234 SSLInfo ssl_info; | 219 SSLInfo ssl_info; |
235 sock_->GetSSLInfo(&ssl_info); | 220 sock_->GetSSLInfo(&ssl_info); |
236 return ssl_info.client_cert_sent; | 221 return ssl_info.client_cert_sent; |
237 } | 222 } |
238 | 223 |
239 scoped_ptr<ServerBoundCertService> cert_service_; | 224 scoped_ptr<ServerBoundCertService> cert_service_; |
240 ClientSocketFactory* socket_factory_; | 225 ClientSocketFactory* socket_factory_; |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 int rv; | 344 int rv; |
360 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); | 345 ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); |
361 | 346 |
362 EXPECT_EQ(ERR_UNEXPECTED, rv); | 347 EXPECT_EQ(ERR_UNEXPECTED, rv); |
363 EXPECT_FALSE(sock_->IsConnected()); | 348 EXPECT_FALSE(sock_->IsConnected()); |
364 } | 349 } |
365 #endif // defined(USE_OPENSSL_CERTS) | 350 #endif // defined(USE_OPENSSL_CERTS) |
366 | 351 |
367 } // namespace | 352 } // namespace |
368 } // namespace net | 353 } // namespace net |
OLD | NEW |