Add error handling for encryption routines
This commit is contained in:
parent
6ac5754075
commit
f798ef3825
|
@ -9,6 +9,7 @@ import (
|
|||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
|
@ -170,7 +171,7 @@ func isMacValid(message, messageMAC, key []byte) bool {
|
|||
return hmac.Equal(messageMAC, expectedMAC)
|
||||
}
|
||||
|
||||
func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, _ error) {
|
||||
func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, err error) {
|
||||
data = padPKCS7(data, aes.BlockSize)
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
|
@ -182,12 +183,28 @@ func encryptAESCBC256(data, key []byte) (iv, ciphertext []byte, _ error) {
|
|||
if _, err := io.ReadFull(cryptorand.Reader, iv); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
var ok bool
|
||||
err, ok = r.(error)
|
||||
if !ok {
|
||||
iv = nil
|
||||
ciphertext = nil
|
||||
err = errors.New("error encrypting AES CBC 256 data")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
mode := cipher.NewCBCEncrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext, data)
|
||||
return iv, ciphertext, nil
|
||||
}
|
||||
|
||||
func decryptAESCBC256(iv, ciphertext, key []byte) ([]byte, error) {
|
||||
func decryptAESCBC256(iv, ciphertext, key []byte) (decryptedData []byte, err error) {
|
||||
ciphertextCopy := make([]byte, len(ciphertext))
|
||||
copy(ciphertextCopy, ciphertext)
|
||||
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -195,28 +212,50 @@ func decryptAESCBC256(iv, ciphertext, key []byte) ([]byte, error) {
|
|||
if len(iv) != aes.BlockSize {
|
||||
return nil, fmt.Errorf("iv length does not match AES block size")
|
||||
}
|
||||
if len(ciphertext)%aes.BlockSize != 0 {
|
||||
if len(ciphertextCopy)%aes.BlockSize != 0 {
|
||||
return nil, fmt.Errorf("ciphertext is not a multiple of AES block size")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
var ok bool
|
||||
err, ok = r.(error)
|
||||
if !ok {
|
||||
decryptedData = nil
|
||||
err = errors.New("error decrypting AES CBC 256 data")
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(ciphertext, ciphertext) // decrypt in-place
|
||||
data, err := unpadPKCS7(ciphertext, aes.BlockSize)
|
||||
mode.CryptBlocks(ciphertextCopy, ciphertextCopy) // decrypt in-place
|
||||
data, err := unpadPKCS7(ciphertextCopy, aes.BlockSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
|
||||
resultBuffer := make([]byte, len(data))
|
||||
copy(resultBuffer, data)
|
||||
return resultBuffer, nil
|
||||
}
|
||||
|
||||
func unpadPKCS7(src []byte, size int) ([]byte, error) {
|
||||
n := src[len(src)-1]
|
||||
if len(src)%size != 0 {
|
||||
return nil, fmt.Errorf("expected PKCS7 padding for block size %d, but have %d bytes", size, len(src))
|
||||
srcCopy := make([]byte, len(src))
|
||||
copy(srcCopy, src)
|
||||
|
||||
n := srcCopy[len(srcCopy)-1]
|
||||
if len(srcCopy)%size != 0 {
|
||||
return nil, fmt.Errorf("expected PKCS7 padding for block size %d, but have %d bytes", size, len(srcCopy))
|
||||
}
|
||||
if len(src) <= int(n) {
|
||||
return nil, fmt.Errorf("cannot unpad %d bytes out of a total of %d", n, len(src))
|
||||
if len(srcCopy) <= int(n) {
|
||||
return nil, fmt.Errorf("cannot unpad %d bytes out of a total of %d", n, len(srcCopy))
|
||||
}
|
||||
src = src[:len(src)-int(n)]
|
||||
return src, nil
|
||||
srcCopy = srcCopy[:len(srcCopy)-int(n)]
|
||||
|
||||
resultCopy := make([]byte, len(srcCopy))
|
||||
copy(resultCopy, srcCopy)
|
||||
|
||||
return resultCopy, nil
|
||||
}
|
||||
|
||||
func padPKCS7(src []byte, size int) []byte {
|
||||
|
|
|
@ -2,8 +2,6 @@ package crypto
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
|
@ -12,12 +10,14 @@ import (
|
|||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
"github.com/quexten/goldwarden/logging"
|
||||
)
|
||||
|
||||
var cryptoLog = logging.GetLogger("Goldwarden", "Crypto")
|
||||
|
||||
type EncString struct {
|
||||
Type EncStringType
|
||||
IV, CT, MAC []byte
|
||||
|
@ -131,11 +131,6 @@ func DecryptWith(s EncString, key SymmetricEncryptionKey) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(encKeyData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch s.Type {
|
||||
case AesCbc256_B64, AesCbc256_HmacSha256_B64:
|
||||
break
|
||||
|
@ -161,13 +156,11 @@ func DecryptWith(s EncString, key SymmetricEncryptionKey) ([]byte, error) {
|
|||
return nil, fmt.Errorf("decrypt: invalid IV length, expected %d, got %d", block.BlockSize(), len(s.IV))
|
||||
}
|
||||
|
||||
mode := cipher.NewCBCDecrypter(block, s.IV)
|
||||
dst := make([]byte, len(s.CT))
|
||||
mode.CryptBlocks(dst, s.CT)
|
||||
dst, err = unpadPKCS7(dst, aes.BlockSize)
|
||||
dst, err := decryptAESCBC256(s.IV, s.CT, encKeyData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
|
@ -188,19 +181,13 @@ func EncryptWith(data []byte, encType EncStringType, key SymmetricEncryptionKey)
|
|||
return s, fmt.Errorf("encrypt: unsupported cipher type %q", s.Type)
|
||||
}
|
||||
s.Type = encType
|
||||
data = padPKCS7(data, aes.BlockSize)
|
||||
|
||||
block, err := aes.NewCipher(encKeyData)
|
||||
iv, ciphertext, err := encryptAESCBC256(data, encKeyData)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
s.IV = make([]byte, aes.BlockSize)
|
||||
if _, err := io.ReadFull(rand.Reader, s.IV); err != nil {
|
||||
return s, err
|
||||
}
|
||||
s.CT = make([]byte, len(data))
|
||||
mode := cipher.NewCBCEncrypter(block, s.IV)
|
||||
mode.CryptBlocks(s.CT, data)
|
||||
s.CT = ciphertext
|
||||
s.IV = iv
|
||||
|
||||
if encType == AesCbc256_HmacSha256_B64 {
|
||||
if len(macKeyData) == 0 {
|
||||
|
|
Loading…
Reference in New Issue