@@ -103,19 +103,13 @@ pub async fn handshake<T: AsyncRead + AsyncWrite + Unpin>(
103103 Ok ( codec. framed ( connection) )
104104}
105105
106- async fn client_hello < T > ( connection : & mut T , gc : Vec < u8 > ) -> io:: Result < Vec < u8 > >
107- where
108- T : AsyncWrite + Unpin ,
109- {
110- let mut client_nonce = vec ! [ 0 ; 0x10 ] ;
111- rand:: rng ( ) . fill_bytes ( & mut client_nonce) ;
112-
113- let platform = match crate :: config:: OS {
114- "freebsd" | "netbsd" | "openbsd" => match ARCH {
106+ fn platform_for ( os : & str , arch : & str ) -> Platform {
107+ match os {
108+ "freebsd" | "netbsd" | "openbsd" => match arch {
115109 "x86_64" => Platform :: PLATFORM_FREEBSD_X86_64 ,
116110 _ => Platform :: PLATFORM_FREEBSD_X86 ,
117111 } ,
118- "ios" => match ARCH {
112+ "ios" => match arch {
119113 "aarch64" => Platform :: PLATFORM_IPHONE_ARM64 ,
120114 _ => Platform :: PLATFORM_IPHONE_ARM ,
121115 } ,
@@ -124,26 +118,37 @@ where
124118 // all APs will reject the client with TryAnotherAP, no matter the credentials
125119 // used was obtained via OAuth using KEYMASTER or ANDROID's client ID or
126120 // Login5Manager::login
127- "linux" | "android" => match ARCH {
121+ "linux" | "android" => match arch {
128122 "arm" | "aarch64" => Platform :: PLATFORM_LINUX_ARM ,
129123 "blackfin" => Platform :: PLATFORM_LINUX_BLACKFIN ,
130124 "mips" => Platform :: PLATFORM_LINUX_MIPS ,
131125 "sh" => Platform :: PLATFORM_LINUX_SH ,
132126 "x86_64" => Platform :: PLATFORM_LINUX_X86_64 ,
133127 _ => Platform :: PLATFORM_LINUX_X86 ,
134128 } ,
135- "macos" => match ARCH {
129+ "macos" => match arch {
136130 "ppc" | "ppc64" => Platform :: PLATFORM_OSX_PPC ,
137131 "x86_64" => Platform :: PLATFORM_OSX_X86_64 ,
138132 _ => Platform :: PLATFORM_OSX_X86 ,
139133 } ,
140- "windows" => match ARCH {
141- "arm" | "aarch64" => Platform :: PLATFORM_WINDOWS_CE_ARM ,
142- "x86_64" => Platform :: PLATFORM_WIN32_X86_64 ,
134+ // Spotify APs reject the legacy Windows CE ARM platform even for Premium
135+ // accounts. Windows on ARM is a desktop client, so identify it as Win32.
136+ "windows" => match arch {
137+ "arm" | "aarch64" | "x86_64" => Platform :: PLATFORM_WIN32_X86_64 ,
143138 _ => Platform :: PLATFORM_WIN32_X86 ,
144139 } ,
145140 _ => Platform :: PLATFORM_LINUX_X86 ,
146- } ;
141+ }
142+ }
143+
144+ async fn client_hello < T > ( connection : & mut T , gc : Vec < u8 > ) -> io:: Result < Vec < u8 > >
145+ where
146+ T : AsyncWrite + Unpin ,
147+ {
148+ let mut client_nonce = vec ! [ 0 ; 0x10 ] ;
149+ rand:: rng ( ) . fill_bytes ( & mut client_nonce) ;
150+
151+ let platform = platform_for ( crate :: config:: OS , ARCH ) ;
147152
148153 #[ cfg( debug_assertions) ]
149154 const PRODUCT_FLAGS : ProductFlags = ProductFlags :: PRODUCT_FLAG_DEV_BUILD ;
@@ -268,3 +273,30 @@ fn compute_keys(shared_secret: &[u8], packets: &[u8]) -> io::Result<(Vec<u8>, Ve
268273 data[ 0x34 ..0x54 ] . to_vec ( ) ,
269274 ) )
270275}
276+
277+ #[ cfg( test) ]
278+ mod tests {
279+ use super :: platform_for;
280+ use crate :: protocol:: keyexchange:: Platform ;
281+
282+ #[ test]
283+ fn windows_on_arm_uses_supported_desktop_platform ( ) {
284+ assert_eq ! (
285+ platform_for( "windows" , "aarch64" ) ,
286+ Platform :: PLATFORM_WIN32_X86_64
287+ ) ;
288+ assert_eq ! (
289+ platform_for( "windows" , "arm" ) ,
290+ Platform :: PLATFORM_WIN32_X86_64
291+ ) ;
292+ }
293+
294+ #[ test]
295+ fn windows_x86_platforms_are_unchanged ( ) {
296+ assert_eq ! (
297+ platform_for( "windows" , "x86_64" ) ,
298+ Platform :: PLATFORM_WIN32_X86_64
299+ ) ;
300+ assert_eq ! ( platform_for( "windows" , "x86" ) , Platform :: PLATFORM_WIN32_X86 ) ;
301+ }
302+ }
0 commit comments