Verificare che un certificato supporti un metodo signature
In questo argomento viene descritto come verificare che un certificato supporti un metodo di firma specifico.
CryptXmlEnumAlgorithmInfo nell'API Di crittografia Microsoft enumera le proprietà di un certificato e viene usato in questo esempio di codice per enumerare i metodi di firma supportati dal certificato. Per utilizzare CryptXmlEnumAlgorithmInfo per enumerare i metodi di firma supportati dal certificato, il chiamante deve fornire un metodo di callback e una struttura di dati nella chiamata a CryptXmlEnumAlgorithmInfo, consentendo al chiamante di passare i dati al metodo di callback.
La struttura dei dati usata nell'esempio di codice successivo include i campi seguenti:
Campo | Descrizione |
---|---|
userSignatureAlgorithmToCheck | Campo LPWSTR che punta alla stringa contenente l'URI dell'algoritmo di firma da controllare. |
certificateAlgorithmInfo | Puntatore a una struttura CRYPT_OID_INFO che contiene informazioni su un algoritmo di firma supportato dal certificato. |
userSignatureAlgorithmSupported | Valore booleano che indica se l'algoritmo di firma è supportato dal certificato. |
struct SignatureMethodData
{
LPCWSTR userSignatureAlgorithmToCheck;
PCCRYPT_OID_INFO certificateAlgorithmInfo;
BOOL userSignatureAlgorithmSupported;
};
Il metodo crypto API che controlla il certificato usa un metodo di callback per restituire i dati al chiamante. CryptXmlEnumAlgorithmInfo enumera i metodi di firma supportati dal certificato e chiama il metodo di callback per ogni metodo di firma fino a quando il metodo di callback non restituisce FAL edizione Standard o fino a quando non vengono enumerati tutti i metodi di firma nel certificato.
Il metodo di callback nell'esempio di codice successivo cerca un metodo di firma passato da CryptXmlEnumAlgorithmInfo che corrisponde al metodo di firma fornito dal metodo chiamante. Quando viene trovata una corrispondenza, il metodo di callback controlla se il metodo di firma è supportato anche dal sistema. Se i metodi di firma corrispondono e sono supportati dal sistema, il metodo di firma viene contrassegnato come supportato dal sistema e il metodo di callback restituisce FAL edizione Standard.
BOOL WINAPI
EnumSignatureMethodCallback (
__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, you might consider
// setting this value dynamically.
static const size_t MAX_ALG_ID_LEN = 128;
SignatureMethodData *certificateAlgorithmData = NULL;
if (NULL != userArg) {
// Assign user data to local data structure
certificateAlgorithmData = (SignatureMethodData*)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 algorithm supported by the certificate matches the URI
// of the algorithm being tested.
int cmpResult = 0;
cmpResult = wcsncmp(
certMethodInfo->wszAlgorithmURI,
certificateAlgorithmData->userSignatureAlgorithmToCheck,
MAX_ALG_ID_LEN );
if ( 0 == cmpResult )
{
// This is a match...
// Check to see if the algorithm supported by the
// certificate matches any of the supported algorithms
// on the system.
cmpResult = wcsncmp(
certMethodInfo->wszCNGExtraAlgid,
certificateAlgorithmData->certificateAlgorithmInfo->pwszCNGAlgid,
MAX_ALG_ID_LEN );
if ( 0 == cmpResult )
{
// This is also a match so set the field in the data structure
// provided by the calling method.
certificateAlgorithmData->userSignatureAlgorithmSupported = TRUE;
// A match was found so there is no point in continuing
// the enumeration.
return FALSE;
}
}
// The enumeration stops when the callback method returns FALSE.
// If here, then return TRUE because a matching algorithm has
// not been found.
return TRUE;
}
Nell'esempio di codice seguente viene eseguito il wrapping della funzionalità di convalida in un singolo metodo. Questo metodo restituisce un valore booleano che indica se il certificato supporta il metodo di firma e se il metodo di firma è supportato dal sistema.
BOOL
SupportsSignatureAlgorithm (
__in LPCWSTR signingMethodToCheck,
__in PCCERT_CONTEXT certificateToCheck
)
{
HRESULT hr = S_OK;
// Initialize the structure that contains the
// information about the signature algorithm to check
SignatureMethodData certificateAlgorithmData;
certificateAlgorithmData.userSignatureAlgorithmSupported =
FALSE;
certificateAlgorithmData.userSignatureAlgorithmToCheck =
signingMethodToCheck;
// Call the crypt API to get information about the algorithms
// that are supported by the certificate and initialize
// certificateAlgorithmData
certificateAlgorithmData.certificateAlgorithmInfo = CryptFindOIDInfo (
CRYPT_OID_INFO_OID_KEY,
certificateToCheck->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId,
CRYPT_PUBKEY_ALG_OID_GROUP_ID | CRYPT_OID_PREFER_CNG_ALGID_FLAG);
if (certificateAlgorithmData.certificateAlgorithmInfo != NULL)
{
// Enumerate the algorithms that are supported by the
// certificate, and use our callback method to determine if
// the user supplied signature algorithm is supported by
// the certificate.
//
// Note that CRYPT_XML_GROUP_ID_SIGN is used to enumerate
// the signature methods
hr = CryptXmlEnumAlgorithmInfo(
CRYPT_XML_GROUP_ID_SIGN, // NOTE: CRYPT_XML_GROUP_ID_SIGN
CRYPT_XML_FLAG_DISABLE_EXTENSIONS,
(void*)&certificateAlgorithmData,
EnumSignatureMethodCallback);
// when the enumeration has returned successfully,
// certificateAlgorithmData.userSignatureAlgorithmSupported
// will be TRUE if the signing method is supported by
// the certificate
}
return certificateAlgorithmData.userSignatureAlgorithmSupported;
}
Argomenti correlati
-
Passaggi successivi
-
Usato in questo esempio
-
CryptXmlEnumAlgorithmInfo
-
Ulteriori informazioni