Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

CXF uses asymmetric algorithms for different purposes: encryption of symmetric keys and payloads, signing security tokens and messages, proof of possession, etc.
Normally the public keys (in the form of X509 certificates) are stored in java keystores.

For example, if the sender encrypts the message payload sending to the receiver, he should have access to the receiver certificate saved in the local keystore.
The sender uses this certificate for message encryption and receiver decrypts the request with corresponded own the corresponding private key:

Seems to be OK? Imagine now that you have a production environment with 100 different clients of this service and the service certificate is expired. You should reissue and replace the certificate in ALL client keystores! Even more, if keystores are packaged into war files or OSGi bundles – they should be unpackaged and updated. Not really acceptable for enterprise environments.

...

Normally it is a responsibility of Public Key Infrastructure (PKI) established in the organization. PKI is responsible to create, manage, store, distribute, synchronize and revoke public certificates and certification authorities (CAs).

XKMS Specification

W3C specifies a protocol to distribute and register public keys, certificates and CAs that can be used for XML-based cryptography, including signature and encryption: XML Key Management Specification (XKMS 2.0).
The XKMS Specification comprises two parts – the XML Key Information Service Specification (XKISS) describing the runtime aspects of key lookup and certificate validation, and the XML Key Registration Service Specification (XKRSS) describing the administrative aspects of registering, renewing, revoking and recovering certificates.
The XKMS Service implements both parts of specification.

The XKMS SOAP interface can be used as a standard frontend to access the Public Key Infrastructure (PKI). Using XKMS message encryption scenario, the message encryption picture will change in the following way:

XKMS Design

Internal structure of XKMS service is represented on in the following figure:

The XKMS Service exposes a SOAP interface specified in XKMS 2.0.
The XKMS implementation realizes chain of responsibility design pattern .
Each XKMS operation defines a handler interface and provides one or more implementations of this interface. Handler implementations are connected into a chain.
Operation implementation invokes handlers one after another from the pre-configured chain until either all handlers will be processed or a critical error will occur.
This design makes the XKMS internal implementation quite flexible: it is easy to add/remove handlers, change their order, introduce handlers supporting new backends, etc.
For example, a certificate can be searched firstly in the LDAP repository by LDAP lookup handler and, if it is not found there, additionally looked for in a remote PKI using an appropriate lookup handler. Validation operation logic is organized in a chain is well: first validation handler checks format and expire expiry date of the X509 certificate, next one checks the certificate trust chain.

Currently the XKMS Service supports simple file based and LDAP backends.
Sample spring configuration of XKMS handlers looks like:

Code Block
xml
xml
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:test="http://apache.org/hello_world_soap_http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
        http://cxf.apache.org/core
        http://cxf.apache.org/schemas/core.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://cxf.apache.org/jaxws                                     
        http://cxf.apache.org/schemas/jaxws.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-2.0.xsd">


    <bean id="dateValidator" class="org.apache.cxf.xkms.x509.validator.DateValidator" />

    <bean id="trustedAuthorityValidator"
        class="org.apache.cxf.xkms.x509.validator.TrustedAuthorityValidator">
        <constructor-arg ref="certificateRepo" />
    </bean>

    <bean id="x509Locator" class="org.apache.cxf.xkms.x509.handlers.X509Locator">
        <constructor-arg ref="certificateRepo" />
    </bean>

    <bean id="x509Register"
        class="org.apache.cxf.xkms.x509.handlers.x509Register">
        <constructor-arg ref="certificateRepo" />
    </bean>


    <!-- LDAP based implementation -->

    <bean id="certificateRepo"
        class="org.apache.cxf.xkms.x509.repo.ldap.LdapCertificateRepo">
        <constructor-arg ref="ldapSearch" />
        <constructor-arg ref="ldapSchemaConfig" />
        <constructor-arg value="dc=example,dc=com" />
    </bean>

    <bean id="ldapSearch" class="org.apache.cxf.xkms.x509.repo.ldap.LdapSearch">
        <constructor-arg value="ldap://localhost:2389" />
        <constructor-arg value="cn=Directory Manager,dc=example,dc=com" />
        <constructor-arg value="test" />
        <constructor-arg value="2" />
    </bean>

    <bean id="ldapSchemaConfig" class="org.apache.cxf.xkms.x509.repo.ldap.LdapSchemaConfig">
        <property name="certObjectClass" value="inetOrgPerson" />
        <property name="attrUID" value="uid" />
        <property name="attrIssuerID" value="manager" />
        <property name="attrSerialNumber" value="employeeNumber" />
        <property name="attrCrtBinary" value="userCertificate;binary" />
        <property name="constAttrNamesCSV" value="sn" />
        <property name="constAttrValuesCSV" value="X509 certificate" />
        <property name="serviceCertRDNTemplate" value="cn=%s,ou=services" />
        <property name="serviceCertUIDTemplate" value="cn=%s" />
	<property name="trustedAuthorityFilter" value="(&#038;(objectClass=inetOrgPerson)(ou:dn:=CAs))" />
	<property name="intermediateFilter" value="(objectClass=inetOrgPerson)" />
    </bean>


    <!-- File based implementation -->

    <!-- bean id="certificateRepo"
        class="org.apache.cxf.xkms.x509.repo.file.FileCertificateRepo">
        <constructor-arg value="../conf/certs" />
    </bean-->

</beans>

The dateValidator and trustedAuthorityValidator beans are implementations of the Validator interface for validity date and trusted chain validation.
x509Locator and x509Register are implementations of Locator and Register interfaces for X509 certificates.
certificateRepo is the repository implementation for LDAP backend. LdapSearch and LdapSchemaConfig contain LDAP configuration described in the following table:

...

Supported certificates types.

XKMS distinguishes between the following types of X509 certificates:

...

XKMS service endpoint is configured in the following way:

Code Block
xml
xml
    <bean id="xkmsProviderBean" class="org.apache.cxf.xkms.service.XKMSService">
        <property name="validators">
            <list>
                <ref bean="dateValidator" />
                <ref bean="trustedAuthorityValidator" />
            </list>
        </property>
        <property name="locators">
            <list>
                <ref bean="x509Locator" />
            </list>
        </property>
        <property name="keyRegisterHandlers">
            <list>
                <ref bean="x509Register" />
            </list>
        </property>
    </bean>

    <jaxws:endpoint id="XKMSService"
        xmlns:serviceNamespace="http://www.w3.org/2002/03/xkms#wsdl"
        serviceName="serviceNamespace:XKMSService" endpointName="serviceNamespace:XKMSPort"
        implementor="#xkmsProviderBean" address="/XKMS">
    </jaxws:endpoint>

...

Integrating the XKMS client into the CXF runtime.

The XKMS client can be integrated into CXF and WSS4J using a custom Crypto provider implementation. In this case, the XKMS service will be automatically invoked when WSS4J requires or validates a certificate. Details are described in this blog. Sample A sample XKMS based implementation of WSS4J Crypto interface is contributed into the XKMS Client component.

Data Formats

Input and output data formats are specified in XML Key Management Service Specification Version 2.0 (see XKMS 2.0). Anyway The XKMS service supports only a subset of the specified requests and responses.
Restrictions of formats for request and responses are described in the following table:

Element XPath

Supporting values

Description

RootElement/QueryKeyBinding/UseKeyWith@Application

urn:ietf:rfc:2459

Application specifies X509 SubjectDN in Identifier attribute. Used for normal users certificates

RootElement/QueryKeyBinding/UseKeyWith@Application

urn:apache:cxf:service:soap

Application specifies Service Id in Identifier attribute as {SERVICE_ NAMESPACE}SERVICE_NAME. Used for service certificates

RootElement/QueryKeyBinding/UseKeyWith@Identifier

X509 Subject DN or Service name as {SERVICE_ NAMESPACE}SERVICE_NAME

Depending on Application attribute public key is identified as X509 Subject DN or Service nameservice certificates

RootElement/UnverifiedKeyBinding/KeyInfo

X509Data/X509Certificate

Only X509Data with X509Certificate is supported

...

Success and Fault Response formats are specified in XKMS 2.0. Error conditions in XKMS service are reported using ResultMajor and ResultMinor attributes in the root response element.
The XKMS Service uses the following values for response codes:

...

Value

Description

Failure

The service attempted to perform the request but the operation failed.

NoMatch

No match was found for the search prototype provided.

TooManyResponses

The request resulted in the number of responses that exceeded limit determined by the service.

TimeInstantNotSupported

The receiver has refused the operation because it does not support the TimeInstant element.

Deployment

The XKMS Service can be deployed into web and OSGi containers. The Service implementation was tested with Tomcat and Karaf.

...