it.cnr.icar.eric.server.security.authentication.AuthenticationServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for it.cnr.icar.eric.server.security.authentication.AuthenticationServiceImpl.java

Source

/*
 * ====================================================================
 * This file is part of the ebXML Registry by Icar Cnr v3.2 
 * ("eRICv32" in the following disclaimer).
 *
 * "eRICv32" is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * "eRICv32" is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License Version 3
 * along with "eRICv32".  If not, see <http://www.gnu.org/licenses/>.
 *
 * eRICv32 is a forked, derivative work, based on:
 *    - freebXML Registry, a royalty-free, open source implementation of the ebXML Registry standard,
 *      which was published under the "freebxml License, Version 1.1";
 *   - ebXML OMAR v3.2 Edition, published under the GNU GPL v3 by S. Krushe & P. Arwanitis.
 * 
 * All derivative software changes and additions are made under
 *
 * Copyright (C) 2013 Ing. Antonio Messina <messina@pa.icar.cnr.it>
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the freebxml Software Foundation.  For more
 * information on the freebxml Software Foundation, please see
 * "http://www.freebxml.org/".
 *
 * This product includes software developed by the Apache Software
 * Foundation (http://www.apache.org/).
 *
 * ====================================================================
 */
package it.cnr.icar.eric.server.security.authentication;

import it.cnr.icar.eric.common.BindingUtility;
import it.cnr.icar.eric.common.CommonProperties;
import it.cnr.icar.eric.common.exceptions.UserNotFoundException;
import it.cnr.icar.eric.common.exceptions.UserRegistrationException;
import it.cnr.icar.eric.server.cache.ServerCache;
import it.cnr.icar.eric.server.common.RegistryProperties;
import it.cnr.icar.eric.server.common.ServerRequestContext;
import it.cnr.icar.eric.server.persistence.PersistenceManagerFactory;
import it.cnr.icar.eric.server.util.ServerResourceBundle;

import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.xml.registry.RegistryException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.oasis.ebxml.registry.bindings.rim.ClassificationType;
import org.oasis.ebxml.registry.bindings.rim.IdentifiableType;
import org.oasis.ebxml.registry.bindings.rim.UserType;

/**
 * Manages authentication functionality for the registry. This includes
 * management of user public keys in the server key store.
 * 
 * @author <a href="mailto:Farrukh.Najmi@Sun.COM">Farrukh S. Najmi</a>
 */
public class AuthenticationServiceImpl /* implements AuthenticationService */ {

    /* Aliases/ids for pre-defined Users. */
    public static final String ALIAS_REGISTRY_OPERATOR = "urn:freebxml:registry:predefinedusers:registryoperator";
    public static final String ALIAS_REGISTRY_GUEST = "urn:freebxml:registry:predefinedusers:registryguest";

    /* Aliases/ids for test Users */
    public static final String ALIAS_FARRUKH = "urn:freebxml:registry:predefinedusers:farrukh";
    public static final String ALIAS_NIKOLA = "urn:freebxml:registry:predefinedusers:nikola";

    it.cnr.icar.eric.server.persistence.PersistenceManager pm = PersistenceManagerFactory.getInstance()
            .getPersistenceManager();

    // Use pm not qm do avoid deadlock or inifinite loop with cache filling
    // QueryManager qm = QueryManagerFactory.getInstance().getQueryManager();

    /**
     * @link
     * @shapeType PatternLink
     * @pattern Singleton
     * @supplierRole Singleton factory
     */

    /* # private AuthenticationServiceImpl _authenticationServiceImpl; */
    private static AuthenticationServiceImpl instance = null;
    private static final Log log = LogFactory.getLog(AuthenticationServiceImpl.class);
    KeyStore keyStore = null;

    /*
     * A lock object to prevent another thread to access the keystore when there
     * is a thread adding certificate to it and writing it to disk
     */
    Object keyStoreWriteLock = new Object();
    KeyStore trustAnchorsKeyStore;
    public UserType registryGuest = null;
    public UserType registryOperator = null;
    public UserType farrukh = null;
    public UserType nikola = null;
    java.util.HashMap<PublicKey, X509Certificate> publicKeyToCertMap = new HashMap<PublicKey, X509Certificate>();
    java.util.HashSet<String> adminIdSet = new java.util.HashSet<String>();
    RegistryProperties propsReader = RegistryProperties.getInstance();

    protected AuthenticationServiceImpl() {
        try {
            loadPredefinedUsers();
            loadRegistryAdministrators();
            loadPublicKeyToCertMap();
        } catch (RegistryException e) {
            throw new java.lang.reflect.UndeclaredThrowableException(e);
        }
    }

    // Key is PublicKey, Value is X509Certificate
    private void loadPublicKeyToCertMap() throws RegistryException {
        try {
            KeyStore store = getKeyStore();

            for (Enumeration<String> e = store.aliases(); e.hasMoreElements();) {
                String alias = e.nextElement();
                X509Certificate cert = (X509Certificate) store.getCertificate(alias);
                PublicKey publicKey = cert.getPublicKey();
                publicKeyToCertMap.put(publicKey, cert);
            }
        } catch (KeyStoreException e) {
            throw new RegistryException(e);
        }

    }

    public KeyStore getTrustAnchorsKeyStore() throws RegistryException {
        try {
            if (trustAnchorsKeyStore == null) {
                synchronized (AuthenticationServiceImpl.class) {
                    if (trustAnchorsKeyStore == null) {
                        String keyStoreFile = propsReader.getProperty("eric.security.trustAnchors.keystoreFile");
                        String keystorePassword = propsReader
                                .getProperty("eric.security.trustAnchors.keystorePassword");
                        String keystoreType = propsReader.getProperty("eric.security.trustAnchors.keystoreType");
                        trustAnchorsKeyStore = KeyStore.getInstance(keystoreType);
                        trustAnchorsKeyStore.load(new java.io.FileInputStream(keyStoreFile),
                                keystorePassword.toCharArray());
                    }
                }
            }

            return trustAnchorsKeyStore;
        } catch (NoSuchAlgorithmException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.trustAnchorsKeystore"), e);
        } catch (KeyStoreException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.trustAnchorsKeystore"), e);
        } catch (java.security.cert.CertificateException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.trustAnchorsKeystore"), e);
        } catch (java.io.FileNotFoundException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.trustAnchorsKeystore"), e);
        } catch (IOException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.trustAnchorsKeystore"), e);
        }
    }

    /**
     * Get the keystore whose path is specified by
     * {@link #getKeyStoreFileName()}. Note that all the methods that access the
     * keystore MUST access the keystore via this method. Do not access the
     * keystore directly by accessing the keystore field. Otherwise the checking
     * the write lock to keystore will be bypassed.
     */
    public KeyStore getKeyStore() throws RegistryException {
        synchronized (keyStoreWriteLock) {
            if (keyStore == null) {
                java.io.FileInputStream fis = null;

                try {
                    String keystoreType = RegistryProperties.getInstance().getProperty("eric.security.keystoreType",
                            "JKS");
                    keyStore = KeyStore.getInstance(keystoreType);

                    String keystoreFile = getKeyStoreFileName();
                    fis = new java.io.FileInputStream(keystoreFile);

                    String keystorePass = getKeyStorePassword();
                    keyStore.load(fis, keystorePass.toCharArray());
                } catch (java.security.cert.CertificateException e) {
                    throw new RegistryException(e);
                } catch (KeyStoreException e) {
                    throw new RegistryException(e);
                } catch (NoSuchAlgorithmException e) {
                    throw new RegistryException(e);
                } catch (java.io.FileNotFoundException e) {
                    throw new RegistryException(e);
                } catch (IOException e) {
                    throw new RegistryException(e);
                } finally {
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

            return keyStore;
        }
    }

    public java.security.PrivateKey getPrivateKey(String alias, String password) throws RegistryException {
        java.security.PrivateKey privateKey = null;

        try {
            privateKey = (java.security.PrivateKey) getKeyStore().getKey(alias, password.toCharArray());
        } catch (KeyStoreException e) {
            throw new RegistryException(ServerResourceBundle.getInstance().getString("message.privateKey"), e);
        } catch (NoSuchAlgorithmException e) {
            throw new RegistryException(ServerResourceBundle.getInstance().getString("message.privateKey"), e);
        } catch (java.security.UnrecoverableKeyException e) {
            throw new RegistryException(ServerResourceBundle.getInstance().getString("message.privateKey"), e);
        }

        return privateKey;
    }

    public X509Certificate getCertificate(String alias) throws RegistryException {
        X509Certificate cert = null;

        try {
            cert = (X509Certificate) getKeyStore().getCertificate(alias);

            if (cert == null) {
                throw new RegistryException(ServerResourceBundle.getInstance()
                        .getString("message.certificateNotFound", new Object[] { alias }));
            }
        } catch (KeyStoreException e) {
            throw new RegistryException(ServerResourceBundle.getInstance().getString("message.gettingCertificate"),
                    e);
        }

        return cert;
    }

    public java.security.cert.Certificate[] getCertificateChain(String alias) throws RegistryException {
        try {
            return getKeyStore().getCertificateChain(alias);
        } catch (KeyStoreException e) {
            throw new RegistryException(
                    ServerResourceBundle.getInstance().getString("message.gettingCertificateChain"), e);
        }
    }

    public synchronized static AuthenticationServiceImpl getInstance() {
        if (instance == null) {
            instance = new it.cnr.icar.eric.server.security.authentication.AuthenticationServiceImpl();
        }

        return instance;
    }

    public String getKeyStoreFileName() throws RegistryException {
        String fileName = RegistryProperties.getInstance().getProperty("eric.security.keystoreFile");

        return fileName;
    }

    public String getKeyStorePassword() throws RegistryException {
        String pw = RegistryProperties.getInstance().getProperty("eric.security.keystorePassword");

        return pw;
    }

    /**
     * Check if the signatures CA is trusted by the registry.
     * 
     * @throws UserRegistrationException
     *             if the certificate issuing CA is not trusted.
     * @throws RegistryException
     *             if the certificates cannot be verified for some other
     *             reasons, such as unable to load trust anchors keystore
     */
    public void validateCertificate(X509Certificate cert) throws UserRegistrationException, RegistryException {
        // TODO:
    }

    /**
     * Gets the alias within the KeyStore for a User
     */
    public String getAliasFromUser(UserType user) throws RegistryException {
        return user.getId();
    }

    /**
     * Gets the alias within the KeyStore for a User
     */
    public X509Certificate getCertificateFromUser(UserType user) throws RegistryException {
        X509Certificate cert = null;

        try {
            String alias = getAliasFromUser(user);

            cert = (X509Certificate) (getKeyStore().getCertificate(alias));
        } catch (KeyStoreException e) {
            throw new RegistryException(e);
        }

        return cert;
    }

    /**
     * Gets the User that is associated with the given alias.
     * 
     * @throws UserNotFoundException
     *             when no matching User is found
     */
    public UserType getUserFromAlias(String alias) throws RegistryException {
        UserType user = null;

        ServerRequestContext context = null;
        try {
            context = new ServerRequestContext("AuthenticationServiceImpl.getUserFromAlias", null);
            context.setUser(this.registryOperator);
            String userId = alias;
            user = (UserType) ServerCache.getInstance().getRegistryObject(context, userId, "User");
            if (user == null) {
                throw new UserNotFoundException(userId);
            }

            // See if User need to be auto-classified as RegistryAdministrator
            boolean isAdmin = isRegistryAdministratorInPropFile(user);

            if (isAdmin) {
                // Make sure that the user is classified with the
                // RegistryAdministrator role
                makeRegistryAdministrator(context, user);
            }

            context.commit();
            context = null;
        } catch (RegistryException e) {
            throw e;
        } catch (Exception e) {
            throw new RegistryException(e);
        } finally {
            if (null != context) {
                // Oh no, it's still here...
                context.rollback();
            }
        }

        return user;
    }

    /**
     * See if User is declared as a RegistryAdministrator in prop file.
     */
    private boolean isRegistryAdministratorInPropFile(UserType user) throws RegistryException {
        boolean isAdmin = false;

        if (user != null) {
            String id = user.getId();

            if (adminIdSet.contains(id)) {
                isAdmin = true;
            }
        }

        return isAdmin;
    }

    /**
     * Determines if user has RegistryAdministrator role.
     * 
     * @return true if user has role Intermediary, otherwise return false
     * 
     */
    public boolean hasRegistryAdministratorRole(UserType user) throws RegistryException {
        return hasRole(user, BindingUtility.CANONICAL_SUBJECT_ROLE_ID_RegistryAdministrator);
    }

    /**
     * Determines if user has Intermediary role.
     * 
     * @return true if user has role Intermediary, otherwise return false
     * 
     */
    public boolean hasIntermediaryRole(UserType user) throws RegistryException {
        return hasRole(user, BindingUtility.CANONICAL_SUBJECT_ROLE_ID_Intermediary);
    }

    /**
     * Determines if specified user has the role specified by roleId.
     * 
     * @return true if user has role specified by roleId, otherwise return false
     * 
     */
    public boolean hasRole(UserType user, String roleId) throws RegistryException {
        boolean hasRole = false;

        List<ClassificationType> classifications = user.getClassification();
        Iterator<ClassificationType> iter = classifications.iterator();

        while (iter.hasNext()) {
            ClassificationType ebClassificationType = iter.next();
            String classificationNodeId = ebClassificationType.getClassificationNode();

            if (classificationNodeId.equals(roleId)) {
                hasRole = true;

                break;
            }
        }
        return hasRole;
    }

    /**
     * Make sure user gets auto-classified as RegistryAdministrator if not so
     * already.
     */
    private void makeRegistryAdministrator(ServerRequestContext context, UserType user) throws RegistryException {

        try {
            if (user != null) {
                boolean isAdmin = hasRegistryAdministratorRole(user);

                if (!isAdmin) {
                    /*
                     * ??? Need new message for this logging. // Log real
                     * changes to security realm -- new admins. if
                     * (log.isInfoEnabled()) {
                     * log.info(ServerResourceBundle.getInstance().
                     * getString("message.getRegistryAdministratorsAddingAdmin",
                     * new Object[]{user.getId()})); }
                     */
                    ClassificationType ebClassificationType = BindingUtility.getInstance().rimFac
                            .createClassificationType();
                    ebClassificationType.setId(it.cnr.icar.eric.common.Utility.getInstance().createId());
                    ebClassificationType
                            .setClassificationNode(BindingUtility.CANONICAL_SUBJECT_ROLE_ID_RegistryAdministrator);
                    ebClassificationType.setClassifiedObject(user.getId());
                    user.getClassification().add(ebClassificationType);

                    // Now persists updated User
                    java.util.List<IdentifiableType> al = new java.util.ArrayList<IdentifiableType>();
                    al.add(user);
                    pm.update(context, al);
                }
            }

            // ??? This method did not create this context, should it commit?
            context.commit();
            // A local signal to the finally block below.
            context = null;
        } catch (RegistryException e) {
            throw e;
        } catch (Exception e) {
            throw new RegistryException(e);
        } finally {
            if (null != context) {
                // Oh no, it's still here...
                context.rollback();
            }
        }
    }

    /*
     * Loads and caches the predefined users during startup.
     */
    private void loadPredefinedUsers() throws RegistryException {
        ServerRequestContext context = null;
        try {
            context = new ServerRequestContext("AuthenticationServiceImpl.loadPredefinedUsers", null);
            registryOperator = (UserType) pm.getRegistryObject(context, ALIAS_REGISTRY_OPERATOR, "User");
            registryGuest = (UserType) pm.getRegistryObject(context, ALIAS_REGISTRY_GUEST, "User");
            farrukh = (UserType) pm.getRegistryObject(context, ALIAS_FARRUKH, "User");
            nikola = (UserType) pm.getRegistryObject(context, ALIAS_NIKOLA, "User");
            if (registryOperator == null) {
                throw new RegistryException(ServerResourceBundle.getInstance().getString("message.registryOperator",
                        new Object[] { ALIAS_REGISTRY_OPERATOR }));
            }
            if (registryGuest == null) {
                throw new RegistryException(ServerResourceBundle.getInstance().getString("message.registryGuest",
                        new Object[] { ALIAS_REGISTRY_GUEST }));
            }
        } catch (RegistryException e) {
            log.error(ServerResourceBundle.getInstance()
                    .getString("message.InternalErrorCouldNotLoadPredefinedUsers"), e);
            throw e;
        }
    }

    /*
     * Loads the list of RegistryAdministrators from the property file during
     * startup.
     */
    private void loadRegistryAdministrators() {
        String adminList = RegistryProperties.getInstance()
                .getProperty("eric.security.authorization.registryAdministrators");

        if (adminList != null) {
            java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(adminList, "|");

            while (tokenizer.hasMoreTokens()) {
                try {
                    String adminId = tokenizer.nextToken();
                    // ??? Note these messages are output whether or not
                    // ??? user already has this role.
                    if (log.isDebugEnabled()) {
                        log.debug(ServerResourceBundle.getInstance().getString(
                                "message.getRegistryAdministratorsAddingAdmin", new Object[] { adminId }));
                    }
                    adminIdSet.add(adminId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } else {
            log.warn(ServerResourceBundle.getInstance()
                    .getString("message.RegistryHasNotDefinedRegistryAdministratorsYet"));
        }
    }

    /**
     * Gets the User that is associated with the specified certificate.
     * 
     * @throws UserNotFoundException
     *             when no matching User is found
     */
    public UserType getUserFromCertificate(X509Certificate cert) throws RegistryException {
        UserType user = null;

        if (cert == null) {
            boolean noRegRequired = Boolean.valueOf(
                    CommonProperties.getInstance().getProperty("eric.common.noUserRegistrationRequired", "false"))
                    .booleanValue();
            if (noRegRequired) {
                return registryOperator;
            } else {
                return registryGuest;
            }
        }

        // The registry expects the KeyInfo to either have the PublicKey or the
        // DN from the public key
        // In case of DN the registry can lookup the public key based on the DN
        @SuppressWarnings("unused")
        java.security.PublicKey publicKey = null;
        String alias = null;

        try {

            // lots of trace
            if (log.isTraceEnabled()) {
                log.trace("getUserFromCertificate cert:\n" + cert);
                StringBuffer storedCerts = new StringBuffer("Stored certificates:");
                Enumeration<String> aliases = getKeyStore().aliases();
                while (aliases.hasMoreElements()) {
                    X509Certificate storedCert = (X509Certificate) getKeyStore()
                            .getCertificate(aliases.nextElement());
                    storedCerts.append("\n").append(storedCert).append("\n--------");
                }
                log.trace(storedCerts.toString());
            } else if (log.isDebugEnabled()) {
                log.debug("getUserFromCertificate cert:\n" + cert);
            }

            alias = getKeyStore().getCertificateAlias(cert);
            if (alias == null) {
                if (log.isDebugEnabled()) {
                    log.debug("Unknown certificate: " + cert.getSubjectDN().getName());
                }
                throw new UserNotFoundException(cert.getSubjectDN().getName());
            }

            if (log.isDebugEnabled()) {
                log.debug("Alias found for certificate:: " + alias);
            }
        } catch (KeyStoreException e) {
            throw new RegistryException(e);
        }

        user = getUserFromAlias(alias);

        return user;

    }

    /**
     * Compares two certificates. It will compare the issuerUniqueID and
     * subjectUniqueID fields of the certificates. If either certificate does
     * not contain either field, it will return false.
     */
    private boolean certificatesAreSame(X509Certificate cert, X509Certificate oldCert) throws RegistryException {
        boolean[] certIssuerID = cert.getIssuerUniqueID();
        boolean[] oldCertIssuerID = oldCert.getIssuerUniqueID();

        if ((certIssuerID == null) || (oldCertIssuerID == null)
                || (certIssuerID.length != oldCertIssuerID.length)) {
            return false;
        }

        for (int i = 0; i < certIssuerID.length; i++) {
            if (certIssuerID[i] != oldCertIssuerID[i]) {
                return false;
            }
        }

        boolean[] certSubjectID = cert.getSubjectUniqueID();
        boolean[] oldCertSubjectID = oldCert.getSubjectUniqueID();

        if ((certSubjectID == null) || (oldCertSubjectID == null)
                || (certSubjectID.length != oldCertSubjectID.length)) {
            return false;
        }

        for (int i = 0; i < certSubjectID.length; i++) {
            if (certSubjectID[i] != oldCertSubjectID[i]) {
                return false;
            }
        }

        return true;
    }

    /**
     * Add a certificate entry in the keystore.
     * 
     * @param userId
     *            The alias of the certificate
     * @param signature
     *            The XMLSignature containing the certificate
     * @throws UserRegistration
     *             fails if the keystore already contrains the entry whose alias
     *             is equal to userId
     */
    // protected void registerUserCertificate(String userId, XMLSignature
    // signature)
    // throws RegistryException {
    // try {
    // X509Certificate cert = getCertificate(signature);
    // registerUserCertificate(userId, cert);
    // } catch (NoSuchAlgorithmException e) {
    // throw new UserRegistrationException(e);
    // } catch (java.security.cert.CertificateException e) {
    // throw new UserRegistrationException(e);
    // } catch (javax.xml.crypto.KeySelectorException e) {
    // throw new RegistryException(e);
    // } catch (java.security.InvalidAlgorithmParameterException e) {
    // throw new RegistryException(e);
    // }
    // }

    /**
     * This method is used to remove a certificate from the server keystore.
     * This is called, for example, when a rim:User has been deleted and the
     * User's credentials need to be cleared from the server keystore
     * 
     * @param alias
     *            A java.lang.String that contains the alias of the public key
     *            credential
     */
    public void deleteUserCertificate(String alias) throws RegistryException {
        KeyStore keyStore = getKeyStore();
        java.io.FileOutputStream fos = null;
        try {
            String keystoreFile = getKeyStoreFileName();
            synchronized (keyStoreWriteLock) {
                fos = new java.io.FileOutputStream(keystoreFile);
                keyStore.deleteEntry(alias);
                String keystorePass = getKeyStorePassword();
                keyStore.store(fos, keystorePass.toCharArray());
                fos.flush();
                this.keyStore = null;
            }
        } catch (Throwable t) {
            throw new RegistryException(t);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException io) {
                    fos = null;
                }
            }
        }
    }

    protected void registerUserCertificate(String userId, X509Certificate cert) throws RegistryException {
        java.io.FileOutputStream fos = null;

        try {
            KeyStore keyStore = getKeyStore();

            // Make sure no other user is registered with same cert under a
            // different alias
            String alias = getKeyStore().getCertificateAlias(cert);
            if ((null != alias) && (!userId.equalsIgnoreCase(alias))) {
                throw new UserRegistrationException(ServerResourceBundle.getInstance()
                        .getString("message.error.certificateAlreadyExists", new Object[] { userId, alias }));
            }

            // Check if already in store
            X509Certificate oldCert = null;

            try {
                oldCert = getCertificate(userId);
            } catch (Exception e) {
            }

            // System.err.println("Checking the certificates are the same...");
            if ((oldCert != null) && !certificatesAreSame(cert, oldCert)) {
                throw new UserRegistrationException(ServerResourceBundle.getInstance()
                        .getString("message.userRegistrationFailed", new Object[] { userId }));
            }

            // Add the cert. to the keystore if the cert. does not exist yet
            if (oldCert == null) {
                if (propsReader.getProperty("eric.security.validateCertificates").trim().equalsIgnoreCase("true")) {
                    validateCertificate(cert);
                }

                synchronized (keyStoreWriteLock) {
                    keyStore.setCertificateEntry(userId, cert);

                    String keystoreFile = getKeyStoreFileName();
                    fos = new java.io.FileOutputStream(keystoreFile);

                    String keystorePass = getKeyStorePassword();
                    keyStore.store(fos, keystorePass.toCharArray());
                    fos.flush();
                    fos.close();
                    this.keyStore = null;

                    // Update publicKeyToCertMap
                    publicKeyToCertMap.put(cert.getPublicKey(), cert);
                }
            }
        } catch (KeyStoreException e) {
            throw new UserRegistrationException(e);
        } catch (IOException e) {
            throw new UserRegistrationException(e);
        } catch (java.security.cert.CertificateException e) {
            throw new UserRegistrationException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new UserRegistrationException(e);
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // private X509Certificate getCertificate(XMLSignature signature)
    // throws NoSuchAlgorithmException, java.security.cert.CertificateException,
    // javax.xml.crypto.KeySelectorException,
    // java.security.InvalidAlgorithmParameterException,
    // RegistryException {
    // XMLSignatureFactory fac =
    // SecurityUtil.getInstance().createXMLSignatureFactory();
    //
    // KeySelector keySelector = new X509KeySelector(keyStore);
    // KeyInfo keyInfo = signature.getKeyInfo();
    // KeySelectorResult result = keySelector.select(keyInfo,
    // KeySelector.Purpose.VERIFY,
    // fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null), null);
    // return ((KeyAliasSelectorResult)result).getCertificate();
    // }
}