Skip to content

Commit

Permalink
Allow RubySaml::Utils.is_cert_expired and is_cert_active to accep…
Browse files Browse the repository at this point in the history
…t an optional time argument.
  • Loading branch information
johnnyshields committed Jan 11, 2025
1 parent 6f73a4f commit a838600
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 56 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* [#715](https://github.com/SAML-Toolkits/ruby-saml/pull/715) Fix typo in error when SPNameQualifier value does not match the SP entityID.
* [#718](https://github.com/SAML-Toolkits/ruby-saml/pull/718/) Add support to retrieve from SAMLResponse the AuthnInstant and AuthnContextClassRef values
* [#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.
* [#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.

### 1.18.0 (???)
* [#718](https://github.com/SAML-Toolkits/ruby-saml/pull/718) Add support to retrieve from SAMLResponse the AuthnInstant and AuthnContextClassRef values
Expand Down
22 changes: 10 additions & 12 deletions lib/ruby_saml/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,32 +35,30 @@ module Utils
# Checks if the x509 cert provided is expired.
#
# @param cert [OpenSSL::X509::Certificate|String] The x509 certificate.
# @param now [Time|Integer] The time to compare.
# @return [true|false] Whether the certificate is expired.
def is_cert_expired(cert)
cert = build_cert_object(cert) if cert.is_a?(String)
cert.not_after < Time.now
def is_cert_expired(cert, now = Time.now)
cert = build_cert_object(cert)
cert.not_after < now
end

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

# Interprets a ISO8601 duration value relative to a given timestamp.
#
# @param duration [String] The duration, as a string.
# @param timestamp [Integer] The unix timestamp we should apply the
# duration to. Optional, default to the
# current time.
#
# @param timestamp [Time|Integer] The unix timestamp we should apply the
# duration to. Optional, default to the current time.
# @return [Integer] The new timestamp, after the duration is applied.
#
def parse_duration(duration, timestamp=Time.now.utc)
def parse_duration(duration, timestamp = Time.now)
matches = duration.match(DURATION_FORMAT)

if matches.nil?
Expand Down
162 changes: 118 additions & 44 deletions test/utils_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -408,66 +408,140 @@ def result(duration, reference = 0)
end

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

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

it 'returns false for active certificate' do
valid_cert = CertificateHelper.generate_cert
refute RubySaml::Utils.is_cert_expired(valid_cert)
end
it 'returns false for not-started certificate' do
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
refute RubySaml::Utils.is_cert_active(not_started_cert)
end

it 'returns true for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
assert RubySaml::Utils.is_cert_expired(expired_cert_string)
end
it 'returns false for active certificate' do
valid_cert = CertificateHelper.generate_cert
refute RubySaml::Utils.is_cert_expired(valid_cert)
end

it 'returns true for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
assert RubySaml::Utils.is_cert_expired(expired_cert_string)
end

it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
end

it 'returns false for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert.to_pem
refute RubySaml::Utils.is_cert_expired(valid_cert_string)
end
end

it 'returns false for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert.to_pem
refute RubySaml::Utils.is_cert_expired(valid_cert_string)
describe 'time argument specified' do
let(:now) { Time.at(10000) }

it 'returns true for expired certificate' do
expired_cert = CertificateHelper.generate_cert(not_after: now - 60)
assert RubySaml::Utils.is_cert_expired(expired_cert, now)
end

it 'returns false for not-started certificate' do
not_started_cert = CertificateHelper.generate_cert(not_before: now + 60)
refute RubySaml::Utils.is_cert_active(not_started_cert, now)
end

it 'returns false for active certificate' do
valid_cert = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60)
refute RubySaml::Utils.is_cert_expired(valid_cert, now)
end

it 'returns true for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: now - 60).to_pem
assert RubySaml::Utils.is_cert_expired(expired_cert_string, now)
end

it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string, now)
end

it 'returns false for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60).to_pem
refute RubySaml::Utils.is_cert_expired(valid_cert_string, now)
end
end
end

describe '.is_cert_active' do
it 'returns true for active certificate' do
valid_cert = CertificateHelper.generate_cert
assert RubySaml::Utils.is_cert_active(valid_cert)
end

it 'returns false for not-started certificate' do
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
refute RubySaml::Utils.is_cert_active(not_started_cert)
end
describe 'time argument not specified' do
it 'returns true for active certificate' do
valid_cert = CertificateHelper.generate_cert
assert RubySaml::Utils.is_cert_active(valid_cert)
end

it 'returns false for expired certificate' do
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
refute RubySaml::Utils.is_cert_active(expired_cert)
end
it 'returns false for not-started certificate' do
not_started_cert = CertificateHelper.generate_cert(not_before: Time.now + 60)
refute RubySaml::Utils.is_cert_active(not_started_cert)
end

it 'returns true for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert.to_pem
assert RubySaml::Utils.is_cert_active(valid_cert_string)
end
it 'returns false for expired certificate' do
expired_cert = CertificateHelper.generate_cert(not_after: Time.now - 60)
refute RubySaml::Utils.is_cert_active(expired_cert)
end

it 'returns true for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert.to_pem
assert RubySaml::Utils.is_cert_active(valid_cert_string)
end

it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: Time.now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string)
end

it 'returns false for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
refute RubySaml::Utils.is_cert_active(expired_cert_string)
end
end

it 'returns false for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: Time.now - 60).to_pem
refute RubySaml::Utils.is_cert_active(expired_cert_string)
describe 'time argument specified' do
let(:now) { Time.at(10000) }

it 'returns true for active certificate' do
valid_cert = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60)
assert RubySaml::Utils.is_cert_active(valid_cert, now)
end

it 'returns false for not-started certificate' do
not_started_cert = CertificateHelper.generate_cert(not_before: now + 60)
refute RubySaml::Utils.is_cert_active(not_started_cert, now)
end

it 'returns false for expired certificate' do
expired_cert = CertificateHelper.generate_cert(not_after: now - 60)
refute RubySaml::Utils.is_cert_active(expired_cert, now)
end

it 'returns true for active certificate string' do
valid_cert_string = CertificateHelper.generate_cert(not_before: now - 60, not_after: now + 60).to_pem
assert RubySaml::Utils.is_cert_active(valid_cert_string, now)
end

it 'returns false for not-started certificate string' do
not_started_cert_string = CertificateHelper.generate_cert(not_before: now + 60).to_pem
refute RubySaml::Utils.is_cert_active(not_started_cert_string, now)
end

it 'returns false for expired certificate string' do
expired_cert_string = CertificateHelper.generate_cert(not_after: now - 60).to_pem
refute RubySaml::Utils.is_cert_active(expired_cert_string, now)
end
end
end
end

0 comments on commit a838600

Please sign in to comment.