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 |