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. And | |
| 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 the certificate |c1| is worse than |c2|. | |
| 61 // | |
| 62 // Criteria: | |
| 63 // 1. An invalid certificate is always worse than a valid certificate. | |
| 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) | |
|
Lambros
2016/09/27 22:13:58
Optional: If this 'if' were moved before the first
Yuwei
2016/09/27 22:22:49
Done. It can be simplified a lot actually :)
| |
| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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) { |
| 175 const std::string& issuer = | 217 const std::string& issuer = |
| 176 third_party_auth_config_.token_validation_cert_issuer; | 218 third_party_auth_config_.token_validation_cert_issuer; |
| 177 if (request_) { | 219 |
| 178 for (size_t i = 0; i < selected_certs->size(); ++i) { | 220 base::Time now = base::Time::Now(); |
| 179 net::X509Certificate* cert = (*selected_certs)[i].get(); | 221 |
| 180 if (issuer == kCertIssuerWildCard || | 222 auto best_match_position = |
| 181 issuer == cert->issuer().common_name) { | 223 std::max_element(selected_certs->begin(), selected_certs->end(), |
| 182 request_->ContinueWithCertificate( | 224 std::bind(&WorseThan, issuer, now, std::placeholders::_1, |
| 183 cert, net::FetchClientCertPrivateKey(cert).get()); | 225 std::placeholders::_2)); |
| 184 return; | 226 |
| 185 } | 227 if (best_match_position == selected_certs->end() || |
| 186 } | 228 !IsCertificateValid(issuer, now, *best_match_position)) { |
| 187 request_->ContinueWithCertificate(nullptr, nullptr); | 229 ContinueWithCertificate(nullptr, nullptr); |
| 230 } else { | |
| 231 ContinueWithCertificate( | |
| 232 best_match_position->get(), | |
| 233 net::FetchClientCertPrivateKey(best_match_position->get()).get()); | |
| 188 } | 234 } |
| 189 } | 235 } |
| 190 | 236 |
| 237 void TokenValidatorBase::ContinueWithCertificate( | |
| 238 net::X509Certificate* client_cert, | |
| 239 net::SSLPrivateKey* client_private_key) { | |
| 240 if (request_) { | |
| 241 request_->ContinueWithCertificate(client_cert, client_private_key); | |
| 242 } | |
| 243 } | |
| 244 | |
| 191 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { | 245 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { |
| 192 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. | 246 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. |
| 193 return token_scope == token_scope_; | 247 return token_scope == token_scope_; |
| 194 } | 248 } |
| 195 | 249 |
| 196 std::string TokenValidatorBase::ProcessResponse(int net_result) { | 250 std::string TokenValidatorBase::ProcessResponse(int net_result) { |
| 197 // Verify that we got a successful response. | 251 // Verify that we got a successful response. |
| 198 if (net_result != net::OK) { | 252 if (net_result != net::OK) { |
| 199 LOG(ERROR) << "Error validating token, err=" << net_result; | 253 LOG(ERROR) << "Error validating token, err=" << net_result; |
| 200 return std::string(); | 254 return std::string(); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 223 return std::string(); | 277 return std::string(); |
| 224 } | 278 } |
| 225 | 279 |
| 226 std::string shared_secret; | 280 std::string shared_secret; |
| 227 // Everything is valid, so return the shared secret to the caller. | 281 // Everything is valid, so return the shared secret to the caller. |
| 228 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); | 282 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); |
| 229 return shared_secret; | 283 return shared_secret; |
| 230 } | 284 } |
| 231 | 285 |
| 232 } // namespace remoting | 286 } // namespace remoting |
| OLD | NEW |