示例#1
0
    def test_replace_key(self):
        """ Test replacing the key (and re-encrypting the database). """
        
        self.assertTrue(util.has_encrypted_data())
        
        # Create a new key
        ekey = hashlib.sha256('new-encrypt').digest()
        skey = hashlib.sha256('new-sign').digest()
        new_key = MasterKey(encryption_key=ekey, signing_key=skey)
        
        with self.assertRaises(exc.DatabaseAlreadyEncrypted):
            util.replace_key(new_key)
        
        # Check existing passwords for an arbitrary user
        for (i,pw) in enumerate(self.data.resources['host1.example.com'].passwords.order_by('username')):
            self.assertEquals('password{0}'.format(i), pw.password_decrypted)
            
        util.replace_key(new_key, force=True)
        
        # The replace_key functions updates the global state, so this should work:
        for (i,pw) in enumerate(self.data.resources['host1.example.com'].passwords.order_by('username')):
            self.assertEquals('password{0}'.format(i), pw.password_decrypted)

        # But using the old key should, of course, now fail:
        for (i,pw) in enumerate(self.data.resources['host1.example.com'].passwords.order_by('username')):
            with self.assertRaises(exc.CryptoAuthenticationFailed):
                engine.decrypt(pw.password, key=self.SECRET_KEY)
示例#2
0
 def test_empty(self):
     """ Test encrypt/decrypt behavior when using empty/None values. """
     self.assertNotEquals("", engine.encrypt(""), "Expected empty strings to actually be encryptable.")
     self.assertIs(None, engine.encrypt(None))
     
     self.assertEquals(None, engine.decrypt(""))
     self.assertIs(None, engine.decrypt(None))
示例#3
0
def validate_key(key):
    """
    Checks the key against an encrypted blob in the database.
    
    :param key: The master key to check.
    :type key: ensconce.crypto.MasterKey
    
    :raise ensconce.exc.MissingKeyMetadata: If the metadata row does not exist yet.
    :raise ensconce.exc.MultipleKeyMetadata: If there are multiple metadata rows.
    :raise ensconce.exc.UnconfiguredModel: If we can't create an SA session.
    """
    if meta.Session is None:
        raise exc.UnconfiguredModel()

    session = meta.Session()
    try:
        key_info = session.query(model.KeyMetadata).one()
        # log.debug("Got bytes for validation: {0!r}".format(key_info.validation))
        try:
            decrypted = engine.decrypt(key_info.validation, key=key)
            # log.debug("Decrypts to: {0!r}".format(decrypted))
        except exc.CryptoAuthenticationFailed:
            log.exception("Validation fails due to error decrypting block.")
            return False
        else:
            return True
    except NoResultFound:
        raise exc.MissingKeyMetadata()
    except MultipleResultsFound:
        raise exc.CryptoError("Multiple key metadata rows are not supported.")
    except:
        log.exception("Error validating encryption key.")
        raise
示例#4
0
 def password_decrypted(self):
     # The unicode conversion *seems* like overkill, but is probably the safe thing to do.
     decrypted = engine.decrypt(self.password)
     if decrypted is not None:
         return unicode(decrypted, 'utf-8')
     else:
         return decrypted
示例#5
0
 def test_encrypt_decrypt(self):
     """ Basic encryption/decryption tests. """
     
     
     #    012345678901234567890123456789012345678901234567890123456789
     #    1         2         3         4         5         6
     a = "The slow dog jumped over."
     b = "The slow dog jumped over the brown fox."
     c = "The slow dog jumped over the brown fox and the roosters too."
 
     a_c = engine.encrypt(a)
     self.assertIsInstance(a_c, str)
     
     self.assertEquals(a, engine.decrypt(a_c))
     
     b_c = engine.encrypt(b)
     self.assertEquals(b, engine.decrypt(b_c))
     
     c_c = engine.encrypt(c)
     self.assertEquals(c, engine.decrypt(c_c))
示例#6
0
 def test_decrypt_garbage(self):
     """ Test that exceptions are raised when decrypt input is garbage. """
     data = os.urandom(100) # 100 bytes of garbage
     with self.assertRaises(exc.CryptoAuthenticationFailed):
         engine.decrypt(data)
     
     # We'll also make it look more like the expected data format
     with self.assertRaises(exc.CryptoAuthenticationFailed):
         engine.decrypt(binascii.hexlify(data))
     
     # And finally we'll even add a pad string, but we still expect
     # an error like "Input strings must be a multiple of 16 in length."
     with self.assertRaises(exc.CryptoAuthenticationFailed):
         engine.decrypt(binascii.hexlify(("%02d" % 10) + data))
示例#7
0
 def test_binary(self):
     """ Test encrypt/decrypt of non-ascii data. """
     data = os.urandom(100) # 100 bytes of binary data
     
     data_c = engine.encrypt(data)
     self.assertEquals(data, engine.decrypt(data_c))
示例#8
0
 def notes_decrypted(self):
     decrypted = engine.decrypt(self.notes)
     if decrypted is not None:
         return unicode(decrypted, 'utf-8')
     else:
         return decrypted
示例#9
0
 def password_decrypted(self):
     return engine.decrypt(self.password)