def _verify(certificate_or_public_key, signature, data, hash_algorithm, rsa_pss_padding=False):
if not isinstance(certificate_or_public_key, (Certificate, PublicKey)):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(certificate_or_public_key)<EOL>))<EOL><DEDENT>if not isinstance(signature, byte_cls):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(signature)<EOL>))<EOL><DEDENT>if not isinstance(data, byte_cls):<EOL><INDENT>raise TypeError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>type_name(data)<EOL>))<EOL><DEDENT>valid_hash_algorithms = set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>'])<EOL>if certificate_or_public_key.algorithm == '<STR_LIT>' and not rsa_pss_padding:<EOL><INDENT>valid_hash_algorithms |= set(['<STR_LIT>'])<EOL><DEDENT>if hash_algorithm not in valid_hash_algorithms:<EOL><INDENT>valid_hash_algorithms_error = '<STR_LIT>'<EOL>if certificate_or_public_key.algorithm == '<STR_LIT>' and not rsa_pss_padding:<EOL><INDENT>valid_hash_algorithms_error += '<STR_LIT>'<EOL><DEDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>valid_hash_algorithms_error,<EOL>repr(hash_algorithm)<EOL>))<EOL><DEDENT>if certificate_or_public_key.algorithm != '<STR_LIT>' and rsa_pss_padding:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>certificate_or_public_key.algorithm.upper()<EOL>))<EOL><DEDENT>if certificate_or_public_key.algorithm == '<STR_LIT>' and hash_algorithm == '<STR_LIT>':<EOL><INDENT>if len(data) > certificate_or_public_key.byte_size - <NUM_LIT:11>:<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>certificate_or_public_key.byte_size,<EOL>len(data)<EOL>))<EOL><DEDENT>rsa = None<EOL>try:<EOL><INDENT>rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey)<EOL>if is_null(rsa):<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>)<EOL><DEDENT>buffer_size = libcrypto.EVP_PKEY_size(certificate_or_public_key.evp_pkey)<EOL>decrypted_buffer = buffer_from_bytes(buffer_size)<EOL>decrypted_length = libcrypto.RSA_public_decrypt(<EOL>len(signature),<EOL>signature,<EOL>decrypted_buffer,<EOL>rsa,<EOL>LibcryptoConst.RSA_PKCS1_PADDING<EOL>)<EOL>handle_openssl_error(decrypted_length)<EOL>decrypted_bytes = bytes_from_buffer(decrypted_buffer, decrypted_length)<EOL>if not constant_compare(data, decrypted_bytes):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>return<EOL><DEDENT>finally:<EOL><INDENT>if rsa:<EOL><INDENT>libcrypto.RSA_free(rsa)<EOL><DEDENT><DEDENT><DEDENT>evp_md_ctx = None<EOL>rsa = None<EOL>dsa = None<EOL>dsa_sig = None<EOL>ec_key = None<EOL>ecdsa_sig = None<EOL>try:<EOL><INDENT>if libcrypto_version_info < (<NUM_LIT:1>, <NUM_LIT:1>):<EOL><INDENT>evp_md_ctx = libcrypto.EVP_MD_CTX_create()<EOL><DEDENT>else:<EOL><INDENT>evp_md_ctx = libcrypto.EVP_MD_CTX_new()<EOL><DEDENT>evp_md = {<EOL>'<STR_LIT>': libcrypto.EVP_md5,<EOL>'<STR_LIT>': libcrypto.EVP_sha1,<EOL>'<STR_LIT>': libcrypto.EVP_sha224,<EOL>'<STR_LIT>': libcrypto.EVP_sha256,<EOL>'<STR_LIT>': libcrypto.EVP_sha384,<EOL>'<STR_LIT>': libcrypto.EVP_sha512<EOL>}[hash_algorithm]()<EOL>if libcrypto_version_info < (<NUM_LIT:1>,):<EOL><INDENT>if certificate_or_public_key.algorithm == '<STR_LIT>' and rsa_pss_padding:<EOL><INDENT>digest = getattr(hashlib, hash_algorithm)(data).digest()<EOL>rsa = libcrypto.EVP_PKEY_get1_RSA(certificate_or_public_key.evp_pkey)<EOL>if is_null(rsa):<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>)<EOL><DEDENT>buffer_size = libcrypto.EVP_PKEY_size(certificate_or_public_key.evp_pkey)<EOL>decoded_buffer = buffer_from_bytes(buffer_size)<EOL>decoded_length = libcrypto.RSA_public_decrypt(<EOL>len(signature),<EOL>signature,<EOL>decoded_buffer,<EOL>rsa,<EOL>LibcryptoConst.RSA_NO_PADDING<EOL>)<EOL>handle_openssl_error(decoded_length)<EOL>res = libcrypto.RSA_verify_PKCS1_PSS(<EOL>rsa,<EOL>digest,<EOL>evp_md,<EOL>decoded_buffer,<EOL>LibcryptoConst.EVP_MD_CTX_FLAG_PSS_MDLEN<EOL>)<EOL><DEDENT>elif certificate_or_public_key.algorithm == '<STR_LIT>':<EOL><INDENT>res = libcrypto.EVP_DigestInit_ex(evp_md_ctx, evp_md, null())<EOL>handle_openssl_error(res)<EOL>res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))<EOL>handle_openssl_error(res)<EOL>res = libcrypto.EVP_VerifyFinal(<EOL>evp_md_ctx,<EOL>signature,<EOL>len(signature),<EOL>certificate_or_public_key.evp_pkey<EOL>)<EOL><DEDENT>elif certificate_or_public_key.algorithm == '<STR_LIT>':<EOL><INDENT>digest = getattr(hashlib, hash_algorithm)(data).digest()<EOL>signature_buffer = buffer_from_bytes(signature)<EOL>signature_pointer = buffer_pointer(signature_buffer)<EOL>dsa_sig = libcrypto.d2i_DSA_SIG(null(), signature_pointer, len(signature))<EOL>if is_null(dsa_sig):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>dsa = libcrypto.EVP_PKEY_get1_DSA(certificate_or_public_key.evp_pkey)<EOL>if is_null(dsa):<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>)<EOL><DEDENT>res = libcrypto.DSA_do_verify(digest, len(digest), dsa_sig, dsa)<EOL><DEDENT>elif certificate_or_public_key.algorithm == '<STR_LIT>':<EOL><INDENT>digest = getattr(hashlib, hash_algorithm)(data).digest()<EOL>signature_buffer = buffer_from_bytes(signature)<EOL>signature_pointer = buffer_pointer(signature_buffer)<EOL>ecdsa_sig = libcrypto.d2i_ECDSA_SIG(null(), signature_pointer, len(signature))<EOL>if is_null(ecdsa_sig):<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>ec_key = libcrypto.EVP_PKEY_get1_EC_KEY(certificate_or_public_key.evp_pkey)<EOL>if is_null(ec_key):<EOL><INDENT>handle_openssl_error(<NUM_LIT:0>)<EOL><DEDENT>res = libcrypto.ECDSA_do_verify(digest, len(digest), ecdsa_sig, ec_key)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>evp_pkey_ctx_pointer_pointer = new(libcrypto, '<STR_LIT>')<EOL>res = libcrypto.EVP_DigestVerifyInit(<EOL>evp_md_ctx,<EOL>evp_pkey_ctx_pointer_pointer,<EOL>evp_md,<EOL>null(),<EOL>certificate_or_public_key.evp_pkey<EOL>)<EOL>handle_openssl_error(res)<EOL>evp_pkey_ctx_pointer = unwrap(evp_pkey_ctx_pointer_pointer)<EOL>if rsa_pss_padding:<EOL><INDENT>res = libcrypto.EVP_PKEY_CTX_ctrl(<EOL>evp_pkey_ctx_pointer,<EOL>LibcryptoConst.EVP_PKEY_RSA,<EOL>-<NUM_LIT:1>,  <EOL>LibcryptoConst.EVP_PKEY_CTRL_RSA_PADDING,<EOL>LibcryptoConst.RSA_PKCS1_PSS_PADDING,<EOL>null()<EOL>)<EOL>handle_openssl_error(res)<EOL>res = libcrypto.EVP_PKEY_CTX_ctrl(<EOL>evp_pkey_ctx_pointer,<EOL>LibcryptoConst.EVP_PKEY_RSA,<EOL>LibcryptoConst.EVP_PKEY_OP_SIGN | LibcryptoConst.EVP_PKEY_OP_VERIFY,<EOL>LibcryptoConst.EVP_PKEY_CTRL_RSA_PSS_SALTLEN,<EOL>-<NUM_LIT:1>,<EOL>null()<EOL>)<EOL>handle_openssl_error(res)<EOL><DEDENT>res = libcrypto.EVP_DigestUpdate(evp_md_ctx, data, len(data))<EOL>handle_openssl_error(res)<EOL>res = libcrypto.EVP_DigestVerifyFinal(evp_md_ctx, signature, len(signature))<EOL><DEDENT>if res < <NUM_LIT:1>:<EOL><INDENT>raise SignatureError('<STR_LIT>')<EOL><DEDENT>handle_openssl_error(res)<EOL><DEDENT>finally:<EOL><INDENT>if evp_md_ctx:<EOL><INDENT>if libcrypto_version_info < (<NUM_LIT:1>, <NUM_LIT:1>):<EOL><INDENT>libcrypto.EVP_MD_CTX_destroy(evp_md_ctx)<EOL><DEDENT>else:<EOL><INDENT>libcrypto.EVP_MD_CTX_free(evp_md_ctx)<EOL><DEDENT><DEDENT>if rsa:<EOL><INDENT>libcrypto.RSA_free(rsa)<EOL><DEDENT>if dsa:<EOL><INDENT>libcrypto.DSA_free(dsa)<EOL><DEDENT>if dsa_sig:<EOL><INDENT>libcrypto.DSA_SIG_free(dsa_sig)<EOL><DEDENT>if ec_key:<EOL><INDENT>libcrypto.EC_KEY_free(ec_key)<EOL><DEDENT>if ecdsa_sig:<EOL><INDENT>libcrypto.ECDSA_SIG_free(ecdsa_sig)<EOL><DEDENT><DEDENT>
Verifies an RSA, DSA or ECDSA signature

: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", "sha224", "sha256", "sha384" or "sha512"

:param rsa_pss_padding:
    If the certificate_or_public_key is an RSA key, this enables PSS padding

: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