Skip to content
This repository was archived by the owner on Feb 27, 2023. It is now read-only.

Commit 1323f1f

Browse files
mangasmbyczkowski
andcommitted
Fix decoding x5t parameters (#304)
When support for optional x5u, x5t, and x5t#S256 parameters in JWK was added in #242 (and subsequently released in 2.5.0) it actually broke parsing of JWKs which included those parameters. See #299 for detailed analysis and discussion. Cherry-picked from #304 Needed minor tweaks, since v2 doesn't use golangci linter nor Go modules. Co-authored-by: Mat Byczkowski <[email protected]>
1 parent 2204b3e commit 1323f1f

File tree

3 files changed

+160
-36
lines changed

3 files changed

+160
-36
lines changed

.travis.yml

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ before_install:
2626
- go get github.com/wadey/gocovmerge
2727
- go get github.com/mattn/goveralls
2828
- go get github.com/stretchr/testify/assert
29+
- go get github.com/stretchr/testify/require
30+
- go get github.com/google/go-cmp/cmp
2931
- go get golang.org/x/tools/cmd/cover || true
3032
- go get code.google.com/p/go.tools/cmd/cover || true
3133
- pip install cram --user

jwk.go

+51-12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"crypto/sha256"
2727
"crypto/x509"
2828
"encoding/base64"
29+
"encoding/hex"
2930
"errors"
3031
"fmt"
3132
"math/big"
@@ -61,10 +62,10 @@ type rawJSONWebKey struct {
6162
Dq *byteBuffer `json:"dq,omitempty"`
6263
Qi *byteBuffer `json:"qi,omitempty"`
6364
// Certificates
64-
X5c []string `json:"x5c,omitempty"`
65-
X5u *url.URL `json:"x5u,omitempty"`
66-
X5tSHA1 *byteBuffer `json:"x5t,omitempty"`
67-
X5tSHA256 *byteBuffer `json:"x5t#S256,omitempty"`
65+
X5c []string `json:"x5c,omitempty"`
66+
X5u *url.URL `json:"x5u,omitempty"`
67+
X5tSHA1 string `json:"x5t,omitempty"`
68+
X5tSHA256 string `json:"x5t#S256,omitempty"`
6869
}
6970

7071
// JSONWebKey represents a public or private key in JWK format.
@@ -130,13 +131,13 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
130131
if x5tSHA1Len != sha1.Size {
131132
return nil, fmt.Errorf("square/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)", sha1.Size, x5tSHA1Len)
132133
}
133-
raw.X5tSHA1 = newFixedSizeBuffer(k.CertificateThumbprintSHA1, sha1.Size)
134+
raw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1)
134135
}
135136
if x5tSHA256Len > 0 {
136137
if x5tSHA256Len != sha256.Size {
137138
return nil, fmt.Errorf("square/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)", sha256.Size, x5tSHA256Len)
138139
}
139-
raw.X5tSHA256 = newFixedSizeBuffer(k.CertificateThumbprintSHA256, sha256.Size)
140+
raw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256)
140141
}
141142

142143
// If cert chain is attached (as opposed to being behind a URL), check the
@@ -146,9 +147,12 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
146147
if len(k.Certificates) > 0 {
147148
expectedSHA1 := sha1.Sum(k.Certificates[0].Raw)
148149
expectedSHA256 := sha256.Sum256(k.Certificates[0].Raw)
149-
if !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) ||
150-
!bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) {
151-
return nil, errors.New("square/go-jose: invalid SHA-1 or SHA-256 thumbprint, does not match cert chain")
150+
151+
if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) {
152+
return nil, errors.New("square/go-jose: invalid SHA-1 thumbprint, does not match cert chain")
153+
}
154+
if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) {
155+
return nil, errors.New("square/go-jose: invalid or SHA-256 thumbprint, does not match cert chain")
152156
}
153157
}
154158

@@ -241,16 +245,51 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
241245
*k = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use, Certificates: certs}
242246

243247
k.CertificatesURL = raw.X5u
244-
k.CertificateThumbprintSHA1 = raw.X5tSHA1.bytes()
245-
k.CertificateThumbprintSHA256 = raw.X5tSHA256.bytes()
248+
249+
// x5t parameters are base64url-encoded SHA thumbprints
250+
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
251+
x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1)
252+
if err != nil {
253+
return errors.New("square/go-jose: invalid JWK, x5t header has invalid encoding")
254+
}
255+
256+
// RFC 7517, Section 4.8 is ambiguous as to whether the digest output should be byte or hex,
257+
// for this reason, after base64 decoding, if the size is sha1.Size it's likely that the value is a byte encoded
258+
// checksum so we skip this. Otherwise if the checksum was hex encoded we expect a 40 byte sized array so we'll
259+
// try to hex decode it. When Marshalling this value we'll always use a base64 encoded version of byte format checksum.
260+
if len(x5tSHA1bytes) == 2*sha1.Size {
261+
hx, err := hex.DecodeString(string(x5tSHA1bytes))
262+
if err != nil {
263+
return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t: %v", err)
264+
265+
}
266+
x5tSHA1bytes = hx
267+
}
268+
269+
k.CertificateThumbprintSHA1 = x5tSHA1bytes
270+
271+
x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256)
272+
if err != nil {
273+
return errors.New("square/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
274+
}
275+
276+
if len(x5tSHA256bytes) == 2*sha256.Size {
277+
hx256, err := hex.DecodeString(string(x5tSHA256bytes))
278+
if err != nil {
279+
return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t#S256: %v", err)
280+
}
281+
x5tSHA256bytes = hx256
282+
}
283+
284+
k.CertificateThumbprintSHA256 = x5tSHA256bytes
246285

247286
x5tSHA1Len := len(k.CertificateThumbprintSHA1)
248287
x5tSHA256Len := len(k.CertificateThumbprintSHA256)
249288
if x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size {
250289
return errors.New("square/go-jose: invalid JWK, x5t header is of incorrect size")
251290
}
252291
if x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size {
253-
return errors.New("square/go-jose: invalid JWK, x5t header is of incorrect size")
292+
return errors.New("square/go-jose: invalid JWK, x5t#S256 header is of incorrect size")
254293
}
255294

256295
// If certificate chain *and* thumbprints are set, verify correctness.

jwk_test.go

+107-24
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ import (
3131
"strings"
3232
"testing"
3333

34+
"github.com/google/go-cmp/cmp"
3435
"github.com/stretchr/testify/assert"
36+
"github.com/stretchr/testify/require"
37+
3538
"golang.org/x/crypto/ed25519"
3639

3740
"gopkg.in/square/go-jose.v2/json"
@@ -246,37 +249,117 @@ func TestRoundtripX509(t *testing.T) {
246249
x5tSHA1 := sha1.Sum(testCertificates[0].Raw)
247250
x5tSHA256 := sha256.Sum256(testCertificates[0].Raw)
248251

249-
jwk := JSONWebKey{
250-
Key: testCertificates[0].PublicKey,
251-
KeyID: "bar",
252-
Algorithm: "foo",
253-
Certificates: testCertificates,
254-
CertificateThumbprintSHA1: x5tSHA1[:],
255-
CertificateThumbprintSHA256: x5tSHA256[:],
252+
cases := []struct {
253+
name string
254+
jwk JSONWebKey
255+
}{
256+
{
257+
name: "all fields",
258+
jwk: JSONWebKey{
259+
Key: testCertificates[0].PublicKey,
260+
KeyID: "bar",
261+
Algorithm: "foo",
262+
Certificates: testCertificates,
263+
CertificateThumbprintSHA1: x5tSHA1[:],
264+
CertificateThumbprintSHA256: x5tSHA256[:],
265+
},
266+
},
267+
{
268+
name: "no optional x5ts",
269+
jwk: JSONWebKey{
270+
Key: testCertificates[0].PublicKey,
271+
KeyID: "bar",
272+
Algorithm: "foo",
273+
Certificates: testCertificates,
274+
},
275+
},
276+
{
277+
name: "no x5t",
278+
jwk: JSONWebKey{
279+
Key: testCertificates[0].PublicKey,
280+
KeyID: "bar",
281+
Algorithm: "foo",
282+
Certificates: testCertificates,
283+
CertificateThumbprintSHA256: x5tSHA256[:],
284+
},
285+
},
286+
{
287+
name: "no x5t#S256",
288+
jwk: JSONWebKey{
289+
Key: testCertificates[0].PublicKey,
290+
KeyID: "bar",
291+
Algorithm: "foo",
292+
Certificates: testCertificates,
293+
CertificateThumbprintSHA1: x5tSHA1[:],
294+
},
295+
},
256296
}
257297

258-
jsonbar, err := jwk.MarshalJSON()
259-
if err != nil {
260-
t.Error("problem marshaling", err)
298+
for _, c := range cases {
299+
t.Run(c.name, func(t *testing.T) {
300+
jsonbar, err := c.jwk.MarshalJSON()
301+
require.NoError(t, err)
302+
303+
var jwk2 JSONWebKey
304+
err = jwk2.UnmarshalJSON(jsonbar)
305+
require.NoError(t, err)
306+
307+
if !reflect.DeepEqual(testCertificates, jwk2.Certificates) {
308+
t.Error("Certificates not equal", c.jwk.Certificates, jwk2.Certificates)
309+
}
310+
311+
jsonbar2, err := jwk2.MarshalJSON()
312+
require.NoError(t, err)
313+
314+
require.Empty(t, cmp.Diff(jsonbar, jsonbar2))
315+
if !bytes.Equal(jsonbar, jsonbar2) {
316+
t.Error("roundtrip should not lose information")
317+
}
318+
})
261319
}
320+
}
321+
322+
func TestRoundtripX509Hex(t *testing.T) {
323+
var hexJWK = `{
324+
"kty":"RSA",
325+
"kid":"bar",
326+
"alg":"foo",
327+
"n":"u7LUr30Mhrh8N79-H4rKiHQ123q6xaBZPYbf1nV4GM19rizSnbEfyebG1kpfCv-XY6c499XiM6lOvcPL-0goTOcfW6Lg7AAR895GbnMeXEmnxICaI8rAZHK6t1WPmiWp82y_qhK2F_pYUaT3GSuiTFiMGq_GNwdpWuMlsInnnMNv1nxFbxtDPwzmCp0fEBxbH5d1EtXZwTPOHMyj8rfa-NIA5Nl4h_5RrbOWveKwBr26_CDAratJgOWh9xcd5g0ot_uDGcMoAgB6xeTuYklfaxCPptvu49kvoxw1J71fp6nKW_ZuhDRAp2F_BQ9inKpTo05sPLJg8tPTdjaeouOuJQ",
328+
"e":"AQAB",
329+
"x5c":[
330+
"MIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMHZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoXDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxlLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3v34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69w8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhRpPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84czKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2Np6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAsBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sMlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7LstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7dvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeLFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2XliJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=",
331+
"MIIDUzCCAjugAwIBAgIJAKg+LQlirffwMA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMHZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1yb290MB4XDTE2MDYxMDIyMTQxMVoXDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxlLXJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKOEoSiNjMQ8/zUFcQW89LWw+UeTXKGwNDSpGjyi8jBKZ1lWPbnMmrjI6DZ9ReevHHzqBdKZt+9NFPFEz7djDMRByIuJhRvzhfFBflaIdSeNk2+NpUaFuUUUd6IIePu0AdRveJ8ZGHXRwCeEDIVCZS4oBYPHOhX/zMWDg8vSO4pSxTjGc7I8fHxaUSkVzUBbeO9T/1eFk0m2uxs3UziUck2X/8YqRd+p/EaBED78nXvKRALAguKAzqxIgk3ccPK0SVQFNFq+eV1/qo8coueQuqMpCAvwVkfpVKhneyC2NlMrfzlcZZbfG/irlSjQn5+ExZX4Isy1pCUbOiVfSrsCdtAgMBAAGjJjAkMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUAA4IBAQCLEJU65vTU+oLbNHLOCR6fALrbjK7xsi6SFDpSXBMm74MWsy3myDBmXpOcN8hCYgsgivUXTQz9ynXP/pzOj4b83zzlaOfPtLTAmMhKWVV4Q85mrDQz+HzG4lKXM78eTsD8PyrocA/tSE7mVEJ0Jal4E2KI/Z9/fqpYFLB6LFlx5n83ehXM/egA0l4OeCC9nBKCeNUN3sIQO85lljyzAJdtWnsdoWogJs6qjcV8n2U5xjZxN5ZFdclYLjq6g2cjEXXMQxb8b7ZhHjLWFdjHP85UvXHK3DpK3JmUg8bYS7t1DJffDQNjawhlsMycKZN+r0ND0Um4m7AjGqxbKT/M2yKF"
332+
],
333+
"x5t": "MDYxMjU0ZmRmNzIwZjJjMGU0YmQzZjMzMzlhMmZlNTM1MGExNWRlMQ",
334+
"x5t#S256": "MjAzMjRhNGI5MmYxMjI2OGVmOWFlMDI1ZmQ1Yzc5ZDE1OGZmNzQ1NzQwMDkyMTk2ZTgzNTNjMDAzMTUxNzUxMQ"
335+
}`
336+
337+
// json output
338+
var output = `{
339+
"kty":"RSA",
340+
"kid":"bar",
341+
"alg":"foo",
342+
"n":"u7LUr30Mhrh8N79-H4rKiHQ123q6xaBZPYbf1nV4GM19rizSnbEfyebG1kpfCv-XY6c499XiM6lOvcPL-0goTOcfW6Lg7AAR895GbnMeXEmnxICaI8rAZHK6t1WPmiWp82y_qhK2F_pYUaT3GSuiTFiMGq_GNwdpWuMlsInnnMNv1nxFbxtDPwzmCp0fEBxbH5d1EtXZwTPOHMyj8rfa-NIA5Nl4h_5RrbOWveKwBr26_CDAratJgOWh9xcd5g0ot_uDGcMoAgB6xeTuYklfaxCPptvu49kvoxw1J71fp6nKW_ZuhDRAp2F_BQ9inKpTo05sPLJg8tPTdjaeouOuJQ",
343+
"e":"AQAB",
344+
"x5c":[
345+
"MIIDfDCCAmSgAwIBAgIJANWAkzF7PA8/MA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMHZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1sZWFmMB4XDTE2MDYxMDIyMTQxMVoXDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxlLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7stSvfQyGuHw3v34fisqIdDXberrFoFk9ht/WdXgYzX2uLNKdsR/J5sbWSl8K/5djpzj31eIzqU69w8v7SChM5x9bouDsABHz3kZucx5cSafEgJojysBkcrq3VY+aJanzbL+qErYX+lhRpPcZK6JMWIwar8Y3B2la4yWwieecw2/WfEVvG0M/DOYKnR8QHFsfl3US1dnBM84czKPyt9r40gDk2XiH/lGts5a94rAGvbr8IMCtq0mA5aH3Fx3mDSi3+4MZwygCAHrF5O5iSV9rEI+m2+7j2S+jHDUnvV+nqcpb9m6ENECnYX8FD2KcqlOjTmw8smDy09N2Np6i464lAgMBAAGjTzBNMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAsBgNVHREEJTAjhwR/AAABhxAAAAAAAAAAAAAAAAAAAAABgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAGM4aa/qrURUweZBIwZYv8O9b2+r4l0HjGAh982/B9sMlM05kojyDCUGvj86z18Lm8mKr4/y+i0nJ+vDIksEvfDuzw5ALAXGcBzPJKtICUf7LstA/n9NNpshWz0kld9ylnB5mbUzSFDncVyeXkEf5sGQXdIIZT9ChRBoiloSaa7dvBVCcsX1LGP2LWqKtD+7nUnw5qCwtyAVT8pthEUxFTpywoiJS5ZdzeEx8MNGvUeLFj2kleqPF78EioEQlSOxViCuctEtnQuPcDLHNFr10byTZY9roObiqdsJLMVvb2XliJjAqaPa9AkYwGE6xHw2ispwg64Rse0+AtKups19WIU=",
346+
"MIIDUzCCAjugAwIBAgIJAKg+LQlirffwMA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UEChMHY2VydGlnbzEQMA4GA1UECxMHZXhhbXBsZTEVMBMGA1UEAxMMZXhhbXBsZS1yb290MB4XDTE2MDYxMDIyMTQxMVoXDTIzMDQxNTIyMTQxMVowVTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQKEwdjZXJ0aWdvMRAwDgYDVQQLEwdleGFtcGxlMRUwEwYDVQQDEwxleGFtcGxlLXJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKOEoSiNjMQ8/zUFcQW89LWw+UeTXKGwNDSpGjyi8jBKZ1lWPbnMmrjI6DZ9ReevHHzqBdKZt+9NFPFEz7djDMRByIuJhRvzhfFBflaIdSeNk2+NpUaFuUUUd6IIePu0AdRveJ8ZGHXRwCeEDIVCZS4oBYPHOhX/zMWDg8vSO4pSxTjGc7I8fHxaUSkVzUBbeO9T/1eFk0m2uxs3UziUck2X/8YqRd+p/EaBED78nXvKRALAguKAzqxIgk3ccPK0SVQFNFq+eV1/qo8coueQuqMpCAvwVkfpVKhneyC2NlMrfzlcZZbfG/irlSjQn5+ExZX4Isy1pCUbOiVfSrsCdtAgMBAAGjJjAkMA4GA1UdDwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEAMA0GCSqGSIb3DQEBCwUAA4IBAQCLEJU65vTU+oLbNHLOCR6fALrbjK7xsi6SFDpSXBMm74MWsy3myDBmXpOcN8hCYgsgivUXTQz9ynXP/pzOj4b83zzlaOfPtLTAmMhKWVV4Q85mrDQz+HzG4lKXM78eTsD8PyrocA/tSE7mVEJ0Jal4E2KI/Z9/fqpYFLB6LFlx5n83ehXM/egA0l4OeCC9nBKCeNUN3sIQO85lljyzAJdtWnsdoWogJs6qjcV8n2U5xjZxN5ZFdclYLjq6g2cjEXXMQxb8b7ZhHjLWFdjHP85UvXHK3DpK3JmUg8bYS7t1DJffDQNjawhlsMycKZN+r0ND0Um4m7AjGqxbKT/M2yKF"
347+
],
348+
"x5t":"BhJU_fcg8sDkvT8zOaL-U1ChXeE",
349+
"x5t#S256":"IDJKS5LxImjvmuAl_Vx50Vj_dFdACSGW6DU8ADFRdRE"
350+
}`
262351

263352
var jwk2 JSONWebKey
264-
err = jwk2.UnmarshalJSON(jsonbar)
265-
if err != nil {
266-
t.Fatal("problem unmarshalling", err)
267-
}
353+
err := jwk2.UnmarshalJSON([]byte(hexJWK))
354+
require.NoError(t, err)
268355

269-
if !reflect.DeepEqual(testCertificates, jwk2.Certificates) {
270-
t.Error("Certificates not equal", jwk.Certificates, jwk2.Certificates)
271-
}
356+
js, err := jwk2.MarshalJSON()
357+
require.NoError(t, err)
272358

273-
jsonbar2, err := jwk2.MarshalJSON()
274-
if err != nil {
275-
t.Error("problem marshaling", err)
276-
}
277-
if !bytes.Equal(jsonbar, jsonbar2) {
278-
t.Error("roundtrip should not lose information")
279-
}
359+
var j1, j2 map[string]interface{}
360+
require.NoError(t, json.Unmarshal(js, &j1))
361+
require.NoError(t, json.Unmarshal([]byte(output), &j2))
362+
require.Empty(t, cmp.Diff(j1, j2))
280363
}
281364

282365
func TestInvalidThumbprintsX509(t *testing.T) {

0 commit comments

Comments
 (0)