OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / golang.org / x / crypto / acme / jws_test.go
1 // Copyright 2015 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.
4
5 package acme
6
7 import (
8         "crypto/ecdsa"
9         "crypto/elliptic"
10         "crypto/rsa"
11         "crypto/x509"
12         "encoding/base64"
13         "encoding/json"
14         "encoding/pem"
15         "fmt"
16         "math/big"
17         "testing"
18 )
19
20 const (
21         testKeyPEM = `
22 -----BEGIN RSA PRIVATE KEY-----
23 MIIEowIBAAKCAQEA4xgZ3eRPkwoRvy7qeRUbmMDe0V+xH9eWLdu0iheeLlrmD2mq
24 WXfP9IeSKApbn34g8TuAS9g5zhq8ELQ3kmjr+KV86GAMgI6VAcGlq3QrzpTCf/30
25 Ab7+zawrfRaFONa1HwEzPY1KHnGVkxJc85gNkwYI9SY2RHXtvln3zs5wITNrdosq
26 EXeaIkVYBEhbhNu54pp3kxo6TuWLi9e6pXeWetEwmlBwtWZlPoib2j3TxLBksKZf
27 oyFyek380mHgJAumQ/I2fjj98/97mk3ihOY4AgVdCDj1z/GCoZkG5Rq7nbCGyosy
28 KWyDX00Zs+nNqVhoLeIvXC4nnWdJMZ6rogxyQQIDAQABAoIBACIEZTOI1Kao9nmV
29 9IeIsuaR1Y61b9neOF/MLmIVIZu+AAJFCMB4Iw11FV6sFodwpEyeZhx2WkpWVN+H
30 r19eGiLX3zsL0DOdqBJoSIHDWCCMxgnYJ6nvS0nRxX3qVrBp8R2g12Ub+gNPbmFm
31 ecf/eeERIVxfifd9VsyRu34eDEvcmKFuLYbElFcPh62xE3x12UZvV/sN7gXbawpP
32 G+w255vbE5MoaKdnnO83cTFlcHvhn24M/78qP7Te5OAeelr1R89kYxQLpuGe4fbS
33 zc6E3ym5Td6urDetGGrSY1Eu10/8sMusX+KNWkm+RsBRbkyKq72ks/qKpOxOa+c6
34 9gm+Y8ECgYEA/iNUyg1ubRdH11p82l8KHtFC1DPE0V1gSZsX29TpM5jS4qv46K+s
35 8Ym1zmrORM8x+cynfPx1VQZQ34EYeCMIX212ryJ+zDATl4NE0I4muMvSiH9vx6Xc
36 7FmhNnaYzPsBL5Tm9nmtQuP09YEn8poiOJFiDs/4olnD5ogA5O4THGkCgYEA5MIL
37 qWYBUuqbEWLRtMruUtpASclrBqNNsJEsMGbeqBJmoMxdHeSZckbLOrqm7GlMyNRJ
38 Ne/5uWRGSzaMYuGmwsPpERzqEvYFnSrpjW5YtXZ+JtxFXNVfm9Z1gLLgvGpOUCIU
39 RbpoDckDe1vgUuk3y5+DjZihs+rqIJ45XzXTzBkCgYBWuf3segruJZy5rEKhTv+o
40 JqeUvRn0jNYYKFpLBeyTVBrbie6GkbUGNIWbrK05pC+c3K9nosvzuRUOQQL1tJbd
41 4gA3oiD9U4bMFNr+BRTHyZ7OQBcIXdz3t1qhuHVKtnngIAN1p25uPlbRFUNpshnt
42 jgeVoHlsBhApcs5DUc+pyQKBgDzeHPg/+g4z+nrPznjKnktRY1W+0El93kgi+J0Q
43 YiJacxBKEGTJ1MKBb8X6sDurcRDm22wMpGfd9I5Cv2v4GsUsF7HD/cx5xdih+G73
44 c4clNj/k0Ff5Nm1izPUno4C+0IOl7br39IPmfpSuR6wH/h6iHQDqIeybjxyKvT1G
45 N0rRAoGBAKGD+4ZI/E1MoJ5CXB8cDDMHagbE3cq/DtmYzE2v1DFpQYu5I4PCm5c7
46 EQeIP6dZtv8IMgtGIb91QX9pXvP0aznzQKwYIA8nZgoENCPfiMTPiEDT9e/0lObO
47 9XWsXpbSTsRPj0sv1rB+UzBJ0PgjK4q2zOF0sNo7b1+6nlM3BWPx
48 -----END RSA PRIVATE KEY-----
49 `
50
51         // This thumbprint is for the testKey defined above.
52         testKeyThumbprint = "6nicxzh6WETQlrvdchkz-U3e3DOQZ4heJKU63rfqMqQ"
53
54         // openssl ecparam -name secp256k1 -genkey -noout
55         testKeyECPEM = `
56 -----BEGIN EC PRIVATE KEY-----
57 MHcCAQEEIK07hGLr0RwyUdYJ8wbIiBS55CjnkMD23DWr+ccnypWLoAoGCCqGSM49
58 AwEHoUQDQgAE5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HThqIrvawF5
59 QAaS/RNouybCiRhRjI3EaxLkQwgrCw0gqQ==
60 -----END EC PRIVATE KEY-----
61 `
62         // openssl ecparam -name secp384r1 -genkey -noout
63         testKeyEC384PEM = `
64 -----BEGIN EC PRIVATE KEY-----
65 MIGkAgEBBDAQ4lNtXRORWr1bgKR1CGysr9AJ9SyEk4jiVnlUWWUChmSNL+i9SLSD
66 Oe/naPqXJ6CgBwYFK4EEACKhZANiAAQzKtj+Ms0vHoTX5dzv3/L5YMXOWuI5UKRj
67 JigpahYCqXD2BA1j0E/2xt5vlPf+gm0PL+UHSQsCokGnIGuaHCsJAp3ry0gHQEke
68 WYXapUUFdvaK1R2/2hn5O+eiQM8YzCg=
69 -----END EC PRIVATE KEY-----
70 `
71         // openssl ecparam -name secp521r1 -genkey -noout
72         testKeyEC512PEM = `
73 -----BEGIN EC PRIVATE KEY-----
74 MIHcAgEBBEIBSNZKFcWzXzB/aJClAb305ibalKgtDA7+70eEkdPt28/3LZMM935Z
75 KqYHh/COcxuu3Kt8azRAUz3gyr4zZKhlKUSgBwYFK4EEACOhgYkDgYYABAHUNKbx
76 7JwC7H6pa2sV0tERWhHhB3JmW+OP6SUgMWryvIKajlx73eS24dy4QPGrWO9/ABsD
77 FqcRSkNVTXnIv6+0mAF25knqIBIg5Q8M9BnOu9GGAchcwt3O7RDHmqewnJJDrbjd
78 GGnm6rb+NnWR9DIopM0nKNkToWoF/hzopxu4Ae/GsQ==
79 -----END EC PRIVATE KEY-----
80 `
81         // 1. openssl ec -in key.pem -noout -text
82         // 2. remove first byte, 04 (the header); the rest is X and Y
83         // 3. convert each with: echo <val> | xxd -r -p | base64 -w 100 | tr -d '=' | tr '/+' '_-'
84         testKeyECPubX    = "5lhEug5xK4xBDZ2nAbaxLtaLiv85bxJ7ePd1dkO23HQ"
85         testKeyECPubY    = "4aiK72sBeUAGkv0TaLsmwokYUYyNxGsS5EMIKwsNIKk"
86         testKeyEC384PubX = "MyrY_jLNLx6E1-Xc79_y-WDFzlriOVCkYyYoKWoWAqlw9gQNY9BP9sbeb5T3_oJt"
87         testKeyEC384PubY = "Dy_lB0kLAqJBpyBrmhwrCQKd68tIB0BJHlmF2qVFBXb2itUdv9oZ-TvnokDPGMwo"
88         testKeyEC512PubX = "AdQ0pvHsnALsfqlraxXS0RFaEeEHcmZb44_pJSAxavK8gpqOXHvd5Lbh3LhA8atY738AGwMWpxFKQ1VNeci_r7SY"
89         testKeyEC512PubY = "AXbmSeogEiDlDwz0Gc670YYByFzC3c7tEMeap7CckkOtuN0Yaebqtv42dZH0MiikzSco2ROhagX-HOinG7gB78ax"
90
91         // echo -n '{"crv":"P-256","kty":"EC","x":"<testKeyECPubX>","y":"<testKeyECPubY>"}' | \
92         // openssl dgst -binary -sha256 | base64 | tr -d '=' | tr '/+' '_-'
93         testKeyECThumbprint = "zedj-Bd1Zshp8KLePv2MB-lJ_Hagp7wAwdkA0NUTniU"
94 )
95
96 var (
97         testKey      *rsa.PrivateKey
98         testKeyEC    *ecdsa.PrivateKey
99         testKeyEC384 *ecdsa.PrivateKey
100         testKeyEC512 *ecdsa.PrivateKey
101 )
102
103 func init() {
104         testKey = parseRSA(testKeyPEM, "testKeyPEM")
105         testKeyEC = parseEC(testKeyECPEM, "testKeyECPEM")
106         testKeyEC384 = parseEC(testKeyEC384PEM, "testKeyEC384PEM")
107         testKeyEC512 = parseEC(testKeyEC512PEM, "testKeyEC512PEM")
108 }
109
110 func decodePEM(s, name string) []byte {
111         d, _ := pem.Decode([]byte(s))
112         if d == nil {
113                 panic("no block found in " + name)
114         }
115         return d.Bytes
116 }
117
118 func parseRSA(s, name string) *rsa.PrivateKey {
119         b := decodePEM(s, name)
120         k, err := x509.ParsePKCS1PrivateKey(b)
121         if err != nil {
122                 panic(fmt.Sprintf("%s: %v", name, err))
123         }
124         return k
125 }
126
127 func parseEC(s, name string) *ecdsa.PrivateKey {
128         b := decodePEM(s, name)
129         k, err := x509.ParseECPrivateKey(b)
130         if err != nil {
131                 panic(fmt.Sprintf("%s: %v", name, err))
132         }
133         return k
134 }
135
136 func TestJWSEncodeJSON(t *testing.T) {
137         claims := struct{ Msg string }{"Hello JWS"}
138         // JWS signed with testKey and "nonce" as the nonce value
139         // JSON-serialized JWS fields are split for easier testing
140         const (
141                 // {"alg":"RS256","jwk":{"e":"AQAB","kty":"RSA","n":"..."},"nonce":"nonce"}
142                 protected = "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQVFBQiIsImt0eSI6" +
143                         "IlJTQSIsIm4iOiI0eGdaM2VSUGt3b1J2eTdxZVJVYm1NRGUwVi14" +
144                         "SDllV0xkdTBpaGVlTGxybUQybXFXWGZQOUllU0tBcGJuMzRnOFR1" +
145                         "QVM5ZzV6aHE4RUxRM2ttanItS1Y4NkdBTWdJNlZBY0dscTNRcnpw" +
146                         "VENmXzMwQWI3LXphd3JmUmFGT05hMUh3RXpQWTFLSG5HVmt4SmM4" +
147                         "NWdOa3dZSTlTWTJSSFh0dmxuM3pzNXdJVE5yZG9zcUVYZWFJa1ZZ" +
148                         "QkVoYmhOdTU0cHAza3hvNlR1V0xpOWU2cFhlV2V0RXdtbEJ3dFda" +
149                         "bFBvaWIyajNUeExCa3NLWmZveUZ5ZWszODBtSGdKQXVtUV9JMmZq" +
150                         "ajk4Xzk3bWszaWhPWTRBZ1ZkQ0RqMXpfR0NvWmtHNVJxN25iQ0d5" +
151                         "b3N5S1d5RFgwMFpzLW5OcVZob0xlSXZYQzRubldkSk1aNnJvZ3h5" +
152                         "UVEifSwibm9uY2UiOiJub25jZSJ9"
153                 // {"Msg":"Hello JWS"}
154                 payload   = "eyJNc2ciOiJIZWxsbyBKV1MifQ"
155                 signature = "eAGUikStX_UxyiFhxSLMyuyBcIB80GeBkFROCpap2sW3EmkU_ggF" +
156                         "knaQzxrTfItICSAXsCLIquZ5BbrSWA_4vdEYrwWtdUj7NqFKjHRa" +
157                         "zpLHcoR7r1rEHvkoP1xj49lS5fc3Wjjq8JUhffkhGbWZ8ZVkgPdC" +
158                         "4tMBWiQDoth-x8jELP_3LYOB_ScUXi2mETBawLgOT2K8rA0Vbbmx" +
159                         "hWNlOWuUf-8hL5YX4IOEwsS8JK_TrTq5Zc9My0zHJmaieqDV0UlP" +
160                         "k0onFjPFkGm7MrPSgd0MqRG-4vSAg2O4hDo7rKv4n8POjjXlNQvM" +
161                         "9IPLr8qZ7usYBKhEGwX3yq_eicAwBw"
162         )
163
164         b, err := jwsEncodeJSON(claims, testKey, "nonce")
165         if err != nil {
166                 t.Fatal(err)
167         }
168         var jws struct{ Protected, Payload, Signature string }
169         if err := json.Unmarshal(b, &jws); err != nil {
170                 t.Fatal(err)
171         }
172         if jws.Protected != protected {
173                 t.Errorf("protected:\n%s\nwant:\n%s", jws.Protected, protected)
174         }
175         if jws.Payload != payload {
176                 t.Errorf("payload:\n%s\nwant:\n%s", jws.Payload, payload)
177         }
178         if jws.Signature != signature {
179                 t.Errorf("signature:\n%s\nwant:\n%s", jws.Signature, signature)
180         }
181 }
182
183 func TestJWSEncodeJSONEC(t *testing.T) {
184         tt := []struct {
185                 key      *ecdsa.PrivateKey
186                 x, y     string
187                 alg, crv string
188         }{
189                 {testKeyEC, testKeyECPubX, testKeyECPubY, "ES256", "P-256"},
190                 {testKeyEC384, testKeyEC384PubX, testKeyEC384PubY, "ES384", "P-384"},
191                 {testKeyEC512, testKeyEC512PubX, testKeyEC512PubY, "ES512", "P-521"},
192         }
193         for i, test := range tt {
194                 claims := struct{ Msg string }{"Hello JWS"}
195                 b, err := jwsEncodeJSON(claims, test.key, "nonce")
196                 if err != nil {
197                         t.Errorf("%d: %v", i, err)
198                         continue
199                 }
200                 var jws struct{ Protected, Payload, Signature string }
201                 if err := json.Unmarshal(b, &jws); err != nil {
202                         t.Errorf("%d: %v", i, err)
203                         continue
204                 }
205
206                 b, err = base64.RawURLEncoding.DecodeString(jws.Protected)
207                 if err != nil {
208                         t.Errorf("%d: jws.Protected: %v", i, err)
209                 }
210                 var head struct {
211                         Alg   string
212                         Nonce string
213                         JWK   struct {
214                                 Crv string
215                                 Kty string
216                                 X   string
217                                 Y   string
218                         } `json:"jwk"`
219                 }
220                 if err := json.Unmarshal(b, &head); err != nil {
221                         t.Errorf("%d: jws.Protected: %v", i, err)
222                 }
223                 if head.Alg != test.alg {
224                         t.Errorf("%d: head.Alg = %q; want %q", i, head.Alg, test.alg)
225                 }
226                 if head.Nonce != "nonce" {
227                         t.Errorf("%d: head.Nonce = %q; want nonce", i, head.Nonce)
228                 }
229                 if head.JWK.Crv != test.crv {
230                         t.Errorf("%d: head.JWK.Crv = %q; want %q", i, head.JWK.Crv, test.crv)
231                 }
232                 if head.JWK.Kty != "EC" {
233                         t.Errorf("%d: head.JWK.Kty = %q; want EC", i, head.JWK.Kty)
234                 }
235                 if head.JWK.X != test.x {
236                         t.Errorf("%d: head.JWK.X = %q; want %q", i, head.JWK.X, test.x)
237                 }
238                 if head.JWK.Y != test.y {
239                         t.Errorf("%d: head.JWK.Y = %q; want %q", i, head.JWK.Y, test.y)
240                 }
241         }
242 }
243
244 func TestJWKThumbprintRSA(t *testing.T) {
245         // Key example from RFC 7638
246         const base64N = "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAt" +
247                 "VT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn6" +
248                 "4tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FD" +
249                 "W2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n9" +
250                 "1CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINH" +
251                 "aQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
252         const base64E = "AQAB"
253         const expected = "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"
254
255         b, err := base64.RawURLEncoding.DecodeString(base64N)
256         if err != nil {
257                 t.Fatalf("Error parsing example key N: %v", err)
258         }
259         n := new(big.Int).SetBytes(b)
260
261         b, err = base64.RawURLEncoding.DecodeString(base64E)
262         if err != nil {
263                 t.Fatalf("Error parsing example key E: %v", err)
264         }
265         e := new(big.Int).SetBytes(b)
266
267         pub := &rsa.PublicKey{N: n, E: int(e.Uint64())}
268         th, err := JWKThumbprint(pub)
269         if err != nil {
270                 t.Error(err)
271         }
272         if th != expected {
273                 t.Errorf("thumbprint = %q; want %q", th, expected)
274         }
275 }
276
277 func TestJWKThumbprintEC(t *testing.T) {
278         // Key example from RFC 7520
279         // expected was computed with
280         // echo -n '{"crv":"P-521","kty":"EC","x":"<base64X>","y":"<base64Y>"}' | \
281         // openssl dgst -binary -sha256 | \
282         // base64 | \
283         // tr -d '=' | tr '/+' '_-'
284         const (
285                 base64X = "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkT" +
286                         "KqjqvjyekWF-7ytDyRXYgCF5cj0Kt"
287                 base64Y = "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUda" +
288                         "QkAgDPrwQrJmbnX9cwlGfP-HqHZR1"
289                 expected = "dHri3SADZkrush5HU_50AoRhcKFryN-PI6jPBtPL55M"
290         )
291
292         b, err := base64.RawURLEncoding.DecodeString(base64X)
293         if err != nil {
294                 t.Fatalf("Error parsing example key X: %v", err)
295         }
296         x := new(big.Int).SetBytes(b)
297
298         b, err = base64.RawURLEncoding.DecodeString(base64Y)
299         if err != nil {
300                 t.Fatalf("Error parsing example key Y: %v", err)
301         }
302         y := new(big.Int).SetBytes(b)
303
304         pub := &ecdsa.PublicKey{Curve: elliptic.P521(), X: x, Y: y}
305         th, err := JWKThumbprint(pub)
306         if err != nil {
307                 t.Error(err)
308         }
309         if th != expected {
310                 t.Errorf("thumbprint = %q; want %q", th, expected)
311         }
312 }
313
314 func TestJWKThumbprintErrUnsupportedKey(t *testing.T) {
315         _, err := JWKThumbprint(struct{}{})
316         if err != ErrUnsupportedKey {
317                 t.Errorf("err = %q; want %q", err, ErrUnsupportedKey)
318         }
319 }