1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <stddef.h> 20 #include <stdint.h> 21 22 #include <functional> 23 #include <string_view> 24 #include <vector> 25 26 #include <android-base/unique_fd.h> 27 #include <openssl/ssl.h> 28 #include <openssl/x509.h> 29 30 namespace adb { 31 namespace tls { 32 33 class TlsConnection { 34 public: 35 // This class will require both client and server to exchange valid 36 // certificates. 37 enum class Role { 38 Server, 39 Client, 40 }; 41 42 enum class TlsError : uint8_t { 43 Success = 0, 44 // An error indicating that we rejected the peer's certificate. 45 CertificateRejected, 46 // An error indicating that the peer rejected our certificate. 47 PeerRejectedCertificate, 48 // Add more if needed 49 UnknownFailure, 50 }; 51 52 using CertVerifyCb = std::function<int(X509_STORE_CTX*)>; 53 using SetCertCb = std::function<int(SSL*)>; 54 55 virtual ~TlsConnection() = default; 56 57 // Adds a trusted certificate to the list for the SSL connection. 58 // During the handshake phase, it will check the list of trusted certificates. 59 // The connection will fail if the peer's certificate is not in the list. If 60 // you would like to accept any certificate, use #SetCertVerifyCallback and 61 // set your callback to always return 1. 62 // 63 // Returns true if |cert| was successfully added, false otherwise. 64 virtual bool AddTrustedCertificate(std::string_view cert) = 0; 65 66 // Sets a custom certificate verify callback. |cb| must return 1 if the 67 // certificate is trusted. Otherwise, return 0 if not. 68 virtual void SetCertVerifyCallback(CertVerifyCb cb) = 0; 69 70 // Configures a client |ca_list| that the server sends to the client in the 71 // CertificateRequest message. 72 virtual void SetClientCAList(STACK_OF(X509_NAME) * ca_list) = 0; 73 74 // Sets a callback that will be called to select a certificate. See 75 // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_cert_cb 76 // for more details. 77 virtual void SetCertificateCallback(SetCertCb cb) = 0; 78 79 // Exports a value derived from the master secret used in the TLS 80 // connection. This value should be used alongside any PAKE to ensure the 81 // peer is the intended peer. |length| is the requested length for the 82 // keying material. This is only valid after |DoHandshake| succeeds. 83 virtual std::vector<uint8_t> ExportKeyingMaterial(size_t length) = 0; 84 85 // Enable client-side check on whether server accepted the handshake. In TLS 86 // 1.3, client will not know the server rejected the handshake until after 87 // performing a read operation. Basically, this will perform an 88 // SSL_peek right after the handshake and see whether that succeeds. 89 // 90 // IMPORTANT: this will only work if the protocol is a server-speaks-first 91 // type. Enabling this for the server is a no-op. This is disabled by 92 // default. 93 virtual void EnableClientPostHandshakeCheck(bool enable) = 0; 94 95 // Starts the handshake process. Returns TlsError::Success if handshake 96 // succeeded. 97 virtual TlsError DoHandshake() = 0; 98 99 // Reads |size| bytes and returns the data. The returned data has either 100 // size |size| or zero, in which case the read failed. 101 virtual std::vector<uint8_t> ReadFully(size_t size) = 0; 102 103 // Overloaded ReadFully method, which accepts a buffer for writing in. 104 // Returns true iff exactly |size| amount of data was written into |buf|, 105 // false otherwise. 106 virtual bool ReadFully(void* buf, size_t size) = 0; 107 108 // Writes |size| bytes. Returns true if all |size| bytes were read. 109 // Returns false otherwise. 110 virtual bool WriteFully(std::string_view data) = 0; 111 112 // Create a new TlsConnection instance. |cert| and |priv_key| cannot be 113 // empty. 114 static std::unique_ptr<TlsConnection> Create(Role role, std::string_view cert, 115 std::string_view priv_key, 116 android::base::borrowed_fd fd); 117 118 // Helper to set the certificate and key strings to a SSL client/server. 119 // Useful when in the set-certificate callback. 120 static bool SetCertAndKey(SSL* ssl, std::string_view cert_chain, std::string_view priv_key); 121 122 protected: 123 TlsConnection() = default; 124 }; // TlsConnection 125 126 } // namespace tls 127 } // namespace adb 128