$Host = 'x.x.x.x'; //hier IP-Adresse TV eintragen $parent_arr = IPS_GetObject(IPS_GetObject($IPS_SELF)['ParentID']); $kategorie_id = $parent_arr['ObjectID']; if (@IPS_GetVariableIDByName ('init_vector', $kategorie_id) == false) create_variabeln($kategorie_id); //anlegen der benötigten Variablen $id_init_vector = IPS_GetVariableIDByName ('init_vector', $kategorie_id); $id_PinCode = IPS_GetVariableIDByName ('PinCode', $kategorie_id); if(GetValue($id_init_vector) == '') { $init_vector = request_pin_code($Host); // erster Scriptdurchlauf Schritte Pin-Abfrage $init_vector = implode(',', $init_vector); SetValue($id_init_vector, $init_vector); //speichern init_vector } Else { $init_vector = GetValue($id_init_vector); // zweiter Scriptdurchlauf $init_vector_Chr = explode(',', $init_vector); $init_vector = ChrArr_to_IntArr($init_vector_Chr); $PinCode = GetValue($id_PinCode); $key = derive_key($init_vector); //aus init_vector wird key abgeleitet $hmac_key = derive_hmac_key($init_vector); //aus init_vector wurd hmac_key abgeleitet $auth_result = authorice_pin($Host, $key, $init_vector, $hmac_key, $PinCode); //PinCode und keys an TV zurück kommt eine Antwort $keys = derive_session_keys($auth_result, $key, $init_vector); //aus der Antwort werden die Session-Keys und die app-id abgeleitet $id_session_init_vector = IPS_GetVariableIDByName ('session_iv', $kategorie_id); $id_session_key = IPS_GetVariableIDByName ('session_key', $kategorie_id); $id_session_hmac_key = IPS_GetVariableIDByName ('session_hmac_key', $kategorie_id); $id_app_id = IPS_GetVariableIDByName ('app_id', $kategorie_id); SetValue($id_session_init_vector, $keys['session_iv']); //speichern der Ergebnisse SetValue($id_session_key, $keys['session_key']); SetValue($id_session_hmac_key, $keys['session_hmac_key']); SetValue($id_app_id, $keys['app_id']); } // Funktionen ================================================================================================ function create_variabeln($kategorie_id) { $PinCode = IPS_CreateVariable(3); IPS_SetName($PinCode, "PinCode"); IPS_SetParent($PinCode, $kategorie_id); $Init_Vector = IPS_CreateVariable(3); IPS_SetName($Init_Vector, "init_vector"); IPS_SetParent($Init_Vector, $kategorie_id); $session_iv = IPS_CreateVariable(3); IPS_SetName($session_iv, "session_iv"); IPS_SetParent($session_iv, $kategorie_id); $session_key = IPS_CreateVariable(3); IPS_SetName($session_key, "session_key"); IPS_SetParent($session_key, $kategorie_id); $session_hmac_key = IPS_CreateVariable(3); IPS_SetName($session_hmac_key, "session_hmac_key"); IPS_setParent($session_hmac_key, $kategorie_id); $app_id = IPS_CreateVariable(3); IPS_SetName($app_id, "app_id"); IPS_SetParent($app_id, $kategorie_id); $session_sequ_num = IPS_CreateVariable(1); IPS_SetName($session_sequ_num, "session_sequ_num"); IPS_SetParent($session_sequ_num, $kategorie_id); $session_id = IPS_CreateVariable(3); IPS_SetName($session_id, "session_id"); IPS_SetParent($session_id, $kategorie_id); $session_is_open = IPS_CreateVariable(0); IPS_SetName($session_is_open, "session_is_open"); IPS_SetParent($session_is_open, $kategorie_id); return; } function request_pin_code($Host, $name='Fernbedienung') { $params = ''.$name.''; $res = SoapRequest($Host, 'nrc/control_0', 'panasonic-com:service:p00NetworkControl:1', 'X_DisplayPinCode', [ 'args' => $params, 'returnXml' => false],'u'); $res = base64_decode($res); $init_vector = str_split($res, 1); for ($i = 0; $i <= 15; $i++) $init_vector[$i] = ord($init_vector[$i]); return($init_vector); } function authorice_pin($Host, $key, $init_vector, $hmac_key, $PinCode) { $data = ''.$PinCode.''; $payload = encrypt_soap_payload($data,$key, $init_vector, $hmac_key); $params = ''.$payload.''; $res = SoapRequest($Host, 'nrc/control_0', 'panasonic-com:service:p00NetworkControl:1', 'X_RequestAuth', [ 'args' => $params, 'returnXml' => false],'u'); return($res); } function derive_session_keys($auth_result, $key, $init_vector) { $res =decrypt_soap_payload($auth_result, $key, $init_vector); $pattern = "|>(.*?)<|"; preg_match_all($pattern, $res, $matches); $app_id = $matches[1][0]; $enc_key = $matches[1][1]; $enc_key = base64_decode($enc_key); $session_iv = str_split($enc_key, 1); for ($i = 0; $i < 16; $i++) $session_iv[$i] = ord($session_iv[$i]); $session_key = array(); $i=0; while($i < 16) { $session_key[$i] = $session_iv[$i + 2]; $session_key[$i + 1] = $session_iv[$i + 3]; $session_key[$i + 2] = $session_iv[$i]; $session_key[$i + 3] = $session_iv[$i + 1]; $i = $i+4; } $session_hmac_key = array_merge($session_iv,$session_iv); $session_iv = array_to_string($session_iv); $session_key = array_to_string($session_key); $session_hmac_key = array_to_string($session_hmac_key); $res = array ( 'session_iv' => base64_encode($session_iv), 'session_key' => base64_encode($session_key), 'session_hmac_key' => base64_encode($session_hmac_key), 'app_id' => $app_id); return ($res); } function SoapRequest($Host, $path, $urn, $action, $option = [], $Body_Element){ $input = ' <'.$Body_Element.':' . $action . ' xmlns:'.$Body_Element.'="urn:' . $urn . '">' . $option['args'] .' '; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, 'http://' . $Host . ':55000/' . $path); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_HTTPHEADER, ['SOAPACTION: "urn:' . $urn . '#' . $action . '"']); curl_setopt($curl, CURLOPT_POSTFIELDS, $input); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($curl); if ($option['returnXml']) { return $data; } else { $xml = simplexml_load_string($data); if ($xml === false) { trigger_error('SoapRequest failed (action = ' . $action . ')'); } $ns = $xml->getNamespaces(true); $soap = $xml->children($ns['s']); $res = $soap->children($ns['u'])->children(); return $res[0]; } } function decrypt_soap_payload($data, $key, $init_vector) { $strinit_vector = ''; for ($i = 0; $i < 16; $i++) $strinit_vector = $strinit_vector.chr($init_vector[$i]); $strkey = ''; for ($i = 0; $i < 16; $i++) $strkey = $strkey.chr($key[$i]); $ciphertext = base64_decode($data); $cipher="AES-128-CBC"; $result = openssl_decrypt($ciphertext, 'AES-128-CBC', $strkey, 3, $strinit_vector); return($result); } function encrypt_soap_payload($data, $key, $init_vector, $hmac_key) { $payload = ''; for ($i = 0; $i <= 11; $i++) $payload=$payload.chr(rand(0,255)); $payload = $payload.pack("N", strlen($data)).$data; $add = 16- (strlen($payload)%16); $i = 0; while($i < $add) { $payload = $payload.chr(0); $i = $i+1; } $strinit_vector = ''; $strhmac_key = ''; $strkey = ''; for ($i = 0; $i < 16; $i++) $strinit_vector = $strinit_vector.chr($init_vector[$i]); for ($i = 0; $i < 32; $i++) $strhmac_key = $strhmac_key.chr($hmac_key[$i]); for ($i = 0; $i < 16; $i++) $strkey = $strkey.chr($key[$i]); $ciphertext = openssl_encrypt($payload, 'AES-128-CBC', $strkey, $options=1, $strinit_vector); $sig = hash_hmac('sha256', $ciphertext, $strhmac_key, true); $result = base64_encode($ciphertext.$sig); return ($result); } function ChrArr_to_IntArr($data) { $result = array(); for ($i = 0; $i < count($data); $i++) $result[$i] = strval($data[$i]); return($result); } function array_to_string($data) { $str = ''; for ($i = 0; $i < count($data); $i++) $str = $str.chr($data[$i]); return($str); } function derive_key($init_vector) { $key = array(); $i=0; while($i < 16) { $key[$i] = $init_vector[$i + 3] ^ 255; $key[$i + 1] = $init_vector[$i + 2] ^ 255; $key[$i + 2] = $init_vector[$i + 1] ^ 255; $key[$i + 3] = $init_vector[$i] ^ 255; $i = $i + 4; } return($key); } function derive_hmac_key($init_vector) { $hmac_key_mask_vals = [ 0x15,0xC9,0x5A,0xC2,0xB0,0x8A,0xA7,0xEB,0x4E,0x22,0x8F,0x81,0x1E, 0x34,0xD0,0x4F,0xA5,0x4B,0xA7,0xDC,0xAC,0x98,0x79,0xFA,0x8A,0xCD, 0xA3,0xFC,0x24,0x4F,0x38,0x54]; $hmac_key = array(); $i = 0; while ($i < 32) { $hmac_key[$i] = $hmac_key_mask_vals[$i] ^ $init_vector[($i + 2) & 0xF]; $hmac_key[$i + 1] = $hmac_key_mask_vals[$i + 1] ^ $init_vector[($i + 3) & 0xF]; $hmac_key[$i + 2] = $hmac_key_mask_vals[$i + 2] ^ $init_vector[$i & 0xF]; $hmac_key[$i + 3] = $hmac_key_mask_vals[$i + 3] ^ $init_vector[($i + 1) & 0xF]; $i = $i+ 4; } return($hmac_key); }