From 1032cad68485c06921fadffc81503b8917f6f6d7 Mon Sep 17 00:00:00 2001 From: Mike Brady <4265913+mikebrady@users.noreply.github.com> Date: Sun, 14 Nov 2021 14:13:31 +0000 Subject: [PATCH] Update to the latest version of ejurgensen's pair_ap library. With thanks. --- pair_ap/{pair_ap-master => }/.gitignore | 0 pair_ap/client-example.c | 15 ++++++++ pair_ap/{pair_ap-master => }/evrtsp/evrtsp.h | 0 pair_ap/{pair_ap-master => }/evrtsp/log.h | 0 .../evrtsp/rtsp-internal.h | 0 pair_ap/{pair_ap-master => }/evrtsp/rtsp.c | 0 pair_ap/pair-internal.h | 6 +++ pair_ap/pair.c | 21 +++++++++++ pair_ap/pair.h | 2 +- pair_ap/pair_fruit.c | 4 +- pair_ap/pair_homekit.c | 14 +++---- pair_ap/server-example.c | 15 ++++++++ shairport.c | 37 ++++++++++++++++--- 13 files changed, 99 insertions(+), 15 deletions(-) rename pair_ap/{pair_ap-master => }/.gitignore (100%) rename pair_ap/{pair_ap-master => }/evrtsp/evrtsp.h (100%) rename pair_ap/{pair_ap-master => }/evrtsp/log.h (100%) rename pair_ap/{pair_ap-master => }/evrtsp/rtsp-internal.h (100%) rename pair_ap/{pair_ap-master => }/evrtsp/rtsp.c (100%) diff --git a/pair_ap/pair_ap-master/.gitignore b/pair_ap/.gitignore similarity index 100% rename from pair_ap/pair_ap-master/.gitignore rename to pair_ap/.gitignore diff --git a/pair_ap/client-example.c b/pair_ap/client-example.c index 35e424ad..1cb766bb 100644 --- a/pair_ap/client-example.c +++ b/pair_ap/client-example.c @@ -9,6 +9,10 @@ #include "evrtsp/evrtsp.h" #include "pair.h" +#ifdef CONFIG_GCRYPT +# include +#endif + #define DEVICE_ID "AABBCCDD11223344" #define ACTIVE_REMOTE "3515324763" #define DACP_ID "FF1DB45949E6CBD3" @@ -553,6 +557,17 @@ main( int argc, char * argv[] ) content_type_setup = CONTENTTYPE_SETUP_HOMEKIT; } +// libgcrypt requires that the application initializes the library +#ifdef CONFIG_GCRYPT + if (!gcry_check_version(NULL)) + { + printf("libgcrypt not initialized\n"); + return -1; + } + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +#endif + evbase = event_base_new(); evcon = evrtsp_connection_new(address, atoi(port)); evrtsp_connection_set_base(evcon, evbase); diff --git a/pair_ap/pair_ap-master/evrtsp/evrtsp.h b/pair_ap/evrtsp/evrtsp.h similarity index 100% rename from pair_ap/pair_ap-master/evrtsp/evrtsp.h rename to pair_ap/evrtsp/evrtsp.h diff --git a/pair_ap/pair_ap-master/evrtsp/log.h b/pair_ap/evrtsp/log.h similarity index 100% rename from pair_ap/pair_ap-master/evrtsp/log.h rename to pair_ap/evrtsp/log.h diff --git a/pair_ap/pair_ap-master/evrtsp/rtsp-internal.h b/pair_ap/evrtsp/rtsp-internal.h similarity index 100% rename from pair_ap/pair_ap-master/evrtsp/rtsp-internal.h rename to pair_ap/evrtsp/rtsp-internal.h diff --git a/pair_ap/pair_ap-master/evrtsp/rtsp.c b/pair_ap/evrtsp/rtsp.c similarity index 100% rename from pair_ap/pair_ap-master/evrtsp/rtsp.c rename to pair_ap/evrtsp/rtsp.c diff --git a/pair_ap/pair-internal.h b/pair_ap/pair-internal.h index e7cd85e3..f9d8fa66 100644 --- a/pair_ap/pair-internal.h +++ b/pair_ap/pair-internal.h @@ -225,6 +225,12 @@ struct pair_definition }; +/* ----------------------------- INITIALIZATION ---------------------------- */ + +bool +is_initialized(void); + + /* -------------------- GCRYPT AND OPENSSL COMPABILITY --------------------- */ /* partly borrowed from ffmpeg (rtmpdh.c) */ diff --git a/pair_ap/pair.c b/pair_ap/pair.c index 6908e8bd..2b58bbe1 100644 --- a/pair_ap/pair.c +++ b/pair_ap/pair.c @@ -44,6 +44,27 @@ static struct pair_definition *pair[] = { &pair_server_homekit, }; +/* ------------------------------ INITIALIZATION ---------------------------- */ + +bool +is_initialized(void) +{ + if (sodium_init() == -1) + return false; + +#if CONFIG_GCRYPT + // According to libgcrypt documentation: "It is important that these + // initialization steps are not done by a library but by the actual + // application. A library using Libgcrypt might want to check for finished + // initialization using:" + if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) + return false; +#endif + + return true; +} + + /* -------------------------- SHARED HASHING HELPERS ------------------------ */ int diff --git a/pair_ap/pair.h b/pair_ap/pair.h index 3877e2bb..d3be0ca9 100644 --- a/pair_ap/pair.h +++ b/pair_ap/pair.h @@ -4,7 +4,7 @@ #include #define PAIR_AP_VERSION_MAJOR 0 -#define PAIR_AP_VERSION_MINOR 8 +#define PAIR_AP_VERSION_MINOR 10 #define PAIR_AP_DEVICE_ID_LEN_MAX 64 diff --git a/pair_ap/pair_fruit.c b/pair_ap/pair_fruit.c index 42e0b066..3236faf5 100644 --- a/pair_ap/pair_fruit.c +++ b/pair_ap/pair_fruit.c @@ -601,7 +601,7 @@ client_setup_new(struct pair_setup_context *handle, const char *pin, pair_cb add { struct pair_client_setup_context *sctx = &handle->sctx.client; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (!pin || strlen(pin) < 4) @@ -876,7 +876,7 @@ client_verify_new(struct pair_verify_context *handle, const char *client_setup_k const char *ptr; int i; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (!client_setup_keys) diff --git a/pair_ap/pair_homekit.c b/pair_ap/pair_homekit.c index bb45df7b..6540d42d 100644 --- a/pair_ap/pair_homekit.c +++ b/pair_ap/pair_homekit.c @@ -281,7 +281,7 @@ calculate_M(enum hash_alg alg, NGConstant *ng, unsigned char *dest, const char * for (i=0; i < hash_len; i++ ) H_xor[i] = H_N[i] ^ H_g[i]; - + hash_init( alg, &ctx ); hash_update( alg, &ctx, H_xor, hash_len ); @@ -410,7 +410,7 @@ srp_user_start_authentication(struct SRPUser *usr, const char **username, // BN_hex2bn(&(usr->a), "D929DFB605687233C9E9030C2280156D03BDB9FDCF3CCE3BC27D9CCFCB5FF6A1"); bnum_modexp(usr->A, usr->ng->g, usr->a, usr->ng->N); - + *len_A = bnum_num_bytes(usr->A); *bytes_A = malloc(*len_A); @@ -515,7 +515,7 @@ static int srp_create_salted_verification_key(enum hash_alg alg, SRP_NGType ng_type, const char *username, const unsigned char *password, int len_password, - unsigned char **bytes_s, int *len_s, + unsigned char **bytes_s, int *len_s, unsigned char **bytes_v, int *len_v, const char *n_hex, const char *g_hex ) { @@ -1137,7 +1137,7 @@ client_setup_new(struct pair_setup_context *handle, const char *pin, pair_cb add { struct pair_client_setup_context *sctx = &handle->sctx.client; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (handle->type == &pair_client_homekit_normal) @@ -1626,7 +1626,7 @@ client_verify_new(struct pair_verify_context *handle, const char *client_setup_k struct pair_client_verify_context *vctx = &handle->vctx.client; size_t hexkey_len; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (!device_id || strlen(device_id) >= PAIR_AP_DEVICE_ID_LEN_MAX) @@ -1950,7 +1950,7 @@ server_setup_new(struct pair_setup_context *handle, const char *pin, pair_cb add { struct pair_server_setup_context *sctx = &handle->sctx.server; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (!pin) @@ -2396,7 +2396,7 @@ server_verify_new(struct pair_verify_context *handle, const char *client_setup_k { struct pair_server_verify_context *vctx = &handle->vctx.server; - if (sodium_init() == -1) + if (!is_initialized()) return -1; if (client_setup_keys) diff --git a/pair_ap/server-example.c b/pair_ap/server-example.c index 73fe4bda..4a6e6fd1 100644 --- a/pair_ap/server-example.c +++ b/pair_ap/server-example.c @@ -37,6 +37,10 @@ #include "pair.h" +#ifdef CONFIG_GCRYPT +# include +#endif + #define DEVICE_ID "FFEEDDCCBBAA9988" #define LISTEN_PORT 7000 #define CONTENT_TYPE_OCTET "application/octet-stream" @@ -668,6 +672,17 @@ main(int argc, char * argv[]) struct event_base *evbase; struct evconnlistener *listener; +// libgcrypt requires that the application initializes the library +#ifdef CONFIG_GCRYPT + if (!gcry_check_version(NULL)) + { + printf("libgcrypt not initialized\n"); + return -1; + } + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); +#endif + evbase = event_base_new(); listener = listen_add(evbase, in_accept_cb, in_error_cb, LISTEN_PORT); diff --git a/shairport.c b/shairport.c index 980fe944..edcb5e10 100644 --- a/shairport.c +++ b/shairport.c @@ -44,6 +44,7 @@ #include "config.h" #ifdef CONFIG_AIRPLAY_2 +#include #include #include #endif @@ -1786,8 +1787,10 @@ int main(int argc, char **argv) { // mDNS string. // note: 0x300401F4A00 works but with weird delays and stuff // config.airplay_features = 0x1C340405FCA00; - uint64_t mask = ((uint64_t)1 << 17) | ((uint64_t)1 << 16) | ((uint64_t)1 << 15) | ((uint64_t)1 << 50); - config.airplay_features = 0x1C340405D4A00 & (~mask); // APX + Authentication4 (b14) with no metadata (see below) + uint64_t mask = + ((uint64_t)1 << 17) | ((uint64_t)1 << 16) | ((uint64_t)1 << 15) | ((uint64_t)1 << 50); + config.airplay_features = + 0x1C340405D4A00 & (~mask); // APX + Authentication4 (b14) with no metadata (see below) // Advertised with mDNS and returned with GET /info, see // https://openairplay.github.io/airplay-spec/status_flags.html 0x4: Audio cable attached, no PIN // required (transient pairing), 0x204: Audio cable attached, OneTimePairingRequired 0x604: Audio @@ -1802,7 +1805,7 @@ int main(int argc, char **argv) { config.airplay_features |= (1 << 15); // 15 is artwork #endif - debug(1,"Features: 0x%" PRIx64 ".", config.airplay_features); + debug(1, "Features: 0x%" PRIx64 ".", config.airplay_features); config.airplay_statusflags = 0x04; // Set to NULL to work with transient pairing config.airplay_pin = NULL; @@ -1910,6 +1913,29 @@ int main(int argc, char **argv) { } else { debug(1, "libsodium initialised."); } + + // this code is based on + // https://www.gnupg.org/documentation/manuals/gcrypt/Initializing-the-library.html + + /* Version check should be the very first call because it + makes sure that important subsystems are initialized. + #define NEED_LIBGCRYPT_VERSION to the minimum required version. */ + +#define NEED_LIBGCRYPT_VERSION "1.5.4" + + if (!gcry_check_version(NEED_LIBGCRYPT_VERSION)) { + die("libgcrypt is too old (need %s, have %s).", NEED_LIBGCRYPT_VERSION, + gcry_check_version(NULL)); + } + + /* Disable secure memory. */ + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); + + /* ... If required, other initialization goes here. */ + + /* Tell Libgcrypt that initialization has completed. */ + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + #endif /* Mess around with the latency options */ @@ -1961,8 +1987,9 @@ int main(int argc, char **argv) { debug(1, "mdns backend \"%s\".", config.mdns_name); debug(2, "userSuppliedLatency is %d.", config.userSuppliedLatency); debug(1, "interpolation setting is \"%s\".", - config.packet_stuffing == ST_basic ? "basic" - : config.packet_stuffing == ST_soxr ? "soxr" : "auto"); + config.packet_stuffing == ST_basic ? "basic" + : config.packet_stuffing == ST_soxr ? "soxr" + : "auto"); debug(1, "interpolation soxr_delay_threshold is %d.", config.soxr_delay_threshold); debug(1, "resync time is %f seconds.", config.resyncthreshold); debug(1, "allow a session to be interrupted: %d.", config.allow_session_interruption);