unable to validate signature from a keystone issued SAML assertion

Bug #1402916 reported by Steve Martinelli
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Fix Released
High
Guang Yee
Juno
Fix Released
High
Guang Yee

Bug Description

In the keystone 2 keystone federation workflow, a keystone acting as an SP should be able to validate the signature of a SAML assertion from a keystone acting as an IdP.

The current work around is to use the NullSecurity rule in the Security Policy file from Shibboleth (this file is usually located at /etc/shibboleth/security-policy.xml):

  <SecurityPolicies xmlns="urn:mace:shibboleth:2.0:native:sp:config">
      <Policy id="default" validate="false">
          <PolicyRule type="NullSecurity"/>
      </Policy>
  </SecurityPolicies>

For what it's worth, it seems that mod_shib performs two other checks in a pipeline fashion, the others being "ExplicitKey" and "PKIX" checks

Revision history for this message
Steve Martinelli (stevemar) wrote :
Download full text (3.2 KiB)

The logs from shibboleth are as follows:

# tail -f /var/log/shibboleth/shibd.log
2014-12-15 08:00:37 DEBUG Shibboleth.Listener [2]: dispatching message (default/SAML2/ECP)
2014-12-15 08:00:37 DEBUG OpenSAML.MessageDecoder.SAML2ECP [2]: validating input
2014-12-15 08:00:37 DEBUG OpenSAML.MessageDecoder.SAML2ECP [2]: received message:
<soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/"> *** Truncated for clarity *** </soap11:Envelope>
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.MessageFlow [2]: evaluating message flow policy (replay checking on, expiration 60)
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.ClientCertAuth [2]: ignoring message, no issuer metadata supplied
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.XMLSigning [2]: ignoring message, no issuer metadata supplied
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.SimpleSigning [2]: ignoring message, no issuer metadata supplied
2014-12-15 08:00:37 DEBUG OpenSAML.MessageDecoder.SAML2 [2]: extracting issuer from SAML 2.0 protocol message
2014-12-15 08:00:37 DEBUG OpenSAML.MessageDecoder.SAML2 [2]: message from (https://keystone.idp/keystone/main/v3/OS-FEDERATION/saml2/idp)
2014-12-15 08:00:37 DEBUG OpenSAML.MessageDecoder.SAML2 [2]: searching metadata for message issuer...
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.MessageFlow [2]: evaluating message flow policy (replay checking on, expiration 60)
2014-12-15 08:00:37 DEBUG XMLTooling.StorageService [2]: inserted record (ac89be0ee993481c957a5f02bf34a0f0) in context (MessageFlow) with expiration (1418652199)
2014-12-15 08:00:37 DEBUG Shibboleth.SSO.SAML2 [2]: processing message against SAML 2.0 SSO profile
2014-12-15 08:00:37 DEBUG Shibboleth.SSO.SAML2 [2]: extracting issuer from SAML 2.0 assertion
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.MessageFlow [2]: evaluating message flow policy (replay checking on, expiration 60)
2014-12-15 08:00:37 DEBUG XMLTooling.StorageService [2]: inserted record (10263fa4539c490598f70c86f3f0e94b) in context (MessageFlow) with expiration (1418652199)
2014-12-15 08:00:37 DEBUG OpenSAML.SecurityPolicyRule.XMLSigning [2]: validating signature profile
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.ExplicitKey [2]: attempting to validate signature with the peer's credentials
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.ExplicitKey [2]: public key did not validate signature: Digital signature does not validate with the supplied key.
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.ExplicitKey [2]: no peer credentials validated the signature
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.PKIX [2]: validating signature using certificate from within the signature
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.PKIX [2]: Digital signature does not validate with the supplied key.
2014-12-15 08:00:37 DEBUG XMLTooling.TrustEngine.PKIX [2]: failed to verify signature with embedded certificates
2014-12-15 08:00:37 ERROR OpenSAML.SecurityPolicyRule.XMLSigning [2]: unable to verify message signature with supplied trust engine
2014-12-15 08:00:37 WARN Shibboleth.SSO.SAML2 [2]: detected a problem with assertion: Message was signed, but sig...

Read more...

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

I think it's safe to confirm this one and mark it as high. I'm sure enough people have run into this - we can close it out if needed if it's a config issue.

Changed in keystone:
importance: Undecided → High
status: New → Confirmed
Guang Yee (guang-yee)
Changed in keystone:
assignee: nobody → Guang Yee (guang-yee)
Revision history for this message
Guang Yee (guang-yee) wrote :

Problem was due to xml namespace. When we sign the assertion, it was converted to an XML string.

https://github.com/openstack/keystone/blob/master/keystone/contrib/federation/idp.py#L401

assertion.to_string()

However, since we don't explicitly specify the prefix for the namespace, the default prefixes were used. For example,

<?xml version='1.0' encoding='UTF-8'?>
<ns0:Assertion xmlns:ns0="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns1="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="b7886b9ba0ec4204888ea4c426423825" IssueInstant="2015-01-06T07:29:23Z" Version="2.0">

Notice the "ns0", "ns1", etc.

However, when we wrap the assertion inside the Response, assertion element became the child element of Response. Consequently, the namespaces prefixes got reassigned. For example,

<?xml version='1.0' encoding='UTF-8'?>
<ns0:Response xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ns1="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Destination="recipient" ID="13b2c5c0e1b54abda42e4472c4e4410d" IssueInstant="2015-01-06T07:29:23Z" Version="2.0"><ns1:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">issuer</ns1:Issuer><ns0:Status><ns0:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></ns0:Status><ns1:Assertion ID="b7886b9ba0ec4204888ea4c426423825" IssueInstant="2015-01-06T07:29:23Z" Version="2.0">

Notice that it was "ns0" for "urn:oasis:names:tc:SAML:2.0:assertion" when the signature was created. Now it became "ns1" after the Response was created.

So now we have an invalid signature because the namespace prefixes are part of the signature.

Revision history for this message
Guang Yee (guang-yee) wrote :

One way to fix this would be to make the namespace prefixes explicit. For example,

        file_path = fileutils.write_to_tempfile(assertion.to_string(
            nspair={'saml': saml2.NAMESPACE,
                            'xmldsig': xmldsig.NAMESPACE}))

I've tested this on my local setup and it seem to solve the problem.

I'll push a patch shortly.

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (master)

Fix proposed to branch: master
Review: https://review.openstack.org/145159

Changed in keystone:
status: Confirmed → In Progress
Revision history for this message
Malini Bhandaru (malini-k-bhandaru) wrote :

Good catch and fix to be Guang Yee!

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to keystone (master)

Reviewed: https://review.openstack.org/145159
Committed: https://git.openstack.org/cgit/openstack/keystone/commit/?id=abb5f0022f117468016f2736206139830e782d0a
Submitter: Jenkins
Branch: master

commit abb5f0022f117468016f2736206139830e782d0a
Author: guang-yee <email address hidden>
Date: Mon Jan 5 23:50:48 2015 -0800

    explicit namespace prefixes for SAML2 assertion

    Make sure the namespace prefixes for the signed SAML2 assertion are explicitly
    defined so they don't get reassigned when we wrap it inside the response.

    Change-Id: I8751dfbec502e0c71d075f31e6067b2ed65e3851
    Closes-Bug: #1402916

Changed in keystone:
status: In Progress → Fix Committed
Revision history for this message
Rodrigo Duarte (rodrigodsousa) wrote :

Nice Guang Yee!

no longer affects: keystone/kilo
Changed in keystone:
milestone: none → kilo-2
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (stable/juno)

Fix proposed to branch: stable/juno
Review: https://review.openstack.org/150190

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to keystone (stable/juno)

Reviewed: https://review.openstack.org/150190
Committed: https://git.openstack.org/cgit/openstack/keystone/commit/?id=acdf034eb189773494849c4b7798f4bf59ea8517
Submitter: Jenkins
Branch: stable/juno

commit acdf034eb189773494849c4b7798f4bf59ea8517
Author: guang-yee <email address hidden>
Date: Mon Jan 5 23:50:48 2015 -0800

    explicit namespace prefixes for SAML2 assertion

    Make sure the namespace prefixes for the signed SAML2 assertion are explicitly
    defined so they don't get reassigned when we wrap it inside the response.

    This patch also fix Python2.6 support by replacing subprocess.check_output()
    with subprocess.Popen().

    Change-Id: I8751dfbec502e0c71d075f31e6067b2ed65e3851
    Closes-Bug: #1402916
    (cherry picked from commit abb5f0022f117468016f2736206139830e782d0a)

Thierry Carrez (ttx)
Changed in keystone:
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in keystone:
milestone: kilo-2 → 2015.1.0
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.