mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-15 00:34:05 +09:00
iOS 8 and 9 decryption now works; need to test AAC audio decompression.
This commit is contained in:
13
lib/global.h
13
lib/global.h
@@ -5,12 +5,15 @@
|
||||
#define GLOBAL_MODEL "AppleTV2,1"
|
||||
#define GLOBAL_VERSION "220.68"
|
||||
|
||||
/* use old protocol for AES key if User-Agent string is contained in these strings */
|
||||
/* replace xxx by any new User-Agent string as needed */
|
||||
#define OLD_PROTOCOL_AUDIO_CLIENT_LIST "AirMyPC/2.0;xxx"
|
||||
#define OLD_PROTOCOL_VIDEO_CLIENT_LIST "AirMyPC/2.0;xxx"
|
||||
/* use old protocol (unhashed AESkey for audio decryption if clients source version is not greater than 330.x.x */
|
||||
#define OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION "330.0.0"
|
||||
|
||||
#define DECRYPTION_TEST 0
|
||||
/* use old protocol for audio or video AES key if client's User-Agent string is contained in these strings */
|
||||
/* replace xxx by any new User-Agent string as needed */
|
||||
#define OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST "AirMyPC/2.0;xxx"
|
||||
#define OLD_PROTOCOL_VIDEO_CLIENT_USER_AGENT_LIST "AirMyPC/2.0;xxx"
|
||||
|
||||
#define DECRYPTION_TEST 2
|
||||
|
||||
#define MAX_HWADDR_LEN 6
|
||||
|
||||
|
||||
@@ -152,8 +152,8 @@ raop_buffer_decrypt(raop_buffer_t *raop_buffer, unsigned char *data, unsigned ch
|
||||
#endif
|
||||
|
||||
if (DECRYPTION_TEST) {
|
||||
printf("%s\n", OLD_PROTOCOL_AUDIO_CLIENT_LIST);
|
||||
printf("%d before %s", payload_size, utils_data_to_string(&data[12],16,16 ));
|
||||
printf("encrypted header %s", utils_data_to_string(data,12,12));
|
||||
if (payload_size) printf("%d before %s", payload_size, utils_data_to_string(&data[12],16,16 ));
|
||||
}
|
||||
encryptedlen = payload_size / 16*16;
|
||||
memset(output, 0, payload_size);
|
||||
@@ -164,9 +164,17 @@ raop_buffer_decrypt(raop_buffer_t *raop_buffer, unsigned char *data, unsigned ch
|
||||
|
||||
memcpy(output + encryptedlen, &data[12 + encryptedlen], payload_size - encryptedlen);
|
||||
*outputlen = payload_size;
|
||||
if (DECRYPTION_TEST){
|
||||
if ( !(output[0] == 0x8d || output[0] == 0x8e || output[0] == 0x20)) printf("***ERROR AUDIO FRAME IS NOT AAC_ELD OR ALAC\n");
|
||||
printf("%d after %s\n", payload_size, utils_data_to_string(output,16,16 ));
|
||||
if (payload_size && DECRYPTION_TEST){
|
||||
if ( !(output[0] == 0x8d || output[0] == 0x8e || output[0] == 0x81 || output[0] == 0x82 || output[0] == 0x20)) {
|
||||
printf("***ERROR AUDIO FRAME IS NOT AAC_ELD OR ALAC\n");
|
||||
}
|
||||
if (DECRYPTION_TEST == 2) {
|
||||
printf("decrypted audio frame, len = %d\n", *outputlen);
|
||||
printf("%s",utils_data_to_string(output,payload_size,16));
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("%d after %s\n", payload_size, utils_data_to_string(output,16,16 ));
|
||||
}
|
||||
}
|
||||
#ifdef DUMP_AUDIO
|
||||
// Decrypted file
|
||||
|
||||
@@ -352,7 +352,10 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
unsigned char aesiv[16];
|
||||
unsigned char aeskey_old[16];
|
||||
unsigned char aeskey[16];
|
||||
unsigned char *aeskey_audio = aeskey;
|
||||
unsigned char *aeskey_video = aeskey;
|
||||
|
||||
|
||||
logger_log(conn->raop->logger, LOGGER_DEBUG, "SETUP 1");
|
||||
|
||||
// First setup
|
||||
@@ -399,25 +402,38 @@ raop_handler_setup(raop_conn_t *conn,
|
||||
logger_log(conn->raop->logger, LOGGER_DEBUG, "16 byte aeskey after sha-256 hash with ecdh_secret:\n%s", str);
|
||||
free(str);
|
||||
|
||||
/* old-protocol clients such as AirMyPC use the unhashed key aeskey_old for both audio and video */
|
||||
/* OLD_PROTOCOL_AUDIO_CLIENT_LIST, OLD_PROTOCOL_VIDEO_CLIENT_LIST are defined in global.h */
|
||||
|
||||
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);
|
||||
unsigned char *aeskey_audio, *aeskey_video;
|
||||
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_LIST,user_agent)) { /* old-protocol clients use the unhashed AES key */
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "This identifies client as using old protocol for AES audio key)");
|
||||
aeskey_audio = aeskey_old;
|
||||
} else {
|
||||
aeskey_audio = aeskey;
|
||||
/* old-protocol clients such as AirMyPC use the unhashed key aeskey_old for both audio and video (ios9, ios10 support)*/
|
||||
/* clients with sourceVersion <= OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION use unhashed aeskey_old for audio decryption */
|
||||
/* this is also done for audio or video if clients User-Agent string is included in OLD_PROTOCOL_[AUDIO,VIDEO]_CLIENT_LIST (AirMyPC support)*/
|
||||
/* OLD_PROTOCOL_AUDIO_CLIENT_LIST, OLD_PROTOCOL_VIDEO_CLIENT_LIST, OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION are defined in global.h */
|
||||
|
||||
plist_t req_source_version_node = plist_dict_get_item(req_root_node, "sourceVersion");
|
||||
char *sourceVersion;
|
||||
plist_get_string_val(req_source_version_node, &sourceVersion);
|
||||
const char *user_agent = http_request_get_header(request, "User-Agent");
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "Client identified as User-Agent: %s, sourceVersion: %s", user_agent, sourceVersion);
|
||||
|
||||
#ifdef OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION
|
||||
char *end_ptr;
|
||||
if (strtoul(sourceVersion, &end_ptr, 10) <= strtoul(OLD_PROTOCOL_AUDIO_CLIENT_SOURCEVERSION , &end_ptr, 10)) aeskey_audio = aeskey_old;
|
||||
#endif
|
||||
|
||||
#ifdef OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST
|
||||
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST, user_agent)) aeskey_audio = aeskey_old;
|
||||
#endif
|
||||
|
||||
#ifdef OLD_PROTOCOL_VIDEO_CLIENT_USER_AGENT_LIST
|
||||
if (strstr(OLD_PROTOCOL_AUDIO_CLIENT_USER_AGENT_LIST, user_agent)) aeskey_video = aeskey_old;
|
||||
#endif
|
||||
|
||||
if (aeskey_audio == aeskey_old) {
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "Client identifed as using old protocol (unhashed) AES audio key)");
|
||||
}
|
||||
if (strstr(OLD_PROTOCOL_VIDEO_CLIENT_LIST, user_agent)) { /* old-protocol clients use the unhashed AES key */
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "This identifies client as using old protocol for AES video key)");
|
||||
aeskey_video = aeskey_old;
|
||||
} else {
|
||||
aeskey_video = aeskey;
|
||||
|
||||
if (aeskey_video == aeskey_old) {
|
||||
logger_log(conn->raop->logger, LOGGER_INFO, "Client identifed as using old protocol (unhashed) AES video key)");
|
||||
}
|
||||
|
||||
|
||||
// Time port
|
||||
uint64_t timing_rport;
|
||||
plist_t time_note = plist_dict_get_item(req_root_node, "timingPort");
|
||||
|
||||
Reference in New Issue
Block a user