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 in compliance with the License. 6 * 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 #include <sys/cdefs.h> 22 23 #if !defined(__INTRODUCED_IN) 24 #define __INTRODUCED_IN(__api_level) /* nothing */ 25 #endif 26 27 // These APIs are for the Adb pairing protocol. This protocol requires both 28 // sides to possess a shared secret to authenticate each other. The connection 29 // is over TLS, and requires that both the client and server have a valid 30 // certificate. 31 // 32 // This protocol is one-to-one, i.e., one PairingConnectionCtx server instance 33 // interacts with only one PairingConnectionCtx client instance. In other words, 34 // every new client instance must be bound to a new server instance. 35 // 36 // If both sides have authenticated, they will exchange their peer information 37 // (see #PeerInfo). 38 __BEGIN_DECLS 39 #if !defined(__ANDROID__) || __ANDROID_API__ >= 30 40 41 const uint32_t kMaxPeerInfoSize = 8192; 42 struct PeerInfo { 43 uint8_t type; 44 uint8_t data[kMaxPeerInfoSize - 1]; 45 } __attribute__((packed)); 46 typedef struct PeerInfo PeerInfo; 47 static_assert(sizeof(PeerInfo) == kMaxPeerInfoSize, "PeerInfo has weird size"); 48 49 enum PeerInfoType : uint8_t { 50 ADB_RSA_PUB_KEY = 0, 51 ADB_DEVICE_GUID = 1, 52 }; 53 54 struct PairingConnectionCtx; 55 typedef struct PairingConnectionCtx PairingConnectionCtx; 56 typedef void (*pairing_result_cb)(const PeerInfo*, int, void*); 57 58 // Starts the pairing connection on a separate thread. 59 // 60 // Upon completion, if the pairing was successful, 61 // |cb| will be called with the peer information and certificate. 62 // Otherwise, |cb| will be called with empty data. |fd| should already 63 // be opened. PairingConnectionCtx will take ownership of the |fd|. 64 // 65 // Pairing is successful if both server/client uses the same non-empty 66 // |pswd|, and they are able to exchange the information. |pswd| and 67 // |certificate| must be non-empty. start() can only be called once in the 68 // lifetime of this object. 69 // 70 // @param ctx the PairingConnectionCtx instance. Will abort if null. 71 // @param fd the fd connecting the peers. This will take ownership of fd. 72 // @param cb the user-provided callback that is called with the result of the 73 // pairing. The callback will be called on a different thread from the 74 // caller. 75 // @param opaque opaque userdata. 76 // @return true if the thread was successfully started, false otherwise. To stop 77 // the connection process, destroy the instance (see 78 // #pairing_connection_destroy). If false is returned, cb will not be 79 // invoked. Otherwise, cb is guaranteed to be invoked, even if you 80 // destroy the ctx while in the pairing process. 81 bool pairing_connection_start(PairingConnectionCtx* ctx, int fd, pairing_result_cb cb, void* opaque) 82 __INTRODUCED_IN(30); 83 84 // Creates a new PairingConnectionCtx instance as the client. 85 // 86 // @param pswd the password to authenticate both peers. Will abort if null. 87 // @param pswd_len the length of pswd. Will abort if 0. 88 // @param peer_info the PeerInfo struct that is exchanged between peers if the 89 // pairing was successful. Will abort if null. 90 // @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null. 91 // @param x509_size the size of x509_cert_pem. Will abort if 0. 92 // @param priv_key_pem the private key corresponding to the given X.509 93 // certificate, in PEM format. Will abort if null. 94 // @param priv_size the size of priv_key_pem. Will abort if 0. 95 // @return a new PairingConnectionCtx client instance. The caller is responsible 96 // for destroying the context via #pairing_connection_destroy. 97 PairingConnectionCtx* pairing_connection_client_new(const uint8_t* pswd, size_t pswd_len, 98 const PeerInfo* peer_info, 99 const uint8_t* x509_cert_pem, size_t x509_size, 100 const uint8_t* priv_key_pem, size_t priv_size) 101 __INTRODUCED_IN(30); 102 103 // Creates a new PairingConnectionCtx instance as the server. 104 // 105 // @param pswd the password to authenticate both peers. Will abort if null. 106 // @param pswd_len the length of pswd. Will abort if 0. 107 // @param peer_info the PeerInfo struct that is exchanged between peers if the 108 // pairing was successful. Will abort if null. 109 // @param x509_cert_pem the X.509 certificate in PEM format. Will abort if null. 110 // @param x509_size the size of x509_cert_pem. Will abort if 0. 111 // @param priv_key_pem the private key corresponding to the given X.509 112 // certificate, in PEM format. Will abort if null. 113 // @param priv_size the size of priv_key_pem. Will abort if 0. 114 // @return a new PairingConnectionCtx server instance. The caller is responsible 115 // for destroying the context via #pairing_connection_destroy. 116 PairingConnectionCtx* pairing_connection_server_new(const uint8_t* pswd, size_t pswd_len, 117 const PeerInfo* peer_info, 118 const uint8_t* x509_cert_pem, size_t x509_size, 119 const uint8_t* priv_key_pem, size_t priv_size) 120 __INTRODUCED_IN(30); 121 122 // Destroys the PairingConnectionCtx instance. 123 // 124 // It is safe to destroy the instance at any point in the pairing process. 125 // 126 // @param ctx the PairingConnectionCtx instance to destroy. Will abort if null. 127 void pairing_connection_destroy(PairingConnectionCtx* ctx) __INTRODUCED_IN(30); 128 129 #endif //!__ANDROID__ || __ANDROID_API__ >= 30 130 __END_DECLS 131