From 523fcf74943c90c5a7d40b947eb4fdb68d6d2de2 Mon Sep 17 00:00:00 2001 From: Tom Sweeney Date: Wed, 29 Apr 2026 17:29:31 -0400 Subject: [PATCH 1/3] [release-1.11] Bump Go Jose to v3.0.5, CVE-2026-34986 Bump Go Jose to v3.0.5 to address CVE-2026-34986 Fixes: https://redhat.atlassian.net/browse/OCPBUGS-81778, https://redhat.atlassian.net/browse/OCPBUGS-81771, https://redhat.atlassian.net/browse/OCPBUGS-81767, https://redhat.atlassian.net/browse/OCPBUGS-81764, https://redhat.atlassian.net/browse/RHEL-164982, https://redhat.atlassian.net/browse/RHEL-164980 Signed-off-by: Tom Sweeney --- go.mod | 4 +-- go.sum | 4 +-- .../go-jose/go-jose/v3/asymmetric.go | 10 ++++++- .../go-jose/go-jose/v3/cipher/key_wrap.go | 10 ++++++- vendor/github.com/go-jose/go-jose/v3/jwe.go | 5 ++-- vendor/github.com/go-jose/go-jose/v3/jws.go | 5 ++-- .../go-jose/go-jose/v3/symmetric.go | 26 +++++++++++++------ vendor/modules.txt | 2 +- 8 files changed, 47 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 1612001b2..4bd0f63d4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/containers/skopeo -go 1.17 +go 1.20 require ( github.com/containers/common v0.51.4 @@ -41,7 +41,7 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-jose/go-jose/v3 v3.0.5 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect diff --git a/go.sum b/go.sum index d4613a36d..2ea568d61 100644 --- a/go.sum +++ b/go.sum @@ -322,8 +322,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= -github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= -github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ= +github.com/go-jose/go-jose/v3 v3.0.5/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= 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-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= diff --git a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go b/vendor/github.com/go-jose/go-jose/v3/asymmetric.go index d4d4961b2..79d9ee57c 100644 --- a/vendor/github.com/go-jose/go-jose/v3/asymmetric.go +++ b/vendor/github.com/go-jose/go-jose/v3/asymmetric.go @@ -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) { diff --git a/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go b/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go index b9effbca8..a2f86e3db 100644 --- a/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go +++ b/vendor/github.com/go-jose/go-jose/v3/cipher/key_wrap.go @@ -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 { diff --git a/vendor/github.com/go-jose/go-jose/v3/jwe.go b/vendor/github.com/go-jose/go-jose/v3/jwe.go index 4267ac750..1ba4ae0c0 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jwe.go +++ b/vendor/github.com/go-jose/go-jose/v3/jwe.go @@ -202,10 +202,11 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { // parseEncryptedCompact parses a message in compact format. func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { - parts := strings.Split(input, ".") - if len(parts) != 5 { + // 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") } + parts := strings.SplitN(input, ".", 5) rawProtected, err := base64URLDecode(parts[0]) if err != nil { diff --git a/vendor/github.com/go-jose/go-jose/v3/jws.go b/vendor/github.com/go-jose/go-jose/v3/jws.go index e37007dbb..401fc18ac 100644 --- a/vendor/github.com/go-jose/go-jose/v3/jws.go +++ b/vendor/github.com/go-jose/go-jose/v3/jws.go @@ -275,10 +275,11 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { // parseSignedCompact parses a message in compact format. func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) { - parts := strings.Split(input, ".") - if len(parts) != 3 { + // Three parts is two separators + if strings.Count(input, ".") != 2 { 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 { return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") diff --git a/vendor/github.com/go-jose/go-jose/v3/symmetric.go b/vendor/github.com/go-jose/go-jose/v3/symmetric.go index 10d8e19fd..4a4bba2cb 100644 --- a/vendor/github.com/go-jose/go-jose/v3/symmetric.go +++ b/vendor/github.com/go-jose/go-jose/v3/symmetric.go @@ -364,11 +364,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 +393,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien parts := &aeadParts{ iv: iv.bytes(), - ciphertext: recipient.encryptedKey, + ciphertext: encryptedKey, tag: tag.bytes(), } @@ -399,7 +409,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 } @@ -440,7 +450,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 } diff --git a/vendor/modules.txt b/vendor/modules.txt index 15dd893fc..627d27a07 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -252,7 +252,7 @@ github.com/docker/go-units # github.com/ghodss/yaml v1.0.0 ## explicit github.com/ghodss/yaml -# github.com/go-jose/go-jose/v3 v3.0.3 +# github.com/go-jose/go-jose/v3 v3.0.5 ## explicit; go 1.12 github.com/go-jose/go-jose/v3 github.com/go-jose/go-jose/v3/cipher From 16a8af6d92ccaa90f07aab3b5eff0b2b85e4b9c4 Mon Sep 17 00:00:00 2001 From: Tom Sweeney Date: Mon, 11 May 2026 19:11:52 -0400 Subject: [PATCH 2/3] [release-1.11] Bump Fedora to 39 in cirrus The lastest Go Jose is calling functions first introduced in Go 1.20. Bumping the CI to Fedora 1.39 where Go 1.20 first appeared in Fedora. Signed-off-by: Tom Sweeney --- .cirrus.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 6f8be8e03..5f3ede29f 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -23,10 +23,10 @@ env: #### #### Cache-image names to test with (double-quotes around names are critical) #### - FEDORA_NAME: "fedora-37" + FEDORA_NAME: "fedora-39" # Google-cloud VM Images - IMAGE_SUFFIX: "c6300530360713216" + IMAGE_SUFFIX: "c20240102t155643z-f39f38d13" FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}" # Container FQIN's From 1fc131e7154a5c096f16e4a0a8386b0616afc747 Mon Sep 17 00:00:00 2001 From: Tom Sweeney Date: Wed, 29 Apr 2026 17:34:06 -0400 Subject: [PATCH 3/3] [release-1.11] Bump Skopeo to v1.11.5 Bump Skopeo to v1.11.5 Signed-off-by: Tom Sweeney --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index 771416131..ab53e39f4 100644 --- a/version/version.go +++ b/version/version.go @@ -1,4 +1,4 @@ package version // Version is the version of the build. -const Version = "1.11.4" +const Version = "1.11.5"