From 05b903a32e34da2ad121927ff9f19412e9e964c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveirinha?= Date: Thu, 17 Mar 2022 22:34:35 +0000 Subject: [PATCH] Revert "CC-796: Remove dependency on unsupported version of go-oidc" This reverts commit 0899d6a13619cba03bc0c933ef0c7032c2393311. --- go.mod | 6 +- go.sum | 10 +- sshgen/sshgen.go | 18 +- sshgen/sshgen_test.go | 36 +- token/token.go | 17 +- vendor/github.com/coreos/go-oidc/LICENSE | 202 +++++++++++ vendor/github.com/coreos/go-oidc/NOTICE | 5 + .../github.com/coreos/go-oidc/jose/claims.go | 126 +++++++ vendor/github.com/coreos/go-oidc/jose/doc.go | 2 + vendor/github.com/coreos/go-oidc/jose/jose.go | 112 ++++++ vendor/github.com/coreos/go-oidc/jose/jwk.go | 135 +++++++ vendor/github.com/coreos/go-oidc/jose/jws.go | 51 +++ vendor/github.com/coreos/go-oidc/jose/jwt.go | 82 +++++ vendor/github.com/coreos/go-oidc/jose/sig.go | 24 ++ .../github.com/coreos/go-oidc/jose/sig_rsa.go | 67 ++++ vendor/gopkg.in/coreos/go-oidc.v2/.travis.yml | 6 +- vendor/gopkg.in/coreos/go-oidc.v2/oidc.go | 34 +- vendor/gopkg.in/coreos/go-oidc.v2/verify.go | 11 +- vendor/gopkg.in/square/go-jose.v2/.gitignore | 1 - vendor/gopkg.in/square/go-jose.v2/.travis.yml | 9 +- .../square/go-jose.v2/cipher/cbc_hmac.go | 2 +- vendor/gopkg.in/square/go-jose.v2/crypter.go | 1 - vendor/gopkg.in/square/go-jose.v2/encoding.go | 14 +- .../gopkg.in/square/go-jose.v2/json/decode.go | 52 +-- .../gopkg.in/square/go-jose.v2/json/stream.go | 7 +- vendor/gopkg.in/square/go-jose.v2/jwk.go | 174 +-------- vendor/gopkg.in/square/go-jose.v2/jws.go | 6 +- .../gopkg.in/square/go-jose.v2/jwt/builder.go | 334 ------------------ .../gopkg.in/square/go-jose.v2/jwt/claims.go | 121 ------- vendor/gopkg.in/square/go-jose.v2/jwt/doc.go | 22 -- .../gopkg.in/square/go-jose.v2/jwt/errors.go | 53 --- vendor/gopkg.in/square/go-jose.v2/jwt/jwt.go | 169 --------- .../square/go-jose.v2/jwt/validation.go | 114 ------ vendor/gopkg.in/square/go-jose.v2/opaque.go | 2 +- vendor/gopkg.in/square/go-jose.v2/shared.go | 6 +- vendor/gopkg.in/square/go-jose.v2/signing.go | 12 +- vendor/modules.txt | 8 +- 37 files changed, 905 insertions(+), 1146 deletions(-) create mode 100644 vendor/github.com/coreos/go-oidc/LICENSE create mode 100644 vendor/github.com/coreos/go-oidc/NOTICE create mode 100644 vendor/github.com/coreos/go-oidc/jose/claims.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/doc.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/jose.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/jwk.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/jws.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/jwt.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/sig.go create mode 100644 vendor/github.com/coreos/go-oidc/jose/sig_rsa.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/builder.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/claims.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/doc.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/errors.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/jwt.go delete mode 100644 vendor/gopkg.in/square/go-jose.v2/jwt/validation.go diff --git a/go.mod b/go.mod index 83328b33..59b8ec7c 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/cloudflare/brotli-go v0.0.0-20191101163834-d34379f7ff93 github.com/cloudflare/golibs v0.0.0-20170913112048-333127dbecfc github.com/coredns/coredns v1.8.7 + github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 // indirect @@ -50,15 +51,14 @@ require ( golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb // indirect google.golang.org/grpc v1.43.0 // indirect + gopkg.in/coreos/go-oidc.v2 v2.1.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0 - gopkg.in/square/go-jose.v2 v2.6.0 + gopkg.in/square/go-jose.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect zombiezen.com/go/capnproto2 v2.18.0+incompatible ) -require gopkg.in/coreos/go-oidc.v2 v2.2.1 - require ( github.com/BurntSushi/toml v0.3.1 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect diff --git a/go.sum b/go.sum index 44c59257..ed534dcb 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,8 @@ github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= github.com/coredns/coredns v1.8.7 h1:wVMjAnyFnY7Mc18AFO+9qbGD6ODPtdVUIlzoWrHr3hk= github.com/coredns/coredns v1.8.7/go.mod h1:bFmbgEfeRz5aizL2VsQ5LRlsvJuXWkgG/MWG9zxqjVM= +github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 h1:7CNPV0LWRCa1FNmqg700pbXhzvmoaXKyfxWRkjRym7Q= +github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -1050,15 +1052,15 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/coreos/go-oidc.v2 v2.2.1 h1:MY5SZClJ7vhjKfr64a4nHAOV/c3WH2gB9BMrR64J1Mc= -gopkg.in/coreos/go-oidc.v2 v2.2.1/go.mod h1:fYaTe2FS96wZZwR17YTDHwG+Mw6fmyqJNxN2eNCGPCI= +gopkg.in/coreos/go-oidc.v2 v2.1.0 h1:E8PjVFdj/SLDKB0hvb70KTbMbYVHjqztiQdSkIg8E+I= +gopkg.in/coreos/go-oidc.v2 v2.1.0/go.mod h1:fYaTe2FS96wZZwR17YTDHwG+Mw6fmyqJNxN2eNCGPCI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.4.0 h1:0kXPskUMGAXXWJlP05ktEMOV0vmzFQUWw6d+aZJQU8A= +gopkg.in/square/go-jose.v2 v2.4.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/sshgen/sshgen.go b/sshgen/sshgen.go index 27e73715..9fba2053 100644 --- a/sshgen/sshgen.go +++ b/sshgen/sshgen.go @@ -15,10 +15,10 @@ import ( "net/url" "time" + "github.com/coreos/go-oidc/jose" homedir "github.com/mitchellh/go-homedir" "github.com/pkg/errors" gossh "golang.org/x/crypto/ssh" - "gopkg.in/square/go-jose.v2/jwt" "github.com/cloudflare/cloudflared/config" cfpath "github.com/cloudflare/cloudflared/token" @@ -87,33 +87,37 @@ func SignCert(token, pubKey string) (string, error) { return "", errors.New("invalid token") } - parsedToken, err := jwt.ParseSigned(token) + jwt, err := jose.ParseJWT(token) if err != nil { return "", errors.Wrap(err, "failed to parse JWT") } - claims := jwt.Claims{} - err = parsedToken.UnsafeClaimsWithoutVerification(&claims) + claims, err := jwt.Claims() if err != nil { return "", errors.Wrap(err, "failed to retrieve JWT claims") } + issuer, _, err := claims.StringClaim("iss") + if err != nil { + return "", errors.Wrap(err, "failed to retrieve JWT iss") + } + buf, err := json.Marshal(&signPayload{ PublicKey: pubKey, JWT: token, - Issuer: claims.Issuer, + Issuer: issuer, }) if err != nil { return "", errors.Wrap(err, "failed to marshal signPayload") } var res *http.Response if mockRequest != nil { - res, err = mockRequest(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf)) + res, err = mockRequest(issuer+signEndpoint, "application/json", bytes.NewBuffer(buf)) } else { client := http.Client{ Timeout: 10 * time.Second, } - res, err = client.Post(claims.Issuer+signEndpoint, "application/json", bytes.NewBuffer(buf)) + res, err = client.Post(issuer+signEndpoint, "application/json", bytes.NewBuffer(buf)) } if err != nil { diff --git a/sshgen/sshgen_test.go b/sshgen/sshgen_test.go index c2716f59..99ac8021 100644 --- a/sshgen/sshgen_test.go +++ b/sshgen/sshgen_test.go @@ -4,6 +4,8 @@ package sshgen import ( + "crypto/rand" + "crypto/rsa" "encoding/json" "fmt" "io" @@ -16,9 +18,8 @@ import ( "testing" "time" + "github.com/coreos/go-oidc/jose" "github.com/stretchr/testify/assert" - "gopkg.in/square/go-jose.v2" - "gopkg.in/square/go-jose.v2/jwt" "github.com/cloudflare/cloudflared/config" cfpath "github.com/cloudflare/cloudflared/token" @@ -96,25 +97,22 @@ func TestCertGenSuccess(t *testing.T) { } func tokenGenerator() string { - iat := time.Now() - exp := time.Now().Add(time.Minute * 5) + iat := time.Now().Unix() + exp := time.Now().Add(time.Minute * 5).Unix() + claims := jose.Claims{} + claims.Add("aud", audTest) + claims.Add("iat", iat) + claims.Add("nonce", nonceTest) + claims.Add("exp", exp) - claims := jwt.Claims{ - Audience: jwt.Audience{audTest}, - IssuedAt: jwt.NewNumericDate(iat), - Expiry: jwt.NewNumericDate(exp), - } - - key := []byte("secret") - signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: key}, (&jose.SignerOptions{}).WithType("JWT")) + k, err := rsa.GenerateKey(rand.Reader, 512) if err != nil { - panic(err) + return "" } - - signedToken, err := jwt.Signed(signer).Claims(claims).CompactSerialize() - if err != nil { - panic(err) + signer := jose.NewSignerRSA("asdf", *k) + token, terr := jose.NewSignedJWT(claims, signer) + if terr != nil { + return "" } - - return signedToken + return token.Encode() } diff --git a/token/token.go b/token/token.go index abccf257..d4f237a9 100644 --- a/token/token.go +++ b/token/token.go @@ -13,9 +13,9 @@ import ( "syscall" "time" + "github.com/coreos/go-oidc/jose" "github.com/pkg/errors" "github.com/rs/zerolog" - "gopkg.in/square/go-jose.v2" "github.com/cloudflare/cloudflared/config" "github.com/cloudflare/cloudflared/retry" @@ -342,7 +342,7 @@ func GetOrgTokenIfExists(authDomain string) (string, error) { return "", err } var payload jwtPayload - err = json.Unmarshal(token.UnsafePayloadWithoutVerification(), &payload) + err = json.Unmarshal(token.Payload, &payload) if err != nil { return "", err } @@ -351,7 +351,7 @@ func GetOrgTokenIfExists(authDomain string) (string, error) { err := os.Remove(path) return "", err } - return token.CompactSerialize() + return token.Encode(), nil } func GetAppTokenIfExists(appInfo *AppInfo) (string, error) { @@ -364,7 +364,7 @@ func GetAppTokenIfExists(appInfo *AppInfo) (string, error) { return "", err } var payload jwtPayload - err = json.Unmarshal(token.UnsafePayloadWithoutVerification(), &payload) + err = json.Unmarshal(token.Payload, &payload) if err != nil { return "", err } @@ -373,21 +373,22 @@ func GetAppTokenIfExists(appInfo *AppInfo) (string, error) { err := os.Remove(path) return "", err } - return token.CompactSerialize() + return token.Encode(), nil } // GetTokenIfExists will return the token from local storage if it exists and not expired -func getTokenIfExists(path string) (*jose.JSONWebSignature, error) { +func getTokenIfExists(path string) (*jose.JWT, error) { content, err := ioutil.ReadFile(path) if err != nil { return nil, err } - token, err := jose.ParseSigned(string(content)) + token, err := jose.ParseJWT(string(content)) if err != nil { return nil, err } - return token, nil + + return &token, nil } // RemoveTokenIfExists removes the a token from local storage if it exists diff --git a/vendor/github.com/coreos/go-oidc/LICENSE b/vendor/github.com/coreos/go-oidc/LICENSE new file mode 100644 index 00000000..e06d2081 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. + diff --git a/vendor/github.com/coreos/go-oidc/NOTICE b/vendor/github.com/coreos/go-oidc/NOTICE new file mode 100644 index 00000000..b39ddfa5 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-oidc/jose/claims.go b/vendor/github.com/coreos/go-oidc/jose/claims.go new file mode 100644 index 00000000..8b48bfd2 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/claims.go @@ -0,0 +1,126 @@ +package jose + +import ( + "encoding/json" + "fmt" + "math" + "time" +) + +type Claims map[string]interface{} + +func (c Claims) Add(name string, value interface{}) { + c[name] = value +} + +func (c Claims) StringClaim(name string) (string, bool, error) { + cl, ok := c[name] + if !ok { + return "", false, nil + } + + v, ok := cl.(string) + if !ok { + return "", false, fmt.Errorf("unable to parse claim as string: %v", name) + } + + return v, true, nil +} + +func (c Claims) StringsClaim(name string) ([]string, bool, error) { + cl, ok := c[name] + if !ok { + return nil, false, nil + } + + if v, ok := cl.([]string); ok { + return v, true, nil + } + + // When unmarshaled, []string will become []interface{}. + if v, ok := cl.([]interface{}); ok { + var ret []string + for _, vv := range v { + str, ok := vv.(string) + if !ok { + return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name) + } + ret = append(ret, str) + } + return ret, true, nil + } + + return nil, false, fmt.Errorf("unable to parse claim as string array: %v", name) +} + +func (c Claims) Int64Claim(name string) (int64, bool, error) { + cl, ok := c[name] + if !ok { + return 0, false, nil + } + + v, ok := cl.(int64) + if !ok { + vf, ok := cl.(float64) + if !ok { + return 0, false, fmt.Errorf("unable to parse claim as int64: %v", name) + } + v = int64(vf) + } + + return v, true, nil +} + +func (c Claims) Float64Claim(name string) (float64, bool, error) { + cl, ok := c[name] + if !ok { + return 0, false, nil + } + + v, ok := cl.(float64) + if !ok { + vi, ok := cl.(int64) + if !ok { + return 0, false, fmt.Errorf("unable to parse claim as float64: %v", name) + } + v = float64(vi) + } + + return v, true, nil +} + +func (c Claims) TimeClaim(name string) (time.Time, bool, error) { + v, ok, err := c.Float64Claim(name) + if !ok || err != nil { + return time.Time{}, ok, err + } + + s := math.Trunc(v) + ns := (v - s) * math.Pow(10, 9) + return time.Unix(int64(s), int64(ns)).UTC(), true, nil +} + +func decodeClaims(payload []byte) (Claims, error) { + var c Claims + if err := json.Unmarshal(payload, &c); err != nil { + return nil, fmt.Errorf("malformed JWT claims, unable to decode: %v", err) + } + return c, nil +} + +func marshalClaims(c Claims) ([]byte, error) { + b, err := json.Marshal(c) + if err != nil { + return nil, err + } + return b, nil +} + +func encodeClaims(c Claims) (string, error) { + b, err := marshalClaims(c) + if err != nil { + return "", err + } + + return encodeSegment(b), nil +} diff --git a/vendor/github.com/coreos/go-oidc/jose/doc.go b/vendor/github.com/coreos/go-oidc/jose/doc.go new file mode 100644 index 00000000..b5e13217 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/doc.go @@ -0,0 +1,2 @@ +// Package jose is DEPRECATED. Use gopkg.in/square/go-jose.v2 instead. +package jose diff --git a/vendor/github.com/coreos/go-oidc/jose/jose.go b/vendor/github.com/coreos/go-oidc/jose/jose.go new file mode 100644 index 00000000..62099265 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/jose.go @@ -0,0 +1,112 @@ +package jose + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strings" +) + +const ( + HeaderMediaType = "typ" + HeaderKeyAlgorithm = "alg" + HeaderKeyID = "kid" +) + +const ( + // Encryption Algorithm Header Parameter Values for JWS + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-6 + AlgHS256 = "HS256" + AlgHS384 = "HS384" + AlgHS512 = "HS512" + AlgRS256 = "RS256" + AlgRS384 = "RS384" + AlgRS512 = "RS512" + AlgES256 = "ES256" + AlgES384 = "ES384" + AlgES512 = "ES512" + AlgPS256 = "PS256" + AlgPS384 = "PS384" + AlgPS512 = "PS512" + AlgNone = "none" +) + +const ( + // Algorithm Header Parameter Values for JWE + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#section-4.1 + AlgRSA15 = "RSA1_5" + AlgRSAOAEP = "RSA-OAEP" + AlgRSAOAEP256 = "RSA-OAEP-256" + AlgA128KW = "A128KW" + AlgA192KW = "A192KW" + AlgA256KW = "A256KW" + AlgDir = "dir" + AlgECDHES = "ECDH-ES" + AlgECDHESA128KW = "ECDH-ES+A128KW" + AlgECDHESA192KW = "ECDH-ES+A192KW" + AlgECDHESA256KW = "ECDH-ES+A256KW" + AlgA128GCMKW = "A128GCMKW" + AlgA192GCMKW = "A192GCMKW" + AlgA256GCMKW = "A256GCMKW" + AlgPBES2HS256A128KW = "PBES2-HS256+A128KW" + AlgPBES2HS384A192KW = "PBES2-HS384+A192KW" + AlgPBES2HS512A256KW = "PBES2-HS512+A256KW" +) + +const ( + // Encryption Algorithm Header Parameter Values for JWE + // See: https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40#page-22 + EncA128CBCHS256 = "A128CBC-HS256" + EncA128CBCHS384 = "A128CBC-HS384" + EncA256CBCHS512 = "A256CBC-HS512" + EncA128GCM = "A128GCM" + EncA192GCM = "A192GCM" + EncA256GCM = "A256GCM" +) + +type JOSEHeader map[string]string + +func (j JOSEHeader) Validate() error { + if _, exists := j[HeaderKeyAlgorithm]; !exists { + return fmt.Errorf("header missing %q parameter", HeaderKeyAlgorithm) + } + + return nil +} + +func decodeHeader(seg string) (JOSEHeader, error) { + b, err := decodeSegment(seg) + if err != nil { + return nil, err + } + + var h JOSEHeader + err = json.Unmarshal(b, &h) + if err != nil { + return nil, err + } + + return h, nil +} + +func encodeHeader(h JOSEHeader) (string, error) { + b, err := json.Marshal(h) + if err != nil { + return "", err + } + + return encodeSegment(b), nil +} + +// Decode JWT specific base64url encoding with padding stripped +func decodeSegment(seg string) ([]byte, error) { + if l := len(seg) % 4; l != 0 { + seg += strings.Repeat("=", 4-l) + } + return base64.URLEncoding.DecodeString(seg) +} + +// Encode JWT specific base64url encoding with padding stripped +func encodeSegment(seg []byte) string { + return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=") +} diff --git a/vendor/github.com/coreos/go-oidc/jose/jwk.go b/vendor/github.com/coreos/go-oidc/jose/jwk.go new file mode 100644 index 00000000..119f073f --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/jwk.go @@ -0,0 +1,135 @@ +package jose + +import ( + "bytes" + "encoding/base64" + "encoding/binary" + "encoding/json" + "math/big" + "strings" +) + +// JSON Web Key +// https://tools.ietf.org/html/draft-ietf-jose-json-web-key-36#page-5 +type JWK struct { + ID string + Type string + Alg string + Use string + Exponent int + Modulus *big.Int + Secret []byte +} + +type jwkJSON struct { + ID string `json:"kid"` + Type string `json:"kty"` + Alg string `json:"alg"` + Use string `json:"use"` + Exponent string `json:"e"` + Modulus string `json:"n"` +} + +func (j *JWK) MarshalJSON() ([]byte, error) { + t := jwkJSON{ + ID: j.ID, + Type: j.Type, + Alg: j.Alg, + Use: j.Use, + Exponent: encodeExponent(j.Exponent), + Modulus: encodeModulus(j.Modulus), + } + + return json.Marshal(&t) +} + +func (j *JWK) UnmarshalJSON(data []byte) error { + var t jwkJSON + err := json.Unmarshal(data, &t) + if err != nil { + return err + } + + e, err := decodeExponent(t.Exponent) + if err != nil { + return err + } + + n, err := decodeModulus(t.Modulus) + if err != nil { + return err + } + + j.ID = t.ID + j.Type = t.Type + j.Alg = t.Alg + j.Use = t.Use + j.Exponent = e + j.Modulus = n + + return nil +} + +type JWKSet struct { + Keys []JWK `json:"keys"` +} + +func decodeExponent(e string) (int, error) { + decE, err := decodeBase64URLPaddingOptional(e) + if err != nil { + return 0, err + } + var eBytes []byte + if len(decE) < 8 { + eBytes = make([]byte, 8-len(decE), 8) + eBytes = append(eBytes, decE...) + } else { + eBytes = decE + } + eReader := bytes.NewReader(eBytes) + var E uint64 + err = binary.Read(eReader, binary.BigEndian, &E) + if err != nil { + return 0, err + } + return int(E), nil +} + +func encodeExponent(e int) string { + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(e)) + var idx int + for ; idx < 8; idx++ { + if b[idx] != 0x0 { + break + } + } + return base64.RawURLEncoding.EncodeToString(b[idx:]) +} + +// Turns a URL encoded modulus of a key into a big int. +func decodeModulus(n string) (*big.Int, error) { + decN, err := decodeBase64URLPaddingOptional(n) + if err != nil { + return nil, err + } + N := big.NewInt(0) + N.SetBytes(decN) + return N, nil +} + +func encodeModulus(n *big.Int) string { + return base64.RawURLEncoding.EncodeToString(n.Bytes()) +} + +// decodeBase64URLPaddingOptional decodes Base64 whether there is padding or not. +// The stdlib version currently doesn't handle this. +// We can get rid of this is if this bug: +// https://github.com/golang/go/issues/4237 +// ever closes. +func decodeBase64URLPaddingOptional(e string) ([]byte, error) { + if m := len(e) % 4; m != 0 { + e += strings.Repeat("=", 4-m) + } + return base64.URLEncoding.DecodeString(e) +} diff --git a/vendor/github.com/coreos/go-oidc/jose/jws.go b/vendor/github.com/coreos/go-oidc/jose/jws.go new file mode 100644 index 00000000..1049ece8 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/jws.go @@ -0,0 +1,51 @@ +package jose + +import ( + "fmt" + "strings" +) + +type JWS struct { + RawHeader string + Header JOSEHeader + RawPayload string + Payload []byte + Signature []byte +} + +// Given a raw encoded JWS token parses it and verifies the structure. +func ParseJWS(raw string) (JWS, error) { + parts := strings.Split(raw, ".") + if len(parts) != 3 { + return JWS{}, fmt.Errorf("malformed JWS, only %d segments", len(parts)) + } + + rawSig := parts[2] + jws := JWS{ + RawHeader: parts[0], + RawPayload: parts[1], + } + + header, err := decodeHeader(jws.RawHeader) + if err != nil { + return JWS{}, fmt.Errorf("malformed JWS, unable to decode header, %s", err) + } + if err = header.Validate(); err != nil { + return JWS{}, fmt.Errorf("malformed JWS, %s", err) + } + jws.Header = header + + payload, err := decodeSegment(jws.RawPayload) + if err != nil { + return JWS{}, fmt.Errorf("malformed JWS, unable to decode payload: %s", err) + } + jws.Payload = payload + + sig, err := decodeSegment(rawSig) + if err != nil { + return JWS{}, fmt.Errorf("malformed JWS, unable to decode signature: %s", err) + } + jws.Signature = sig + + return jws, nil +} diff --git a/vendor/github.com/coreos/go-oidc/jose/jwt.go b/vendor/github.com/coreos/go-oidc/jose/jwt.go new file mode 100644 index 00000000..3b3e9634 --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/jwt.go @@ -0,0 +1,82 @@ +package jose + +import "strings" + +type JWT JWS + +func ParseJWT(token string) (jwt JWT, err error) { + jws, err := ParseJWS(token) + if err != nil { + return + } + + return JWT(jws), nil +} + +func NewJWT(header JOSEHeader, claims Claims) (jwt JWT, err error) { + jwt = JWT{} + + jwt.Header = header + jwt.Header[HeaderMediaType] = "JWT" + + claimBytes, err := marshalClaims(claims) + if err != nil { + return + } + jwt.Payload = claimBytes + + eh, err := encodeHeader(header) + if err != nil { + return + } + jwt.RawHeader = eh + + ec, err := encodeClaims(claims) + if err != nil { + return + } + jwt.RawPayload = ec + + return +} + +func (j *JWT) KeyID() (string, bool) { + kID, ok := j.Header[HeaderKeyID] + return kID, ok +} + +func (j *JWT) Claims() (Claims, error) { + return decodeClaims(j.Payload) +} + +// Encoded data part of the token which may be signed. +func (j *JWT) Data() string { + return strings.Join([]string{j.RawHeader, j.RawPayload}, ".") +} + +// Full encoded JWT token string in format: header.claims.signature +func (j *JWT) Encode() string { + d := j.Data() + s := encodeSegment(j.Signature) + return strings.Join([]string{d, s}, ".") +} + +func NewSignedJWT(claims Claims, s Signer) (*JWT, error) { + header := JOSEHeader{ + HeaderKeyAlgorithm: s.Alg(), + HeaderKeyID: s.ID(), + } + + jwt, err := NewJWT(header, claims) + if err != nil { + return nil, err + } + + sig, err := s.Sign([]byte(jwt.Data())) + if err != nil { + return nil, err + } + jwt.Signature = sig + + return &jwt, nil +} diff --git a/vendor/github.com/coreos/go-oidc/jose/sig.go b/vendor/github.com/coreos/go-oidc/jose/sig.go new file mode 100644 index 00000000..7b2b253c --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/sig.go @@ -0,0 +1,24 @@ +package jose + +import ( + "fmt" +) + +type Verifier interface { + ID() string + Alg() string + Verify(sig []byte, data []byte) error +} + +type Signer interface { + Verifier + Sign(data []byte) (sig []byte, err error) +} + +func NewVerifier(jwk JWK) (Verifier, error) { + if jwk.Type != "RSA" { + return nil, fmt.Errorf("unsupported key type %q", jwk.Type) + } + + return NewVerifierRSA(jwk) +} diff --git a/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go b/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go new file mode 100644 index 00000000..004e45dd --- /dev/null +++ b/vendor/github.com/coreos/go-oidc/jose/sig_rsa.go @@ -0,0 +1,67 @@ +package jose + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" + "fmt" +) + +type VerifierRSA struct { + KeyID string + Hash crypto.Hash + PublicKey rsa.PublicKey +} + +type SignerRSA struct { + PrivateKey rsa.PrivateKey + VerifierRSA +} + +func NewVerifierRSA(jwk JWK) (*VerifierRSA, error) { + if jwk.Alg != "" && jwk.Alg != "RS256" { + return nil, fmt.Errorf("unsupported key algorithm %q", jwk.Alg) + } + + v := VerifierRSA{ + KeyID: jwk.ID, + PublicKey: rsa.PublicKey{ + N: jwk.Modulus, + E: jwk.Exponent, + }, + Hash: crypto.SHA256, + } + + return &v, nil +} + +func NewSignerRSA(kid string, key rsa.PrivateKey) *SignerRSA { + return &SignerRSA{ + PrivateKey: key, + VerifierRSA: VerifierRSA{ + KeyID: kid, + PublicKey: key.PublicKey, + Hash: crypto.SHA256, + }, + } +} + +func (v *VerifierRSA) ID() string { + return v.KeyID +} + +func (v *VerifierRSA) Alg() string { + return "RS256" +} + +func (v *VerifierRSA) Verify(sig []byte, data []byte) error { + h := v.Hash.New() + h.Write(data) + return rsa.VerifyPKCS1v15(&v.PublicKey, v.Hash, h.Sum(nil), sig) +} + +func (s *SignerRSA) Sign(data []byte) ([]byte, error) { + h := s.Hash.New() + h.Write(data) + return rsa.SignPKCS1v15(rand.Reader, &s.PrivateKey, s.Hash, h.Sum(nil)) +} diff --git a/vendor/gopkg.in/coreos/go-oidc.v2/.travis.yml b/vendor/gopkg.in/coreos/go-oidc.v2/.travis.yml index 3fddaaac..6ff9dd96 100644 --- a/vendor/gopkg.in/coreos/go-oidc.v2/.travis.yml +++ b/vendor/gopkg.in/coreos/go-oidc.v2/.travis.yml @@ -1,13 +1,13 @@ language: go go: - - "1.12" - - "1.13" + - "1.9" + - "1.10" install: - go get -v -t github.com/coreos/go-oidc/... - go get golang.org/x/tools/cmd/cover - - go get golang.org/x/lint/golint + - go get github.com/golang/lint/golint script: - ./test diff --git a/vendor/gopkg.in/coreos/go-oidc.v2/oidc.go b/vendor/gopkg.in/coreos/go-oidc.v2/oidc.go index b39cb515..508b39d3 100644 --- a/vendor/gopkg.in/coreos/go-oidc.v2/oidc.go +++ b/vendor/gopkg.in/coreos/go-oidc.v2/oidc.go @@ -69,7 +69,6 @@ type Provider struct { authURL string tokenURL string userInfoURL string - algorithms []string // Raw claims returned by the server. rawClaims []byte @@ -83,27 +82,11 @@ type cachedKeys struct { } type providerJSON struct { - Issuer string `json:"issuer"` - AuthURL string `json:"authorization_endpoint"` - TokenURL string `json:"token_endpoint"` - JWKSURL string `json:"jwks_uri"` - UserInfoURL string `json:"userinfo_endpoint"` - Algorithms []string `json:"id_token_signing_alg_values_supported"` -} - -// supportedAlgorithms is a list of algorithms explicitly supported by this -// package. If a provider supports other algorithms, such as HS256 or none, -// those values won't be passed to the IDTokenVerifier. -var supportedAlgorithms = map[string]bool{ - RS256: true, - RS384: true, - RS512: true, - ES256: true, - ES384: true, - ES512: true, - PS256: true, - PS384: true, - PS512: true, + Issuer string `json:"issuer"` + AuthURL string `json:"authorization_endpoint"` + TokenURL string `json:"token_endpoint"` + JWKSURL string `json:"jwks_uri"` + UserInfoURL string `json:"userinfo_endpoint"` } // NewProvider uses the OpenID Connect discovery mechanism to construct a Provider. @@ -140,18 +123,11 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) { if p.Issuer != issuer { return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuer, p.Issuer) } - var algs []string - for _, a := range p.Algorithms { - if supportedAlgorithms[a] { - algs = append(algs, a) - } - } return &Provider{ issuer: p.Issuer, authURL: p.AuthURL, tokenURL: p.TokenURL, userInfoURL: p.UserInfoURL, - algorithms: algs, rawClaims: body, remoteKeySet: NewRemoteKeySet(ctx, p.JWKSURL), }, nil diff --git a/vendor/gopkg.in/coreos/go-oidc.v2/verify.go b/vendor/gopkg.in/coreos/go-oidc.v2/verify.go index d43f0662..ff7555db 100644 --- a/vendor/gopkg.in/coreos/go-oidc.v2/verify.go +++ b/vendor/gopkg.in/coreos/go-oidc.v2/verify.go @@ -79,9 +79,7 @@ type Config struct { ClientID string // If specified, only this set of algorithms may be used to sign the JWT. // - // If the IDTokenVerifier is created from a provider with (*Provider).Verifier, this - // defaults to the set of algorithms the provider supports. Otherwise this values - // defaults to RS256. + // Since many providers only support RS256, SupportedSigningAlgs defaults to this value. SupportedSigningAlgs []string // If true, no ClientID check performed. Must be true if ClientID field is empty. @@ -107,13 +105,6 @@ type Config struct { // The returned IDTokenVerifier is tied to the Provider's context and its behavior is // undefined once the Provider's context is canceled. func (p *Provider) Verifier(config *Config) *IDTokenVerifier { - if len(config.SupportedSigningAlgs) == 0 && len(p.algorithms) > 0 { - // Make a copy so we don't modify the config values. - cp := &Config{} - *cp = *config - cp.SupportedSigningAlgs = p.algorithms - config = cp - } return NewVerifier(p.issuer, p.remoteKeySet, config) } diff --git a/vendor/gopkg.in/square/go-jose.v2/.gitignore b/vendor/gopkg.in/square/go-jose.v2/.gitignore index 95a85158..5b4d73b6 100644 --- a/vendor/gopkg.in/square/go-jose.v2/.gitignore +++ b/vendor/gopkg.in/square/go-jose.v2/.gitignore @@ -5,4 +5,3 @@ *.pem *.cov jose-util/jose-util -jose-util.t.err \ No newline at end of file diff --git a/vendor/gopkg.in/square/go-jose.v2/.travis.yml b/vendor/gopkg.in/square/go-jose.v2/.travis.yml index 391b99a4..9ab2abf6 100644 --- a/vendor/gopkg.in/square/go-jose.v2/.travis.yml +++ b/vendor/gopkg.in/square/go-jose.v2/.travis.yml @@ -8,8 +8,8 @@ matrix: - go: tip go: -- '1.14.x' -- '1.15.x' +- '1.11.x' +- '1.12.x' - tip go_import_path: gopkg.in/square/go-jose.v2 @@ -26,8 +26,6 @@ before_install: - go get github.com/wadey/gocovmerge - go get github.com/mattn/goveralls - go get github.com/stretchr/testify/assert -- go get github.com/stretchr/testify/require -- go get github.com/google/go-cmp/cmp - go get golang.org/x/tools/cmd/cover || true - go get code.google.com/p/go.tools/cmd/cover || true - pip install cram --user @@ -37,9 +35,10 @@ script: - go test ./cipher -v -covermode=count -coverprofile=cipher/profile.cov - go test ./jwt -v -covermode=count -coverprofile=jwt/profile.cov - go test ./json -v # no coverage for forked encoding/json package -- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util +- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t - cd .. after_success: - gocovmerge *.cov */*.cov > merged.coverprofile - $HOME/gopath/bin/goveralls -coverprofile merged.coverprofile -service=travis-ci + diff --git a/vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go b/vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go index f6465c04..126b85ce 100644 --- a/vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go +++ b/vendor/gopkg.in/square/go-jose.v2/cipher/cbc_hmac.go @@ -150,7 +150,7 @@ func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte { return hmac.Sum(nil)[:ctx.authtagBytes] } -// resize ensures that the given slice has a capacity of at least n bytes. +// resize ensures the the given slice has a capacity of at least n bytes. // If the capacity of the slice is less than n, a new slice is allocated // and the existing data will be copied. func resize(in []byte, n uint64) (head, tail []byte) { diff --git a/vendor/gopkg.in/square/go-jose.v2/crypter.go b/vendor/gopkg.in/square/go-jose.v2/crypter.go index be7433e2..d24cabf6 100644 --- a/vendor/gopkg.in/square/go-jose.v2/crypter.go +++ b/vendor/gopkg.in/square/go-jose.v2/crypter.go @@ -216,7 +216,6 @@ func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *Encrypter if opts != nil { encrypter.compressionAlg = opts.Compression - encrypter.extraHeaders = opts.ExtraHeaders } for _, recipient := range rcpts { diff --git a/vendor/gopkg.in/square/go-jose.v2/encoding.go b/vendor/gopkg.in/square/go-jose.v2/encoding.go index 70f7385c..b9687c64 100644 --- a/vendor/gopkg.in/square/go-jose.v2/encoding.go +++ b/vendor/gopkg.in/square/go-jose.v2/encoding.go @@ -23,12 +23,13 @@ import ( "encoding/binary" "io" "math/big" - "strings" - "unicode" + "regexp" "gopkg.in/square/go-jose.v2/json" ) +var stripWhitespaceRegex = regexp.MustCompile("\\s") + // Helper function to serialize known-good objects. // Precondition: value is not a nil pointer. func mustSerializeJSON(value interface{}) []byte { @@ -55,14 +56,7 @@ func mustSerializeJSON(value interface{}) []byte { // Strip all newlines and whitespace func stripWhitespace(data string) string { - buf := strings.Builder{} - buf.Grow(len(data)) - for _, r := range data { - if !unicode.IsSpace(r) { - buf.WriteRune(r) - } - } - return buf.String() + return stripWhitespaceRegex.ReplaceAllString(data, "") } // Perform compression based on algorithm diff --git a/vendor/gopkg.in/square/go-jose.v2/json/decode.go b/vendor/gopkg.in/square/go-jose.v2/json/decode.go index 4dbc4146..37457e5a 100644 --- a/vendor/gopkg.in/square/go-jose.v2/json/decode.go +++ b/vendor/gopkg.in/square/go-jose.v2/json/decode.go @@ -13,7 +13,6 @@ import ( "encoding/base64" "errors" "fmt" - "math" "reflect" "runtime" "strconv" @@ -246,18 +245,6 @@ func isValidNumber(s string) bool { return s == "" } -type NumberUnmarshalType int - -const ( - // unmarshal a JSON number into an interface{} as a float64 - UnmarshalFloat NumberUnmarshalType = iota - // unmarshal a JSON number into an interface{} as a `json.Number` - UnmarshalJSONNumber - // unmarshal a JSON number into an interface{} as a int64 - // if value is an integer otherwise float64 - UnmarshalIntOrFloat -) - // decodeState represents the state while decoding a JSON value. type decodeState struct { data []byte @@ -265,7 +252,7 @@ type decodeState struct { scan scanner nextscan scanner // for calls to nextValue savedError error - numberType NumberUnmarshalType + useNumber bool } // errPhase is used for errors that should not happen unless @@ -736,38 +723,17 @@ func (d *decodeState) literal(v reflect.Value) { d.literalStore(d.data[start:d.off], v, false) } -// convertNumber converts the number literal s to a float64, int64 or a Number -// depending on d.numberDecodeType. +// convertNumber converts the number literal s to a float64 or a Number +// depending on the setting of d.useNumber. func (d *decodeState) convertNumber(s string) (interface{}, error) { - switch d.numberType { - - case UnmarshalJSONNumber: + if d.useNumber { return Number(s), nil - case UnmarshalIntOrFloat: - v, err := strconv.ParseInt(s, 10, 64) - if err == nil { - return v, nil - } - - // tries to parse integer number in scientific notation - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} - } - - // if it has no decimal value use int64 - if fi, fd := math.Modf(f); fd == 0.0 { - return int64(fi), nil - } - return f, nil - default: - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} - } - return f, nil } - + f, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0), int64(d.off)} + } + return f, nil } var numberType = reflect.TypeOf(Number("")) diff --git a/vendor/gopkg.in/square/go-jose.v2/json/stream.go b/vendor/gopkg.in/square/go-jose.v2/json/stream.go index 9b2b926b..8ddcf4d2 100644 --- a/vendor/gopkg.in/square/go-jose.v2/json/stream.go +++ b/vendor/gopkg.in/square/go-jose.v2/json/stream.go @@ -31,14 +31,9 @@ func NewDecoder(r io.Reader) *Decoder { return &Decoder{r: r} } -// Deprecated: Use `SetNumberType` instead // UseNumber causes the Decoder to unmarshal a number into an interface{} as a // Number instead of as a float64. -func (dec *Decoder) UseNumber() { dec.d.numberType = UnmarshalJSONNumber } - -// SetNumberType causes the Decoder to unmarshal a number into an interface{} as a -// Number, float64 or int64 depending on `t` enum value. -func (dec *Decoder) SetNumberType(t NumberUnmarshalType) { dec.d.numberType = t } +func (dec *Decoder) UseNumber() { dec.d.useNumber = true } // Decode reads the next JSON-encoded value from its // input and stores it in the value pointed to by v. diff --git a/vendor/gopkg.in/square/go-jose.v2/jwk.go b/vendor/gopkg.in/square/go-jose.v2/jwk.go index 222e260c..936a0202 100644 --- a/vendor/gopkg.in/square/go-jose.v2/jwk.go +++ b/vendor/gopkg.in/square/go-jose.v2/jwk.go @@ -17,20 +17,15 @@ package jose import ( - "bytes" "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rsa" - "crypto/sha1" - "crypto/sha256" "crypto/x509" "encoding/base64" - "encoding/hex" "errors" "fmt" "math/big" - "net/url" "reflect" "strings" @@ -62,31 +57,16 @@ type rawJSONWebKey struct { Dq *byteBuffer `json:"dq,omitempty"` Qi *byteBuffer `json:"qi,omitempty"` // Certificates - X5c []string `json:"x5c,omitempty"` - X5u *url.URL `json:"x5u,omitempty"` - X5tSHA1 string `json:"x5t,omitempty"` - X5tSHA256 string `json:"x5t#S256,omitempty"` + X5c []string `json:"x5c,omitempty"` } // JSONWebKey represents a public or private key in JWK format. type JSONWebKey struct { - // Cryptographic key, can be a symmetric or asymmetric key. - Key interface{} - // Key identifier, parsed from `kid` header. - KeyID string - // Key algorithm, parsed from `alg` header. - Algorithm string - // Key use, parsed from `use` header. - Use string - - // X.509 certificate chain, parsed from `x5c` header. + Key interface{} Certificates []*x509.Certificate - // X.509 certificate URL, parsed from `x5u` header. - CertificatesURL *url.URL - // X.509 certificate thumbprint (SHA-1), parsed from `x5t` header. - CertificateThumbprintSHA1 []byte - // X.509 certificate thumbprint (SHA-256), parsed from `x5t#S256` header. - CertificateThumbprintSHA256 []byte + KeyID string + Algorithm string + Use string } // MarshalJSON serializes the given key to its JSON representation. @@ -125,39 +105,6 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) { raw.X5c = append(raw.X5c, base64.StdEncoding.EncodeToString(cert.Raw)) } - x5tSHA1Len := len(k.CertificateThumbprintSHA1) - x5tSHA256Len := len(k.CertificateThumbprintSHA256) - if x5tSHA1Len > 0 { - if x5tSHA1Len != sha1.Size { - return nil, fmt.Errorf("square/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)", sha1.Size, x5tSHA1Len) - } - raw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1) - } - if x5tSHA256Len > 0 { - if x5tSHA256Len != sha256.Size { - return nil, fmt.Errorf("square/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)", sha256.Size, x5tSHA256Len) - } - raw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256) - } - - // If cert chain is attached (as opposed to being behind a URL), check the - // keys thumbprints to make sure they match what is expected. This is to - // ensure we don't accidentally produce a JWK with semantically inconsistent - // data in the headers. - if len(k.Certificates) > 0 { - expectedSHA1 := sha1.Sum(k.Certificates[0].Raw) - expectedSHA256 := sha256.Sum256(k.Certificates[0].Raw) - - if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) { - return nil, errors.New("square/go-jose: invalid SHA-1 thumbprint, does not match cert chain") - } - if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) { - return nil, errors.New("square/go-jose: invalid or SHA-256 thumbprint, does not match cert chain") - } - } - - raw.X5u = k.CertificatesURL - return json.Marshal(raw) } @@ -169,61 +116,28 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { return err } - certs, err := parseCertificateChain(raw.X5c) - if err != nil { - return fmt.Errorf("square/go-jose: failed to unmarshal x5c field: %s", err) - } - var key interface{} - var certPub interface{} - var keyPub interface{} - - if len(certs) > 0 { - // We need to check that leaf public key matches the key embedded in this - // JWK, as required by the standard (see RFC 7517, Section 4.7). Otherwise - // the JWK parsed could be semantically invalid. Technically, should also - // check key usage fields and other extensions on the cert here, but the - // standard doesn't exactly explain how they're supposed to map from the - // JWK representation to the X.509 extensions. - certPub = certs[0].PublicKey - } - switch raw.Kty { case "EC": if raw.D != nil { key, err = raw.ecPrivateKey() - if err == nil { - keyPub = key.(*ecdsa.PrivateKey).Public() - } } else { key, err = raw.ecPublicKey() - keyPub = key } case "RSA": if raw.D != nil { key, err = raw.rsaPrivateKey() - if err == nil { - keyPub = key.(*rsa.PrivateKey).Public() - } } else { key, err = raw.rsaPublicKey() - keyPub = key } case "oct": - if certPub != nil { - return errors.New("square/go-jose: invalid JWK, found 'oct' (symmetric) key with cert chain") - } key, err = raw.symmetricKey() case "OKP": if raw.Crv == "Ed25519" && raw.X != nil { if raw.D != nil { key, err = raw.edPrivateKey() - if err == nil { - keyPub = key.(ed25519.PrivateKey).Public() - } } else { key, err = raw.edPublicKey() - keyPub = key } } else { err = fmt.Errorf("square/go-jose: unknown curve %s'", raw.Crv) @@ -232,78 +146,12 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { err = fmt.Errorf("square/go-jose: unknown json web key type '%s'", raw.Kty) } - if err != nil { - return - } + if err == nil { + *k = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use} - if certPub != nil && keyPub != nil { - if !reflect.DeepEqual(certPub, keyPub) { - return errors.New("square/go-jose: invalid JWK, public keys in key and x5c fields do not match") - } - } - - *k = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use, Certificates: certs} - - k.CertificatesURL = raw.X5u - - // x5t parameters are base64url-encoded SHA thumbprints - // See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8 - x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1) - if err != nil { - return errors.New("square/go-jose: invalid JWK, x5t header has invalid encoding") - } - - // RFC 7517, Section 4.8 is ambiguous as to whether the digest output should be byte or hex, - // for this reason, after base64 decoding, if the size is sha1.Size it's likely that the value is a byte encoded - // checksum so we skip this. Otherwise if the checksum was hex encoded we expect a 40 byte sized array so we'll - // try to hex decode it. When Marshalling this value we'll always use a base64 encoded version of byte format checksum. - if len(x5tSHA1bytes) == 2*sha1.Size { - hx, err := hex.DecodeString(string(x5tSHA1bytes)) + k.Certificates, err = parseCertificateChain(raw.X5c) if err != nil { - return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t: %v", err) - - } - x5tSHA1bytes = hx - } - - k.CertificateThumbprintSHA1 = x5tSHA1bytes - - x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256) - if err != nil { - return errors.New("square/go-jose: invalid JWK, x5t#S256 header has invalid encoding") - } - - if len(x5tSHA256bytes) == 2*sha256.Size { - hx256, err := hex.DecodeString(string(x5tSHA256bytes)) - if err != nil { - return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t#S256: %v", err) - } - x5tSHA256bytes = hx256 - } - - k.CertificateThumbprintSHA256 = x5tSHA256bytes - - x5tSHA1Len := len(k.CertificateThumbprintSHA1) - x5tSHA256Len := len(k.CertificateThumbprintSHA256) - if x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size { - return errors.New("square/go-jose: invalid JWK, x5t header is of incorrect size") - } - if x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size { - return errors.New("square/go-jose: invalid JWK, x5t#S256 header is of incorrect size") - } - - // If certificate chain *and* thumbprints are set, verify correctness. - if len(k.Certificates) > 0 { - leaf := k.Certificates[0] - sha1sum := sha1.Sum(leaf.Raw) - sha256sum := sha256.Sum256(leaf.Raw) - - if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(sha1sum[:], k.CertificateThumbprintSHA1) { - return errors.New("square/go-jose: invalid JWK, x5c thumbprint does not match x5t value") - } - - if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(sha256sum[:], k.CertificateThumbprintSHA256) { - return errors.New("square/go-jose: invalid JWK, x5c thumbprint does not match x5t#S256 value") + return fmt.Errorf("failed to unmarshal x5c field: %s", err) } } @@ -332,7 +180,7 @@ func (s *JSONWebKeySet) Key(kid string) []JSONWebKey { const rsaThumbprintTemplate = `{"e":"%s","kty":"RSA","n":"%s"}` const ecThumbprintTemplate = `{"crv":"%s","kty":"EC","x":"%s","y":"%s"}` -const edThumbprintTemplate = `{"crv":"%s","kty":"OKP","x":"%s"}` +const edThumbprintTemplate = `{"crv":"%s","kty":"OKP",x":"%s"}` func ecThumbprintInput(curve elliptic.Curve, x, y *big.Int) (string, error) { coordLength := curveSize(curve) @@ -406,7 +254,7 @@ func (k *JSONWebKey) IsPublic() bool { } } -// Public creates JSONWebKey with corresponding public key if JWK represents asymmetric private key. +// Public creates JSONWebKey with corresponding publik key if JWK represents asymmetric private key. func (k *JSONWebKey) Public() JSONWebKey { if k.IsPublic() { return *k diff --git a/vendor/gopkg.in/square/go-jose.v2/jws.go b/vendor/gopkg.in/square/go-jose.v2/jws.go index 7e261f93..e52a4766 100644 --- a/vendor/gopkg.in/square/go-jose.v2/jws.go +++ b/vendor/gopkg.in/square/go-jose.v2/jws.go @@ -102,14 +102,14 @@ func (sig Signature) mergedHeaders() rawHeader { } // Compute data to be signed -func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature) ([]byte, error) { +func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature) []byte { var authData bytes.Buffer protectedHeader := new(rawHeader) if signature.original != nil && signature.original.Protected != nil { if err := json.Unmarshal(signature.original.Protected.bytes(), protectedHeader); err != nil { - return nil, err + panic(err) } authData.WriteString(signature.original.Protected.base64()) } else if signature.protected != nil { @@ -134,7 +134,7 @@ func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature authData.Write(payload) } - return authData.Bytes(), nil + return authData.Bytes() } // parseSignedFull parses a message in full format. diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/builder.go b/vendor/gopkg.in/square/go-jose.v2/jwt/builder.go deleted file mode 100644 index 3afa9030..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/builder.go +++ /dev/null @@ -1,334 +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 ( - "bytes" - "reflect" - - "gopkg.in/square/go-jose.v2/json" - - "gopkg.in/square/go-jose.v2" -) - -// Builder is a utility for making JSON Web Tokens. Calls can be chained, and -// errors are accumulated until the final call to CompactSerialize/FullSerialize. -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 - // struct field tags to specify the name for the JSON key to be used when - // serializing. - Claims(i interface{}) Builder - // Token builds a JSONWebToken from provided data. - Token() (*JSONWebToken, error) - // FullSerialize serializes a token using the full serialization format. - FullSerialize() (string, error) - // CompactSerialize serializes a token using the compact serialization format. - CompactSerialize() (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. -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 - // struct field tags to specify the name for the JSON key to be used when - // serializing. - Claims(i interface{}) NestedBuilder - // Token builds a NestedJSONWebToken from provided data. - Token() (*NestedJSONWebToken, error) - // FullSerialize serializes a token using the full serialization format. - FullSerialize() (string, error) - // CompactSerialize serializes a token using the compact serialization format. - CompactSerialize() (string, error) -} - -type builder struct { - payload map[string]interface{} - err error -} - -type signedBuilder struct { - builder - sig jose.Signer -} - -type encryptedBuilder struct { - builder - enc jose.Encrypter -} - -type nestedBuilder struct { - builder - sig jose.Signer - enc jose.Encrypter -} - -// Signed creates builder for signed tokens. -func Signed(sig jose.Signer) Builder { - return &signedBuilder{ - sig: sig, - } -} - -// Encrypted creates builder for encrypted tokens. -func Encrypted(enc jose.Encrypter) Builder { - return &encryptedBuilder{ - enc: enc, - } -} - -// SignedAndEncrypted creates builder for signed-then-encrypted tokens. -// ErrInvalidContentType will be returned if encrypter doesn't have JWT content type. -func SignedAndEncrypted(sig jose.Signer, enc jose.Encrypter) NestedBuilder { - if contentType, _ := enc.Options().ExtraHeaders[jose.HeaderContentType].(jose.ContentType); contentType != "JWT" { - return &nestedBuilder{ - builder: builder{ - err: ErrInvalidContentType, - }, - } - } - return &nestedBuilder{ - sig: sig, - enc: enc, - } -} - -func (b builder) claims(i interface{}) builder { - if b.err != nil { - return b - } - - m, ok := i.(map[string]interface{}) - switch { - case ok: - return b.merge(m) - case reflect.Indirect(reflect.ValueOf(i)).Kind() == reflect.Struct: - m, err := normalize(i) - if err != nil { - return builder{ - err: err, - } - } - return b.merge(m) - default: - return builder{ - err: ErrInvalidClaims, - } - } -} - -func normalize(i interface{}) (map[string]interface{}, error) { - m := make(map[string]interface{}) - - raw, err := json.Marshal(i) - if err != nil { - return nil, err - } - - d := json.NewDecoder(bytes.NewReader(raw)) - d.SetNumberType(json.UnmarshalJSONNumber) - - if err := d.Decode(&m); err != nil { - return nil, err - } - - return m, nil -} - -func (b *builder) merge(m map[string]interface{}) builder { - p := make(map[string]interface{}) - for k, v := range b.payload { - p[k] = v - } - for k, v := range m { - p[k] = v - } - - return builder{ - payload: p, - } -} - -func (b *builder) token(p func(interface{}) ([]byte, error), h []jose.Header) (*JSONWebToken, error) { - return &JSONWebToken{ - payload: p, - Headers: h, - }, nil -} - -func (b *signedBuilder) Claims(i interface{}) Builder { - return &signedBuilder{ - builder: b.builder.claims(i), - sig: b.sig, - } -} - -func (b *signedBuilder) Token() (*JSONWebToken, error) { - sig, err := b.sign() - if err != nil { - return nil, err - } - - h := make([]jose.Header, len(sig.Signatures)) - for i, v := range sig.Signatures { - h[i] = v.Header - } - - return b.builder.token(sig.Verify, h) -} - -func (b *signedBuilder) CompactSerialize() (string, error) { - sig, err := b.sign() - if err != nil { - return "", err - } - - 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 - } - - p, err := json.Marshal(b.payload) - if err != nil { - return nil, err - } - - return b.sig.Sign(p) -} - -func (b *encryptedBuilder) Claims(i interface{}) Builder { - return &encryptedBuilder{ - builder: b.builder.claims(i), - enc: b.enc, - } -} - -func (b *encryptedBuilder) CompactSerialize() (string, error) { - enc, err := b.encrypt() - if err != nil { - return "", err - } - - 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 { - return nil, err - } - - return b.builder.token(enc.Decrypt, []jose.Header{enc.Header}) -} - -func (b *encryptedBuilder) encrypt() (*jose.JSONWebEncryption, error) { - if b.err != nil { - return nil, b.err - } - - p, err := json.Marshal(b.payload) - if err != nil { - return nil, err - } - - return b.enc.Encrypt(p) -} - -func (b *nestedBuilder) Claims(i interface{}) NestedBuilder { - return &nestedBuilder{ - builder: b.builder.claims(i), - sig: b.sig, - enc: b.enc, - } -} - -func (b *nestedBuilder) Token() (*NestedJSONWebToken, error) { - enc, err := b.signAndEncrypt() - if err != nil { - return nil, err - } - - return &NestedJSONWebToken{ - enc: enc, - Headers: []jose.Header{enc.Header}, - }, nil -} - -func (b *nestedBuilder) CompactSerialize() (string, error) { - enc, err := b.signAndEncrypt() - if err != nil { - return "", err - } - - return enc.CompactSerialize() -} - -func (b *nestedBuilder) FullSerialize() (string, error) { - enc, err := b.signAndEncrypt() - if err != nil { - return "", err - } - - return enc.FullSerialize(), nil -} - -func (b *nestedBuilder) signAndEncrypt() (*jose.JSONWebEncryption, error) { - if b.err != nil { - return nil, b.err - } - - p, err := json.Marshal(b.payload) - if err != nil { - return nil, err - } - - sig, err := b.sig.Sign(p) - if err != nil { - return nil, err - } - - p2, err := sig.CompactSerialize() - if err != nil { - return nil, err - } - - return b.enc.Encrypt([]byte(p2)) -} diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/claims.go b/vendor/gopkg.in/square/go-jose.v2/jwt/claims.go deleted file mode 100644 index 5f40ef3b..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/claims.go +++ /dev/null @@ -1,121 +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 ( - "strconv" - "time" - - "gopkg.in/square/go-jose.v2/json" -) - -// Claims represents public claim values (as specified in RFC 7519). -type Claims struct { - Issuer string `json:"iss,omitempty"` - Subject string `json:"sub,omitempty"` - Audience Audience `json:"aud,omitempty"` - Expiry *NumericDate `json:"exp,omitempty"` - NotBefore *NumericDate `json:"nbf,omitempty"` - IssuedAt *NumericDate `json:"iat,omitempty"` - ID string `json:"jti,omitempty"` -} - -// NumericDate represents date and time as the number of seconds since the -// epoch, ignoring leap seconds. Non-integer values can be represented -// in the serialized format, but we round to the nearest second. -// See RFC7519 Section 2: https://tools.ietf.org/html/rfc7519#section-2 -type NumericDate int64 - -// NewNumericDate constructs NumericDate from time.Time value. -func NewNumericDate(t time.Time) *NumericDate { - if t.IsZero() { - return nil - } - - // While RFC 7519 technically states that NumericDate values may be - // non-integer values, we don't bother serializing timestamps in - // claims with sub-second accurancy and just round to the nearest - // second instead. Not convined sub-second accuracy is useful here. - out := NumericDate(t.Unix()) - return &out -} - -// MarshalJSON serializes the given NumericDate into its JSON representation. -func (n NumericDate) MarshalJSON() ([]byte, error) { - return []byte(strconv.FormatInt(int64(n), 10)), nil -} - -// UnmarshalJSON reads a date from its JSON representation. -func (n *NumericDate) UnmarshalJSON(b []byte) error { - s := string(b) - - f, err := strconv.ParseFloat(s, 64) - if err != nil { - return ErrUnmarshalNumericDate - } - - *n = NumericDate(f) - return nil -} - -// Time returns time.Time representation of NumericDate. -func (n *NumericDate) Time() time.Time { - if n == nil { - return time.Time{} - } - return time.Unix(int64(*n), 0) -} - -// Audience represents the recipients that the token is intended for. -type Audience []string - -// UnmarshalJSON reads an audience from its JSON representation. -func (s *Audience) UnmarshalJSON(b []byte) error { - var v interface{} - if err := json.Unmarshal(b, &v); err != nil { - return err - } - - switch v := v.(type) { - case string: - *s = []string{v} - case []interface{}: - a := make([]string, len(v)) - for i, e := range v { - s, ok := e.(string) - if !ok { - return ErrUnmarshalAudience - } - a[i] = s - } - *s = a - default: - return ErrUnmarshalAudience - } - - return nil -} - -func (s Audience) Contains(v string) bool { - for _, a := range s { - if a == v { - return true - } - } - return false -} diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/doc.go b/vendor/gopkg.in/square/go-jose.v2/jwt/doc.go deleted file mode 100644 index 4cf97b54..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -/*- - * Copyright 2017 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 provides an implementation of the JSON Web Token standard. - -*/ -package jwt diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/errors.go b/vendor/gopkg.in/square/go-jose.v2/jwt/errors.go deleted file mode 100644 index 09f76ae4..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/errors.go +++ /dev/null @@ -1,53 +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 "errors" - -// ErrUnmarshalAudience indicates that aud claim could not be unmarshalled. -var ErrUnmarshalAudience = errors.New("square/go-jose/jwt: expected string or array value to unmarshal to Audience") - -// ErrUnmarshalNumericDate indicates that JWT NumericDate could not be unmarshalled. -var ErrUnmarshalNumericDate = errors.New("square/go-jose/jwt: expected number value to unmarshal NumericDate") - -// ErrInvalidClaims indicates that given claims have invalid type. -var ErrInvalidClaims = errors.New("square/go-jose/jwt: expected claims to be value convertible into JSON object") - -// ErrInvalidIssuer indicates invalid iss claim. -var ErrInvalidIssuer = errors.New("square/go-jose/jwt: validation failed, invalid issuer claim (iss)") - -// ErrInvalidSubject indicates invalid sub claim. -var ErrInvalidSubject = errors.New("square/go-jose/jwt: validation failed, invalid subject claim (sub)") - -// ErrInvalidAudience indicated invalid aud claim. -var ErrInvalidAudience = errors.New("square/go-jose/jwt: validation failed, invalid audience claim (aud)") - -// ErrInvalidID indicates invalid jti claim. -var ErrInvalidID = errors.New("square/go-jose/jwt: validation failed, invalid ID claim (jti)") - -// ErrNotValidYet indicates that token is used before time indicated in nbf claim. -var ErrNotValidYet = errors.New("square/go-jose/jwt: validation failed, token not valid yet (nbf)") - -// ErrExpired indicates that token is used after expiry time indicated in exp claim. -var ErrExpired = errors.New("square/go-jose/jwt: validation failed, token is expired (exp)") - -// ErrIssuedInTheFuture indicates that the iat field is in the future. -var ErrIssuedInTheFuture = errors.New("square/go-jose/jwt: validation field, token issued in the future (iat)") - -// ErrInvalidContentType indicates that token requires JWT cty header. -var ErrInvalidContentType = errors.New("square/go-jose/jwt: expected content type to be JWT (cty header)") diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/jwt.go b/vendor/gopkg.in/square/go-jose.v2/jwt/jwt.go deleted file mode 100644 index 47498840..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/jwt.go +++ /dev/null @@ -1,169 +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 "gopkg.in/square/go-jose.v2" - "gopkg.in/square/go-jose.v2/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 { - payloadKey := tryJWKS(t.Headers, key) - - b, err := t.payload(payloadKey) - 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("square/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) { - key := tryJWKS(t.Headers, decryptionKey) - - b, err := t.enc.Decrypt(key) - 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 -} - -func tryJWKS(headers []jose.Header, key interface{}) interface{} { - var jwks jose.JSONWebKeySet - - switch jwksType := key.(type) { - case *jose.JSONWebKeySet: - jwks = *jwksType - case jose.JSONWebKeySet: - jwks = jwksType - default: - return key - } - - var kid string - for _, header := range headers { - if header.KeyID != "" { - kid = header.KeyID - break - } - } - - if kid == "" { - return key - } - - keys := jwks.Key(kid) - if len(keys) == 0 { - return key - } - - return keys[0].Key -} diff --git a/vendor/gopkg.in/square/go-jose.v2/jwt/validation.go b/vendor/gopkg.in/square/go-jose.v2/jwt/validation.go deleted file mode 100644 index 6f3ff4e8..00000000 --- a/vendor/gopkg.in/square/go-jose.v2/jwt/validation.go +++ /dev/null @@ -1,114 +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 "time" - -const ( - // DefaultLeeway defines the default leeway for matching NotBefore/Expiry claims. - DefaultLeeway = 1.0 * time.Minute -) - -// Expected defines values used for protected claims validation. -// If field has zero value then validation is skipped. -type Expected struct { - // Issuer matches the "iss" claim exactly. - Issuer string - // Subject matches the "sub" claim exactly. - Subject string - // Audience matches the values in "aud" claim, regardless of their order. - Audience Audience - // ID matches the "jti" claim exactly. - ID string - // Time matches the "exp", "nbf" and "iat" claims with leeway. - Time time.Time -} - -// WithTime copies expectations with new time. -func (e Expected) WithTime(t time.Time) Expected { - e.Time = t - return e -} - -// Validate checks claims in a token against expected values. -// A default leeway value of one minute is used to compare time values. -// -// The default leeway will cause the token to be deemed valid until one -// minute after the expiration time. If you're a server application that -// wants to give an extra minute to client tokens, use this -// function. If you're a client application wondering if the server -// will accept your token, use ValidateWithLeeway with a leeway <=0, -// otherwise this function might make you think a token is valid when -// it is not. -func (c Claims) Validate(e Expected) error { - return c.ValidateWithLeeway(e, DefaultLeeway) -} - -// ValidateWithLeeway checks claims in a token against expected values. A -// custom leeway may be specified for comparing time values. You may pass a -// zero value to check time values with no leeway, but you should not that -// numeric date values are rounded to the nearest second and sub-second -// precision is not supported. -// -// The leeway gives some extra time to the token from the server's -// point of view. That is, if the token is expired, ValidateWithLeeway -// will still accept the token for 'leeway' amount of time. This fails -// if you're using this function to check if a server will accept your -// token, because it will think the token is valid even after it -// expires. So if you're a client validating if the token is valid to -// be submitted to a server, use leeway <=0, if you're a server -// validation a token, use leeway >=0. -func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error { - if e.Issuer != "" && e.Issuer != c.Issuer { - return ErrInvalidIssuer - } - - if e.Subject != "" && e.Subject != c.Subject { - return ErrInvalidSubject - } - - if e.ID != "" && e.ID != c.ID { - return ErrInvalidID - } - - if len(e.Audience) != 0 { - for _, v := range e.Audience { - if !c.Audience.Contains(v) { - return ErrInvalidAudience - } - } - } - - if !e.Time.IsZero() { - if c.NotBefore != nil && e.Time.Add(leeway).Before(c.NotBefore.Time()) { - return ErrNotValidYet - } - - if c.Expiry != nil && e.Time.Add(-leeway).After(c.Expiry.Time()) { - return ErrExpired - } - - // IssuedAt is optional but cannot be in the future. This is not required by the RFC, but - // something is misconfigured if this happens and we should not trust it. - if c.IssuedAt != nil && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { - return ErrIssuedInTheFuture - } - } - - return nil -} diff --git a/vendor/gopkg.in/square/go-jose.v2/opaque.go b/vendor/gopkg.in/square/go-jose.v2/opaque.go index fc3e8d2e..df747f99 100644 --- a/vendor/gopkg.in/square/go-jose.v2/opaque.go +++ b/vendor/gopkg.in/square/go-jose.v2/opaque.go @@ -17,7 +17,7 @@ package jose // OpaqueSigner is an interface that supports signing payloads with opaque -// private key(s). Private key operations performed by implementers may, for +// private key(s). Private key operations preformed by implementors may, for // example, occur in a hardware module. An OpaqueSigner may rotate signing keys // transparently to the user of this interface. type OpaqueSigner interface { diff --git a/vendor/gopkg.in/square/go-jose.v2/shared.go b/vendor/gopkg.in/square/go-jose.v2/shared.go index f72e5a53..f8438641 100644 --- a/vendor/gopkg.in/square/go-jose.v2/shared.go +++ b/vendor/gopkg.in/square/go-jose.v2/shared.go @@ -183,7 +183,7 @@ type Header struct { // Unverified certificate chain parsed from x5c header. certificates []*x509.Certificate - // Any headers not recognised above get unmarshalled + // Any headers not recognised above get unmarshaled // from JSON in a generic manner and placed in this map. ExtraHeaders map[HeaderKey]interface{} } @@ -295,12 +295,12 @@ func (parsed rawHeader) getAPV() (*byteBuffer, error) { return parsed.getByteBuffer(headerAPV) } -// getIV extracts parsed "iv" from the raw JSON. +// getIV extracts parsed "iv" frpom the raw JSON. func (parsed rawHeader) getIV() (*byteBuffer, error) { return parsed.getByteBuffer(headerIV) } -// getTag extracts parsed "tag" from the raw JSON. +// getTag extracts parsed "tag" frpom the raw JSON. func (parsed rawHeader) getTag() (*byteBuffer, error) { return parsed.getByteBuffer(headerTag) } diff --git a/vendor/gopkg.in/square/go-jose.v2/signing.go b/vendor/gopkg.in/square/go-jose.v2/signing.go index bad820ce..664a51cc 100644 --- a/vendor/gopkg.in/square/go-jose.v2/signing.go +++ b/vendor/gopkg.in/square/go-jose.v2/signing.go @@ -370,11 +370,7 @@ func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey inter } } - input, err := obj.computeAuthData(payload, &signature) - if err != nil { - return ErrCryptoFailure - } - + input := obj.computeAuthData(payload, &signature) alg := headers.getSignatureAlgorithm() err = verifier.verifyPayload(input, signature.Signature, alg) if err == nil { @@ -425,11 +421,7 @@ outer: } } - input, err := obj.computeAuthData(payload, &signature) - if err != nil { - continue - } - + input := obj.computeAuthData(payload, &signature) alg := headers.getSignatureAlgorithm() err = verifier.verifyPayload(input, signature.Signature, alg) if err == nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 3b296241..648e7327 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -62,6 +62,9 @@ github.com/coredns/coredns/plugin/pkg/transport github.com/coredns/coredns/plugin/pkg/uniq github.com/coredns/coredns/plugin/test github.com/coredns/coredns/request +# github.com/coreos/go-oidc v0.0.0-20171002155002-a93f71fdfe73 +## explicit +github.com/coreos/go-oidc/jose # github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf ## explicit github.com/coreos/go-systemd/daemon @@ -527,18 +530,17 @@ google.golang.org/protobuf/types/descriptorpb google.golang.org/protobuf/types/known/anypb google.golang.org/protobuf/types/known/durationpb google.golang.org/protobuf/types/known/timestamppb -# gopkg.in/coreos/go-oidc.v2 v2.2.1 +# gopkg.in/coreos/go-oidc.v2 v2.1.0 ## explicit gopkg.in/coreos/go-oidc.v2 # gopkg.in/natefinch/lumberjack.v2 v2.0.0 ## explicit gopkg.in/natefinch/lumberjack.v2 -# gopkg.in/square/go-jose.v2 v2.6.0 +# gopkg.in/square/go-jose.v2 v2.4.0 ## explicit gopkg.in/square/go-jose.v2 gopkg.in/square/go-jose.v2/cipher gopkg.in/square/go-jose.v2/json -gopkg.in/square/go-jose.v2/jwt # gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 ## explicit gopkg.in/tomb.v1