def sign(data, pkey_buffer, pkey_pass=_ffi.NULL, digest_name="sha1"): """ Sign data with private key. Returns binary signature :param unicode data: Data to sign :param bytes pkey_buffer: Private key :param unicode pkey_pass: Private key's passphrase :param str digest_name: Message digest method :return bytes: Signature """ md = _lib.EVP_get_digestbyname(_utils.byte_string(digest_name)) if md == _ffi.NULL: raise ValueError("No such digest method: {0}".format(digest_name)) md_ctx = _ffi.new("EVP_MD_CTX *") md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup) if _lib.EVP_SignInit(md_ctx, md) != 1: _raise_current_error() if _lib.EVP_SignUpdate(md_ctx, data, len(data)) != 1: _raise_current_error() signature_buffer = _ffi.new("unsigned char []", 512) signature_length = _ffi.new("unsigned int *") signature_length[0] = len(signature_buffer) pkey = _load_private_key(pkey_buffer, pkey_pass) final_result = _lib.EVP_SignFinal(md_ctx, signature_buffer, signature_length, pkey) if final_result != 1: _raise_current_error() return _ffi.buffer(signature_buffer, signature_length[0])[:]
def get_text_digest(text, digest_name="sha1"): """ Returns binary digest value for given text. :param basestring text: Text for digest processing :param str digest_name: Digest algorithm name :return str: text digest """ evp_md = _lib.EVP_get_digestbyname(digest_name) if evp_md == _ffi.NULL: raise ValueError("No such digest method") evp_md_ctx = _lib.EVP_MD_CTX_create() if _lib.EVP_DigestInit_ex(evp_md_ctx, evp_md, _ffi.NULL) == 0: _raise_current_error() input_buffer = _utils.byte_string(text) if _lib.EVP_DigestUpdate(evp_md_ctx, input_buffer, len(input_buffer)) == 0: _raise_current_error() result_buf = _ffi.new("char[]", _lib.EVP_MAX_MD_SIZE) result_len = _ffi.new("unsigned int[]", 1) result_len[0] = len(result_buf) if _lib.EVP_DigestFinal_ex(evp_md_ctx, result_buf, result_len) == 0: _raise_current_error() _lib.EVP_MD_CTX_destroy(evp_md_ctx) return b"".join(_ffi.buffer(result_buf, result_len[0]))
def verify(data, cert_data, signature, digest_name="sha1"): """ Verifies text signature with certificate. Raises InvalidSignature in case of signature is not correct and Error if internal openssl error occurred. :param basestring data: Signed data :param basestring cert_data: Certificate :param basestring signature: Binary signature of data :param str digest_name: Digest method name :raises: ValueError, spyne_smev.crypto.InvalidSignature, spyne_smev.crypto.Error """ md = _lib.EVP_get_digestbyname(_utils.byte_string(digest_name)) if md == _ffi.NULL: raise ValueError("No such digest method") md_ctx = _ffi.new("EVP_MD_CTX*") md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup) if _lib.EVP_VerifyInit(md_ctx, md) == 0: _raise_current_error() if _lib.EVP_VerifyUpdate(md_ctx, data, len(data)) == 0: _raise_current_error() cert = _load_certificate(cert_data) pkey = _get_cert_pub_key(cert) if pkey == _ffi.NULL: _raise_current_error() pkey = _ffi.gc(pkey, _lib.EVP_PKEY_free) result = _lib.EVP_VerifyFinal(md_ctx, signature, len(signature), pkey) if result == -1: _raise_current_error() elif result == 0: raise InvalidSignature("Invalid signature")
def verify(data, cert_data, signature, digest_name="sha1"): """ Verifies text signature with certificate. Raises InvalidSignature in case of signature is not correct and Error if internal openssl error occurred. :param basestring data: Signed data :param basestring cert_data: Certificate :param basestring signature: Binary signature of data :param str digest_name: Digest method name :raises: ValueError, spyne_smev.crypto.InvalidSignature, spyne_smev.crypto.Error """ md = _lib.EVP_get_digestbyname(_utils.byte_string(digest_name)) if md == _ffi.NULL: raise ValueError("No such digest method") md_ctx = _ffi.new("EVP_MD_CTX*") md_ctx = _ffi.gc(md_ctx, _lib.EVP_MD_CTX_cleanup) if _lib.EVP_VerifyInit(md_ctx, md) == 0: _raise_current_error() if _lib.EVP_VerifyUpdate(md_ctx, data, len(data)) == 0: _raise_current_error() cert = _load_certificate(cert_data) pkey = _get_cert_pub_key(cert) if pkey == _ffi.NULL: _raise_current_error() result = _lib.EVP_VerifyFinal(md_ctx, signature, len(signature), pkey) if result == -1: _raise_current_error() elif result == 0: raise InvalidSignature("Invalid signature")