15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""Class for storing shared keys."""
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from utils.cryptomath import *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from utils.compat import *
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from mathtls import *
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from Session import Session
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from BaseDB import BaseDB
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SharedKeyDB(BaseDB):
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """This class represent an in-memory or on-disk database of shared
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    A SharedKeyDB can be passed to a server handshake function to
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticate a client based on one of the shared keys.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    This class is thread-safe.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __init__(self, filename=None):
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Create a new SharedKeyDB.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @type filename: str
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param filename: Filename for an on-disk database, or None for
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        an in-memory database.  If the filename already exists, follow
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this with a call to open().  To create a new on-disk database,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        follow this with a call to create().
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BaseDB.__init__(self, filename, "shared key")
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def _getItem(self, username, valueStr):
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session = Session()
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        session._createSharedKey(username, valueStr)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return session
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def __setitem__(self, username, sharedKey):
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """Add a shared key to the database.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @type username: str
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param username: The username to associate the shared key with.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Must be less than or equal to 16 characters in length, and must
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        not already be in the database.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @type sharedKey: str
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        @param sharedKey: The shared key to add.  Must be less than 48
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        characters in length.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        """
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BaseDB.__setitem__(self, username, sharedKey)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def _setItem(self, username, value):
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if len(username)>16:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            raise ValueError("username too long")
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if len(value)>=48:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            raise ValueError("shared key too long")
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return value
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def _checkItem(self, value, username, param):
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        newSession = self._getItem(username, param)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return value.masterSecret == newSession.masterSecret