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