Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node RSAKeyValue from my Idp's SAML metadatas #427

Open
MatthieuCt opened this issue Feb 6, 2020 · 3 comments
Open

Node RSAKeyValue from my Idp's SAML metadatas #427

MatthieuCt opened this issue Feb 6, 2020 · 3 comments

Comments

@MatthieuCt
Copy link

MatthieuCt commented Feb 6, 2020

Hi,

I'm trying to use your library inside one of my project but I've reached a deadlock.

My idp's metadata contains node called RSAKeyValue. Here is an example of the KeyDescriptor:

  <KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
          <ds:KeyValue>
	<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
		<Modulus>Modulus Content</Modulus>
		<Exponent>AQAB</Exponent>
	  </RSAKeyValue>
          </ds:KeyValue>
      </ds:KeyInfo>
  </KeyDescriptor>

Does php-saml support RSAKeyValue node ?

If so how am I supposed to write settings ?

@pitbulk
Copy link
Contributor

pitbulk commented Feb 6, 2020

php-saml uses xmlseclibs and in that library I find on the method staticLocateKeyInfo the term
[RSAKeyValue(https://github.com/robrichards/xmlseclibs/blob/0f5466070e2a0f2d5d7f41968afdbbf982eea69c/src/XMLSecEnc.php#L443)

Can you provide more details in what are you trying to achieve?

@MatthieuCt
Copy link
Author

I'm trying to setup SSO connection via SAML. Actually I'm using https://github.com/hslavich/OneloginSamlBundle to do so as I'm working with Symfony. (That's why I referenced this issue in my original issue on haslavich's project)

Idp metadata looks like this :

<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
    entityID="https://sso.app.com/saml/metadata">

  <IDPSSODescriptor
      WantAuthnRequestsSigned="true"
      protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
	        <ds:X509Certificate>Cert</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:KeyValue>
          <RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
            <Modulus>Modulus</Modulus>
            <Exponent>AQAB</Exponent>
          </RSAKeyValue>
        </ds:KeyValue>
      </ds:KeyInfo>
    <ArtifactResolutionService
      isDefault="true"
      index="0"
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/artifact" />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/singleLogoutSOAP" />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://sso.app.com/saml/singleLogout"
      
      ResponseLocation="https://sso.app.com/saml/singleLogoutReturn"
      />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://sso.app.com/saml/singleLogout"
      
      ResponseLocation="https://sso.app.com/saml/singleLogoutReturn"
      />
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://sso.app.com/saml/singleSignOn"
      />
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://sso.app.com/saml/singleSignOn"
      />
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
      Location="https://sso.app.com/saml/singleSignOnArtifact"
      />
    <SingleSignOnService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/singleSignOnSOAP" />
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
  </IDPSSODescriptor>

  <SPSSODescriptor
      AuthnRequestsSigned="true"
      WantAssertionsSigned="true"
      protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
	        <ds:X509Certificate>Cert</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:KeyValue>
          <RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
            <Modulus>Modulus</Modulus>
            <Exponent>AQAB</Exponent>
          </RSAKeyValue>
        </ds:KeyValue>
      </ds:KeyInfo>
    </KeyDescriptor>
    <ArtifactResolutionService
      isDefault="true"
      index="0"
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/artifact" />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/proxySingleLogoutSOAP" />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
      Location="https://sso.app.com/saml/proxySingleLogout"
      
      ResponseLocation="https://sso.app.com/saml/proxySingleLogoutReturn"
      />
    <SingleLogoutService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://sso.app.com/saml/proxySingleLogout"
      
      ResponseLocation="https://sso.app.com/saml/proxySingleLogoutReturn"
      />
    <AssertionConsumerService
      isDefault="false"
      index="0"
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
      Location="https://sso.app.com/saml/proxySingleSignOnArtifact" />
    <AssertionConsumerService
      isDefault="true"
      index="1"
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
      Location="https://sso.app.com/saml/proxySingleSignOnPost" />
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
  </SPSSODescriptor>

  <AttributeAuthorityDescriptor
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <KeyDescriptor use="signing">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
	        <ds:X509Certificate>Cert</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <KeyDescriptor use="encryption">
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:KeyValue>
          <RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
            <Modulus>Modulus</Modulus>
            <Exponent>AQAB</Exponent>
          </RSAKeyValue>
        </ds:KeyValue>
      </ds:KeyInfo>
    </KeyDescriptor>
    <AttributeService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
      Location="https://sso.app.com/saml/AA/SOAP"/>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:kerberos</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:entity</NameIDFormat>
    <NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
  </AttributeAuthorityDescriptor>
  
  <Organization>
    <OrganizationName xml:lang="en">Organization</OrganizationName>
    <OrganizationDisplayName xml:lang="en">Organization</OrganizationDisplayName>
    <OrganizationURL xml:lang="en">https://sso.app.com/</OrganizationURL>
  </Organization>

</EntityDescriptor>

I've already tried to parse Idp's metadata using IdpMetadataParser, I get this array

array(2) { 
    ["idp"]=> array(4) { 
        ["entityId"]=> string(42) "https://sso.app.com/saml/metadata" 
        ["singleSignOnService"]=> array(2) { 
            ["url"]=> string(46) "https://sso.app.com/saml/singleSignOn" 
            ["binding"]=> string(50) "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        }
        ["singleLogoutService"]=> array(3) { 
            ["url"]=> string(46) "https://sso.app.com/saml/singleLogout" 
            ["binding"]=> string(50) "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 
            ["responseUrl"]=> string(52) "https://sso.app.com/saml/singleLogoutReturn" 
        }
        ["x509cert"]=> string(1133) "Cert"
    }
    ["sp"]=> array(1) { 
        ["NameIDFormat"]=> string(54) "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    }
}

@pitbulk
Copy link
Contributor

pitbulk commented Nov 25, 2020

It seems that xmlseclibs support a way to convert RSAKeyValue Modulus/Exponent to PEM format:
https://github.com/robrichards/xmlseclibs/blob/e6626a857b2bb0e7f81d32b20bfef7f935b49b46/src/XMLSecurityKey.php#L734

So we need to extend the parseXML method

to not only search by:

$keyDescriptorCertSigningNodes = OneLogin_Saml2_Utils::query($dom, './md:KeyDescriptor[not(contains(@use, "encryption"))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate', $idpDescriptor);

$keyDescriptorCertEncryptionNodes = OneLogin_Saml2_Utils::query($dom, './md:KeyDescriptor[not(contains(@use, "signing"))]/ds:KeyInfo/ds:X509Data/ds:X509Certificate', $idpDescriptor);

but also search by:

$keyDescriptorCertSigningKeyValueNodes = OneLogin_Saml2_Utils::query($dom, './md:KeyDescriptor[not(contains(@use, "encryption"))]/ds:KeyInfo/ds:KeyValue', $idpDescriptor);

$keyDescriptorCertEncryptionKeyValueNodes = OneLogin_Saml2_Utils::query($dom, './md:KeyDescriptor[not(contains(@use, "signing"))]/ds:KeyInfo/KeyValue', $idpDescriptor);

and later extract from the nodes the modulus and exponent values
and call with them to convertRSA method to get the formated pem version,
After it, you will get the value in a similar way than providing the ds:X509Data in the XML
when executing

OneLogin_Saml2_Utils::formatCert($keyDescriptorCertSigningNode->nodeValue, false);

PR welcome

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

No branches or pull requests

2 participants