title: The signature verified correctly with the key contained in the signature, but that key is not trusted
body: <p>I am trying to configure SAML2 IdP <code>Salesforce</code> as external provider in IdentityServer3. I am using <a href="https://github.com/Sustainsys/Saml2" rel="nofollow noreferrer">SustainSys/Saml2</a> library. So for testing purpose I have downloaded <a href="https://github.com/Sustainsys/Saml2/tree/master/Samples/SampleIdentityServer3" rel="nofollow noreferrer">SampleIdentityServer3</a>. and configured SAML2 IdP like below</p>
  
  <pre><code>    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);
      }
  </code></pre>
  
  <p>Note that if i don't set <code>MinIncomingSigningAlgorithm</code> to sh1 then the SustainSys library throws error.</p>
  
  <blockquote>
    <p>Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signing
    algorithm <a href="http://www.w3.org/2000/09/xmldsig#rsa-sha1" rel="nofollow noreferrer">http://www.w3.org/2000/09/xmldsig#rsa-sha1</a> is weaker than
    the minimum accepted
    <a href="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" rel="nofollow noreferrer">http://www.w3.org/2001/04/xmldsig-more#rsa-sha256</a>. If you want to
    allow this signing algorithm, use the minIncomingSigningAlgorithm
    configuration attribute.</p>
  </blockquote>
  
  <p>So i set the <code>MinIncomingSigningAlgorithm</code> to <code>"http://www.w3.org/2000/09/xmldsig#rsa-sha1"</code> to get rid of the error.</p>
  
  <p>But then i get different error</p>
  
  <blockquote>
    <p>Sustainsys.Saml2.Exceptions.InvalidSignatureException: The signature
    verified correctly with the key contained in the signature, but that
    key is not trusted.</p>
  </blockquote>
  
  <p>based on issue <a href="https://github.com/Sustainsys/Saml2/issues/493" rel="nofollow noreferrer">#493</a> <a href="https://github.com/Sustainsys/Saml2/issues/735" rel="nofollow noreferrer">#735</a> the certificate in metadata must match with the certificate in SAML2 response.</p>
  
  <p>In metadata the certificate is (notice start and end values)</p>
  
  <pre><code>  &lt;ds:X509Data&gt;
      &lt;ds:X509Certificate&gt;
         MIIGk... removed from brevity....tmv6J1g==
      &lt;/ds:X509Certificate&gt;
    &lt;/ds:X509Data&gt;
  </code></pre>
  
  <p>But in SAML2 response ( the one that is logged by SustainSys library)  </p>
  
  <pre><code>&lt;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"&gt;
      &lt;saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity"&gt;https://XXXXXXX-dev-ed.my.salesforce.com&lt;/saml:Issuer&gt;
      &lt;ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;ds:SignedInfo&gt;
              &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
              &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
              &lt;ds:Reference URI="#_19fd2d8d9aab0401f56f642dXXXXXXXXXXXXX"&gt;
                  &lt;ds:Transforms&gt;
                      &lt;ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" /&gt;
                      &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml samlp" /&gt;&lt;/ds:Transform&gt;
                  &lt;/ds:Transforms&gt;
                  &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
                  &lt;ds:DigestValue&gt;fQiiyd0T57Ztr5BAfMFe9MTrhY0=&lt;/ds:DigestValue&gt;
              &lt;/ds:Reference&gt;
          &lt;/ds:SignedInfo&gt;
          &lt;ds:SignatureValue&gt;
              B6hndlsBgY45J+hm8My2gPVo....removed for brevity....YT88ajt7jQ==
          &lt;/ds:SignatureValue&gt;
          &lt;ds:KeyInfo&gt;
              &lt;ds:X509Data&gt;
                  &lt;ds:X509Certificate&gt;
                      MIIENz... remove for brevity....y2Ul24Jyc4V/jJN
                  &lt;/ds:X509Certificate&gt;
              &lt;/ds:X509Data&gt;
          &lt;/ds:KeyInfo&gt;
          &lt;/ds:Signature&gt;
          &lt;samlp:Status&gt;
              &lt;samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:AuthnFailed" /&gt;
          &lt;/samlp:Status&gt;
      &lt;/samlp:Response&gt;
  </code></pre>
  
  <p>looking at <code>X509Certificate</code> value in metadata and in SAML2 response they don't match. </p>
  
  <p><strong>Question</strong><br>
  Does the <code>X509Certificate</code> value in SAML2 response supposed to match with <code>X509Certificate</code> value in metadata? If yes, why can't SustainSys library always use the <code>X509Certificate</code> value from SAML2 response?</p>
  
  <p><strong>Update</strong><br>
  Just to see if matching the values would work, I saved certificate value from SAML2 response into separate <code>.cer</code> file. and Then in KeyInfoSerializer.cs file i updated <code>ReadX509Certificate</code> method (this is the method that loads the certificate from metadata)</p>
  
  <pre><code>    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;
      }
  </code></pre>
  
  <p>However, it still throws error <code>The signature verified correctly with the key contained in the signature, but that key is not trusted.</code></p>