def Upload(self, fd, sign_fn=None):
    """Uploads data from a given stream and signs them with a given key."""

    if not sign_fn:
      raise ValueError("sign_fn can't be empty. "
                       "See DefaultUploadSigner as a possible option.")

    args = binary_management_pb2.ApiUploadGrrBinaryArgs(
        type=self.binary_type, path=self.path)

    while True:
      data = fd.read(self.__class__.CHUNK_SIZE)
      if not data:
        break

      blob = args.blobs.add()

      blob.signature = sign_fn(data)
      blob.signature_type = blob.RSA_PKCS1v15

      blob.digest = hashlib.sha256(data).digest()
      blob.digest_type = blob.SHA256

      blob.data = data

    self._context.SendRequest("UploadGrrBinary", args)