Hi everybody,
I'm trying to encrypt the webservice call response using the client
BinarySecurityToken embedded in the request soap header.
To do that,
1) I changed the "signatureKeyIdentifier" property to "DirectReference" in
the client.xml WSS4JOutInterceptor definition
2) I changed the "encryptionUser" property to "useReqSigCert" in the
service.xml WSS4JOutInterceptor definition
The BinarySecurityToken is embedded in the request soap header (see below) but
when the service creates the response, and tries to encrypt the generated
symmetric key used to encrypt the message it seems that it can't find the
certificate that contains the client public key.
In the org.apache.ws.security.message.WSSecEncrypt class, prepare(Document doc,
Crypto crypto) method (see below), the line that gets the certificate with the
user "useReqSigCert" returns null.
/*
* Get the certificate that contains the public key for the public key
* algorithm that will encrypt the generated symmetric (session) key.
*/
if(this.encryptSymmKey) {
X509Certificate remoteCert = null;
if (useThisCert != null) {
remoteCert = useThisCert;
} else {
X509Certificate[] certs = crypto.getCertificates(user);
if (certs == null || certs.length <= 0) {
throw new WSSecurityException(WSSecurityException.FAILURE,
"invalidX509Data", new Object[] { "for Encryption" });
}
remoteCert = certs[0];
}
prepareInternal(this.ephemeralKey, remoteCert, crypto);
}
Request SOAP Header BST
<wsse:BinarySecurityToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-7518237"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
MIIDJjCCAo+gAwIBAgIQbAuWL3AdDuWrlipWXiUHIjANBgkqhkiG9w0BAQUFADCBhzELMAkGA1UEBhMCWkExIjAgBgNVBAgTGUZPUiBURVNUSU5HIFBVUlBPU0VTIE9OTFkxHTAbBgNVBAoTFFRoYXd0ZSBDZXJ0aWZpY2F0aW9uMRcwFQYDVQQLEw5URVNUIFRFU1QgVEVTVDEcMBoGA1UEAxMTVGhhd3RlIFRlc3QgQ0EgUm9vdDAeFw0wODAxMDQxMTExMzZaFw0wODAxMjUxMTExMzZaMHIxCzAJBgNVBAYTAkNIMQswCQYDVQQIEwJWRDERMA8GA1UEBxMITGF1c2FubmUxDjAMBgNVBAoTBUJlZGFnMREwDwYDVQQLEwhFU29jaWV0ZTEgMB4GA1UEAxMXd3d3LmRldmVwYXkuZXNvY2lldGUuY2gwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJIweOZ2zZDbbNacrWAK6sLXRY90da2f27ZYHwN/b7Te0m5qVJc3XTLDGmjKoF0YN/IZcXJIF+2hfW54HL/ZU1E1bAP06pCqmAkrRnSKqju8cieUf0Np4/NL96geRxCqCCs8SeJcguYIAodCkUoqGzZtV9yvrSNhk0/PrbCEDkjDAgMBAAGjgaYwgaMwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2NybC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMA0GCSqGSIb3DQEBBQUAA4GBAKZqkoO+USbtbX+cRF0KvXfFjTbrrceeTYoOVhvfn+dkYIc4VeBSbEoofZVtM13EsbVdWDslzw2tCrCYTdRWoOIWTGo5ng1QTrjSy1KJh6bqWiygLr/EYMBsJNG9hOVy4HCymWN2mlFTw6OfmrMMlzMWiYp/Kwu4OgdL4k+UwD7n
</wsse:BinarySecurityToken>
For the test I'm using the CXF Geeter unit test
(org.apache.cxf.systest.ws.security).
I'm using the latest cxf 2.1-snapshot version.
I really need this feature as it's nearly impossible to manage to add every
client's certificate to the server keystore.
Is it a bug in the cxf implementation or is it me doing something wrong?
Any idea would be welcome.
Thank you.
client.xml config
<jaxws:client
name="{http://apache.org/hello_world_soap_http}TimestampSignEncrypt"
createdFromAPI="true">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<ref bean="TimestampSignEncrypt_Request"/>
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="TimestampSignEncrypt_Response"/>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
</jaxws:inInterceptors>
</jaxws:client>
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
id="TimestampSignEncrypt_Request">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="user" value="client"/>
<entry key="encryptionUser" value="service"/>
<entry key="signatureKeyIdentifier" value="DirectReference"/>
<entry key="signaturePropFile"
value="org/apache/cxf/systest/ws/security/client_security.properties"/>
<entry key="encryptionPropFile"
value="org/apache/cxf/systest/ws/security/client_security.properties"/>
<entry key="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
<entry key="passwordCallbackClass"
value="org.apache.cxf.systest.ws.security.KeystorePasswordCallback"/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionParts"
value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionKeyTransportAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<entry key="encryptionSymAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
</map>
</constructor-arg>
</bean>
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
id="TimestampSignEncrypt_Response">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="signaturePropFile"
value="org/apache/cxf/systest/ws/security/client_security.properties"/>
<entry key="encryptionPropFile"
value="org/apache/cxf/systest/ws/security/client_security.properties"/>
<entry key="passwordCallbackClass"
value="org.apache.cxf.systest.ws.security.KeystorePasswordCallback"/>
</map>
</constructor-arg>
</bean>
server.xml config
<jaxws:endpoint
name="{http://apache.org/hello_world_soap_http}TimestampSignEncrypt"
createdFromAPI="true">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<ref bean="TimestampSignEncrypt_Response"/>
</jaxws:outInterceptors>
<jaxws:inInterceptors>
<ref bean="TimestampSignEncrypt_Request"/>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
</jaxws:inInterceptors>
</jaxws:endpoint>
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor"
id="TimestampSignEncrypt_Response">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="user" value="service"/>
<entry key="encryptionUser" value="useReqSigCert"/>
<entry key="signaturePropFile"
value="org/apache/cxf/systest/ws/security/server_security.properties"/>
<entry key="encryptionPropFile"
value="org/apache/cxf/systest/ws/security/server_security.properties"/>
<entry key="signatureKeyIdentifier" value="SKIKeyIdentifier"/>
<entry key="encryptionKeyIdentifier" value="SKIKeyIdentifier" />
<entry key="passwordCallbackClass"
value="org.apache.cxf.systest.ws.security.KeystorePasswordCallback"/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionKeyTransportAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<entry key="encryptionSymAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
</map>
</constructor-arg>
</bean>
<bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
id="TimestampSignEncrypt_Request">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="signaturePropFile"
value="org/apache/cxf/systest/ws/security/server_security.properties"/>
<entry key="encryptionPropFile"
value="org/apache/cxf/systest/ws/security/server_security.properties"/>
<entry key="passwordCallbackClass"
value="org.apache.cxf.systest.ws.security.KeystorePasswordCallback"/>
</map>
</constructor-arg>
</bean>
Philippe Wanner
Software Architect
Bedag Informatique SA
Avenue de Sévelin 46
CH-1004 Lausanne
+41 21 313 20 48
+41 79 375 81 54
[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>
www.bedag.ch <http://www.bedag.ch/>