OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "remoting/host/token_validator_base.h" | 5 #include "remoting/host/token_validator_base.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "net/base/upload_data_stream.h" | 23 #include "net/base/upload_data_stream.h" |
24 #include "net/ssl/client_cert_store.h" | 24 #include "net/ssl/client_cert_store.h" |
25 #if defined(USE_NSS_CERTS) | 25 #if defined(USE_NSS_CERTS) |
26 #include "net/ssl/client_cert_store_nss.h" | 26 #include "net/ssl/client_cert_store_nss.h" |
27 #elif defined(OS_WIN) | 27 #elif defined(OS_WIN) |
28 #include "net/ssl/client_cert_store_win.h" | 28 #include "net/ssl/client_cert_store_win.h" |
29 #elif defined(OS_MACOSX) | 29 #elif defined(OS_MACOSX) |
30 #include "net/ssl/client_cert_store_mac.h" | 30 #include "net/ssl/client_cert_store_mac.h" |
31 #endif | 31 #endif |
32 #include "net/ssl/ssl_cert_request_info.h" | 32 #include "net/ssl/ssl_cert_request_info.h" |
33 #include "net/ssl/ssl_platform_key.h" | |
34 #include "net/ssl/ssl_private_key.h" | 33 #include "net/ssl/ssl_private_key.h" |
35 #include "net/url_request/redirect_info.h" | 34 #include "net/url_request/redirect_info.h" |
36 #include "net/url_request/url_request.h" | 35 #include "net/url_request/url_request.h" |
37 #include "net/url_request/url_request_context.h" | 36 #include "net/url_request/url_request_context.h" |
38 #include "net/url_request/url_request_status.h" | 37 #include "net/url_request/url_request_status.h" |
39 #include "remoting/base/logging.h" | 38 #include "remoting/base/logging.h" |
40 #include "url/gurl.h" | 39 #include "url/gurl.h" |
41 | 40 |
42 namespace { | 41 namespace { |
43 | 42 |
44 const int kBufferSize = 4096; | 43 const int kBufferSize = 4096; |
45 const char kCertIssuerWildCard[] = "*"; | 44 const char kCertIssuerWildCard[] = "*"; |
46 | 45 |
47 // The certificate is valid if: | 46 // The certificate is valid if: |
48 // * The certificate issuer matches exactly |issuer| or the |issuer| is a | 47 // * The certificate issuer matches exactly |issuer| or the |issuer| is a |
49 // wildcard. And | 48 // wildcard. And |
50 // * |now| is within [valid_start, valid_expiry]. | 49 // * |now| is within [valid_start, valid_expiry]. |
51 bool IsCertificateValid(const std::string& issuer, | 50 bool IsCertificateValid(const std::string& issuer, |
52 const base::Time& now, | 51 const base::Time& now, |
53 const scoped_refptr<net::X509Certificate>& cert) { | 52 const net::X509Certificate* cert) { |
54 return (issuer == kCertIssuerWildCard || | 53 return (issuer == kCertIssuerWildCard || |
55 issuer == cert->issuer().common_name) && | 54 issuer == cert->issuer().common_name) && |
56 cert->valid_start() <= now && cert->valid_expiry() > now; | 55 cert->valid_start() <= now && cert->valid_expiry() > now; |
57 } | 56 } |
58 | 57 |
59 // Returns true if the certificate |c1| is worse than |c2|. | 58 // Returns true if the certificate |c1| is worse than |c2|. |
60 // | 59 // |
61 // Criteria: | 60 // Criteria: |
62 // 1. An invalid certificate is always worse than a valid certificate. | 61 // 1. An invalid certificate is always worse than a valid certificate. |
63 // 2. Invalid certificates are equally bad, in which case false will be | 62 // 2. Invalid certificates are equally bad, in which case false will be |
64 // returned. | 63 // returned. |
65 // 3. A certificate with earlier |valid_start| time is worse. | 64 // 3. A certificate with earlier |valid_start| time is worse. |
66 // 4. When |valid_start| are the same, the certificate with earlier | 65 // 4. When |valid_start| are the same, the certificate with earlier |
67 // |valid_expiry| is worse. | 66 // |valid_expiry| is worse. |
68 bool WorseThan(const std::string& issuer, | 67 bool WorseThan(const std::string& issuer, |
69 const base::Time& now, | 68 const base::Time& now, |
70 const scoped_refptr<net::X509Certificate>& c1, | 69 const std::unique_ptr<net::ClientCertIdentity>& i1, |
71 const scoped_refptr<net::X509Certificate>& c2) { | 70 const std::unique_ptr<net::ClientCertIdentity>& i2) { |
| 71 net::X509Certificate* c1 = i1->certificate(); |
| 72 net::X509Certificate* c2 = i2->certificate(); |
| 73 |
72 if (!IsCertificateValid(issuer, now, c2)) | 74 if (!IsCertificateValid(issuer, now, c2)) |
73 return false; | 75 return false; |
74 | 76 |
75 if (!IsCertificateValid(issuer, now, c1)) | 77 if (!IsCertificateValid(issuer, now, c1)) |
76 return true; | 78 return true; |
77 | 79 |
78 if (c1->valid_start() != c2->valid_start()) | 80 if (c1->valid_start() != c2->valid_start()) |
79 return c1->valid_start() < c2->valid_start(); | 81 return c1->valid_start() < c2->valid_start(); |
80 | 82 |
81 return c1->valid_expiry() < c2->valid_expiry(); | 83 return c1->valid_expiry() < c2->valid_expiry(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 // client_cert_store to stay alive until the callback is called. So we must | 205 // client_cert_store to stay alive until the callback is called. So we must |
204 // give it a WeakPtr for |this|, and ownership of the other parameters. | 206 // give it a WeakPtr for |this|, and ownership of the other parameters. |
205 client_cert_store->GetClientCerts( | 207 client_cert_store->GetClientCerts( |
206 *cert_request_info, | 208 *cert_request_info, |
207 base::Bind(&TokenValidatorBase::OnCertificatesSelected, | 209 base::Bind(&TokenValidatorBase::OnCertificatesSelected, |
208 weak_factory_.GetWeakPtr(), base::Owned(client_cert_store))); | 210 weak_factory_.GetWeakPtr(), base::Owned(client_cert_store))); |
209 } | 211 } |
210 | 212 |
211 void TokenValidatorBase::OnCertificatesSelected( | 213 void TokenValidatorBase::OnCertificatesSelected( |
212 net::ClientCertStore* unused, | 214 net::ClientCertStore* unused, |
213 net::CertificateList selected_certs) { | 215 net::ClientCertIdentityList selected_certs) { |
214 const std::string& issuer = | 216 const std::string& issuer = |
215 third_party_auth_config_.token_validation_cert_issuer; | 217 third_party_auth_config_.token_validation_cert_issuer; |
216 | 218 |
217 base::Time now = base::Time::Now(); | 219 base::Time now = base::Time::Now(); |
218 | 220 |
219 auto best_match_position = | 221 auto best_match_position = |
220 std::max_element(selected_certs.begin(), selected_certs.end(), | 222 std::max_element(selected_certs.begin(), selected_certs.end(), |
221 std::bind(&WorseThan, issuer, now, std::placeholders::_1, | 223 std::bind(&WorseThan, issuer, now, std::placeholders::_1, |
222 std::placeholders::_2)); | 224 std::placeholders::_2)); |
223 | 225 |
224 if (best_match_position == selected_certs.end() || | 226 if (best_match_position == selected_certs.end() || |
225 !IsCertificateValid(issuer, now, *best_match_position)) { | 227 !IsCertificateValid(issuer, now, (*best_match_position)->certificate())) { |
226 ContinueWithCertificate(nullptr, nullptr); | 228 ContinueWithCertificate(nullptr, nullptr); |
227 } else { | 229 } else { |
228 ContinueWithCertificate( | 230 scoped_refptr<net::X509Certificate> cert = |
229 best_match_position->get(), | 231 (*best_match_position)->certificate(); |
230 net::FetchClientCertPrivateKey(best_match_position->get()).get()); | 232 net::ClientCertIdentity::SelfOwningAcquirePrivateKey( |
| 233 std::move(*best_match_position), |
| 234 base::Bind(&TokenValidatorBase::ContinueWithCertificate, |
| 235 weak_factory_.GetWeakPtr(), std::move(cert))); |
231 } | 236 } |
232 } | 237 } |
233 | 238 |
234 void TokenValidatorBase::ContinueWithCertificate( | 239 void TokenValidatorBase::ContinueWithCertificate( |
235 net::X509Certificate* client_cert, | 240 scoped_refptr<net::X509Certificate> client_cert, |
236 net::SSLPrivateKey* client_private_key) { | 241 scoped_refptr<net::SSLPrivateKey> client_private_key) { |
237 if (request_) { | 242 if (request_) { |
238 if (client_cert) { | 243 if (client_cert) { |
239 HOST_LOG << "Using certificate issued by: '" | 244 HOST_LOG << "Using certificate issued by: '" |
240 << client_cert->issuer().common_name << "' with start date: '" | 245 << client_cert->issuer().common_name << "' with start date: '" |
241 << client_cert->valid_start() << "' and expiry date: '" | 246 << client_cert->valid_start() << "' and expiry date: '" |
242 << client_cert->valid_expiry() << "'"; | 247 << client_cert->valid_expiry() << "'"; |
243 } | 248 } |
244 | 249 |
245 request_->ContinueWithCertificate(client_cert, client_private_key); | 250 request_->ContinueWithCertificate(std::move(client_cert), |
| 251 std::move(client_private_key)); |
246 } | 252 } |
247 } | 253 } |
248 | 254 |
249 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { | 255 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { |
250 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. | 256 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. |
251 return token_scope == token_scope_; | 257 return token_scope == token_scope_; |
252 } | 258 } |
253 | 259 |
254 std::string TokenValidatorBase::ProcessResponse(int net_result) { | 260 std::string TokenValidatorBase::ProcessResponse(int net_result) { |
255 // Verify that we got a successful response. | 261 // Verify that we got a successful response. |
(...skipping 25 matching lines...) Expand all Loading... |
281 return std::string(); | 287 return std::string(); |
282 } | 288 } |
283 | 289 |
284 std::string shared_secret; | 290 std::string shared_secret; |
285 // Everything is valid, so return the shared secret to the caller. | 291 // Everything is valid, so return the shared secret to the caller. |
286 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); | 292 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); |
287 return shared_secret; | 293 return shared_secret; |
288 } | 294 } |
289 | 295 |
290 } // namespace remoting | 296 } // namespace remoting |
OLD | NEW |