Add support for local (PLAINTEXT!) encryption key storage. Future commits will expand on this by allowing encrypted-at-rest storage of key material.

pull/1/head
Steven Jennison 11 months ago
parent b13a3349fb
commit 1c8528e2b9

@ -1,7 +1,8 @@
# #
# Digital Voice Modem - Desktop Dispatch Console # Digital Voice Modem - Desktop Dispatch Console
# #
# Full path to local key YAML file (see keys.example.clear for formatting)
#keyFile: "Full/Path/To/Keyfile.clear"
# #
# FNE Masters # FNE Masters
# #

@ -0,0 +1,15 @@
keys:
-
# The key ID, in hex, for this key
keyId: 0x1
# The algorithm ID, in hex, for this key
algId: 0x84
# The key material, as a hex string representation, for this key
key: "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQR"
-
# The key ID, in hex, for this key
keyId: 0x2
# The algorithm ID, in hex, for this key
algId: 0xAA
# The key material, as a hex string representation, for this key
key: "1234567890"

@ -25,6 +25,10 @@ namespace dvmconsole
** Properties ** Properties
*/ */
/// <summary>
/// The location of the YAML keyfile
/// </summary>
public string KeyFile { get; set; } = null;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>

@ -0,0 +1,28 @@
namespace dvmconsole;
/// <summary>
/// POCO which is used to decode a YML keyfile
/// </summary>
public class KeyContainer
{
public List<KeyEntry> Keys { get; set; } = [];
}
public class KeyEntry
{
public ushort KeyId { get; set; }
public int AlgId { get; set; }
public string Key { get; set; }
/// <summary>
/// Gets the contents of the Key property as a byte[]
/// </summary>
public byte[] KeyBytes => string.IsNullOrEmpty(Key) ? [] : StringToByteArray(Key);
private static byte[] StringToByteArray(string hex) {
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
}

@ -559,7 +559,52 @@ namespace dvmconsole
// if the channel is configured for encryption request the key from the FNE // if the channel is configured for encryption request the key from the FNE
uint newTgid = uint.Parse(cpgChannel.Tgid); uint newTgid = uint.Parse(cpgChannel.Tgid);
if (cpgChannel.GetAlgoId() != 0 && cpgChannel.GetKeyId() != 0) if (cpgChannel.GetAlgoId() != 0 && cpgChannel.GetKeyId() != 0)
{
fne.peer.SendMasterKeyRequest(cpgChannel.GetAlgoId(), cpgChannel.GetKeyId()); fne.peer.SendMasterKeyRequest(cpgChannel.GetAlgoId(), cpgChannel.GetKeyId());
if (Codeplug.KeyFile != null)
{
if (!File.Exists(Codeplug.KeyFile))
{
MessageBox.Show($"Key file {Codeplug.KeyFile} not found. {PLEASE_CHECK_CODEPLUG}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
else
{
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.IgnoreUnmatchedProperties()
.Build();
var keys = deserializer.Deserialize<KeyContainer>(File.ReadAllText(Codeplug.KeyFile));
var KeysetItems = new Dictionary<int, KeysetItem>();
foreach (var keyEntry in keys.Keys)
{
var keyItem = new KeyItem();
keyItem.KeyId = keyEntry.KeyId;
var keyBytes = keyEntry.KeyBytes;
keyItem.SetKey(keyBytes,(uint)keyBytes.Length);
if (!KeysetItems.ContainsKey(keyEntry.AlgId))
{
var asByte = (byte)keyEntry.AlgId;
KeysetItems.Add(keyEntry.AlgId, new KeysetItem() { AlgId = asByte });
}
KeysetItems[keyEntry.AlgId].AddKey(keyItem);
}
foreach (var eventData in KeysetItems.Select(keyValuePair => keyValuePair.Value).Select(keysetItem => new KeyResponseEvent(0, new KmmModifyKey
{
AlgId = 0,
KeyId = 0,
MessageId = 0,
MessageLength = 0,
KeysetItem = keysetItem
}, [])))
{
KeyResponseReceived(eventData);
}
}
}
}
} }
} }
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.