Update 15.03.2011: previous code sometime crashed due of StringBuilder buffer overflow. The code is updated to correctly size buffer.


I just wrote a little script that retrieves all CSPs (cryptographic service provider) that are registered on the system. It could be very useful when you are dealing with offline certificate requests via certreq.exe utility and other purposes. This script demonstrates some p/invoke techniques in Windows PowerShell. Code routine I got from corresponding CryptoAPI function MSDN pages: CryptEnumProviders and CryptEnumProviderTypes. Even though examples are in C++ it is not difficult to translate it to your .NET language (C#, PowerShell, etc). Here is a code:

function Get-CSP {
$signature = @"
[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern bool CryptEnumProviders(
    uint dwIndex,
    uint pdwReserved,
    uint dwFlags,
    ref uint pdwProvType,
    System.Text.StringBuilder pszProvName,
    ref uint pcbProvName
);
[DllImport("advapi32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern bool CryptEnumProviderTypes(
    uint dwIndex,
    uint pdwReserved,
    uint dwFlags,
    ref uint pdwProvType,
    System.Text.StringBuilder pszTypeName,
    ref uint pcbTypeName
);
"@

    Add-Type -MemberDefinition $signature -Namespace PKI -Name CSP
    $CSP = "" | select Name, Type
    $ProvTypes = @{}
#region default value definition for provider types
    [UInt32]$dwIndex = 0
    [UInt32]$pdwProvType = 0
    $pszTypeName = New-Object Text.StringBuilder
    [UInt32]$pcbTypeName = 0
#endregion

    # retrieve provider type enumeration to a hashtable
    while ([PKI.CSP]::CryptEnumProviderTypes($dwIndex,0,0,[ref]$pdwProvType,$null,[ref]$pcbTypeName)) {
        $pszTypeName.Length = $pcbTypeName
        if ([PKI.CSP]::CryptEnumProviderTypes($dwIndex++,0,0,[ref]$pdwProvType,$pszTypeName,[ref]$pcbTypeName)) {
            $Type = $pszTypeName.TosTring()
            $ProvTypes.Add($pdwProvType,$Type)
        }
    }

#region default value definition for providers
    [UInt32]$dwIndex = 0
    [UInt32]$pdwProvType = 0
    $pszProvName = New-Object Text.Stringbuilder
    [UInt32]$pcbProvName = 0
#endregion
    
    # retrieve providers
    while ([PKI.CSP]::CryptEnumProviders($dwIndex,0,0,[ref]$pdwProvType,$null,[ref]$pcbProvName)) {
        $pszProvName.Length = $pcbProvName
        if ([PKI.CSP]::CryptEnumProviders($dwIndex++,0,0,[ref]$pdwProvType,$pszProvName,[ref]$pcbProvName)) {
            $CSP.Name = $pszProvName.ToString()
            $CSP.Type = $ProvTypes[$pdwProvType]
            $CSP
        }
    }
}

and code output:

[↓] [vPodans] Get-CSP

Name                                                        Type
----                                                        ----
eToken Base Cryptographic Provider                          RSA Full (Signature and Key Exchange)
Microsoft Base Cryptographic Provider v1.0                  RSA Full (Signature and Key Exchange)
Microsoft Base DSS and Diffie-Hellman Cryptographic Prov... DSS Signature with Diffie-Hellman Key Exchange
Microsoft Base DSS Cryptographic Provider                   DSS Signature
Microsoft Base Smart Card Crypto Provider                   RSA Full (Signature and Key Exchange)
Microsoft DH SChannel Cryptographic Provider                Diffie-Hellman SChannel
Microsoft Enhanced Cryptographic Provider v1.0              RSA Full (Signature and Key Exchange)
Microsoft Enhanced DSS and Diffie-Hellman Cryptographic ... DSS Signature with Diffie-Hellman Key Exchange
Microsoft Enhanced RSA and AES Cryptographic Provider       RSA Full and AES
Microsoft RSA SChannel Cryptographic Provider               RSA SChannel
Microsoft Strong Cryptographic Provider                     RSA Full (Signature and Key Exchange)


[↓] [vPodans]

Share this article:

Comments:


Post your comment:

Please, solve this little equation and enter result below. Captcha