Skip to content

Commit f66e7a8

Browse files
authored
Ensure backwards compatibility (#676)
* Remove unused exception * openssl 2.0 * Check for PS support * Check for PS support * Check for PS support * Does it work with superold version * Avoid intantiating key to check for method existance * Disable Naming/PredicateMethod * Try to avoid truffleruby error
1 parent 6aac2d6 commit f66e7a8

File tree

6 files changed

+51
-56
lines changed

6 files changed

+51
-56
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
experimental: [false]
5151
include:
5252
- os: ubuntu-latest
53-
ruby: "3.0"
53+
ruby: "2.5"
5454
gemfile: "gemfiles/openssl.gemfile"
5555
experimental: false
5656
- os: ubuntu-latest
@@ -64,7 +64,6 @@ jobs:
6464
continue-on-error: ${{ matrix.experimental }}
6565
env:
6666
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
67-
6867
steps:
6968
- uses: actions/checkout@v4
7069

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ Layout/LineLength:
2222

2323
Gemspec/DevelopmentDependencies:
2424
EnforcedStyle: gemspec
25+
26+
Naming/PredicateMethod:
27+
Enabled: false

gemfiles/openssl.gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
source "https://rubygems.org"
44

5-
gem "openssl", "~> 2.1"
5+
gem "openssl", "< 2.0"
66

77
gemspec path: "../"

lib/jwt/error.rb

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ class EncodeError < StandardError; end
77
# The DecodeError class is raised when there is an error decoding a JWT.
88
class DecodeError < StandardError; end
99

10-
# The RequiredDependencyError class is raised when a required dependency is missing.
11-
class RequiredDependencyError < StandardError; end
12-
1310
# The VerificationError class is raised when there is an error verifying a JWT.
1411
class VerificationError < DecodeError; end
1512

spec/jwt/jwa/ps_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
let(:ps384_instance) { described_class.new('PS384') }
88
let(:ps512_instance) { described_class.new('PS512') }
99

10+
before do
11+
skip 'OpenSSL gem missing RSA-PSS support' unless OpenSSL::PKey::RSA.method_defined?(:sign_pss)
12+
end
13+
1014
describe '#initialize' do
1115
it 'initializes with the correct algorithm and digest' do
1216
expect(ps256_instance.instance_variable_get(:@alg)).to eq('PS256')

spec/jwt/jwt_spec.rb

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@
163163
end
164164

165165
%w[ES256 ES384 ES512 ES256K].each do |alg|
166+
before do
167+
skip 'OpenSSL gem missing RSA-PSS support' unless OpenSSL::PKey::RSA.method_defined?(:sign_pss)
168+
end
169+
166170
context "alg: #{alg}" do
167171
before(:each) do
168172
data[alg] = JWT.encode(payload, data["#{alg}_private"], alg)
@@ -198,64 +202,51 @@
198202
end
199203
end
200204

201-
if Gem::Version.new(OpenSSL::VERSION) >= Gem::Version.new('2.1')
202-
%w[PS256 PS384 PS512].each do |alg|
203-
context "alg: #{alg}" do
204-
before(:each) do
205-
data[alg] = JWT.encode payload, data[:rsa_private], alg
206-
end
205+
%w[PS256 PS384 PS512].each do |alg|
206+
context "alg: #{alg}" do
207+
before(:each) do
208+
data[alg] = JWT.encode payload, data[:rsa_private], alg
209+
end
207210

208-
let(:wrong_key) { data[:wrong_rsa_public] }
211+
let(:wrong_key) { data[:wrong_rsa_public] }
209212

210-
it 'should generate a valid token' do
211-
token = data[alg]
213+
it 'should generate a valid token' do
214+
token = data[alg]
212215

213-
header, body, signature = token.split('.')
216+
header, body, signature = token.split('.')
214217

215-
expect(header).to eql(Base64.strict_encode64({ alg: alg }.to_json))
216-
expect(body).to eql(Base64.strict_encode64(payload.to_json))
218+
expect(header).to eql(Base64.strict_encode64({ alg: alg }.to_json))
219+
expect(body).to eql(Base64.strict_encode64(payload.to_json))
217220

218-
# Validate signature is made of up header and body of JWT
219-
translated_alg = alg.gsub('PS', 'sha')
220-
valid_signature = data[:rsa_public].verify_pss(
221-
translated_alg,
222-
JWT::Base64.url_decode(signature),
223-
[header, body].join('.'),
224-
salt_length: :auto,
225-
mgf1_hash: translated_alg
226-
)
227-
expect(valid_signature).to be true
228-
end
229-
230-
it 'should decode a valid token' do
231-
jwt_payload, header = JWT.decode data[alg], data[:rsa_public], true, algorithm: alg
221+
# Validate signature is made of up header and body of JWT
222+
translated_alg = alg.gsub('PS', 'sha')
223+
valid_signature = data[:rsa_public].verify_pss(
224+
translated_alg,
225+
JWT::Base64.url_decode(signature),
226+
[header, body].join('.'),
227+
salt_length: :auto,
228+
mgf1_hash: translated_alg
229+
)
230+
expect(valid_signature).to be true
231+
end
232232

233-
expect(header['alg']).to eq alg
234-
expect(jwt_payload).to eq payload
235-
end
233+
it 'should decode a valid token' do
234+
jwt_payload, header = JWT.decode data[alg], data[:rsa_public], true, algorithm: alg
236235

237-
it 'wrong key should raise JWT::DecodeError' do
238-
expect do
239-
JWT.decode data[alg], wrong_key
240-
end.to raise_error JWT::DecodeError
241-
end
236+
expect(header['alg']).to eq alg
237+
expect(jwt_payload).to eq payload
238+
end
242239

243-
it 'wrong key and verify = false should not raise JWT::DecodeError' do
244-
expect do
245-
JWT.decode data[alg], wrong_key, false
246-
end.not_to raise_error
247-
end
240+
it 'wrong key should raise JWT::DecodeError' do
241+
expect do
242+
JWT.decode data[alg], wrong_key
243+
end.to raise_error JWT::DecodeError
248244
end
249-
end
250-
else
251-
%w[PS256 PS384 PS512].each do |alg|
252-
context "alg: #{alg}" do
253-
it 'raises error about OpenSSL version' do
254-
expect { JWT.encode payload, data[:rsa_private], alg }.to raise_error(
255-
JWT::RequiredDependencyError,
256-
/You currently have OpenSSL .*. PS support requires >= 2.1/
257-
)
258-
end
245+
246+
it 'wrong key and verify = false should not raise JWT::DecodeError' do
247+
expect do
248+
JWT.decode data[alg], wrong_key, false
249+
end.not_to raise_error
259250
end
260251
end
261252
end
@@ -766,8 +757,9 @@
766757
let(:token) { JWT.encode(payload, 'secret', 'HS256') }
767758

768759
it 'starts trying with the algorithm referred in the header' do
769-
expect(JWT::JWA::Rsa).not_to receive(:verify)
760+
allow(JWT::JWA::Rsa).to receive(:verify)
770761
JWT.decode(token, 'secret', true, algorithm: %w[RS512 HS256])
762+
expect(JWT::JWA::Rsa).not_to have_received(:verify)
771763
end
772764
end
773765

0 commit comments

Comments
 (0)