/// <summary> /// Create signature and verify with given verification policy /// </summary> /// <param name="childTags">Child tags</param> /// <param name="hash">Signed hash</param> private KsiSignature CreateAndVerify(ITlvTag[] childTags, DataHash hash) { KsiSignature signature = new KsiSignature(false, false, childTags); Verify(signature, hash); return(signature); }
/// <summary> /// Create signature and verify with given verification policy /// </summary> /// <param name="signatureRaw">KSI signature</param> /// <param name="hash">Signed hash</param> private KsiSignature CreateAndVerify(RawTag signatureRaw, DataHash hash) { KsiSignature signature = new KsiSignature(signatureRaw); Verify(signature, hash); return(signature); }
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> /// Verify signature with given verification policy /// </summary> /// <param name="signature">KSI signature</param> /// <param name="hash">Signed hash</param> private void Verify(KsiSignature signature, DataHash hash) { _verificationContext.Signature = signature; _verificationContext.DocumentHash = hash; VerificationResult verificationResult = _verificationPolicy.Verify(_verificationContext); if (verificationResult.ResultCode != VerificationResultCode.Ok) { Logger.Warn("Signature verification failed.{0}Verification policy: {1}{0}Verification error: {2}{0}Verification result: {3}{0}Signature: {4}", Environment.NewLine, _verificationPolicy.GetRuleName(), verificationResult.VerificationError, verificationResult, signature); throw new KsiSignatureInvalidContentException("Signature verification failed.", signature, verificationResult); } }
/// <summary> /// Create KSI signature instance from stream. /// </summary> /// <param name="stream">signature data stream</param> /// <param name="hash">Signed hash</param> /// <returns>KSI signature</returns> public IKsiSignature Create(Stream stream, DataHash hash = null) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } using (TlvReader reader = new TlvReader(stream)) { try { Logger.Debug("Creating KSI signature from stream."); KsiSignature signature = CreateAndVerify(reader.ReadTag(), null); Logger.Debug("Creating KSI signature from stream successful."); return(signature); } catch (TlvException e) { Logger.Warn("Creating KSI signature from stream failed: {0}", e); throw; } } }
private KsiSignature CreateFromResponsePayload(SignRequestResponsePayload payload, ulong requestId, DataHash hash, uint?level) { try { Logger.Debug("Creating KSI signature from aggregation response. (request id: {0})", requestId); KsiSignature signature = new KsiSignature(false, false, payload.GetSignatureChildTags()); if (level > 0) { signature = CreateSignatureWithLevelCorrection(signature, level.Value); } Verify(signature, hash); Logger.Debug("Creating KSI signature from aggregation response successful. (request id: {0})", requestId); return(signature); } catch (TlvException e) { Logger.Warn("Creating KSI signature from aggregation response failed: {0} (request id: {1})", e, requestId); throw; } }