mirror of
https://github.com/containers/skopeo.git
synced 2026-05-04 10:22:34 +00:00
Merge pull request #2852 from TomSweeneyRedHat/dev/tsweeney/release-1.20-cve-2026-34986
[release-1.20] Bump Go Jose v4.1.4, CVE-2026-34986
This commit is contained in:
4
go.mod
4
go.mod
@@ -1,7 +1,7 @@
|
||||
module github.com/containers/skopeo
|
||||
|
||||
// Minimum required golang version
|
||||
go 1.23.3
|
||||
go 1.24.0
|
||||
|
||||
// Warning: Ensure the "go" and "toolchain" versions match exactly to prevent unwanted auto-updates
|
||||
|
||||
@@ -48,7 +48,7 @@ require (
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -87,8 +87,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
|
||||
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
96
vendor/github.com/go-jose/go-jose/v4/CHANGELOG.md
generated
vendored
@@ -1,96 +0,0 @@
|
||||
# v4.0.4
|
||||
|
||||
## Fixed
|
||||
|
||||
- Reverted "Allow unmarshalling JSONWebKeySets with unsupported key types" as a
|
||||
breaking change. See #136 / #137.
|
||||
|
||||
# v4.0.3
|
||||
|
||||
## Changed
|
||||
|
||||
- Allow unmarshalling JSONWebKeySets with unsupported key types (#130)
|
||||
- Document that OpaqueKeyEncrypter can't be implemented (for now) (#129)
|
||||
- Dependency updates
|
||||
|
||||
# v4.0.2
|
||||
|
||||
## Changed
|
||||
|
||||
- Improved documentation of Verify() to note that JSONWebKeySet is a supported
|
||||
argument type (#104)
|
||||
- Defined exported error values for missing x5c header and unsupported elliptic
|
||||
curves error cases (#117)
|
||||
|
||||
# v4.0.1
|
||||
|
||||
## Fixed
|
||||
|
||||
- An attacker could send a JWE containing compressed data that used large
|
||||
amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
|
||||
Those functions now return an error if the decompressed data would exceed
|
||||
250kB or 10x the compressed size (whichever is larger). Thanks to
|
||||
Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
|
||||
for reporting.
|
||||
|
||||
# v4.0.0
|
||||
|
||||
This release makes some breaking changes in order to more thoroughly
|
||||
address the vulnerabilities discussed in [Three New Attacks Against JSON Web
|
||||
Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
|
||||
token".
|
||||
|
||||
## Changed
|
||||
|
||||
- Limit JWT encryption types (exclude password or public key types) (#78)
|
||||
- Enforce minimum length for HMAC keys (#85)
|
||||
- jwt: match any audience in a list, rather than requiring all audiences (#81)
|
||||
- jwt: accept only Compact Serialization (#75)
|
||||
- jws: Add expected algorithms for signatures (#74)
|
||||
- Require specifying expected algorithms for ParseEncrypted,
|
||||
ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
|
||||
jwt.ParseSignedAndEncrypted (#69, #74)
|
||||
- Usually there is a small, known set of appropriate algorithms for a program
|
||||
to use and it's a mistake to allow unexpected algorithms. For instance the
|
||||
"billion hash attack" relies in part on programs accepting the PBES2
|
||||
encryption algorithm and doing the necessary work even if they weren't
|
||||
specifically configured to allow PBES2.
|
||||
- Revert "Strip padding off base64 strings" (#82)
|
||||
- The specs require base64url encoding without padding.
|
||||
- Minimum supported Go version is now 1.21
|
||||
|
||||
## Added
|
||||
|
||||
- ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
|
||||
- These allow parsing a specific serialization, as opposed to ParseSigned and
|
||||
ParseEncrypted, which try to automatically detect which serialization was
|
||||
provided. It's common to require a specific serialization for a specific
|
||||
protocol - for instance JWT requires Compact serialization.
|
||||
|
||||
[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
|
||||
|
||||
# v3.0.2
|
||||
|
||||
## Fixed
|
||||
|
||||
- DecryptMulti: handle decompression error (#19)
|
||||
|
||||
## Changed
|
||||
|
||||
- jwe/CompactSerialize: improve performance (#67)
|
||||
- Increase the default number of PBKDF2 iterations to 600k (#48)
|
||||
- Return the proper algorithm for ECDSA keys (#45)
|
||||
|
||||
## Added
|
||||
|
||||
- Add Thumbprint support for opaque signers (#38)
|
||||
|
||||
# v3.0.1
|
||||
|
||||
## Fixed
|
||||
|
||||
- Security issue: an attacker specifying a large "p2c" value can cause
|
||||
JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
|
||||
amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
|
||||
disclosure and to Tom Tervoort for originally publishing the category of attack.
|
||||
https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
|
||||
76
vendor/github.com/go-jose/go-jose/v4/README.md
generated
vendored
76
vendor/github.com/go-jose/go-jose/v4/README.md
generated
vendored
@@ -3,7 +3,6 @@
|
||||
[](https://pkg.go.dev/github.com/go-jose/go-jose/v4)
|
||||
[](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt)
|
||||
[](https://raw.githubusercontent.com/go-jose/go-jose/master/LICENSE)
|
||||
[](https://github.com/go-jose/go-jose/actions)
|
||||
|
||||
Package jose aims to provide an implementation of the Javascript Object Signing
|
||||
and Encryption set of standards. This includes support for JSON Web Encryption,
|
||||
@@ -29,17 +28,20 @@ libraries in other languages.
|
||||
|
||||
### Versions
|
||||
|
||||
[Version 4](https://github.com/go-jose/go-jose)
|
||||
([branch](https://github.com/go-jose/go-jose/tree/main),
|
||||
[doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version:
|
||||
The forthcoming Version 5 will be released with several breaking API changes,
|
||||
and will require Golang's `encoding/json/v2`, which is currently requires
|
||||
Go 1.25 built with GOEXPERIMENT=jsonv2.
|
||||
|
||||
Version 4 is the current stable version:
|
||||
|
||||
import "github.com/go-jose/go-jose/v4"
|
||||
|
||||
The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which
|
||||
are still useable but not actively developed anymore.
|
||||
It supports at least the current and previous Golang release. Currently it
|
||||
requires Golang 1.24.
|
||||
|
||||
Version 3, in this repo, is still receiving security fixes but not functionality
|
||||
updates.
|
||||
Version 3 is only receiving critical security updates. Migration to Version 4 is recommended.
|
||||
|
||||
Versions 1 and 2 are obsolete, but can be found in the old repository, [square/go-jose](https://github.com/square/go-jose).
|
||||
|
||||
### Supported algorithms
|
||||
|
||||
@@ -47,36 +49,36 @@ See below for a table of supported algorithms. Algorithm identifiers match
|
||||
the names in the [JSON Web Algorithms](https://dx.doi.org/10.17487/RFC7518)
|
||||
standard where possible. The Godoc reference has a list of constants.
|
||||
|
||||
Key encryption | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
RSA-PKCS#1v1.5 | RSA1_5
|
||||
RSA-OAEP | RSA-OAEP, RSA-OAEP-256
|
||||
AES key wrap | A128KW, A192KW, A256KW
|
||||
AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW
|
||||
ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW
|
||||
ECDH-ES (direct) | ECDH-ES<sup>1</sup>
|
||||
Direct encryption | dir<sup>1</sup>
|
||||
| Key encryption | Algorithm identifier(s) |
|
||||
|:-----------------------|:-----------------------------------------------|
|
||||
| RSA-PKCS#1v1.5 | RSA1_5 |
|
||||
| RSA-OAEP | RSA-OAEP, RSA-OAEP-256 |
|
||||
| AES key wrap | A128KW, A192KW, A256KW |
|
||||
| AES-GCM key wrap | A128GCMKW, A192GCMKW, A256GCMKW |
|
||||
| ECDH-ES + AES key wrap | ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW |
|
||||
| ECDH-ES (direct) | ECDH-ES<sup>1</sup> |
|
||||
| Direct encryption | dir<sup>1</sup> |
|
||||
|
||||
<sup>1. Not supported in multi-recipient mode</sup>
|
||||
|
||||
Signing / MAC | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
RSASSA-PKCS#1v1.5 | RS256, RS384, RS512
|
||||
RSASSA-PSS | PS256, PS384, PS512
|
||||
HMAC | HS256, HS384, HS512
|
||||
ECDSA | ES256, ES384, ES512
|
||||
Ed25519 | EdDSA<sup>2</sup>
|
||||
| Signing / MAC | Algorithm identifier(s) |
|
||||
|:------------------|:------------------------|
|
||||
| RSASSA-PKCS#1v1.5 | RS256, RS384, RS512 |
|
||||
| RSASSA-PSS | PS256, PS384, PS512 |
|
||||
| HMAC | HS256, HS384, HS512 |
|
||||
| ECDSA | ES256, ES384, ES512 |
|
||||
| Ed25519 | EdDSA<sup>2</sup> |
|
||||
|
||||
<sup>2. Only available in version 2 of the package</sup>
|
||||
|
||||
Content encryption | Algorithm identifier(s)
|
||||
:------------------------- | :------------------------------
|
||||
AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512
|
||||
AES-GCM | A128GCM, A192GCM, A256GCM
|
||||
| Content encryption | Algorithm identifier(s) |
|
||||
|:-------------------|:--------------------------------------------|
|
||||
| AES-CBC+HMAC | A128CBC-HS256, A192CBC-HS384, A256CBC-HS512 |
|
||||
| AES-GCM | A128GCM, A192GCM, A256GCM |
|
||||
|
||||
Compression | Algorithm identifiers(s)
|
||||
:------------------------- | -------------------------------
|
||||
DEFLATE (RFC 1951) | DEF
|
||||
| Compression | Algorithm identifiers(s) |
|
||||
|:-------------------|--------------------------|
|
||||
| DEFLATE (RFC 1951) | DEF |
|
||||
|
||||
### Supported key types
|
||||
|
||||
@@ -85,12 +87,12 @@ library, and can be passed to corresponding functions such as `NewEncrypter` or
|
||||
`NewSigner`. Each of these keys can also be wrapped in a JWK if desired, which
|
||||
allows attaching a key id.
|
||||
|
||||
Algorithm(s) | Corresponding types
|
||||
:------------------------- | -------------------------------
|
||||
RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey)
|
||||
ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey)
|
||||
EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey)
|
||||
AES, HMAC | []byte
|
||||
| Algorithm(s) | Corresponding types |
|
||||
|:------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| RSA | *[rsa.PublicKey](https://pkg.go.dev/crypto/rsa/#PublicKey), *[rsa.PrivateKey](https://pkg.go.dev/crypto/rsa/#PrivateKey) |
|
||||
| ECDH, ECDSA | *[ecdsa.PublicKey](https://pkg.go.dev/crypto/ecdsa/#PublicKey), *[ecdsa.PrivateKey](https://pkg.go.dev/crypto/ecdsa/#PrivateKey) |
|
||||
| EdDSA<sup>1</sup> | [ed25519.PublicKey](https://pkg.go.dev/crypto/ed25519#PublicKey), [ed25519.PrivateKey](https://pkg.go.dev/crypto/ed25519#PrivateKey) |
|
||||
| AES, HMAC | []byte |
|
||||
|
||||
<sup>1. Only available in version 2 or later of the package</sup>
|
||||
|
||||
|
||||
10
vendor/github.com/go-jose/go-jose/v4/asymmetric.go
generated
vendored
10
vendor/github.com/go-jose/go-jose/v4/asymmetric.go
generated
vendored
@@ -414,6 +414,9 @@ func (ctx ecKeyGenerator) genKey() ([]byte, rawHeader, error) {
|
||||
|
||||
// Decrypt the given payload and return the content encryption key.
|
||||
func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
|
||||
if recipient == nil {
|
||||
return nil, errors.New("go-jose/go-jose: missing recipient")
|
||||
}
|
||||
epk, err := headers.getEPK()
|
||||
if err != nil {
|
||||
return nil, errors.New("go-jose/go-jose: invalid epk header")
|
||||
@@ -461,13 +464,18 @@ func (ctx ecDecrypterSigner) decryptKey(headers rawHeader, recipient *recipientI
|
||||
return nil, ErrUnsupportedAlgorithm
|
||||
}
|
||||
|
||||
encryptedKey := recipient.encryptedKey
|
||||
if len(encryptedKey) == 0 {
|
||||
return nil, errors.New("go-jose/go-jose: missing JWE Encrypted Key")
|
||||
}
|
||||
|
||||
key := deriveKey(string(algorithm), keySize)
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return josecipher.KeyUnwrap(block, recipient.encryptedKey)
|
||||
return josecipher.KeyUnwrap(block, encryptedKey)
|
||||
}
|
||||
|
||||
func (ctx edDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
|
||||
|
||||
10
vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go
generated
vendored
10
vendor/github.com/go-jose/go-jose/v4/cipher/key_wrap.go
generated
vendored
@@ -66,12 +66,20 @@ 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.
|
||||
//
|
||||
// https://datatracker.ietf.org/doc/html/rfc7518#section-4.4
|
||||
// https://datatracker.ietf.org/doc/html/rfc7518#section-4.6
|
||||
// https://datatracker.ietf.org/doc/html/rfc7518#section-4.8
|
||||
func KeyUnwrap(block cipher.Block, ciphertext []byte) ([]byte, error) {
|
||||
n := (len(ciphertext) / 8) - 1
|
||||
if n <= 0 {
|
||||
return nil, errors.New("go-jose/go-jose: JWE Encrypted Key too short")
|
||||
}
|
||||
|
||||
if len(ciphertext)%8 != 0 {
|
||||
return nil, errors.New("go-jose/go-jose: key wrap input must be 8 byte blocks")
|
||||
}
|
||||
|
||||
n := (len(ciphertext) / 8) - 1
|
||||
r := make([][]byte, n)
|
||||
|
||||
for i := range r {
|
||||
|
||||
20
vendor/github.com/go-jose/go-jose/v4/crypter.go
generated
vendored
20
vendor/github.com/go-jose/go-jose/v4/crypter.go
generated
vendored
@@ -286,6 +286,10 @@ func makeJWERecipient(alg KeyAlgorithm, encryptionKey interface{}) (recipientKey
|
||||
return newSymmetricRecipient(alg, encryptionKey)
|
||||
case string:
|
||||
return newSymmetricRecipient(alg, []byte(encryptionKey))
|
||||
case JSONWebKey:
|
||||
recipient, err := makeJWERecipient(alg, encryptionKey.Key)
|
||||
recipient.keyID = encryptionKey.KeyID
|
||||
return recipient, err
|
||||
case *JSONWebKey:
|
||||
recipient, err := makeJWERecipient(alg, encryptionKey.Key)
|
||||
recipient.keyID = encryptionKey.KeyID
|
||||
@@ -450,13 +454,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
||||
return nil, errors.New("go-jose/go-jose: too many recipients in payload; expecting only one")
|
||||
}
|
||||
|
||||
critical, err := headers.getCritical()
|
||||
err := headers.checkNoCritical()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
|
||||
}
|
||||
|
||||
if len(critical) > 0 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||
@@ -523,13 +523,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
|
||||
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
|
||||
globalHeaders := obj.mergedHeaders(nil)
|
||||
|
||||
critical, err := globalHeaders.getCritical()
|
||||
err := globalHeaders.checkNoCritical()
|
||||
if err != nil {
|
||||
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: invalid crit header")
|
||||
}
|
||||
|
||||
if len(critical) > 0 {
|
||||
return -1, Header{}, nil, fmt.Errorf("go-jose/go-jose: unsupported crit header")
|
||||
return -1, Header{}, nil, err
|
||||
}
|
||||
|
||||
key, err := tryJWKS(decryptionKey, obj.Header)
|
||||
|
||||
19
vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
19
vendor/github.com/go-jose/go-jose/v4/jwe.go
generated
vendored
@@ -274,7 +274,7 @@ func validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncr
|
||||
if alg != "" && !containsKeyAlgorithm(keyAlgorithms, alg) {
|
||||
return fmt.Errorf("unexpected key algorithm %q; expected %q", alg, keyAlgorithms)
|
||||
}
|
||||
if alg != "" && !containsContentEncryption(contentEncryption, enc) {
|
||||
if enc != "" && !containsContentEncryption(contentEncryption, enc) {
|
||||
return fmt.Errorf("unexpected content encryption algorithm %q; expected %q", enc, contentEncryption)
|
||||
}
|
||||
return nil
|
||||
@@ -288,11 +288,20 @@ func ParseEncryptedCompact(
|
||||
keyAlgorithms []KeyAlgorithm,
|
||||
contentEncryption []ContentEncryption,
|
||||
) (*JSONWebEncryption, error) {
|
||||
// Five parts is four separators
|
||||
if strings.Count(input, ".") != 4 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts")
|
||||
var parts [5]string
|
||||
var ok bool
|
||||
|
||||
for i := range 4 {
|
||||
parts[i], input, ok = strings.Cut(input, ".")
|
||||
if !ok {
|
||||
return nil, errors.New("go-jose/go-jose: compact JWE format must have five parts")
|
||||
}
|
||||
}
|
||||
parts := strings.SplitN(input, ".", 5)
|
||||
// Validate that the last part does not contain more dots
|
||||
if strings.ContainsRune(input, '.') {
|
||||
return nil, errors.New("go-jose/go-jose: compact JWE format must have five parts")
|
||||
}
|
||||
parts[4] = input
|
||||
|
||||
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||
if err != nil {
|
||||
|
||||
59
vendor/github.com/go-jose/go-jose/v4/jwk.go
generated
vendored
59
vendor/github.com/go-jose/go-jose/v4/jwk.go
generated
vendored
@@ -175,6 +175,8 @@ func (k JSONWebKey) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
// UnmarshalJSON reads a key from its JSON representation.
|
||||
//
|
||||
// Returns ErrUnsupportedKeyType for unrecognized or unsupported "kty" header values.
|
||||
func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
||||
var raw rawJSONWebKey
|
||||
err = json.Unmarshal(data, &raw)
|
||||
@@ -228,7 +230,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
||||
}
|
||||
key, err = raw.symmetricKey()
|
||||
case "OKP":
|
||||
if raw.Crv == "Ed25519" && raw.X != nil {
|
||||
if raw.Crv == "Ed25519" {
|
||||
if raw.D != nil {
|
||||
key, err = raw.edPrivateKey()
|
||||
if err == nil {
|
||||
@@ -238,17 +240,27 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) {
|
||||
key, err = raw.edPublicKey()
|
||||
keyPub = key
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("go-jose/go-jose: unknown curve %s'", raw.Crv)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("go-jose/go-jose: unknown json web key type '%s'", raw.Kty)
|
||||
case "":
|
||||
// kty MUST be present
|
||||
err = fmt.Errorf("go-jose/go-jose: missing json web key type")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if key == nil {
|
||||
// RFC 7517:
|
||||
// 5. JWK Set Format
|
||||
// ...
|
||||
// Implementations SHOULD ignore JWKs within a JWK Set that use "kty"
|
||||
// (key type) values that are not understood by them, that are missing
|
||||
// required members, or for which values are out of the supported
|
||||
// ranges.
|
||||
return ErrUnsupportedKeyType
|
||||
}
|
||||
|
||||
if certPub != nil && keyPub != nil {
|
||||
if !reflect.DeepEqual(certPub, keyPub) {
|
||||
return errors.New("go-jose/go-jose: invalid JWK, public keys in key and x5c fields do not match")
|
||||
@@ -581,10 +593,10 @@ func fromEcPublicKey(pub *ecdsa.PublicKey) (*rawJSONWebKey, error) {
|
||||
|
||||
func (key rawJSONWebKey) edPrivateKey() (ed25519.PrivateKey, error) {
|
||||
var missing []string
|
||||
switch {
|
||||
case key.D == nil:
|
||||
if key.D == nil {
|
||||
missing = append(missing, "D")
|
||||
case key.X == nil:
|
||||
}
|
||||
if key.X == nil {
|
||||
missing = append(missing, "X")
|
||||
}
|
||||
|
||||
@@ -611,19 +623,21 @@ func (key rawJSONWebKey) edPublicKey() (ed25519.PublicKey, error) {
|
||||
|
||||
func (key rawJSONWebKey) rsaPrivateKey() (*rsa.PrivateKey, error) {
|
||||
var missing []string
|
||||
switch {
|
||||
case key.N == nil:
|
||||
if key.N == nil {
|
||||
missing = append(missing, "N")
|
||||
case key.E == nil:
|
||||
}
|
||||
if key.E == nil {
|
||||
missing = append(missing, "E")
|
||||
case key.D == nil:
|
||||
}
|
||||
if key.D == nil {
|
||||
missing = append(missing, "D")
|
||||
case key.P == nil:
|
||||
}
|
||||
if key.P == nil {
|
||||
missing = append(missing, "P")
|
||||
case key.Q == nil:
|
||||
}
|
||||
if key.Q == nil {
|
||||
missing = append(missing, "Q")
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: invalid RSA private key, missing %s value(s)", strings.Join(missing, ", "))
|
||||
}
|
||||
@@ -698,8 +712,19 @@ func (key rawJSONWebKey) ecPrivateKey() (*ecdsa.PrivateKey, error) {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: unsupported elliptic curve '%s'", key.Crv)
|
||||
}
|
||||
|
||||
if key.X == nil || key.Y == nil || key.D == nil {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, missing x/y/d values")
|
||||
var missing []string
|
||||
if key.X == nil {
|
||||
missing = append(missing, "X")
|
||||
}
|
||||
if key.Y == nil {
|
||||
missing = append(missing, "Y")
|
||||
}
|
||||
if key.D == nil {
|
||||
missing = append(missing, "D")
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: invalid EC private key, missing %s value(s)", strings.Join(missing, ", "))
|
||||
}
|
||||
|
||||
// The length of this octet string MUST be the full size of a coordinate for
|
||||
|
||||
74
vendor/github.com/go-jose/go-jose/v4/jws.go
generated
vendored
74
vendor/github.com/go-jose/go-jose/v4/jws.go
generated
vendored
@@ -75,7 +75,14 @@ type Signature struct {
|
||||
original *rawSignatureInfo
|
||||
}
|
||||
|
||||
// ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization.
|
||||
// ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization. Validation fails if
|
||||
// the JWS is signed with an algorithm that isn't in the provided list of signature algorithms.
|
||||
// Applications should decide for themselves which signature algorithms are acceptable. If you're
|
||||
// not sure which signature algorithms your application might receive, consult the documentation of
|
||||
// the program which provides them or the protocol that you are implementing. You can also try
|
||||
// getting an example JWS and decoding it with a tool like https://jwt.io to see what its "alg"
|
||||
// header parameter indicates. The signature on the JWS does not get validated during parsing. Call
|
||||
// Verify() after parsing to validate the signature and obtain the payload.
|
||||
//
|
||||
// https://datatracker.ietf.org/doc/html/rfc7515#section-7
|
||||
func ParseSigned(
|
||||
@@ -90,7 +97,14 @@ func ParseSigned(
|
||||
return parseSignedCompact(signature, nil, signatureAlgorithms)
|
||||
}
|
||||
|
||||
// ParseSignedCompact parses a message in JWS Compact Serialization.
|
||||
// ParseSignedCompact parses a message in JWS Compact Serialization. Validation fails if the JWS is
|
||||
// signed with an algorithm that isn't in the provided list of signature algorithms. Applications
|
||||
// should decide for themselves which signature algorithms are acceptable.If you're not sure which
|
||||
// signature algorithms your application might receive, consult the documentation of the program
|
||||
// which provides them or the protocol that you are implementing. You can also try getting an
|
||||
// example JWS and decoding it with a tool like https://jwt.io to see what its "alg" header
|
||||
// parameter indicates. The signature on the JWS does not get validated during parsing. Call
|
||||
// Verify() after parsing to validate the signature and obtain the payload.
|
||||
//
|
||||
// https://datatracker.ietf.org/doc/html/rfc7515#section-7.1
|
||||
func ParseSignedCompact(
|
||||
@@ -101,6 +115,15 @@ func ParseSignedCompact(
|
||||
}
|
||||
|
||||
// ParseDetached parses a signed message in compact serialization format with detached payload.
|
||||
// Validation fails if the JWS is signed with an algorithm that isn't in the provided list of
|
||||
// signature algorithms. Applications should decide for themselves which signature algorithms are
|
||||
// acceptable. If you're not sure which signature algorithms your application might receive, consult
|
||||
// the documentation of the program which provides them or the protocol that you are implementing.
|
||||
// You can also try getting an example JWS and decoding it with a tool like https://jwt.io to see
|
||||
// what its "alg" header parameter indicates. The signature on the JWS does not get validated during
|
||||
// parsing. Call Verify() after parsing to validate the signature and obtain the payload.
|
||||
//
|
||||
// https://datatracker.ietf.org/doc/html/rfc7515#appendix-F
|
||||
func ParseDetached(
|
||||
signature string,
|
||||
payload []byte,
|
||||
@@ -181,6 +204,25 @@ func containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureA
|
||||
return false
|
||||
}
|
||||
|
||||
// ErrUnexpectedSignatureAlgorithm is returned when the signature algorithm in
|
||||
// the JWS header does not match one of the expected algorithms.
|
||||
type ErrUnexpectedSignatureAlgorithm struct {
|
||||
// Got is the signature algorithm found in the JWS header.
|
||||
Got SignatureAlgorithm
|
||||
expected []SignatureAlgorithm
|
||||
}
|
||||
|
||||
func (e *ErrUnexpectedSignatureAlgorithm) Error() string {
|
||||
return fmt.Sprintf("unexpected signature algorithm %q; expected %q", e.Got, e.expected)
|
||||
}
|
||||
|
||||
func newErrUnexpectedSignatureAlgorithm(got SignatureAlgorithm, expected []SignatureAlgorithm) error {
|
||||
return &ErrUnexpectedSignatureAlgorithm{
|
||||
Got: got,
|
||||
expected: expected,
|
||||
}
|
||||
}
|
||||
|
||||
// sanitized produces a cleaned-up JWS object from the raw JSON.
|
||||
func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) {
|
||||
if len(signatureAlgorithms) == 0 {
|
||||
@@ -236,8 +278,7 @@ func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgo
|
||||
|
||||
alg := SignatureAlgorithm(signature.Header.Algorithm)
|
||||
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
|
||||
alg, signatureAlgorithms)
|
||||
return nil, newErrUnexpectedSignatureAlgorithm(alg, signatureAlgorithms)
|
||||
}
|
||||
|
||||
if signature.header != nil {
|
||||
@@ -285,8 +326,7 @@ func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgo
|
||||
|
||||
alg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm)
|
||||
if !containsSignatureAlgorithm(signatureAlgorithms, alg) {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q",
|
||||
alg, signatureAlgorithms)
|
||||
return nil, newErrUnexpectedSignatureAlgorithm(alg, signatureAlgorithms)
|
||||
}
|
||||
|
||||
if obj.Signatures[i].header != nil {
|
||||
@@ -321,35 +361,43 @@ func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgo
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
const tokenDelim = "."
|
||||
|
||||
// parseSignedCompact parses a message in compact format.
|
||||
func parseSignedCompact(
|
||||
input string,
|
||||
payload []byte,
|
||||
signatureAlgorithms []SignatureAlgorithm,
|
||||
) (*JSONWebSignature, error) {
|
||||
// Three parts is two separators
|
||||
if strings.Count(input, ".") != 2 {
|
||||
protected, s, ok := strings.Cut(input, tokenDelim)
|
||||
if !ok { // no period found
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
||||
}
|
||||
claims, sig, ok := strings.Cut(s, tokenDelim)
|
||||
if !ok { // only one period found
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
||||
}
|
||||
if strings.ContainsRune(sig, '.') { // too many periods found
|
||||
return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts")
|
||||
}
|
||||
parts := strings.SplitN(input, ".", 3)
|
||||
|
||||
if parts[1] != "" && payload != nil {
|
||||
if claims != "" && payload != nil {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: payload is not detached")
|
||||
}
|
||||
|
||||
rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0])
|
||||
rawProtected, err := base64.RawURLEncoding.DecodeString(protected)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if payload == nil {
|
||||
payload, err = base64.RawURLEncoding.DecodeString(parts[1])
|
||||
payload, err = base64.RawURLEncoding.DecodeString(claims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
signature, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||
signature, err := base64.RawURLEncoding.DecodeString(sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
33
vendor/github.com/go-jose/go-jose/v4/shared.go
generated
vendored
33
vendor/github.com/go-jose/go-jose/v4/shared.go
generated
vendored
@@ -77,6 +77,9 @@ var (
|
||||
|
||||
// ErrUnsupportedEllipticCurve indicates unsupported or unknown elliptic curve has been found.
|
||||
ErrUnsupportedEllipticCurve = errors.New("go-jose/go-jose: unsupported/unknown elliptic curve")
|
||||
|
||||
// ErrUnsupportedCriticalHeader is returned when a header is marked critical but not supported by go-jose.
|
||||
ErrUnsupportedCriticalHeader = errors.New("go-jose/go-jose: unsupported critical header")
|
||||
)
|
||||
|
||||
// Key management algorithms
|
||||
@@ -167,8 +170,8 @@ const (
|
||||
)
|
||||
|
||||
// supportedCritical is the set of supported extensions that are understood and processed.
|
||||
var supportedCritical = map[string]bool{
|
||||
headerB64: true,
|
||||
var supportedCritical = map[string]struct{}{
|
||||
headerB64: {},
|
||||
}
|
||||
|
||||
// rawHeader represents the JOSE header for JWE/JWS objects (used for parsing).
|
||||
@@ -346,6 +349,32 @@ func (parsed rawHeader) getCritical() ([]string, error) {
|
||||
return q, nil
|
||||
}
|
||||
|
||||
// checkNoCritical verifies there are no critical headers present.
|
||||
func (parsed rawHeader) checkNoCritical() error {
|
||||
if _, ok := parsed[headerCritical]; ok {
|
||||
return ErrUnsupportedCriticalHeader
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkSupportedCritical verifies there are no unsupported critical headers.
|
||||
// Supported headers are passed in as a set: map of names to empty structs
|
||||
func (parsed rawHeader) checkSupportedCritical(supported map[string]struct{}) error {
|
||||
crit, err := parsed.getCritical()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range crit {
|
||||
if _, ok := supported[name]; !ok {
|
||||
return ErrUnsupportedCriticalHeader
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getS2C extracts parsed "p2c" from the raw JSON.
|
||||
func (parsed rawHeader) getP2C() (int, error) {
|
||||
v := parsed[headerP2C]
|
||||
|
||||
44
vendor/github.com/go-jose/go-jose/v4/signing.go
generated
vendored
44
vendor/github.com/go-jose/go-jose/v4/signing.go
generated
vendored
@@ -404,15 +404,23 @@ func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey inter
|
||||
}
|
||||
|
||||
signature := obj.Signatures[0]
|
||||
headers := signature.mergedHeaders()
|
||||
critical, err := headers.getCritical()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
if signature.header != nil {
|
||||
// Per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11,
|
||||
// 4.1.11. "crit" (Critical) Header Parameter
|
||||
// "When used, this Header Parameter MUST be integrity
|
||||
// protected; therefore, it MUST occur only within the JWS
|
||||
// Protected Header."
|
||||
err = signature.header.checkNoCritical()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range critical {
|
||||
if !supportedCritical[name] {
|
||||
return ErrCryptoFailure
|
||||
if signature.protected != nil {
|
||||
err = signature.protected.checkSupportedCritical(supportedCritical)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,6 +429,7 @@ func (obj JSONWebSignature) DetachedVerify(payload []byte, verificationKey inter
|
||||
return ErrCryptoFailure
|
||||
}
|
||||
|
||||
headers := signature.mergedHeaders()
|
||||
alg := headers.getSignatureAlgorithm()
|
||||
err = verifier.verifyPayload(input, signature.Signature, alg)
|
||||
if err == nil {
|
||||
@@ -469,14 +478,22 @@ func (obj JSONWebSignature) DetachedVerifyMulti(payload []byte, verificationKey
|
||||
|
||||
outer:
|
||||
for i, signature := range obj.Signatures {
|
||||
headers := signature.mergedHeaders()
|
||||
critical, err := headers.getCritical()
|
||||
if err != nil {
|
||||
continue
|
||||
if signature.header != nil {
|
||||
// Per https://www.rfc-editor.org/rfc/rfc7515.html#section-4.1.11,
|
||||
// 4.1.11. "crit" (Critical) Header Parameter
|
||||
// "When used, this Header Parameter MUST be integrity
|
||||
// protected; therefore, it MUST occur only within the JWS
|
||||
// Protected Header."
|
||||
err = signature.header.checkNoCritical()
|
||||
if err != nil {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range critical {
|
||||
if !supportedCritical[name] {
|
||||
if signature.protected != nil {
|
||||
// Check for only supported critical headers
|
||||
err = signature.protected.checkSupportedCritical(supportedCritical)
|
||||
if err != nil {
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
@@ -486,6 +503,7 @@ outer:
|
||||
continue
|
||||
}
|
||||
|
||||
headers := signature.mergedHeaders()
|
||||
alg := headers.getSignatureAlgorithm()
|
||||
err = verifier.verifyPayload(input, signature.Signature, alg)
|
||||
if err == nil {
|
||||
|
||||
39
vendor/github.com/go-jose/go-jose/v4/symmetric.go
generated
vendored
39
vendor/github.com/go-jose/go-jose/v4/symmetric.go
generated
vendored
@@ -21,6 +21,7 @@ import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/hmac"
|
||||
"crypto/pbkdf2"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
@@ -30,8 +31,6 @@ import (
|
||||
"hash"
|
||||
"io"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
josecipher "github.com/go-jose/go-jose/v4/cipher"
|
||||
)
|
||||
|
||||
@@ -330,7 +329,10 @@ func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
|
||||
|
||||
// derive key
|
||||
keyLen, h := getPbkdf2Params(alg)
|
||||
key := pbkdf2.Key(ctx.key, salt, ctx.p2c, keyLen, h)
|
||||
key, err := pbkdf2.Key(h, string(ctx.key), salt, ctx.p2c, keyLen)
|
||||
if err != nil {
|
||||
return recipientInfo{}, nil
|
||||
}
|
||||
|
||||
// use AES cipher with derived key
|
||||
block, err := aes.NewCipher(key)
|
||||
@@ -364,11 +366,21 @@ func (ctx *symmetricKeyCipher) encryptKey(cek []byte, alg KeyAlgorithm) (recipie
|
||||
|
||||
// Decrypt the content encryption key.
|
||||
func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipientInfo, generator keyGenerator) ([]byte, error) {
|
||||
switch headers.getAlgorithm() {
|
||||
case DIRECT:
|
||||
cek := make([]byte, len(ctx.key))
|
||||
copy(cek, ctx.key)
|
||||
return cek, nil
|
||||
if recipient == nil {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: missing recipient")
|
||||
}
|
||||
|
||||
alg := headers.getAlgorithm()
|
||||
if alg == DIRECT {
|
||||
return bytes.Clone(ctx.key), nil
|
||||
}
|
||||
|
||||
encryptedKey := recipient.encryptedKey
|
||||
if len(encryptedKey) == 0 {
|
||||
return nil, fmt.Errorf("go-jose/go-jose: missing JWE Encrypted Key")
|
||||
}
|
||||
|
||||
switch alg {
|
||||
case A128GCMKW, A192GCMKW, A256GCMKW:
|
||||
aead := newAESGCM(len(ctx.key))
|
||||
|
||||
@@ -383,7 +395,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
||||
|
||||
parts := &aeadParts{
|
||||
iv: iv.bytes(),
|
||||
ciphertext: recipient.encryptedKey,
|
||||
ciphertext: encryptedKey,
|
||||
tag: tag.bytes(),
|
||||
}
|
||||
|
||||
@@ -399,7 +411,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)
|
||||
cek, err := josecipher.KeyUnwrap(block, encryptedKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -432,7 +444,10 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
||||
|
||||
// derive key
|
||||
keyLen, h := getPbkdf2Params(alg)
|
||||
key := pbkdf2.Key(ctx.key, salt, p2c, keyLen, h)
|
||||
key, err := pbkdf2.Key(h, string(ctx.key), salt, p2c, keyLen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// use AES cipher with derived key
|
||||
block, err := aes.NewCipher(key)
|
||||
@@ -440,7 +455,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cek, err := josecipher.KeyUnwrap(block, recipient.encryptedKey)
|
||||
cek, err := josecipher.KeyUnwrap(block, encryptedKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@@ -284,8 +284,8 @@ github.com/docker/go-units
|
||||
# github.com/felixge/httpsnoop v1.0.4
|
||||
## explicit; go 1.13
|
||||
github.com/felixge/httpsnoop
|
||||
# github.com/go-jose/go-jose/v4 v4.0.5
|
||||
## explicit; go 1.21
|
||||
# github.com/go-jose/go-jose/v4 v4.1.4
|
||||
## explicit; go 1.24.0
|
||||
github.com/go-jose/go-jose/v4
|
||||
github.com/go-jose/go-jose/v4/cipher
|
||||
github.com/go-jose/go-jose/v4/json
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package version
|
||||
|
||||
// Version is the version of the build.
|
||||
const Version = "1.20.0"
|
||||
const Version = "1.20.1"
|
||||
|
||||
Reference in New Issue
Block a user