File: symmetric_key_encrypted_test.go

package info (click to toggle)
golang-github-protonmail-go-crypto 0.0~git20230124.0acdc8a-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-backports
  • size: 1,304 kB
  • sloc: makefile: 7
file content (167 lines) | stat: -rw-r--r-- 4,331 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package packet

import (
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"io"
	"io/ioutil"
	mathrand "math/rand"
	"testing"
)

const maxPassLen = 64

// Tests against RFC vectors
func TestDecryptSymmetricKeyAndEncryptedDataPacket(t *testing.T) {
	for _, testCase := range keyAndIpePackets {
		// Key
		buf := readerFromHex(testCase.packets)
		packet, err := Read(buf)
		if err != nil {
			t.Fatalf("failed to read SymmetricKeyEncrypted: %s", err)
		}
		ske, ok := packet.(*SymmetricKeyEncrypted)
		if !ok {
			t.Fatal("didn't find SymmetricKeyEncrypted packet")
		}
		// Decrypt key
		key, cipherFunc, err := ske.Decrypt([]byte(testCase.password))
		if err != nil {
			t.Fatal(err)
		}
		packet, err = Read(buf)
		if err != nil {
			t.Fatalf("failed to read SymmetricallyEncrypted: %s", err)
		}
		// Decrypt contents
		var edp EncryptedDataPacket
		switch packet.(type) {
		case *SymmetricallyEncrypted:
			edp, _ = packet.(*SymmetricallyEncrypted)
		case *AEADEncrypted:
			edp, _ = packet.(*AEADEncrypted)
		default:
			t.Fatal("no integrity protected packet")
		}
		r, err := edp.Decrypt(cipherFunc, key)
		if err != nil {
			t.Fatal(err)
		}

		contents, err := ioutil.ReadAll(r)
		if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
			t.Fatal(err)
		}

		expectedContents, _ := hex.DecodeString(testCase.contents)
		if !bytes.Equal(expectedContents, contents) {
			t.Errorf("bad contents got:%x want:%x", contents, expectedContents)
		}
	}
}

func TestSerializeSymmetricKeyEncryptedV5RandomizeSlow(t *testing.T) {
	ciphers := map[string] CipherFunction {
		"AES128": CipherAES128,
		"AES192": CipherAES192,
		"AES256": CipherAES256,
	}

	modes := map[string] AEADMode {
		"EAX": AEADModeEAX,
		"OCB": AEADModeOCB,
		"GCM": AEADModeGCM,
	}

	for cipherName, cipher := range ciphers {
		t.Run(cipherName, func(t *testing.T) {
			for modeName, mode := range modes {
				t.Run(modeName, func(t *testing.T) {
					var buf bytes.Buffer
					passphrase := randomKey(mathrand.Intn(maxPassLen))

					config := &Config{
						DefaultCipher: cipher,
						AEADConfig:    &AEADConfig{DefaultMode: mode},
					}

					key, err := SerializeSymmetricKeyEncrypted(&buf, passphrase, config)
					p, err := Read(&buf)
					if err != nil {
						t.Errorf("failed to reparse %s", err)
					}
					ske, ok := p.(*SymmetricKeyEncrypted)
					if !ok {
						t.Errorf("parsed a different packet type: %#v", p)
					}

					parsedKey, _, err := ske.Decrypt(passphrase)
					if err != nil {
						t.Errorf("failed to decrypt reparsed SKE: %s", err)
					}
					if !bytes.Equal(key, parsedKey) {
						t.Errorf("keys don't match after Decrypt: %x (original) vs %x (parsed)", key, parsedKey)
					}
				})
			}
		})
	}
}

func TestSerializeSymmetricKeyEncryptedCiphersV4(t *testing.T) {
	tests := map[string] CipherFunction {
		"3DES": Cipher3DES,
		"CAST5": CipherCAST5,
		"AES128": CipherAES128,
		"AES192": CipherAES192,
		"AES256": CipherAES256,
	}

	for cipherName, cipher := range tests {
		t.Run(cipherName, func(t *testing.T) {
			var buf bytes.Buffer
			passphrase := make([]byte, mathrand.Intn(maxPassLen))
			if _, err := rand.Read(passphrase); err != nil {
				panic(err)
			}
			config := &Config{
				DefaultCipher: cipher,
			}

			key, err := SerializeSymmetricKeyEncrypted(&buf, passphrase, config)
			if err != nil {
				t.Fatalf("failed to serialize: %s", err)
			}

			p, err := Read(&buf)
			if err != nil {
				t.Fatalf("failed to reparse: %s", err)
			}

			ske, ok := p.(*SymmetricKeyEncrypted)
			if !ok {
				t.Fatalf("parsed a different packet type: %#v", p)
			}

			if ske.CipherFunc != config.DefaultCipher {
				t.Fatalf("SKE cipher function is %d (expected %d)", ske.CipherFunc, config.DefaultCipher)
			}
			parsedKey, parsedCipherFunc, err := ske.Decrypt(passphrase)
			if err != nil {
				t.Fatalf("failed to decrypt reparsed SKE: %s", err)
			}
			if !bytes.Equal(key, parsedKey) {
				t.Fatalf("keys don't match after Decrypt: %x (original) vs %x (parsed)", key, parsedKey)
			}
			if parsedCipherFunc != cipher {
				t.Fatalf("cipher function doesn't match after Decrypt: %d (original) vs %d (parsed)",
					cipher, parsedCipherFunc)
			}
		})
	}
}