def Run(self, args): """Run.""" # Open the file. fd = vfs.VFSOpen(args.pathspec, progress_callback=self.Progress) if args.address_family == rdf_client.NetworkAddress.Family.INET: family = socket.AF_INET elif args.address_family == rdf_client.NetworkAddress.Family.INET6: family = socket.AF_INET6 else: raise RuntimeError("Socket address family not supported.") s = socket.socket(family, socket.SOCK_STREAM) try: s.connect((args.host, args.port)) except socket.error as e: raise RuntimeError(str(e)) cipher = rdf_crypto.AES128CBCCipher(args.key, args.iv, rdf_crypto.Cipher.OP_ENCRYPT) while True: data = fd.read(self.BLOCK_SIZE) if not data: break self.Send(s, cipher.Update(data)) # Send heartbeats for long files. self.Progress() self.Send(s, cipher.Final()) s.close() self.SendReply(fd.Stat())
def InitializeFromEncryption(self, string, username, password): """Initialize client credentials from encrypted string from the master.""" # Use the same key used in Encrypt() key = self._MakeEncryptKey(username, password) # Initialization vector was prepended. init_vector_str = string[:INITVECTOR_SIZE] init_vector = crypto.AES128Key(init_vector_str) ciphertext = string[INITVECTOR_SIZE:] decryptor = crypto.AES128CBCCipher(key, init_vector, crypto.Cipher.OP_DECRYPT) # Decrypt credentials information and set the required fields. try: plain = decryptor.Update(ciphertext) plain += decryptor.Final() # Remove padding plain = plain.strip(" ") creds = data_server.DataServerClientCredentials(plain) # Create client credentials. self.client_users = {} for client in creds.users: self.client_users[client.username] = client return self except EVP.EVPError: return None
def CheckFlow(self): if self.local_client: original_data = open("/bin/ls", "rb").read() received_cipher = "".join(self.listener.result) cipher = rdf_crypto.AES128CBCCipher(key=self.key, iv=self.iv) received_data = cipher.Decrypt(received_cipher) self.assertEqual(received_data, original_data)
def SetPolicy(self, policy): serialized_policy = policy.SerializeToString() rsa_private_key = config.CONFIG["PrivateKeys.server_key"] aes_key = rdf_crypto.EncryptionKey.FromHex( hashlib.sha256(rsa_private_key.SerializeToString()).hexdigest()) iv = rdf_crypto.EncryptionKey.GenerateRandomIV() cipher = rdf_crypto.AES128CBCCipher(aes_key, iv) self.encrypted_policy = cipher.Encrypt(serialized_policy) self.iv = iv
def SetPayload(self, payload, username, password): key = self._MakeEncryptKey(username, password) self.sha256 = hashlib.sha256(payload).digest() self.init_vector = crypto.AES128Key.GenerateRandomIV() encryptor = crypto.AES128CBCCipher(key, self.init_vector) self.ciphertext = encryptor.Encrypt(payload)
def CheckFlow(self): if self.local_client: original_data = open("/bin/ls", "rb").read() received_cipher = "".join(self.listener.result) cipher = crypto.AES128CBCCipher(key=self.key, iv=self.iv, mode=crypto.AES128CBCCipher.OP_DECRYPT) received_data = cipher.Update(received_cipher) + cipher.Final() self.assertEqual(received_data, original_data)
def RunWithSendToSocket(self, dump_option, conditions=None): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((socket.gethostname(), 0)) port = sock.getsockname()[1] send_to_socket_action = memory.MemoryCollectorSendToSocketAction( host=socket.gethostname(), port=port, key=self.key, iv=self.iv, dump_option=dump_option) flow_urn = flow.GRRFlow.StartFlow( client_id=self.client_id, flow_name="MemoryCollector", conditions=conditions or [], action=memory.MemoryCollectorAction( action_type=memory.MemoryCollectorAction.Action.SEND_TO_SOCKET, send_to_socket=send_to_socket_action), token=self.token, output=self.output_path) socket_data = [] def ReadFromSocket(): sock.listen(1) client_socket, _ = sock.accept() while 1: data = client_socket.recv(1024) if not data: break socket_data.append(data) client_socket.close() sock.close() thread = threading.Thread(target=ReadFromSocket) thread.daemon = True thread.start() for _ in test_lib.TestFlowHelper(flow_urn, self.client_mock, client_id=self.client_id, token=self.token): pass thread.join() encrypted_data = "".join(socket_data) # Data should be encrypted, so they're not equal self.assertNotEqual(encrypted_data, self.memory_dump) cipher = rdf_crypto.AES128CBCCipher( key=self.key, iv=self.iv, mode=rdf_crypto.AES128CBCCipher.OP_DECRYPT) decrypted_data = cipher.Update(encrypted_data) + cipher.Final() return flow_urn, encrypted_data, decrypted_data
def testM2CryptoCipherCompatibility(self): m2crypto_ciphertext = open( os.path.join(self.base_path, "m2crypto/send_file_data"), "rb").read() key = rdf_crypto.EncryptionKey("x" * 16) iv = rdf_crypto.EncryptionKey("y" * 16) cipher = rdf_crypto.AES128CBCCipher(key, iv) plaintext = cipher.Decrypt(m2crypto_ciphertext) self.assertEqual(plaintext, self.memory_dump)
def SetPayload(self, payload, username, password): key = self._MakeEncryptKey(username, password) hasher = hashlib.sha256(payload) self.sha256 = hasher.digest() self.init_vector = self._MakeInitVector() encryptor = crypto.AES128CBCCipher(key, self.init_vector, crypto.Cipher.OP_ENCRYPT) self.ciphertext = encryptor.Encrypt(payload)
def testAES128CBCCipher(self): key = rdf_crypto.AES128Key() iv = rdf_crypto.AES128Key() cipher = rdf_crypto.AES128CBCCipher(key, iv) plain_text = "hello world!" cipher_text = cipher.Encrypt(plain_text) # Repeatadly calling Encrypt should repeat the same cipher text. self.assertEqual(cipher_text, cipher.Encrypt(plain_text)) self.assertNotEqual(cipher_text, plain_text) self.assertEqual(cipher.Decrypt(cipher_text), plain_text)
def testAES128CBCCipher(self): key = rdf_crypto.AES128Key.GenerateKey() iv = rdf_crypto.AES128Key.GenerateKey() cipher = rdf_crypto.AES128CBCCipher(key, iv) plain_text = "hello world!" cipher_text = cipher.Encrypt(plain_text) # Repeatedly calling Encrypt should repeat the same cipher text. self.assertEqual(cipher_text, cipher.Encrypt(plain_text)) self.assertNotEqual(cipher_text, plain_text) self.assertEqual(cipher.Decrypt(cipher_text), plain_text) key2 = rdf_crypto.AES128Key.GenerateKey() iv2 = rdf_crypto.AES128Key.GenerateKey() cipher = rdf_crypto.AES128CBCCipher(key, iv2) self.assertRaises(rdf_crypto.CipherError, cipher.Decrypt, plain_text) cipher = rdf_crypto.AES128CBCCipher(key2, iv) self.assertRaises(rdf_crypto.CipherError, cipher.Decrypt, plain_text) cipher = rdf_crypto.AES128CBCCipher(key2, iv2) self.assertRaises(rdf_crypto.CipherError, cipher.Decrypt, plain_text)
def GetPayload(self, username, password): # Use the same key used in SetPayload() key = self._MakeEncryptKey(username, password) decryptor = crypto.AES128CBCCipher(key, self.init_vector) # Decrypt credentials information and set the required fields. plain = decryptor.Decrypt(self.ciphertext) hasher = hashlib.sha256(plain) if hasher.digest() != self.sha256: raise crypto.CipherError("Hash does not match") return plain
def Encrypt(self, username, password): """Encrypt the client credentials to other data servers.""" # We use the servers username and password to encrypt # the client credentials. creds = data_server.DataServerClientCredentials( users=self.client_users.values()) key = self._MakeEncryptKey(username, password) # We encrypt the credentials object. string = creds.SerializeToString() if len(string) % 16: string += " " * (16 - len(string) % 16) # Must be in 16 byte blocks. init_vector = self._MakeInitVector() encryptor = crypto.AES128CBCCipher(key, init_vector, crypto.Cipher.OP_ENCRYPT) data = encryptor.Update(string) data += encryptor.Final() # Initialization vector is prepended to the encrypted credentials. return str(init_vector) + data
def __init__(self, readers_public_key, writers_private_key, fd, chunk_size=1024 * 1024): """Constructor. Args: readers_public_key: The public key of the destined reader of this stream. The stream will be encrypted with the readers public key. writers_private_key: The private_key of the writer of this stream. Data will be signed using this private key. fd: A file like object we read from. chunk_size: This will be the size of the parts. """ self.fd = fd self.readers_public_key = readers_public_key self.writers_private_key = writers_private_key self.chunk_size = chunk_size # Prepare the initial header. self.cipher_properties = flows.CipherProperties.GetInializedKeys() self.cipher = crypto.AES128CBCCipher( self.cipher_properties.key, self.cipher_properties.metadata_iv) self.hmac = crypto.HMAC(self.cipher_properties.hmac_key.RawBytes()) serialized_cipher = self.cipher_properties.SerializeToString() signature = SignaturePart( encrypted_cipher=readers_public_key.Encrypt(serialized_cipher), signature=writers_private_key.Sign(serialized_cipher), ) # First part is the encrypted cipher. self.encrypted_buffer = BufferedReader() self.encrypted_buffer.write( self._get_part(signature.SerializeToString(), PART_TYPE_ENCRYPTED_CIPHER)) self.eof = False
def Encrypt(self, username, password): """Encrypt the client credentials to other data servers.""" # We use the servers username and password to encrypt # the client credentials. creds = rdfvalue.DataServerClientCredentials() for client_user, (perm, pwd) in self.client_users.iteritems(): client = rdfvalue.DataServerClientInformation(username=client_user, password=pwd, permissions=perm) creds.users.Append(client) key = self._MakeEncryptKey(username, password) # We encrypt the credentials object. string = creds.SerializeToString() if len(string) % 16: string += " " * (16 - len(string) % 16 ) # Must be in 16 byte blocks. init_vector = self._MakeInitVector() encryptor = crypto.AES128CBCCipher(key, init_vector, crypto.Cipher.OP_ENCRYPT) data = encryptor.Update(string) data += encryptor.Final() # Initialization vector is prepended to the encrypted credentials. return str(init_vector) + data
def testStreamingCBCEncryptor(self): key = rdf_crypto.AES128Key.GenerateKey() iv = rdf_crypto.AES128Key.GenerateKey() # 160 characters. message = "Hello World!!!!!" * 10 for plaintext, partitions in [ (message, [ [160], [80, 80], [75, 75, 10], [1, 159], [10] * 16, [1] * 160, ]), # Prime length, not a multiple of blocksize. (message[:149], [ [149], [80, 69], [75, 55, 19], [1, 148], [10] * 14 + [9], [1] * 149, ]) ]: for partition in partitions: cipher = rdf_crypto.AES128CBCCipher(key, iv) streaming_cbc = rdf_crypto.StreamingCBCEncryptor(cipher) it = iter(plaintext) out = [] for n in partition: next_partition = "".join([it.next() for _ in xrange(n)]) out.append(streaming_cbc.Update(next_partition)) out.append(streaming_cbc.Finalize()) self.assertEqual(cipher.Decrypt("".join(out)), plaintext)
def GetCipher(self): if self.name == "AES128CBC": return rdf_crypto.AES128CBCCipher(self.key, self.metadata_iv)
def Encrypt(self, data, iv=None): """Symmetrically encrypt the data using the optional iv.""" if iv is None: iv = rdf_crypto.EncryptionKey.GenerateKey(length=128) cipher = rdf_crypto.AES128CBCCipher(self.cipher.key, iv) return iv, cipher.Encrypt(data)
def FromEncryptedPolicy(cls, encrypted_policy, iv): rsa_private_key = config.CONFIG["PrivateKeys.server_key"] aes_key = rdf_crypto.EncryptionKey.FromHex( hashlib.sha256(rsa_private_key.SerializeToString()).hexdigest()) cipher = rdf_crypto.AES128CBCCipher(aes_key, iv) return cls.FromSerializedString(cipher.Decrypt(encrypted_policy))
def Decrypt(self, data, iv): """Symmetrically decrypt the data.""" key = rdf_crypto.EncryptionKey(self.cipher.key) iv = rdf_crypto.EncryptionKey(iv) return rdf_crypto.AES128CBCCipher(key, iv).Decrypt(data)