Skip to content

Conversation

edwardneal
Copy link
Contributor

Description

This is my final PR in this set of changes to this area, picking up where #3612 left off. Benchmarks for this PR are located in #3554.

The previous PR used the AlwaysEncrypted primitives in SqlColumnEncryptionCspProvider and SqlColumnEncryptionCngProvider. This one introduces them to SqlColumnEncryptionCertificateStoreProvider.

While verifying this, I also noticed that the TestRsaCryptoWithNativeBaseline test was calling private methods using reflection, but that there was a TODO item in the test to use the public API surface instead. I've done this.

Issues

PR 1/3: #3554.
PR 2/3: #3612.
PR 3/3: this one.

Testing

As in the previous PR, automated tests pass. I also created an AE-enabled table in SSMS which used a certificate store-based master key and confirmed that I was able to query it and insert records into it.

…ypair

Also remove an indentation level and dispose of the intermediary X509Certificate2.
This changes some of the test behaviour: previously, it was calling RSADecrypt and RSAVerifySignature directly. Since these methods no longer exist, we follow the public API (which also calls these methods' equivalent functionality.)
This also addresses a TODO: in the test code.
Also ensure that the ref structs implement IDisposable.
@edwardneal edwardneal requested a review from a team as a code owner October 4, 2025 18:52
foreach (CryptoVector cryptoParameter in cryptoParametersListForTest)
// Convert the PFX into a certificate and install it into the local user's certificate store.
// We can only do this cross-platform on the CurrentUser store, which matches the baseline data we have.
Debug.Assert(rsaPfx != null && rsaPfx.Length > 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be an xUnit Assert() ? Here and below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. There were a few other existing instances in the same test, I've changed those too.


// Find the certificate and return
return GetCertificate(storeLocation, storeName, keyPath, thumbprint, isSystemOp);
else
Copy link
Contributor

Choose a reason for hiding this comment

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

Unnecessary else here.

if (!certificate.HasPrivateKey)
{
// Close the certificate store
certificateStore?.Close();
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still need to Close()? The X509Store docs don't say whether or not Dispose() includes whatever Close() does.

The source code clearly does though:

https://github.com/dotnet/runtime/blob/1d1bf92fcf43aa6981804dc53c5174445069c9e4/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Store.cs#L203

So you're good, despite the docs :(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes - backed up by the netfx reference source.

It looks like this was new in net46 though, which might explain the old usage.

@paulmedynski
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@paulmedynski paulmedynski self-assigned this Oct 6, 2025
Swap Debug.Assert to xUnit assertions.
Add explanatory comment when parsing master key path.
Remove redundant else.
Copy link
Contributor

@paulmedynski paulmedynski left a comment

Choose a reason for hiding this comment

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

Looks great!

@paulmedynski
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants