mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-02-26 19:34:41 +00:00
139 lines
4.1 KiB
Python
139 lines
4.1 KiB
Python
"""
|
|
Ported to Python 3.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
from __future__ import unicode_literals
|
|
|
|
from future.utils import PY2
|
|
if PY2:
|
|
from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
|
|
|
|
try:
|
|
from typing import Union
|
|
except ImportError:
|
|
pass
|
|
|
|
import attr
|
|
|
|
from nacl.hash import blake2b
|
|
from nacl.encoding import RawEncoder
|
|
|
|
from .lease import (
|
|
LeaseInfo,
|
|
HashedLeaseInfo,
|
|
)
|
|
|
|
@attr.s(frozen=True)
|
|
class CleartextLeaseSerializer(object):
|
|
"""
|
|
Serialize and unserialize leases with cleartext secrets.
|
|
"""
|
|
_to_data = attr.ib()
|
|
_from_data = attr.ib()
|
|
|
|
def serialize(self, lease):
|
|
# type: (LeaseInfo) -> bytes
|
|
"""
|
|
Represent the given lease as bytes with cleartext secrets.
|
|
"""
|
|
if isinstance(lease, LeaseInfo):
|
|
return self._to_data(lease)
|
|
raise ValueError(
|
|
"ShareFile v1 schema only supports LeaseInfo, not {!r}".format(
|
|
lease,
|
|
),
|
|
)
|
|
|
|
def unserialize(self, data):
|
|
# type: (bytes) -> LeaseInfo
|
|
"""
|
|
Load a lease with cleartext secrets from the given bytes representation.
|
|
"""
|
|
# In v1 of the immutable schema lease secrets are stored plaintext.
|
|
# So load the data into a plain LeaseInfo which works on plaintext
|
|
# secrets.
|
|
return self._from_data(data)
|
|
|
|
@attr.s(frozen=True)
|
|
class HashedLeaseSerializer(object):
|
|
_to_data = attr.ib()
|
|
_from_data = attr.ib()
|
|
|
|
@classmethod
|
|
def _hash_secret(cls, secret):
|
|
# type: (bytes) -> bytes
|
|
"""
|
|
Hash a lease secret for storage.
|
|
"""
|
|
return blake2b(secret, digest_size=32, encoder=RawEncoder())
|
|
|
|
@classmethod
|
|
def _hash_lease_info(cls, lease_info):
|
|
# type: (LeaseInfo) -> HashedLeaseInfo
|
|
"""
|
|
Hash the cleartext lease info secrets into a ``HashedLeaseInfo``.
|
|
"""
|
|
if not isinstance(lease_info, LeaseInfo):
|
|
# Provide a little safety against misuse, especially an attempt to
|
|
# re-hash an already-hashed lease info which is represented as a
|
|
# different type.
|
|
raise TypeError(
|
|
"Can only hash LeaseInfo, not {!r}".format(lease_info),
|
|
)
|
|
|
|
# Hash the cleartext secrets in the lease info and wrap the result in
|
|
# a new type.
|
|
return HashedLeaseInfo(
|
|
attr.assoc(
|
|
lease_info,
|
|
renew_secret=cls._hash_secret(lease_info.renew_secret),
|
|
cancel_secret=cls._hash_secret(lease_info.cancel_secret),
|
|
),
|
|
cls._hash_secret,
|
|
)
|
|
|
|
def serialize(self, lease):
|
|
# type: (Union[LeaseInfo, HashedLeaseInfo]) -> bytes
|
|
if isinstance(lease, LeaseInfo):
|
|
# v2 of the immutable schema stores lease secrets hashed. If
|
|
# we're given a LeaseInfo then it holds plaintext secrets. Hash
|
|
# them before trying to serialize.
|
|
lease = self._hash_lease_info(lease)
|
|
if isinstance(lease, HashedLeaseInfo):
|
|
return self._to_data(lease)
|
|
raise ValueError(
|
|
"ShareFile v2 schema cannot represent lease {!r}".format(
|
|
lease,
|
|
),
|
|
)
|
|
|
|
def unserialize(self, data):
|
|
# type: (bytes) -> HashedLeaseInfo
|
|
# In v2 of the immutable schema lease secrets are stored hashed. Wrap
|
|
# a LeaseInfo in a HashedLeaseInfo so it can supply the correct
|
|
# interpretation for those values.
|
|
return HashedLeaseInfo(self._from_data(data), self._hash_secret)
|
|
|
|
v1_immutable = CleartextLeaseSerializer(
|
|
LeaseInfo.to_immutable_data,
|
|
LeaseInfo.from_immutable_data,
|
|
)
|
|
|
|
v2_immutable = HashedLeaseSerializer(
|
|
HashedLeaseInfo.to_immutable_data,
|
|
LeaseInfo.from_immutable_data,
|
|
)
|
|
|
|
v1_mutable = CleartextLeaseSerializer(
|
|
LeaseInfo.to_mutable_data,
|
|
LeaseInfo.from_mutable_data,
|
|
)
|
|
|
|
v2_mutable = HashedLeaseSerializer(
|
|
HashedLeaseInfo.to_mutable_data,
|
|
LeaseInfo.from_mutable_data,
|
|
)
|