I'm having trouble with implementing a handshake with a Philips Hue Bridge for home light automation app. The problem lies with my implementation of Apples Network framework. I don't know how to use it basically :) and this is the first time I have tried networking that isn't http. URLSession I am ok with.
I'm guessing my main problem is that I have generated a PSK (See Client Key Example) but I haven't converted it to binary and passed it to the framework somehow. I kind of assumed I didn't need too as I have already generated it with the bridge. I would really appreciate some help.
I have followed these Phillips Hue developer guides:
https://developers.meethue.com/develop/get-started-2/
DTLS Handshaking
UDP port 2100 is used for DTLS handshaking and streaming. Only DTLS mode version 1.2 with Pre-Shared Key (PSK) Key exchange method with TLS_PSK_WITH_AES_128_GCM_SHA256 set as Cipher Suite is supported.
The PSK and PSK identity are provided by the CLIP authentication passing the {“generateclientkey”=true} parameter when push linking your application.
CLIENT KEY EXAMPLE:
[
{
"success":{
"username":"myzFXhsLU5Wg10eBithGE-LFikgjC7Q7SEGZsoEf",
"clientkey":"E3B550C65F78022EFD9E52E28378583"
}
}
]
The PSK identity exactly matches the CLIP “username” (ASCII / UTF-8 string) from the response.
The PSK is derived from the “client key” in the response by decoding the 32 character ASCII hex string into its 16 byte binary representation. - I'M NOT SURE WHAT TO DO HERE.
THIS IS THE CODE I HAVE IMPLEMENTED IN MY PROJECT:
func connectToHueNetwork(){
let connection = NWConnection(host: "192.168.178.59", port: 2100, using: .dtls)
connection.stateUpdateHandler = { (newState) in
switch newState {
case .ready:
print("READY")
case .waiting(let error):
print("WAITING SERVER ERROR: \(error)\n")
print("DEBUG DESCRIPTION: " + connection.parameters.debugDescription)
print("CONNECTION STATE: \(connection.state)")
print("ENDPOINT: \(connection.endpoint)")
print("PARAMETERS: \(connection.parameters)")
case .failed(let error):
print("FAILED SERVER ERROR: \(error)")
default:
break
}
}
connection.start(queue: .main)
}
ERRORS:
2021-02-24 14:37:06.432222+0000 TLSHandshake[923:179774] [boringssl] boringssl_context_handle_fatal_alert(1763) [C2:1][0x106410070] read alert, level: fatal, description: handshake failure 2021-02-24 14:37:06.440314+0000 TLSHandshake[923:179774] [boringssl] boringssl_session_handshake_incomplete(90) [C2:1][0x106410070] SSL library error 2021-02-24 14:37:06.440469+0000 TLSHandshake[923:179774] [boringssl] boringssl_session_handshake_error_print(41) [C2:1][0x106410070] Error: 4399898168:error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE:/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-351.40.2/ssl/tls_record.cc:592:SSL alert number 40 2021-02-24 14:37:06.440581+0000 TLSHandshake[923:179774] [boringssl] nw_protocol_boringssl_handshake_negotiate_proceed(767) [C2:1][0x106410070] handshake failed at state 12288: not completed WAITING SERVER ERROR: -9824: Optional(handshake failure)
DEBUG DESCRIPTION: udp, tls, indefinite
CONNECTION STATE: waiting(-9824: Optional(handshake failure))
ENDPOINT: 192.168.178.59:2100
PARAMETERS: udp, tls, indefinite