diff --git a/lib/onelogin/ruby-saml/settings.rb b/lib/onelogin/ruby-saml/settings.rb index 401732ac..c395602e 100644 --- a/lib/onelogin/ruby-saml/settings.rb +++ b/lib/onelogin/ruby-saml/settings.rb @@ -312,28 +312,33 @@ def get_all_sp_certs # Validate certificate, certificate_new, private_key, and sp_cert_multi params. def validate_sp_certs_params! - multi = sp_cert_multi && !sp_cert_multi.empty? - cert = certificate && !certificate.empty? - cert_new = certificate_new && !certificate_new.empty? - pk = private_key && !private_key.empty? - if multi && (cert || cert_new || pk) + has_multi = sp_cert_multi && !sp_cert_multi.empty? + has_pk = private_key && !private_key.empty? + if has_multi && (has_cert?(certificate) || has_cert?(certificate_new) || has_pk) raise ArgumentError.new("Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters") end end + # Check if a certificate is present. + def has_cert?(cert) + return true if cert.is_a?(OpenSSL::X509::Certificate) + + cert && !cert.empty? + end + # Get certs from certificate, certificate_new, and private_key parameters. def get_sp_certs_single certs = { :signing => [], :encryption => [] } sp_key = OneLogin::RubySaml::Utils.build_private_key_object(private_key) - cert = OneLogin::RubySaml::Utils.build_cert_object(certificate) + cert = build_cert_object(certificate) if cert || sp_key ary = [cert, sp_key].freeze certs[:signing] << ary certs[:encryption] << ary end - cert_new = OneLogin::RubySaml::Utils.build_cert_object(certificate_new) + cert_new = build_cert_object(certificate_new) if cert_new ary = [cert_new, sp_key].freeze certs[:signing] << ary @@ -368,7 +373,7 @@ def get_sp_certs_multi end certs[type] << [ - OneLogin::RubySaml::Utils.build_cert_object(cert), + build_cert_object(cert), OneLogin::RubySaml::Utils.build_private_key_object(key) ].freeze end @@ -377,6 +382,12 @@ def get_sp_certs_multi certs.each { |_, ary| ary.freeze } certs end + + def build_cert_object(cert) + return cert if cert.is_a?(OpenSSL::X509::Certificate) + + OneLogin::RubySaml::Utils.build_cert_object(cert) + end end end end diff --git a/test/settings_test.rb b/test/settings_test.rb index 8e7cb9f6..fc8bcecb 100644 --- a/test/settings_test.rb +++ b/test/settings_test.rb @@ -485,6 +485,47 @@ class SettingsTest < Minitest::Test assert_equal expected_encryption, actual[:encryption].map {|ary| ary.map(&:to_pem) } end + it "handles OpenSSL::X509::Certificate objects for single case" do + @settings.certificate = OpenSSL::X509::Certificate.new(cert_text1) + @settings.private_key = key_text1 + + actual = @settings.get_sp_certs + expected = [[cert_text1, key_text1]] + assert_equal [:signing, :encryption], actual.keys + assert_equal expected, actual[:signing].map {|ary| ary.map(&:to_pem) } + assert_equal expected, actual[:encryption].map {|ary| ary.map(&:to_pem) } + end + + it "handles OpenSSL::X509::Certificate objects for single case with new cert" do + @settings.certificate = cert_text1 + @settings.certificate_new = OpenSSL::X509::Certificate.new(cert_text2) + @settings.private_key = key_text1 + + actual = @settings.get_sp_certs + expected = [[cert_text1, key_text1], [cert_text2, key_text1]] + assert_equal [:signing, :encryption], actual.keys + assert_equal expected, actual[:signing].map {|ary| ary.map(&:to_pem) } + assert_equal expected, actual[:encryption].map {|ary| ary.map(&:to_pem) } + end + + it "handles OpenSSL::X509::Certificate objects for multi case" do + x509_certificate1 = OpenSSL::X509::Certificate.new(cert_text1) + x509_certificate2 = OpenSSL::X509::Certificate.new(cert_text2) + @settings.sp_cert_multi = { + signing: [{ certificate: x509_certificate1, private_key: key_text1 }, + { certificate: cert_text2, private_key: key_text1 }], + encryption: [{ certificate: x509_certificate2, private_key: key_text1 }, + { certificate: cert_text3, private_key: key_text2 }] + } + + actual = @settings.get_sp_certs + expected_signing = [[cert_text1, key_text1], [cert_text2, key_text1]] + expected_encryption = [[cert_text2, key_text1], [cert_text3, key_text2]] + assert_equal [:signing, :encryption], actual.keys + assert_equal expected_signing, actual[:signing].map {|ary| ary.map(&:to_pem) } + assert_equal expected_encryption, actual[:encryption].map {|ary| ary.map(&:to_pem) } + end + it "sp_cert_multi allows sending only signing" do @settings.sp_cert_multi = { signing: [{ certificate: cert_text1, private_key: key_text1 },