Package org.apache.cxf.xkms.x509.repo.file

Source Code of org.apache.cxf.xkms.x509.repo.file.FileCertificateRepo

/**
* 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.repo.file;

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.net.URISyntaxException;
import java.security.cert.CRLException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.cxf.xkms.exception.XKMSConfigurationException;
import org.apache.cxf.xkms.handlers.Applications;
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.x509.repo.CertificateRepo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileCertificateRepo implements CertificateRepo {
    private static final Logger LOG = LoggerFactory.getLogger(FileCertificateRepo.class);
    private static final String CN_PREFIX = "cn=";
    private static final String TRUSTED_CAS_PATH = "trusted_cas";
    private static final String CRLS_PATH = "crls";
    private static final String CAS_PATH = "cas";
    private final File storageDir;
    private final CertificateFactory certFactory;

    public FileCertificateRepo(String path) {
        storageDir = new File(path);
        try {
            this.certFactory = CertificateFactory.getInstance("X.509");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    public void saveCertificate(X509Certificate cert, UseKeyWithType id) {
        saveCategorizedCertificate(cert, id, false, false);
    }

    public void saveTrustedCACertificate(X509Certificate cert, UseKeyWithType id) {
        saveCategorizedCertificate(cert, id, true, false);
    }

    public void saveCACertificate(X509Certificate cert, UseKeyWithType id) {
        saveCategorizedCertificate(cert, id, false, true);
    }
   
    public void saveCRL(X509CRL crl, UseKeyWithType id) {
        String name = crl.getIssuerX500Principal().getName();
        try {
            String path = convertIdForFileSystem(name) + ".cer";
            Pattern p = Pattern.compile("[a-zA-Z_0-9-_]");
            if (!p.matcher(path).find()) {
                throw new URISyntaxException(path, "Input did not match [a-zA-Z_0-9-_].");
            }
           
            File certFile = new File(storageDir + "/" + CRLS_PATH, path);
            certFile.getParentFile().mkdirs();
            FileOutputStream fos = new FileOutputStream(certFile);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bos.write(crl.getEncoded());
            bos.close();
            fos.close();
        } catch (Exception e) {
            throw new RuntimeException("Error saving CRL " + name + ": " + e.getMessage(), e);
        }
    }

    private boolean saveCategorizedCertificate(X509Certificate cert, UseKeyWithType id, boolean isTrustedCA,
                                               boolean isCA) {
        String category = "";
        if (isTrustedCA) {
            category = TRUSTED_CAS_PATH;
        }
        if (isCA) {
            category = CAS_PATH;
        }
        try {
            File certFile = new File(storageDir + "/" + category,
                                     getCertPath(cert, id));
            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 " + cert.getSubjectDN() + ": " + e.getMessage(), e);
        }
        return true;
    }

    public String convertIdForFileSystem(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 getCertPath(X509Certificate cert, UseKeyWithType id)
        throws URISyntaxException {
        Applications application = null;
        String path = null;
        if (id != null) {
            application = Applications.fromUri(id.getApplication());
        }
        if (application == Applications.SERVICE_ENDPOINT) {
            path = id.getIdentifier();
        } else {
            path = cert.getSubjectDN().getName();
        }
        path = convertIdForFileSystem(path) + ".cer";
        validateCertificatePath(path);
        return path;
    }

    private void validateCertificatePath(String path) throws URISyntaxException {
        Pattern p = Pattern.compile("[a-zA-Z_0-9-_]");
        if (!p.matcher(path).find()) {
            throw new URISyntaxException(path, "Input did not match [a-zA-Z_0-9-_].");
        }
    }

    private File[] getX509Files() {
        List<File> certificateFiles = new ArrayList<File>();
        try {
            certificateFiles.addAll(Arrays.asList(storageDir.listFiles()));
            certificateFiles.addAll(Arrays.asList(new File(storageDir + "/" + TRUSTED_CAS_PATH).listFiles()));
            certificateFiles.addAll(Arrays.asList(new File(storageDir + "/" + CAS_PATH).listFiles()));
            certificateFiles.addAll(Arrays.asList(new File(storageDir + "/" + CRLS_PATH).listFiles()));
        } catch (NullPointerException e) {
            //
        }
        if (certificateFiles.isEmpty()) {
            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 certificateFiles.toArray(new File[certificateFiles.size()]);
    }

    public X509Certificate readCertificate(File certFile) throws CertificateException, FileNotFoundException {
        FileInputStream fis = new FileInputStream(certFile);
        return (X509Certificate)certFactory.generateCertificate(fis);
    }
   
    public X509CRL readCRL(File crlFile) throws FileNotFoundException, CRLException {
        FileInputStream fis = new FileInputStream(crlFile);
        return (X509CRL)certFactory.generateCRL(fis);
    }

    @Override
    public List<X509Certificate> getTrustedCaCerts() {
        List<X509Certificate> results = new ArrayList<X509Certificate>();
        File[] list = getX509Files();
        for (File certFile : list) {
            try {
                if (certFile.isDirectory()) {
                    continue;
                }
                if (certFile.getParent().endsWith(TRUSTED_CAS_PATH)) {
                    X509Certificate cert = readCertificate(certFile);
                    results.add(cert);
                }
            } catch (Exception e) {
                LOG.warn(String.format("Cannot load certificate from file: %s. Error: %s", certFile,
                                       e.getMessage()));
            }

        }
        return results;
    }

    @Override
    public List<X509Certificate> getCaCerts() {
        List<X509Certificate> results = new ArrayList<X509Certificate>();
        File[] list = getX509Files();
        for (File certFile : list) {
            try {
                if (certFile.isDirectory()) {
                    continue;
                }
                if (certFile.getParent().endsWith(CAS_PATH)) {
                    X509Certificate cert = readCertificate(certFile);
                    results.add(cert);
                }
            } catch (Exception e) {
                LOG.warn(String.format("Cannot load certificate from file: %s. Error: %s", certFile,
                                       e.getMessage()));
            }

        }
        return results;
    }
   
    @Override
    public List<X509CRL> getCRLs() {
        List<X509CRL> results = new ArrayList<X509CRL>();
        File[] list = getX509Files();
        for (File crlFile : list) {
            try {
                if (crlFile.isDirectory()) {
                    continue;
                }
                if (crlFile.getParent().endsWith(CRLS_PATH)) {
                    X509CRL crl = readCRL(crlFile);
                    results.add(crl);
                }
            } catch (Exception e) {
                LOG.warn(String.format("Cannot load CRL from file: %s. Error: %s", crlFile,
                                       e.getMessage()));
            }

        }
       
        return results;
    }

    @Override
    public X509Certificate findByServiceName(String serviceName) {
        return findBySubjectDn(CN_PREFIX + serviceName);
    }

    @Override
    public X509Certificate findByEndpoint(String endpoint) {
        try {
            String path = convertIdForFileSystem(endpoint) + ".cer";
            validateCertificatePath(path);
            File certFile = new File(storageDir.getAbsolutePath() + "/" + path);
            if (!certFile.exists()) {
                LOG.warn(String.format("Certificate not found for endpoint %s, path %s", endpoint,
                                       certFile.getAbsolutePath()));
                return null;
            }
            return (X509Certificate)certFactory.generateCertificate(new FileInputStream(certFile));
        } catch (Exception e) {
            LOG.warn(String.format("Cannot load certificate by endpoint: %s. Error: %s", endpoint,
                                   e.getMessage()), e);
            return null;
        }
    }

    @Override
    public X509Certificate findBySubjectDn(String subjectDn) {
        List<X509Certificate> result = new ArrayList<X509Certificate>();
        File[] list = getX509Files();
        for (File certFile : list) {
            try {
                if (certFile.isDirectory()) {
                    continue;
                }
                X509Certificate cert = readCertificate(certFile);
                LOG.debug("Searching for " + subjectDn + ". Checking cert "
                    + cert.getSubjectDN().getName() + ", " + cert.getSubjectX500Principal().getName());
                if (subjectDn.equalsIgnoreCase(cert.getSubjectDN().getName())
                    || subjectDn.equalsIgnoreCase(cert.getSubjectX500Principal().getName())) {
                    result.add(cert);
                }
            } catch (Exception e) {
                LOG.warn(String.format("Cannot load certificate from file: %s. Error: %s", certFile,
                                       e.getMessage()));
            }

        }
        if (!result.isEmpty()) {
            return result.get(0);
        }
        return null;
    }

    @Override
    public X509Certificate findByIssuerSerial(String issuer, String serial) {
        List<X509Certificate> result = new ArrayList<X509Certificate>();
        File[] list = getX509Files();
        for (File certFile : list) {
            try {
                if (certFile.isDirectory()) {
                    continue;
                }
                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) {
                LOG.warn(String.format("Cannot load certificate from file: %s. Error: %s", certFile,
                                       e.getMessage()));
            }

        }
        if (!result.isEmpty()) {
            return result.get(0);
        }
        return null;
    }

}
TOP

Related Classes of org.apache.cxf.xkms.x509.repo.file.FileCertificateRepo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.