Esempio n. 1
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))
Esempio n. 2
0
def create_key_validation_payload(key=None):
    """
    Utility function to create the encrypted payload that we will late use for key validation.
    
    TODO: Consider replacing with something smarter.  HMAC?
    """
    some_bytes = get_random_bytes(256)
    return engine.encrypt(some_bytes, key=key)
Esempio n. 3
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))
Esempio n. 4
0
def replace_key(new_key, force=False):
    """
    Replaces the database key.  If there are encrypted contents in the database, you
    must specify force=True which will *reencrypt* the database contents with the new key.
    
    This is dangerous.
    
    !!!! BACKUP FIRST !!!!
    !!!! STOP WEB SERVER !!!!
    
    :param new_key: The new encryption key.
    :raise ensconce.exc.CryptoNotInitialized: If the engine has not been initialized (with the correct current key).
    :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.
    :raise ensconce.exc.DatabaseAlreadyEncrypted: If database has encrypted data and `force` param is not `True`.
    """
    assert isinstance(new_key, MasterKey)

    if not state.initialized:
        raise exc.CryptoNotInitialized()

    if meta.Session is None:
        raise exc.UnconfiguredModel()

    if has_encrypted_data() and not force:
        raise exc.DatabaseAlreadyEncrypted(
            "Database has existing encrypted data (must specify force to reencrypt existing data)."
        )

    session = meta.Session()
    assert session.autocommit == False

    with state.key_lock:
        try:
            key_info = session.query(model.KeyMetadata).one()

            pass_t = model.passwords_table

            # Re-encrypt all of the passwords with the new key.
            for pw in session.query(model.Password).filter(and_(pass_t.c.password != None, pass_t.c.password != "")):
                # Important: set the *encrypted* password here (not password_decrypted)
                pw.password = engine.encrypt(pw.password_decrypted, key=new_key)

            session.flush()

            ph_t = model.password_history_table
            for pwh in session.query(model.PasswordHistory).filter(
                and_(ph_t.c.password != None, ph_t.c.password != "")
            ):
                # Important: set the *encrypted* password here (not password_decrypted)
                pwh.password = engine.encrypt(pwh.password_decrypted, key=new_key)

            session.flush()

            # Re-encrypt all of the notes fields for resources
            resources_t = model.resources_table
            for rsc in session.query(model.Resource).filter(
                and_(resources_t.c.notes != None, resources_t.c.notes != "")
            ):
                # Important: set the *encrypted* password here (not password_decrypted)
                rsc.notes = engine.encrypt(rsc.notes_decrypted, key=new_key)

            session.flush()

            key_info.validation = create_key_validation_payload(key=new_key)

            session.flush()

            state.secret_key = new_key

        except NoResultFound:
            raise exc.MissingKeyMetadata("No key metadata found; initialize key metadata before replacing key.")
        except MultipleResultsFound:
            raise exc.CryptoError("Multiple key metadata rows are not supported.")
        except:
            session.rollback()
            log.exception("Error replacing key; rolling back transaction.")
            raise
        else:
            session.commit()
Esempio n. 5
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))
Esempio n. 6
0
 def notes_decrypted(self, cleartext):
     self.notes = engine.encrypt(cleartext)
Esempio n. 7
0
 def password_decrypted(self, cleartext):
     self.password = engine.encrypt(cleartext)