...

Source file src/github.com/ory/fosite/token/jwt/token_test.go

Documentation: github.com/ory/fosite/token/jwt

     1  package jwt
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  	"gopkg.in/square/go-jose.v2"
    11  	"gopkg.in/square/go-jose.v2/jwt"
    12  
    13  	"crypto/rand"
    14  	"crypto/rsa"
    15  	"crypto/x509"
    16  	"encoding/pem"
    17  	"fmt"
    18  )
    19  
    20  func TestUnsignedToken(t *testing.T) {
    21  	key := UnsafeAllowNoneSignatureType
    22  	token := NewWithClaims(SigningMethodNone, MapClaims{
    23  		"aud": "foo",
    24  		"exp": time.Now().UTC().Add(time.Hour).Unix(),
    25  		"iat": time.Now().UTC().Unix(),
    26  		"sub": "nestor",
    27  	})
    28  	rawToken, err := token.SignedString(key)
    29  	require.NoError(t, err)
    30  	require.NotEmpty(t, rawToken)
    31  	parts := strings.Split(rawToken, ".")
    32  	require.Len(t, parts, 3)
    33  	require.Empty(t, parts[2])
    34  	tk, err := jwt.ParseSigned(rawToken)
    35  	require.NoError(t, err)
    36  	require.Len(t, tk.Headers, 1)
    37  	require.Equal(t, "JWT", tk.Headers[0].ExtraHeaders[jose.HeaderKey("typ")])
    38  }
    39  
    40  func TestJWTHeaders(t *testing.T) {
    41  	rawToken := makeSampleToken(nil, jose.RS256, MustRSAKey())
    42  	tk, err := jwt.ParseSigned(rawToken)
    43  	require.NoError(t, err)
    44  	require.Len(t, tk.Headers, 1)
    45  	require.Equal(t, tk.Headers[0].Algorithm, "RS256")
    46  	require.Equal(t, "JWT", tk.Headers[0].ExtraHeaders[jose.HeaderKey("typ")])
    47  }
    48  
    49  var keyFuncError error = fmt.Errorf("error loading key")
    50  var (
    51  	jwtTestDefaultKey *rsa.PublicKey = parseRSAPublicKeyFromPEM(defaultPubKeyPEM)
    52  	defaultKeyFunc    Keyfunc        = func(t *Token) (interface{}, error) { return jwtTestDefaultKey, nil }
    53  	emptyKeyFunc      Keyfunc        = func(t *Token) (interface{}, error) { return nil, nil }
    54  	errorKeyFunc      Keyfunc        = func(t *Token) (interface{}, error) { return nil, keyFuncError }
    55  	nilKeyFunc        Keyfunc        = nil
    56  )
    57  
    58  // Many test cases where taken from https://github.com/dgrijalva/jwt-go/blob/master/parser_test.go
    59  // Test cases related to json.Number where excluded because that is not supported by go-jose,
    60  // it is not used in fosite and therefore not supported.
    61  func TestParser_Parse(t *testing.T) {
    62  	var (
    63  		defaultES256PrivateKey = MustECDSAKey()
    64  		defaultSigningKey      = parseRSAPrivateKeyFromPEM(defaultPrivateKeyPEM)
    65  		publicECDSAKey         = func(*Token) (interface{}, error) { return &defaultES256PrivateKey.PublicKey, nil }
    66  		noneKey                = func(*Token) (interface{}, error) { return UnsafeAllowNoneSignatureType, nil }
    67  		randomKey              = func(*Token) (interface{}, error) {
    68  			k, err := rsa.GenerateKey(rand.Reader, 2048)
    69  			require.NoError(t, err)
    70  			return &k.PublicKey, nil
    71  		}
    72  	)
    73  	type expected struct {
    74  		errors  uint32
    75  		keyFunc Keyfunc
    76  		valid   bool
    77  		claims  MapClaims
    78  	}
    79  	type generate struct {
    80  		claims     MapClaims
    81  		signingKey interface{}             // defaultSigningKey
    82  		method     jose.SignatureAlgorithm // default RS256
    83  	}
    84  	type given struct {
    85  		name        string
    86  		tokenString string
    87  		generate    *generate
    88  	}
    89  	var jwtTestData = []struct {
    90  		expected
    91  		given
    92  	}{
    93  		{
    94  			given: given{
    95  				name:        "basic",
    96  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
    97  			},
    98  			expected: expected{
    99  				keyFunc: defaultKeyFunc,
   100  				claims:  MapClaims{"foo": "bar"},
   101  				valid:   true,
   102  				errors:  0,
   103  			},
   104  		},
   105  		{
   106  			given: given{
   107  				name: "basic expired",
   108  				generate: &generate{
   109  					claims: MapClaims{"foo": "bar", "exp": time.Now().Unix() - 100},
   110  				},
   111  			},
   112  			expected: expected{
   113  				keyFunc: defaultKeyFunc,
   114  				claims:  MapClaims{"foo": "bar", "exp": time.Now().Unix() - 100},
   115  				valid:   false,
   116  				errors:  ValidationErrorExpired,
   117  			},
   118  		},
   119  		{
   120  			given: given{
   121  				name: "basic nbf",
   122  				generate: &generate{
   123  					claims: MapClaims{"foo": "bar", "nbf": time.Now().Unix() + 100},
   124  				},
   125  			},
   126  			expected: expected{
   127  				keyFunc: defaultKeyFunc,
   128  				claims:  MapClaims{"foo": "bar", "nbf": time.Now().Unix() + 100},
   129  				valid:   false,
   130  				errors:  ValidationErrorNotValidYet,
   131  			},
   132  		},
   133  		{
   134  			given: given{
   135  				name: "expired and nbf",
   136  				generate: &generate{
   137  					claims: MapClaims{"foo": "bar", "nbf": time.Now().Unix() + 100, "exp": time.Now().Unix() - 100},
   138  				},
   139  			},
   140  			expected: expected{
   141  				keyFunc: defaultKeyFunc,
   142  				claims:  MapClaims{"foo": "bar", "nbf": time.Now().Unix() + 100, "exp": time.Now().Unix() - 100},
   143  				valid:   false,
   144  				errors:  ValidationErrorNotValidYet | ValidationErrorExpired,
   145  			},
   146  		},
   147  		{
   148  			given: given{
   149  				name:        "basic invalid",
   150  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   151  			},
   152  			expected: expected{
   153  				keyFunc: defaultKeyFunc,
   154  				claims:  MapClaims{"foo": "bar"},
   155  				valid:   false,
   156  				errors:  ValidationErrorSignatureInvalid,
   157  			},
   158  		},
   159  		{
   160  			given: given{
   161  				name:        "basic nokeyfunc",
   162  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   163  			},
   164  			expected: expected{
   165  				keyFunc: nilKeyFunc,
   166  				claims:  MapClaims{"foo": "bar"},
   167  				valid:   false,
   168  				errors:  ValidationErrorUnverifiable,
   169  			},
   170  		},
   171  		{
   172  			given: given{
   173  				name:        "basic nokey",
   174  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   175  			},
   176  			expected: expected{
   177  				keyFunc: emptyKeyFunc,
   178  				claims:  MapClaims{"foo": "bar"},
   179  				valid:   false,
   180  				errors:  ValidationErrorSignatureInvalid,
   181  			},
   182  		},
   183  		{
   184  			given: given{
   185  				name:        "basic errorkey",
   186  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   187  				generate: &generate{
   188  					claims: MapClaims{"foo": "bar"},
   189  				},
   190  			},
   191  			expected: expected{
   192  				keyFunc: errorKeyFunc,
   193  				claims:  MapClaims{"foo": "bar"},
   194  				valid:   false,
   195  				errors:  ValidationErrorUnverifiable,
   196  			},
   197  		},
   198  		{
   199  			given: given{
   200  				name: "valid signing method",
   201  				generate: &generate{
   202  					claims: MapClaims{"foo": "bar"},
   203  				},
   204  			},
   205  			expected: expected{
   206  				keyFunc: defaultKeyFunc,
   207  				claims:  MapClaims{"foo": "bar"},
   208  				valid:   true,
   209  				errors:  0,
   210  			},
   211  		},
   212  		{
   213  			given: given{
   214  				name:        "invalid",
   215  				tokenString: "foo_invalid_token",
   216  			},
   217  			expected: expected{
   218  				keyFunc: defaultKeyFunc,
   219  				claims:  MapClaims(nil),
   220  				valid:   false,
   221  				errors:  ValidationErrorMalformed,
   222  			},
   223  		},
   224  		{
   225  			given: given{
   226  				name:        "valid format invalid content",
   227  				tokenString: "foo.bar.baz",
   228  			},
   229  			expected: expected{
   230  				keyFunc: defaultKeyFunc,
   231  				claims:  MapClaims(nil),
   232  				valid:   false,
   233  				errors:  ValidationErrorMalformed,
   234  			},
   235  		},
   236  		{
   237  			given: given{
   238  				name:        "wrong key, expected ECDSA got RSA",
   239  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   240  			},
   241  			expected: expected{
   242  				keyFunc: publicECDSAKey,
   243  				claims:  MapClaims{"foo": "bar"},
   244  				valid:   false,
   245  				errors:  ValidationErrorSignatureInvalid,
   246  			},
   247  		},
   248  		{
   249  			given: given{
   250  				name:        "should fail, got RSA but found no key",
   251  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   252  			},
   253  			expected: expected{
   254  				keyFunc: emptyKeyFunc,
   255  				claims:  MapClaims{"foo": "bar"},
   256  				valid:   false,
   257  				errors:  ValidationErrorSignatureInvalid,
   258  			},
   259  		},
   260  		{
   261  			given: given{
   262  				name:        "key does not match",
   263  				tokenString: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg",
   264  			},
   265  			expected: expected{
   266  				keyFunc: randomKey,
   267  				claims:  MapClaims{"foo": "bar"},
   268  				valid:   false,
   269  				errors:  ValidationErrorSignatureInvalid,
   270  			},
   271  		},
   272  		{
   273  			given: given{
   274  				name: "used before issued",
   275  				generate: &generate{
   276  					claims: MapClaims{"foo": "bar", "iat": time.Now().Unix() + 500},
   277  				},
   278  			},
   279  			expected: expected{
   280  				keyFunc: defaultKeyFunc,
   281  				claims:  MapClaims{"foo": "bar", "iat": time.Now().Unix() + 500},
   282  				valid:   false,
   283  				errors:  ValidationErrorIssuedAt,
   284  			},
   285  		},
   286  		{
   287  			given: given{
   288  				name: "valid ECDSA signing method",
   289  				generate: &generate{
   290  					claims:     MapClaims{"foo": "bar"},
   291  					signingKey: defaultES256PrivateKey,
   292  					method:     jose.ES256,
   293  				},
   294  			},
   295  			expected: expected{
   296  				keyFunc: publicECDSAKey,
   297  				claims:  MapClaims{"foo": "bar"},
   298  				valid:   true,
   299  				errors:  0,
   300  			},
   301  		},
   302  		{
   303  			given: given{
   304  				name: "should pass, valid NONE signing method",
   305  				generate: &generate{
   306  					claims:     MapClaims{"foo": "bar"},
   307  					signingKey: UnsafeAllowNoneSignatureType,
   308  					method:     SigningMethodNone,
   309  				},
   310  			},
   311  			expected: expected{
   312  				keyFunc: noneKey,
   313  				claims:  MapClaims{"foo": "bar"},
   314  				valid:   true,
   315  				errors:  0,
   316  			},
   317  		},
   318  		{
   319  			given: given{
   320  				name: "should fail, expected RS256 but got NONE",
   321  				generate: &generate{
   322  					claims:     MapClaims{"foo": "bar"},
   323  					signingKey: UnsafeAllowNoneSignatureType,
   324  					method:     SigningMethodNone,
   325  				},
   326  			},
   327  			expected: expected{
   328  				keyFunc: defaultKeyFunc,
   329  				claims:  MapClaims{"foo": "bar"},
   330  				valid:   false,
   331  				errors:  ValidationErrorSignatureInvalid,
   332  			},
   333  		},
   334  		{
   335  			given: given{
   336  				name: "should fail, expected ECDSA but got NONE",
   337  				generate: &generate{
   338  					claims:     MapClaims{"foo": "bar"},
   339  					signingKey: UnsafeAllowNoneSignatureType,
   340  					method:     SigningMethodNone,
   341  				},
   342  			},
   343  			expected: expected{
   344  				keyFunc: publicECDSAKey,
   345  				claims:  MapClaims{"foo": "bar"},
   346  				valid:   false,
   347  				errors:  ValidationErrorSignatureInvalid,
   348  			},
   349  		},
   350  	}
   351  
   352  	// Iterate over test data set and run tests
   353  	for _, data := range jwtTestData {
   354  		t.Run(data.name, func(t *testing.T) {
   355  			if data.generate != nil {
   356  				signingKey := data.generate.signingKey
   357  				method := data.generate.method
   358  				if signingKey == nil {
   359  					// use test defaults
   360  					signingKey = defaultSigningKey
   361  					method = jose.RS256
   362  				}
   363  				data.tokenString = makeSampleToken(data.generate.claims, method, signingKey)
   364  			}
   365  
   366  			// Parse the token
   367  			var token *Token
   368  			var err error
   369  
   370  			// Figure out correct claims type
   371  			token, err = ParseWithClaims(data.tokenString, MapClaims{}, data.keyFunc)
   372  			// Verify result matches expectation
   373  			assert.EqualValues(t, data.claims, token.Claims)
   374  			if data.valid && err != nil {
   375  				t.Errorf("[%v] Error while verifying token: %T:%v", data.name, err, err)
   376  			}
   377  
   378  			if !data.valid && err == nil {
   379  				t.Errorf("[%v] Invalid token passed validation", data.name)
   380  			}
   381  
   382  			if (err == nil && !token.Valid()) || (err != nil && token.Valid()) {
   383  				t.Errorf("[%v] Inconsistent behavior between returned error and token.Valid", data.name)
   384  			}
   385  
   386  			if data.errors != 0 {
   387  				if err == nil {
   388  					t.Errorf("[%v] Expecting error.  Didn't get one.", data.name)
   389  				} else {
   390  
   391  					ve := err.(*ValidationError)
   392  					// compare the bitfield part of the error
   393  					if e := ve.Errors; e != data.errors {
   394  						t.Errorf("[%v] Errors don't match expectation.  %v != %v", data.name, e, data.errors)
   395  					}
   396  
   397  					if err.Error() == keyFuncError.Error() && ve.Inner != keyFuncError {
   398  						t.Errorf("[%v] Inner error does not match expectation.  %v != %v", data.name, ve.Inner, keyFuncError)
   399  					}
   400  				}
   401  			}
   402  		})
   403  	}
   404  }
   405  
   406  func makeSampleToken(c MapClaims, m jose.SignatureAlgorithm, key interface{}) string {
   407  	token := NewWithClaims(m, c)
   408  	s, e := token.SignedString(key)
   409  
   410  	if e != nil {
   411  		panic(e.Error())
   412  	}
   413  
   414  	return s
   415  }
   416  
   417  func parseRSAPublicKeyFromPEM(key []byte) *rsa.PublicKey {
   418  	var err error
   419  
   420  	// Parse PEM block
   421  	var block *pem.Block
   422  	if block, _ = pem.Decode(key); block == nil {
   423  		panic("not possible to decode")
   424  	}
   425  
   426  	// Parse the key
   427  	var parsedKey interface{}
   428  	if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
   429  		if cert, err := x509.ParseCertificate(block.Bytes); err == nil {
   430  			parsedKey = cert.PublicKey
   431  		} else {
   432  			panic(err)
   433  		}
   434  	}
   435  
   436  	var pkey *rsa.PublicKey
   437  	var ok bool
   438  	if pkey, ok = parsedKey.(*rsa.PublicKey); !ok {
   439  		panic("not an *rsa.PublicKey")
   440  	}
   441  
   442  	return pkey
   443  }
   444  
   445  func parseRSAPrivateKeyFromPEM(key []byte) *rsa.PrivateKey {
   446  	var err error
   447  
   448  	// Parse PEM block
   449  	var block *pem.Block
   450  	if block, _ = pem.Decode(key); block == nil {
   451  		panic("unable to decode")
   452  	}
   453  
   454  	var parsedKey interface{}
   455  	if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
   456  		if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
   457  			panic(err)
   458  		}
   459  	}
   460  
   461  	var pkey *rsa.PrivateKey
   462  	var ok bool
   463  	if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok {
   464  		panic("not an rsa private key")
   465  	}
   466  
   467  	return pkey
   468  }
   469  
   470  var (
   471  	defaultPubKeyPEM = []byte(`
   472  -----BEGIN PUBLIC KEY-----
   473  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4f5wg5l2hKsTeNem/V41
   474  fGnJm6gOdrj8ym3rFkEU/wT8RDtnSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7
   475  mCpz9Er5qLaMXJwZxzHzAahlfA0icqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBp
   476  HssPnpYGIn20ZZuNlX2BrClciHhCPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2
   477  XrHhR+1DcKJzQBSTAGnpYVaqpsARap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3b
   478  ODIRe1AuTyHceAbewn8b462yEWKARdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy
   479  7wIDAQAB
   480  -----END PUBLIC KEY-----`)
   481  	defaultPrivateKeyPEM = []byte(`
   482  -----BEGIN RSA PRIVATE KEY-----
   483  MIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEU/wT8RDtn
   484  SgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7mCpz9Er5qLaMXJwZxzHzAahlfA0i
   485  cqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBpHssPnpYGIn20ZZuNlX2BrClciHhC
   486  PUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2XrHhR+1DcKJzQBSTAGnpYVaqpsAR
   487  ap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3bODIRe1AuTyHceAbewn8b462yEWKA
   488  Rdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy7wIDAQABAoIBAQCwia1k7+2oZ2d3
   489  n6agCAbqIE1QXfCmh41ZqJHbOY3oRQG3X1wpcGH4Gk+O+zDVTV2JszdcOt7E5dAy
   490  MaomETAhRxB7hlIOnEN7WKm+dGNrKRvV0wDU5ReFMRHg31/Lnu8c+5BvGjZX+ky9
   491  POIhFFYJqwCRlopGSUIxmVj5rSgtzk3iWOQXr+ah1bjEXvlxDOWkHN6YfpV5ThdE
   492  KdBIPGEVqa63r9n2h+qazKrtiRqJqGnOrHzOECYbRFYhexsNFz7YT02xdfSHn7gM
   493  IvabDDP/Qp0PjE1jdouiMaFHYnLBbgvlnZW9yuVf/rpXTUq/njxIXMmvmEyyvSDn
   494  FcFikB8pAoGBAPF77hK4m3/rdGT7X8a/gwvZ2R121aBcdPwEaUhvj/36dx596zvY
   495  mEOjrWfZhF083/nYWE2kVquj2wjs+otCLfifEEgXcVPTnEOPO9Zg3uNSL0nNQghj
   496  FuD3iGLTUBCtM66oTe0jLSslHe8gLGEQqyMzHOzYxNqibxcOZIe8Qt0NAoGBAO+U
   497  I5+XWjWEgDmvyC3TrOSf/KCGjtu0TSv30ipv27bDLMrpvPmD/5lpptTFwcxvVhCs
   498  2b+chCjlghFSWFbBULBrfci2FtliClOVMYrlNBdUSJhf3aYSG2Doe6Bgt1n2CpNn
   499  /iu37Y3NfemZBJA7hNl4dYe+f+uzM87cdQ214+jrAoGAXA0XxX8ll2+ToOLJsaNT
   500  OvNB9h9Uc5qK5X5w+7G7O998BN2PC/MWp8H+2fVqpXgNENpNXttkRm1hk1dych86
   501  EunfdPuqsX+as44oCyJGFHVBnWpm33eWQw9YqANRI+pCJzP08I5WK3osnPiwshd+
   502  hR54yjgfYhBFNI7B95PmEQkCgYBzFSz7h1+s34Ycr8SvxsOBWxymG5zaCsUbPsL0
   503  4aCgLScCHb9J+E86aVbbVFdglYa5Id7DPTL61ixhl7WZjujspeXZGSbmq0Kcnckb
   504  mDgqkLECiOJW2NHP/j0McAkDLL4tysF8TLDO8gvuvzNC+WQ6drO2ThrypLVZQ+ry
   505  eBIPmwKBgEZxhqa0gVvHQG/7Od69KWj4eJP28kq13RhKay8JOoN0vPmspXJo1HY3
   506  CKuHRG+AP579dncdUnOMvfXOtkdM4vk0+hWASBQzM9xzVcztCa+koAugjVaLS9A+
   507  9uQoqEeVNTckxx0S2bYevRy7hGQmUJTyQm3j1zEUR5jpdbL83Fbq
   508  -----END RSA PRIVATE KEY-----`)
   509  )
   510  

View as plain text