1 // Copyright 2017 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 CHROMEOS_SERVICES_SECURE_CHANNEL_SECURE_CHANNEL_H_ 6 #define CHROMEOS_SERVICES_SECURE_CHANNEL_SECURE_CHANNEL_H_ 7 8 #include "base/containers/queue.h" 9 #include "base/macros.h" 10 #include "base/memory/weak_ptr.h" 11 #include "chromeos/components/multidevice/remote_device_ref.h" 12 #include "chromeos/services/secure_channel/authenticator.h" 13 #include "chromeos/services/secure_channel/connection.h" 14 #include "chromeos/services/secure_channel/connection_observer.h" 15 #include "chromeos/services/secure_channel/device_to_device_authenticator.h" 16 #include "chromeos/services/secure_channel/secure_context.h" 17 18 namespace chromeos { 19 20 namespace secure_channel { 21 22 // An authenticated bi-directional channel for exchanging messages with remote 23 // devices. |SecureChannel| manages a |Connection| by initializing it and 24 // authenticating it via a security handshake once the connection has occurred. 25 // Once the channel has been authenticated, messages sent are automatically 26 // encrypted and messages received are automatically decrypted. 27 class SecureChannel : public ConnectionObserver { 28 public: 29 // Enumeration of possible states of connecting to a remote device. 30 // DISCONNECTED: There is no connection to the device, nor is there a 31 // pending connection attempt. 32 // CONNECTING: There is an ongoing connection attempt. 33 // CONNECTED: There is a Bluetooth connection to the device, but the 34 // connection has not yet been authenticated. 35 // AUTHENTICATING: There is an active connection that is currently in the 36 // process of authenticating via a 3-message authentication handshake. 37 // AUTHENTICATED: The connection has been authenticated, and arbitrary 38 // messages can be sent/received to/from the device. 39 // DISCONNECTING: The connection has started disconnecting but has not yet 40 // finished. 41 enum class Status { 42 DISCONNECTED, 43 CONNECTING, 44 CONNECTED, 45 AUTHENTICATING, 46 AUTHENTICATED, 47 DISCONNECTING 48 }; 49 50 static std::string StatusToString(const Status& status); 51 52 class Observer { 53 public: OnSecureChannelStatusChanged(SecureChannel * secure_channel,const Status & old_status,const Status & new_status)54 virtual void OnSecureChannelStatusChanged(SecureChannel* secure_channel, 55 const Status& old_status, 56 const Status& new_status) {} 57 OnMessageReceived(SecureChannel * secure_channel,const std::string & feature,const std::string & payload)58 virtual void OnMessageReceived(SecureChannel* secure_channel, 59 const std::string& feature, 60 const std::string& payload) {} 61 62 // Called when a message has been sent successfully; |sequence_number| 63 // corresponds to the value returned by an earlier call to SendMessage(). OnMessageSent(SecureChannel * secure_channel,int sequence_number)64 virtual void OnMessageSent(SecureChannel* secure_channel, 65 int sequence_number) {} 66 }; 67 68 class Factory { 69 public: 70 static std::unique_ptr<SecureChannel> Create( 71 std::unique_ptr<Connection> connection); 72 73 static void SetFactoryForTesting(Factory* factory); 74 75 protected: 76 virtual std::unique_ptr<SecureChannel> CreateInstance( 77 std::unique_ptr<Connection> connection) = 0; 78 79 private: 80 static Factory* factory_instance_; 81 }; 82 83 ~SecureChannel() override; 84 85 virtual void Initialize(); 86 87 // Sends a message over the connection and returns a sequence number. If the 88 // message is successfully sent, observers will be notified that the message 89 // has been sent and will be provided this sequence number. 90 virtual int SendMessage(const std::string& feature, 91 const std::string& payload); 92 93 virtual void Disconnect(); 94 95 virtual void AddObserver(Observer* observer); 96 virtual void RemoveObserver(Observer* observer); 97 98 // Returns the RSSI of the connection; if no derived class overrides this 99 // function, base::nullopt is returned. 100 virtual void GetConnectionRssi( 101 base::OnceCallback<void(base::Optional<int32_t>)> callback); 102 103 // The |responder_auth| message. Returns null if |secure_context_| is null or 104 // status() != AUTHENTICATED. 105 virtual base::Optional<std::string> GetChannelBindingData(); 106 status()107 Status status() const { return status_; } 108 109 // ConnectionObserver: 110 void OnConnectionStatusChanged(Connection* connection, 111 Connection::Status old_status, 112 Connection::Status new_status) override; 113 void OnMessageReceived(const Connection& connection, 114 const WireMessage& wire_message) override; 115 void OnSendCompleted(const Connection& connection, 116 const WireMessage& wire_message, 117 bool success) override; 118 119 protected: 120 SecureChannel(std::unique_ptr<Connection> connection); 121 122 Status status_; 123 124 private: 125 friend class SecureChannelConnectionTest; 126 127 // Message waiting to be sent. Note that this is *not* the message that will 128 // end up being sent over the wire; before that can be done, the payload must 129 // be encrypted. 130 struct PendingMessage { 131 PendingMessage(const std::string& feature, 132 const std::string& payload, 133 int sequence_number); 134 virtual ~PendingMessage(); 135 136 const std::string feature; 137 const std::string payload; 138 const int sequence_number; 139 }; 140 141 void TransitionToStatus(const Status& new_status); 142 void Authenticate(); 143 void ProcessMessageQueue(); 144 void OnMessageEncoded(const std::string& feature, 145 int sequence_number, 146 const std::string& encoded_message); 147 void OnMessageDecoded(const std::string& feature, 148 const std::string& decoded_message); 149 void OnAuthenticationResult(Authenticator::Result result, 150 std::unique_ptr<SecureContext> secure_context); 151 152 std::unique_ptr<Connection> connection_; 153 std::unique_ptr<Authenticator> authenticator_; 154 std::unique_ptr<SecureContext> secure_context_; 155 base::queue<std::unique_ptr<PendingMessage>> queued_messages_; 156 std::unique_ptr<PendingMessage> pending_message_; 157 int next_sequence_number_ = 0; 158 base::ObserverList<Observer>::Unchecked observer_list_; 159 base::WeakPtrFactory<SecureChannel> weak_ptr_factory_{this}; 160 161 DISALLOW_COPY_AND_ASSIGN(SecureChannel); 162 }; 163 164 } // namespace secure_channel 165 166 } // namespace chromeos 167 168 #endif // CHROMEOS_SERVICES_SECURE_CHANNEL_SECURE_CHANNEL_H_ 169