diff --git a/cli/internal/oauth/jwt.go b/cli/internal/oauth/jwt.go index 9397ff1795..87ad1024e9 100644 --- a/cli/internal/oauth/jwt.go +++ b/cli/internal/oauth/jwt.go @@ -1,7 +1,8 @@ package oauth import ( - "github.com/go-jose/go-jose/v3/jwt" + "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/jwt" ) // Claims represents standard claims along with some custom ones. @@ -66,8 +67,23 @@ func GetClaims(accessToken string) (claims Claims, err error) { return } +// allowedSignatureAlgorithms is a list of allowed signature algorithms for JWTs. +// We add all supported algorithms for Auth0, including with higher key lengths. +// See auth0 docs: https://auth0.com/docs/get-started/applications/signing-algorithms +var allowedSignatureAlgorithms = []jose.SignatureAlgorithm{ + jose.HS256, + jose.HS384, + jose.HS512, + jose.RS256, // currently used for auth0 + jose.RS384, + jose.RS512, + jose.PS256, + jose.PS384, + jose.PS512, +} + // parseSigned parses a JWT and returns the signature object or error. This does // not verify the validity of the JWT. func parseSigned(token string) (*jwt.JSONWebToken, error) { - return jwt.ParseSigned(token) + return jwt.ParseSigned(token, allowedSignatureAlgorithms) } diff --git a/vendor.mod b/vendor.mod index d81c691238..23e0dff17b 100644 --- a/vendor.mod +++ b/vendor.mod @@ -18,7 +18,7 @@ require ( github.com/docker/go-connections v0.5.0 github.com/docker/go-units v0.5.0 github.com/fvbommel/sortorder v1.1.0 - github.com/go-jose/go-jose/v3 v3.0.3 + github.com/go-jose/go-jose/v4 v4.0.4 github.com/go-viper/mapstructure/v2 v2.0.0 github.com/gogo/protobuf v1.3.2 github.com/google/go-cmp v0.6.0 diff --git a/vendor.sum b/vendor.sum index 097832687e..d30731ca6c 100644 --- a/vendor.sum +++ b/vendor.sum @@ -76,8 +76,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw= github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= -github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -106,7 +106,6 @@ github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519 github.com/google/certificate-transparency-go v1.1.4 h1:hCyXHDbtqlr/lMXU0D4WgbalXL0Zk4dSWWMbPV8VrqY= github.com/google/certificate-transparency-go v1.1.4/go.mod h1:D6lvbfwckhNrbM9WVl1EVeMOyzC19mpIjMOI4nxBHtQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -280,7 +279,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17 github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc h1:zkGwegkOW709y0oiAraH/3D8njopUR/pARHv4tZZ6pw= github.com/zmap/zcrypto v0.0.0-20210511125630-18f1e0152cfc/go.mod h1:FM4U1E3NzlNMRnSUTU3P1UdukWhYGifqEsjk9fn7BCk= github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0= @@ -318,14 +316,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -333,10 +327,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -345,8 +335,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -358,32 +346,16 @@ golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= @@ -392,8 +364,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/jwt.go b/vendor/github.com/go-jose/go-jose/v3/jwt/jwt.go deleted file mode 100644 index 8553fc50b0..0000000000 --- a/vendor/github.com/go-jose/go-jose/v3/jwt/jwt.go +++ /dev/null @@ -1,133 +0,0 @@ -/*- - * Copyright 2016 Zbigniew Mandziejewicz - * Copyright 2016 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package jwt - -import ( - "fmt" - "strings" - - jose "github.com/go-jose/go-jose/v3" - "github.com/go-jose/go-jose/v3/json" -) - -// JSONWebToken represents a JSON Web Token (as specified in RFC7519). -type JSONWebToken struct { - payload func(k interface{}) ([]byte, error) - unverifiedPayload func() []byte - Headers []jose.Header -} - -type NestedJSONWebToken struct { - enc *jose.JSONWebEncryption - Headers []jose.Header -} - -// Claims deserializes a JSONWebToken into dest using the provided key. -func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error { - b, err := t.payload(key) - if err != nil { - return err - } - - for _, d := range dest { - if err := json.Unmarshal(b, d); err != nil { - return err - } - } - - return nil -} - -// UnsafeClaimsWithoutVerification deserializes the claims of a -// JSONWebToken into the dests. For signed JWTs, the claims are not -// verified. This function won't work for encrypted JWTs. -func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error { - if t.unverifiedPayload == nil { - return fmt.Errorf("go-jose/go-jose: Cannot get unverified claims") - } - claims := t.unverifiedPayload() - for _, d := range dest { - if err := json.Unmarshal(claims, d); err != nil { - return err - } - } - return nil -} - -func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) { - b, err := t.enc.Decrypt(decryptionKey) - if err != nil { - return nil, err - } - - sig, err := ParseSigned(string(b)) - if err != nil { - return nil, err - } - - return sig, nil -} - -// ParseSigned parses token from JWS form. -func ParseSigned(s string) (*JSONWebToken, error) { - sig, err := jose.ParseSigned(s) - if err != nil { - return nil, err - } - headers := make([]jose.Header, len(sig.Signatures)) - for i, signature := range sig.Signatures { - headers[i] = signature.Header - } - - return &JSONWebToken{ - payload: sig.Verify, - unverifiedPayload: sig.UnsafePayloadWithoutVerification, - Headers: headers, - }, nil -} - -// ParseEncrypted parses token from JWE form. -func ParseEncrypted(s string) (*JSONWebToken, error) { - enc, err := jose.ParseEncrypted(s) - if err != nil { - return nil, err - } - - return &JSONWebToken{ - payload: enc.Decrypt, - Headers: []jose.Header{enc.Header}, - }, nil -} - -// ParseSignedAndEncrypted parses signed-then-encrypted token from JWE form. -func ParseSignedAndEncrypted(s string) (*NestedJSONWebToken, error) { - enc, err := jose.ParseEncrypted(s) - if err != nil { - return nil, err - } - - contentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string) - if strings.ToUpper(contentType) != "JWT" { - return nil, ErrInvalidContentType - } - - return &NestedJSONWebToken{ - enc: enc, - Headers: []jose.Header{enc.Header}, - }, nil -} diff --git a/vendor/github.com/go-jose/go-jose/v3/.gitignore b/vendor/github.com/go-jose/go-jose/v4/.gitignore similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/.gitignore rename to vendor/github.com/go-jose/go-jose/v4/.gitignore diff --git a/vendor/github.com/go-jose/go-jose/v3/.golangci.yml b/vendor/github.com/go-jose/go-jose/v4/.golangci.yml similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/.golangci.yml rename to vendor/github.com/go-jose/go-jose/v4/.golangci.yml diff --git a/vendor/github.com/go-jose/go-jose/v3/.travis.yml b/vendor/github.com/go-jose/go-jose/v4/.travis.yml similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/.travis.yml rename to vendor/github.com/go-jose/go-jose/v4/.travis.yml diff --git a/vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md similarity index 84% rename from vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md rename to vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md index ce2a54ebf2..6f717dbd86 100644 --- a/vendor/github.com/go-jose/go-jose/v3/CHANGELOG.md +++ b/vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md @@ -1,3 +1,27 @@ +# v4.0.4 + +## Fixed + + - Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a + breaking change. See #136 / #137. + +# v4.0.3 + +## Changed + + - Allow unmarshalling JSONWebKeySets with unsupported key types (#130) + - Document that OpaqueKeyEncrypter can't be implemented (for now) (#129) + - Dependency updates + +# v4.0.2 + +## Changed + + - Improved documentation of Verify() to note that JSONWebKeySet is a supported + argument type (#104) + - Defined exported error values for missing x5c header and unsupported elliptic + curves error cases (#117) + # v4.0.1 ## Fixed @@ -45,12 +69,6 @@ token". [1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf -# v3.0.3 - -## Fixed - - - Limit decompression output size to prevent a DoS. Backport from v4.0.1. - # v3.0.2 ## Fixed diff --git a/vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md b/vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/CONTRIBUTING.md rename to vendor/github.com/go-jose/go-jose/v4/CONTRIBUTING.md diff --git a/vendor/github.com/go-jose/go-jose/v3/LICENSE b/vendor/github.com/go-jose/go-jose/v4/LICENSE similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/LICENSE rename to vendor/github.com/go-jose/go-jose/v4/LICENSE diff --git a/vendor/github.com/go-jose/go-jose/v3/README.md b/vendor/github.com/go-jose/go-jose/v4/README.md similarity index 82% rename from vendor/github.com/go-jose/go-jose/v3/README.md rename to vendor/github.com/go-jose/go-jose/v4/README.md index 282cd9e135..79a7c5ecc8 100644 --- a/vendor/github.com/go-jose/go-jose/v3/README.md +++ b/vendor/github.com/go-jose/go-jose/v4/README.md @@ -1,17 +1,9 @@ # Go JOSE -### Versions - -[Version 4](https://github.com/go-jose/go-jose) -([branch](https://github.com/go-jose/go-jose/), -[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version: - - import "github.com/go-jose/go-jose/v4" - -The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which -are deprecated. - -### Summary +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4) +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt) +[![license](https://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE) +[![test](https://img.shields.io/github/checks-status/go-jose/go-jose/v4)](https://github.com/go-jose/go-jose/actions) Package jose aims to provide an implementation of the Javascript Object Signing and Encryption set of standards. This includes support for JSON Web Encryption, @@ -43,6 +35,20 @@ of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/curren This is to avoid differences in interpretation of messages between go-jose and libraries in other languages. +### Versions + +[Version 4](https://github.com/go-jose/go-jose) +([branch](https://github.com/go-jose/go-jose/tree/main), +[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version: + + import "github.com/go-jose/go-jose/v4" + +The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which +are still useable but not actively developed anymore. + +Version 3, in this repo, is still receiving security fixes but not functionality +updates. + ### Supported algorithms See below for a table of supported algorithms. Algorithm identifiers match @@ -98,11 +104,11 @@ allows attaching a key id. ## Examples -[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3) -[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v3/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v3/jwt) +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4) +[![godoc](https://pkg.go.dev/badge/github.com/go-jose/go-jose/v4/jwt.svg)](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt) Examples can be found in the Godoc reference for this package. The -[`jose-util`](https://github.com/go-jose/go-jose/tree/v3/jose-util) +[`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util) subdirectory also contains a small command-line utility which might be useful as an example as well. diff --git a/vendor/github.com/go-jose/go-jose/v3/SECURITY.md b/vendor/github.com/go-jose/go-jose/v4/SECURITY.md similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/SECURITY.md rename to vendor/github.com/go-jose/go-jose/v4/SECURITY.md diff --git a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go b/vendor/github.com/go-jose/go-jose/v4/asymmetric.go similarity index 99% rename from vendor/github.com/go-jose/go-jose/v3/asymmetric.go rename to vendor/github.com/go-jose/go-jose/v4/asymmetric.go index d4d4961b24..f8d5774ef5 100644 --- a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go +++ b/vendor/github.com/go-jose/go-jose/v4/asymmetric.go @@ -29,8 +29,8 @@ import ( "fmt" "math/big" - josecipher "github.com/go-jose/go-jose/v3/cipher" - "github.com/go-jose/go-jose/v3/json" + josecipher "github.com/go-jose/go-jose/v4/cipher" + "github.com/go-jose/go-jose/v4/json" ) // A generic RSA-based encrypter/verifier diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go b/vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/cipher/cbc_hmac.go rename to vendor/github.com/go-jose/go-jose/v4/cipher/cbc_hmac.go diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go b/vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/cipher/concat_kdf.go rename to vendor/github.com/go-jose/go-jose/v4/cipher/concat_kdf.go diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go b/vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/cipher/ecdh_es.go rename to vendor/github.com/go-jose/go-jose/v4/cipher/ecdh_es.go diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go b/vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go rename to vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go diff --git a/vendor/github.com/go-jose/go-jose/v3/crypter.go b/vendor/github.com/go-jose/go-jose/v4/crypter.go similarity index 98% rename from vendor/github.com/go-jose/go-jose/v3/crypter.go rename to vendor/github.com/go-jose/go-jose/v4/crypter.go index 8870e8905f..d81b03b447 100644 --- a/vendor/github.com/go-jose/go-jose/v3/crypter.go +++ b/vendor/github.com/go-jose/go-jose/v4/crypter.go @@ -22,7 +22,7 @@ import ( "errors" "fmt" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // Encrypter represents an encrypter which produces an encrypted JWE object. @@ -459,7 +459,10 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") } - key := tryJWKS(decryptionKey, obj.Header) + key, err := tryJWKS(decryptionKey, obj.Header) + if err != nil { + return nil, err + } decrypter, err := newDecrypter(key) if err != nil { return nil, err @@ -529,7 +532,10 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header") } - key := tryJWKS(decryptionKey, obj.Header) + key, err := tryJWKS(decryptionKey, obj.Header) + if err != nil { + return -1, Header{}, nil, err + } decrypter, err := newDecrypter(key) if err != nil { return -1, Header{}, nil, err diff --git a/vendor/github.com/go-jose/go-jose/v3/doc.go b/vendor/github.com/go-jose/go-jose/v4/doc.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/doc.go rename to vendor/github.com/go-jose/go-jose/v4/doc.go diff --git a/vendor/github.com/go-jose/go-jose/v3/encoding.go b/vendor/github.com/go-jose/go-jose/v4/encoding.go similarity index 92% rename from vendor/github.com/go-jose/go-jose/v3/encoding.go rename to vendor/github.com/go-jose/go-jose/v4/encoding.go index 9f07cfdcb8..4f6e0d4a5c 100644 --- a/vendor/github.com/go-jose/go-jose/v3/encoding.go +++ b/vendor/github.com/go-jose/go-jose/v4/encoding.go @@ -27,7 +27,7 @@ import ( "strings" "unicode" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // Helper function to serialize known-good objects. @@ -106,10 +106,7 @@ func inflate(input []byte) ([]byte, error) { output := new(bytes.Buffer) reader := flate.NewReader(bytes.NewBuffer(input)) - maxCompressedSize := 10 * int64(len(input)) - if maxCompressedSize < 250000 { - maxCompressedSize = 250000 - } + maxCompressedSize := max(250_000, 10*int64(len(input))) limit := maxCompressedSize + 1 n, err := io.CopyN(output, reader, limit) @@ -167,7 +164,7 @@ func (b *byteBuffer) UnmarshalJSON(data []byte) error { return nil } - decoded, err := base64URLDecode(encoded) + decoded, err := base64.RawURLEncoding.DecodeString(encoded) if err != nil { return err } @@ -197,12 +194,6 @@ func (b byteBuffer) toInt() int { return int(b.bigInt().Int64()) } -// base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C -func base64URLDecode(value string) ([]byte, error) { - value = strings.TrimRight(value, "=") - return base64.RawURLEncoding.DecodeString(value) -} - func base64EncodeLen(sl []byte) int { return base64.RawURLEncoding.EncodedLen(len(sl)) } diff --git a/vendor/github.com/go-jose/go-jose/v3/json/LICENSE b/vendor/github.com/go-jose/go-jose/v4/json/LICENSE similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/LICENSE rename to vendor/github.com/go-jose/go-jose/v4/json/LICENSE diff --git a/vendor/github.com/go-jose/go-jose/v3/json/README.md b/vendor/github.com/go-jose/go-jose/v4/json/README.md similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/README.md rename to vendor/github.com/go-jose/go-jose/v4/json/README.md diff --git a/vendor/github.com/go-jose/go-jose/v3/json/decode.go b/vendor/github.com/go-jose/go-jose/v4/json/decode.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/decode.go rename to vendor/github.com/go-jose/go-jose/v4/json/decode.go diff --git a/vendor/github.com/go-jose/go-jose/v3/json/encode.go b/vendor/github.com/go-jose/go-jose/v4/json/encode.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/encode.go rename to vendor/github.com/go-jose/go-jose/v4/json/encode.go diff --git a/vendor/github.com/go-jose/go-jose/v3/json/indent.go b/vendor/github.com/go-jose/go-jose/v4/json/indent.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/indent.go rename to vendor/github.com/go-jose/go-jose/v4/json/indent.go diff --git a/vendor/github.com/go-jose/go-jose/v3/json/scanner.go b/vendor/github.com/go-jose/go-jose/v4/json/scanner.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/scanner.go rename to vendor/github.com/go-jose/go-jose/v4/json/scanner.go diff --git a/vendor/github.com/go-jose/go-jose/v3/json/stream.go b/vendor/github.com/go-jose/go-jose/v4/json/stream.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/stream.go rename to vendor/github.com/go-jose/go-jose/v4/json/stream.go diff --git a/vendor/github.com/go-jose/go-jose/v3/json/tags.go b/vendor/github.com/go-jose/go-jose/v4/json/tags.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/json/tags.go rename to vendor/github.com/go-jose/go-jose/v4/json/tags.go diff --git a/vendor/github.com/go-jose/go-jose/v3/jwe.go b/vendor/github.com/go-jose/go-jose/v4/jwe.go similarity index 63% rename from vendor/github.com/go-jose/go-jose/v3/jwe.go rename to vendor/github.com/go-jose/go-jose/v4/jwe.go index 4267ac7502..89f03ee3e1 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwe.go +++ b/vendor/github.com/go-jose/go-jose/v4/jwe.go @@ -18,10 +18,11 @@ package jose import ( "encoding/base64" + "errors" "fmt" "strings" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing. @@ -104,29 +105,75 @@ func (obj JSONWebEncryption) computeAuthData() []byte { return output } -// ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format. -func ParseEncrypted(input string) (*JSONWebEncryption, error) { - input = stripWhitespace(input) - if strings.HasPrefix(input, "{") { - return parseEncryptedFull(input) +func containsKeyAlgorithm(haystack []KeyAlgorithm, needle KeyAlgorithm) bool { + for _, algorithm := range haystack { + if algorithm == needle { + return true + } } - - return parseEncryptedCompact(input) + return false } -// parseEncryptedFull parses a message in compact format. -func parseEncryptedFull(input string) (*JSONWebEncryption, error) { +func containsContentEncryption(haystack []ContentEncryption, needle ContentEncryption) bool { + for _, algorithm := range haystack { + if algorithm == needle { + return true + } + } + return false +} + +// ParseEncrypted parses an encrypted message in JWE Compact or JWE JSON Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1 +// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2 +// +// The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc" +// header parameters respectively. They must be nonempty, and each "alg" or "enc" header in +// parsed data must contain a value that is present in the corresponding parameter. That +// includes the protected and unprotected headers as well as all recipients. To accept +// multiple algorithms, pass a slice of all the algorithms you want to accept. +func ParseEncrypted(input string, + keyEncryptionAlgorithms []KeyAlgorithm, + contentEncryption []ContentEncryption, +) (*JSONWebEncryption, error) { + input = stripWhitespace(input) + if strings.HasPrefix(input, "{") { + return ParseEncryptedJSON(input, keyEncryptionAlgorithms, contentEncryption) + } + + return ParseEncryptedCompact(input, keyEncryptionAlgorithms, contentEncryption) +} + +// ParseEncryptedJSON parses a message in JWE JSON Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7516#section-3.2 +func ParseEncryptedJSON( + input string, + keyEncryptionAlgorithms []KeyAlgorithm, + contentEncryption []ContentEncryption, +) (*JSONWebEncryption, error) { var parsed rawJSONWebEncryption err := json.Unmarshal([]byte(input), &parsed) if err != nil { return nil, err } - return parsed.sanitized() + return parsed.sanitized(keyEncryptionAlgorithms, contentEncryption) } // sanitized produces a cleaned-up JWE object from the raw JSON. -func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { +func (parsed *rawJSONWebEncryption) sanitized( + keyEncryptionAlgorithms []KeyAlgorithm, + contentEncryption []ContentEncryption, +) (*JSONWebEncryption, error) { + if len(keyEncryptionAlgorithms) == 0 { + return nil, errors.New("go-jose/go-jose: no key algorithms provided") + } + if len(contentEncryption) == 0 { + return nil, errors.New("go-jose/go-jose: no content encryption algorithms provided") + } + obj := &JSONWebEncryption{ original: parsed, unprotected: parsed.Unprotected, @@ -170,7 +217,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { } else { obj.recipients = make([]recipientInfo, len(parsed.Recipients)) for r := range parsed.Recipients { - encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey) + encryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey) if err != nil { return nil, err } @@ -185,10 +232,31 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { } } - for _, recipient := range obj.recipients { + for i, recipient := range obj.recipients { headers := obj.mergedHeaders(&recipient) - if headers.getAlgorithm() == "" || headers.getEncryption() == "" { - return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers") + if headers.getAlgorithm() == "" { + return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "alg"`, i) + } + if headers.getEncryption() == "" { + return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "enc"`, i) + } + err := validateAlgEnc(headers, keyEncryptionAlgorithms, contentEncryption) + if err != nil { + return nil, fmt.Errorf("go-jose/go-jose: recipient %d: %s", i, err) + } + + } + + if obj.protected != nil { + err := validateAlgEnc(*obj.protected, keyEncryptionAlgorithms, contentEncryption) + if err != nil { + return nil, fmt.Errorf("go-jose/go-jose: protected header: %s", err) + } + } + if obj.unprotected != nil { + err := validateAlgEnc(*obj.unprotected, keyEncryptionAlgorithms, contentEncryption) + if err != nil { + return nil, fmt.Errorf("go-jose/go-jose: unprotected header: %s", err) } } @@ -200,34 +268,52 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { return obj, nil } -// parseEncryptedCompact parses a message in compact format. -func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { +func validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncryption []ContentEncryption) error { + alg := headers.getAlgorithm() + enc := headers.getEncryption() + if alg != "" && !containsKeyAlgorithm(keyAlgorithms, alg) { + return fmt.Errorf("unexpected key algorithm %q; expected %q", alg, keyAlgorithms) + } + if alg != "" && !containsContentEncryption(contentEncryption, enc) { + return fmt.Errorf("unexpected content encryption algorithm %q; expected %q", enc, contentEncryption) + } + return nil +} + +// ParseEncryptedCompact parses a message in JWE Compact Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7516#section-3.1 +func ParseEncryptedCompact( + input string, + keyAlgorithms []KeyAlgorithm, + contentEncryption []ContentEncryption, +) (*JSONWebEncryption, error) { parts := strings.Split(input, ".") if len(parts) != 5 { return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts") } - rawProtected, err := base64URLDecode(parts[0]) + rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) if err != nil { return nil, err } - encryptedKey, err := base64URLDecode(parts[1]) + encryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { return nil, err } - iv, err := base64URLDecode(parts[2]) + iv, err := base64.RawURLEncoding.DecodeString(parts[2]) if err != nil { return nil, err } - ciphertext, err := base64URLDecode(parts[3]) + ciphertext, err := base64.RawURLEncoding.DecodeString(parts[3]) if err != nil { return nil, err } - tag, err := base64URLDecode(parts[4]) + tag, err := base64.RawURLEncoding.DecodeString(parts[4]) if err != nil { return nil, err } @@ -240,7 +326,7 @@ func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { Tag: newBuffer(tag), } - return raw.sanitized() + return raw.sanitized(keyAlgorithms, contentEncryption) } // CompactSerialize serializes an object using the compact serialization format. diff --git a/vendor/github.com/go-jose/go-jose/v3/jwk.go b/vendor/github.com/go-jose/go-jose/v4/jwk.go similarity index 96% rename from vendor/github.com/go-jose/go-jose/v3/jwk.go rename to vendor/github.com/go-jose/go-jose/v4/jwk.go index e4021959ab..8a52842106 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwk.go +++ b/vendor/github.com/go-jose/go-jose/v4/jwk.go @@ -35,7 +35,7 @@ import ( "reflect" "strings" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing. @@ -266,7 +266,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { // x5t parameters are base64url-encoded SHA thumbprints // See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8 - x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1) + x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1) if err != nil { return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding") } @@ -286,7 +286,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { k.CertificateThumbprintSHA1 = x5tSHA1bytes - x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256) + x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256) if err != nil { return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding") } @@ -779,7 +779,13 @@ func (key rawJSONWebKey) symmetricKey() ([]byte, error) { return key.K.bytes(), nil } -func tryJWKS(key interface{}, headers ...Header) interface{} { +var ( + // ErrJWKSKidNotFound is returned when a JWKS does not contain a JWK with a + // key ID which matches one in the provided tokens headers. + ErrJWKSKidNotFound = errors.New("go-jose/go-jose: JWK with matching kid not found in JWK Set") +) + +func tryJWKS(key interface{}, headers ...Header) (interface{}, error) { var jwks JSONWebKeySet switch jwksType := key.(type) { @@ -788,9 +794,11 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { case JSONWebKeySet: jwks = jwksType default: - return key + // If the specified key is not a JWKS, return as is. + return key, nil } + // Determine the KID to search for from the headers. var kid string for _, header := range headers { if header.KeyID != "" { @@ -799,14 +807,17 @@ func tryJWKS(key interface{}, headers ...Header) interface{} { } } + // If no KID is specified in the headers, reject. if kid == "" { - return key + return nil, ErrJWKSKidNotFound } + // Find the JWK with the matching KID. If no JWK with the specified KID is + // found, reject. keys := jwks.Key(kid) if len(keys) == 0 { - return key + return nil, ErrJWKSKidNotFound } - return keys[0].Key + return keys[0].Key, nil } diff --git a/vendor/github.com/go-jose/go-jose/v3/jws.go b/vendor/github.com/go-jose/go-jose/v4/jws.go similarity index 80% rename from vendor/github.com/go-jose/go-jose/v3/jws.go rename to vendor/github.com/go-jose/go-jose/v4/jws.go index e37007dbb8..3a912301af 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jws.go +++ b/vendor/github.com/go-jose/go-jose/v4/jws.go @@ -23,7 +23,7 @@ import ( "fmt" "strings" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing. @@ -75,22 +75,41 @@ type Signature struct { original *rawSignatureInfo } -// ParseSigned parses a signed message in compact or JWS JSON Serialization format. -func ParseSigned(signature string) (*JSONWebSignature, error) { +// ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7515#section-7 +func ParseSigned( + signature string, + signatureAlgorithms []SignatureAlgorithm, +) (*JSONWebSignature, error) { signature = stripWhitespace(signature) if strings.HasPrefix(signature, "{") { - return parseSignedFull(signature) + return ParseSignedJSON(signature, signatureAlgorithms) } - return parseSignedCompact(signature, nil) + return parseSignedCompact(signature, nil, signatureAlgorithms) +} + +// ParseSignedCompact parses a message in JWS Compact Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7515#section-7.1 +func ParseSignedCompact( + signature string, + signatureAlgorithms []SignatureAlgorithm, +) (*JSONWebSignature, error) { + return parseSignedCompact(signature, nil, signatureAlgorithms) } // ParseDetached parses a signed message in compact serialization format with detached payload. -func ParseDetached(signature string, payload []byte) (*JSONWebSignature, error) { +func ParseDetached( + signature string, + payload []byte, + signatureAlgorithms []SignatureAlgorithm, +) (*JSONWebSignature, error) { if payload == nil { return nil, errors.New("go-jose/go-jose: nil payload") } - return parseSignedCompact(stripWhitespace(signature), payload) + return parseSignedCompact(stripWhitespace(signature), payload, signatureAlgorithms) } // Get a header value @@ -137,19 +156,36 @@ func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature return authData.Bytes(), nil } -// parseSignedFull parses a message in full format. -func parseSignedFull(input string) (*JSONWebSignature, error) { +// ParseSignedJSON parses a message in JWS JSON Serialization. +// +// https://datatracker.ietf.org/doc/html/rfc7515#section-7.2 +func ParseSignedJSON( + input string, + signatureAlgorithms []SignatureAlgorithm, +) (*JSONWebSignature, error) { var parsed rawJSONWebSignature err := json.Unmarshal([]byte(input), &parsed) if err != nil { return nil, err } - return parsed.sanitized() + return parsed.sanitized(signatureAlgorithms) +} + +func containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureAlgorithm) bool { + for _, algorithm := range haystack { + if algorithm == needle { + return true + } + } + return false } // sanitized produces a cleaned-up JWS object from the raw JSON. -func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { +func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) { + if len(signatureAlgorithms) == 0 { + return nil, errors.New("go-jose/go-jose: no signature algorithms specified") + } if parsed.Payload == nil { return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message") } @@ -198,6 +234,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { return nil, err } + alg := SignatureAlgorithm(signature.Header.Algorithm) + if !containsSignatureAlgorithm(signatureAlgorithms, alg) { + return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q", + alg, signatureAlgorithms) + } + if signature.header != nil { signature.Unprotected, err = signature.header.sanitized() if err != nil { @@ -241,6 +283,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { return nil, err } + alg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm) + if !containsSignatureAlgorithm(signatureAlgorithms, alg) { + return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q", + alg, signatureAlgorithms) + } + if obj.Signatures[i].header != nil { obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized() if err != nil { @@ -274,7 +322,11 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { } // parseSignedCompact parses a message in compact format. -func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) { +func parseSignedCompact( + input string, + payload []byte, + signatureAlgorithms []SignatureAlgorithm, +) (*JSONWebSignature, error) { parts := strings.Split(input, ".") if len(parts) != 3 { return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts") @@ -284,19 +336,19 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") } - rawProtected, err := base64URLDecode(parts[0]) + rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) if err != nil { return nil, err } if payload == nil { - payload, err = base64URLDecode(parts[1]) + payload, err = base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { return nil, err } } - signature, err := base64URLDecode(parts[2]) + signature, err := base64.RawURLEncoding.DecodeString(parts[2]) if err != nil { return nil, err } @@ -306,7 +358,7 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) Protected: newBuffer(rawProtected), Signature: newBuffer(signature), } - return raw.sanitized() + return raw.sanitized(signatureAlgorithms) } func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) { diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/builder.go b/vendor/github.com/go-jose/go-jose/v4/jwt/builder.go similarity index 83% rename from vendor/github.com/go-jose/go-jose/v3/jwt/builder.go rename to vendor/github.com/go-jose/go-jose/v4/jwt/builder.go index 7df270cc39..d68bb3725c 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwt/builder.go +++ b/vendor/github.com/go-jose/go-jose/v4/jwt/builder.go @@ -21,13 +21,13 @@ import ( "bytes" "reflect" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" - "github.com/go-jose/go-jose/v3" + "github.com/go-jose/go-jose/v4" ) // Builder is a utility for making JSON Web Tokens. Calls can be chained, and -// errors are accumulated until the final call to CompactSerialize/FullSerialize. +// errors are accumulated until the final call to Serialize. type Builder interface { // Claims encodes claims into JWE/JWS form. Multiple calls will merge claims // into single JSON object. If you are passing private claims, make sure to set @@ -36,15 +36,13 @@ type Builder interface { Claims(i interface{}) Builder // Token builds a JSONWebToken from provided data. Token() (*JSONWebToken, error) - // FullSerialize serializes a token using the JWS/JWE JSON Serialization format. - FullSerialize() (string, error) - // CompactSerialize serializes a token using the compact serialization format. - CompactSerialize() (string, error) + // Serialize serializes a token. + Serialize() (string, error) } // NestedBuilder is a utility for making Signed-Then-Encrypted JSON Web Tokens. // Calls can be chained, and errors are accumulated until final call to -// CompactSerialize/FullSerialize. +// Serialize. type NestedBuilder interface { // Claims encodes claims into JWE/JWS form. Multiple calls will merge claims // into single JSON object. If you are passing private claims, make sure to set @@ -53,10 +51,8 @@ type NestedBuilder interface { Claims(i interface{}) NestedBuilder // Token builds a NestedJSONWebToken from provided data. Token() (*NestedJSONWebToken, error) - // FullSerialize serializes a token using the JSON Serialization format. - FullSerialize() (string, error) - // CompactSerialize serializes a token using the compact serialization format. - CompactSerialize() (string, error) + // Serialize serializes a token. + Serialize() (string, error) } type builder struct { @@ -194,7 +190,7 @@ func (b *signedBuilder) Token() (*JSONWebToken, error) { return b.builder.token(sig.Verify, h) } -func (b *signedBuilder) CompactSerialize() (string, error) { +func (b *signedBuilder) Serialize() (string, error) { sig, err := b.sign() if err != nil { return "", err @@ -203,15 +199,6 @@ func (b *signedBuilder) CompactSerialize() (string, error) { return sig.CompactSerialize() } -func (b *signedBuilder) FullSerialize() (string, error) { - sig, err := b.sign() - if err != nil { - return "", err - } - - return sig.FullSerialize(), nil -} - func (b *signedBuilder) sign() (*jose.JSONWebSignature, error) { if b.err != nil { return nil, b.err @@ -232,7 +219,7 @@ func (b *encryptedBuilder) Claims(i interface{}) Builder { } } -func (b *encryptedBuilder) CompactSerialize() (string, error) { +func (b *encryptedBuilder) Serialize() (string, error) { enc, err := b.encrypt() if err != nil { return "", err @@ -241,15 +228,6 @@ func (b *encryptedBuilder) CompactSerialize() (string, error) { return enc.CompactSerialize() } -func (b *encryptedBuilder) FullSerialize() (string, error) { - enc, err := b.encrypt() - if err != nil { - return "", err - } - - return enc.FullSerialize(), nil -} - func (b *encryptedBuilder) Token() (*JSONWebToken, error) { enc, err := b.encrypt() if err != nil { @@ -280,6 +258,8 @@ func (b *nestedBuilder) Claims(i interface{}) NestedBuilder { } } +// Token produced a token suitable for serialization. It cannot be decrypted +// without serializing and then deserializing. func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) { enc, err := b.signAndEncrypt() if err != nil { @@ -287,12 +267,13 @@ func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) { } return &NestedJSONWebToken{ - enc: enc, - Headers: []jose.Header{enc.Header}, + allowedSignatureAlgorithms: nil, + enc: enc, + Headers: []jose.Header{enc.Header}, }, nil } -func (b *nestedBuilder) CompactSerialize() (string, error) { +func (b *nestedBuilder) Serialize() (string, error) { enc, err := b.signAndEncrypt() if err != nil { return "", err diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/claims.go b/vendor/github.com/go-jose/go-jose/v4/jwt/claims.go similarity index 98% rename from vendor/github.com/go-jose/go-jose/v3/jwt/claims.go rename to vendor/github.com/go-jose/go-jose/v4/jwt/claims.go index b2a8dc8d4d..e73412a391 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwt/claims.go +++ b/vendor/github.com/go-jose/go-jose/v4/jwt/claims.go @@ -21,7 +21,7 @@ import ( "strconv" "time" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // Claims represents public claim values (as specified in RFC 7519). diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/doc.go b/vendor/github.com/go-jose/go-jose/v4/jwt/doc.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/jwt/doc.go rename to vendor/github.com/go-jose/go-jose/v4/jwt/doc.go diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/errors.go b/vendor/github.com/go-jose/go-jose/v4/jwt/errors.go similarity index 100% rename from vendor/github.com/go-jose/go-jose/v3/jwt/errors.go rename to vendor/github.com/go-jose/go-jose/v4/jwt/errors.go diff --git a/vendor/github.com/go-jose/go-jose/v4/jwt/jwt.go b/vendor/github.com/go-jose/go-jose/v4/jwt/jwt.go new file mode 100644 index 0000000000..c4998d7875 --- /dev/null +++ b/vendor/github.com/go-jose/go-jose/v4/jwt/jwt.go @@ -0,0 +1,198 @@ +/*- + * Copyright 2016 Zbigniew Mandziejewicz + * Copyright 2016 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package jwt + +import ( + "fmt" + "strings" + + jose "github.com/go-jose/go-jose/v4" + "github.com/go-jose/go-jose/v4/json" +) + +// JSONWebToken represents a JSON Web Token (as specified in RFC7519). +type JSONWebToken struct { + payload func(k interface{}) ([]byte, error) + unverifiedPayload func() []byte + Headers []jose.Header +} + +type NestedJSONWebToken struct { + enc *jose.JSONWebEncryption + Headers []jose.Header + // Used when parsing and decrypting an input + allowedSignatureAlgorithms []jose.SignatureAlgorithm +} + +// Claims deserializes a JSONWebToken into dest using the provided key. +func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error { + b, err := t.payload(key) + if err != nil { + return err + } + + for _, d := range dest { + if err := json.Unmarshal(b, d); err != nil { + return err + } + } + + return nil +} + +// UnsafeClaimsWithoutVerification deserializes the claims of a +// JSONWebToken into the dests. For signed JWTs, the claims are not +// verified. This function won't work for encrypted JWTs. +func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error { + if t.unverifiedPayload == nil { + return fmt.Errorf("go-jose/go-jose: Cannot get unverified claims") + } + claims := t.unverifiedPayload() + for _, d := range dest { + if err := json.Unmarshal(claims, d); err != nil { + return err + } + } + return nil +} + +func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) { + b, err := t.enc.Decrypt(decryptionKey) + if err != nil { + return nil, err + } + + sig, err := ParseSigned(string(b), t.allowedSignatureAlgorithms) + if err != nil { + return nil, err + } + + return sig, nil +} + +// ParseSigned parses token from JWS form. +func ParseSigned(s string, signatureAlgorithms []jose.SignatureAlgorithm) (*JSONWebToken, error) { + sig, err := jose.ParseSignedCompact(s, signatureAlgorithms) + if err != nil { + return nil, err + } + headers := make([]jose.Header, len(sig.Signatures)) + for i, signature := range sig.Signatures { + headers[i] = signature.Header + } + + return &JSONWebToken{ + payload: sig.Verify, + unverifiedPayload: sig.UnsafePayloadWithoutVerification, + Headers: headers, + }, nil +} + +func validateKeyEncryptionAlgorithm(algs []jose.KeyAlgorithm) error { + for _, alg := range algs { + switch alg { + case jose.ED25519, + jose.RSA1_5, + jose.RSA_OAEP, + jose.RSA_OAEP_256, + jose.ECDH_ES, + jose.ECDH_ES_A128KW, + jose.ECDH_ES_A192KW, + jose.ECDH_ES_A256KW: + return fmt.Errorf("asymmetric encryption algorithms not supported for JWT: "+ + "invalid key encryption algorithm: %s", alg) + case jose.PBES2_HS256_A128KW, + jose.PBES2_HS384_A192KW, + jose.PBES2_HS512_A256KW: + return fmt.Errorf("password-based encryption not supported for JWT: "+ + "invalid key encryption algorithm: %s", alg) + } + } + return nil +} + +func parseEncryptedCompact( + s string, + keyAlgorithms []jose.KeyAlgorithm, + contentEncryption []jose.ContentEncryption, +) (*jose.JSONWebEncryption, error) { + err := validateKeyEncryptionAlgorithm(keyAlgorithms) + if err != nil { + return nil, err + } + enc, err := jose.ParseEncryptedCompact(s, keyAlgorithms, contentEncryption) + if err != nil { + return nil, err + } + return enc, nil +} + +// ParseEncrypted parses token from JWE form. +// +// The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc" +// header parameters respectively. They must be nonempty, and each "alg" or "enc" header in +// parsed data must contain a value that is present in the corresponding parameter. That +// includes the protected and unprotected headers as well as all recipients. To accept +// multiple algorithms, pass a slice of all the algorithms you want to accept. +func ParseEncrypted(s string, + keyAlgorithms []jose.KeyAlgorithm, + contentEncryption []jose.ContentEncryption, +) (*JSONWebToken, error) { + enc, err := parseEncryptedCompact(s, keyAlgorithms, contentEncryption) + if err != nil { + return nil, err + } + + return &JSONWebToken{ + payload: enc.Decrypt, + Headers: []jose.Header{enc.Header}, + }, nil +} + +// ParseSignedAndEncrypted parses signed-then-encrypted token from JWE form. +// +// The encryptionKeyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc" +// header parameters, respectively, of the outer JWE. They must be nonempty, and each "alg" or "enc" +// header in parsed data must contain a value that is present in the corresponding parameter. That +// includes the protected and unprotected headers as well as all recipients. To accept +// multiple algorithms, pass a slice of all the algorithms you want to accept. +// +// The signatureAlgorithms parameter is used to validate the "alg" header parameter of the +// inner JWS. It must be nonempty, and the "alg" header in the inner JWS must contain a value +// that is present in the parameter. +func ParseSignedAndEncrypted(s string, + encryptionKeyAlgorithms []jose.KeyAlgorithm, + contentEncryption []jose.ContentEncryption, + signatureAlgorithms []jose.SignatureAlgorithm, +) (*NestedJSONWebToken, error) { + enc, err := parseEncryptedCompact(s, encryptionKeyAlgorithms, contentEncryption) + if err != nil { + return nil, err + } + + contentType, _ := enc.Header.ExtraHeaders[jose.HeaderContentType].(string) + if strings.ToUpper(contentType) != "JWT" { + return nil, ErrInvalidContentType + } + + return &NestedJSONWebToken{ + allowedSignatureAlgorithms: signatureAlgorithms, + enc: enc, + Headers: []jose.Header{enc.Header}, + }, nil +} diff --git a/vendor/github.com/go-jose/go-jose/v3/jwt/validation.go b/vendor/github.com/go-jose/go-jose/v4/jwt/validation.go similarity index 91% rename from vendor/github.com/go-jose/go-jose/v3/jwt/validation.go rename to vendor/github.com/go-jose/go-jose/v4/jwt/validation.go index 09d8541f4c..841a93eef4 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwt/validation.go +++ b/vendor/github.com/go-jose/go-jose/v4/jwt/validation.go @@ -33,8 +33,9 @@ type Expected struct { Issuer string // Subject matches the "sub" claim exactly. Subject string - // Audience matches the values in "aud" claim, regardless of their order. - Audience Audience + // AnyAudience matches if there is a non-empty intersection between + // its values and the values in the "aud" claim. + AnyAudience Audience // ID matches the "jti" claim exactly. ID string // Time matches the "exp", "nbf" and "iat" claims with leeway. @@ -88,12 +89,18 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error { return ErrInvalidID } - if len(e.Audience) != 0 { - for _, v := range e.Audience { - if !c.Audience.Contains(v) { - return ErrInvalidAudience + if len(e.AnyAudience) != 0 { + var intersection bool + for _, v := range e.AnyAudience { + if c.Audience.Contains(v) { + intersection = true + break } } + + if !intersection { + return ErrInvalidAudience + } } // validate using the e.Time, or time.Now if not provided diff --git a/vendor/github.com/go-jose/go-jose/v3/opaque.go b/vendor/github.com/go-jose/go-jose/v4/opaque.go similarity index 97% rename from vendor/github.com/go-jose/go-jose/v3/opaque.go rename to vendor/github.com/go-jose/go-jose/v4/opaque.go index 68db085ef6..429427232e 100644 --- a/vendor/github.com/go-jose/go-jose/v3/opaque.go +++ b/vendor/github.com/go-jose/go-jose/v4/opaque.go @@ -83,6 +83,9 @@ func (o *opaqueVerifier) verifyPayload(payload []byte, signature []byte, alg Sig } // OpaqueKeyEncrypter is an interface that supports encrypting keys with an opaque key. +// +// Note: this cannot currently be implemented outside this package because of its +// unexported method. type OpaqueKeyEncrypter interface { // KeyID returns the kid KeyID() string diff --git a/vendor/github.com/go-jose/go-jose/v3/shared.go b/vendor/github.com/go-jose/go-jose/v4/shared.go similarity index 97% rename from vendor/github.com/go-jose/go-jose/v3/shared.go rename to vendor/github.com/go-jose/go-jose/v4/shared.go index 489a04e32a..1ec3396126 100644 --- a/vendor/github.com/go-jose/go-jose/v3/shared.go +++ b/vendor/github.com/go-jose/go-jose/v4/shared.go @@ -23,7 +23,7 @@ import ( "errors" "fmt" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // KeyAlgorithm represents a key management algorithm. @@ -71,6 +71,12 @@ var ( // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a // nonce header parameter was included in an unprotected header object. ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header") + + // ErrMissingX5cHeader indicates that the JWT header is missing x5c headers. + ErrMissingX5cHeader = errors.New("go-jose/go-jose: no x5c header present in message") + + // ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found. + ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve") ) // Key management algorithms @@ -199,7 +205,7 @@ type Header struct { // not be validated with the given verify options. func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) { if len(h.certificates) == 0 { - return nil, errors.New("go-jose/go-jose: no x5c header present in message") + return nil, ErrMissingX5cHeader } leaf := h.certificates[0] @@ -501,7 +507,7 @@ func curveName(crv elliptic.Curve) (string, error) { case elliptic.P521(): return "P-521", nil default: - return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve") + return "", ErrUnsupportedEllipticCurve } } diff --git a/vendor/github.com/go-jose/go-jose/v3/signing.go b/vendor/github.com/go-jose/go-jose/v4/signing.go similarity index 95% rename from vendor/github.com/go-jose/go-jose/v3/signing.go rename to vendor/github.com/go-jose/go-jose/v4/signing.go index 52f3d85604..3dec0112b6 100644 --- a/vendor/github.com/go-jose/go-jose/v3/signing.go +++ b/vendor/github.com/go-jose/go-jose/v4/signing.go @@ -25,7 +25,7 @@ import ( "errors" "fmt" - "github.com/go-jose/go-jose/v3/json" + "github.com/go-jose/go-jose/v4/json" ) // NonceSource represents a source of random nonces to go into JWS objects @@ -49,6 +49,11 @@ type Signer interface { // - JSONWebKey // - []byte (an HMAC key) // - Any type that satisfies the OpaqueSigner interface +// +// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output: +// - HS256: 32 bytes +// - HS384: 48 bytes +// - HS512: 64 bytes type SigningKey struct { Algorithm SignatureAlgorithm Key interface{} @@ -353,8 +358,15 @@ func (ctx *genericSigner) Options() SignerOptions { // - *rsa.PublicKey // - *JSONWebKey // - JSONWebKey +// - *JSONWebKeySet +// - JSONWebKeySet // - []byte (an HMAC key) // - Any type that implements the OpaqueVerifier interface. +// +// If the key is an HMAC key, it must have at least as many bytes as the relevant hash output: +// - HS256: 32 bytes +// - HS384: 48 bytes +// - HS512: 64 bytes func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) { err := obj.DetachedVerify(obj.payload, verificationKey) if err != nil { @@ -378,7 +390,10 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte { // The verificationKey argument must have one of the types allowed for the // verificationKey argument of JSONWebSignature.Verify(). func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error { - key := tryJWKS(verificationKey, obj.headers()...) + key, err := tryJWKS(verificationKey, obj.headers()...) + if err != nil { + return err + } verifier, err := newVerifier(key) if err != nil { return err @@ -443,7 +458,10 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa // The verificationKey argument must have one of the types allowed for the // verificationKey argument of JSONWebSignature.Verify(). func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) { - key := tryJWKS(verificationKey, obj.headers()...) + key, err := tryJWKS(verificationKey, obj.headers()...) + if err != nil { + return -1, Signature{}, err + } verifier, err := newVerifier(key) if err != nil { return -1, Signature{}, err diff --git a/vendor/github.com/go-jose/go-jose/v3/symmetric.go b/vendor/github.com/go-jose/go-jose/v4/symmetric.go similarity index 96% rename from vendor/github.com/go-jose/go-jose/v3/symmetric.go rename to vendor/github.com/go-jose/go-jose/v4/symmetric.go index 10d8e19fd1..a69103b084 100644 --- a/vendor/github.com/go-jose/go-jose/v3/symmetric.go +++ b/vendor/github.com/go-jose/go-jose/v4/symmetric.go @@ -32,7 +32,7 @@ import ( "golang.org/x/crypto/pbkdf2" - josecipher "github.com/go-jose/go-jose/v3/cipher" + josecipher "github.com/go-jose/go-jose/v4/cipher" ) // RandReader is a cryptographically secure random number generator (stubbed out in tests). @@ -454,7 +454,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { mac, err := ctx.hmac(payload, alg) if err != nil { - return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac") + return Signature{}, err } return Signature{ @@ -486,12 +486,24 @@ func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureA func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) { var hash func() hash.Hash + // https://datatracker.ietf.org/doc/html/rfc7518#section-3.2 + // A key of the same size as the hash output (for instance, 256 bits for + // "HS256") or larger MUST be used switch alg { case HS256: + if len(ctx.key)*8 < 256 { + return nil, ErrInvalidKeySize + } hash = sha256.New case HS384: + if len(ctx.key)*8 < 384 { + return nil, ErrInvalidKeySize + } hash = sha512.New384 case HS512: + if len(ctx.key)*8 < 512 { + return nil, ErrInvalidKeySize + } hash = sha512.New default: return nil, ErrUnsupportedAlgorithm diff --git a/vendor/modules.txt b/vendor/modules.txt index 05db4f2c51..430194d842 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -123,12 +123,12 @@ github.com/felixge/httpsnoop # github.com/fvbommel/sortorder v1.1.0 ## explicit; go 1.13 github.com/fvbommel/sortorder -# github.com/go-jose/go-jose/v3 v3.0.3 -## explicit; go 1.12 -github.com/go-jose/go-jose/v3 -github.com/go-jose/go-jose/v3/cipher -github.com/go-jose/go-jose/v3/json -github.com/go-jose/go-jose/v3/jwt +# github.com/go-jose/go-jose/v4 v4.0.4 +## explicit; go 1.21 +github.com/go-jose/go-jose/v4 +github.com/go-jose/go-jose/v4/cipher +github.com/go-jose/go-jose/v4/json +github.com/go-jose/go-jose/v4/jwt # github.com/go-logr/logr v1.4.2 ## explicit; go 1.18 github.com/go-logr/logr