Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java client to WCF service interop with mutual certificate - Cannot resolve KeyInfo for verifying signature

Exception: MessageSecurityException: Cannot resolve KeyInfo for verifying signature: KeyInfo 'SecurityKeyIdentifier

I have to set up a WCF service to receive SOAP calls from a Java client that is sending signed content with the following header:

<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soap:mustUnderstand="1">
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-2">
    <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
      <ds:Reference URI="#id-3" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
        <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">…</ds:DigestValue>
      </ds:Reference>
      <ds:Reference URI="#Timestamp-1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
        <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">…</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      …
    </ds:SignatureValue>
    <ds:KeyInfo Id="KeyId-66FC0491F2BB65AFF813274134607712" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
      <wsse:SecurityTokenReference xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="...." xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
          <ds:X509IssuerSerial xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <ds:X509IssuerName xmlns:ds="http://www.w3.org/2000/09/xmldsig#">CN=XXXXXXXX</ds:X509IssuerName>
            <ds:X509SerialNumber xmlns:ds="http://www.w3.org/2000/09/xmldsig#">111122222</ds:X509SerialNumber>
          </ds:X509IssuerSerial>
        </ds:X509Data>
      </wsse:SecurityTokenReference>
    </ds:KeyInfo>
  </ds:Signature>
  <wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1">
    <wsu:Created>xxxxx</wsu:Created>
    <wsu:Expires>xxxx</wsu:Expires>
  </wsu:Timestamp></wsse:Security></soap:Header>

I have tried setting up the following binding and behavior:

      <customBinding>
    <binding name="javaclientBinding">
      <security
        defaultAlgorithmSuite="Basic256Rsa15" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10"
        allowSerializedSigningTokenOnReply="true"
        authenticationMode="MutualCertificateDuplex"
        requireDerivedKeys="false"
        securityHeaderLayout="LaxTimestampLast"
        allowInsecureTransport="true"
        requireSignatureConfirmation="false"
        requireSecurityContextCancellation="false">
      </security>
      <textMessageEncoding messageVersion="Soap11" />
      <httpTransport />
    </binding>
  </customBinding>



<behavior name="javaclientBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
<serviceCredentials>
    <clientCertificate>
    <authentication certificateValidationMode="PeerTrust"/>
</clientCertificate>
<serviceCertificate
    findValue="applicationServer"
  storeLocation="CurrentUser"
  storeName="My"
  x509FindType="FindBySubjectName" />
</serviceCredentials>
   </behavior>

But I get the following exception in the servers event log:

ClientIdentity: 
   ActivityId: <null>
   MessageSecurityException: Cannot resolve KeyInfo for verifying signature: KeyInfo
  'SecurityKeyIdentifier
   (
       IsReadOnly = False,
       Count = 1,
       Clause[0] = X509IssuerSerialKeyIdentifierClause(Issuer = 'CN=XXXXXX)
    )
   ', available tokens 'SecurityTokenResolver
(
TokenCount = 0,
)

'.

We have to get signature validation working, and we have no possibility to change what the java client is sending.

like image 636
Bjørn Otto Vasbotten Avatar asked Feb 06 '12 13:02

Bjørn Otto Vasbotten


1 Answers

Actually I'm having the same problem, and i'm using the aproach suggested by Yaron Naveh.

I haven't finished yet, but I'm making some advances (I'll post a full answer when I finish).

The request uses an AsymmetricSecurityBindingElement, not a SymmetricSecurityBindingElement as Yaron suggested.

The Inclusion Mode of the X509SecurityTokenParameters should be set to SecurityTokenInclusionMode.AlwaysToInitiator

The binding should look like this

//Only the following MessageSecurityVersion are asimetric: 

//WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
//WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10

AsymmetricSecurityBindingElement abe =(AsymmetricSecurityBindingElement)
SecurityBindingElement.CreateMutualCertificateBindingElement(    
  MessageSecurityVersion.WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);

abe.SetKeyDerivation(false);

X509SecurityTokenParameters x509ProtectionParameters =
    new X509SecurityTokenParameters(X509KeyIdentifierClauseType.IssuerSerial);

x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToInitiator;
x509ProtectionParameters.X509ReferenceStyle = X509KeyIdentifierClauseType.IssuerSerial;

abe.InitiatorTokenParameters = x509ProtectionParameters;
abe.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
abe.DefaultAlgorithmSuite = SecurityAlgorithmSuite.TripleDesRsa15;

HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();
System.ServiceModel.Channels.Binding binding = new CustomBinding(abe, httpBinding);
return binding;

I hope this helps a bit

like image 186
DkAngelito Avatar answered Sep 30 '22 18:09

DkAngelito