Ejemplo n.º 1
0
    def __init__(self, options, callback):
        """Abstracts libmongocrypt's mongocrypt_t type.

        :Parameters:
          - `options`: A :class:`MongoCryptOptions`.
          - `callback`: A :class:`MongoCryptCallback`.
        """
        self.__opts = options
        self.__callback = callback
        self.__crypt = None

        if not isinstance(options, MongoCryptOptions):
            raise TypeError("options must be a MongoCryptOptions")

        if not isinstance(callback, MongoCryptCallback):
            raise TypeError("callback must be a MongoCryptCallback")

        self.__crypt = lib.mongocrypt_new()
        if self.__crypt == ffi.NULL:
            raise MongoCryptError("unable to create new mongocrypt object")

        try:
            self.__init()
        except Exception:
            # Destroy the mongocrypt object on error.
            self.close()
            raise
Ejemplo n.º 2
0
def _write_bytes(mongocrypt_binary, data):
    """Writes the given data to a mongocrypt_binary_t."""
    buf = lib.mongocrypt_binary_data(mongocrypt_binary)
    if buf == ffi.NULL:
        raise MongoCryptError('mongocrypt_binary_data returned NULL')

    ffi.memmove(buf, data, len(data))
Ejemplo n.º 3
0
def _to_bytes(mongocrypt_binary):
    """Returns this mongocrypt_binary_t as bytes."""
    data = lib.mongocrypt_binary_data(mongocrypt_binary)
    if data == ffi.NULL:
        raise MongoCryptError('mongocrypt_binary_data returned NULL')
    data_len = lib.mongocrypt_binary_len(mongocrypt_binary)
    return ffi.unpack(ffi.cast("char*", data), data_len)
Ejemplo n.º 4
0
 def __raise_from_status(self):
     status = lib.mongocrypt_status_new()
     try:
         lib.mongocrypt_kms_ctx_status(self.__ctx, status)
         exc = MongoCryptError.from_status(status)
     finally:
         lib.mongocrypt_status_destroy(status)
     raise exc
Ejemplo n.º 5
0
def run_state_machine(ctx, callback):
    """Run the libmongocrypt state machine until completion.

    :Parameters:
      - `ctx`: A :class:`MongoCryptContext`.
      - `callback`: A :class:`MongoCryptCallback`.

    :Returns:
      The completed libmongocrypt operation.
    """
    while True:
        state = ctx.state
        # Check for terminal states first.
        if state == lib.MONGOCRYPT_CTX_ERROR:
            ctx._raise_from_status()
        elif state == lib.MONGOCRYPT_CTX_READY:
            return ctx.finish()
        elif state == lib.MONGOCRYPT_CTX_DONE:
            return None

        if state == lib.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
            list_colls_filter = ctx.mongo_operation()
            coll_info = callback.collection_info(ctx.database,
                                                 list_colls_filter)
            if coll_info:
                ctx.add_mongo_operation_result(coll_info)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
            mongocryptd_cmd = ctx.mongo_operation()
            result = callback.mark_command(ctx.database, mongocryptd_cmd)
            ctx.add_mongo_operation_result(result)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS:
            key_filter = ctx.mongo_operation()
            for key in callback.fetch_keys(key_filter):
                ctx.add_mongo_operation_result(key)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_KMS:
            for kms_ctx in ctx.kms_contexts():
                with kms_ctx:
                    callback.kms_request(kms_ctx)
            ctx.complete_kms()
        else:
            raise MongoCryptError('unknown state: %r' % (state, ))
Ejemplo n.º 6
0
 def __init__(self, binary):
     """Wraps a mongocrypt_binary_t."""
     if binary == ffi.NULL:
         raise MongoCryptError(
             "unable to create new mongocrypt_binary object")
     self.bin = binary