diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs
index 69e0cfd1..55b4f503 100644
--- a/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs
+++ b/Common/Hardware/WaterMeter/Genesis/GenesisFile/MeterPwdFile.cs
@@ -223,6 +223,64 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile
return true;
}
+ ///
+ /// Check the hashed password file:
+ /// - Checks if password level 8 is unequal to skeleton key
+ /// - Checks if password level 3 is unequal to password level 8 (level 3 may be overwritten by level 8
+ /// password hash)
+ /// - Builds skeleton key password hash and checks if this is placed at password level 3,
+ /// - Builds password level 8 hash and checks if this is placed at level 8.
+ ///
+ ///
+ /// SkeletonKey for comparison
+ ///
+ ///
+ ///
+ /// - Initial.
+ ///
+ public Boolean CheckHashedPwdFile(Byte[] pwdFile, String skeletonKey, String pwdLevel8)
+ {
+
+ var retVal = false;
+ // the skeletonKey has to be unequally to the passwordLvl8
+ if (skeletonKey.Equals(pwdLevel8))
+ {
+ return false;
+ }
+
+ // compare hashed skeletonKey and passwordLvl8
+ for (var c = 0; c < MeterPwdDb.HashedPwdLength; c++)
+ {
+ // hashed level 3 and level 8 have to be unequal on at least one byte position
+ if (pwdFile[MeterPwdDb.SkeletonKeyIdx * MeterPwdDb.HashedPwdLength + c] !=
+ pwdFile[MeterPwdDb.PwdLevel8Idx * MeterPwdDb.HashedPwdLength + c])
+ {
+ retVal = true;
+ break;
+ }
+ }
+
+ // hash the skeleton and check if equal to hashed level 3
+ // hash the passwordLvl8 and check if equal to hashed level 8
+ using (var sha1 = new System.Security.Cryptography.SHA1Managed())
+ {
+ var skeletonHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(skeletonKey));
+ var passwordLvl8Hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(pwdLevel8));
+
+ for (var c = 0; c < MeterPwdDb.HashedPwdLength; c++)
+ {
+ // if any byte is different the passwords do not match
+ if (pwdFile[MeterPwdDb.SkeletonKeyIdx * MeterPwdDb.HashedPwdLength + c] != skeletonHash[c] ||
+ pwdFile[MeterPwdDb.PwdLevel8Idx * MeterPwdDb.HashedPwdLength + c] != passwordLvl8Hash[c])
+ {
+ return false;
+ }
+ }
+ }
+
+ return retVal;
+ }
+
///
/// Build skeleton key out of unique processor Id
///
diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateBuilder/FrmFwUpdateBuilder.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateBuilder/FrmFwUpdateBuilder.cs
index 435738e9..2d014734 100644
--- a/ServiceFwUpdate/Ui/ServiceFwUpdateBuilder/FrmFwUpdateBuilder.cs
+++ b/ServiceFwUpdate/Ui/ServiceFwUpdateBuilder/FrmFwUpdateBuilder.cs
@@ -1341,14 +1341,14 @@ namespace Xylem.ServiceFwUpdate.Ui.FwUpdateBuilder
fwUpdateSafe.Updates.CordonelDeviceInfos = _cordonelUpdateList;
////TODO THW remove this DEBUG to map from current selection to TEST BOARD
- //_cordonelUpdateList[0].CustomerSerialNumber = "8 SEN20 1975 6272";
- //_cordonelUpdateList[0].PcbId = "182100041";
- //GetPwdFromDb(_cordonelUpdateList[0]);
- //fwUpdateSafe.License.Build = 5;
- //var dateTime = fwUpdateSafe.License.ValidTo.AddDays(-1);
- //fwUpdateSafe.License.ValidTo = dateTime;
- //var addDays = fwUpdateSafe.SafeInfo.FwUpdateValidDate.AddDays(-1);
- //fwUpdateSafe.SafeInfo.FwUpdateValidDate = addDays;
+ _cordonelUpdateList[0].CustomerSerialNumber = "8 SEN20 1975 6272";
+ _cordonelUpdateList[0].PcbId = "182100041";
+ GetPwdFromDb(_cordonelUpdateList[0]);
+ fwUpdateSafe.License.Build = 5;
+ var dateTime = fwUpdateSafe.License.ValidTo.AddDays(-1);
+ fwUpdateSafe.License.ValidTo = dateTime;
+ var addDays = fwUpdateSafe.SafeInfo.FwUpdateValidDate.AddDays(-1);
+ fwUpdateSafe.SafeInfo.FwUpdateValidDate = addDays;
////TODO THW remove this DEBUG to map from current selection to TEST BOARD
var serializedData = JsonConvert.SerializeObject(fwUpdateSafe);
diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs
index 406f4095..318e3383 100644
--- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs
+++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/FrmServiceFwUpdateSw.cs
@@ -52,6 +52,8 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
private GenesisMeter _currentGenesis;
private readonly MeterBatch _meterBatch;
private Byte[] _hashedPwdFile;
+ private String _passwordLvl8;
+ private String _skeletonKey;
// port settings
private MeterPortScanner _serialPortScanner;
@@ -3006,15 +3008,15 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
}
// Search the PCB ID and extract password for login
- String password = null;
- String skeletonKey = null;
+ _skeletonKey = null;
+ _passwordLvl8 = null;
_genesisInUpdateList = false;
if (_cordonelDeviceInfos != null)
{
foreach (var device in _cordonelDeviceInfos.Where(device => _currentGenesis.PcbId == device.PcbId))
{
- skeletonKey = device.PwdContainer.SkeletonKey;
- password = device.PwdContainer.PasswordLvl8;
+ _skeletonKey = device.PwdContainer.SkeletonKey;
+ _passwordLvl8 = device.PwdContainer.PasswordLvl8;
if (!string.IsNullOrEmpty(device.CustomerSerialNumber))
_customerSerialNumber = device.CustomerSerialNumber;
@@ -3026,7 +3028,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
}
}
- if (password == null || skeletonKey == null)
+ if (_passwordLvl8 == null || _skeletonKey == null)
{
_processState = ProcessState.Error;
return false;
@@ -3038,7 +3040,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
// This login may be time consuming on readout of application information
// first try to login with password Level 8, this is needed if the password file is installed
- if (LoginAndSpecialSetupProcedure(password))
+ if (LoginAndSpecialSetupProcedure(_passwordLvl8))
{
LogText(Resources.StrLoginPwdLevel8);
_passwordFileIsCorrupted = false;
@@ -3057,7 +3059,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
Thread.Sleep(5000);
// Use the skeleton key for login as the password file may not be installed or invalid
- if (LoginAndSpecialSetupProcedure(skeletonKey))
+ if (LoginAndSpecialSetupProcedure(_skeletonKey))
{
LogText(Resources.StrLoginSkeletonKey);
return true;
@@ -3736,13 +3738,12 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
return;
}
- //TODO THW avoid installation of password file if hash of level 3 equals level 8
- //TODO THW avoid installation if password file level 3 is unequal hashed skeletonKey
- //TODO THW avoid installation if password file level 8 is unequal hashed password
InfoProcessActive(lblPasswordFileCheck, Resources.StrPasswordFileRestoreActive);
// try to install password, first get the password file from device info
var pwdFileObject = new MeterPwdFile(_currentGenesis);
- if (_hashedPwdFile != null && _hashedPwdFile.Length == MeterPwdDb.PwdFileLength)
+ if (_hashedPwdFile != null &&
+ _hashedPwdFile.Length == MeterPwdDb.PwdFileLength &&
+ pwdFileObject.CheckHashedPwdFile(_hashedPwdFile , _skeletonKey, _passwordLvl8))
{
SetControlsCommunicationActive();
_currentGenesis?.ReLogin();
@@ -3768,7 +3769,7 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw
// the password file is NOT in the password container
else
{
- InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordNotDelivered);
+ InfoProcessFailed(lblPasswordFileCheck, Resources.StrPasswordFileFromSafeInvalid);
_processState = errorExitState;
}
diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs
index 82a8f624..5652a101 100644
--- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs
+++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.Designer.cs
@@ -745,6 +745,15 @@ namespace Xylem.ServiceFwUpdate.Ui.ServiceFwUpdateSw.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to ERROR: Password file from FW update safe is invalid!.
+ ///
+ internal static string StrPasswordFileFromSafeInvalid {
+ get {
+ return ResourceManager.GetString("StrPasswordFileFromSafeInvalid", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ERROR: Password file not installed or invalid!.
///
diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx
index ed4d5f64..c3ae07a8 100644
--- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx
+++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.de.resx
@@ -604,4 +604,7 @@
FW-Update Builderoperator ID:
+
+ FEHLER: Paßwortdatei vom FW Update Safe ist ungültig!
+
\ No newline at end of file
diff --git a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx
index b9f53c7c..1cf5292e 100644
--- a/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx
+++ b/ServiceFwUpdate/Ui/ServiceFwUpdateSw/Properties/Resources.resx
@@ -604,4 +604,7 @@
FW-Update Builder Operator ID:
+
+ ERROR: Password file from FW update safe is invalid!
+
\ No newline at end of file