예제 #1
0
 def test_has_encrypted_data_nulls(self):
     """ Ensure correct detection of encrypted data in db (null cols). """
     # By default (with default data) this will be true
     self.assertTrue(util.has_encrypted_data())
     
     session = meta.Session()
     session.execute(model.passwords_table.update().values(password=None))
     session.flush()
     
     self.assertTrue(util.has_encrypted_data())
     
     session.execute(model.resources_table.update().values(notes=None))
     session.flush()
     
     self.assertFalse(util.has_encrypted_data(), "With all password and notes field set to NULL, there should be no encrypted data in DB.")
예제 #2
0
def init_crypto(options):
    """
    Interactive target to initialize the database with a new crypto passphrase.
    """
    print "Initializing crypto for an empty database."
    if crypto_util.has_encrypted_data():
        raise BuildFailure("Database has existing encrypted contents; use the 'rekey' target instead.")

    passphrase = raw_input("Passphrase: ")
    print "The database will be initialized with the passphrase between the arrows: --->%s<---" % passphrase
    print "The MD5 of the passphrase you entered is: %s" % hashlib.md5(passphrase).hexdigest()
    
    confirm = raw_input("Type 'YES' to confirm passphrase and MD5 are correct: ")
    if confirm != 'YES':
        raise ValueError("You must enter 'YES' to proceed.")
    
    salt = get_random_bytes(16)
    key = crypto_util.derive_key(passphrase=passphrase, salt=salt)
    crypto_util.initialize_key_metadata(key=key, salt=salt, force_overwrite=False)
    
    print "Database key metadata has been initialized.  Your application is ready for use."
    if config.get('debug'):
        print "The new key is: %s%s" % (binascii.hexlify(key.encryption_key), binascii.hexlify(key.signing_key))

    print "*************************************************************"
    print "IMPORTANT"
    print "Make sure your database master passphrase is stored somewhere"
    print "outside of Ensconce."
    print ""
    print "There is no recovery mechanism for this passphrase (or for "
    print "your database, should you lose it.)"
    print "*************************************************************"    
예제 #3
0
def rekey(options):
    """
    Interactive target to change the passphrase for the database.
    """
    info("This is an EXTREMELY DANGEROUS activity.")
    info("Backup your database first.")
    
    curr_passphrase = raw_input("Current passphrase: ")
    
    crypto_util.configure_crypto_state(curr_passphrase)
    
    new_passphrase = raw_input("New passphrase: ")
    confirm = raw_input("MD5 of passphrase is %s (type \"YES\" to confirm): " % hashlib.md5(new_passphrase).hexdigest())
    if confirm != 'YES':
        raise ValueError("You must enter 'YES' to proceed.")
    
    if crypto_util.has_encrypted_data():
        confirm = raw_input("There is existing encrypted data in the database.  Type 'REKEY' to proceed with re-encryption: ")
        if confirm != 'REKEY':
            raise ValueError("You must enter 'REKEY' to proceed.")
    
    # Use the same salt as previous key
    new_key = crypto_util.derive_configured_key(new_passphrase)
    
    crypto_util.replace_key(new_key=new_key, force=True)
    
    info("Re-encryption completed successfully.")
    
    if config.get('debug'):
        print "The new key is: %s%s" % (binascii.hexlify(new_key.encryption_key), binascii.hexlify(new_key.signing_key))
예제 #4
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)
예제 #5
0
 def test_has_encrypted_data_basic(self):
     """ Ensure correct detection of encrypted data in db (basic). """
     # By default (with default data) this will be true
     self.assertTrue(util.has_encrypted_data())
     
     session = meta.Session()
     session.execute(model.passwords_table.delete())
     session.flush()
     
     # Should be true still ...
     self.assertTrue(util.has_encrypted_data())
     
     session.execute(model.resources_table.delete())
     session.flush()
     
     # But not anymore.
     self.assertFalse(util.has_encrypted_data())