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 3 // found in the LICENSE file. 4 5 #ifndef REMOTING_PROTOCOL_PAIRING_AUTHENTICATOR_BASE_H_ 6 #define REMOTING_PROTOCOL_PAIRING_AUTHENTICATOR_BASE_H_ 7 8 #include "base/memory/weak_ptr.h" 9 #include "remoting/protocol/authenticator.h" 10 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 11 12 namespace remoting { 13 namespace protocol { 14 15 // The pairing authenticator builds on top of V2Authenticator to add 16 // support for PIN-less authentication via device pairing: 17 // 18 // * If a client device is already paired, it includes in the initial 19 // authentication message a Client Id and the first SPAKE message 20 // using the Paired Secret and HMAC_SHA256. 21 // * If the host recognizes the Client Id, it looks up the corresponding 22 // Paired Secret and continue the SPAKE exchange. 23 // * If it does not recognize the Client Id, it initiates a SPAKE exchange 24 // with HMAC_SHA256 using the PIN as the shared secret. The initial 25 // message of this exchange includes an an error message, which 26 // informs the client that the PIN-less connection failed and causes 27 // it to prompt the user for a PIN to use for authentication 28 // instead. 29 // * If, at any point, the SPAKE exchange fails with the Paired Secret, 30 // the endpoint that detects the failure initiates a new SPAKE exchange 31 // using the PIN, and includes an error message to instruct the peer 32 // to do likewise. 33 // 34 // If a client device is not already paired, but supports pairing, then 35 // the V2Authenticator is used instead of this class. Only the method name 36 // differs, which the client uses to determine that pairing should be offered 37 // to the user (see NegotiatingHostAuthenticator::CreateAuthenticator and 38 // NegotiatingClientAuthenticator::CreateAuthenticatorForCurrentMethod). 39 class PairingAuthenticatorBase : public Authenticator { 40 public: 41 PairingAuthenticatorBase(); 42 virtual ~PairingAuthenticatorBase(); 43 44 // Authenticator interface. 45 virtual State state() const OVERRIDE; 46 virtual RejectionReason rejection_reason() const OVERRIDE; 47 virtual void ProcessMessage(const buzz::XmlElement* message, 48 const base::Closure& resume_callback) OVERRIDE; 49 virtual scoped_ptr<buzz::XmlElement> GetNextMessage() OVERRIDE; 50 virtual scoped_ptr<ChannelAuthenticator> 51 CreateChannelAuthenticator() const OVERRIDE; 52 53 protected: 54 typedef base::Callback<void(scoped_ptr<Authenticator> authenticator)> 55 SetAuthenticatorCallback; 56 57 static const buzz::StaticQName kPairingInfoTag; 58 static const buzz::StaticQName kClientIdAttribute; 59 60 // Create a V2 authenticator in the specified state, prompting the user for 61 // the PIN first if necessary. 62 virtual void CreateV2AuthenticatorWithPIN( 63 State initial_state, 64 const SetAuthenticatorCallback& callback) = 0; 65 66 // Amend an authenticator message, for example to add client- or host-specific 67 // elements to it. 68 virtual void AddPairingElements(buzz::XmlElement* message) = 0; 69 70 // A non-fatal error message that derived classes should set in order to 71 // cause the peer to be notified that pairing has failed and that it should 72 // fall back on PIN authentication. This string need not be human-readable, 73 // nor is it currently used other than being logged. 74 std::string error_message_; 75 76 // The underlying V2 authenticator, created with either the PIN or the 77 // Paired Secret by the derived class. 78 scoped_ptr<Authenticator> v2_authenticator_; 79 80 // Derived classes must set this to True if the underlying authenticator is 81 // using the Paired Secret. 82 bool using_paired_secret_; 83 84 private: 85 // Helper methods for ProcessMessage and GetNextMessage 86 void MaybeAddErrorMessage(buzz::XmlElement* message); 87 bool HasErrorMessage(const buzz::XmlElement* message) const; 88 void CheckForFailedSpakeExchange(const base::Closure& resume_callback); 89 void SetAuthenticatorAndProcessMessage( 90 const buzz::XmlElement* message, 91 const base::Closure& resume_callback, 92 scoped_ptr<Authenticator> authenticator); 93 94 // Set to true if a PIN-based authenticator has been requested but has not 95 // yet been set. 96 bool waiting_for_authenticator_; 97 98 base::WeakPtrFactory<PairingAuthenticatorBase> weak_factory_; 99 100 DISALLOW_COPY_AND_ASSIGN(PairingAuthenticatorBase); 101 }; 102 103 } // namespace protocol 104 } // namespace remoting 105 106 #endif // REMOTING_PROTOCOL_PAIRING_AUTHENTICATOR_H_ 107