github.com/lestrrat-go/jwx/v2@v2.0.21/jwk/jwk_internal_test.go (about)

     1  package jwk
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/lestrrat-go/jwx/v2/cert"
     9  	"github.com/lestrrat-go/jwx/v2/internal/base64"
    10  	"github.com/lestrrat-go/jwx/v2/internal/json"
    11  	"github.com/lestrrat-go/jwx/v2/jwa"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestX509CertChain(t *testing.T) {
    16  	certSrc := []string{
    17  		"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=",
    18  		"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==",
    19  		"MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd",
    20  	}
    21  	var c cert.Chain
    22  	for _, src := range certSrc {
    23  		_ = c.AddString(src)
    24  	}
    25  	for _, key := range []Key{
    26  		newRSAPrivateKey(),
    27  		newRSAPublicKey(),
    28  		newECDSAPrivateKey(),
    29  		newECDSAPublicKey(),
    30  		newSymmetricKey(),
    31  	} {
    32  		key := key
    33  		t.Run("Set X509CertChainKey", func(t *testing.T) {
    34  			if !assert.NoError(t, key.Set(X509CertChainKey, &c), "Set for x5c should succeed") {
    35  				return
    36  			}
    37  
    38  			v, ok := key.Get(X509CertChainKey)
    39  			if !assert.True(t, ok, "Get for x5c should succeed") {
    40  				return
    41  			}
    42  			gotcerts := v.(*cert.Chain)
    43  			if !assert.Equal(t, gotcerts.Len(), 3, `should have 3 cert`) {
    44  				return
    45  			}
    46  		})
    47  	}
    48  }
    49  
    50  func TestIterator(t *testing.T) {
    51  	commonValues := map[string]interface{}{
    52  		AlgorithmKey: jwa.KeyAlgorithmFrom("dummy"),
    53  		KeyIDKey:     "dummy-kid",
    54  		KeyUsageKey:  "dummy-usage",
    55  		KeyOpsKey:    KeyOperationList{KeyOpSign, KeyOpVerify, KeyOpEncrypt, KeyOpDecrypt, KeyOpWrapKey, KeyOpUnwrapKey, KeyOpDeriveKey, KeyOpDeriveBits},
    56  		"private":    "dummy-private",
    57  	}
    58  
    59  	verifyIterators := func(t *testing.T, v Key, expected map[string]interface{}) {
    60  		t.Helper()
    61  		t.Run("Iterate", func(t *testing.T) {
    62  			seen := make(map[string]interface{})
    63  			for iter := v.Iterate(context.TODO()); iter.Next(context.TODO()); {
    64  				pair := iter.Pair()
    65  				seen[pair.Key.(string)] = pair.Value
    66  
    67  				getV, ok := v.Get(pair.Key.(string))
    68  				if !assert.True(t, ok, `v.Get should succeed for key %#v`, pair.Key) {
    69  					return
    70  				}
    71  				if !assert.Equal(t, pair.Value, getV, `pair.Value should match value from v.Get()`) {
    72  					return
    73  				}
    74  			}
    75  			if !assert.Equal(t, expected, seen, `values should match`) {
    76  				return
    77  			}
    78  		})
    79  		t.Run("Walk", func(t *testing.T) {
    80  			seen := make(map[string]interface{})
    81  			v.Walk(context.TODO(), HeaderVisitorFunc(func(key string, value interface{}) error {
    82  				seen[key] = value
    83  				return nil
    84  			}))
    85  			if !assert.Equal(t, expected, seen, `values should match`) {
    86  				return
    87  			}
    88  		})
    89  		t.Run("AsMap", func(t *testing.T) {
    90  			seen, err := v.AsMap(context.TODO())
    91  			if !assert.NoError(t, err, `v.AsMap should succeed`) {
    92  				return
    93  			}
    94  			if !assert.Equal(t, expected, seen, `values should match`) {
    95  				return
    96  			}
    97  		})
    98  	}
    99  
   100  	type iterTestCase struct {
   101  		Extras map[string]interface{}
   102  		Func   func() Key
   103  	}
   104  
   105  	testcases := []iterTestCase{
   106  		{
   107  			Extras: map[string]interface{}{
   108  				RSANKey:  []byte("0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"),
   109  				RSAEKey:  []byte("AQAB"),
   110  				RSADKey:  []byte("X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqijwp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d_cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBznbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFzme1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q"),
   111  				RSAPKey:  []byte("83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPVnwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqVWlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs"),
   112  				RSAQKey:  []byte("3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyumqjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgxkIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk"),
   113  				RSADPKey: []byte("G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oimYwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_NmtuYZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0"),
   114  				RSADQKey: []byte("s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUUvMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk"),
   115  				RSAQIKey: []byte("GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzgUIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rxyR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU"),
   116  			},
   117  			Func: func() Key {
   118  				return newRSAPrivateKey()
   119  			},
   120  		},
   121  		{
   122  			Extras: map[string]interface{}{
   123  				RSANKey: []byte("0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"),
   124  				RSAEKey: []byte("AQAB"),
   125  			},
   126  			Func: func() Key {
   127  				return newRSAPublicKey()
   128  			},
   129  		},
   130  		{
   131  			Extras: map[string]interface{}{
   132  				ECDSACrvKey: jwa.P256,
   133  				ECDSAXKey: (func() []byte {
   134  					s, _ := base64.DecodeString("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4")
   135  					return s
   136  				})(),
   137  				ECDSAYKey: (func() []byte {
   138  					s, _ := base64.DecodeString("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM")
   139  					return s
   140  				})(),
   141  				ECDSADKey: (func() []byte {
   142  					s, _ := base64.DecodeString("870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE")
   143  					return s
   144  				})(),
   145  			},
   146  			Func: func() Key {
   147  				return newECDSAPrivateKey()
   148  			},
   149  		},
   150  		{
   151  			Extras: map[string]interface{}{
   152  				ECDSACrvKey: jwa.P256,
   153  				ECDSAXKey: (func() []byte {
   154  					s, _ := base64.DecodeString("MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4")
   155  					return s
   156  				})(),
   157  				ECDSAYKey: (func() []byte {
   158  					s, _ := base64.DecodeString("4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM")
   159  					return s
   160  				})(),
   161  			},
   162  			Func: func() Key {
   163  				return newECDSAPublicKey()
   164  			},
   165  		},
   166  		{
   167  			Extras: map[string]interface{}{
   168  				SymmetricOctetsKey: []byte("abcd"),
   169  			},
   170  			Func: func() Key {
   171  				return newSymmetricKey()
   172  			},
   173  		},
   174  	}
   175  	for _, test := range testcases {
   176  		key := test.Func()
   177  		key2 := test.Func()
   178  		expected := make(map[string]interface{})
   179  		expected[KeyTypeKey] = key.KeyType()
   180  		for k, v := range commonValues {
   181  			if !assert.NoError(t, key.Set(k, v), `key.Set %#v should succeed`, k) {
   182  				return
   183  			}
   184  			expected[k] = v
   185  		}
   186  		for k, v := range test.Extras {
   187  			if !assert.NoError(t, key.Set(k, v), `key.Set %#v should succeed`, k) {
   188  				return
   189  			}
   190  			expected[k] = v
   191  		}
   192  
   193  		t.Run(fmt.Sprintf("%T", key), func(t *testing.T) {
   194  			verifyIterators(t, key, expected)
   195  		})
   196  		t.Run(fmt.Sprintf("%T (after json roundtripping)", key), func(t *testing.T) {
   197  			buf, err := json.Marshal(key)
   198  			if !assert.NoError(t, err, `json.Marshal should succeed`) {
   199  				return
   200  			}
   201  
   202  			if !assert.NoError(t, json.Unmarshal(buf, key2), `json.Unmarshal should succeed`) {
   203  				t.Logf("%s", buf)
   204  				return
   205  			}
   206  
   207  			verifyIterators(t, key2, expected)
   208  		})
   209  	}
   210  }