File: common.py

package info (click to toggle)
python-srptools 1.0.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 216 kB
  • sloc: python: 656; makefile: 5; sh: 5
file content (134 lines) | stat: -rw-r--r-- 3,808 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from __future__ import unicode_literals

from binascii import unhexlify

from .utils import hex_from, int_from_hex, hex_from_b64, value_encode, b64_from
from .exceptions import SRPException


if False:  # pragma: no cover
    from .context import SRPContext


class SRPSessionBase(object):
    """Base session class for server and client."""

    role = None

    def __init__(self, srp_context, private=None):
        """
        :param SRPContext srp_context:
        :param str|unicode private:
        """
        self._context = srp_context

        self._salt = None  # type: bytes
        self._common_secret = None  # type: int
        self._key = None  # type: bytes
        self._key_proof = None  # type: bytes
        self._key_proof_hash = None  # type: bytes

        self._server_public = None  # type: int
        self._client_public = None  # type: int

        self._this_private = None  # type: int

        if private:
            self._this_private = int_from_hex(private)  # type: int

    @property
    def _this_public(self):
        return getattr(self, '_%s_public' % self.role)

    def _other_public(self, val):
        other = ('server' if self.role == 'client' else 'client')
        setattr(self, '_%s_public' % other, val)

    _other_public = property(None, _other_public)

    @property
    def private(self):
        return hex_from(self._this_private)

    @property
    def private_b64(self):
        return b64_from(self._this_private)

    @property
    def public(self):
        return hex_from(self._this_public)

    @property
    def public_b64(self):
        return b64_from(self._this_public)

    @property
    def key(self):
        return hex_from(self._key)

    @property
    def key_b64(self):
        return b64_from(self._key)

    @property
    def key_proof(self):
        return hex_from(self._key_proof)

    @property
    def key_proof_b64(self):
        return b64_from(self._key_proof)

    @property
    def key_proof_hash(self):
        return hex_from(self._key_proof_hash)

    @property
    def key_proof_hash_b64(self):
        return b64_from(self._key_proof_hash)

    @classmethod
    def _value_decode(cls, value, base64=False):
        """Decodes value into hex optionally from base64"""
        return hex_from_b64(value) if base64 else value

    def process(self, other_public, salt, base64=False):
        salt = self._value_decode(salt, base64)
        other_public = self._value_decode(other_public, base64)

        self.init_base(salt)
        self.init_common_secret(other_public)
        self.init_session_key()
        self.init_session_key_proof()

        key = value_encode(self._key, base64)
        key_proof = value_encode(self._key_proof, base64)
        key_proof_hash = value_encode(self._key_proof_hash, base64)

        return key, key_proof, key_proof_hash

    def init_base(self, salt):
        salt = unhexlify(salt)
        self._salt = salt

    def init_session_key(self):
        """"""

    def verify_proof(self, key_prove, base64=False):
        """"""

    def init_common_secret(self, other_public):
        other_public = int_from_hex(other_public)

        if other_public % self._context._prime == 0:  # A % N is zero | B % N is zero
            raise SRPException('Wrong public provided for %s.' % self.__class__.__name__)

        self._other_public = other_public

        self._common_secret = self._context.get_common_secret(self._server_public, self._client_public)

    def init_session_key_proof(self):
        proof = self._context.get_common_session_key_proof(
            self._key, self._salt, self._server_public, self._client_public)
        self._key_proof = proof

        self._key_proof_hash = self._context.get_common_session_key_proof_hash(self._key, proof, self._client_public)