1
16
17 package jose
18
19 import (
20 "crypto/x509"
21 "encoding/base64"
22 "strings"
23 "testing"
24
25 "github.com/stretchr/testify/assert"
26 )
27
28 const trustedCA = `
29 -----BEGIN CERTIFICATE-----
30 MIIE8DCCAtigAwIBAgIJAPgBgSSm5PSpMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
31 BAMMCVRydXN0ZWRDQTAeFw0yMDEwMDQyMjU0MzlaFw00MDEwMDQyMjU0MzlaMBQx
32 EjAQBgNVBAMMCVRydXN0ZWRDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
33 ggIBAJ+o4csEF8uhudNfBgOilhJbJT4D+gLTJT2l7+YEaRnJsyKnaaMYTZl3j+6z
34 8eRPCIx0wkeVvy9H0XXARkXPylycpFrFdOOE+jG7n/KpglOgD4cnpJEc2cZOGnxi
35 d1EiVEoFS9iD1L+SZG0XLfczfGCi970lK1UfBkADrjxXPdUmml+LFlQbLwdjw29e
36 b8heaYep3ltXpyfy2W0mgLakqV+mWqPzcp4dWjohSrOWr/iZSWTVLKlXyKvj3nfC
37 lcXU5FqDSlU5m6tbxhfscEvG2n12TzpGTNSez7my3qxNaAFf1rd/+RvJYjJ4gelH
38 O9ZF9POqOxdoRgZca2SQetRaUlrYbJTY9cjKEJLloo83I65vWDqgMREChzpMorKz
39 ZCeqCVgsgAdo75kiCW1fHY6MvBFk2x9kfZqwv/Dp+vyv22bOVa7ob84CEWbRYMIt
40 wCXRXrewAkvCHFvB6Uoz2Qn2c+3jWzlyRNCucfaPtWnNzRaG6lVm9ieucQI/+Ij4
41 XwuZmmPzOAvKlXadVXNlnsExkrAabc6UJEyqKI7raSeJaR/8RLLfxTDSv3UuWY8v
42 I2QMdS1f6fC8VJKTYMfbdnIw4RQ9Eqi2EmNPgJ4I2mTilG12pRxl/dvfFTl/7/TM
43 Mu6jCLNvJnm3B96at1Y4evWoee51EcvpkNnwotyPLtJFpEMLAgMBAAGjRTBDMB0G
44 A1UdDgQWBBTJ8bqL9u+G1ykEpl9uakSgZGq3JDASBgNVHRMBAf8ECDAGAQH/AgEB
45 MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAB9WBvqUM+tM+1JAS
46 YmUmRKjYlrKUYwNTzgrAyyiYLWzp9cmcw+3hbAjDV0Lu1Im8QQ0eRdq2H8103JYd
47 +nJJx+zlJ04s3pms02uZf8s05XJPSqlYb03uyfZ5uQcOAsRAPHeXaxEmZ/K6PGqO
48 14O3anXb5u+Qq2cb7DGG/Qcek8iX8vI5RqxvLGOOD9z9mpqE9M6aTsjuBVSLM3aQ
49 yIIkRk3deXiOfZd8d+0pShKgVBSrAC8c7A+Yps/r/vSGmN8L+LDoNzfx4NaPLBzu
50 dgiKVpYYgjFEnDzYItWpyxkPVjfMxPEQkz8choJaYNuoROpZtEnSFb4MFHlYGqhO
51 ZYETsYL3BRCHp0WysA3KuXTyA2Tmr+503Xw0btO2ieGEOCe3v/Yc7WGQX3RRAdci
52 2TkBISG6QlH5FzeV11hPriKEMSFHFdJvVrtRORtkGPeE6DUjHQ8MSK8Vm0niKT5P
53 l9GLvIrBN00Pa+YUX0j1xaCY0aj0oxKDFIdyWTn6aR/q9M7CfW6H0fNjPu56+jit
54 q+yQijumIkI5MTlbj0ja51yN62/tNhpTZx/NXpWjgZ+S/668/BJ2veV99PGuQCss
55 jlhHfN8RbHaPuKTKLLslkTvtpIYTc6F9TmcnVAdyKxN8e1XHcV4WrIOzgegVE4IF
56 48TF8WeXgGnsH4Bvob3cZcqWA+w=
57 -----END CERTIFICATE-----`
58
59 const intermediateCA = `
60 -----BEGIN CERTIFICATE-----
61 MIIEDzCCAfegAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJVHJ1
62 c3RlZENBMB4XDTIwMTAwNDIzMDMzM1oXDTQwMTAwNDIzMDMzM1owGTEXMBUGA1UE
63 AwwOSW50ZXJtZWRpYXRlQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
64 AQDiKADoUoaNvD4yCLPySuPR1saLWHNRlt2nqbd7smwB1quNKnKwAKKnLyaBUHIC
65 FrQjCTA7IF7KUndVU0vutMFzn6hKuliZMYbwDQgx6x8u34m8Ar8cAg/AJPgT5Kk6
66 Ds8soUaTzRG/GXVjGll0ArjRp97LmOW1Tc53R4YJji6eTThgb4Al6XDou2AeEMNY
67 C46yqafwzOvHOnzSQwy8IwdcFjNKry15pvutIK3UhZscAmfbNEN5ou3miWcz3PuV
68 GORxKAqlA4mYoJWE2AF52fgNTYcTFCDdiThaFSBzgqEgFoDzzROhf1B+/bSJ4gUL
69 K9YQxpXVmt8/tlvXjNygDj1LAgMBAAGjZjBkMB0GA1UdDgQWBBTZZOBbEfV70Ocm
70 9RIM16yhAw4SyjAfBgNVHSMEGDAWgBTJ8bqL9u+G1ykEpl9uakSgZGq3JDASBgNV
71 HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC
72 AgEADfEtLh3YDabrTsx+KmJ1f8ybwdltgI3gPiubd5RcYcoO3Pd33/INJDMkJYfL
73 CrSDLI5Y94szOUhkP/rSwrUgJErnPSPUEW11GgA230d7vjc3bFJO/bPb2ZAwm/eC
74 7dMMyyDH/2Wty7h7SOuXXJljZYIvuavJymZxsmkDAu7MtdntHVLr5bruEYvM9IKa
75 d9YZSchRP1Q3kIZuTmNvBgLGwrVw/UcOpczajULNNzPUNPDFs9Zo04tx/YF1R1fO
76 GUhif13DMk+6JU7zUXZL3iqOSkxBRrlMQX6nKAQ68cMqO2UsrfXBqH5xm3O9+Nxs
77 fN3CkkTcyBcvVFMaMe0670lCh3DcFOMDt2YdlqS5tEsBn3TdOFKSjv2dVnT2eeXc
78 q5IvuC4nkEXzZDROfQVrnraBhHOiyLAlfwhA1LHZGlJfNZaWRDdXHKV+pIMr2JyO
79 v/hf9aaWzjwyy7FJwn3yrEwHGfBgx0vgKPj6l6N8qxQ6l1XMyANx4ExlpXfffx+C
80 PWV9eeMi4Wh6V9641LesQnlOGgL5R03jQRjaicp3nvzsNElDEgPq0s9PE8s6weFK
81 Bz5ykrw/Gg4QWmw6MfwjOX5Fu1oJF9ABoCFD5umvKhpoJkcT8aYM0+E1xiEAx64u
82 Wq2b2GCGP4wMEZuqCcE72fiue295ovPkNsbEjTQk/ijWza0=
83 -----END CERTIFICATE-----`
84
85 func TestEmbeddedHMAC(t *testing.T) {
86
87 msg := `{"payload":"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ","protected":"eyJhbGciOiJIUzI1NiIsICJqd2siOnsia3R5Ijoib2N0IiwgImsiOiJNVEV4In19","signature":"lvo41ZZsuHwQvSh0uJtEXRR3vmuBJ7in6qMoD7p9jyo"}`
88
89 _, err := ParseSigned(msg)
90 if err == nil {
91 t.Error("should not allow parsing JWS with embedded JWK with HMAC key")
92 }
93 }
94
95 func TestCompactParseJWS(t *testing.T) {
96
97 msg := "eyJhbGciOiJYWVoifQ.cGF5bG9hZA.c2lnbmF0dXJl"
98 _, err := ParseSigned(msg)
99 if err != nil {
100 t.Error("Unable to parse valid message:", err)
101 }
102
103
104 msg = "eyJhbGciOiJYWVoifQ..c2lnbmF0dXJl"
105 _, err = ParseSigned(msg)
106 if err != nil {
107 t.Error("Unable to parse valid message:", err)
108 }
109
110
111 failures := []string{
112
113 "eyJhbGciOiJYWVoifQ.cGF5bG9hZA",
114
115 "eyJhbGciOiJYWVoifQ.cGF5bG9hZA.////",
116
117 "eyJhbGciOiJYWVoifQ.////.c2lnbmF0dXJl",
118
119 "////.eyJhbGciOiJYWVoifQ.c2lnbmF0dXJl",
120
121 "cGF5bG9hZA.cGF5bG9hZA.c2lnbmF0dXJl",
122 }
123
124 for i := range failures {
125 _, err = ParseSigned(failures[i])
126 if err == nil {
127 t.Error("Able to parse invalid message")
128 }
129 }
130 }
131
132 func TestFullParseJWS(t *testing.T) {
133
134 successes := []string{
135 "{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"e30\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"},{\"protected\":\"e30\",\"signature\":\"CUJD\"}]}",
136 }
137
138 for i := range successes {
139 _, err := ParseSigned(successes[i])
140 if err != nil {
141 t.Error("Unble to parse valid message", err, successes[i])
142 }
143 }
144
145
146 failures := []string{
147
148 "{}",
149
150 "{XX",
151
152 "{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
153
154 "{\"payload\":\"CUJD\",\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}",
155
156 "{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"###\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
157
158 "{\"payload\":\"###\",\"signatures\":[{\"protected\":\"CUJD\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"CUJD\"}]}",
159
160 "{\"payload\":\"CUJD\",\"signatures\":[{\"protected\":\"e30\",\"header\":{\"kid\":\"XYZ\"},\"signature\":\"###\"}]}",
161 }
162
163 for i := range failures {
164 _, err := ParseSigned(failures[i])
165 if err == nil {
166 t.Error("Able to parse invalid message", err, failures[i])
167 }
168 }
169 }
170
171 func TestRejectUnprotectedJWSNonce(t *testing.T) {
172
173
174
175 input := `{
176 "header": { "nonce": "should-cause-an-error" },
177 "payload": "does-not-matter",
178 "signature": "does-not-matter"
179 }`
180 _, err := ParseSigned(input)
181 if err == nil {
182 t.Error("JWS with an unprotected nonce parsed as valid.")
183 } else if err != ErrUnprotectedNonce {
184 t.Errorf("Improper error for unprotected nonce: %v", err)
185 }
186
187
188 input = `{
189 "payload": "does-not-matter",
190 "signatures": [{
191 "header": { "nonce": "should-cause-an-error" },
192 "signature": "does-not-matter"
193 }]
194 }`
195 _, err = ParseSigned(input)
196 if err == nil {
197 t.Error("JWS with an unprotected nonce parsed as valid.")
198 } else if err != ErrUnprotectedNonce {
199 t.Errorf("Improper error for unprotected nonce: %v", err)
200 }
201 }
202
203 func TestVerifyFlattenedWithIncludedUnprotectedKey(t *testing.T) {
204 input := `{
205 "header": {
206 "alg": "RS256",
207 "jwk": {
208 "e": "AQAB",
209 "kty": "RSA",
210 "n": "tSwgy3ORGvc7YJI9B2qqkelZRUC6F1S5NwXFvM4w5-M0TsxbFsH5UH6adigV0jzsDJ5imAechcSoOhAh9POceCbPN1sTNwLpNbOLiQQ7RD5mY_pSUHWXNmS9R4NZ3t2fQAzPeW7jOfF0LKuJRGkekx6tXP1uSnNibgpJULNc4208dgBaCHo3mvaE2HV2GmVl1yxwWX5QZZkGQGjNDZYnjFfa2DKVvFs0QbAk21ROm594kAxlRlMMrvqlf24Eq4ERO0ptzpZgm_3j_e4hGRD39gJS7kAzK-j2cacFQ5Qi2Y6wZI2p-FCq_wiYsfEAIkATPBiLKl_6d_Jfcvs_impcXQ"
211 }
212 },
213 "payload": "Zm9vCg",
214 "signature": "hRt2eYqBd_MyMRNIh8PEIACoFtmBi7BHTLBaAhpSU6zyDAFdEBaX7us4VB9Vo1afOL03Q8iuoRA0AT4akdV_mQTAQ_jhTcVOAeXPr0tB8b8Q11UPQ0tXJYmU4spAW2SapJIvO50ntUaqU05kZd0qw8-noH1Lja-aNnU-tQII4iYVvlTiRJ5g8_CADsvJqOk6FcHuo2mG643TRnhkAxUtazvHyIHeXMxydMMSrpwUwzMtln4ZJYBNx4QGEq6OhpAD_VSp-w8Lq5HOwGQoNs0bPxH1SGrArt67LFQBfjlVr94E1sn26p4vigXm83nJdNhWAMHHE9iV67xN-r29LT-FjA"
215 }`
216
217 jws, err := ParseSigned(input)
218 if err != nil {
219 t.Fatal("Unable to parse valid message", err)
220 }
221 if len(jws.Signatures) != 1 {
222 t.Error("Too many or too few signatures.")
223 }
224 sig := jws.Signatures[0]
225 if sig.Header.JSONWebKey == nil {
226 t.Error("No JWK in signature header.")
227 }
228 payload, err := jws.Verify(sig.Header.JSONWebKey)
229 if err != nil {
230 t.Errorf("Signature did not validate: %v", err)
231 }
232 if string(payload) != "foo\n" {
233 t.Errorf("Payload was incorrect: '%s' should have been 'foo\\n'", string(payload))
234 }
235 }
236
237
238 func TestDetachedVerifyJWS(t *testing.T) {
239 rsaPublicKey, err := x509.ParsePKIXPublicKey(fromBase64Bytes(`
240 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3aLSGwbeX0ZA2Ha+EvELaIFGzO
241 91+Q15JQc/tdGdCgGW3XAbrh7ZUhDh1XKzbs+UOQxqn3Eq4YOx18IG0WsJSuCaHQIxnDlZ
242 t/GP8WLwjMC0izlJLm2SyfM/EEoNpmTC3w6MQ2dHK7SZ9Zoq+sKijQd+V7CYdr8zHMpDrd
243 NKoEcR0HjmvzzdMoUChhkGH5TaNbZyollULTggepaYUKS8QphqdSDMWiSetKG+g6V87lv6
244 CVYyK1FF6g7Esp5OOj5pNn3/bmF+7V+b7TvK91NCIlURCjE9toRgNoIP4TDnWRn/vvfZ3G
245 zNrtWmlizqz3r5KdvIs71ahWgMUSD4wfazrwIDAQAB`))
246 if err != nil {
247 t.Fatal(err)
248 }
249
250 sampleMessages := []string{
251 "eyJhbGciOiJSUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.YHX849fvekz6wJGeyqnQhFqyHFcUXNJKj3o2w3ddR46YLlsCopUJrlifRU_ZuTWzpYxt5oC--T2eoqMhlCvltSWrE5_1_EumqiMfAYsZULx9E6Jns7q3w7mttonYFSIh7aR3-yg2HMMfTCgoAY1y_AZ4VjXwHDcZ5gu1oZDYgvZF4uXtCmwT6e5YtR1m8abiWPF8BgoTG_BD3KV6ClLj_QQiNFdfdxAMDw7vKVOKG1T7BFtz6cDs2Q3ILS4To5E2IjcVSSYS8mi77EitCrWmrqbK_G3WCdKeUFGnMnyuKXaCDy_7FLpAZ6Z5RomRr5iskXeJZdZqIKcJV8zl4fpsPA",
252 "eyJhbGciOiJSUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.meyfoOTjAAjXHFYiNlU7EEnsYtbeUYeEglK6BL_cxISEr2YAGLr1Gwnn2HnucTnH6YilyRio7ZC1ohy_ZojzmaljPHqpr8kn1iqNFu9nFE2M16ZPgJi38-PGzppcDNliyzOQO-c7L-eA-v8Gfww5uyRaOJdiWg-hUJmeGBIngPIeLtSVmhJtz8oTeqeNdUOqQv7f7VRCuvagLhW1PcEM91VUS-gS0WEUXoXWZ2lp91No0v1O24izgX3__FKiX_16XhrOfAgJ82F61vjbTIQYwhexHPZyYTlXYt_scNRzFGhSKeGFin4zVdFLOXWJqKWdUd5IrDP5Nya3FSoWbWDXAg",
253 }
254
255 for _, msg := range sampleMessages {
256 obj, err := ParseSigned(msg)
257 if err != nil {
258 t.Error("unable to parse message", msg, err)
259 continue
260 }
261 payload := obj.payload
262 obj.payload = nil
263 err = obj.DetachedVerify(payload, rsaPublicKey)
264 if err != nil {
265 t.Error("unable to verify message", msg, err)
266 continue
267 }
268 idx, _, err := obj.DetachedVerifyMulti(payload, rsaPublicKey)
269 if idx != 0 || err != nil {
270 t.Error("unable to verify message", msg, err)
271 continue
272 }
273 }
274 }
275
276 func TestVerifyFlattenedWithPrivateProtected(t *testing.T) {
277
278
279
280 input := `{"header":{"alg":"RS256","jwk":{"kty":"RSA","n":"7ixeydcbxxppzxrBphrW1atUiEZqTpiHDpI-79olav5XxAgWolHmVsJyxzoZXRxmtED8PF9-EICZWBGdSAL9ZTD0hLUCIsPcpdgT_LqNW3Sh2b2caPL2hbMF7vsXvnCGg9varpnHWuYTyRrCLUF9vM7ES-V3VCYTa7LcCSRm56Gg9r19qar43Z9kIKBBxpgt723v2cC4bmLmoAX2s217ou3uCpCXGLOeV_BesG4--Nl3pso1VhCfO85wEWjmW6lbv7Kg4d7Jdkv5DjDZfJ086fkEAYZVYGRpIgAvJBH3d3yKDCrSByUEud1bWuFjQBmMaeYOrVDXO_mbYg5PwUDMhw","e":"AQAB"}},"protected":"eyJub25jZSI6IjhISWVwVU5GWlVhLWV4S1RyWFZmNGcifQ","payload":"eyJjb250YWN0IjpbIm1haWx0bzpmb29AYmFyLmNvbSJdfQ","signature":"AyvVGMgXsQ1zTdXrZxE_gyO63pQgotL1KbI7gv6Wi8I7NRy0iAOkDAkWcTQT9pcCYApJ04lXfEDZfP5i0XgcFUm_6spxi5mFBZU-NemKcvK9dUiAbXvb4hB3GnaZtZiuVnMQUb_ku4DOaFFKbteA6gOYCnED_x7v0kAPHIYrQnvIa-KZ6pTajbV9348zgh9TL7NgGIIsTcMHd-Jatr4z1LQ0ubGa8tS300hoDhVzfoDQaEetYjCo1drR1RmdEN1SIzXdHOHfubjA3ZZRbrF_AJnNKpRRoIwzu1VayOhRmdy1qVSQZq_tENF4VrQFycEL7DhG7JLoXC4T2p1urwMlsw"}`
281
282 jws, err := ParseSigned(input)
283 if err != nil {
284 t.Error("Unable to parse valid message.")
285 }
286 if len(jws.Signatures) != 1 {
287 t.Error("Too many or too few signatures.")
288 }
289 sig := jws.Signatures[0]
290 if sig.Header.JSONWebKey == nil {
291 t.Error("No JWK in signature header.")
292 }
293 payload, err := jws.Verify(sig.Header.JSONWebKey)
294 if err != nil {
295 t.Errorf("Signature did not validate: %v", err)
296 }
297 expected := "{\"contact\":[\"mailto:foo@bar.com\"]}"
298 if string(payload) != expected {
299 t.Errorf("Payload was incorrect: '%s' should have been '%s'", string(payload), expected)
300 }
301 }
302
303
304 func TestSampleNimbusJWSMessagesRSA(t *testing.T) {
305 rsaPublicKey, err := x509.ParsePKIXPublicKey(fromBase64Bytes(`
306 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3aLSGwbeX0ZA2Ha+EvELaIFGzO
307 91+Q15JQc/tdGdCgGW3XAbrh7ZUhDh1XKzbs+UOQxqn3Eq4YOx18IG0WsJSuCaHQIxnDlZ
308 t/GP8WLwjMC0izlJLm2SyfM/EEoNpmTC3w6MQ2dHK7SZ9Zoq+sKijQd+V7CYdr8zHMpDrd
309 NKoEcR0HjmvzzdMoUChhkGH5TaNbZyollULTggepaYUKS8QphqdSDMWiSetKG+g6V87lv6
310 CVYyK1FF6g7Esp5OOj5pNn3/bmF+7V+b7TvK91NCIlURCjE9toRgNoIP4TDnWRn/vvfZ3G
311 zNrtWmlizqz3r5KdvIs71ahWgMUSD4wfazrwIDAQAB`))
312 if err != nil {
313 panic(err)
314 }
315
316 rsaSampleMessages := []string{
317 "eyJhbGciOiJSUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.YHX849fvekz6wJGeyqnQhFqyHFcUXNJKj3o2w3ddR46YLlsCopUJrlifRU_ZuTWzpYxt5oC--T2eoqMhlCvltSWrE5_1_EumqiMfAYsZULx9E6Jns7q3w7mttonYFSIh7aR3-yg2HMMfTCgoAY1y_AZ4VjXwHDcZ5gu1oZDYgvZF4uXtCmwT6e5YtR1m8abiWPF8BgoTG_BD3KV6ClLj_QQiNFdfdxAMDw7vKVOKG1T7BFtz6cDs2Q3ILS4To5E2IjcVSSYS8mi77EitCrWmrqbK_G3WCdKeUFGnMnyuKXaCDy_7FLpAZ6Z5RomRr5iskXeJZdZqIKcJV8zl4fpsPA",
318 "eyJhbGciOiJSUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.meyfoOTjAAjXHFYiNlU7EEnsYtbeUYeEglK6BL_cxISEr2YAGLr1Gwnn2HnucTnH6YilyRio7ZC1ohy_ZojzmaljPHqpr8kn1iqNFu9nFE2M16ZPgJi38-PGzppcDNliyzOQO-c7L-eA-v8Gfww5uyRaOJdiWg-hUJmeGBIngPIeLtSVmhJtz8oTeqeNdUOqQv7f7VRCuvagLhW1PcEM91VUS-gS0WEUXoXWZ2lp91No0v1O24izgX3__FKiX_16XhrOfAgJ82F61vjbTIQYwhexHPZyYTlXYt_scNRzFGhSKeGFin4zVdFLOXWJqKWdUd5IrDP5Nya3FSoWbWDXAg",
319 "eyJhbGciOiJSUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.rQPz0PDh8KyE2AX6JorgI0MLwv-qi1tcWlz6tuZuWQG1hdrlzq5tR1tQg1evYNc_SDDX87DWTSKXT7JEqhKoFixLfZa13IJrOc7FB8r5ZLx7OwOBC4F--OWrvxMA9Y3MTJjPN3FemQePUo-na2vNUZv-YgkcbuOgbO3hTxwQ7j1JGuqy-YutXOFnccdXvntp3t8zYZ4Mg1It_IyL9pzgGqHIEmMV1pCFGHsDa-wStB4ffmdhrADdYZc0q_SvxUdobyC_XzZCz9ENzGIhgwYxyyrqg7kjqUGoKmCLmoSlUFW7goTk9IC5SXdUyLPuESxOWNfHoRClGav230GYjPFQFA",
320 "eyJhbGciOiJQUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.UTtxjsv_6x4CdlAmZfAW6Lun3byMjJbcwRp_OlPH2W4MZaZar7aql052mIB_ddK45O9VUz2aphYVRvKPZY8WHmvlTUU30bk0z_cDJRYB9eIJVMOiRCYj0oNkz1iEZqsP0YgngxwuUDv4Q4A6aJ0Bo5E_rZo3AnrVHMHUjPp_ZRRSBFs30tQma1qQ0ApK4Gxk0XYCYAcxIv99e78vldVRaGzjEZmQeAVZx4tGcqZP20vG1L84nlhSGnOuZ0FhR8UjRFLXuob6M7EqtMRoqPgRYw47EI3fYBdeSivAg98E5S8R7R1NJc7ef-l03RvfUSY0S3_zBq_4PlHK6A-2kHb__w",
321 "eyJhbGciOiJSUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.meyfoOTjAAjXHFYiNlU7EEnsYtbeUYeEglK6BL_cxISEr2YAGLr1Gwnn2HnucTnH6YilyRio7ZC1ohy_ZojzmaljPHqpr8kn1iqNFu9nFE2M16ZPgJi38-PGzppcDNliyzOQO-c7L-eA-v8Gfww5uyRaOJdiWg-hUJmeGBIngPIeLtSVmhJtz8oTeqeNdUOqQv7f7VRCuvagLhW1PcEM91VUS-gS0WEUXoXWZ2lp91No0v1O24izgX3__FKiX_16XhrOfAgJ82F61vjbTIQYwhexHPZyYTlXYt_scNRzFGhSKeGFin4zVdFLOXWJqKWdUd5IrDP5Nya3FSoWbWDXAg",
322 "eyJhbGciOiJSUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.rQPz0PDh8KyE2AX6JorgI0MLwv-qi1tcWlz6tuZuWQG1hdrlzq5tR1tQg1evYNc_SDDX87DWTSKXT7JEqhKoFixLfZa13IJrOc7FB8r5ZLx7OwOBC4F--OWrvxMA9Y3MTJjPN3FemQePUo-na2vNUZv-YgkcbuOgbO3hTxwQ7j1JGuqy-YutXOFnccdXvntp3t8zYZ4Mg1It_IyL9pzgGqHIEmMV1pCFGHsDa-wStB4ffmdhrADdYZc0q_SvxUdobyC_XzZCz9ENzGIhgwYxyyrqg7kjqUGoKmCLmoSlUFW7goTk9IC5SXdUyLPuESxOWNfHoRClGav230GYjPFQFA",
323 }
324
325 for _, msg := range rsaSampleMessages {
326 obj, err := ParseSigned(msg)
327 if err != nil {
328 t.Error("unable to parse message", msg, err)
329 continue
330 }
331 payload, err := obj.Verify(rsaPublicKey)
332 if err != nil {
333 t.Error("unable to verify message", msg, err)
334 continue
335 }
336 if string(payload) != "Lorem ipsum dolor sit amet" {
337 t.Error("payload is not what we expected for msg", msg)
338 }
339 }
340 }
341
342
343 func TestSampleNimbusJWSMessagesEC(t *testing.T) {
344 ecPublicKeyP256, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIg62jq6FyL1otEj9Up7S35BUrwGF9TVrAzrrY1rHUKZqYIGEg67u/imjgadVcr7y9Q32I0gB8W8FHqbqt696rA=="))
345 if err != nil {
346 panic(err)
347 }
348 ecPublicKeyP384, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEPXsVlqCtN2oTY+F+hFZm3M0ldYpb7IeeJM5wYmT0k1RaqzBFDhDMNnYK5Q5x+OyssZrAtHgYDFw02AVJhhng/eHRp7mqmL/vI3wbxJtrLKYldIbBA+9fYBQcKeibjlu5"))
349 if err != nil {
350 panic(err)
351 }
352 ecPublicKeyP521, err := x509.ParsePKIXPublicKey(fromBase64Bytes("MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAa2w3MMJ5FWD6tSf68G+Wy5jIhWXOD3IA7pE5IC/myQzo1lWcD8KS57SM6nm4POtPcxyLmDhL7FLuh8DKoIZyvtAAdK8+tOQP7XXRlT2bkvzIuazp05It3TAPu00YzTIpKfDlc19Y1lvf7etrbFqhShD92B+hHmhT4ddrdbPCBDW8hvU="))
353 if err != nil {
354 panic(err)
355 }
356
357 ecPublicKeys := []interface{}{ecPublicKeyP256, ecPublicKeyP384, ecPublicKeyP521}
358
359 ecSampleMessages := []string{
360 "eyJhbGciOiJFUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.MEWJVlvGRQyzMEGOYm4rwuiwxrX-6LjnlbaRDAuhwmnBm2Gtn7pRpGXRTMFZUXsSGDz2L1p-Hz1qn8j9bFIBtQ",
361 "eyJhbGciOiJFUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.nbdjPnJPYQtVNNdBIx8-KbFKplTxrz-hnW5UNhYUY7SBkwHK4NZnqc2Lv4DXoA0aWHq9eiypgOh1kmyPWGEmqKAHUx0xdIEkBoHk3ZsbmhOQuq2jL_wcMUG6nTWNhLrB",
362 "eyJhbGciOiJFUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.AeYNFC1rwIgQv-5fwd8iRyYzvTaSCYTEICepgu9gRId-IW99kbSVY7yH0MvrQnqI-a0L8zwKWDR35fW5dukPAYRkADp3Y1lzqdShFcEFziUVGo46vqbiSajmKFrjBktJcCsfjKSaLHwxErF-T10YYPCQFHWb2nXJOOI3CZfACYqgO84g",
363 }
364
365 for i, msg := range ecSampleMessages {
366 obj, err := ParseSigned(msg)
367 if err != nil {
368 t.Error("unable to parse message", msg, err)
369 continue
370 }
371 payload, err := obj.Verify(ecPublicKeys[i])
372 if err != nil {
373 t.Error("unable to verify message", msg, err)
374 continue
375 }
376 if string(payload) != "Lorem ipsum dolor sit amet" {
377 t.Error("payload is not what we expected for msg", msg)
378 }
379 }
380 }
381
382
383 func TestSampleNimbusJWSMessagesHMAC(t *testing.T) {
384 hmacTestKey := fromHexBytes("DF1FA4F36FFA7FC42C81D4B3C033928D")
385
386 hmacSampleMessages := []string{
387 "eyJhbGciOiJIUzI1NiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.W5tc_EUhxexcvLYEEOckyyvdb__M5DQIVpg6Nmk1XGM",
388 "eyJhbGciOiJIUzM4NCJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.sBu44lXOJa4Nd10oqOdYH2uz3lxlZ6o32QSGHaoGdPtYTDG5zvSja6N48CXKqdAh",
389 "eyJhbGciOiJIUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.M0yR4tmipsORIix-BitIbxEPGaxPchDfj8UNOpKuhDEfnb7URjGvCKn4nOlyQ1z9mG1FKbwnqR1hOVAWSzAU_w",
390 }
391
392 for _, msg := range hmacSampleMessages {
393 obj, err := ParseSigned(msg)
394 if err != nil {
395 t.Error("unable to parse message", msg, err)
396 continue
397 }
398 payload, err := obj.Verify(hmacTestKey)
399 if err != nil {
400 t.Error("unable to verify message", msg, err)
401 continue
402 }
403 if string(payload) != "Lorem ipsum dolor sit amet" {
404 t.Error("payload is not what we expected for msg", msg)
405 }
406 }
407 }
408
409 func TestHeaderFieldsCompact(t *testing.T) {
410 msg := "eyJhbGciOiJFUzUxMiJ9.TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ.AeYNFC1rwIgQv-5fwd8iRyYzvTaSCYTEICepgu9gRId-IW99kbSVY7yH0MvrQnqI-a0L8zwKWDR35fW5dukPAYRkADp3Y1lzqdShFcEFziUVGo46vqbiSajmKFrjBktJcCsfjKSaLHwxErF-T10YYPCQFHWb2nXJOOI3CZfACYqgO84g"
411
412 obj, err := ParseSigned(msg)
413 if err != nil {
414 t.Fatal("unable to parse message", msg, err)
415 }
416 if obj.Signatures[0].Header.Algorithm != "ES512" {
417 t.Error("merged header did not contain expected alg value")
418 }
419 if obj.Signatures[0].Protected.Algorithm != "ES512" {
420 t.Error("protected header did not contain expected alg value")
421 }
422 if obj.Signatures[0].Unprotected.Algorithm != "" {
423 t.Error("unprotected header contained an alg value")
424 }
425 }
426
427 func TestHeaderFieldsFull(t *testing.T) {
428 msg := `{"payload":"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ","protected":"eyJhbGciOiJFUzUxMiJ9","header":{"custom":"test"},"signature":"AeYNFC1rwIgQv-5fwd8iRyYzvTaSCYTEICepgu9gRId-IW99kbSVY7yH0MvrQnqI-a0L8zwKWDR35fW5dukPAYRkADp3Y1lzqdShFcEFziUVGo46vqbiSajmKFrjBktJcCsfjKSaLHwxErF-T10YYPCQFHWb2nXJOOI3CZfACYqgO84g"}`
429
430 obj, err := ParseSigned(msg)
431 if err != nil {
432 t.Fatal("unable to parse message", msg, err)
433 }
434 if obj.Signatures[0].Header.Algorithm != "ES512" {
435 t.Error("merged header did not contain expected alg value")
436 }
437 if obj.Signatures[0].Protected.Algorithm != "ES512" {
438 t.Error("protected header did not contain expected alg value")
439 }
440 if obj.Signatures[0].Unprotected.Algorithm != "" {
441 t.Error("unprotected header contained an alg value")
442 }
443 if obj.Signatures[0].Unprotected.ExtraHeaders["custom"] != "test" {
444 t.Error("unprotected header did not contain custom header value")
445 }
446 }
447
448
449 func TestErrorMissingPayloadJWS(t *testing.T) {
450 _, err := (&rawJSONWebSignature{}).sanitized()
451 if err == nil {
452 t.Error("was able to parse message with missing payload")
453 }
454 if !strings.Contains(err.Error(), "missing payload") {
455 t.Errorf("unexpected error message, should contain 'missing payload': %s", err)
456 }
457 }
458
459
460 func TestNullHeaderValue(t *testing.T) {
461 msg := `{
462 "payload":
463 "eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGF
464 tcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
465 "protected":"eyJhbGciOiJFUzI1NiIsIm5vbmNlIjpudWxsfQ",
466 "header":
467 {"kid":"e9bc097a-ce51-4036-9562-d2ade882db0d"},
468 "signature":
469 "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8IS
470 lSApmWQxfKTUJqPP3-Kg6NU1Q"
471 }`
472
473 defer func() {
474 if r := recover(); r != nil {
475 t.Errorf("ParseSigned panic'd when parsing a message with a null protected header value")
476 }
477 }()
478 ParseSigned(msg)
479 }
480
481
482
483 func TestEmbedJWKBug(t *testing.T) {
484 signerKey := SigningKey{
485 Key: &JSONWebKey{
486 Key: rsaTestKey,
487 KeyID: "rsa-test-key",
488 },
489 Algorithm: RS256,
490 }
491
492 signer, err := NewSigner(signerKey, &SignerOptions{EmbedJWK: true})
493 if err != nil {
494 t.Fatal(err)
495 }
496
497 signerNoEmbed, err := NewSigner(signerKey, &SignerOptions{EmbedJWK: false})
498 if err != nil {
499 t.Fatal(err)
500 }
501
502 jws, err := signer.Sign([]byte("Lorem ipsum dolor sit amet"))
503 if err != nil {
504 t.Fatal(err)
505 }
506
507 jwsNoEmbed, err := signerNoEmbed.Sign([]byte("Lorem ipsum dolor sit amet"))
508 if err != nil {
509 t.Fatal(err)
510 }
511
512
513
514 output := jws.FullSerialize()
515 outputNoEmbed := jwsNoEmbed.FullSerialize()
516
517
518
519 parsed, err := ParseSigned(output)
520 if err != nil {
521 t.Fatal(err)
522 }
523
524 parsedNoEmbed, err := ParseSigned(outputNoEmbed)
525 if err != nil {
526 t.Fatal(err)
527 }
528
529 if parsed.Signatures[0].Header.KeyID != "" {
530 t.Error("expected kid field in protected header to be empty")
531 }
532 if parsed.Signatures[0].Header.JSONWebKey.KeyID != "rsa-test-key" {
533 t.Error("expected rsa-test-key to be kid in embedded JWK in protected header")
534 }
535 if parsedNoEmbed.Signatures[0].Header.KeyID != "rsa-test-key" {
536 t.Error("expected kid field in protected header to be rsa-test-key")
537 }
538 if parsedNoEmbed.Signatures[0].Header.JSONWebKey != nil {
539 t.Error("expected no embedded JWK to be present")
540 }
541 }
542
543 func TestJWSWithCertificateChain(t *testing.T) {
544 signerKey := SigningKey{
545 Key: rsaTestKey,
546 Algorithm: RS256,
547 }
548
549 certs := []string{
550
551 "MIIDOjCCAiKgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwGTEXMBUGA1UEAwwOSW50ZXJtZWRpYXRlQ0EwHhcNMjAxMDA0MjMzNDA3WhcNNDAxMDA0MjMzNDA3WjAYMRYwFAYDVQQDDA1UcnVzdGVkU2lnbmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAswje1TAIK6aBvvVbuf3bq0emTEDXsTnovRv7HArauy0Lc72Gai8tuc1WVAmw8byxqaNHnHTfIT66UxPBcktr59A9KW2NqNXtNlhVgyIcYFEBFgmKjItmHG2BTw8HIvUnrcneRY9w/gE74f+7BPl0WUE2jsKkf8cIvZso5osGoBwVRN5YP0aWersaXVpA+hVUbMuwUnAvLdvuSvXDtL6SDdisHV9rhZH2jRAj6BzmC4mAD9BATeFFqC1Nt+bo1d7TUNk/FEbjyzs6g9QCUsTTL2RoPFvdQYjnYoIl4tVClUGipeEXb3e84k/ZEUDC04ENCONM/BsQEHBcR0eylViD7QIDAQABo4GMMIGJMB0GA1UdDgQWBBQ5GmxMDIgf21y8SDTSMy2/bZjcLjAfBgNVHSMEGDAWgBTZZOBbEfV70Ocm9RIM16yhAw4SyjAOBgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBgGA1UdEQQRMA+CDVRydXN0ZWRTaWduZXIwDQYJKoZIhvcNAQELBQADggEBAHS3KHVV/8H5eH2ZsDRsXyZkdqQlArlWCNK5I1xXW3jxnmAkrMu/Boin82foKLX7sNV33pdec8QMZMY3sTqr8OR+4haehYT9Dw6K4FEBtwRcuR08KducwnQO+kEeixkYtGpRX81hzLLdPHup9u+70WRsiSbgrYq9mV9bec+0uylbfh7ervNncIMTQvjZVkMnELrxe5l31UsZddHs2bzPbdlHuEhNmYxgzCXcFmpvv/WuuNiqVruQKzLYgR+F+eeE5UtmtE/gEBtPFHyLqQCoDcPqRY6B0VqNdcobPz4VOV8Fbf1HOzYEn7TdVglw6PTb5AXQ7/wnRss6SUofg6wzdzY=",
552
553 "MIIEDzCCAfegAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJVHJ1c3RlZENBMB4XDTIwMTAwNDIzMDMzM1oXDTQwMTAwNDIzMDMzM1owGTEXMBUGA1UEAwwOSW50ZXJtZWRpYXRlQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiKADoUoaNvD4yCLPySuPR1saLWHNRlt2nqbd7smwB1quNKnKwAKKnLyaBUHICFrQjCTA7IF7KUndVU0vutMFzn6hKuliZMYbwDQgx6x8u34m8Ar8cAg/AJPgT5Kk6Ds8soUaTzRG/GXVjGll0ArjRp97LmOW1Tc53R4YJji6eTThgb4Al6XDou2AeEMNYC46yqafwzOvHOnzSQwy8IwdcFjNKry15pvutIK3UhZscAmfbNEN5ou3miWcz3PuVGORxKAqlA4mYoJWE2AF52fgNTYcTFCDdiThaFSBzgqEgFoDzzROhf1B+/bSJ4gULK9YQxpXVmt8/tlvXjNygDj1LAgMBAAGjZjBkMB0GA1UdDgQWBBTZZOBbEfV70Ocm9RIM16yhAw4SyjAfBgNVHSMEGDAWgBTJ8bqL9u+G1ykEpl9uakSgZGq3JDASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEADfEtLh3YDabrTsx+KmJ1f8ybwdltgI3gPiubd5RcYcoO3Pd33/INJDMkJYfLCrSDLI5Y94szOUhkP/rSwrUgJErnPSPUEW11GgA230d7vjc3bFJO/bPb2ZAwm/eC7dMMyyDH/2Wty7h7SOuXXJljZYIvuavJymZxsmkDAu7MtdntHVLr5bruEYvM9IKad9YZSchRP1Q3kIZuTmNvBgLGwrVw/UcOpczajULNNzPUNPDFs9Zo04tx/YF1R1fOGUhif13DMk+6JU7zUXZL3iqOSkxBRrlMQX6nKAQ68cMqO2UsrfXBqH5xm3O9+NxsfN3CkkTcyBcvVFMaMe0670lCh3DcFOMDt2YdlqS5tEsBn3TdOFKSjv2dVnT2eeXcq5IvuC4nkEXzZDROfQVrnraBhHOiyLAlfwhA1LHZGlJfNZaWRDdXHKV+pIMr2JyOv/hf9aaWzjwyy7FJwn3yrEwHGfBgx0vgKPj6l6N8qxQ6l1XMyANx4ExlpXfffx+CPWV9eeMi4Wh6V9641LesQnlOGgL5R03jQRjaicp3nvzsNElDEgPq0s9PE8s6weFKBz5ykrw/Gg4QWmw6MfwjOX5Fu1oJF9ABoCFD5umvKhpoJkcT8aYM0+E1xiEAx64uWq2b2GCGP4wMEZuqCcE72fiue295ovPkNsbEjTQk/ijWza0=",
554 }
555
556 testCases := []struct {
557
558 chain []string
559
560 intermediates []string
561 root string
562
563 success bool
564 }{
565 {certs, nil, trustedCA, true},
566 {certs, []string{intermediateCA}, trustedCA, true},
567 {certs[0:1], nil, intermediateCA, true},
568 {certs[0:1], nil, trustedCA, false},
569 {[]string{}, nil, trustedCA, false},
570 }
571
572 for i, testCase := range testCases {
573 signer, err := NewSigner(signerKey, &SignerOptions{
574 ExtraHeaders: map[HeaderKey]interface{}{HeaderKey("x5c"): testCase.chain},
575 })
576 if err != nil {
577 t.Fatal(err)
578 }
579
580 signed, err := signer.Sign([]byte("Lorem ipsum dolor sit amet"))
581 if err != nil {
582 t.Fatal(err)
583 }
584
585 parsed, err := ParseSigned(signed.FullSerialize())
586 if err != nil {
587 t.Fatal(err)
588 }
589
590 opts := x509.VerifyOptions{
591 DNSName: "TrustedSigner",
592 Roots: x509.NewCertPool(),
593 }
594
595 ok := opts.Roots.AppendCertsFromPEM([]byte(testCase.root))
596 if !ok {
597 t.Fatal("failed to parse trusted root certificate")
598 }
599
600 if len(testCase.intermediates) > 0 {
601 opts.Intermediates = x509.NewCertPool()
602 for _, intermediate := range testCase.intermediates {
603 ok := opts.Intermediates.AppendCertsFromPEM([]byte(intermediate))
604 if !ok {
605 t.Fatal("failed to parse trusted root certificate")
606 }
607 }
608 }
609
610 chains, err := parsed.Signatures[0].Protected.Certificates(opts)
611 if testCase.success && (len(chains) == 0 || err != nil) {
612 t.Fatalf("failed to verify certificate chain for test case %d: %s", i, err)
613 }
614 if !testCase.success && (len(chains) != 0 && err == nil) {
615 t.Fatalf("incorrectly verified certificate chain for test case %d (should fail)", i)
616 }
617 }
618 }
619
620 func TestDetachedCompactSerialization(t *testing.T) {
621 msg := "eyJhbGciOiJSUzI1NiJ9.JC4wMg.W5tc_EUhxexcvLYEEOckyyvdb__M5DQIVpg6Nmk1XGM"
622 exp := "eyJhbGciOiJSUzI1NiJ9..W5tc_EUhxexcvLYEEOckyyvdb__M5DQIVpg6Nmk1XGM"
623
624 obj, err := ParseSigned(msg)
625 if err != nil {
626 t.Fatal(err)
627 }
628
629 ser, err := obj.DetachedCompactSerialize()
630 if err != nil {
631 t.Fatal(err)
632 }
633
634 if ser != exp {
635 t.Fatalf("got '%s', expected '%s'", ser, exp)
636 }
637
638 obj, err = ParseDetached(ser, []byte("$.02"))
639 if err != nil {
640 t.Fatal(err)
641 }
642
643 ser, err = obj.CompactSerialize()
644 if err != nil {
645 t.Fatal(err)
646 }
647
648 if ser != msg {
649 t.Fatalf("got '%s', expected '%s'", ser, msg)
650 }
651 }
652
653 func TestJWSComputeAuthDataBase64(t *testing.T) {
654 jws := JSONWebSignature{}
655
656 _, err := jws.computeAuthData([]byte{0x01}, &Signature{
657 original: &rawSignatureInfo{
658 Protected: newBuffer([]byte("{!invalid-json}")),
659 },
660 })
661
662 assert.NotNil(t, err)
663
664 payload := []byte{0x01}
665 encodedPayload := base64.RawURLEncoding.EncodeToString(payload)
666
667 b64TrueHeader := newBuffer([]byte(`{"alg":"RSA-OAEP","enc":"A256GCM","b64":true}`))
668 b64FalseHeader := newBuffer([]byte(`{"alg":"RSA-OAEP","enc":"A256GCM","b64":false}`))
669
670 data, err := jws.computeAuthData(payload, &Signature{
671 original: &rawSignatureInfo{
672 Protected: b64TrueHeader,
673 },
674 })
675 assert.Nil(t, err)
676
677 assert.Len(t, data, len(b64TrueHeader.base64())+len(encodedPayload)+1)
678
679 data, err = jws.computeAuthData(payload, &Signature{
680 original: &rawSignatureInfo{
681 Protected: b64FalseHeader,
682 },
683 })
684 assert.Nil(t, err)
685
686 assert.Len(t, data, len(b64FalseHeader.base64())+len(payload)+1)
687 }
688
View as plain text