Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration tests for CertificateValidationMessageHandler #341

Merged
merged 1 commit into from Feb 20, 2018

Conversation

loic-sharma
Copy link
Contributor

No description provided.

@@ -246,7 +246,7 @@ internal struct CERT_TRUST_STATUS
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct CRL_ENTRY
{
public CRYPTOAPI_BLOB SerializeNumber;
public CRYPTOAPI_BLOB SerialNumber;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the proper name for the property (docs here).

@@ -107,6 +107,12 @@ private SignatureDecider MakeDeciderForRevokedCodeSigningCertificate(DateTime? r
throw new InvalidOperationException($"Signature {signature.Key} has multiple trusted timestamps");
}

// Revoked certificates invalidate all dependent signatures at ingestion.
if (signature.Status == PackageSignatureStatus.Unknown)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug fix. We do not accept signatures with revoked certificates at ingestion, even if the revocation date is after the signing time.

@@ -52,7 +52,12 @@ public CertificateIntegrationTestFixture()

public Task<SigningTestServer> GetTestServerAsync() => _testServer.Value;
public Task<Uri> GetTimestampServiceUrlAsync() => _timestampServiceUrl.Value;
public Task<X509Certificate2> GetSigningCertificateAsync() => _signingCertificate.Value;

public async Task<X509Certificate2> GetSigningCertificateAsync()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before, this certificate was shared and would be disposed by the message handler - this caused weird issues in integration tests. A new X509Certificate2 is created now, so you can dispose it willy-nilly without affecting other tests.

@@ -230,7 +230,7 @@ public static IEnumerable<object[]> RevokedCodeSigningCertificateWithRevocationD
{
yield return new object[]
{
TimeSpan.FromDays(-1), SignatureDecision.Ignore, SignatureDecision.Ignore, SignatureDecision.Ignore
TimeSpan.FromDays(-1), SignatureDecision.Reject, SignatureDecision.Ignore, SignatureDecision.Ignore
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signatures should be rejected at ingestion time if their certificate is revoked, regardless of the revocation time.

var ca = await GetCertificateAuthority();
var ca2 = ca.CreateIntermediateCertificateAuthority();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some weird caching of certificates is happening. Windows is sometimes able to build a chain without the CA Issuer attribute if the intermediate certificate has been seen before.

With this change, a new intermediate CA with no CA responders is issued every time a new end certificate is requested. Since the intermediate CA's certificate has never seen before, caching certificates cannot help build the chain.

{
public static readonly DateTime RevocationTime = DateTime.UtcNow.AddDays(-4);
public static readonly DateTime BeforeRevocationTime = RevocationTime.AddDays(-1);
public static readonly DateTime AfterRevocationTime = RevocationTime.AddDays(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these be private?

Also, I'm not sure what the default validity period is for your certificates, but I recommend minimizing the validity period of your test certificates.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I'll lower the visibility.

We will need to update Test.Utility APIs to customize the "not after" date. I think I'll do this in a separate PR once a newer version has been released.

var certificateValidationService = new CertificateValidationService(
_context.Object,
_telemetryService.Object,
new Mock<ILogger<CertificateValidationService>>().Object);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a shorthand for this:

Mock.Of<ILogger<CertificateValidationService>>()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion, I didn't know about that :)


var (publicCertificate, certificate) = IssueCertificate(ca, "Revoked Timestamping", CustomizeAsSigningCertificate);

ca.Revoke(publicCertificate, reason: 0, revocationDate: revocationDate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revoke(...)'s second parameter is an int, because BouncyCastle does not have an enum for revocation reasons. However, BouncyCastle does have a class (Org.BouncyCastle.Asn1.X509.CrlReason) with some predefined revocation reasons. I could have created my own enum and map between the two, and maybe I should still do that. However, without that, I recommend passing CrlReason.Unspecified (0) or some other field instead of passing a constant literal 0, which is frustratingly obtuse.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll go ahead and use a const for this. The Test.Utility package has an enum for the reason now - after the latest version is released, we will switch over to the enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

var ca = await GetCertificateAuthority();
var ca2 = ca.CreateIntermediateCertificateAuthority();

responders.AddRange(testServer.RegisterResponders(ca2, addCa: false));
Copy link
Contributor

@dtivel dtivel Feb 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a suboptimal use of a IHttpResponder's. SigningTestServer.RegisterResponder(...) returns an IDisposable, which deregisters an IHttpResponder on disposal. Registered responders should be scoped as narrowly as possible. For the default, trusted chain (root, intermediate, end), it's reasonable to scope the responders for the lifetime of your test fixture. In all other cases, the registered responders should be deterministically disposed by each test, ideally with a using statement. Here is an example of a responder that is scoped to a single test.

I think this should be scoped at the test level, since this method always creates a new, single-use ca2 and end certificate anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. I went ahead and made a return type too as the tuple wasn't the prettiest.


ca.Revoke(publicCertificate, reason: 0, revocationDate: DateTimeOffset.UtcNow);
ca2.Revoke(publicCertificate, reason: 0, revocationDate: DateTimeOffset.UtcNow);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same feedback here for reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

public X509Certificate2 EndCertificate { get; }
public X509Certificate2[] IntermediateCertificates { get; }

public void Dispose() { /*=> _responders.Dispose()*/; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be commented out? Or removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - this should not be commented out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@loic-sharma loic-sharma merged commit ffed70e into dev Feb 20, 2018
@loic-sharma loic-sharma deleted the loshar-integration-tests branch February 20, 2018 21:30
joelverhagen pushed a commit that referenced this pull request Sep 27, 2019
joelverhagen pushed a commit that referenced this pull request Sep 27, 2019
* Feed2Catalog:  replace inner loops with one outer loop (#329)
Resolve NuGet/Engineering#1526.
* V3:  rename asynchronous IStorage methods (#336)
Progress on NuGet/NuGetGallery#6267.
* Test:  fix flaky basic search tests (#337)
Progress on NuGet/NuGetGallery#6292.
* Add signing to search service (#338)
Progress on https://github.com/NuGet/Engineering/issues/1644
* Test:  add registration tests (#341)
Progress on NuGet/NuGetGallery#6317.
* remove unused scripts (#340)
* MonitoringProcessor:  improve throughput (#342)
Progress on NuGet/NuGetGallery#6327.
* Catalog2Dnx:  improve throughput (#335)
Progress on NuGet/NuGetGallery#6267.
* Functional tests should not be dependent on a specific hash and file size of the test package (#343)
* Add MicroBuild dependency and signing of output DLLs (#345)
Progress on https://github.com/NuGet/Engineering/issues/1644
* Rewrite SafeRoleEnvironment to not use Assembly.LoadWithPartialName (#339)
* Test:  improve and add registration tests (#346)
More progress on NuGet/NuGetGallery#6317.
* Use ServerCommon commit that is consistent with other repositories (#347)
Progress on https://github.com/NuGet/Engineering/issues/1644
* [Monitoring] Ensure packages are signed (#348)
This adds a validation to ensure indexed packages are signed by verifying that the package contains a [package signature file](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-the-package-signature-file).
This validation is disabled for now. To enable this validation, the flag `-expectsSignature true` must be added to ng.exe's command line arguments. This validation will be enabled once all packages are repository signed.
Part of NuGet/Engineering#1627
* V3:  make stylistic consistency and cleanup changes (#349)
Progress on NuGet/NuGetGallery#6411.
joelverhagen pushed a commit that referenced this pull request Oct 26, 2020
joelverhagen pushed a commit that referenced this pull request Oct 26, 2020
* Feed2Catalog:  replace inner loops with one outer loop (#329)
Resolve NuGet/Engineering#1526.
* V3:  rename asynchronous IStorage methods (#336)
Progress on NuGet/NuGetGallery#6267.
* Test:  fix flaky basic search tests (#337)
Progress on NuGet/NuGetGallery#6292.
* Add signing to search service (#338)
Progress on https://github.com/NuGet/Engineering/issues/1644
* Test:  add registration tests (#341)
Progress on NuGet/NuGetGallery#6317.
* remove unused scripts (#340)
* MonitoringProcessor:  improve throughput (#342)
Progress on NuGet/NuGetGallery#6327.
* Catalog2Dnx:  improve throughput (#335)
Progress on NuGet/NuGetGallery#6267.
* Functional tests should not be dependent on a specific hash and file size of the test package (#343)
* Add MicroBuild dependency and signing of output DLLs (#345)
Progress on https://github.com/NuGet/Engineering/issues/1644
* Rewrite SafeRoleEnvironment to not use Assembly.LoadWithPartialName (#339)
* Test:  improve and add registration tests (#346)
More progress on NuGet/NuGetGallery#6317.
* Use ServerCommon commit that is consistent with other repositories (#347)
Progress on https://github.com/NuGet/Engineering/issues/1644
* [Monitoring] Ensure packages are signed (#348)
This adds a validation to ensure indexed packages are signed by verifying that the package contains a [package signature file](https://github.com/NuGet/Home/wiki/Package-Signatures-Technical-Details#-the-package-signature-file).
This validation is disabled for now. To enable this validation, the flag `-expectsSignature true` must be added to ng.exe's command line arguments. This validation will be enabled once all packages are repository signed.
Part of NuGet/Engineering#1627
* V3:  make stylistic consistency and cleanup changes (#349)
Progress on NuGet/NuGetGallery#6411.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants