def _advapi32_verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False):
algo = certificate_or_public_key.algorithm<EOL>if algo == '<STR_LIT>' and rsa_pss_padding:<EOL><INDENT>hash_length = {<EOL>'<STR_LIT>': <NUM_LIT:20>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT:32>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT:64><EOL>}.get(hash_algorithm, <NUM_LIT:0>)<EOL>decrypted_signature = raw_rsa_public_crypt(certificate_or_public_key, signature)<EOL>key_size = certificate_or_public_key.bit_size<EOL>if not verify_pss_padding(hash_algorithm, hash_length, key_size, data, decrypted_signature):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>return<EOL><DEDENT>if algo == '<STR_LIT>' and hash_algorithm == '<STR_LIT>':<EOL><INDENT>padded_plaintext = raw_rsa_public_crypt(certificate_or_public_key, signature)<EOL>try:<EOL><INDENT>plaintext = remove_pkcs1v15_signature_padding(certificate_or_public_key.byte_size, padded_plaintext)<EOL>if not constant_compare(plaintext, data):<EOL><INDENT>raise ValueError()<EOL><DEDENT><DEDENT>except (ValueError):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>return<EOL><DEDENT>hash_handle = None<EOL>try:<EOL><INDENT>alg_id = {<EOL>'<STR_LIT>': Advapi32Const.CALG_MD5,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA1,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_256,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_384,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_512,<EOL>}[hash_algorithm]<EOL>hash_handle_pointer = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptCreateHash(<EOL>certificate_or_public_key.context_handle,<EOL>alg_id,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>hash_handle_pointer<EOL>)<EOL>handle_error(res)<EOL>hash_handle = unwrap(hash_handle_pointer)<EOL>res = advapi32.CryptHashData(hash_handle, data, len(data), <NUM_LIT:0>)<EOL>handle_error(res)<EOL>if algo == '<STR_LIT>':<EOL><INDENT>try:<EOL><INDENT>signature = algos.DSASignature.load(signature).to_p1363()<EOL>half_len = len(signature) // <NUM_LIT:2><EOL>signature = signature[half_len:] + signature[:half_len]<EOL><DEDENT>except (ValueError, OverflowError, TypeError):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT><DEDENT>reversed_signature = signature[::-<NUM_LIT:1>]<EOL>res = advapi32.CryptVerifySignatureW(<EOL>hash_handle,<EOL>reversed_signature,<EOL>len(signature),<EOL>certificate_or_public_key.key_handle,<EOL>null(),<EOL><NUM_LIT:0><EOL>)<EOL>handle_error(res)<EOL><DEDENT>finally:<EOL><INDENT>if hash_handle:<EOL><INDENT>advapi32.CryptDestroyHash(hash_handle)<EOL><DEDENT><DEDENT>
Verifies an RSA, DSA or ECDSA signature via CryptoAPI

:param certificate_or_public_key:
    A Certificate or PublicKey instance to verify the signature with

:param signature:
    A byte string of the signature to verify

:param data:
    A byte string of the data the signature is for

:param hash_algorithm:
    A unicode string of "md5", "sha1", "sha256", "sha384", "sha512" or "raw"

:param rsa_pss_padding:
    If PSS padding should be used for RSA keys

:raises:
    oscrypto.errors.SignatureError - when the signature is determined to be invalid
    ValueError - when any of the parameters contain an invalid value
    TypeError - when any of the parameters are of the wrong type
    OSError - when an error is returned by the OS crypto library