/// <summary> /// Generates a signed copy of a package and returns the path to that package /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact] /// </summary> /// <param name="certificate">Certificate to be used while signing the package</param> /// <param name="nupkg">Package to be signed</param> /// <param name="dir">Directory for placing the signed package</param> /// <param name="timestampService">RFC 3161 timestamp service URL.</param> /// <param name="request">An author signing request.</param> /// <returns>Path to the signed copy of the package</returns> public static async Task <string> CreateSignedAndTimeStampedPackageAsync( X509Certificate2 certificate, SimpleTestPackageContext nupkg, string dir, Uri timestampService, AuthorSignPackageRequest request = null) { var testLogger = new TestLogger(); using (var zipReadStream = nupkg.CreateAsStream()) using (var zipWriteStream = nupkg.CreateAsStream()) { var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString()); using (var signPackage = new SignedPackageArchive(zipReadStream, zipWriteStream)) { request = request ?? new AuthorSignPackageRequest(certificate, HashAlgorithmName.SHA256); // Sign the package await SignAndTimeStampPackageAsync(testLogger, certificate, signPackage, timestampService, request); } zipWriteStream.Seek(offset: 0, loc: SeekOrigin.Begin); using (Stream fileStream = File.OpenWrite(signedPackagePath)) { zipWriteStream.CopyTo(fileStream); } return(signedPackagePath); } }
/// <summary> /// Generates a signed copy of a package and returns the path to that package /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact] /// </summary> /// <param name="testCert">Certificate to be used while signing the package</param> /// <param name="nupkg">Package to be signed</param> /// <param name="dir">Directory for placing the signed package</param> /// <param name="timestampService">RFC 3161 timestamp service URL.</param> /// <returns>Path to the signed copy of the package</returns> public static async Task <string> CreateSignedAndTimeStampedPackageAsync( X509Certificate2 testCert, SimpleTestPackageContext nupkg, string dir, Uri timestampService) { var testLogger = new TestLogger(); using (var zipReadStream = nupkg.CreateAsStream()) using (var zipWriteStream = nupkg.CreateAsStream()) { var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString()); using (var signPackage = new SignedPackageArchive(zipReadStream, zipWriteStream)) { // Sign the package await SignAndTimeStampPackageAsync(testLogger, testCert, signPackage, timestampService); } zipWriteStream.Seek(offset: 0, loc: SeekOrigin.Begin); using (Stream fileStream = File.OpenWrite(signedPackagePath)) { zipWriteStream.CopyTo(fileStream); } return(signedPackagePath); } }
private static async Task <MemoryStream> CreateSignedPackageAsync( X509Certificate2 certificate, Stream unsignedPackage = null) { if (unsignedPackage == null) { var packageContext = new SimpleTestPackageContext(); unsignedPackage = packageContext.CreateAsStream(); } var signatureProvider = new X509SignatureProvider(timestampProvider: null); var overwrite = true; using (var request = new AuthorSignPackageRequest(certificate, HashAlgorithmName.SHA256)) using (var outputPackageStream = new MemoryStream()) using (var options = new SigningOptions( new Lazy <Stream>(() => unsignedPackage), new Lazy <Stream>(() => outputPackageStream), overwrite, signatureProvider, NullLogger.Instance)) { await SigningUtility.SignAsync(options, request, CancellationToken.None); var isSigned = await SignedArchiveTestUtility.IsSignedAsync(options.OutputPackageStream); Assert.True(isSigned); return(new MemoryStream(outputPackageStream.ToArray())); } }
internal static Test CreateUnsigned() { var packageContext = new SimpleTestPackageContext(); var package = packageContext.CreateAsStream(); return(new Test(package)); }
/// <summary> /// Generates an repository signed copy of a package and returns the path to that package /// This method can timestamp a package and should only be used with tests marked with [CIOnlyFact] /// </summary> /// <param name="certificate">Certificate to be used while signing the package</param> /// <param name="nupkg">Package to be signed</param> /// <param name="dir">Directory for placing the signed package</param> /// <param name="timestampService">RFC 3161 timestamp service URL.</param> /// <param name="v3ServiceIndex">Value for the V3ServiceIndex for the repository signature attribute</param> /// <param name="packageOwners">List of package owners for teh repository signature attribute</param> /// <param name="signatureHashAlgorithm">Hash algorithm to be used in the signature. Defaults to SHA256</param> /// <param name="timestampHashAlgorithm">Hash algorithm to be used in the timestamp. Defaults to SHA256</param> /// <returns>Path to the signed copy of the package</returns> public static async Task <string> RepositorySignPackageAsync( X509Certificate2 certificate, SimpleTestPackageContext nupkg, string dir, Uri v3ServiceIndex, Uri timestampService = null, IReadOnlyList <string> packageOwners = null, HashAlgorithmName signatureHashAlgorithm = HashAlgorithmName.SHA256, HashAlgorithmName timestampHashAlgorithm = HashAlgorithmName.SHA256) { var testLogger = new TestLogger(); var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString()); var tempPath = Path.GetTempFileName(); using (var packageStream = nupkg.CreateAsStream()) using (var fileStream = File.OpenWrite(tempPath)) { packageStream.CopyTo(fileStream); } using (var originalPackage = File.OpenRead(tempPath)) using (var signedPackage = File.Open(signedPackagePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) using (var request = new RepositorySignPackageRequest(certificate, signatureHashAlgorithm, timestampHashAlgorithm, v3ServiceIndex, packageOwners)) { await CreateSignedPackageAsync(request, originalPackage, signedPackage, timestampService); } FileUtility.Delete(tempPath); return(signedPackagePath); }
/// <summary> /// Generates a signed copy of a package and returns the path to that package /// This method timestamps a package and should only be used with tests marked with [CIOnlyFact] /// </summary> /// <param name="certificate">Certificate to be used while signing the package</param> /// <param name="nupkg">Package to be signed</param> /// <param name="dir">Directory for placing the signed package</param> /// <param name="timestampService">RFC 3161 timestamp service URL.</param> /// <param name="request">An author signing request.</param> /// <returns>Path to the signed copy of the package</returns> public static async Task <string> CreateSignedAndTimeStampedPackageAsync( X509Certificate2 certificate, SimpleTestPackageContext nupkg, string dir, Uri timestampService, AuthorSignPackageRequest request = null) { var testLogger = new TestLogger(); var signedPackagePath = Path.Combine(dir, Guid.NewGuid().ToString()); var tempPath = Path.GetTempFileName(); using (var packageStream = nupkg.CreateAsStream()) using (var fileStream = File.OpenWrite(tempPath)) { packageStream.CopyTo(fileStream); } #if IS_DESKTOP using (var cert = new X509Certificate2(certificate)) using (request = request ?? new AuthorSignPackageRequest(cert, HashAlgorithmName.SHA256)) { await SignAndTimeStampPackageAsync(testLogger, tempPath, signedPackagePath, timestampService, request); } #endif FileUtility.Delete(tempPath); return(signedPackagePath); }
public async Task GetTimestamp_AssertCompleteChain_Success() { var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var timestampProvider = new Rfc3161TimestampProvider(timestampService.Url); var nupkg = new SimpleTestPackageContext(); using (var authorCert = new X509Certificate2(_trustedTestCert.Source.Cert)) using (var packageStream = nupkg.CreateAsStream()) { // Act var signature = await SignedArchiveTestUtility.CreateAuthorSignatureForPackageAsync(authorCert, packageStream, timestampProvider); var authorSignedCms = signature.SignedCms; var timestamp = signature.Timestamps.First(); var timestampCms = timestamp.SignedCms; IX509CertificateChain certificateChain; var chainBuildSuccess = true; // rebuild the chain to get the list of certificates using (var chainHolder = new X509ChainHolder()) { var chain = chainHolder.Chain; var policy = chain.ChainPolicy; policy.ApplicationPolicy.Add(new Oid(Oids.TimeStampingEku)); policy.VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid; policy.RevocationFlag = X509RevocationFlag.ExcludeRoot; policy.RevocationMode = X509RevocationMode.Online; var timestampSignerCertificate = timestampCms.SignerInfos[0].Certificate; chainBuildSuccess = chain.Build(timestampSignerCertificate); certificateChain = CertificateChainUtility.GetCertificateChain(chain); } using (certificateChain) { // Assert authorSignedCms.Should().NotBeNull(); authorSignedCms.Detached.Should().BeFalse(); authorSignedCms.ContentInfo.Should().NotBeNull(); authorSignedCms.SignerInfos.Count.Should().Be(1); authorSignedCms.SignerInfos[0].UnsignedAttributes.Count.Should().Be(1); authorSignedCms.SignerInfos[0].UnsignedAttributes[0].Oid.Value.Should().Be(Oids.SignatureTimeStampTokenAttribute); timestampCms.Should().NotBeNull(); timestampCms.Detached.Should().BeFalse(); timestampCms.ContentInfo.Should().NotBeNull(); chainBuildSuccess.Should().BeTrue(); certificateChain.Count.Should().Be(timestampCms.Certificates.Count); foreach (var cert in certificateChain) { timestampCms.Certificates.Contains(cert).Should().BeTrue(); } } } }
internal Test(X509Certificate2 certificate) { _directory = TestDirectory.Create(); _certificate = new X509Certificate2(certificate); var packageContext = new SimpleTestPackageContext(); ReadStream = packageContext.CreateAsStream(); WriteStream = packageContext.CreateAsStream(); Package = new SignedPackageArchive(ReadStream, WriteStream); Request = new AuthorSignPackageRequest(_certificate, HashAlgorithmName.SHA256); var signatureProvider = new X509SignatureProvider(timestampProvider: null); Signer = new Signer(Package, signatureProvider); }
public async Task HasRepositoryCountersignature_WithSignatureWithoutRepositoryCountersignature_ReturnsFalseAsync() { using (var certificate = _fixture.GetDefaultCertificate()) { var packageContext = new SimpleTestPackageContext(); var unsignedPackageStream = packageContext.CreateAsStream(); var signature = await SignedArchiveTestUtility.CreateAuthorSignatureForPackageAsync( certificate, unsignedPackageStream); var hasRepoCountersignature = SignatureUtility.HasRepositoryCountersignature(signature); Assert.False(hasRepoCountersignature); } }
public async Task GetTrustResultAsync_SettingsRequireExactlyOneTimestamp_MultipleTimestamps_Fails() { // Arrange var nupkg = new SimpleTestPackageContext(); var testLogger = new TestLogger(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var setting = new SignedPackageVerifierSettings( allowUnsigned: false, allowIllegal: false, allowUntrusted: false, allowUntrustedSelfIssuedCertificate: false, allowIgnoreTimestamp: false, allowMultipleTimestamps: false, allowNoTimestamp: false, allowUnknownRevocation: false, allowNoClientCertificateList: true, allowNoRepositoryCertificateList: true); var timestampProvider = new Rfc3161TimestampProvider(timestampService.Url); var verificationProvider = new SignatureTrustAndValidityVerificationProvider(); using (var package = new PackageArchiveReader(nupkg.CreateAsStream(), leaveStreamOpen: false)) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) using (var signatureRequest = new AuthorSignPackageRequest(testCertificate, HashAlgorithmName.SHA256)) { var signature = await SignedArchiveTestUtility.CreatePrimarySignatureForPackageAsync(package, signatureRequest); var timestampedSignature = await SignedArchiveTestUtility.TimestampSignature(timestampProvider, signature, signatureRequest.TimestampHashAlgorithm, SignaturePlacement.PrimarySignature, testLogger); var reTimestampedSignature = await SignedArchiveTestUtility.TimestampSignature(timestampProvider, timestampedSignature, signatureRequest.TimestampHashAlgorithm, SignaturePlacement.PrimarySignature, testLogger); timestampedSignature.Timestamps.Count.Should().Be(1); reTimestampedSignature.Timestamps.Count.Should().Be(2); // Act var result = await verificationProvider.GetTrustResultAsync(package, reTimestampedSignature, setting, CancellationToken.None); var totalErrorIssues = result.GetErrorIssues(); // Assert result.Trust.Should().Be(SignatureVerificationStatus.Illegal); totalErrorIssues.Count().Should().Be(1); totalErrorIssues.First().Code.Should().Be(NuGetLogCode.NU3000); } }
/// <summary> /// Generates a signed copy of a package and returns the path to that package /// </summary> /// <param name="testCert">Certificate to be used while signing the package</param> /// <param name="nupkg">Package to be signed</param> /// <param name="dir">Directory for placing the signed package</param> /// <param name="name">Name of the signed package file to create.</param> /// <returns>Path to the signed copy of the package</returns> public static async Task <string> CreateSignedPackageAsync(X509Certificate2 testCert, SimpleTestPackageContext nupkg, string dir, string name = null) { var testLogger = new TestLogger(); var signedPackagePath = Path.Combine(dir, name ?? Guid.NewGuid().ToString()); var tempPath = Path.GetTempFileName(); using (var packageStream = nupkg.CreateAsStream()) using (var fileStream = File.OpenWrite(tempPath)) { packageStream.CopyTo(fileStream); } await SignPackageAsync(testLogger, testCert, tempPath, signedPackagePath); FileUtility.Delete(tempPath); return(signedPackagePath); }
public async Task HasRepositoryCountersignature_WithSignatureWithRepositoryCountersignature_ReturnsTrueAsync() { using (var certificate = _fixture.GetDefaultCertificate()) using (var repositoryCertificate = _fixture.GetDefaultCertificate()) { var packageContext = new SimpleTestPackageContext(); var unsignedPackageStream = packageContext.CreateAsStream(); var signature = await SignedArchiveTestUtility.CreatePrimarySignatureForPackageAsync( certificate, unsignedPackageStream); var reposignedSignature = await SignedArchiveTestUtility.RepositoryCountersignPrimarySignatureAsync(repositoryCertificate, signature); var hasRepoCountersignature = SignatureUtility.HasRepositoryCountersignature(reposignedSignature); Assert.True(hasRepoCountersignature); } }
public async Task HasRepositoryCountersignature_WithSignatureWithRepositoryCountersignature_ReturnsTrueAsync() { using (var certificate = _fixture.GetDefaultCertificate()) using (var repositoryCertificate = _fixture.GetDefaultCertificate()) { var packageContext = new SimpleTestPackageContext(); var unsignedPackageStream = packageContext.CreateAsStream(); var signature = await SignedArchiveTestUtility.CreateAuthorSignatureForPackageAsync( certificate, unsignedPackageStream); var hashAlgorithm = Common.HashAlgorithmName.SHA256; var v3ServiceIndexUri = new Uri("https://v3serviceIndex.test/api/index.json"); using (var request = new RepositorySignPackageRequest(repositoryCertificate, hashAlgorithm, hashAlgorithm, v3ServiceIndexUri, null)) { var reposignedSignature = await SignedArchiveTestUtility.RepositoryCountersignPrimarySignatureAsync(signature, request); var hasRepoCountersignature = SignatureUtility.HasRepositoryCountersignature(reposignedSignature); Assert.True(hasRepoCountersignature); } } }