diff --git a/KeyManager.Library.KeyStore.HSM_PKCS11/PKCS11KeyStore.cs b/KeyManager.Library.KeyStore.HSM_PKCS11/PKCS11KeyStore.cs index 6cb064d..1b91eb4 100644 --- a/KeyManager.Library.KeyStore.HSM_PKCS11/PKCS11KeyStore.cs +++ b/KeyManager.Library.KeyStore.HSM_PKCS11/PKCS11KeyStore.cs @@ -117,7 +117,7 @@ public override async Task Create(IChangeKeyEntry change) { foreach (var material in entry.Variant.KeyContainers[0].Key.Materials) { - var rawkey = material.GetFormattedValue(KeyValueFormat.Binary); + var rawkey = material.GetValueBinary(); if (rawkey != null) { var attributes = GetKeyEntryAttributes(entry, true); @@ -586,7 +586,7 @@ public override async Task Update(IChangeKeyEntry change, bool ignoreIfMissing) var attributes = GetKeyEntryAttributes(entry); if (entry.Variant?.KeyContainers.Count == 1) { - var rawkey = entry.Variant.KeyContainers[0].Key.GetAggregatedValue(KeyValueFormat.Binary); + var rawkey = entry.Variant.KeyContainers[0].Key.GetAggregatedValueBinary(); if (rawkey != null) { // We should already have only one key material during an update diff --git a/KeyManager.Library.KeyStore.LCP/LCPKeyStore.cs b/KeyManager.Library.KeyStore.LCP/LCPKeyStore.cs index 33b22b0..59b1d1c 100644 --- a/KeyManager.Library.KeyStore.LCP/LCPKeyStore.cs +++ b/KeyManager.Library.KeyStore.LCP/LCPKeyStore.cs @@ -127,7 +127,7 @@ public override async Task Delete(KeyEntryId identifier, KeyEntryClass keClass, var kc = ke.Variant.KeyContainers[0]; if (!string.IsNullOrEmpty(key.Value)) { - kc.Key.SetAggregatedValue(key.Value); + kc.Key.SetAggregatedValueString(key.Value); } if (kc is KeyVersion kv && key.Version != null) { @@ -280,7 +280,7 @@ private static CredentialKey CreateCredentialKey(KeyEntryId identifier, KeyConta } if (kc != null) { - var rawkey = kc.Key.GetAggregatedValue(KeyValueFormat.Binary); + var rawkey = kc.Key.GetAggregatedValueBinary(); key.Value = (rawkey != null) ? Convert.ToHexString(rawkey) : null; } if (!string.IsNullOrEmpty(kc?.Key.Link?.KeyStoreFavorite)) diff --git a/KeyManager.Library.KeyStore.NXP_SAM.UI/Domain/SAMKeyStoreToolsControlViewModel.cs b/KeyManager.Library.KeyStore.NXP_SAM.UI/Domain/SAMKeyStoreToolsControlViewModel.cs index 13ee9f5..fb6653c 100644 --- a/KeyManager.Library.KeyStore.NXP_SAM.UI/Domain/SAMKeyStoreToolsControlViewModel.cs +++ b/KeyManager.Library.KeyStore.NXP_SAM.UI/Domain/SAMKeyStoreToolsControlViewModel.cs @@ -152,7 +152,7 @@ private void SAMAuthenticate() key.setKeyType(LibLogicalAccess.Card.DESFireKeyType.DF_KEY_3K3DES); } - key.fromString(SAMAuthKey.Key.GetAggregatedValue(KeyValueFormat.HexStringWithSpace)); + key.fromString(SAMAuthKey.Key.GetAggregatedValueString(KeyValueStringFormat.HexStringWithSpace)); key.setKeyVersion(SAMAuthKey.Version); var cmd = (KeyStore as SAMKeyStore)?.Chip?.getCommands(); if (cmd is SAMAV1ISO7816Commands samav1cmd) @@ -231,7 +231,7 @@ private void SAMLockUnlock() var key = new LibLogicalAccess.Card.DESFireKey(); key.setKeyType(LibLogicalAccess.Card.DESFireKeyType.DF_KEY_AES); - key.fromString(SAMUnlockKey.Key.GetAggregatedValue(KeyValueFormat.HexStringWithSpace)); + key.fromString(SAMUnlockKey.Key.GetAggregatedValueString(KeyValueStringFormat.HexStringWithSpace)); key.setKeyVersion(SAMUnlockKey.Version); if (cmd is SAMAV1ISO7816Commands samav1cmd) diff --git a/KeyManager.Library.KeyStore.NXP_SAM/ISLOG/ISLOGKeyStore.cs b/KeyManager.Library.KeyStore.NXP_SAM/ISLOG/ISLOGKeyStore.cs index 92b42dd..70de994 100644 --- a/KeyManager.Library.KeyStore.NXP_SAM/ISLOG/ISLOGKeyStore.cs +++ b/KeyManager.Library.KeyStore.NXP_SAM/ISLOG/ISLOGKeyStore.cs @@ -128,28 +128,26 @@ public override async Task Open() var versionEl = keEl.Element("KeyVersion"); if (versionEl != null && keyEl != null) { - var keya = ke.Variant.KeyContainers[0] as KeyVersion; - var keyb = ke.Variant.KeyContainers[1] as KeyVersion; KeyVersion? keyc = null; if (ke.Variant.KeyContainers.Count > 2) { keyc = ke.Variant.KeyContainers[2] as KeyVersion; } - if (keya != null) + if (ke.Variant.KeyContainers[0] is KeyVersion keya) { keya.Version = byte.Parse(versionEl.Attribute("vera")?.Value ?? "0"); - keya.Key.SetAggregatedValue(keyEl.Attribute("keya")?.Value ?? string.Empty); + keya.Key.SetAggregatedValueString(keyEl.Attribute("keya")?.Value ?? string.Empty); } - if (keyb != null) + if (ke.Variant.KeyContainers[1] is KeyVersion keyb) { keyb.Version = byte.Parse(versionEl.Attribute("verb")?.Value ?? "0"); - keyb.Key.SetAggregatedValue(keyEl.Attribute("keyb")?.Value ?? string.Empty); + keyb.Key.SetAggregatedValueString(keyEl.Attribute("keyb")?.Value ?? string.Empty); } if (keyc != null) { keyc.Version = byte.Parse(versionEl.Attribute("verc")?.Value ?? "0"); - keyc.Key.SetAggregatedValue(keyEl.Attribute("keyc")?.Value ?? string.Empty); + keyc.Key.SetAggregatedValueString(keyEl.Attribute("keyc")?.Value ?? string.Empty); } } } diff --git a/KeyManager.Library.KeyStore.NXP_SAM/SAMKeyStore.cs b/KeyManager.Library.KeyStore.NXP_SAM/SAMKeyStore.cs index f4a4dce..e0a0cce 100644 --- a/KeyManager.Library.KeyStore.NXP_SAM/SAMKeyStore.cs +++ b/KeyManager.Library.KeyStore.NXP_SAM/SAMKeyStore.cs @@ -250,14 +250,14 @@ public override Task MoveUp(KeyEntryId identifier, KeyEntryClass keClass) throw new KeyStoreException("Unexpected number of keys on the SAM Key Entry."); } - keyVersions[0].Key.SetAggregatedValue(Convert.ToHexString(keysdata[0].ToArray())); + keyVersions[0].Key.SetAggregatedValueString(Convert.ToHexString(keysdata[0].ToArray())); keyVersions[0].Version = infoav2.vera; - keyVersions[1].Key.SetAggregatedValue(Convert.ToHexString(keysdata[1].ToArray())); + keyVersions[1].Key.SetAggregatedValueString(Convert.ToHexString(keysdata[1].ToArray())); keyVersions[1].Version = infoav2.verb; if (keyEntry.Variant.KeyContainers.Count >= 3) { - keyVersions[2].Key.SetAggregatedValue(Convert.ToHexString(keysdata[2].ToArray())); + keyVersions[2].Key.SetAggregatedValueString(Convert.ToHexString(keysdata[2].ToArray())); keyVersions[2].Version = infoav2.verc; } } @@ -393,7 +393,7 @@ public override Task Update(IChangeKeyEntry change, bool ignoreIfMissing) key.setKeyVersion(GetSAMProperties().AuthenticateKeyVersion); if (!string.IsNullOrEmpty(Properties?.Secret)) { - key.fromString(KeyMaterial.GetFormattedValue(Properties.Secret, KeyValueFormat.HexStringWithSpace)); + key.fromString(KeyMaterial.GetValueString(Properties.Secret, KeyValueStringFormat.HexStringWithSpace)); } else { @@ -428,13 +428,13 @@ public override Task Update(IChangeKeyEntry change, bool ignoreIfMissing) var keys = new LibLogicalAccess.UCharCollectionCollection(keyVersions.Length); foreach (var keyversion in samkey.Variant.KeyContainers) { - if (string.IsNullOrEmpty(keyversion.Key.GetAggregatedValue())) + if (string.IsNullOrEmpty(keyversion.Key.GetAggregatedValueString())) { keys.Add(new LibLogicalAccess.ByteVector(new byte[keyversion.Key.KeySize])); } else { - keys.Add(new LibLogicalAccess.ByteVector(keyversion.Key.GetAggregatedValue(KeyValueFormat.Binary))); + keys.Add(new LibLogicalAccess.ByteVector(keyversion.Key.GetAggregatedValueBinary())); } } @@ -532,7 +532,7 @@ public static void SwitchSAMToAV2(LibLogicalAccess.Reader.SAMAV1ISO7816Commands var key = CreateDESFireKey(keyType, keyVersion, keyValue); if (keyType != LibLogicalAccess.Card.DESFireKeyType.DF_KEY_AES) { - var kb = KeyMaterial.GetFormattedValue(keyValue, KeyValueFormat.Binary); + var kb = Convert.FromHexString(keyValue); var keys = new LibLogicalAccess.UCharCollectionCollection(3) { new LibLogicalAccess.ByteVector(kb), @@ -568,7 +568,7 @@ public static LibLogicalAccess.Card.DESFireKey CreateDESFireKey(LibLogicalAccess key.setKeyType(keyType); if (!string.IsNullOrEmpty(keyValue)) { - key.fromString(KeyMaterial.GetFormattedValue(keyValue, KeyValueFormat.HexStringWithSpace)); + key.fromString(KeyMaterial.GetValueString(keyValue, KeyValueStringFormat.HexStringWithSpace)); } return key; } @@ -653,7 +653,7 @@ public void UpdateCounter(SAMKeyUsageCounter counter) key.setKeyVersion(GetSAMProperties().AuthenticateKeyVersion); if (!string.IsNullOrEmpty(Properties?.Secret)) { - key.fromString(KeyMaterial.GetFormattedValue(Properties.Secret, KeyValueFormat.HexStringWithSpace)); + key.fromString(KeyMaterial.GetValueString(Properties.Secret, KeyValueStringFormat.HexStringWithSpace)); } else { @@ -714,7 +714,7 @@ public void UpdateCounter(SAMKeyUsageCounter counter) { if (!string.IsNullOrEmpty(GetSAMProperties().Secret) && !_unlocked) { - UnlockSAM(av2cmd, GetSAMProperties().AuthenticateKeyEntryIdentifier, GetSAMProperties().AuthenticateKeyVersion, KeyMaterial.GetFormattedValue(Properties?.Secret, KeyValueFormat.HexStringWithSpace)); + UnlockSAM(av2cmd, GetSAMProperties().AuthenticateKeyEntryIdentifier, GetSAMProperties().AuthenticateKeyVersion, KeyMaterial.GetValueString(Properties?.Secret, KeyValueStringFormat.HexStringWithSpace)); _unlocked = true; } diff --git a/KeyManager.Library.Tests/KeyGenerationTests.cs b/KeyManager.Library.Tests/KeyGenerationTests.cs new file mode 100644 index 0000000..9017fe5 --- /dev/null +++ b/KeyManager.Library.Tests/KeyGenerationTests.cs @@ -0,0 +1,30 @@ +namespace Leosac.KeyManager.Library.Tests +{ + [TestClass] + public class KeyGenerationTests + { + [TestMethod] + [DataRow(8)] + [DataRow(16)] + [DataRow(32)] + public void Test_Random(int keySize) + { + var key1 = KeyGeneration.Random(keySize); + Assert.AreEqual(keySize * 2, key1.Length); + + var key2 = KeyGeneration.Random(keySize); + Assert.AreNotEqual(key1, key2); + } + + [TestMethod] + [DataRow(8)] + [DataRow(16)] + [DataRow(32)] + public void Test_FromPassword(int keySize) + { + var key = KeyGeneration.FromPassword("test", "Security Freedom", keySize); + var rkey = "E088566240571EAD486818BE1199F53EB407411014BA1E36101C242FC34DEBAF"[..(keySize * 2)]; + Assert.AreEqual(rkey, key, true); + } + } +} diff --git a/KeyManager.Library.Tests/KeyTests.cs b/KeyManager.Library.Tests/KeyTests.cs new file mode 100644 index 0000000..4ae9f31 --- /dev/null +++ b/KeyManager.Library.Tests/KeyTests.cs @@ -0,0 +1,73 @@ +namespace Leosac.KeyManager.Library.Tests +{ + [TestClass] + public class KeyTests + { + [TestMethod] + public void OneMaterial_GetAggregatedValue_HexString() + { + var key = new Key(null, "00112233445566778899AABBCCDDEEFF"); + var v = key.GetAggregatedValueString(); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", v, true); + } + + [TestMethod] + public void OneMaterial_SetAggregatedValue_HexString() + { + var key = new Key(); + key.SetAggregatedValueString("00112233445566778899AABBCCDDEEFF"); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", key.Materials[0].Value, true); + } + + [TestMethod] + public void OneMaterial_GetAggregatedValue_Binary() + { + var key = new Key(null, "00112233445566778899AABBCCDDEEFF"); + var v = key.GetAggregatedValueBinary(); + Assert.IsNotNull(v); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", Convert.ToHexString(v), true); + } + + [TestMethod] + public void OneMaterial_GetAggregatedValue_HexStringWithSpace() + { + var key = new Key(null, "00112233445566778899AABBCCDDEEFF"); + var v = key.GetAggregatedValueString(KeyValueStringFormat.HexStringWithSpace); + Assert.AreEqual("00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF", v, true); + } + + [TestMethod] + public void OneMaterial_SetAggregatedValue_HexStringWithSpace() + { + var key = new Key(); + key.SetAggregatedValueString("00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF", KeyValueStringFormat.HexStringWithSpace); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", key.Materials[0].Value, true); + } + + [TestMethod] + public void TwoMaterials_GetAggregatedValue_HexString() + { + var key = new Key(null, 8, new KeyMaterial("0011223344556677"), new KeyMaterial("8899AABBCCDDEEFF")); + var v = key.GetAggregatedValueString(); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", v, true); + } + + [TestMethod] + public void TwoMaterials_SetAggregatedValue_HexString() + { + var key = new Key(null, 8, 2); + key.SetAggregatedValueString("00112233445566778899AABBCCDDEEFF"); + Assert.AreEqual("0011223344556677", key.Materials[0].Value, true); + Assert.AreEqual("8899AABBCCDDEEFF", key.Materials[1].Value, true); + } + + [TestMethod] + public void TwoMaterials_GetAggregatedValue_Binary() + { + var key = new Key(null, 8, new KeyMaterial("0011223344556677"), new KeyMaterial("8899AABBCCDDEEFF")); + var v = key.GetAggregatedValueBinary(); + Assert.IsNotNull(v); + Assert.AreEqual("00112233445566778899AABBCCDDEEFF", Convert.ToHexString(v), true); + } + } +} diff --git a/KeyManager.Library.UI/Domain/KeyChecksumConverter.cs b/KeyManager.Library.UI/Domain/KeyChecksumConverter.cs index b1cca09..606355e 100644 --- a/KeyManager.Library.UI/Domain/KeyChecksumConverter.cs +++ b/KeyManager.Library.UI/Domain/KeyChecksumConverter.cs @@ -12,7 +12,7 @@ public object Convert(object[] values, Type targetType, object parameter, Cultur return Binding.DoNothing; } - if (string.IsNullOrEmpty(value2.GetAggregatedValue())) + if (string.IsNullOrEmpty(value2.GetAggregatedValueString())) { return Binding.DoNothing; } diff --git a/KeyManager.Library.UI/KeyActionButtonsControl.xaml.cs b/KeyManager.Library.UI/KeyActionButtonsControl.xaml.cs index da0240d..d6599ab 100644 --- a/KeyManager.Library.UI/KeyActionButtonsControl.xaml.cs +++ b/KeyManager.Library.UI/KeyActionButtonsControl.xaml.cs @@ -60,7 +60,7 @@ public KeyEntryClass KClass private void BtnCopy_Click(object sender, RoutedEventArgs e) { - Clipboard.SetText(Key?.GetAggregatedValue()); + Clipboard.SetText(Key?.GetAggregatedValueString()); } private async void BtnKeyStoreLink_Click(object sender, RoutedEventArgs e) @@ -90,7 +90,7 @@ private void BtnImport_Click(object sender, RoutedEventArgs e) if (ofd.ShowDialog() == true) { var key = System.IO.File.ReadAllBytes(ofd.FileName); - Key.SetAggregatedValue(Convert.ToHexString(key)); + Key.SetAggregatedValueString(Convert.ToHexString(key)); } } @@ -99,7 +99,7 @@ private void BtnExport_Click(object sender, RoutedEventArgs e) var sfd = new SaveFileDialog(); if (sfd.ShowDialog() == true) { - System.IO.File.WriteAllBytes(sfd.FileName, Convert.FromHexString(Key.GetAggregatedValue() ?? "")); + System.IO.File.WriteAllBytes(sfd.FileName, Convert.FromHexString(Key.GetAggregatedValueString() ?? "")); } } @@ -115,7 +115,7 @@ private void BtnPrint_Click(object sender, RoutedEventArgs e) if (KClass == KeyEntryClass.Symmetric) { var kcv = new KCV(); - control.KeyChecksum = kcv.ComputeKCV(Key.Tags, Key.GetAggregatedValue() ?? "", null); + control.KeyChecksum = kcv.ComputeKCV(Key.Tags, Key.GetAggregatedValueString() ?? "", null); } printDialog.PrintVisual(control, "Leosac Key Manager - Key Printing"); } diff --git a/KeyManager.Library/CRC32Checksum.cs b/KeyManager.Library/CRC32Checksum.cs index f39290d..43eac2d 100644 --- a/KeyManager.Library/CRC32Checksum.cs +++ b/KeyManager.Library/CRC32Checksum.cs @@ -8,7 +8,7 @@ public class CRC32Checksum : KeyChecksum public override byte[] ComputeKCV(Key key, byte[]? iv) { - var rawkey = key.GetAggregatedValue(KeyValueFormat.Binary) ?? throw new Exception("Key value is null"); + var rawkey = key.GetAggregatedValueBinary() ?? throw new Exception("Key value is null"); // Use the IV as a Salt byte[] data; diff --git a/KeyManager.Library/EncryptJsonConverter.cs b/KeyManager.Library/EncryptJsonConverter.cs index 6eb7864..45a3faa 100644 --- a/KeyManager.Library/EncryptJsonConverter.cs +++ b/KeyManager.Library/EncryptJsonConverter.cs @@ -21,10 +21,7 @@ public EncryptJsonConverter(string? encryptionKey) { encryptionKey = MasterKey; } - using (var sha = SHA256.Create()) - { - _encryptionKeyBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(encryptionKey)); - } + _encryptionKeyBytes = SHA256.HashData(Encoding.UTF8.GetBytes(encryptionKey)); } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) @@ -35,12 +32,10 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer writer.WriteNull(); return; } - using (var aes = Aes.Create()) - { - aes.Key = _encryptionKeyBytes; - var data = aes.EncryptCbc(Encoding.UTF8.GetBytes(stringValue), new byte[16], System.Security.Cryptography.PaddingMode.PKCS7); - writer.WriteValue(Convert.ToBase64String(data)); - } + using var aes = Aes.Create(); + aes.Key = _encryptionKeyBytes; + var data = aes.EncryptCbc(Encoding.UTF8.GetBytes(stringValue), new byte[16], System.Security.Cryptography.PaddingMode.PKCS7); + writer.WriteValue(Convert.ToBase64String(data)); } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) @@ -54,12 +49,10 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer try { var buffer = Convert.FromBase64String(value); - using (var aes = Aes.Create()) - { - aes.Key = _encryptionKeyBytes; - var data = aes.DecryptCbc(buffer, new byte[16], System.Security.Cryptography.PaddingMode.PKCS7); - return Encoding.UTF8.GetString(data); - } + using var aes = Aes.Create(); + aes.Key = _encryptionKeyBytes; + var data = aes.DecryptCbc(buffer, new byte[16], System.Security.Cryptography.PaddingMode.PKCS7); + return Encoding.UTF8.GetString(data); } catch { diff --git a/KeyManager.Library/KCV.cs b/KeyManager.Library/KCV.cs index f1df00a..5e66103 100644 --- a/KeyManager.Library/KCV.cs +++ b/KeyManager.Library/KCV.cs @@ -32,7 +32,7 @@ public override byte[] ComputeKCV(Key key, byte[]? iv) using (var ms = new MemoryStream()) { var crypto = KeyHelper.GetSymmetricAlgorithm(key, CipherMode.CBC, true) ?? throw new Exception("Unsupported key for KCV calcul."); - var parameters = new ParametersWithIV(new KeyParameter(key.GetAggregatedValue(KeyValueFormat.Binary)), paddediv); + var parameters = new ParametersWithIV(new KeyParameter(key.GetAggregatedValueBinary()), paddediv); crypto.Init(true, parameters); result = crypto.DoFinal(data); Array.Resize(ref result, 3); diff --git a/KeyManager.Library/Key.cs b/KeyManager.Library/Key.cs index acfda91..4e029d1 100644 --- a/KeyManager.Library/Key.cs +++ b/KeyManager.Library/Key.cs @@ -51,7 +51,7 @@ public Key(IEnumerable? tags, uint keySize, string value) : this(tags, k Materials.Add(new KeyMaterial(value)); if (keySize == 0) { - KeySize = (uint)Materials[0].GetFormattedValue(KeyValueFormat.Binary)!.Length; + KeySize = (uint)Materials[0].GetValueBinary()!.Length; } } @@ -115,69 +115,94 @@ public void ValidatePolicies(string value) } } - public T? GetAggregatedValue() where T : class + public string? GetAggregatedValueString() { - return GetAggregatedValue(KeyValueFormat.HexString); + return GetAggregatedValueString(KeyValueStringFormat.HexString); } - public T? GetAggregatedValue(KeyValueFormat format) where T : class + public string? GetAggregatedValueString(KeyValueStringFormat format) { - T? ret = default; + return GetAggregatedValueString(format, KeySize == 0 ? Environment.NewLine : null); + } + + public string? GetAggregatedValueString(KeyValueStringFormat format, string? delimiter) + { + string? ret = null; foreach (var m in Materials) { - var v = m.GetFormattedValue(format); - if (ret == default(T)) - { - ret = v; - } - else + var v = m.GetValueString(format); + if (ret != null) { - if (typeof(T) == typeof(byte[])) + if (delimiter != null) { - ret = (ret as byte[])!.Concat((v as byte[])!) as T; + ret += delimiter; } - else if (typeof(T) == typeof(string)) + if (v != null) { - ret = (ret.ToString() + Environment.NewLine + ret.ToString()) as T; + ret += v; } } + else + { + ret = v ?? string.Empty; + } } return ret; } - public void SetAggregatedValue(object? value) + public byte[]? GetAggregatedValueBinary() { - SetAggregatedValue(value, KeyValueFormat.HexString); + var data = new List(); + foreach (var m in Materials) + { + var mdata = m.GetValueBinary(); + if (mdata != null) + { + data.AddRange(mdata); + } + } + return data.ToArray(); } - public void SetAggregatedValue(object? value, KeyValueFormat format) + public void SetAggregatedValueString(string? value) { - value ??= string.Empty; + SetAggregatedValueString(value, KeyValueStringFormat.HexString); + } - switch(format) + public void SetAggregatedValueString(string? value, KeyValueStringFormat format) + { + if (KeySize == 0) { - case KeyValueFormat.HexString: - { - if (value is string v) - { - var values = v.Split(Environment.NewLine); - if (Materials.Count >= values.Length) - { - for (int i = 0; i < values.Length; ++i) - { - Materials[i].SetFormattedValue(values[i], format); - } - } - } - } - break; - default: - if (Materials.Count > 0) + SetAggregatedValueString(value, format, Environment.NewLine); + } + else + { + var invariant = KeyMaterial.GetInvariantStringValue(value, format); + if (!string.IsNullOrEmpty(invariant)) + { + int length = (int)KeySize * 2; + int i = 0; + do { - Materials[0].SetFormattedValue(value, format); - } + int pos = i * length; + var sub = invariant.Substring(pos, (pos + length) < invariant.Length ? length : (invariant.Length - pos)); + Materials[i++].SetValueString(sub, KeyValueStringFormat.HexString); + } while (i < Materials.Count && invariant.Length >= (i + 1) * KeySize * 2); + } + } + } + + public void SetAggregatedValueString(string? value, KeyValueStringFormat format, string? separator) + { + var v = value ?? string.Empty; + var values = separator != null ? v.Split(separator) : new[] { v }; - break; + if (Materials.Count >= values.Length) + { + for (int i = 0; i < values.Length; ++i) + { + Materials[i].SetValueString(values[i], format); + } } } } diff --git a/KeyManager.Library/KeyGeneration.cs b/KeyManager.Library/KeyGeneration.cs index 74b9b61..832d7b1 100644 --- a/KeyManager.Library/KeyGeneration.cs +++ b/KeyManager.Library/KeyGeneration.cs @@ -7,12 +7,10 @@ public static class KeyGeneration { public static string Random(int keySize) { - using (var rng = RandomNumberGenerator.Create()) - { - var key = new byte[keySize]; - rng.GetBytes(key); - return Convert.ToHexString(key); - } + using var rng = RandomNumberGenerator.Create(); + var key = new byte[keySize]; + rng.GetBytes(key); + return Convert.ToHexString(key); } public static string FromPassword(string password, string salt, int keySize) diff --git a/KeyManager.Library/KeyMaterial.cs b/KeyManager.Library/KeyMaterial.cs index ee8e805..c6f4da0 100644 --- a/KeyManager.Library/KeyMaterial.cs +++ b/KeyManager.Library/KeyMaterial.cs @@ -53,65 +53,50 @@ public string? Name set { SetProperty(ref _name, value); } } - public static T? GetFormattedValue(string? value, KeyValueFormat format) where T : class + public static string? GetValueString(string? value, KeyValueStringFormat format) { - T? v; if (value != null) { - switch (format) + if (format == KeyValueStringFormat.HexStringWithSpace) { - case KeyValueFormat.HexString: - if (typeof(T) != typeof(string)) - { - throw new InvalidCastException(); - } - v = value as T; - break; - case KeyValueFormat.HexStringWithSpace: - if (typeof(T) != typeof(string)) - { - throw new InvalidCastException(); - } - v = HexStringRegex().Replace(value, "$0 ") as T; - break; - default: - if (typeof(T) != typeof(byte[])) - { - throw new InvalidCastException(); - } - v = Convert.FromHexString(value) as T; - break; + return HexStringRegex().Replace(value, "$0 ").TrimEnd(); } } - else + return value; + } + + public string? GetValueString(KeyValueStringFormat format) + { + return GetValueString(Value, format); + } + + public void SetValueString(string? value, KeyValueStringFormat format) + { + Value = GetInvariantStringValue(value, format); + } + + public byte[]? GetValueBinary() + { + if (Value != null) { - v = null; + return Convert.FromHexString(Value); } - return v; + + return null; } - public T? GetFormattedValue(KeyValueFormat format) where T : class + public void SetValueBinary(byte[]? value) { - return GetFormattedValue(Value, format); + Value = (value != null) ? Convert.ToHexString(value) : string.Empty; } - public void SetFormattedValue(object value, KeyValueFormat format) + public static string GetInvariantStringValue(string? value, KeyValueStringFormat format) { - switch (format) + return format switch { - case KeyValueFormat.HexString: - case KeyValueFormat.HexStringWithSpace: - { - var v = value as string; - Value = v ?? string.Empty; - } - break; - default: - { - Value = value is byte[] v ? Convert.ToHexString(v) : string.Empty; - } - break; - } + KeyValueStringFormat.HexStringWithSpace => (value ?? string.Empty).Replace(" ", ""), + _ => value ?? string.Empty + }; } [GeneratedRegex(".{2}")] diff --git a/KeyManager.Library/KeyStore/KeyStore.cs b/KeyManager.Library/KeyStore/KeyStore.cs index ec423b4..dd77a3b 100644 --- a/KeyManager.Library/KeyStore/KeyStore.cs +++ b/KeyManager.Library/KeyStore/KeyStore.cs @@ -244,7 +244,7 @@ public virtual async Task Publish(KeyStore store, Func getFav KeyEntry = entry, KeyContainer = kv }; - kv.Key.SetAggregatedValue(await ks.ResolveKeyLink(kv.Key.Link.KeyIdentifier, keClass, kv.Key.Link.ContainerSelector, ComputeDivInput(divContext, kv.Key.Link.DivInput))); + kv.Key.SetAggregatedValueString(await ks.ResolveKeyLink(kv.Key.Link.KeyIdentifier, keClass, kv.Key.Link.ContainerSelector, ComputeDivInput(divContext, kv.Key.Link.DivInput))); await ks.Close(); } } @@ -337,7 +337,7 @@ protected void OnKeyEntryUpdated(IChangeKeyEntry keyEntry) return null; } - public async Task GetKeyValue(KeyEntryId keyIdentifier, KeyEntryClass keClass, string? keyContainerSelector, string? divInput) where T : class + public async Task GetKeyValue(KeyEntryId keyIdentifier, KeyEntryClass keClass, string? keyContainerSelector, string? divInput) { if (!string.IsNullOrEmpty(divInput)) { @@ -346,7 +346,7 @@ protected void OnKeyEntryUpdated(IChangeKeyEntry keyEntry) } var key = await GetKey(keyIdentifier, keClass, keyContainerSelector); - return key?.GetAggregatedValue(); + return key?.GetAggregatedValueString(); } /// @@ -407,7 +407,6 @@ protected void OnKeyEntryUpdated(IChangeKeyEntry keyEntry) public virtual async Task ResolveKeyLink(KeyEntryId keyIdentifier, KeyEntryClass keClass, string? containerSelector, string? divInput) { - string? result = null; log.Info(string.Format("Resolving key link with Key Entry Identifier `{0}`, Container Selector `{1}`, Div Input `{2}`...", keyIdentifier, containerSelector, divInput)); if (!await CheckKeyEntryExists(keyIdentifier, keClass)) @@ -416,7 +415,7 @@ protected void OnKeyEntryUpdated(IChangeKeyEntry keyEntry) throw new KeyStoreException("The key entry do not exists."); } - result = await GetKeyValue(keyIdentifier, keClass, containerSelector, divInput); + var result = await GetKeyValue(keyIdentifier, keClass, containerSelector, divInput); if (string.IsNullOrEmpty(result)) { log.Warn("Key link returned an empty value."); diff --git a/KeyManager.Library/KeyValueFormat.cs b/KeyManager.Library/KeyValueStringFormat.cs similarity index 68% rename from KeyManager.Library/KeyValueFormat.cs rename to KeyManager.Library/KeyValueStringFormat.cs index 425e3b4..360b39b 100644 --- a/KeyManager.Library/KeyValueFormat.cs +++ b/KeyManager.Library/KeyValueStringFormat.cs @@ -1,8 +1,7 @@ namespace Leosac.KeyManager.Library { - public enum KeyValueFormat + public enum KeyValueStringFormat { - Binary, HexString, HexStringWithSpace } diff --git a/KeyManager.Library/Sha256Checksum.cs b/KeyManager.Library/Sha256Checksum.cs index 1d13526..a3989d5 100644 --- a/KeyManager.Library/Sha256Checksum.cs +++ b/KeyManager.Library/Sha256Checksum.cs @@ -8,7 +8,7 @@ public class Sha256Checksum : KeyChecksum public override byte[] ComputeKCV(Key key, byte[]? iv) { - var rawkey = key.GetAggregatedValue(KeyValueFormat.Binary) ?? throw new Exception("Key value is null"); + var rawkey = key.GetAggregatedValueBinary() ?? throw new Exception("Key value is null"); // Use the IV as a Salt byte[] data;