コード例 #1
0
ファイル: test_certif.py プロジェクト: Scille/parsec-cloud
def test_device_certificate():
    from parsec.api.data.certif import (
        _RsDeviceCertificateContent,
        DeviceCertificateContent,
        _PyDeviceCertificateContent,
    )

    assert DeviceCertificateContent is _RsDeviceCertificateContent

    def _assert_device_certificate_eq(py, rs):
        assert py.author == rs.author
        assert py.timestamp == rs.timestamp
        assert py.device_id == rs.device_id
        assert py.device_label == rs.device_label
        assert py.verify_key == rs.verify_key

    kwargs = {
        "author": DeviceID.new(),
        "timestamp": pendulum.now(),
        "device_id": DeviceID("bob@dev1"),
        "device_label": DeviceLabel("dev machine"),
        "verify_key": SigningKey.generate().verify_key,
    }

    py_dc = _PyDeviceCertificateContent(**kwargs)
    rs_dc = DeviceCertificateContent(**kwargs)
    _assert_device_certificate_eq(py_dc, rs_dc)

    kwargs = {
        "author": DeviceID.new(),
        "timestamp": pendulum.now(),
        "device_id": DeviceID("alice@dev1"),
        "device_label": None,
        "verify_key": SigningKey.generate().verify_key,
    }

    py_dc = py_dc.evolve(**kwargs)
    rs_dc = rs_dc.evolve(**kwargs)
    _assert_device_certificate_eq(py_dc, rs_dc)

    sign_key = SigningKey.generate()
    py_data = py_dc.dump_and_sign(sign_key)
    rs_data = rs_dc.dump_and_sign(sign_key)

    py_dc = _PyDeviceCertificateContent.verify_and_load(
        rs_data, sign_key.verify_key, expected_author=py_dc.author, expected_device=py_dc.device_id
    )
    rs_dc = DeviceCertificateContent.verify_and_load(
        py_data, sign_key.verify_key, expected_author=rs_dc.author, expected_device=rs_dc.device_id
    )
    _assert_device_certificate_eq(py_dc, rs_dc)

    py_dc = _PyDeviceCertificateContent.unsecure_load(rs_data)
    rs_dc = DeviceCertificateContent.unsecure_load(py_data)
    _assert_device_certificate_eq(py_dc, rs_dc)
コード例 #2
0
def _create_new_user_certificates(
    author: LocalDevice,
    device_label: Optional[DeviceLabel],
    human_handle: Optional[HumanHandle],
    profile: UserProfile,
    public_key: PublicKey,
    verify_key: VerifyKey,
) -> Tuple[bytes, bytes, bytes, bytes, InviteUserConfirmation]:
    """Helper to prepare the creation of a new user."""
    device_id = DeviceID.new()
    try:
        timestamp = author.timestamp()

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

        device_certificate = DeviceCertificateContent(
            author=author.device_id,
            timestamp=timestamp,
            device_id=device_id,
            device_label=device_label,
            verify_key=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

    invite_user_confirmation = InviteUserConfirmation(
        device_id=device_id,
        device_label=device_label,
        human_handle=human_handle,
        profile=profile,
        root_verify_key=author.root_verify_key,
    )

    return (
        user_certificate,
        redacted_user_certificate,
        device_certificate,
        redacted_device_certificate,
        invite_user_confirmation,
    )
コード例 #3
0
 def __init__(self) -> None:
     super().__init__()
     self.oracle = open(tmpdir / "oracle.txt", "w+b")
     self.manifest = LocalFileManifest.new_placeholder(DeviceID.new(),
                                                       parent=EntryID(),
                                                       blocksize=8)
     self.storage = Storage()
コード例 #4
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(
        device_id=DeviceID.new(),
        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,
        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,
                                                  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)

    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,
    )

    return device
コード例 #5
0
ファイル: test_certif.py プロジェクト: Scille/parsec-cloud
def test_revoked_user_certificate():
    from parsec.api.data.certif import (
        _RsRevokedUserCertificateContent,
        RevokedUserCertificateContent,
        _PyRevokedUserCertificateContent,
    )

    assert RevokedUserCertificateContent is _RsRevokedUserCertificateContent

    def _assert_revoked_user_certificate_eq(py, rs):
        assert py.author == rs.author
        assert py.timestamp == rs.timestamp
        assert py.user_id == rs.user_id

    kwargs = {"author": DeviceID.new(), "timestamp": pendulum.now(), "user_id": UserID("bob")}

    py_ruc = _PyRevokedUserCertificateContent(**kwargs)
    rs_ruc = RevokedUserCertificateContent(**kwargs)
    _assert_revoked_user_certificate_eq(py_ruc, rs_ruc)

    kwargs = {"author": DeviceID.new(), "timestamp": pendulum.now(), "user_id": UserID("alice")}

    py_ruc = py_ruc.evolve(**kwargs)
    rs_ruc = rs_ruc.evolve(**kwargs)
    _assert_revoked_user_certificate_eq(py_ruc, rs_ruc)

    sign_key = SigningKey.generate()
    py_data = py_ruc.dump_and_sign(sign_key)
    rs_data = rs_ruc.dump_and_sign(sign_key)

    py_ruc = _PyRevokedUserCertificateContent.verify_and_load(
        rs_data, sign_key.verify_key, expected_author=py_ruc.author, expected_user=py_ruc.user_id
    )
    rs_ruc = RevokedUserCertificateContent.verify_and_load(
        py_data, sign_key.verify_key, expected_author=rs_ruc.author, expected_user=rs_ruc.user_id
    )
    _assert_revoked_user_certificate_eq(py_ruc, rs_ruc)

    py_ruc = _PyRevokedUserCertificateContent.unsecure_load(rs_data)
    rs_ruc = RevokedUserCertificateContent.unsecure_load(py_data)
    _assert_revoked_user_certificate_eq(py_ruc, rs_ruc)
コード例 #6
0
def generate_new_device(
    organization_addr: BackendOrganizationAddr,
    device_id: Optional[DeviceID] = None,
    profile: UserProfile = UserProfile.STANDARD,
    human_handle: Optional[HumanHandle] = None,
    device_label: Optional[DeviceLabel] = None,
    signing_key: Optional[SigningKey] = None,
    private_key: Optional[PrivateKey] = None,
) -> LocalDevice:
    return LocalDevice(
        organization_addr=organization_addr,
        device_id=device_id or DeviceID.new(),
        device_label=device_label,
        human_handle=human_handle,
        signing_key=signing_key or SigningKey.generate(),
        private_key=private_key or PrivateKey.generate(),
        profile=profile,
        user_manifest_id=EntryID.new(),
        user_manifest_key=SecretKey.generate(),
        local_symkey=SecretKey.generate(),
    )
コード例 #7
0
ファイル: greeter.py プロジェクト: stjordanis/parsec-cloud
    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)
コード例 #8
0
ファイル: test_certif.py プロジェクト: Scille/parsec-cloud
def test_user_certificate():
    from parsec.api.data.certif import (
        _RsUserCertificateContent,
        UserCertificateContent,
        _PyUserCertificateContent,
    )

    assert UserCertificateContent is _RsUserCertificateContent

    def _assert_user_certificate_eq(py, rs):
        assert py.is_admin == rs.is_admin
        assert py.author == rs.author
        assert py.timestamp == rs.timestamp
        assert py.user_id == rs.user_id
        assert py.human_handle == rs.human_handle
        assert py.public_key == rs.public_key
        assert py.profile == rs.profile

    kwargs = {
        "author": DeviceID.new(),
        "timestamp": pendulum.now(),
        "user_id": UserID("bob"),
        "human_handle": HumanHandle("*****@*****.**", "Boby McBobFace"),
        "public_key": PrivateKey.generate().public_key,
        "profile": UserProfile.ADMIN,
    }

    py_uc = _PyUserCertificateContent(**kwargs)
    rs_uc = UserCertificateContent(**kwargs)
    _assert_user_certificate_eq(py_uc, rs_uc)

    kwargs = {
        "author": DeviceID.new(),
        "timestamp": pendulum.now(),
        "user_id": UserID("alice"),
        "human_handle": None,
        "public_key": PrivateKey.generate().public_key,
        "profile": UserProfile.STANDARD,
    }

    py_uc = py_uc.evolve(**kwargs)
    rs_uc = rs_uc.evolve(**kwargs)
    _assert_user_certificate_eq(py_uc, rs_uc)

    sign_key = SigningKey.generate()
    py_data = py_uc.dump_and_sign(sign_key)
    rs_data = rs_uc.dump_and_sign(sign_key)

    py_uc = _PyUserCertificateContent.verify_and_load(
        rs_data,
        sign_key.verify_key,
        expected_author=py_uc.author,
        expected_user=py_uc.user_id,
        expected_human_handle=py_uc.human_handle,
    )
    rs_uc = UserCertificateContent.verify_and_load(
        py_data,
        sign_key.verify_key,
        expected_author=rs_uc.author,
        expected_user=rs_uc.user_id,
        expected_human_handle=rs_uc.human_handle,
    )
    _assert_user_certificate_eq(py_uc, rs_uc)

    py_uc = _PyUserCertificateContent.unsecure_load(rs_data)
    rs_uc = UserCertificateContent.unsecure_load(py_data)
    _assert_user_certificate_eq(py_uc, rs_uc)
コード例 #9
0
def test_complete_scenario():
    storage = Storage()

    with freeze_time("2000-01-01"):
        base = manifest = LocalFileManifest.new_placeholder(
            DeviceID.new(), parent=EntryID.new(), blocksize=16)
        assert manifest == base.evolve(size=0)

    with freeze_time("2000-01-02") as t2:
        manifest = storage.write(manifest, b"Hello ", 0)
        assert storage.read(manifest, 6, 0) == b"Hello "

    (chunk0, ), = manifest.blocks
    assert manifest == base.evolve(size=6, blocks=((chunk0, ), ), updated=t2)
    assert chunk0 == Chunk(id=chunk0.id,
                           start=0,
                           stop=6,
                           raw_offset=0,
                           raw_size=6,
                           access=None)
    assert storage[chunk0.id] == b"Hello "

    with freeze_time("2000-01-03") as t3:
        manifest = storage.write(manifest, b"world !", 6)
        assert storage.read(manifest, 13, 0) == b"Hello world !"

    (_, chunk1), = manifest.blocks
    assert manifest == base.evolve(size=13,
                                   blocks=((chunk0, chunk1), ),
                                   updated=t3)
    assert chunk1 == Chunk(id=chunk1.id,
                           start=6,
                           stop=13,
                           raw_offset=6,
                           raw_size=7,
                           access=None)
    assert storage[chunk1.id] == b"world !"

    with freeze_time("2000-01-04") as t4:
        manifest = storage.write(manifest, b"\n More kontent", 13)
        assert storage.read(manifest, 27, 0) == b"Hello world !\n More kontent"

    (_, _, chunk2), (chunk3, ) = manifest.blocks
    assert storage[chunk2.id] == b"\n M"
    assert storage[chunk3.id] == b"ore kontent"
    assert manifest == base.evolve(size=27,
                                   blocks=((chunk0, chunk1, chunk2),
                                           (chunk3, )),
                                   updated=t4)

    with freeze_time("2000-01-05") as t5:
        manifest = storage.write(manifest, b"c", 20)
        assert storage.read(manifest, 27, 0) == b"Hello world !\n More content"

    chunk4, chunk5, chunk6 = manifest.blocks[1]
    assert chunk3.id == chunk4.id == chunk6.id
    assert storage[chunk5.id] == b"c"
    assert manifest == base.evolve(size=27,
                                   blocks=((chunk0, chunk1, chunk2),
                                           (chunk4, chunk5, chunk6)),
                                   updated=t5)

    with freeze_time("2000-01-06") as t6:
        manifest = storage.resize(manifest, 40)
        expected = b"Hello world !\n More content" + b"\x00" * 13
        assert storage.read(manifest, 40, 0) == expected

    (_, _, _, chunk7), (chunk8, ) = manifest.blocks[1:]
    assert storage[chunk7.id] == b"\x00" * 5
    assert storage[chunk8.id] == b"\x00" * 8
    assert manifest == base.evolve(
        size=40,
        blocks=((chunk0, chunk1, chunk2), (chunk4, chunk5, chunk6, chunk7),
                (chunk8, )),
        updated=t6,
    )

    with freeze_time("2000-01-07") as t7:
        manifest = storage.resize(manifest, 25)
        expected = b"Hello world !\n More conte"
        assert storage.read(manifest, 25, 0) == expected

    (_, _, chunk9), = manifest.blocks[1:]
    assert chunk9.id == chunk6.id
    assert manifest == base.evolve(size=25,
                                   blocks=((chunk0, chunk1, chunk2),
                                           (chunk4, chunk5, chunk9)),
                                   updated=t7)

    with freeze_time("2000-01-08"):
        assert not manifest.is_reshaped()
        manifest = storage.reshape(manifest)
        expected = b"Hello world !\n More conte"
        assert storage.read(manifest, 25, 0) == expected
        assert manifest.is_reshaped()

    (chunk10, ), (chunk11, ) = manifest.blocks
    assert storage[chunk10.id] == b"Hello world !\n M"
    assert storage[chunk11.id] == b"ore conte"
    assert manifest == base.evolve(size=25,
                                   blocks=((chunk10, ), (chunk11, )),
                                   updated=t7)