From 15a14c8dc6d1ad721de4dbfc98eb8bd6e9e6eb1c Mon Sep 17 00:00:00 2001 From: Marius Date: Wed, 1 Nov 2017 17:06:57 +0100 Subject: [PATCH] Encrypt: Add support for AES-256-CBC --- pkcs7.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ pkcs7_test.go | 1 + 2 files changed, 51 insertions(+) diff --git a/pkcs7.go b/pkcs7.go index 8d5af85..4ee4570 100644 --- a/pkcs7.go +++ b/pkcs7.go @@ -15,6 +15,7 @@ import ( "encoding/asn1" "errors" "fmt" + "io" "math/big" "sort" "time" @@ -745,6 +746,7 @@ func DegenerateCertificate(cert []byte) ([]byte, error) { const ( EncryptionAlgorithmDESCBC = iota EncryptionAlgorithmAES128GCM + EncryptionAlgorithmAES256CBC ) // ContentEncryptionAlgorithm determines the algorithm used to encrypt the @@ -763,6 +765,51 @@ type aesGCMParameters struct { ICVLen int } +func encryptAES256CBC(content []byte) ([]byte, *encryptedContentInfo, error) { + // Create AES key + key := make([]byte, 32) + + _, err := rand.Read(key) + if err != nil { + return nil, nil, err + } + + // Encrypt content + block, err := aes.NewCipher(key) + if err != nil { + return nil, nil, err + } + + // Add padding + paddedPlaintext, err := pad(content, aes.BlockSize) + if err != nil { + return nil, nil, err + } + + ciphertext := make([]byte, aes.BlockSize+len(paddedPlaintext)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, nil, err + } + + mode := cipher.NewCBCEncrypter(block, iv) + mode.CryptBlocks(ciphertext[aes.BlockSize:], paddedPlaintext) + + eci := encryptedContentInfo{ + ContentType: oidData, + ContentEncryptionAlgorithm: pkix.AlgorithmIdentifier{ + Algorithm: oidEncryptionAlgorithmAES256CBC, + Parameters: asn1.RawValue{ + Tag: asn1.TagOctetString, + Bytes: iv, + }, + }, + EncryptedContent: marshalEncryptedContent(ciphertext[aes.BlockSize:]), + } + + return key, &eci, nil +} + func encryptAES128GCM(content []byte) ([]byte, *encryptedContentInfo, error) { // Create AES key and nonce key := make([]byte, 16) @@ -877,6 +924,9 @@ func Encrypt(content []byte, recipients []*x509.Certificate) ([]byte, error) { case EncryptionAlgorithmAES128GCM: key, eci, err = encryptAES128GCM(content) + case EncryptionAlgorithmAES256CBC: + key, eci, err = encryptAES256CBC(content) + default: return nil, ErrUnsupportedEncryptionAlgorithm } diff --git a/pkcs7_test.go b/pkcs7_test.go index cbe2c5c..39bfe44 100644 --- a/pkcs7_test.go +++ b/pkcs7_test.go @@ -251,6 +251,7 @@ func TestEncrypt(t *testing.T) { modes := []int{ EncryptionAlgorithmDESCBC, EncryptionAlgorithmAES128GCM, + EncryptionAlgorithmAES256CBC, } for _, mode := range modes {