Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A9524DC34 for ; Sat, 18 May 2013 16:05:08 +0000 (UTC) Received: (qmail 51239 invoked by uid 500); 18 May 2013 16:05:09 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 51191 invoked by uid 500); 18 May 2013 16:05:08 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 51178 invoked by uid 99); 18 May 2013 16:05:08 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 May 2013 16:05:08 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 18 May 2013 16:05:04 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 9C8492388A6E; Sat, 18 May 2013 16:04:44 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1484133 [5/6] - in /cxf/trunk/services: ./ xkms/ xkms/xkms-client/ xkms/xkms-client/src/ xkms/xkms-client/src/main/ xkms/xkms-client/src/main/java/ xkms/xkms-client/src/main/java/org/ xkms/xkms-client/src/main/java/org/apache/ xkms/xkms-cl... Date: Sat, 18 May 2013 16:04:40 -0000 To: commits@cxf.apache.org From: ashakirin@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130518160444.9C8492388A6E@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LDAPSearch.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LDAPSearch.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LDAPSearch.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LDAPSearch.java Sat May 18 16:04:37 2013 @@ -0,0 +1,165 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.x509.handlers; + +import java.util.Hashtable; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.naming.CommunicationException; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; +import javax.naming.ldap.InitialLdapContext; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.xkms.exception.XKMSException; +import org.apache.cxf.xkms.model.xkms.ResultMajorEnum; +import org.apache.cxf.xkms.model.xkms.ResultMinorEnum; + +public class LDAPSearch { + private static final String SECURITY_AUTHENTICATION = "simple"; + private static final Logger LOG = LogUtils.getL7dLogger(LDAPSearch.class); + + private String ldapuri; + private String bindDN; + private String bindPassword; + private int numRetries; + + private InitialDirContext dirContext; + + public LDAPSearch(String ldapuri, String bindDN, String bindPassword, int numRetries) { + this.ldapuri = ldapuri; + this.bindDN = bindDN; + this.bindPassword = bindPassword; + this.numRetries = numRetries; + } + + //CHECKSTYLE:OFF + private InitialDirContext createInitialContext() throws NamingException { + Hashtable env = new Hashtable(5); + env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); + env.put(javax.naming.Context.PROVIDER_URL, ldapuri.toString()); + env.put(javax.naming.Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION); + env.put(javax.naming.Context.SECURITY_PRINCIPAL, bindDN); + env.put(javax.naming.Context.SECURITY_CREDENTIALS, bindPassword); + return new InitialLdapContext(env, null); + } + //CHECKSTYLE:ON + + public NamingEnumeration searchSubTree(String rootEntry, String filter) throws NamingException { + int retry = 0; + while (true) { + try { + if (this.dirContext == null) { + this.dirContext = createInitialContext(); + } + SearchControls ctls = new SearchControls(); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + return dirContext.search(rootEntry, filter, ctls); + } catch (CommunicationException e) { + LOG.log(Level.WARNING, "Error in ldap search: " + e.getMessage(), e); + this.dirContext = null; + retry++; + if (retry >= numRetries) { + throw new XKMSException(ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_RECEIVER, + ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_FAILURE, "Backend failure"); + } + } + } + } + + public Attributes getAttributes(String dn) throws NamingException { + int retry = 0; + while (true) { + try { + if (this.dirContext == null) { + this.dirContext = createInitialContext(); + } + return dirContext.getAttributes(dn); + } catch (CommunicationException e) { + LOG.log(Level.WARNING, "Error in ldap search: " + e.getMessage(), e); + this.dirContext = null; + retry++; + if (retry >= numRetries) { + throw new XKMSException(ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_RECEIVER, + ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_FAILURE, "Backend failure"); + } + } + } + } + + public Attribute getAttribute(String dn, String attrName) throws NamingException { + Attribute attr = getAttributes(dn).get(attrName); + if (attr != null) { + return attr; + } + throw new RuntimeException("Did not find a matching attribute for dn: " + dn + + " attributeName: " + attrName); + } + + public Attributes findAttributes(String rootDN, String filter) throws NamingException { + NamingEnumeration answer = searchSubTree(rootDN, filter); + if (answer.hasMore()) { + SearchResult sr = answer.next(); + return sr.getAttributes(); + } else { + return null; + } + } + + public Attribute findAttribute(String rootDN, String filter, String attrName) throws NamingException { + Attributes attrs = findAttributes(rootDN, filter); + if (attrs != null) { + Attribute attr = attrs.get(attrName); + if (attr == null) { + throw new RuntimeException("Did not find a matching attribute for root: " + rootDN + + " filter: " + filter + " attributeName: " + attrName); + } + return attr; + } + return null; + } + + public void bind(String dn, Attributes attribs) throws NamingException { + int retry = 0; + while (true) { + try { + if (this.dirContext == null) { + this.dirContext = createInitialContext(); + } + dirContext.bind(dn, null, attribs); + return; + } catch (CommunicationException e) { + LOG.log(Level.WARNING, "Error in ldap search: " + e.getMessage(), e); + this.dirContext = null; + retry++; + if (retry >= numRetries) { + throw new XKMSException(ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_RECEIVER, + ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_FAILURE, "Backend failure"); + } + } + } + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LdapRegisterHandler.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LdapRegisterHandler.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LdapRegisterHandler.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/handlers/LdapRegisterHandler.java Sat May 18 16:04:37 2013 @@ -0,0 +1,81 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.x509.handlers; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.regex.Matcher; + +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; + +import org.apache.cxf.xkms.exception.XKMSArgumentNotMatchException; +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; + +public class LdapRegisterHandler extends AbstractX509RegisterHandler { + + private static final String OU_SERVICES = "ou=services"; + private static final String CN_PREFIX = "cn="; + private static final String INET_ORG_PERSON = "inetOrgPerson"; + private static final String ATTR_OBJECT_CLASS = "objectClass"; + private static final String ATTR_SN = "sn"; + private static final String ATTR_UID_NAME = "uid"; + private static final String ATTR_ISSUER_IDENTIFIER = "manager"; + private static final String ATTR_SERIAL_NUMBER = "employeeNumber"; + private static final String ATTR_USER_CERTIFICATE_BINARY = "userCertificate;binary"; + + private final LDAPSearch ldapSearch; + private final String rootDN; + + public LdapRegisterHandler(LDAPSearch ldapSearch, String rootDN) throws CertificateException { + super(); + this.ldapSearch = ldapSearch; + this.rootDN = rootDN; + } + + @Override + public void saveCertificate(X509Certificate cert, UseKeyWithType id) { + Attributes attribs = new BasicAttributes(); + attribs.put(new BasicAttribute(ATTR_OBJECT_CLASS, INET_ORG_PERSON)); + attribs.put(new BasicAttribute(ATTR_SN, "X509 certificate")); + attribs.put(new BasicAttribute(ATTR_UID_NAME, cert.getSubjectX500Principal().getName())); + attribs.put(new BasicAttribute(ATTR_SERIAL_NUMBER, cert.getSerialNumber().toString(16))); + attribs.put(new BasicAttribute(ATTR_ISSUER_IDENTIFIER, cert.getIssuerX500Principal().getName())); + try { + attribs.put(new BasicAttribute(ATTR_USER_CERTIFICATE_BINARY, cert.getEncoded())); + String dn = getDN(id.getApplication(), id.getIdentifier()); + ldapSearch.bind(dn, attribs); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + private String getDN(String applicationUri, String identifier) { + if (Applications.PKIX.getUri().equals(applicationUri)) { + return identifier + "," + rootDN; + } else if (Applications.SERVICE_SOAP.getUri().equals(applicationUri)) { + String escapedIdentifier = identifier.replaceAll("\\/", Matcher.quoteReplacement("\\/")); + return CN_PREFIX + escapedIdentifier + "," + OU_SERVICES + "," + rootDN; + } else { + throw new XKMSArgumentNotMatchException("Unsupported application uri: " + applicationUri); + } + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/FileLocator.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/FileLocator.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/FileLocator.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/FileLocator.java Sat May 18 16:04:37 2013 @@ -0,0 +1,216 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.locator; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.math.BigInteger; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.cxf.xkms.exception.XKMSArgumentNotMatchException; +import org.apache.cxf.xkms.exception.XKMSCertificateException; +import org.apache.cxf.xkms.exception.XKMSConfigurationException; +import org.apache.cxf.xkms.exception.XKMSTooManyResponsesException; +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.handlers.Locator; +import org.apache.cxf.xkms.model.xkms.LocateRequestType; +import org.apache.cxf.xkms.model.xkms.ResultMajorEnum; +import org.apache.cxf.xkms.model.xkms.ResultMinorEnum; +import org.apache.cxf.xkms.model.xkms.UnverifiedKeyBindingType; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.x509.parser.LocateRequestParser; +import org.apache.cxf.xkms.x509.utils.X509Utils; + +public class FileLocator implements Locator { + + private static final String CN_PREFIX = "cn="; + //private static final Logger LOG = LoggerFactory.getLogger(FilePersistenceManager.class); + private final File storageDir; + private final CertificateFactory certFactory; + + public FileLocator(File storageDir) throws CertificateException { + if (storageDir == null) { + throw new IllegalStateException("File Persistence: root certificate directory is not initialized"); + } + this.storageDir = storageDir; + this.certFactory = CertificateFactory.getInstance("X.509"); + } + + @Override + public UnverifiedKeyBindingType locate(LocateRequestType request) { + + List keyIDs = LocateRequestParser.parse(request); + + X509Certificate cert = findCertificate(keyIDs); + + if (cert == null) { + return null; + } + + try { + UnverifiedKeyBindingType result = new UnverifiedKeyBindingType(); + result.setKeyInfo(X509Utils.getKeyInfo(cert)); + return result; + } catch (CertificateEncodingException e) { + throw new XKMSCertificateException("Cannot encode certificate: " + e.getMessage(), e); + } + } + + public X509Certificate findCertificate(List ids) { + List certs = Collections.emptyList(); + if ((ids.size() == 1) && (getIdForApplication(Applications.PKIX, ids) != null) + || (getIdForApplication(Applications.SERVICE_SOAP, ids) != null)) { + String subjectDN = getSubjectDN(ids.get(0).getApplication(), ids.get(0).getIdentifier()); + certs = findCertificateBySubjectDn(subjectDN); + } + String issuer = getIdForApplication(Applications.ISSUER, ids); + String serial = getIdForApplication(Applications.SERIAL, ids); + if ((issuer != null) && (serial != null)) { + certs = findCertificateByIssuerSerial(issuer, serial); + } + if (certs.size() > 1) { + throw new XKMSTooManyResponsesException("More than one matching key was found for: " + ids); + } + if (certs.size() == 0) { + return null; + } + return certs.get(0); + } + + private String getSubjectDN(String applicationUri, String identifier) { + if (Applications.PKIX.getUri().equals(applicationUri)) { + return identifier; + } else if (Applications.SERVICE_SOAP.getUri().equals(applicationUri)) { + return CN_PREFIX + identifier; + } else { + throw new XKMSArgumentNotMatchException("Unsupported application uri: " + applicationUri); + } + } + + private List findCertificateBySubjectDn(String subjectDN) { + List result = new ArrayList(); + File[] list = getX509Files(); + // String searchId = DnUtils.extractMostSignificantAttribute(subjectDN); + for (File certFile : list) { + try { + X509Certificate cert = readCertificate(certFile); + // String id = DnUtils.extractMostSignificantAttribute(cert.getSubjectDN().getName()); + // if (searchId.equalsIgnoreCase(id)) { + if (subjectDN.equalsIgnoreCase(cert.getSubjectDN().getName()) + || subjectDN.equalsIgnoreCase(cert.getSubjectX500Principal().getName())) { + result.add(cert); + } + } catch (Exception e) { + throw new RuntimeException("Error reading certificate for " + subjectDN + ": " + e.getMessage(), e); + } + + } + return result; + } + + private List findCertificateByIssuerSerial(String issuer, String serial) { + List result = new ArrayList(); + File[] list = getX509Files(); + for (File certFile : list) { + try { + X509Certificate cert = readCertificate(certFile); + BigInteger cs = cert.getSerialNumber(); + BigInteger ss = new BigInteger(serial, 16); + if (issuer.equalsIgnoreCase(cert.getIssuerX500Principal().getName()) && cs.equals(ss)) { + result.add(cert); + } + } catch (Exception e) { + throw new RuntimeException("Error reading certificate for issuer " + issuer + ": " + e.getMessage(), e); + } + + } + return result; + } + + private File[] getX509Files() { + File[] list = storageDir.listFiles(); + if (list == null) { + throw new XKMSConfigurationException(ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_RECEIVER, + ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_FAILURE, + "File base persistence storage is not found: " + storageDir.getPath()); + } + return list; + } + + private X509Certificate readCertificate(File certFile) throws CertificateException, FileNotFoundException { + FileInputStream fis = new FileInputStream(certFile); + return (X509Certificate) certFactory.generateCertificate(fis); + } + + public void saveCertificate(X509Certificate cert, UseKeyWithType id) { + String name = cert.getSubjectX500Principal().getName(); + try { + File certFile = new File(storageDir, getRelativePathForSubjectDn(id.getIdentifier(), cert)); + certFile.getParentFile().mkdirs(); + FileOutputStream fos = new FileOutputStream(certFile); + BufferedOutputStream bos = new BufferedOutputStream(fos); + bos.write(cert.getEncoded()); + bos.close(); + fos.close(); + } catch (Exception e) { + throw new RuntimeException("Error saving certificate " + name + ": " + e.getMessage(), e); + } + } + + public String convertDnForFileSystem(String dn) { + String result = dn.replace("=", "-"); + result = result.replace(", ", "_"); + result = result.replace(",", "_"); + result = result.replace("/", "_"); + result = result.replace("\\", "_"); + result = result.replace("{", "_"); + result = result.replace("}", "_"); + result = result.replace(":", "_"); + return result; + } + + public String getRelativePathForSubjectDn(String subjectDn, X509Certificate cert) { + BigInteger serialNumber = cert.getSerialNumber(); + String issuer = cert.getIssuerX500Principal().getName(); + String path = convertDnForFileSystem(subjectDn) + "-" + serialNumber.toString() + "-" + + convertDnForFileSystem(issuer) + ".cer"; + // TODO Filter for only valid and safe characters + return path; + } + + private String getIdForApplication(Applications application, List ids) { + for (UseKeyWithType id : ids) { + if (application.getUri().equalsIgnoreCase(id.getApplication())) { + return id.getIdentifier(); + } + } + return null; + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/LdapLocator.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/LdapLocator.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/LdapLocator.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/locator/LdapLocator.java Sat May 18 16:04:37 2013 @@ -0,0 +1,191 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.locator; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; + +import javax.naming.NamingException; +import javax.naming.directory.Attribute; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.xkms.exception.XKMSArgumentNotMatchException; +import org.apache.cxf.xkms.exception.XKMSCertificateException; +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.handlers.Locator; +import org.apache.cxf.xkms.model.xkms.LocateRequestType; +import org.apache.cxf.xkms.model.xkms.UnverifiedKeyBindingType; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.x509.handlers.LDAPSearch; +import org.apache.cxf.xkms.x509.parser.LocateRequestParser; +import org.apache.cxf.xkms.x509.utils.X509Utils; + +public class LdapLocator implements Locator { + + private static final String OU_SERVICES = "ou=services"; + private static final String CN_PREFIX = "cn="; + private static final String ATTR_UID_NAME = "uid"; + private static final String ATTR_ISSUER_IDENTIFIER = "manager"; + private static final String ATTR_SERIAL_NUMBER = "employeeNumber"; + private static final String ATTR_USER_CERTIFICATE_BINARY = "userCertificate;binary"; + private static final String FILTER_UID = "(" + ATTR_UID_NAME + "=%s)"; + private static final String FILTER_ISSUER_SERIAL = "(&(" + ATTR_ISSUER_IDENTIFIER + "=%s)(" + ATTR_SERIAL_NUMBER + + "=%s))"; + private static final Logger LOG = LogUtils.getL7dLogger(LdapLocator.class); + private final LDAPSearch ldapSearch; + private CertificateFactory certificateFactory; + private final String rootDN; + + public LdapLocator(LDAPSearch ldapSearch, String rootDN) { + this.ldapSearch = ldapSearch; + this.rootDN = rootDN; + try { + this.certificateFactory = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + LOG.log(Level.SEVERE, e.getMessage(), e); + } + } + + @Override + public UnverifiedKeyBindingType locate(LocateRequestType request) { + + List keyIDs = LocateRequestParser.parse(request); + + X509Certificate cert = findCertificate(keyIDs); + + if (cert == null) { + return null; + } + + try { + UnverifiedKeyBindingType result = new UnverifiedKeyBindingType(); + result.setKeyInfo(X509Utils.getKeyInfo(cert)); + return result; + } catch (CertificateEncodingException e) { + throw new XKMSCertificateException("Cannot encode certificate: " + e.getMessage(), e); + } + } + + public X509Certificate findCertificate(List ids) { + try { + String issuer = null; + String serial = null; + + for (UseKeyWithType key : ids) { + if (Applications.PKIX.getUri().equals(key.getApplication())) { + return findByDn(key.getApplication(), key.getIdentifier()); + } else if (Applications.SERVICE_SOAP.getUri().equals(key.getApplication())) { + return findByDn(key.getApplication(), key.getIdentifier()); + } else if (Applications.ISSUER.getUri().equals(key.getApplication())) { + issuer = key.getIdentifier(); + } else if (Applications.SERIAL.getUri().equals(key.getApplication())) { + serial = key.getIdentifier(); + } + } + + if (issuer != null && serial != null) { + return findByIssuerSerial(issuer, serial); + } + + throw new IllegalArgumentException("Application identifier not supported"); + + } catch (Exception e) { + throw new RuntimeException("Search certificates failure: " + e.getMessage(), e); + } + } + + private X509Certificate findByDn(String application, String id) throws CertificateException { + byte[] content = null; + try { + String dn = getDN(application, id); + content = getCertificateForDn(dn); + } catch (NamingException e) { + // Not found + } + // Try to find certificate by search for distinguishedName attribute + try { + if (content == null) { + content = getCertificateForDnAttr(getSubjectDN(application, id)); + } + } catch (NamingException e) { + // Not found + } + return (content != null) + ? (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(content)) + : null; + } + + private byte[] getCertificateForDn(String dn) throws NamingException { + Attribute attr = ldapSearch.getAttribute(dn, ATTR_USER_CERTIFICATE_BINARY); + return (attr != null) + ? (byte[]) attr.get() + : null; + } + + private X509Certificate findByIssuerSerial(String issuer, String serial) throws CertificateException, + NamingException { + + if ((issuer == null) || (serial == null)) { + throw new IllegalArgumentException("Issuer and serial applications are expected in request"); + } + String filter = String.format(FILTER_ISSUER_SERIAL, issuer, serial); + Attribute attr = ldapSearch.findAttribute(rootDN, filter, ATTR_USER_CERTIFICATE_BINARY); + if ((attr != null) && (attr.get() != null)) { + return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream((byte[]) attr + .get())); + } else { + return null; + } + } + + private String getDN(String applicationUri, String identifier) { + if (Applications.PKIX.getUri().equals(applicationUri)) { + return identifier + "," + rootDN; + } else if (Applications.SERVICE_SOAP.getUri().equals(applicationUri)) { + String escapedIdentifier = identifier.replaceAll("\\/", Matcher.quoteReplacement("\\/")); + return CN_PREFIX + escapedIdentifier + "," + OU_SERVICES + "," + rootDN; + } else { + throw new XKMSArgumentNotMatchException("Unsupported application uri: " + applicationUri); + } + } + + private String getSubjectDN(String application, String id) { + if (application.equalsIgnoreCase(Applications.SERVICE_SOAP.getUri())) { + return CN_PREFIX + id; + } else { + return id; + } + } + + private byte[] getCertificateForDnAttr(String dn) throws NamingException { + String filter = String.format(FILTER_UID, dn); + Attribute attr = ldapSearch.findAttribute(rootDN, filter, ATTR_USER_CERTIFICATE_BINARY); + return (attr != null) + ? (byte[]) attr.get() + : null; + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/LocateRequestParser.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/LocateRequestParser.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/LocateRequestParser.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/LocateRequestParser.java Sat May 18 16:04:37 2013 @@ -0,0 +1,119 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.x509.parser; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBElement; + +import org.apache.cxf.xkms.exception.XKMSException; +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.model.xkms.LocateRequestType; +import org.apache.cxf.xkms.model.xkms.QueryKeyBindingType; +import org.apache.cxf.xkms.model.xkms.ResultMajorEnum; +import org.apache.cxf.xkms.model.xkms.ResultMinorEnum; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.model.xmldsig.KeyInfoType; +import org.apache.cxf.xkms.model.xmldsig.X509DataType; +import org.apache.cxf.xkms.model.xmldsig.X509IssuerSerialType; +import org.apache.cxf.xkms.x509.utils.X509Utils; + +public final class LocateRequestParser { + + private LocateRequestParser() { + } + + public static List parse(LocateRequestType request) { + List keyIDs = new ArrayList(); + if (request == null) { + return keyIDs; + } + + QueryKeyBindingType query = request.getQueryKeyBinding(); + if (query == null) { + return keyIDs; + } + + // http://www.w3.org/TR/xkms2/ [213] + if (query.getTimeInstant() != null) { + throw new XKMSException(ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_RECEIVER, + ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_TIME_INSTANT_NOT_SUPPORTED); + } + + keyIDs.addAll(parse(query.getKeyInfo())); + + List useKeyList = query.getUseKeyWith(); + keyIDs.addAll(useKeyList); + + return keyIDs; + } + + protected static List parse(KeyInfoType keyInfo) { + List keyIDs = new ArrayList(); + + if (keyInfo == null) { + return keyIDs; + } + + List content = keyInfo.getContent(); + for (Object obj1 : content) { + if (obj1 instanceof JAXBElement) { + JAXBElement keyInfoChild = (JAXBElement) obj1; + if (X509Utils.X509_KEY_NAME.equals(keyInfoChild.getName())) { + UseKeyWithType keyDN = new UseKeyWithType(); + keyDN.setApplication(Applications.PKIX.getUri()); + keyDN.setIdentifier((String) keyInfoChild.getValue()); + keyIDs.add(keyDN); + + } else if (X509Utils.X509_DATA.equals(keyInfoChild.getName())) { + X509DataType x509Data = (X509DataType) keyInfoChild.getValue(); + List x509DataContent = x509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName(); + + for (Object obj2 : x509DataContent) { + if (obj2 instanceof JAXBElement) { + JAXBElement x509DataChild = (JAXBElement) obj2; + + if (X509Utils.X509_ISSUER_SERIAL.equals(x509DataChild.getName())) { + X509IssuerSerialType x509IssuerSerial = (X509IssuerSerialType) x509DataChild.getValue(); + + UseKeyWithType issuer = new UseKeyWithType(); + issuer.setApplication(Applications.ISSUER.getUri()); + issuer.setIdentifier(x509IssuerSerial.getX509IssuerName()); + keyIDs.add(issuer); + + UseKeyWithType serial = new UseKeyWithType(); + serial.setApplication(Applications.SERIAL.getUri()); + serial.setIdentifier(x509IssuerSerial.getX509SerialNumber().toString()); + keyIDs.add(serial); + + } else if (X509Utils.X509_SUBJECT_NAME.equals(x509DataChild.getName())) { + UseKeyWithType keyDN = new UseKeyWithType(); + keyDN.setApplication(Applications.PKIX.getUri()); + keyDN.setIdentifier((String) x509DataChild.getValue()); + keyIDs.add(keyDN); + } + } + } + } + } + } + return keyIDs; + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/ValidateRequestParser.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/ValidateRequestParser.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/ValidateRequestParser.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/parser/ValidateRequestParser.java Sat May 18 16:04:37 2013 @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.x509.parser; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import javax.xml.bind.JAXBElement; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.xkms.exception.XKMSRequestException; +import org.apache.cxf.xkms.model.xkms.ValidateRequestType; +import org.apache.cxf.xkms.model.xmldsig.X509DataType; +import org.apache.cxf.xkms.x509.utils.X509Utils; + +public final class ValidateRequestParser { + + private static final Logger LOG = LogUtils.getL7dLogger(ValidateRequestParser.class); + + private ValidateRequestParser() { + } + + /** + * Extract the X509 certificates from ValidateRequestType and return them as list. + */ + public static List parse(ValidateRequestType request) { + List certs = new ArrayList(); + + if ((request.getQueryKeyBinding()) != null && (request.getQueryKeyBinding().getKeyInfo() != null)) { + List keyInfoContent = request.getQueryKeyBinding().getKeyInfo().getContent(); + for (Object keyInfoObject : keyInfoContent) { + if (keyInfoObject instanceof JAXBElement) { + JAXBElement dataInstance = (JAXBElement) keyInfoObject; + if (X509Utils.X509_DATA.equals(dataInstance.getName())) { + try { + X509Utils.parseX509Data((X509DataType) dataInstance.getValue(), certs); + LOG.fine("Extracted " + certs.size() + " certificates from ValidateRequest"); + } catch (CertificateException e) { + throw new XKMSRequestException("Corrupted X509 certificate in request: " + e.getMessage(), + e); + } + } + } + } + } + return certs; + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/utils/X509Utils.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/utils/X509Utils.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/utils/X509Utils.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/utils/X509Utils.java Sat May 18 16:04:37 2013 @@ -0,0 +1,171 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.utils; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; + +import javax.xml.bind.JAXBElement; +import javax.xml.namespace.QName; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.xkms.model.xkms.LocateRequestType; +import org.apache.cxf.xkms.model.xkms.LocateResultType; +import org.apache.cxf.xkms.model.xkms.ResultMajorEnum; +import org.apache.cxf.xkms.model.xkms.ResultMinorEnum; +import org.apache.cxf.xkms.model.xkms.UnverifiedKeyBindingType; +import org.apache.cxf.xkms.model.xmldsig.KeyInfoType; +import org.apache.cxf.xkms.model.xmldsig.ObjectFactory; +import org.apache.cxf.xkms.model.xmldsig.X509DataType; + +public final class X509Utils { + public static final QName X509_DATA = new QName("http://www.w3.org/2000/09/xmldsig#", "X509Data"); + + public static final QName X509_KEY_NAME = new QName("http://www.w3.org/2000/09/xmldsig#", "KeyName"); + + public static final QName X509_ISSUER_SERIAL = new QName("http://www.w3.org/2000/09/xmldsig#", "X509IssuerSerial"); + + public static final QName X509_SUBJECT_NAME = new QName("http://www.w3.org/2000/09/xmldsig#", "X509SubjectName"); + + public static final QName X509_CERTIFICATE = new QName("http://www.w3.org/2000/09/xmldsig#", "X509Certificate"); + + private static final Logger LOG = LogUtils.getL7dLogger(X509Utils.class); + + private static final CertificateFactory X509_FACTORY; + + + static { + try { + X509_FACTORY = CertificateFactory.getInstance("X.509"); + } catch (CertificateException e) { + throw new IllegalStateException("Cannot initialize X509 CertificateFactory: " + e.getMessage(), e); + } + } + + private X509Utils() { + + } + + public static void parseX509Data(X509DataType x509Data, List certs) throws CertificateException { + List dataList = x509Data.getX509IssuerSerialOrX509SKIOrX509SubjectName(); + for (Object x509Object : dataList) { + if (x509Object instanceof JAXBElement) { + JAXBElement x509Item = (JAXBElement) x509Object; + X509Certificate certificate = parseX509Item(x509Item); + if (null != certificate) { + certs.add(certificate); + } + } + } + } + + private static X509Certificate parseX509Item(JAXBElement x509Item) throws CertificateException { + QName x509ItemName = x509Item.getName(); + if (X509_CERTIFICATE.equals(x509ItemName)) { + X509Certificate certificate; + certificate = extractCertificate(x509Item); + LOG.fine("Extracted " + certificate.getSubjectX500Principal().getName()); + return certificate; + } + return null; + } + + private static X509Certificate extractCertificate(JAXBElement x509Item) throws CertificateException { + @SuppressWarnings("unchecked") + JAXBElement byteElement = (JAXBElement) x509Item; + byte[] bytes = byteElement.getValue(); + InputStream stream = new ByteArrayInputStream(bytes); + Certificate certificate = X509_FACTORY.generateCertificate(stream); + if (certificate instanceof X509Certificate) { + return (X509Certificate) certificate; + } else { + throw new CertificateException("Unsupported certificate type encountered: " + + certificate.getClass().getName()); + } + } + + void addResult(LocateResultType response, Collection certificates, List reasons) { + String result = null; + if (0 != certificates.size()) { + result = ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_SUCCESS.value(); + } else { + if ((null != reasons) && (0 != reasons.size())) { + // At least one of the components reported a problem, so we + // include the reported error code + Iterator reason = reasons.iterator(); + result = reason.next(); + String minor = reason.next(); + if (null != minor) { + response.setResultMinor(minor); + } + } else { + // no error here, we simply did not find any matching + // certificates + result = ResultMajorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_SUCCESS.value(); + response.setResultMinor(ResultMinorEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_NO_MATCH.value()); + } + } + response.setResultMajor(result); + } + + public static UnverifiedKeyBindingType getUnverifiedKeyBinding(X509Certificate cert) + throws CertificateEncodingException { + UnverifiedKeyBindingType unverifiedKeyBinding = new UnverifiedKeyBindingType(); + unverifiedKeyBinding.setKeyInfo(getKeyInfo(cert)); + return unverifiedKeyBinding; + } + + public static KeyInfoType getKeyInfo(X509Certificate cert) throws CertificateEncodingException { + KeyInfoType keyInfo = new KeyInfoType(); + JAXBElement certificate = new ObjectFactory().createX509DataTypeX509Certificate(cert.getEncoded()); + X509DataType x509DataType = new X509DataType(); + List x509DataContent = x509DataType.getX509IssuerSerialOrX509SKIOrX509SubjectName(); + x509DataContent.add(certificate); + JAXBElement x509Data = new ObjectFactory().createX509Data(x509DataType); + List keyInfoContent = keyInfo.getContent(); + keyInfoContent.add(x509Data); + return keyInfo; + } + + LocateResultType createResponse(LocateRequestType request) { + LocateResultType ret = new LocateResultType(); + ret.setId(UUID.randomUUID().toString()); + ret.setRequestId(request.getId()); + ret.setService("http://services.sopera.org/xkms/v2.0"); + return ret; + } + + public static void assertElementNotNull(Object element, Class elementClass) { + if (element == null) { + throw new IllegalArgumentException(elementClass.getName() + " must be set"); + } + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/validator/DateValidator.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/validator/DateValidator.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/validator/DateValidator.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/main/java/org/apache/cxf/xkms/x509/validator/DateValidator.java Sat May 18 16:04:37 2013 @@ -0,0 +1,99 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.validator; + +import java.security.cert.CertificateExpiredException; +import java.security.cert.CertificateNotYetValidException; +import java.security.cert.X509Certificate; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.logging.Logger; + +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.xkms.handlers.Validator; +import org.apache.cxf.xkms.model.xkms.KeyBindingEnum; +import org.apache.cxf.xkms.model.xkms.ReasonEnum; +import org.apache.cxf.xkms.model.xkms.StatusType; +import org.apache.cxf.xkms.model.xkms.ValidateRequestType; +import org.apache.cxf.xkms.x509.parser.ValidateRequestParser; + +public class DateValidator implements Validator { + + private static final Logger LOG = LogUtils.getL7dLogger(DateValidator.class); + + /** + * Checks if a certificate is within its validity period. + * + * @param certificate to check + * @return the validity state of the certificate + */ + public boolean isCertificateValid(X509Certificate certificate) { + Date date = Calendar.getInstance().getTime(); + + try { + certificate.checkValidity(date); + } catch (CertificateNotYetValidException e) { + return false; + } catch (CertificateExpiredException e) { + return false; + } + /* + * TODO: clarify use of KeyUsage with customer if (null == certificate.getKeyUsage()) { return false; } + * boolean[] keyUsage = certificate.getKeyUsage(); if (!keyUsage[KeyUsage.digitalSignature.ordinal()] || + * !keyUsage[KeyUsage.dataEncipherment.ordinal()] || keyUsage[KeyUsage.encipherOnly.ordinal()] || + * keyUsage[KeyUsage.decipherOnly.ordinal()]) { return false; } + */ + return true; + } + + @Override + public StatusType validate(ValidateRequestType request) { + StatusType status = new StatusType(); + List certificates = ValidateRequestParser.parse(request); + if (certificates == null || certificates.isEmpty()) { + status.setStatusValue(KeyBindingEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_INDETERMINATE); + status.getIndeterminateReason().add("http://www.cxf.apache.org/2002/03/xkms#RequestNotSupported"); + } + if (isCertificateChainValid(certificates)) { + status.getValidReason().add(ReasonEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALIDITY_INTERVAL.value()); + status.setStatusValue(KeyBindingEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALID); + } else { + status.getInvalidReason().add(ReasonEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALIDITY_INTERVAL.value()); + status.setStatusValue(KeyBindingEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_INVALID); + } + return status; + } + + public boolean isCertificateChainValid(List certificates) { + if (certificates == null) { + return false; + } + + for (X509Certificate x509Certificate : certificates) { + if (!isCertificateValid(x509Certificate)) { + LOG.severe("Certificate is expired: " + x509Certificate.getSubjectX500Principal()); + return false; + } + } + return true; + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/file/persistence/FilePersistenceManagerTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/file/persistence/FilePersistenceManagerTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/file/persistence/FilePersistenceManagerTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/file/persistence/FilePersistenceManagerTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,135 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.file.persistence; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.DatatypeConverter; + +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.x509.handlers.FileRegisterHandler; +import org.apache.cxf.xkms.x509.locator.FileLocator; +import org.junit.Assert; +import org.junit.Test; + +public class FilePersistenceManagerTest { + private static final String EXAMPLE_SUBJECT_DN = "CN=www.issuer.com, L=CGN, ST=NRW, C=DE, O=Issuer"; + private static final String EXPECTED_CERT_FILE_NAME = "CN-www.issuer.com_L-CGN_ST-NRW_C-DE_O-Issuer-" + + "11688544847478700689-CN-www.issuer.com_L-CGN_ST-NRW_C-DE_O-Issuer.cer"; + + @Test + public void testSaveAndFind() throws CertificateException, IOException { + File storageDir = new File("target/teststore1"); + storageDir.mkdirs(); + FileRegisterHandler fileRegisterHandler = new FileRegisterHandler(storageDir); + FileLocator fileLocator = new FileLocator(storageDir); + InputStream is = this.getClass().getResourceAsStream("/store1/" + EXPECTED_CERT_FILE_NAME); + if (is == null) { + throw new RuntimeException("Can not find path " + is + " in classpath"); + } + X509Certificate cert = loadTestCert(is); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXAMPLE_SUBJECT_DN); + fileRegisterHandler.saveCertificate(cert, key); + + File certFile = new File(storageDir, EXPECTED_CERT_FILE_NAME); + Assert.assertTrue("Cert file " + certFile + " should exist", certFile.exists()); + FileInputStream fis = new FileInputStream(certFile); + X509Certificate outCert = loadTestCert(fis); + Assert.assertEquals(cert, outCert); + + List ids = new ArrayList(); + key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXAMPLE_SUBJECT_DN); + ids.add(key); + X509Certificate resultCert = fileLocator.findCertificate(ids); + Assert.assertNotNull(resultCert); + } + + private X509Certificate loadTestCert(InputStream is) throws IOException, CertificateException { + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) factory.generateCertificate(is); + } + + private String read(InputStream is) throws java.io.IOException { + StringBuffer fileData = new StringBuffer(1000); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + char[] buf = new char[1024]; + int numRead = 0; + while ((numRead = reader.read(buf)) != -1) { + String readData = String.valueOf(buf, 0, numRead); + fileData.append(readData); + buf = new char[1024]; + } + reader.close(); + return fileData.toString(); + } + + @SuppressWarnings("unused") + private void convertBase64ToCer(String sourcePath, String destPath) throws IOException { + InputStream is = this.getClass().getResourceAsStream(sourcePath); + String certString = read(is); + is.close(); + byte[] certData = DatatypeConverter.parseBase64Binary(certString); + File file = new File(destPath); + FileOutputStream fos = new FileOutputStream(file); + BufferedOutputStream bos = new BufferedOutputStream(fos); + bos.write(certData); + bos.close(); + fos.close(); + } + + @Test + public void testFindBySubjectName() throws CertificateException { + File storageDir = new File("src/test/resources/store1"); + Assert.assertTrue(storageDir.exists()); + Assert.assertTrue(storageDir.isDirectory()); + FileLocator persistenceManager = new FileLocator(storageDir); + List ids = new ArrayList(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXAMPLE_SUBJECT_DN); + ids.add(key); + X509Certificate resCert = persistenceManager.findCertificate(ids); + Assert.assertNotNull(resCert); + } + + @Test + public void testConvertDnForFileSystem() throws CertificateException { + File storageDir = new File("src/test/resources/store1"); + String convertedName = new FileRegisterHandler(storageDir).convertDnForFileSystem(EXAMPLE_SUBJECT_DN); + Assert.assertEquals("CN-www.issuer.com_L-CGN_ST-NRW_C-DE_O-Issuer", convertedName); + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerITest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerITest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerITest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerITest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,115 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.ldap.persistence; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URISyntaxException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import javax.naming.NamingException; + +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.x509.handlers.LDAPSearch; +import org.apache.cxf.xkms.x509.handlers.LdapRegisterHandler; +import org.apache.cxf.xkms.x509.locator.LdapLocator; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Tests need a real ldap server + */ +public class LDAPPersistenceManagerITest { + private static final String EXPECTED_SUBJECT_DN = "CN=www.issuer.com, L=CGN, ST=NRW, C=DE, O=Issuer"; + + @Test + @Ignore + public void testFindUserCert() throws URISyntaxException, NamingException, CertificateException { + LdapLocator persistenceManager = createLdapLocator(); + testFindBySubjectDnInternal(persistenceManager); + } + + @Test + @Ignore + public void testFindUserCertForNonExistantDn() throws URISyntaxException, NamingException, CertificateException { + LdapLocator persistenceManager = createLdapLocator(); + List ids = new ArrayList(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier("CN=wrong"); + ids.add(key); + X509Certificate cert = persistenceManager.findCertificate(ids); + Assert.assertNull("Certifiacte should be null", cert); + } + + @Test + @Ignore + public void testFindServiceCert() throws URISyntaxException, NamingException, CertificateException { + LdapLocator persistenceManager = createLdapLocator(); + String serviceUri = "cn=http:\\/\\/myservice.apache.org\\/MyServiceName,ou=services"; + List ids = new ArrayList(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.SERVICE_SOAP.getUri()); + key.setIdentifier(serviceUri); + ids.add(key); + X509Certificate cert = persistenceManager.findCertificate(ids); + Assert.assertEquals(EXPECTED_SUBJECT_DN, cert.getSubjectDN().toString()); + } + + @Test + @Ignore + public void testSave() throws Exception { + LDAPSearch ldapSearch = new LDAPSearch("ldap://localhost:2389", "cn=Directory Manager", "test", 2); + LdapLocator locator = createLdapLocator(); + LdapRegisterHandler persistenceManager = new LdapRegisterHandler(ldapSearch, "dc=example,dc=com"); + File certFile = new File("src/test/java/cert1.cer"); + Assert.assertTrue(certFile.exists()); + FileInputStream fis = new FileInputStream(certFile); + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) factory.generateCertificate(fis); + + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXPECTED_SUBJECT_DN); + persistenceManager.saveCertificate(cert, key); + testFindBySubjectDnInternal(locator); + } + + private LdapLocator createLdapLocator() throws CertificateException { + LDAPSearch ldapSearch = new LDAPSearch("ldap://localhost:2389", "cn=Directory Manager", "test", 2); + return new LdapLocator(ldapSearch, "dc=example,dc=com"); + } + + private void testFindBySubjectDnInternal(LdapLocator persistenceManager) { + List ids = new ArrayList(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXPECTED_SUBJECT_DN); + ids.add(key); + X509Certificate cert2 = persistenceManager.findCertificate(ids); + Assert.assertEquals(EXPECTED_SUBJECT_DN, cert2.getSubjectDN().toString()); + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPPersistenceManagerTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,88 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.ldap.persistence; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import javax.naming.directory.Attributes; + +import org.apache.cxf.xkms.handlers.Applications; +import org.apache.cxf.xkms.model.xkms.UseKeyWithType; +import org.apache.cxf.xkms.x509.handlers.LDAPSearch; +import org.apache.cxf.xkms.x509.handlers.LdapRegisterHandler; +import org.easymock.EasyMock; +import org.easymock.IMocksControl; +import org.junit.Assert; +import org.junit.Test; + +public class LDAPPersistenceManagerTest { + private static final String ROOT_DN = "dc=example,dc=com"; + private static final String EXPECTED_SUBJECT_DN = "CN=www.issuer.com,L=CGN,ST=NRW,C=DE,O=Issuer"; + private static final String EXPECTED_SERVICE_URI = "http://myservice.apache.org/MyServiceName"; + private static final String EXPECTED_DN_FOR_SERVICE = + "cn=http:\\/\\/myservice.apache.org\\/MyServiceName,ou=services"; + + @Test + public void testSaveUserCert() throws Exception { + IMocksControl c = EasyMock.createControl(); + LDAPSearch ldapSearch = c.createMock(LDAPSearch.class); + ldapSearch.bind(EasyMock.eq(EXPECTED_SUBJECT_DN + "," + ROOT_DN), EasyMock.anyObject(Attributes.class)); + EasyMock.expectLastCall().once(); + LdapRegisterHandler persistenceManager = new LdapRegisterHandler(ldapSearch, ROOT_DN); + X509Certificate cert = getTestCert(); + + c.replay(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.PKIX.getUri()); + key.setIdentifier(EXPECTED_SUBJECT_DN); + persistenceManager.saveCertificate(cert, key); + c.verify(); + } + + @Test + public void testSaveServiceCert() throws Exception { + IMocksControl c = EasyMock.createControl(); + LDAPSearch ldapSearch = c.createMock(LDAPSearch.class); + ldapSearch.bind(EasyMock.eq(EXPECTED_DN_FOR_SERVICE + "," + ROOT_DN), EasyMock.anyObject(Attributes.class)); + EasyMock.expectLastCall().once(); + LdapRegisterHandler persistenceManager = new LdapRegisterHandler(ldapSearch, ROOT_DN); + X509Certificate cert = getTestCert(); + + c.replay(); + UseKeyWithType key = new UseKeyWithType(); + key.setApplication(Applications.SERVICE_SOAP.getUri()); + key.setIdentifier(EXPECTED_SERVICE_URI); + persistenceManager.saveCertificate(cert, key); + c.verify(); + } + + private X509Certificate getTestCert() throws FileNotFoundException, CertificateException { + File certFile = new File("src/test/resources/cert1.cer"); + Assert.assertTrue(certFile.exists()); + FileInputStream fis = new FileInputStream(certFile); + CertificateFactory factory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) factory.generateCertificate(fis); + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPSearchTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPSearchTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPSearchTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/ldap/persistence/LDAPSearchTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,50 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.ldap.persistence; + +import java.net.URISyntaxException; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.SearchResult; + +import org.apache.cxf.xkms.x509.handlers.LDAPSearch; +import org.junit.Ignore; +import org.junit.Test; + +/** + * Tests need a real ldap server + */ +public class LDAPSearchTest { + @Test + @Ignore + public void testSearch() throws URISyntaxException, NamingException { + LDAPSearch ldapSearch = new LDAPSearch("ldap://localhost:2389", "cn=Directory Manager", "test", 2); + NamingEnumeration answer = ldapSearch.searchSubTree("dc=example, dc=com", "(cn=Testuser)"); + while (answer.hasMore()) { + SearchResult sr = answer.next(); + Attributes attrs = sr.getAttributes(); + Attribute cn = attrs.get("sn"); + System.out.println(cn.get()); + } + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/BasicValidationTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/BasicValidationTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/BasicValidationTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/BasicValidationTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.handlers; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.junit.Before; + +public class BasicValidationTest { + protected JAXBContext jc; + protected Unmarshaller u; + + + @Before + public void setUp() throws JAXBException { + jc = JAXBContext.newInstance("org.apache.cxf.xkms.model.xkms"); + u = jc.createUnmarshaller(); + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/ValidateDateHandlerTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/ValidateDateHandlerTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/ValidateDateHandlerTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/handlers/ValidateDateHandlerTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,62 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.xkms.x509.handlers; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; + +import org.apache.cxf.xkms.model.xkms.KeyBindingEnum; +import org.apache.cxf.xkms.model.xkms.ReasonEnum; +import org.apache.cxf.xkms.model.xkms.StatusType; +import org.apache.cxf.xkms.model.xkms.ValidateRequestType; +import org.apache.cxf.xkms.x509.validator.DateValidator; + +import org.junit.Assert; +import org.junit.Test; + +public class ValidateDateHandlerTest extends BasicValidationTest { + + @Test + public void validateDateOK() throws JAXBException { + StatusType result = processRequest("/validateRequestOK.xml"); + Assert.assertEquals(KeyBindingEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALID, result.getStatusValue()); + Assert.assertFalse(result.getValidReason().isEmpty()); + Assert.assertEquals(ReasonEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALIDITY_INTERVAL.value(), result.getValidReason() + .get(0)); + } + + @Test + public void validateDateExpired() throws JAXBException { + StatusType result = processRequest("/validateRequestExpired.xml"); + Assert.assertEquals(result.getStatusValue(), KeyBindingEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_INVALID); + Assert.assertFalse(result.getInvalidReason().isEmpty()); + Assert.assertEquals(ReasonEnum.HTTP_WWW_W_3_ORG_2002_03_XKMS_VALIDITY_INTERVAL.value(), result + .getInvalidReason().get(0)); + } + + private StatusType processRequest(String path) throws JAXBException { + @SuppressWarnings("unchecked") + JAXBElement request = (JAXBElement) u.unmarshal(this.getClass() + .getResourceAsStream(path)); + DateValidator validator = new DateValidator(); + return validator.validate(request.getValue()); + + } + +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/utils/X509UtilsTest.java URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/utils/X509UtilsTest.java?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/utils/X509UtilsTest.java (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/java/org/apache/cxf/xkms/x509/utils/X509UtilsTest.java Sat May 18 16:04:37 2013 @@ -0,0 +1,55 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.xkms.x509.utils; + +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; + +import org.apache.cxf.xkms.exception.XKMSRequestException; +import org.apache.cxf.xkms.model.xkms.ValidateRequestType; +import org.apache.cxf.xkms.x509.handlers.BasicValidationTest; +import org.apache.cxf.xkms.x509.parser.ValidateRequestParser; + +import org.junit.Assert; +import org.junit.Test; + +public class X509UtilsTest extends BasicValidationTest { + private static final String CERT_DN = "CN=www.anothersts.com, L=CGN, ST=NRW, C=DE, O=AnotherSTS"; + + public void extractValidatingCertsOK() throws JAXBException { + @SuppressWarnings("unchecked") + JAXBElement request = (JAXBElement)u.unmarshal(this.getClass() + .getResourceAsStream("/validateRequestOK.xml")); + List certs = ValidateRequestParser.parse(request.getValue()); + Assert.assertEquals("Exactly one certificate should be found", 1, certs.size()); + Assert.assertEquals("Unexcpected certificate DN", CERT_DN, certs.get(0).getSubjectDN().getName()); + } + + @Test(expected = XKMSRequestException.class) + public void extractValidatingCertsCorrupted() throws JAXBException { + @SuppressWarnings("unchecked") + JAXBElement request = (JAXBElement)u.unmarshal(this.getClass() + .getResourceAsStream("/validateRequestCorrupted.xml")); + ValidateRequestParser.parse(request.getValue()); + } +} Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.bas64 URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.bas64?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.bas64 (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.bas64 Sat May 18 16:04:37 2013 @@ -0,0 +1,2 @@ +MIIF4DCCA8igAwIBAgIJAKI2DZw3MLqRMA0GCSqGSIb3DQEBBQUAMFMxDzANBgNVBAoTBklzc3VlcjELMAkGA1UEBhMCREUxDDAKBgNVBAgTA05SVzEMMAoGA1UEBxMDQ0dOMRcwFQYDVQQDEw53d3cuaXNzdWVyLmNvbTAeFw0xMjAyMjkxMDIzMDFaFw0xMzAyMjgxMDIzMDFaMFMxDzANBgNVBAoTBklzc3VlcjELMAkGA1UEBhMCREUxDDAKBgNVBAgTA05SVzEMMAoGA1UEBxMDQ0dOMRcwFQYDVQQDEw53d3cuaXNzdWVyLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMSCbQd/92wAJnfaFZTRmEP0afGGS0lGJghLg3uoMpewcQj4A2RZVJl2sfFbk/OppUqtJYxLKv0LRkx9MsZ2rQOq1YfmHShxpb6PeyRx8dEgSCtgWivVzKk/w+UudilQVC3cTNWtCayjajHcc0UAG4Kaaypl5CNEWH0M4JapcjFCwU3t7INI/DcAZK2J0aZI0pevw977nEzHyHOeea3O0RFrTTQomt/fv4gtP08F4x13cK0ssD93YZwhzFQ/63E/P0UM6daKJG8Ysg9owjwuSGR6bDR/FNuDeH4hqq0QGuvFHANpVTakvE5d+WWw1BDIZ8RK2vf3yFs+/jazTUhUJvoiniqtTf6VnMUmI7n5mDFQbutiIOeFzK4bQ+KKYch/aO2Pc6dXoEYmCfgA/SdcoOhEfGJKqU8mvPU/bXJEDVj1VgFzRssnaZcmReXfrcFuxW9fkVMEQ4jXlUF6v63uwqpdMWqgBGlti5hHjOuE/MOYpmBv6mUNX0MxqtgRU7/8fUoR6HwgAlRBOoWGCHIzv/0V6fSm804OiUf+DY65dbpZRhZmd7yANYYoewSwrNokDXGlz6e5cPaXMUnakIgcj2crr+dqQpxkrpTgP5ihq8Jrw8GHY Zwm0SE4dqhA/DcyL6UlJarZSk7U3XEGvs60p0YThEgbpHCkgyruxocyQ4z3AgMBAAGjgbYwgbMwHQYDVR0OBBYEFCN8oLmMeAxU7v5mcE6U2bDmP63cMIGDBgNVHSMEfDB6gBQjfKC5jHgMVO7+ZnBOlNmw5j+t3KFXpFUwUzEPMA0GA1UEChMGSXNzdWVyMQswCQYDVQQGEwJERTEMMAoGA1UECBMDTlJXMQwwCgYDVQQHEwNDR04xFzAVBgNVBAMTDnd3dy5pc3N1ZXIuY29tggkAojYNnDcwupEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAPDAcr3TdfLlczzkBR6iiN63ERK/FnIcB8vIJdxJeYsq/w49CgxMjOugGsZ7rKTmT89zPQzVe/GJITRHNS1q81cf8hd4SWZ/i3z7k8tqhMRq0b31aQqkLzjPWD6PAwzDWUAY8HMMq9Gbxx52u4yXxx1PabTxq/0EDtX7+JfZ462BGtWCcUrrXq6Wck4acvAw2NmMfUR+RYLVKLINen82KD1YAl+mOKFfc3r9i1mLi/ylE2LuKN6Z3LnYAcaUgq22mRKR6hGXyw4zU2HzFNlgBnoJottYdZWxa5Chcr6wMgZS/rg3gQ8z6ALOFG/UTBxcXRmI0CCBhTPjn4Dq8gd+BWixBzFVF8DoYEyVEX7fGNOAwb3OZCQMVsaM6PuqIfiz0s5oiqdohYSzwXc6ajmQB7JJkfHE8B43dnL+G1+d2mqvhXhTeJNlwC0Hcqtc7MY2rRDY0Kj0LrGqjhN6kKiXHXA0YqVpn1W7qsu+GS51jxpxZ2DUELNuIhXU/xbP3IS/BKMgiwNM2kZBtP0qkfKlsO9IemiQTNGZzxm+DJvE5U4wC0cVxsvqRTqdfKumaIMoUHsIrC5OWibTZ658KFuZZGHtxolH1sZnSPjs9D9RC9xDv5OyIHcHcMhN6c7wk2Tf3GpY91r6Sp6 TxIkB2cZQDT8eTSS/PTHC+muh5/365lRE= + Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.cer URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.cer?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.cer (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/cert1.cer Sat May 18 16:04:37 2013 @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIF4DCCA8igAwIBAgIJAKI2DZw3MLqRMA0GCSqGSIb3DQEBBQUAMFMxDzANBgNVBAoTBklzc3Vl +cjELMAkGA1UEBhMCREUxDDAKBgNVBAgTA05SVzEMMAoGA1UEBxMDQ0dOMRcwFQYDVQQDEw53d3cu +aXNzdWVyLmNvbTAeFw0xMjAyMjkxMDIzMDFaFw0xMzAyMjgxMDIzMDFaMFMxDzANBgNVBAoTBklz +c3VlcjELMAkGA1UEBhMCREUxDDAKBgNVBAgTA05SVzEMMAoGA1UEBxMDQ0dOMRcwFQYDVQQDEw53 +d3cuaXNzdWVyLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMSCbQd/92wAJnfa +FZTRmEP0afGGS0lGJghLg3uoMpewcQj4A2RZVJl2sfFbk/OppUqtJYxLKv0LRkx9MsZ2rQOq1Yfm +HShxpb6PeyRx8dEgSCtgWivVzKk/w+UudilQVC3cTNWtCayjajHcc0UAG4Kaaypl5CNEWH0M4Jap +cjFCwU3t7INI/DcAZK2J0aZI0pevw977nEzHyHOeea3O0RFrTTQomt/fv4gtP08F4x13cK0ssD93 +YZwhzFQ/63E/P0UM6daKJG8Ysg9owjwuSGR6bDR/FNuDeH4hqq0QGuvFHANpVTakvE5d+WWw1BDI +Z8RK2vf3yFs+/jazTUhUJvoiniqtTf6VnMUmI7n5mDFQbutiIOeFzK4bQ+KKYch/aO2Pc6dXoEYm +CfgA/SdcoOhEfGJKqU8mvPU/bXJEDVj1VgFzRssnaZcmReXfrcFuxW9fkVMEQ4jXlUF6v63uwqpd +MWqgBGlti5hHjOuE/MOYpmBv6mUNX0MxqtgRU7/8fUoR6HwgAlRBOoWGCHIzv/0V6fSm804OiUf+ +DY65dbpZRhZmd7yANYYoewSwrNokDXGlz6e5cPaXMUnakIgcj2crr+dqQpxkrpTgP5ihq8Jrw8GH +YZwm0SE4dqhA/DcyL6UlJarZSk7U3XEGvs60p0YThEgbpHCkgyruxocyQ4z3AgMBAAGjgbYwgbMw +HQYDVR0OBBYEFCN8oLmMeAxU7v5mcE6U2bDmP63cMIGDBgNVHSMEfDB6gBQjfKC5jHgMVO7+ZnBO +lNmw5j+t3KFXpFUwUzEPMA0GA1UEChMGSXNzdWVyMQswCQYDVQQGEwJERTEMMAoGA1UECBMDTlJX +MQwwCgYDVQQHEwNDR04xFzAVBgNVBAMTDnd3dy5pc3N1ZXIuY29tggkAojYNnDcwupEwDAYDVR0T +BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAPDAcr3TdfLlczzkBR6iiN63ERK/FnIcB8vIJdxJe +Ysq/w49CgxMjOugGsZ7rKTmT89zPQzVe/GJITRHNS1q81cf8hd4SWZ/i3z7k8tqhMRq0b31aQqkL +zjPWD6PAwzDWUAY8HMMq9Gbxx52u4yXxx1PabTxq/0EDtX7+JfZ462BGtWCcUrrXq6Wck4acvAw2 +NmMfUR+RYLVKLINen82KD1YAl+mOKFfc3r9i1mLi/ylE2LuKN6Z3LnYAcaUgq22mRKR6hGXyw4zU +2HzFNlgBnoJottYdZWxa5Chcr6wMgZS/rg3gQ8z6ALOFG/UTBxcXRmI0CCBhTPjn4Dq8gd+BWixB +zFVF8DoYEyVEX7fGNOAwb3OZCQMVsaM6PuqIfiz0s5oiqdohYSzwXc6ajmQB7JJkfHE8B43dnL+G +1+d2mqvhXhTeJNlwC0Hcqtc7MY2rRDY0Kj0LrGqjhN6kKiXHXA0YqVpn1W7qsu+GS51jxpxZ2DUE +LNuIhXU/xbP3IS/BKMgiwNM2kZBtP0qkfKlsO9IemiQTNGZzxm+DJvE5U4wC0cVxsvqRTqdfKuma +IMoUHsIrC5OWibTZ658KFuZZGHtxolH1sZnSPjs9D9RC9xDv5OyIHcHcMhN6c7wk2Tf3GpY91r6S +p6TxIkB2cZQDT8eTSS/PTHC+muh5/365lRE= +-----END CERTIFICATE----- Added: cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/registerRequest.xml URL: http://svn.apache.org/viewvc/cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/registerRequest.xml?rev=1484133&view=auto ============================================================================== --- cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/registerRequest.xml (added) +++ cxf/trunk/services/xkms/xkms-x509-handlers/src/test/resources/registerRequest.xml Sat May 18 16:04:37 2013 @@ -0,0 +1,76 @@ + + + http://www.w3.org/2002/03/xkms#X509Cert + http://www.w3.org/2002/03/xkms#X509Chain + + + + + + 0nIsmR+aVW2egl5MIfOKy4HuMKkk9AZ/IQuDLVPlhzOfgngjVQCjr8uvmnqtNu8 + HBupui8LgGthO6U9D0CNT5mbmhIAErRADUMIAFsi7LzBarUvNWTqYNEJmcHsAUZ + drdcDrkNnG7SzbuJx+GDNiHKVDQggPBLc1XagW20RMvok= + + AQAB + + + + http://www.w3.org/2002/03/xkms#Signature + http://www.w3.org/2002/03/xkms#Encryption + http://www.w3.org/2002/03/xkms#Exchange + + + + + 5AEAai06hFJEkuqyDyqNh8k/u3M= + + + + + + + + + + + + + + WCbpkifxJ1zIJ+V6/knZgxRhR34= + + + iJSKM+98hj5ae+btC2WjwBYP+/k= + + + + + + + + + + + + + + WCbpkifxJ1zIJ+V6/knZgxRhR34= + + + + DcPw742vN120QNrCjCKw0jiCX3pUvbMeRkYjktZkn4nbgo1b7leXU0sJgXM2CY/ + oQugaRsgz18+qUzM0UX+jr1t1wtCMci5fjzVKZB63oZyKZ9+CJLcBCbirsgJAId + +Pq9w4WiwKDf2AytsdXHlN5V1byQIkpfR1CypvBzQa1b4= + + + +