func createCipher(db *sql.DB, password string, passwordStretch int) (*crypto.Cipher, *crypto.Cipher, error) { const version = 1 tx, err := db.Begin() if err != nil { return nil, nil, err } defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() passwordKey, passwordSalt, err := crypto.NewPasswordKey(password, passwordStretch) if err != nil { return nil, nil, err } passwordCipher, err := crypto.NewCipher(passwordKey) if err != nil { return nil, nil, err } key := crypto.NewKey() keyCipher, err := crypto.NewCipher(key) if err != nil { return nil, nil, err } insert, err := tx.Prepare(` INSERT INTO settings (password_salt, password_stretch, password_nonce, encrypted_key, key_nonce, version) VALUES (?, ?, ?, ?, ?, ?) `) if err != nil { return nil, nil, err } defer insert.Close() encryptedKey := passwordCipher.Encrypt(key) insert.Exec( passwordSalt, passwordStretch, passwordCipher.GetNonce(), encryptedKey, keyCipher.GetNonce(), version) return passwordCipher, keyCipher, nil }
func (s *CryptoSuite) TestNewLoadCipher(c *C) { key := crypto.NewKey() newCipher, _ := crypto.NewCipher(key) loadCipher, _ := crypto.LoadCipher(key, newCipher.GetNonce()) c.Assert(loadCipher, NotNil) c.Assert(loadCipher.GetNonce(), DeepEquals, newCipher.GetNonce()) }
func (s *CryptoSuite) TestTryDecrypt(c *C) { cipher, _ := crypto.NewCipher(crypto.NewKey()) plaintext := []byte{1, 2, 3, 4, 5} ciphertext := cipher.Encrypt(plaintext) plaintextVerify, err := cipher.TryDecrypt(ciphertext) c.Assert(err, IsNil) c.Assert(plaintextVerify, NotNil) c.Assert(plaintextVerify, DeepEquals, plaintext) }
func (s *CryptoSuite) TestDecrypt(c *C) { key := crypto.NewKey() encipher, _ := crypto.NewCipher(key) plaintext := []byte{1, 2, 3, 4, 5} ciphertext := encipher.Encrypt(plaintext) decipher, _ := crypto.LoadCipher(key, encipher.GetNonce()) plaintextVerify := decipher.Decrypt(ciphertext) c.Assert(plaintextVerify, NotNil) c.Assert(plaintextVerify, DeepEquals, plaintext) }
func (s *CryptoSuite) TestTryDecryptFail(c *C) { key := crypto.NewKey() encipher, _ := crypto.NewCipher(key) plaintext := []byte{1, 2, 3, 4, 5} ciphertext := encipher.Encrypt(plaintext) newKey := crypto.NewKey() c.Assert(key, Not(DeepEquals), newKey) decipher, _ := crypto.LoadCipher(newKey, encipher.GetNonce()) plaintextVerify, err := decipher.TryDecrypt(ciphertext) c.Assert(err, NotNil) c.Assert(len(plaintextVerify), Equals, 0) }
func (store *Store) UpdateMasterPassword(password string, passwordStretch int) error { return store.update(func(tx *sql.Tx) error { query := "SELECT encrypted_key FROM settings" rows, err := tx.Query(query) if err != nil { return err } defer rows.Close() rows.Next() var encryptedKey []byte rows.Scan(&encryptedKey) key := store.passwordCipher.Decrypt(encryptedKey) passwordKey, passwordSalt, err := crypto.NewPasswordKey(password, passwordStretch) if err != nil { return err } passwordCipher, err := crypto.NewCipher(passwordKey) if err != nil { return err } update, err := tx.Prepare(` UPDATE settings SET password_salt=?, password_stretch=?, password_nonce=?, encrypted_key=? `) if err != nil { return err } defer update.Close() update.Exec( passwordSalt, passwordStretch, passwordCipher.GetNonce(), passwordCipher.Encrypt(key)) store.passwordCipher = passwordCipher return nil }) }
func (s *CryptoSuite) TestEncrypt(c *C) { cipher, _ := crypto.NewCipher(crypto.NewKey()) nonce0 := cipher.GetNonce() plaintext := []byte{1, 2, 3, 4, 5} ciphertext1 := cipher.Encrypt(plaintext) nonce1 := cipher.GetNonce() c.Assert(ciphertext1, NotNil) c.Assert(len(ciphertext1), Not(Equals), 0) c.Assert(ciphertext1, Not(DeepEquals), plaintext) c.Assert(nonce0, Not(DeepEquals), nonce1) ciphertext2 := cipher.Encrypt(plaintext) nonce2 := cipher.GetNonce() c.Assert(ciphertext2, Not(DeepEquals), plaintext) c.Assert(ciphertext2, Not(DeepEquals), ciphertext1) c.Assert(nonce1, Not(DeepEquals), nonce2) }
func (s *CryptoSuite) TestGetNonce(c *C) { cipher, _ := crypto.NewCipher(crypto.NewKey()) nonce := cipher.GetNonce() c.Assert(nonce, NotNil) }
func (s *CryptoSuite) TestNewCipherFail(c *C) { cipher, err := crypto.NewCipher([]byte{}) c.Assert(cipher, IsNil) c.Assert(err, NotNil) }
func (s *CryptoSuite) TestNewCipher(c *C) { cipher, err := crypto.NewCipher(crypto.NewKey()) c.Assert(cipher, NotNil) c.Assert(err, IsNil) }