Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oxisto committed Dec 28, 2023
1 parent 458db31 commit 4436b7f
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 13 deletions.
19 changes: 9 additions & 10 deletions storage/pem.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,11 @@ func EncryptPEMBlock(rand io.Reader, data, password []byte) (block *pem.Block, e
sha256.New,
)

// Set up symmetric encryption of our block
cipherBlock, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("could not create AES cipher mode: %w", err)
}

// Set up symmetric encryption of our block. We can safely ignore the errors
// here, because the only error which can occur in aes.NewCipher is an
// invalid key size and the above line makes sure we always have a 32 bytes
// key.
cipherBlock, _ := aes.NewCipher(key)
mode := cipher.NewCBCEncrypter(cipherBlock, keyInfo.EncryptionAlgorithm.Params.EncryptionScheme.IV)

copy(keyInfo.EncryptedData, data)
Expand Down Expand Up @@ -227,11 +226,11 @@ func DecryptPEMBlock(block *pem.Block, password []byte) ([]byte, error) {
keyHash := sha256.New

symkey := pbkdf2.Key(password, keyParams.Salt, keyParams.IterationCount, 32, keyHash)
cipherBlock, err := aes.NewCipher(symkey)
if err != nil {
return nil, fmt.Errorf("could not create AES cipher mode: %w", err)
}

// We can safely ignore the errors here, because the only error which can
// occur in aes.NewCipher is an invalid key size and the above line makes
// sure we always have a 32 bytes key.
cipherBlock, _ := aes.NewCipher(symkey)
mode := cipher.NewCBCDecrypter(cipherBlock, keyInfo.EncryptionAlgorithm.Params.EncryptionScheme.IV)
mode.CryptBlocks(keyInfo.EncryptedData, keyInfo.EncryptedData)

Expand Down
133 changes: 130 additions & 3 deletions storage/pem_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package storage

import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/asn1"
"encoding/pem"
"io"
"reflect"
"testing"
"testing/iotest"
)

func TestParseECPrivateKeyFromPEMWithPassword(t *testing.T) {
Expand Down Expand Up @@ -157,14 +160,86 @@ func TestDecryptPEMBlock(t *testing.T) {
wantErr: true,
},
{
name: "wrong algorithmn",
name: "wrong encryption algorithm",
args: args{
block: &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: func() []byte {
b, _ := asn1.Marshal(&EncryptedPrivateKeyInfo{
EncryptionAlgorithm: EncryptionAlgorithmIdentifier{},
b, err := asn1.Marshal(EncryptedPrivateKeyInfo{
EncryptionAlgorithm: EncryptionAlgorithmIdentifier{
Algorithm: asn1.ObjectIdentifier{0, 0},
Params: PBES2Params{
KeyDerivationFunc: KeyDerivationFunc{
Algorithm: oidPBKDF2,
},
EncryptionScheme: EncryptionScheme{
EncryptionAlgorithm: oidAESCBC,
},
},
},
})
if err != nil {
t.Fatal(err)
}
return b
}(),
},
},
wantErr: true,
},
{
name: "wrong key derivation algorithm",
args: args{
block: &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: func() []byte {
b, err := asn1.Marshal(EncryptedPrivateKeyInfo{
EncryptionAlgorithm: EncryptionAlgorithmIdentifier{
Algorithm: oidPBES2,
Params: PBES2Params{
KeyDerivationFunc: KeyDerivationFunc{
Algorithm: asn1.ObjectIdentifier{0, 0},
},
EncryptionScheme: EncryptionScheme{
EncryptionAlgorithm: oidAESCBC,
},
},
},
})
if err != nil {
t.Fatal(err)
}
return b
}(),
},
},
wantErr: true,
},
{
name: "wrong PRF",
args: args{
block: &pem.Block{
Type: "ENCRYPTED PRIVATE KEY",
Bytes: func() []byte {
b, err := asn1.Marshal(EncryptedPrivateKeyInfo{
EncryptionAlgorithm: EncryptionAlgorithmIdentifier{
Algorithm: oidPBES2,
Params: PBES2Params{
KeyDerivationFunc: KeyDerivationFunc{
Algorithm: oidPBKDF2,
PBKDF2Params: PBKDF2Params{
PRF: asn1.ObjectIdentifier{0, 0},
},
},
EncryptionScheme: EncryptionScheme{
EncryptionAlgorithm: oidAESCBC,
},
},
},
})
if err != nil {
t.Fatal(err)
}
return b
}(),
},
Expand All @@ -186,3 +261,55 @@ func TestDecryptPEMBlock(t *testing.T) {
})
}
}

func TestEncryptPEMBlock(t *testing.T) {
// manipulate OID to provoke an error
oidPBKDF2 = asn1.ObjectIdentifier{0}

type args struct {
rand io.Reader
data []byte
password []byte
}
tests := []struct {
name string
args args
wantBlock *pem.Block
wantErr bool
}{
{
name: "invalid rand",
args: args{
rand: iotest.ErrReader(io.EOF),
},
wantErr: true,
},
{
name: "invalid rand",
args: args{
rand: bytes.NewReader(make([]byte, 8)),
},
wantErr: true,
},
{
name: "invalid",
args: args{
rand: bytes.NewReader(make([]byte, 16)),
},
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotBlock, err := EncryptPEMBlock(tt.args.rand, tt.args.data, tt.args.password)
if (err != nil) != tt.wantErr {
t.Errorf("EncryptPEMBlock() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotBlock, tt.wantBlock) {
t.Errorf("EncryptPEMBlock() = %v, want %v", gotBlock, tt.wantBlock)
}
})
}
}

0 comments on commit 4436b7f

Please sign in to comment.