Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1393)

Side by Side Diff: remoting/protocol/negotiating_host_authenticator.cc

Issue 1755273003: Simplify AuthenticationMethod type and PIN hash handling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 10 matching lines...) Expand all
21 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" 21 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
22 22
23 namespace remoting { 23 namespace remoting {
24 namespace protocol { 24 namespace protocol {
25 25
26 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator( 26 NegotiatingHostAuthenticator::NegotiatingHostAuthenticator(
27 const std::string& local_cert, 27 const std::string& local_cert,
28 scoped_refptr<RsaKeyPair> key_pair) 28 scoped_refptr<RsaKeyPair> key_pair)
29 : NegotiatingAuthenticatorBase(WAITING_MESSAGE), 29 : NegotiatingAuthenticatorBase(WAITING_MESSAGE),
30 local_cert_(local_cert), 30 local_cert_(local_cert),
31 local_key_pair_(key_pair) { 31 local_key_pair_(key_pair) {}
32
33 // static
34 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateForIt2Me(
35 const std::string& local_cert,
36 scoped_refptr<RsaKeyPair> key_pair,
37 const std::string& access_code) {
38 scoped_ptr<NegotiatingHostAuthenticator> result(
39 new NegotiatingHostAuthenticator(local_cert, key_pair));
40 result->shared_secret_hash_ = access_code;
41 result->AddMethod(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN);
42 return std::move(result);
32 } 43 }
33 44
34 // static 45 // static
35 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithSharedSecret( 46 scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithPin(
36 const std::string& local_cert, 47 const std::string& local_cert,
37 scoped_refptr<RsaKeyPair> key_pair, 48 scoped_refptr<RsaKeyPair> key_pair,
38 const std::string& shared_secret_hash, 49 const std::string& pin_hash,
39 AuthenticationMethod::HashFunction hash_function,
40 scoped_refptr<PairingRegistry> pairing_registry) { 50 scoped_refptr<PairingRegistry> pairing_registry) {
41 scoped_ptr<NegotiatingHostAuthenticator> result( 51 scoped_ptr<NegotiatingHostAuthenticator> result(
42 new NegotiatingHostAuthenticator(local_cert, key_pair)); 52 new NegotiatingHostAuthenticator(local_cert, key_pair));
43 result->shared_secret_hash_ = shared_secret_hash; 53 result->shared_secret_hash_ = pin_hash;
44 result->pairing_registry_ = pairing_registry; 54 result->pairing_registry_ = pairing_registry;
45 result->AddMethod(AuthenticationMethod::Spake2(hash_function)); 55 result->AddMethod(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC);
46 if (pairing_registry.get()) { 56 if (pairing_registry.get()) {
47 result->AddMethod(AuthenticationMethod::Spake2Pair()); 57 result->AddMethod(AuthenticationMethod::SPAKE2_PAIR);
48 } 58 }
49 return std::move(result); 59 return std::move(result);
50 } 60 }
51 61
52 // static 62 // static
53 scoped_ptr<Authenticator> 63 scoped_ptr<Authenticator>
54 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( 64 NegotiatingHostAuthenticator::CreateWithThirdPartyAuth(
55 const std::string& local_cert, 65 const std::string& local_cert,
56 scoped_refptr<RsaKeyPair> key_pair, 66 scoped_refptr<RsaKeyPair> key_pair,
57 scoped_ptr<TokenValidator> token_validator) { 67 scoped_ptr<TokenValidator> token_validator) {
58 scoped_ptr<NegotiatingHostAuthenticator> result( 68 scoped_ptr<NegotiatingHostAuthenticator> result(
59 new NegotiatingHostAuthenticator(local_cert, key_pair)); 69 new NegotiatingHostAuthenticator(local_cert, key_pair));
60 result->token_validator_ = std::move(token_validator); 70 result->token_validator_ = std::move(token_validator);
61 result->AddMethod(AuthenticationMethod::ThirdParty()); 71 result->AddMethod(AuthenticationMethod::THIRD_PARTY);
62 return std::move(result); 72 return std::move(result);
63 } 73 }
64 74
65 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() { 75 NegotiatingHostAuthenticator::~NegotiatingHostAuthenticator() {
66 } 76 }
67 77
68 void NegotiatingHostAuthenticator::ProcessMessage( 78 void NegotiatingHostAuthenticator::ProcessMessage(
69 const buzz::XmlElement* message, 79 const buzz::XmlElement* message,
70 const base::Closure& resume_callback) { 80 const base::Closure& resume_callback) {
71 DCHECK_EQ(state(), WAITING_MESSAGE); 81 DCHECK_EQ(state(), WAITING_MESSAGE);
72 82
73 std::string method_attr = message->Attr(kMethodAttributeQName); 83 std::string method_attr = message->Attr(kMethodAttributeQName);
74 AuthenticationMethod method = AuthenticationMethod::FromString(method_attr); 84 AuthenticationMethod method = ParseAuthenticationMethodString(method_attr);
75 85
76 // If the host has already chosen a method, it can't be changed by the client. 86 // If the host has already chosen a method, it can't be changed by the client.
77 if (current_method_.is_valid() && method != current_method_) { 87 if (current_method_ != AuthenticationMethod::INVALID &&
88 method != current_method_) {
78 state_ = REJECTED; 89 state_ = REJECTED;
79 rejection_reason_ = PROTOCOL_ERROR; 90 rejection_reason_ = PROTOCOL_ERROR;
80 resume_callback.Run(); 91 resume_callback.Run();
81 return; 92 return;
82 } 93 }
83 94
84 // If the client did not specify a preferred auth method, or specified an 95 // If the client did not specify a preferred auth method, or specified an
85 // unknown or unsupported method, then select the first known method from 96 // unknown or unsupported method, then select the first known method from
86 // the supported-methods attribute. 97 // the supported-methods attribute.
87 if (!method.is_valid() || 98 if (method == AuthenticationMethod::INVALID ||
88 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { 99 std::find(methods_.begin(), methods_.end(), method) == methods_.end()) {
89 method = AuthenticationMethod::Invalid(); 100 method = AuthenticationMethod::INVALID;
90 101
91 std::string supported_methods_attr = 102 std::string supported_methods_attr =
92 message->Attr(kSupportedMethodsAttributeQName); 103 message->Attr(kSupportedMethodsAttributeQName);
93 if (supported_methods_attr.empty()) { 104 if (supported_methods_attr.empty()) {
94 // Message contains neither method nor supported-methods attributes. 105 // Message contains neither method nor supported-methods attributes.
95 state_ = REJECTED; 106 state_ = REJECTED;
96 rejection_reason_ = PROTOCOL_ERROR; 107 rejection_reason_ = PROTOCOL_ERROR;
97 resume_callback.Run(); 108 resume_callback.Run();
98 return; 109 return;
99 } 110 }
100 111
101 // Find the first mutually-supported method in the client's list of 112 // Find the first mutually-supported method in the client's list of
102 // supported-methods. 113 // supported-methods.
103 for (const std::string& method_str : 114 for (const std::string& method_str :
104 base::SplitString(supported_methods_attr, 115 base::SplitString(supported_methods_attr,
105 std::string(1, kSupportedMethodsSeparator), 116 std::string(1, kSupportedMethodsSeparator),
106 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { 117 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
107 AuthenticationMethod list_value = 118 AuthenticationMethod list_value =
108 AuthenticationMethod::FromString(method_str); 119 ParseAuthenticationMethodString(method_str);
109 if (list_value.is_valid() && 120 if (list_value != AuthenticationMethod::INVALID &&
110 std::find(methods_.begin(), 121 std::find(methods_.begin(), methods_.end(), list_value) !=
111 methods_.end(), list_value) != methods_.end()) { 122 methods_.end()) {
112 // Found common method. 123 // Found common method.
113 method = list_value; 124 method = list_value;
114 break; 125 break;
115 } 126 }
116 } 127 }
117 128
118 if (!method.is_valid()) { 129 if (method == AuthenticationMethod::INVALID) {
119 // Failed to find a common auth method. 130 // Failed to find a common auth method.
120 state_ = REJECTED; 131 state_ = REJECTED;
121 rejection_reason_ = PROTOCOL_ERROR; 132 rejection_reason_ = PROTOCOL_ERROR;
122 resume_callback.Run(); 133 resume_callback.Run();
123 return; 134 return;
124 } 135 }
125 136
126 // Drop the current message because we've chosen a different method. 137 // Drop the current message because we've chosen a different method.
127 current_method_ = method; 138 current_method_ = method;
128 state_ = PROCESSING_MESSAGE; 139 state_ = PROCESSING_MESSAGE;
129 CreateAuthenticator(MESSAGE_READY, base::Bind( 140 CreateAuthenticator(MESSAGE_READY, base::Bind(
130 &NegotiatingHostAuthenticator::UpdateState, 141 &NegotiatingHostAuthenticator::UpdateState,
131 base::Unretained(this), resume_callback)); 142 base::Unretained(this), resume_callback));
132 return; 143 return;
133 } 144 }
134 145
135 // If the client specified a supported method, and the host hasn't chosen a 146 // If the client specified a supported method, and the host hasn't chosen a
136 // method yet, use the client's preferred method and process the message. 147 // method yet, use the client's preferred method and process the message.
137 if (!current_method_.is_valid()) { 148 if (current_method_ == AuthenticationMethod::INVALID) {
138 current_method_ = method; 149 current_method_ = method;
139 state_ = PROCESSING_MESSAGE; 150 state_ = PROCESSING_MESSAGE;
140 // Copy the message since the authenticator may process it asynchronously. 151 // Copy the message since the authenticator may process it asynchronously.
141 CreateAuthenticator(WAITING_MESSAGE, base::Bind( 152 CreateAuthenticator(WAITING_MESSAGE, base::Bind(
142 &NegotiatingAuthenticatorBase::ProcessMessageInternal, 153 &NegotiatingAuthenticatorBase::ProcessMessageInternal,
143 base::Unretained(this), base::Owned(new buzz::XmlElement(*message)), 154 base::Unretained(this), base::Owned(new buzz::XmlElement(*message)),
144 resume_callback)); 155 resume_callback));
145 return; 156 return;
146 } 157 }
147 158
148 // If the client is using the host's current method, just process the message. 159 // If the client is using the host's current method, just process the message.
149 ProcessMessageInternal(message, resume_callback); 160 ProcessMessageInternal(message, resume_callback);
150 } 161 }
151 162
152 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { 163 scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() {
153 return GetNextMessageInternal(); 164 return GetNextMessageInternal();
154 } 165 }
155 166
156 void NegotiatingHostAuthenticator::CreateAuthenticator( 167 void NegotiatingHostAuthenticator::CreateAuthenticator(
157 Authenticator::State preferred_initial_state, 168 Authenticator::State preferred_initial_state,
158 const base::Closure& resume_callback) { 169 const base::Closure& resume_callback) {
159 DCHECK(current_method_.is_valid()); 170 DCHECK(current_method_ != AuthenticationMethod::INVALID);
160 171
161 if (current_method_.type() == AuthenticationMethod::THIRD_PARTY) { 172 if (current_method_ == AuthenticationMethod::THIRD_PARTY) {
162 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. 173 // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|.
163 // The authentication method negotiation logic should guarantee that only 174 // The authentication method negotiation logic should guarantee that only
164 // one |ThirdPartyHostAuthenticator| will need to be created per session. 175 // one |ThirdPartyHostAuthenticator| will need to be created per session.
165 DCHECK(token_validator_); 176 DCHECK(token_validator_);
166 current_authenticator_.reset(new ThirdPartyHostAuthenticator( 177 current_authenticator_.reset(new ThirdPartyHostAuthenticator(
167 local_cert_, local_key_pair_, std::move(token_validator_))); 178 local_cert_, local_key_pair_, std::move(token_validator_)));
168 } else if (current_method_ == AuthenticationMethod::Spake2Pair() && 179 } else if (current_method_ == AuthenticationMethod::SPAKE2_PAIR &&
169 preferred_initial_state == WAITING_MESSAGE) { 180 preferred_initial_state == WAITING_MESSAGE) {
170 // If the client requested Spake2Pair and sent an initial message, attempt 181 // If the client requested Spake2Pair and sent an initial message, attempt
171 // the paired connection protocol. 182 // the paired connection protocol.
172 current_authenticator_.reset(new PairingHostAuthenticator( 183 current_authenticator_.reset(new PairingHostAuthenticator(
173 pairing_registry_, local_cert_, local_key_pair_, shared_secret_hash_)); 184 pairing_registry_, local_cert_, local_key_pair_, shared_secret_hash_));
174 } else { 185 } else {
175 // In all other cases, use the V2 protocol. Note that this includes the 186 // In all other cases, use the V2 protocol. Note that this includes the
176 // case where the protocol is Spake2Pair but the client is not yet paired. 187 // case where the protocol is Spake2Pair but the client is not yet paired.
177 // In this case, the on-the-wire protocol is plain Spake2, advertised as 188 // In this case, the on-the-wire protocol is plain Spake2, advertised as
178 // Spake2Pair so that the client knows that the host supports pairing and 189 // Spake2Pair so that the client knows that the host supports pairing and
179 // that it can therefore present the option to the user when they enter 190 // that it can therefore present the option to the user when they enter
180 // the PIN. 191 // the PIN.
181 DCHECK(current_method_.type() == AuthenticationMethod::SPAKE2 || 192 DCHECK(current_method_ ==
182 current_method_.type() == AuthenticationMethod::SPAKE2_PAIR); 193 AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN ||
194 current_method_ == AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC ||
195 current_method_ == AuthenticationMethod::SPAKE2_PAIR);
183 current_authenticator_ = V2Authenticator::CreateForHost( 196 current_authenticator_ = V2Authenticator::CreateForHost(
184 local_cert_, local_key_pair_, shared_secret_hash_, 197 local_cert_, local_key_pair_, shared_secret_hash_,
185 preferred_initial_state); 198 preferred_initial_state);
186 } 199 }
187 resume_callback.Run(); 200 resume_callback.Run();
188 } 201 }
189 202
190 } // namespace protocol 203 } // namespace protocol
191 } // namespace remoting 204 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698