org.sipfoundry.sipxconfig.cert.CertificateManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.sipfoundry.sipxconfig.cert.CertificateManagerImpl.java

Source

/*
 *
 *
 * Copyright (C) 2008 Pingtel Corp., certain elements licensed under a Contributor Agreement.
 * Contributors retain copyright to elements licensed under a Contributor Agreement.
 * Licensed to the User under the LGPL license.
 *
 * $
 */
package org.sipfoundry.sipxconfig.cert;

import static java.lang.String.format;

import java.io.IOException;
import java.io.InputStream;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sipfoundry.sipxconfig.cfgmgt.ConfigManager;
import org.sipfoundry.sipxconfig.common.DaoUtils;
import org.sipfoundry.sipxconfig.common.SipxHibernateDaoSupport;
import org.sipfoundry.sipxconfig.common.UserException;
import org.sipfoundry.sipxconfig.commserver.LocationsManager;
import org.sipfoundry.sipxconfig.domain.Domain;
import org.sipfoundry.sipxconfig.setting.BeanWithSettingsDao;
import org.sipfoundry.sipxconfig.setup.SetupListener;
import org.sipfoundry.sipxconfig.setup.SetupManager;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Certificate Management Implementation.
 */
public class CertificateManagerImpl extends SipxHibernateDaoSupport implements CertificateManager, SetupListener {
    private static final Log LOG = LogFactory.getLog(CertificateManager.class);
    private static final String AUTHORITY_TABLE = "authority";
    private static final String CERT_TABLE = "cert";
    private static final String CERT_COLUMN = "data";
    private static final String KEY_COLUMN = "private_key";
    private static final String SELF_SIGN_AUTHORITY_PREFIX = "ca.";
    private BeanWithSettingsDao<CertificateSettings> m_settingsDao;
    private LocationsManager m_locationsManager;
    private JdbcTemplate m_jdbc;
    private ConfigManager m_configManager;
    private List<String> m_thirdPartyAuthorites;

    public CertificateSettings getSettings() {
        return m_settingsDao.findOrCreateOne();
    }

    public void saveSettings(CertificateSettings settings) {
        m_settingsDao.upsert(settings);
    }

    @Override
    public void setWebCertificate(String cert) {
        setWebCertificate(cert, null);
    }

    @Override
    public void setWebCertificate(String cert, String key) {
        validateCert(cert, key);
        updateCertificate(WEB_CERT, cert, key, getSelfSigningAuthority());
    }

    @Override
    public String getNamedPrivateKey(String id) {
        return getSecurityData(CERT_TABLE, KEY_COLUMN, id);
    }

    @Override
    public String getNamedCertificate(String id) {
        return getSecurityData(CERT_TABLE, CERT_COLUMN, id);
    }

    @Override
    public void setCommunicationsCertificate(String cert) {
        setCommunicationsCertificate(cert, null);
    }

    public void setCommunicationsCertificate(String cert, String key) {
        validateCert(cert, key);
        updateCertificate(COMM_CERT, cert, key, getSelfSigningAuthority());
    }

    @Override
    public String getChainCertificate() {
        return getSecurityData(CERT_TABLE, CERT_COLUMN, CHAIN_CERT);
    }

    @Override
    public void setChainCertificate(String cert) {
        validateCert(cert, null);
        updateCertificate(CHAIN_CERT, cert, null, null);
    }

    @Override
    public String getCACertificate() {
        return getSecurityData(CERT_TABLE, CERT_COLUMN, CA_CERT);
    }

    @Override
    public void setCACertificate(String cert) {
        validateCert(cert, null);
        updateCertificate(CA_CERT, cert, null, null);
    }

    void updateCertificate(String name, String cert, String key, String authority) {
        updateNamedCertificate(name, cert, key, authority);
        m_configManager.configureEverywhere(FEATURE);
    }

    @Override
    public void updateNamedCertificate(String name, String cert, String key, String authority) {
        m_jdbc.update("delete from cert where name = ?", name);
        m_jdbc.update("insert into cert (name, data, private_key, authority) values (?, ?, ?, ?)", name, cert, key,
                authority);
    }

    void addThirdPartyAuthority(String name, String data) {
        addAuthority(name, data, null);
    }

    void addAuthority(String name, String data, String key) {
        m_jdbc.update("delete from authority where name = ? ", name);
        m_jdbc.update("delete from cert where authority = ? ", name); // should be zero
        m_jdbc.update("insert into authority (name, data, private_key) values (?, ?, ?)", name, data, key);
        m_configManager.configureEverywhere(FEATURE);
    }

    String getSecurityData(String table, String column, String name) {
        String sql = format("select %s from %s where name = ?", column, table);
        return DaoUtils.requireOneOrZero(m_jdbc.queryForList(sql, String.class, name), sql);
    }

    @Override
    public String getWebCertificate() {
        return getSecurityData(CERT_TABLE, CERT_COLUMN, WEB_CERT);
    }

    @Override
    public String getWebPrivateKey() {
        return getSecurityData(CERT_TABLE, KEY_COLUMN, WEB_CERT);
    }

    @Override
    public String getCommunicationsCertificate() {
        return getSecurityData(CERT_TABLE, CERT_COLUMN, COMM_CERT);
    }

    @Override
    public String getCommunicationsPrivateKey() {
        return getSecurityData(CERT_TABLE, KEY_COLUMN, COMM_CERT);
    }

    @Override
    public List<String> getThirdPartyAuthorities() {
        List<String> authorities = m_jdbc.queryForList("select name from authority where name != ? order by name",
                String.class, getSelfSigningAuthority());
        return authorities;
    }

    @Override
    public List<String> getAuthorities() {
        List<String> authorities = m_jdbc.queryForList("select name from authority order by name", String.class);
        return authorities;
    }

    @Override
    public String getAuthorityCertificate(String authority) {
        return getSecurityData(AUTHORITY_TABLE, CERT_COLUMN, authority);
    }

    @Override
    public String getAuthorityKey(String authority) {
        return getSecurityData(AUTHORITY_TABLE, KEY_COLUMN, authority);
    }

    @Override
    public String getSelfSigningAuthority() {
        String domain = Domain.getDomain().getName();
        return SELF_SIGN_AUTHORITY_PREFIX + domain;
    }

    @Override
    public String getSelfSigningAuthorityText() {
        return getAuthorityCertificate(getSelfSigningAuthority());
    }

    @Override
    public void addTrustedAuthority(String authority, String cert) {
        validateAuthority(cert);
        addAuthority(authority, cert, null);
    }

    @Override
    public void rebuildSelfSignedData() {
        forceDeleteTrustedAuthority(getSelfSigningAuthority());
        checkSetup();
    }

    @Override
    public void rebuildCommunicationsCert() {
        rebuildCert(COMM_CERT);
    }

    @Override
    public void rebuildWebCert() {
        rebuildCert(WEB_CERT);
    }

    void rebuildCert(String type) {
        String domain = Domain.getDomain().getName();
        String fqdn = m_locationsManager.getPrimaryLocation().getFqdn();
        String authority = getSelfSigningAuthority();
        String issuer = getIssuer(authority);
        String authKey = getAuthorityKey(authority);
        CertificateGenerator gen;
        if (type.equals(COMM_CERT)) {
            gen = CertificateGenerator.sip(domain, fqdn, issuer, authKey);
        } else {
            gen = CertificateGenerator.web(domain, fqdn, issuer, authKey);
        }
        updateCertificate(type, gen.getCertificateText(), gen.getPrivateKeyText(), authority);
    }

    @Override
    public void deleteTrustedAuthority(String authority) {
        if (authority.equals(getSelfSigningAuthority())) {
            throw new UserException("Cannot delete self signing certificate authority");
        }

        forceDeleteTrustedAuthority(authority);
    }

    void forceDeleteTrustedAuthority(String authority) {
        m_jdbc.update("delete from authority where name = ?", authority);
        m_jdbc.update("delete from cert where authority = ?", authority);
        m_configManager.configureEverywhere(FEATURE);
    }

    void checkSetup() {
        String domain = Domain.getDomain().getName();
        String authority = getSelfSigningAuthority();
        String authorityCertificate = getAuthorityCertificate(authority);
        if (authorityCertificate == null) {
            CertificateAuthorityGenerator gen = new CertificateAuthorityGenerator(domain);
            addAuthority(authority, gen.getCertificateText(), gen.getPrivateKeyText());
        }
        for (String thirdPartAuth : m_thirdPartyAuthorites) {
            if (getAuthorityCertificate(thirdPartAuth) == null) {
                try {
                    InputStream thirdPartIn = getClass().getResourceAsStream(thirdPartAuth);
                    if (thirdPartIn == null) {
                        throw new IOException("Missing resource " + thirdPartAuth);
                    }
                    String thirdPartCert = IOUtils.toString(thirdPartIn);
                    String thirdPartAuthId = CertificateUtils.stripPath(thirdPartAuth);
                    addThirdPartyAuthority(thirdPartAuthId, thirdPartCert);
                } catch (IOException e) {
                    LOG.error("Cannot import authority " + thirdPartAuth, e);
                }
            }
        }

        String fqdn = m_locationsManager.getPrimaryLocation().getFqdn();
        String issuer = getIssuer(authority);
        String authKey = getAuthorityKey(authority);
        if (!hasCertificate(COMM_CERT, authority)) {
            CertificateGenerator gen = CertificateGenerator.sip(domain, fqdn, issuer, authKey);
            updateCertificate(COMM_CERT, gen.getCertificateText(), gen.getPrivateKeyText(), authority);
        }
        if (!hasCertificate(WEB_CERT, authority)) {
            CertificateGenerator gen = CertificateGenerator.web(domain, fqdn, issuer, authKey);
            updateCertificate(WEB_CERT, gen.getCertificateText(), gen.getPrivateKeyText(), authority);
        }
    }

    boolean hasCertificate(String id, String authority) {
        int check = m_jdbc.queryForInt("select count(*) from cert where name = ? and authority = ?", id, authority);
        return (check >= 1);
    }

    String getIssuer(String authority) {
        String authCertText = getSecurityData(AUTHORITY_TABLE, CERT_COLUMN, authority);
        X509Certificate authCert = CertificateUtils.readCertificate(authCertText);
        return authCert.getSubjectDN().getName();
    }

    void validateCert(String certTxt, String keyTxt) {
        X509Certificate cert = CertificateUtils.readCertificate(certTxt);
        try {
            cert.checkValidity();
        } catch (CertificateExpiredException e) {
            throw new UserException("Certificate has expired.");
        } catch (CertificateNotYetValidException e) {
            throw new UserException("Certificate valid date range is in the future, it is not yet valid.");
        }
        if (StringUtils.isNotBlank(keyTxt)) {
            CertificateUtils.readCertificateKey(keyTxt);
        }
        // to do, validate key w/cert and cert w/authorities
    }

    void validateAuthority(String cert) {
        validateCert(cert, null);
        // to do validate authority cert
    }

    @Override
    public boolean setup(SetupManager manager) {
        checkSetup();
        return true;
    }

    public void setJdbc(JdbcTemplate jdbc) {
        m_jdbc = jdbc;
    }

    public void setLocationsManager(LocationsManager locationsManager) {
        m_locationsManager = locationsManager;
    }

    public void setSettingsDao(BeanWithSettingsDao<CertificateSettings> settingsDao) {
        m_settingsDao = settingsDao;
    }

    public void setConfigManager(ConfigManager configManager) {
        m_configManager = configManager;
    }

    public void setThirdPartyAuthorites(List<String> thirdPartyAuthorites) {
        m_thirdPartyAuthorites = thirdPartyAuthorites;
    }
}