The signature verified correctly with the key contained in the signature, but that key is not trusted

5.3k Views Asked by At

I am trying to configure SAML2 IdP Salesforce as external provider in IdentityServer3. I am using SustainSys/Saml2 library. So for testing purpose I have downloaded SampleIdentityServer3. and configured SAML2 IdP like below

    private void ConfigureSaml2(IAppBuilder app, string signInAsType)
    {
        ServicePointManager.Expect100Continue = true;
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3;

        var options = new Saml2AuthenticationOptions(false)
        {
            SPOptions = new SPOptions
            {
                EntityId = new EntityId("http://localhost:4589/IdSrv3/Saml2"),    
                MinIncomingSigningAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
            },
            SignInAsAuthenticationType = signInAsType,
            Caption = "SAML2p",

        };

        UseIdSrv3LogoutOnFederatedLogout(app, options);

        options.SPOptions.ServiceCertificates.Add(new X509Certificate2(
            AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/Sustainsys.Saml2.Tests.pfx"));

        var idp = new IdentityProvider(
            new EntityId("https://XXXXXX-dev-ed.my.salesforce.com"),
            options.SPOptions)
        {
            MetadataLocation = "https://XXXXXX-dev-ed.my.salesforce.com/.well-known/samlidp.xml",
            LoadMetadata = true,                
        };

        options.IdentityProviders.Add(idp);
        app.UseSaml2Authentication(options);
    }

Note that if i don't set MinIncomingSigningAlgorithm to sh1 then the SustainSys library throws error.

Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signing algorithm http://www.w3.org/2000/09/xmldsig#rsa-sha1 is weaker than the minimum accepted http://www.w3.org/2001/04/xmldsig-more#rsa-sha256. If you want to allow this signing algorithm, use the minIncomingSigningAlgorithm configuration attribute.

So i set the MinIncomingSigningAlgorithm to "http://www.w3.org/2000/09/xmldsig#rsa-sha1" to get rid of the error.

But then i get different error

Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signature verified correctly with the key contained in the signature, but that key is not trusted.

based on issue #493 #735 the certificate in metadata must match with the certificate in SAML2 response.

In metadata the certificate is (notice start and end values)

  <ds:X509Data>
    <ds:X509Certificate>
       MIIGk... removed from brevity....tmv6J1g==
    </ds:X509Certificate>
  </ds:X509Data>

But in SAML2 response ( the one that is logged by SustainSys library)

<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:4589/IdSrv3/Saml2/Acs" ID="_19fd2d8d9aab0401f56fXXXXXXXXX" InResponseTo="id473a52c49f194bXXXXXXXXX"    IssueInstant="2018-08-27T20:10:04.296Z" Version="2.0">
    <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://XXXXXXX-dev-ed.my.salesforce.com</saml: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="#_19fd2d8d9aab0401f56f642dXXXXXXXXXXXXX">
                <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#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml samlp" /></ds:Transform>
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                <ds:DigestValue>fQiiyd0T57Ztr5BAfMFe9MTrhY0=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>
            B6hndlsBgY45J+hm8My2gPVo....removed for brevity....YT88ajt7jQ==
        </ds:SignatureValue>
        <ds:KeyInfo>
            <ds:X509Data>
                <ds:X509Certificate>
                    MIIENz... remove for brevity....y2Ul24Jyc4V/jJN
                </ds:X509Certificate>
            </ds:X509Data>
        </ds:KeyInfo>
        </ds:Signature>
        <samlp:Status>
            <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" />
        </samlp:Status>
    </samlp:Response>

looking at X509Certificate value in metadata and in SAML2 response they don't match.

Question
Does the X509Certificate value in SAML2 response supposed to match with X509Certificate value in metadata? If yes, why can't SustainSys library always use the X509Certificate value from SAML2 response?

Update
Just to see if matching the values would work, I saved certificate value from SAML2 response into separate .cer file. and Then in KeyInfoSerializer.cs file i updated ReadX509Certificate method (this is the method that loads the certificate from metadata)

    private static SecurityKeyIdentifierClause ReadX509Certificate(XmlReader reader)
    {
        reader.ReadStartElement("X509Certificate", SignedXml.XmlDsigNamespaceUrl);
        ((XmlDictionaryReader)reader).ReadContentAsString();

        var cer = new X509Certificate2(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/App_Data/salesforcepublickey.cer");
        var clause = new X509RawDataKeyIdentifierClause(cer);
        reader.ReadEndElement();
        return clause;
    }

However, it still throws error The signature verified correctly with the key contained in the signature, but that key is not trusted.

2

There are 2 best solutions below

0
LP13 On BEST ANSWER

Found it.
It was issue on Salesforce side. In Saleforce, when i check the logs Identity->Identity Provider Event Log i see error Error: User does not have access to this service provider

For this, the user was not given permission. Even if the user is System Administrator, the access to Connected App is not given by default. To give permission, go to 'Manage Users -> Users' and click edit on the user you are testing.Click profile name link .e.g System Administrator. This takes to profile page. You can scroll below to 'Connected App Access' and you would see that the access is not given. Give the access by clicking edit profile in the top of page.

0
Abdul Rehman Sayed On

Not related to this one but this question comes first when we google the error so posting the solution here. We had an integration with kentor auth services library from a third party provider in our ASP.net application & it was failing with the above error.

The issue was that the IIS was somehow unable to reach the certificate store. We enabled loadUserProfile setting on the Application Pool for our website & it was able to run perfectly. We applied this on Windows Server 2016.