/// <summary> /// Parse child tag /// </summary> protected override ITlvTag ParseChild(ITlvTag childTag) { switch (childTag.Type) { case Constants.AggregationHashChain.TagType: AggregationHashChain aggregationChainTag = childTag as AggregationHashChain ?? new AggregationHashChain(childTag); _aggregationHashChains.Add(aggregationChainTag); return(aggregationChainTag); case Constants.CalendarHashChain.TagType: return(CalendarHashChain = childTag as CalendarHashChain ?? new CalendarHashChain(childTag)); case Constants.PublicationRecord.TagTypeInSignature: return(PublicationRecord = childTag as PublicationRecordInSignature ?? new PublicationRecordInSignature(childTag)); case Constants.CalendarAuthenticationRecord.TagType: return(CalendarAuthenticationRecord = childTag as CalendarAuthenticationRecord ?? new CalendarAuthenticationRecord(childTag)); case Constants.Rfc3161Record.TagType: return(Rfc3161Record = childTag as Rfc3161Record ?? new Rfc3161Record(childTag)); default: return(base.ParseChild(childTag)); } }
private static KsiSignature CreateSignatureWithLevelCorrection(KsiSignature signature, uint addToFirstLinkLinkLevelCorrection) { ReadOnlyCollection <AggregationHashChain> aggregationHashChains = signature.GetAggregationHashChains(); TlvTagBuilder builder = new TlvTagBuilder(signature); AggregationHashChain firstAggregationHashChain = aggregationHashChains[0]; ulong levelCorrection = firstAggregationHashChain.GetChainLinks()[0].LevelCorrection + addToFirstLinkLinkLevelCorrection; builder.ReplaceChildTag(firstAggregationHashChain, CreateAggregationHashChainWithLevelCorrection(firstAggregationHashChain, levelCorrection)); return(new KsiSignature(false, false, builder.GetChildTags())); }
/// <summary> /// Create KSI signature instance from given signature by adding a new aggregation hash chain as the lowest level chain. /// </summary> /// <param name="signature">Base KSI signature</param> /// <param name="inputHash">Input hash of the aggregation chain to be added.</param> /// <param name="aggregationAlgorithm">Aggregation algorithm of the aggregation chain to be added.</param> /// <param name="chainLinks">Hash chain links of the aggregation chain to be added.</param> /// <returns></returns> public IKsiSignature CreateSignatureWithAggregationChain(IKsiSignature signature, DataHash inputHash, HashAlgorithm aggregationAlgorithm, AggregationHashChain.Link[] chainLinks) { AggregationHashChain lowestChain = signature.GetAggregationHashChains()[0]; // create chain index ulong[] firstLevelChainIndex = lowestChain.GetChainIndex(); ulong[] chainIndex = new ulong[firstLevelChainIndex.Length + 1]; Array.Copy(firstLevelChainIndex, 0, chainIndex, 0, firstLevelChainIndex.Length); chainIndex[chainIndex.Length - 1] = AggregationHashChain.CalcLocationPointer(chainLinks); // Create new lowest chain AggregationHashChain newAggregationHashChain = new AggregationHashChain(lowestChain.AggregationTime, chainIndex, inputHash, aggregationAlgorithm.Id, chainLinks); // check level correction AggregationHashChainResult chainResult = newAggregationHashChain.GetOutputHash(new AggregationHashChainResult(0, inputHash)); ulong levelCorrection = lowestChain.GetChainLinks()[0].LevelCorrection; if (chainResult.Level > levelCorrection) { throw new KsiException(string.Format( "The aggregation hash chain cannot be added as lowest level chain. It's output level ({0}) is bigger than level correction of the first link of the first aggregation hash chain of the base signature ({1}).", chainResult.Level, levelCorrection)); } if (chainResult.Hash != lowestChain.InputHash) { throw new KsiException("The aggregation hash chain cannot be added as lowest level chain. It's output hash does not match base signature input hash."); } // Create list on new signature child tags. // Add new aggregation hash chain as the first element. // Add the chain that was initally the lowest (with corrected level correction) as second element List <ITlvTag> childTags = new List <ITlvTag> { newAggregationHashChain, CreateAggregationHashChainWithLevelCorrection(lowestChain, levelCorrection - chainResult.Level) }; foreach (ITlvTag tag in signature) { // Add all the signature components except the chain that was initially the lowest. if (!ReferenceEquals(tag, lowestChain)) { childTags.Add(tag); } } KsiSignature resultSignature = new KsiSignature(false, false, childTags.ToArray()); Verify(resultSignature, inputHash); return(resultSignature); }
/// <summary> /// Get the identity of the signature. /// </summary> /// <returns></returns> public IEnumerable <IIdentity> GetIdentity() { for (int i = _aggregationHashChains.Count - 1; i >= 0; i--) { AggregationHashChain chain = _aggregationHashChains[i]; foreach (IIdentity identity in chain.GetIdentity()) { yield return(identity); } } }
private static AggregationHashChain CreateAggregationHashChainWithLevelCorrection(AggregationHashChain aggregationHashChain, ulong levelCorrection) { ReadOnlyCollection <AggregationHashChain.Link> chainLinks = aggregationHashChain.GetChainLinks(); TlvTagBuilder builder = new TlvTagBuilder(aggregationHashChain); AggregationHashChain.Link firstLink = chainLinks[0]; builder.ReplaceChildTag(firstLink, CreateLinkWithLevelCorrection(firstLink, levelCorrection)); return(new AggregationHashChain(builder.BuildTag())); }