def encrypt(self, message, key, iv, aad): """ Function to encrypt binary with a CCM 128 bit cipher. input: binary_blob: Binary blob to encrypt hex_preexisting_128_bit_key: hex representarion of 128bit key | None, if None, the key is generated hex_preexisting_iv: hex representarion of image IV | None, if None, the IV is generated hex_preexisting_aad: hex representation of Additional Authentication data needed by the algorithm output: (encrypted_binary, encryption_key, image_iv, hex_preexisting_aad): Tuple with the encrypted binary, the key, the IV, and the AAD """ message_path, encrypted_message_path = None, None try: message_path = c_path.create_tmp_file(message) encrypted_message_path = c_path.create_tmp_file() cmd = [ self.crypto_cbc, '--operation=encrypt', '--input-file', message_path, '--output', encrypted_message_path, '--key', key, '--iv', iv, '--aad', aad ] run_command(cmd) return c_path.load_data_from_file(encrypted_message_path) finally: if message_path is not None: c_path.remove_tmp_file(message_path) if encrypted_message_path is not None: c_path.remove_tmp_file(encrypted_message_path)
def decrypt(self, message, key, iv, aad): """ Function to decrypt a CCM encrypted binary. input: encrypted_blob: Encrypted Binary blob to decrypt hex_preexisting_128_bit_key: hex representarion of 128bit key hex_preexisting_iv: hex representarion of image IV hex_preexisting_aad: hex representation of Additional Authentication data needed by the algorithm output: plaintext_binary: Decrypted plaintext binary """ message_path, decrypted_message_path = None, None try: message_path = c_path.create_tmp_file(message) decrypted_message_path = c_path.create_tmp_file() cmd = [ self.crypto_ccm, '--operation=decrypt', '--input-file', message_path, '--output', decrypted_message_path, '--key', key, '--iv', iv, '--aad', aad ] run_command(cmd) return c_path.load_data_from_file(decrypted_message_path) finally: if message_path is not None: c_path.remove_tmp_file(message_path) if decrypted_message_path is not None: c_path.remove_tmp_file(decrypted_message_path)
def decrypt(self, message, key, iv): """ Function to decrypt a CBC encrypted binary. input: encrypted_blob: Encrypted Binary blob to decrypt hex_preexisting_128_bit_key: hex representation of 128bit key hex_preexisting_iv: hex representation of image IV output: plaintext_binary: Decrypted plaintext binary """ message_path, decrypted_message_path = None, None try: message_path = c_path.create_tmp_file(message) decrypted_message_path = c_path.create_tmp_file() cmd = [ self.openssl, 'enc', '-aes-128-cbc', '-d', '-in', message_path, '-out', decrypted_message_path, '-K', key, '-iv', iv, '-nopad' ] run_command(cmd) return c_path.load_data_from_file(decrypted_message_path) finally: if message_path is not None: c_path.remove_tmp_file(message_path) if decrypted_message_path is not None: c_path.remove_tmp_file(decrypted_message_path)
def encrypt(self, message, key, iv): """ Function to encrypt binary with a CBC 128 bit cipher. input: binary_blob: Binary blob to encrypt hex_preexisting_128_bit_key: hex representation of 128bit key | None, if None, the key is generated hex_preexisting_iv: hex representation of image IV | None, if None, the IV is generated output: (encrypted_binary, encryption_key, image_iv): Tuple with the encrypted binary, the key, and the IV """ message_path, encrypted_message_path = None, None try: message_path = c_path.create_tmp_file(message) encrypted_message_path = c_path.create_tmp_file() cmd = [ self.openssl, 'enc', '-aes-128-cbc', '-in', message_path, '-out', encrypted_message_path, '-K', key, '-iv', iv, '-nopad' ] run_command(cmd) return c_path.load_data_from_file(encrypted_message_path) finally: if message_path is not None: c_path.remove_tmp_file(message_path) if encrypted_message_path is not None: c_path.remove_tmp_file(encrypted_message_path)
def verify(self, message, key, signature): """ Decrypt and verify an encrypted message using a public key and signature :param message: message to verify :param key: public key :param signature: signature :return verified: boolean outcome of verification :rtype: bool """ signature = EcdsaOpenSSLImpl.strip_sig_padding(signature) expected_retcode = 1 message_path = c_path.create_tmp_file(message) key_path = c_path.create_tmp_file(key) signature_path = c_path.create_tmp_file(signature) cmd = ([ self.openssl, OPENSSL_PKEYUTL_MODE, '-verify', '-pubin', '-inkey', key_path, '-sigfile', signature_path, '-in', message_path ]) try: output = run_command(cmd, expected_retcode) if output.strip() == 'Signature Verified Successfully': return True else: return False finally: c_path.remove_tmp_file(message_path) c_path.remove_tmp_file(key_path) c_path.remove_tmp_file(signature_path)
def validate_cert_chain(self, root_cert, ca_cert_chain): """ Verify the certificate chain to be valid input: certificate_chain: [cert1,cert2,cert3] List of certificates (*in PEM FORMAT*) in the certificate chain. It assumes that the last certificate is the Root CA certificate. output: [True|False] Boolean value """ ca_cert_chain_path, root_cert_path = None, None try: ca_cert_chain_path = c_path.create_tmp_file(ca_cert_chain) root_cert_path = c_path.create_tmp_file(root_cert) cmd = [ self.openssl, 'verify', '-CAfile', ca_cert_chain_path, root_cert_path ] validity = run_command(cmd).rstrip() return validity == (root_cert_path + ': OK') finally: if ca_cert_chain_path is not None: c_path.remove_tmp_file(ca_cert_chain_path) if root_cert_path is not None: c_path.remove_tmp_file(root_cert_path)
def create_cert(self, priv_key, subject_params=None, config=None, hash_algo=CertBase.HASH_ALGO_SHA256, self_sign=False, days=None, serial=None, padding=CertBase.PAD_PKCS, pad_hash_algo=CertBase.HASH_ALGO_SHA256, pad_salt_len=CertBase.PAD_PSS_SALT_1): """ Create a self signed certificate input: subject_params = { 'C' : "US", 'ST' : "California", 'L' : "San Diego", 'O' : "ASIC", 'CN' : "Qualcomm", } Dictionary of parameters to put in the certificate. The parameters above are an example days = validity period of certificate in days configfile = configfile used by openssl serial_num = Serial number of certificate padding = Type of padding output: certificate: String representation of PEM certificate. """ priv_path = c_path.create_tmp_file(priv_key) try: cmd = [self.openssl, 'req', '-new', '-key', priv_path] if subject_params is not None: subject = self.get_subject_from_params(subject_params) cmd += ['-subj', subject] if config is not None: cmd += ['-config', config] if hash_algo is not None: cmd += ['-' + hash_algo] if self_sign: cmd += ['-x509'] if padding == self.PAD_PSS: cmd += [ '-sigopt', 'rsa_padding_mode:pss', '-sigopt', 'rsa_pss_saltlen:' + pad_salt_len, '-sigopt', 'digest:' + pad_hash_algo ] if serial is not None: cmd += ['-set_serial', str(serial)] if days is not None: cmd += ['-days', str(days)] return run_command(cmd) finally: c_path.remove_tmp_file(priv_path)
def _pkeyutl(self, message, key, preopts, options, expected_retcode=0): message_path = c_path.create_tmp_file(message) key_path = c_path.create_tmp_file(key) cmd = ([self.openssl, OPENSSL_PKEYUTL_MODE] + preopts + ['-inkey', key_path, '-in', message_path] + options) try: return run_command(cmd, expected_retcode) finally: c_path.remove_tmp_file(message_path) c_path.remove_tmp_file(key_path)
def get_pubkey_from_cert(self, cert, inform, text_output=False): inform_opt = self._get_format_opt(inform) cert_path, pub_path = None, None try: cert_path = c_path.create_tmp_file(cert) cmd = [ self.openssl, OPENSSL_CERT_MODE, '-pubkey', '-noout', '-in', cert_path, '-inform', inform_opt ] pub_key = run_command(cmd) if text_output: pub_path = c_path.create_tmp_file(pub_key) cmd = [ self.openssl, 'rsa', '-pubin', '-text', '-noout' '-in', cert_path, '-inform', inform_opt ] pub_key = run_command(cmd) finally: if cert_path is not None: c_path.remove_tmp_file(cert_path) if pub_path is not None: c_path.remove_tmp_file(pub_path) return pub_key
def sign_cert(self, cert, ca_cert, ca_priv_key, days=None, serial=None, hash_algo=CertBase.HASH_ALGO_SHA256, extfile=None, padding=CertBase.PAD_PKCS, pad_hash_algo=CertBase.HASH_ALGO_SHA256, pad_salt_len=CertBase.PAD_PSS_SALT_1): cert_path, ca_cert_path, ca_priv_path = None, None, None try: cert_path = c_path.create_tmp_file(cert) ca_cert_path = c_path.create_tmp_file(ca_cert) ca_priv_path = c_path.create_tmp_file(ca_priv_key) cmd = [ self.openssl, 'x509', '-req', '-in', cert_path, '-CA', ca_cert_path, '-CAkey', ca_priv_path, ] if serial is not None: cmd += ['-set_serial', str(serial)] else: cmd += ['-CAcreateserial'] if hash_algo is not None: cmd += ['-' + hash_algo] if days is not None: cmd += ['-days', str(days)] if extfile is not None: cmd += ['-extfile', extfile] if padding == self.PAD_PSS: cmd += [ '-sigopt', 'rsa_padding_mode:pss', '-sigopt', 'rsa_pss_saltlen:' + pad_salt_len, '-sigopt', 'digest:' + pad_hash_algo ] return run_command(cmd) finally: if cert_path is not None: c_path.remove_tmp_file(cert_path) if ca_cert_path is not None: c_path.remove_tmp_file(ca_cert_path) if ca_priv_path is not None: c_path.remove_tmp_file(ca_priv_path)
def get_key_in_format(self, key, inform, outform, is_public=False): inform_opt = self._get_format_opt(inform) outform_opt = self._get_format_opt(outform) key_path = c_path.create_tmp_file(key) try: cmd = [ self.openssl, 'ec', '-in', key_path, '-inform', inform_opt, '-outform', outform_opt ] if is_public: cmd.append('-pubin') return run_command(cmd) finally: c_path.remove_tmp_file(key_path)
def get_cert_in_format(self, cert, inform, outform): if "BEGIN CERTIFICATE" not in cert and outform == utils.FORMAT_DER: return cert inform_opt = self._get_format_opt(inform) outform_opt = self._get_format_opt(outform) cert_path = c_path.create_tmp_file(cert) try: cmd = [ self.openssl, OPENSSL_CERT_MODE, '-in', cert_path, '-inform', inform_opt, '-outform', outform_opt ] return run_command(cmd) finally: c_path.remove_tmp_file(cert_path)
def _get_pub_from_priv(self, priv_path): cmd = [self.openssl, 'ec', '-in', priv_path, '-pubout'] return run_command(cmd)
def _gen_ecdsa_key_pair(self, curve): cmd = [ self.openssl, 'ecparam', '-genkey', '-name', curve, '-outform', 'PEM', '-noout', '-text' ] return run_command(cmd)
def _gen_rsa_key_pair(self, exponent, keysize): exponent_opt, keysize_opt = self._get_opts(exponent, keysize) cmd = [self.openssl, 'genpkey', '-algorithm', 'RSA', '-outform', 'PEM', '-pkeyopt', 'rsa_keygen_bits:' + keysize_opt, '-pkeyopt', 'rsa_keygen_pubexp:' + exponent_opt] return run_command(cmd)