protocol modifications allowing "supports legacy pairing" to be disabled

This commit is contained in:
F. Duncanh
2023-05-30 01:32:24 -04:00
parent aab89c2f50
commit d38f8690c2
4 changed files with 38 additions and 24 deletions

View File

@@ -24,7 +24,8 @@
#define RAOP_CN "0,1,2,3" /* Audio codec: PCM, ALAC, AAC, AAC ELD */
#define RAOP_ET "0,3,5" /* Encryption type: None, FairPlay, FairPlay SAPv2.5 */
#define RAOP_VV "2"
#define FEATURES_1 "0x5A7FFEE6" /* first 32 bits of features */
#define FEATURES_1 "0x5A7FFEE6" /* first 32 bits of features, with bit 27 ("supports legacy pairing") ON */
//#define FEATURES_1 "0x527FFEE6" /* first 32 bits of features, with bit 27 ("supports legacy pairing") OFF */
#define FEATURES_2 "0x0" /* second 32 bits of features */
#define RAOP_FT FEATURES_1 "," FEATURES_2
#define RAOP_RHD "5.6.0.0"

View File

@@ -90,14 +90,19 @@ pairing_get_public_key(pairing_t *pairing, unsigned char public_key[ED25519_KEY_
ed25519_key_get_raw(public_key, pairing->ed);
}
void
int
pairing_get_ecdh_secret_key(pairing_session_t *session, unsigned char ecdh_secret[X25519_KEY_SIZE])
{
assert(session);
memcpy(ecdh_secret, session->ecdh_secret, X25519_KEY_SIZE);
switch (session->status) {
case STATUS_INITIAL:
return 0;
default:
memcpy(ecdh_secret, session->ecdh_secret, X25519_KEY_SIZE);
return 1;
}
}
pairing_session_t *
pairing_session_init(pairing_t *pairing)
{

View File

@@ -38,6 +38,6 @@ void pairing_session_destroy(pairing_session_t *session);
void pairing_destroy(pairing_t *pairing);
void pairing_get_ecdh_secret_key(pairing_session_t *session, unsigned char ecdh_secret[X25519_KEY_SIZE]);
int pairing_get_ecdh_secret_key(pairing_session_t *session, unsigned char ecdh_secret[X25519_KEY_SIZE]);
#endif

View File

@@ -395,14 +395,6 @@ raop_handler_setup(raop_conn_t *conn,
free(str);
}
unsigned char ecdh_secret[X25519_KEY_SIZE];
pairing_get_ecdh_secret_key(conn->pairing, ecdh_secret);
if (logger_debug) {
char *str = utils_data_to_string(ecdh_secret, X25519_KEY_SIZE, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "32 byte shared ecdh_secret:\n%s", str);
free(str);
}
const char *user_agent = http_request_get_header(request, "User-Agent");
logger_log(conn->raop->logger, LOGGER_INFO, "Client identified as User-Agent: %s", user_agent);
@@ -413,17 +405,33 @@ raop_handler_setup(raop_conn_t *conn,
if (old_protocol) { /* some windows AirPlay-client emulators use old AirPlay 1 protocol with unhashed AES key */
logger_log(conn->raop->logger, LOGGER_INFO, "Client identifed as using old protocol (unhashed) AES audio key)");
} else {
memcpy(eaeskey, aeskey, 16);
sha_ctx_t *ctx = sha_init();
sha_update(ctx, eaeskey, 16);
sha_update(ctx, ecdh_secret, 32);
sha_final(ctx, eaeskey, NULL);
sha_destroy(ctx);
memcpy(aeskey, eaeskey, 16);
if (logger_debug) {
char *str = utils_data_to_string(aeskey, 16, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "16 byte aeskey after sha-256 hash with ecdh_secret:\n%s", str);
free(str);
unsigned char ecdh_secret[X25519_KEY_SIZE];
if (pairing_get_ecdh_secret_key(conn->pairing, ecdh_secret)) {
/* In this case (legacy) pairing with client was successfully set up and created the shared ecdh_secret:
* aeskey must be hashed with it
*
* If byte 27 of features ("supports legacy pairing") is turned off, the client does not request pairsetup
* and does NOT set up pairing (this eliminates a 5 second delay in connecting with no apparent bad effects).
* This may be because uxplay currently does not support connections with more than one client at a time
* while AppleTV supports up to 12 clients, and uses pairing to give each a distinct SessionID .*/
if (logger_debug) {
char *str = utils_data_to_string(ecdh_secret, X25519_KEY_SIZE, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "32 byte shared ecdh_secret:\n%s", str);
free(str);
}
memcpy(eaeskey, aeskey, 16);
sha_ctx_t *ctx = sha_init();
sha_update(ctx, eaeskey, 16);
sha_update(ctx, ecdh_secret, 32);
sha_final(ctx, eaeskey, NULL);
sha_destroy(ctx);
memcpy(aeskey, eaeskey, 16);
if (logger_debug) {
char *str = utils_data_to_string(aeskey, 16, 16);
logger_log(conn->raop->logger, LOGGER_DEBUG, "16 byte aeskey after sha-256 hash with ecdh_secret:\n%s", str);
free(str);
}
}
}