Skip to content

Commit

Permalink
Shamir setup: custom error for certificate verification.
Browse files Browse the repository at this point in the history
  • Loading branch information
AureliaDolo committed May 21, 2024
1 parent 7fe5503 commit bd1ead2
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
10 changes: 7 additions & 3 deletions server/parsec/components/memory/shamir.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
MemoryDatamodel,
MemoryShamirSetup,
)
from parsec.components.shamir import BaseShamirComponent, verify_certificates
from parsec.components.shamir import (
BaseShamirComponent,
VerifyCertificatesBadOutcome,
verify_certificates,
)


class MemoryShamirComponent(BaseShamirComponent):
Expand Down Expand Up @@ -36,5 +40,5 @@ async def add_recovery_setup(
setup.ciphered_data, setup.reveal_token, brief, shares
)

case authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData() as error:
return error
case VerifyCertificatesBadOutcome.INVALID_DATA:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
24 changes: 14 additions & 10 deletions server/parsec/components/shamir.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

from enum import auto

from parsec._parsec import (
DeviceID,
OrganizationID,
Expand All @@ -13,6 +15,7 @@
)
from parsec.api import api
from parsec.client_context import AuthenticatedClientContext
from parsec.types import BadOutcomeEnum


class BaseShamirComponent:
Expand Down Expand Up @@ -61,42 +64,43 @@ async def add_recovery_setup(
raise NotImplementedError


class VerifyCertificatesBadOutcome(BadOutcomeEnum):
INVALID_DATA = auto()


def verify_certificates(
setup: authenticated_cmds.latest.shamir_recovery_setup.ShamirRecoverySetup,
author: DeviceID,
author_verify_key: VerifyKey,
) -> (
tuple[ShamirRecoveryBriefCertificate, dict[UserID, bytes]]
| authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData
):
) -> tuple[ShamirRecoveryBriefCertificate, dict[UserID, bytes]] | VerifyCertificatesBadOutcome:
share_certificates: dict[UserID, bytes] = {}
try:
brief_certificate = ShamirRecoveryBriefCertificate.verify_and_load(
setup.brief, author_verify_key, expected_author=author
)
except ValueError:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA

for raw_share in setup.shares:
try:
share_certificate = ShamirRecoveryShareCertificate.verify_and_load(
raw_share, author_verify_key, expected_author=author, expected_recipient=None
)
except ValueError:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA

# share recipient not in brief
if share_certificate.recipient not in brief_certificate.per_recipient_shares:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA
# this recipient already has a share
if share_certificate.recipient in share_certificates:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA
# user included themselves as a share recipient
if share_certificate.recipient == author.user_id:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA
share_certificates[share_certificate.recipient] = raw_share
delta = set(brief_certificate.per_recipient_shares) - set(share_certificates)
# some recipient specified in brief has no share
if delta:
return authenticated_cmds.latest.shamir_recovery_setup.RepInvalidData()
return VerifyCertificatesBadOutcome.INVALID_DATA
return brief_certificate, share_certificates

0 comments on commit bd1ead2

Please sign in to comment.