/// <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)); } }
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()); } }