Skip to content

Remove undocumented certificate APIs#3818

Merged
daxian-dbw merged 10 commits intoPowerShell:masterfrom
TravisEz13:Remove_undocumented_APIs
May 23, 2017
Merged

Remove undocumented certificate APIs#3818
daxian-dbw merged 10 commits intoPowerShell:masterfrom
TravisEz13:Remove_undocumented_APIs

Conversation

@TravisEz13
Copy link
Copy Markdown
Member

@TravisEz13 TravisEz13 commented May 19, 2017

Addresses #3792

The code paths deleted where using the undocumented API on WIn8 and newer for the following purposes:

  • Faster filtering
  • Getting two properties (left empty on Win7 and below)
  • Logging using Certificate components when a cert is deleted or copied.

After the change, all the code uses public APIs. Filtering is done in PowerShell using existing code. I don't believe the logging is needed.

Copy link
Copy Markdown
Member

@SteveL-MSFT SteveL-MSFT left a comment

Choose a reason for hiding this comment

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

Is there sufficient test coverage?

{
return new CertificateProviderCodeSigningDynamicParameters();
}
return new CertificateProviderCodeSigningDynamicParameters();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will work on downlevel like Win7?

Copy link
Copy Markdown
Member Author

@TravisEz13 TravisEz13 May 19, 2017

Choose a reason for hiding this comment

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

This is the code path that is always taken on Windows PowerShell on Win7. It should work.


Security.NativeMethods.LogCertDelete(fMachine, cert.Handle);
}
//TODO: log cert move
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Open issue

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

filed #3826, until this is resolved

{
Security.NativeMethods.LogCertDelete(fMachine, cert.Handle);
}
//TODO: Log Cert Delete
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Open issue for TODO

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'm not sure we need these, but I'll open an issue or remove them based on my investigation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

filed #3826, until this is resolved

names.Add(new DnsNameRepresentation(
Marshal.PtrToStringUni(Marshal.ReadIntPtr(papwszPunycodeNames, i * Marshal.SizeOf(papwszPunycodeNames))),
Marshal.PtrToStringUni(Marshal.ReadIntPtr(papwszUnicodeNames, i * Marshal.SizeOf(papwszUnicodeNames)))));
//TODO: detect and handle punyCode
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Open issue

out papwszUnicodeNames);
if (hr != Security.NativeConstants.S_OK)
// Get the part after 'DNS Name='
if(nameLine.Length > 9)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Any validation needed here? Prefer to have const DnsNamePrefixLength used than 9

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, I was planning on adding it with the support for punyCode. The only way I can see puny code being supported is a different record format.

@SteveL-MSFT SteveL-MSFT requested a review from PaulHigin May 19, 2017 19:26
@TravisEz13 TravisEz13 force-pushed the Remove_undocumented_APIs branch from ca9f38b to 0348ee2 Compare May 19, 2017 19:35
Copy link
Copy Markdown
Member

@SteveL-MSFT SteveL-MSFT left a comment

Choose a reason for hiding this comment

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

My concerns are addressed, but would like @LeeHolmes to review before we merge

@daxian-dbw daxian-dbw self-assigned this May 19, 2017
@@ -480,22 +445,6 @@ public void Open(bool includeArchivedCerts)
public IntPtr GetFirstCert(
CertificateFilterInfo filter)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like the "filter" argument is no longer needed here.

}
if (Valid)
{
if (_filterHandle != null)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do we lose by removing this down level cert filtering option?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

probably just performance. Looking at the CmdLet we only supported filtering by codesigning certs which the tests pass after the change.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

line 2636, is filtering.

{
if (DownLevelHelper.NativeFilteringSupported())
{
return new CertificateProviderDynamicParameters();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like the internal CertificateProviderDynamicParameters class is no longer used. Has it been removed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#resolved

Collection<string> ekuCollection = System.Management.Automation.Internal.SecuritySupport.GetCertEKU(cert);

foreach (string oidString in ekuCollection)
if (extension.Oid.FriendlyName == "Enhanced Key Usage")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be better to use the Oid.Value property ("1.3.6.1.5.5.7.3.4")? Maybe it makes no difference but I wonder if we should use case insensitive string compare?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Comparing the value would be better. I'll update the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Except that is the OID for a specific EKU, not specifying an EKU. The OID should be 2.5.29.37

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#Resolved

if (extension.Oid.FriendlyName == "Enhanced Key Usage")
{
if (!String.IsNullOrEmpty(oidString))
X509EnhancedKeyUsageExtension ext = (X509EnhancedKeyUsageExtension)extension;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this cast guaranteed? Or should we be using "as" keyword cast and check for null?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#Resolved

{
private List<DnsNameRepresentation> _dnsList = new List<DnsNameRepresentation>();
private System.Globalization.IdnMapping idnMapping = new System.Globalization.IdnMapping();
private static string dnsNamePrefix = "DNS Name=";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We normally use "private const string"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#resolved

// extract DNS name from subject distinguish name
// if it exists and does not contain a comma
// a comma, indicates it is not a DNS name
if(cert.Subject.Length > distinguishedNamePrefix.Length &&
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think the Length check is necessary. I would expect the StartsWith method to do that check.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#resolved

}
if (cPunycodeName != cUnicodeName)
// Get the part after 'DNS Name='
if(nameLine.Length > dnsNamePrefix.Length && nameLine.StartsWith(dnsNamePrefix, System.StringComparison.InvariantCulture))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Again, I don't think the length check is needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#resolved

dnsName = new DnsNameRepresentation(name,unicodeName);

// Only add the name if it is not the same as an existing name.
if(!_dnsList.Contains(dnsName))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this be a case sensitive compare?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The old code gave all variations back in the results. So, no.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

#resolved

@@ -0,0 +1,138 @@
Import-Module (Join-Path -Path $PSScriptRoot 'certificateCommon.psm1') -Force
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please put this test prep inside "if ($IsWindows) {}"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

What is the concern here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems like we can skip the prep work if not running on Windows.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The only imports functions, the actual prep work is done in the beforeall of the feature tests and is skipped on non-windows platforms.

Copy link
Copy Markdown
Contributor

@PaulHigin PaulHigin left a comment

Choose a reason for hiding this comment

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

LGTM

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.

5 participants