Example #1
0
        /// <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];

            using (var chain = CertificateChainUtility.GetCertificateChain(
                       signerInfo.Certificate,
                       timestampCms.Certificates,
                       logger,
                       CertificateType.Timestamp))
            {
                return(EnsureCertificatesInCertificatesCollection(timestampCms, chain));
            }
        }
Example #2
0
 public Rfc3161TimestampRequestNet472Wrapper(
     byte[] messageHash,
     HashAlgorithmName hashAlgorithm,
     Oid requestedPolicyId,
     byte[] nonce,
     bool requestSignerCertificates,
     X509ExtensionCollection extensions)
 {
     _rfc3161TimestampRequest = new Rfc3161TimestampRequest(
         messageHash,
         hashAlgorithm,
         requestedPolicyId,
         nonce,
         requestSignerCertificates,
         extensions);
 }
        /// <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());
            }
        }