Skip to content

Redo supporting multiple certs per ServiceProvider#4898

Merged
zachmargolis merged 9 commits intomainfrom
margolis-redo-multiple-certs
Apr 9, 2021
Merged

Redo supporting multiple certs per ServiceProvider#4898
zachmargolis merged 9 commits intomainfrom
margolis-redo-multiple-certs

Conversation

@zachmargolis
Copy link
Contributor

@zachmargolis zachmargolis commented Apr 8, 2021

This is a draft, I'm putting it down for now and taking a break

The change this time are:

  1. Updating the saml_idp gem to accept multiple certs, and to not need a fingerprint (since that can be derived from the cert): Support Multiple Certs saml_idp#39
  2. Trying to actually construct a working signed logout request... as far as I can tell neither the gem nor our codebase has tests that pass the Signature and SigAlg params.... this is where I'm stuck (update: got it working)

To see just the "redo" diff:
c43651a00e474a8507fb551125e34a13ef2ad547...margolis-redo-multiple-certs

Comment on lines +97 to +103
expect(
certificate.public_key.verify(
OpenSSL::Digest::SHA256.new,
Base64.decode64(signature),
canon_string,
),
).to eq(true)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this passes, but the equivalent .verify inside the gem is failing:

https://github.com/18F/saml_idp/blob/eba368170c24f2a241537565bb1be32532ac754a/lib/saml_idp/xml_security.rb#L190

all the puts statements confirmed of for me that the string, the signature, and the serial are all the same, and the outside verificatin works but the gem says no

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out Hash#to_query does not preserve order, fixed in a31640f

else
current_service_provider.encryption_opts
elsif current_service_provider.encrypt_responses?
cert = saml_request.service_provider.matching_cert || current_service_provider.ssl_certs.first
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in updating the gem to try multiple certs... I figured maybe we just have the gem keep track of which one for us... it's a nasty side effect but I am getting desperate:
https://github.com/18F/saml_idp/pull/39/files#diff-29ac8f422d334e3198b369e7cd6d2139af467645af1128deb0def18de1c05409R27

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's reasonable technical debt to take on - the gem is already a mess and tbh since the signature validation all happens there it feels like it will be cleaner.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed


expect(response).to_not be_redirect

expect { xmldoc.saml_response(first_cert_settings) }.to raise_error
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the assertion I was relying on the most to make sure that I wasn't magically defaulting to a wrong cert, ex if we change matching_cert || service_provider.ssl_certs.last this will fail

@zachmargolis zachmargolis marked this pull request as ready for review April 9, 2021 00:38
@zachmargolis zachmargolis changed the title Redo multiple certs Redo supporting multiple certs per ServiceProvider Apr 9, 2021
Copy link
Contributor

@orenyk orenyk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looked at the new diff and it looks good to me but given the complexity I'd feel better with another set of eyes on it 😄. Nice work!

else
current_service_provider.encryption_opts
elsif current_service_provider.encrypt_responses?
cert = saml_request.service_provider.matching_cert || current_service_provider.ssl_certs.first
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's reasonable technical debt to take on - the gem is already a mess and tbh since the signature validation all happens there it feels like it will be cleaner.

Copy link
Contributor

@stevegsa stevegsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants