Exemplo de programa C: enumerando provedores CSP e tipos de provedor

O exemplo a seguir lista os CSPs disponíveis em um computador e usa as seguintes funções cryptoAPI :

Este exemplo usa a função MyHandleError. O código dessa função está incluído neste exemplo. O código para essa e outras funções auxiliares também está listado em Uso Geral Functions.

O exemplo a seguir mostra a enumeração de CSPs e tipos de provedor.

//-------------------------------------------------------------------
// Copyright (C) Microsoft.  All rights reserved.
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "crypt32.lib")

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <wincrypt.h>

void MyHandleError(TCHAR* s);
void Wait(TCHAR* s);

int _tmain(int argc, _TCHAR* argv[])
{
    // Declare and initialize variables.
    HCRYPTPROV hProv;
    LPTSTR pszName;
    DWORD dwType;
    DWORD cbName;
    DWORD dwIndex = 0;
    BYTE* ptr;
    ALG_ID aiAlgid;
    DWORD dwBits;
    DWORD dwNameLen;
    CHAR szName[100];
    BYTE pbData[1024];
    DWORD cbData = 1024;
    DWORD dwIncrement = sizeof(DWORD);
    DWORD dwFlags = CRYPT_FIRST;
    DWORD dwParam = PP_CLIENT_HWND;
    CHAR* pszAlgType = NULL;
    BOOL fMore = TRUE;
    LPTSTR pbProvName;
    DWORD cbProvName;

    //--------------------------------------------------------------
    // Print header lines for provider types.
    _tprintf(TEXT("Listing Available Provider Types.\n"));
    _tprintf(TEXT("Provider type    Provider Type Name\n"));
    _tprintf(TEXT("_____________    ")
        TEXT("_____________________________________\n"));

    // Loop through enumerating provider types.
    dwIndex = 0;
    while(CryptEnumProviderTypes(
        dwIndex,
        NULL,
        0,
        &dwType,
        NULL,
        &cbName))
    {
        //-----------------------------------------------------------
        // cbName is the length of the name of the next provider 
        // type.

        // Allocate memory in a buffer to retrieve that name.
        if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
        {
           MyHandleError(TEXT("ERROR - LocalAlloc failed!"));
        }

        //-----------------------------------------------------------
        // Get the provider type name.
        if (CryptEnumProviderTypes(
            dwIndex++,
            NULL,
            NULL,
            &dwType,   
            pszName,
            &cbName))     
        {
            _tprintf (TEXT("     %4.0d        %s\n"), 
                dwType, 
                pszName);
        }
        else
        {
            MyHandleError(TEXT("ERROR - CryptEnumProviders"));
        }

        LocalFree(pszName);
    }

    //--------------------------------------------------------------
    // Print header lines for providers.
    _tprintf(TEXT("\n\nListing Available Providers.\n"));
    _tprintf(TEXT("Provider type    Provider Name\n"));
    _tprintf(TEXT("_____________    ")
        TEXT("_____________________________________\n"));

    //---------------------------------------------------------------
    // Loop through enumerating providers.
    dwIndex = 0;
    while(CryptEnumProviders(
        dwIndex,
        NULL,
        0,
        &dwType,
        NULL,
        &cbName))
    {
        //-----------------------------------------------------------
        // cbName is the length of the name of the next provider.
        // Allocate memory in a buffer to retrieve that name.
        if (!(pszName = (LPTSTR)LocalAlloc(LMEM_ZEROINIT, cbName)))
        {
           MyHandleError(TEXT("ERROR - LocalAlloc failed!"));
        }

        //-----------------------------------------------------------
        // Get the provider name.
        if (CryptEnumProviders(
            dwIndex++,
            NULL,
            0,
            &dwType,
            pszName,
            &cbName))
        {
            _tprintf (TEXT("     %4.0d        %s\n"), 
                dwType, 
                pszName);
        }
        else
        {
            MyHandleError(TEXT("ERROR - CryptEnumProviders"));
        }

        LocalFree(pszName);
    } // End while loop.

    //---------------------------------------------------------------
    // Get the name of the default CSP specified for the 
    // PROV_RSA_FULL type for the computer.

    //---------------------------------------------------------------
    // Get the length of the RSA_FULL default provider name.
    if (!(CryptGetDefaultProvider(
        PROV_RSA_FULL, 
        NULL, 
        CRYPT_MACHINE_DEFAULT,
        NULL, 
        &cbProvName))) 
    { 
       MyHandleError(TEXT("Error getting the length of the ")
           TEXT("default provider name."));
    }

    //---------------------------------------------------------------
    // Allocate local memory for the name of the default provider.
    if (!(pbProvName = (LPTSTR)LocalAlloc(
        LMEM_ZEROINIT, 
        cbProvName)))
    {
        MyHandleError(TEXT("Error during memory allocation ")
            TEXT("for provider name."));
    }

    //---------------------------------------------------------------
    // Get the name of the default PROV_RSA_FULL provider.
    if (CryptGetDefaultProvider(
        PROV_RSA_FULL, 
        NULL, 
        CRYPT_MACHINE_DEFAULT,
        pbProvName,
        &cbProvName)) 
    {
        _tprintf(TEXT("\nThe default provider name is \"%s\"\n"), 
            pbProvName);
    }
    else
    {
        MyHandleError(TEXT("Getting the provider name failed."));
    }

    LocalFree(pbProvName);

    //-----------------------------------------------------
    //  Acquire a cryptographic context.
    if(!CryptAcquireContext(
        &hProv, 
        NULL,
        NULL,
        PROV_RSA_FULL, 
        NULL))  
    {
        MyHandleError(TEXT("Error during CryptAcquireContext!"));
    }

    //------------------------------------------------------
    // Enumerate the supported algorithms.

    //------------------------------------------------------
    // Print header for algorithm information table.
    _tprintf(TEXT("\nEnumerating the supported ")
        TEXT("algorithms\n\n"));
    _tprintf(TEXT("     Algid      Bits      Type        ")
        TEXT("Name         Algorithm\n"));
    _tprintf(TEXT("                                     Length")
        TEXT("          Name\n"));
    _tprintf(TEXT("    _______________________________________")
        TEXT("_________________\n"));
    while(fMore)
    {
        //------------------------------------------------------
        // Retrieve information about an algorithm.
        if(CryptGetProvParam(
            hProv, 
            PP_ENUMALGS, 
            pbData, 
            &cbData, 
            dwFlags))
        {       
            //-------------------------------------------------------
            // Extract algorithm information from the pbData buffer.
           dwFlags = 0;
           ptr = pbData;
           aiAlgid = *(ALG_ID *)ptr;
           ptr += sizeof(ALG_ID);
           dwBits = *(DWORD *)ptr;
           ptr += dwIncrement;
           dwNameLen = *(DWORD *)ptr;
           ptr += dwIncrement;
           strncpy_s(szName, sizeof(szName), (char *) ptr, dwNameLen);
           
            //-------------------------------------------------------
            // Determine the algorithm type.
           switch(GET_ALG_CLASS(aiAlgid)) 
           {
           case ALG_CLASS_DATA_ENCRYPT: 
               pszAlgType = "Encrypt  ";
               break;
            
            case ALG_CLASS_HASH:         
                pszAlgType = "Hash     ";
                break;

            case ALG_CLASS_KEY_EXCHANGE: 
                pszAlgType = "Exchange ";
                break;

            case ALG_CLASS_SIGNATURE:    
                pszAlgType = "Signature";
                break;

            default:
                pszAlgType = "Unknown  ";
                break;
           }

           //--------------------------------------------------------
            // Print information about the algorithm.
            printf("    %8.8xh    %-4d    %s     %-2d          %s\n",
                aiAlgid, 
                dwBits, 
                pszAlgType, 
                dwNameLen, 
                szName);
        }
        else
        {
            fMore = FALSE;
        }
    }

    Wait(TEXT("\nPress Enter to continue."));

    if(!(CryptReleaseContext(hProv, 0)))
    {
        MyHandleError(TEXT("Error during CryptReleaseContext.")); 
    }

    if(GetLastError() == ERROR_NO_MORE_ITEMS)
    { 
       _tprintf(TEXT("\nThe program completed without error.\n"));
    }
    else
    { 
       MyHandleError(TEXT("Error reading algorithm!"));
    }

} // End main.

//-------------------------------------------------------------------
//  This example uses the function MyHandleError, a simple error
//  handling function, to print an error message and exit 
//  the program. 
//  For most applications, replace this function with one 
//  that does more extensive error reporting.

void MyHandleError(TCHAR *s)
{
    _tprintf(TEXT("An error occurred in running the program.\n"));
    _tprintf(TEXT("%s\n"),s);
    _tprintf(TEXT("Error number %x\n."), GetLastError());
    _tprintf(TEXT("Program terminating.\n"));
    exit(1);
}

void Wait(TCHAR *s)
{
    char x;
    _tprintf(s);
    x = getchar();
}