1 // Copyright 2013 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
24 func TestEMSAPSS(t
*testing
.T
) {
25 // Test vector in file pss-int.txt from: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
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,
41 0xe3, 0xb5, 0xd5, 0xd0, 0x02, 0xc1, 0xbc, 0xe5, 0x0c, 0x2b,
42 0x65, 0xef, 0x88, 0xa1, 0x88, 0xd8, 0x3b, 0xce, 0x7e, 0x61,
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,
62 hashed
:= hash
.Sum(nil)
64 encoded
, err
:= emsaPSSEncode(hashed
, 1023, salt
, sha1
.New())
66 t
.Errorf("Error from emsaPSSEncode: %s\n", err
)
68 if !bytes
.Equal(encoded
, expected
) {
69 t
.Errorf("Bad encoding. got %x, want %x", encoded
, expected
)
72 if err
= emsaPSSVerify(hashed
, encoded
, 1023, len(salt
), sha1
.New()); err
!= nil {
73 t
.Errorf("Bad verification: %s", err
)
77 // TestPSSGolden tests all the test vectors in pss-vect.txt from
78 // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1-vec.zip
79 func TestPSSGolden(t
*testing
.T
) {
80 inFile
, err
:= os
.Open("testdata/pss-vect.txt.bz2")
82 t
.Fatalf("Failed to open input file: %s", err
)
86 // The pss-vect.txt file contains RSA keys and then a series of
87 // signatures. A goroutine is used to preprocess the input by merging
88 // lines, removing spaces in hex values and identifying the start of
89 // new keys and signature blocks.
90 const newKeyMarker
= "START NEW KEY"
91 const newSignatureMarker
= "START NEW SIGNATURE"
93 values
:= make(chan string)
97 scanner
:= bufio
.NewScanner(bzip2
.NewReader(inFile
))
98 var partialValue
string
102 line
:= scanner
.Text()
105 if len(partialValue
) > 0 {
106 values
<- strings
.Replace(partialValue
, " ", "", -1)
111 case strings
.HasPrefix(line
, "# ======") && lastWasValue
:
112 values
<- newKeyMarker
114 case strings
.HasPrefix(line
, "# ------") && lastWasValue
:
115 values
<- newSignatureMarker
117 case strings
.HasPrefix(line
, "#"):
123 if err
:= scanner
.Err(); err
!= nil {
133 SaltLength
: PSSSaltLengthEqualsHash
,
136 for marker
:= range values
{
144 key
.N
= bigFromHex(nHex
)
145 key
.E
= intFromHex(<-values
)
146 // We don't care for d, p, q, dP, dQ or qInv.
147 for i
:= 0; i
< 6; i
++ {
150 case newSignatureMarker
:
151 msg
:= fromHex(<-values
)
152 <-values
// skip salt
153 sig
:= fromHex(<-values
)
157 hashed
= h
.Sum(hashed
[:0])
159 if err
:= VerifyPSS(key
, hash
, hashed
, sig
, opts
); err
!= nil {
163 t
.Fatalf("unknown marker: " + marker
)
168 // TestPSSOpenSSL ensures that we can verify a PSS signature from OpenSSL with
169 // the default options. OpenSSL sets the salt length to be maximal.
170 func TestPSSOpenSSL(t
*testing
.T
) {
171 hash
:= crypto
.SHA256
173 h
.Write([]byte("testing"))
176 // Generated with `echo -n testing | openssl dgst -sign key.pem -sigopt rsa_padding_mode:pss -sha256 > sig`
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,
187 if err
:= VerifyPSS(&rsaPrivateKey
.PublicKey
, hash
, hashed
, sig
, nil); err
!= nil {
192 func TestPSSNilOpts(t
*testing
.T
) {
193 hash
:= crypto
.SHA256
195 h
.Write([]byte("testing"))
198 SignPSS(rand
.Reader
, rsaPrivateKey
, hash
, hashed
, nil)
201 func TestPSSSigning(t
*testing
.T
) {
202 var saltLengthCombinations
= []struct {
203 signSaltLength
, verifySaltLength
int
206 {PSSSaltLengthAuto
, PSSSaltLengthAuto
, true},
207 {PSSSaltLengthEqualsHash
, PSSSaltLengthAuto
, true},
208 {PSSSaltLengthEqualsHash
, PSSSaltLengthEqualsHash
, true},
209 {PSSSaltLengthEqualsHash
, 8, false},
210 {PSSSaltLengthAuto
, PSSSaltLengthEqualsHash
, false},
216 h
.Write([]byte("testing"))
220 for i
, test
:= range saltLengthCombinations
{
221 opts
.SaltLength
= test
.signSaltLength
222 sig
, err
:= SignPSS(rand
.Reader
, rsaPrivateKey
, hash
, hashed
, &opts
)
224 t
.Errorf("#%d: error while signing: %s", i
, err
)
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
)
236 func bigFromHex(hex
string) *big
.Int
{
237 n
, ok
:= new(big
.Int
).SetString(hex
, 16)
239 panic("bad hex: " + hex
)
244 func intFromHex(hex
string) int {
245 i
, err
:= strconv
.ParseInt(hex
, 16, 32)
252 func fromHex(hexStr
string) []byte {
253 s
, err
:= hex
.DecodeString(hexStr
)