[adbwifi] Add A_STLS command.

This command will be sent by adbd to notify the client that the
connection will be over TLS.

When client connects, it will send the CNXN packet, as usual. If the
server connection has TLS enabled, it will send the A_STLS packet
(regardless of whether auth is required). At this point, the client's
only valid response is to send a A_STLS packet. Once both sides have
exchanged the A_STLS packet, both will start the TLS handshake.

If auth is required, then the client will receive a CertificateRequest
with a list of known public keys (SHA256 hash) that it can use in its
certificate. Otherwise, the list will be empty and the client can assume
that either any key will work, or none will work.

If the handshake was successful, the server will send the CNXN packet
and the usual adb protocol is resumed over TLS. If the handshake failed,
both sides will disconnect, as there's no point to retry because the
server's known keys have already been communicated.

Bug: 111434128

Test: WIP; will add to adb_test.py/adb_device.py.

Enable wireless debugging in the Settings, then 'adb connect
<ip>:<port>'. Connection should succeed if key is in keystore. Used
wireshark to check for packet encryption.

Change-Id: I3d60647491c6c6b92297e4f628707a6457fa9420
diff --git a/transport.h b/transport.h
index 5a750ee..8a0f62a 100644
--- a/transport.h
+++ b/transport.h
@@ -43,6 +43,14 @@
 
 typedef std::unordered_set<std::string> FeatureSet;
 
+namespace adb {
+namespace tls {
+
+class TlsConnection;
+
+}  // namespace tls
+}  // namespace adb
+
 const FeatureSet& supported_features();
 
 // Encodes and decodes FeatureSet objects into human-readable strings.
@@ -104,6 +112,8 @@
     virtual void Start() = 0;
     virtual void Stop() = 0;
 
+    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0;
+
     // Stop, and reset the device if it's a USB connection.
     virtual void Reset();
 
@@ -128,6 +138,8 @@
     virtual bool Read(apacket* packet) = 0;
     virtual bool Write(apacket* packet) = 0;
 
+    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key = nullptr) = 0;
+
     // Terminate a connection.
     // This method must be thread-safe, and must cause concurrent Reads/Writes to terminate.
     // Formerly known as 'Kick' in atransport.
@@ -146,9 +158,12 @@
 
     virtual void Start() override final;
     virtual void Stop() override final;
+    virtual bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
 
     virtual void Reset() override final;
 
+  private:
+    void StartReadThread() REQUIRES(mutex_);
     bool started_ GUARDED_BY(mutex_) = false;
     bool stopped_ GUARDED_BY(mutex_) = false;
 
@@ -164,16 +179,22 @@
 };
 
 struct FdConnection : public BlockingConnection {
-    explicit FdConnection(unique_fd fd) : fd_(std::move(fd)) {}
+    explicit FdConnection(unique_fd fd);
+    ~FdConnection();
 
     bool Read(apacket* packet) override final;
     bool Write(apacket* packet) override final;
+    bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
 
     void Close() override;
     virtual void Reset() override final { Close(); }
 
   private:
+    bool DispatchRead(void* buf, size_t len);
+    bool DispatchWrite(void* buf, size_t len);
+
     unique_fd fd_;
+    std::unique_ptr<adb::tls::TlsConnection> tls_;
 };
 
 struct UsbConnection : public BlockingConnection {
@@ -182,6 +203,7 @@
 
     bool Read(apacket* packet) override final;
     bool Write(apacket* packet) override final;
+    bool DoTlsHandshake(RSA* key, std::string* auth_key) override final;
 
     void Close() override final;
     virtual void Reset() override final;
@@ -279,6 +301,12 @@
     std::string device;
     std::string devpath;
 
+    // If this is set, the transport will initiate the connection with a
+    // START_TLS command, instead of AUTH.
+    bool use_tls = false;
+    int tls_version = A_STLS_VERSION;
+    int get_tls_version() const;
+
 #if !ADB_HOST
     // Used to provide the key to the framework.
     std::string auth_key;
@@ -288,6 +316,8 @@
     bool IsTcpDevice() const { return type == kTransportLocal; }
 
 #if ADB_HOST
+    // The current key being authorized.
+    std::shared_ptr<RSA> Key();
     std::shared_ptr<RSA> NextKey();
     void ResetKeys();
 #endif
@@ -400,6 +430,10 @@
 atransport* find_transport(const char* serial);
 void kick_all_tcp_devices();
 void kick_all_transports();
+void kick_all_tcp_tls_transports();
+#if !ADB_HOST
+void kick_all_transports_by_auth_key(std::string_view auth_key);
+#endif
 
 void register_transport(atransport* transport);
 void register_usb_transport(usb_handle* h, const char* serial,
@@ -410,7 +444,8 @@
 
 /* cause new transports to be init'd and added to the list */
 bool register_socket_transport(unique_fd s, std::string serial, int port, int local,
-                               atransport::ReconnectCallback reconnect, int* error = nullptr);
+                               atransport::ReconnectCallback reconnect, bool use_tls,
+                               int* error = nullptr);
 
 // This should only be used for transports with connection_state == kCsNoPerm.
 void unregister_usb_transport(usb_handle* usb);