diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d928ef427..226e337f5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - uses: golangci/golangci-lint-action@v2 with: - version: v1.41.1 + version: v1.45.2 - name: Run go vet run: | go vet ./... diff --git a/.golangci.yml b/.golangci.yml index b5afb667a..f2b084529 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,11 +28,14 @@ linters: - gofumpt - golint #deprecated - gomnd + - gomoddirectives # I think it's broken - gosec - govet - interfacer # deprecated - ifshort + - ireturn # No, I _LIKE_ returning interfaces - lll + - maintidx # Do this in code review - maligned # deprecated - makezero - nakedret @@ -42,7 +45,8 @@ linters: - scopelint # deprecated - tagliatelle - testpackage - - thelper + - thelper # Tests are fine + - varnamelen # Short names are ok - wrapcheck - wsl @@ -63,9 +67,15 @@ issues: - path: internal/codegen/codegen.go linters: - errcheck + - path: internal/jwxtest/jwxtest.go + linters: + - errcheck + - errchkjson + - forcetypeassert - path: /*_test.go linters: - errcheck + - errchkjson - forcetypeassert - path: /*_example_test.go linters: diff --git a/cmd/jwx/jwx b/cmd/jwx/jwx new file mode 100755 index 000000000..7ddf4a068 Binary files /dev/null and b/cmd/jwx/jwx differ diff --git a/cmd/jwx/key.jwk b/cmd/jwx/key.jwk new file mode 100644 index 000000000..ad0f2d141 --- /dev/null +++ b/cmd/jwx/key.jwk @@ -0,0 +1,6 @@ +{ + "crv": "Ed25519", + "d": "OJwlw3P0dqt7i7zInqap0ifDj0iVVSRmexe4lzNrXc4", + "kty": "OKP", + "x": "14sVO4wa1ZKZ5w5cbiZiwjXeDkEJia_7A6OvJEwGRHA" +} \ No newline at end of file diff --git a/cmd/jwx/message.jws b/cmd/jwx/message.jws new file mode 100644 index 000000000..f8a00b3e7 --- /dev/null +++ b/cmd/jwx/message.jws @@ -0,0 +1 @@ +eyJhbGciOiJFZERTQSJ9.aGVsbG8.ttC4S9aCLoCFPzMpqJVMrcfE-Xc9_4bI6f79AD6ZheNBrSXwvJRS3SMK6LID8scZOvhdjv_iOF5t0KaX6kIFDw \ No newline at end of file diff --git a/examples/hoge.jwk b/examples/hoge.jwk new file mode 100644 index 000000000..225c878bc --- /dev/null +++ b/examples/hoge.jwk @@ -0,0 +1,11 @@ + {"kty":"RSA", + "n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddxHmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMsD1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSHSXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ", + "e":"AQAB", + "d":"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97IjlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYTCBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLhBOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ", + "p":"4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdiYrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPGBY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc", +"q":"uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxaewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA-njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc", + "dp":"BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3QCLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0", + "dq":"h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-kyNlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU", + "qi":"IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2oy26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLUW0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U" + } + diff --git a/go.mod b/go.mod index 792046272..34870409d 100644 --- a/go.mod +++ b/go.mod @@ -15,4 +15,4 @@ require ( golang.org/x/crypto v0.0.0-20220214200702-86341886e292 ) -retract v1.2.16 +retract v1.2.16 // Packaging problems. diff --git a/internal/ecutil/ecutil.go b/internal/ecutil/ecutil.go index 1d79aeb37..128666913 100644 --- a/internal/ecutil/ecutil.go +++ b/internal/ecutil/ecutil.go @@ -61,6 +61,7 @@ var ecpointBufferPool = sync.Pool{ } func getCrvFixedBuffer(size int) []byte { + //nolint:forcetypeassert buf := *(ecpointBufferPool.Get().(*[]byte)) if size > ec521BufferSize && cap(buf) < size { buf = append(buf, make([]byte, size-cap(buf))...) diff --git a/internal/iter/mapiter.go b/internal/iter/mapiter.go index 184d3f0c1..f7ddc1189 100644 --- a/internal/iter/mapiter.go +++ b/internal/iter/mapiter.go @@ -22,6 +22,7 @@ func (fn MapVisitorFunc) Visit(s string, v interface{}) error { func WalkMap(ctx context.Context, src mapiter.Source, visitor MapVisitor) error { return mapiter.Walk(ctx, src, mapiter.VisitorFunc(func(k, v interface{}) error { + //nolint:forcetypeassert return visitor.Visit(k.(string), v) })) } diff --git a/internal/json/stdlib.go b/internal/json/stdlib.go index 0d0c5ce3d..62b1a5ff5 100644 --- a/internal/json/stdlib.go +++ b/internal/json/stdlib.go @@ -1,3 +1,4 @@ +//go:build !jwx_goccy // +build !jwx_goccy package json diff --git a/internal/jwxtest/jwxtest.go b/internal/jwxtest/jwxtest.go index 673203da3..ecd52c43d 100644 --- a/internal/jwxtest/jwxtest.go +++ b/internal/jwxtest/jwxtest.go @@ -88,7 +88,6 @@ func GenerateEcdsaPublicJwk() (jwk.Key, error) { func GenerateSymmetricKey() []byte { sharedKey := make([]byte, 64) - //nolint:errcheck rand.Read(sharedKey) return sharedKey } diff --git a/internal/pool/pool.go b/internal/pool/pool.go index 09a4af8b2..fae560b7c 100644 --- a/internal/pool/pool.go +++ b/internal/pool/pool.go @@ -15,6 +15,7 @@ func allocBytesBuffer() interface{} { } func GetBytesBuffer() *bytes.Buffer { + //nolint:forcetypeassert return bytesBufferPool.Get().(*bytes.Buffer) } @@ -32,6 +33,7 @@ func allocBigInt() interface{} { } func GetBigInt() *big.Int { + //nolint:forcetypeassert return bigIntPool.Get().(*big.Int) } @@ -48,6 +50,7 @@ func allocKeyToErrorMap() interface{} { } func GetKeyToErrorMap() map[string]error { + //nolint:forcetypeassert return keyToErrorMapPool.Get().(map[string]error) } diff --git a/jwe/encrypt.go b/jwe/encrypt.go index 0b1b40bf4..230b5aba9 100644 --- a/jwe/encrypt.go +++ b/jwe/encrypt.go @@ -16,6 +16,7 @@ var encryptCtxPool = sync.Pool{ } func getEncryptCtx() *encryptCtx { + //nolint:forcetypeassert return encryptCtxPool.Get().(*encryptCtx) } diff --git a/jwe/headers.go b/jwe/headers.go index 7d8efd634..eacbfda01 100644 --- a/jwe/headers.go +++ b/jwe/headers.go @@ -71,8 +71,10 @@ func (h *stdHeaders) Clone(ctx context.Context) (Headers, error) { func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error { for _, pair := range h.makePairs() { - if err := dst.Set(pair.Key.(string), pair.Value); err != nil { - return errors.Wrapf(err, `failed to set header`) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := dst.Set(key, pair.Value); err != nil { + return errors.Wrapf(err, `failed to set header %q`, key) } } return nil diff --git a/jwe/internal/cipher/cipher.go b/jwe/internal/cipher/cipher.go index 586feff89..4581f648b 100644 --- a/jwe/internal/cipher/cipher.go +++ b/jwe/internal/cipher/cipher.go @@ -96,10 +96,8 @@ func (c AesContentCipher) Encrypt(cek, plaintext, aad []byte) (iv, ciphertext, t switch e := e.(type) { case error: err = e - case string: - err = errors.New(e) default: - err = fmt.Errorf("%s", e) + err = errors.Errorf("%s", e) } err = errors.Wrap(err, "failed to encrypt") } @@ -142,10 +140,8 @@ func (c AesContentCipher) Decrypt(cek, iv, ciphertxt, tag, aad []byte) (plaintex switch e := e.(type) { case error: err = e - case string: - err = errors.New(e) default: - err = fmt.Errorf("%s", e) + err = errors.Errorf("%s", e) } err = errors.Wrap(err, "failed to decrypt") return diff --git a/jwe/message.go b/jwe/message.go index d3dc2535b..6609a6924 100644 --- a/jwe/message.go +++ b/jwe/message.go @@ -395,8 +395,10 @@ func (m *Message) UnmarshalJSON(buf []byte) error { m.rawProtectedHeaders = base64.Encode(protectedHeadersRaw) } - if !proxy.UnprotectedHeaders.(isZeroer).isZero() { - m.unprotectedHeaders = proxy.UnprotectedHeaders + if iz, ok := proxy.UnprotectedHeaders.(isZeroer); ok { + if !iz.isZero() { + m.unprotectedHeaders = proxy.UnprotectedHeaders + } } if len(m.recipients) == 0 { diff --git a/jwk/ecdsa.go b/jwk/ecdsa.go index 1f011ce78..19e0f8847 100644 --- a/jwk/ecdsa.go +++ b/jwk/ecdsa.go @@ -149,8 +149,10 @@ func makeECDSAPublicKey(v interface { case ECDSADKey: continue default: - if err := newKey.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set field %s`, pair.Key) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := newKey.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set field %q`, key) } } } diff --git a/jwk/jwk.go b/jwk/jwk.go index 84e3766c4..0ef377c95 100644 --- a/jwk/jwk.go +++ b/jwk/jwk.go @@ -624,8 +624,10 @@ func cloneKey(src Key) (Key, error) { } for _, pair := range src.makePairs() { - if err := dst.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set %s`, pair.Key.(string)) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := dst.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set %q`, key) } } return dst, nil diff --git a/jwk/okp.go b/jwk/okp.go index 565fb448f..6d99bd6fe 100644 --- a/jwk/okp.go +++ b/jwk/okp.go @@ -85,6 +85,7 @@ func buildOKPPrivateKey(alg jwa.EllipticCurveAlgorithm, xbuf []byte, dbuf []byte switch alg { case jwa.Ed25519: ret := ed25519.NewKeyFromSeed(dbuf) + //nolint:forcetypeassert if !bytes.Equal(xbuf, ret.Public().(ed25519.PublicKey)) { return nil, errors.Errorf(`invalid x value given d value`) } @@ -94,6 +95,7 @@ func buildOKPPrivateKey(alg jwa.EllipticCurveAlgorithm, xbuf []byte, dbuf []byte if err != nil { return nil, errors.Wrap(err, `unable to construct x25519 private key from seed`) } + //nolint:forcetypeassert if !bytes.Equal(xbuf, ret.Public().(x25519.PublicKey)) { return nil, errors.Errorf(`invalid x value given d value`) } @@ -126,8 +128,10 @@ func makeOKPPublicKey(v interface { case OKPDKey: continue default: - if err := newKey.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set field %s`, pair.Key) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := newKey.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set field %q`, key) } } } diff --git a/jwk/rsa.go b/jwk/rsa.go index 5ef2260c4..1a31caa7a 100644 --- a/jwk/rsa.go +++ b/jwk/rsa.go @@ -183,8 +183,10 @@ func makeRSAPublicKey(v interface { case RSADKey, RSADPKey, RSADQKey, RSAPKey, RSAQKey, RSAQIKey: continue default: - if err := newKey.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set field %s`, pair.Key) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := newKey.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set field %q`, key) } } } diff --git a/jwk/symmetric.go b/jwk/symmetric.go index ae2cd15d0..8511cff00 100644 --- a/jwk/symmetric.go +++ b/jwk/symmetric.go @@ -51,8 +51,10 @@ func (k *symmetricKey) PublicKey() (Key, error) { newKey := NewSymmetricKey() for _, pair := range k.makePairs() { - if err := newKey.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set field %s`, pair.Key) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := newKey.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set field %q`, key) } } return newKey, nil diff --git a/jws/headers.go b/jws/headers.go index 2eca43158..9ca8f656e 100644 --- a/jws/headers.go +++ b/jws/headers.go @@ -36,8 +36,10 @@ func (h *stdHeaders) AsMap(ctx context.Context) (map[string]interface{}, error) func (h *stdHeaders) Copy(ctx context.Context, dst Headers) error { for _, pair := range h.makePairs() { - if err := dst.Set(pair.Key.(string), pair.Value); err != nil { - return errors.Wrapf(err, `failed to set header`) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := dst.Set(key, pair.Value); err != nil { + return errors.Wrapf(err, `failed to set header %q`, key) } } return nil diff --git a/jws/jws.go b/jws/jws.go index c767116ff..c7811bc36 100644 --- a/jws/jws.go +++ b/jws/jws.go @@ -165,6 +165,7 @@ func Sign(payload []byte, alg jwa.SignatureAlgorithm, key interface{}, options . func SignMulti(payload []byte, options ...Option) ([]byte, error) { var signers []*payloadSigner for _, o := range options { + //nolint:forcetypeassert switch o.Ident() { case identPayloadSigner{}: signers = append(signers, o.Value().(*payloadSigner)) diff --git a/jws/message.go b/jws/message.go index 669041a0a..802b29771 100644 --- a/jws/message.go +++ b/jws/message.go @@ -81,10 +81,12 @@ func (s *Signature) UnmarshalJSON(data []byte) error { } prt := NewHeaders() + //nolint:forcetypeassert prt.(*stdHeaders).SetDecodeCtx(s.DecodeCtx()) if err := json.Unmarshal(src, prt); err != nil { return errors.Wrap(err, `failed to unmarshal protected headers`) } + //nolint:forcetypeassert prt.(*stdHeaders).SetDecodeCtx(nil) s.protected = prt } @@ -305,10 +307,12 @@ func (m *Message) UnmarshalJSON(buf []byte) error { return errors.Wrap(err, `failed to base64 decode flattened protected headers`) } prt := NewHeaders() + //nolint:forcetypeassert prt.(*stdHeaders).SetDecodeCtx(m.DecodeCtx()) if err := json.Unmarshal(decoded, prt); err != nil { return errors.Wrap(err, `failed to unmarshal flattened protected headers`) } + //nolint:forcetypeassert prt.(*stdHeaders).SetDecodeCtx(nil) sig.protected = prt } diff --git a/jwt/http.go b/jwt/http.go index be19abb76..aaaf27f13 100644 --- a/jwt/http.go +++ b/jwt/http.go @@ -63,6 +63,7 @@ func ParseRequest(req *http.Request, options ...ParseOption) (Token, error) { var formkeys []string var parseOptions []ParseOption for _, option := range options { + //nolint:forcetypeassert switch option.Ident() { case identHeaderKey{}: hdrkeys = append(hdrkeys, option.Value().(string)) diff --git a/jwt/jwt.go b/jwt/jwt.go index 3c35279d1..13c153934 100644 --- a/jwt/jwt.go +++ b/jwt/jwt.go @@ -529,8 +529,10 @@ func (t *stdToken) Clone() (Token, error) { dst := New() for _, pair := range t.makePairs() { - if err := dst.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set %s`, pair.Key.(string)) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := dst.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set %s`, key) } } return dst, nil diff --git a/jwt/openid/openid.go b/jwt/openid/openid.go index bfd0a446a..7631ea38a 100644 --- a/jwt/openid/openid.go +++ b/jwt/openid/openid.go @@ -19,8 +19,10 @@ func (t *stdToken) Clone() (jwt.Token, error) { var dst jwt.Token = New() for _, pair := range t.makePairs() { - if err := dst.Set(pair.Key.(string), pair.Value); err != nil { - return nil, errors.Wrapf(err, `failed to set %s`, pair.Key.(string)) + //nolint:forcetypeassert + key := pair.Key.(string) + if err := dst.Set(key, pair.Value); err != nil { + return nil, errors.Wrapf(err, `failed to set %s`, key) } } return dst, nil diff --git a/jwt/validate.go b/jwt/validate.go index c1a6894c0..631e3841a 100644 --- a/jwt/validate.go +++ b/jwt/validate.go @@ -204,6 +204,7 @@ func SetValidationCtxClock(ctx context.Context, cl Clock) context.Context { // the current validation context. This value will always be available // during validation of tokens. func ValidationCtxClock(ctx context.Context) Clock { + //nolint:forcetypeassert return ctx.Value(identValidationCtxClock{}).(Clock) } @@ -212,6 +213,7 @@ func SetValidationCtxSkew(ctx context.Context, dur time.Duration) context.Contex } func ValidationCtxSkew(ctx context.Context) time.Duration { + //nolint:forcetypeassert return ctx.Value(identValidationCtxSkew{}).(time.Duration) }