| // Copyright 2015 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 COMPONENTS_PROXIMITY_DEVICE_TO_DEVICE_AUTHENTICATOR_H | 
 | #define COMPONENTS_PROXIMITY_DEVICE_TO_DEVICE_AUTHENTICATOR_H | 
 |  | 
 | #include "base/callback.h" | 
 | #include "base/macros.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "components/proximity_auth/authenticator.h" | 
 | #include "components/proximity_auth/connection_observer.h" | 
 |  | 
 | namespace base { | 
 | class Timer; | 
 | }; | 
 |  | 
 | namespace proximity_auth { | 
 |  | 
 | class Connection; | 
 | class SecureMessageDelegate; | 
 |  | 
 | // Authenticator implementation using the "device to device" protocol, which is | 
 | // in turn built on top of the SecureMessage library. | 
 | // This protocol contains the following steps (local device is the initiator): | 
 | //   1. Both initiator and responder devices generate a temporary key pair for | 
 | //      the session. | 
 | //   2. Initiator sends [Hello] message to responder device, which contains the | 
 | //      initiator's session public key. | 
 | //   3. Responder responds with a [Responder Auth] message, containing its | 
 | //      session public key and data that allows the initiator to assert the | 
 | //      identity of the responder. | 
 | //   4. Initiator sends [Initiator Auth] message, containing data allowing the | 
 | //      responder to assert the identity of the initiator. | 
 | //   5. Both devices derive a symmetric key by running a key agreement protocol | 
 | //      session public keys they obtain from from the messages above. This | 
 | //      symmetric key is used in the subsequent SecureContext. | 
 | // The authentication protocol fails if any of the steps above fail. | 
 | // This protocol requires exclusive use of the connection. No other message | 
 | // should be sent or received while authentication is in progress. | 
 | class DeviceToDeviceAuthenticator : public Authenticator, | 
 |                                     public ConnectionObserver { | 
 |  public: | 
 |   // Creates the instance: | 
 |   // |connection|: The connection to the remote device, which must be in a | 
 |   //     connected state. Not owned. | 
 |   // |account_id|: The canonical account id of the user who is the owner of both | 
 |   //     the local and remote devices. | 
 |   // |secure_message_delegate|: Handles the SecureMessage crypto operations. | 
 |   DeviceToDeviceAuthenticator( | 
 |       Connection* connection, | 
 |       const std::string& account_id, | 
 |       scoped_ptr<SecureMessageDelegate> secure_message_delegate); | 
 |  | 
 |   ~DeviceToDeviceAuthenticator() override; | 
 |  | 
 |   // Authenticator: | 
 |   void Authenticate(const AuthenticationCallback& callback) override; | 
 |  | 
 |  protected: | 
 |   // Creates a base::Timer instance. Exposed for testing. | 
 |   virtual scoped_ptr<base::Timer> CreateTimer(); | 
 |  | 
 |  private: | 
 |   // The current state of the authentication flow. | 
 |   enum class State { | 
 |     NOT_STARTED, | 
 |     GENERATING_SESSION_KEYS, | 
 |     SENDING_HELLO, | 
 |     SENT_HELLO, | 
 |     RECEIVED_RESPONDER_AUTH, | 
 |     VALIDATED_RESPONDER_AUTH, | 
 |     SENT_INITIATOR_AUTH, | 
 |     AUTHENTICATION_SUCCESS, | 
 |     AUTHENTICATION_FAILURE, | 
 |   }; | 
 |  | 
 |   // Callback when the session key pair is generated. | 
 |   void OnKeyPairGenerated(const std::string& public_key, | 
 |                           const std::string& private_key); | 
 |  | 
 |   // Callback when [Hello] is created. | 
 |   void OnHelloMessageCreated(const std::string& message); | 
 |  | 
 |   // Callback when waiting for [Remote Auth] times out. | 
 |   void OnResponderAuthTimedOut(); | 
 |  | 
 |   // Callback for validating the received [Remote Auth]. | 
 |   void OnResponderAuthValidated(bool validated, | 
 |                                 const std::string& session_symmetric_key); | 
 |  | 
 |   // Callback when [Initiator Auth] is created. | 
 |   void OnInitiatorAuthCreated(const std::string& message); | 
 |  | 
 |   // Callback when the session symmetric key is derived. | 
 |   void OnKeyDerived(const std::string& session_symmetric_key); | 
 |  | 
 |   // Called when the authentication flow fails, and logs |error_message|. The | 
 |   // overloaded version specifies the Result to be reported; | 
 |   // otherwise, a FAILURE result will be reported. | 
 |   void Fail(const std::string& error_message); | 
 |   void Fail(const std::string& error_message, Result result); | 
 |  | 
 |   // Called when the authentication flow succeeds. | 
 |   void Succeed(); | 
 |  | 
 |   // ConnectionObserver: | 
 |   void OnConnectionStatusChanged(Connection* connection, | 
 |                                  Connection::Status old_status, | 
 |                                  Connection::Status new_status) override; | 
 |   void OnMessageReceived(const Connection& connection, | 
 |                          const WireMessage& message) override; | 
 |   void OnSendCompleted(const Connection& connection, | 
 |                        const WireMessage& message, | 
 |                        bool success) override; | 
 |  | 
 |   // The connection to the remote device. It is expected to be in the CONNECTED | 
 |   // state at all times during authentication. | 
 |   // Not owned, and must outlive this instance. | 
 |   Connection* const connection_; | 
 |  | 
 |   // The account id of the user who owns the local and remote devices. This is | 
 |   // normally an email address, and should be canonicalized. | 
 |   const std::string account_id_; | 
 |  | 
 |   // Handles SecureMessage crypto operations. | 
 |   scoped_ptr<SecureMessageDelegate> secure_message_delegate_; | 
 |  | 
 |   // The current state in the authentication flow. | 
 |   State state_; | 
 |  | 
 |   // Callback to invoke when authentication completes. | 
 |   AuthenticationCallback callback_; | 
 |  | 
 |   // Used for timing out when waiting for [Remote Auth] from the remote device. | 
 |   scoped_ptr<base::Timer> timer_; | 
 |  | 
 |   // The bytes of the [Hello] message sent to the remote device. | 
 |   std::string hello_message_; | 
 |  | 
 |   // The bytes of the [Responder Auth] message received from the remote device. | 
 |   std::string responder_auth_message_; | 
 |  | 
 |   // The private key generated for the session. | 
 |   std::string local_session_private_key_; | 
 |  | 
 |   // The derived symmetric key for the session. | 
 |   std::string session_symmetric_key_; | 
 |  | 
 |   base::WeakPtrFactory<DeviceToDeviceAuthenticator> weak_ptr_factory_; | 
 |  | 
 |   DISALLOW_COPY_AND_ASSIGN(DeviceToDeviceAuthenticator); | 
 | }; | 
 |  | 
 | }  // namespace proximity_auth | 
 |  | 
 | #endif  // COMPONENTS_PROXIMITY_DEVICE_TO_DEVICE_AUTHENTICATOR_H |