<s> """<STR_LIT>""" <EOL> from __future__ import print_function <EOL> from __future__ import absolute_import <EOL> from __future__ import division <EOL> from __future__ import unicode_literals <EOL> import os <EOL> import binascii <EOL> import json <EOL> from cryptography . hazmat . primitives import serialization <EOL> from cryptography . hazmat . backends . interfaces import PEMSerializationBackend <EOL> from cryptography . hazmat . primitives . serialization import load_pem_private_key <EOL> from cryptography . hazmat . backends import default_backend <EOL> import cryptography . exceptions <EOL> from cryptography . hazmat . primitives . asymmetric import rsa <EOL> import Crypto . PublicKey . RSA <EOL> from cryptography . hazmat . primitives import hashes <EOL> from cryptography . hazmat . primitives import hmac <EOL> from cryptography . hazmat . primitives . asymmetric import padding <EOL> from cryptography . hazmat . primitives . kdf . pbkdf2 import PBKDF2HMAC <EOL> from cryptography . hazmat . primitives . ciphers import Cipher , algorithms <EOL> from cryptography . hazmat . primitives . ciphers import modes <EOL> import tuf <EOL> import tuf . hash <EOL> import tuf . formats <EOL> import tuf . conf <EOL> import tuf . util <EOL> _DEFAULT_RSA_KEY_BITS = <NUM_LIT> <EOL> _ENCRYPTION_DELIMITER = '<STR_LIT>' <EOL> _AES_KEY_SIZE = <NUM_LIT:32> <EOL> _SALT_SIZE = <NUM_LIT:16> <EOL> _PBKDF2_ITERATIONS = tuf . conf . PBKDF2_ITERATIONS <EOL> def generate_rsa_public_and_private ( bits = _DEFAULT_RSA_KEY_BITS ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . RSAKEYBITS_SCHEMA . check_match ( bits ) <EOL> private_key = rsa . generate_private_key ( public_exponent = <NUM_LIT> , key_size = bits , <EOL> backend = default_backend ( ) ) <EOL> private_pem = private_key . private_bytes ( encoding = serialization . Encoding . PEM , <EOL> format = serialization . PrivateFormat . TraditionalOpenSSL , <EOL> encryption_algorithm = serialization . NoEncryption ( ) ) <EOL> public_key = private_key . public_key ( ) <EOL> public_pem = public_key . public_bytes ( encoding = serialization . Encoding . PEM , <EOL> format = serialization . PublicFormat . SubjectPublicKeyInfo ) <EOL> return public_pem . decode ( ) , private_pem . decode ( ) <EOL> def create_rsa_signature ( private_key , data ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . PEMRSA_SCHEMA . check_match ( private_key ) <EOL> tuf . formats . DATA_SCHEMA . check_match ( data ) <EOL> method = '<STR_LIT>' <EOL> signature = None <EOL> if len ( private_key ) : <EOL> try : <EOL> private_key_object = load_pem_private_key ( private_key . encode ( '<STR_LIT:utf-8>' ) , <EOL> password = None , <EOL> backend = default_backend ( ) ) <EOL> rsa_signer = private_key_object . signer ( padding . PSS ( mgf = padding . MGF1 ( hashes . SHA256 ( ) ) , <EOL> salt_length = hashes . SHA256 ( ) . digest_size ) , hashes . SHA256 ( ) ) <EOL> except ValueError : <EOL> raise tuf . CryptoError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> except TypeError : <EOL> raise tuf . CryptoError ( '<STR_LIT>' ) <EOL> except cryptography . exceptions . UnsupportedAlgorithm : <EOL> raise tuf . CryptoError ( '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> rsa_signer . update ( data ) <EOL> signature = rsa_signer . finalize ( ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' ) <EOL> return signature , method <EOL> def verify_rsa_signature ( signature , signature_method , public_key , data ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . PEMRSA_SCHEMA . check_match ( public_key ) <EOL> tuf . formats . NAME_SCHEMA . check_match ( signature_method ) <EOL> tuf . formats . PYCACRYPTOSIGNATURE_SCHEMA . check_match ( signature ) <EOL> tuf . formats . DATA_SCHEMA . check_match ( data ) <EOL> valid_signature = False <EOL> if signature_method != '<STR_LIT>' : <EOL> raise tuf . UnknownMethodError ( signature_method ) <EOL> try : <EOL> public_key_object = serialization . load_pem_public_key ( public_key . encode ( '<STR_LIT:utf-8>' ) , <EOL> backend = default_backend ( ) ) <EOL> verifier = public_key_object . verifier ( signature , <EOL> padding . PSS ( mgf = padding . MGF1 ( hashes . SHA256 ( ) ) , <EOL> salt_length = hashes . SHA256 ( ) . digest_size ) , <EOL> hashes . SHA256 ( ) ) <EOL> verifier . update ( data ) <EOL> try : <EOL> verifier . verify ( ) <EOL> return True <EOL> except cryptography . exceptions . InvalidSignature : <EOL> return False <EOL> except ValueError : <EOL> raise tuf . CryptoError ( '<STR_LIT>' ) <EOL> except cryptography . exceptions . UnsupportedAlgorithm : <EOL> raise tuf . CryptoError ( '<STR_LIT>' ) <EOL> def create_rsa_encrypted_pem ( private_key , passphrase ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . PEMRSA_SCHEMA . check_match ( private_key ) <EOL> tuf . formats . PASSWORD_SCHEMA . check_match ( passphrase ) <EOL> if len ( private_key ) : <EOL> try : <EOL> rsa_key_object = Crypto . PublicKey . RSA . importKey ( private_key ) <EOL> encrypted_pem = rsa_key_object . exportKey ( format = '<STR_LIT>' , <EOL> passphrase = passphrase ) <EOL> except ( ValueError , IndexError , TypeError ) as e : <EOL> raise tuf . CryptoError ( '<STR_LIT>' <EOL> '<STR_LIT>' + str ( e ) ) <EOL> else : <EOL> raise TypeError ( '<STR_LIT>' ) <EOL> return encrypted_pem . decode ( ) <EOL> def create_rsa_public_and_private_from_encrypted_pem ( encrypted_pem , passphrase ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . PEMRSA_SCHEMA . check_match ( encrypted_pem ) <EOL> tuf . formats . PASSWORD_SCHEMA . check_match ( passphrase ) <EOL> try : <EOL> private_key = load_pem_private_key ( encrypted_pem . encode ( '<STR_LIT:utf-8>' ) , <EOL> passphrase . encode ( '<STR_LIT:utf-8>' ) , <EOL> backend = default_backend ( ) ) <EOL> except ( ValueError , TypeError , cryptography . exceptions . UnsupportedAlgorithm ) as e : <EOL> raise tuf . CryptoError ( '<STR_LIT>' <EOL> '<STR_LIT>' + str ( e ) ) <EOL> private_pem = private_key . private_bytes ( encoding = serialization . Encoding . PEM , <EOL> format = serialization . PrivateFormat . TraditionalOpenSSL , <EOL> encryption_algorithm = serialization . NoEncryption ( ) ) <EOL> public_key = private_key . public_key ( ) <EOL> public_pem = public_key . public_bytes ( encoding = serialization . Encoding . PEM , <EOL> format = serialization . PublicFormat . SubjectPublicKeyInfo ) <EOL> return public_pem . decode ( ) , private_pem . decode ( ) <EOL> def encrypt_key ( key_object , password ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . ANYKEY_SCHEMA . check_match ( key_object ) <EOL> tuf . formats . PASSWORD_SCHEMA . check_match ( password ) <EOL> if not key_object [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> raise tuf . FormatError ( '<STR_LIT>' ) <EOL> salt , iterations , derived_key = _generate_derived_key ( password ) <EOL> derived_key_information = { '<STR_LIT>' : salt , '<STR_LIT>' : iterations , <EOL> '<STR_LIT>' : derived_key } <EOL> encrypted_key = _encrypt ( json . dumps ( key_object ) , derived_key_information ) <EOL> return encrypted_key <EOL> def decrypt_key ( encrypted_key , password ) : <EOL> """<STR_LIT>""" <EOL> tuf . formats . ENCRYPTEDKEY_SCHEMA . check_match ( encrypted_key ) <EOL> tuf . formats . PASSWORD_SCHEMA . check_match ( password ) <EOL> json_data = _decrypt ( encrypted_key . decode ( '<STR_LIT:utf-8>' ) , password ) <EOL> key_object = tuf . util . load_json_string ( json_data . decode ( ) ) <EOL> return key_object <EOL> def _generate_derived_key ( password , salt = None , iterations = None ) : <EOL> """<STR_LIT>""" <EOL> backend = default_backend ( ) <EOL> if salt is None : <EOL> salt = os . urandom ( _SALT_SIZE ) <EOL> if iterations is None : <EOL> iterations = _PBKDF2_ITERATIONS <EOL> pbkdf_object = PBKDF2HMAC ( algorithm = hashes . SHA256 ( ) , length = <NUM_LIT:32> , salt = salt , <EOL> iterations = iterations , backend = backend ) <EOL> derived_key = pbkdf_object . derive ( password . encode ( '<STR_LIT:utf-8>' ) ) <EOL> return salt , iterations , derived_key <EOL> def _encrypt ( key_data , derived_key_information ) : <EOL> """<STR_LIT>""" <EOL> iv = os . urandom ( <NUM_LIT:16> ) <EOL> symmetric_key = derived_key_information [ '<STR_LIT>' ] <EOL> encryptor = Cipher ( algorithms . AES ( symmetric_key ) , modes . CTR ( iv ) , <EOL> backend = default_backend ( ) ) . encryptor ( ) <EOL> ciphertext = encryptor . update ( key_data . encode ( '<STR_LIT:utf-8>' ) ) + encryptor . finalize ( ) <EOL> symmetric_key = derived_key_information [ '<STR_LIT>' ] <EOL> salt = derived_key_information [ '<STR_LIT>' ] <EOL> hmac_object = cryptography . hazmat . primitives . hmac . HMAC ( symmetric_key , hashes . SHA256 ( ) , <EOL> backend = default_backend ( ) ) <EOL> hmac_object . update ( ciphertext ) <EOL> hmac_value = binascii . hexlify ( hmac_object . finalize ( ) ) <EOL> iterations = derived_key_information [ '<STR_LIT>' ] <EOL> return binascii . hexlify ( salt ) . decode ( ) + _ENCRYPTION_DELIMITER + str ( iterations ) + _ENCRYPTION_DELIMITER + hmac_value . decode ( ) + _ENCRYPTION_DELIMITER + binascii . hexlify ( iv ) . decode ( ) + _ENCRYPTION_DELIMITER + binascii . hexlify ( ciphertext ) . decode ( ) <EOL> def _decrypt ( file_contents , password ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> salt , iterations , hmac , iv , ciphertext = file_contents . split ( _ENCRYPTION_DELIMITER ) <EOL> except ValueError : <EOL> raise tuf . CryptoError ( '<STR_LIT>' ) <EOL> salt = binascii . unhexlify ( salt . encode ( '<STR_LIT:utf-8>' ) ) <EOL> iterations = int ( iterations ) <EOL> iv = binascii . unhexlify ( iv . encode ( '<STR_LIT:utf-8>' ) ) <EOL> ciphertext = binascii . unhexlify ( ciphertext . encode ( '<STR_LIT:utf-8>' ) ) <EOL> junk_old_salt , junk_old_iterations , symmetric_key = _generate_derived_key ( password , salt , iterations ) <EOL> generated_hmac_object = cryptography . hazmat . primitives . hmac . HMAC ( symmetric_key , hashes . SHA256 ( ) , <EOL> backend = default_backend ( ) ) <EOL> generated_hmac_object . update ( ciphertext ) <EOL> generated_hmac = binascii . hexlify ( generated_hmac_object . finalize ( ) ) <EOL> if not tuf . util . digests_are_equal ( generated_hmac . decode ( ) , hmac ) : <EOL> raise tuf . CryptoError ( '<STR_LIT>' ) <EOL> decryptor = Cipher ( algorithms . AES ( symmetric_key ) , modes . CTR ( iv ) , <EOL> backend = default_backend ( ) ) . decryptor ( ) <EOL> plaintext = decryptor . update ( ciphertext ) + decryptor . finalize ( ) <EOL> return plaintext <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import doctest <EOL> doctest . testmod ( ) </s>
