示例#1
0
async def bootstrap_organization(
    cmds: APIV1_BackendAnonymousCmds,
    human_handle: Optional[HumanHandle],
    device_label: Optional[str],
) -> LocalDevice:
    root_signing_key = SigningKey.generate()
    root_verify_key = root_signing_key.verify_key

    organization_addr = BackendOrganizationAddr.build(
        backend_addr=cmds.addr,
        organization_id=cmds.addr.organization_id,
        root_verify_key=root_verify_key,
    )

    device = generate_new_device(
        organization_addr=organization_addr,
        profile=UserProfile.ADMIN,
        human_handle=human_handle,
        device_label=device_label,
    )

    now = pendulum_now()
    user_certificate = UserCertificateContent(
        author=None,
        timestamp=now,
        user_id=device.user_id,
        human_handle=device.human_handle,
        public_key=device.public_key,
        profile=device.profile,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    device_certificate = DeviceCertificateContent(
        author=None,
        timestamp=now,
        device_id=device.device_id,
        device_label=device.device_label,
        verify_key=device.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user_certificate = user_certificate.dump_and_sign(root_signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        root_signing_key)
    device_certificate = device_certificate.dump_and_sign(root_signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        root_signing_key)

    rep = await cmds.organization_bootstrap(
        organization_id=cmds.addr.organization_id,
        bootstrap_token=cmds.addr.token,
        root_verify_key=root_verify_key,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=redacted_user_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    _check_rep(rep, step_name="organization bootstrap")

    return device
示例#2
0
async def test_redacted_certificates_cannot_contain_sensitive_data(
        alice_backend_sock, alice, mallory):
    now = pendulum.now()
    user_certificate = UserCertificateContent(
        author=alice.device_id,
        timestamp=now,
        user_id=mallory.user_id,
        human_handle=mallory.human_handle,
        public_key=mallory.public_key,
        profile=UserProfile.STANDARD,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=mallory.device_id,
        device_label=mallory.device_label,
        verify_key=mallory.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user_certificate = user_certificate.dump_and_sign(alice.signing_key)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        alice.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        alice.signing_key)

    with freeze_time(now):
        rep = await user_create(
            alice_backend_sock,
            user_certificate=user_certificate,
            device_certificate=device_certificate,
            redacted_user_certificate=user_certificate,
            redacted_device_certificate=redacted_device_certificate,
        )
        assert rep == {
            "status":
            "invalid_data",
            "reason":
            "Redacted User certificate must not contain a human_handle field.",
        }

        rep = await user_create(
            alice_backend_sock,
            user_certificate=user_certificate,
            device_certificate=device_certificate,
            redacted_user_certificate=redacted_user_certificate,
            redacted_device_certificate=device_certificate,
        )
        assert rep == {
            "status":
            "invalid_data",
            "reason":
            "Redacted Device certificate must not contain a device_label field.",
        }
示例#3
0
def local_device_to_backend_user(
    device: LocalDevice, certifier: Union[LocalDevice, OrganizationFullData]
) -> Tuple[BackendUser, BackendDevice]:
    if isinstance(certifier, OrganizationFullData):
        certifier_id = None
        certifier_signing_key = certifier.root_signing_key
    else:
        certifier_id = certifier.device_id
        certifier_signing_key = certifier.signing_key

    now = pendulum.now()

    user_certificate = UserCertificateContent(
        author=certifier_id,
        timestamp=now,
        user_id=device.user_id,
        public_key=device.public_key,
        profile=device.profile,
        human_handle=device.human_handle,
    )
    device_certificate = DeviceCertificateContent(
        author=certifier_id,
        timestamp=now,
        device_id=device.device_id,
        device_label=device.device_label,
        verify_key=device.verify_key,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user = BackendUser(
        user_id=device.user_id,
        human_handle=device.human_handle,
        profile=device.profile,
        user_certificate=user_certificate.dump_and_sign(certifier_signing_key),
        redacted_user_certificate=redacted_user_certificate.dump_and_sign(
            certifier_signing_key),
        user_certifier=certifier_id,
        created_on=now,
    )

    first_device = BackendDevice(
        device_id=device.device_id,
        device_label=device.device_label,
        device_certificate=device_certificate.dump_and_sign(
            certifier_signing_key),
        redacted_device_certificate=redacted_device_certificate.dump_and_sign(
            certifier_signing_key),
        device_certifier=certifier_id,
        created_on=now,
    )

    return user, first_device
示例#4
0
    async def do_create_new_device(self, author: LocalDevice,
                                   device_label: Optional[str]) -> None:
        device_id = author.user_id.to_device_id(DeviceName.new())
        try:
            now = pendulum_now()

            device_certificate = DeviceCertificateContent(
                author=author.device_id,
                timestamp=now,
                device_id=device_id,
                device_label=device_label,
                verify_key=self._verify_key,
            )
            redacted_device_certificate = device_certificate.evolve(
                device_label=None)

            device_certificate = device_certificate.dump_and_sign(
                author.signing_key)
            redacted_device_certificate = redacted_device_certificate.dump_and_sign(
                author.signing_key)

        except DataError as exc:
            raise InviteError(
                f"Cannot generate device certificate: {exc}") from exc

        rep = await self._cmds.device_create(
            device_certificate=device_certificate,
            redacted_device_certificate=redacted_device_certificate,
        )
        _check_rep(rep, step_name="device creation")

        try:
            payload = InviteDeviceConfirmation(
                device_id=device_id,
                device_label=device_label,
                human_handle=author.human_handle,
                profile=author.profile,
                private_key=author.private_key,
                user_manifest_id=author.user_manifest_id,
                user_manifest_key=author.user_manifest_key,
                root_verify_key=author.root_verify_key,
            ).dump_and_encrypt(key=self._shared_secret_key)
        except DataError as exc:
            raise InviteError(
                "Cannot generate InviteUserConfirmation payload") from exc

        rep = await self._cmds.invite_4_greeter_communicate(token=self.token,
                                                            payload=payload)
        _check_rep(rep, step_name="step 4 (confirmation exchange)")

        await self._cmds.invite_delete(token=self.token,
                                       reason=InvitationDeletedReason.FINISHED)
示例#5
0
async def _register_new_user(
    cmds: BackendAuthenticatedCmds,
    author: LocalDevice,
    device_label: Optional[str],
    human_handle: Optional[HumanHandle],
    profile: UserProfile,
) -> LocalDevice:
    new_device = generate_new_device(
        organization_addr=cmds.addr,
        device_label=device_label,
        human_handle=human_handle,
        profile=profile,
    )
    now = pendulum_now()

    user_certificate = UserCertificateContent(
        author=author.device_id,
        timestamp=now,
        user_id=new_device.device_id.user_id,
        human_handle=new_device.human_handle,
        public_key=new_device.public_key,
        profile=new_device.profile,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)

    device_certificate = DeviceCertificateContent(
        author=author.device_id,
        timestamp=now,
        device_id=new_device.device_id,
        device_label=new_device.device_label,
        verify_key=new_device.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user_certificate = user_certificate.dump_and_sign(author.signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        author.signing_key)
    device_certificate = device_certificate.dump_and_sign(author.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        author.signing_key)

    rep = await cmds.user_create(
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=redacted_user_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    if rep["status"] != "ok":
        raise RuntimeError(f"Cannot create user: {rep}")

    return new_device
示例#6
0
async def test_user_create_human_handle_with_revoked_previous_one(
        alice_backend_sock, alice, bob, backend_data_binder):
    # First revoke bob
    await backend_data_binder.bind_revocation(user_id=bob.user_id,
                                              certifier=alice)

    # Now recreate another user with bob's human handle
    now = pendulum.now()
    bob2_device_id = DeviceID("bob2@dev1")
    user_certificate = UserCertificateContent(
        author=alice.device_id,
        timestamp=now,
        user_id=bob2_device_id.user_id,
        human_handle=bob.human_handle,
        public_key=bob.public_key,
        profile=UserProfile.STANDARD,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=bob2_device_id,
        device_label=bob.
        device_label,  # Device label doesn't have to be unique
        verify_key=bob.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user_certificate = user_certificate.dump_and_sign(alice.signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        alice.signing_key)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        alice.signing_key)

    rep = await user_create(
        alice_backend_sock,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=redacted_user_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    assert rep == {"status": "ok"}
示例#7
0
async def test_user_create_human_handle_already_exists(alice_backend_sock,
                                                       alice, bob):
    now = pendulum.now()
    bob2_device_id = DeviceID("bob2@dev1")
    user_certificate = UserCertificateContent(
        author=alice.device_id,
        timestamp=now,
        user_id=bob2_device_id.user_id,
        human_handle=bob.human_handle,
        public_key=bob.public_key,
        profile=UserProfile.STANDARD,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=bob2_device_id,
        device_label="dev2",
        verify_key=bob.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    user_certificate = user_certificate.dump_and_sign(alice.signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        alice.signing_key)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        alice.signing_key)

    rep = await user_create(
        alice_backend_sock,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=redacted_user_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    assert rep == {
        "status":
        "already_exists",
        "reason":
        f"Human handle `{bob.human_handle}` already corresponds to a non-revoked user",
    }
示例#8
0
async def test_device_create_ok(backend, backend_sock_factory,
                                alice_backend_sock, alice, alice_nd,
                                with_labels):
    now = pendulum.now()
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=alice_nd.device_id,
        device_label=alice_nd.device_label,
        verify_key=alice_nd.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)
    if not with_labels:
        device_certificate = redacted_device_certificate
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        alice.signing_key)

    rep = await device_create(
        alice_backend_sock,
        device_certificate=device_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    assert rep == {"status": "ok"}

    # Make sure the new device can connect now
    async with backend_sock_factory(backend, alice_nd) as sock:
        rep = await ping(sock, ping="Hello world !")
        assert rep == {"status": "ok", "pong": "Hello world !"}

    # Check the resulting data in the backend
    _, backend_device = await backend.user.get_user_with_device(
        alice_nd.organization_id, alice_nd.device_id)
    assert backend_device == Device(
        device_id=alice_nd.device_id,
        device_label=alice_nd.device_label if with_labels else None,
        device_certificate=device_certificate,
        redacted_device_certificate=redacted_device_certificate,
        device_certifier=alice.device_id,
        created_on=now,
    )
示例#9
0
async def test_device_create_bad_redacted_device_certificate(
        alice_backend_sock, alice, alice_nd):
    now = pendulum.now()
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=alice_nd.device_id,
        device_label=alice_nd.device_label,
        verify_key=alice_nd.verify_key,
    )
    good_redacted_device_certificate = device_certificate.evolve(
        device_label=None)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    for bad_redacted_device_certificate in (
            good_redacted_device_certificate.evolve(timestamp=now.add(
                seconds=1)),
            good_redacted_device_certificate.evolve(device_id=alice.device_id),
            good_redacted_device_certificate.evolve(
                verify_key=alice.verify_key),
    ):
        rep = await device_create(
            alice_backend_sock,
            device_certificate=device_certificate,
            redacted_device_certificate=bad_redacted_device_certificate.
            dump_and_sign(alice.signing_key),
        )
        assert rep == {
            "status":
            "invalid_data",
            "reason":
            "Redacted Device certificate differs from Device certificate.",
        }

    # Finally just make sure good was really good
    rep = await device_create(
        alice_backend_sock,
        device_certificate=device_certificate,
        redacted_device_certificate=good_redacted_device_certificate.
        dump_and_sign(alice.signing_key),
    )
    assert rep == {"status": "ok"}
示例#10
0
async def _register_new_device(cmds: BackendAuthenticatedCmds,
                               author: LocalDevice,
                               device_label: Optional[str]):
    new_device = LocalDevice(
        organization_addr=author.organization_addr,
        device_id=DeviceID(f"{author.user_id}@{DeviceName.new()}"),
        device_label=device_label,
        human_handle=author.human_handle,
        profile=author.profile,
        private_key=author.private_key,
        signing_key=SigningKey.generate(),
        user_manifest_id=author.user_manifest_id,
        user_manifest_key=author.user_manifest_key,
        local_symkey=author.local_symkey,
    )
    now = pendulum_now()

    device_certificate = DeviceCertificateContent(
        author=author.device_id,
        timestamp=now,
        device_id=new_device.device_id,
        device_label=new_device.device_label,
        verify_key=new_device.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)

    device_certificate = device_certificate.dump_and_sign(author.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        author.signing_key)

    rep = await cmds.device_create(
        device_certificate=device_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )

    if rep["status"] != "ok":
        raise RuntimeError(f"Cannot create device: {rep}")

    return new_device
示例#11
0
async def test_user_create_bad_redacted_device_certificate(
        alice_backend_sock, alice, mallory):
    now = pendulum.now()
    user_certificate = UserCertificateContent(
        author=alice.device_id,
        timestamp=now,
        user_id=mallory.user_id,
        human_handle=None,  # Can be used as regular and redacted certificate
        public_key=mallory.public_key,
        profile=UserProfile.STANDARD,
    ).dump_and_sign(alice.signing_key)
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=mallory.device_id,
        device_label=mallory.device_label,
        verify_key=mallory.verify_key,
    )
    good_redacted_device_certificate = device_certificate.evolve(
        device_label=None)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    for bad_redacted_device_certificate in (
            good_redacted_device_certificate.evolve(timestamp=now.add(
                seconds=1)),
            good_redacted_device_certificate.evolve(device_id=alice.device_id),
            good_redacted_device_certificate.evolve(
                verify_key=alice.verify_key),
    ):
        rep = await user_create(
            alice_backend_sock,
            user_certificate=user_certificate,
            device_certificate=device_certificate,
            redacted_user_certificate=user_certificate,
            redacted_device_certificate=bad_redacted_device_certificate.
            dump_and_sign(alice.signing_key),
        )
        assert rep == {
            "status":
            "invalid_data",
            "reason":
            "Redacted Device certificate differs from Device certificate.",
        }

    # Missing redacted certificate is not allowed as well
    rep = await user_create(
        alice_backend_sock,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=user_certificate,
        redacted_device_certificate=None,
    )
    assert rep == {
        "status": "bad_message",
        "reason": "Invalid message.",
        "errors": {
            "redacted_device_certificate":
            ["Missing data for required field."]
        },
    }

    # Finally just make sure good was really good
    rep = await user_create(
        alice_backend_sock,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=user_certificate,
        redacted_device_certificate=good_redacted_device_certificate.
        dump_and_sign(alice.signing_key),
    )
    assert rep == {"status": "ok"}
示例#12
0
async def test_user_create_ok(backend, backend_sock_factory,
                              alice_backend_sock, alice, mallory, profile,
                              with_labels):
    now = pendulum.now()
    user_certificate = UserCertificateContent(
        author=alice.device_id,
        timestamp=now,
        user_id=mallory.user_id,
        human_handle=mallory.human_handle,
        public_key=mallory.public_key,
        profile=profile,
    )
    redacted_user_certificate = user_certificate.evolve(human_handle=None)
    device_certificate = DeviceCertificateContent(
        author=alice.device_id,
        timestamp=now,
        device_id=mallory.device_id,
        device_label=mallory.device_label,
        verify_key=mallory.verify_key,
    )
    redacted_device_certificate = device_certificate.evolve(device_label=None)
    if not with_labels:
        user_certificate = redacted_user_certificate
        device_certificate = redacted_device_certificate

    user_certificate = user_certificate.dump_and_sign(alice.signing_key)
    device_certificate = device_certificate.dump_and_sign(alice.signing_key)
    redacted_user_certificate = redacted_user_certificate.dump_and_sign(
        alice.signing_key)
    redacted_device_certificate = redacted_device_certificate.dump_and_sign(
        alice.signing_key)

    rep = await user_create(
        alice_backend_sock,
        user_certificate=user_certificate,
        device_certificate=device_certificate,
        redacted_user_certificate=redacted_user_certificate,
        redacted_device_certificate=redacted_device_certificate,
    )
    assert rep == {"status": "ok"}

    # Make sure mallory can connect now
    async with backend_sock_factory(backend, mallory) as sock:
        rep = await user_get(sock, user_id=mallory.user_id)
        assert rep["status"] == "ok"

    # Check the resulting data in the backend
    backend_user, backend_device = await backend.user.get_user_with_device(
        mallory.organization_id, mallory.device_id)
    assert backend_user == User(
        user_id=mallory.user_id,
        human_handle=mallory.human_handle if with_labels else None,
        profile=profile,
        user_certificate=user_certificate,
        redacted_user_certificate=redacted_user_certificate,
        user_certifier=alice.device_id,
        created_on=now,
    )
    assert backend_device == Device(
        device_id=mallory.device_id,
        device_label=mallory.device_label if with_labels else None,
        device_certificate=device_certificate,
        redacted_device_certificate=redacted_device_certificate,
        device_certifier=alice.device_id,
        created_on=now,
    )
示例#13
0
    async def do_create_new_user(
        self,
        author: LocalDevice,
        device_label: Optional[str],
        human_handle: Optional[HumanHandle],
        profile: UserProfile,
    ) -> None:
        device_id = DeviceID.new()
        try:
            now = pendulum_now()

            user_certificate = UserCertificateContent(
                author=author.device_id,
                timestamp=now,
                user_id=device_id.user_id,
                human_handle=human_handle,
                public_key=self._public_key,
                profile=profile,
            )
            redacted_user_certificate = user_certificate.evolve(
                human_handle=None)

            device_certificate = DeviceCertificateContent(
                author=author.device_id,
                timestamp=now,
                device_id=device_id,
                device_label=device_label,
                verify_key=self._verify_key,
            )
            redacted_device_certificate = device_certificate.evolve(
                device_label=None)

            user_certificate = user_certificate.dump_and_sign(
                author.signing_key)
            redacted_user_certificate = redacted_user_certificate.dump_and_sign(
                author.signing_key)
            device_certificate = device_certificate.dump_and_sign(
                author.signing_key)
            redacted_device_certificate = redacted_device_certificate.dump_and_sign(
                author.signing_key)

        except DataError as exc:
            raise InviteError(
                f"Cannot generate device certificate: {exc}") from exc

        rep = await self._cmds.user_create(
            user_certificate=user_certificate,
            device_certificate=device_certificate,
            redacted_user_certificate=redacted_user_certificate,
            redacted_device_certificate=redacted_device_certificate,
        )
        if rep["status"] != "ok":
            raise InviteError(f"Cannot create device: {rep}")

        try:
            payload = InviteUserConfirmation(
                device_id=device_id,
                device_label=device_label,
                human_handle=human_handle,
                profile=profile,
                root_verify_key=author.root_verify_key,
            ).dump_and_encrypt(key=self._shared_secret_key)
        except DataError as exc:
            raise InviteError(
                "Cannot generate InviteUserConfirmation payload") from exc

        rep = await self._cmds.invite_4_greeter_communicate(token=self.token,
                                                            payload=payload)
        _check_rep(rep, step_name="step 4 (confirmation exchange)")

        await self._cmds.invite_delete(token=self.token,
                                       reason=InvitationDeletedReason.FINISHED)
示例#14
0
async def test_organization_bootstrap_bad_data(
    backend_data_binder,
    apiv1_backend_sock_factory,
    organization_factory,
    local_device_factory,
    backend,
    coolorg,
):
    neworg = organization_factory("NewOrg")
    newalice = local_device_factory("alice@dev1", neworg)
    await backend_data_binder.bind_organization(neworg)

    bad_organization_id = coolorg.organization_id
    good_organization_id = neworg.organization_id

    root_signing_key = neworg.root_signing_key
    bad_root_signing_key = coolorg.root_signing_key

    good_bootstrap_token = neworg.bootstrap_token
    bad_bootstrap_token = coolorg.bootstrap_token

    good_rvk = neworg.root_verify_key
    bad_rvk = coolorg.root_verify_key

    good_device_id = newalice.device_id

    good_user_id = newalice.user_id
    bad_user_id = UserID("dummy")

    public_key = newalice.public_key
    verify_key = newalice.verify_key

    now = pendulum.now()
    bad_now = now.subtract(seconds=1)

    good_cu = UserCertificateContent(
        author=None,
        timestamp=now,
        user_id=good_user_id,
        public_key=public_key,
        profile=UserProfile.ADMIN,
        human_handle=newalice.human_handle,
    )
    good_redacted_cu = good_cu.evolve(human_handle=None)
    good_cd = DeviceCertificateContent(
        author=None,
        timestamp=now,
        device_id=good_device_id,
        device_label=newalice.device_label,
        verify_key=verify_key,
    )
    good_redacted_cd = good_cd.evolve(device_label=None)
    bad_now_cu = good_cu.evolve(timestamp=bad_now)
    bad_now_cd = good_cd.evolve(timestamp=bad_now)
    bad_now_redacted_cu = good_redacted_cu.evolve(timestamp=bad_now)
    bad_now_redacted_cd = good_redacted_cd.evolve(timestamp=bad_now)
    bad_id_cu = good_cu.evolve(user_id=bad_user_id)
    bad_not_admin_cu = good_cu.evolve(profile=UserProfile.STANDARD)

    bad_key_cu = good_cu.dump_and_sign(bad_root_signing_key)
    bad_key_cd = good_cd.dump_and_sign(bad_root_signing_key)

    good_cu = good_cu.dump_and_sign(root_signing_key)
    good_redacted_cu = good_redacted_cu.dump_and_sign(root_signing_key)
    good_cd = good_cd.dump_and_sign(root_signing_key)
    good_redacted_cd = good_redacted_cd.dump_and_sign(root_signing_key)
    bad_now_cu = bad_now_cu.dump_and_sign(root_signing_key)
    bad_now_cd = bad_now_cd.dump_and_sign(root_signing_key)
    bad_now_redacted_cu = bad_now_redacted_cu.dump_and_sign(root_signing_key)
    bad_now_redacted_cd = bad_now_redacted_cd.dump_and_sign(root_signing_key)
    bad_id_cu = bad_id_cu.dump_and_sign(root_signing_key)
    bad_not_admin_cu = bad_not_admin_cu.dump_and_sign(root_signing_key)

    for i, (status, organization_id, *params) in enumerate([
        ("not_found", good_organization_id, bad_bootstrap_token, good_cu,
         good_cd, good_rvk),
        (
            "already_bootstrapped",
            bad_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
        ),
        (
            "invalid_certification",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            bad_rvk,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            bad_now_cu,
            good_cd,
            good_rvk,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            bad_id_cu,
            good_cd,
            good_rvk,
        ),
        (
            "invalid_certification",
            good_organization_id,
            good_bootstrap_token,
            bad_key_cu,
            good_cd,
            good_rvk,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            bad_now_cd,
            good_rvk,
        ),
        (
            "invalid_certification",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            bad_key_cd,
            good_rvk,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            bad_not_admin_cu,
            good_cd,
            good_rvk,
        ),
            # Tests with redacted certificates
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_cu,  # Not redacted !
            good_redacted_cd,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_redacted_cu,
            good_cd,  # Not redacted !
        ),
        (
            "bad_message",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            None,  # None not allowed
            good_redacted_cd,
        ),
        (
            "bad_message",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_redacted_cu,
            None,  # None not allowed
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            bad_now_redacted_cu,
            good_redacted_cd,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_redacted_cu,
            bad_now_redacted_cd,
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_redacted_cu,
            _missing,  # Must proved redacted_device if redacted user is present
        ),
        (
            "invalid_data",
            good_organization_id,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            _missing,  # Must proved redacted_device if redacted user is present
            good_redacted_cd,
        ),
    ]):
        print(f"sub test {i}")
        async with apiv1_backend_sock_factory(backend,
                                              organization_id) as sock:
            rep = await organization_bootstrap(sock, *params)
        assert rep["status"] == status

    # Finally cheap test to make sure our "good" data were really good
    async with apiv1_backend_sock_factory(backend,
                                          good_organization_id) as sock:
        rep = await organization_bootstrap(
            sock,
            good_bootstrap_token,
            good_cu,
            good_cd,
            good_rvk,
            good_redacted_cu,
            good_redacted_cd,
        )
    assert rep["status"] == "ok"