...

Source file src/github.com/lestrrat-go/jwx/jwk/jwk_test.go

Documentation: github.com/lestrrat-go/jwx/jwk

     1  package jwk_test
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto"
     7  	"crypto/ecdsa"
     8  	"crypto/ed25519"
     9  	"crypto/rsa"
    10  	"fmt"
    11  	"io"
    12  	"math/big"
    13  	"net/http"
    14  	"net/http/httptest"
    15  	"reflect"
    16  	"regexp"
    17  	"strconv"
    18  	"strings"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/lestrrat-go/jwx/internal/ecutil"
    23  	"github.com/lestrrat-go/jwx/internal/jose"
    24  	"github.com/lestrrat-go/jwx/internal/json"
    25  	"github.com/lestrrat-go/jwx/internal/jwxtest"
    26  	"github.com/lestrrat-go/jwx/jws"
    27  	"github.com/pkg/errors"
    28  
    29  	"github.com/lestrrat-go/jwx/internal/base64"
    30  	"github.com/lestrrat-go/jwx/jwa"
    31  	"github.com/lestrrat-go/jwx/jwk"
    32  	"github.com/lestrrat-go/jwx/x25519"
    33  	"github.com/stretchr/testify/assert"
    34  )
    35  
    36  var zeroval reflect.Value
    37  var certChainSrc = []string{
    38  	"MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYwMTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3HKrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQmVZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpRSgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRTcDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEuMB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDSkdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUHAgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IGOgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMUA2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTXRE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuHqDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWVU+4=",
    39  	"MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoXDTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHUTBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMbVmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwgSW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlvbiBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEgMB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUwAwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdvZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUdIAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4OWBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0VmsfSxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==",
    40  	"MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd",
    41  }
    42  
    43  type keyDef struct {
    44  	Expected interface{}
    45  	Value    interface{}
    46  	Method   string
    47  }
    48  
    49  var commonDef map[string]keyDef
    50  
    51  func init() {
    52  	var certChain jwk.CertificateChain
    53  	certChain.Accept(certChainSrc)
    54  
    55  	commonDef = map[string]keyDef{
    56  		jwk.AlgorithmKey: {
    57  			Method: "Algorithm",
    58  			Value:  "random-algorithm",
    59  		},
    60  		jwk.KeyIDKey: {
    61  			Method: "KeyID",
    62  			Value:  "12312rdfsdfer2342342",
    63  		},
    64  		jwk.KeyUsageKey: {
    65  			Method:   "KeyUsage",
    66  			Value:    jwk.ForSignature,
    67  			Expected: string(jwk.ForSignature),
    68  		},
    69  		jwk.KeyOpsKey: {
    70  			Method: "KeyOps",
    71  			Value: jwk.KeyOperationList{
    72  				jwk.KeyOpSign,
    73  				jwk.KeyOpVerify,
    74  				jwk.KeyOpEncrypt,
    75  				jwk.KeyOpDecrypt,
    76  				jwk.KeyOpWrapKey,
    77  				jwk.KeyOpUnwrapKey,
    78  				jwk.KeyOpDeriveKey,
    79  				jwk.KeyOpDeriveBits,
    80  			},
    81  		},
    82  		jwk.X509CertChainKey: {
    83  			Method:   "X509CertChain",
    84  			Value:    certChainSrc,
    85  			Expected: certChain.Get(),
    86  		},
    87  		jwk.X509CertThumbprintKey: {
    88  			Value:  "x5t blah",
    89  			Method: "X509CertThumbprint",
    90  		},
    91  		jwk.X509CertThumbprintS256Key: {
    92  			Value:  "x5t#256 blah",
    93  			Method: "X509CertThumbprintS256",
    94  		},
    95  		jwk.X509URLKey: {
    96  			Value:  "http://github.com/lestrrat-go/jwx",
    97  			Method: "X509URL",
    98  		},
    99  		"private": {Value: "boofoo"},
   100  	}
   101  }
   102  
   103  func complimentDef(def map[string]keyDef) map[string]keyDef {
   104  	for k, v := range commonDef {
   105  		if _, ok := def[k]; !ok {
   106  			def[k] = v
   107  		}
   108  	}
   109  	return def
   110  }
   111  
   112  func makeKeyJSON(def map[string]keyDef) []byte {
   113  	data := map[string]interface{}{}
   114  	for k, v := range def {
   115  		data[k] = v.Value
   116  	}
   117  	src, err := json.Marshal(data)
   118  	if err != nil {
   119  		panic(err)
   120  	}
   121  	return src
   122  }
   123  
   124  func expectBase64(kdef keyDef) keyDef {
   125  	v, err := base64.DecodeString(kdef.Value.(string))
   126  	if err != nil {
   127  		panic(err)
   128  	}
   129  	kdef.Expected = v
   130  	return kdef
   131  }
   132  
   133  func expectedRawKeyType(key jwk.Key) interface{} {
   134  	switch key := key.(type) {
   135  	case jwk.RSAPrivateKey:
   136  		return &rsa.PrivateKey{}
   137  	case jwk.RSAPublicKey:
   138  		return &rsa.PublicKey{}
   139  	case jwk.ECDSAPrivateKey:
   140  		return &ecdsa.PrivateKey{}
   141  	case jwk.ECDSAPublicKey:
   142  		return &ecdsa.PublicKey{}
   143  	case jwk.SymmetricKey:
   144  		return []byte(nil)
   145  	case jwk.OKPPrivateKey:
   146  		switch key.Crv() {
   147  		case jwa.Ed25519:
   148  			return ed25519.PrivateKey(nil)
   149  		case jwa.X25519:
   150  			return x25519.PrivateKey(nil)
   151  		default:
   152  			panic("unknown curve type for OKPPrivateKey:" + key.Crv())
   153  		}
   154  	case jwk.OKPPublicKey:
   155  		switch key.Crv() {
   156  		case jwa.Ed25519:
   157  			return ed25519.PublicKey(nil)
   158  		case jwa.X25519:
   159  			return x25519.PublicKey(nil)
   160  		default:
   161  			panic("unknown curve type for OKPPublicKey:" + key.Crv())
   162  		}
   163  	default:
   164  		panic("unknown key type:" + reflect.TypeOf(key).String())
   165  	}
   166  }
   167  
   168  func VerifyKey(t *testing.T, def map[string]keyDef) {
   169  	t.Helper()
   170  
   171  	def = complimentDef(def)
   172  	key, err := jwk.ParseKey(makeKeyJSON(def))
   173  	if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
   174  		return
   175  	}
   176  
   177  	t.Run("Fields", func(t *testing.T) {
   178  		for k, kdef := range def {
   179  			k := k
   180  			kdef := kdef
   181  			t.Run(k, func(t *testing.T) {
   182  				getval, ok := key.Get(k)
   183  				if !assert.True(t, ok, `key.Get(%s) should succeed`, k) {
   184  					return
   185  				}
   186  				expected := kdef.Expected
   187  				if expected == nil {
   188  					expected = kdef.Value
   189  				}
   190  				if !assert.Equal(t, expected, getval) {
   191  					return
   192  				}
   193  
   194  				if mname := kdef.Method; mname != "" {
   195  					method := reflect.ValueOf(key).MethodByName(mname)
   196  					if !assert.NotEqual(t, zeroval, method, `method should not be a zero value`) {
   197  						return
   198  					}
   199  					retvals := method.Call(nil)
   200  
   201  					if !assert.Len(t, retvals, 1, `there should be 1 return value`) {
   202  						return
   203  					}
   204  
   205  					if !assert.Equal(t, expected, retvals[0].Interface()) {
   206  						return
   207  					}
   208  				}
   209  			})
   210  		}
   211  	})
   212  	t.Run("Roundtrip", func(t *testing.T) {
   213  		buf, err := json.Marshal(key)
   214  		if !assert.NoError(t, err, `json.Marshal should succeed`) {
   215  			return
   216  		}
   217  
   218  		newkey, err := jwk.ParseKey(buf)
   219  		if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
   220  			return
   221  		}
   222  
   223  		m1, err := key.AsMap(context.TODO())
   224  		if !assert.NoError(t, err, `key.AsMap should succeed`) {
   225  			return
   226  		}
   227  
   228  		m2, err := newkey.AsMap(context.TODO())
   229  		if !assert.NoError(t, err, `key.AsMap should succeed`) {
   230  			return
   231  		}
   232  
   233  		if !assert.Equal(t, m1, m2, `keys should match`) {
   234  			return
   235  		}
   236  	})
   237  	t.Run("Raw", func(t *testing.T) {
   238  		typ := expectedRawKeyType(key)
   239  
   240  		var rawkey interface{}
   241  		if !assert.NoError(t, key.Raw(&rawkey), `Raw() should succeed`) {
   242  			return
   243  		}
   244  		if !assert.IsType(t, rawkey, typ, `raw key should be of this type`) {
   245  			return
   246  		}
   247  	})
   248  	t.Run("PublicKey", func(t *testing.T) {
   249  		_, err := jwk.PublicKeyOf(key)
   250  		if !assert.NoError(t, err, `jwk.PublicKeyOf should succeed`) {
   251  			return
   252  		}
   253  	})
   254  	t.Run("Set/Remove", func(t *testing.T) {
   255  		ctx := context.TODO()
   256  
   257  		newkey, err := key.Clone()
   258  		if !assert.NoError(t, err, `key.Clone should succeed`) {
   259  			return
   260  		}
   261  
   262  		for iter := key.Iterate(ctx); iter.Next(ctx); {
   263  			pair := iter.Pair()
   264  			newkey.Remove(pair.Key.(string))
   265  		}
   266  
   267  		m, err := newkey.AsMap(ctx)
   268  		if !assert.NoError(t, err, `key.AsMap should succeed`) {
   269  			return
   270  		}
   271  
   272  		if !assert.Len(t, m, 1, `keys should have 1 key (kty remains)`) {
   273  			return
   274  		}
   275  
   276  		for iter := key.Iterate(ctx); iter.Next(ctx); {
   277  			pair := iter.Pair()
   278  			if !assert.NoError(t, newkey.Set(pair.Key.(string), pair.Value), `newkey.Set should succeed`) {
   279  				return
   280  			}
   281  		}
   282  	})
   283  }
   284  
   285  func TestNew(t *testing.T) {
   286  	t.Parallel()
   287  	k, err := jwk.New(nil)
   288  	if !assert.Nil(t, k, "key should be nil") {
   289  		return
   290  	}
   291  	if !assert.Error(t, err, "nil key should cause an error") {
   292  		return
   293  	}
   294  }
   295  
   296  func TestParse(t *testing.T) {
   297  	t.Parallel()
   298  	verify := func(t *testing.T, src string, expected reflect.Type) {
   299  		t.Helper()
   300  		t.Run("json.Unmarshal", func(t *testing.T) {
   301  			set := jwk.NewSet()
   302  			if err := json.Unmarshal([]byte(src), set); !assert.NoError(t, err, `json.Unmarshal should succeed`) {
   303  				return
   304  			}
   305  
   306  			if !assert.True(t, set.Len() > 0, "set.Keys should be greater than 0") {
   307  				return
   308  			}
   309  
   310  			ctx, cancel := context.WithCancel(context.Background())
   311  			defer cancel()
   312  
   313  			for iter := set.Iterate(ctx); iter.Next(ctx); {
   314  				pair := iter.Pair()
   315  				if !assert.True(t, reflect.TypeOf(pair.Value).AssignableTo(expected), "key should be a %s", expected) {
   316  					return
   317  				}
   318  			}
   319  		})
   320  		t.Run("jwk.Parse", func(t *testing.T) {
   321  			t.Helper()
   322  			set, err := jwk.Parse([]byte(`{"keys":[` + src + `]}`))
   323  			if !assert.NoError(t, err, `jwk.Parse should succeed`) {
   324  				return
   325  			}
   326  
   327  			if !assert.True(t, set.Len() > 0, "set.Len should be greater than 0") {
   328  				return
   329  			}
   330  
   331  			for iter := set.Iterate(context.TODO()); iter.Next(context.TODO()); {
   332  				pair := iter.Pair()
   333  				key := pair.Value.(jwk.Key)
   334  
   335  				switch key := key.(type) {
   336  				case jwk.RSAPrivateKey, jwk.ECDSAPrivateKey, jwk.OKPPrivateKey, jwk.RSAPublicKey, jwk.ECDSAPublicKey, jwk.OKPPublicKey, jwk.SymmetricKey:
   337  				default:
   338  					assert.Fail(t, fmt.Sprintf("invalid type: %T", key))
   339  				}
   340  			}
   341  		})
   342  		t.Run("jwk.ParseKey", func(t *testing.T) {
   343  			t.Helper()
   344  			key, err := jwk.ParseKey([]byte(src))
   345  			if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
   346  				return
   347  			}
   348  
   349  			t.Run("Raw", func(t *testing.T) {
   350  				t.Helper()
   351  
   352  				var irawkey interface{}
   353  				if !assert.NoError(t, key.Raw(&irawkey), `key.Raw(&interface) should ucceed`) {
   354  					return
   355  				}
   356  
   357  				var crawkey interface{}
   358  				switch k := key.(type) {
   359  				case jwk.RSAPrivateKey:
   360  					var rawkey rsa.PrivateKey
   361  					if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&rsa.PrivateKey) should succeed`) {
   362  						return
   363  					}
   364  					crawkey = &rawkey
   365  				case jwk.RSAPublicKey:
   366  					var rawkey rsa.PublicKey
   367  					if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&rsa.PublicKey) should succeed`) {
   368  						return
   369  					}
   370  					crawkey = &rawkey
   371  				case jwk.ECDSAPrivateKey:
   372  					var rawkey ecdsa.PrivateKey
   373  					if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&ecdsa.PrivateKey) should succeed`) {
   374  						return
   375  					}
   376  					crawkey = &rawkey
   377  				case jwk.OKPPrivateKey:
   378  					switch k.Crv() {
   379  					case jwa.Ed25519:
   380  						var rawkey ed25519.PrivateKey
   381  						if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&ed25519.PrivateKey) should succeed`) {
   382  							return
   383  						}
   384  						crawkey = rawkey
   385  					case jwa.X25519:
   386  						var rawkey x25519.PrivateKey
   387  						if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&x25519.PrivateKey) should succeed`) {
   388  							return
   389  						}
   390  						crawkey = rawkey
   391  					default:
   392  						t.Errorf(`invalid curve %s`, k.Crv())
   393  					}
   394  				// NOTE: Has to come after private
   395  				// key, since it's a subset of the
   396  				// private key variant.
   397  				case jwk.OKPPublicKey:
   398  					switch k.Crv() {
   399  					case jwa.Ed25519:
   400  						var rawkey ed25519.PublicKey
   401  						if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&ed25519.PublicKey) should succeed`) {
   402  							return
   403  						}
   404  						crawkey = rawkey
   405  					case jwa.X25519:
   406  						var rawkey x25519.PublicKey
   407  						if !assert.NoError(t, key.Raw(&rawkey), `key.Raw(&x25519.PublicKey) should succeed`) {
   408  							return
   409  						}
   410  						crawkey = rawkey
   411  					default:
   412  						t.Errorf(`invalid curve %s`, k.Crv())
   413  					}
   414  				default:
   415  					t.Errorf(`invalid key type %T`, key)
   416  					return
   417  				}
   418  
   419  				if !assert.IsType(t, crawkey, irawkey, `key types should match`) {
   420  					return
   421  				}
   422  			})
   423  		})
   424  		t.Run("ParseRawKey", func(t *testing.T) {
   425  			var v interface{}
   426  			if !assert.NoError(t, jwk.ParseRawKey([]byte(src), &v), `jwk.ParseRawKey should succeed`) {
   427  				return
   428  			}
   429  		})
   430  	}
   431  
   432  	t.Run("RSA Public Key", func(t *testing.T) {
   433  		t.Parallel()
   434  		const src = `{
   435        "e":"AQAB",
   436  			"kty":"RSA",
   437        "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
   438  		}`
   439  		verify(t, src, reflect.TypeOf((*jwk.RSAPublicKey)(nil)).Elem())
   440  	})
   441  	t.Run("RSA Private Key", func(t *testing.T) {
   442  		t.Parallel()
   443  		const src = `{
   444        "kty":"RSA",
   445        "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
   446        "e":"AQAB",
   447        "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
   448        "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
   449        "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
   450        "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
   451        "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
   452        "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
   453        "alg":"RS256",
   454        "kid":"2011-04-29"
   455       }`
   456  		verify(t, src, reflect.TypeOf((*jwk.RSAPrivateKey)(nil)).Elem())
   457  	})
   458  	t.Run("ECDSA Private Key", func(t *testing.T) {
   459  		t.Parallel()
   460  		const src = `{
   461  		  "kty" : "EC",
   462  		  "crv" : "P-256",
   463  		  "x"   : "SVqB4JcUD6lsfvqMr-OKUNUphdNn64Eay60978ZlL74",
   464  		  "y"   : "lf0u0pMj4lGAzZix5u4Cm5CMQIgMNpkwy163wtKYVKI",
   465  		  "d"   : "0g5vAEKzugrXaRbgKG0Tj2qJ5lMP4Bezds1_sTybkfk"
   466  		}`
   467  		verify(t, src, reflect.TypeOf((*jwk.ECDSAPrivateKey)(nil)).Elem())
   468  	})
   469  	t.Run("Invalid ECDSA Private Key", func(t *testing.T) {
   470  		t.Parallel()
   471  		const src = `{
   472  		  "kty" : "EC",
   473  		  "crv" : "P-256",
   474  		  "y"   : "lf0u0pMj4lGAzZix5u4Cm5CMQIgMNpkwy163wtKYVKI",
   475  		  "d"   : "0g5vAEKzugrXaRbgKG0Tj2qJ5lMP4Bezds1_sTybkfk"
   476  		}`
   477  		_, err := jwk.ParseString(src)
   478  		if !assert.Error(t, err, `jwk.ParseString should fail`) {
   479  			return
   480  		}
   481  	})
   482  	t.Run("Ed25519 Public Key", func(t *testing.T) {
   483  		t.Parallel()
   484  		// Key taken from RFC 8037
   485  		const src = `{
   486  		  "kty" : "OKP",
   487  		  "crv" : "Ed25519",
   488  		  "x"   : "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
   489  		}`
   490  		verify(t, src, reflect.TypeOf((*jwk.OKPPublicKey)(nil)).Elem())
   491  	})
   492  	t.Run("Ed25519 Private Key", func(t *testing.T) {
   493  		t.Parallel()
   494  		// Key taken from RFC 8037
   495  		const src = `{
   496  		  "kty" : "OKP",
   497  		  "crv" : "Ed25519",
   498  		  "d"   : "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
   499  		  "x"   : "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo"
   500  		}`
   501  		verify(t, src, reflect.TypeOf((*jwk.OKPPrivateKey)(nil)).Elem())
   502  	})
   503  	t.Run("X25519 Public Key", func(t *testing.T) {
   504  		t.Parallel()
   505  		// Key taken from RFC 8037
   506  		const src = `{
   507  		  "kty" : "OKP",
   508  		  "crv" : "X25519",
   509  		  "x"   : "3p7bfXt9wbTTW2HC7OQ1Nz-DQ8hbeGdNrfx-FG-IK08"
   510  		}`
   511  		verify(t, src, reflect.TypeOf((*jwk.OKPPublicKey)(nil)).Elem())
   512  	})
   513  	t.Run("X25519 Private Key", func(t *testing.T) {
   514  		t.Parallel()
   515  		// Key taken from RFC 8037
   516  		const src = `{
   517  		  "kty" : "OKP",
   518  		  "crv" : "X25519",
   519  		  "d"   : "dwdtCnMYpX08FsFyUbJmRd9ML4frwJkqsXf7pR25LCo",
   520  		  "x"   : "hSDwCYkwp1R0i33ctD73Wg2_Og0mOBr066SpjqqbTmo"
   521  		}`
   522  		verify(t, src, reflect.TypeOf((*jwk.OKPPrivateKey)(nil)).Elem())
   523  	})
   524  }
   525  
   526  func TestRoundtrip(t *testing.T) {
   527  	t.Parallel()
   528  	generateRSA := func(use string, keyID string) (jwk.Key, error) {
   529  		k, err := jwxtest.GenerateRsaJwk()
   530  		if err != nil {
   531  			return nil, err
   532  		}
   533  
   534  		k.Set(jwk.KeyUsageKey, use)
   535  		k.Set(jwk.KeyIDKey, keyID)
   536  		return k, nil
   537  	}
   538  
   539  	generateECDSA := func(use, keyID string) (jwk.Key, error) {
   540  		k, err := jwxtest.GenerateEcdsaJwk()
   541  		if err != nil {
   542  			return nil, err
   543  		}
   544  
   545  		k.Set(jwk.KeyUsageKey, use)
   546  		k.Set(jwk.KeyIDKey, keyID)
   547  		return k, nil
   548  	}
   549  
   550  	generateSymmetric := func(use, keyID string) (jwk.Key, error) {
   551  		k, err := jwxtest.GenerateSymmetricJwk()
   552  		if err != nil {
   553  			return nil, err
   554  		}
   555  
   556  		k.Set(jwk.KeyUsageKey, use)
   557  		k.Set(jwk.KeyIDKey, keyID)
   558  		return k, nil
   559  	}
   560  
   561  	generateEd25519 := func(use, keyID string) (jwk.Key, error) {
   562  		k, err := jwxtest.GenerateEd25519Jwk()
   563  		if err != nil {
   564  			return nil, err
   565  		}
   566  
   567  		k.Set(jwk.KeyUsageKey, use)
   568  		k.Set(jwk.KeyIDKey, keyID)
   569  		return k, nil
   570  	}
   571  
   572  	generateX25519 := func(use, keyID string) (jwk.Key, error) {
   573  		k, err := jwxtest.GenerateX25519Jwk()
   574  		if err != nil {
   575  			return nil, err
   576  		}
   577  
   578  		k.Set(jwk.KeyUsageKey, use)
   579  		k.Set(jwk.KeyIDKey, keyID)
   580  		return k, nil
   581  	}
   582  
   583  	tests := []struct {
   584  		generate func(string, string) (jwk.Key, error)
   585  		use      string
   586  		keyID    string
   587  	}{
   588  		{
   589  			use:      "enc",
   590  			keyID:    "enc1",
   591  			generate: generateRSA,
   592  		},
   593  		{
   594  			use:      "enc",
   595  			keyID:    "enc2",
   596  			generate: generateRSA,
   597  		},
   598  		{
   599  			use:      "sig",
   600  			keyID:    "sig1",
   601  			generate: generateRSA,
   602  		},
   603  		{
   604  			use:      "sig",
   605  			keyID:    "sig2",
   606  			generate: generateRSA,
   607  		},
   608  		{
   609  			use:      "sig",
   610  			keyID:    "sig3",
   611  			generate: generateSymmetric,
   612  		},
   613  		{
   614  			use:      "enc",
   615  			keyID:    "enc4",
   616  			generate: generateECDSA,
   617  		},
   618  		{
   619  			use:      "enc",
   620  			keyID:    "enc5",
   621  			generate: generateECDSA,
   622  		},
   623  		{
   624  			use:      "sig",
   625  			keyID:    "sig4",
   626  			generate: generateECDSA,
   627  		},
   628  		{
   629  			use:      "sig",
   630  			keyID:    "sig5",
   631  			generate: generateECDSA,
   632  		},
   633  		{
   634  			use:      "sig",
   635  			keyID:    "sig6",
   636  			generate: generateEd25519,
   637  		},
   638  		{
   639  			use:      "enc",
   640  			keyID:    "enc6",
   641  			generate: generateX25519,
   642  		},
   643  	}
   644  
   645  	ks1 := jwk.NewSet()
   646  	for _, tc := range tests {
   647  		key, err := tc.generate(tc.use, tc.keyID)
   648  		if !assert.NoError(t, err, `tc.generate should succeed`) {
   649  			return
   650  		}
   651  		if !assert.True(t, ks1.Add(key), `ks1.Add should succeed`) {
   652  			return
   653  		}
   654  	}
   655  
   656  	buf, err := json.MarshalIndent(ks1, "", "  ")
   657  	if !assert.NoError(t, err, "JSON marshal succeeded") {
   658  		return
   659  	}
   660  
   661  	ks2, err := jwk.Parse(buf)
   662  	if !assert.NoError(t, err, "JSON unmarshal succeeded") {
   663  		t.Logf("%s", buf)
   664  		return
   665  	}
   666  
   667  	for _, tc := range tests {
   668  		key1, ok := ks2.LookupKeyID(tc.keyID)
   669  		if !assert.True(t, ok, "ks2.LookupKeyID should succeed") {
   670  			return
   671  		}
   672  
   673  		key2, ok := ks1.LookupKeyID(tc.keyID)
   674  		if !assert.True(t, ok, "ks1.LookupKeyID should succeed") {
   675  			return
   676  		}
   677  
   678  		pk1json, _ := json.Marshal(key1)
   679  		pk2json, _ := json.Marshal(key2)
   680  		if !assert.Equal(t, pk1json, pk2json, "Keys should match (kid = %s)", tc.keyID) {
   681  			return
   682  		}
   683  	}
   684  }
   685  
   686  func TestAccept(t *testing.T) {
   687  	t.Parallel()
   688  	t.Run("KeyOperation", func(t *testing.T) {
   689  		t.Parallel()
   690  		testcases := []struct {
   691  			Args  interface{}
   692  			Error bool
   693  		}{
   694  			{
   695  				Args: "sign",
   696  			},
   697  			{
   698  				Args: []jwk.KeyOperation{jwk.KeyOpSign, jwk.KeyOpVerify, jwk.KeyOpEncrypt, jwk.KeyOpDecrypt, jwk.KeyOpWrapKey, jwk.KeyOpUnwrapKey},
   699  			},
   700  			{
   701  				Args: jwk.KeyOperationList{jwk.KeyOpSign, jwk.KeyOpVerify, jwk.KeyOpEncrypt, jwk.KeyOpDecrypt, jwk.KeyOpWrapKey, jwk.KeyOpUnwrapKey},
   702  			},
   703  			{
   704  				Args: []interface{}{"sign", "verify", "encrypt", "decrypt", "wrapKey", "unwrapKey"},
   705  			},
   706  			{
   707  				Args: []string{"sign", "verify", "encrypt", "decrypt", "wrapKey", "unwrapKey"},
   708  			},
   709  			{
   710  				Args:  []string{"sigh"},
   711  				Error: true,
   712  			},
   713  		}
   714  
   715  		for _, test := range testcases {
   716  			var ops jwk.KeyOperationList
   717  			if test.Error {
   718  				if !assert.Error(t, ops.Accept(test.Args), `KeyOperationList.Accept should fail`) {
   719  					return
   720  				}
   721  			} else {
   722  				if !assert.NoError(t, ops.Accept(test.Args), `KeyOperationList.Accept should succeed`) {
   723  					return
   724  				}
   725  			}
   726  		}
   727  	})
   728  	t.Run("KeyUsage", func(t *testing.T) {
   729  		t.Parallel()
   730  		testcases := []struct {
   731  			Args  interface{}
   732  			Error bool
   733  		}{
   734  			{Args: jwk.ForSignature},
   735  			{Args: jwk.ForEncryption},
   736  			{Args: jwk.ForSignature.String()},
   737  			{Args: jwk.ForEncryption.String()},
   738  			{Args: jwk.KeyUsageType("bogus"), Error: true},
   739  			{Args: "bogus", Error: true},
   740  		}
   741  		for _, test := range testcases {
   742  			var usage jwk.KeyUsageType
   743  			if test.Error {
   744  				if !assert.Error(t, usage.Accept(test.Args), `KeyUsage.Accept should fail`) {
   745  					return
   746  				}
   747  			} else {
   748  				if !assert.NoError(t, usage.Accept(test.Args), `KeyUsage.Accept should succeed`) {
   749  					return
   750  				}
   751  			}
   752  		}
   753  	})
   754  }
   755  
   756  func TestAssignKeyID(t *testing.T) {
   757  	t.Parallel()
   758  	generators := []func() (jwk.Key, error){
   759  		jwxtest.GenerateRsaJwk,
   760  		jwxtest.GenerateRsaPublicJwk,
   761  		jwxtest.GenerateEcdsaJwk,
   762  		jwxtest.GenerateEcdsaPublicJwk,
   763  		jwxtest.GenerateSymmetricJwk,
   764  		jwxtest.GenerateEd25519Jwk,
   765  	}
   766  
   767  	for _, generator := range generators {
   768  		k, err := generator()
   769  		if !assert.NoError(t, err, `jwk generation should be successful`) {
   770  			return
   771  		}
   772  
   773  		if !assert.Empty(t, k.KeyID(), `k.KeyID should be non-empty`) {
   774  			return
   775  		}
   776  		if !assert.NoError(t, jwk.AssignKeyID(k), `AssignKeyID shuld be successful`) {
   777  			return
   778  		}
   779  
   780  		if !assert.NotEmpty(t, k.KeyID(), `k.KeyID should be non-empty`) {
   781  			return
   782  		}
   783  	}
   784  }
   785  
   786  func TestPublicKeyOf(t *testing.T) {
   787  	t.Parallel()
   788  
   789  	rsakey, err := jwxtest.GenerateRsaKey()
   790  	if !assert.NoError(t, err, `generating raw RSA key should succeed`) {
   791  		return
   792  	}
   793  
   794  	ecdsakey, err := jwxtest.GenerateEcdsaKey(jwa.P521)
   795  	if !assert.NoError(t, err, `generating raw ECDSA key should succeed`) {
   796  		return
   797  	}
   798  
   799  	octets := jwxtest.GenerateSymmetricKey()
   800  
   801  	ed25519key, err := jwxtest.GenerateEd25519Key()
   802  	if !assert.NoError(t, err, `generating raw Ed25519 key should succeed`) {
   803  		return
   804  	}
   805  
   806  	x25519key, err := jwxtest.GenerateX25519Key()
   807  	if !assert.NoError(t, err, `generating raw X25519 key should succeed`) {
   808  		return
   809  	}
   810  
   811  	keys := []struct {
   812  		Key           interface{}
   813  		PublicKeyType reflect.Type
   814  	}{
   815  		{
   816  			Key:           rsakey,
   817  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(rsakey.PublicKey)),
   818  		},
   819  		{
   820  			Key:           *rsakey,
   821  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(rsakey.PublicKey)),
   822  		},
   823  		{
   824  			Key:           rsakey.PublicKey,
   825  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(rsakey.PublicKey)),
   826  		},
   827  		{
   828  			Key:           &rsakey.PublicKey,
   829  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(rsakey.PublicKey)),
   830  		},
   831  		{
   832  			Key:           ecdsakey,
   833  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(ecdsakey.PublicKey)),
   834  		},
   835  		{
   836  			Key:           *ecdsakey,
   837  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(ecdsakey.PublicKey)),
   838  		},
   839  		{
   840  			Key:           ecdsakey.PublicKey,
   841  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(ecdsakey.PublicKey)),
   842  		},
   843  		{
   844  			Key:           &ecdsakey.PublicKey,
   845  			PublicKeyType: reflect.PtrTo(reflect.TypeOf(ecdsakey.PublicKey)),
   846  		},
   847  		{
   848  			Key:           octets,
   849  			PublicKeyType: reflect.TypeOf(octets),
   850  		},
   851  		{
   852  			Key:           ed25519key,
   853  			PublicKeyType: reflect.TypeOf(ed25519key.Public()),
   854  		},
   855  		{
   856  			Key:           ed25519key.Public(),
   857  			PublicKeyType: reflect.TypeOf(ed25519key.Public()),
   858  		},
   859  		{
   860  			Key:           x25519key,
   861  			PublicKeyType: reflect.TypeOf(x25519key.Public()),
   862  		},
   863  		{
   864  			Key:           x25519key.Public(),
   865  			PublicKeyType: reflect.TypeOf(x25519key.Public()),
   866  		},
   867  	}
   868  
   869  	for _, key := range keys {
   870  		key := key
   871  		t.Run(fmt.Sprintf("%T", key.Key), func(t *testing.T) {
   872  			t.Parallel()
   873  
   874  			pubkey, err := jwk.PublicRawKeyOf(key.Key)
   875  			if !assert.NoError(t, err, `jwk.PublicKeyOf(%T) should succeed`, key.Key) {
   876  				return
   877  			}
   878  
   879  			if !assert.Equal(t, key.PublicKeyType, reflect.TypeOf(pubkey), `public key types should match (got %T)`, pubkey) {
   880  				return
   881  			}
   882  
   883  			// Go through jwk.New
   884  			jwkKey, err := jwk.New(key.Key)
   885  			if !assert.NoError(t, err, `jwk.New should succeed`) {
   886  				return
   887  			}
   888  
   889  			pubJwkKey, err := jwk.PublicKeyOf(jwkKey)
   890  			if !assert.NoError(t, err, `jwk.PublicKeyOf(%T) should succeed`, jwkKey) {
   891  				return
   892  			}
   893  
   894  			// Get the raw key to compare
   895  			var rawKey interface{}
   896  			if !assert.NoError(t, pubJwkKey.Raw(&rawKey), `pubJwkKey.Raw should succeed`) {
   897  				return
   898  			}
   899  
   900  			if !assert.Equal(t, key.PublicKeyType, reflect.TypeOf(rawKey), `public key types should match (got %T)`, rawKey) {
   901  				return
   902  			}
   903  		})
   904  	}
   905  	t.Run("Set", func(t *testing.T) {
   906  		var setKeys []struct {
   907  			Key           jwk.Key
   908  			PublicKeyType reflect.Type
   909  		}
   910  		set := jwk.NewSet()
   911  		count := 0
   912  		for _, key := range keys {
   913  			if reflect.TypeOf(key.Key) == key.PublicKeyType {
   914  				continue
   915  			}
   916  			jwkKey, err := jwk.New(key.Key)
   917  			if !assert.NoError(t, err, `jwk.New should succeed`) {
   918  				return
   919  			}
   920  			jwkKey.Set(jwk.KeyIDKey, fmt.Sprintf("key%d", count))
   921  			setKeys = append(setKeys, struct {
   922  				Key           jwk.Key
   923  				PublicKeyType reflect.Type
   924  			}{
   925  				Key:           jwkKey,
   926  				PublicKeyType: key.PublicKeyType,
   927  			})
   928  			set.Add(jwkKey)
   929  			count++
   930  		}
   931  
   932  		newSet, err := jwk.PublicSetOf(set)
   933  		if !assert.NoError(t, err, `jwk.PublicKeyOf(jwk.Set) should succeed`) {
   934  			return
   935  		}
   936  
   937  		for i, key := range setKeys {
   938  			setKey, ok := newSet.Get(i)
   939  			if !assert.True(t, ok, `element %d should be present`, i) {
   940  				return
   941  			}
   942  
   943  			if !assert.Equal(t, fmt.Sprintf("key%d", i), setKey.KeyID(), `KeyID() should match for %T`, setKey) {
   944  				return
   945  			}
   946  
   947  			// Get the raw key to compare
   948  			var rawKey interface{}
   949  			if !assert.NoError(t, setKey.Raw(&rawKey), `pubJwkKey.Raw should succeed`) {
   950  				return
   951  			}
   952  
   953  			if !assert.Equal(t, key.PublicKeyType, reflect.TypeOf(rawKey), `public key types should match (got %T)`, rawKey) {
   954  				return
   955  			}
   956  		}
   957  	})
   958  }
   959  
   960  func TestIssue207(t *testing.T) {
   961  	t.Parallel()
   962  	const src = `{"kty":"EC","alg":"ECMR","crv":"P-521","key_ops":["deriveKey"],"x":"AJwCS845x9VljR-fcrN2WMzIJHDYuLmFShhyu8ci14rmi2DMFp8txIvaxG8n7ZcODeKIs1EO4E_Bldm_pxxs8cUn","y":"ASjz754cIQHPJObihPV8D7vVNfjp_nuwP76PtbLwUkqTk9J1mzCDKM3VADEk-Z1tP-DHiwib6If8jxnb_FjNkiLJ"}`
   963  
   964  	// Using a loop here because we're using sync.Pool
   965  	// just for sanity.
   966  	for i := 0; i < 10; i++ {
   967  		k, err := jwk.ParseKey([]byte(src))
   968  		if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
   969  			return
   970  		}
   971  
   972  		thumb, err := k.Thumbprint(crypto.SHA1)
   973  		if !assert.NoError(t, err, `k.Thumbprint should succeed`) {
   974  			return
   975  		}
   976  
   977  		if !assert.Equal(t, `2Mc_43O_BOrOJTNrGX7uJ6JsIYE`, base64.EncodeToString(thumb), `thumbprints should match`) {
   978  			return
   979  		}
   980  	}
   981  }
   982  
   983  func TestIssue270(t *testing.T) {
   984  	t.Parallel()
   985  	const src = `{"kty":"EC","alg":"ECMR","crv":"P-521","key_ops":["deriveKey"],"x":"AJwCS845x9VljR-fcrN2WMzIJHDYuLmFShhyu8ci14rmi2DMFp8txIvaxG8n7ZcODeKIs1EO4E_Bldm_pxxs8cUn","y":"ASjz754cIQHPJObihPV8D7vVNfjp_nuwP76PtbLwUkqTk9J1mzCDKM3VADEk-Z1tP-DHiwib6If8jxnb_FjNkiLJ"}`
   986  	k, err := jwk.ParseKey([]byte(src))
   987  	if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
   988  		return
   989  	}
   990  
   991  	for _, usage := range []string{"sig", "enc"} {
   992  		if !assert.NoError(t, k.Set(jwk.KeyUsageKey, usage)) {
   993  			return
   994  		}
   995  		if !assert.NoError(t, k.Set(jwk.KeyUsageKey, jwk.KeyUsageType(usage))) {
   996  			return
   997  		}
   998  	}
   999  }
  1000  
  1001  func TestReadFile(t *testing.T) {
  1002  	t.Parallel()
  1003  	if !jose.Available() {
  1004  		t.SkipNow()
  1005  	}
  1006  
  1007  	ctx, cancel := context.WithCancel(context.Background())
  1008  	defer cancel()
  1009  
  1010  	fn, clean, err := jose.GenerateJwk(ctx, t, `{"alg": "RS256"}`)
  1011  	if !assert.NoError(t, err, `jose.GenerateJwk`) {
  1012  		return
  1013  	}
  1014  
  1015  	defer clean()
  1016  	if _, err := jwk.ReadFile(fn); !assert.NoError(t, err, `jwk.ReadFile should succeed`) {
  1017  		return
  1018  	}
  1019  }
  1020  
  1021  func TestRSA(t *testing.T) {
  1022  	t.Parallel()
  1023  	t.Run("PublicKey", func(t *testing.T) {
  1024  		t.Parallel()
  1025  		VerifyKey(t, map[string]keyDef{
  1026  			jwk.RSAEKey: expectBase64(keyDef{
  1027  				Method: "E",
  1028  				Value:  "AQAB",
  1029  			}),
  1030  			jwk.KeyTypeKey: {
  1031  				Method: "KeyType",
  1032  				Value:  jwa.RSA,
  1033  			},
  1034  			jwk.RSANKey: expectBase64(keyDef{
  1035  				Method: "N",
  1036  				Value:  "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  1037  			}),
  1038  		})
  1039  		t.Run("New", func(t *testing.T) {
  1040  			for _, raw := range []rsa.PublicKey{
  1041  				{},
  1042  			} {
  1043  				_, err := jwk.New(raw)
  1044  				if !assert.Error(t, err, `jwk.New should fail for invalid key`) {
  1045  					return
  1046  				}
  1047  			}
  1048  		})
  1049  	})
  1050  	t.Run("Private Key", func(t *testing.T) {
  1051  		t.Parallel()
  1052  		VerifyKey(t, map[string]keyDef{
  1053  			jwk.KeyTypeKey: {
  1054  				Method: "KeyType",
  1055  				Value:  jwa.RSA,
  1056  			},
  1057  			jwk.RSANKey: expectBase64(keyDef{
  1058  				Method: "N",
  1059  				Value:  "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
  1060  			}),
  1061  			jwk.RSAEKey: expectBase64(keyDef{
  1062  				Method: "E",
  1063  				Value:  "AQAB",
  1064  			}),
  1065  			jwk.RSADKey: expectBase64(keyDef{
  1066  				Method: "D",
  1067  				Value:  "X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
  1068  			}),
  1069  			jwk.RSAPKey: expectBase64(keyDef{
  1070  				Method: "P",
  1071  				Value:  "83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
  1072  			}),
  1073  			jwk.RSAQKey: expectBase64(keyDef{
  1074  				Method: "Q",
  1075  				Value:  "3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
  1076  			}),
  1077  			jwk.RSADPKey: expectBase64(keyDef{
  1078  				Method: "DP",
  1079  				Value:  "G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
  1080  			}),
  1081  			jwk.RSADQKey: expectBase64(keyDef{
  1082  				Method: "DQ",
  1083  				Value:  "s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
  1084  			}),
  1085  			jwk.RSAQIKey: expectBase64(keyDef{
  1086  				Method: "QI",
  1087  				Value:  "GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
  1088  			}),
  1089  		})
  1090  		t.Run("New", func(t *testing.T) {
  1091  			for _, raw := range []rsa.PrivateKey{
  1092  				{}, // Missing D
  1093  				{ // Missing primes
  1094  					D: &big.Int{},
  1095  				},
  1096  				{ // Missing Primes[0]
  1097  					D:      &big.Int{},
  1098  					Primes: []*big.Int{nil, {}},
  1099  				},
  1100  				{ // Missing Primes[1]
  1101  					D:      &big.Int{},
  1102  					Primes: []*big.Int{{}, nil},
  1103  				},
  1104  				{ // Missing PrivateKey.N
  1105  					D:      &big.Int{},
  1106  					Primes: []*big.Int{{}, {}},
  1107  				},
  1108  			} {
  1109  				_, err := jwk.New(raw)
  1110  				if !assert.Error(t, err, `jwk.New should fail for empty key`) {
  1111  					return
  1112  				}
  1113  			}
  1114  		})
  1115  	})
  1116  	t.Run("Thumbprint", func(t *testing.T) {
  1117  		expected := []byte{55, 54, 203, 177, 120, 124, 184, 48, 156, 119, 238,
  1118  			140, 55, 5, 197, 225, 111, 251, 158, 133, 151, 21, 144, 31, 30, 76, 89,
  1119  			177, 17, 130, 245, 123,
  1120  		}
  1121  		const src = `{
  1122  	   			"kty":"RSA",
  1123  	   			"e": "AQAB",
  1124  	   			"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
  1125  	   		}`
  1126  
  1127  		key, err := jwk.ParseKey([]byte(src))
  1128  		if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
  1129  			return
  1130  		}
  1131  
  1132  		tp, err := key.Thumbprint(crypto.SHA256)
  1133  		if !assert.NoError(t, err, "Thumbprint should succeed") {
  1134  			return
  1135  		}
  1136  
  1137  		if !assert.Equal(t, expected, tp, "Thumbprint should match") {
  1138  			return
  1139  		}
  1140  	})
  1141  }
  1142  
  1143  func TestECDSA(t *testing.T) {
  1144  	t.Run("PrivateKey", func(t *testing.T) {
  1145  		t.Run("New", func(t *testing.T) {
  1146  			for _, raw := range []ecdsa.PrivateKey{
  1147  				{},
  1148  				{ // Missing PublicKey
  1149  					D: &big.Int{},
  1150  				},
  1151  				{ // Missing PublicKey.X
  1152  					D: &big.Int{},
  1153  					PublicKey: ecdsa.PublicKey{
  1154  						Y: &big.Int{},
  1155  					},
  1156  				},
  1157  				{ // Missing PublicKey.Y
  1158  					D: &big.Int{},
  1159  					PublicKey: ecdsa.PublicKey{
  1160  						X: &big.Int{},
  1161  					},
  1162  				},
  1163  			} {
  1164  				_, err := jwk.New(raw)
  1165  				if !assert.Error(t, err, `jwk.New should fail for invalid key`) {
  1166  					return
  1167  				}
  1168  			}
  1169  		})
  1170  		VerifyKey(t, map[string]keyDef{
  1171  			jwk.KeyTypeKey: {
  1172  				Method: "KeyType",
  1173  				Value:  jwa.EC,
  1174  			},
  1175  			jwk.ECDSACrvKey: {
  1176  				Method: "Crv",
  1177  				Value:  jwa.P256,
  1178  			},
  1179  			jwk.ECDSAXKey: expectBase64(keyDef{
  1180  				Method: "X",
  1181  				Value:  "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
  1182  			}),
  1183  			jwk.ECDSAYKey: expectBase64(keyDef{
  1184  				Method: "Y",
  1185  				Value:  "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
  1186  			}),
  1187  			jwk.ECDSADKey: expectBase64(keyDef{
  1188  				Method: "D",
  1189  				Value:  "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE",
  1190  			}),
  1191  		})
  1192  	})
  1193  	t.Run("PublicKey", func(t *testing.T) {
  1194  		t.Run("New", func(t *testing.T) {
  1195  			for _, raw := range []ecdsa.PublicKey{
  1196  				{},
  1197  				{ // Missing X
  1198  					Y: &big.Int{},
  1199  				},
  1200  				{ // Missing Y
  1201  					X: &big.Int{},
  1202  				},
  1203  			} {
  1204  				_, err := jwk.New(raw)
  1205  				if !assert.Error(t, err, `jwk.New should fail for invalid key`) {
  1206  					return
  1207  				}
  1208  			}
  1209  		})
  1210  		VerifyKey(t, map[string]keyDef{
  1211  			jwk.KeyTypeKey: {
  1212  				Method: "KeyType",
  1213  				Value:  jwa.EC,
  1214  			},
  1215  			jwk.ECDSACrvKey: {
  1216  				Method: "Crv",
  1217  				Value:  jwa.P256,
  1218  			},
  1219  			jwk.ECDSAXKey: expectBase64(keyDef{
  1220  				Method: "X",
  1221  				Value:  "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
  1222  			}),
  1223  			jwk.ECDSAYKey: expectBase64(keyDef{
  1224  				Method: "Y",
  1225  				Value:  "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
  1226  			}),
  1227  		})
  1228  	})
  1229  	t.Run("Curve types", func(t *testing.T) {
  1230  		for _, alg := range ecutil.AvailableAlgorithms() {
  1231  			alg := alg
  1232  			t.Run(alg.String(), func(t *testing.T) {
  1233  				key, err := jwxtest.GenerateEcdsaKey(alg)
  1234  				if !assert.NoError(t, err, `jwxtest.GenerateEcdsaKey should succeed`) {
  1235  					return
  1236  				}
  1237  
  1238  				privkey := jwk.NewECDSAPrivateKey()
  1239  				if !assert.NoError(t, privkey.FromRaw(key), `privkey.FromRaw should succeed`) {
  1240  					return
  1241  				}
  1242  				pubkey := jwk.NewECDSAPublicKey()
  1243  				if !assert.NoError(t, pubkey.FromRaw(&key.PublicKey), `pubkey.FromRaw should succeed`) {
  1244  					return
  1245  				}
  1246  
  1247  				privtp, err := privkey.Thumbprint(crypto.SHA512)
  1248  				if !assert.NoError(t, err, `privkey.Thumbprint should succeed`) {
  1249  					return
  1250  				}
  1251  
  1252  				pubtp, err := pubkey.Thumbprint(crypto.SHA512)
  1253  				if !assert.NoError(t, err, `pubkey.Thumbprint should succeed`) {
  1254  					return
  1255  				}
  1256  
  1257  				if !assert.Equal(t, privtp, pubtp, `Thumbprints should match`) {
  1258  					return
  1259  				}
  1260  			})
  1261  		}
  1262  	})
  1263  }
  1264  
  1265  func TestSymmetric(t *testing.T) {
  1266  	t.Run("Key", func(t *testing.T) {
  1267  		VerifyKey(t, map[string]keyDef{
  1268  			jwk.KeyTypeKey: {
  1269  				Method: "KeyType",
  1270  				Value:  jwa.OctetSeq,
  1271  			},
  1272  			jwk.SymmetricOctetsKey: expectBase64(keyDef{
  1273  				Method: "Octets",
  1274  				Value:  "aGVsbG8K",
  1275  			}),
  1276  		})
  1277  	})
  1278  }
  1279  
  1280  func TestOKP(t *testing.T) {
  1281  	t.Parallel()
  1282  
  1283  	t.Run("Ed25519", func(t *testing.T) {
  1284  		t.Parallel()
  1285  		t.Run("PrivateKey", func(t *testing.T) {
  1286  			t.Parallel()
  1287  			VerifyKey(t, map[string]keyDef{
  1288  				jwk.KeyTypeKey: {
  1289  					Method: "KeyType",
  1290  					Value:  jwa.OKP,
  1291  				},
  1292  				jwk.OKPDKey: expectBase64(keyDef{
  1293  					Method: "D",
  1294  					Value:  "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
  1295  				}),
  1296  				jwk.OKPXKey: expectBase64(keyDef{
  1297  					Method: "X",
  1298  					Value:  "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
  1299  				}),
  1300  				jwk.OKPCrvKey: {
  1301  					Method: "Crv",
  1302  					Value:  jwa.Ed25519,
  1303  				},
  1304  			})
  1305  		})
  1306  		t.Run("PublicKey", func(t *testing.T) {
  1307  			t.Parallel()
  1308  			VerifyKey(t, map[string]keyDef{
  1309  				jwk.KeyTypeKey: {
  1310  					Method: "KeyType",
  1311  					Value:  jwa.OKP,
  1312  				},
  1313  				jwk.OKPXKey: expectBase64(keyDef{
  1314  					Method: "X",
  1315  					Value:  "11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo",
  1316  				}),
  1317  				jwk.OKPCrvKey: {
  1318  					Method: "Crv",
  1319  					Value:  jwa.Ed25519,
  1320  				},
  1321  			})
  1322  		})
  1323  	})
  1324  	t.Run("X25519", func(t *testing.T) {
  1325  		t.Parallel()
  1326  		t.Run("PublicKey", func(t *testing.T) {
  1327  			t.Parallel()
  1328  			VerifyKey(t, map[string]keyDef{
  1329  				jwk.KeyTypeKey: {
  1330  					Method: "KeyType",
  1331  					Value:  jwa.OKP,
  1332  				},
  1333  				jwk.OKPXKey: expectBase64(keyDef{
  1334  					Method: "X",
  1335  					Value:  "3p7bfXt9wbTTW2HC7OQ1Nz-DQ8hbeGdNrfx-FG-IK08",
  1336  				}),
  1337  				jwk.OKPCrvKey: {
  1338  					Method: "Crv",
  1339  					Value:  jwa.X25519,
  1340  				},
  1341  			})
  1342  		})
  1343  	})
  1344  }
  1345  
  1346  func TestCustomField(t *testing.T) {
  1347  	// XXX has global effect!!!
  1348  	jwk.RegisterCustomField(`x-birthday`, time.Time{})
  1349  	defer jwk.RegisterCustomField(`x-birthday`, nil)
  1350  
  1351  	expected := time.Date(2015, 11, 4, 5, 12, 52, 0, time.UTC)
  1352  	bdaybytes, _ := expected.MarshalText() // RFC3339
  1353  
  1354  	var b strings.Builder
  1355  	b.WriteString(`{"e":"AQAB", "kty":"RSA", "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw","x-birthday":"`)
  1356  	b.Write(bdaybytes)
  1357  	b.WriteString(`"}`)
  1358  	src := b.String()
  1359  
  1360  	t.Run("jwk.ParseKey", func(t *testing.T) {
  1361  		key, err := jwk.ParseKey([]byte(src))
  1362  		if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
  1363  			return
  1364  		}
  1365  
  1366  		v, ok := key.Get(`x-birthday`)
  1367  		if !assert.True(t, ok, `key.Get("x-birthday") should succeed`) {
  1368  			return
  1369  		}
  1370  
  1371  		if !assert.Equal(t, expected, v, `values should match`) {
  1372  			return
  1373  		}
  1374  	})
  1375  	t.Run("json.Unmarshal", func(t *testing.T) {
  1376  		key := jwk.NewRSAPublicKey()
  1377  		if !assert.NoError(t, json.Unmarshal([]byte(src), key), `json.Unmarshal should succeed`) {
  1378  			return
  1379  		}
  1380  
  1381  		v, ok := key.Get(`x-birthday`)
  1382  		if !assert.True(t, ok, `key.Get("x-birthday") should succeed`) {
  1383  			return
  1384  		}
  1385  
  1386  		if !assert.Equal(t, expected, v, `values should match`) {
  1387  			return
  1388  		}
  1389  	})
  1390  }
  1391  
  1392  func TestCertificate(t *testing.T) {
  1393  	const src = `-----BEGIN CERTIFICATE-----
  1394  MIIEljCCAn4CCQCTQBoGDvUbQTANBgkqhkiG9w0BAQsFADANMQswCQYDVQQGEwJK
  1395  UDAeFw0yMTA0MDEwMDE4MjhaFw0yMjA0MDEwMDE4MjhaMA0xCzAJBgNVBAYTAkpQ
  1396  MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvws4H/OxVS3CW1zvUgjs
  1397  H443df9zCAblLVPPdeRD11Jl1OZmGS7rtQNjQyT5xGpeuk77ZJcfDNLx+mSEtiYQ
  1398  V37GD5MPz+RX3hP2azuLvxoBseaHE6kC8tkDed8buQLl1hgms15KmKnt7E8B+EK2
  1399  1YRj0w6ZzehIllTbbj6gDJ39kZ2VHdLf5+4W0Kyh9cM4aA0si2jQJQsohW2rpt89
  1400  b+IagFau+sxP3GFUjSEvyXIamXhS0NLWuAW9UvY/RwhnIo5BzmWZd/y2R305T+QT
  1401  rHtb/8aGav8mP3uDx6AMDp/0UMKFUO4mpoOusMnrplUPS4Lz6RNpffmrrglOEuRZ
  1402  /eSFzGL35OeL12aYSyrbFIVsc/aLs6MkoplsuSG6Zhx345h/dA2a8Ub5khr6bksP
  1403  zGLer+bpBrQQsy21unvCIUz5y7uaYhV3Ql+aIZ+dwpEgZ3xxAvdKKeoCGQlhH/4J
  1404  0sSuutUtuTLfrBSgLHJEv2HIzeynChL2CYR8aku/nL68VTdmSt9UY2JGMOf9U8BI
  1405  fGRpkWBvI8hddMxNm8wF+09WScaZ2JWu7qW/l2jOdgesPIWRg+Hm3NaRSHqAWCOq
  1406  VUJk9WkCAye0FPALqSvH0ApDKxNtGZb5JZRCW19TqmhgXbAqIf5hsxDaGIXZcW9S
  1407  CqapZPw7Ccs7BOKSFvmM9p0CAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAVfLzKRdA
  1408  0vFpAAp3K+CDth7mag2WWFOXjlWZ+4pxfEBX3k7erJbj6+qYuCvCHXqIZnK1kZzD
  1409  p4zwsu8t8RfSmPvxcm/jkvecG4DAIGTdhBVtAf/9PU3e4kZFQCqizicQABh+ZFKV
  1410  dDtkRebUA5EAvP8E/OrvrjYU5xnOxOZU3arVXJfKFjVD619qLuF8XXW5700Gdqwn
  1411  wBgasTCCg9+tniiscKaET1m9C4PdrlXuAIscV9tGcJ7yEAao1BXokyJ+mK6K2Zv1
  1412  z/vvUJA/rGMBJoUjnWrRHON1JMNou2KyRO6z37GpRnfPiNgFpGv2x3ZNeix7H4bP
  1413  6+x4KZWQir5047p9hV4YrqMXeULEj3uG2GnOgdR7+hiN39arFVr11DMgABmx19SM
  1414  VQpTHrC8a605wwCBWnkiYdNojLa5WgeEHdBghKVpWnx9frYgZcz2UP861el5Lg9R
  1415  j04wkGL4IORYiM7VHSHNU4u/dlgfQE1y0T+1CzXwquy4csvbBzBKnZ1o9ZBsOtWS
  1416  ox0RaBsMD70mvTwKKmlCSD5HgZZTC0CfGWk4dQp/Mct5Z0x0HJMEJCJzpgTn3CRX
  1417  z8CjezfckLs7UKJOlhu3OU9TFsiGDzSDBZdDWO1/uciJ/AAWeSmsBt8cKL0MirIr
  1418  c4wOvhbalcX0FqTM3mXCgMFRbibquhwdxbU=
  1419  -----END CERTIFICATE-----`
  1420  	key, err := jwk.ParseKey([]byte(src), jwk.WithPEM(true))
  1421  	if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
  1422  		return
  1423  	}
  1424  
  1425  	if !assert.Equal(t, jwa.RSA, key.KeyType(), `key type should be RSA`) {
  1426  		return
  1427  	}
  1428  
  1429  	var pubkey rsa.PublicKey
  1430  	if !assert.NoError(t, key.Raw(&pubkey), `key.Raw should succeed`) {
  1431  		return
  1432  	}
  1433  
  1434  	N := &big.Int{}
  1435  	N, _ = N.SetString(`779390807991489150242580488277564408218067197694419403671246387831173881192316375931050469298375090533614189460270485948672580508192398132571230359681952349714254730569052029178325305344289615160181016909374016900403698428293142159695593998453788610098596363011884623801134548926432366560975619087466760747503535615491182090094278093592303467050094984372887804234341012289019841973178427045121609424191835554013017436743418746919496835541323790719629313070434897002108079086472354410640690933161025543816362962891190753195691593288890628966181309776957070655619665306995097798188588453327627252794498823229009195585001242181503742627414517186199717150645163224325403559815442522031412813762764879089624715721999552786759649849125487587658121901233329199571710176245013452847516179837767710027433169340850618643815395642568876192931279303797384539146396956216244189819533317558165234451499206045369678277987397913889177569796721689284116762473340601498426367267765652880247655009239893325078809797979771964770948333084772104541394544131668212262901583064272659565503500144472388676955404823979083054620299811247635425415371418720649368570747531327436083928369741631909855731133100553629456091216238379430154237251461586878393695925917`, 10)
  1436  
  1437  	if !assert.Equal(t, N, pubkey.N, `value for N should match`) {
  1438  		return
  1439  	}
  1440  
  1441  	if !assert.Equal(t, 65537, pubkey.E, `value for E should amtch`) {
  1442  		return
  1443  	}
  1444  }
  1445  
  1446  type typedField struct {
  1447  	Foo string
  1448  	Bar int
  1449  }
  1450  
  1451  func TestTypedFields(t *testing.T) {
  1452  	expected := &typedField{Foo: "Foo", Bar: 0xdeadbeef}
  1453  	var keys []jwk.Key
  1454  	{
  1455  		k1, _ := jwxtest.GenerateRsaJwk()
  1456  		k2, _ := jwxtest.GenerateEcdsaJwk()
  1457  		k3, _ := jwxtest.GenerateSymmetricJwk()
  1458  		k4, _ := jwxtest.GenerateEd25519Jwk()
  1459  		keys = []jwk.Key{k1, k2, k3, k4}
  1460  	}
  1461  	for _, key := range keys {
  1462  		key.Set("typed-field", expected)
  1463  	}
  1464  
  1465  	testcases := []struct {
  1466  		Name        string
  1467  		Options     []jwk.ParseOption
  1468  		PostProcess func(*testing.T, interface{}) (*typedField, error)
  1469  	}{
  1470  		{
  1471  			Name:    "Basic",
  1472  			Options: []jwk.ParseOption{jwk.WithTypedField("typed-field", typedField{})},
  1473  			PostProcess: func(t *testing.T, field interface{}) (*typedField, error) {
  1474  				t.Helper()
  1475  				v, ok := field.(typedField)
  1476  				if !ok {
  1477  					return nil, errors.Errorf(`field value should be of type "typedField", but got %T`, field)
  1478  				}
  1479  				return &v, nil
  1480  			},
  1481  		},
  1482  		{
  1483  			Name:    "json.RawMessage",
  1484  			Options: []jwk.ParseOption{jwk.WithTypedField("typed-field", json.RawMessage{})},
  1485  			PostProcess: func(t *testing.T, field interface{}) (*typedField, error) {
  1486  				t.Helper()
  1487  				v, ok := field.(json.RawMessage)
  1488  				if !ok {
  1489  					return nil, errors.Errorf(`field value should be of type "json.RawMessage", but got %T`, field)
  1490  				}
  1491  
  1492  				var c typedField
  1493  				if err := json.Unmarshal(v, &c); err != nil {
  1494  					return nil, errors.Wrap(err, `json.Unmarshal failed`)
  1495  				}
  1496  
  1497  				return &c, nil
  1498  			},
  1499  		},
  1500  	}
  1501  
  1502  	for _, key := range keys {
  1503  		key := key
  1504  		serialized, err := json.Marshal(key)
  1505  		if !assert.NoError(t, err, `json.Marshal should succeed`) {
  1506  			return
  1507  		}
  1508  
  1509  		t.Run(fmt.Sprintf("%T", key), func(t *testing.T) {
  1510  			for _, tc := range testcases {
  1511  				tc := tc
  1512  				t.Run(tc.Name, func(t *testing.T) {
  1513  					got, err := jwk.ParseKey(serialized, tc.Options...)
  1514  					if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1515  						return
  1516  					}
  1517  
  1518  					v, ok := got.Get("typed-field")
  1519  					if !assert.True(t, ok, `got.Get() should succeed`) {
  1520  						return
  1521  					}
  1522  					field, err := tc.PostProcess(t, v)
  1523  					if !assert.NoError(t, err, `tc.PostProcess should succeed`) {
  1524  						return
  1525  					}
  1526  
  1527  					if !assert.Equal(t, field, expected, `field should match expected value`) {
  1528  						return
  1529  					}
  1530  				})
  1531  			}
  1532  		})
  1533  	}
  1534  
  1535  	t.Run("Set", func(t *testing.T) {
  1536  		s := jwk.NewSet()
  1537  		for _, key := range keys {
  1538  			s.Add(key)
  1539  		}
  1540  
  1541  		serialized, err := json.Marshal(s)
  1542  		if !assert.NoError(t, err, `json.Marshal should succeed`) {
  1543  			return
  1544  		}
  1545  
  1546  		for _, tc := range testcases {
  1547  			tc := tc
  1548  			t.Run(tc.Name, func(t *testing.T) {
  1549  				ctx, cancel := context.WithCancel(context.Background())
  1550  				defer cancel()
  1551  
  1552  				got, err := jwk.Parse(serialized, tc.Options...)
  1553  				if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1554  					return
  1555  				}
  1556  
  1557  				for iter := got.Iterate(ctx); iter.Next(ctx); {
  1558  					pair := iter.Pair()
  1559  					key, _ := pair.Value.(jwk.Key)
  1560  					v, ok := key.Get("typed-field")
  1561  					if !assert.True(t, ok, `key.Get() should succeed`) {
  1562  						return
  1563  					}
  1564  					field, err := tc.PostProcess(t, v)
  1565  					if !assert.NoError(t, err, `tc.PostProcess should succeed`) {
  1566  						return
  1567  					}
  1568  
  1569  					if !assert.Equal(t, field, expected, `field should match expected value`) {
  1570  						return
  1571  					}
  1572  				}
  1573  			})
  1574  		}
  1575  	})
  1576  }
  1577  
  1578  func TestGH412(t *testing.T) {
  1579  	base := jwk.NewSet()
  1580  
  1581  	const max = 5
  1582  	kids := make(map[string]struct{})
  1583  	for i := 0; i < max; i++ {
  1584  		k, err := jwxtest.GenerateRsaJwk()
  1585  		if !assert.NoError(t, err, `jwxttest.GenerateRsaJwk() should succeed`) {
  1586  			return
  1587  		}
  1588  
  1589  		kid := "key-" + strconv.Itoa(i)
  1590  		k.Set(jwk.KeyIDKey, kid)
  1591  		base.Add(k)
  1592  		kids[kid] = struct{}{}
  1593  	}
  1594  
  1595  	for i := 0; i < max; i++ {
  1596  		idx := i
  1597  		currentKid := "key-" + strconv.Itoa(i)
  1598  		t.Run(fmt.Sprintf("Remove at position %d", i), func(t *testing.T) {
  1599  			set, err := base.Clone()
  1600  			if !assert.NoError(t, err, `base.Clone() should succeed`) {
  1601  				return
  1602  			}
  1603  
  1604  			if !assert.Equal(t, max, set.Len(), `set.Len should be %d`, max) {
  1605  				return
  1606  			}
  1607  
  1608  			k, ok := set.Get(idx)
  1609  			if !assert.True(t, ok, `set.Get should succeed`) {
  1610  				return
  1611  			}
  1612  
  1613  			if !assert.True(t, set.Remove(k), `set.Remove should succeed`) {
  1614  				return
  1615  			}
  1616  			t.Logf("deleted key %s", k.KeyID())
  1617  
  1618  			if !assert.Equal(t, max-1, set.Len(), `set.Len should be %d`, max-1) {
  1619  				return
  1620  			}
  1621  
  1622  			expected := make(map[string]struct{})
  1623  			for k := range kids {
  1624  				if k == currentKid {
  1625  					continue
  1626  				}
  1627  				expected[k] = struct{}{}
  1628  			}
  1629  
  1630  			ctx := context.Background()
  1631  			for iter := set.Iterate(ctx); iter.Next(ctx); {
  1632  				pair := iter.Pair()
  1633  				key := pair.Value.(jwk.Key)
  1634  				if !assert.NotEqual(t, k.KeyID(), key.KeyID(), `key id should not match`) {
  1635  					return
  1636  				}
  1637  				t.Logf("%s found", key.KeyID())
  1638  				delete(expected, key.KeyID())
  1639  			}
  1640  
  1641  			if !assert.Len(t, expected, 0, `expected map should be empty`) {
  1642  				return
  1643  			}
  1644  		})
  1645  	}
  1646  }
  1647  
  1648  func TestGH491(t *testing.T) {
  1649  	msg := `{"keys":[{"alg":"ECMR","crv":"P-521","key_ops":["deriveKey"],"kty":"EC","x":"AEFldixpd6xWI1rPigk_i_fW_9SLXh3q3h_CbmRIJ2vmnneWnfylvg37q9_BeSxhLpTQkq580tP-7QiOoNem4ubg","y":"AD8MroFIWQI4nm1rVKOb0ImO0Y7EzPt1HTQfZxagv2IoMez8H_vV7Ra9fU7lJhoe3v-Th6x3-4540FodeIxxiphn"},{"alg":"ES512","crv":"P-521","key_ops":["verify"],"kty":"EC","x":"AFZApUzXzvjVJCZQX1De3LUudI7fiWZcZS3t4F2yrxn0tItCYIZrfygPiCZfV1hVKa3WuH2YMrISZUPrSgi_RN2d","y":"ASEyw-_9xcwNBnvpT7thmAF5qHv9-UPYf38AC7y5QBVejQH_DO1xpKzlTbrHCz0jrMeEir8TyW5ywZIYnqGzPBpn"}]}`
  1650  	keys, err := jwk.Parse([]byte(msg))
  1651  	if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1652  		return
  1653  	}
  1654  
  1655  	// there should be 2 keys , get the first key
  1656  	k, _ := keys.Get(0)
  1657  	ops := k.KeyOps()
  1658  	if !assert.Equal(t, jwk.KeyOperationList{jwk.KeyOpDeriveKey}, ops, `k.KeyOps should match`) {
  1659  		return
  1660  	}
  1661  }
  1662  
  1663  func TestSetWithPrivateParams(t *testing.T) {
  1664  	k1, err := jwxtest.GenerateRsaJwk()
  1665  	if !assert.NoError(t, err, `jwxtest.GenerateRsaJwk should succeed`) {
  1666  		return
  1667  	}
  1668  	k2, err := jwxtest.GenerateEcdsaJwk()
  1669  	if !assert.NoError(t, err, `jwxtest.GenerateEcdsaJwk should succeed`) {
  1670  		return
  1671  	}
  1672  	k3, err := jwxtest.GenerateSymmetricJwk()
  1673  	if !assert.NoError(t, err, `jwxtest.GenerateSymmetricJwk should succeed`) {
  1674  		return
  1675  	}
  1676  
  1677  	t.Run("JWK instead of JWKS", func(t *testing.T) {
  1678  		var buf bytes.Buffer
  1679  		_ = k1.Set(`renewal_kid`, "foo")
  1680  		_ = json.NewEncoder(&buf).Encode(k1)
  1681  
  1682  		var check = func(t *testing.T, buf []byte) {
  1683  			set, err := jwk.Parse(buf)
  1684  			if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1685  				return
  1686  			}
  1687  
  1688  			if !assert.Equal(t, 1, set.Len(), `set.Len() should be 1`) {
  1689  				return
  1690  			}
  1691  
  1692  			v, ok := set.Field(`renewal_kid`)
  1693  			if !assert.True(t, ok, `set.Field("renewal_kid") should return ok = true`) {
  1694  				return
  1695  			}
  1696  
  1697  			if !assert.Equal(t, `foo`, v, `set.Field("renewal_kid") should return "foo"`) {
  1698  				return
  1699  			}
  1700  
  1701  			key, ok := set.Get(0)
  1702  			if !assert.True(t, ok, `set.Get(0) should return ok = true`) {
  1703  				return
  1704  			}
  1705  
  1706  			v, ok = key.Get(`renewal_kid`)
  1707  			if !assert.True(t, ok, `key.Get("renewal_kid") should return ok = true`) {
  1708  				return
  1709  			}
  1710  
  1711  			if !assert.Equal(t, `foo`, v, `key.Get("renewal_kid") should return "foo"`) {
  1712  				return
  1713  			}
  1714  		}
  1715  
  1716  		t.Run("Check original buffer", func(t *testing.T) {
  1717  			check(t, buf.Bytes())
  1718  		})
  1719  		t.Run("Check serialized", func(t *testing.T) {
  1720  			set, err := jwk.Parse(buf.Bytes())
  1721  			if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1722  				return
  1723  			}
  1724  			js, err := json.MarshalIndent(set, "", "  ")
  1725  			if !assert.NoError(t, err, `json.MarshalIndent should succeed`) {
  1726  				return
  1727  			}
  1728  			check(t, js)
  1729  		})
  1730  	})
  1731  	t.Run("JWKS with multiple keys", func(t *testing.T) {
  1732  		var buf bytes.Buffer
  1733  		buf.WriteString(`{"renewal_kid":"foo","keys":[`)
  1734  		enc := json.NewEncoder(&buf)
  1735  		_ = enc.Encode(k1)
  1736  		buf.WriteByte(',')
  1737  		_ = enc.Encode(k2)
  1738  		buf.WriteByte(',')
  1739  		_ = enc.Encode(k3)
  1740  		buf.WriteString(`]}`)
  1741  
  1742  		var check = func(t *testing.T, buf []byte) {
  1743  			set, err := jwk.Parse(buf)
  1744  			if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1745  				return
  1746  			}
  1747  
  1748  			if !assert.Equal(t, 3, set.Len(), `set.Len() should be 3`) {
  1749  				return
  1750  			}
  1751  
  1752  			v, ok := set.Field(`renewal_kid`)
  1753  			if !assert.True(t, ok, `set.Field("renewal_kid") should return ok = true`) {
  1754  				return
  1755  			}
  1756  
  1757  			if !assert.Equal(t, `foo`, v, `set.Field("renewal_kid") should return "foo"`) {
  1758  				return
  1759  			}
  1760  		}
  1761  
  1762  		t.Run("Check original buffer", func(t *testing.T) {
  1763  			check(t, buf.Bytes())
  1764  		})
  1765  		t.Run("Check serialized", func(t *testing.T) {
  1766  			set, err := jwk.Parse(buf.Bytes())
  1767  			if !assert.NoError(t, err, `jwk.Parse should succeed`) {
  1768  				return
  1769  			}
  1770  			js, err := json.MarshalIndent(set, "", "  ")
  1771  			if !assert.NoError(t, err, `json.MarshalIndent should succeed`) {
  1772  				return
  1773  			}
  1774  			check(t, js)
  1775  		})
  1776  	})
  1777  	t.Run("Set private parameters", func(t *testing.T) {
  1778  		set := jwk.NewSet()
  1779  		if !assert.NoError(t, set.Set(`renewal_kid`, `foo`), `set.Set should succeed`) {
  1780  			return
  1781  		}
  1782  
  1783  		v, ok := set.Field(`renewal_kid`)
  1784  		if !assert.True(t, ok, `set.Get("renewal_kid") should succeed`) {
  1785  			return
  1786  		}
  1787  
  1788  		if !assert.Equal(t, `foo`, v, `set.Get("renewal_kid") should return "foo"`) {
  1789  			return
  1790  		}
  1791  
  1792  		if !assert.Error(t, set.Set(`keys`, []string{"foo"}), `set.Set should fail`) {
  1793  			return
  1794  		}
  1795  
  1796  		k, err := jwk.New([]byte("foobar"))
  1797  		if !assert.NoError(t, err, `jwk.New should succeed`) {
  1798  			return
  1799  		}
  1800  		keys := []jwk.Key{k}
  1801  
  1802  		if !assert.NoError(t, set.Set(`keys`, keys), `set.Set should succeed`) {
  1803  			return
  1804  		}
  1805  
  1806  		if !assert.Equal(t, set.Len(), 1, `set should have 1 key`) {
  1807  			return
  1808  		}
  1809  	})
  1810  }
  1811  
  1812  func TestFetch(t *testing.T) {
  1813  	k1, err := jwxtest.GenerateRsaJwk()
  1814  	if !assert.NoError(t, err, `jwxtest.GenerateRsaJwk should succeed`) {
  1815  		return
  1816  	}
  1817  	k2, err := jwxtest.GenerateEcdsaJwk()
  1818  	if !assert.NoError(t, err, `jwxtest.GenerateEcdsaJwk should succeed`) {
  1819  		return
  1820  	}
  1821  	k3, err := jwxtest.GenerateSymmetricJwk()
  1822  	if !assert.NoError(t, err, `jwxtest.GenerateSymmetricJwk should succeed`) {
  1823  		return
  1824  	}
  1825  	set := jwk.NewSet()
  1826  	set.Add(k1)
  1827  	set.Add(k2)
  1828  	set.Add(k3)
  1829  
  1830  	expected, err := json.MarshalIndent(set, "", "  ")
  1831  	if !assert.NoError(t, err, `json.MarshalIndent should succeed`) {
  1832  		return
  1833  	}
  1834  
  1835  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  1836  		w.WriteHeader(http.StatusOK)
  1837  		w.Write(expected)
  1838  	}))
  1839  	defer srv.Close()
  1840  
  1841  	testcases := []struct {
  1842  		Name      string
  1843  		Whitelist func() jwk.Whitelist
  1844  		Error     bool
  1845  	}{
  1846  		{
  1847  			Name: `InsecureWhitelist`,
  1848  			Whitelist: func() jwk.Whitelist {
  1849  				return jwk.InsecureWhitelist{}
  1850  			},
  1851  		},
  1852  		{
  1853  			Name:  `MapWhitelist`,
  1854  			Error: true,
  1855  			Whitelist: func() jwk.Whitelist {
  1856  				return jwk.NewMapWhitelist().
  1857  					Add(`https://www.googleapis.com/oauth2/v3/certs`).
  1858  					Add(srv.URL)
  1859  			},
  1860  		},
  1861  		{
  1862  			Name:  `RegexpWhitelist`,
  1863  			Error: true,
  1864  			Whitelist: func() jwk.Whitelist {
  1865  				return jwk.NewRegexpWhitelist().
  1866  					Add(regexp.MustCompile(regexp.QuoteMeta(srv.URL)))
  1867  			},
  1868  		},
  1869  		{
  1870  			Name:  `WhitelistFunc`,
  1871  			Error: true,
  1872  			Whitelist: func() jwk.Whitelist {
  1873  				return jwk.WhitelistFunc(func(s string) bool {
  1874  					return s == srv.URL
  1875  				})
  1876  			},
  1877  		},
  1878  	}
  1879  
  1880  	for _, tc := range testcases {
  1881  		tc := tc
  1882  		t.Run(tc.Name, func(t *testing.T) {
  1883  			ctx, cancel := context.WithCancel(context.Background())
  1884  			defer cancel()
  1885  
  1886  			wl := tc.Whitelist()
  1887  
  1888  			_, err = jwk.Fetch(ctx, `https://github.com/lestrrat-go/jwx`, jwk.WithFetchWhitelist(wl))
  1889  			if tc.Error {
  1890  				if !assert.Error(t, err, `jwk.Fetch should fail`) {
  1891  					return
  1892  				}
  1893  				if !assert.True(t, strings.Contains(err.Error(), `rejected by whitelist`), `error should be whitelist error`) {
  1894  					return
  1895  				}
  1896  			}
  1897  
  1898  			fetched, err := jwk.Fetch(ctx, srv.URL, jwk.WithFetchWhitelist(wl))
  1899  			if !assert.NoError(t, err, `jwk.Fetch should succeed`) {
  1900  				return
  1901  			}
  1902  
  1903  			got, err := json.MarshalIndent(fetched, "", "  ")
  1904  			if !assert.NoError(t, err, `json.MarshalIndent should succeed`) {
  1905  				return
  1906  			}
  1907  
  1908  			if !assert.Equal(t, expected, got, `data should match`) {
  1909  				return
  1910  			}
  1911  		})
  1912  	}
  1913  }
  1914  
  1915  func TestGH567(t *testing.T) {
  1916  	const src = `{
  1917    "keys": [
  1918      {
  1919        "kty": "RSA",
  1920        "use": "sig",
  1921        "kid": "20595A4BE9F566771792BC3DBC7DF78FF9C36575",
  1922        "x5t": "20595A4BE9F566771792BC3DBC7DF78FF9C36575",
  1923        "e": "AQAB",
  1924        "n": "tAN2xCfMuGpZukiGJl_-aQi_HGd4voyEwuOyL79wZphgtAmMAeOEO9QgxSX00ZczonlOm_I1Xpv2RVnNzSiHfB0bTqn4bLt15JVCBhE1vXaRf63QXn5oZ38fxm_aNctfnmkf65sF3lSzcZmfp1934L1KxJObq4BEOpIxvj00gIOpZQ4Mqw1khfsLhIVeXh8xtiEJwQZPdwIUQD03Yt5XQ_QU3NhxmyXiG8c6auOstdZybbGw10uJQEN4PrW0ESvp_GMnLssYrq6x9PhyvJhZhMFX3rBsYhOI7ILMaqo-QeDYUo0lQ1ENoQFyvtWrNQ_6A-CbmJvL9HdN6AuMkujtUmZzEfbT-k3FRyaZL0JE4-yQikdPGHVK6Q2Ho_Zggx2OTNmLbEORBHNe8cbb7t_5fmK6Fk4TpW3795PR8dG-v-AUGpQEgipg5j-3ONxefyBVZyWyjXaxrhQk6nCeRKcXJ0dKiZQX6ykYrtkgwE3mlcuw9-WzUqvHVEMZgAqBhBhL",
  1925        "x5c": [
  1926          "MIIGpDCCBYygAwIBAgIEX5xBDDANBgkqhkiG9w0BAQsFADBJMQswCQYDVQQGEwJESzESMBAGA1UECgwJVFJVU1QyNDA4MSYwJAYDVQQDDB1UUlVTVDI0MDggU3lzdGVtdGVzdCBYWFhJViBDQTAeFw0yMTA0MjYxMjI1NDBaFw0yNDA0MjYxMTM5NDBaMIGNMQswCQYDVQQGEwJESzEsMCoGA1UECgwjU0lHTkFUVVJHUlVQUEVOIEEvUyAvLyBDVlI6Mjk5MTU5MzgxUDAgBgNVBAUTGUNWUjoyOTkxNTkzOC1VSUQ6NTk5MTEyMjcwLAYDVQQDDCVTSUdOQVRVUkdSVVBQRU4gQS9TIC0gTkVCIFRyYW5zYWN0IFBQMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtAN2xCfMuGpZukiGJl/\u002BaQi/HGd4voyEwuOyL79wZphgtAmMAeOEO9QgxSX00ZczonlOm/I1Xpv2RVnNzSiHfB0bTqn4bLt15JVCBhE1vXaRf63QXn5oZ38fxm/aNctfnmkf65sF3lSzcZmfp1934L1KxJObq4BEOpIxvj00gIOpZQ4Mqw1khfsLhIVeXh8xtiEJwQZPdwIUQD03Yt5XQ/QU3NhxmyXiG8c6auOstdZybbGw10uJQEN4PrW0ESvp/GMnLssYrq6x9PhyvJhZhMFX3rBsYhOI7ILMaqo\u002BQeDYUo0lQ1ENoQFyvtWrNQ/6A\u002BCbmJvL9HdN6AuMkujtUmZzEfbT\u002Bk3FRyaZL0JE4\u002ByQikdPGHVK6Q2Ho/Zggx2OTNmLbEORBHNe8cbb7t/5fmK6Fk4TpW3795PR8dG\u002Bv\u002BAUGpQEgipg5j\u002B3ONxefyBVZyWyjXaxrhQk6nCeRKcXJ0dKiZQX6ykYrtkgwE3mlcuw9\u002BWzUqvHVEMZgAqBhBhLAgMBAAGjggLNMIICyTAOBgNVHQ8BAf8EBAMCA7gwgZcGCCsGAQUFBwEBBIGKMIGHMDwGCCsGAQUFBzABhjBodHRwOi8vb2NzcC5zeXN0ZW10ZXN0MzQudHJ1c3QyNDA4LmNvbS9yZXNwb25kZXIwRwYIKwYBBQUHMAKGO2h0dHA6Ly92LmFpYS5zeXN0ZW10ZXN0MzQudHJ1c3QyNDA4LmNvbS9zeXN0ZW10ZXN0MzQtY2EuY2VyMIIBIAYDVR0gBIIBFzCCARMwggEPBg0rBgEEAYH0UQIEBgMFMIH9MC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LnRydXN0MjQwOC5jb20vcmVwb3NpdG9yeTCByQYIKwYBBQUHAgIwgbwwDBYFRGFuSUQwAwIBARqBq0RhbklEIHRlc3QgY2VydGlmaWthdGVyIGZyYSBkZW5uZSBDQSB1ZHN0ZWRlcyB1bmRlciBPSUQgMS4zLjYuMS40LjEuMzEzMTMuMi40LjYuMy41LiBEYW5JRCB0ZXN0IGNlcnRpZmljYXRlcyBmcm9tIHRoaXMgQ0EgYXJlIGlzc3VlZCB1bmRlciBPSUQgMS4zLjYuMS40LjEuMzEzMTMuMi40LjYuMy41LjCBrQYDVR0fBIGlMIGiMDygOqA4hjZodHRwOi8vY3JsLnN5c3RlbXRlc3QzNC50cnVzdDI0MDguY29tL3N5c3RlbXRlc3QzNC5jcmwwYqBgoF6kXDBaMQswCQYDVQQGEwJESzESMBAGA1UECgwJVFJVU1QyNDA4MSYwJAYDVQQDDB1UUlVTVDI0MDggU3lzdGVtdGVzdCBYWFhJViBDQTEPMA0GA1UEAwwGQ1JMMTUwMB8GA1UdIwQYMBaAFM1saJc5chmkNatk6vQRo4GH\u002BGk7MB0GA1UdDgQWBBSJJABtTjZRzzFHsb1JwED0qCo49TAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQA2yBdGVPbKoYUYRZj4bHLj5Xwqk/yh6sodxwAPYrwxkJBzUKFAwUCTCigpwq8NE00kp3xhFT7Hz/9Z7aZLV4N/D94tc0qDU0JIwlbkrn/i3wx8N8UXf242WVaunJLdKqGtV4ijqjZFGa68XBc3elGjnAMY8eoF56dGg35Ps8Cw2BZyG2aXyEQNs6JYUNzp57\u002B6lJWl0T9Zniaut7Aw2rCII8XRe9WY\u002BHIQX6GuBSw0Q4v9wAfyYftnoULsgfVklkxtQI4kAO5rG17Z5NJuvRkXJD8jp\u002B2jRzcaD8Ud\u002Bpe4keTvuJZ\u002BRj\u002BBDLn/3\u002ByPbs3arD3CIO\u002BlW3Nndr34Le/s"
  1927        ],
  1928        "alg": "RS256"
  1929      },
  1930      {
  1931        "kty": "RSA",
  1932        "use": "sig",
  1933        "kid": "048058BB59F4D3007045896FD488CE81F4EB4923",
  1934        "x5t": "048058BB59F4D3007045896FD488CE81F4EB4923",
  1935        "e": "AQAB",
  1936        "n": "4bOwMSWoWqOSJoLvwFOCVrKmIO_XX5BCI8KYDIgWjII3a83vwia0a11UHm3B6oPlR3L5udworbH7axrmnPz4GEamQp57Yf0uhnGctlVpVVZHOvXPaMlZgTTGhWpJAGnLnyihZbARgyJefuxZ6ZIqeNyjgc_fC-0J7RWFMxNKS_n6ZKFqQlIlmJInJPWR-YZTuooIb4T4C0JAwFDEvXiAs_fX34Tj1FvD1nv01VPGF5Wx6cBV6fejbRCjY4uFfovhE-dtKX0IakZI8jks-uqMjIOB2x1pOuaqrmrINrTYzKTCKrnMpfaW4urhFmQRKNIgaoLnPgzIb3W9F-vpgrdTjw",
  1937        "x5c": [
  1938          "MIID/DCCAeSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBBMQswCQYDVQQGEwJESzEyMDAGA1UEAxMpTmV0cyBlSUQgQnJva2VyIFRva2VuIFNpZ25pbmcgUm9vdCBQUCBFbnYwHhcNMjEwMjI0MDAwMDAwWhcNNDEwMjI0MDAwMDAwWjA\u002BMQswCQYDVQQGEwJESzEvMC0GA1UEAxMmTmV0cyBlSUQgQnJva2VyIFRva2VuIFNpZ25pbmcgMSBQUCBFbnYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhs7AxJahao5Imgu/AU4JWsqYg79dfkEIjwpgMiBaMgjdrze/CJrRrXVQebcHqg\u002BVHcvm53CitsftrGuac/PgYRqZCnnth/S6GcZy2VWlVVkc69c9oyVmBNMaFakkAacufKKFlsBGDIl5\u002B7Fnpkip43KOBz98L7QntFYUzE0pL\u002BfpkoWpCUiWYkick9ZH5hlO6ighvhPgLQkDAUMS9eICz99ffhOPUW8PWe/TVU8YXlbHpwFXp96NtEKNji4V\u002Bi\u002BET520pfQhqRkjyOSz66oyMg4HbHWk65qquasg2tNjMpMIqucyl9pbi6uEWZBEo0iBqguc\u002BDMhvdb0X6\u002BmCt1OPAgMBAAGjAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQAFKs2PbOIHLgLTNPIhqKCv7Uj\u002Buj0tpF6vO7CFtw1Q0NKo0UB4wD0T9AYu\u002B8sq3M\u002BZjR77eHP6IkvVBEaqBrZgjq6wU1pijPuIUliXF772\u002B/Hr8Wa23iILWevk\u002BleOXDI8kN7E1JPfr0ADsnCJxaXApDqE6Mysd68\u002BGN2adRuvGAcEcKauVfYLAGPQVctkmQSH6VhIJoDKni7gFF/oMZUZ362sOguhlYltcNUMIILJZkFkksRRriHOlz4I8HJiTzWI1Ufuw6iqFWMquOR4BsQZzBSsdPVGlQvjyqOiBia7rPTJE1Z3Kj0mujIbgKTri8YsnFsBynyHq8puYWvMwoGLWu0goxq9rFrINTe39/YpRE6lZUUZU50DddS\u002B0syBTs1H1gX00ofqt6FgWmACc20zJZm2GyhWDtqtiMurn5WKLoZBQrwN5/a6c6HNCStSVxn8o0g9xCgmWM855S8TqHFYXKJSMG00xZZEbsOAPqujkbKakhC/kJQU7XKGjFRskQZhHvpGipFTK4ZapHYYoo5KqZTytAvFENIcuibIk0u8zlCZuXU/PsowMN4G54FftVVyNHuj4TqiKIvB\u002BZNj/zcPopQHHUISVRApR6YO6fqwPxVaJmSTzZ/0uPTaAdnMz5j1wIYf\u002BZDk1ywTxOBRS7/FwNnWAyIuYGFzewY4H2QUNg=="
  1939        ],
  1940        "alg": "RS256"
  1941      },
  1942      {
  1943        "kty": "RSA",
  1944        "use": "enc",
  1945        "kid": "A2E10A6BAF4E43E86273F57F218A44B824203176",
  1946        "x5t": "A2E10A6BAF4E43E86273F57F218A44B824203176",
  1947        "x5c": [
  1948          "MIIDGjCCAgKgAwIBAgIIQFkx7rDLvyowDQYJKoZIhvcNAQELBQAwNDEyMDAGA1UEAxMpTmV0cyBlSUQgQnJva2VyIGNsaWVudCByZXF1ZXN0IGVuY3J5cHRpb24wIBcNMjIwMjA5MTQxMDQ1WhgPMjExMjAyMTAxNDEwNDVaMDQxMjAwBgNVBAMTKU5ldHMgZUlEIEJyb2tlciBjbGllbnQgcmVxdWVzdCBlbmNyeXB0aW9uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps2R1sxEGxyYfP\u002BK2jq4uDONxrEP4W4oAKJkTv71oOJiK3CBK4ybyk597WufUZfpy8isUKtuqx1x6DTK6vnecUv5KV77/ql6Ac8LJaj5zQBRGuPoPezbD2tPglxp4XEU\u002BqivoyMJiZoLl75MklxvmVVlJQgu1H4RmvdCcp0xYmV2CBX4GKvK6g26y3IZ1FW4Vj5G8eB\u002Bxw423EtsBO3iKPx24BbVZWXC56lhke\u002BQbpbagU/hpQnOdW5tdWdm7oHGUfGwsvg1f6b2Yllwv57ANJkk\u002BfBr\u002BoN0eD2DRNyHbExzJfOBPkDt2FEq1u30kfLP\u002B6ecSByaxSFTl\u002BgFeUUw0wIDAQABoy4wLDALBgNVHQ8EBAMCBBAwHQYDVR0OBBYEFPK08YkmSYK1xNIFEr1AdscfYKnZMA0GCSqGSIb3DQEBCwUAA4IBAQAYeP7IAv3ND\u002B6UMGr9X\u002BP1wURz7UQd66oRldhcdkdS\u002BBNMcU/gVeiU31Es5Y/GhdmKPiuQGdIQdPO88u9A7STWIYUj/lnrgtKif\u002BJ8V/PtfsvHbBYD5f7wFd7fqOpcDFQ2dobOathhrqJ1r3ShFaObpVBX3PL3\u002BSFK3ofHaMYWuIoD\u002BroiOJfIYlL02rrKiiw9r2L9nUCZfSAq3G9rMw\u002BzL38D9BQvrEe9yvwqM3im0m3seiNODiArcY/ee\u002B538\u002BYaToaMPHxUAizREeJFm4aOtwzGND48XHQzbNyfhoSsJesCJsugcNfHUe6o0nuPZ\u002BzvdLrboutrrtxEN8yOm489"
  1949        ],
  1950        "alg": "http://www.w3.org/2001/04/xmlenc#rsa-oaep"
  1951      }
  1952    ]
  1953  }`
  1954  
  1955  	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  1956  		w.Header().Set(`Content-Type`, `application/json`)
  1957  		w.WriteHeader(http.StatusOK)
  1958  
  1959  		io.WriteString(w, src)
  1960  	}))
  1961  	defer srv.Close()
  1962  
  1963  	for _, ignoreParseError := range []bool{true, false} {
  1964  		ignoreParseError := ignoreParseError
  1965  		t.Run(fmt.Sprintf(`Parse with ignoreParseError=%t`, ignoreParseError), func(t *testing.T) {
  1966  			ctx, cancel := context.WithCancel(context.Background())
  1967  			defer cancel()
  1968  
  1969  			ar := jwk.NewAutoRefresh(ctx)
  1970  			ar.Configure(srv.URL, jwk.WithIgnoreParseError(ignoreParseError))
  1971  
  1972  			set, err := ar.Fetch(ctx, srv.URL)
  1973  			if ignoreParseError {
  1974  				if !assert.NoError(t, err, `ar.Fetch should succeed`) {
  1975  					return
  1976  				}
  1977  				if !assert.Equal(t, set.Len(), 2, `JWKS should contain two keys`) {
  1978  					return
  1979  				}
  1980  			} else {
  1981  				if !assert.Error(t, err, `ar.Fetch should fail`) {
  1982  					return
  1983  				}
  1984  			}
  1985  		})
  1986  	}
  1987  
  1988  	// Test the case when WithIgnoreParseError is passed to ParseKey
  1989  	t.Run(`ParseKey + WithIgnoreParseError should be an error`, func(t *testing.T) {
  1990  		key, err := jwxtest.GenerateRsaJwk()
  1991  		if !assert.NoError(t, err, `jwxtest.GenerateRsaJwk() should succeed`) {
  1992  			return
  1993  		}
  1994  
  1995  		buf, err := json.Marshal(key)
  1996  		if !assert.NoError(t, err, `json.Marshal should succeed`) {
  1997  			return
  1998  		}
  1999  
  2000  		_, err = jwk.ParseKey(buf)
  2001  		if !assert.NoError(t, err, `jwk.ParseKey (no WithIgnoreParseError) should succeed`) {
  2002  			return
  2003  		}
  2004  
  2005  		_, err = jwk.ParseKey(buf, jwk.WithIgnoreParseError(true))
  2006  		if !assert.Error(t, err, `jwk.ParseKey (no WithIgnoreParseError) should fail`) {
  2007  			return
  2008  		}
  2009  	})
  2010  }
  2011  
  2012  func TestGH664(t *testing.T) {
  2013  	privkey, err := jwxtest.GenerateRsaKey()
  2014  	if !assert.NoError(t, err, `jwxtext.GenerateRsaKey() should succeed`) {
  2015  		return
  2016  	}
  2017  
  2018  	privkey.Primes = append(privkey.Primes, &big.Int{})
  2019  	// first, test a stupid case where Primes > 2
  2020  	_, err = jwk.New(privkey)
  2021  	if !assert.Error(t, err, `jwk.New should fail`) {
  2022  		return
  2023  	}
  2024  
  2025  	privkey.Primes = privkey.Primes[:2]
  2026  
  2027  	// nuke p and q, dp, dq, qi
  2028  	for i := 0; i < 3; i++ {
  2029  		i := i
  2030  		t.Run(fmt.Sprintf("Check what happens when primes are reduced to %d", i), func(t *testing.T) {
  2031  			privkey.Primes = privkey.Primes[:i]
  2032  			privkey.Precomputed.Dp = nil
  2033  			privkey.Precomputed.Dq = nil
  2034  			privkey.Precomputed.Qinv = nil
  2035  			privkey.Precomputed.CRTValues = nil
  2036  
  2037  			jwkPrivkey, err := jwk.New(privkey)
  2038  			if !assert.NoError(t, err, `jwk.FromRaw should succeed`) {
  2039  				return
  2040  			}
  2041  
  2042  			buf, _ := json.MarshalIndent(jwkPrivkey, "", "  ")
  2043  			parsed, err := jwk.ParseKey(buf)
  2044  			if !assert.NoError(t, err, `jwk.ParseKey should succeed`) {
  2045  				return
  2046  			}
  2047  
  2048  			payload := []byte(`hello , world!`)
  2049  			signed, err := jws.Sign(payload, jwa.RS256, parsed)
  2050  			if !assert.NoError(t, err, `jws.Sign should succeed`) {
  2051  				return
  2052  			}
  2053  
  2054  			verified, err := jws.Verify(signed, jwa.RS256, privkey.PublicKey)
  2055  			if !assert.NoError(t, err, `jws.Verify should succeed`) {
  2056  				return
  2057  			}
  2058  
  2059  			if !assert.Equal(t, payload, verified, `verified content should match`) {
  2060  				return
  2061  			}
  2062  		})
  2063  	}
  2064  }
  2065  

View as plain text