| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/protocol/negotiating_host_authenticator.h" | 5 #include "remoting/protocol/negotiating_host_authenticator.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/strings/string_split.h" | 14 #include "base/strings/string_split.h" |
| 15 #include "remoting/base/rsa_key_pair.h" | 15 #include "remoting/base/rsa_key_pair.h" |
| 16 #include "remoting/protocol/channel_authenticator.h" | 16 #include "remoting/protocol/channel_authenticator.h" |
| 17 #include "remoting/protocol/pairing_host_authenticator.h" | 17 #include "remoting/protocol/pairing_host_authenticator.h" |
| 18 #include "remoting/protocol/pairing_registry.h" | 18 #include "remoting/protocol/pairing_registry.h" |
| 19 #include "remoting/protocol/spake2_authenticator.h" |
| 19 #include "remoting/protocol/token_validator.h" | 20 #include "remoting/protocol/token_validator.h" |
| 20 #include "remoting/protocol/v2_authenticator.h" | 21 #include "remoting/protocol/v2_authenticator.h" |
| 21 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 22 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
| 22 | 23 |
| 23 namespace remoting { | 24 namespace remoting { |
| 24 namespace protocol { | 25 namespace protocol { |
| 25 | 26 |
| 26 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( | 27 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( |
| 28 const std::string& local_id, |
| 29 const std::string& remote_id, |
| 27 const std::string& local_cert, | 30 const std::string& local_cert, |
| 28 scoped_refptr<RsaKeyPair> key_pair) | 31 scoped_refptr<RsaKeyPair> key_pair) |
| 29 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), | 32 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), |
| 33 local_id_(local_id), |
| 34 remote_id_(remote_id), |
| 30 local_cert_(local_cert), | 35 local_cert_(local_cert), |
| 31 local_key_pair_(key_pair) {} | 36 local_key_pair_(key_pair) {} |
| 32 | 37 |
| 33 // static | 38 // static |
| 34 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateForIt2Me( | 39 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateForIt2Me( |
| 40 const std::string& local_id, |
| 41 const std::string& remote_id, |
| 35 const std::string& local_cert, | 42 const std::string& local_cert, |
| 36 scoped_refptr<RsaKeyPair> key_pair, | 43 scoped_refptr<RsaKeyPair> key_pair, |
| 37 const std::string& access_code) { | 44 const std::string& access_code) { |
| 38 scoped_ptr<NegotiatingHostAuthenticator> result( | 45 scoped_ptr<NegotiatingHostAuthenticator> result( |
| 39 new NegotiatingHostAuthenticator(local_cert, key_pair)); | 46 new NegotiatingHostAuthenticator(local_id, remote_id, local_cert, |
| 47 key_pair)); |
| 40 result->shared_secret_hash_ = access_code; | 48 result->shared_secret_hash_ = access_code; |
| 41 result->AddMethod(Method::SPAKE2_SHARED_SECRET_PLAIN); | 49 result->AddMethod(Method::SHARED_SECRET_PLAIN_SPAKE2_P224); |
| 42 return std::move(result); | 50 return std::move(result); |
| 43 } | 51 } |
| 44 | 52 |
| 45 // static | 53 // static |
| 46 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithPin( | 54 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithPin( |
| 55 const std::string& local_id, |
| 56 const std::string& remote_id, |
| 47 const std::string& local_cert, | 57 const std::string& local_cert, |
| 48 scoped_refptr<RsaKeyPair> key_pair, | 58 scoped_refptr<RsaKeyPair> key_pair, |
| 49 const std::string& pin_hash, | 59 const std::string& pin_hash, |
| 50 scoped_refptr<PairingRegistry> pairing_registry) { | 60 scoped_refptr<PairingRegistry> pairing_registry) { |
| 51 scoped_ptr<NegotiatingHostAuthenticator> result( | 61 scoped_ptr<NegotiatingHostAuthenticator> result( |
| 52 new NegotiatingHostAuthenticator(local_cert, key_pair)); | 62 new NegotiatingHostAuthenticator(local_id, remote_id, local_cert, |
| 63 key_pair)); |
| 53 result->shared_secret_hash_ = pin_hash; | 64 result->shared_secret_hash_ = pin_hash; |
| 54 result->pairing_registry_ = pairing_registry; | 65 result->pairing_registry_ = pairing_registry; |
| 55 result->AddMethod(Method::SPAKE2_SHARED_SECRET_HMAC); | 66 result->AddMethod(Method::SHARED_SECRET_SPAKE2_CURVE25519); |
| 67 result->AddMethod(Method::SHARED_SECRET_SPAKE2_P224); |
| 56 if (pairing_registry.get()) { | 68 if (pairing_registry.get()) { |
| 57 result->AddMethod(Method::SPAKE2_PAIR); | 69 result->AddMethod(Method::PAIRED_SPAKE2_P224); |
| 58 } | 70 } |
| 59 return std::move(result); | 71 return std::move(result); |
| 60 } | 72 } |
| 61 | 73 |
| 62 // static | 74 // static |
| 63 scoped_ptr<Authenticator> | 75 scoped_ptr<Authenticator> |
| 64 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( | 76 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( |
| 77 const std::string& local_id, |
| 78 const std::string& remote_id, |
| 65 const std::string& local_cert, | 79 const std::string& local_cert, |
| 66 scoped_refptr<RsaKeyPair> key_pair, | 80 scoped_refptr<RsaKeyPair> key_pair, |
| 67 scoped_ptr<TokenValidator> token_validator) { | 81 scoped_ptr<TokenValidator> token_validator) { |
| 68 scoped_ptr<NegotiatingHostAuthenticator> result( | 82 scoped_ptr<NegotiatingHostAuthenticator> result( |
| 69 new NegotiatingHostAuthenticator(local_cert, key_pair)); | 83 new NegotiatingHostAuthenticator(local_id, remote_id, local_cert, |
| 84 key_pair)); |
| 70 result->token_validator_ = std::move(token_validator); | 85 result->token_validator_ = std::move(token_validator); |
| 71 result->AddMethod(Method::THIRD_PARTY); | 86 result->AddMethod(Method::THIRD_PARTY_SPAKE2_CURVE25519); |
| 87 result->AddMethod(Method::THIRD_PARTY_SPAKE2_P224); |
| 72 return std::move(result); | 88 return std::move(result); |
| 73 } | 89 } |
| 74 | 90 |
| 75 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() { | 91 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() {} |
| 76 } | |
| 77 | 92 |
| 78 void NegotiatingHostAuthenticator::ProcessMessage( | 93 void NegotiatingHostAuthenticator::ProcessMessage( |
| 79 const buzz::XmlElement* message, | 94 const buzz::XmlElement* message, |
| 80 const base::Closure& resume_callback) { | 95 const base::Closure& resume_callback) { |
| 81 DCHECK_EQ(state(), WAITING_MESSAGE); | 96 DCHECK_EQ(state(), WAITING_MESSAGE); |
| 82 | 97 |
| 83 std::string method_attr = message->Attr(kMethodAttributeQName); | 98 std::string method_attr = message->Attr(kMethodAttributeQName); |
| 84 Method method = ParseMethodString(method_attr); | 99 Method method = ParseMethodString(method_attr); |
| 85 | 100 |
| 86 // If the host has already chosen a method, it can't be changed by the client. | 101 // If the host has already chosen a method, it can't be changed by the client. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 | 175 |
| 161 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { | 176 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { |
| 162 return GetNextMessageInternal(); | 177 return GetNextMessageInternal(); |
| 163 } | 178 } |
| 164 | 179 |
| 165 void NegotiatingHostAuthenticator::CreateAuthenticator( | 180 void NegotiatingHostAuthenticator::CreateAuthenticator( |
| 166 Authenticator::State preferred_initial_state, | 181 Authenticator::State preferred_initial_state, |
| 167 const base::Closure& resume_callback) { | 182 const base::Closure& resume_callback) { |
| 168 DCHECK(current_method_ != Method::INVALID); | 183 DCHECK(current_method_ != Method::INVALID); |
| 169 | 184 |
| 170 if (current_method_ == Method::THIRD_PARTY) { | 185 if (current_method_ == Method::THIRD_PARTY_SPAKE2_P224) { |
| 171 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. | 186 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. |
| 172 // The authentication method negotiation logic should guarantee that only | 187 // The authentication method negotiation logic should guarantee that only |
| 173 // one |ThirdPartyHostAuthenticator| will need to be created per session. | 188 // one |ThirdPartyHostAuthenticator| will need to be created per session. |
| 174 DCHECK(token_validator_); | 189 DCHECK(token_validator_); |
| 175 current_authenticator_.reset(new ThirdPartyHostAuthenticator( | 190 current_authenticator_.reset(new ThirdPartyHostAuthenticator( |
| 176 base::Bind(&V2Authenticator::CreateForHost, local_cert_, | 191 base::Bind(&V2Authenticator::CreateForHost, local_cert_, |
| 177 local_key_pair_), | 192 local_key_pair_), |
| 178 std::move(token_validator_))); | 193 std::move(token_validator_))); |
| 179 } else if (current_method_ == Method::SPAKE2_PAIR && | 194 } else if (current_method_ == Method::THIRD_PARTY_SPAKE2_CURVE25519) { |
| 195 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. |
| 196 // The authentication method negotiation logic should guarantee that only |
| 197 // one |ThirdPartyHostAuthenticator| will need to be created per session. |
| 198 DCHECK(token_validator_); |
| 199 current_authenticator_.reset(new ThirdPartyHostAuthenticator( |
| 200 base::Bind(&Spake2Authenticator::CreateForHost, local_id_, remote_id_, |
| 201 local_cert_, local_key_pair_), |
| 202 std::move(token_validator_))); |
| 203 } else if (current_method_ == Method::SHARED_SECRET_SPAKE2_CURVE25519) { |
| 204 current_authenticator_ = Spake2Authenticator::CreateForHost( |
| 205 local_id_, remote_id_, local_cert_, local_key_pair_, |
| 206 shared_secret_hash_, preferred_initial_state); |
| 207 } else if (current_method_ == Method::PAIRED_SPAKE2_P224 && |
| 180 preferred_initial_state == WAITING_MESSAGE) { | 208 preferred_initial_state == WAITING_MESSAGE) { |
| 181 // If the client requested Spake2Pair and sent an initial message, attempt | 209 // If the client requested Spake2Pair and sent an initial message, attempt |
| 182 // the paired connection protocol. | 210 // the paired connection protocol. |
| 183 current_authenticator_.reset(new PairingHostAuthenticator( | 211 current_authenticator_.reset(new PairingHostAuthenticator( |
| 184 pairing_registry_, base::Bind(&V2Authenticator::CreateForHost, | 212 pairing_registry_, base::Bind(&V2Authenticator::CreateForHost, |
| 185 local_cert_, local_key_pair_), | 213 local_cert_, local_key_pair_), |
| 186 shared_secret_hash_)); | 214 shared_secret_hash_)); |
| 187 } else { | 215 } else { |
| 188 // In all other cases, use the V2 protocol. Note that this includes the | 216 // In all other cases, use the V2 protocol. Note that this includes the |
| 189 // case where the protocol is Spake2Pair but the client is not yet paired. | 217 // case where the protocol is Spake2Pair but the client is not yet paired. |
| 190 // In this case, the on-the-wire protocol is plain Spake2, advertised as | 218 // In this case, the on-the-wire protocol is plain Spake2, advertised as |
| 191 // Spake2Pair so that the client knows that the host supports pairing and | 219 // Spake2Pair so that the client knows that the host supports pairing and |
| 192 // that it can therefore present the option to the user when they enter | 220 // that it can therefore present the option to the user when they enter |
| 193 // the PIN. | 221 // the PIN. |
| 194 DCHECK(current_method_ == Method::SPAKE2_SHARED_SECRET_PLAIN || | 222 DCHECK(current_method_ == Method::SHARED_SECRET_PLAIN_SPAKE2_P224 || |
| 195 current_method_ == Method::SPAKE2_SHARED_SECRET_HMAC || | 223 current_method_ == Method::SHARED_SECRET_SPAKE2_P224 || |
| 196 current_method_ == Method::SPAKE2_PAIR); | 224 current_method_ == Method::PAIRED_SPAKE2_P224); |
| 197 current_authenticator_ = V2Authenticator::CreateForHost( | 225 current_authenticator_ = V2Authenticator::CreateForHost( |
| 198 local_cert_, local_key_pair_, shared_secret_hash_, | 226 local_cert_, local_key_pair_, shared_secret_hash_, |
| 199 preferred_initial_state); | 227 preferred_initial_state); |
| 200 } | 228 } |
| 201 resume_callback.Run(); | 229 resume_callback.Run(); |
| 202 } | 230 } |
| 203 | 231 |
| 204 } // namespace protocol | 232 } // namespace protocol |
| 205 } // namespace remoting | 233 } // namespace remoting |
| OLD | NEW |