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