Condividi tramite


Verificare che il sistema supporti un metodo Digest

In questo argomento viene descritto come verificare che il sistema supporti un metodo digest.

Le firme digitali XPS usano l'API Crypto, che fornisce metodi per verificare che il sistema supporti un metodo digest specifico. Per usare la funzione CryptXmlEnumAlgorithmInfo dell'API Crypto per enumerare i metodi digest supportati dal sistema, il chiamante deve fornire un metodo di callback e una struttura di dati. La funzione CryptXmlEnumAlgorithmInfo passa i dati di enumerazione al chiamante tramite il metodo di callback.

La struttura dei dati usata in questo esempio è illustrata nell'esempio di codice seguente e contiene i campi seguenti:

Campo Descrizione
userDigestAlgorithm Campo LPWSTR che punta alla stringa contenente l'URI dell'algoritmo digest da controllare.
userDigestAlgorithmSupported Valore booleano che indica se l'algoritmo digest è supportato dal certificato.

 

struct DigestMethodData
{
    LPCWSTR userDigestAlgorithm; 
    BOOL    userDigestAlgorithmSupported;
};

Il metodo Crypto API che enumera i metodi digest usa un metodo di callback per restituire i dati al chiamante. CryptXmlEnumAlgorithmInfo enumera i metodi digest supportati dal sistema e chiama il metodo di callback per ogni metodo digest enumerato, fino a quando il metodo di callback non restituisce FAL edizione Standard o fino a quando non vengono enumerati tutti i metodi digest supportati dal sistema. Il metodo di callback in questo esempio confronta il metodo digest passato da CryptXmlEnumAlgorithmInfo con il metodo digest fornito dal metodo chiamante.

BOOL WINAPI 
EnumDigestMethodCallback (
    __in   const CRYPT_XML_ALGORITHM_INFO *certMethodInfo,
    __inout_opt  void                     *userArg
)
{
    // MAX_ALG_ID_LEN is used to set the maximum length of the 
    // algorithm URI in the string comparison. The URI is not 
    // likely to be longer than 128 characters so a fixed-size
    // buffer is used in this example.
    // To make this function more robust, consider
    // setting this value dynamically.
    static const  size_t MAX_ALG_ID_LEN = 128;
    DigestMethodData   *certificateAlgorithmData = 
        (DigestMethodData*)userArg;

    if (NULL != userArg) {
        // Assign user data to local data structure
        certificateAlgorithmData = (DigestMethodData*)userArg;
    } else {
        // Unable to continue this enumeration without 
        //  data from calling method.
        return FALSE;
    }
    
    // For each algorithm in the enumeration, check to see 
    //  if the URI of the current supported algorithm matches 
    //  the URI passed in userArg.
    int cmpResult = 0;
    cmpResult = wcsncmp( 
        certMethodInfo->wszAlgorithmURI, 
        certificateAlgorithmData->userDigestAlgorithm, 
        MAX_ALG_ID_LEN );

    if ( 0 == cmpResult )
    {
        // This is a match...
        //  set supported value to true
        certificateAlgorithmData->userDigestAlgorithmSupported = TRUE;
        //  ...and return FALSE to stop any further enumeration
        return FALSE;
    } 
    else
    {
        // no match was found
        // return TRUE to continue enumeration
        return TRUE;
    }
}

L'esempio di codice seguente esegue il wrapping della funzionalità di convalida in un singolo metodo, che restituisce un valore booleano che indica se il sistema supporta il metodo digest.

BOOL 
SupportsDigestAlgorithm (
    __in LPCWSTR digestMethodToCheck
)
{
    HRESULT  hr = S_OK;

    // Initialize the structure that will hold information about the 
    //  digest method to check
    DigestMethodData  certificateAlgorithmData;

    certificateAlgorithmData.userDigestAlgorithmSupported = FALSE;
    certificateAlgorithmData.userDigestAlgorithm = digestMethodToCheck;

    // Enumerate the algorithms that are supported on the system, 
    //  the callback method compares each supported algorithm to the one
    //  passed in digestMethodToCheck and returns true in the
    //  certificateAlgorithmData.userDigestAlgorithmSupported field if
    //  the provided digest algorithm is supported by system.
    //
    // Note that CRYPT_XML_GROUP_ID_HASH is set to enumerate 
    //  digest methods
    hr = CryptXmlEnumAlgorithmInfo(
        CRYPT_XML_GROUP_ID_HASH,       // NOTE: CRYPT_XML_GROUP_ID_HASH
        CRYPT_XML_FLAG_DISABLE_EXTENSIONS,
        (void*)&certificateAlgorithmData,
        EnumDigestMethodCallback);

    return certificateAlgorithmData.userDigestAlgorithmSupported;
}

Passaggi successivi

Caricare un certificato da un file

Verificare che un certificato supporti un metodo signature

Incorporare catene di certificati in un documento

Usato in questo esempio

CryptXmlEnumAlgorithmInfo

Ulteriori informazioni

API di crittografia

Funzioni di crittografia

Errori dell'API di firma digitale XPS

Errori del documento XPS

Specifica di carta XML