Vérifier que le système prend en charge une méthode Digest

Cette rubrique explique comment vérifier que le système prend en charge une méthode Digest.

Les signatures numériques XPS utilisent l’API Crypto qui fournit des méthodes pour vérifier que le système prend en charge une méthode Digest spécifique. Pour utiliser la fonction CryptXmlEnumAlgorithmInfo de l’API Crypto pour énumérer les méthodes Digest prises en charge par le système, l’appelant doit fournir une méthode de rappel et une structure de données. La fonction CryptXmlEnumAlgorithmInfo retransmet les données d’énumération à l’appelant à l’aide de la méthode de rappel.

La structure de données utilisée dans cet exemple est illustrée dans l’exemple de code suivant et contient les champs suivants :

Champ Description
userDigestAlgorithm Champ LPWSTR qui pointe vers la chaîne contenant l’URI de l’algorithme Digest à vérifier.
userDigestAlgorithmSupported Valeur booléenne qui indique si l’algorithme Digest est pris en charge par le certificat.

 

struct DigestMethodData
{
    LPCWSTR userDigestAlgorithm; 
    BOOL    userDigestAlgorithmSupported;
};

La méthode d’API Crypto qui énumère les méthodes Digest utilise une méthode de rappel pour renvoyer des données vers l’appelant. CryptXmlEnumAlgorithmInfo énumère les méthodes Digest prises en charge par le système et appelle la méthode de rappel pour chaque méthode Digest qu’elle énumère, jusqu’à ce que la méthode de rappel retourne FALSE ou jusqu’à ce que toutes les méthodes Digest prises en charge par le système soient énumérées. La méthode de rappel de cet exemple compare la méthode Digest transmise par CryptXmlEnumAlgorithmInfo à la méthode Digest fournie par la méthode appelante.

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’exemple de code suivant effectue une inclusion dans un wrapper de la fonctionnalité de validation dans une seule méthode qui retourne une valeur booléenne indiquant si le système prend en charge la méthode 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;
}

Étapes suivantes

Charger un certificat à partir d’un fichier

Vérifier qu’un certificat prend en charge une méthode de signature

Incorporer des chaînes de certificats dans un document

Utilisé dans cet exemple

CryptXmlEnumAlgorithmInfo

Pour plus d'informations

API Chiffrement

Fonctions de chiffrement

Erreurs de l’API Signature numérique XPS

Erreurs de document XPS

XML Paper Specification