commit 8f325a33327480535fe20215d2a278cce7fc8b18
parent f3997de0ff6b8eeed1deba9d7d8177fc6b42a392
Author: Sean Enck <sean@ttypty.com>
Date: Sun, 18 Sep 2022 13:10:02 -0400
restructure some encrypt/decrypt, better errors for bad data
Diffstat:
2 files changed, 58 insertions(+), 14 deletions(-)
diff --git a/internal/encrypt/core.go b/internal/encrypt/core.go
@@ -23,8 +23,11 @@ const (
)
var (
- cryptoVers = []byte{0, 1}
- cryptoVersLength = len(cryptoVers)
+ cryptoMajorVers = uint8(0)
+ cryptoMinorVers = uint8(1)
+ cryptoVers = []byte{cryptoMajorVers, cryptoMinorVers}
+ cryptoVersLength = len(cryptoVers)
+ requiredEncryptLength = cryptoVersLength + saltLength + nonceLength
)
type (
@@ -91,11 +94,6 @@ func init() {
// Encrypt will encrypt contents to file.
func (l Lockbox) Encrypt(datum []byte) error {
- var nonce [nonceLength]byte
- padTo := random.Intn(padLength)
- if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
- return err
- }
data := datum
if data == nil {
b, err := inputs.RawStdin()
@@ -104,18 +102,26 @@ func (l Lockbox) Encrypt(datum []byte) error {
}
data = b
}
+ if len(data) == 0 {
+ return errors.New("no data")
+ }
var padding [padLength]byte
if _, err := io.ReadFull(rand.Reader, padding[:]); err != nil {
return err
}
- var salt [saltLength]byte
- if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
- return err
- }
+ padTo := random.Intn(padLength)
var write []byte
write = append(write, byte(padTo))
write = append(write, padding[0:padTo]...)
write = append(write, data...)
+ var salt [saltLength]byte
+ if _, err := io.ReadFull(rand.Reader, salt[:]); err != nil {
+ return err
+ }
+ var nonce [nonceLength]byte
+ if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
+ return err
+ }
key, err := pad(salt[:], l.secret[:])
if err != nil {
return err
@@ -130,18 +136,26 @@ func (l Lockbox) Encrypt(datum []byte) error {
// Decrypt will decrypt an object from file.
func (l Lockbox) Decrypt() ([]byte, error) {
- var nonce [nonceLength]byte
- var salt [saltLength]byte
encrypted, err := os.ReadFile(l.file)
if err != nil {
return nil, err
}
+ if len(encrypted) <= requiredEncryptLength {
+ return nil, errors.New("invalid encrypted data")
+ }
+ major := encrypted[0]
+ minor := encrypted[1]
+ if major != cryptoMajorVers || minor != cryptoMinorVers {
+ return nil, errors.New("invalid data, bad header")
+ }
+ var salt [saltLength]byte
copy(salt[:], encrypted[cryptoVersLength:saltLength+cryptoVersLength])
- copy(nonce[:], encrypted[cryptoVersLength+saltLength:cryptoVersLength+saltLength+nonceLength])
key, err := pad(salt[:], l.secret[:])
if err != nil {
return nil, err
}
+ var nonce [nonceLength]byte
+ copy(nonce[:], encrypted[cryptoVersLength+saltLength:cryptoVersLength+saltLength+nonceLength])
decrypted, ok := secretbox.Open(nil, encrypted[cryptoVersLength+saltLength+nonceLength:], &nonce, &key)
if !ok {
return nil, errors.New("decrypt not ok")
diff --git a/internal/encrypt/core_test.go b/internal/encrypt/core_test.go
@@ -91,3 +91,33 @@ func TestEncryptDecryptPlainText(t *testing.T) {
t.Error("data mismatch")
}
}
+
+func TestEncryptDecryptErrors(t *testing.T) {
+ file := setupData(t)
+ e, _ := encrypt.NewLockbox(encrypt.LockboxOptions{Key: "plain", KeyMode: inputs.PlainKeyMode, File: file})
+ if err := e.Encrypt([]byte{}); err.Error() != "no data" {
+ t.Errorf("failed, should be no data: %v", err)
+ }
+ os.WriteFile(file, []byte{0, 2, 3}, 0600)
+ if _, err := e.Decrypt(); err.Error() != "invalid encrypted data" {
+ t.Errorf("failed, should be invalid data: %v", err)
+ }
+ e.Encrypt([]byte("TEST"))
+ b, _ := os.ReadFile(file)
+ b[0] = 1
+ os.WriteFile(file, b, 0600)
+ if _, err := e.Decrypt(); err.Error() != "invalid data, bad header" {
+ t.Errorf("failed, should be invalid header data: %v", err)
+ }
+ b[0] = 0
+ b[1] = 0
+ os.WriteFile(file, b, 0600)
+ if _, err := e.Decrypt(); err.Error() != "invalid data, bad header" {
+ t.Errorf("failed, should be invalid header data: %v", err)
+ }
+ b[1] = 1
+ os.WriteFile(file, b, 0600)
+ if _, err := e.Decrypt(); err != nil {
+ t.Error("decrypt should succeed")
+ }
+}