mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 06:52:26 -05:00 
			
		
		
		
	[chore]: Bump github.com/coreos/go-oidc/v3 from 3.9.0 to 3.10.0 (#2779)
This commit is contained in:
		
					parent
					
						
							
								5f43419a87
							
						
					
				
			
			
				commit
				
					
						a24936040c
					
				
			
		
					 38 changed files with 284 additions and 126 deletions
				
			
		|  | @ -45,12 +45,6 @@ token". | |||
| 
 | ||||
| [1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf | ||||
| 
 | ||||
| # v3.0.3 | ||||
| 
 | ||||
| ## Fixed | ||||
| 
 | ||||
|  - Limit decompression output size to prevent a DoS. Backport from v4.0.1. | ||||
| 
 | ||||
| # v3.0.2 | ||||
| 
 | ||||
| ## Fixed | ||||
|  | @ -1,17 +1,9 @@ | |||
| # Go JOSE | ||||
| 
 | ||||
| ### Versions | ||||
| 
 | ||||
| [Version 4](https://github.com/go-jose/go-jose) | ||||
| ([branch](https://github.com/go-jose/go-jose/), | ||||
| [doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version: | ||||
| 
 | ||||
|     import "github.com/go-jose/go-jose/v4" | ||||
| 
 | ||||
| The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which | ||||
| are deprecated. | ||||
| 
 | ||||
| ### Summary | ||||
| [](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, | ||||
|  | @ -43,6 +35,20 @@ of [case-insensitive matching](https://www.ietf.org/mail-archive/web/json/curren | |||
| This is to avoid differences in interpretation of messages between go-jose and | ||||
| libraries in other languages. | ||||
| 
 | ||||
| ### Versions | ||||
| 
 | ||||
| [Version 4](https://github.com/go-jose/go-jose) | ||||
| ([branch](https://github.com/go-jose/go-jose/tree/main), | ||||
| [doc](https://pkg.go.dev/github.com/go-jose/go-jose/v4), [releases](https://github.com/go-jose/go-jose/releases)) is the current stable version: | ||||
| 
 | ||||
|     import "github.com/go-jose/go-jose/v4" | ||||
| 
 | ||||
| The old [square/go-jose](https://github.com/square/go-jose) repo contains the prior v1 and v2 versions, which | ||||
| are still useable but not actively developed anymore. | ||||
| 
 | ||||
| Version 3, in this repo, is still receiving security fixes but not functionality | ||||
| updates. | ||||
| 
 | ||||
| ### Supported algorithms | ||||
| 
 | ||||
| See below for a table of supported algorithms. Algorithm identifiers match | ||||
|  | @ -98,11 +104,11 @@ allows attaching a key id. | |||
| 
 | ||||
| ## Examples | ||||
| 
 | ||||
| [](https://pkg.go.dev/github.com/go-jose/go-jose/v3) | ||||
| [](https://pkg.go.dev/github.com/go-jose/go-jose/v3/jwt) | ||||
| [](https://pkg.go.dev/github.com/go-jose/go-jose/v4) | ||||
| [](https://pkg.go.dev/github.com/go-jose/go-jose/v4/jwt) | ||||
| 
 | ||||
| Examples can be found in the Godoc | ||||
| reference for this package. The | ||||
| [`jose-util`](https://github.com/go-jose/go-jose/tree/v3/jose-util) | ||||
| [`jose-util`](https://github.com/go-jose/go-jose/tree/v4/jose-util) | ||||
| subdirectory also contains a small command-line utility which might be useful | ||||
| as an example as well. | ||||
|  | @ -29,8 +29,8 @@ import ( | |||
| 	"fmt" | ||||
| 	"math/big" | ||||
| 
 | ||||
| 	josecipher "github.com/go-jose/go-jose/v3/cipher" | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	josecipher "github.com/go-jose/go-jose/v4/cipher" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // A generic RSA-based encrypter/verifier | ||||
|  | @ -22,7 +22,7 @@ import ( | |||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // Encrypter represents an encrypter which produces an encrypted JWE object. | ||||
|  | @ -27,7 +27,7 @@ import ( | |||
| 	"strings" | ||||
| 	"unicode" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // Helper function to serialize known-good objects. | ||||
|  | @ -106,10 +106,7 @@ func inflate(input []byte) ([]byte, error) { | |||
| 	output := new(bytes.Buffer) | ||||
| 	reader := flate.NewReader(bytes.NewBuffer(input)) | ||||
| 
 | ||||
| 	maxCompressedSize := 10 * int64(len(input)) | ||||
| 	if maxCompressedSize < 250000 { | ||||
| 		maxCompressedSize = 250000 | ||||
| 	} | ||||
| 	maxCompressedSize := max(250_000, 10*int64(len(input))) | ||||
| 
 | ||||
| 	limit := maxCompressedSize + 1 | ||||
| 	n, err := io.CopyN(output, reader, limit) | ||||
|  | @ -167,7 +164,7 @@ func (b *byteBuffer) UnmarshalJSON(data []byte) error { | |||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	decoded, err := base64URLDecode(encoded) | ||||
| 	decoded, err := base64.RawURLEncoding.DecodeString(encoded) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -197,12 +194,6 @@ func (b byteBuffer) toInt() int { | |||
| 	return int(b.bigInt().Int64()) | ||||
| } | ||||
| 
 | ||||
| // base64URLDecode is implemented as defined in https://www.rfc-editor.org/rfc/rfc7515.html#appendix-C | ||||
| func base64URLDecode(value string) ([]byte, error) { | ||||
| 	value = strings.TrimRight(value, "=") | ||||
| 	return base64.RawURLEncoding.DecodeString(value) | ||||
| } | ||||
| 
 | ||||
| func base64EncodeLen(sl []byte) int { | ||||
| 	return base64.RawURLEncoding.EncodedLen(len(sl)) | ||||
| } | ||||
							
								
								
									
										134
									
								
								vendor/github.com/go-jose/go-jose/v3/jwe.go → vendor/github.com/go-jose/go-jose/v4/jwe.go
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										134
									
								
								vendor/github.com/go-jose/go-jose/v3/jwe.go → vendor/github.com/go-jose/go-jose/v4/jwe.go
									
										
									
										generated
									
									
										vendored
									
									
								
							|  | @ -18,10 +18,11 @@ package jose | |||
| 
 | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // rawJSONWebEncryption represents a raw JWE JSON object. Used for parsing/serializing. | ||||
|  | @ -104,29 +105,75 @@ func (obj JSONWebEncryption) computeAuthData() []byte { | |||
| 	return output | ||||
| } | ||||
| 
 | ||||
| // ParseEncrypted parses an encrypted message in compact or JWE JSON Serialization format. | ||||
| func ParseEncrypted(input string) (*JSONWebEncryption, error) { | ||||
| 	input = stripWhitespace(input) | ||||
| 	if strings.HasPrefix(input, "{") { | ||||
| 		return parseEncryptedFull(input) | ||||
| func containsKeyAlgorithm(haystack []KeyAlgorithm, needle KeyAlgorithm) bool { | ||||
| 	for _, algorithm := range haystack { | ||||
| 		if algorithm == needle { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return parseEncryptedCompact(input) | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // parseEncryptedFull parses a message in compact format. | ||||
| func parseEncryptedFull(input string) (*JSONWebEncryption, error) { | ||||
| func containsContentEncryption(haystack []ContentEncryption, needle ContentEncryption) bool { | ||||
| 	for _, algorithm := range haystack { | ||||
| 		if algorithm == needle { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // ParseEncrypted parses an encrypted message in JWE Compact or JWE JSON Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7516#section-3.1 | ||||
| // https://datatracker.ietf.org/doc/html/rfc7516#section-3.2 | ||||
| // | ||||
| // The keyAlgorithms and contentEncryption parameters are used to validate the "alg" and "enc" | ||||
| // header parameters respectively. They must be nonempty, and each "alg" or "enc" header in | ||||
| // parsed data must contain a value that is present in the corresponding parameter. That | ||||
| // includes the protected and unprotected headers as well as all recipients. To accept | ||||
| // multiple algorithms, pass a slice of all the algorithms you want to accept. | ||||
| func ParseEncrypted(input string, | ||||
| 	keyEncryptionAlgorithms []KeyAlgorithm, | ||||
| 	contentEncryption []ContentEncryption, | ||||
| ) (*JSONWebEncryption, error) { | ||||
| 	input = stripWhitespace(input) | ||||
| 	if strings.HasPrefix(input, "{") { | ||||
| 		return ParseEncryptedJSON(input, keyEncryptionAlgorithms, contentEncryption) | ||||
| 	} | ||||
| 
 | ||||
| 	return ParseEncryptedCompact(input, keyEncryptionAlgorithms, contentEncryption) | ||||
| } | ||||
| 
 | ||||
| // ParseEncryptedJSON parses a message in JWE JSON Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7516#section-3.2 | ||||
| func ParseEncryptedJSON( | ||||
| 	input string, | ||||
| 	keyEncryptionAlgorithms []KeyAlgorithm, | ||||
| 	contentEncryption []ContentEncryption, | ||||
| ) (*JSONWebEncryption, error) { | ||||
| 	var parsed rawJSONWebEncryption | ||||
| 	err := json.Unmarshal([]byte(input), &parsed) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return parsed.sanitized() | ||||
| 	return parsed.sanitized(keyEncryptionAlgorithms, contentEncryption) | ||||
| } | ||||
| 
 | ||||
| // sanitized produces a cleaned-up JWE object from the raw JSON. | ||||
| func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { | ||||
| func (parsed *rawJSONWebEncryption) sanitized( | ||||
| 	keyEncryptionAlgorithms []KeyAlgorithm, | ||||
| 	contentEncryption []ContentEncryption, | ||||
| ) (*JSONWebEncryption, error) { | ||||
| 	if len(keyEncryptionAlgorithms) == 0 { | ||||
| 		return nil, errors.New("go-jose/go-jose: no key algorithms provided") | ||||
| 	} | ||||
| 	if len(contentEncryption) == 0 { | ||||
| 		return nil, errors.New("go-jose/go-jose: no content encryption algorithms provided") | ||||
| 	} | ||||
| 
 | ||||
| 	obj := &JSONWebEncryption{ | ||||
| 		original:    parsed, | ||||
| 		unprotected: parsed.Unprotected, | ||||
|  | @ -170,7 +217,7 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { | |||
| 	} else { | ||||
| 		obj.recipients = make([]recipientInfo, len(parsed.Recipients)) | ||||
| 		for r := range parsed.Recipients { | ||||
| 			encryptedKey, err := base64URLDecode(parsed.Recipients[r].EncryptedKey) | ||||
| 			encryptedKey, err := base64.RawURLEncoding.DecodeString(parsed.Recipients[r].EncryptedKey) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
|  | @ -185,10 +232,31 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, recipient := range obj.recipients { | ||||
| 	for i, recipient := range obj.recipients { | ||||
| 		headers := obj.mergedHeaders(&recipient) | ||||
| 		if headers.getAlgorithm() == "" || headers.getEncryption() == "" { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: message is missing alg/enc headers") | ||||
| 		if headers.getAlgorithm() == "" { | ||||
| 			return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "alg"`, i) | ||||
| 		} | ||||
| 		if headers.getEncryption() == "" { | ||||
| 			return nil, fmt.Errorf(`go-jose/go-jose: recipient %d: missing header "enc"`, i) | ||||
| 		} | ||||
| 		err := validateAlgEnc(headers, keyEncryptionAlgorithms, contentEncryption) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: recipient %d: %s", i, err) | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if obj.protected != nil { | ||||
| 		err := validateAlgEnc(*obj.protected, keyEncryptionAlgorithms, contentEncryption) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: protected header: %s", err) | ||||
| 		} | ||||
| 	} | ||||
| 	if obj.unprotected != nil { | ||||
| 		err := validateAlgEnc(*obj.unprotected, keyEncryptionAlgorithms, contentEncryption) | ||||
| 		if err != nil { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: unprotected header: %s", err) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -200,34 +268,52 @@ func (parsed *rawJSONWebEncryption) sanitized() (*JSONWebEncryption, error) { | |||
| 	return obj, nil | ||||
| } | ||||
| 
 | ||||
| // parseEncryptedCompact parses a message in compact format. | ||||
| func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { | ||||
| func validateAlgEnc(headers rawHeader, keyAlgorithms []KeyAlgorithm, contentEncryption []ContentEncryption) error { | ||||
| 	alg := headers.getAlgorithm() | ||||
| 	enc := headers.getEncryption() | ||||
| 	if alg != "" && !containsKeyAlgorithm(keyAlgorithms, alg) { | ||||
| 		return fmt.Errorf("unexpected key algorithm %q; expected %q", alg, keyAlgorithms) | ||||
| 	} | ||||
| 	if alg != "" && !containsContentEncryption(contentEncryption, enc) { | ||||
| 		return fmt.Errorf("unexpected content encryption algorithm %q; expected %q", enc, contentEncryption) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ParseEncryptedCompact parses a message in JWE Compact Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7516#section-3.1 | ||||
| func ParseEncryptedCompact( | ||||
| 	input string, | ||||
| 	keyAlgorithms []KeyAlgorithm, | ||||
| 	contentEncryption []ContentEncryption, | ||||
| ) (*JSONWebEncryption, error) { | ||||
| 	parts := strings.Split(input, ".") | ||||
| 	if len(parts) != 5 { | ||||
| 		return nil, fmt.Errorf("go-jose/go-jose: compact JWE format must have five parts") | ||||
| 	} | ||||
| 
 | ||||
| 	rawProtected, err := base64URLDecode(parts[0]) | ||||
| 	rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	encryptedKey, err := base64URLDecode(parts[1]) | ||||
| 	encryptedKey, err := base64.RawURLEncoding.DecodeString(parts[1]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	iv, err := base64URLDecode(parts[2]) | ||||
| 	iv, err := base64.RawURLEncoding.DecodeString(parts[2]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	ciphertext, err := base64URLDecode(parts[3]) | ||||
| 	ciphertext, err := base64.RawURLEncoding.DecodeString(parts[3]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	tag, err := base64URLDecode(parts[4]) | ||||
| 	tag, err := base64.RawURLEncoding.DecodeString(parts[4]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -240,7 +326,7 @@ func parseEncryptedCompact(input string) (*JSONWebEncryption, error) { | |||
| 		Tag:          newBuffer(tag), | ||||
| 	} | ||||
| 
 | ||||
| 	return raw.sanitized() | ||||
| 	return raw.sanitized(keyAlgorithms, contentEncryption) | ||||
| } | ||||
| 
 | ||||
| // CompactSerialize serializes an object using the compact serialization format. | ||||
|  | @ -35,7 +35,7 @@ import ( | |||
| 	"reflect" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // rawJSONWebKey represents a public or private key in JWK format, used for parsing/serializing. | ||||
|  | @ -266,7 +266,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { | |||
| 
 | ||||
| 	// x5t parameters are base64url-encoded SHA thumbprints | ||||
| 	// See RFC 7517, Section 4.8, https://tools.ietf.org/html/rfc7517#section-4.8 | ||||
| 	x5tSHA1bytes, err := base64URLDecode(raw.X5tSHA1) | ||||
| 	x5tSHA1bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA1) | ||||
| 	if err != nil { | ||||
| 		return errors.New("go-jose/go-jose: invalid JWK, x5t header has invalid encoding") | ||||
| 	} | ||||
|  | @ -286,7 +286,7 @@ func (k *JSONWebKey) UnmarshalJSON(data []byte) (err error) { | |||
| 
 | ||||
| 	k.CertificateThumbprintSHA1 = x5tSHA1bytes | ||||
| 
 | ||||
| 	x5tSHA256bytes, err := base64URLDecode(raw.X5tSHA256) | ||||
| 	x5tSHA256bytes, err := base64.RawURLEncoding.DecodeString(raw.X5tSHA256) | ||||
| 	if err != nil { | ||||
| 		return errors.New("go-jose/go-jose: invalid JWK, x5t#S256 header has invalid encoding") | ||||
| 	} | ||||
|  | @ -23,7 +23,7 @@ import ( | |||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // rawJSONWebSignature represents a raw JWS JSON object. Used for parsing/serializing. | ||||
|  | @ -75,22 +75,41 @@ type Signature struct { | |||
| 	original  *rawSignatureInfo | ||||
| } | ||||
| 
 | ||||
| // ParseSigned parses a signed message in compact or JWS JSON Serialization format. | ||||
| func ParseSigned(signature string) (*JSONWebSignature, error) { | ||||
| // ParseSigned parses a signed message in JWS Compact or JWS JSON Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7515#section-7 | ||||
| func ParseSigned( | ||||
| 	signature string, | ||||
| 	signatureAlgorithms []SignatureAlgorithm, | ||||
| ) (*JSONWebSignature, error) { | ||||
| 	signature = stripWhitespace(signature) | ||||
| 	if strings.HasPrefix(signature, "{") { | ||||
| 		return parseSignedFull(signature) | ||||
| 		return ParseSignedJSON(signature, signatureAlgorithms) | ||||
| 	} | ||||
| 
 | ||||
| 	return parseSignedCompact(signature, nil) | ||||
| 	return parseSignedCompact(signature, nil, signatureAlgorithms) | ||||
| } | ||||
| 
 | ||||
| // ParseSignedCompact parses a message in JWS Compact Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7515#section-7.1 | ||||
| func ParseSignedCompact( | ||||
| 	signature string, | ||||
| 	signatureAlgorithms []SignatureAlgorithm, | ||||
| ) (*JSONWebSignature, error) { | ||||
| 	return parseSignedCompact(signature, nil, signatureAlgorithms) | ||||
| } | ||||
| 
 | ||||
| // ParseDetached parses a signed message in compact serialization format with detached payload. | ||||
| func ParseDetached(signature string, payload []byte) (*JSONWebSignature, error) { | ||||
| func ParseDetached( | ||||
| 	signature string, | ||||
| 	payload []byte, | ||||
| 	signatureAlgorithms []SignatureAlgorithm, | ||||
| ) (*JSONWebSignature, error) { | ||||
| 	if payload == nil { | ||||
| 		return nil, errors.New("go-jose/go-jose: nil payload") | ||||
| 	} | ||||
| 	return parseSignedCompact(stripWhitespace(signature), payload) | ||||
| 	return parseSignedCompact(stripWhitespace(signature), payload, signatureAlgorithms) | ||||
| } | ||||
| 
 | ||||
| // Get a header value | ||||
|  | @ -137,19 +156,36 @@ func (obj JSONWebSignature) computeAuthData(payload []byte, signature *Signature | |||
| 	return authData.Bytes(), nil | ||||
| } | ||||
| 
 | ||||
| // parseSignedFull parses a message in full format. | ||||
| func parseSignedFull(input string) (*JSONWebSignature, error) { | ||||
| // ParseSignedJSON parses a message in JWS JSON Serialization. | ||||
| // | ||||
| // https://datatracker.ietf.org/doc/html/rfc7515#section-7.2 | ||||
| func ParseSignedJSON( | ||||
| 	input string, | ||||
| 	signatureAlgorithms []SignatureAlgorithm, | ||||
| ) (*JSONWebSignature, error) { | ||||
| 	var parsed rawJSONWebSignature | ||||
| 	err := json.Unmarshal([]byte(input), &parsed) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	return parsed.sanitized() | ||||
| 	return parsed.sanitized(signatureAlgorithms) | ||||
| } | ||||
| 
 | ||||
| func containsSignatureAlgorithm(haystack []SignatureAlgorithm, needle SignatureAlgorithm) bool { | ||||
| 	for _, algorithm := range haystack { | ||||
| 		if algorithm == needle { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // sanitized produces a cleaned-up JWS object from the raw JSON. | ||||
| func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { | ||||
| func (parsed *rawJSONWebSignature) sanitized(signatureAlgorithms []SignatureAlgorithm) (*JSONWebSignature, error) { | ||||
| 	if len(signatureAlgorithms) == 0 { | ||||
| 		return nil, errors.New("go-jose/go-jose: no signature algorithms specified") | ||||
| 	} | ||||
| 	if parsed.Payload == nil { | ||||
| 		return nil, fmt.Errorf("go-jose/go-jose: missing payload in JWS message") | ||||
| 	} | ||||
|  | @ -198,6 +234,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { | |||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		alg := SignatureAlgorithm(signature.Header.Algorithm) | ||||
| 		if !containsSignatureAlgorithm(signatureAlgorithms, alg) { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q", | ||||
| 				alg, signatureAlgorithms) | ||||
| 		} | ||||
| 
 | ||||
| 		if signature.header != nil { | ||||
| 			signature.Unprotected, err = signature.header.sanitized() | ||||
| 			if err != nil { | ||||
|  | @ -241,6 +283,12 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { | |||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		alg := SignatureAlgorithm(obj.Signatures[i].Header.Algorithm) | ||||
| 		if !containsSignatureAlgorithm(signatureAlgorithms, alg) { | ||||
| 			return nil, fmt.Errorf("go-jose/go-jose: unexpected signature algorithm %q; expected %q", | ||||
| 				alg, signatureAlgorithms) | ||||
| 		} | ||||
| 
 | ||||
| 		if obj.Signatures[i].header != nil { | ||||
| 			obj.Signatures[i].Unprotected, err = obj.Signatures[i].header.sanitized() | ||||
| 			if err != nil { | ||||
|  | @ -274,7 +322,11 @@ func (parsed *rawJSONWebSignature) sanitized() (*JSONWebSignature, error) { | |||
| } | ||||
| 
 | ||||
| // parseSignedCompact parses a message in compact format. | ||||
| func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) { | ||||
| func parseSignedCompact( | ||||
| 	input string, | ||||
| 	payload []byte, | ||||
| 	signatureAlgorithms []SignatureAlgorithm, | ||||
| ) (*JSONWebSignature, error) { | ||||
| 	parts := strings.Split(input, ".") | ||||
| 	if len(parts) != 3 { | ||||
| 		return nil, fmt.Errorf("go-jose/go-jose: compact JWS format must have three parts") | ||||
|  | @ -284,19 +336,19 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) | |||
| 		return nil, fmt.Errorf("go-jose/go-jose: payload is not detached") | ||||
| 	} | ||||
| 
 | ||||
| 	rawProtected, err := base64URLDecode(parts[0]) | ||||
| 	rawProtected, err := base64.RawURLEncoding.DecodeString(parts[0]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	if payload == nil { | ||||
| 		payload, err = base64URLDecode(parts[1]) | ||||
| 		payload, err = base64.RawURLEncoding.DecodeString(parts[1]) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	signature, err := base64URLDecode(parts[2]) | ||||
| 	signature, err := base64.RawURLEncoding.DecodeString(parts[2]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -306,7 +358,7 @@ func parseSignedCompact(input string, payload []byte) (*JSONWebSignature, error) | |||
| 		Protected: newBuffer(rawProtected), | ||||
| 		Signature: newBuffer(signature), | ||||
| 	} | ||||
| 	return raw.sanitized() | ||||
| 	return raw.sanitized(signatureAlgorithms) | ||||
| } | ||||
| 
 | ||||
| func (obj JSONWebSignature) compactSerialize(detached bool) (string, error) { | ||||
|  | @ -23,7 +23,7 @@ import ( | |||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // KeyAlgorithm represents a key management algorithm. | ||||
|  | @ -25,7 +25,7 @@ import ( | |||
| 	"errors" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/go-jose/go-jose/v3/json" | ||||
| 	"github.com/go-jose/go-jose/v4/json" | ||||
| ) | ||||
| 
 | ||||
| // NonceSource represents a source of random nonces to go into JWS objects | ||||
|  | @ -49,6 +49,11 @@ type Signer interface { | |||
| //   - JSONWebKey | ||||
| //   - []byte (an HMAC key) | ||||
| //   - Any type that satisfies the OpaqueSigner interface | ||||
| // | ||||
| // If the key is an HMAC key, it must have at least as many bytes as the relevant hash output: | ||||
| //   - HS256: 32 bytes | ||||
| //   - HS384: 48 bytes | ||||
| //   - HS512: 64 bytes | ||||
| type SigningKey struct { | ||||
| 	Algorithm SignatureAlgorithm | ||||
| 	Key       interface{} | ||||
|  | @ -355,6 +360,11 @@ func (ctx *genericSigner) Options() SignerOptions { | |||
| //   - JSONWebKey | ||||
| //   - []byte (an HMAC key) | ||||
| //   - Any type that implements the OpaqueVerifier interface. | ||||
| // | ||||
| // If the key is an HMAC key, it must have at least as many bytes as the relevant hash output: | ||||
| //   - HS256: 32 bytes | ||||
| //   - HS384: 48 bytes | ||||
| //   - HS512: 64 bytes | ||||
| func (obj JSONWebSignature) Verify(verificationKey interface{}) ([]byte, error) { | ||||
| 	err := obj.DetachedVerify(obj.payload, verificationKey) | ||||
| 	if err != nil { | ||||
|  | @ -32,7 +32,7 @@ import ( | |||
| 
 | ||||
| 	"golang.org/x/crypto/pbkdf2" | ||||
| 
 | ||||
| 	josecipher "github.com/go-jose/go-jose/v3/cipher" | ||||
| 	josecipher "github.com/go-jose/go-jose/v4/cipher" | ||||
| ) | ||||
| 
 | ||||
| // RandReader is a cryptographically secure random number generator (stubbed out in tests). | ||||
|  | @ -454,7 +454,7 @@ func (ctx *symmetricKeyCipher) decryptKey(headers rawHeader, recipient *recipien | |||
| func (ctx symmetricMac) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) { | ||||
| 	mac, err := ctx.hmac(payload, alg) | ||||
| 	if err != nil { | ||||
| 		return Signature{}, errors.New("go-jose/go-jose: failed to compute hmac") | ||||
| 		return Signature{}, err | ||||
| 	} | ||||
| 
 | ||||
| 	return Signature{ | ||||
|  | @ -486,12 +486,24 @@ func (ctx symmetricMac) verifyPayload(payload []byte, mac []byte, alg SignatureA | |||
| func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) { | ||||
| 	var hash func() hash.Hash | ||||
| 
 | ||||
| 	// https://datatracker.ietf.org/doc/html/rfc7518#section-3.2 | ||||
| 	// A key of the same size as the hash output (for instance, 256 bits for | ||||
| 	// "HS256") or larger MUST be used | ||||
| 	switch alg { | ||||
| 	case HS256: | ||||
| 		if len(ctx.key)*8 < 256 { | ||||
| 			return nil, ErrInvalidKeySize | ||||
| 		} | ||||
| 		hash = sha256.New | ||||
| 	case HS384: | ||||
| 		if len(ctx.key)*8 < 384 { | ||||
| 			return nil, ErrInvalidKeySize | ||||
| 		} | ||||
| 		hash = sha512.New384 | ||||
| 	case HS512: | ||||
| 		if len(ctx.key)*8 < 512 { | ||||
| 			return nil, ErrInvalidKeySize | ||||
| 		} | ||||
| 		hash = sha512.New | ||||
| 	default: | ||||
| 		return nil, ErrUnsupportedAlgorithm | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue