~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/acme/jws_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

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