Chromium Code Reviews| 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 25 matching lines...) Expand all Loading... | |
| 36 #include "net/url_request/url_request.h" | 36 #include "net/url_request/url_request.h" |
| 37 #include "net/url_request/url_request_context.h" | 37 #include "net/url_request/url_request_context.h" |
| 38 #include "net/url_request/url_request_status.h" | 38 #include "net/url_request/url_request_status.h" |
| 39 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 const int kBufferSize = 4096; | 43 const int kBufferSize = 4096; |
| 44 const char kCertIssuerWildCard[] = "*"; | 44 const char kCertIssuerWildCard[] = "*"; |
| 45 | 45 |
| 46 // The certificate is valid if: | |
| 47 // * The issuer matches exactly the expected issuer or the expected issuer is | |
| 48 // a wildcard. | |
| 49 // * |now| is within [valid_start, valid_expiry], or [valid_start, +inf) | |
| 50 // if |valid_expiry| is null. | |
| 51 bool IsCertificateValid(const std::string& issuer, | |
| 52 const base::Time& now, | |
| 53 const scoped_refptr<net::X509Certificate>& cert) { | |
| 54 return (issuer == kCertIssuerWildCard || | |
| 55 issuer == cert->issuer().common_name) && | |
| 56 cert->valid_start() <= now && | |
| 57 (cert->valid_expiry() > now || cert->valid_expiry().is_null()); | |
| 58 } | |
| 59 | |
| 60 // Returns true if |c1| is a worse certificate to use than |c2|. | |
| 61 // | |
| 62 // Criteria: | |
| 63 // 1. An invalid certificate is always worse than a valid certificate. | |
|
Yuwei
2016/09/27 21:37:42
Ideally if there is something like a filtering ite
| |
| 64 // 2. Invalid certificates are equally worse, in which case false will be | |
| 65 // returned. | |
| 66 // 3. A certificate with earlier |valid_start| time is worse. | |
| 67 // 4. When |valid_start| are the same, the certificate with earlier | |
| 68 // |valid_expiry| is worse. | |
| 69 bool WorseThan(const std::string& issuer, | |
| 70 const base::Time& now, | |
| 71 const scoped_refptr<net::X509Certificate>& c1, | |
| 72 const scoped_refptr<net::X509Certificate>& c2) { | |
| 73 bool c1_valid = IsCertificateValid(issuer, now, c1); | |
| 74 bool c2_valid = IsCertificateValid(issuer, now, c2); | |
| 75 | |
| 76 if (!c1_valid && c2_valid) | |
| 77 return true; | |
| 78 | |
| 79 if (!c2_valid) | |
| 80 return false; | |
| 81 | |
| 82 if (c1->valid_start() != c2->valid_start()) | |
| 83 return c1->valid_start() < c2->valid_start(); | |
| 84 | |
| 85 return c1->valid_expiry() < c2->valid_expiry(); | |
| 86 } | |
| 87 | |
| 46 } // namespace | 88 } // namespace |
| 47 | 89 |
| 48 namespace remoting { | 90 namespace remoting { |
| 49 | 91 |
| 50 TokenValidatorBase::TokenValidatorBase( | 92 TokenValidatorBase::TokenValidatorBase( |
| 51 const ThirdPartyAuthConfig& third_party_auth_config, | 93 const ThirdPartyAuthConfig& third_party_auth_config, |
| 52 const std::string& token_scope, | 94 const std::string& token_scope, |
| 53 scoped_refptr<net::URLRequestContextGetter> request_context_getter) | 95 scoped_refptr<net::URLRequestContextGetter> request_context_getter) |
| 54 : third_party_auth_config_(third_party_auth_config), | 96 : third_party_auth_config_(third_party_auth_config), |
| 55 token_scope_(token_scope), | 97 token_scope_(token_scope), |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 client_cert_store->GetClientCerts( | 207 client_cert_store->GetClientCerts( |
| 166 *cert_request_info, selected_certs, | 208 *cert_request_info, selected_certs, |
| 167 base::Bind(&TokenValidatorBase::OnCertificatesSelected, | 209 base::Bind(&TokenValidatorBase::OnCertificatesSelected, |
| 168 weak_factory_.GetWeakPtr(), base::Owned(selected_certs), | 210 weak_factory_.GetWeakPtr(), base::Owned(selected_certs), |
| 169 base::Owned(client_cert_store))); | 211 base::Owned(client_cert_store))); |
| 170 } | 212 } |
| 171 | 213 |
| 172 void TokenValidatorBase::OnCertificatesSelected( | 214 void TokenValidatorBase::OnCertificatesSelected( |
| 173 net::CertificateList* selected_certs, | 215 net::CertificateList* selected_certs, |
| 174 net::ClientCertStore* unused) { | 216 net::ClientCertStore* unused) { |
| 217 if (!request_) | |
| 218 return; | |
| 219 | |
| 175 const std::string& issuer = | 220 const std::string& issuer = |
| 176 third_party_auth_config_.token_validation_cert_issuer; | 221 third_party_auth_config_.token_validation_cert_issuer; |
| 177 if (request_) { | 222 |
| 178 for (size_t i = 0; i < selected_certs->size(); ++i) { | 223 base::Time now = base::Time::Now(); |
| 179 net::X509Certificate* cert = (*selected_certs)[i].get(); | 224 |
| 180 if (issuer == kCertIssuerWildCard || | 225 auto best_match_position = |
| 181 issuer == cert->issuer().common_name) { | 226 std::max_element(selected_certs->begin(), selected_certs->end(), |
| 182 request_->ContinueWithCertificate( | 227 std::bind(&WorseThan, issuer, now, std::placeholders::_1, |
| 183 cert, net::FetchClientCertPrivateKey(cert).get()); | 228 std::placeholders::_2)); |
| 184 return; | 229 |
| 185 } | 230 if (best_match_position == selected_certs->end() || |
| 186 } | 231 !IsCertificateValid(issuer, now, *best_match_position)) { |
| 187 request_->ContinueWithCertificate(nullptr, nullptr); | 232 request_->ContinueWithCertificate(nullptr, nullptr); |
| 233 } else { | |
| 234 request_->ContinueWithCertificate( | |
| 235 best_match_position->get(), | |
| 236 net::FetchClientCertPrivateKey(best_match_position->get()).get()); | |
| 188 } | 237 } |
| 189 } | 238 } |
| 190 | 239 |
| 191 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { | 240 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { |
| 192 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. | 241 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. |
| 193 return token_scope == token_scope_; | 242 return token_scope == token_scope_; |
| 194 } | 243 } |
| 195 | 244 |
| 196 std::string TokenValidatorBase::ProcessResponse(int net_result) { | 245 std::string TokenValidatorBase::ProcessResponse(int net_result) { |
| 197 // Verify that we got a successful response. | 246 // Verify that we got a successful response. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 223 return std::string(); | 272 return std::string(); |
| 224 } | 273 } |
| 225 | 274 |
| 226 std::string shared_secret; | 275 std::string shared_secret; |
| 227 // Everything is valid, so return the shared secret to the caller. | 276 // Everything is valid, so return the shared secret to the caller. |
| 228 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); | 277 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); |
| 229 return shared_secret; | 278 return shared_secret; |
| 230 } | 279 } |
| 231 | 280 |
| 232 } // namespace remoting | 281 } // namespace remoting |
| OLD | NEW |