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