Esempio n. 1
0
  def DecodeMessages(self, response_comms):
    """Extract and verify server message.

    Args:
        response_comms: A ClientCommunication rdfvalue

    Returns:
       list of messages and the CN where they came from.

    Raises:
       DecryptionError: If the message failed to decrypt properly.
    """
    # Have we seen this cipher before?
    cipher_verified = False
    cipher = communicator.ReceivedCipher(response_comms, self.private_key)

    source = cipher.GetSource()
    try:
      remote_public_key = self._GetRemotePublicKey(source)
      if cipher.VerifyCipherSignature(remote_public_key):
        cipher_verified = True

    except UnknownServerCertError:
      # We don't know who we are talking to.
      remote_public_key = None

    # Decrypt the message with the per packet IV.
    plain = cipher.Decrypt(response_comms.encrypted, response_comms.packet_iv)
    try:
      packed_message_list = rdf_flows.PackedMessageList.FromSerializedBytes(
          plain)
    except rdfvalue.DecodeError as e:
      raise DecryptionError(e)

    message_list = self.DecompressMessageList(packed_message_list)

    # Are these messages authenticated?
    # pyformat: disable
    auth_state = self.VerifyMessageSignature(
        response_comms,
        packed_message_list,
        cipher,
        cipher_verified,
        response_comms.api_version,
        remote_public_key)
    # pyformat: enable

    # Mark messages as authenticated and where they came from.
    for msg in message_list.job:
      msg.auth_state = auth_state
      msg.source = cipher.cipher_metadata.source

    return (message_list.job, cipher.cipher_metadata.source,
            packed_message_list.timestamp)
Esempio n. 2
0
    def DecodeMessages(self, response_comms):
        """Extract and verify server message.

    Args:
        response_comms: A ClientCommunication rdfvalue

    Returns:
       list of messages and the CN where they came from.

    Raises:
       DecryptionError: If the message failed to decrypt properly.
    """
        # Have we seen this cipher before?
        cipher_verified = False
        try:
            cipher = self.encrypted_cipher_cache.Get(
                response_comms.encrypted_cipher)
            GRR_ENCRYPTED_CIPHER_CACHE.Increment(fields=["hits"])

            # Even though we have seen this encrypted cipher already, we should still
            # make sure that all the other fields are sane and verify the HMAC.
            cipher.VerifyReceivedHMAC(response_comms)
            cipher_verified = True

            # If we have the cipher in the cache, we know the source and
            # should have a corresponding public key.
            source = cipher.GetSource()
            remote_public_key = self._GetRemotePublicKey(source)
        except KeyError:
            GRR_ENCRYPTED_CIPHER_CACHE.Increment(fields=["misses"])
            cipher = communicator.ReceivedCipher(response_comms,
                                                 self.private_key)

            source = cipher.GetSource()
            try:
                remote_public_key = self._GetRemotePublicKey(source)
                if cipher.VerifyCipherSignature(remote_public_key):
                    # At this point we know this cipher is legit, we can cache it.
                    self.encrypted_cipher_cache.Put(
                        response_comms.encrypted_cipher, cipher)
                    cipher_verified = True

            except UnknownClientCertError:
                # We don't know who we are talking to.
                remote_public_key = None

        # Decrypt the message with the per packet IV.
        plain = cipher.Decrypt(response_comms.encrypted,
                               response_comms.packet_iv)
        try:
            packed_message_list = rdf_flows.PackedMessageList.FromSerializedBytes(
                plain)
        except rdfvalue.DecodeError as e:
            raise DecryptionError(e)

        message_list = self.DecompressMessageList(packed_message_list)

        # Are these messages authenticated?
        # pyformat: disable
        auth_state = self.VerifyMessageSignature(response_comms,
                                                 packed_message_list, cipher,
                                                 cipher_verified,
                                                 response_comms.api_version,
                                                 remote_public_key)
        # pyformat: enable

        # Mark messages as authenticated and where they came from.
        for msg in message_list.job:
            msg.auth_state = auth_state
            msg.source = cipher.cipher_metadata.source

        return (message_list.job, cipher.cipher_metadata.source,
                packed_message_list.timestamp)