Skip to content

Commit 603f97e

Browse files
author
Tobias Amft
committed
Allow SP certificates to be OpenSSL::X509::Certificate
This allows settings to accept instances of OpenSSL::X509::Certificate as service provider (SP) certificates.
1 parent 0124daf commit 603f97e

2 files changed

Lines changed: 60 additions & 8 deletions

File tree

lib/ruby_saml/settings.rb

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,28 +373,33 @@ def get_all_sp_certs
373373

374374
# Validate certificate, certificate_new, private_key, and sp_cert_multi params.
375375
def validate_sp_certs_params!
376-
multi = sp_cert_multi && !sp_cert_multi.empty?
377-
cert = certificate && !certificate.empty?
378-
cert_new = certificate_new && !certificate_new.empty?
379-
pk = private_key && !private_key.empty?
380-
if multi && (cert || cert_new || pk)
376+
has_multi = sp_cert_multi && !sp_cert_multi.empty?
377+
has_pk = private_key && !private_key.empty?
378+
if has_multi && (has_cert?(certificate) || has_cert?(certificate_new) || has_pk)
381379
raise ArgumentError.new("Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters")
382380
end
383381
end
384382

383+
# Check if a certificate is present.
384+
def has_cert?(cert)
385+
return true if cert.is_a?(OpenSSL::X509::Certificate)
386+
387+
cert && !cert.empty?
388+
end
389+
385390
# Get certs from certificate, certificate_new, and private_key parameters.
386391
def get_sp_certs_single
387392
certs = { :signing => [], :encryption => [] }
388393

389394
sp_key = RubySaml::Utils.build_private_key_object(private_key)
390-
cert = RubySaml::Utils.build_cert_object(certificate)
395+
cert = build_cert_object(certificate)
391396
if cert || sp_key
392397
ary = [cert, sp_key].freeze
393398
certs[:signing] << ary
394399
certs[:encryption] << ary
395400
end
396401

397-
cert_new = RubySaml::Utils.build_cert_object(certificate_new)
402+
cert_new = build_cert_object(certificate_new)
398403
if cert_new
399404
ary = [cert_new, sp_key].freeze
400405
certs[:signing] << ary
@@ -429,7 +434,7 @@ def get_sp_certs_multi
429434
end
430435

431436
certs[type] << [
432-
RubySaml::Utils.build_cert_object(cert),
437+
build_cert_object(cert),
433438
RubySaml::Utils.build_private_key_object(key)
434439
].freeze
435440
end
@@ -438,5 +443,11 @@ def get_sp_certs_multi
438443
certs.each { |_, ary| ary.freeze }
439444
certs
440445
end
446+
447+
def build_cert_object(cert)
448+
return cert if cert.is_a?(OpenSSL::X509::Certificate)
449+
450+
OneLogin::RubySaml::Utils.build_cert_object(cert)
451+
end
441452
end
442453
end

test/settings_test.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,47 @@ class SettingsTest < Minitest::Test
515515
end
516516
end
517517

518+
it "handles OpenSSL::X509::Certificate objects for single case" do
519+
@settings.certificate = OpenSSL::X509::Certificate.new(cert_text1)
520+
@settings.private_key = key_text1
521+
522+
actual = @settings.get_sp_certs
523+
expected = [[cert_text1, key_text1]]
524+
assert_equal [:signing, :encryption], actual.keys
525+
assert_equal expected, actual[:signing].map {|ary| ary.map(&:to_pem) }
526+
assert_equal expected, actual[:encryption].map {|ary| ary.map(&:to_pem) }
527+
end
528+
529+
it "handles OpenSSL::X509::Certificate objects for single case with new cert" do
530+
@settings.certificate = cert_text1
531+
@settings.certificate_new = OpenSSL::X509::Certificate.new(cert_text2)
532+
@settings.private_key = key_text1
533+
534+
actual = @settings.get_sp_certs
535+
expected = [[cert_text1, key_text1], [cert_text2, key_text1]]
536+
assert_equal [:signing, :encryption], actual.keys
537+
assert_equal expected, actual[:signing].map {|ary| ary.map(&:to_pem) }
538+
assert_equal expected, actual[:encryption].map {|ary| ary.map(&:to_pem) }
539+
end
540+
541+
it "handles OpenSSL::X509::Certificate objects for multi case" do
542+
x509_certificate1 = OpenSSL::X509::Certificate.new(cert_text1)
543+
x509_certificate2 = OpenSSL::X509::Certificate.new(cert_text2)
544+
@settings.sp_cert_multi = {
545+
signing: [{ certificate: x509_certificate1, private_key: key_text1 },
546+
{ certificate: cert_text2, private_key: key_text1 }],
547+
encryption: [{ certificate: x509_certificate2, private_key: key_text1 },
548+
{ certificate: cert_text3, private_key: key_text2 }]
549+
}
550+
551+
actual = @settings.get_sp_certs
552+
expected_signing = [[cert_text1, key_text1], [cert_text2, key_text1]]
553+
expected_encryption = [[cert_text2, key_text1], [cert_text3, key_text2]]
554+
assert_equal [:signing, :encryption], actual.keys
555+
assert_equal expected_signing, actual[:signing].map {|ary| ary.map(&:to_pem) }
556+
assert_equal expected_encryption, actual[:encryption].map {|ary| ary.map(&:to_pem) }
557+
end
558+
518559
it "sp_cert_multi allows sending only signing" do
519560
@settings.sp_cert_multi = {
520561
signing: [{ certificate: cert_text1, private_key: key_text1 },

0 commit comments

Comments
 (0)