Source code for glideinwms.lib.hashCrypto
# SPDX-FileCopyrightText: 2009 Fermi Research Alliance, LLC
# SPDX-License-Identifier: Apache-2.0
# Project:
# glideinWMS
#
# File Version:
#
"""hashCrypto - This module defines classes to perform hash based cryptography
It uses M2Crypto: https://github.com/mcepl/M2Crypto
a wrapper around OpenSSL: https://www.openssl.org/docs/man1.1.1/man3/
NOTE get_hash() and extract_hash() both return Unicode utf-8 (defaults.BINARY_ENCODING_CRYPTO) strings and
get_hash() accepts byte-like objects or utf-8 encoded Unicode strings.
Same for all the get_XXX or extract_XXX that use those functions.
Other class methods and functions use bytes for input and output
"""
# TODO: should this module be replaced (or reimplemented) by using Python's hashlib?
import binascii
import M2Crypto.EVP
from . import defaults
######################
#
# Available hash algos:
# 'sha1'
# 'sha224'
# 'sha256',
# 'ripemd160'
# 'md5'
#
######################
##########################################################################
# Generic hash class
[docs]
class Hash:
"""Generic hash class
Available hash algorithms:
'sha1'
'sha224'
'sha256',
'ripemd160'
'md5'
"""
def __init__(self, hash_algo):
self.hash_algo = hash_algo
return
[docs]
def redefine(self, hash_algo):
self.hash_algo = hash_algo
return
###########################################
# compute hash inline
[docs]
def compute(self, data):
"""Compute hash inline
len(data) must be less than len(key)
Args:
data (bytes): data to calculate the hash of
Returns:
bytes: digest value as bytes string (OpenSSL final and digest together)
"""
h = M2Crypto.EVP.MessageDigest(self.hash_algo)
h.update(data)
return h.final()
[docs]
def compute_base64(self, data):
"""like compute, but base64 encoded"""
return binascii.b2a_base64(self.compute(data))
[docs]
def compute_hex(self, data):
"""like compute, but hex encoded"""
return binascii.b2a_hex(self.compute(data))
###########################################
# extract hash from a file
#########################################
[docs]
def get_hash(hash_algo, data):
"""Compute hash inline
Args:
hash_algo (str): hash algorithm to use
data (AnyStr): data of which to calculate the hash
Returns:
str: utf-8 encoded hash
"""
# Check to see if the data is already in bytes
bdata = defaults.force_bytes(data)
h = Hash(hash_algo)
return h.compute_hex(bdata).decode(defaults.BINARY_ENCODING_CRYPTO)
##########################################################################
# Explicit hash algo section
[docs]
class HashMD5(Hash):
def __init__(self):
Hash.__init__(self, "md5")
[docs]
def get_md5(data):
return get_hash("md5", data)
[docs]
class HashSHA1(Hash):
def __init__(self):
Hash.__init__(self, "sha1")
[docs]
def get_sha1(data):
return get_hash("sha1", data)
[docs]
class HashSHA256(Hash):
def __init__(self):
Hash.__init__(self, "sha256")
[docs]
def get_sha256(data):
return get_hash("sha256", data)