Skip to content

Commit 2caea57

Browse files
committed
Allow RubySaml::Utils.is_cert_expired and is_cert_active to accept an optional time argument.
1 parent 6f73a4f commit 2caea57

File tree

3 files changed

+127
-54
lines changed

3 files changed

+127
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* [#715](https://github.com/SAML-Toolkits/ruby-saml/pull/715) Fix typo in error when SPNameQualifier value does not match the SP entityID.
1515
* [#718](https://github.com/SAML-Toolkits/ruby-saml/pull/718/) Add support to retrieve from SAMLResponse the AuthnInstant and AuthnContextClassRef values
1616
* [#711](https://github.com/SAML-Toolkits/ruby-saml/pull/711) Standardize how RubySaml reads and formats certificate and private_key PEM values, including the `RubySaml::Util#format_cert` and `#format_private_key` methods.
17+
* [#733](https://github.com/SAML-Toolkits/ruby-saml/pull/733) Allow `RubySaml::Utils.is_cert_expired` and `is_cert_active` to accept an optional time argument.
1718

1819
### 1.18.0 (???)
1920
* [#718](https://github.com/SAML-Toolkits/ruby-saml/pull/718) Add support to retrieve from SAMLResponse the AuthnInstant and AuthnContextClassRef values

lib/ruby_saml/utils.rb

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,30 @@ module Utils
3535
# Checks if the x509 cert provided is expired.
3636
#
3737
# @param cert [OpenSSL::X509::Certificate|String] The x509 certificate.
38+
# @param now [Time|Integer] The time to compare.
3839
# @return [true|false] Whether the certificate is expired.
39-
def is_cert_expired(cert)
40+
def is_cert_expired(cert, now = Time.now)
4041
cert = build_cert_object(cert) if cert.is_a?(String)
41-
cert.not_after < Time.now
42+
cert.not_after < now
4243
end
4344

4445
# Checks if the x509 cert provided has both started and has not expired.
4546
#
4647
# @param cert [OpenSSL::X509::Certificate|String] The x509 certificate.
48+
# @param now [Time|Integer] The time to compare.
4749
# @return [true|false] Whether the certificate is currently active.
48-
def is_cert_active(cert)
50+
def is_cert_active(cert, now = Time.now)
4951
cert = build_cert_object(cert) if cert.is_a?(String)
50-
now = Time.now
5152
cert.not_before <= now && cert.not_after >= now
5253
end
5354

5455
# Interprets a ISO8601 duration value relative to a given timestamp.
5556
#
5657
# @param duration [String] The duration, as a string.
57-
# @param timestamp [Integer] The unix timestamp we should apply the
58-
# duration to. Optional, default to the
59-
# current time.
60-
#
58+
# @param timestamp [Time|Integer] The unix timestamp we should apply the
59+
# duration to. Optional, default to the current time.
6160
# @return [Integer] The new timestamp, after the duration is applied.
62-
#
63-
def parse_duration(duration, timestamp=Time.now.utc)
61+
def parse_duration(duration, timestamp = Time.now)
6462
matches = duration.match(DURATION_FORMAT)
6563

6664
if matches.nil?

test/utils_test.rb

Lines changed: 118 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -408,66 +408,140 @@ def result(duration, reference = 0)
408408
end
409409

410410
describe '.is_cert_expired' do
411-
it 'returns true for expired certificate' do
412-
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
413-
assert RubySaml::Utils.is_cert_expired(expired_cert)
414-
end
415411

416-
it 'returns false for not-started certificate' do
417-
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
418-
refute RubySaml::Utils.is_cert_active(not_started_cert)
419-
end
412+
describe 'time argument not specified' do
413+
it 'returns true for expired certificate' do
414+
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
415+
assert RubySaml::Utils.is_cert_expired(expired_cert)
416+
end
420417

421-
it 'returns false for active certificate' do
422-
valid_cert = CertificateHelper.generate_cert
423-
refute RubySaml::Utils.is_cert_expired(valid_cert)
424-
end
418+
it 'returns false for not-started certificate' do
419+
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
420+
refute RubySaml::Utils.is_cert_active(not_started_cert)
421+
end
425422

426-
it 'returns true for expired certificate string' do
427-
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
428-
assert RubySaml::Utils.is_cert_expired(expired_cert_string)
429-
end
423+
it 'returns false for active certificate' do
424+
valid_cert = CertificateHelper.generate_cert
425+
refute RubySaml::Utils.is_cert_expired(valid_cert)
426+
end
427+
428+
it 'returns true for expired certificate string' do
429+
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
430+
assert RubySaml::Utils.is_cert_expired(expired_cert_string)
431+
end
430432

431-
it 'returns false for not-started certificate string' do
432-
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
433-
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
433+
it 'returns false for not-started certificate string' do
434+
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
435+
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
436+
end
437+
438+
it 'returns false for active certificate string' do
439+
valid_cert_string = CertificateHelper.generate_cert.to_pem
440+
refute RubySaml::Utils.is_cert_expired(valid_cert_string)
441+
end
434442
end
435443

436-
it 'returns false for active certificate string' do
437-
valid_cert_string = CertificateHelper.generate_cert.to_pem
438-
refute RubySaml::Utils.is_cert_expired(valid_cert_string)
444+
describe 'time argument specified' do
445+
let(:now) { Time.at(10000) }
446+
447+
it 'returns true for expired certificate' do
448+
expired_cert = CertificateHelper.generate_cert(not_after: now - 60)
449+
assert RubySaml::Utils.is_cert_expired(expired_cert, now)
450+
end
451+
452+
it 'returns false for not-started certificate' do
453+
not_started_cert = CertificateHelper.generate_cert(not_before: now + 60)
454+
refute RubySaml::Utils.is_cert_active(not_started_cert, now)
455+
end
456+
457+
it 'returns false for active certificate' do
458+
valid_cert = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60)
459+
refute RubySaml::Utils.is_cert_expired(valid_cert, now)
460+
end
461+
462+
it 'returns true for expired certificate string' do
463+
expired_cert_string = CertificateHelper.generate_cert(not_after: now - 60).to_pem
464+
assert RubySaml::Utils.is_cert_expired(expired_cert_string, now)
465+
end
466+
467+
it 'returns false for not-started certificate string' do
468+
not_started_cert_string = CertificateHelper.generate_cert(not_before: now + 60).to_pem
469+
refute RubySaml::Utils.is_cert_active(not_started_cert_string, now)
470+
end
471+
472+
it 'returns false for active certificate string' do
473+
valid_cert_string = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60).to_pem
474+
refute RubySaml::Utils.is_cert_expired(valid_cert_string, now)
475+
end
439476
end
440477
end
441478

442479
describe '.is_cert_active' do
443-
it 'returns true for active certificate' do
444-
valid_cert = CertificateHelper.generate_cert
445-
assert RubySaml::Utils.is_cert_active(valid_cert)
446-
end
447480

448-
it 'returns false for not-started certificate' do
449-
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
450-
refute RubySaml::Utils.is_cert_active(not_started_cert)
451-
end
481+
describe 'time argument not specified' do
482+
it 'returns true for active certificate' do
483+
valid_cert = CertificateHelper.generate_cert
484+
assert RubySaml::Utils.is_cert_active(valid_cert)
485+
end
452486

453-
it 'returns false for expired certificate' do
454-
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
455-
refute RubySaml::Utils.is_cert_active(expired_cert)
456-
end
487+
it 'returns false for not-started certificate' do
488+
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
489+
refute RubySaml::Utils.is_cert_active(not_started_cert)
490+
end
457491

458-
it 'returns true for active certificate string' do
459-
valid_cert_string = CertificateHelper.generate_cert.to_pem
460-
assert RubySaml::Utils.is_cert_active(valid_cert_string)
461-
end
492+
it 'returns false for expired certificate' do
493+
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
494+
refute RubySaml::Utils.is_cert_active(expired_cert)
495+
end
496+
497+
it 'returns true for active certificate string' do
498+
valid_cert_string = CertificateHelper.generate_cert.to_pem
499+
assert RubySaml::Utils.is_cert_active(valid_cert_string)
500+
end
462501

463-
it 'returns false for not-started certificate string' do
464-
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
465-
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
502+
it 'returns false for not-started certificate string' do
503+
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
504+
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
505+
end
506+
507+
it 'returns false for expired certificate string' do
508+
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
509+
refute RubySaml::Utils.is_cert_active(expired_cert_string)
510+
end
466511
end
467512

468-
it 'returns false for expired certificate string' do
469-
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
470-
refute RubySaml::Utils.is_cert_active(expired_cert_string)
513+
describe 'time argument specified' do
514+
let(:now) { Time.at(10000) }
515+
516+
it 'returns true for active certificate' do
517+
valid_cert = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60)
518+
assert RubySaml::Utils.is_cert_active(valid_cert, now)
519+
end
520+
521+
it 'returns false for not-started certificate' do
522+
not_started_cert = CertificateHelper.generate_cert(not_before: now + 60)
523+
refute RubySaml::Utils.is_cert_active(not_started_cert, now)
524+
end
525+
526+
it 'returns false for expired certificate' do
527+
expired_cert = CertificateHelper.generate_cert(not_after: now - 60)
528+
refute RubySaml::Utils.is_cert_active(expired_cert, now)
529+
end
530+
531+
it 'returns true for active certificate string' do
532+
valid_cert_string = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60).to_pem
533+
assert RubySaml::Utils.is_cert_active(valid_cert_string, now)
534+
end
535+
536+
it 'returns false for not-started certificate string' do
537+
not_started_cert_string = CertificateHelper.generate_cert(not_before: now + 60).to_pem
538+
refute RubySaml::Utils.is_cert_active(not_started_cert_string, now)
539+
end
540+
541+
it 'returns false for expired certificate string' do
542+
expired_cert_string = CertificateHelper.generate_cert(not_after: now - 60).to_pem
543+
refute RubySaml::Utils.is_cert_active(expired_cert_string, now)
544+
end
471545
end
472546
end
473547
end

0 commit comments

Comments
 (0)