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