Git Product home page Git Product logo

pkix.net's People

Contributors

crypt32 avatar kendall18 avatar lennybacon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

pkix.net's Issues

[Bug] X509CRL2.Build fails

Hi (last bug report today, promised),

I cannot manage to make the Build method of X509CRL2 work.
Simply put, my objective is to create a certain number of CRLs for an offline CA in advance in order to avoid too frequent operations on this CA. We don't want to increase the CRL validity of course because if we ever need to revoke a subCA, it would take too long for clients to refresh the CRL.

Here is a simplified version of my script:

$initialCrl = Get-CertificateRevocationList -Path $Path
$startDate = Get-Date

if ($null -eq $InitialCRLNumber) {
    $InitialCRLNumber = $initialCrl.GetCRLNumber()
}

$issuer = Get-Item Cert:\LocalMachine\My\$issuerHash

foreach ($i in 1 .. $NumberToCreate) {
    $InitialCRLNumber = $InitialCRLNumber + 1
    $nextPublish = $startDate.AddMonths(1)
    $nextCrlFilename = "$i.crl"

    $crlNumberExt = New-Object System.Security.Cryptography.X509Certificates.X509CRLNumberExtension $InitialCRLNumber, $false
    $nextPublishExt = New-Object System.Security.Cryptography.X509Certificates.X509NextCRLPublishExtension $nextPublish, $false
    $extCollection = New-Object System.Security.Cryptography.X509Certificates.X509ExtensionCollection
    [void] $extCollection.Add($crlNumberExt)
    [void] $extCollection.Add($nextPublishExt)

    $crl = New-Object System.Security.Cryptography.X509Certificates.X509CRL2
    $crl.SetThisUpdate($startDate)
    $crl.SetNextUpdate($startDate.AddDays(45))
    $crl.SetHashingAlgorithm((oid2 $initialCrl.SignatureAlgorithm.Value -Group SignatureAlgorithm))
    if ($null -ne $initialCrl.RevokedCertificates) {
        $crl.ImportCRLEntries($initialCrl.RevokedCertificates)
    }
    $crl.ImportExtensions($extCollection)
    $crl.Build($issuer, $false, $true)
    $crl.Export($nextCrlFilename, [System.Security.Cryptography.X509Certificates.X509EncodingType]::Binary)

    # for next loop
    $startDate = $nextPublish
}

I have several problems which look like bugs in the Build method:

  • Each time the build method is called, the extensions are duplicated (x2 on first call, x3 on second, etc.). It is duplicated in the object but also in the RawData property and thus in the exported CRL. The stranger thing is that even if I recreate a X509CRL2 object from scratch, there seems to be some remanence of information from the last object because the extensions are then x4, x5, etc. If I forcefully remove the variable and call [GC]::collect(), it is not duplicated anymore.
  • The build method always fails if I leave the signature algorithm to "sha256RSA" (which is the algorithm of my initial CRL). The error is Exception calling "Build" with "3" argument(s): "Object reference not set to an instance of an object.".
  • If I switch to "sha256NoSign" and put the second argument of the Build method to $true then it works but of course this would not be an acceptable CRL...

Note that in order to be sure it was not linked with my particular environment, I have tested in a lab with a freshly installed standalone root CA.

X509Certificate2.ResolveExtensions() fails when checking Certificate Template Name extension

Test Certificate

This method throws an exception when current extension OID is 1.3.6.1.4.1.311.20.2 (Certificate Template Name) because Crypt32.CryptDecodeObject() returns false

void m_decode(Byte[] rawData) {
UInt32 pcbStructInfo = 0;
if (Crypt32.CryptDecodeObject(1, _oid.Value, rawData, (UInt32)rawData.Length, 0, IntPtr.Zero, ref pcbStructInfo)) {
IntPtr pbStructInfo = Marshal.AllocHGlobal((Int32)pcbStructInfo);
Crypt32.CryptDecodeObject(1, _oid.Value, rawData, (UInt32)rawData.Length, 0, pbStructInfo, ref pcbStructInfo);
var structure = (Wincrypt.CERT_TEMPLATE_EXT)Marshal.PtrToStructure(pbStructInfo, typeof(Wincrypt.CERT_TEMPLATE_EXT));
Marshal.FreeHGlobal(pbStructInfo);
TemplateOid = new Oid(structure.pszObjId);
MajorVersion = (Int32)structure.dwMajorVersion;
MinorVersion = (Int32)structure.dwMinorVersion;
} else {
throw new Win32Exception(Marshal.GetLastWin32Error());
}

PKI.ManagedAPI.Crypt32Managed::DecodeX509Extensions error with empty sequence

Hello Vadims,

A customer of mine sent me a CSR that your library cannot parse while certutil succeeds.
I think the CSR is not strictly valid from an RFC point of view but I'm pretty sure his appliance cannot be configured to generate valid ones unfortunately.

The error I get is "ASN1 bad tag value met." and the stack trace shows that the error is thrown from PKI.ManagedAPI.Crypt32Managed::DecodeX509Extensions:

   at PKI.ManagedAPI.Crypt32Managed.DecodeX509Extensions(Byte[] rawData)
   at System.Security.Cryptography.X509CertificateRequests.X509CertificateRequest.getAttributes()
   at System.Security.Cryptography.X509CertificateRequests.X509CertificateRequest.m_decode()
   at System.Security.Cryptography.X509CertificateRequests.X509CertificateRequest.m_initialize()

There is a Certificate Extensions (1.2.840.113549.1.9.14) attribute in the CSR but it is empty.
Looking at it with your ASN.1 Editor, here is the portion that seems to be the problem:

Offset|Length|LenByte|
======+======+=======+==========================================================================================
   481|    15|      1|   SEQUENCE : 
   483|     9|      1|      OBJECT_IDENTIFIER : 'Certificate Extensions (1.2.840.113549.1.9.14)'
   494|     2|      1|      SET : '3000'

Certutil shows the following output for this attribute:

  Attribute[0]: 1.2.840.113549.1.9.14 (Certificate Extensions)
    Value[0][0], Length = 2
    Unknown Attribute type
Certificate Extensions: 0

I cannot send you the complete CSR unfortunately. Even if not strictly compliant, do you think you could add a case for such requests?

X509Certificate2::ResolveExtensions is missing "Certificate Template Information" extension

After the latest commit, X509Certificate2::ResolveExtensions() is not including the "Certificate Template Information" extension in the resulting collection when it exists.

test cert

Certutil Dump

>certutil test.cer
.
.
.
Certificate Extensions: 8
    1.3.6.1.4.1.311.21.7: Flags = 0, Length = 2f
    Certificate Template Information
        Template=1.3.6.1.4.1.311.21.8.12071204.7030896.1589380.8706350.14889434.199.7071011.580170
        Major Version Number=100
        Minor Version Number=5

Using PKI Library

var test = new X509Certificate2(@"D:\junk\test.cer");
var extensions = test.ResolveExtensions();
foreach (var element in extensions)
{
	Console.WriteLine($"{element.Oid.Value} : {element.Oid.FriendlyName}");
}

Console.WriteLine();

if (extensions[X509ExtensionOid.CertificateTemplate] is X509Extension v1TemplateExt)
{
	Console.WriteLine($"Certificate Template Name : {v1TemplateExt.Format(false)}");
}

Output:

1.3.6.1.4.1.311.20.2 : Certificate Template Name
2.5.29.37 : Enhanced Key Usage
2.5.29.15 : Key Usage
1.3.6.1.4.1.311.21.10 : Application Policies
2.5.29.14 : Subject Key Identifier
2.5.29.35 : Authority Key Identifier
2.5.29.31 : CRL Distribution Points
1.3.6.1.5.5.7.1.1 : Authority Information Access

Certificate Template Name : 302D06252B060104018237150885E0E22483AD9070E181048493B22E878CE35A814783AFCA23A3B44A020164020105

[BreakingChange|Feature] Redesign entire library

General concerns are expressed in this post and comments: https://www.sysadmins.lv/blog-en/powershell-pki-module-v327-is-out.aspx

Problem: current library design/structure is nearly unsalvageable and at some point this problem must be solved. Sooner is better.

This is going to be a big change for the library. General idea is to:

  • create separate project with correct class/namespace hierarchy (e.g. move away from .NET default namespaces)
  • review each class before moving to new library
  • remove unnecessary classes and/or redesign existing
  • fix existing library state at where it is and ship along with a new library with PSPKI
  • any new class should go to new project
  • PS module will be ported
  • give a chance for customers to port their existing code to a new one (while maintaining existing code for backward compatibility)
  • something else (will be added later)

Support for alternate signature format (RSASSA-PSS) and additional algorithms

Hello Vadims,

Earlier today I tried initializing a X509CertificateRequest object with a CSR provided by a user that used the "alternate signature format" (RSASSA-PSS). Since this algorithm is not currently supported by your library it failed with a "Signature algorithm not supported" exception.

I'm not sure whether this is an often used signature algorithm but since it is supported by ADCS, it would be good maybe to support it as well in your library.

On the same topic, Windows 10 added support for new elliptic curves (https://msdn.microsoft.com/en-us/library/windows/desktop/mt632245%28v=vs.85%29.aspx) and although probably nobody is really using them for enterprise CAs today, that may come in the future and supporting them would at least allow to properly parse the CSRs like certutil does.

CATemplate.Remove doesn't work

CATemplate.Remove always returns false because of incorrect CertificateTemplate.Equals method. The method relies on OID.GetHashCode which is different for each OID instance even with the same name/value pair.

Is there a NuGet feed available?

Hello,

I am interested in using this package and am curious if there is already a NuGet feed available? I was unable to find anything on nuget.org.

Thank you!

Steve

[Feature request] Get list of templates current user is allowed for enrolment

I wrote the following PowerShell function some time ago to get the list of all certificate templates issued by a particular CA for which the current user has enroll permissions.
There may exists some native way of doing it with COM classes but I did not find it.
I think this might be useful in your library/module.

function Get-AllowedCertificateTemplate {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('CA')]
        [PKI.CertificateServices.CertificateAuthority[]] $CertificationAuthority
    )

    # Get current user's identities
    $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $allowedSids = @($currentUser.UserClaims |
        Where-Object Type -in ([System.Security.Claims.ClaimTypes]::PrimaryGroupSid,
                               [System.Security.Claims.ClaimTypes]::PrimarySid,
                               [System.Security.Claims.ClaimTypes]::GroupSid,
                               [System.Security.Claims.ClaimTypes]::Sid) |
        ForEach-Object { $_.Value })
    $deniedSids = $allowedSids + @($currentUser.UserClaims |
        Where-Object Type -in ([System.Security.Claims.ClaimTypes]::DenyOnlyPrimaryGroupSid,
                               [System.Security.Claims.ClaimTypes]::DenyOnlyPrimarySid,
                               [System.Security.Claims.ClaimTypes]::DenyOnlySid) |
        ForEach-Object { $_.Value })
    
    ($CertificationAuthority | Get-CATemplate).Templates |
        Sort-Object DisplayName -Unique |
        Where-Object {
            # Retrieve only templates whose names are supplied in request (i.e. no auto-enrollment)
            $_.Settings.SubjectName -band [PKI.CertificateTemplates.CertificateTemplateNameFlags]::EnrolleeSuppliesSubject
        } |
        Where-Object {
            # Retrieve only templates for which the current user has 'Enroll' permission
            $denied = $false
            $allowed = $false
            ($_ | Get-CertificateTemplateAcl).Access |
                Where-Object {
                    $_.Permissions -contains [PKI.Security.TemplateRight]::Enroll
                } |
                ForEach-Object {
                    $sid = $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value
                    if ($_.AccessType -eq [System.Security.AccessControl.AccessControlType]::Deny -and $sid -in $deniedSids) {
                        $denied = $true
                    } elseif ($_.AccessType -eq [System.Security.AccessControl.AccessControlType]::Allow -and $sid -in $allowedSids) {
                        $allowed = $true
                    }
                }

            -not $denied -and $allowed
        }
}

Getting Registry key exception on EnumEnterpriseCAs when using library version 3.5.0.0 in my C# project

Issue:Getting Registry key exception when using library version 3.5.0.0 in C# project

CertificateAuthority[] certificateAuthority = CertificateAuthority.EnumEnterpriseCAs("Name","*");

Please note same thing happens on EnumEnterpriseCAs("Server","*");

Appears to be similar to the issue PSPKI issue 73.

Exception details:

{"Requested registry access is not allowed."}
{System.Collections.ListDictionaryInternal}
null
null
null
null
-2146233078
null
null
"Requested registry access is not allowed."
null
null
null
null
null
"Microsoft.Win32.Registry"
" at Microsoft.Win32.RegistryKey.InternalOpenSubKeyCore(String name, Boolean writable)\r\n at PKI.Utils.CryptoRegistry.GetRReg(String entry, String caName, String computerName, String node)\r\n at PKI.CertificateServices.CertificateAuthority.pingRegistry(String computerName)\r\n at PKI.CertificateServices.CertificateAuthority..ctor(String computerName, String name)\r\n at PKI.CertificateServices.CertificateAuthority.EnumEnterpriseCAs(String findType, String findValue)\r\n at CertExporter.Startup.StartAsync(CancellationToken cancellationToken) in D:\Alexey\p\CertExporter\Startup.cs:line 40\r\n at Microsoft.Extensions.Hosting.Internal.Host.d__9.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.d__4.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.d__4.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)\r\n at CertExporter.Program.Main(String[] args) in D:\Alexey\p\CertExporter\Program.cs:line 104"
{Microsoft.Win32.RegistryKey InternalOpenSubKeyCore(System.String, Boolean)}
null

{string[0]}
{Microsoft.Extensions.Hosting.Internal.Host}

[Feature request] Implement way to manage certificate managers/enrolment agents rights

See blog post https://www.sysadmins.lv/blog-en/how-to-read-adcs-enrollment-agentcertificate-manager-rights-in-powershell.aspx

This would be good to have this officially implemented in pkix.net/PSPKI module and thus be able to read but also write certificate managers and enrolment agents rights.

One step further would be to implement a method actually checking the current user's permissions (based on its current security token) for a given template.
I did write such a method some time ago, using a slightly modified version of your Get-OfficerRights function from the blog post. It is quite ugly but if it may help you some bit, here it is:

# We don't use the simpler $CertificationAuthority.GetMyRoles() either because it
# does not check "deny only" SIDs and does not test certificate mnagers restrictions
function Test-CertificateManager {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('CA')]
        [PKI.CertificateServices.CertificateAuthority] $CertificationAuthority,

        [PKI.CertificateTemplates.CertificateTemplate] $Template
    )

    # Get current user's identities
    $currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $allowedSids = @($currentUser.UserClaims |
        Where-Object Type -in ([System.Security.Claims.ClaimTypes]::PrimaryGroupSid,
                               [System.Security.Claims.ClaimTypes]::PrimarySid,
                               [System.Security.Claims.ClaimTypes]::GroupSid,
                               [System.Security.Claims.ClaimTypes]::Sid) |
        ForEach-Object { $_.Value })
    $deniedSids = $allowedSids + @($currentUser.UserClaims |
        Where-Object Type -in ([System.Security.Claims.ClaimTypes]::DenyOnlyPrimaryGroupSid,
                               [System.Security.Claims.ClaimTypes]::DenyOnlyPrimarySid,
                               [System.Security.Claims.ClaimTypes]::DenyOnlySid) |
        ForEach-Object { $_.Value })

    $denied = $false
    $allowed = $false
    (Get-CASecurityDescriptor -CertificationAuthority $CertificationAuthority).Access |
        Where-Object {
            $_.CertificationAuthorityRights -band [PKI.Security.AccessControl.CertificationAuthorityRights]::ManageCertificates
        } |
        ForEach-Object {
            $sid = $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value
            if ($_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Deny -and $sid -in $deniedSids) {
                $denied = $true
            } elseif ($_.AccessControlType -eq [System.Security.AccessControl.AccessControlType]::Allow -and $sid -in $allowedSids) {
                $allowed = $true
            }
        }

    $isOfficer = -not $denied -and $allowed
    if (-not $Template -or -not $isOfficer) {
        return $isOfficer
    }

    # Test certificate managers restrictions
    $CertAdmin = New-Object -ComObject CertificateAuthority.Admin
    try {
        $aclBytes = $CertAdmin.GetConfigEntry($CertificationAuthority.ConfigString, [String]::Empty, 'OfficerRights')
        $denied = $false
        $allowed = $false
        Convert-OfficerRights $aclBytes |
            Where-Object { [String]::IsNullOrEmpty($_.Template) -or $_.Template.Value -eq $Template.OID.Value } |
            Where-Object {
                $ret = $false
                $toBeTestedSids = if ($_.AceType -eq [System.Security.AccessControl.AceQualifier]::AccessDenied) { $deniedSids } else { $allowedSids }
                $_.Securables | ForEach-Object { $ret = $ret -or $_ -in $toBeTestedSids }
                $ret
            } |
            ForEach-Object {
                if ($_.AceType -eq [System.Security.AccessControl.AceQualifier]::AccessDenied -and $_.Officer -in $deniedSids) {
                    $denied = $true
                } elseif ($_.AceType -eq [System.Security.AccessControl.AceQualifier]::AccessAllowed -and $_.Officer -in $allowedSids) {
                    $allowed = $true
                }
            }

        return -not $denied -and $allowed

    } catch {
        # There is no restriction applied so return previous result
        return $isOfficer
    } finally {
        [void] [Runtime.InteropServices.Marshal]::ReleaseComObject($CertAdmin)
    }
}

Deny-CertificateRequest Warning

When Denying a request I a seeing WARNING: The request's with ID = REQID current status does not allow this operation

However the certificate denial is actually completed successfully

Get-PendingRequest -CertificationAuthority -RequestID ##### |Deny-CertificateRequest
WARNING: The request's with ID = ##### current status does not allow this operation.

Additionally... Thank you very much for your work on PSPKI, it has greatly improved management of Microsoft CA's!

CryptoConfig.EncodeOID Bug - "Value was either too large or too small for an Int32."

Multiple places in the code and its dependent libraries end up calling .NET's CryptoConfig.EncodeOID:

SysadminsLV.Asn1Parser.Asn1Utils.EncodeObjectIdentifier uses it as well and it is used extensively throughout the code base:
image

There appears to be an integer parsing bug in CryptoConfig.EncodeOID. The following PowerShell demonstrates this bug.

PS C:\> [System.Security.Cryptography.CryptoConfig]::EncodeOID('1.3.6.1.4.1.311.21.8.2473183039')

Exception calling "EncodeOID" with "1" argument(s): "Value was either too large or too small for an Int32."
At line:1 char:1
+ [System.Security.Cryptography.CryptoConfig]::EncodeOID('1.3.6.1.4.1.3 ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : OverflowException

The bug is due to the following code in .NET's CryptoConfig.EncodeOID function:

public static byte[] EncodeOID(string str)
{
	if (str == null)
	{
		throw new ArgumentNullException("str");
	}
	char[] separator = new char[]
	{
		'.'
	};
	string[] array = str.Split(separator);
	uint[] array2 = new uint[array.Length];
	for (int i = 0; i < array.Length; i++)
	{
		array2[i] = (uint)int.Parse(array[i], CultureInfo.InvariantCulture);
	}

Note that the code use splits the OID string by periods, and then attempts to parse each numeric value using int.Parse. The bug is 2473183039 is a valid OID value, but it is too large for int.Parse to handle. As such, the Value was either too large or too small for an Int32. exception gets thrown.

We originally encountered bug when using PSPKI's Get-CATemplate cmdlet in an environment where AD CS assigned a template OID that caused the exception. In that case, pkix.net appears to use CryptoConfig.EncodeOID primarly for OID input validation (just making sure it's a well-formed OID). I'd suggest implementing your own function to do the validation until .NET can fix the bug upstream. Other places in the code, however, appear to use SysadminsLV.Asn1Parser.Asn1Utils.EncodeObjectIdentifier to get the OID bytes, so a replacement for CryptoConfig.EncodeOID may be needed in those instances.

Make CryptographyUtils.ConvertExtension public

Just as the title suggests, this simple yet very useful method would prevent us from converting the extensions ourselves each time we manipulate standard X509Certificate2 objects for instance.

You could also maybe extend the X509Certificate2 object with a new ResolvedExtensions ScriptProperty for instance that would automatically convert them all.

[Bug] X509CRLNumberExtension always displays 0

Hello again,

When you initialize a X509CRLNumberExtension, the CRLNumber property always displays "0" whatever the value you specified.
The RawData property is correctly set though and the issue is not present when you decode an existing CRLNumber extension from a real CRL.

Asking Help about the OCSP?

Dear PKISolutions,

Why my OCSP Server is not working it shows the INTERNAL SERVER ERROR 500? Do you have any tutorials how to configure the OCSP Server?

Best Regards,
Dara Penhchet

Issuer for the speified certificate not found.

How I bypass this exception Issuer for the speified certificate not found. when the ACRaiz isn't add globally? Because the provider, provide me this certified that's approved by ACRaiz of Country.

image

Thanks!

Values for X509ExtensionOid.CertTemplateInfoV2 and X509ExtensionOid.CertificateTemplate should be swapped.

public const String CertTemplateInfoV2 = "1.3.6.1.4.1.311.20.2";
public const String CAVersion = "1.3.6.1.4.1.311.21.1";
public const String PreviousCaHash = "1.3.6.1.4.1.311.21.2";
public const String VirtualBaseCRL = "1.3.6.1.4.1.311.21.3";
public const String NextCRLPublish = "1.3.6.1.4.1.311.21.4";
public const String CertificateTemplate = "1.3.6.1.4.1.311.21.7";

CertificateTemplate should be : 1.3.6.1.4.1.311.20.2
CertTemplateInfoV2 should be : 1.3.6.1.4.1.311.21.7

[Feature request] Implement equivalent of certreq -sign for CSRs in native code

certreq -sign allows to sign CSRs with personal certificates, allowing to use the "This number of authorized signatures" feature from the "Issuance requirements" tab of certificate templates.
It is also used for enrolment agents to sign on behalf of someone else I believe (I never used that feature though).

Having this in native code would be really helpful, especially because currently there are some things that can only be done with this command.
SignedCms never worked for me but I managed to use the X509Enrollment COM classes to sign a PKCS#10, never a PKCS#7 or CMC directly.

Note that this should work with any kind of CSP/KSP. In my environment for instance I am using a signing certificate stored on a smart card and using a 3rd party KSP (which is why SignedCms did not work if I recall correctly...).

    $csr = Get-CertificateRequest -Path $Path
    if ($csr.RequestType -eq [System.Security.Cryptography.X509CertificateRequests.X509CertificateRequestType]::PKCS10) {
        $pkcs10 = New-Object -ComObject X509Enrollment.CX509CertificateRequestPkcs10
        $pkcs10.InitializeDecode([Convert]::ToBase64String($csr.RawData), 0x1)
        $pkcs7 = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs7
        $pkcs7.InitializeFromInnerRequest($pkcs10)
        $signer = New-Object -ComObject X509Enrollment.CSignerCertificate
        $signer.Initialize(0, 0, 0xC, $cert.Thumbprint)
        $pkcs7.SignerCertificate = $signer
        $pkcs7.Encode()
        $pkcs7.RawData(0x0) | Out-File -FilePath $outFile -Force
        [void] [Runtime.InteropServices.Marshal]::ReleaseComObject($pkcs7)
        [void] [Runtime.InteropServices.Marshal]::ReleaseComObject($pkcs10)
        [void] [Runtime.InteropServices.Marshal]::ReleaseComObject($signer)
    } else {
        certreq.exe -sign -cert $cert.Thumbprint $Path $outFile
    }

PKI.OCSP.OCSPRequest class is failing on PowerShell 5

Expected behavior

Perform a OCSP request/response using PKI.OCSP.OCSPRequest class.

Actual behavior

When creating object with PKI.OCSP.OCSPRequest class, it is unable to retrieve RawData and RequestList attributes. Calling the SendRequest() method fails.

Steps to reproduce

  1. Launch PowerShell 5 on Windows 10 or Server 2012 R2
  2. Install PSPKI module 3.2.7.0
Install-Module PSPKI -Scope CurrentUser
Import-Module PSPKI
  1. Follow OCSP Client Tool guide to create OCSP challenge/response.
$cert = (Test-WebServerSSL login.live.com).Certificate
$Request = New-Object pki.ocsp.ocsprequest $cert
$Request

Version : 1
Nonce : False
NonceValue :
RequestList : {System.Security.Cryptography.X509Certificates.X500DistinguishedName}
Extensions :
URL : http://ocsp.msocsp.com/
SignerCertificate :
Proxy :
IsReadOnly : False
AcceptedSignatureAlgorithms : {sha1RSA}
RawData :

$cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2 "D:\smartcard-staging.cer"
$Request = New-Object pki.ocsp.ocsprequest $cert
$Request.RequestList

The following exception occurred while trying to enumerate the collection: "The method or operation is not implemented."

$cert = (Test-WebServerSSL login.live.com).Certificate
$Request = New-Object pki.ocsp.ocsprequest $cert
$Request.SendRequest()

Exception calling "SendRequest" with "0" argument(s): "The method or operation is not implemented."

X509CRLBuilder and NextPublish extension

I know CRL extensions modification is on your todo list but there is at least one beside CRLNumber that should be implemented in priority: NextPublish extension.
At the moment, even if we change ThisUpdate and NextUpdate, the original NextPublish extension is not modified or even settable.

I intended to use this new class to generate CRLs in the future but lack of support of the NextPublish means that those generated CRLs would have dates set in the past.
From an API perspective, just add a new NextPublish public property like for ThisUpdate and NextUpdate. If not set AND ThisUpdate/NextUpdate differ from the original CRL, I guess the best would be to remove entirely the extension if it is present.

[Feature request] Create managed classes for CertAdm.OCSPAdmin COM class

Implement CertAdm.OCSPAdmin into managed .NET code, if possible even PowerShell cmdlets in PSPKI module.

And if possible also implement methods for creating/managing an OCSP array, forcing a controller and force synchronization of its members and of revocation data.
I did not find any such method in the COM classes, only in the MMC snap-in so it would be good to have scripted way of doing it!

What I did on past projects with this COM class is the following:

  • Change OCSP audit filter
  • Create/modify several OCSP configurations for various CAs with either automatically retrieved from the CA configuration or manually entered BaseCrlUrls property, with given signing algo, signing flags, and so on...
  • Test the configurations

[Feature request] Implement a Get-RDNAttribute function/method

I think this belongs better here than in the PowerShell module.
As said in blog comment, a Get-RDNAttribute function would be helpful. I personally don't mind at all about a generator but the decoder helped me writing some custom validation code for every component of the subject name, without having to do some ugly regex parsing.

Files in network shares return "access denied"

Hello Vadims,

Seems like some of the CryptoAPI calls you are using within the library do not support UNC paths.
When I try to parse a CSR located on a file share (where my user account obviously has read access), with Get-CertificateRequest cmdlet from PSPKI for instance, I get error:
Access to the path '\\server\share\file.req' is denied.

Parsing it with certutil with the same UNC path returns the expected output.

I haven't tried with certificates or CRLs or anything else but I guess it would be exactly the same thing.

[Feature] Delete private key

In web applications, it is common when certificate is loaded from a file and is not persisted (not installed in certificate store). However, private key material is loaded into CSP and is not removed after use. There should be X509Certificate2.DeleteKey() extension method.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.