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