rebase: bump github.com/hashicorp/vault/api from 1.9.1 to 1.9.2

Bumps [github.com/hashicorp/vault/api](https://github.com/hashicorp/vault) from 1.9.1 to 1.9.2.
- [Release notes](https://github.com/hashicorp/vault/releases)
- [Changelog](https://github.com/hashicorp/vault/blob/main/CHANGELOG.md)
- [Commits](https://github.com/hashicorp/vault/compare/v1.9.1...v1.9.2)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/vault/api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] 2023-06-01 15:49:07 +00:00 committed by mergify[bot]
parent 40c1d32518
commit 57a4fcbaa3
44 changed files with 432 additions and 341 deletions

4
go.mod
View File

@ -18,7 +18,7 @@ require (
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/hashicorp/vault/api v1.9.1 github.com/hashicorp/vault/api v1.9.2
github.com/kubernetes-csi/csi-lib-utils v0.13.0 github.com/kubernetes-csi/csi-lib-utils v0.13.0
github.com/kubernetes-csi/external-snapshotter/client/v6 v6.2.0 github.com/kubernetes-csi/external-snapshotter/client/v6 v6.2.0
github.com/libopenstorage/secrets v0.0.0-20210908194121-a1d19aa9713a github.com/libopenstorage/secrets v0.0.0-20210908194121-a1d19aa9713a
@ -72,6 +72,7 @@ require (
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gemalto/flume v0.13.0 // indirect github.com/gemalto/flume v0.13.0 // indirect
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect
@ -149,7 +150,6 @@ require (
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.26.2 // indirect k8s.io/apiextensions-apiserver v0.26.2 // indirect

8
go.sum
View File

@ -343,6 +343,8 @@ github.com/go-errors/errors v1.4.1 h1:IvVlgbzSsaUNudsw5dcXSzF3EWyXTi5XrAdngnuhRy
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@ -678,8 +680,8 @@ github.com/hashicorp/vault/api v1.0.5-0.20191122173911-80fcc7907c78/go.mod h1:Uf
github.com/hashicorp/vault/api v1.0.5-0.20200215224050-f6547fa8e820/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o= github.com/hashicorp/vault/api v1.0.5-0.20200215224050-f6547fa8e820/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o=
github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o= github.com/hashicorp/vault/api v1.0.5-0.20200317185738-82f498082f02/go.mod h1:3f12BMfgDGjTsTtIUj+ZKZwSobQpZtYGFIEehOv5z1o=
github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk= github.com/hashicorp/vault/api v1.0.5-0.20200902155336-f9d5ce5a171a/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk=
github.com/hashicorp/vault/api v1.9.1 h1:LtY/I16+5jVGU8rufyyAkwopgq/HpUnxFBg+QLOAV38= github.com/hashicorp/vault/api v1.9.2 h1:YjkZLJ7K3inKgMZ0wzCU9OHqc+UqMQyXsPXnf3Cl2as=
github.com/hashicorp/vault/api v1.9.1/go.mod h1:78kktNcQYbBGSrOjQfHjXN32OhhxXnbYl3zxpd2uPUs= github.com/hashicorp/vault/api v1.9.2/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
github.com/hashicorp/vault/sdk v0.1.8/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU= github.com/hashicorp/vault/sdk v0.1.8/go.mod h1:tHZfc6St71twLizWNHvnnbiGFo1aq0eD2jGPLtP8kAU=
github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/vault/sdk v0.1.14-0.20191108161836-82f2b5571044/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU= github.com/hashicorp/vault/sdk v0.1.14-0.20191108161836-82f2b5571044/go.mod h1:PcekaFGiPJyHnFy+NZhP6ll650zEw51Ag7g/YEa+EOU=
@ -1200,6 +1202,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@ -1743,7 +1746,6 @@ gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76
gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= 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/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -1,8 +1,2 @@
*~
.*.swp
*.out
*.test
*.pem
*.cov
jose-util/jose-util jose-util/jose-util
jose-util.t.err jose-util.t.err

53
vendor/github.com/go-jose/go-jose/v3/.golangci.yml generated vendored Normal file
View File

@ -0,0 +1,53 @@
# https://github.com/golangci/golangci-lint
run:
skip-files:
- doc_test.go
modules-download-mode: readonly
linters:
enable-all: true
disable:
- gochecknoglobals
- goconst
- lll
- maligned
- nakedret
- scopelint
- unparam
- funlen # added in 1.18 (requires go-jose changes before it can be enabled)
linters-settings:
gocyclo:
min-complexity: 35
issues:
exclude-rules:
- text: "don't use ALL_CAPS in Go names"
linters:
- golint
- text: "hardcoded credentials"
linters:
- gosec
- text: "weak cryptographic primitive"
linters:
- gosec
- path: json/
linters:
- dupl
- errcheck
- gocritic
- gocyclo
- golint
- govet
- ineffassign
- staticcheck
- structcheck
- stylecheck
- unused
- path: _test\.go
linters:
- scopelint
- path: jwk.go
linters:
- gocyclo

33
vendor/github.com/go-jose/go-jose/v3/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,33 @@
language: go
matrix:
fast_finish: true
allow_failures:
- go: tip
go:
- "1.13.x"
- "1.14.x"
- tip
before_script:
- export PATH=$HOME/.local/bin:$PATH
before_install:
- go get -u github.com/mattn/goveralls github.com/wadey/gocovmerge
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
- pip install cram --user
script:
- go test -v -covermode=count -coverprofile=profile.cov .
- go test -v -covermode=count -coverprofile=cryptosigner/profile.cov ./cryptosigner
- go test -v -covermode=count -coverprofile=cipher/profile.cov ./cipher
- go test -v -covermode=count -coverprofile=jwt/profile.cov ./jwt
- go test -v ./json # no coverage for forked encoding/json package
- golangci-lint run
- cd jose-util && go build && PATH=$PWD:$PATH cram -v jose-util.t # cram tests jose-util
- cd ..
after_success:
- gocovmerge *.cov */*.cov > merged.coverprofile
- goveralls -coverprofile merged.coverprofile -service=travis-ci

View File

@ -9,6 +9,7 @@ sure all tests pass by running `go test`, and format your code with `go fmt`.
We also recommend using `golint` and `errcheck`. We also recommend using `golint` and `errcheck`.
Before your code can be accepted into the project you must also sign the Before your code can be accepted into the project you must also sign the
[Individual Contributor License Agreement][1]. Individual Contributor License Agreement. We use [cla-assistant.io][1] and you
will be prompted to sign once a pull request is opened.
[1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1 [1]: https://cla-assistant.io/

View File

@ -1,10 +1,10 @@
# Go JOSE # Go JOSE
[![godoc](http://img.shields.io/badge/godoc-version_1-blue.svg?style=flat)](https://godoc.org/gopkg.in/square/go-jose.v1) [![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2)
[![godoc](http://img.shields.io/badge/godoc-version_2-blue.svg?style=flat)](https://godoc.org/gopkg.in/square/go-jose.v2) [![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt)
[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/square/go-jose/master/LICENSE) [![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
[![build](https://travis-ci.org/square/go-jose.svg?branch=v2)](https://travis-ci.org/square/go-jose) [![build](https://travis-ci.org/go-jose/go-jose.svg?branch=master)](https://travis-ci.org/go-jose/go-jose)
[![coverage](https://coveralls.io/repos/github/square/go-jose/badge.svg?branch=v2)](https://coveralls.io/r/square/go-jose) [![coverage](https://coveralls.io/repos/github/go-jose/go-jose/badge.svg?branch=master)](https://coveralls.io/r/go-jose/go-jose)
Package jose aims to provide an implementation of the Javascript Object Signing Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. This includes support for JSON Web Encryption, and Encryption set of standards. This includes support for JSON Web Encryption,
@ -23,11 +23,11 @@ US maintained blocked list.
The implementation follows the The implementation follows the
[JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516) (RFC 7516), [JSON Web Encryption](http://dx.doi.org/10.17487/RFC7516) (RFC 7516),
[JSON Web Signature](http://dx.doi.org/10.17487/RFC7515) (RFC 7515), and [JSON Web Signature](http://dx.doi.org/10.17487/RFC7515) (RFC 7515), and
[JSON Web Token](http://dx.doi.org/10.17487/RFC7519) (RFC 7519). [JSON Web Token](http://dx.doi.org/10.17487/RFC7519) (RFC 7519) specifications.
Tables of supported algorithms are shown below. The library supports both Tables of supported algorithms are shown below. The library supports both
the compact and full serialization formats, and has optional support for the compact and JWS/JWE JSON Serialization formats, and has optional support for
multiple recipients. It also comes with a small command-line utility multiple recipients. It also comes with a small command-line utility
([`jose-util`](https://github.com/square/go-jose/tree/v2/jose-util)) ([`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util))
for dealing with JOSE messages in a shell. for dealing with JOSE messages in a shell.
**Note**: We use a forked version of the `encoding/json` package from the Go **Note**: We use a forked version of the `encoding/json` package from the Go
@ -38,20 +38,24 @@ libraries in other languages.
### Versions ### Versions
We use [gopkg.in](https://gopkg.in) for versioning. [Version 2](https://gopkg.in/go-jose/go-jose.v2)
([branch](https://github.com/go-jose/go-jose/tree/v2),
[doc](https://godoc.org/gopkg.in/go-jose/go-jose.v2)) is the current stable version:
[Version 2](https://gopkg.in/square/go-jose.v2) import "gopkg.in/go-jose/go-jose.v2"
([branch](https://github.com/square/go-jose/tree/v2),
[doc](https://godoc.org/gopkg.in/square/go-jose.v2)) is the current version:
import "gopkg.in/square/go-jose.v2" [Version 3](https://github.com/go-jose/go-jose)
([branch](https://github.com/go-jose/go-jose/tree/master),
[doc](https://godoc.org/github.com/go-jose/go-jose)) is the under development/unstable version (not released yet):
The old `v1` branch ([go-jose.v1](https://gopkg.in/square/go-jose.v1)) will import "github.com/go-jose/go-jose/v3"
still receive backported bug fixes and security fixes, but otherwise
development is frozen. All new feature development takes place on the `v2` All new feature development takes place on the `master` branch, which we are
branch. Version 2 also contains additional sub-packages such as the preparing to release as version 3 soon. Version 2 will continue to receive
[jwt](https://godoc.org/gopkg.in/square/go-jose.v2/jwt) implementation critical bug and security fixes. Note that starting with version 3 we are
contributed by [@shaxbee](https://github.com/shaxbee). using Go modules for versioning instead of `gopkg.in` as before. Version 3 also will require Go version 1.13 or higher.
Version 1 (on the `v1` branch) is frozen and not supported anymore.
### Supported algorithms ### Supported algorithms
@ -101,18 +105,18 @@ allows attaching a key id.
:------------------------- | ------------------------------- :------------------------- | -------------------------------
RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey) RSA | *[rsa.PublicKey](http://golang.org/pkg/crypto/rsa/#PublicKey), *[rsa.PrivateKey](http://golang.org/pkg/crypto/rsa/#PrivateKey)
ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey) ECDH, ECDSA | *[ecdsa.PublicKey](http://golang.org/pkg/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](http://golang.org/pkg/crypto/ecdsa/#PrivateKey)
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://godoc.org/golang.org/x/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://godoc.org/golang.org/x/crypto/ed25519#PrivateKey) EdDSA<sup>1</sup> | [ed25519.PublicKey](https://godoc.org/pkg/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://godoc.org/pkg/crypto/ed25519#PrivateKey)
AES, HMAC | []byte AES, HMAC | []byte
<sup>1. Only available in version 2 of the package</sup> <sup>1. Only available in version 2 or later of the package</sup>
## Examples ## Examples
[![godoc](http://img.shields.io/badge/godoc-version_1-blue.svg?style=flat)](https://godoc.org/gopkg.in/square/go-jose.v1) [![godoc](http://img.shields.io/badge/godoc-jose_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2)
[![godoc](http://img.shields.io/badge/godoc-version_2-blue.svg?style=flat)](https://godoc.org/gopkg.in/square/go-jose.v2) [![godoc](http://img.shields.io/badge/godoc-jwt_package-blue.svg?style=flat)](https://godoc.org/gopkg.in/go-jose/go-jose.v2/jwt)
Examples can be found in the Godoc Examples can be found in the Godoc
reference for this package. The reference for this package. The
[`jose-util`](https://github.com/square/go-jose/tree/v2/jose-util) [`jose-util`](https://github.com/go-jose/go-jose/tree/master/jose-util)
subdirectory also contains a small command-line utility which might be useful subdirectory also contains a small command-line utility which might be useful
as an example. as an example as well.

View File

@ -20,6 +20,7 @@ import (
"crypto" "crypto"
"crypto/aes" "crypto/aes"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/sha1" "crypto/sha1"
@ -28,9 +29,8 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"golang.org/x/crypto/ed25519" josecipher "github.com/go-jose/go-jose/v3/cipher"
josecipher "gopkg.in/square/go-jose.v2/cipher" "github.com/go-jose/go-jose/v3/json"
"gopkg.in/square/go-jose.v2/json"
) )
// A generic RSA-based encrypter/verifier // A generic RSA-based encrypter/verifier
@ -413,28 +413,28 @@ func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) { func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
epk, err := headers.getEPK() epk, err := headers.getEPK()
if err != nil { if err != nil {
return nil, errors.New("square/go-jose: invalid epk header") return nil, errors.New("go-jose/go-jose: invalid epk header")
} }
if epk == nil { if epk == nil {
return nil, errors.New("square/go-jose: missing epk header") return nil, errors.New("go-jose/go-jose: missing epk header")
} }
publicKey, ok := epk.Key.(*ecdsa.PublicKey) publicKey, ok := epk.Key.(*ecdsa.PublicKey)
if publicKey == nil || !ok { if publicKey == nil || !ok {
return nil, errors.New("square/go-jose: invalid epk header") return nil, errors.New("go-jose/go-jose: invalid epk header")
} }
if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) { if !ctx.privateKey.Curve.IsOnCurve(publicKey.X, publicKey.Y) {
return nil, errors.New("square/go-jose: invalid public key in epk header") return nil, errors.New("go-jose/go-jose: invalid public key in epk header")
} }
apuData, err := headers.getAPU() apuData, err := headers.getAPU()
if err != nil { if err != nil {
return nil, errors.New("square/go-jose: invalid apu header") return nil, errors.New("go-jose/go-jose: invalid apu header")
} }
apvData, err := headers.getAPV() apvData, err := headers.getAPV()
if err != nil { if err != nil {
return nil, errors.New("square/go-jose: invalid apv header") return nil, errors.New("go-jose/go-jose: invalid apv header")
} }
deriveKey := func(algID string, size int) []byte { deriveKey := func(algID string, size int) []byte {
@ -489,7 +489,7 @@ func (ctx edEncrypterVerifier) verifyPayload(payload []byte, signature []byte, a
} }
ok := ed25519.Verify(ctx.publicKey, payload, signature) ok := ed25519.Verify(ctx.publicKey, payload, signature)
if !ok { if !ok {
return errors.New("square/go-jose: ed25519 signature failed to verify") return errors.New("go-jose/go-jose: ed25519 signature failed to verify")
} }
return nil return nil
} }
@ -513,7 +513,7 @@ func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm)
curveBits := ctx.privateKey.Curve.Params().BitSize curveBits := ctx.privateKey.Curve.Params().BitSize
if expectedBitSize != curveBits { if expectedBitSize != curveBits {
return Signature{}, fmt.Errorf("square/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits) return Signature{}, fmt.Errorf("go-jose/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
} }
hasher := hash.New() hasher := hash.New()
@ -571,7 +571,7 @@ func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, a
} }
if len(signature) != 2*keySize { if len(signature) != 2*keySize {
return fmt.Errorf("square/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize) return fmt.Errorf("go-jose/go-jose: invalid signature size, have %d bytes, wanted %d", len(signature), 2*keySize)
} }
hasher := hash.New() hasher := hash.New()
@ -585,7 +585,7 @@ func (ctx ecEncrypterVerifier) verifyPayload(payload []byte, signature []byte, a
match := ecdsa.Verify(ctx.publicKey, hashed, r, s) match := ecdsa.Verify(ctx.publicKey, hashed, r, s)
if !match { if !match {
return errors.New("square/go-jose: ecdsa signature failed to verify") return errors.New("go-jose/go-jose: ecdsa signature failed to verify")
} }
return nil return nil

View File

@ -101,23 +101,23 @@ func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte {
// Open decrypts and authenticates the ciphertext. // Open decrypts and authenticates the ciphertext.
func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
if len(ciphertext) < ctx.authtagBytes { if len(ciphertext) < ctx.authtagBytes {
return nil, errors.New("square/go-jose: invalid ciphertext (too short)") return nil, errors.New("go-jose/go-jose: invalid ciphertext (too short)")
} }
offset := len(ciphertext) - ctx.authtagBytes offset := len(ciphertext) - ctx.authtagBytes
expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset]) expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:]) match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
if match != 1 { if match != 1 {
return nil, errors.New("square/go-jose: invalid ciphertext (auth tag mismatch)") return nil, errors.New("go-jose/go-jose: invalid ciphertext (auth tag mismatch)")
} }
cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce) cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)
// Make copy of ciphertext buffer, don't want to modify in place // Make copy of ciphertext buffer, don't want to modify in place
buffer := append([]byte{}, []byte(ciphertext[:offset])...) buffer := append([]byte{}, ciphertext[:offset]...)
if len(buffer)%ctx.blockCipher.BlockSize() > 0 { if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
return nil, errors.New("square/go-jose: invalid ciphertext (invalid length)") return nil, errors.New("go-jose/go-jose: invalid ciphertext (invalid length)")
} }
cbc.CryptBlocks(buffer, buffer) cbc.CryptBlocks(buffer, buffer)
@ -177,19 +177,19 @@ func padBuffer(buffer []byte, blockSize int) []byte {
// Remove padding // Remove padding
func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) { func unpadBuffer(buffer []byte, blockSize int) ([]byte, error) {
if len(buffer)%blockSize != 0 { if len(buffer)%blockSize != 0 {
return nil, errors.New("square/go-jose: invalid padding") return nil, errors.New("go-jose/go-jose: invalid padding")
} }
last := buffer[len(buffer)-1] last := buffer[len(buffer)-1]
count := int(last) count := int(last)
if count == 0 || count > blockSize || count > len(buffer) { if count == 0 || count > blockSize || count > len(buffer) {
return nil, errors.New("square/go-jose: invalid padding") return nil, errors.New("go-jose/go-jose: invalid padding")
} }
padding := bytes.Repeat([]byte{last}, count) padding := bytes.Repeat([]byte{last}, count)
if !bytes.HasSuffix(buffer, padding) { if !bytes.HasSuffix(buffer, padding) {
return nil, errors.New("square/go-jose: invalid padding") return nil, errors.New("go-jose/go-jose: invalid padding")
} }
return buffer[:len(buffer)-count], nil return buffer[:len(buffer)-count], nil

View File

@ -28,7 +28,7 @@ var defaultIV = []byte{0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6}
// KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher. // KeyWrap implements NIST key wrapping; it wraps a content encryption key (cek) with the given block cipher.
func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) { func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
if len(cek)%8 != 0 { if len(cek)%8 != 0 {
return nil, errors.New("square/go-jose: key wrap input must be 8 byte blocks") return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
} }
n := len(cek) / 8 n := len(cek) / 8
@ -51,7 +51,7 @@ func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
binary.BigEndian.PutUint64(tBytes, uint64(t+1)) binary.BigEndian.PutUint64(tBytes, uint64(t+1))
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
buffer[i] = buffer[i] ^ tBytes[i] buffer[i] ^= tBytes[i]
} }
copy(r[t%n], buffer[8:]) copy(r[t%n], buffer[8:])
} }
@ -68,7 +68,7 @@ func KeyWrap(block cipher.Block, cek []byte) ([]byte, error) {
// KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher. // KeyUnwrap implements NIST key unwrapping; it unwraps a content encryption key (cek) with the given block cipher.
func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) { func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
if len(ciphertext)%8 != 0 { if len(ciphertext)%8 != 0 {
return nil, errors.New("square/go-jose: key wrap input must be 8 byte blocks") return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
} }
n := (len(ciphertext) / 8) - 1 n := (len(ciphertext) / 8) - 1
@ -87,7 +87,7 @@ func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
binary.BigEndian.PutUint64(tBytes, uint64(t+1)) binary.BigEndian.PutUint64(tBytes, uint64(t+1))
for i := 0; i < 8; i++ { for i := 0; i < 8; i++ {
buffer[i] = buffer[i] ^ tBytes[i] buffer[i] ^= tBytes[i]
} }
copy(buffer[8:], r[t%n]) copy(buffer[8:], r[t%n])
@ -97,7 +97,7 @@ func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
} }
if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 { if subtle.ConstantTimeCompare(buffer[:8], defaultIV) == 0 {
return nil, errors.New("square/go-jose: failed to unwrap key") return nil, errors.New("go-jose/go-jose: failed to unwrap key")
} }
out := make([]byte, n*8) out := make([]byte, n*8)

View File

@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"reflect" "reflect"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// Encrypter represents an encrypter which produces an encrypted JWE object. // Encrypter represents an encrypter which produces an encrypted JWE object.
@ -201,8 +201,8 @@ func NewMultiEncrypter(enc ContentEncryption, rcpts []Recipient, opts *Encrypter
if cipher == nil { if cipher == nil {
return nil, ErrUnsupportedAlgorithm return nil, ErrUnsupportedAlgorithm
} }
if rcpts == nil || len(rcpts) == 0 { if len(rcpts) == 0 {
return nil, fmt.Errorf("square/go-jose: recipients is nil or empty") return nil, fmt.Errorf("go-jose/go-jose: recipients is nil or empty")
} }
encrypter := &genericEncrypter{ encrypter := &genericEncrypter{
@ -234,7 +234,7 @@ func (ctx *genericEncrypter) addRecipient(recipient Recipient) (err error) {
switch recipient.Algorithm { switch recipient.Algorithm {
case DIRECT, ECDH_ES: case DIRECT, ECDH_ES:
return fmt.Errorf("square/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm) return fmt.Errorf("go-jose/go-jose: key algorithm '%s' not supported in multi-recipient mode", recipient.Algorithm)
} }
recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key) recipientInfo, err = makeJWERecipient(recipient.Algorithm, recipient.Key)
@ -326,7 +326,7 @@ func (ctx *genericEncrypter) EncryptWithAuthData(plaintext, aad []byte) (*JSONWe
obj.recipients = make([]recipientInfo, len(ctx.recipients)) obj.recipients = make([]recipientInfo, len(ctx.recipients))
if len(ctx.recipients) == 0 { if len(ctx.recipients) == 0 {
return nil, fmt.Errorf("square/go-jose: no recipients to encrypt to") return nil, fmt.Errorf("go-jose/go-jose: no recipients to encrypt to")
} }
cek, headers, err := ctx.keyGenerator.genKey() cek, headers, err := ctx.keyGenerator.genKey()
@ -410,26 +410,27 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
headers := obj.mergedHeaders(nil) headers := obj.mergedHeaders(nil)
if len(obj.recipients) > 1 { if len(obj.recipients) > 1 {
return nil, errors.New("square/go-jose: too many recipients in payload; expecting only one") return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one")
} }
critical, err := headers.getCritical() critical, err := headers.getCritical()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid crit header") return nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
} }
if len(critical) > 0 { if len(critical) > 0 {
return nil, fmt.Errorf("square/go-jose: unsupported crit header") return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
} }
decrypter, err := newDecrypter(decryptionKey) key := tryJWKS(decryptionKey, obj.Header)
decrypter, err := newDecrypter(key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cipher := getContentCipher(headers.getEncryption()) cipher := getContentCipher(headers.getEncryption())
if cipher == nil { if cipher == nil {
return nil, fmt.Errorf("square/go-jose: unsupported enc value '%s'", string(headers.getEncryption())) return nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(headers.getEncryption()))
} }
generator := randomKeyGenerator{ generator := randomKeyGenerator{
@ -475,14 +476,15 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
critical, err := globalHeaders.getCritical() critical, err := globalHeaders.getCritical()
if err != nil { if err != nil {
return -1, Header{}, nil, fmt.Errorf("square/go-jose: invalid crit header") return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
} }
if len(critical) > 0 { if len(critical) > 0 {
return -1, Header{}, nil, fmt.Errorf("square/go-jose: unsupported crit header") return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
} }
decrypter, err := newDecrypter(decryptionKey) key := tryJWKS(decryptionKey, obj.Header)
decrypter, err := newDecrypter(key)
if err != nil { if err != nil {
return -1, Header{}, nil, err return -1, Header{}, nil, err
} }
@ -490,7 +492,7 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
encryption := globalHeaders.getEncryption() encryption := globalHeaders.getEncryption()
cipher := getContentCipher(encryption) cipher := getContentCipher(encryption)
if cipher == nil { if cipher == nil {
return -1, Header{}, nil, fmt.Errorf("square/go-jose: unsupported enc value '%s'", string(encryption)) return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported enc value '%s'", string(encryption))
} }
generator := randomKeyGenerator{ generator := randomKeyGenerator{
@ -524,18 +526,18 @@ func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Heade
} }
} }
if plaintext == nil || err != nil { if plaintext == nil {
return -1, Header{}, nil, ErrCryptoFailure return -1, Header{}, nil, ErrCryptoFailure
} }
// The "zip" header parameter may only be present in the protected header. // The "zip" header parameter may only be present in the protected header.
if comp := obj.protected.getCompression(); comp != "" { if comp := obj.protected.getCompression(); comp != "" {
plaintext, err = decompress(comp, plaintext) plaintext, _ = decompress(comp, plaintext)
} }
sanitized, err := headers.sanitized() sanitized, err := headers.sanitized()
if err != nil { if err != nil {
return -1, Header{}, nil, fmt.Errorf("square/go-jose: failed to sanitize header: %v", err) return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: failed to sanitize header: %v", err)
} }
return index, sanitized, plaintext, err return index, sanitized, plaintext, err

View File

@ -18,9 +18,9 @@
Package jose aims to provide an implementation of the Javascript Object Signing Package jose aims to provide an implementation of the Javascript Object Signing
and Encryption set of standards. It implements encryption and signing based on and Encryption set of standards. It implements encryption and signing based on
the JSON Web Encryption and JSON Web Signature standards, with optional JSON the JSON Web Encryption and JSON Web Signature standards, with optional JSON Web
Web Token support available in a sub-package. The library supports both the Token support available in a sub-package. The library supports both the compact
compact and full serialization formats, and has optional support for multiple and JWS/JWE JSON Serialization formats, and has optional support for multiple
recipients. recipients.
*/ */

View File

@ -26,7 +26,7 @@ import (
"strings" "strings"
"unicode" "unicode"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// Helper function to serialize known-good objects. // Helper function to serialize known-good objects.
@ -41,7 +41,7 @@ func mustSerializeJSON(value interface{}) []byte {
// MarshalJSON will happily serialize it as the top-level value "null". If // MarshalJSON will happily serialize it as the top-level value "null". If
// that value is then embedded in another operation, for instance by being // that value is then embedded in another operation, for instance by being
// base64-encoded and fed as input to a signing algorithm // base64-encoded and fed as input to a signing algorithm
// (https://github.com/square/go-jose/issues/22), the result will be // (https://github.com/go-jose/go-jose/issues/22), the result will be
// incorrect. Because this method is intended for known-good objects, and a nil // incorrect. Because this method is intended for known-good objects, and a nil
// pointer is not a known-good object, we are free to panic in this case. // pointer is not a known-good object, we are free to panic in this case.
// Note: It's not possible to directly check whether the data pointed at by an // Note: It's not possible to directly check whether the data pointed at by an
@ -127,7 +127,7 @@ func newBuffer(data []byte) *byteBuffer {
func newFixedSizeBuffer(data []byte, length int) *byteBuffer { func newFixedSizeBuffer(data []byte, length int) *byteBuffer {
if len(data) > length { if len(data) > length {
panic("square/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)") panic("go-jose/go-jose: invalid call to newFixedSizeBuffer (len(data) > length)")
} }
pad := make([]byte, length-len(data)) pad := make([]byte, length-len(data))
return newBuffer(append(pad, data...)) return newBuffer(append(pad, data...))
@ -154,7 +154,7 @@ func (b *byteBuffer) UnmarshalJSON(data []byte) error {
return nil return nil
} }
decoded, err := base64.RawURLEncoding.DecodeString(encoded) decoded, err := base64URLDecode(encoded)
if err != nil { if err != nil {
return err return err
} }
@ -183,3 +183,9 @@ func (b byteBuffer) bigInt() *big.Int {
func (b byteBuffer) toInt() int { func (b byteBuffer) toInt() int {
return int(b.bigInt().Int64()) 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)
}

View File

@ -648,7 +648,7 @@ func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) {
// for large buffers, avoid unnecessary extra temporary // for large buffers, avoid unnecessary extra temporary
// buffer space. // buffer space.
enc := base64.NewEncoder(base64.StdEncoding, e) enc := base64.NewEncoder(base64.StdEncoding, e)
enc.Write(s) _, _ = enc.Write(s)
enc.Close() enc.Close()
} }
e.WriteByte('"') e.WriteByte('"')

View File

@ -21,7 +21,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing. // rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing.
@ -86,11 +86,12 @@ func (obj JSONWebEncryption) mergedHeaders(recipient *recipientInfo) rawHeader {
func (obj JSONWebEncryption) computeAuthData() []byte { func (obj JSONWebEncryption) computeAuthData() []byte {
var protected string var protected string
if obj.original != nil && obj.original.Protected != nil { switch {
case obj.original != nil && obj.original.Protected != nil:
protected = obj.original.Protected.base64() protected = obj.original.Protected.base64()
} else if obj.protected != nil { case obj.protected != nil:
protected = base64.RawURLEncoding.EncodeToString(mustSerializeJSON((obj.protected))) protected = base64.RawURLEncoding.EncodeToString(mustSerializeJSON((obj.protected)))
} else { default:
protected = "" protected = ""
} }
@ -103,7 +104,7 @@ func (obj JSONWebEncryption) computeAuthData() []byte {
return output return output
} }
// ParseEncrypted parses an encrypted message in compact or full serialization format. // ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format.
func ParseEncrypted(input string) (*JSONWebEncryption, error) { func ParseEncrypted(input string) (*JSONWebEncryption, error) {
input = stripWhitespace(input) input = stripWhitespace(input)
if strings.HasPrefix(input, "{") { if strings.HasPrefix(input, "{") {
@ -146,7 +147,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 { if parsed.Protected != nil && len(parsed.Protected.bytes()) > 0 {
err := json.Unmarshal(parsed.Protected.bytes(), &obj.protected) err := json.Unmarshal(parsed.Protected.bytes(), &obj.protected)
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid protected header: %s, %s", err, parsed.Protected.base64()) return nil, fmt.Errorf("go-jose/go-jose: invalid protected header: %s, %s", err, parsed.Protected.base64())
} }
} }
@ -156,7 +157,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
mergedHeaders := obj.mergedHeaders(nil) mergedHeaders := obj.mergedHeaders(nil)
obj.Header, err = mergedHeaders.sanitized() obj.Header, err = mergedHeaders.sanitized()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: cannot sanitize merged headers: %v (%v)", err, mergedHeaders) return nil, fmt.Errorf("go-jose/go-jose: cannot sanitize merged headers: %v (%v)", err, mergedHeaders)
} }
if len(parsed.Recipients) == 0 { if len(parsed.Recipients) == 0 {
@ -169,7 +170,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
} else { } else {
obj.recipients = make([]recipientInfo, len(parsed.Recipients)) obj.recipients = make([]recipientInfo, len(parsed.Recipients))
for r := range parsed.Recipients { for r := range parsed.Recipients {
encryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey) encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -187,7 +188,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
for _, recipient := range obj.recipients { for _, recipient := range obj.recipients {
headers := obj.mergedHeaders(&recipient) headers := obj.mergedHeaders(&recipient)
if headers.getAlgorithm() == "" || headers.getEncryption() == "" { if headers.getAlgorithm() == "" || headers.getEncryption() == "" {
return nil, fmt.Errorf("square/go-jose: message is missing alg/enc headers") return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers")
} }
} }
@ -203,30 +204,30 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) {
func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { func parseEncryptedCompact(input string) (*JSONWebEncryption, error) {
parts := strings.Split(input, ".") parts := strings.Split(input, ".")
if len(parts) != 5 { if len(parts) != 5 {
return nil, fmt.Errorf("square/go-jose: compact JWE format must have five parts") return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
} }
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) rawProtected, err := base64URLDecode(parts[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
encryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1]) encryptedKey, err := base64URLDecode(parts[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
iv, err := base64.RawURLEncoding.DecodeString(parts[2]) iv, err := base64URLDecode(parts[2])
if err != nil { if err != nil {
return nil, err return nil, err
} }
ciphertext, err := base64.RawURLEncoding.DecodeString(parts[3]) ciphertext, err := base64URLDecode(parts[3])
if err != nil { if err != nil {
return nil, err return nil, err
} }
tag, err := base64.RawURLEncoding.DecodeString(parts[4]) tag, err := base64URLDecode(parts[4])
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519"
"crypto/elliptic" "crypto/elliptic"
"crypto/rsa" "crypto/rsa"
"crypto/sha1" "crypto/sha1"
@ -34,9 +35,7 @@ import (
"reflect" "reflect"
"strings" "strings"
"golang.org/x/crypto/ed25519" "github.com/go-jose/go-jose/v3/json"
"gopkg.in/square/go-jose.v2/json"
) )
// rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing. // rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing.
@ -63,7 +62,7 @@ type rawJSONWebKey struct {
Qi *byteBuffer `json:"qi,omitempty"` Qi *byteBuffer `json:"qi,omitempty"`
// Certificates // Certificates
X5c []string `json:"x5c,omitempty"` X5c []string `json:"x5c,omitempty"`
X5u *url.URL `json:"x5u,omitempty"` X5u string `json:"x5u,omitempty"`
X5tSHA1 string `json:"x5t,omitempty"` X5tSHA1 string `json:"x5t,omitempty"`
X5tSHA256 string `json:"x5t#S256,omitempty"` X5tSHA256 string `json:"x5t#S256,omitempty"`
} }
@ -110,7 +109,7 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
case []byte: case []byte:
raw, err = fromSymmetricKey(key) raw, err = fromSymmetricKey(key)
default: default:
return nil, fmt.Errorf("square/go-jose: unknown key type '%s'", reflect.TypeOf(key)) return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
} }
if err != nil { if err != nil {
@ -129,13 +128,13 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
x5tSHA256Len := len(k.CertificateThumbprintSHA256) x5tSHA256Len := len(k.CertificateThumbprintSHA256)
if x5tSHA1Len > 0 { if x5tSHA1Len > 0 {
if x5tSHA1Len != sha1.Size { if x5tSHA1Len != sha1.Size {
return nil, fmt.Errorf("square/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)", sha1.Size, x5tSHA1Len) return nil, fmt.Errorf("go-jose/go-jose: invalid SHA-1 thumbprint (must be %d bytes, not %d)", sha1.Size, x5tSHA1Len)
} }
raw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1) raw.X5tSHA1 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA1)
} }
if x5tSHA256Len > 0 { if x5tSHA256Len > 0 {
if x5tSHA256Len != sha256.Size { if x5tSHA256Len != sha256.Size {
return nil, fmt.Errorf("square/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)", sha256.Size, x5tSHA256Len) return nil, fmt.Errorf("go-jose/go-jose: invalid SHA-256 thumbprint (must be %d bytes, not %d)", sha256.Size, x5tSHA256Len)
} }
raw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256) raw.X5tSHA256 = base64.RawURLEncoding.EncodeToString(k.CertificateThumbprintSHA256)
} }
@ -149,14 +148,16 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
expectedSHA256 := sha256.Sum256(k.Certificates[0].Raw) expectedSHA256 := sha256.Sum256(k.Certificates[0].Raw)
if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(k.CertificateThumbprintSHA1, expectedSHA1[:]) { 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") return nil, errors.New("go-jose/go-jose: invalid SHA-1 thumbprint, does not match cert chain")
} }
if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(k.CertificateThumbprintSHA256, expectedSHA256[:]) { 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") return nil, errors.New("go-jose/go-jose: invalid or SHA-256 thumbprint, does not match cert chain")
} }
} }
raw.X5u = k.CertificatesURL if k.CertificatesURL != nil {
raw.X5u = k.CertificatesURL.String()
}
return json.Marshal(raw) return json.Marshal(raw)
} }
@ -171,7 +172,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
certs, err := parseCertificateChain(raw.X5c) certs, err := parseCertificateChain(raw.X5c)
if err != nil { if err != nil {
return fmt.Errorf("square/go-jose: failed to unmarshal x5c field: %s", err) return fmt.Errorf("go-jose/go-jose: failed to unmarshal x5c field: %s", err)
} }
var key interface{} var key interface{}
@ -211,7 +212,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
} }
case "oct": case "oct":
if certPub != nil { if certPub != nil {
return errors.New("square/go-jose: invalid JWK, found 'oct' (symmetric) key with cert chain") return errors.New("go-jose/go-jose: invalid JWK, found 'oct' (symmetric) key with cert chain")
} }
key, err = raw.symmetricKey() key, err = raw.symmetricKey()
case "OKP": case "OKP":
@ -226,10 +227,10 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
keyPub = key keyPub = key
} }
} else { } else {
err = fmt.Errorf("square/go-jose: unknown curve %s'", raw.Crv) err = fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv)
} }
default: default:
err = fmt.Errorf("square/go-jose: unknown json web key type '%s'", raw.Kty) err = fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty)
} }
if err != nil { if err != nil {
@ -238,19 +239,24 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
if certPub != nil && keyPub != nil { if certPub != nil && keyPub != nil {
if !reflect.DeepEqual(certPub, keyPub) { if !reflect.DeepEqual(certPub, keyPub) {
return errors.New("square/go-jose: invalid JWK, public keys in key and x5c fields do not match") return errors.New("go-jose/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 = JSONWebKey{Key: key, KeyID: raw.Kid, Algorithm: raw.Alg, Use: raw.Use, Certificates: certs}
k.CertificatesURL = raw.X5u if raw.X5u != "" {
k.CertificatesURL, err = url.Parse(raw.X5u)
if err != nil {
return fmt.Errorf("go-jose/go-jose: invalid JWK, x5u header is invalid URL: %w", err)
}
}
// x5t parameters are base64url-encoded SHA thumbprints // x5t parameters are base64url-encoded SHA thumbprints
// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8 // See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8
x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1) x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1)
if err != nil { if err != nil {
return errors.New("square/go-jose: invalid JWK, x5t header has invalid encoding") return errors.New("go-jose/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, // RFC 7517, Section 4.8 is ambiguous as to whether the digest output should be byte or hex,
@ -260,7 +266,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
if len(x5tSHA1bytes) == 2*sha1.Size { if len(x5tSHA1bytes) == 2*sha1.Size {
hx, err := hex.DecodeString(string(x5tSHA1bytes)) hx, err := hex.DecodeString(string(x5tSHA1bytes))
if err != nil { if err != nil {
return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t: %v", err) return fmt.Errorf("go-jose/go-jose: invalid JWK, unable to hex decode x5t: %v", err)
} }
x5tSHA1bytes = hx x5tSHA1bytes = hx
@ -268,15 +274,15 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
k.CertificateThumbprintSHA1 = x5tSHA1bytes k.CertificateThumbprintSHA1 = x5tSHA1bytes
x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256) x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256)
if err != nil { if err != nil {
return errors.New("square/go-jose: invalid JWK, x5t#S256 header has invalid encoding") return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding")
} }
if len(x5tSHA256bytes) == 2*sha256.Size { if len(x5tSHA256bytes) == 2*sha256.Size {
hx256, err := hex.DecodeString(string(x5tSHA256bytes)) hx256, err := hex.DecodeString(string(x5tSHA256bytes))
if err != nil { if err != nil {
return fmt.Errorf("square/go-jose: invalid JWK, unable to hex decode x5t#S256: %v", err) return fmt.Errorf("go-jose/go-jose: invalid JWK, unable to hex decode x5t#S256: %v", err)
} }
x5tSHA256bytes = hx256 x5tSHA256bytes = hx256
} }
@ -286,10 +292,10 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
x5tSHA1Len := len(k.CertificateThumbprintSHA1) x5tSHA1Len := len(k.CertificateThumbprintSHA1)
x5tSHA256Len := len(k.CertificateThumbprintSHA256) x5tSHA256Len := len(k.CertificateThumbprintSHA256)
if x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size { if x5tSHA1Len > 0 && x5tSHA1Len != sha1.Size {
return errors.New("square/go-jose: invalid JWK, x5t header is of incorrect size") return errors.New("go-jose/go-jose: invalid JWK, x5t header is of incorrect size")
} }
if x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size { if x5tSHA256Len > 0 && x5tSHA256Len != sha256.Size {
return errors.New("square/go-jose: invalid JWK, x5t#S256 header is of incorrect size") return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header is of incorrect size")
} }
// If certificate chain *and* thumbprints are set, verify correctness. // If certificate chain *and* thumbprints are set, verify correctness.
@ -299,11 +305,11 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
sha256sum := sha256.Sum256(leaf.Raw) sha256sum := sha256.Sum256(leaf.Raw)
if len(k.CertificateThumbprintSHA1) > 0 && !bytes.Equal(sha1sum[:], k.CertificateThumbprintSHA1) { 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") return errors.New("go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t value")
} }
if len(k.CertificateThumbprintSHA256) > 0 && !bytes.Equal(sha256sum[:], k.CertificateThumbprintSHA256) { 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 errors.New("go-jose/go-jose: invalid JWK, x5c thumbprint does not match x5t#S256 value")
} }
} }
@ -342,7 +348,7 @@ func ecThumbprintInput(curve elliptic.Curve, x, y *big.Int) (string, error) {
} }
if len(x.Bytes()) > coordLength || len(y.Bytes()) > coordLength { if len(x.Bytes()) > coordLength || len(y.Bytes()) > coordLength {
return "", errors.New("square/go-jose: invalid elliptic key (too large)") return "", errors.New("go-jose/go-jose: invalid elliptic key (too large)")
} }
return fmt.Sprintf(ecThumbprintTemplate, crv, return fmt.Sprintf(ecThumbprintTemplate, crv,
@ -359,7 +365,7 @@ func rsaThumbprintInput(n *big.Int, e int) (string, error) {
func edThumbprintInput(ed ed25519.PublicKey) (string, error) { func edThumbprintInput(ed ed25519.PublicKey) (string, error) {
crv := "Ed25519" crv := "Ed25519"
if len(ed) > 32 { if len(ed) > 32 {
return "", errors.New("square/go-jose: invalid elliptic key (too large)") return "", errors.New("go-jose/go-jose: invalid elliptic key (too large)")
} }
return fmt.Sprintf(edThumbprintTemplate, crv, return fmt.Sprintf(edThumbprintTemplate, crv,
newFixedSizeBuffer(ed, 32).base64()), nil newFixedSizeBuffer(ed, 32).base64()), nil
@ -384,7 +390,7 @@ func (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
case ed25519.PrivateKey: case ed25519.PrivateKey:
input, err = edThumbprintInput(ed25519.PublicKey(key[32:])) input, err = edThumbprintInput(ed25519.PublicKey(key[32:]))
default: default:
return nil, fmt.Errorf("square/go-jose: unknown key type '%s'", reflect.TypeOf(key)) return nil, fmt.Errorf("go-jose/go-jose: unknown key type '%s'", reflect.TypeOf(key))
} }
if err != nil { if err != nil {
@ -392,7 +398,7 @@ func (k *JSONWebKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
} }
h := hash.New() h := hash.New()
h.Write([]byte(input)) _, _ = h.Write([]byte(input))
return h.Sum(nil), nil return h.Sum(nil), nil
} }
@ -463,7 +469,7 @@ func (k *JSONWebKey) Valid() bool {
func (key rawJSONWebKey) rsaPublicKey() (*rsa.PublicKey, error) { func (key rawJSONWebKey) rsaPublicKey() (*rsa.PublicKey, error) {
if key.N == nil || key.E == nil { if key.N == nil || key.E == nil {
return nil, fmt.Errorf("square/go-jose: invalid RSA key, missing n/e values") return nil, fmt.Errorf("go-jose/go-jose: invalid RSA key, missing n/e values")
} }
return &rsa.PublicKey{ return &rsa.PublicKey{
@ -498,29 +504,29 @@ func (key rawJSONWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
case "P-521": case "P-521":
curve = elliptic.P521() curve = elliptic.P521()
default: default:
return nil, fmt.Errorf("square/go-jose: unsupported elliptic curve '%s'", key.Crv) return nil, fmt.Errorf("go-jose/go-jose: unsupported elliptic curve '%s'", key.Crv)
} }
if key.X == nil || key.Y == nil { if key.X == nil || key.Y == nil {
return nil, errors.New("square/go-jose: invalid EC key, missing x/y values") return nil, errors.New("go-jose/go-jose: invalid EC key, missing x/y values")
} }
// The length of this octet string MUST be the full size of a coordinate for // The length of this octet string MUST be the full size of a coordinate for
// the curve specified in the "crv" parameter. // the curve specified in the "crv" parameter.
// https://tools.ietf.org/html/rfc7518#section-6.2.1.2 // https://tools.ietf.org/html/rfc7518#section-6.2.1.2
if curveSize(curve) != len(key.X.data) { if curveSize(curve) != len(key.X.data) {
return nil, fmt.Errorf("square/go-jose: invalid EC public key, wrong length for x") return nil, fmt.Errorf("go-jose/go-jose: invalid EC public key, wrong length for x")
} }
if curveSize(curve) != len(key.Y.data) { if curveSize(curve) != len(key.Y.data) {
return nil, fmt.Errorf("square/go-jose: invalid EC public key, wrong length for y") return nil, fmt.Errorf("go-jose/go-jose: invalid EC public key, wrong length for y")
} }
x := key.X.bigInt() x := key.X.bigInt()
y := key.Y.bigInt() y := key.Y.bigInt()
if !curve.IsOnCurve(x, y) { if !curve.IsOnCurve(x, y) {
return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve") return nil, errors.New("go-jose/go-jose: invalid EC key, X/Y are not on declared curve")
} }
return &ecdsa.PublicKey{ return &ecdsa.PublicKey{
@ -532,7 +538,7 @@ func (key rawJSONWebKey) ecPublicKey() (*ecdsa.PublicKey, error) {
func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) { func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) {
if pub == nil || pub.X == nil || pub.Y == nil { if pub == nil || pub.X == nil || pub.Y == nil {
return nil, fmt.Errorf("square/go-jose: invalid EC key (nil, or X/Y missing)") return nil, fmt.Errorf("go-jose/go-jose: invalid EC key (nil, or X/Y missing)")
} }
name, err := curveName(pub.Curve) name, err := curveName(pub.Curve)
@ -546,7 +552,7 @@ func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) {
yBytes := pub.Y.Bytes() yBytes := pub.Y.Bytes()
if len(xBytes) > size || len(yBytes) > size { if len(xBytes) > size || len(yBytes) > size {
return nil, fmt.Errorf("square/go-jose: invalid EC key (X/Y too large)") return nil, fmt.Errorf("go-jose/go-jose: invalid EC key (X/Y too large)")
} }
key := &rawJSONWebKey{ key := &rawJSONWebKey{
@ -569,7 +575,7 @@ func (key rawJSONWebKey) edPrivateKey() (ed25519.PrivateKey, error) {
} }
if len(missing) > 0 { if len(missing) > 0 {
return nil, fmt.Errorf("square/go-jose: invalid Ed25519 private key, missing %s value(s)", strings.Join(missing, ", ")) return nil, fmt.Errorf("go-jose/go-jose: invalid Ed25519 private key, missing %s value(s)", strings.Join(missing, ", "))
} }
privateKey := make([]byte, ed25519.PrivateKeySize) privateKey := make([]byte, ed25519.PrivateKeySize)
@ -581,7 +587,7 @@ func (key rawJSONWebKey) edPrivateKey() (ed25519.PrivateKey, error) {
func (key rawJSONWebKey) edPublicKey() (ed25519.PublicKey, error) { func (key rawJSONWebKey) edPublicKey() (ed25519.PublicKey, error) {
if key.X == nil { if key.X == nil {
return nil, fmt.Errorf("square/go-jose: invalid Ed key, missing x value") return nil, fmt.Errorf("go-jose/go-jose: invalid Ed key, missing x value")
} }
publicKey := make([]byte, ed25519.PublicKeySize) publicKey := make([]byte, ed25519.PublicKeySize)
copy(publicKey[0:32], key.X.bytes()) copy(publicKey[0:32], key.X.bytes())
@ -605,7 +611,7 @@ func (key rawJSONWebKey) rsaPrivateKey() (*rsa.PrivateKey, error) {
} }
if len(missing) > 0 { if len(missing) > 0 {
return nil, fmt.Errorf("square/go-jose: invalid RSA private key, missing %s value(s)", strings.Join(missing, ", ")) return nil, fmt.Errorf("go-jose/go-jose: invalid RSA private key, missing %s value(s)", strings.Join(missing, ", "))
} }
rv := &rsa.PrivateKey{ rv := &rsa.PrivateKey{
@ -675,34 +681,34 @@ func (key rawJSONWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {
case "P-521": case "P-521":
curve = elliptic.P521() curve = elliptic.P521()
default: default:
return nil, fmt.Errorf("square/go-jose: unsupported elliptic curve '%s'", key.Crv) return nil, fmt.Errorf("go-jose/go-jose: unsupported elliptic curve '%s'", key.Crv)
} }
if key.X == nil || key.Y == nil || key.D == nil { if key.X == nil || key.Y == nil || key.D == nil {
return nil, fmt.Errorf("square/go-jose: invalid EC private key, missing x/y/d values") return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, missing x/y/d values")
} }
// The length of this octet string MUST be the full size of a coordinate for // The length of this octet string MUST be the full size of a coordinate for
// the curve specified in the "crv" parameter. // the curve specified in the "crv" parameter.
// https://tools.ietf.org/html/rfc7518#section-6.2.1.2 // https://tools.ietf.org/html/rfc7518#section-6.2.1.2
if curveSize(curve) != len(key.X.data) { if curveSize(curve) != len(key.X.data) {
return nil, fmt.Errorf("square/go-jose: invalid EC private key, wrong length for x") return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for x")
} }
if curveSize(curve) != len(key.Y.data) { if curveSize(curve) != len(key.Y.data) {
return nil, fmt.Errorf("square/go-jose: invalid EC private key, wrong length for y") return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for y")
} }
// https://tools.ietf.org/html/rfc7518#section-6.2.2.1 // https://tools.ietf.org/html/rfc7518#section-6.2.2.1
if dSize(curve) != len(key.D.data) { if dSize(curve) != len(key.D.data) {
return nil, fmt.Errorf("square/go-jose: invalid EC private key, wrong length for d") return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, wrong length for d")
} }
x := key.X.bigInt() x := key.X.bigInt()
y := key.Y.bigInt() y := key.Y.bigInt()
if !curve.IsOnCurve(x, y) { if !curve.IsOnCurve(x, y) {
return nil, errors.New("square/go-jose: invalid EC key, X/Y are not on declared curve") return nil, errors.New("go-jose/go-jose: invalid EC key, X/Y are not on declared curve")
} }
return &ecdsa.PrivateKey{ return &ecdsa.PrivateKey{
@ -722,7 +728,7 @@ func fromEcPrivateKey(ec *ecdsa.PrivateKey) (*rawJSONWebKey, error) {
} }
if ec.D == nil { if ec.D == nil {
return nil, fmt.Errorf("square/go-jose: invalid EC private key") return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key")
} }
raw.D = newFixedSizeBuffer(ec.D.Bytes(), dSize(ec.PublicKey.Curve)) raw.D = newFixedSizeBuffer(ec.D.Bytes(), dSize(ec.PublicKey.Curve))
@ -740,7 +746,7 @@ func dSize(curve elliptic.Curve) int {
bitLen := order.BitLen() bitLen := order.BitLen()
size := bitLen / 8 size := bitLen / 8
if bitLen%8 != 0 { if bitLen%8 != 0 {
size = size + 1 size++
} }
return size return size
} }
@ -754,7 +760,39 @@ func fromSymmetricKey(key []byte) (*rawJSONWebKey, error) {
func (key rawJSONWebKey) symmetricKey() ([]byte, error) { func (key rawJSONWebKey) symmetricKey() ([]byte, error) {
if key.K == nil { if key.K == nil {
return nil, fmt.Errorf("square/go-jose: invalid OCT (symmetric) key, missing k value") return nil, fmt.Errorf("go-jose/go-jose: invalid OCT (symmetric) key, missing k value")
} }
return key.K.bytes(), nil return key.K.bytes(), nil
} }
func tryJWKS(key interface{}, headers ...Header) interface{} {
var jwks JSONWebKeySet
switch jwksType := key.(type) {
case *JSONWebKeySet:
jwks = *jwksType
case 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
}

View File

@ -23,7 +23,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing. // rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing.
@ -75,7 +75,7 @@ type Signature struct {
original *rawSignatureInfo original *rawSignatureInfo
} }
// ParseSigned parses a signed message in compact or full serialization format. // ParseSigned parses a signed message in compact or JWS JSON Serialization format.
func ParseSigned(signature string) (*JSONWebSignature, error) { func ParseSigned(signature string) (*JSONWebSignature, error) {
signature = stripWhitespace(signature) signature = stripWhitespace(signature)
if strings.HasPrefix(signature, "{") { if strings.HasPrefix(signature, "{") {
@ -88,7 +88,7 @@ func ParseSigned(signature string) (*JSONWebSignature, error) {
// ParseDetached parses a signed message in compact serialization format with detached payload. // 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) (*JSONWebSignature, error) {
if payload == nil { if payload == nil {
return nil, errors.New("square/go-jose: nil payload") return nil, errors.New("go-jose/go-jose: nil payload")
} }
return parseSignedCompact(stripWhitespace(signature), payload) return parseSignedCompact(stripWhitespace(signature), payload)
} }
@ -151,7 +151,7 @@ func parseSignedFull(input string) (*JSONWebSignature, error) {
// sanitized produces a cleaned-up JWS object from the raw JSON. // sanitized produces a cleaned-up JWS object from the raw JSON.
func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
if parsed.Payload == nil { if parsed.Payload == nil {
return nil, fmt.Errorf("square/go-jose: missing payload in JWS message") return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message")
} }
obj := &JSONWebSignature{ obj := &JSONWebSignature{
@ -215,7 +215,7 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded. // As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
jwk := signature.Header.JSONWebKey jwk := signature.Header.JSONWebKey
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) { if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
return nil, errors.New("square/go-jose: invalid embedded jwk, must be public key") return nil, errors.New("go-jose/go-jose: invalid embedded jwk, must be public key")
} }
obj.Signatures = append(obj.Signatures, signature) obj.Signatures = append(obj.Signatures, signature)
@ -260,7 +260,7 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
// As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded. // As per RFC 7515 Section 4.1.3, only public keys are allowed to be embedded.
jwk := obj.Signatures[i].Header.JSONWebKey jwk := obj.Signatures[i].Header.JSONWebKey
if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) { if jwk != nil && (!jwk.Valid() || !jwk.IsPublic()) {
return nil, errors.New("square/go-jose: invalid embedded jwk, must be public key") return nil, errors.New("go-jose/go-jose: invalid embedded jwk, must be public key")
} }
// Copy value of sig // Copy value of sig
@ -277,26 +277,26 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) {
func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) { func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) {
parts := strings.Split(input, ".") parts := strings.Split(input, ".")
if len(parts) != 3 { if len(parts) != 3 {
return nil, fmt.Errorf("square/go-jose: compact JWS format must have three parts") return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
} }
if parts[1] != "" && payload != nil { if parts[1] != "" && payload != nil {
return nil, fmt.Errorf("square/go-jose: payload is not detached") return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
} }
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) rawProtected, err := base64URLDecode(parts[0])
if err != nil { if err != nil {
return nil, err return nil, err
} }
if payload == nil { if payload == nil {
payload, err = base64.RawURLEncoding.DecodeString(parts[1]) payload, err = base64URLDecode(parts[1])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
signature, err := base64.RawURLEncoding.DecodeString(parts[2]) signature, err := base64URLDecode(parts[2])
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -21,9 +21,9 @@ import (
"bytes" "bytes"
"reflect" "reflect"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
"gopkg.in/square/go-jose.v2" "github.com/go-jose/go-jose/v3"
) )
// Builder is a utility for making JSON Web Tokens. Calls can be chained, and // Builder is a utility for making JSON Web Tokens. Calls can be chained, and
@ -36,7 +36,7 @@ type Builder interface {
Claims(i interface{}) Builder Claims(i interface{}) Builder
// Token builds a JSONWebToken from provided data. // Token builds a JSONWebToken from provided data.
Token() (*JSONWebToken, error) Token() (*JSONWebToken, error)
// FullSerialize serializes a token using the full serialization format. // FullSerialize serializes a token using the JWS/JWE JSON Serialization format.
FullSerialize() (string, error) FullSerialize() (string, error)
// CompactSerialize serializes a token using the compact serialization format. // CompactSerialize serializes a token using the compact serialization format.
CompactSerialize() (string, error) CompactSerialize() (string, error)
@ -53,7 +53,7 @@ type NestedBuilder interface {
Claims(i interface{}) NestedBuilder Claims(i interface{}) NestedBuilder
// Token builds a NestedJSONWebToken from provided data. // Token builds a NestedJSONWebToken from provided data.
Token() (*NestedJSONWebToken, error) Token() (*NestedJSONWebToken, error)
// FullSerialize serializes a token using the full serialization format. // FullSerialize serializes a token using the JSON Serialization format.
FullSerialize() (string, error) FullSerialize() (string, error)
// CompactSerialize serializes a token using the compact serialization format. // CompactSerialize serializes a token using the compact serialization format.
CompactSerialize() (string, error) CompactSerialize() (string, error)

View File

@ -21,7 +21,7 @@ import (
"strconv" "strconv"
"time" "time"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// Claims represents public claim values (as specified in RFC 7519). // Claims represents public claim values (as specified in RFC 7519).
@ -111,6 +111,15 @@ func (s *Audience) UnmarshalJSON(b []byte) error {
return nil return nil
} }
// MarshalJSON converts audience to json representation.
func (s Audience) MarshalJSON() ([]byte, error) {
if len(s) == 1 {
return json.Marshal(s[0])
}
return json.Marshal([]string(s))
}
//Contains checks whether a given string is included in the Audience
func (s Audience) Contains(v string) bool { func (s Audience) Contains(v string) bool {
for _, a := range s { for _, a := range s {
if a == v { if a == v {

View File

@ -20,34 +20,34 @@ package jwt
import "errors" import "errors"
// ErrUnmarshalAudience indicates that aud claim could not be unmarshalled. // 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") var ErrUnmarshalAudience = errors.New("go-jose/go-jose/jwt: expected string or array value to unmarshal to Audience")
// ErrUnmarshalNumericDate indicates that JWT NumericDate could not be unmarshalled. // ErrUnmarshalNumericDate indicates that JWT NumericDate could not be unmarshalled.
var ErrUnmarshalNumericDate = errors.New("square/go-jose/jwt: expected number value to unmarshal NumericDate") var ErrUnmarshalNumericDate = errors.New("go-jose/go-jose/jwt: expected number value to unmarshal NumericDate")
// ErrInvalidClaims indicates that given claims have invalid type. // 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") var ErrInvalidClaims = errors.New("go-jose/go-jose/jwt: expected claims to be value convertible into JSON object")
// ErrInvalidIssuer indicates invalid iss claim. // ErrInvalidIssuer indicates invalid iss claim.
var ErrInvalidIssuer = errors.New("square/go-jose/jwt: validation failed, invalid issuer claim (iss)") var ErrInvalidIssuer = errors.New("go-jose/go-jose/jwt: validation failed, invalid issuer claim (iss)")
// ErrInvalidSubject indicates invalid sub claim. // ErrInvalidSubject indicates invalid sub claim.
var ErrInvalidSubject = errors.New("square/go-jose/jwt: validation failed, invalid subject claim (sub)") var ErrInvalidSubject = errors.New("go-jose/go-jose/jwt: validation failed, invalid subject claim (sub)")
// ErrInvalidAudience indicated invalid aud claim. // ErrInvalidAudience indicated invalid aud claim.
var ErrInvalidAudience = errors.New("square/go-jose/jwt: validation failed, invalid audience claim (aud)") var ErrInvalidAudience = errors.New("go-jose/go-jose/jwt: validation failed, invalid audience claim (aud)")
// ErrInvalidID indicates invalid jti claim. // ErrInvalidID indicates invalid jti claim.
var ErrInvalidID = errors.New("square/go-jose/jwt: validation failed, invalid ID claim (jti)") var ErrInvalidID = errors.New("go-jose/go-jose/jwt: validation failed, invalid ID claim (jti)")
// ErrNotValidYet indicates that token is used before time indicated in nbf claim. // 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)") var ErrNotValidYet = errors.New("go-jose/go-jose/jwt: validation failed, token not valid yet (nbf)")
// ErrExpired indicates that token is used after expiry time indicated in exp claim. // 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)") var ErrExpired = errors.New("go-jose/go-jose/jwt: validation failed, token is expired (exp)")
// ErrIssuedInTheFuture indicates that the iat field is in the future. // 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)") var ErrIssuedInTheFuture = errors.New("go-jose/go-jose/jwt: validation field, token issued in the future (iat)")
// ErrInvalidContentType indicates that token requires JWT cty header. // ErrInvalidContentType indicates that token requires JWT cty header.
var ErrInvalidContentType = errors.New("square/go-jose/jwt: expected content type to be JWT (cty header)") var ErrInvalidContentType = errors.New("go-jose/go-jose/jwt: expected content type to be JWT (cty header)")

View File

@ -21,8 +21,8 @@ import (
"fmt" "fmt"
"strings" "strings"
jose "gopkg.in/square/go-jose.v2" jose "github.com/go-jose/go-jose/v3"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// JSONWebToken represents a JSON Web Token (as specified in RFC7519). // JSONWebToken represents a JSON Web Token (as specified in RFC7519).
@ -39,9 +39,7 @@ type NestedJSONWebToken struct {
// Claims deserializes a JSONWebToken into dest using the provided key. // Claims deserializes a JSONWebToken into dest using the provided key.
func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error { func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
payloadKey := tryJWKS(t.Headers, key) b, err := t.payload(key)
b, err := t.payload(payloadKey)
if err != nil { if err != nil {
return err return err
} }
@ -60,7 +58,7 @@ func (t *JSONWebToken) Claims(key interface{}, dest ...interface{}) error {
// verified. This function won't work for encrypted JWTs. // verified. This function won't work for encrypted JWTs.
func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error { func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) error {
if t.unverifiedPayload == nil { if t.unverifiedPayload == nil {
return fmt.Errorf("square/go-jose: Cannot get unverified claims") return fmt.Errorf("go-jose/go-jose: Cannot get unverified claims")
} }
claims := t.unverifiedPayload() claims := t.unverifiedPayload()
for _, d := range dest { for _, d := range dest {
@ -72,9 +70,7 @@ func (t *JSONWebToken) UnsafeClaimsWithoutVerification(dest ...interface{}) erro
} }
func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) { func (t *NestedJSONWebToken) Decrypt(decryptionKey interface{}) (*JSONWebToken, error) {
key := tryJWKS(t.Headers, decryptionKey) b, err := t.enc.Decrypt(decryptionKey)
b, err := t.enc.Decrypt(key)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -135,35 +131,3 @@ func ParseSignedAndEncrypted(s string) (*NestedJSONWebToken, error) {
Headers: []jose.Header{enc.Header}, Headers: []jose.Header{enc.Header},
}, nil }, 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
}

View File

@ -25,7 +25,9 @@ const (
) )
// Expected defines values used for protected claims validation. // Expected defines values used for protected claims validation.
// If field has zero value then validation is skipped. // If field has zero value then validation is skipped, with the exception of
// Time, where the zero value means "now." To skip validating them, set the
// corresponding field in the Claims struct to nil.
type Expected struct { type Expected struct {
// Issuer matches the "iss" claim exactly. // Issuer matches the "iss" claim exactly.
Issuer string Issuer string
@ -61,7 +63,7 @@ func (c Claims) Validate(e Expected) error {
// ValidateWithLeeway checks claims in a token against expected values. A // ValidateWithLeeway checks claims in a token against expected values. A
// custom leeway may be specified for comparing time values. You may pass 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 // zero value to check time values with no leeway, but you should note that
// numeric date values are rounded to the nearest second and sub-second // numeric date values are rounded to the nearest second and sub-second
// precision is not supported. // precision is not supported.
// //
@ -94,21 +96,25 @@ func (c Claims) ValidateWithLeeway(e Expected, leeway time.Duration) error {
} }
} }
if !e.Time.IsZero() { // validate using the e.Time, or time.Now if not provided
if c.NotBefore != nil && e.Time.Add(leeway).Before(c.NotBefore.Time()) { validationTime := e.Time
if validationTime.IsZero() {
validationTime = time.Now()
}
if c.NotBefore != nil && validationTime.Add(leeway).Before(c.NotBefore.Time()) {
return ErrNotValidYet return ErrNotValidYet
} }
if c.Expiry != nil && e.Time.Add(-leeway).After(c.Expiry.Time()) { if c.Expiry != nil && validationTime.Add(-leeway).After(c.Expiry.Time()) {
return ErrExpired return ErrExpired
} }
// IssuedAt is optional but cannot be in the future. This is not required by the RFC, but // 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. // something is misconfigured if this happens and we should not trust it.
if c.IssuedAt != nil && e.Time.Add(leeway).Before(c.IssuedAt.Time()) { if c.IssuedAt != nil && validationTime.Add(leeway).Before(c.IssuedAt.Time()) {
return ErrIssuedInTheFuture return ErrIssuedInTheFuture
} }
}
return nil return nil
} }

View File

@ -23,7 +23,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"gopkg.in/square/go-jose.v2/json" "github.com/go-jose/go-jose/v3/json"
) )
// KeyAlgorithm represents a key management algorithm. // KeyAlgorithm represents a key management algorithm.
@ -45,32 +45,32 @@ var (
// ErrCryptoFailure represents an error in cryptographic primitive. This // ErrCryptoFailure represents an error in cryptographic primitive. This
// occurs when, for example, a message had an invalid authentication tag or // occurs when, for example, a message had an invalid authentication tag or
// could not be decrypted. // could not be decrypted.
ErrCryptoFailure = errors.New("square/go-jose: error in cryptographic primitive") ErrCryptoFailure = errors.New("go-jose/go-jose: error in cryptographic primitive")
// ErrUnsupportedAlgorithm indicates that a selected algorithm is not // ErrUnsupportedAlgorithm indicates that a selected algorithm is not
// supported. This occurs when trying to instantiate an encrypter for an // supported. This occurs when trying to instantiate an encrypter for an
// algorithm that is not yet implemented. // algorithm that is not yet implemented.
ErrUnsupportedAlgorithm = errors.New("square/go-jose: unknown/unsupported algorithm") ErrUnsupportedAlgorithm = errors.New("go-jose/go-jose: unknown/unsupported algorithm")
// ErrUnsupportedKeyType indicates that the given key type/format is not // ErrUnsupportedKeyType indicates that the given key type/format is not
// supported. This occurs when trying to instantiate an encrypter and passing // supported. This occurs when trying to instantiate an encrypter and passing
// it a key of an unrecognized type or with unsupported parameters, such as // it a key of an unrecognized type or with unsupported parameters, such as
// an RSA private key with more than two primes. // an RSA private key with more than two primes.
ErrUnsupportedKeyType = errors.New("square/go-jose: unsupported key type/format") ErrUnsupportedKeyType = errors.New("go-jose/go-jose: unsupported key type/format")
// ErrInvalidKeySize indicates that the given key is not the correct size // ErrInvalidKeySize indicates that the given key is not the correct size
// for the selected algorithm. This can occur, for example, when trying to // for the selected algorithm. This can occur, for example, when trying to
// encrypt with AES-256 but passing only a 128-bit key as input. // encrypt with AES-256 but passing only a 128-bit key as input.
ErrInvalidKeySize = errors.New("square/go-jose: invalid key size for algorithm") ErrInvalidKeySize = errors.New("go-jose/go-jose: invalid key size for algorithm")
// ErrNotSupported serialization of object is not supported. This occurs when // ErrNotSupported serialization of object is not supported. This occurs when
// trying to compact-serialize an object which can't be represented in // trying to compact-serialize an object which can't be represented in
// compact form. // compact form.
ErrNotSupported = errors.New("square/go-jose: compact serialization not supported for object") ErrNotSupported = errors.New("go-jose/go-jose: compact serialization not supported for object")
// ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a // ErrUnprotectedNonce indicates that while parsing a JWS or JWE object, a
// nonce header parameter was included in an unprotected header object. // nonce header parameter was included in an unprotected header object.
ErrUnprotectedNonce = errors.New("square/go-jose: Nonce parameter included in unprotected header") ErrUnprotectedNonce = errors.New("go-jose/go-jose: Nonce parameter included in unprotected header")
) )
// Key management algorithms // Key management algorithms
@ -133,7 +133,7 @@ const (
type HeaderKey string type HeaderKey string
const ( const (
HeaderType HeaderKey = "typ" // string HeaderType = "typ" // string
HeaderContentType = "cty" // string HeaderContentType = "cty" // string
// These are set by go-jose and shouldn't need to be set by consumers of the // These are set by go-jose and shouldn't need to be set by consumers of the
@ -194,7 +194,7 @@ type Header struct {
// not be validated with the given verify options. // not be validated with the given verify options.
func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) { func (h Header) Certificates(opts x509.VerifyOptions) ([][]*x509.Certificate, error) {
if len(h.certificates) == 0 { if len(h.certificates) == 0 {
return nil, errors.New("square/go-jose: no x5c header present in message") return nil, errors.New("go-jose/go-jose: no x5c header present in message")
} }
leaf := h.certificates[0] leaf := h.certificates[0]
@ -452,8 +452,8 @@ func parseCertificateChain(chain []string) ([]*x509.Certificate, error) {
return out, nil return out, nil
} }
func (dst rawHeader) isSet(k HeaderKey) bool { func (parsed rawHeader) isSet(k HeaderKey) bool {
dvr := dst[k] dvr := parsed[k]
if dvr == nil { if dvr == nil {
return false return false
} }
@ -472,17 +472,17 @@ func (dst rawHeader) isSet(k HeaderKey) bool {
} }
// Merge headers from src into dst, giving precedence to headers from l. // Merge headers from src into dst, giving precedence to headers from l.
func (dst rawHeader) merge(src *rawHeader) { func (parsed rawHeader) merge(src *rawHeader) {
if src == nil { if src == nil {
return return
} }
for k, v := range *src { for k, v := range *src {
if dst.isSet(k) { if parsed.isSet(k) {
continue continue
} }
dst[k] = v parsed[k] = v
} }
} }
@ -496,7 +496,7 @@ func curveName(crv elliptic.Curve) (string, error) {
case elliptic.P521(): case elliptic.P521():
return "P-521", nil return "P-521", nil
default: default:
return "", fmt.Errorf("square/go-jose: unsupported/unknown elliptic curve") return "", fmt.Errorf("go-jose/go-jose: unsupported/unknown elliptic curve")
} }
} }

View File

@ -19,14 +19,13 @@ package jose
import ( import (
"bytes" "bytes"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/ed25519"
"crypto/rsa" "crypto/rsa"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"golang.org/x/crypto/ed25519" "github.com/go-jose/go-jose/v3/json"
"gopkg.in/square/go-jose.v2/json"
) )
// NonceSource represents a source of random nonces to go into JWS objects // NonceSource represents a source of random nonces to go into JWS objects
@ -227,7 +226,7 @@ func newJWKSigner(alg SignatureAlgorithm, signingKey JSONWebKey) (recipientSigIn
// This should be impossible, but let's check anyway. // This should be impossible, but let's check anyway.
if !recipient.publicKey().IsPublic() { if !recipient.publicKey().IsPublic() {
return recipientSigInfo{}, errors.New("square/go-jose: public key was unexpectedly not public") return recipientSigInfo{}, errors.New("go-jose/go-jose: public key was unexpectedly not public")
} }
} }
return recipient, nil return recipient, nil
@ -251,7 +250,7 @@ func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
// result of the JOSE spec. We've decided that this library will only include one or // result of the JOSE spec. We've decided that this library will only include one or
// the other to avoid this confusion. // the other to avoid this confusion.
// //
// See https://github.com/square/go-jose/issues/157 for more context. // See https://github.com/go-jose/go-jose/issues/157 for more context.
if ctx.embedJWK { if ctx.embedJWK {
protected[headerJWK] = recipient.publicKey() protected[headerJWK] = recipient.publicKey()
} else { } else {
@ -265,7 +264,7 @@ func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
if ctx.nonceSource != nil { if ctx.nonceSource != nil {
nonce, err := ctx.nonceSource.Nonce() nonce, err := ctx.nonceSource.Nonce()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: Error generating nonce: %v", err) return nil, fmt.Errorf("go-jose/go-jose: Error generating nonce: %v", err)
} }
protected[headerNonce] = nonce protected[headerNonce] = nonce
} }
@ -279,7 +278,7 @@ func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
if b64, ok := protected[headerB64]; ok { if b64, ok := protected[headerB64]; ok {
if needsBase64, ok = b64.(bool); !ok { if needsBase64, ok = b64.(bool); !ok {
return nil, errors.New("square/go-jose: Invalid b64 header parameter") return nil, errors.New("go-jose/go-jose: Invalid b64 header parameter")
} }
} }
@ -303,7 +302,7 @@ func (ctx *genericSigner) Sign(payload []byte) (*JSONWebSignature, error) {
for k, v := range protected { for k, v := range protected {
b, err := json.Marshal(v) b, err := json.Marshal(v)
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: Error marshalling item %#v: %v", k, err) return nil, fmt.Errorf("go-jose/go-jose: Error marshalling item %#v: %v", k, err)
} }
(*signatureInfo.protected)[k] = makeRawMessage(b) (*signatureInfo.protected)[k] = makeRawMessage(b)
} }
@ -348,13 +347,14 @@ func (obj JSONWebSignature) UnsafePayloadWithoutVerification() []byte {
// is only useful if you have a payload and signature that are separated from // is only useful if you have a payload and signature that are separated from
// each other. // each other.
func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error { func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey interface{}) error {
verifier, err := newVerifier(verificationKey) key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key)
if err != nil { if err != nil {
return err return err
} }
if len(obj.Signatures) > 1 { if len(obj.Signatures) > 1 {
return errors.New("square/go-jose: too many signatures in payload; expecting only one") return errors.New("go-jose/go-jose: too many signatures in payload; expecting only one")
} }
signature := obj.Signatures[0] signature := obj.Signatures[0]
@ -406,7 +406,8 @@ func (obj JSONWebSignature) VerifyMulti(verificationKey interface{}) (int, Signa
// separated from each other, and the signature can have multiple signers at the // separated from each other, and the signature can have multiple signers at the
// same time. // same time.
func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) { func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey interface{}) (int, Signature, error) {
verifier, err := newVerifier(verificationKey) key := tryJWKS(verificationKey, obj.headers()...)
verifier, err := newVerifier(key)
if err != nil { if err != nil {
return -1, Signature{}, err return -1, Signature{}, err
} }
@ -439,3 +440,11 @@ outer:
return -1, Signature{}, ErrCryptoFailure return -1, Signature{}, ErrCryptoFailure
} }
func (obj JSONWebSignature) headers() []Header {
headers := make([]Header, len(obj.Signatures))
for i, sig := range obj.Signatures {
headers[i] = sig.Header
}
return headers
}

View File

@ -31,10 +31,11 @@ import (
"io" "io"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
"gopkg.in/square/go-jose.v2/cipher"
josecipher "github.com/go-jose/go-jose/v3/cipher"
) )
// Random reader (stubbed out in tests) // RandReader is a cryptographically secure random number generator (stubbed out in tests).
var RandReader = rand.Reader var RandReader = rand.Reader
const ( const (
@ -278,8 +279,14 @@ func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
} }
header := &rawHeader{} header := &rawHeader{}
header.set(headerIV, newBuffer(parts.iv))
header.set(headerTag, newBuffer(parts.tag)) if err = header.set(headerIV, newBuffer(parts.iv)); err != nil {
return recipientInfo{}, err
}
if err = header.set(headerTag, newBuffer(parts.tag)); err != nil {
return recipientInfo{}, err
}
return recipientInfo{ return recipientInfo{
header: header, header: header,
@ -332,8 +339,14 @@ func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
} }
header := &rawHeader{} header := &rawHeader{}
header.set(headerP2C, ctx.p2c)
header.set(headerP2S, newBuffer(ctx.p2s)) if err = header.set(headerP2C, ctx.p2c); err != nil {
return recipientInfo{}, err
}
if err = header.set(headerP2S, newBuffer(ctx.p2s)); err != nil {
return recipientInfo{}, err
}
return recipientInfo{ return recipientInfo{
encryptedKey: jek, encryptedKey: jek,
@ -356,11 +369,11 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
iv, err := headers.getIV() iv, err := headers.getIV()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid IV: %v", err) return nil, fmt.Errorf("go-jose/go-jose: invalid IV: %v", err)
} }
tag, err := headers.getTag() tag, err := headers.getTag()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid tag: %v", err) return nil, fmt.Errorf("go-jose/go-jose: invalid tag: %v", err)
} }
parts := &aeadParts{ parts := &aeadParts{
@ -389,18 +402,18 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW: case PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW:
p2s, err := headers.getP2S() p2s, err := headers.getP2S()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid P2S: %v", err) return nil, fmt.Errorf("go-jose/go-jose: invalid P2S: %v", err)
} }
if p2s == nil || len(p2s.data) == 0 { if p2s == nil || len(p2s.data) == 0 {
return nil, fmt.Errorf("square/go-jose: invalid P2S: must be present") return nil, fmt.Errorf("go-jose/go-jose: invalid P2S: must be present")
} }
p2c, err := headers.getP2C() p2c, err := headers.getP2C()
if err != nil { if err != nil {
return nil, fmt.Errorf("square/go-jose: invalid P2C: %v", err) return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: %v", err)
} }
if p2c <= 0 { if p2c <= 0 {
return nil, fmt.Errorf("square/go-jose: invalid P2C: must be a positive integer") return nil, fmt.Errorf("go-jose/go-jose: invalid P2C: must be a positive integer")
} }
// salt is UTF8(Alg) || 0x00 || Salt Input // salt is UTF8(Alg) || 0x00 || Salt Input
@ -431,7 +444,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
mac, err := ctx.hmac(payload, alg) mac, err := ctx.hmac(payload, alg)
if err != nil { if err != nil {
return Signature{}, errors.New("square/go-jose: failed to compute hmac") return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac")
} }
return Signature{ return Signature{
@ -444,16 +457,16 @@ func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Sig
func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureAlgorithm) error { func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureAlgorithm) error {
expected, err := ctx.hmac(payload, alg) expected, err := ctx.hmac(payload, alg)
if err != nil { if err != nil {
return errors.New("square/go-jose: failed to compute hmac") return errors.New("go-jose/go-jose: failed to compute hmac")
} }
if len(mac) != len(expected) { if len(mac) != len(expected) {
return errors.New("square/go-jose: invalid hmac") return errors.New("go-jose/go-jose: invalid hmac")
} }
match := subtle.ConstantTimeCompare(mac, expected) match := subtle.ConstantTimeCompare(mac, expected)
if match != 1 { if match != 1 {
return errors.New("square/go-jose: invalid hmac") return errors.New("go-jose/go-jose: invalid hmac")
} }
return nil return nil

View File

@ -1280,8 +1280,9 @@ func (c *Client) NewRequest(method, requestPath string) *Request {
// a Vault server not configured with this client. This is an advanced operation // a Vault server not configured with this client. This is an advanced operation
// that generally won't need to be called externally. // that generally won't need to be called externally.
// //
// Deprecated: This method should not be used directly. Use higher level // Deprecated: RawRequest exists for historical compatibility and should not be
// methods instead. // used directly. Use client.Logical().ReadRaw(...) or higher level methods
// instead.
func (c *Client) RawRequest(r *Request) (*Response, error) { func (c *Client) RawRequest(r *Request) (*Response, error) {
return c.RawRequestWithContext(context.Background(), r) return c.RawRequestWithContext(context.Background(), r)
} }
@ -1290,8 +1291,9 @@ func (c *Client) RawRequest(r *Request) (*Response, error) {
// a Vault server not configured with this client. This is an advanced operation // a Vault server not configured with this client. This is an advanced operation
// that generally won't need to be called externally. // that generally won't need to be called externally.
// //
// Deprecated: This method should not be used directly. Use higher level // Deprecated: RawRequestWithContext exists for historical compatibility and
// methods instead. // should not be used directly. Use client.Logical().ReadRawWithContext(...)
// or higher level methods instead.
func (c *Client) RawRequestWithContext(ctx context.Context, r *Request) (*Response, error) { func (c *Client) RawRequestWithContext(ctx context.Context, r *Request) (*Response, error) {
// Note: we purposefully do not call cancel manually. The reason is // Note: we purposefully do not call cancel manually. The reason is
// when canceled, the request.Body will EOF when reading due to the way // when canceled, the request.Body will EOF when reading due to the way

View File

@ -14,7 +14,7 @@ import (
"os" "os"
"regexp" "regexp"
squarejwt "gopkg.in/square/go-jose.v2/jwt" "github.com/go-jose/go-jose/v3/jwt"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
) )
@ -135,7 +135,7 @@ func VaultPluginTLSProviderContext(ctx context.Context, apiTLSConfig *TLSConfig)
return func() (*tls.Config, error) { return func() (*tls.Config, error) {
unwrapToken := os.Getenv(PluginUnwrapTokenEnv) unwrapToken := os.Getenv(PluginUnwrapTokenEnv)
parsedJWT, err := squarejwt.ParseSigned(unwrapToken) parsedJWT, err := jwt.ParseSigned(unwrapToken)
if err != nil { if err != nil {
return nil, errwrap.Wrapf("error parsing wrapping token: {{err}}", err) return nil, errwrap.Wrapf("error parsing wrapping token: {{err}}", err)
} }

View File

@ -150,8 +150,8 @@ TOKEN_DONE:
// Identity policies // Identity policies
{ {
_, ok := s.Data["identity_policies"] v, ok := s.Data["identity_policies"]
if !ok { if !ok || v == nil {
goto DONE goto DONE
} }

View File

@ -1 +0,0 @@
'|Ę&{tÄU|gGę(ěŹCy=+¨śňcű:u:/pś#~žü["±4¤!­nŮAŞDK<Šuf˙hĹażÂ:şü¸ˇ´B/ŁŘ¤ą¤ň_<C588>hÎŰSăT*wĚxĽŻťą-ç|ťŕŔÓ<C594>ŃÄäóĚ㣗A$$â6ŁÁâG)8nĎpűĆˡ3ĚšśoďĎB­]xÝ“Ó2l§G•|qRŢŻ ö2 5R–Ó×Ç$´ń˝YčˇŢÝ™lË«yAI"ŰŚ<C5B0>®íĂ»ąĽkÄ|Kĺţ[9ĆâŇĺ=°ú˙źń|@S•3 ó#ćťx?ľV„,ľSĆÝőśwPíogŇ6&V6 ©D.dBŠ 7

View File

@ -1,45 +0,0 @@
language: go
sudo: false
matrix:
fast_finish: true
allow_failures:
- go: tip
go:
- '1.14.x'
- '1.15.x'
- tip
go_import_path: gopkg.in/square/go-jose.v2
before_script:
- export PATH=$HOME/.local/bin:$PATH
before_install:
# Install encrypted gitcookies to get around bandwidth-limits
# that is causing Travis-CI builds to fail. For more info, see
# https://github.com/golang/go/issues/12933
- openssl aes-256-cbc -K $encrypted_1528c3c2cafd_key -iv $encrypted_1528c3c2cafd_iv -in .gitcookies.sh.enc -out .gitcookies.sh -d || true
- bash .gitcookies.sh || true
- 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
script:
- go test . -v -covermode=count -coverprofile=profile.cov
- 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 ..
after_success:
- gocovmerge *.cov */*.cov > merged.coverprofile
- $HOME/gopath/bin/goveralls -coverprofile merged.coverprofile -service=travis-ci

14
vendor/modules.txt vendored
View File

@ -194,6 +194,12 @@ github.com/gemalto/kmip-go/ttlv
# github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 # github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
## explicit ## explicit
github.com/ghodss/yaml github.com/ghodss/yaml
# github.com/go-jose/go-jose/v3 v3.0.0
## 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-logr/logr v1.2.4 # github.com/go-logr/logr v1.2.4
## explicit; go 1.16 ## explicit; go 1.16
github.com/go-logr/logr github.com/go-logr/logr
@ -321,7 +327,7 @@ github.com/hashicorp/hcl/json/token
## explicit; go 1.19 ## explicit; go 1.19
github.com/hashicorp/vault/command/agent/auth github.com/hashicorp/vault/command/agent/auth
github.com/hashicorp/vault/command/agent/auth/kubernetes github.com/hashicorp/vault/command/agent/auth/kubernetes
# github.com/hashicorp/vault/api v1.9.1 # github.com/hashicorp/vault/api v1.9.2
## explicit; go 1.19 ## explicit; go 1.19
github.com/hashicorp/vault/api github.com/hashicorp/vault/api
# github.com/hashicorp/vault/sdk v0.7.0 # github.com/hashicorp/vault/sdk v0.7.0
@ -737,12 +743,6 @@ google.golang.org/protobuf/types/known/wrapperspb
# gopkg.in/inf.v0 v0.9.1 # gopkg.in/inf.v0 v0.9.1
## explicit ## explicit
gopkg.in/inf.v0 gopkg.in/inf.v0
# gopkg.in/square/go-jose.v2 v2.6.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/yaml.v2 v2.4.0 # gopkg.in/yaml.v2 v2.4.0
## explicit; go 1.15 ## explicit; go 1.15
gopkg.in/yaml.v2 gopkg.in/yaml.v2