Skip to content

Remove undocumented certificate APIs - #3818

Merged
Dongbo Wang (daxian-dbw) merged 10 commits into
PowerShell:masterfrom
TravisEz13:Remove_undocumented_APIs
May 23, 2017
Merged

Remove undocumented certificate APIs#3818
Dongbo Wang (daxian-dbw) merged 10 commits into
PowerShell:masterfrom
TravisEz13:Remove_undocumented_APIs

Conversation

@TravisEz13

@TravisEz13 Travis Plunk (TravisEz13) commented May 19, 2017

Copy link
Copy Markdown
Member

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.

@SteveL-MSFT Steve Lee (SteveL-MSFT) left a comment

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.

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?

@TravisEz13 Travis Plunk (TravisEz13) May 19, 2017

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.

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 Steve Lee (SteveL-MSFT) left a comment

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.

My concerns are addressed, but would like Lee Holmes (@LeeHolmes) to review before we merge

@@ -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

Choose a reason for hiding this comment

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

LGTM

@daxian-dbw
Dongbo Wang (daxian-dbw) merged commit 3496136 into PowerShell:master May 23, 2017
@TravisEz13
Travis Plunk (TravisEz13) deleted the Remove_undocumented_APIs branch May 23, 2017 17:50
Thatgfsj (Thatgfsj) pushed a commit to Thatgfsj/PowerShell that referenced this pull request Aug 6, 2026
The code paths deleted where using the undocumented Win32 APIs 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.
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