001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)JavaStdKeyStoreManager.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: /**
030: * JavaStdKeyStoreManager.java
031: *
032: * SUN PROPRIETARY/CONFIDENTIAL.
033: * This software is the proprietary information of Sun Microsystems, Inc.
034: * Use is subject to license terms.
035: *
036: * Created on October 24, 2004, 12:35 AM
037: */package com.sun.jbi.internal.security.keymgt;
038:
039: import com.sun.enterprise.security.jauth.callback.*;
040:
041: import com.sun.jbi.StringTranslator;
042: import com.sun.jbi.internal.security.Constants;
043:
044: import java.security.cert.CertStore;
045: import java.security.cert.CollectionCertStoreParameters;
046: import java.security.KeyStore;
047: import java.util.Properties;
048: import java.util.logging.Logger;
049: import java.io.FileInputStream;
050:
051: import javax.security.auth.callback.Callback;
052: import javax.security.auth.callback.CallbackHandler;
053: import javax.security.auth.callback.UnsupportedCallbackException;
054:
055: /**
056: *
057: * @author Sun Microsystems, Inc.
058: */
059: public class JavaStdKeyStoreManager implements
060: com.sun.jbi.internal.security.KeyStoreManager {
061: /** The KeyStore. */
062: private KeyStore mKeyStore;
063:
064: /** The KeyStore Passphrase. */
065: private String mKeyStorePass;
066:
067: /** The TrustStore Passphrase. */
068: private String mTrustStorePass;
069:
070: /** The TrustStore. */
071: private KeyStore mTrustStore;
072:
073: /** The Certificate Store. */
074: private CertStore mCertStore;
075:
076: /** The context. */
077: private Properties mProps;
078:
079: /** KeyStoreManager Name. */
080: private String mName;
081:
082: /** The StringTranslator. */
083: private StringTranslator mTranslator;
084:
085: /** Key Store Init flag. */
086: private boolean mIsKeyStoreInitialized;
087:
088: /** Trust Store Init flag. */
089: private boolean mIsTrustStoreInitialized;
090:
091: /** Cert Store Init flag. */
092: private boolean mIsCertStoreInitialized;
093:
094: /** Type. */
095: private String mType;
096:
097: /** Constructor. */
098: public JavaStdKeyStoreManager() {
099: Logger mLogger = Logger
100: .getLogger(com.sun.jbi.internal.security.Constants.PACKAGE);
101: mIsCertStoreInitialized = false;
102: mIsTrustStoreInitialized = false;
103: mIsKeyStoreInitialized = false;
104: }
105:
106: /**
107: * Get the Type String.
108: * In Shasta 1.0 we support "JavaStandard" which encompasses : JKS, PKCS12, JCEKS
109: * and "SJSAS" which implies the Application Server environment.
110: *
111: * @return manager type
112: */
113: public String getType() {
114: return mType;
115: }
116:
117: /**
118: * Set the type string.
119: *
120: * @param type is the type.
121: */
122: public void setType(String type) {
123: mType = type;
124: }
125:
126: /**
127: * Get the name of the KeyStoreManager.
128: * @return the name of KeyStoreManager
129: */
130: public String getName() {
131: return mName;
132: }
133:
134: /**
135: * Set the User KeyStoreManager.
136: * @param name is the name of the KeyStoreManager
137: */
138: public void setName(String name) {
139: mName = name;
140: }
141:
142: /**
143: * Set the StringTranslator on the Plugin. The StringTranslator
144: * is created for the package the plugin belongs to.
145: *
146: * @param translator is the StringTranslator to use.
147: */
148: public void setStringTranslator(StringTranslator translator) {
149: mTranslator = translator;
150: }
151:
152: /**
153: * @return a KeyStore instance. This KeyStore has the Private Keys.
154: */
155: public KeyStore getKeyStore() {
156: if (!mIsKeyStoreInitialized) {
157: initializeKeyStore(mProps);
158: }
159: return mKeyStore;
160: }
161:
162: /**
163: * @return a TrustStore instance. This KeyStore has the Public Key Certificates and
164: * Trusted CA Certificates.
165: */
166: public KeyStore getTrustStore() {
167: if (!mIsTrustStoreInitialized) {
168: initializeTrustStore(mProps);
169: }
170: return mTrustStore;
171: }
172:
173: /**
174: * @return the password required for accessing the Trust Store
175: */
176: /*public String geyTrustStorePassword()
177: {
178: return mTrustStorePass;
179: }*/
180:
181: /**
182: * Initialize this KeyStore Service.
183: *
184: * @param initProperties are the Properties specified for the Service
185: * @throws IllegalStateException if the domain cannot be initialized
186: */
187: public void initialize(Properties initProperties)
188: throws IllegalStateException {
189: mProps = initProperties;
190: }
191:
192: /**
193: * Initialize the Keystore.
194: *
195: * @param props the Properties which are required for initialization. This
196: * particualr instance of the service looks for the properties keystore.url,
197: * keystore.type and keystore.password
198: */
199: public synchronized void initializeKeyStore(Properties props) {
200: // -- This is to take care of the condition where there
201: // -- are two threads which check if key store is initialized,
202: // -- one thread would then initialize the store, then the other
203: // -- would attempt to initialize as well, this check avoids re-initialization.
204: // -- The init status check could be synchronized too but that would slow things.
205: if (mIsKeyStoreInitialized) {
206: return;
207: }
208: String keyStoreURL = (String) props
209: .getProperty(Constants.PARAM_KEYSTORE_LOCATION);
210: String keyStoreType = (String) props
211: .getProperty(Constants.PARAM_KEYSTORE_TYPE);
212: String keyStorePass = (String) props
213: .getProperty(Constants.PARAM_KEYSTORE_PASS);
214:
215: if ((keyStoreURL == null) || (keyStoreType == null)
216: || (keyStorePass == null)) {
217: String missingParam = new String(
218: Constants.PARAM_KEYSTORE_LOCATION + " / "
219: + Constants.PARAM_KEYSTORE_TYPE + " / "
220: + Constants.PARAM_KEYSTORE_PASS);
221: String errMsg = null;
222: if (mTranslator != null) {
223: errMsg = mTranslator.getString(
224: LocalStringConstants.BC_ERR_KS_MISSING_PARAM,
225: missingParam, getName());
226: } else {
227: errMsg = "One of the parameters "
228: + missingParam
229: + " required to initialize the KeyStore for JavaStdKeyStoreManager "
230: + getName()
231: + " is missing, JavaStdKeyStoreManager "
232: + "is in invalid state.";
233: }
234: throw new IllegalStateException(errMsg);
235: }
236:
237: try {
238: mKeyStore = KeyStore.getInstance(keyStoreType);
239: mKeyStore.load(new FileInputStream(keyStoreURL),
240: keyStorePass.toCharArray());
241: mKeyStorePass = keyStorePass;
242: mIsKeyStoreInitialized = true;
243: } catch (Exception ex) {
244: String errMsg = null;
245: if (mTranslator != null) {
246: errMsg = mTranslator.getString(
247: LocalStringConstants.BC_ERR_KS_INIT_FAILED,
248: getName(), ex.toString());
249: } else {
250: errMsg = "A problem occured in initializing the"
251: + " KeyStore for JavaStdKeyStoreManager "
252: + getName() + " error details: "
253: + ex.toString();
254: }
255: throw new IllegalStateException(errMsg);
256: }
257: }
258:
259: /**
260: * Initialize the TrustStore.
261: *
262: * @param props the Properties which are required for initialization. This
263: * particualr instance of the service looks for the properties keystore.url,
264: * keystore.type and keystore.password
265: */
266: public synchronized void initializeTrustStore(Properties props) {
267: // -- This is to take care of the condition where there
268: // -- are two threads which check if cert store is initialized,
269: // -- one thread would then initialize the store, then the other
270: // -- would attempt to initialize as well, this check avoids re-initialization.
271: // -- The init status cjeck could be synchronized too but that would slow things.
272: if (mIsTrustStoreInitialized) {
273: return;
274: }
275: String trustStoreURL = (String) props
276: .getProperty(Constants.PARAM_TRUSTSTORE_LOCATION);
277: String trustStoreType = (String) props
278: .getProperty(Constants.PARAM_TRUSTSTORE_TYPE);
279: String trustStorePass = (String) props
280: .getProperty(Constants.PARAM_TRUSTSTORE_PASS);
281:
282: if ((trustStoreURL == null) || (trustStoreType == null)
283: || (trustStorePass == null)) {
284: String missingParam = new String(
285: Constants.PARAM_TRUSTSTORE_LOCATION + " / "
286: + Constants.PARAM_TRUSTSTORE_TYPE + " / "
287: + Constants.PARAM_TRUSTSTORE_PASS);
288: String errMsg = null;
289: if (mTranslator != null) {
290: errMsg = mTranslator.getString(
291: LocalStringConstants.BC_ERR_TS_MISSING_PARAM,
292: missingParam, getName());
293: } else {
294: errMsg = "One of the parameters "
295: + missingParam
296: + " required to initialize the TrustStore for JavaStdKeyStoreManager"
297: + " "
298: + getName()
299: + " is missing, JavaStdKeyStoreManager is in invalid state.";
300: }
301: throw new IllegalStateException(errMsg);
302: }
303:
304: try {
305: mTrustStore = KeyStore.getInstance(trustStoreType);
306: mTrustStore.load(new FileInputStream(trustStoreURL),
307: trustStorePass.toCharArray());
308: mTrustStorePass = trustStorePass;
309: mIsTrustStoreInitialized = true;
310: } catch (Exception ex) {
311: String errMsg = null;
312: if (mTranslator != null) {
313: errMsg = mTranslator.getString(
314: LocalStringConstants.BC_ERR_TS_INIT_FAILED,
315: getName(), ex.toString());
316: } else {
317: errMsg = "A problem occured in initializing the"
318: + " TrustStore for JavaStdKeyStoreManager "
319: + getName() + " error details: "
320: + ex.toString();
321: }
322: throw new IllegalStateException(errMsg);
323: }
324: }
325:
326: /**
327: * Get the Certificate Store. This gets all the client certificates from the Trust
328: * Store and returns the Certificate store.
329: *
330: * @return a CertificateStore instance, this store has the client certificates which
331: * will be used in verifying a certification path.
332: */
333: public CertStore getCertStore() {
334: if (!mIsCertStoreInitialized) {
335: initializeCertStore();
336: }
337: return mCertStore;
338: }
339:
340: /**
341: * Initialize Certificate Store.
342: */
343: private synchronized void initializeCertStore() {
344: // -- This is to take care of the condition where there
345: // -- are two threads which check if cert store is initialized,
346: // -- one thread would then initialize the store, then the other
347: // -- would attempt to initialize as well, this check avoids re-initialization.
348: // -- The init status cjeck could be synchronized too but that would slow things.
349: if (mIsCertStoreInitialized) {
350: return;
351: }
352:
353: KeyStore ts = getTrustStore();
354: java.util.List list = new java.util.ArrayList();
355: try {
356: java.util.Enumeration aliases = ts.aliases();
357: while (aliases.hasMoreElements()) {
358: String alias = (String) aliases.nextElement();
359: if (ts.isCertificateEntry(alias)) {
360: list.add(ts.getCertificate(alias));
361: }
362: }
363:
364: // -- Create the CertStore
365: mCertStore = CertStore.getInstance("Collection",
366: new CollectionCertStoreParameters(list));
367: mIsCertStoreInitialized = true;
368: } catch (Exception ex) {
369: String errMsg = null;
370: if (mTranslator != null) {
371: errMsg = mTranslator.getString(
372: LocalStringConstants.BC_ERR_CS_INIT_FAILED,
373: getName(), ex.toString());
374: } else {
375: errMsg = "A problem occured in initializing the"
376: + " CertStore for JavaStdKeyStoreManager "
377: + getName() + " error details: "
378: + ex.toString();
379: }
380: throw new IllegalStateException(errMsg);
381: }
382: }
383:
384: /**
385: * Reload the Key / Trust Stores.
386: *
387: * @throws IllegalStateException if the information cannot be reloaded
388: */
389: public void reload() throws IllegalStateException {
390: initialize(mProps);
391: }
392:
393: /**
394: * The implementation on the CallbackHandlerInterface. This class supports
395: * CertStoreCallback, PrivateKeyCallback, SecretKeyCallback & TrustStoreCallback
396: *
397: * @param callbacks - array of Callbacks to be handled.
398: * @throws java.io.IOException - if an input or output error occurs.
399: * @throws UnsupportedCallbackException - if the implementation of this method
400: * does not support one or more of the Callbacks specified in the callbacks
401: * parameter.
402: */
403: public void handle(Callback[] callbacks)
404: throws java.io.IOException, UnsupportedCallbackException {
405: for (int i = 0; i < callbacks.length; i++) {
406: CallbackHandler handler = null;
407:
408: if (callbacks[i] instanceof CertStoreCallback) {
409: handler = new com.sun.jbi.internal.security.callback.CertStoreCallbackHandler(
410: this );
411: } else if (callbacks[i] instanceof PrivateKeyCallback) {
412: handler = new com.sun.jbi.internal.security.callback.PrivateKeyCallbackHandler(
413: this );
414: } else if (callbacks[i] instanceof SecretKeyCallback) {
415: handler = new com.sun.jbi.internal.security.callback.SecretKeyCallbackHandler(
416: this );
417: } else if (callbacks[i] instanceof TrustStoreCallback) {
418: handler = new com.sun.jbi.internal.security.callback.TrustStoreCallbackHandler(
419: this );
420: } else {
421: throw new UnsupportedCallbackException(callbacks[i]);
422: }
423:
424: // -- Handle the request
425: handler.handle(new Callback[] { callbacks[i] });
426: }
427: }
428:
429: /**
430: * @return the password required for accessing the KeyStore
431: */
432: public String getKeyStorePassword() {
433: return mKeyStorePass;
434: }
435:
436: }
|