KFDtool/sw/control/KFDtool.P25/Kmm/ModifyKeyCommand.cs

157 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace KFDtool.P25.Kmm
{
/* TIA 102.AACA-A 10.2.19 and TIA 102.AACD-A 3.9.2.17 */
public class ModifyKeyCommand : KmmBody
{
private int _keysetId;
private int _algorithmId;
public int KeysetId
{
get
{
return _keysetId;
}
set
{
if (value < 0 || value > 0xFF)
{
throw new ArgumentOutOfRangeException();
}
_keysetId = value;
}
}
public int AlgorithmId
{
get
{
return _algorithmId;
}
set
{
if (value < 0 || value > 0xFF)
{
throw new ArgumentOutOfRangeException();
}
_algorithmId = value;
}
}
public List<KeyItem> KeyItems { get; set; }
public override MessageId MessageId
{
get
{
return MessageId.ModifyKeyCommand;
}
}
public override ResponseKind ResponseKind
{
get
{
return ResponseKind.Immediate;
}
}
public ModifyKeyCommand()
{
KeyItems = new List<KeyItem>();
}
public override byte[] ToBytes()
{
List<byte> keys = new List<byte>();
foreach (KeyItem key in KeyItems)
{
keys.AddRange(key.ToBytes());
}
List<byte> contents = new List<byte>();
/* decryption instruction format */
contents.Add(0x00);
/* extended decryption instruction format */
contents.Add(0x00);
/* algorithm id */
contents.Add(0x80);
/* key id */
contents.Add(0x00);
contents.Add(0x00);
/* keyset id */
contents.Add((byte)KeysetId);
/* algorithm id */
contents.Add((byte)AlgorithmId);
/* key length */
contents.Add((byte)KeyItems[0].Key.Length);
/* number of keys */
contents.Add((byte)KeyItems.Count);
/* keys */
contents.AddRange(keys);
return contents.ToArray();
}
public override void Parse(byte[] contents)
{
if (contents.Length < 9)
{
throw new ArgumentOutOfRangeException(string.Format("length mismatch - expected at least 9, got {0} - {1}", contents.Length.ToString(), BitConverter.ToString(contents)));
}
/* keyset id */
KeysetId = contents[5];
/* algorithm id */
AlgorithmId = contents[6];
/* key length */
int keyLength = contents[7];
/* number of keys */
int keyCount = contents[8];
/* keys */
if ((keyCount == 0) && (contents.Length == 9))
{
return;
}
else if (((keyCount * (5 + keyLength)) % (contents.Length - 9)) == 0)
{
for (int i = 0; i < keyCount; i++)
{
byte[] item = new byte[5 + keyLength];
Array.Copy(contents, 9 + (i * (5 + keyLength)), item, 0, 5 + keyLength);
KeyItem item2 = new KeyItem();
item2.Parse(item, keyLength);
KeyItems.Add(item2);
}
}
else
{
throw new Exception("number of keys field and length mismatch");
}
}
}
}