mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
10_ZWave.pm: Update NONCE Handling (Forum #60976)
git-svn-id: https://svn.fhem.de/fhem/trunk@12909 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
b03ef8ff29
commit
4164c2188c
@ -3592,16 +3592,97 @@ ZWave_secCreateNonce($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
if (ZWave_secIsEnabled($hash)) {
|
||||
my $nonce = ZWave_secGetNonce();
|
||||
setReadingsVal($hash, "send_nonce", $nonce, TimeNow());
|
||||
#return ("",'80'.$nonce);
|
||||
my $nonce;
|
||||
my $nonce_id;
|
||||
my $n=0;
|
||||
|
||||
$hash->{secNonce} = {} if (!$hash->{secNonce});
|
||||
foreach my $id (sort keys %{$hash->{secNonce}}) {
|
||||
$n++;
|
||||
}
|
||||
|
||||
my $time = gettimeofday();
|
||||
if ($n>50) { #clean up only if more than 50 nonce are active
|
||||
foreach my $id (sort keys %{$hash->{secNonce}}) {
|
||||
my $dt = $time - $hash->{secNonce}{$id}{timeStamp};
|
||||
if ($dt > 10) {
|
||||
Log3 $hash->{NAME}, 3, "$hash->{NAME}: SECURITY: nonce "
|
||||
.$hash->{secNonce}{$id}{nonce} ."is too old ("
|
||||
.sprintf("%d seconds", $dt)
|
||||
.") and is removed from list";
|
||||
delete($hash->{secNonce}{$id});
|
||||
$n--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($n >10) {
|
||||
Log3 $hash->{NAME}, 2, "$hash->{NAME}: SECURITY: multiple nonce warning, "
|
||||
."there are $n nonce active";
|
||||
}
|
||||
|
||||
$n=0;
|
||||
do {
|
||||
$nonce = ZWave_secGetNonce();
|
||||
$nonce_id = substr($nonce, 0, 2);
|
||||
$n++;
|
||||
} until ((!$hash->{secNonce}{$nonce_id}) || $n>512);
|
||||
|
||||
if ($n >512) {
|
||||
Log3 $hash->{NAME}, 1, "$hash->{NAME}: SECURITY: could not generate "
|
||||
."unique nonce, ignoring request!";
|
||||
return ('00');
|
||||
}
|
||||
|
||||
my $id = substr($nonce, 0 ,2);
|
||||
|
||||
$hash->{secNonce} = {} if (!$hash->{secNonce});
|
||||
|
||||
$hash->{secNonce}{$id}{nonce} = $nonce;
|
||||
$hash->{secNonce}{$id}{timeStamp} = gettimeofday();
|
||||
|
||||
return ('80'.$nonce);
|
||||
} else {
|
||||
#return ("", '00');
|
||||
return ('00');
|
||||
}
|
||||
}
|
||||
|
||||
sub
|
||||
ZWave_secRetrieveNonce($$)
|
||||
{
|
||||
my ($hash, $s_nonce_id_hex) = @_;
|
||||
my $s_nonce_hex;
|
||||
my $n=0;
|
||||
|
||||
return undef if (!$hash->{secNonce});
|
||||
|
||||
# remove old (>10 seconds) entries BEFORE trying to retrieve nonce
|
||||
my $time = gettimeofday();
|
||||
foreach my $id (sort keys %{$hash->{secNonce}}) {
|
||||
$n++;
|
||||
my $dt = $time - $hash->{secNonce}{$id}{timeStamp};
|
||||
if ($dt > 10) {
|
||||
Log3 $hash->{NAME}, 5, "$hash->{NAME}: SECURITY: nonce "
|
||||
.$hash->{secNonce}{$id}{nonce} ."is too old ("
|
||||
.sprintf("%d seconds", $dt)
|
||||
.") and is removed from list";
|
||||
delete($hash->{secNonce}{$id});
|
||||
$n--;
|
||||
}
|
||||
}
|
||||
if ($n >1) {
|
||||
Log3 $hash->{NAME}, 5, "$hash->{NAME}: SECURITY: multiple nonce warning, "
|
||||
."there are $n nonce active";
|
||||
}
|
||||
|
||||
if ($hash->{secNonce}{$s_nonce_id_hex}) {
|
||||
$s_nonce_hex = $hash->{secNonce}{$s_nonce_id_hex}{nonce};
|
||||
delete($hash->{secNonce}{$s_nonce_id_hex});
|
||||
return $s_nonce_hex;
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub
|
||||
ZWave_secGetNonce()
|
||||
{
|
||||
@ -3664,15 +3745,6 @@ ZWave_secDecrypt($$$)
|
||||
my $enc_key = ZWave_secEncryptECB($key, $init_enc_key);
|
||||
my $auth_key = ZWave_secEncryptECB($key, $init_auth_key);
|
||||
|
||||
my $s_nonce_hex = ReadingsVal($name, "send_nonce", undef);
|
||||
if (!$s_nonce_hex) {
|
||||
Log3 $name, 1, "$name: Error, no send_nonce to decrypt message available";
|
||||
ZWave_secEnd($hash);
|
||||
return "";
|
||||
}
|
||||
|
||||
delete $hash->{READINGS}{send_nonce};
|
||||
|
||||
# encrypted message format:
|
||||
# data= bcb328fe5d924a402b2901fc2699cc3bcacd30e0
|
||||
# bcb328fe5d924a40 = 8 byte r_nonce
|
||||
@ -3685,6 +3757,14 @@ ZWave_secDecrypt($$$)
|
||||
return "";
|
||||
}
|
||||
my ($r_nonce_hex, $msg_hex, $s_nonce_id_hex, $auth_code_hex) = ($1, $2, $3, $4);
|
||||
my $s_nonce_hex = ZWave_secRetrieveNonce($hash, $s_nonce_id_hex);
|
||||
if (!$s_nonce_hex) {
|
||||
Log3 $name, 1, "$name: Error, no send_nonce to decrypt message available";
|
||||
ZWave_secEnd($hash);
|
||||
return "";
|
||||
}
|
||||
Log3 $name, 5, "$name: secDecrypt: send_nonce $s_nonce_hex with "
|
||||
."nonce_id $s_nonce_id_hex retrieved";
|
||||
|
||||
my $iv = pack 'H*', $r_nonce_hex . $s_nonce_hex;
|
||||
my $out_hex = ZWave_secEncryptOFB ($enc_key, $iv, $msg_hex);
|
||||
|
Loading…
Reference in New Issue
Block a user