title: WSE3003: The certificate's trust chain could not be verified
body: <p>I am writing a system that consumes a public web service. I'm consuming the web service using VS2008 and classic .NET Framework 2.0 Web Services technology. My problem is not consuming the web service or calling it's operations.</p>
  
  <p>The problem is when I get the response back from the operation it is signed and behind-the-scenes the generated proxy starts verifying the signature. And at that time I get the WSE3003 error. I (think I) have loaded the service certificate into my LocalComputer/TrustedPeople certificate storage and when I look at it's certificate path I can see that all is ok:</p>
  
  <blockquote>
    <p>VeriSign Class 3 Public Primary CA<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97...<br/>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;servcert.there.com</p>
  </blockquote>
  
  <p>But I keep getting the following exception:</p>
  
  <blockquote>
    <p>Microsoft.Web.Services3.ResponseProcessingException:
    WSE910: An error happened during the
    processing of a response message, and
    you can find the error in the inner
    exception.  You can also find the
    response message in the Response
    property. --->
    Microsoft.Web.Services3.Security.SecurityFault:
    The security token could not be
    authenticated or authorized --->
    System.Security.SecurityException:
    <strong>WSE3003: The certificate's trust chain</strong>
    <strong>could not be verified.</strong>  Please check
    if the certificate has been properly
    installed in the Trusted People
    Certificate store.  Or you might want
    to set allowTestRoot configuration
    section to true if this is a test
    certificate.</p>
  </blockquote>
  
  <p>The following code probably doesn't compile and I have removed some of the sensitive stuff but here is the idea behind how I do my part:</p>
  
  <pre><code>// Construct the wse proxy
  MyServiceWse wsClient = new MyServiceWse();
  
  // Assign the credentials
  UsernameToken userToken = new UsernameToken("user", "pass", PasswordOption.SendPlainText);
  wsClient.SetClientCredential(userToken);
  wsClient.RequestSoapContext.IdentityToken = userToken;
  
  // Find the client and service certificates
  X509Certificate2 clientCert = MyCertificateManager.FindCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, "mycert.here.com");
  X509Certificate2 serviceCert = MyCertificateManager.FindCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, "servicecert.there.com");
  
  // Add the policy to the proxy
  Policy policy = new Policy();
  MySecurityClientAssertion assertion = new MySecurityClientAssertion();
  assertion.SetServiceCertificate(serviceCert);
  assertion.SetClientCertificate(clientCert);
  policy.Assertions.Add(assertion);
  wsClient.SetPolicy(policy);
  
  // Assign the service URL and call an operation
  wsClient.Url = "https://services.there.com/TheirService.asmx";
  TheirOperationResponse r = wsClient.CallTheirOperation();
  </code></pre>
  
  <p>I sure hope my code is wrong because I can understand that a lot better than the certificate storage and trust chain stuff. Any help would be great. Thanks for you efforts.</p>