Source file
src/crypto/rsa/pss_test.go
1
2
3
4
5 package rsa_test
6
7 import (
8 "bufio"
9 "bytes"
10 "compress/bzip2"
11 "crypto"
12 "crypto/rand"
13 . "crypto/rsa"
14 "crypto/sha1"
15 "crypto/sha256"
16 "crypto/sha512"
17 "encoding/hex"
18 "math/big"
19 "os"
20 "strconv"
21 "strings"
22 "testing"
23 )
24
25 func TestEMSAPSS(t *testing.T) {
26
27 msg := []byte{
28 0x85, 0x9e, 0xef, 0x2f, 0xd7, 0x8a, 0xca, 0x00, 0x30, 0x8b,
29 0xdc, 0x47, 0x11, 0x93, 0xbf, 0x55, 0xbf, 0x9d, 0x78, 0xdb,
30 0x8f, 0x8a, 0x67, 0x2b, 0x48, 0x46, 0x34, 0xf3, 0xc9, 0xc2,
31 0x6e, 0x64, 0x78, 0xae, 0x10, 0x26, 0x0f, 0xe0, 0xdd, 0x8c,
32 0x08, 0x2e, 0x53, 0xa5, 0x29, 0x3a, 0xf2, 0x17, 0x3c, 0xd5,
33 0x0c, 0x6d, 0x5d, 0x35, 0x4f, 0xeb, 0xf7, 0x8b, 0x26, 0x02,
34 0x1c, 0x25, 0xc0, 0x27, 0x12, 0xe7, 0x8c, 0xd4, 0x69, 0x4c,
35 0x9f, 0x46, 0x97, 0x77, 0xe4, 0x51, 0xe7, 0xf8, 0xe9, 0xe0,
36 0x4c, 0xd3, 0x73, 0x9c, 0x6b, 0xbf, 0xed, 0xae, 0x48, 0x7f,
37 0xb5, 0x56, 0x44, 0xe9, 0xca, 0x74, 0xff, 0x77, 0xa5, 0x3c,
38 0xb7, 0x29, 0x80, 0x2f, 0x6e, 0xd4, 0xa5, 0xff, 0xa8, 0xba,
39 0x15, 0x98, 0x90, 0xfc,
40 }
41 salt := []byte{
42 0xe3, 0xb5, 0xd5, 0xd0, 0x02, 0xc1, 0xbc, 0xe5, 0x0c, 0x2b,
43 0x65, 0xef, 0x88, 0xa1, 0x88, 0xd8, 0x3b, 0xce, 0x7e, 0x61,
44 }
45 expected := []byte{
46 0x66, 0xe4, 0x67, 0x2e, 0x83, 0x6a, 0xd1, 0x21, 0xba, 0x24,
47 0x4b, 0xed, 0x65, 0x76, 0xb8, 0x67, 0xd9, 0xa4, 0x47, 0xc2,
48 0x8a, 0x6e, 0x66, 0xa5, 0xb8, 0x7d, 0xee, 0x7f, 0xbc, 0x7e,
49 0x65, 0xaf, 0x50, 0x57, 0xf8, 0x6f, 0xae, 0x89, 0x84, 0xd9,
50 0xba, 0x7f, 0x96, 0x9a, 0xd6, 0xfe, 0x02, 0xa4, 0xd7, 0x5f,
51 0x74, 0x45, 0xfe, 0xfd, 0xd8, 0x5b, 0x6d, 0x3a, 0x47, 0x7c,
52 0x28, 0xd2, 0x4b, 0xa1, 0xe3, 0x75, 0x6f, 0x79, 0x2d, 0xd1,
53 0xdc, 0xe8, 0xca, 0x94, 0x44, 0x0e, 0xcb, 0x52, 0x79, 0xec,
54 0xd3, 0x18, 0x3a, 0x31, 0x1f, 0xc8, 0x96, 0xda, 0x1c, 0xb3,
55 0x93, 0x11, 0xaf, 0x37, 0xea, 0x4a, 0x75, 0xe2, 0x4b, 0xdb,
56 0xfd, 0x5c, 0x1d, 0xa0, 0xde, 0x7c, 0xec, 0xdf, 0x1a, 0x89,
57 0x6f, 0x9d, 0x8b, 0xc8, 0x16, 0xd9, 0x7c, 0xd7, 0xa2, 0xc4,
58 0x3b, 0xad, 0x54, 0x6f, 0xbe, 0x8c, 0xfe, 0xbc,
59 }
60
61 hash := sha1.New()
62 hash.Write(msg)
63 hashed := hash.Sum(nil)
64
65 encoded, err := EMSAPSSEncode(hashed, 1023, salt, sha1.New())
66 if err != nil {
67 t.Errorf("Error from emsaPSSEncode: %s\n", err)
68 }
69 if !bytes.Equal(encoded, expected) {
70 t.Errorf("Bad encoding. got %x, want %x", encoded, expected)
71 }
72
73 if err = EMSAPSSVerify(hashed, encoded, 1023, len(salt), sha1.New()); err != nil {
74 t.Errorf("Bad verification: %s", err)
75 }
76 }
77
78
79
80 func TestPSSGolden(t *testing.T) {
81 inFile, err := os.Open("testdata/pss-vect.txt.bz2")
82 if err != nil {
83 t.Fatalf("Failed to open input file: %s", err)
84 }
85 defer inFile.Close()
86
87
88
89
90
91 const newKeyMarker = "START NEW KEY"
92 const newSignatureMarker = "START NEW SIGNATURE"
93
94 values := make(chan string)
95
96 go func() {
97 defer close(values)
98 scanner := bufio.NewScanner(bzip2.NewReader(inFile))
99 var partialValue string
100 lastWasValue := true
101
102 for scanner.Scan() {
103 line := scanner.Text()
104 switch {
105 case len(line) == 0:
106 if len(partialValue) > 0 {
107 values <- strings.ReplaceAll(partialValue, " ", "")
108 partialValue = ""
109 lastWasValue = true
110 }
111 continue
112 case strings.HasPrefix(line, "# ======") && lastWasValue:
113 values <- newKeyMarker
114 lastWasValue = false
115 case strings.HasPrefix(line, "# ------") && lastWasValue:
116 values <- newSignatureMarker
117 lastWasValue = false
118 case strings.HasPrefix(line, "#"):
119 continue
120 default:
121 partialValue += line
122 }
123 }
124 if err := scanner.Err(); err != nil {
125 panic(err)
126 }
127 }()
128
129 var key *PublicKey
130 var hashed []byte
131 hash := crypto.SHA1
132 h := hash.New()
133 opts := &PSSOptions{
134 SaltLength: PSSSaltLengthEqualsHash,
135 }
136
137 for marker := range values {
138 switch marker {
139 case newKeyMarker:
140 key = new(PublicKey)
141 nHex, ok := <-values
142 if !ok {
143 continue
144 }
145 key.N = bigFromHex(nHex)
146 key.E = intFromHex(<-values)
147
148 for i := 0; i < 6; i++ {
149 <-values
150 }
151 case newSignatureMarker:
152 msg := fromHex(<-values)
153 <-values
154 sig := fromHex(<-values)
155
156 h.Reset()
157 h.Write(msg)
158 hashed = h.Sum(hashed[:0])
159
160 if err := VerifyPSS(key, hash, hashed, sig, opts); err != nil {
161 t.Error(err)
162 }
163 default:
164 t.Fatalf("unknown marker: %s", marker)
165 }
166 }
167 }
168
169
170
171 func TestPSSOpenSSL(t *testing.T) {
172 hash := crypto.SHA256
173 h := hash.New()
174 h.Write([]byte("testing"))
175 hashed := h.Sum(nil)
176
177
178 sig := []byte{
179 0x95, 0x59, 0x6f, 0xd3, 0x10, 0xa2, 0xe7, 0xa2, 0x92, 0x9d,
180 0x4a, 0x07, 0x2e, 0x2b, 0x27, 0xcc, 0x06, 0xc2, 0x87, 0x2c,
181 0x52, 0xf0, 0x4a, 0xcc, 0x05, 0x94, 0xf2, 0xc3, 0x2e, 0x20,
182 0xd7, 0x3e, 0x66, 0x62, 0xb5, 0x95, 0x2b, 0xa3, 0x93, 0x9a,
183 0x66, 0x64, 0x25, 0xe0, 0x74, 0x66, 0x8c, 0x3e, 0x92, 0xeb,
184 0xc6, 0xe6, 0xc0, 0x44, 0xf3, 0xb4, 0xb4, 0x2e, 0x8c, 0x66,
185 0x0a, 0x37, 0x9c, 0x69,
186 }
187
188 if err := VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, nil); err != nil {
189 t.Error(err)
190 }
191 }
192
193 func TestPSSNilOpts(t *testing.T) {
194 hash := crypto.SHA256
195 h := hash.New()
196 h.Write([]byte("testing"))
197 hashed := h.Sum(nil)
198
199 SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, nil)
200 }
201
202 func TestPSSSigning(t *testing.T) {
203 var saltLengthCombinations = []struct {
204 signSaltLength, verifySaltLength int
205 good bool
206 }{
207 {PSSSaltLengthAuto, PSSSaltLengthAuto, true},
208 {PSSSaltLengthEqualsHash, PSSSaltLengthAuto, true},
209 {PSSSaltLengthEqualsHash, PSSSaltLengthEqualsHash, true},
210 {PSSSaltLengthEqualsHash, 8, false},
211 {PSSSaltLengthAuto, PSSSaltLengthEqualsHash, false},
212 {8, 8, true},
213 {PSSSaltLengthAuto, 42, true},
214 {PSSSaltLengthAuto, 20, false},
215 {PSSSaltLengthAuto, -2, false},
216 }
217
218 hash := crypto.SHA1
219 h := hash.New()
220 h.Write([]byte("testing"))
221 hashed := h.Sum(nil)
222 var opts PSSOptions
223
224 for i, test := range saltLengthCombinations {
225 opts.SaltLength = test.signSaltLength
226 sig, err := SignPSS(rand.Reader, rsaPrivateKey, hash, hashed, &opts)
227 if err != nil {
228 t.Errorf("#%d: error while signing: %s", i, err)
229 continue
230 }
231
232 opts.SaltLength = test.verifySaltLength
233 err = VerifyPSS(&rsaPrivateKey.PublicKey, hash, hashed, sig, &opts)
234 if (err == nil) != test.good {
235 t.Errorf("#%d: bad result, wanted: %t, got: %s", i, test.good, err)
236 }
237 }
238 }
239
240 func TestPSS513(t *testing.T) {
241
242
243
244 key, err := GenerateKey(rand.Reader, 513)
245 if err != nil {
246 t.Fatal(err)
247 }
248 digest := sha256.Sum256([]byte("message"))
249 signature, err := key.Sign(rand.Reader, digest[:], &PSSOptions{
250 SaltLength: PSSSaltLengthAuto,
251 Hash: crypto.SHA256,
252 })
253 if err != nil {
254 t.Fatal(err)
255 }
256 err = VerifyPSS(&key.PublicKey, crypto.SHA256, digest[:], signature, nil)
257 if err != nil {
258 t.Error(err)
259 }
260 }
261
262 func bigFromHex(hex string) *big.Int {
263 n, ok := new(big.Int).SetString(hex, 16)
264 if !ok {
265 panic("bad hex: " + hex)
266 }
267 return n
268 }
269
270 func intFromHex(hex string) int {
271 i, err := strconv.ParseInt(hex, 16, 32)
272 if err != nil {
273 panic(err)
274 }
275 return int(i)
276 }
277
278 func fromHex(hexStr string) []byte {
279 s, err := hex.DecodeString(hexStr)
280 if err != nil {
281 panic(err)
282 }
283 return s
284 }
285
286 func TestInvalidPSSSaltLength(t *testing.T) {
287 key, err := GenerateKey(rand.Reader, 245)
288 if err != nil {
289 t.Fatal(err)
290 }
291
292 digest := sha256.Sum256([]byte("message"))
293
294
295 if _, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{
296 SaltLength: -2,
297 Hash: crypto.SHA256,
298 }); err.Error() != InvalidSaltLenErr.Error() {
299 t.Fatalf("SignPSS unexpected error: got %v, want %v", err, InvalidSaltLenErr)
300 }
301
302
303
304 if err := VerifyPSS(&key.PublicKey, crypto.SHA256, []byte{1, 2, 3}, make([]byte, 31), &PSSOptions{
305 SaltLength: -2,
306 }); err == nil {
307 t.Fatal("VerifyPSS unexpected success")
308 }
309 }
310
311 func TestHashOverride(t *testing.T) {
312 key, err := GenerateKey(rand.Reader, 1024)
313 if err != nil {
314 t.Fatal(err)
315 }
316
317 digest := sha512.Sum512([]byte("message"))
318
319 sig, err := SignPSS(rand.Reader, key, crypto.SHA256, digest[:], &PSSOptions{Hash: crypto.SHA512})
320 if err != nil {
321 t.Fatalf("SignPSS unexpected error: got %v, want nil", err)
322 }
323
324
325 if err := VerifyPSS(&key.PublicKey, crypto.SHA512, digest[:], sig, &PSSOptions{Hash: crypto.SHA256}); err != nil {
326 t.Fatalf("VerifyPSS unexpected error: got %v, want nil", err)
327 }
328 }
329
View as plain text