SAML 2.0 SP metadata: Purpose and the use of certificate - metadata

Here is the part of SP metadata.
Reference: Metadata for the OASIS Security Assertion Markup Language (SAML) V2.0
...
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
...
Are there any benefits to choose same (or different) certificate in both signing and encryption certificate ?
What is the purpose of including signing certificate here ?
If the message is sent through https, a transport layer encryption is provided. Do we still need to include encryption certificate here ?

In SAML 2.0 Web SSO's metadata providers typically declare the same certificate for both signing and encryption usage.
There are some use-cases where usage of different keys makes sense - e.g. when SP itself is not supposed to be able to decrypt data provided by IDP (e.g. nameID or attributes), but this is only done by the ultimate recipient of the Assertion; or when a different party provides content for creation of assertion than the party who actually creates the SAML messages - but those use-cases are rare and more relevant for other profiles than Web SSO.
The signing certificate is included in order to inform users of the metadata on how to verify messages provided by the issuer of the metadata. For example, when SP receives a message from IDP, it uses signing certificate defined in IDP's metadata in order to verify whether the message was created by the IDP and wasn't tampered with during transport.
You typically don't need to include the encryption certificate in case encryption is done on transport layer and you don't perform any encryption on message level (e.g. of whole message, assertion, nameID or attributes).

Related

OpenAM SSO SAML AuthnRequestsSigned error

I am trying to set the signing and encryption option on my SP metadata to have AuthnRequestsSigned="true" but my AM server keeps throwing the below Error in the /debug/Federation log
Authentication Requests Signed option is the only one giving me issues.
Im running
ForgeRock Access Management 6.5.2
Tomcat 8.0.35
openjdk version "1.8.0_212"
AM Settings
Error Message
libSAML2:08/02/2019 03:16:50:299 PM UTC: Thread[http-nio-80-exec-8,5,main]: TransactionId[f1638b0a-6687-4953-ae04-8ce8c9299079-62363]
ERROR: UtilProxySAMLAuthenticator.authenticate: authn request destination verification failed for
IdpEntity: http://x.canadacentral.cloudapp.azure.com:80/opensso
MetaAlias: /idp Destination: http://x.canadacentral.cloudapp.azure.com/opensso/SSORedirect/metaAlias/idp
Location: http://x.canadacentral.cloudapp.azure.com:80/opensso/SSORedirect/metaAlias/idp
SP Meta-data
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2019-08-02T12:04:36Z"
cacheDuration="PT604800S" entityID="nestjs-sp-signed-0070">
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
</md:KeyDescriptor>
<md:NameIDFormat>
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
</md:NameIDFormat>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="http://localhost:3000/auth/logout/callback"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="http://localhost:3000/auth/login/callback" index="0"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post"
Location="http://localhost:3000/auth/login/callback" index="1"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
Location="http://localhost:3000/auth/login/callback" index="2"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"
Location="http://localhost:3000/auth/login/callback" index="3"/>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:profiles:holder-of-key:SSO:browser"
Location="http://localhost:3000/auth/login/callback" index="4"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Passport Settings
export const samlPassportConf = {
issuer: 'nestjs-sp-signed-0070', // match metadata entityID
identifierFormat: 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
callbackUrl: 'http://localhost:3000/auth/login/callback',
entryPoint: 'http://x.canadacentral.cloudapp.azure.com/opensso/SSORedirect/metaAlias/idp',
logoutUrl: 'http://x.canadacentral.cloudapp.azure.com/opensso/IDPSloRedirect/metaAlias/idp',
privateCert: fs.readFileSync('cert/privatekey.pem', 'utf-8'),
decryptionPvk: fs.readFileSync('cert/privatekey.pem', 'utf-8'),
};
Question:
I am trying to set the signing and encryption option on my SP metadata to have AuthnRequestsSigned="true" but my AM server keeps throwing the below Error in the /debug/Federation log
(1) Authentication Requests Signed option is the only one giving me issues.
(2) I unchecked authentication requests signed and it works.
Answer:
(1) You unchecked authentication requests signed, indicating that OpenAM SAML IdP would never verify the signature of authentication request sent by your SAML SP, thus it works as you expected.
(2) Your SAML SP signs Authentication Request using a signing key.
OpenAM SAML IdP uses the corresponding public cert (which it extracts from your SAML SP metadata) to verify the signed Authentication Request sent by your SAML SP.
If the Authentication Request is signed, OpenAM SAML IdP MUST verify Destination (i.e., SAML Login URL/Entrypoint of SAML IdP) and entityID of SAML SP.
Two issues have been identified:
(I) Destination "http://x.canadacentral.cloudapp.azure.com/opensso/SSORedirect/metaAlias/idp"
does NOT exactly matches the location/entryPoint
"http://idp5.canadacentral.cloudapp.azure.com/opensso/SSORedirect/metaAlias/idp"
Your SAML SP sends "idp5.canadacentral", but OpenAM SAML IdP receives "x.canadacentral"
(II) issuer: 'nestjs-sp-signed-0070' in the Authentication Request sent by your SAML SP
does NOT match
entityID="nestjs-sp-signed-0090"
in your SAMP SP metadata uploaded to OpenAM SAML IdP.
Resolution:
In your Passport Settings, Replace 'nestjs-sp-signed-0070' with 'nestjs-sp-signed-0090', because OpenAM SAML IdP MUST verify that entityID of your SAML SP 'nestjs-sp-signed-0070' carried by the Authentication Request should be exactly equal to entityID of your SAML SP 'nestjs-sp-signed-0090' in your SAML SP metadata.
(III) You need to ensure that private key and public cert should be a key pair. that is,
private key "privateCert: fs.readFileSync('cert/privatekey.pem', 'utf-8')" in your Passport Settings
should be corresponding to
public cert in your SAML SP metadata
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
Potential root cause of Authentication Requests Signed is that
OpenAM SAML IdP uses the public cert of encryption (carried by your SAML SP metadata) to verify the signed Authentication Request. That is, OpenAM SAML IdP uses the wrong public cert for signature verification.
Resolution:
Use the same key pair for both signing and encryption. In your SAML SP metadata, let both signing cert and encryption cert "" be the same, that is,
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
is the same as
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>...
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
</md:KeyDescriptor>

IBM Bluemix Single Sign On (SSO) import metadata error FBTRBA331E

We have a Single Sign On service connects to our Node.js app on IBM Bluemix. We need to use SAML Enterprise as our identify source. When I upload the SAML 2.0 Identity Provider metadata file - I get the error saying:
Error executing REST service.
FBTRBA331E The action: Import Metadata failed because the metadata file or federation role is invalid.
I also found the error code from another IBM page, but it doesn't say how to fix it.
http://www.ibm.com/support/knowledgecenter/SSELE6_8.0.1.3/com.ibm.isam.doc/messages/messages/FBTRBA331E.html
According to this Bluemix SSO document (scroll down to the SAML metadata files section):
https://console.ng.bluemix.net/docs/services/SingleSignOn/saml_information.html#saml_information
IdP (Identify Provider) metadata file must contain both Signing and Encryption Key sections. If the encryption certificate is missing, you see an upload error indicating that the format of the metadata file is wrong or that improper federation roles exist.
Both of the following KeyDescriptor sections are required.
<md:KeyDescriptor use="signing">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>(...signing certificate...)</X509Certificate>
</X509Data>
</KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>(...encryption certificate...)</X509Certificate>
</X509Data>
</KeyInfo>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
</md:KeyDescriptor>
Please double check the metadata file you received from your Identity Provider to see if the encryption section is missing.

SAML Secured AuthnRequest Fails

I'm not able to make a secured ECP AuthnRequest to my Shibboleth IdP. I've got a small proof of concept SP running which is based heavily on the Spring SAML extension sample app. My SP metadata was generated using the Spring SAML extension sample app's metadata generator. The signing key being used is the apollo one included with the sample app samlKeystore.jks key store, all of which is also in my own small SP app.
In my SP metadata, I have the AuthnRequestsSigned attribute set to true like so :
<md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
If I set AuthnRequestsSigned to false and make the ECP SOAP POST to the IdP, it works just fine. I get the proper SOAP message back from the IdP. But if that value is true, I get a non-descriptive error message:
<env:Fault>
<faultcode>env:Client</faultcode>
<faultstring>An error occurred processing the request.</faultstring>
<detail/>
</env:Fault>
I look in the Shibboleth (IdP) logs and see:
Attempting to extract credential from an X509Data
Found 1 X509Certificates
Found 0 X509CRLs
Single certificate was present, treating as end-entity certificate
Credentials successfully extracted from child {http://www.w3.org/2000/09/xmldsig#}X509Data by provider org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider
A total of 1 credentials were resolved
This displays twice in the log for my transaction. My assumption is because it's finding the certificate in the request and in my SP metadata. Further down in the log during this same transaction I see this followed by a stack trace:
Attempting to validate signature using key from supplied credential
Creating XMLSignature object
Validating signature with signature algorithm URI: http://www.w3.org/2000/09/xmldsig#rsa-sha1
Validation credential key algorithm 'RSA', key instance class 'sun.security.rsa.RSAPublicKeyImpl'
Signature did not validate against the credential's key
Signature validation using candidate validation credential failed
Signature did not validate against the credential's key
I compared the certificate that is in the ECP POST AuthnRequest to the one in my SP metadata used for "signing" and they are the same. So I'm not sure why I'm getting this error.
My understanding is that the IdP will take the certificate found in the <ds:X509Certificate> tag of the request (which is the public key) and make sure that's the same one defined in the SP metadata. Then use that cert to verify the signature value which is also in the request in the <ds:SignatureValue> element. If it validates then it moves forward with the AuthnRequest. Is this accurate?
What piece am I missing?
Update 1: I've added the logging lines as suggested and here's all it shows for the ECP requests:
signatureMethodURI = http://www.w3.org/2000/09/xmldsig#rsa-sha1
jceSigAlgorithm = SHA1withRSA
jceSigProvider = SunRsaSign
PublicKey = Sun RSA public key, 2048 bits
modulus: <long value here>
public exponent: 65537
Signature verification failed.
One thing of note, if I make a request to my SP via a browser and I'm not signed in, I get redirected to my IdP login page as expected. I check the IdP logs and see that that request was also signed and it validates. I looked at the form data sent to the IdP from the SP and see that AuthnRequest is also signed using the same certificate but the SignatureValue value are different of course. That non-ECP request data XML looks very similar to the ECP request SOAP XML yet the ECP one fails.
UPDATE 2: I'm using spring-security-saml-1.0.0.RELEASE, and Shibboleth IdP v2.4.0. Here's a sample message I'm sending to the IdP:
<?xml version="1.0" encoding="UTF-8"?>
<soap11:Envelope
xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header>
</soap11:Header>
<soap11:Body>
<saml2p:AuthnRequest
xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://1XP21VRS.mydomain.com:8080/proofofconceptapp-sso/saml/SSO/alias/conceptSSO" ForceAuthn="false" ID="a3j6fd01d0ciahe25b56i326bhe212" IsPassive="false" IssueInstant="2014-10-24T19:37:43.207Z" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:PAOS" Version="2.0">
<saml2:Issuer
xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">http://1XP21VRS.mydomain.com:8080/proofofconceptapp-sso
</saml2:Issuer>
<ds:Signature
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#a3j6fd01d0ciahe25b56i326bhe212">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>mMJbjpmWr6OMP9eU70RA9TtfXGY=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>I6rHpgjWgl5l5sjst+VHuSUnjUaOBnPIbUrWwcAfdTDSFY2wxUuNdHpXt/YqBfP9ZKdTWZV1IjbTR666T7sa1bZawgT3UO07FoBVAc5z+AH0nCvIz+UNSqpunPTaEdUhSaGmNHSItvFtvz2fDmvZl18GwXrTz4g6vvxKkdo/FijgvYldfYYuO+obcjof1SJmpOOr1iRNvpyGQMxcaH9e07QfJO9SDcLP2elvPvwbJsGGl/n/3sIG+kIm0MECU3hv/4pLx6+SyHDXjdhdOD2HyxGL1t7iIYG1AaDX4dkIt2wH2WOyzhfO2MyykqChhRcYWFdEdgqaQW/IBLPxsVjN9g==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIDUjCCAjqgAwIBAgIEUOLIQTANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQGEwJGSTEQMA4GA1UE
CBMHVXVzaW1hYTERMA8GA1UEBxMISGVsc2lua2kxGDAWBgNVBAoTD1JNNSBTb2Z0d2FyZSBPeTEM
MAoGA1UECwwDUiZEMQ8wDQYDVQQDEwZhcG9sbG8wHhcNMTMwMTAxMTEyODAxWhcNMjIxMjMwMTEy
ODAxWjBrMQswCQYDVQQGEwJGSTEQMA4GA1UECBMHVXVzaW1hYTERMA8GA1UEBxMISGVsc2lua2kx
GDAWBgNVBAoTD1JNNSBTb2Z0d2FyZSBPeTEMMAoGA1UECwwDUiZEMQ8wDQYDVQQDEwZhcG9sbG8w
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCXqP0wqL2Ai1haeTj0alwsLafhrDtUt00E
5xc7kdD7PISRA270ZmpYMB4W24Uk2QkuwaBp6dI/yRdUvPfOT45YZrqIxMe2451PAQWtEKWF5Z13
F0J4/lB71TtrzyH94RnqSHXFfvRN8EY/rzuEzrpZrHdtNs9LRyLqcRTXMMO4z7QghBuxh3K5gu7K
qxpHx6No83WNZj4B3gvWLRWv05nbXh/F9YMeQClTX1iBNAhLQxWhwXMKB4u1iPQ/KSaal3R26pON
UUmu1qVtU1quQozSTPD8HvsDqGG19v2+/N3uf5dRYtvEPfwXN3wIY+/R93vBA6lnl5nTctZIRsyg
0Gv5AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFQwAAYUjso1VwjDc2kypK/RRcB8bMAUUIG0hLGL
82IvnKouGixGqAcULwQKIvTs6uGmlgbSG6Gn5ROb2mlBztXqQ49zRvi5qWNRttir6eyqwRFGOM6A
8rxj3Jhxi2Vb/MJn7XzeVHHLzA1sV5hwl/2PLnaL2h9WyG9QwBbwtmkMEqUt/dgixKb1Rvby/tBu
RogWgPONNSACiW+Z5o8UdAOqNMZQozD/i1gOjBXoF0F5OksjQN7xoQZLj9xXefxCFQ69FPcFDeEW
bHwSoBy5hLPNALaEUoa5zPDwlixwRjFQTc5XXaRpgIjy/2gsL8+Y5QRhyXnLqgO67BlLYW/GuHE=</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</saml2p:AuthnRequest>
</soap11:Body>
</soap11:Envelope>
I'm pretty much just copying the response from the initial PAOS request to the SP (Spring SAML), removing the header innards, and sending that along to the Shibboleth IdP. The headers that I send are:
Content-Type: text/xml
Authorization: Basic <base64 encoded credential string here>
Update 3: Signed non-ECP AuthnRequests validate just fine. So it's only SOAP ECP AuthnRequests to the IdP where the signature fails. Any ideas?
Update 4: Still can't get this working. Any help would be appreciated.

Is SAML certificate redundant?

To configure Salesforce for SAML SSO you need to upload your organization's SAML certificate (step 7 here).
At the same time, I can see that SAML certificate is part of organization IdP metadata file:
<IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="encryption">
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>...
</X509Certificate>
</X509Data>
</KeyInfo>
</KeyDescriptor>
...
</IDPSSODescriptor>
Doesn't that make SAML certificate upload redundant?
For SAML the certitifiate does not need to be send in any other form than metadata. Salesforce may need this for other puruposes though. The implementation may require the certificate to be installed. This is the case in OpenAM, a certificate file must then be installed in the machines java keystore

SAML 2.0 SP metadata

I am implementing an SP initiated web browser SAML SSO profile.
My application is the SP.
The customers ask me to supply them a metadata file.
I have a Shibboleth metadata file I used for testing my application against a local Shibboleth IDP server.
Now, When I sent this file to a non-Shibboleth customer, he said that this file is a Shibboleth file and he needs a different one.
My question is:
Is there a standard SP metadata file I can use which will fit all customers, no matter what IDP they are using?
I found an example:
<md:EntityDescriptor
xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
ID="_z7b6d339da96016iib0ed98ed476er3d7ae4dct5"
entityID="https://my.application.sp/login">
<md:SPSSODescriptor AuthnRequestsSigned="false"
WantAssertionsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509SubjectName>CN=my.application.sp</ds:X509SubjectName>
<ds:X509Certificate>--my certificate--</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>--my certificate--</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:AssertionConsumerService
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://my.application.sp/handleLogin" index="0"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
Is this enough?
Can I use this as a general metadata for all the IDPs?
Thanks
The sp.xml is constrained by SAML which is an open protocol so there's no such thing as "Shibboleth metadata" - it is SAML metadata as used by Shibboleth.
The various details have to be negotiated between the two parties e.g. you have specified HTTP-POST.
What if the IDP prefers HTTP-Redirect?
What if they want the nameid-format to be persistent rather than transient and so on.
Or your certificate might be 1024 bit instead of 2048?
The metadata as it pertains to SAML can be used as a general example but it probably won't meet all the individual IDP requirements.