Update pair_ap to 0.7 (fixes incorrect pair-list response)
This commit is contained in:
+7
-6
@@ -2,9 +2,10 @@
|
|||||||
C client implementation of pairing for:
|
C client implementation of pairing for:
|
||||||
* Apple TV device verification, which became mandatory with tvOS 10.2 (this is
|
* Apple TV device verification, which became mandatory with tvOS 10.2 (this is
|
||||||
called fruit mode in pair_ap)
|
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.
|
Credit goes to @funtax and @ViktoriiaKh for doing some of the heavy lifting.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- libsodium
|
- libsodium
|
||||||
- libgcrypt or libopenssl
|
- 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
|
the ID and public key of all the other devices, so that the user only needs to
|
||||||
pair a device once.
|
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
|
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
|
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
|
`/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`
|
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
|
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
|
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,
|
strictly necessary if client or server doesn't care about verifying the peer,
|
||||||
i.e. that `/pair-setup` has actually been completed.
|
i.e. that `/pair-setup` has actually been completed.
|
||||||
|
|
||||||
The result of `/pair-verify` is a shared secret that is used for symmetric
|
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
|
### Transient pairing
|
||||||
Some devices don't require a code from the user for pairing (e.g. an Airport
|
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
|
sequence which results in a shared secret, which is then used for encrypted
|
||||||
communication. A fixed code of 3939 is used.
|
communication. A fixed code of 3939 is used.
|
||||||
|
|
||||||
Such devices don't appear to be fully Homekit compatible - they will not, for
|
The controller can still use `/pair-add` etc. towards such devices.
|
||||||
instance - appear in the Home app.
|
|
||||||
|
|
||||||
## "fruit" pairing
|
## "fruit" pairing
|
||||||
Like normal Homekit pairing, this consists of first requesting a code with
|
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](https://github.com/funtax/AirPlayAuth)
|
||||||
- [AirPlayAuth-ObjC](https://github.com/ViktoriiaKh/AirPlayAuth-ObjC)
|
- [AirPlayAuth-ObjC](https://github.com/ViktoriiaKh/AirPlayAuth-ObjC)
|
||||||
- [ap2-sender](https://github.com/ViktoriiaKh/ap2-sender)
|
- [ap2-sender](https://github.com/ViktoriiaKh/ap2-sender)
|
||||||
|
- [airplay2-receiver](https://github.com/ckdo/airplay2-receiver)
|
||||||
- [csrp](https://github.com/cocagne/csrp)
|
- [csrp](https://github.com/cocagne/csrp)
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PAIR_AP_VERSION_MAJOR 0
|
#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
|
#define PAIR_AP_DEVICE_ID_LEN_MAX 64
|
||||||
|
|
||||||
|
|||||||
+13
-3
@@ -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 *device_id;
|
||||||
pair_tlv_t *pk;
|
pair_tlv_t *pk;
|
||||||
char id_str[PAIR_AP_DEVICE_ID_LEN_MAX] = { 0 };
|
char id_str[PAIR_AP_DEVICE_ID_LEN_MAX] = { 0 };
|
||||||
|
uint8_t *public_key = NULL;
|
||||||
|
|
||||||
request = message_process(in, in_len, &errmsg);
|
request = message_process(in, in_len, &errmsg);
|
||||||
if (!request)
|
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);
|
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))
|
||||||
if (!device_id || device_id->size >= sizeof(id_str) || !pk || pk->size != crypto_sign_PUBLICKEYBYTES)
|
|
||||||
{
|
{
|
||||||
goto error;
|
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);
|
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);
|
pair_tlv_free(request);
|
||||||
return 0;
|
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)
|
server_list_cb(uint8_t public_key[crypto_sign_PUBLICKEYBYTES], const char *device_id, void *cb_arg)
|
||||||
{
|
{
|
||||||
pair_tlv_values_t *response = 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_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_PublicKey, public_key, crypto_sign_PUBLICKEYBYTES);
|
||||||
|
pair_tlv_add_value(response, TLVType_Permissions, &permissions, sizeof(permissions));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user