Update pair_ap to 0.7 (fixes incorrect pair-list response)

This commit is contained in:
ejurgensen
2021-07-13 22:28:34 +02:00
parent a7047e41d7
commit 1959d2cf0c
3 changed files with 21 additions and 10 deletions
+7 -6
View File
@@ -2,9 +2,10 @@
C client implementation of pairing for:
* Apple TV device verification, which became mandatory with tvOS 10.2 (this is
called fruit mode in pair_ap)
* Homekit pairing (for AirPlay 2, not working for Home app)
* Homekit pairing (also for AirPlay 2)
Credit goes to @funtax and @ViktoriiaKh for doing some of the heavy lifting.
## Requirements
- libsodium
- libgcrypt or libopenssl
@@ -33,7 +34,7 @@ The controller uses `/pair-add` to make sure that all devices on a network get
the ID and public key of all the other devices, so that the user only needs to
pair a device once.
### Normal pairing
### Normal pairing with one-time code
For a normal first-time pairing, the client needs a one-time code (the device
announces via mDNS whether a code is required). The client calls
`/pair-pin-start` and the device displays the code. There is also QR-based
@@ -42,12 +43,12 @@ pairing, which is (probably?) an encoded code.
After obtaining the code, the client initiates a three step `/pair-setup`
sequence, which results in both peers registering each other's ID and public
key. Henceforth, a pairing is verified with the two step `/pair-verify`, where
the parties check each-others identify. Saving the peer's ID + public key isn't
the parties check eachothers identify. Saving the peer's ID + public key isn't
strictly necessary if client or server doesn't care about verifying the peer,
i.e. that `/pair-setup` has actually been completed.
The result of `/pair-verify` is a shared secret that is used for symmetric
encryption of the following communinacation between the parties.
encryption of the following communication between the parties.
### Transient pairing
Some devices don't require a code from the user for pairing (e.g. an Airport
@@ -55,8 +56,7 @@ Express 2). If so, the client just needs to go through a two-step `/pair-setup`
sequence which results in a shared secret, which is then used for encrypted
communication. A fixed code of 3939 is used.
Such devices don't appear to be fully Homekit compatible - they will not, for
instance - appear in the Home app.
The controller can still use `/pair-add` etc. towards such devices.
## "fruit" pairing
Like normal Homekit pairing, this consists of first requesting a code with
@@ -69,4 +69,5 @@ shared secret.
- [AirPlayAuth](https://github.com/funtax/AirPlayAuth)
- [AirPlayAuth-ObjC](https://github.com/ViktoriiaKh/AirPlayAuth-ObjC)
- [ap2-sender](https://github.com/ViktoriiaKh/ap2-sender)
- [airplay2-receiver](https://github.com/ckdo/airplay2-receiver)
- [csrp](https://github.com/cocagne/csrp)
+1 -1
View File
@@ -4,7 +4,7 @@
#include <stdint.h>
#define PAIR_AP_VERSION_MAJOR 0
#define PAIR_AP_VERSION_MINOR 5
#define PAIR_AP_VERSION_MINOR 7
#define PAIR_AP_DEVICE_ID_LEN_MAX 64
+13 -3
View File
@@ -2679,6 +2679,7 @@ server_add_remove_request(pair_cb cb, void *cb_arg, const uint8_t *in, size_t in
pair_tlv_t *device_id;
pair_tlv_t *pk;
char id_str[PAIR_AP_DEVICE_ID_LEN_MAX] = { 0 };
uint8_t *public_key = NULL;
request = message_process(in, in_len, &errmsg);
if (!request)
@@ -2687,15 +2688,21 @@ server_add_remove_request(pair_cb cb, void *cb_arg, const uint8_t *in, size_t in
}
device_id = pair_tlv_get_value(request, TLVType_Identifier);
pk = pair_tlv_get_value(request, TLVType_PublicKey);
if (!device_id || device_id->size >= sizeof(id_str) || !pk || pk->size != crypto_sign_PUBLICKEYBYTES)
if (!device_id || device_id->size >= sizeof(id_str))
{
goto error;
}
// Only present when adding
pk = pair_tlv_get_value(request, TLVType_PublicKey);
if (pk && pk->size == crypto_sign_PUBLICKEYBYTES)
{
public_key = pk->value;
}
memcpy(id_str, device_id->value, device_id->size);
cb(pk->value, id_str, cb_arg);
cb(public_key, id_str, cb_arg);
pair_tlv_free(request);
return 0;
@@ -2757,9 +2764,12 @@ static int
server_list_cb(uint8_t public_key[crypto_sign_PUBLICKEYBYTES], const char *device_id, void *cb_arg)
{
pair_tlv_values_t *response = cb_arg;
uint8_t permissions = 1; // Means admin (TODO don't hardcode - let caller set)
pair_tlv_add_value(response, TLVType_Identifier, (unsigned char *)device_id, strlen(device_id));
pair_tlv_add_value(response, TLVType_PublicKey, public_key, crypto_sign_PUBLICKEYBYTES);
pair_tlv_add_value(response, TLVType_Permissions, &permissions, sizeof(permissions));
return 0;
}