def __init__(self, source, private_key, remote_public_key): self.private_key = private_key # The CipherProperties() protocol buffer specifying the session keys, that # we send to the other end point. It will be encrypted using the RSA private # key. self.cipher = rdf_flows.CipherProperties( name=self.cipher_name, key=rdf_crypto.EncryptionKey.GenerateKey(length=self.key_size), metadata_iv=rdf_crypto.EncryptionKey.GenerateKey(length=self.key_size), hmac_key=rdf_crypto.EncryptionKey.GenerateKey(length=self.key_size), hmac_type="FULL_HMAC") serialized_cipher = self.cipher.SerializeToString() self.cipher_metadata = rdf_flows.CipherMetadata(source=source) # Sign this cipher. self.cipher_metadata.signature = self.private_key.Sign(serialized_cipher) # Now encrypt the cipher. stats.STATS.IncrementCounter("grr_rsa_operations") self.encrypted_cipher = remote_public_key.Encrypt(serialized_cipher) # Encrypt the metadata block symmetrically. _, self.encrypted_cipher_metadata = self.Encrypt( self.cipher_metadata.SerializeToString(), self.cipher.metadata_iv)
def __init__(self, source, destination, private_key, pub_key_cache): self.private_key = private_key # The CipherProperties() protocol buffer specifying the session keys, that # we send to the other end point. It will be encrypted using the RSA private # key. self.cipher = rdf_flows.CipherProperties( name=self.cipher_name, key=os.urandom(self.key_size / 8), metadata_iv=os.urandom(self.iv_size / 8), hmac_key=os.urandom(self.key_size / 8), hmac_type="FULL_HMAC") self.pub_key_cache = pub_key_cache serialized_cipher = self.cipher.SerializeToString() self.cipher_metadata = rdf_flows.CipherMetadata(source=source) # Sign this cipher. digest = self.hash_function(serialized_cipher).digest() # We never want to have a password dialog private_key = self.private_key.GetPrivateKey() self.cipher_metadata.signature = private_key.sign( digest, self.hash_function_name) # Now encrypt the cipher with our key rsa_key = pub_key_cache.GetRSAPublicKey(destination) stats.STATS.IncrementCounter("grr_rsa_operations") # M2Crypto verifies the key on each public_encrypt call which is horribly # slow therefore we just call the swig wrapped method directly. self.encrypted_cipher = m2.rsa_public_encrypt(rsa_key.rsa, serialized_cipher, self.e_padding) # Encrypt the metadata block symmetrically. _, self.encrypted_cipher_metadata = self.Encrypt( self.cipher_metadata.SerializeToString(), self.cipher.metadata_iv) self.signature_verified = True
def __init__(self, response_comms, private_key): self.private_key = private_key self.response_comms = response_comms if response_comms.api_version not in [3]: raise DecryptionError("Unsupported api version: %s, expected 3." % response_comms.api_version) if not response_comms.encrypted_cipher: # The message is not encrypted. We do not allow unencrypted # messages: raise DecryptionError("Server response is not encrypted.") try: # The encrypted_cipher contains the session key, iv and hmac_key. self.serialized_cipher = private_key.Decrypt( response_comms.encrypted_cipher) # If we get here we have the session keys. self.cipher = rdf_flows.CipherProperties(self.serialized_cipher) # Check the key lengths. if (len(self.cipher.key) != self.key_size / 8 or len(self.cipher.metadata_iv) != self.iv_size / 8 or len(self.cipher.hmac_key) != self.key_size / 8): raise DecryptionError("Invalid cipher.") self.VerifyHMAC() # Cipher_metadata contains information about the cipher - It is encrypted # using the symmetric session key. It contains the RSA signature of the # digest of the serialized CipherProperties(). It is stored inside the # encrypted payload. serialized_metadata = self.Decrypt( response_comms.encrypted_cipher_metadata, self.cipher.metadata_iv) self.cipher_metadata = rdf_flows.CipherMetadata( serialized_metadata) except (rdf_crypto.InvalidSignature, rdf_crypto.CipherError) as e: raise DecryptionError(e)
def __init__(self, response_comms, private_key, pub_key_cache): self.private_key = private_key self.pub_key_cache = pub_key_cache # Decrypt the message private_key = self.private_key.GetPrivateKey() try: # The encrypted_cipher contains the session key, iv and hmac_key. self.encrypted_cipher = response_comms.encrypted_cipher # M2Crypto verifies the key on each private_decrypt call which is horribly # slow therefore we just call the swig wrapped method directly. self.serialized_cipher = m2.rsa_private_decrypt( private_key.rsa, response_comms.encrypted_cipher, self.e_padding) # If we get here we have the session keys. self.cipher = rdf_flows.CipherProperties(self.serialized_cipher) # Check the key lengths. if (len(self.cipher.key) != self.key_size / 8 or len(self.cipher.metadata_iv) != self.iv_size / 8): raise DecryptionError("Invalid cipher.") # Check the hmac key for sanity. self.VerifyHMAC(response_comms) # Cipher_metadata contains information about the cipher - It is encrypted # using the symmetric session key. It contains the RSA signature of the # digest of the serialized CipherProperties(). It is stored inside the # encrypted payload. self.cipher_metadata = rdf_flows.CipherMetadata( self.Decrypt(response_comms.encrypted_cipher_metadata, self.cipher.metadata_iv)) self.VerifyCipherSignature() except RSA.RSAError as e: raise DecryptionError(e)