public void TestImprintTagCreateFromTag() { RawTag rawTag = new RawTag(0x1, false, false, new byte[] { 0x1, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 }); ImprintTag tag = new ImprintTag(rawTag); Assert.AreEqual(0x1, tag.Type, "Tag type should be correct"); Assert.IsFalse(tag.NonCritical, "Tag non critical flag should be correct"); Assert.IsFalse(tag.Forward, "Tag forward flag should be correct"); Assert.AreEqual( new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 }), tag.Value, "Tag value should be decoded correctly"); Assert.AreEqual("TLV[0x1]:0x010102030405060708091011121314151617181920212223242526272829303132", tag.ToString(), "Tag string representation should be correct"); ImprintTag newTag = new ImprintTag(rawTag); Assert.AreEqual(newTag, tag, "Value should be equal"); }
private static void CheckMacAlgorithm(ImprintTag mac, HashAlgorithm expectedMacAlgorithm) { if (mac != null && mac.Value.Algorithm.Id != expectedMacAlgorithm.Id) { throw new KsiServiceException(string.Format("HMAC algorithm mismatch. Expected {0}, received {1}", expectedMacAlgorithm.Name, mac.Value.Algorithm.Name)); } }
/// <summary> /// Validate PDU against given MAC. /// </summary> /// <param name="pduBytes">PDU encoded as byte array</param> /// <param name="mac">MAC</param> /// <param name="key">message key</param> /// <returns>true if MAC is valid</returns> public static bool ValidateMac(byte[] pduBytes, ImprintTag mac, byte[] key) { if (pduBytes == null) { throw new ArgumentNullException(nameof(pduBytes)); } if (mac == null) { throw new ArgumentNullException(nameof(mac)); } if (pduBytes.Length < mac.Value.Algorithm.Length) { Logger.Warn("PDU MAC validation failed. PDU bytes array is too short to contain given MAC."); return(false); } DataHash calculatedMac = CalcMacValue(pduBytes, mac.Value.Algorithm, key); if (!calculatedMac.Equals(mac.Value)) { Logger.Warn("PDU MAC validation failed. Calculated MAC and given MAC do not match."); return(false); } return(true); }
/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.AggregationHashChain.AggregationTimeTagType: return(_aggregationTime = GetIntegerTag(childTag)); case Constants.AggregationHashChain.ChainIndexTagType: IntegerTag chainIndexTag = GetIntegerTag(childTag); _chainIndex.Add(chainIndexTag); return(chainIndexTag); case Constants.AggregationHashChain.InputDataTagType: return(_inputData = GetRawTag(childTag)); case Constants.AggregationHashChain.InputHashTagType: return(_inputHash = GetImprintTag(childTag)); case Constants.AggregationHashChain.AggregationAlgorithmIdTagType: IntegerTag aggrAlgorithmTag = GetIntegerTag(childTag); _aggrAlgorithm = HashAlgorithm.GetById((byte)aggrAlgorithmTag.Value); return(aggrAlgorithmTag); case (uint)LinkDirection.Left: case (uint)LinkDirection.Right: Link linkTag = childTag as Link ?? new Link(childTag); _links.Add(linkTag); return(linkTag); default: return(base.ParseChild(childTag)); } }
public void PduMacValidationInvalidWithPduTooShortTest() { ImprintTag mac = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.IsFalse(Pdu.ValidateMac(new byte[] { 1, 2, 3 }, mac, Util.EncodeNullTerminatedUtf8String(TestConstants.ServicePass)), "MAC should be invalid"); }
/// <summary> /// Set MAC tag value /// </summary> /// <param name="macAlgorithm"></param> /// <param name="key">HMAC key</param> protected void SetMacValue(HashAlgorithm macAlgorithm, byte[] key) { for (int i = 0; i < Count; i++) { ITlvTag childTag = this[i]; if (childTag.Type == Constants.Pdu.MacTagType) { this[i] = Mac = CreateMacTag(CalcMacValue(macAlgorithm, key)); break; } } }
public void TestImprintTagHashCode() { ImprintTag tag = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.AreEqual(-1500617533, tag.GetHashCode(), "Hash code should be correct"); }
/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.PublicationData.PublicationTimeTagType: return(_publicationTime = GetIntegerTag(childTag)); case Constants.PublicationData.PublicationHashTagType: return(_publicationHash = GetImprintTag(childTag)); default: return(base.ParseChild(childTag)); } }
public void PduMacValidationInvalidTest() { byte[] bytes = File.ReadAllBytes(Path.Combine(TestSetup.LocalPath, Resources.KsiService_AggregatorConfigResponsePdu)); ImprintTag mac = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.IsFalse(Pdu.ValidateMac(bytes, mac, Util.EncodeNullTerminatedUtf8String(TestConstants.ServicePass)), "MAC should be invalid"); }
/// <summary> /// Validate mac attached to PDU. /// </summary> /// <param name="pduBytes">PDU encoded as byte array</param> /// <param name="mac">MAC</param> /// <param name="key">message key</param> /// <returns>true if MAC is valid</returns> public static bool ValidateMac(byte[] pduBytes, ImprintTag mac, byte[] key) { if (pduBytes == null) { throw new ArgumentNullException(nameof(pduBytes)); } if (mac == null) { throw new ArgumentNullException(nameof(mac)); } if (pduBytes.Length < 1) { Logger.Warn("PDU MAC validation failed. PDU bytes array is empty."); return(false); } // We will use only header and payload for mac calculation. // It is assumed that mac tag is the last one. HashAlgorithm hashAlgorithm = mac.Value.Algorithm; int macTagLength = 3 + hashAlgorithm.Length; // tlv-8 header bytes + algorithm type byte + algorithm value bool tlv16 = (pduBytes[0] & Constants.Tlv.Tlv16Flag) != 0; int startFrom = tlv16 ? 4 : 2; int calcDataLength = pduBytes.Length - startFrom - macTagLength; if (calcDataLength < 0) { Logger.Warn("PDU MAC validation failed. PDU bytes array is too short to contain given MAC."); return(false); } byte[] target = new byte[calcDataLength]; Array.Copy(pduBytes, startFrom, target, 0, target.Length); DataHash calculatedMac = CalculateMac(hashAlgorithm, key, target); if (!calculatedMac.Equals(mac.Value)) { Logger.Warn("PDU MAC validation failed. Calculated MAC and given MAC do no match."); return(false); } return(true); }
/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.PduPayload.RequestIdTagType: return(_requestId = GetIntegerTag(childTag)); case Constants.AggregationRequestPayload.RequestHashTagType: return(_requestHash = GetImprintTag(childTag)); case Constants.AggregationRequestPayload.RequestLevelTagType: return(_requestLevel = GetIntegerTag(childTag)); default: return(base.ParseChild(childTag)); } }
public void TestStringTagCastToString() { ImprintTag tag = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.AreEqual( new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 }), tag.Value, "Tag should cast correctly to DataHash"); }
public void TestImprintTagEquals() { ImprintTag tag = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.AreEqual( new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })), tag, "Tag Equals function should compare correctly"); Assert.IsTrue(tag.Equals(tag), "Tags should be equal"); Assert.IsTrue( tag == new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })), "Tag should compare correctly with other objects"); Assert.IsTrue( tag != new ChildImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })), "Tag should compare correctly with other objects"); Assert.IsFalse(tag.Equals(new StringTag(0x1, false, false, "test")), "Tag Equals function should compare correctly with other objects"); Assert.IsFalse(tag.Equals(new object()), "Tag Equals function should compare correctly with other objects"); }
/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.Rfc3161Record.AggregationTimeTagType: return(_aggregationTime = GetIntegerTag(childTag)); case Constants.Rfc3161Record.ChainIndexTagType: IntegerTag chainTag = GetIntegerTag(childTag); _chainIndex.Add(chainTag); return(chainTag); case Constants.Rfc3161Record.InputHashTagType: return(_inputHash = GetImprintTag(childTag)); case Constants.Rfc3161Record.TstInfoPrefixTagType: return(_tstInfoPrefix = GetRawTag(childTag)); case Constants.Rfc3161Record.TstInfoSuffixTagType: return(_tstInfoSuffix = GetRawTag(childTag)); case Constants.Rfc3161Record.TstInfoAlgorithmTagType: IntegerTag tstInfoAlgorithmTag = GetIntegerTag(childTag); _tstInfoAlgorithm = HashAlgorithm.GetById((byte)tstInfoAlgorithmTag.Value); return(tstInfoAlgorithmTag); case Constants.Rfc3161Record.SignedAttributesPrefixTagType: return(_signedAttributesPrefix = GetRawTag(childTag)); case Constants.Rfc3161Record.SignedAttributesSuffixTagType: return(_signedAttributesSuffix = GetRawTag(childTag)); case Constants.Rfc3161Record.SignedAttributesAlgorithmTagType: IntegerTag signedAttributesAlgorithmTag = GetIntegerTag(childTag); _signedAttributesAlgorithm = HashAlgorithm.GetById((byte)signedAttributesAlgorithmTag.Value); return(signedAttributesAlgorithmTag); default: return(base.ParseChild(childTag)); } }
/// <summary> /// Parse child element /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.AggregationHashChain.Link.LevelCorrectionTagType: return(_levelCorrection = GetIntegerTag(childTag)); case Constants.AggregationHashChain.Link.SiblingHashTagType: return(_siblingHash = GetImprintTag(childTag)); case Constants.AggregationHashChain.Link.LegacyId: _legacyId = GetRawTag(childTag); _legacyIdString = GetLegacyIdString(_legacyId.Value); return(_legacyId); case Constants.AggregationHashChain.Metadata.TagType: return(_metadata = childTag as Metadata ?? new Metadata(childTag)); default: return(base.ParseChild(childTag)); } }
public void TestImprintTagToString() { ImprintTag tag = new ImprintTag(0x1, false, false, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.AreEqual("TLV[0x1]:0x010102030405060708091011121314151617181920212223242526272829303132", tag.ToString(), "Tag imprint representation should be correct"); tag = new ImprintTag(0x1, true, true, new DataHash(HashAlgorithm.Sha2256, new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32 })); Assert.AreEqual("TLV[0x1,N,F]:0x010102030405060708091011121314151617181920212223242526272829303132", tag.ToString(), "Tag imprint representation should be correct"); }
/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.CalendarHashChain.PublicationTimeTagType: return(_publicationTime = GetIntegerTag(childTag)); case Constants.CalendarHashChain.AggregationTimeTagType: return(_aggregationTime = GetIntegerTag(childTag)); case Constants.CalendarHashChain.InputHashTagType: return(_inputHash = GetImprintTag(childTag)); case (uint)LinkDirection.Left: case (uint)LinkDirection.Right: Link chainTag = childTag as Link ?? new Link(childTag); _chain.Add(chainTag); return(chainTag); default: return(base.ParseChild(childTag)); } }
public LegacyExtendPdu(PduHeader header, PduPayload payload, ImprintTag mac) : base(Constants.LegacyExtendPdu.TagType, false, false, new ITlvTag[] { header, payload, mac }) { }