public void GetCertificateChain_WithRepositoryCountersignature_ReturnsCertificates() { var primarySignature = PrimarySignature.Load(SigningTestUtility.GetResourceBytes(".signature.p7s")); var repositoryCountersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature); using (var certificates = SignatureUtility.GetCertificateChain(primarySignature, repositoryCountersignature)) { Assert.Equal(3, certificates.Count); Assert.Equal("8d8cc5bdf9e5f86b971d7fb961fe24b999486483", certificates[0].Thumbprint, StringComparer.OrdinalIgnoreCase); Assert.Equal("c8ae47bfd632870a15e3775784affd2bdc96cbf1", certificates[1].Thumbprint, StringComparer.OrdinalIgnoreCase); Assert.Equal("d4e8185475a062de3518d1aa693f13c4283f81ff", certificates[2].Thumbprint, StringComparer.OrdinalIgnoreCase); } }
public void GetHashString_ReturnsCorrectHashForSupportedAlgorithms() { using (var certificate = SigningTestUtility.GetCertificate("leaf.crt")) { var sha256Fingerprint = CertificateUtility.GetHashString(certificate, Common.HashAlgorithmName.SHA256); var sha384Fingerprint = CertificateUtility.GetHashString(certificate, Common.HashAlgorithmName.SHA384); var sha512Fingerprint = CertificateUtility.GetHashString(certificate, Common.HashAlgorithmName.SHA512); Assert.Equal("9893F4B40FD236F16C189AD8F01D8B92FE682DFA6E768354ED25F4741BF51C73", sha256Fingerprint); Assert.Equal("6471116F2B2A4DBA7B021A208408F53FBA2BCA1661ED006112E82850AA9DFD06EC9B5C9A50B4D2E6890B756781503FE5", sha384Fingerprint); Assert.Equal("5B00A6B778AF9DC19BB62BFA688556FEC0A35AEFFB63DACD8D4EF2F227EC0EF43DA8B27F3E12F8C3485D128F32E4E7CA20136AF3BB3DF21A4B47AE54137698F3", sha512Fingerprint); } }
public void GetTimestampCertificateChain_WithRepositoryCountersignatureTimestamp_ReturnsCertificates() { var primarySignature = PrimarySignature.Load(SigningTestUtility.GetResourceBytes(".signature.p7s")); var repositoryCountersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature); using (var certificates = SignatureUtility.GetTimestampCertificateChain(primarySignature, repositoryCountersignature)) { Assert.Equal(3, certificates.Count); Assert.Equal("96b479acf63394f3bcc9928c396264afd60909ed", certificates[0].Thumbprint, StringComparer.OrdinalIgnoreCase); Assert.Equal("fa4e4ca3d9a26b92a73bb875f964972983b55ccd", certificates[1].Thumbprint, StringComparer.OrdinalIgnoreCase); Assert.Equal("88b288ff6d3d826469a9ef7816166a7def221885", certificates[2].Thumbprint, StringComparer.OrdinalIgnoreCase); } }
public void IsSigned_WithCentralDirectoryHeaderUsingUtf8_ReturnsFalse() { var zipBytes = SigningTestUtility.GetResourceBytes("SignatureFileEntry.zip"); zipBytes[35] = 0x08; using (var test = new Test(zipBytes)) { var isSigned = SignedPackageArchiveUtility.IsSigned(test.Reader); Assert.False(isSigned); } }
public void GetTimestampCertificateChain_WithUnrelatedRepositoryCountersignature_Throws() { var primarySignature = PrimarySignature.Load(SigningTestUtility.GetResourceBytes(".signature.p7s")); var repositoryCountersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature); primarySignature = RemoveRepositoryCountersignature(primarySignature); var exception = Assert.Throws <ArgumentException>( () => SignatureUtility.GetTimestampCertificateChain(primarySignature, repositoryCountersignature)); Assert.Equal("repositoryCountersignature", exception.ParamName); Assert.StartsWith("The primary signature and repository countersignature are unrelated.", exception.Message); }
private static void VerifyAttributes( System.Security.Cryptography.CryptographicAttributeObjectCollection attributes, SignPackageRequest request) { var pkcs9SigningTimeAttributeFound = false; var commitmentTypeIndicationAttributeFound = false; var signingCertificateV2AttributeFound = false; foreach (var attribute in attributes) { Assert.Equal(1, attribute.Values.Count); switch (attribute.Oid.Value) { case "1.2.840.113549.1.9.5": // PKCS #9 signing time Assert.IsType <Pkcs9SigningTime>(attribute.Values[0]); pkcs9SigningTimeAttributeFound = true; break; case Oids.CommitmentTypeIndication: var qualifier = CommitmentTypeQualifier.Read(attribute.Values[0].RawData); var expectedCommitmentType = AttributeUtility.GetSignatureTypeOid(request.SignatureType); Assert.Equal(expectedCommitmentType, qualifier.CommitmentTypeIdentifier.Value); commitmentTypeIndicationAttributeFound = true; break; case Oids.SigningCertificateV2: var signingCertificateV2 = SigningCertificateV2.Read(attribute.Values[0].RawData); Assert.Equal(1, signingCertificateV2.Certificates.Count); var essCertIdV2 = signingCertificateV2.Certificates[0]; Assert.Equal(SigningTestUtility.GetHash(request.Certificate, request.SignatureHashAlgorithm), essCertIdV2.CertificateHash); Assert.Equal(request.SignatureHashAlgorithm.ConvertToOidString(), essCertIdV2.HashAlgorithm.Algorithm.Value); Assert.Equal(request.Certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name); SigningTestUtility.VerifySerialNumber(request.Certificate, essCertIdV2.IssuerSerial); Assert.Null(signingCertificateV2.Policies); signingCertificateV2AttributeFound = true; break; } } Assert.True(pkcs9SigningTimeAttributeFound); Assert.True(commitmentTypeIndicationAttributeFound); Assert.True(signingCertificateV2AttributeFound); }
public async Task VerifySignaturesAsync_ExpiredCertificateAndTimestamp_Success() { var ca = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var keyPair = SigningTestUtility.GenerateKeyPair(publicKeyLength: 2048); var now = DateTimeOffset.UtcNow; var issueOptions = new IssueCertificateOptions(keyPair.Public) { NotAfter = now.AddSeconds(10), NotBefore = now.AddSeconds(-2), SubjectName = new X509Name("CN=NuGet Test Expired Certificate") }; var bcCertificate = ca.IssueCertificate(issueOptions); using (var certificate = new X509Certificate2(bcCertificate.GetEncoded())) using (var directory = TestDirectory.Create()) { certificate.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters); var packageContext = new SimpleTestPackageContext(); var signedPackagePath = await SignedArchiveTestUtility.CreateSignedAndTimeStampedPackageAsync( certificate, packageContext, directory, timestampService.Url); var notAfter = certificate.NotAfter.ToUniversalTime(); var waitDuration = (notAfter - DateTimeOffset.UtcNow).Add(TimeSpan.FromSeconds(1)); // Wait for the certificate to expire. Trust of the signature will require a valid timestamp. await Task.Delay(waitDuration); Assert.True(DateTime.UtcNow > notAfter); var verifier = new PackageSignatureVerifier(_trustProviders, SignedPackageVerifierSettings.VerifyCommandDefaultPolicy); using (var packageReader = new PackageArchiveReader(signedPackagePath)) { var result = await verifier.VerifySignaturesAsync(packageReader, CancellationToken.None); var trustProvider = result.Results.Single(); Assert.True(result.Valid); Assert.Equal(SignatureVerificationStatus.Trusted, trustProvider.Trust); Assert.Equal(0, trustProvider.Issues.Count(issue => issue.Level == LogLevel.Error)); Assert.Equal(0, trustProvider.Issues.Count(issue => issue.Level == LogLevel.Warning)); } } }
public async Task DotnetTrust_CertificateFingerPrintAction_WithExistingSigner_AppendSucceeds(bool allowUntrustedRoot) { // Arrange var nugetConfigFileName = "NuGet.Config"; var package = new SimpleTestPackageContext(); using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext()) using (MemoryStream zipStream = await package.CreateAsStreamAsync()) using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate()) { var certFingerprint = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256); var repoServiceIndex = "https://serviceindex.test/v3/index.json"; var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex)); var config = @"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <trustedSigners> <author name=""MyCompanyCert""> <certificate fingerprint=""abcdefg"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""false"" /> </author> </trustedSigners> </configuration>"; SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config); var nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName); var allowUntrustedRootArg = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty; var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false"; var authorName = "MyCompanyCert"; // Act CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet( pathContext.SolutionRoot, $"nuget trust certificate {authorName} {certFingerprint} {allowUntrustedRootArg} --algorithm SHA256 --configfile {nugetConfigPath}"); // Assert resultAdd.Success.Should().BeTrue(); resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, "Successfully updated the trusted signer '{0}'.", authorName)); string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> < trustedSigners> <author name = ""{authorName}""> < certificate fingerprint = ""abcdefg"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""false""/> < certificate fingerprint = ""{certFingerprint}"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""{allowUntruestedRootValue}""/> </author> </trustedSigners> </configuration>"); SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult); } }
public async Task DotnetTrust_RepositoryAction_Succeeds(bool allowUntrustedRoot, string owners) { // Arrange var nugetConfigFileName = "NuGet.Config"; var package = new SimpleTestPackageContext(); using (SimpleTestPathContext pathContext = _msbuildFixture.CreateSimpleTestPathContext()) using (MemoryStream zipStream = await package.CreateAsStreamAsync()) using (TrustedTestCert <TestCertificate> trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate()) { var certFingerprint = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256); var repoServiceIndex = "https://serviceindex.test/v3/index.json"; var signedPackagePath = await SignedArchiveTestUtility.RepositorySignPackageAsync(trustedTestCert.Source.Cert, package, pathContext.PackageSource, new Uri(repoServiceIndex)); var config = $@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> </configuration>"; SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, pathContext.WorkingDirectory, config); var nugetConfigPath = Path.Combine(pathContext.WorkingDirectory, nugetConfigFileName); var allowUntrustedRootArg = allowUntrustedRoot ? "--allow-untrusted-root" : string.Empty; var allowUntruestedRootValue = allowUntrustedRoot ? "true" : "false"; var ownersArgs = string.Empty; var expectedOwners = string.Empty; if (owners != null) { ownersArgs = $"--owners {owners}"; expectedOwners = $"<owners>{owners}</owners>"; } // Act CommandRunnerResult resultAdd = _msbuildFixture.RunDotnet( pathContext.SolutionRoot, $"nuget trust repository nuget {signedPackagePath} {allowUntrustedRootArg} {ownersArgs} --configfile {nugetConfigPath}"); // Assert resultAdd.Success.Should().BeTrue(); resultAdd.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "repository", "nuget")); string expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> < trustedSigners> <repository name = ""nuget"" serviceIndex=""https://serviceindex.test/v3/index.json""> < certificate fingerprint = ""{certFingerprint}"" hashAlgorithm = ""SHA256"" allowUntrustedRoot = ""{allowUntruestedRootValue}""/>{expectedOwners} </repository> </trustedSigners> </configuration>"); SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult); } }
public void IsSigned_WithIncorrectSignatureFileNameInCentralDirectoryHeader_ReturnsFalse() { var zipBytes = SigningTestUtility.GetResourceBytes("SignatureFileEntry.zip"); var fileName = Encoding.ASCII.GetBytes(SigningSpecifications.V1.SignaturePath.ToUpper()); Array.Copy(fileName, sourceIndex: 0, destinationArray: zipBytes, destinationIndex: 0x5a, length: fileName.Length); using (var test = new Test(zipBytes)) { var isSigned = SignedPackageArchiveUtility.IsSigned(test.Reader); Assert.False(isSigned); } }
public async Task SignAsync_WhenPackageIsZip64_ThrowsAsync() { using (var test = SignTest.Create( _fixture.GetDefaultCertificate(), HashAlgorithmName.SHA256, SigningTestUtility.GetResourceBytes("CentralDirectoryHeaderWithZip64ExtraField.zip"))) { var exception = await Assert.ThrowsAsync <SignatureException>( () => SigningUtility.SignAsync(test.Options, test.Request, CancellationToken.None)); Assert.Equal(NuGetLogCode.NU3006, exception.Code); Assert.Equal("Signed Zip64 packages are not supported.", exception.Message); } }
public async Task Restore_TamperedPackageInPackagesConfig_FailsWithErrorAsync() { // Arrange var packagesConfigContent = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<packages>" + " <package id=\"X\" version=\"9.0.0\" targetFramework=\"net461\" />" + "</packages>"; using (var pathContext = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(_trustedTestCert.Source.Cert)) { // Set up solution, project, and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); var projectA = new SimpleTestProjectContext( "a", ProjectStyle.PackagesConfig, pathContext.SolutionRoot); var packageX = new SimpleTestPackageContext("X", "9.0.0"); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, packageX, pathContext.PackageSource); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); projectA.AddPackageToAllFrameworks(packageX); solution.Projects.Add(projectA); solution.Create(pathContext.SolutionRoot); var packagesConfigPath = Path.Combine(Directory.GetParent(projectA.ProjectPath).FullName, "packages.config"); File.WriteAllBytes(packagesConfigPath, Encoding.ASCII.GetBytes(packagesConfigContent)); var args = new string[] { projectA.ProjectPath, "-Source", pathContext.PackageSource, "-PackagesDirectory", "./packages" }; // Act var result = RunRestore(_nugetExePath, pathContext, expectedExitCode: 1, additionalArgs: args); // Assert result.ExitCode.Should().Be(1); result.Errors.Should().Contain(string.Format(_NU3008, SigningTestUtility.AddSignatureLogPrefix(_NU3008Message, packageX.Identity, pathContext.PackageSource))); result.AllOutput.Should().Contain(string.Format(_NU3027, SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, packageX.Identity, pathContext.PackageSource))); } }
public void GetTimestampCertificateChain_WithRepositoryCountersignatureWithoutTimestamp_Throws() { var primarySignature = PrimarySignature.Load(SigningTestUtility.GetResourceBytes(".signature.p7s")); primarySignature = RemoveRepositoryCountersignatureTimestamp(primarySignature); var repositoryCountersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature); var exception = Assert.Throws <SignatureException>( () => SignatureUtility.GetTimestampCertificateChain(primarySignature, repositoryCountersignature)); Assert.Equal(NuGetLogCode.NU3000, exception.Code); Assert.Equal("The repository countersignature does not have a timestamp.", exception.Message); }
public async Task Install_TamperedAndRevokedCertificateSignaturePackage_FailsAsync() { // Arrange var nupkg = new SimpleTestPackageContext("A", "1.0.0"); var testServer = await _testFixture.GetSigningTestServerAsync(); var certificateAuthority = await _testFixture.GetDefaultTrustedCertificateAuthorityAsync(); var issueOptions = IssueCertificateOptions.CreateDefaultForEndCertificate(); var bcCertificate = certificateAuthority.IssueCertificate(issueOptions); using (var context = new SimpleTestPathContext()) using (var testCertificate = new X509Certificate2(bcCertificate.GetEncoded())) { testCertificate.PrivateKey = DotNetUtilities.ToRSA(issueOptions.KeyPair.Private as RsaPrivateCrtKeyParameters); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(testCertificate, nupkg, context.WorkingDirectory); SignedArchiveTestUtility.TamperWithPackage(signedPackagePath); await certificateAuthority.OcspResponder.WaitForResponseExpirationAsync(bcCertificate); certificateAuthority.Revoke( bcCertificate, RevocationReason.KeyCompromise, DateTimeOffset.UtcNow.AddSeconds(-1)); var args = new string[] { nupkg.Id, "-Version", nupkg.Version, "-DirectDownload", "-NoCache", "-Source", context.WorkingDirectory, "-OutputDirectory", Path.Combine(context.WorkingDirectory, "packages") }; // Act var result = RunInstall(_nugetExePath, context, expectedExitCode: 1, additionalArgs: args); // Assert result.ExitCode.Should().Be(1); result.Errors.Should().Contain(string.Format(_NU3008, SigningTestUtility.AddSignatureLogPrefix(_NU3008Message, nupkg.Identity, context.WorkingDirectory))); result.Errors.Should().Contain(string.Format(_NU3012, SigningTestUtility.AddSignatureLogPrefix(_NU3012Message, nupkg.Identity, context.WorkingDirectory))); result.AllOutput.Should().Contain($"WARNING: {string.Format(_NU3027, SigningTestUtility.AddSignatureLogPrefix(_NU3027Message, nupkg.Identity, context.WorkingDirectory))}"); } }
public void Create_WithLargePositiveSerialNumber_ReturnsIssuerSerial() { using (var certificate = SigningTestUtility.GenerateCertificate("test", generator => { var bytes = BitConverter.GetBytes(long.MaxValue); Array.Reverse(bytes); generator.SetSerialNumber(bytes); })) { var issuerSerial = IssuerSerial.Create(certificate); SigningTestUtility.VerifySerialNumber(certificate, issuerSerial); } }
public void CreateSignedAttributes_SignPackageRequest_WithValidInput_ReturnsAttributes() { using (var rootCertificate = SigningTestUtility.GetCertificate("root.crt")) using (var intermediateCertificate = SigningTestUtility.GetCertificate("intermediate.crt")) using (var leafCertificate = SigningTestUtility.GetCertificate("leaf.crt")) using (var request = CreateRequest(leafCertificate)) { var certList = new[] { leafCertificate, intermediateCertificate, rootCertificate }; var attributes = SigningUtility.CreateSignedAttributes(request, certList); Assert.Equal(3, attributes.Count); VerifyAttributes(attributes, request); } }
public void IsValidForPurposeFast_WithAnyExtendedKeyUsage_ReturnsFalseForCodeSigningEku() { using (var certificate = SigningTestUtility.GenerateCertificate("test", generator => { generator.AddExtension( X509Extensions.ExtendedKeyUsage.Id, critical: false, extensionValue: new ExtendedKeyUsage(KeyPurposeID.IdKPEmailProtection, KeyPurposeID.AnyExtendedKeyUsage)); })) { Assert.Equal(2, GetExtendedKeyUsageCount(certificate)); Assert.False(CertificateUtility.IsValidForPurposeFast(certificate, Oids.CodeSigningEku)); } }
public void HasExtendedKeyUsage_WithEku_ReturnsTrueForEku() { using (var certificate = SigningTestUtility.GenerateCertificate("test", generator => { generator.AddExtension( X509Extensions.ExtendedKeyUsage.Id, critical: false, extensionValue: new ExtendedKeyUsage(KeyPurposeID.IdKPCodeSigning)); })) { Assert.Equal(1, GetExtendedKeyUsageCount(certificate)); Assert.True(CertificateUtility.HasExtendedKeyUsage(certificate, Oids.CodeSigningEku)); } }
public void Create_WithSha512_ReturnsEssCertIdV2() { var hashAlgorithmName = HashAlgorithmName.SHA512; using (var certificate = _fixture.GetDefaultCertificate()) { var essCertIdV2 = EssCertIdV2.Create(certificate, hashAlgorithmName); Assert.Equal(SigningTestUtility.GetHash(certificate, hashAlgorithmName), essCertIdV2.CertificateHash); Assert.Equal(Oids.Sha512, essCertIdV2.HashAlgorithm.Algorithm.Value); Assert.Equal(1, essCertIdV2.IssuerSerial.GeneralNames.Count); Assert.Equal(certificate.IssuerName.Name, essCertIdV2.IssuerSerial.GeneralNames[0].DirectoryName.Name); SigningTestUtility.VerifySerialNumber(certificate, essCertIdV2.IssuerSerial); } }
public async Task SignAsync_WhenCertificateSignatureAlgorithmIsUnsupported_ThrowsAsync() { using (var certificate = SigningTestUtility.GenerateCertificate( "test", generator => { }, "SHA256WITHRSAANDMGF1")) using (var test = SignTest.Create(certificate, HashAlgorithmName.SHA256)) { var exception = await Assert.ThrowsAsync <SignatureException>( () => SigningUtility.SignAsync(test.Options, test.Request, CancellationToken.None)); Assert.Equal(NuGetLogCode.NU3013, exception.Code); Assert.Contains("The signing certificate has an unsupported signature algorithm.", exception.Message); } }
public async Task SignAsync_WhenCertificatePublicKeyLengthIsUnsupported_ThrowsAsync() { using (var certificate = SigningTestUtility.GenerateCertificate( "test", generator => { }, publicKeyLength: 1024)) using (var test = SignTest.Create(certificate, HashAlgorithmName.SHA256)) { var exception = await Assert.ThrowsAsync <SignatureException>( () => SigningUtility.SignAsync(test.Options, test.Request, CancellationToken.None)); Assert.Equal(NuGetLogCode.NU3014, exception.Code); Assert.Contains("The signing certificate does not meet a minimum public key length requirement.", exception.Message); } }
public void GetCertificateChain_WithUntrustedRoot_Throws() { using (var chainHolder = new X509ChainHolder()) using (var rootCertificate = SigningTestUtility.GetCertificate("root.crt")) using (var intermediateCertificate = SigningTestUtility.GetCertificate("intermediate.crt")) using (var leafCertificate = SigningTestUtility.GetCertificate("leaf.crt")) { var chain = chainHolder.Chain; var extraStore = new X509Certificate2Collection() { rootCertificate, intermediateCertificate }; var logger = new TestLogger(); var exception = Assert.Throws <SignatureException>( () => CertificateChainUtility.GetCertificateChain( leafCertificate, extraStore, logger, CertificateType.Signature)); Assert.Equal(NuGetLogCode.NU3018, exception.Code); Assert.Equal("Certificate chain validation failed.", exception.Message); Assert.Equal(1, logger.Errors); SigningTestUtility.AssertUntrustedRoot(logger.LogMessages, LogLevel.Error); SigningTestUtility.AssertRevocationStatusUnknown(logger.LogMessages, LogLevel.Warning); if (RuntimeEnvironmentHelper.IsWindows) { Assert.Equal(2, logger.Warnings); SigningTestUtility.AssertOfflineRevocation(logger.LogMessages, LogLevel.Warning); } else if (RuntimeEnvironmentHelper.IsLinux) { #if NETCORE5_0 Assert.Equal(2, logger.Warnings); SigningTestUtility.AssertOfflineRevocation(logger.LogMessages, LogLevel.Warning); #else Assert.Equal(1, logger.Warnings); #endif } else { Assert.Equal(1, logger.Warnings); } } }
public async Task TimestampSignatureAsync_TimestampingCountersignature_Succeeds() { var logger = new TestLogger(); var timestampService = await _testFixture.GetDefaultTrustedTimestampServiceAsync(); var timestampProvider = new Rfc3161TimestampProvider(timestampService.Url); var signatureContent = new SignatureContent(SigningSpecifications.V1, Common.HashAlgorithmName.SHA256, "Test data to be signed and timestamped"); using (var authorCert = new X509Certificate2(_trustedTestCert.Source.Cert)) { var timestampHashAlgorithm = Common.HashAlgorithmName.SHA256; var signedCms = SigningTestUtility.GenerateRepositoryCountersignedSignedCms(authorCert, signatureContent.GetBytes()); var signature = PrimarySignature.Load(signedCms.Encode()); var signatureValue = signature.GetSignatureValue(); var messageHash = timestampHashAlgorithm.ComputeHash(signatureValue); var request = new TimestampRequest( SigningSpecifications.V1, messageHash, timestampHashAlgorithm, SignaturePlacement.Countersignature); // Act var primarySignature = await timestampProvider.TimestampSignatureAsync(signature, request, logger, CancellationToken.None); var repositoryCountersignature = RepositoryCountersignature.GetRepositoryCountersignature(primarySignature); // Assert repositoryCountersignature.Should().NotBeNull(); repositoryCountersignature.SignerInfo.Should().NotBeNull(); repositoryCountersignature.SignerInfo.UnsignedAttributes.Count.Should().BeGreaterOrEqualTo(1); var hasTimestampUnsignedAttribute = false; var timestampCms = new SignedCms(); foreach (var attr in repositoryCountersignature.SignerInfo.UnsignedAttributes) { if (string.Compare(attr.Oid.Value, Oids.SignatureTimeStampTokenAttribute, CultureInfo.CurrentCulture, CompareOptions.Ordinal) == 0) { hasTimestampUnsignedAttribute = true; timestampCms.Decode(attr.Values[0].RawData); } } hasTimestampUnsignedAttribute.Should().BeTrue(); timestampCms.CheckSignature(verifySignatureOnly: true); } }
public CertificatesFixture() { Key = RSA.Create(keySizeInBits: 2048); _defaultCertificate = SigningTestUtility.GenerateCertificate("test", Key); _rsaSsaPssCertificate = SigningTestUtility.GenerateCertificate("test", generator => { }, hashAlgorithm: Common.HashAlgorithmName.SHA256, paddingMode: RSASignaturePaddingMode.Pss); _lifetimeSigningCertificate = SigningTestUtility.GenerateCertificate( "test", generator => { generator.Extensions.Add( new X509EnhancedKeyUsageExtension( new OidCollection { new Oid(Oids.LifetimeSigningEku) }, critical: true)); }); _expiredCertificate = SigningTestUtility.GenerateCertificate( "test", SigningTestUtility.CertificateModificationGeneratorExpiredCert); _notYetValidCertificate = SigningTestUtility.GenerateCertificate( "test", SigningTestUtility.CertificateModificationGeneratorNotYetValidCert); _nonSelfSignedCertificate = SigningTestUtility.GenerateCertificate( "test non-self-signed certificate", // Must be different than the issuing certificate's subject name. generator => { }, chainCertificateRequest: new ChainCertificateRequest() { Issuer = _defaultCertificate }); _selfIssuedCertificate = SigningTestUtility.GenerateSelfIssuedCertificate(isCa: false); _rootCertificate = SigningTestUtility.GenerateSelfIssuedCertificate(isCa: true); const string name1 = "NuGet Cyclic Test Certificate 1"; const string name2 = "NuGet Cyclic Test Certificate 2"; using (var rsa1 = RSA.Create(keySizeInBits: 2048)) using (var rsa2 = RSA.Create(keySizeInBits: 2048)) { _cyclicChain = new DisposableList <X509Certificate2>() { SigningTestUtility.GenerateCertificate(name1, name2, rsa1, rsa2), SigningTestUtility.GenerateCertificate(name2, name1, rsa2, rsa1) }; } }
[InlineData(null)] // No commitment type. public async Task AllowsNonAuthorAndRepositoryCounterSignatures(string commitmentTypeOidBase64) { // Arrange _message = new SignatureValidationMessage( TestResources.SignedPackageLeafId, TestResources.SignedPackageLeaf1Version, new Uri($"https://unit.test/validation/{TestResources.SignedPackageLeaf1.ToLowerInvariant()}"), Guid.NewGuid()); var packageStream = await GetSignedPackageStream1Async(); ModifySignatureContent( packageStream, configuredSignedCms: signedCms => { using (var counterCertificate = SigningTestUtility.GenerateCertificate(subjectName: null, modifyGenerator: null)) { var cmsSigner = new CmsSigner(counterCertificate); if (commitmentTypeOidBase64 != null) { var value = new AsnEncodedData( Oids.CommitmentTypeIndication, Convert.FromBase64String(commitmentTypeOidBase64)); var attribute = new CryptographicAttributeObject( new Oid(Oids.CommitmentTypeIndication), new AsnEncodedDataCollection(value)); cmsSigner.SignedAttributes.Add(attribute); } signedCms.SignerInfos[0].ComputeCounterSignature(cmsSigner); } }); // Act var result = await _target.ValidateAsync( _packageKey, _packageStream, _message, _token); // Assert VerifyPackageSigningStatus(result, ValidationStatus.Failed, PackageSigningStatus.Invalid); // This failure type indicates the counter signature validation passed. VerifyNU3008(result); }
private void CreateSignedPackageWithExpiredCertificate() { _expiredSignedTestPackageV1Directory = TestDirectory.Create(); _trustedExpiredTestCert = SigningTestUtility.GenerateTrustedTestCertificateThatExpiresIn5Seconds(); _expiredSignedTestPackageV1 = Utils.CreatePackage(_expiredTestPackageName, _packageVersion); _expiredSignedTestPackageV1.AuthorSignatureCertificate = _trustedExpiredTestCert.Source.Cert; SimpleTestPackageUtility.CreatePackages(_expiredSignedTestPackageV1Directory, _expiredSignedTestPackageV1); _expiredSignedTestPackageV1Path = Path.Combine(_expiredSignedTestPackageV1Directory, _expiredSignedTestPackageV1.PackageName); // Wait for cert to expire Thread.Sleep(5000); Assert.True(IsCertificateExpired(_trustedExpiredTestCert.Source.Cert)); }
public void OpenPackageSignatureFileStream_WithFakeContent_ReturnsContent() { using (var test = new Test(SigningTestUtility.GetResourceBytes("SignatureFileWithFakeContent.zip"))) using (var stream = SignedPackageArchiveUtility.OpenPackageSignatureFileStream(test.Reader)) { Assert.False(stream.CanWrite); using (var reader = new BinaryReader(stream)) { var expectedBytes = Encoding.ASCII.GetBytes("content"); var actualBytes = reader.ReadBytes((int)reader.BaseStream.Length); Assert.Equal(expectedBytes, actualBytes); } } }
private async Task <X509Certificate2> CreateDefaultRepositorySigningCertificateAsync() { var ca = await CreateDefaultTrustedCertificateAuthorityAsync(); var keyPair = SigningTestUtility.GenerateKeyPair(publicKeyLength: 2048); var issueOptions = new IssueCertificateOptions() { KeyPair = keyPair, NotBefore = DateTimeOffset.UtcNow.AddSeconds(-2), NotAfter = DateTimeOffset.UtcNow.AddHours(1), SubjectName = new X509Name("CN=NuGet Cross Verify Test Repository Signning Certificate") }; var bcCertificate = ca.IssueCertificate(issueOptions); return(CertificateUtilities.GetCertificateWithPrivateKey(bcCertificate, keyPair)); }
public void ReadSignedArchiveMetadata_WithSignedPackage_ReturnsMetadata() { using (var stream = new MemoryStream(SigningTestUtility.GetResourceBytes("SignedPackage.1.0.0.nupkg"))) using (var reader = new BinaryReader(stream)) { var metadata = SignedPackageArchiveIOUtility.ReadSignedArchiveMetadata(reader); Assert.Equal(0, metadata.StartOfLocalFileHeaders); Assert.Equal(6, metadata.CentralDirectoryHeaders.Count); Assert.Equal(0xd7c, metadata.EndOfCentralDirectory); Assert.Equal(5, metadata.SignatureCentralDirectoryHeaderIndex); var expectedHeaders = new[] { new { ChangeInOffset = 0L, FileEntryTotalSize = 0x136, HeaderSize = 0x39, IndexInHeaders = 0, IsPackageSignatureFile = false, OffsetToFileHeader = 0, Position = 0xbcc }, new { ChangeInOffset = 0L, FileEntryTotalSize = 0x110, HeaderSize = 0x42, IndexInHeaders = 1, IsPackageSignatureFile = false, OffsetToFileHeader = 0x136, Position = 0xc05 }, new { ChangeInOffset = 0L, FileEntryTotalSize = 0x29, HeaderSize = 0x39, IndexInHeaders = 2, IsPackageSignatureFile = false, OffsetToFileHeader = 0x246, Position = 0xc47 }, new { ChangeInOffset = 0L, FileEntryTotalSize = 0xff, HeaderSize = 0x41, IndexInHeaders = 3, IsPackageSignatureFile = false, OffsetToFileHeader = 0x26f, Position = 0xc80 }, new { ChangeInOffset = 0L, FileEntryTotalSize = 0x1dd, HeaderSize = 0x7f, IndexInHeaders = 4, IsPackageSignatureFile = false, OffsetToFileHeader = 0x36e, Position = 0xcc1 }, new { ChangeInOffset = 0L, FileEntryTotalSize = 0x681, HeaderSize = 0x3c, IndexInHeaders = 5, IsPackageSignatureFile = true, OffsetToFileHeader = 0x54b, Position = 0xd40 }, }; Assert.Equal(expectedHeaders.Length, metadata.CentralDirectoryHeaders.Count); for (var i = 0; i < expectedHeaders.Length; ++i) { var expectedHeader = expectedHeaders[i]; var actualHeader = metadata.CentralDirectoryHeaders[i]; Assert.Equal(expectedHeader.Position, actualHeader.Position); Assert.Equal(expectedHeader.OffsetToFileHeader, actualHeader.OffsetToLocalFileHeader); Assert.Equal(expectedHeader.FileEntryTotalSize, actualHeader.FileEntryTotalSize); Assert.Equal(expectedHeader.IsPackageSignatureFile, actualHeader.IsPackageSignatureFile); Assert.Equal(expectedHeader.HeaderSize, actualHeader.HeaderSize); Assert.Equal(expectedHeader.ChangeInOffset, actualHeader.ChangeInOffset); Assert.Equal(expectedHeader.IndexInHeaders, actualHeader.IndexInHeaders); } } }
public async Task TrustedSignersCommand_AddTrustedSigner_WithAuthorSignedPackage_AddsItSuccesfullyToConfigAsync(bool allowUntrustedRoot) { // Arrange var nugetConfigFileName = "NuGet.Config"; var config = @"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> </configuration>"; // Arrange var package = new SimpleTestPackageContext(); using (var dir = TestDirectory.Create()) using (var zipStream = await package.CreateAsStreamAsync()) using (var trustedTestCert = SigningTestUtility.GenerateTrustedTestCertificate()) { var certFingerprint = SignatureTestUtility.GetFingerprint(trustedTestCert.Source.Cert, HashAlgorithmName.SHA256); var signedPackagePath = await SignedArchiveTestUtility.AuthorSignPackageAsync(trustedTestCert.Source.Cert, package, dir); SettingsTestUtils.CreateConfigurationFile(nugetConfigFileName, dir, config); var nugetConfigPath = Path.Combine(dir, nugetConfigFileName); var allowUntrustedRootArg = allowUntrustedRoot ? "-AllowUntrustedRoot" : string.Empty; // Act var commandResult = CommandRunner.Run( _nugetExePath, dir, $"trusted-signers add {signedPackagePath} -Name signer -Author {allowUntrustedRootArg} -Config {nugetConfigPath}", waitForExit: true); // Assert commandResult.Success.Should().BeTrue(); commandResult.AllOutput.Should().Contain(string.Format(CultureInfo.CurrentCulture, _successfulAddTrustedSigner, "author", "signer")); var expectedResult = SettingsTestUtils.RemoveWhitespace($@"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <trustedSigners> <author name=""signer""> <certificate fingerprint=""{certFingerprint}"" hashAlgorithm=""SHA256"" allowUntrustedRoot=""{allowUntrustedRoot.ToString().ToLower()}"" /> </author> </trustedSigners> </configuration>"); SettingsTestUtils.RemoveWhitespace(File.ReadAllText(nugetConfigPath)).Should().Be(expectedResult); } }