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