/// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        internal async Task <SignedCms> GetTimestampAsync(TimestampRequest request, ILogger logger, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            // Allows us to track the request.
            var nonce = GenerateNonce();
            var rfc3161TimestampRequest = Rfc3161TimestampRequestFactory.Create(
                request.HashedMessage,
                request.HashAlgorithm.ConvertToSystemSecurityHashAlgorithmName(),
                requestedPolicyId: null,
                nonce: nonce,
                requestSignerCertificates: true,
                extensions: null);

            // Request a timestamp
            // The response status need not be checked here as lower level api will throw if the response is invalid
            IRfc3161TimestampToken timestampToken = await rfc3161TimestampRequest.SubmitRequestAsync(
                _timestamperUrl,
                RequestTimeout);

            // quick check for response validity
            var normalizedNonce = rfc3161TimestampRequest.GetNonce();

            ValidateTimestampResponse(normalizedNonce, request.HashedMessage, timestampToken);

            var timestampCms = timestampToken.AsSignedCms();

            ValidateTimestampCms(request.SigningSpecifications, timestampCms, timestampToken);

            // If the timestamp signed CMS already has a complete chain for the signing certificate,
            // it's ready to be added to the signature to be timestamped.
            // However, a timestamp service is not required to include all certificates in a complete
            // chain for the signing certificate in the SignedData.certificates collection.
            // Some timestamp services include all certificates except the root in the
            // SignedData.certificates collection.
            var signerInfo = timestampCms.SignerInfos[0];

            using (var chain = CertificateChainUtility.GetCertificateChain(
                       signerInfo.Certificate,
                       timestampCms.Certificates,
                       logger,
                       CertificateType.Timestamp))
            {
                return(EnsureCertificatesInCertificatesCollection(timestampCms, chain));
            }
        }
Exemple #2
0
        private Task <Signature> TimestampSignature(SignPackageRequest request, ILogger logger, Signature signature, CancellationToken token)
        {
            var timestampRequest = new TimestampRequest
            {
                SignatureValue         = signature.GetBytes(),
                SigningSpec            = SigningSpecifications.V1,
                TimestampHashAlgorithm = request.TimestampHashAlgorithm
            };

            return(_timestampProvider.TimestampSignatureAsync(timestampRequest, logger, token));
        }
Exemple #3
0
        private Task <PrimarySignature> TimestampPrimarySignatureAsync(SignPackageRequest request, ILogger logger, PrimarySignature signature, CancellationToken token)
        {
            var signatureValue = signature.GetSignatureValue();
            var messageHash    = request.TimestampHashAlgorithm.ComputeHash(signatureValue);

            var timestampRequest = new TimestampRequest(
                signingSpecifications: SigningSpecifications.V1,
                hashedMessage: messageHash,
                hashAlgorithm: request.TimestampHashAlgorithm,
                target: SignaturePlacement.PrimarySignature
                );

            return(_timestampProvider.TimestampSignatureAsync(signature, timestampRequest, logger, token));
        }
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public SignedCms GetTimestamp(TimestampRequest request, ILogger logger, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            // Allows us to track the request.
            var nonce = GenerateNonce();
            var rfc3161TimestampRequest = new Rfc3161TimestampRequest(
                request.HashedMessage,
                request.HashAlgorithm.ConvertToSystemSecurityHashAlgorithmName(),
                nonce: nonce,
                requestSignerCertificates: true);

            // Request a timestamp
            // The response status need not be checked here as lower level api will throw if the response is invalid
            var timestampToken = rfc3161TimestampRequest.SubmitRequest(
                _timestamperUrl,
                TimeSpan.FromSeconds(_rfc3161RequestTimeoutSeconds));

            // quick check for response validity
            ValidateTimestampResponse(nonce, request.HashedMessage, timestampToken);

            var timestampCms = timestampToken.AsSignedCms();

            ValidateTimestampCms(request.SigningSpecifications, timestampCms);

            // If the timestamp signed CMS already has a complete chain for the signing certificate,
            // it's ready to be added to the signature to be timestamped.
            // However, a timestamp service is not required to include all certificates in a complete
            // chain for the signing certificate in the SignedData.certificates collection.
            // Some timestamp services include all certificates except the root in the
            // SignedData.certificates collection.
            var signerInfo = timestampCms.SignerInfos[0];
            var chain      = CertificateChainUtility.GetCertificateChain(
                signerInfo.Certificate,
                timestampCms.Certificates,
                logger,
                CertificateType.Timestamp);

            return(EnsureCertificatesInCertificatesCollection(timestampCms, chain));
        }
Exemple #5
0
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest request, ILogger logger, CancellationToken token)
        {
            var timestampCms = GetTimestamp(request, logger, token);

            using (var signatureNativeCms = NativeCms.Decode(primarySignature.GetBytes()))
            {
                if (request.Target == SignaturePlacement.Countersignature)
                {
                    signatureNativeCms.AddTimestampToRepositoryCountersignature(timestampCms);
                }
                else
                {
                    signatureNativeCms.AddTimestamp(timestampCms);
                }
                return(Task.FromResult(PrimarySignature.Load(signatureNativeCms.Encode())));
            }
        }
Exemple #6
0
 /// <summary>
 /// Timestamp a signature.
 /// </summary>
 public Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest timestampRequest, ILogger logger, CancellationToken token)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public async Task <PrimarySignature> TimestampSignatureAsync(PrimarySignature primarySignature, TimestampRequest request, ILogger logger, CancellationToken token)
        {
            SignedCms timestampCms = await GetTimestampAsync(request, logger, token);

            using (ICms signatureCms = CmsFactory.Create(primarySignature.GetBytes()))
            {
                if (request.Target == SignaturePlacement.Countersignature)
                {
                    signatureCms.AddTimestampToRepositoryCountersignature(timestampCms);
                }
                else
                {
                    signatureCms.AddTimestamp(timestampCms);
                }
                return(PrimarySignature.Load(signatureCms.Encode()));
            }
        }
Exemple #8
0
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public Task <PrimarySignature> TimestampPrimarySignatureAsync(TimestampRequest request, ILogger logger, CancellationToken token)
        {
            var timestampedSignature = TimestampData(request, logger, token);

            return(Task.FromResult(PrimarySignature.Load(timestampedSignature)));
        }
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public byte[] TimestampData(TimestampRequest request, ILogger logger, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            // Get the signatureValue from the signerInfo object
            using (var signatureNativeCms = NativeCms.Decode(request.SignatureValue, detached: false))
            {
                var signatureValueHashByteArray = NativeCms.GetSignatureValueHash(
                    request.TimestampHashAlgorithm,
                    signatureNativeCms);

                // Allows us to track the request.
                var nonce = GenerateNonce();
                var rfc3161TimestampRequest = new Rfc3161TimestampRequest(
                    signatureValueHashByteArray,
                    request.TimestampHashAlgorithm.ConvertToSystemSecurityHashAlgorithmName(),
                    nonce: nonce,
                    requestSignerCertificates: true);

                // Request a timestamp
                // The response status need not be checked here as lower level api will throw if the response is invalid
                var timestampToken = rfc3161TimestampRequest.SubmitRequest(
                    _timestamperUrl,
                    TimeSpan.FromSeconds(_rfc3161RequestTimeoutSeconds));

                // quick check for response validity
                ValidateTimestampResponse(nonce, signatureValueHashByteArray, timestampToken);

                var timestampCms = timestampToken.AsSignedCms();
                ValidateTimestampCms(request.SigningSpec, timestampCms);

                byte[] timestampByteArray;

                using (var timestampNativeCms = NativeCms.Decode(timestampCms.Encode(), detached: false))
                    using (var chainHolder = new X509ChainHolder())
                    {
                        var chain  = chainHolder.Chain;
                        var policy = chain.ChainPolicy;

                        policy.ApplicationPolicy.Add(new Oid(Oids.TimeStampingEku));
                        policy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid | X509VerificationFlags.IgnoreCtlNotTimeValid;

                        policy.ExtraStore.AddRange(timestampCms.Certificates);

                        policy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                        policy.RevocationMode = X509RevocationMode.Online;

                        var timestampSignerCertificate = timestampCms.SignerInfos[0].Certificate;

                        if (timestampSignerCertificate == null)
                        {
                            throw new TimestampException(NuGetLogCode.NU3020, Strings.TimestampNoCertificate);
                        }

                        if (!chain.Build(timestampSignerCertificate))
                        {
                            var messages = CertificateChainUtility.GetMessagesFromChainStatuses(chain.ChainStatus);

                            throw new TimestampException(NuGetLogCode.NU3028, string.Format(CultureInfo.CurrentCulture, Strings.TimestampCertificateChainBuildFailure, string.Join(", ", messages)));
                        }

                        // Insert all the certificates into timestampCms
                        InsertTimestampCertChainIntoTimestampCms(timestampCms, chain, timestampNativeCms);
                        timestampByteArray = timestampNativeCms.Encode();
                    }

                signatureNativeCms.AddTimestamp(timestampByteArray);

                return(signatureNativeCms.Encode());
            }
        }
        /// <summary>
        /// Timestamps data present in the TimestampRequest.
        /// </summary>
        public byte[] TimestampData(TimestampRequest request, ILogger logger, CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            // Get the signatureValue from the signerInfo object
            using (var signatureNativeCms = NativeCms.Decode(request.SignatureValue, detached: false))
            {
                var signatureValueHashByteArray = NativeCms.GetSignatureValueHash(
                    request.TimestampHashAlgorithm,
                    signatureNativeCms);

                // Allows us to track the request.
                var nonce = GenerateNonce();
                var rfc3161TimestampRequest = new Rfc3161TimestampRequest(
                    signatureValueHashByteArray,
                    request.TimestampHashAlgorithm.ConvertToSystemSecurityHashAlgorithmName(),
                    nonce: nonce,
                    requestSignerCertificates: true);

                // Request a timestamp
                // The response status need not be checked here as lower level api will throw if the response is invalid
                var timestampToken = rfc3161TimestampRequest.SubmitRequest(
                    _timestamperUrl,
                    TimeSpan.FromSeconds(_rfc3161RequestTimeoutSeconds));

                // ensure response is for this request
                ValidateTimestampResponseNonce(nonce, timestampToken);

                var timestampCms = timestampToken.AsSignedCms();

                byte[] timestampByteArray;

                using (var timestampNativeCms = NativeCms.Decode(timestampCms.Encode(), detached: false))
                    using (var timestampCertChain = new X509Chain())
                    {
                        var policy = timestampCertChain.ChainPolicy;

                        policy.ApplicationPolicy.Add(new Oid(Oids.TimeStampingEkuOid));
                        policy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid;

                        policy.ExtraStore.AddRange(timestampCms.Certificates);

                        policy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
                        policy.RevocationMode = X509RevocationMode.Online;

                        var timestampSignerCertificate = GetTimestampSignerCertificate(timestampCms);
                        if (DateTime.Now < timestampSignerCertificate.NotBefore)
                        {
                            throw new TimestampException(LogMessage.CreateError(
                                                             NuGetLogCode.NU3025,
                                                             string.Format(CultureInfo.CurrentCulture,
                                                                           Strings.TimestampCertificateInvalid,
                                                                           $"{Environment.NewLine}{CertificateUtility.X509Certificate2ToString(timestampSignerCertificate)}")));
                        }

                        if (!timestampCertChain.Build(timestampSignerCertificate))
                        {
                            throw new TimestampException(LogMessage.CreateError(
                                                             NuGetLogCode.NU3028,
                                                             string.Format(CultureInfo.CurrentCulture,
                                                                           Strings.TimestampCertificateChainBuildFailure,
                                                                           $"{Environment.NewLine}{CertificateUtility.X509Certificate2ToString(timestampSignerCertificate)}")));
                        }

                        // Insert all the certificates into timestampCms
                        InsertTimestampCertChainIntoTimestampCms(timestampCms, timestampCertChain, timestampNativeCms);
                        timestampByteArray = timestampCms.Encode();
                    }

                signatureNativeCms.AddTimestamp(timestampByteArray);

                return(signatureNativeCms.Encode());
            }
        }