Example #1
0
    def verify_password(self, guessed_password, tryinverted=True):
        """Check a proposed password, to see if it's able to open and load a
        user's account."""

        # The cleanest way to see if the password is accurate is to see if it successfully decodes the content in the account.
        # We can do this by attempting to decode the private key.
        # We can then verify it decoded properly, by re-deriving the public key, and seeing if they match.

        test_passkey = self.Keys['master'].get_passkey(guessed_password)
        byteprivatekey = base64.b64decode(
            self.encryptedprivkey.encode('utf-8'))

        # We decoded something. Check to see if we can recreate the pubkey using this.
        if byteprivatekey is None:
            return False
        else:
            test_key = Key()
            test_key.gpg.import_keys(byteprivatekey)
            reconstituted_pubkey = test_key.gpg.export_keys(
                test_key.gpg.list_keys()[0]['fingerprint'])
            test_key.pubkey = reconstituted_pubkey
            test_key._format_keys()

            if test_key.pubkey == user.pubkey:
                return True

            # Let's try one other variation before we give up.
            # It's possible the user has caps lock on, and so their keys are inverted.
            # Testing this doesn't substantially decrease security, but it does help make things easier for users who had a long day.
            # Based on the FB-technique, as described at http://blog.agilebits.com/2011/09/13/facebook-and-caps-lock-unintuitive-security/

            if tryinverted:
                return self.verify_password(
                    guessed_password=guessed_password.swapcase(),
                    tryinverted=False)