예제 #1
0
def WriteSignedBinary(binary_urn: rdfvalue.RDFURN,
                      binary_content: bytes,
                      private_key: rdf_crypto.RSAPrivateKey,
                      public_key: Optional[rdf_crypto.RSAPublicKey],
                      chunk_size: int = 1024):
    """Signs a binary and saves it to the datastore.

  If a signed binary with the given URN already exists, its contents will get
  overwritten.

  Args:
    binary_urn: URN that should serve as a unique identifier for the binary.
    binary_content: Contents of the binary, as raw bytes.
    private_key: Key that should be used for signing the binary contents.
    public_key: Key that should be used to verify the signature generated using
      the private key.
    chunk_size: Size, in bytes, of the individual blobs that the binary contents
      will be split to before saving to the datastore.
  """
    blob_references = rdf_objects.BlobReferences()
    for chunk_offset in range(0, len(binary_content), chunk_size):
        chunk = binary_content[chunk_offset:chunk_offset + chunk_size]
        blob_rdf = rdf_crypto.SignedBlob()
        blob_rdf.Sign(chunk, private_key, verify_key=public_key)
        blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(
            blob_rdf.SerializeToBytes())
        blob_references.items.Append(
            rdf_objects.BlobReference(offset=chunk_offset,
                                      size=len(chunk),
                                      blob_id=blob_id))
    data_store.REL_DB.WriteSignedBinaryReferences(
        SignedBinaryIDFromURN(binary_urn), blob_references)
예제 #2
0
def WriteSignedBinaryBlobs(binary_urn, blobs, token=None):
    """Saves signed blobs to the datastore.

  If a signed binary with the given URN already exists, its contents will get
  overwritten.

  Args:
    binary_urn: RDFURN that should serve as a unique identifier for the binary.
    blobs: An Iterable of signed blobs to write to the datastore.
    token: ACL token to use with the legacy (non-relational) datastore.
  """
    if _ShouldUseLegacyDatastore():
        aff4.FACTORY.Delete(binary_urn, token=token)
        with data_store.DB.GetMutationPool() as mutation_pool:
            with aff4.FACTORY.Create(binary_urn,
                                     collects.GRRSignedBlob,
                                     mode="w",
                                     mutation_pool=mutation_pool,
                                     token=token) as fd:
                for blob in blobs:
                    fd.Add(blob, mutation_pool=mutation_pool)

    if data_store.RelationalDBWriteEnabled():
        blob_references = rdf_objects.BlobReferences()
        current_offset = 0
        for blob in blobs:
            blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(
                blob.SerializeToString())
            blob_references.items.Append(
                rdf_objects.BlobReference(offset=current_offset,
                                          size=len(blob.data),
                                          blob_id=blob_id))
            current_offset += len(blob.data)
        data_store.REL_DB.WriteSignedBinaryReferences(
            _SignedBinaryIDFromURN(binary_urn), blob_references)
예제 #3
0
 def WriteHashBlobReferences(self, references_by_hash, cursor):
   """Writes blob references for a given set of hashes."""
   values = []
   for hash_id, blob_refs in iteritems(references_by_hash):
     refs = rdf_objects.BlobReferences(items=blob_refs).SerializeToString()
     values.append({
         "hash_id": hash_id.AsBytes(),
         "blob_references": refs,
     })
   _Insert(cursor, "hash_blob_references", values)
예제 #4
0
def WriteSignedBinary(binary_urn,
                      binary_content,
                      private_key,
                      public_key,
                      chunk_size=1024,
                      token=None):
    """Signs a binary and saves it to the datastore.

  If a signed binary with the given URN already exists, its contents will get
  overwritten.

  Args:
    binary_urn: URN that should serve as a unique identifier for the binary.
    binary_content: Contents of the binary, as raw bytes.
    private_key: Key that should be used for signing the binary contents.
    public_key: Key that should be used to verify the signature generated using
      the private key.
    chunk_size: Size, in bytes, of the individual blobs that the binary contents
      will be split to before saving to the datastore.
    token: ACL token to use with the legacy (non-relational) datastore.
  """
    if _ShouldUseLegacyDatastore():
        collects.GRRSignedBlob.NewFromContent(binary_content,
                                              binary_urn,
                                              chunk_size=chunk_size,
                                              token=token,
                                              private_key=private_key,
                                              public_key=public_key)

    if data_store.RelationalDBWriteEnabled():
        blob_references = rdf_objects.BlobReferences()
        for chunk_offset in range(0, len(binary_content), chunk_size):
            chunk = binary_content[chunk_offset:chunk_offset + chunk_size]
            blob_rdf = rdf_crypto.SignedBlob()
            blob_rdf.Sign(chunk, private_key, verify_key=public_key)
            blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(
                blob_rdf.SerializeToString())
            blob_references.items.Append(
                rdf_objects.BlobReference(offset=chunk_offset,
                                          size=len(chunk),
                                          blob_id=blob_id))
        data_store.REL_DB.WriteSignedBinaryReferences(
            _SignedBinaryIDFromURN(binary_urn), blob_references)
def WriteSignedBinaryBlobs(binary_urn: rdfvalue.RDFURN,
                           blobs: Iterable[rdf_crypto.SignedBlob]):
  """Saves signed blobs to the datastore.

  If a signed binary with the given URN already exists, its contents will get
  overwritten.

  Args:
    binary_urn: RDFURN that should serve as a unique identifier for the binary.
    blobs: An Iterable of signed blobs to write to the datastore.
  """
  blob_references = rdf_objects.BlobReferences()
  current_offset = 0
  for blob in blobs:
    blob_id = data_store.BLOBS.WriteBlobWithUnknownHash(blob.SerializeToBytes())
    blob_references.items.Append(
        rdf_objects.BlobReference(
            offset=current_offset, size=len(blob.data), blob_id=blob_id))
    current_offset += len(blob.data)
  data_store.REL_DB.WriteSignedBinaryReferences(
      _SignedBinaryIDFromURN(binary_urn), blob_references)
예제 #6
0
"""Tests for signed-binary DB functionality."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals

from grr_response_server import db
from grr_response_server.rdfvalues import objects as rdf_objects

_test_id1 = rdf_objects.SignedBinaryID(
    binary_type=rdf_objects.SignedBinaryID.BinaryType.EXECUTABLE,
    path="linux/test/hello")
_test_id2 = rdf_objects.SignedBinaryID(
    binary_type=rdf_objects.SignedBinaryID.BinaryType.PYTHON_HACK,
    path="windows/test/hello")
_test_references1 = rdf_objects.BlobReferences(items=[
    rdf_objects.BlobReference(offset=0, size=2, blob_id=b"\xaa" * 32),
    rdf_objects.BlobReference(offset=2, size=3, blob_id=b"\xbb" * 32),
])
_test_references2 = rdf_objects.BlobReferences(items=[
    rdf_objects.BlobReference(offset=0, size=3, blob_id=b"\xcc" * 32),
    rdf_objects.BlobReference(offset=3, size=2, blob_id=b"\xdd" * 32),
])


class DatabaseTestSignedBinariesMixin(object):
    """Mixin that adds tests for signed binary DB functionality."""
    def testReadSignedBinaryReferences(self):
        self.db.WriteSignedBinaryReferences(_test_id1, _test_references1)
        stored_hash_id, stored_timestamp = self.db.ReadSignedBinaryReferences(
            _test_id1)
        self.assertEqual(stored_hash_id, _test_references1)
        self.assertGreater(stored_timestamp.AsMicrosecondsSinceEpoch(), 0)