From 621d9e5c413e561293d7484b93882d985b3fe15f Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Sat, 24 Mar 2012 02:27:47 -0500 Subject: Removed unnecessary pki folder. Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131 --- .../cmscore/authentication/AuthSubsystem.java | 515 +++++++++++++++++++++ .../authentication/CertUserDBAuthentication.java | 260 +++++++++++ .../ChallengePhraseAuthentication.java | 411 ++++++++++++++++ .../cmscore/authentication/NullAuthentication.java | 161 +++++++ .../authentication/PasswdUserDBAuthentication.java | 274 +++++++++++ .../SSLClientCertAuthentication.java | 291 ++++++++++++ .../cmscore/authentication/VerifiedCert.java | 90 ++++ .../cmscore/authentication/VerifiedCerts.java | 158 +++++++ 8 files changed, 2160 insertions(+) create mode 100644 base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java create mode 100644 base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java (limited to 'base/common/src/com/netscape/cmscore/authentication') diff --git a/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java b/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java new file mode 100644 index 000000000..64a09173f --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/AuthSubsystem.java @@ -0,0 +1,515 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthManagerProxy; +import com.netscape.certsrv.authentication.AuthMgrPlugin; +import com.netscape.certsrv.authentication.EAuthException; +import com.netscape.certsrv.authentication.EAuthMgrNotFound; +import com.netscape.certsrv.authentication.EAuthMgrPluginNotFound; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthSubsystem; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.ISubsystem; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.cmscore.util.Debug; + +/** + * Default authentication subsystem + *

+ * + * @author cfu + * @author lhsiao + * @version $Revision$, $Date$ + */ +public class AuthSubsystem implements IAuthSubsystem { + public static final String ID = "auths"; + + public Hashtable mAuthMgrPlugins = new Hashtable(); + public Hashtable mAuthMgrInsts = new Hashtable(); + private String mId = "auths"; + private IConfigStore mConfig = null; + + private ILogger mLogger = null; + + // singleton enforcement + + private static AuthSubsystem mInstance = new AuthSubsystem(); + + public static synchronized AuthSubsystem getInstance() { + return mInstance; + } + + // end singleton enforcement. + + private AuthSubsystem() { + } + + /** + * Initializes the authentication subsystem from the config store. + * Load Authentication manager plugins, create and initialize + * initialize authentication manager instances. + * + * @param owner The owner of this module. + * @param config The configuration store. + */ + public void init(ISubsystem owner, IConfigStore config) + throws EBaseException { + try { + mLogger = CMS.getLogger(); + mConfig = config; + + // hardcode admin and agent plugins required for the server to be + // functional. + + AuthMgrPlugin newPlugin = null; + + newPlugin = new AuthMgrPlugin(PASSWDUSERDB_PLUGIN_ID, + PasswdUserDBAuthentication.class.getName()); + newPlugin.setVisible(false); + mAuthMgrPlugins.put(PASSWDUSERDB_PLUGIN_ID, newPlugin); + + newPlugin = new AuthMgrPlugin(CERTUSERDB_PLUGIN_ID, + CertUserDBAuthentication.class.getName()); + newPlugin.setVisible(false); + mAuthMgrPlugins.put(CERTUSERDB_PLUGIN_ID, newPlugin); + + newPlugin = new AuthMgrPlugin(CHALLENGE_PLUGIN_ID, + ChallengePhraseAuthentication.class.getName()); + newPlugin.setVisible(false); + mAuthMgrPlugins.put(CHALLENGE_PLUGIN_ID, newPlugin); + + // Bugscape #56659 + // Removed NullAuthMgr to harden CMS. Otherwise, + // any request submitted for nullAuthMgr will + // be approved automatically + // + // newPlugin = new AuthMgrPlugin(NULL_PLUGIN_ID, + // NullAuthentication.class.getName()); + // newPlugin.setVisible(false); + // mAuthMgrPlugins.put(NULL_PLUGIN_ID, newPlugin); + + newPlugin = new AuthMgrPlugin(SSLCLIENTCERT_PLUGIN_ID, + SSLClientCertAuthentication.class.getName()); + newPlugin.setVisible(false); + mAuthMgrPlugins.put(SSLCLIENTCERT_PLUGIN_ID, newPlugin); + + // get auth manager plugins. + + IConfigStore c = config.getSubStore(PROP_IMPL); + Enumeration mImpls = c.getSubStoreNames(); + + while (mImpls.hasMoreElements()) { + String id = (String) mImpls.nextElement(); + String pluginPath = c.getString(id + "." + PROP_CLASS); + + AuthMgrPlugin plugin = new AuthMgrPlugin(id, pluginPath); + + mAuthMgrPlugins.put(id, plugin); + } + if (Debug.ON) { + Debug.trace("loaded auth plugins"); + } + + // hardcode admin and agent auth manager instances for the server + // to be functional + + IAuthManager passwdUserDBAuth = new PasswdUserDBAuthentication(); + + passwdUserDBAuth.init(PASSWDUSERDB_AUTHMGR_ID, PASSWDUSERDB_PLUGIN_ID, null); + mAuthMgrInsts.put(PASSWDUSERDB_AUTHMGR_ID, new + AuthManagerProxy(true, passwdUserDBAuth)); + if (Debug.ON) { + Debug.trace("loaded password based auth manager"); + } + + IAuthManager certUserDBAuth = new CertUserDBAuthentication(); + + certUserDBAuth.init(CERTUSERDB_AUTHMGR_ID, CERTUSERDB_PLUGIN_ID, config); + mAuthMgrInsts.put(CERTUSERDB_AUTHMGR_ID, new AuthManagerProxy(true, certUserDBAuth)); + if (Debug.ON) { + Debug.trace("loaded certificate based auth manager"); + } + + IAuthManager challengeAuth = new ChallengePhraseAuthentication(); + + challengeAuth.init(CHALLENGE_AUTHMGR_ID, CHALLENGE_PLUGIN_ID, config); + mAuthMgrInsts.put(CHALLENGE_AUTHMGR_ID, new AuthManagerProxy(true, challengeAuth)); + if (Debug.ON) { + Debug.trace("loaded challenge phrase auth manager"); + } + + IAuthManager cmcAuth = new com.netscape.cms.authentication.CMCAuth(); + + cmcAuth.init(CMCAUTH_AUTHMGR_ID, CMCAUTH_PLUGIN_ID, config); + mAuthMgrInsts.put(CMCAUTH_AUTHMGR_ID, new AuthManagerProxy(true, cmcAuth)); + if (Debug.ON) { + Debug.trace("loaded cmc auth manager"); + } + + // #56659 + // IAuthManager nullAuth = new NullAuthentication(); + + // nullAuth.init(NULL_AUTHMGR_ID, NULL_PLUGIN_ID, config); + // mAuthMgrInsts.put(NULL_AUTHMGR_ID, new AuthManagerProxy(true, nullAuth)); + // if (Debug.ON) { + // Debug.trace("loaded null auth manager"); + // } + + IAuthManager sslClientCertAuth = new SSLClientCertAuthentication(); + + sslClientCertAuth.init(SSLCLIENTCERT_AUTHMGR_ID, SSLCLIENTCERT_PLUGIN_ID, config); + mAuthMgrInsts.put(SSLCLIENTCERT_AUTHMGR_ID, new AuthManagerProxy(true, sslClientCertAuth)); + if (Debug.ON) { + Debug.trace("loaded sslClientCert auth manager"); + } + + // get auth manager instances. + c = config.getSubStore(PROP_INSTANCE); + Enumeration instances = c.getSubStoreNames(); + + while (instances.hasMoreElements()) { + String insName = (String) instances.nextElement(); + String implName = c.getString(insName + "." + PROP_PLUGIN); + AuthMgrPlugin plugin = + (AuthMgrPlugin) mAuthMgrPlugins.get(implName); + + if (plugin == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_CANT_FIND_PLUGIN", implName)); + throw new EAuthMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", + implName)); + } + String className = plugin.getClassPath(); + + boolean isEnable = false; + // Instantiate and init the authentication manager. + IAuthManager authMgrInst = null; + + try { + authMgrInst = (IAuthManager) + Class.forName(className).newInstance(); + IConfigStore authMgrConfig = c.getSubStore(insName); + + authMgrInst.init(insName, implName, authMgrConfig); + isEnable = true; + + log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_ADD_AUTH_INSTANCE", insName)); + } catch (ClassNotFoundException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } catch (IllegalAccessException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } catch (InstantiationException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTHSUB_ERROR", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } catch (EBaseException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString())); + // Skip the authenticaiton instance if + // it is mis-configurated. This give + // administrator another chance to + // fix the problem via console + } catch (Throwable e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AUTH_INIT_ERROR", insName, e.toString())); + // Skip the authenticaiton instance if + // it is mis-configurated. This give + // administrator another chance to + // fix the problem via console + } + // add manager instance to list. + mAuthMgrInsts.put(insName, new + AuthManagerProxy(isEnable, authMgrInst)); + if (Debug.ON) { + Debug.trace("loaded auth instance " + insName + " impl " + implName); + } + } + log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", getId())); + } catch (EBaseException ee) { + if (CMS.isPreOpMode()) + return; + throw ee; + } + } + + /** + * Authenticate to the named authentication manager instance + *

+ * + * @param authCred authentication credentials subject to the + * requirements of each authentication manager + * @param authMgrName name of the authentication manager instance + * @return authentication token with individualized authenticated + * information. + * @exception EMissingCredential If a required credential for the + * authentication manager is missing. + * @exception EInvalidCredentials If the credentials cannot be authenticated + * @exception EAuthMgrNotFound The auth manager is not found. + * @exception EBaseException If an internal error occurred. + */ + public IAuthToken authenticate( + IAuthCredentials authCred, String authMgrInstName) + throws EMissingCredential, EInvalidCredentials, + EAuthMgrNotFound, EBaseException { + AuthManagerProxy proxy = (AuthManagerProxy) + mAuthMgrInsts.get(authMgrInstName); + + if (proxy == null) { + throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName)); + } + if (!proxy.isEnable()) { + throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName)); + } + IAuthManager authMgrInst = proxy.getAuthManager(); + + if (authMgrInst == null) { + throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName)); + } + return (authMgrInst.authenticate(authCred)); + } + + /** + * Gets a list of required authentication credential names + * of the specified authentication manager. + */ + public String[] getRequiredCreds(String authMgrInstName) + throws EAuthMgrNotFound { + IAuthManager authMgrInst = get(authMgrInstName); + + if (authMgrInst == null) { + throw new EAuthMgrNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", authMgrInstName)); + } + return authMgrInst.getRequiredCreds(); + } + + /** + * Gets configuration parameters for the given + * authentication manager plugin. + * + * @param implName Name of the authentication plugin. + * @return Hashtable of required parameters. + */ + public String[] getConfigParams(String implName) + throws EAuthMgrPluginNotFound, EBaseException { + // is this a registered implname? + AuthMgrPlugin plugin = (AuthMgrPlugin) mAuthMgrPlugins.get(implName); + + if (plugin == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_PLUGIN_NOT_FOUND", implName)); + throw new EAuthMgrPluginNotFound(CMS.getUserMessage("CMS_AUTHENTICATION_AUTHMGR_NOT_FOUND", implName)); + } + + // a temporary instance + IAuthManager authMgrInst = null; + String className = plugin.getClassPath(); + + try { + authMgrInst = (IAuthManager) + Class.forName(className).newInstance(); + return (authMgrInst.getConfigParams()); + } catch (InstantiationException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } catch (ClassNotFoundException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } catch (IllegalAccessException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString())); + throw new EAuthException(CMS.getUserMessage("CMS_ACL_CLASS_LOAD_FAIL", className)); + } + } + + /** + * Add an authentication manager instance. + * + * @param name name of the authentication manager instance + * @param authMgr the authentication manager instance to be added + */ + public void add(String name, IAuthManager authMgrInst) { + mAuthMgrInsts.put(name, new AuthManagerProxy(true, authMgrInst)); + } + + /* + * Removes a authentication manager instance. + * @param name name of the authentication manager + */ + public void delete(String name) { + mAuthMgrInsts.remove(name); + } + + /** + * Gets the authentication manager instance of the specified name. + * + * @param name name of the authentication manager instance + * @return the named authentication manager instance + */ + public IAuthManager get(String name) { + AuthManagerProxy proxy = (AuthManagerProxy) mAuthMgrInsts.get(name); + + if (proxy == null) + return null; + return proxy.getAuthManager(); + } + + /** + * Enumerate all authentication manager instances. + */ + public Enumeration getAuthManagers() { + Vector inst = new Vector(); + Enumeration e = mAuthMgrInsts.keys(); + + while (e.hasMoreElements()) { + IAuthManager p = get(e.nextElement()); + + if (p != null) { + inst.addElement(p); + } + } + return (inst.elements()); + } + + /** + * Enumerate all registered authentication manager plugins. + */ + public Enumeration getAuthManagerPlugins() { + return (mAuthMgrPlugins.elements()); + } + + /** + * retrieve a single auth manager plugin by name + */ + public AuthMgrPlugin getAuthManagerPluginImpl(String name) { + return (AuthMgrPlugin) mAuthMgrPlugins.get(name); + } + + /** + * Retrieve a single auth manager instance + */ + + /* getconfigparams above should be recoded to use this func */ + public IAuthManager getAuthManagerPlugin(String name) { + AuthMgrPlugin plugin = (AuthMgrPlugin) mAuthMgrPlugins.get(name); + String classpath = plugin.getClassPath(); + IAuthManager authMgrInst = null; + + try { + authMgrInst = (IAuthManager) Class.forName(classpath).newInstance(); + return (authMgrInst); + } catch (Exception e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_NOT_CREATED", e.toString())); + return null; + } + } + + /** + * Retrieves id (name) of this subsystem. + * + * @return name of the authentication subsystem + */ + public String getId() { + return (mId); + } + + /** + * Sets id string to this subsystem. + *

+ * Use with caution. Should not do it when sharing with others + * + * @param id name to be applied to an authentication sybsystem + */ + public void setId(String id) throws EBaseException { + mId = id; + } + + /** + * registers the administration servlet with the administration subsystem. + */ + public void startup() throws EBaseException { + //remove the log since it's already logged from S_ADMIN + //String infoMsg = "Auth subsystem administration Servlet registered"; + //log(ILogger.LL_INFO, infoMsg); + } + + /** + * shuts down authentication managers one by one. + *

+ */ + public void shutdown() { + for (Enumeration e = mAuthMgrInsts.keys(); e.hasMoreElements();) { + + IAuthManager mgr = (IAuthManager) get((String) e.nextElement()); + + log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INSTANCE_SHUTDOWN", mgr.getName())); + + mgr.shutdown(); + } + + mAuthMgrPlugins.clear(); + mAuthMgrPlugins = null; + mAuthMgrInsts.clear(); + mAuthMgrInsts = null; + } + + public Hashtable getPlugins() { + return mAuthMgrPlugins; + } + + public Hashtable getInstances() { + return mAuthMgrInsts; + } + + /** + * Returns the root configuration storage of this system. + *

+ * + * @return configuration store of this subsystem + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + /** + * gets the named authentication manager + * + * @param name of the authentication manager + * @return the named authentication manager + */ + public IAuthManager getAuthManager(String name) { + return ((IAuthManager) get(name)); + } + + /** + * logs an entry in the log file. + */ + public void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } + +} diff --git a/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java new file mode 100644 index 000000000..84807430f --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/CertUserDBAuthentication.java @@ -0,0 +1,260 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import java.security.cert.X509Certificate; + +import netscape.security.x509.X509CertImpl; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.usrgrp.Certificates; +import com.netscape.certsrv.usrgrp.EUsrGrpException; +import com.netscape.certsrv.usrgrp.ICertUserLocator; +import com.netscape.cmscore.usrgrp.ExactMatchCertUserLocator; +import com.netscape.cmscore.usrgrp.User; + +/** + * Certificate server agent authentication. + * Maps a SSL client authenticate certificate to a user (agent) entry in the + * internal database. + *

+ * + * @author lhsiao + * @author cfu + * @version $Revision$, $Date$ + */ +public class CertUserDBAuthentication implements IAuthManager { + + /* result auth token attributes */ + public static final String TOKEN_USERDN = "user"; + public static final String TOKEN_USER_DN = "userdn"; + public static final String TOKEN_USERID = "userid"; + public static final String TOKEN_UID = "uid"; + + /* required credentials */ + public static final String CRED_CERT = IAuthManager.CRED_SSL_CLIENT_CERT; + protected String[] mRequiredCreds = { CRED_CERT }; + + /* config parameters to pass to console (none) */ + protected static String[] mConfigParams = null; + + private String mName = null; + private String mImplName = null; + private IConfigStore mConfig = null; + + private ICertUserLocator mCULocator = null; + private ILogger mLogger = CMS.getLogger(); + + private boolean mRevocationCheckingEnabled = false; + private IConfigStore mRevocationChecking = null; + private String mRequestor = null; + + public CertUserDBAuthentication() { + } + + /** + * initializes the CertUserDBAuthentication auth manager + *

+ * called by AuthSubsystem init() method, when initializing all available authentication managers. + * + * @param owner - The authentication subsystem that hosts this + * auth manager + * @param config - The configuration store used by the + * authentication subsystem + */ + public void init(String name, String implName, IConfigStore config) + throws EBaseException { + mName = name; + mImplName = implName; + mConfig = config; + + if (mConfig != null) { + mRevocationChecking = mConfig.getSubStore("revocationChecking"); + } + if (mRevocationChecking != null) { + mRevocationCheckingEnabled = mRevocationChecking.getBoolean("enabled", false); + if (mRevocationCheckingEnabled) { + int size = mRevocationChecking.getInteger("bufferSize", 0); + long interval = (long) mRevocationChecking.getInteger("validityInterval", 28800); + long unknownStateInterval = (long) mRevocationChecking.getInteger("unknownStateInterval", 1800); + + if (size > 0) + CMS.setListOfVerifiedCerts(size, interval, unknownStateInterval); + } + } + + mCULocator = new ExactMatchCertUserLocator(); + log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name)); + } + + /** + * Gets the name of this authentication manager. + */ + public String getName() { + return mName; + } + + /** + * Gets the plugin name of authentication manager. + */ + public String getImplName() { + return mImplName; + } + + /** + * authenticates user(agent) by certificate + *

+ * called by other subsystems or their servlets to authenticate users (agents) + * + * @param authCred - authentication credential that contains + * an usrgrp.Certificates of the user (agent) + * @return the authentication token that contains the following + * + * @exception com.netscape.certsrv.base.EAuthsException any + * authentication failure or insufficient credentials + * @see com.netscape.certsrv.authentication.AuthToken + * @see com.netscape.certsrv.usrgrp.Certificates + */ + public IAuthToken authenticate(IAuthCredentials authCred) + throws EMissingCredential, EInvalidCredentials, EBaseException { + CMS.debug("CertUserDBAuth: started"); + AuthToken authToken = new AuthToken(this); + CMS.debug("CertUserDBAuth: Retrieving client certificate"); + X509Certificate[] x509Certs = + (X509Certificate[]) authCred.get(CRED_CERT); + + if (x509Certs == null) { + CMS.debug("CertUserDBAuth: no client certificate found"); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_CERT")); + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT)); + } + CMS.debug("CertUserDBAuth: Got client certificate"); + + if (mRevocationCheckingEnabled) { + X509CertImpl cert0 = (X509CertImpl) x509Certs[0]; + if (cert0 == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_NO_CERT")); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_NO_CERT")); + } + if (CMS.isRevoked(x509Certs)) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_REVOKED_CERT")); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + } + + CMS.debug("Authentication: client certificate found"); + + // map cert to user + User user = null; + Certificates certs = new Certificates(x509Certs); + + try { + user = (User) mCULocator.locateUser(certs); + } catch (EUsrGrpException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_AUTH_FAILED", x509Certs[0].getSerialNumber() + .toString(16), x509Certs[0].getSubjectDN().toString(), e.toString())); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } catch (netscape.ldap.LDAPException e) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_CANNOT_AGENT_AUTH", e.toString())); + throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString())); + } + + // any unexpected error occurs like internal db down, + // UGSubsystem only returns null for user. + if (user == null) { + CMS.debug("Authentication: cannot map certificate to user"); + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_AGENT_USER_NOT_FOUND")); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + + CMS.debug("Authentication: mapped certificate to user"); + + authToken.set(TOKEN_USERDN, user.getUserDN()); + authToken.set(TOKEN_USER_DN, user.getUserDN()); + authToken.set(TOKEN_USERID, user.getUserID()); + authToken.set(TOKEN_UID, user.getUserID()); + authToken.set(CRED_CERT, certs); + + log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", user.getUserID())); + CMS.debug("authenticated " + user.getUserDN()); + + return authToken; + } + + /** + * get the list of authentication credential attribute names + * required by this authentication manager. Generally used by + * the servlets that handle agent operations to authenticate its + * users. It calls this method to know which are the + * required credentials from the user (e.g. Javascript form data) + * + * @return attribute names in Vector + */ + public String[] getRequiredCreds() { + return (mRequiredCreds); + } + + /** + * get the list of configuration parameter names + * required by this authentication manager. Generally used by + * the Certificate Server Console to display the table for + * configuration purposes. CertUserDBAuthentication is currently not + * exposed in this case, so this method is not to be used. + * + * @return configuration parameter names in Hashtable of Vectors + * where each hashtable entry's key is the substore name, value is a + * Vector of parameter names. If no substore, the parameter name + * is the Hashtable key itself, with value same as key. + */ + public String[] getConfigParams() { + return (mConfigParams); + } + + /** + * prepare this authentication manager for shutdown. + */ + public void shutdown() { + } + + /** + * gets the configuretion substore used by this authentication + * manager + * + * @return configuration store + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + private void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } + +} diff --git a/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java new file mode 100644 index 000000000..a7d5329c0 --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/ChallengePhraseAuthentication.java @@ -0,0 +1,411 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.EAuthException; +import com.netscape.certsrv.authentication.EAuthUserError; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.MetaInfo; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.ra.IRegistrationAuthority; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.IRequestQueue; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.certsrv.usrgrp.ICertUserLocator; +import com.netscape.cmscore.base.SubsystemRegistry; +import com.netscape.cmscore.dbs.CertRecord; +import com.netscape.cmscore.dbs.CertificateRepository; +import com.netscape.cmscore.util.Debug; +import com.netscape.cmsutil.util.Utils; + +/** + * Challenge phrase based authentication. + * Maps a certificate to the request in the + * internal database and further compares the challenge phrase with + * that from the EE input. + *

+ * + * @author cfu chrisho + * @version $Revision$, $Date$ + */ +public class ChallengePhraseAuthentication implements IAuthManager { + + /* result auth token attributes */ + public static final String TOKEN_CERT_SERIAL = "certSerialToRevoke"; + + /* required credentials */ + public static final String CRED_CERT_SERIAL = IAuthManager.CRED_CERT_SERIAL_TO_REVOKE; + public static final String CRED_CHALLENGE = "challengePhrase"; + protected String[] mRequiredCreds = { CRED_CERT_SERIAL, CRED_CHALLENGE }; + + /* config parameters to pass to console (none) */ + protected static String[] mConfigParams = null; + protected ICertificateAuthority mCA = null; + protected ICertificateRepository mCertDB = null; + + private String mName = null; + private String mImplName = null; + private IConfigStore mConfig = null; + + private ICertUserLocator mCULocator = null; + private ILogger mLogger = CMS.getLogger(); + private String mRequestor = null; + private MessageDigest mSHADigest = null; + + // request attributes hacks + public static final String CHALLENGE_PHRASE = CRED_CHALLENGE; + public static final String SUBJECTNAME = "subjectName"; + public static final String SERIALNUMBER = "serialNumber"; + public static final String SERIALNOARRAY = "serialNoArray"; + + public ChallengePhraseAuthentication() { + } + + /** + * initializes the ChallengePhraseAuthentication auth manager + *

+ * called by AuthSubsystem init() method, when initializing all available authentication managers. + * + * @param name The name of this authentication manager instance. + * @param implName The name of the authentication manager plugin. + * @param config The configuration store for this authentication manager. + */ + public void init(String name, String implName, IConfigStore config) + throws EBaseException { + mName = name; + mImplName = implName; + mConfig = config; + + try { + mSHADigest = MessageDigest.getInstance("SHA1"); + } catch (NoSuchAlgorithmException e) { + throw new EAuthException(CMS.getUserMessage("CMS_AUTHENTICATION_INTERNAL_ERROR", e.getMessage())); + } + + log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name)); + } + + /** + * Gets the name of this authentication manager. + */ + public String getName() { + return mName; + } + + /** + * Gets the plugin name of authentication manager. + */ + public String getImplName() { + return mImplName; + } + + /** + * authenticates revocation of a certification by a challenge phrase + *

+ * called by other subsystems or their servlets to authenticate a revocation request + * + * @param authCred - authentication credential that contains + * a Certificate to revoke + * @return the authentication token that contains the request id + * + * @exception EMissingCredential If a required credential for this + * authentication manager is missing. + * @exception EInvalidCredentials If credentials cannot be authenticated. + * @exception EBaseException If an internal error occurred. + * @see com.netscape.certsrv.authentication.AuthToken + */ + public IAuthToken authenticate(IAuthCredentials authCred) + throws EMissingCredential, EInvalidCredentials, EBaseException { + mCA = (ICertificateAuthority) + SubsystemRegistry.getInstance().get("ca"); + + if (mCA != null) { + mCertDB = (CertificateRepository) mCA.getCertificateRepository(); + } + + AuthToken authToken = new AuthToken(this); + + /* + X509Certificate[] x509Certs = + (X509Certificate[]) authCred.get(CRED_CERT); + if (x509Certs == null) { + log(ILogger.LL_FAILURE, + " missing cert credential."); + throw new EMissingCredential(CRED_CERT_SERIAL); + } + */ + + String serialNumString = (String) authCred.get(CRED_CERT_SERIAL); + + BigInteger serialNum = null; + + if (serialNumString == null || serialNumString.equals("")) + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT_SERIAL)); + else { + //serialNumString = getDecimalStr(serialNumString); + try { + serialNumString = serialNumString.trim(); + if (serialNumString.startsWith("0x") || serialNumString.startsWith("0X")) { + serialNum = new + BigInteger(serialNumString.substring(2), 16); + } else { + serialNum = new + BigInteger(serialNumString); + } + + } catch (NumberFormatException e) { + throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", + "Invalid serial number.")); + } + } + + String challenge = (String) authCred.get(CRED_CHALLENGE); + + if (challenge == null) { + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CHALLENGE)); + } + if (challenge.equals("")) { + // empty challenge not allowed + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_REVO_ATTEMPT", serialNum.toString())); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + + /* maybe later + if (mCertDB.isCertificateRevoked(cert) != null) { + log(ILogger.LL_FAILURE, + "Certificate has already been revoked."); + // throw something else...cfu + throw new EInvalidCredentials(); + } + */ + + BigInteger[] bigIntArray = null; + + // check challenge phrase against request + /* + * map cert to a request: a cert serial number maps to a + * cert record in the internal db, from the cert record, + * where we'll find the challenge phrase + */ + if (mCertDB != null) { /* is CA */ + CertRecord record = null; + + try { + record = (CertRecord) mCertDB.readCertificateRecord(serialNum); + } catch (EBaseException ee) { + if (Debug.ON) { + Debug.trace(ee.toString()); + } + } + if (record != null) { + String status = record.getStatus(); + + if (!status.equals("REVOKED")) { + boolean samepwd = compareChallengePassword(record, challenge); + + if (samepwd) { + bigIntArray = new BigInteger[1]; + bigIntArray[0] = record.getSerialNumber(); + } else + throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", + "Invalid password.")); + + } else { + bigIntArray = new BigInteger[0]; + } + } else { + bigIntArray = new BigInteger[0]; + } + } else { + + /* + * ra, build a request and send through the connection for + * authentication + */ + IRequestQueue queue = getReqQueue(); + + if (queue != null) { + IRequest checkChallengeReq = null; + + checkChallengeReq = + queue.newRequest(IRequest.REVOCATION_CHECK_CHALLENGE_REQUEST); + checkChallengeReq.setExtData(CHALLENGE_PHRASE, challenge); + // pass just serial number instead of whole cert + if (serialNum != null) + checkChallengeReq.setExtData(SERIALNUMBER, serialNum); + queue.processRequest(checkChallengeReq); + // check request status... + RequestStatus status = checkChallengeReq.getRequestStatus(); + + if (status == RequestStatus.COMPLETE) { + bigIntArray = checkChallengeReq.getExtDataInBigIntegerArray("serialNoArray"); + } else { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_INCOMPLETE_REQUEST")); + } + } else { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_FAILED_GET_QUEUE")); + throw new EBaseException(CMS.getUserMessage("CMS_BASE_REVOCATION_CHALLENGE_QUEUE_FAILED")); + } + } // else, ra + if (bigIntArray != null && bigIntArray.length > 0) { + if (Debug.ON) { + Debug.trace("challenge authentication serialno array not null"); + for (int i = 0; i < bigIntArray.length; i++) + Debug.trace("challenge auth serialno " + bigIntArray[i]); + } + } + if (Debug.ON) { + Debug.trace("challenge authentication set " + TOKEN_CERT_SERIAL); + } + authToken.set(TOKEN_CERT_SERIAL, bigIntArray); + + return authToken; + } + + private boolean compareChallengePassword(CertRecord record, String pwd) + throws EBaseException { + MetaInfo metaInfo = (MetaInfo) record.get(CertRecord.ATTR_META_INFO); + + if (metaInfo == null) { + throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "metaInfo")); + } + + if (pwd == null) { + if (Debug.ON) { + Debug.trace("challenge pwd is null"); + } + return false; + } + String hashpwd = hashPassword(pwd); + + // got metaInfo + String challengeString = + (String) metaInfo.get(CertRecord.META_CHALLENGE_PHRASE); + + if (challengeString == null) { + if (Debug.ON) { + Debug.trace("challengeString null"); + } + return false; + } + + if (!challengeString.equals(hashpwd)) { + return false; + + /* + log(ILogger.LL_FAILURE, + "Incorrect challenge phrase password used for revocation"); + throw new EInvalidCredentials(); + */ + } else + return true; + } + + /** + * get the list of authentication credential attribute names + * required by this authentication manager. Generally used by + * the servlets that handle agent operations to authenticate its + * users. It calls this method to know which are the + * required credentials from the user (e.g. Javascript form data) + * + * @return attribute names in Vector + */ + public String[] getRequiredCreds() { + return (mRequiredCreds); + } + + /** + * get the list of configuration parameter names + * required by this authentication manager. Generally used by + * the Certificate Server Console to display the table for + * configuration purposes. ChallengePhraseAuthentication is currently not + * exposed in this case, so this method is not to be used. + * + * @return configuration parameter names in Hashtable of Vectors + * where each hashtable entry's key is the substore name, value is a + * Vector of parameter names. If no substore, the parameter name + * is the Hashtable key itself, with value same as key. + */ + public String[] getConfigParams() { + return (mConfigParams); + } + + /** + * prepare this authentication manager for shutdown. + */ + public void shutdown() { + } + + /** + * gets the configuretion substore used by this authentication + * manager + * + * @return configuration store + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + private void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } + + private IRequestQueue getReqQueue() { + IRequestQueue queue = null; + + try { + IRegistrationAuthority ra = (IRegistrationAuthority) + SubsystemRegistry.getInstance().get("ra"); + + if (ra != null) { + queue = ra.getRequestQueue(); + mRequestor = IRequest.REQUESTOR_RA; + } + } catch (Exception e) { + log(ILogger.LL_FAILURE, + " cannot get access to the request queue."); + } + + return queue; + } + + private String hashPassword(String pwd) { + String salt = "lala123"; + byte[] pwdDigest = mSHADigest.digest((salt + pwd).getBytes()); + String b64E = Utils.base64encode(pwdDigest); + + return "{SHA}" + b64E; + } +} diff --git a/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java new file mode 100644 index 000000000..e124f1407 --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/NullAuthentication.java @@ -0,0 +1,161 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.logging.ILogger; + +/** + * This authentication does nothing but just returns an empty authToken. + *

+ * + * @author chrisho + * @version $Revision$, $Date$ + */ +public class NullAuthentication implements IAuthManager { + + /* configuration params to pass to console (none) */ + protected static String[] mConfigParams = null; + + protected static String[] mRequiredCred = {}; + private String mName = null; + private String mImplName = null; + private IConfigStore mConfig = null; + private ILogger mLogger = CMS.getLogger(); + + public NullAuthentication() { + } + + /** + * initializes the NullAuthentication auth manager + *

+ * called by AuthSubsystem init() method, when initializing all available authentication managers. + * + * @param name - Name assigned to this authentication manager instance. + * @param implName - Name of the authentication plugin. + * @param config - The configuration store used by the + * authentication subsystem. + */ + public void init(String name, String implName, IConfigStore config) + throws EBaseException { + mName = name; + mImplName = implName; + mConfig = config; + + log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName)); + } + + /** + * authenticates nothing + *

+ * called by other subsystems or their servlets to authenticate administrators + * + * @param authCred Authentication credentials. + * "uid" and "pwd" are required. + * @return the authentication token (authToken) that contains the following + * userdn = [userdn, in case of success]
+ * authMgrName = [authMgrName]
+ * @exception com.netscape.certsrv.base.MissingCredential If either + * "uid" or "pwd" is missing from the given credentials. + * @exception com.netscape.certsrv.base.InvalidCredentials If the + * the credentials failed to authenticate. + * @exception com.netscape.certsrv.base.EBaseException If an internal + * error occurred. + */ + public IAuthToken authenticate(IAuthCredentials authCred) + throws EMissingCredential, EInvalidCredentials, EBaseException { + AuthToken authToken = new AuthToken(this); + + authToken.set("authType", "NOAUTH"); + + return authToken; + } + + /** + * gets the name of this authentication manager instance + */ + public String getName() { + return mName; + } + + /** + * gets the name of the authentication manager plugin + */ + public String getImplName() { + return mImplName; + } + + /** + * get the list of authentication credential attribute names + * required by this authentication manager. Generally used by + * servlets that use this authentication manager, to retrieve + * required credentials from the user (e.g. Javascript form data) + * + * @return attribute names in Vector + */ + public String[] getRequiredCreds() { + return (mRequiredCred); + } + + /** + * Get the list of configuration parameter names + * required by this authentication manager. In this case, an empty list. + * + * @return String array of configuration parameters. + */ + public String[] getConfigParams() { + return (mConfigParams); + } + + /** + * disconnects the member connection + */ + public void shutdown() { + } + + /** + * gets the configuration substore used by this authentication + * manager + * + * @return configuration store + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + /** + * Log a message. + * + * @param level The logging level. + * @param msg The message to log. + */ + private void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } +} diff --git a/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java new file mode 100644 index 000000000..f20bd5f07 --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/PasswdUserDBAuthentication.java @@ -0,0 +1,274 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import netscape.ldap.LDAPConnection; +import netscape.ldap.LDAPEntry; +import netscape.ldap.LDAPException; +import netscape.ldap.LDAPSearchResults; +import netscape.ldap.LDAPv2; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.ldap.ELdapException; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.usrgrp.IUser; +import com.netscape.cmscore.dbs.DBSubsystem; +import com.netscape.cmscore.ldapconn.LdapAnonConnFactory; +import com.netscape.cmscore.ldapconn.LdapBoundConnFactory; +import com.netscape.cmscore.ldapconn.LdapConnInfo; +import com.netscape.cmscore.usrgrp.UGSubsystem; +import com.netscape.cmscore.util.Debug; + +/** + * Certificate Server admin authentication. + * Used to authenticate administrators in the Certificate Server Console. + * Authentications by checking the uid and password against the + * database. + *

+ * + * @author lhsiao, cfu + * @version $Revision$, $Date$ + */ +public class PasswdUserDBAuthentication implements IAuthManager { + + /* required credentials. uid, pwd are strings */ + public static final String CRED_UID = "uid"; + public static final String CRED_PWD = "pwd"; + protected static String[] mRequiredCred = { CRED_UID, CRED_PWD }; + + /* attribute in returned token */ + public static final String TOKEN_USERDN = "userdn"; + public static final String TOKEN_USERID = "userid"; + + /* configuration params to pass to console (none) */ + protected static String[] mConfigParams = null; + + private String mName = null; + private String mImplName = null; + private IConfigStore mConfig; + private String mBaseDN = null; + private LdapBoundConnFactory mConnFactory = null; + private LdapAnonConnFactory mAnonConnFactory = null; + private ILogger mLogger = CMS.getLogger(); + + public PasswdUserDBAuthentication() { + } + + /** + * initializes the PasswdUserDBAuthentication auth manager + *

+ * called by AuthSubsystem init() method, when initializing all available authentication managers. + * + * @param name - Name assigned to this authentication manager instance. + * @param implName - Name of the authentication plugin. + * @param config - The configuration store used by the + * authentication subsystem. + */ + public void init(String name, String implName, IConfigStore config) + throws EBaseException { + mName = name; + mImplName = implName; + mConfig = config; + + /* internal database directory used */ + DBSubsystem dbs = (DBSubsystem) DBSubsystem.getInstance(); + LdapConnInfo ldapinfo = dbs.getLdapConnInfo(); + if (ldapinfo == null && CMS.isPreOpMode()) + return; + + mBaseDN = dbs.getBaseDN(); + mConnFactory = new LdapBoundConnFactory(3, 20, ldapinfo, dbs.getLdapAuthInfo()); + mAnonConnFactory = new LdapAnonConnFactory(3, 20, ldapinfo); + + log(ILogger.LL_INFO, CMS.getLogMessage("CMSCORE_AUTH_INIT_AUTH", mName)); + } + + /** + * authenticates administratrators by LDAP uid/pwd + *

+ * called by other subsystems or their servlets to authenticate administrators + * + * @param authCred Authentication credentials. + * "uid" and "pwd" are required. + * @return the authentication token (authToken) that contains the following + * userdn = [userdn, in case of success]
+ * authMgrName = [authMgrName]
+ * @exception com.netscape.certsrv.base.MissingCredential If either + * "uid" or "pwd" is missing from the given credentials. + * @exception com.netscape.certsrv.base.InvalidCredentials If the + * the credentials failed to authenticate. + * @exception com.netscape.certsrv.base.EBaseException If an internal + * error occurred. + */ + public IAuthToken authenticate(IAuthCredentials authCred) + throws EMissingCredential, EInvalidCredentials, EBaseException { + AuthToken authToken = new AuthToken(this); + + // make sure the required credentials are provided + String uid = (String) authCred.get(CRED_UID); + CMS.debug("Authentication: UID=" + uid); + if (uid == null) { + log(ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_AUTH_MISSING_UID")); + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_UID)); + } + String pwd = (String) authCred.get(CRED_PWD); + + if (pwd == null) { + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NULL_PW", uid)); + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_PWD)); + } + // don't allow anonymous binding + if (pwd == "") { + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_EMPTY_PW", uid)); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + + String userdn = null; + LDAPConnection conn = null; + LDAPConnection anonConn = null; + + try { + conn = mConnFactory.getConn(); + // do anonymous search for the user's dn. + LDAPSearchResults res = conn.search(mBaseDN, + LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", null, false); + + if (res.hasMoreElements()) { + LDAPEntry entry = (LDAPEntry) res.nextElement(); + + userdn = entry.getDN(); + } + if (userdn == null) { + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_ADMIN_NOT_FOUND", uid)); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + anonConn = mAnonConnFactory.getConn(); + anonConn.authenticate(userdn, pwd); + } catch (LDAPException e) { + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_AUTH_FAILED", uid, e.toString())); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } finally { + if (conn != null) + mConnFactory.returnConn(conn); + if (anonConn != null) + mAnonConnFactory.returnConn(anonConn); + } + + UGSubsystem ug = UGSubsystem.getInstance(); + + authToken.set(TOKEN_USERDN, userdn); + authToken.set(CRED_UID, uid); // return original uid for info + + IUser user = null; + + try { + user = ug.getUser(uid); + } catch (EBaseException e) { + if (Debug.ON) + e.printStackTrace(); + // not a user in our user/group database. + log(ILogger.LL_SECURITY, CMS.getLogMessage("CMSCORE_AUTH_UID_NOT_FOUND", uid, e.toString())); + throw new EInvalidCredentials(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_CREDENTIAL")); + } + authToken.set(TOKEN_USERDN, user.getUserDN()); + authToken.set(TOKEN_USERID, user.getUserID()); + log(ILogger.LL_INFO, CMS.getLogMessage("CMS_AUTH_AUTHENTICATED", uid)); + + return authToken; + } + + /** + * gets the name of this authentication manager instance + */ + public String getName() { + return mName; + } + + /** + * gets the name of the authentication manager plugin + */ + public String getImplName() { + return mImplName; + } + + /** + * get the list of authentication credential attribute names + * required by this authentication manager. Generally used by + * servlets that use this authentication manager, to retrieve + * required credentials from the user (e.g. Javascript form data) + * + * @return attribute names in Vector + */ + public String[] getRequiredCreds() { + return (mRequiredCred); + } + + /** + * Get the list of configuration parameter names + * required by this authentication manager. In this case, an empty list. + * + * @return String array of configuration parameters. + */ + public String[] getConfigParams() { + return (mConfigParams); + } + + /** + * disconnects the member connection + */ + public void shutdown() { + try { + // disconnect all outstanding connections in the factory + mConnFactory.reset(); + mConnFactory = null; + } catch (ELdapException e) { + log(ILogger.LL_FAILURE, e.toString()); + } + } + + /** + * gets the configuretion substore used by this authentication + * manager + * + * @return configuration store + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + /** + * Log a message. + * + * @param level The logging level. + * @param msg The message to log. + */ + private void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } +} diff --git a/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java b/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java new file mode 100644 index 000000000..3f0d7a87b --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/SSLClientCertAuthentication.java @@ -0,0 +1,291 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +// ldap java sdk + +// cert server imports. +import java.math.BigInteger; +import java.security.Principal; +import java.security.cert.X509Certificate; + +import netscape.security.x509.X509CertImpl; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; +import com.netscape.certsrv.authentication.EAuthUserError; +import com.netscape.certsrv.authentication.EInvalidCredentials; +import com.netscape.certsrv.authentication.EMissingCredential; +import com.netscape.certsrv.authentication.IAuthCredentials; +import com.netscape.certsrv.authentication.IAuthManager; +import com.netscape.certsrv.authentication.IAuthToken; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.ca.ICertificateAuthority; +import com.netscape.certsrv.dbs.certdb.ICertRecord; +import com.netscape.certsrv.dbs.certdb.ICertificateRepository; +import com.netscape.certsrv.logging.ILogger; +import com.netscape.certsrv.ra.IRegistrationAuthority; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.IRequestQueue; +import com.netscape.certsrv.request.RequestStatus; +import com.netscape.cmscore.util.Debug; + +/** + * SSL client based authentication. + *

+ * + * @author chrisho + * @version $Revision$, $Date$ + */ +public class SSLClientCertAuthentication implements IAuthManager { + + /* required credential to authenticate, client certificate */ + public static final String CRED_CERT = IAuthManager.CRED_SSL_CLIENT_CERT; + public static final String SERIALNUMBER = "serialNumber"; + public static final String ISSUERDN = "issuerDN"; + protected static String[] mRequiredCreds = { CRED_CERT }; + + private ICertificateAuthority mCA = null; + private ICertificateRepository mCertDB = null; + private ILogger mLogger = CMS.getLogger(); + private String mName = null; + private String mImplName = null; + private IConfigStore mConfig = null; + private String mRequestor = null; + + /* Holds configuration parameters accepted by this implementation. + * This list is passed to the configuration console so configuration + * for instances of this implementation can be configured through the + * console. + */ + protected static String[] mConfigParams = + new String[] {}; + + /** + * Default constructor, initialization must follow. + */ + public SSLClientCertAuthentication() { + super(); + } + + public void init(String name, String implName, IConfigStore config) + throws EBaseException { + mName = name; + mImplName = implName; + mConfig = config; + + log(ILogger.LL_INFO, CMS.getLogMessage("INIT_DONE", name)); + } + + public IAuthToken authenticate(IAuthCredentials authCred) + throws EMissingCredential, EInvalidCredentials, EBaseException { + + AuthToken authToken = new AuthToken(this); + + CMS.debug("SSLCertAuth: Retrieving client certificates"); + X509Certificate[] x509Certs = + (X509Certificate[]) authCred.get(CRED_CERT); + + if (x509Certs == null) { + CMS.debug("SSLCertAuth: No client certificate found"); + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSCORE_AUTH_MISSING_CERT")); + throw new EMissingCredential(CMS.getUserMessage("CMS_AUTHENTICATION_NULL_CREDENTIAL", CRED_CERT)); + } + CMS.debug("SSLCertAuth: Got client certificate"); + + mCA = (ICertificateAuthority) CMS.getSubsystem("ca"); + + if (mCA != null) { + mCertDB = (ICertificateRepository) mCA.getCertificateRepository(); + } + + X509CertImpl clientCert = (X509CertImpl) x509Certs[0]; + + BigInteger serialNum = null; + + try { + serialNum = (BigInteger) clientCert.getSerialNumber(); + //serialNum = new BigInteger(s.substring(2), 16); + } catch (NumberFormatException e) { + throw new EAuthUserError(CMS.getUserMessage("CMS_AUTHENTICATION_INVALID_ATTRIBUTE_VALUE", + "Invalid serial number.")); + } + + String clientCertIssuerDN = clientCert.getIssuerDN().toString(); + + if (mCertDB != null) { /* is CA */ + ICertRecord record = null; + + try { + record = (ICertRecord) mCertDB.readCertificateRecord(serialNum); + } catch (EBaseException ee) { + if (Debug.ON) { + Debug.trace(ee.toString()); + } + } + if (record != null) { + String status = record.getStatus(); + + if (status.equals("VALID")) { + + X509CertImpl cacert = mCA.getCACert(); + Principal p = cacert.getSubjectDN(); + + if (!p.toString().equals(clientCertIssuerDN)) { + throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ISSUER_NAME")); + } + } else { + throw new EBaseException( + CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", status)); + } + } else { + throw new EBaseException(CMS.getUserMessage("CMS_BASE_CERT_NOT_FOUND")); + } + } else { + + /* + * ra, build a request and send through the connection for + * authentication + */ + IRequestQueue queue = getReqQueue(); + + if (queue != null) { + IRequest getCertStatusReq = null; + + getCertStatusReq = + queue.newRequest(IRequest.GETCERT_STATUS_REQUEST); + // pass just serial number instead of whole cert + if (serialNum != null) { + getCertStatusReq.setExtData(SERIALNUMBER, serialNum); + getCertStatusReq.setExtData(ISSUERDN, clientCertIssuerDN); + } + queue.processRequest(getCertStatusReq); + // check request status... + RequestStatus status = getCertStatusReq.getRequestStatus(); + + if (status == RequestStatus.COMPLETE) { + String certStatus = + getCertStatusReq.getExtDataInString(IRequest.CERT_STATUS); + + if (certStatus == null) { + String[] params = { "null status" }; + + throw new EBaseException( + CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", params)); + } else if (certStatus.equals("INVALIDCERTROOT")) { + throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ISSUER_NAME")); + } else if (!certStatus.equals("VALID")) { + String[] params = { status.toString() }; + + throw new EBaseException( + CMS.getUserMessage("CMS_BASE_INVALID_CERT_STATUS", params)); + } + } else { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSCORE_AUTH_INCOMPLETE_REQUEST")); + throw new EBaseException(CMS.getUserMessage("CMS_BASE_REQUEST_IN_BAD_STATE")); + } + } else { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("CMSCORE_AUTH_FAILED_GET_QUEUE")); + throw new EBaseException(CMS.getUserMessage("CMS_BASE_GET_QUEUE_FAILED")); + } + } // else, ra + + authToken.set(AuthToken.TOKEN_CERT, clientCert); + + return authToken; + } + + /** + * prepare this authentication manager for shutdown. + */ + public void shutdown() { + } + + /** + * Returns a list of configuration parameter names. + * The list is passed to the configuration console so instances of + * this implementation can be configured through the console. + * + * @return String array of configuration parameter names. + */ + public String[] getConfigParams() { + return (mConfigParams); + } + + /** + * Returns array of required credentials for this authentication manager. + * + * @return Array of required credentials. + */ + public String[] getRequiredCreds() { + return mRequiredCreds; + } + + private void log(int level, String msg) { + if (mLogger == null) + return; + mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_AUTHENTICATION, + level, msg); + } + + private IRequestQueue getReqQueue() { + IRequestQueue queue = null; + + try { + IRegistrationAuthority ra = + (IRegistrationAuthority) CMS.getSubsystem("ra"); + + if (ra != null) { + queue = ra.getRequestQueue(); + mRequestor = IRequest.REQUESTOR_RA; + } + } catch (Exception e) { + log(ILogger.LL_FAILURE, + " cannot get access to the request queue."); + } + + return queue; + } + + /** + * Gets the configuration substore used by this authentication manager + * + * @return configuration store + */ + public IConfigStore getConfigStore() { + return mConfig; + } + + /** + * gets the name of this authentication manager instance + */ + public String getName() { + return mName; + } + + /** + * gets the plugin name of this authentication manager. + */ + public String getImplName() { + return mImplName; + } +} diff --git a/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java b/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java new file mode 100644 index 000000000..173d69f89 --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/VerifiedCert.java @@ -0,0 +1,90 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import java.math.BigInteger; +import java.util.Date; + +import com.netscape.certsrv.apps.CMS; + +/** + * class storing verified certificate. + * + * @version $Revision$, $Date$ + */ + +public class VerifiedCert { + public static final int CHECKED = 4; + public static final int EXPIRED = 3; + public static final int NOT_REVOKED = 2; + public static final int REVOKED = 1; + public static final int UNKNOWN = 0; + + private int mStatus = UNKNOWN; + private Date mCreated = null; + private BigInteger mSerialNumber = null; + private byte[] mCertEncoded = null; + + /** + * Constructs verified certiificate record + */ + + public VerifiedCert(BigInteger serialNumber, byte[] certEncoded, + int status) { + mStatus = status; + mSerialNumber = serialNumber; + mCertEncoded = certEncoded; + mCreated = CMS.getCurrentDate(); + } + + public int check(BigInteger serialNumber, byte[] certEncoded, + long interval, long unknownStateInterval) { + int status = UNKNOWN; + + if (mSerialNumber.equals(serialNumber)) { + if (mCertEncoded != null) { + if (certEncoded != null && + mCertEncoded.length == certEncoded.length) { + int i; + + for (i = 0; i < mCertEncoded.length; i++) { + if (mCertEncoded[i] != certEncoded[i]) + break; + } + if (i >= mCertEncoded.length) { + Date expires = new Date(mCreated.getTime() + (interval * 1000)); + Date now = CMS.getCurrentDate(); + + if (now.after(expires)) + mStatus = EXPIRED; + status = mStatus; + } + } + } else if (unknownStateInterval > 0) { + Date expires = new Date(mCreated.getTime() + (unknownStateInterval * 1000)); + Date now = CMS.getCurrentDate(); + + if (now.after(expires)) + mStatus = EXPIRED; + status = mStatus; // CHECKED + } + } + + return status; + } +} diff --git a/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java b/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java new file mode 100644 index 000000000..52ce91fdf --- /dev/null +++ b/base/common/src/com/netscape/cmscore/authentication/VerifiedCerts.java @@ -0,0 +1,158 @@ +// --- BEGIN COPYRIGHT BLOCK --- +// This program 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; version 2 of the License. +// +// This program 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 along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (C) 2007 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- +package com.netscape.cmscore.authentication; + +import java.math.BigInteger; + +import netscape.security.x509.X509CertImpl; + +/** + * class storing verified certificates. + * + * @version $Revision$, $Date$ + */ + +public class VerifiedCerts { + + /* the value type of the dn component */ + private int mFirst = 0; + private int mLast = 0; + private int mNext = 0; + private VerifiedCert[] mVCerts = null; + private long mInterval = 0; + private long mUnknownStateInterval = 0; + + /** + * Constructs verified certiificates list + */ + + public VerifiedCerts(int size, long interval) { + mVCerts = new VerifiedCert[size]; + mInterval = interval; + mUnknownStateInterval = interval; + } + + public VerifiedCerts(int size, long interval, long unknownStateInterval) { + mVCerts = new VerifiedCert[size]; + mInterval = interval; + mUnknownStateInterval = unknownStateInterval; + } + + public void update(X509CertImpl cert, int status) { + if (cert != null) { + byte[] certEncoded = null; + + try { + certEncoded = cert.getEncoded(); + } catch (Exception e) { + } + if ((certEncoded != null || + (status == VerifiedCert.CHECKED && mUnknownStateInterval > 0)) + && mInterval > 0) { + update(cert.getSerialNumber(), certEncoded, status); + } + } + } + + public synchronized void update(BigInteger serialNumber, byte[] certEncoded, int status) { + if ((status == VerifiedCert.NOT_REVOKED || + status == VerifiedCert.REVOKED || + (status == VerifiedCert.CHECKED && mUnknownStateInterval > 0)) + && mInterval > 0) { + if (mLast == mNext && mFirst == mNext) { // empty + mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status); + mNext = next(mNext); + } else if (mFirst == mNext) { // full + mFirst = next(mFirst); + mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status); + mLast = mNext; + mNext = next(mNext); + } else { + mVCerts[mNext] = new VerifiedCert(serialNumber, certEncoded, status); + mLast = mNext; + mNext = next(mNext); + } + } + } + + public int check(X509CertImpl cert) { + int status = VerifiedCert.UNKNOWN; + + if (mLast != mNext && mInterval > 0) { // if not empty and + if (cert != null) { + byte[] certEncoded = null; + + try { + certEncoded = cert.getEncoded(); + } catch (Exception e) { + } + if (certEncoded != null) { + status = check(cert.getSerialNumber(), certEncoded); + } + } + } + + return status; + } + + public synchronized int check(BigInteger serialNumber, byte[] certEncoded) { + int status = VerifiedCert.UNKNOWN; + int i = mLast; + + if (mVCerts != null && mLast != mNext && mInterval > 0) { // if not empty and + while (status == VerifiedCert.UNKNOWN) { + if (mVCerts[i] == null) + return status; + status = mVCerts[i].check(serialNumber, certEncoded, + mInterval, mUnknownStateInterval); + if (status == VerifiedCert.EXPIRED) { + if (mFirst == mLast) + mNext = mLast; + else + mFirst = next(i); + break; + } else if (mFirst == i) { + break; + } else { + i = previous(i); + } + } + if (status == VerifiedCert.UNKNOWN) + status = mVCerts[i].check(serialNumber, certEncoded, + mInterval, mUnknownStateInterval); + } + + return status; + } + + private int next(int i) { + i++; + if (i >= mVCerts.length) + i = 0; + + return i; + } + + private int previous(int i) { + if (i <= 0) + i = mVCerts.length; + i--; + + return i; + } +} -- cgit