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