I must make my WCF Client consume a web service (IBM DataPower) and sign/encrypt the request using Web Services Security X.509 Certificate Token Profile 1.1 OASIS Standard Specification, 1 February 2006.
So far I have created a custom binding and "think" I am working along the right lines:
Updated to reflect latest attempt
Private Function CreateCustomBinding() As Channels.Binding
Dim asbe As New Channels.AsymmetricSecurityBindingElement
asbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10
asbe.InitiatorTokenParameters = New ServiceModel.Security.Tokens.X509SecurityTokenParameters
asbe.RecipientTokenParameters = New ServiceModel.Security.Tokens.X509SecurityTokenParameters
asbe.MessageProtectionOrder = Security.MessageProtectionOrder.EncryptBeforeSign
asbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict
asbe.IncludeTimestamp = True
asbe.SetKeyDerivation(False)
asbe.DefaultAlgorithmSuite = Security.SecurityAlgorithmSuite.Basic128Rsa15 'By default, AES-128 is used as the encryption algorithm.
'Add the elements to the custom binding
Dim myBinding As New CustomBinding
'element order is important - see http://msdn.microsoft.com/en-us/library/ms733893(v=vs.90).aspx
'Protocol Binding Elements (security)
myBinding.Elements.Add(asbe)
'Encoding Binding Element
myBinding.Elements.Add(New TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, System.Text.Encoding.UTF8))
'Transport Binding Element
Dim httpsBindingElement As New HttpsTransportBindingElement()
httpsBindingElement.RequireClientCertificate = True
myBinding.Elements.Add(httpsBindingElement)
Return myBinding
End Function
Then use this binding like so:
Dim epi As EndpointIdentity = EndpointIdentity.CreateDnsIdentity("xgtwsqa.theirdomain.com")
Dim epuri As Uri = New Uri("https://xgtwqa.theirdomain.com/5067/ProcessRepairOrder")
Dim ea As New EndpointAddress(epuri, epi, New AddressHeaderCollection)
Dim myBinding As Binding = GetCustomBinding2()
' Create the client.
Dim starClientProxy As New wcfStarServiceProxy.starTransportPortTypesClient(myBinding, ea)
' Specify a certificate to use for authenticating the client.
starClientProxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "*.mydomain.org.uk")
starClientProxy.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.AddressBook, X509FindType.FindBySubjectName, "xgtwsqa.theirdomain.com")
'starClientProxy.ClientCredentials.ServiceCertificate.SetScopedCertificate(StoreLocation.CurrentUser, StoreName.AddressBook, X509FindType.FindBySubjectName, "xgtwsqa.theirdomain.com", New Uri("https://xgtwqa.thedomain.com/5067/ProcessRepairOrder"))
' Begin using the client.
Dim response As wcfStarServiceProxy.AcknowledgeRepairOrderPayload = starClientProxy.ProcessMessage(payload)
Would someone either tell me what else I need to configure in the binding (I am pretty sure the binding method isn't quite right) or provide me with the code I need?
The above produces the following SOAP:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_3">
http://www.starstandards.org/webservices/2009/transport/operations/ProcessMessage</a:Action>
<a:MessageID u:Id="_4">
urn:uuid:c2acbb72-49c2-465b-b177-e806494cdef7</a:MessageID>
<a:ReplyTo u:Id="_5">
<a:Address>
http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1" u:Id="_6">
https://xgtwqa.theirdomain.com/5067/ProcessRepairOrder</a:To>
<o:Security s:mustUnderstand="1"
xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="uuid-b8d302ff-a098-42bb-afc6-694e647c23b0-1">
<u:Created>2012-06-01T14:35:18.781Z</u:Created>
<u:Expires>2012-06-01T14:40:18.781Z</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-2"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
removed</o:BinarySecurityToken>
<o:BinarySecurityToken u:Id="uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-1"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
removed</o:BinarySecurityToken>
<e:EncryptedKey Id="_0"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
URI="#uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-1" />
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>
removed</e:CipherValue>
</e:CipherData>
</e:EncryptedKey>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#_2">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
<Reference URI="#_3">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
<Reference URI="#_4">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
<Reference URI="#_5">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
<Reference URI="#_6">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
<Reference URI="#uuid-b8d302ff-a098-42bb-afc6-694e647c23b0-1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removed</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
removed</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
URI="#uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-2" />
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
<e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:DataReference URI="#_1" />
</e:ReferenceList>
</o:Security>
</s:Header>
<s:Body u:Id="_2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<e:EncryptedData Id="_1"
Type="http://www.w3.org/2001/04/xmlenc#Content"
xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
</e:EncryptionMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:Reference URI="#_0"></o:Reference>
</o:SecurityTokenReference>
</KeyInfo>
<e:CipherData>
<e:CipherValue>removed</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>
This is a sample of the SOAP I am expected to send:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:star="http://www.starstandard.org/STAR/5"
xmlns:tran="http://www.starstandards.org/webservices/2005/10/transport">
<soap:Header>
<wsa:To>urn:removed/star/services/v1/GetConditionCodes</wsa:To>
<wsa:Action>
http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage</wsa:Action>
<wsa:MessageID>
ef67ec85-d5c7-4669-b1a6-440ec2fe938b</wsa:MessageID>
<tns:RespondTo xmlns:tns="urn:removed/soa/routing/v1.0">
<tns:Endpoint>
https://b2b-test.mydomain.com/Async/removed/StarWebService.ashx</tns:Endpoint>
</tns:RespondTo>
<tran:payloadManifest>
<tran:manifest contentID="A0"
namespaceURI="http://www.starstandard.org/STAR/5"
element="GetStandardCodes" version="5.2.4" />
</tran:payloadManifest>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
mustUnderstand="1">
<u:Timestamp xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
Id="timestamp" u:Id="timestamp">
<u:Created>2012-05-30T16:39:39Z</u:Created>
<u:Expires>2012-05-30T16:44:39Z</u:Expires>
</u:Timestamp>
<wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
wsu:Id="binary_security_token">
removed</wsse:BinarySecurityToken>
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<wsse:SecurityTokenReference>
<wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
4qEuhS3IWjReFLSSCOcVoN6Ywzo=</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</KeyInfo>
<CipherData>
<CipherValue>
removed</CipherValue>
</CipherData>
<ReferenceList>
<DataReference URI="#encrypt" />
</ReferenceList>
</EncryptedKey>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#body">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removeddigestvalue</DigestValue>
</Reference>
<Reference URI="#timestamp">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>removeddigestvalue</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
removed</SignatureValue>
<KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#binary_security_token"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
</wsse:Security>
</soap:Header>
<soap:Body xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
id="body" u:Id="body">
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"
Id="encrypt" Type="http://www.w3.org/2001/04/xmlenc#Content">
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
<CipherData>
<CipherValue>
removed</CipherValue>
</CipherData>
</EncryptedData>
</soap:Body>
</soap:Envelope>
try to use this config:
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<security authenticationMode="MutualCertificate" messageProtectionOrder="SignBeforeEncrypt"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
</bindings>
if you want to use code the main difference is the use of WSSEcurity10 in the version (even though you need 11, this is compatible) and the messageProtectionOrder (which is why you only see encryption and not signature).
this may require further fine tuning, let me know the progress.
since you use code also set:
asbe.RecipientTokenParameters.X509ReferenceStyle=X509KeyIdentifierClauseType .SubjectKeyIdentifier
and:
asbe.RecipientTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never