Beispiel #1
0
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
}
Beispiel #2
0
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())
}
Beispiel #3
0
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)
}
Beispiel #4
0
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)
}
Beispiel #5
0
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)
}
Beispiel #6
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
	})
}
Beispiel #7
0
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)
}
Beispiel #8
0
func (s *CryptoSuite) TestGetNonce(c *C) {
	cipher, _ := crypto.NewCipher(crypto.NewKey())
	nonce := cipher.GetNonce()
	c.Assert(nonce, NotNil)
}
Beispiel #9
0
func (s *CryptoSuite) TestNewCipherFail(c *C) {
	cipher, err := crypto.NewCipher([]byte{})
	c.Assert(cipher, IsNil)
	c.Assert(err, NotNil)
}
Beispiel #10
0
func (s *CryptoSuite) TestNewCipher(c *C) {
	cipher, err := crypto.NewCipher(crypto.NewKey())
	c.Assert(cipher, NotNil)
	c.Assert(err, IsNil)
}