Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

**Fixes and enhancements:**

- Your contribution here
- Fix rejection of unknown algorithms from JWKs for RFC compliance and pquip [#728](https://github.com/jwt/ruby-jwt/pull/728)

## [v3.2.0](https://github.com/jwt/ruby-jwt/tree/v3.2.0) (2026-05-13)

Expand Down
3 changes: 3 additions & 0 deletions lib/jwt/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ class Base64DecodeError < DecodeError; end

# The JWKError class is raised when there is an error with the JSON Web Key (JWK).
class JWKError < DecodeError; end

# Raised when a JWK uses a key type (kty) that this library does not support.
class UnsupportedKeyType < JWKError; end
end
2 changes: 1 addition & 1 deletion lib/jwt/jwk.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def create_from(key, params = nil, options = {})
raise JWT::JWKError, 'Key type (kty) not provided' unless jwk_kty

return mappings.fetch(jwk_kty.to_s) do |kty|
raise JWT::JWKError, "Key type #{kty} not supported"
raise JWT::UnsupportedKeyType, "Key type #{kty} not supported"
end.new(key, params, options)
end

Expand Down
6 changes: 5 additions & 1 deletion lib/jwt/jwk/set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ def initialize(jwks = nil, options = {}) # rubocop:disable Metrics/CyclomaticCom
[jwks]
when Hash
jwks = jwks.transform_keys(&:to_sym)
[*jwks[:keys]].map { |k| JWT::JWK.new(k, nil, options) }
[*jwks[:keys]].each_with_object([]) do |k, arr|
arr << JWT::JWK.new(k, nil, options)
rescue JWT::UnsupportedKeyType
nil
end
when Array
jwks.map { |k| JWT::JWK.new(k, nil, options) }
else
Expand Down
32 changes: 32 additions & 0 deletions spec/jwt/jwk/set_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,38 @@
end
end

it 'ignores keys with unsupported kty values (RFC 7517 §5), required for hybrid PQC' do
jwks = {
keys: [
{ kty: 'unknown', alg: 'unknown-alg', kid: 'unknown' },
{ kty: 'oct', k: Base64.strict_encode64('testkey') }
]
}
set = described_class.new(jwks)
expect(set.size).to eql(1)
expect(set.keys[0][:kty]).to eql('oct')
end

it 'returns an empty set when all keys have unsupported kty values' do
jwks = {
keys: [
{ kty: 'unknown', alg: 'unknown-alg', kid: 'unknown-1' },
{ kty: 'future', alg: 'future-alg', kid: 'future-1' }
]
}
set = described_class.new(jwks)
expect(set.size).to eql(0)
end

it 'raises on malformed keys with a known kty' do
jwks = {
keys: [
{ kty: 'RSA' }
]
}
expect { described_class.new(jwks) }.to raise_error(JWT::JWKError, /Key format is invalid for RSA/)
end

it 'raises an error on invalid inputs' do
expect { described_class.new(42) }.to raise_error(ArgumentError)
end
Expand Down
Loading