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/webrtc/libjingle/xmllite/xmlelement.h" 11 12namespace remoting { 13namespace 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). 39class PairingAuthenticatorBase : public Authenticator { 40 public: 41 PairingAuthenticatorBase(); 42 virtual ~PairingAuthenticatorBase(); 43 44 // Authenticator interface. 45 virtual State state() const OVERRIDE; 46 virtual bool started() const OVERRIDE; 47 virtual RejectionReason rejection_reason() const OVERRIDE; 48 virtual void ProcessMessage(const buzz::XmlElement* message, 49 const base::Closure& resume_callback) OVERRIDE; 50 virtual scoped_ptr<buzz::XmlElement> GetNextMessage() OVERRIDE; 51 virtual scoped_ptr<ChannelAuthenticator> 52 CreateChannelAuthenticator() const OVERRIDE; 53 54 protected: 55 typedef base::Callback<void(scoped_ptr<Authenticator> authenticator)> 56 SetAuthenticatorCallback; 57 58 static const buzz::StaticQName kPairingInfoTag; 59 static const buzz::StaticQName kClientIdAttribute; 60 61 // Create a V2 authenticator in the specified state, prompting the user for 62 // the PIN first if necessary. 63 virtual void CreateV2AuthenticatorWithPIN( 64 State initial_state, 65 const SetAuthenticatorCallback& callback) = 0; 66 67 // Amend an authenticator message, for example to add client- or host-specific 68 // elements to it. 69 virtual void AddPairingElements(buzz::XmlElement* message) = 0; 70 71 // A non-fatal error message that derived classes should set in order to 72 // cause the peer to be notified that pairing has failed and that it should 73 // fall back on PIN authentication. This string need not be human-readable, 74 // nor is it currently used other than being logged. 75 std::string error_message_; 76 77 // The underlying V2 authenticator, created with either the PIN or the 78 // Paired Secret by the derived class. 79 scoped_ptr<Authenticator> v2_authenticator_; 80 81 // Derived classes must set this to True if the underlying authenticator is 82 // using the Paired Secret. 83 bool using_paired_secret_; 84 85 private: 86 // Helper methods for ProcessMessage and GetNextMessage 87 void MaybeAddErrorMessage(buzz::XmlElement* message); 88 bool HasErrorMessage(const buzz::XmlElement* message) const; 89 void CheckForFailedSpakeExchange(const base::Closure& resume_callback); 90 void SetAuthenticatorAndProcessMessage( 91 const buzz::XmlElement* message, 92 const base::Closure& resume_callback, 93 scoped_ptr<Authenticator> authenticator); 94 95 // Set to true if a PIN-based authenticator has been requested but has not 96 // yet been set. 97 bool waiting_for_authenticator_; 98 99 base::WeakPtrFactory<PairingAuthenticatorBase> weak_factory_; 100 101 DISALLOW_COPY_AND_ASSIGN(PairingAuthenticatorBase); 102}; 103 104} // namespace protocol 105} // namespace remoting 106 107#endif // REMOTING_PROTOCOL_PAIRING_AUTHENTICATOR_H_ 108