Getting ComponentSpace.SAML2.Exceptions.SAMLBindingException while trying to send SAML request to IdP via HTTP-Artifact binding

Hi Team,
I am using low level API to send SAML request to IdP server using HTTP-Artifact binding. I have used below code. While it try to hit the server throw the exception below.
Code calling IdP
created artifactResolveXml. Sample given below .

<samlp:ArtifactResolve ID=“_c5d8e0a0-2b4e-4910-9ea3-08868ee8e061” Version=“2.0” IssueInstant=“2018-05-28T18:28:50.586Z” Destination=“” xmlns:samlp=“urn:oasis:names:tc:SAML:2.0:protocol”><saml:Issuer xmlns:saml=“urn:oasis:names:tc:SAML:2.0:assertion”> Issuer details</saml:Issuer>samlp:Artifact</samlp:Artifact>Request SAMLart value</samlp:ArtifactResolve>

XmlElement artifactResponseXml = ArtifactResolver.SendRequestReceiveResponse(spArtifactResponderURL, artifactResolveXml);


Error :-

ReceiveSAMLResponse for bindingType urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact The SAML response Exception.
ComponentSpace.SAML2.Exceptions.SAMLBindingException: Failed to send/receive SAML request/response over SOAP. —> System.Net.WebException: The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse()
at ComponentSpace.SAML2.Bindings.SOAPBinding.SendRequestReceiveResponse(WebRequest webRequest, XmlElement samlMessage)
— End of inner exception stack trace —
at ComponentSpace.SAML2.Bindings.SOAPBinding.SendRequestReceiveResponse(WebRequest webRequest, XmlElement samlMessage)
at ComponentSpace.SAML2.Bindings.SOAPBinding.SendRequestReceiveResponse(String destinationURL, XmlElement samlMessage)
at ComponentSpace.SAML2.Profiles.ArtifactResolution.ArtifactResolver.SendRequestReceiveResponse(String destinationURL, XmlElement artifactResolve)
at passionapi.SAML.AssertionConsumerService.ReceiveSAMLResponse(SAMLResponse& samlResponse, String& relayState, String bindingType)
SPReceiveSAMLResponse Received SAML response end bindingType urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact
SPurn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact End ProcessSAMLResponse

This looks like a transport-level error establishing an SSL connection.
It’s possible the server certificate fails to validate.
What happens if you attempt to browse to the same URL?
Do you get a certificate error?
If so, you can use the following code to ignore certificate errors.
However, under normal circumstances this shouldn’t be required as the certificate chain should validate.


// In a test environment with self-signed certificates, override certificate validation so all certificates are trusted.
private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}

protected void Application_Start(object sender, EventArgs e)
{
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
}


[quote]
ComponentSpace - 5/28/2018
This looks like a transport-level error establishing an SSL connection.
It's possible the server certificate fails to validate.
What happens if you attempt to browse to the same URL?
Do you get a certificate error?
If so, you can use the following code to ignore certificate errors.
However, under normal circumstances this shouldn't be required as the certificate chain should validate.


// In a test environment with self-signed certificates, override certificate validation so all certificates are trusted.
private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}

protected void Application_Start(object sender, EventArgs e)
{
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
}


[/quote]

Thanks for reply, May i know what TLS used by componentspace to send the request. I checked with our IdP team they said it should be TLS 1.2.
[quote]
ComponentSpace - 5/28/2018
This looks like a transport-level error establishing an SSL connection.
It's possible the server certificate fails to validate.
What happens if you attempt to browse to the same URL?
Do you get a certificate error?
If so, you can use the following code to ignore certificate errors.
However, under normal circumstances this shouldn't be required as the certificate chain should validate.


// In a test environment with self-signed certificates, override certificate validation so all certificates are trusted.
private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}

protected void Application_Start(object sender, EventArgs e)
{
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;
}


[/quote]

We don't have server access so we can only get to know via code only. I will not able to test via browser. I am using subject to load certificate.

X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
X509Certificate2Collection Results = store.Certificates.Find(X509FindType.FindBySubjectName, domainName, false);

TLS configuration is handled by the local and remote operating systems.
SAML requests are sent over HTTPS so it’s the same configuration as if you were browsing to the URL.
Did you try the code I suggested?

[quote]
ComponentSpace - 5/29/2018
TLS configuration is handled by the local and remote operating systems.
SAML requests are sent over HTTPS so it's the same configuration as if you were browsing to the URL.
Did you try the code I suggested?
[/quote]

I can not try it using browser. As i said it is cloud system and we don't have control. Even i can not skip the certificate validation.
They have given sample SAML 2.0 ARTIFACTRESOLVE EXAMPLE in documentation.

">http://schemas.xmlsoap.org/soap/envelope/">


http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="" ID="FIMREQ_2910820a-014b-199f-ac2d-e83c73da428a" IssueInstant="2015-01-27T01:45:22Z" Version="2.0">
Issuer value


http://www.w3.org/2001/10/xml-exc-c14n#" />
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />


http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
">http://www.w3.org/2001/10/xml-exc-c14n#">
http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="samlp saml ds" />


http://www.w3.org/2001/04/xmlenc#sha256" />
DigestValue


Signature value


value



Request Artifact value



The issue is not at the SAML or SOAP layer. The issue is at the transport layer.
An HTTPS connection cannot be made as the TLS handshake is failing for some reason.
I suggested trying the browser to make debugging simpler. If you can’t browse to the URL for some reason, you will need to use a package capture application to capture the HTTPS traffic and debug the TLS handshake.
Alternatively, try the ServerCertificateValidationCallback suggestion I made. This involves adding a few lines of code to your application as described.

[quote]
ComponentSpace - 5/29/2018
The issue is not at the SAML or SOAP layer. The issue is at the transport layer.
An HTTPS connection cannot be made as the TLS handshake is failing for some reason.
I suggested trying the browser to make debugging simpler. If you can't browse to the URL for some reason, you will need to use a package capture application to capture the HTTPS traffic and debug the TLS handshake.
Alternatively, try the ServerCertificateValidationCallback suggestion I made. This involves adding a few lines of code to your application as described.
[/quote]

Hi Team,

I check with IdP team, they said the request is not coming via TSL 1.2 so that we got TSL issue. May i know how i can explicitly send the request with TSL 1.2. IS below code work for component space before sending the request.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls12;

Our client server is in cloud and cloud team said TSL 1.2 should configure at application level. I am not sure how to configure at application level in case server is not able to send with TSL 1.2.

Is any way in componentspace to sent via TSL 1.2 ?
[quote]
ComponentSpace - 5/29/2018
The issue is not at the SAML or SOAP layer. The issue is at the transport layer.
An HTTPS connection cannot be made as the TLS handshake is failing for some reason.
I suggested trying the browser to make debugging simpler. If you can't browse to the URL for some reason, you will need to use a package capture application to capture the HTTPS traffic and debug the TLS handshake.
Alternatively, try the ServerCertificateValidationCallback suggestion I made. This involves adding a few lines of code to your application as described.
[/quote]

Hi Team,
I checked with client cloud support team and they confirm that TLS protocols is supported upto TLS 1.2 on the servers but i am not sure which TLS is used by the server when i tried to send the request.
I know you ask me to hit via browser but my challenge is i don't have any control on server and we can't do any thing.
May i know if componentspace provide any feature where we can force our request to sent using TLS 1.2 . Some code like below.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls12;

Thanks
Pramod

There’s nothing specific that has to be done at the SAML API level to support TLS 1.2.
This support is a function of the operating system and .NET framework.
I recommend upgrading to .NET framework v4.6.2 or later where TLS 1.2 is the default protocol.
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
Otherwise, if you’re using .NET framework v4.0, refer to:
https://blogs.msdn.microsoft.com/saurabs/2017/06/01/wcfwstls-get-net-framework-4-0-application-use-tls-1-2-as-default-protocol/
Specifying TLS 1.2 by setting the ServicePointManager.SecurityProtocol property in your application is possible but isn’t considered best practice by Microsoft.
https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.securityprotocol(v=vs.110).aspx

[quote]
ComponentSpace - 6/7/2018
There's nothing specific that has to be done at the SAML API level to support TLS 1.2.
This support is a function of the operating system and .NET framework.
I recommend upgrading to .NET framework v4.6.2 or later where TLS 1.2 is the default protocol.
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/tls
Otherwise, if you're using .NET framework v4.0, refer to:
https://blogs.msdn.microsoft.com/saurabs/2017/06/01/wcfwstls-get-net-framework-4-0-application-use-tls-1-2-as-default-protocol/
Specifying TLS 1.2 by setting the ServicePointManager.SecurityProtocol property in your application is possible but isn't considered best practice by Microsoft.
https://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.securityprotocol(v=vs.110).aspx
[/quote]

Hi Team,

Thanks for the reply. We resolved the issue and getting the response from IdP server as well. But as per IdP documentation we need to perform two level description.
To decrypt the encrypted SAML assertion message, SP would need to perform 2 levels of decryptions.
1. RSA Encrypted Cipher Text
a. Perform RSA decryption to obtain the AES symmetric key
2. AES Encrypted Cipher Text
a. Perform AES decryption to obtain the plain text which contains the NAMEID parameter

While i tried as per your example code i got below error. Please let me know how we can achieve via your componentspace library.

My Code
SAMLAssertion samlAssertion = (SAMLAssertion)samlResponse.Assertions[0];

System.InvalidCastException: Unable to cast object of type 'ComponentSpace.SAML2.Assertions.EncryptedAssertion' to type 'ComponentSpace.SAML2.Assertions.SAMLAssertion'.
at passionapi.SAML.AssertionConsumerService.ProcessSuccessSAMLResponse(SAMLResponse samlResponse, String relayState)


Your code should be:

// Retrieve the encrypted assertion from the SAML response.
EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion();

// Load the SP’s X509Certificate2 containing the private key.
// Details not shown.
X509Certificate2 x509Certificate;

// Decrypt the SAML assertion.
SAMLAssertion samlAssertion = encryptedAssertion.Decrypt(x509Certificate);


[quote]
ComponentSpace - 6/21/2018
Your code should be:

// Retrieve the encrypted assertion from the SAML response.
EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion();

// Load the SP's X509Certificate2 containing the private key.
// Details not shown.
X509Certificate2 x509Certificate;

// Decrypt the SAML assertion.
SAMLAssertion samlAssertion = encryptedAssertion.Decrypt(x509Certificate);


[/quote]

ok thanks for quick reply. Now my question is , will it Decrypt both level given below. Then what is the use of IdP public key cert file provided by the IdP team.

Also i am not using saml.config so EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion(); shall i need to pass public key of IdP cert file. if yest then what will be the method.

1. RSA Encrypted Cipher Text
a. Perform RSA decryption to obtain the AES symmetric key
2. AES Encrypted Cipher Text
a. Perform AES decryption to obtain the plain text which contains the NAMEID parameter

[quote]
ComponentSpace - 6/21/2018
Your code should be:

// Retrieve the encrypted assertion from the SAML response.
EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion();

// Load the SP's X509Certificate2 containing the private key.
// Details not shown.
X509Certificate2 x509Certificate;

// Decrypt the SAML assertion.
SAMLAssertion samlAssertion = encryptedAssertion.Decrypt(x509Certificate);


[/quote]

Also i am getting the saml:EncryptedAssertion in below format:- It have two signature.

My SAML response is like that

http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="FIMRSP_2090fbc2-0164-1cd7-ad8c-82efa566b086" InResponseTo="_a23aeaf8-8b89-423d-bfab-f2d949a15d96" IssueInstant="2018-06-21T04:18:49Z" Version="2.0">



http://www.w3.org/2001/10/xml-exc-c14n#" />
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />


http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
">http://www.w3.org/2001/10/xml-exc-c14n#">
http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="samlp xs saml xsi ds" />


http://www.w3.org/2001/04/xmlenc#sha256" />
value removed


value removed


value removed






https://api.passioncard.sg/passionapi/SAML/AssertionConsumerService.aspx" ID="FIMRSP_2090fbc3-0164-1dea-ad39-82efa566b086" IssueInstant="2018-06-21T04:18:49Z" Version="2.0">
value removed


http://www.w3.org/2001/10/xml-exc-c14n#" />
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />


http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
">http://www.w3.org/2001/10/xml-exc-c14n#">
http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="" />


http://www.w3.org/2001/04/xmlenc#sha256" />
value removed


value removed


value removed







http://www.w3.org/2001/04/xmlenc#" Id="uuid2090ee1b-0164-1b31-a7ce-82efa566b086" Type="">http://www.w3.org/2001/04/xmlenc#Element">
http://www.w3.org/2001/04/xmlenc#aes256-cbc" />


http://www.w3.org/2001/04/xmlenc#rsa-1_5" />

value removed


value removed




value removed





[quote]
ComponentSpace - 6/21/2018
Your code should be:

// Retrieve the encrypted assertion from the SAML response.
EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion();

// Load the SP's X509Certificate2 containing the private key.
// Details not shown.
X509Certificate2 x509Certificate;

// Decrypt the SAML assertion.
SAMLAssertion samlAssertion = encryptedAssertion.Decrypt(x509Certificate);


[/quote]

ok thanks for quick reply. Now my question is , will it Decrypt both level given below. Then what is the use of IdP public key cert file provided by the IdP team.

Also i am not using saml.config so EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion(); shall i need to pass public key of IdP cert file. if yest then what will be the method.

1. RSA Encrypted Cipher Text
a. Perform RSA decryption to obtain the AES symmetric key
2. AES Encrypted Cipher Text
a. Perform AES decryption to obtain the plain text which contains the NAMEID parameter

[/quote]
My SAML Response format is below.

http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="FIMRSP_2090fbc2-0164-1cd7-ad8c-82efa566b086" InResponseTo="_a23aeaf8-8b89-423d-bfab-f2d949a15d96" IssueInstant="2018-06-21T04:18:49Z" Version="2.0">



http://www.w3.org/2001/10/xml-exc-c14n#" />
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />


http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
">http://www.w3.org/2001/10/xml-exc-c14n#">
http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="samlp xs saml xsi ds" />


http://www.w3.org/2001/04/xmlenc#sha256" />
value removed


value removed


value removed






https://api.passioncard.sg/passionapi/SAML/AssertionConsumerService.aspx" ID="FIMRSP_2090fbc3-0164-1dea-ad39-82efa566b086" IssueInstant="2018-06-21T04:18:49Z" Version="2.0">
value removed


http://www.w3.org/2001/10/xml-exc-c14n#" />
http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />


http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
">http://www.w3.org/2001/10/xml-exc-c14n#">
http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="" />


http://www.w3.org/2001/04/xmlenc#sha256" />
value removed


value removed


value removed







http://www.w3.org/2001/04/xmlenc#" Id="uuid2090ee1b-0164-1b31-a7ce-82efa566b086" Type="">http://www.w3.org/2001/04/xmlenc#Element">
http://www.w3.org/2001/04/xmlenc#aes256-cbc" />


http://www.w3.org/2001/04/xmlenc#rsa-1_5" />

value removed


value removed




value removed





Yes, it handles all the encryption meaning the supplied asymmetric key is used to decrypt the random symmetric key which in turn is used to decrypt the SAML assertion.
The asymmetric key used to perform the decryption of the symmetric key is the SP’s private key.
The IdP’s public key is not used.

[quote]
ComponentSpace - 6/21/2018
Yes, it handles all the encryption meaning the supplied asymmetric key is used to decrypt the random symmetric key which in turn is used to decrypt the SAML assertion.
The asymmetric key used to perform the decryption of the symmetric key is the SP's private key.
The IdP's public key is not used.
[/quote]

Hi Team,

Thanks for reply. It means i need not to validate the signature using SAMLMessageSignature.Verify(samlResponseXml, x509Certificate) with IdP public cert.
Or it is best practice to validate the signature.
If yes then with which key i need to validate as i have given my SAML response format above.
SAMLMessageSignature.Verify(samlResponseXml, x509Certificate)

You should verify the signatures.
The XML signatures are verified using the IdP’s public key.
The SAML assertion is decrypted using the SP’s private key.

The following code outlines the processing steps.

// Receive the artifact response.
XmlElement artifactResponseElement =
ArtifactResolver.SendRequestReceiveResponse(spArtifactResponderURL, artifactResolveXml);

// Load the IdP’s X509Certificate2.
// Details not shown.
X509Certificate2 idpX509Certificate;

// Verify the artifact response signature.
if (!SAMLMessageSignature.Verify(artifactResponseElement, idpX509Certificate))
{
// Handle signature failure.
}

// Deserialize the artifact response.
ArtifactResponse artifactResponse = new ArtifactResponse(artifactResponseElement);

// Get the SAML response from the artifact response.
XmlElement samlResponseElement = artifactResponse.SAMLMessage;

// Verify the SAML response signature.
if (!SAMLMessageSignature.Verify(samlResponseElement, idpX509Certificate))
{
// Handle signature failure.
}

// Deserialize the SAML response.
SAMLResponse samlResponse = new SAMLResponse(samlResponseElement);

// Retrieve the encrypted assertion from the SAML response.
EncryptedAssertion encryptedAssertion = samlResponse.GetEncryptedAssertion();

// Load the SP’s X509Certificate2 containing the private key.
// Details not shown.
X509Certificate2 spX509Certificate;

// Decrypt the SAML assertion.
SAMLAssertion samlAssertion = encryptedAssertion.Decrypt(spX509Certificate);