diff options
author | sergeyu <sergeyu@chromium.org> | 2016-03-08 21:37:03 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-09 05:38:32 +0000 |
commit | 42cb6f9f0990561fa6c5e8bf436b6dcd60d0b52f (patch) | |
tree | d57de28901a65540030b555029fc6be30cf111f1 /remoting/protocol | |
parent | 020716dc6d2dc9e3e2bd59de86ad27dd50e904b2 (diff) | |
download | chromium_src-42cb6f9f0990561fa6c5e8bf436b6dcd60d0b52f.zip chromium_src-42cb6f9f0990561fa6c5e8bf436b6dcd60d0b52f.tar.gz chromium_src-42cb6f9f0990561fa6c5e8bf436b6dcd60d0b52f.tar.bz2 |
Cleanup AuthenticationMethod usage.
Previously AuthenticationMethod type was used in many places. Removed
all dependencies on it except from NegotiatingAuthenticator classes.
AuthenticationMethod has been moved to
NegotiatingAuthenticatorBase::Method.
Also includes the following cleanups:
- removed old authentication functions from auth_util.cc which were
no longer needed.
- Remove HashFunction enum as it wasn't useful.
BUG=589698
Review URL: https://codereview.chromium.org/1768383004
Cr-Commit-Position: refs/heads/master@{#380078}
Diffstat (limited to 'remoting/protocol')
-rw-r--r-- | remoting/protocol/auth_util.cc | 25 | ||||
-rw-r--r-- | remoting/protocol/auth_util.h | 15 | ||||
-rw-r--r-- | remoting/protocol/authentication_method.cc | 80 | ||||
-rw-r--r-- | remoting/protocol/authentication_method.h | 49 | ||||
-rw-r--r-- | remoting/protocol/me2me_host_authenticator_factory.h | 1 | ||||
-rw-r--r-- | remoting/protocol/negotiating_authenticator_base.cc | 38 | ||||
-rw-r--r-- | remoting/protocol/negotiating_authenticator_base.h | 31 | ||||
-rw-r--r-- | remoting/protocol/negotiating_authenticator_unittest.cc | 86 | ||||
-rw-r--r-- | remoting/protocol/negotiating_client_authenticator.cc | 50 | ||||
-rw-r--r-- | remoting/protocol/negotiating_client_authenticator.h | 6 | ||||
-rw-r--r-- | remoting/protocol/negotiating_host_authenticator.cc | 39 | ||||
-rw-r--r-- | remoting/protocol/negotiating_host_authenticator.h | 12 | ||||
-rw-r--r-- | remoting/protocol/pairing_client_authenticator.cc | 11 | ||||
-rw-r--r-- | remoting/protocol/pairing_client_authenticator.h | 4 |
14 files changed, 168 insertions, 279 deletions
diff --git a/remoting/protocol/auth_util.cc b/remoting/protocol/auth_util.cc index 17263bf..d7eba4d 100644 --- a/remoting/protocol/auth_util.cc +++ b/remoting/protocol/auth_util.cc @@ -22,20 +22,19 @@ const char kHostAuthSslExporterLabel[] = const char kSslFakeHostName[] = "chromoting"; -std::string GenerateSupportAuthToken(const std::string& jid, - const std::string& access_code) { - std::string sha256 = crypto::SHA256HashString(jid + " " + access_code); - std::string sha256_base64; - base::Base64Encode(sha256, &sha256_base64); - return sha256_base64; -} +std::string GetSharedSecretHash(const std::string& tag, + const std::string& shared_secret) { + crypto::HMAC response(crypto::HMAC::SHA256); + if (!response.Init(tag)) { + LOG(FATAL) << "HMAC::Init failed"; + } + + unsigned char out_bytes[kSharedSecretHashLength]; + if (!response.Sign(shared_secret, out_bytes, sizeof(out_bytes))) { + LOG(FATAL) << "HMAC::Sign failed"; + } -bool VerifySupportAuthToken(const std::string& jid, - const std::string& access_code, - const std::string& auth_token) { - std::string expected_token = - GenerateSupportAuthToken(jid, access_code); - return expected_token == auth_token; + return std::string(out_bytes, out_bytes + sizeof(out_bytes)); } // static diff --git a/remoting/protocol/auth_util.h b/remoting/protocol/auth_util.h index 61f98cf..642a943 100644 --- a/remoting/protocol/auth_util.h +++ b/remoting/protocol/auth_util.h @@ -31,18 +31,9 @@ const size_t kSharedSecretHashLength = 32; // Size of the HMAC-SHA-256 digest used for channel authentication. const size_t kAuthDigestLength = 32; -// TODO(sergeyu): The following two methods are used for V1 -// authentication. Remove them when we finally switch to V2 -// authentication method. crbug.com/110483 . - -// Generates auth token for the specified |jid| and |access_code|. -std::string GenerateSupportAuthToken(const std::string& jid, - const std::string& access_code); - -// Verifies validity of an |access_token|. -bool VerifySupportAuthToken(const std::string& jid, - const std::string& access_code, - const std::string& auth_token); +// Returns HMAC-SHA-256 hash for |shared_secret| with the specified |tag|. +std::string GetSharedSecretHash(const std::string& tag, + const std::string& shared_secret); // Returns authentication bytes that must be used for the given // |socket|. Empty string is returned in case of failure. diff --git a/remoting/protocol/authentication_method.cc b/remoting/protocol/authentication_method.cc deleted file mode 100644 index f78b0db..0000000 --- a/remoting/protocol/authentication_method.cc +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "remoting/protocol/authentication_method.h" - -#include "base/logging.h" -#include "crypto/hmac.h" -#include "remoting/protocol/auth_util.h" -#include "remoting/protocol/name_value_map.h" - -namespace remoting { -namespace protocol { - -const NameMapElement<AuthenticationMethod> kAuthenticationMethodStrings[] = { - {AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN, "spake2_plain"}, - {AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC, "spake2_hmac"}, - {AuthenticationMethod::SPAKE2_PAIR, "spake2_pair"}, - {AuthenticationMethod::THIRD_PARTY, "third_party"}}; - -AuthenticationMethod ParseAuthenticationMethodString(const std::string& value) { - AuthenticationMethod result; - if (!NameToValue(kAuthenticationMethodStrings, value, &result)) - return AuthenticationMethod::INVALID; - return result; -} - -const std::string AuthenticationMethodToString( - AuthenticationMethod method) { - return ValueToName(kAuthenticationMethodStrings, method); -} - -HashFunction GetHashFunctionForAuthenticationMethod( - AuthenticationMethod method) { - switch (method) { - case AuthenticationMethod::INVALID: - NOTREACHED(); - return HashFunction::NONE; - - case AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN: - case AuthenticationMethod::THIRD_PARTY: - return HashFunction::NONE; - - case AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC: - case AuthenticationMethod::SPAKE2_PAIR: - return HashFunction::HMAC_SHA256; - } - - NOTREACHED(); - return HashFunction::NONE; -} - -std::string ApplySharedSecretHashFunction(HashFunction hash_function, - const std::string& tag, - const std::string& shared_secret) { - switch (hash_function) { - case HashFunction::NONE: - return shared_secret; - - case HashFunction::HMAC_SHA256: { - crypto::HMAC response(crypto::HMAC::SHA256); - if (!response.Init(tag)) { - LOG(FATAL) << "HMAC::Init failed"; - } - - unsigned char out_bytes[kSharedSecretHashLength]; - if (!response.Sign(shared_secret, out_bytes, sizeof(out_bytes))) { - LOG(FATAL) << "HMAC::Sign failed"; - } - - return std::string(out_bytes, out_bytes + sizeof(out_bytes)); - } - } - - NOTREACHED(); - return shared_secret; -} - -} // namespace protocol -} // namespace remoting diff --git a/remoting/protocol/authentication_method.h b/remoting/protocol/authentication_method.h deleted file mode 100644 index 1b8dc46..0000000 --- a/remoting/protocol/authentication_method.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#ifndef REMOTING_PROTOCOL_AUTHENTICATION_METHOD_H_ -#define REMOTING_PROTOCOL_AUTHENTICATION_METHOD_H_ - -#include <string> - -namespace remoting { -namespace protocol { - -class Authenticator; - -// AuthenticationMethod represents an authentication algorithm. -enum class AuthenticationMethod { - INVALID, - SPAKE2_SHARED_SECRET_PLAIN, - SPAKE2_SHARED_SECRET_HMAC, - SPAKE2_PAIR, - THIRD_PARTY -}; - -enum class HashFunction { - NONE, - HMAC_SHA256, -}; - -// Parses a string that defines an authentication method. Returns -// AuthenticationMethod::INVALID if the string is invalid. -AuthenticationMethod ParseAuthenticationMethodString(const std::string& value); - -// Returns string representation of |method|. -const std::string AuthenticationMethodToString(AuthenticationMethod method); - -// Returns hash function applied to the shared secret on both ends for the -// spefied |method|. -HashFunction GetHashFunctionForAuthenticationMethod( - AuthenticationMethod method); - -// Applies the specified hash function to |shared_secret| with the -// specified |tag| as a key. -std::string ApplySharedSecretHashFunction(HashFunction hash_function, - const std::string& tag, - const std::string& shared_secret); - -} // namespace protocol -} // namespace remoting - -#endif // REMOTING_PROTOCOL_AUTHENTICATION_METHOD_H_ diff --git a/remoting/protocol/me2me_host_authenticator_factory.h b/remoting/protocol/me2me_host_authenticator_factory.h index 0f1cc7d..cda0989 100644 --- a/remoting/protocol/me2me_host_authenticator_factory.h +++ b/remoting/protocol/me2me_host_authenticator_factory.h @@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/third_party_host_authenticator.h" #include "remoting/protocol/token_validator.h" diff --git a/remoting/protocol/negotiating_authenticator_base.cc b/remoting/protocol/negotiating_authenticator_base.cc index dbb3aac..5fe8129 100644 --- a/remoting/protocol/negotiating_authenticator_base.cc +++ b/remoting/protocol/negotiating_authenticator_base.cc @@ -13,11 +13,26 @@ #include "base/strings/string_split.h" #include "remoting/base/rsa_key_pair.h" #include "remoting/protocol/channel_authenticator.h" +#include "remoting/protocol/name_value_map.h" #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" namespace remoting { namespace protocol { +namespace { + +const NameMapElement<NegotiatingAuthenticatorBase::Method> + kAuthenticationMethodStrings[] = { + {NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_PLAIN, + "spake2_plain"}, + {NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_HMAC, + "spake2_hmac"}, + {NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR, "spake2_pair"}, + {NegotiatingAuthenticatorBase::Method::THIRD_PARTY, "third_party"}, +}; + +} // namespace + const buzz::StaticQName NegotiatingAuthenticatorBase::kMethodAttributeQName = { "", "method" }; const buzz::StaticQName @@ -47,6 +62,20 @@ NegotiatingAuthenticatorBase::rejection_reason() const { return rejection_reason_; } +// static +NegotiatingAuthenticatorBase::Method +NegotiatingAuthenticatorBase::ParseMethodString(const std::string& value) { + Method result; + if (!NameToValue(kAuthenticationMethodStrings, value, &result)) + return Method::INVALID; + return result; +} + +// static +std::string NegotiatingAuthenticatorBase::MethodToString(Method method) { + return ValueToName(kAuthenticationMethodStrings, method); +} + void NegotiatingAuthenticatorBase::ProcessMessageInternal( const buzz::XmlElement* message, const base::Closure& resume_callback) { @@ -78,7 +107,7 @@ void NegotiatingAuthenticatorBase::UpdateState( scoped_ptr<buzz::XmlElement> NegotiatingAuthenticatorBase::GetNextMessageInternal() { DCHECK_EQ(state(), MESSAGE_READY); - DCHECK(current_method_ != AuthenticationMethod::INVALID); + DCHECK(current_method_ != Method::INVALID); scoped_ptr<buzz::XmlElement> result; if (current_authenticator_->state() == MESSAGE_READY) { @@ -88,13 +117,12 @@ NegotiatingAuthenticatorBase::GetNextMessageInternal() { } state_ = current_authenticator_->state(); DCHECK(state_ == ACCEPTED || state_ == WAITING_MESSAGE); - result->AddAttr(kMethodAttributeQName, - AuthenticationMethodToString(current_method_)); + result->AddAttr(kMethodAttributeQName, MethodToString(current_method_)); return result; } -void NegotiatingAuthenticatorBase::AddMethod(AuthenticationMethod method) { - DCHECK(method != AuthenticationMethod::INVALID); +void NegotiatingAuthenticatorBase::AddMethod(Method method) { + DCHECK(method != Method::INVALID); methods_.push_back(method); } diff --git a/remoting/protocol/negotiating_authenticator_base.h b/remoting/protocol/negotiating_authenticator_base.h index 4d67a80..a920af4 100644 --- a/remoting/protocol/negotiating_authenticator_base.h +++ b/remoting/protocol/negotiating_authenticator_base.h @@ -8,10 +8,10 @@ #include <string> #include <vector> +#include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" @@ -60,6 +60,15 @@ namespace protocol { // mix of webapp, client plugin and host, for both Me2Me and IT2Me. class NegotiatingAuthenticatorBase : public Authenticator { public: + // Method represents an authentication algorithm. + enum class Method { + INVALID, + SPAKE2_SHARED_SECRET_PLAIN, + SPAKE2_SHARED_SECRET_HMAC, + SPAKE2_PAIR, + THIRD_PARTY, + }; + ~NegotiatingAuthenticatorBase() override; // Authenticator interface. @@ -74,18 +83,24 @@ class NegotiatingAuthenticatorBase : public Authenticator { void ProcessMessageInternal(const buzz::XmlElement* message, const base::Closure& resume_callback); - const AuthenticationMethod& current_method_for_testing() const { - return current_method_; - } - protected: + friend class NegotiatingAuthenticatorTest; + FRIEND_TEST_ALL_PREFIXES(NegotiatingAuthenticatorTest, IncompatibleMethods); + static const buzz::StaticQName kMethodAttributeQName; static const buzz::StaticQName kSupportedMethodsAttributeQName; static const char kSupportedMethodsSeparator; + // Parses a string that defines an authentication method. Returns + // Method::INVALID if the string is invalid. + static Method ParseMethodString(const std::string& value); + + // Returns string representation of |method|. + static std::string MethodToString(Method method); + explicit NegotiatingAuthenticatorBase(Authenticator::State initial_state); - void AddMethod(AuthenticationMethod method); + void AddMethod(Method method); // Updates |state_| to reflect the current underlying authenticator state. // |resume_callback| is called after the state is updated. @@ -95,8 +110,8 @@ class NegotiatingAuthenticatorBase : public Authenticator { // the 'method' tag with |current_method_|. virtual scoped_ptr<buzz::XmlElement> GetNextMessageInternal(); - std::vector<AuthenticationMethod> methods_; - AuthenticationMethod current_method_ = AuthenticationMethod::INVALID; + std::vector<Method> methods_; + Method current_method_ = Method::INVALID; scoped_ptr<Authenticator> current_authenticator_; State state_; RejectionReason rejection_reason_ = INVALID_CREDENTIALS; diff --git a/remoting/protocol/negotiating_authenticator_unittest.cc b/remoting/protocol/negotiating_authenticator_unittest.cc index 4461d1d..5ed3a32 100644 --- a/remoting/protocol/negotiating_authenticator_unittest.cc +++ b/remoting/protocol/negotiating_authenticator_unittest.cc @@ -6,6 +6,7 @@ #include "base/macros.h" #include "net/base/net_errors.h" #include "remoting/base/rsa_key_pair.h" +#include "remoting/protocol/auth_util.h" #include "remoting/protocol/authenticator_test_base.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/connection_tester.h" @@ -53,33 +54,25 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { const std::string& client_paired_secret, const std::string& client_interactive_pin, const std::string& host_secret, - bool it2me, - bool client_hmac_only) { + bool it2me) { if (it2me) { host_ = NegotiatingHostAuthenticator::CreateForIt2Me( host_cert_, key_pair_, host_secret); } else { - std::string host_secret_hash = ApplySharedSecretHashFunction( - HashFunction::HMAC_SHA256, kTestHostId, host_secret); + std::string host_secret_hash = + GetSharedSecretHash(kTestHostId, host_secret); host_ = NegotiatingHostAuthenticator::CreateWithPin( host_cert_, key_pair_, host_secret_hash, pairing_registry_); } - std::vector<AuthenticationMethod> methods; - methods.push_back(AuthenticationMethod::SPAKE2_PAIR); - methods.push_back(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); - if (!client_hmac_only) { - methods.push_back(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN); - } bool pairing_expected = pairing_registry_.get() != nullptr; FetchSecretCallback fetch_secret_callback = base::Bind(&NegotiatingAuthenticatorTest::FetchSecret, client_interactive_pin, pairing_expected); client_as_negotiating_authenticator_ = new NegotiatingClientAuthenticator( - client_id, client_paired_secret, - kTestHostId, fetch_secret_callback, - nullptr, methods); + client_id, client_paired_secret, kTestHostId, fetch_secret_callback, + nullptr); client_.reset(client_as_negotiating_authenticator_); } @@ -113,7 +106,7 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { } } - void VerifyAccepted(const AuthenticationMethod& expected_method) { + void VerifyAccepted(NegotiatingAuthenticatorBase::Method expected_method) { ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); ASSERT_EQ(Authenticator::ACCEPTED, host_->state()); @@ -132,9 +125,8 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { tester.Start(); message_loop_.Run(); tester.CheckResults(); - EXPECT_EQ( - expected_method, - client_as_negotiating_authenticator_->current_method_for_testing()); + EXPECT_EQ(expected_method, + client_as_negotiating_authenticator_->current_method_); } // Use a bare pointer because the storage is managed by the base class. @@ -148,35 +140,43 @@ class NegotiatingAuthenticatorTest : public AuthenticatorTestBase { TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthMe2MePin) { ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, - kTestPin, kTestPin, false, false)); - VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); + kTestPin, kTestPin, false)); + VerifyAccepted( + NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_HMAC); } TEST_F(NegotiatingAuthenticatorTest, SuccessfulAuthIt2me) { ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, - kTestPin, kTestPin, true, false)); - VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN); + kTestPin, kTestPin, true)); + VerifyAccepted( + NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_PLAIN); } TEST_F(NegotiatingAuthenticatorTest, InvalidMe2MePin) { - ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kNoClientId, kNoPairedSecret, kTestPinBad, kTestPin, false, false)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, + kTestPinBad, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); VerifyRejected(Authenticator::INVALID_CREDENTIALS); } TEST_F(NegotiatingAuthenticatorTest, InvalidIt2MeAccessCode) { - ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, true, false)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, + kTestPin, kTestPinBad, true)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); VerifyRejected(Authenticator::INVALID_CREDENTIALS); } TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { - ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kNoClientId, kNoPairedSecret, kTestPin, kTestPinBad, true, true)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, + kTestPin, kTestPinBad, true)); + std::vector<NegotiatingAuthenticatorBase::Method>* methods = + &(client_as_negotiating_authenticator_->methods_); + methods->erase(std::find( + methods->begin(), methods->end(), + NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_PLAIN)); + ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); VerifyRejected(Authenticator::PROTOCOL_ERROR); @@ -184,57 +184,57 @@ TEST_F(NegotiatingAuthenticatorTest, IncompatibleMethods) { TEST_F(NegotiatingAuthenticatorTest, PairingNotSupported) { ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, - kTestPin, kTestPin, false, false)); + kTestPin, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); - VerifyAccepted(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); + VerifyAccepted( + NegotiatingAuthenticatorBase::Method::SPAKE2_SHARED_SECRET_HMAC); } TEST_F(NegotiatingAuthenticatorTest, PairingSupportedButNotPaired) { CreatePairingRegistry(false); ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kNoClientId, kNoPairedSecret, - kTestPin, kTestPin, false, false)); + kTestPin, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); - VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); + VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); } TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinOkay) { CreatePairingRegistry(false); ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, - kTestPin, kTestPin, false, false)); + kTestPin, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); - VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); + VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); } TEST_F(NegotiatingAuthenticatorTest, PairingRevokedPinBad) { CreatePairingRegistry(false); - ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, false, false)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, + kTestPinBad, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); VerifyRejected(Authenticator::INVALID_CREDENTIALS); } TEST_F(NegotiatingAuthenticatorTest, PairingSucceeded) { CreatePairingRegistry(true); - ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kTestClientId, kTestPairedSecret, kTestPinBad, kTestPin, false, false)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, kTestPairedSecret, + kTestPinBad, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); - VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); + VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); } TEST_F(NegotiatingAuthenticatorTest, PairingSucceededInvalidSecretButPinOkay) { CreatePairingRegistry(true); ASSERT_NO_FATAL_FAILURE(InitAuthenticators( - kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, false, false)); + kTestClientId, kTestPairedSecretBad, kTestPin, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); - VerifyAccepted(AuthenticationMethod::SPAKE2_PAIR); + VerifyAccepted(NegotiatingAuthenticatorBase::Method::SPAKE2_PAIR); } TEST_F(NegotiatingAuthenticatorTest, PairingFailedInvalidSecretAndPin) { CreatePairingRegistry(true); - ASSERT_NO_FATAL_FAILURE(InitAuthenticators(kTestClientId, - kTestPairedSecretBad, kTestPinBad, - kTestPin, false, false)); + ASSERT_NO_FATAL_FAILURE(InitAuthenticators( + kTestClientId, kTestPairedSecretBad, kTestPinBad, kTestPin, false)); ASSERT_NO_FATAL_FAILURE(RunAuthExchange()); VerifyRejected(Authenticator::INVALID_CREDENTIALS); } diff --git a/remoting/protocol/negotiating_client_authenticator.cc b/remoting/protocol/negotiating_client_authenticator.cc index 43b5825..3ea252a 100644 --- a/remoting/protocol/negotiating_client_authenticator.cc +++ b/remoting/protocol/negotiating_client_authenticator.cc @@ -12,6 +12,7 @@ #include "base/callback.h" #include "base/logging.h" #include "base/strings/string_split.h" +#include "remoting/protocol/auth_util.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/pairing_client_authenticator.h" #include "remoting/protocol/v2_authenticator.h" @@ -25,21 +26,18 @@ NegotiatingClientAuthenticator::NegotiatingClientAuthenticator( const std::string& shared_secret, const std::string& authentication_tag, const FetchSecretCallback& fetch_secret_callback, - scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher, - const std::vector<AuthenticationMethod>& methods) + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher) : NegotiatingAuthenticatorBase(MESSAGE_READY), client_pairing_id_(client_pairing_id), shared_secret_(shared_secret), authentication_tag_(authentication_tag), fetch_secret_callback_(fetch_secret_callback), token_fetcher_(std::move(token_fetcher)), - method_set_by_host_(false), weak_factory_(this) { - DCHECK(!methods.empty()); - for (std::vector<AuthenticationMethod>::const_iterator it = methods.begin(); - it != methods.end(); ++it) { - AddMethod(*it); - } + AddMethod(Method::THIRD_PARTY); + AddMethod(Method::SPAKE2_PAIR); + AddMethod(Method::SPAKE2_SHARED_SECRET_HMAC); + AddMethod(Method::SPAKE2_SHARED_SECRET_PLAIN); } NegotiatingClientAuthenticator::~NegotiatingClientAuthenticator() {} @@ -50,13 +48,13 @@ void NegotiatingClientAuthenticator::ProcessMessage( DCHECK_EQ(state(), WAITING_MESSAGE); std::string method_attr = message->Attr(kMethodAttributeQName); - AuthenticationMethod method = ParseAuthenticationMethodString(method_attr); + Method method = ParseMethodString(method_attr); // The host picked a method different from the one the client had selected. if (method != current_method_) { // The host must pick a method that is valid and supported by the client, // and it must not change methods after it has picked one. - if (method_set_by_host_ || method == AuthenticationMethod::INVALID || + if (method_set_by_host_ || method == Method::INVALID || std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { state_ = REJECTED; rejection_reason_ = PROTOCOL_ERROR; @@ -83,7 +81,7 @@ scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { DCHECK_EQ(state(), MESSAGE_READY); // This is the first message to the host, send a list of supported methods. - if (current_method_ == AuthenticationMethod::INVALID) { + if (current_method_ == Method::INVALID) { // If no authentication method has been chosen, see if we can optimistically // choose one. scoped_ptr<buzz::XmlElement> result; @@ -97,10 +95,10 @@ scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { // Include a list of supported methods. std::string supported_methods; - for (AuthenticationMethod method : methods_) { + for (Method method : methods_) { if (!supported_methods.empty()) supported_methods += kSupportedMethodsSeparator; - supported_methods += AuthenticationMethodToString(method); + supported_methods += MethodToString(method); } result->AddAttr(kSupportedMethodsAttributeQName, supported_methods); state_ = WAITING_MESSAGE; @@ -112,8 +110,8 @@ scoped_ptr<buzz::XmlElement> NegotiatingClientAuthenticator::GetNextMessage() { void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod( Authenticator::State preferred_initial_state, const base::Closure& resume_callback) { - DCHECK(current_method_ != AuthenticationMethod::INVALID); - if (current_method_ == AuthenticationMethod::THIRD_PARTY) { + DCHECK(current_method_ != Method::INVALID); + if (current_method_ == Method::THIRD_PARTY) { // |ThirdPartyClientAuthenticator| takes ownership of |token_fetcher_|. // The authentication method negotiation logic should guarantee that only // one |ThirdPartyClientAuthenticator| will need to be created per session. @@ -123,12 +121,10 @@ void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod( std::move(token_fetcher_))); resume_callback.Run(); } else { - DCHECK(current_method_ == - AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN || - current_method_ == AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC || - current_method_ == AuthenticationMethod::SPAKE2_PAIR); - bool pairing_supported = - (current_method_ == AuthenticationMethod::SPAKE2_PAIR); + DCHECK(current_method_ == Method::SPAKE2_SHARED_SECRET_PLAIN || + current_method_ == Method::SPAKE2_PAIR || + current_method_ == Method::SPAKE2_SHARED_SECRET_HMAC); + bool pairing_supported = (current_method_ == Method::SPAKE2_PAIR); SecretFetchedCallback callback = base::Bind( &NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret, weak_factory_.GetWeakPtr(), preferred_initial_state, resume_callback); @@ -138,15 +134,15 @@ void NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod( void NegotiatingClientAuthenticator::CreatePreferredAuthenticator() { if (!client_pairing_id_.empty() && !shared_secret_.empty() && - std::find(methods_.begin(), methods_.end(), - AuthenticationMethod::SPAKE2_PAIR) != methods_.end()) { + std::find(methods_.begin(), methods_.end(), Method::SPAKE2_PAIR) != + methods_.end()) { // If the client specified a pairing id and shared secret, then create a // PairingAuthenticator. current_authenticator_.reset(new PairingClientAuthenticator( client_pairing_id_, shared_secret_, base::Bind(&V2Authenticator::CreateForClient), fetch_secret_callback_, authentication_tag_)); - current_method_ = AuthenticationMethod::SPAKE2_PAIR; + current_method_ = Method::SPAKE2_PAIR; } } @@ -155,9 +151,9 @@ void NegotiatingClientAuthenticator::CreateV2AuthenticatorWithSecret( const base::Closure& resume_callback, const std::string& shared_secret) { current_authenticator_ = V2Authenticator::CreateForClient( - ApplySharedSecretHashFunction( - GetHashFunctionForAuthenticationMethod(current_method_), - authentication_tag_, shared_secret), + (current_method_ == Method::SPAKE2_SHARED_SECRET_PLAIN) + ? shared_secret + : GetSharedSecretHash(authentication_tag_, shared_secret), initial_state); resume_callback.Run(); } diff --git a/remoting/protocol/negotiating_client_authenticator.h b/remoting/protocol/negotiating_client_authenticator.h index 1c03afd9..c664a65 100644 --- a/remoting/protocol/negotiating_client_authenticator.h +++ b/remoting/protocol/negotiating_client_authenticator.h @@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/negotiating_authenticator_base.h" #include "remoting/protocol/third_party_client_authenticator.h" @@ -29,8 +28,7 @@ class NegotiatingClientAuthenticator : public NegotiatingAuthenticatorBase { const std::string& shared_secret, const std::string& authentication_tag, const FetchSecretCallback& fetch_secret_callback, - scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher_, - const std::vector<AuthenticationMethod>& methods); + scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher_); ~NegotiatingClientAuthenticator() override; @@ -80,7 +78,7 @@ class NegotiatingClientAuthenticator : public NegotiatingAuthenticatorBase { scoped_ptr<ThirdPartyClientAuthenticator::TokenFetcher> token_fetcher_; // Internal NegotiatingClientAuthenticator data. - bool method_set_by_host_; + bool method_set_by_host_ = false; base::WeakPtrFactory<NegotiatingClientAuthenticator> weak_factory_; DISALLOW_COPY_AND_ASSIGN(NegotiatingClientAuthenticator); diff --git a/remoting/protocol/negotiating_host_authenticator.cc b/remoting/protocol/negotiating_host_authenticator.cc index bcdb591..bfdb80f 100644 --- a/remoting/protocol/negotiating_host_authenticator.cc +++ b/remoting/protocol/negotiating_host_authenticator.cc @@ -38,7 +38,7 @@ scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateForIt2Me( scoped_ptr<NegotiatingHostAuthenticator> result( new NegotiatingHostAuthenticator(local_cert, key_pair)); result->shared_secret_hash_ = access_code; - result->AddMethod(AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN); + result->AddMethod(Method::SPAKE2_SHARED_SECRET_PLAIN); return std::move(result); } @@ -52,9 +52,9 @@ scoped_ptr<Authenticator> NegotiatingHostAuthenticator::CreateWithPin( new NegotiatingHostAuthenticator(local_cert, key_pair)); result->shared_secret_hash_ = pin_hash; result->pairing_registry_ = pairing_registry; - result->AddMethod(AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC); + result->AddMethod(Method::SPAKE2_SHARED_SECRET_HMAC); if (pairing_registry.get()) { - result->AddMethod(AuthenticationMethod::SPAKE2_PAIR); + result->AddMethod(Method::SPAKE2_PAIR); } return std::move(result); } @@ -68,7 +68,7 @@ NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( scoped_ptr<NegotiatingHostAuthenticator> result( new NegotiatingHostAuthenticator(local_cert, key_pair)); result->token_validator_ = std::move(token_validator); - result->AddMethod(AuthenticationMethod::THIRD_PARTY); + result->AddMethod(Method::THIRD_PARTY); return std::move(result); } @@ -81,11 +81,10 @@ void NegotiatingHostAuthenticator::ProcessMessage( DCHECK_EQ(state(), WAITING_MESSAGE); std::string method_attr = message->Attr(kMethodAttributeQName); - AuthenticationMethod method = ParseAuthenticationMethodString(method_attr); + Method method = ParseMethodString(method_attr); // If the host has already chosen a method, it can't be changed by the client. - if (current_method_ != AuthenticationMethod::INVALID && - method != current_method_) { + if (current_method_ != Method::INVALID && method != current_method_) { state_ = REJECTED; rejection_reason_ = PROTOCOL_ERROR; resume_callback.Run(); @@ -95,9 +94,9 @@ void NegotiatingHostAuthenticator::ProcessMessage( // If the client did not specify a preferred auth method, or specified an // unknown or unsupported method, then select the first known method from // the supported-methods attribute. - if (method == AuthenticationMethod::INVALID || + if (method == Method::INVALID || std::find(methods_.begin(), methods_.end(), method) == methods_.end()) { - method = AuthenticationMethod::INVALID; + method = Method::INVALID; std::string supported_methods_attr = message->Attr(kSupportedMethodsAttributeQName); @@ -115,9 +114,8 @@ void NegotiatingHostAuthenticator::ProcessMessage( base::SplitString(supported_methods_attr, std::string(1, kSupportedMethodsSeparator), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { - AuthenticationMethod list_value = - ParseAuthenticationMethodString(method_str); - if (list_value != AuthenticationMethod::INVALID && + Method list_value = ParseMethodString(method_str); + if (list_value != Method::INVALID && std::find(methods_.begin(), methods_.end(), list_value) != methods_.end()) { // Found common method. @@ -126,7 +124,7 @@ void NegotiatingHostAuthenticator::ProcessMessage( } } - if (method == AuthenticationMethod::INVALID) { + if (method == Method::INVALID) { // Failed to find a common auth method. state_ = REJECTED; rejection_reason_ = PROTOCOL_ERROR; @@ -145,7 +143,7 @@ void NegotiatingHostAuthenticator::ProcessMessage( // If the client specified a supported method, and the host hasn't chosen a // method yet, use the client's preferred method and process the message. - if (current_method_ == AuthenticationMethod::INVALID) { + if (current_method_ == Method::INVALID) { current_method_ = method; state_ = PROCESSING_MESSAGE; // Copy the message since the authenticator may process it asynchronously. @@ -167,9 +165,9 @@ scoped_ptr<buzz::XmlElement> NegotiatingHostAuthenticator::GetNextMessage() { void NegotiatingHostAuthenticator::CreateAuthenticator( Authenticator::State preferred_initial_state, const base::Closure& resume_callback) { - DCHECK(current_method_ != AuthenticationMethod::INVALID); + DCHECK(current_method_ != Method::INVALID); - if (current_method_ == AuthenticationMethod::THIRD_PARTY) { + if (current_method_ == Method::THIRD_PARTY) { // |ThirdPartyHostAuthenticator| takes ownership of |token_validator_|. // The authentication method negotiation logic should guarantee that only // one |ThirdPartyHostAuthenticator| will need to be created per session. @@ -178,7 +176,7 @@ void NegotiatingHostAuthenticator::CreateAuthenticator( base::Bind(&V2Authenticator::CreateForHost, local_cert_, local_key_pair_), std::move(token_validator_))); - } else if (current_method_ == AuthenticationMethod::SPAKE2_PAIR && + } else if (current_method_ == Method::SPAKE2_PAIR && preferred_initial_state == WAITING_MESSAGE) { // If the client requested Spake2Pair and sent an initial message, attempt // the paired connection protocol. @@ -193,10 +191,9 @@ void NegotiatingHostAuthenticator::CreateAuthenticator( // Spake2Pair so that the client knows that the host supports pairing and // that it can therefore present the option to the user when they enter // the PIN. - DCHECK(current_method_ == - AuthenticationMethod::SPAKE2_SHARED_SECRET_PLAIN || - current_method_ == AuthenticationMethod::SPAKE2_SHARED_SECRET_HMAC || - current_method_ == AuthenticationMethod::SPAKE2_PAIR); + DCHECK(current_method_ == Method::SPAKE2_SHARED_SECRET_PLAIN || + current_method_ == Method::SPAKE2_SHARED_SECRET_HMAC || + current_method_ == Method::SPAKE2_PAIR); current_authenticator_ = V2Authenticator::CreateForHost( local_cert_, local_key_pair_, shared_secret_hash_, preferred_initial_state); diff --git a/remoting/protocol/negotiating_host_authenticator.h b/remoting/protocol/negotiating_host_authenticator.h index ed0c8ee..c2e2c54 100644 --- a/remoting/protocol/negotiating_host_authenticator.h +++ b/remoting/protocol/negotiating_host_authenticator.h @@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "remoting/protocol/authentication_method.h" #include "remoting/protocol/authenticator.h" #include "remoting/protocol/negotiating_authenticator_base.h" #include "remoting/protocol/pairing_registry.h" @@ -35,9 +34,9 @@ class NegotiatingHostAuthenticator : public NegotiatingAuthenticatorBase { scoped_refptr<RsaKeyPair> key_pair, const std::string& access_code); - // Creates a host authenticator, using a fixed PIN. - // If |pairing_registry| is non-nullptr then the spake2_pair method will - // be offered, supporting PIN-less authentication. + // Creates a host authenticator, using a fixed PIN. If |pairing_registry| is + // non-nullptr then the paired methods will be offered, supporting + // PIN-less authentication. static scoped_ptr<Authenticator> CreateWithPin( const std::string& local_cert, scoped_refptr<RsaKeyPair> key_pair, @@ -56,9 +55,8 @@ class NegotiatingHostAuthenticator : public NegotiatingAuthenticatorBase { scoped_ptr<buzz::XmlElement> GetNextMessage() override; private: - NegotiatingHostAuthenticator( - const std::string& local_cert, - scoped_refptr<RsaKeyPair> key_pair); + NegotiatingHostAuthenticator(const std::string& local_cert, + scoped_refptr<RsaKeyPair> key_pair); // (Asynchronously) creates an authenticator, and stores it in // |current_authenticator_|. Authenticators that can be started in either diff --git a/remoting/protocol/pairing_client_authenticator.cc b/remoting/protocol/pairing_client_authenticator.cc index 747654c..c4e0b29 100644 --- a/remoting/protocol/pairing_client_authenticator.cc +++ b/remoting/protocol/pairing_client_authenticator.cc @@ -7,8 +7,7 @@ #include "base/bind.h" #include "base/logging.h" #include "remoting/base/constants.h" -#include "remoting/base/rsa_key_pair.h" -#include "remoting/protocol/authentication_method.h" +#include "remoting/protocol/auth_util.h" #include "remoting/protocol/channel_authenticator.h" #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" @@ -20,12 +19,12 @@ PairingClientAuthenticator::PairingClientAuthenticator( const std::string& paired_secret, const CreateBaseAuthenticatorCallback& create_base_authenticator_callback, const FetchSecretCallback& fetch_pin_callback, - const std::string& authentication_tag) + const std::string& host_id) : client_id_(client_id), paired_secret_(paired_secret), create_base_authenticator_callback_(create_base_authenticator_callback), fetch_pin_callback_(fetch_pin_callback), - authentication_tag_(authentication_tag), + host_id_(host_id), weak_factory_(this) { spake2_authenticator_ = create_base_authenticator_callback_.Run(paired_secret_, MESSAGE_READY); @@ -72,9 +71,7 @@ void PairingClientAuthenticator::OnPinFetched( DCHECK(!spake2_authenticator_); waiting_for_pin_ = false; spake2_authenticator_ = create_base_authenticator_callback_.Run( - ApplySharedSecretHashFunction(HashFunction::HMAC_SHA256, - authentication_tag_, pin), - initial_state); + GetSharedSecretHash(host_id_, pin), initial_state); resume_callback.Run(); } diff --git a/remoting/protocol/pairing_client_authenticator.h b/remoting/protocol/pairing_client_authenticator.h index 0e1a709..ad93877 100644 --- a/remoting/protocol/pairing_client_authenticator.h +++ b/remoting/protocol/pairing_client_authenticator.h @@ -19,7 +19,7 @@ class PairingClientAuthenticator : public PairingAuthenticatorBase { const std::string& paired_secret, const CreateBaseAuthenticatorCallback& create_base_authenticator_callback, const FetchSecretCallback& fetch_pin_callback, - const std::string& authentication_tag); + const std::string& host_id); ~PairingClientAuthenticator() override; // Authenticator interface. @@ -42,7 +42,7 @@ class PairingClientAuthenticator : public PairingAuthenticatorBase { std::string paired_secret_; CreateBaseAuthenticatorCallback create_base_authenticator_callback_; FetchSecretCallback fetch_pin_callback_; - std::string authentication_tag_; + std::string host_id_; // Set to true if a PIN-based authenticator has been requested but has not // yet been set. |