Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        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()));
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
            }
        }
Beispiel #6
0
        /// <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;
                }
            }
        }
Beispiel #7
0
        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;
            }
        }