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: * @(#)SSLClientKeyManager.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: /**
030: * SSLClientKeyManager.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 November 20, 2004, 10:36 PM
037: */package com.sun.jbi.internal.security.https;
038:
039: import com.sun.jbi.StringTranslator;
040: import com.sun.jbi.internal.security.KeyStoreManager;
041: import com.sun.enterprise.security.jauth.callback.PrivateKeyCallback;
042:
043: import java.security.Principal;
044: import java.security.KeyStoreException;
045: import java.security.PrivateKey;
046: import java.security.cert.Certificate;
047: import java.security.cert.X509Certificate;
048:
049: import javax.security.auth.callback.Callback;
050: import javax.net.ssl.X509KeyManager;
051: import java.util.logging.Logger;
052: import java.util.Vector;
053:
054: /**
055: * This is an implementation of the X509KeyManger, an instance of which is
056: * initialized for a particular alias and can be passed to
057: * the SSLContext.init() method. This is done when the SSL configuration
058: * specifies that a particular client alias is to be used for Client Authentication.
059: *
060: * @author Sun Microsystems, Inc.
061: */
062: public class SSLClientKeyManager implements X509KeyManager {
063:
064: /** The alias. */
065: private String mAlias;
066:
067: /** The Public Key Type. */
068: private String mKeyType;
069:
070: /** The Name of the issuer. */
071: private Principal mIssuer;
072:
073: /** The Logger. */
074: private Logger mLogger;
075:
076: /** The String Translator. */
077: private StringTranslator mTranslator;
078:
079: /** The Private Key. */
080: private PrivateKey mPrivateKey;
081:
082: /** The Public Key Cert Chain. */
083: private Certificate[] mCertChain;
084:
085: /** The Public Key Certificate. */
086: private X509Certificate mCert;
087:
088: /**
089: * Creates a new instance of SSLClientKeyManager.
090: *
091: * @param ksMgr is KeyStoreManager, which is the source of
092: * the private Key and Certificate for the alias.
093: * @param translator is the StringTranslator
094: * @param alias is the alias
095: * @throws KeyStoreException if there are problems in getting the
096: * Client Key/Certificate
097: */
098: public SSLClientKeyManager(KeyStoreManager ksMgr, String alias,
099: StringTranslator translator) throws KeyStoreException {
100: mLogger = Logger
101: .getLogger(com.sun.jbi.internal.security.Constants.PACKAGE);
102: mTranslator = translator;
103: mAlias = alias;
104:
105: getPrivateKeyCertPair(alias, ksMgr);
106: mKeyType = mCert.getPublicKey().getAlgorithm();
107: mIssuer = mCert.getIssuerX500Principal();
108:
109: }
110:
111: /**
112: *
113: * @param str the key algorithm type name(s), ordered with the most-preferred
114: * key type first.
115: * @param principal issuers the list of acceptable CA issuer subject names or null
116: * if it does not matter which issuers are used.
117: * @param socket the socket to be used for this connection. This parameter can be
118: * null, in which case this method will return the most generic alias to use.
119: * @return the alias name for the desired key, or null if there are no matches.
120: */
121:
122: public String chooseClientAlias(String[] str,
123: java.security.Principal[] principal, java.net.Socket socket) {
124: for (int s = 0; s < str.length; s++) {
125: if (mKeyType.equals(str[s])) {
126: if (principal == null) {
127: return mAlias;
128: }
129: for (int p = 0; p < principal.length; p++) {
130: if (mIssuer.equals(principal[p])) {
131: return mAlias;
132: }
133: }
134: }
135: }
136: return null;
137: }
138:
139: /**
140: * This method should never be called, as we can only control the client side
141: * of the SSL connection since the server connections are managed by the HTTP
142: * Listener.
143: *
144: * @param keyType the key algorithm type name(s), ordered with the most-preferred
145: * key type first.
146: * @param principal issuers the list of acceptable CA issuer subject names or null
147: * if it does not matter which issuers are used.
148: * @param socket the socket to be used for this connection. This parameter can be
149: * null, in which case this method will return the most generic alias to use.
150: * @return the alias name for the desired key, or null if there are no matches.
151: */
152: public String chooseServerAlias(String keyType,
153: java.security.Principal[] principal, java.net.Socket socket) {
154: String[] keyTypes = { keyType };
155: return chooseClientAlias(keyTypes, principal, socket);
156: }
157:
158: /**
159: *
160: * @param alias is the Alias name
161: * @return the certificate chain associated with the given alias.
162: */
163: public X509Certificate[] getCertificateChain(String alias) {
164: Vector x509Certs = new Vector();
165: if (mCertChain != null) {
166: for (int c = 0; c < mCertChain.length; c++) {
167: x509Certs.add(mCertChain[c]);
168: }
169:
170: return ((X509Certificate[]) x509Certs
171: .toArray(new X509Certificate[1]));
172: }
173: return null;
174: }
175:
176: /**
177: * Get the matching aliases for authenticating the client side of a secure socket
178: * given the public key type and the list of certificate issuer authorities
179: * recognized by the peer (if any).
180: *
181: * @param keyType is the key algorithm type name
182: * @param principal is the list of acceptable CA issuer subject names, or null if
183: * it does not matter which issuers are used.
184: * @return an array of the matching alias names, or null if there were no matches.
185: */
186: public String[] getClientAliases(String keyType,
187: java.security.Principal[] principal) {
188: String[] keyTypes = { keyType };
189: String alias = chooseClientAlias(keyTypes, principal, null);
190: if (alias == null) {
191: return new String[0];
192: } else {
193: String[] aliases = new String[1];
194: aliases[0] = alias;
195: return aliases;
196: }
197: }
198:
199: /**
200: *
201: * @param alias is the alias name.
202: * @return the key associated with the given alias.
203: */
204: public PrivateKey getPrivateKey(String alias) {
205: try {
206: return mPrivateKey;
207: } catch (Exception ksex) {
208: mLogger.severe(mTranslator.getString(
209: HttpConstants.BC_ERR_GET_PRIVATE_KEY_FAILED,
210: mAlias, ksex.toString()));
211: return null;
212: }
213:
214: }
215:
216: /**
217: * Get the matching aliases for authenticating the server side of a secure socket
218: * given the public key type and the list of certificate issuer authorities
219: * recognized by the peer (if any).
220: *
221: * @param keyType is the key algorithm type name
222: * @param principal is the list of acceptable CA issuer subject names, or null if
223: * it does not matter which issuers are used.
224: * @return an array of the matching alias names, or null if there were no matches.
225: */
226: public String[] getServerAliases(String keyType,
227: java.security.Principal[] principal) {
228: return getClientAliases(keyType, principal);
229: }
230:
231: /**
232: * Get the Private Key and Cert. Chain for the alias
233: *
234: * @param alias is the alias for whom the Private Key / Certificate pair
235: * is to be retrieved.
236: * @param ksMgr the KeyStoreManager which has the Private Key / Public Key Cert info.
237: * @throws KeyStoreException if the Private Key / Certificate pair information
238: * cannot be retrieved.
239: */
240: private void getPrivateKeyCertPair(String alias,
241: KeyStoreManager ksMgr) throws KeyStoreException {
242: PrivateKeyCallback pkCB = new PrivateKeyCallback(
243: new PrivateKeyCallback.AliasRequest(alias));
244: try {
245: ksMgr.handle(new Callback[] { pkCB });
246: } catch (Exception ex) {
247: throw new KeyStoreException(ex.toString());
248: }
249:
250: mPrivateKey = pkCB.getKey();
251: mCertChain = pkCB.getChain();
252: if (mCertChain != null) {
253: mCert = (X509Certificate) mCertChain[0];
254: }
255:
256: if (mPrivateKey == null || mCertChain == null) {
257: String errMsg = mTranslator.getString(
258: HttpConstants.BC_ERR_MISSING_PRIVATE_KEY, ksMgr
259: .getName(), ksMgr.getType(), mAlias);
260: mLogger.severe(errMsg);
261: throw new KeyStoreException(errMsg);
262: }
263:
264: }
265:
266: }
|