<commit_before>"""
This module contains several utility functions regarding certificate and key
handling.
"""
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.serialization import load_pem_public_key, Encoding, PublicFormat
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature

def sha256(data):
    """
    Hashes the given data using SHA256.
    :param data: The data to be hashed as a byte list.
    :return: The hashed data as a byte list.
    """
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(data)
    return digest.finalize()

def aes256ctr(iv, key, data):
    """
    Encrypts the given data using AES-256 in CTR mode with the given IV and key.
    Can also be used for decryption due to how the CTR mode works.
    :param iv: The IV as a byte list.
    :param key: The key as a byte list.
    :param data: The data to be encrypted as a byte list.
    :return: The encrypted data as a byte list.
    """
    cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend = default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(data) + encryptor.finalize()

def loadCert(pem):
    """
    Creates a cryptography certificate object from the given PEM certificate.
    :param pem: A certificate as a PEM string.
    :return: A cryptography certificate object.
    """
    return x509.load_pem_x509_certificate(pem.encode("utf-8"), default_backend())

def loadPubKey(pem):
    """
    Creates a cryptography public key object from the given PEM public key.
    :param pem: A public key as a PEM string.
    :return: A cryptography public key object.
    """
    return load_pem_public_key(pem.encode("utf-8"), default_backend())

def exportCertToPEM(cert):
    """
    Converts a cryptography certificate object to a one-line PEM string without
    header and footer (i.e. the \"-----...\" lines).
    :param cert: The certificate object.
    :return: A string containing the PEM certificate.
    """
    pem = cert.public_bytes(Encoding.PEM).decode("utf-8").splitlines()[1:-1]
    return ''.join(pem)

def exportKeyToPEM(key):
    """
    Converts a cryptography public key object to a one-line PEM string without
    header and footer (i.e. the \"-----...\" lines).
    :param key: The public key object.
    :return: A string containing the PEM public key.
    """
    pem = key.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo
            ).decode("utf-8").splitlines()[1:-1]
    return ''.join(pem)

def addPEMCertHeaders(cert):
    """
    Adds a certificate header and footer to a PEM certificate string.
    :param cert: The PEM certificate string.
    :return: The PEM certificate string with header and footer.
    """
    return '-----BEGIN CERTIFICATE-----\n' + cert + '\n-----END CERTIFICATE-----'

def addPEMPubKeyHeaders(pubKey):
    """
    Adds a public key header and footer to a PEM public key string.
    :param pubKey: The PEM public key string.
    :return: The PEM public key string with header and footer.
    """
    return '-----BEGIN PUBLIC KEY-----\n' + pubKey + '\n-----END PUBLIC KEY-----'

def verifyCert(cert, signCert):
    """
    Verifies that a certificate has been signed with another. Note that this
    function only verifies the cryptographic signature and is probably wrong and
    dangerous. Do not use it to verify certificates. This function only supports
    ECDSA signatures, all other signature types will fail.
    :param cert: The certificate whose signature we want to verify as a
    cryptography certificate object.
    :param signCert: The certificate that was used to sign the first certificate
    as a cryptography certificate object.
    :return: True if the signature is a valid ECDSA signature, False otherwise.<commit_msg>Convert pubkeys and certs to PEM properly<commit_after>"""
This module contains several utility functions regarding certificate and key
handling.
"""
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.serialization import load_pem_public_key, Encoding, PublicFormat
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature

def sha256(data):
    """
    Hashes the given data using SHA256.
    :param data: The data to be hashed as a byte list.
    :return: The hashed data as a byte list.
    """
    digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
    digest.update(data)
    return digest.finalize()

def aes256ctr(iv, key, data):
    """
    Encrypts the given data using AES-256 in CTR mode with the given IV and key.
    Can also be used for decryption due to how the CTR mode works.
    :param iv: The IV as a byte list.
    :param key: The key as a byte list.
    :param data: The data to be encrypted as a byte list.
    :return: The encrypted data as a byte list.
    """
    cipher = Cipher(algorithms.AES(key), modes.CTR(iv), backend = default_backend())
    encryptor = cipher.encryptor()
    return encryptor.update(data) + encryptor.finalize()

def loadCert(pem):
    """
    Creates a cryptography certificate object from the given PEM certificate.
    :param pem: A certificate as a PEM string.
    :return: A cryptography certificate object.
    """
    return x509.load_pem_x509_certificate(pem.encode("utf-8"), default_backend())

def loadPubKey(pem):
    """
    Creates a cryptography public key object from the given PEM public key.
    :param pem: A public key as a PEM string.
    :return: A cryptography public key object.
    """
    return load_pem_public_key(pem.encode("utf-8"), default_backend())

def exportCertToPEM(cert):
    """
    Converts a cryptography certificate object to a one-line PEM string without
    header and footer (i.e. the \"-----...\" lines).
    :param cert: The certificate object.
    :return: A string containing the PEM certificate.
    """
    pem = cert.public_bytes(Encoding.PEM).decode("utf-8").splitlines()[1:-1]
    return ''.join(pem)

def exportKeyToPEM(key):
    """
    Converts a cryptography public key object to a one-line PEM string without
    header and footer (i.e. the \"-----...\" lines).
    :param key: The public key object.
    :return: A string containing the PEM public key.
    """
    pem = key.public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo
            ).decode("utf-8").splitlines()[1:-1]
    return ''.join(pem)

def addPEMCertHeaders(cert):
    """
    Adds a certificate header and footer to a PEM certificate string.
    :param cert: The PEM certificate string.
    :return: The PEM certificate string with header and footer.
    """
    return '-----BEGIN CERTIFICATE-----\n' + '\n'.join(
            [cert[i:i+64] for i in range(0, len(cert), 64)]
            ) + '\n-----END CERTIFICATE-----'

def addPEMPubKeyHeaders(pubKey):
    """
    Adds a public key header and footer to a PEM public key string.
    :param pubKey: The PEM public key string.
    :return: The PEM public key string with header and footer.
    """
    return '-----BEGIN PUBLIC KEY-----\n' + '\n'.join(
            [pubKey[i:i+64] for i in range(0, len(pubKey), 64)]
            ) + '\n-----END PUBLIC KEY-----'

def verifyCert(cert, signCert):
    """
    Verifies that a certificate has been signed with another. Note that this
    function only verifies the cryptographic signature and is probably wrong and
    dangerous. Do not use it to verify certificates. This function only supports
    ECDSA signatures, all other signature types will fail.
    :param cert: The certificate whose signature we want to verify as a
    cryptography certificate object.
    :param signCert: The certificate that was used to sign the first certificate
    as a cryptography certificate object.
    :return: True if the signature is a valid ECDSA signature, False otherwise.
{'fraction_non_alphanumeric': 0.09934418265727471, 'fraction_numerical': 0.008987126548457614, 'mean_word_length': 3.2602172788411794, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2663462', 'n_tokens_mistral': 2450, 'n_tokens_neox': 2347, 'n_words': 925}