001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris Kuznetsov
020: * @version $Revision$
021: */package org.apache.harmony.xnet.provider.jsse;
022:
023: import java.net.Socket;
024: import java.security.KeyStore;
025: import java.security.KeyStoreException;
026: import java.security.NoSuchAlgorithmException;
027: import java.security.Principal;
028: import java.security.PrivateKey;
029: import java.security.UnrecoverableEntryException;
030: import java.security.cert.Certificate;
031: import java.security.cert.X509Certificate;
032: import java.util.Enumeration;
033: import java.util.Hashtable;
034: import java.util.Vector;
035:
036: import javax.net.ssl.SSLEngine;
037: import javax.net.ssl.X509ExtendedKeyManager;
038: import javax.security.auth.x500.X500Principal;
039:
040: /**
041: * KeyManager implementation.
042: * This implementation uses hashed key store information.
043: * It works faster than retrieving all of the data from the key store.
044: * Any key store changes, that happen after key manager was created, have no effect.
045: * The implementation does not use peer information (host, port)
046: * that may be obtained from socket or engine.
047: *
048: * @see javax.net.ssl.KeyManager
049: *
050: */
051: public class KeyManagerImpl extends X509ExtendedKeyManager {
052:
053: // hashed key store information
054: private final Hashtable hash = new Hashtable();
055:
056: /**
057: * Creates Key manager
058: *
059: * @param keyStore
060: * @param pwd
061: */
062: public KeyManagerImpl(KeyStore keyStore, char[] pwd) {
063: String alias;
064: KeyStore.PrivateKeyEntry entry;
065: Enumeration aliases;
066: try {
067: aliases = keyStore.aliases();
068: } catch (KeyStoreException e) {
069: return;
070: }
071: for (; aliases.hasMoreElements();) {
072: alias = (String) aliases.nextElement();
073: try {
074: if (keyStore.entryInstanceOf(alias,
075: KeyStore.PrivateKeyEntry.class)) {
076: entry = (KeyStore.PrivateKeyEntry) keyStore
077: .getEntry(
078: alias,
079: new KeyStore.PasswordProtection(pwd));
080: hash.put(alias, entry);
081: }
082: } catch (KeyStoreException e) {
083: continue;
084: } catch (UnrecoverableEntryException e) {
085: continue;
086: } catch (NoSuchAlgorithmException e) {
087: continue;
088: }
089: }
090:
091: }
092:
093: /**
094: * @see javax.net.ssl.X509ExtendedKeyManager.chooseClientAlias(String[]
095: * keyType, Principal[] issuers, Socket socket)
096: */
097: public String chooseClientAlias(String[] keyType,
098: Principal[] issuers, Socket socket) {
099: String[] al = chooseAlias(keyType, issuers);
100: if (al != null) {
101: return al[0];
102: } else {
103: return null;
104: }
105: }
106:
107: /**
108: * @see javax.net.ssl.X509ExtendedKeyManager.chooseServerAlias(String
109: * keyType, Principal[] issuers, Socket socket)
110: */
111: public String chooseServerAlias(String keyType,
112: Principal[] issuers, Socket socket) {
113: String[] al = chooseAlias(new String[] { keyType }, issuers);
114: if (al != null) {
115: return al[0];
116: } else {
117: return null;
118: }
119: }
120:
121: /**
122: * @see javax.net.ssl.X509ExtendedKeyManager.getCertificateChain(String
123: * alias)
124: */
125: public X509Certificate[] getCertificateChain(String alias) {
126: if (hash.containsKey(alias)) {
127: Certificate[] certs = ((KeyStore.PrivateKeyEntry) hash
128: .get(alias)).getCertificateChain();
129: if (certs[0] instanceof X509Certificate) {
130: X509Certificate[] xcerts = new X509Certificate[certs.length];
131: for (int i = 0; i < certs.length; i++) {
132: xcerts[i] = (X509Certificate) certs[i];
133: }
134: return xcerts;
135: }
136: }
137: return null;
138:
139: }
140:
141: /**
142: * @see javax.net.ssl.X509ExtendedKeyManager.getClientAliases(String
143: * keyType, Principal[] issuers)
144: */
145: public String[] getClientAliases(String keyType, Principal[] issuers) {
146: return chooseAlias(new String[] { keyType }, issuers);
147: }
148:
149: /**
150: * @see javax.net.ssl.X509ExtendedKeyManager.getServerAliases(String
151: * keyType, Principal[] issuers)
152: */
153: public String[] getServerAliases(String keyType, Principal[] issuers) {
154: return chooseAlias(new String[] { keyType }, issuers);
155: }
156:
157: /**
158: * @see javax.net.ssl.X509ExtendedKeyManager.getPrivateKey(String alias)
159: */
160: public PrivateKey getPrivateKey(String alias) {
161: if (hash.containsKey(alias)) {
162: return ((KeyStore.PrivateKeyEntry) hash.get(alias))
163: .getPrivateKey();
164: }
165: return null;
166: }
167:
168: /**
169: * @see javax.net.ssl.X509ExtendedKeyManager.chooseEngineClientAlias(String[]
170: * keyType, Principal[] issuers, SSLEngine engine)
171: */
172: public String chooseEngineClientAlias(String[] keyType,
173: Principal[] issuers, SSLEngine engine) {
174: String[] al = chooseAlias(keyType, issuers);
175: if (al != null) {
176: return al[0];
177: } else {
178: return null;
179: }
180: }
181:
182: /**
183: * @see javax.net.ssl.X509ExtendedKeyManager.chooseEngineServerAlias(String
184: * keyType, Principal[] issuers, SSLEngine engine)
185: */
186: public String chooseEngineServerAlias(String keyType,
187: Principal[] issuers, SSLEngine engine) {
188: String[] al = chooseAlias(new String[] { keyType }, issuers);
189: if (al != null) {
190: return al[0];
191: } else {
192: return null;
193: }
194: }
195:
196: private String[] chooseAlias(String[] keyType, Principal[] issuers) {
197: String alias;
198: KeyStore.PrivateKeyEntry entry;
199:
200: if (keyType == null || keyType.length == 0) {
201: return null;
202: }
203: Vector found = new Vector();
204: int count = 0;
205: for (Enumeration aliases = hash.keys(); aliases
206: .hasMoreElements();) {
207: alias = (String) aliases.nextElement();
208: entry = (KeyStore.PrivateKeyEntry) hash.get(alias);
209: Certificate[] certs = entry.getCertificateChain();
210: String alg = certs[0].getPublicKey().getAlgorithm();
211: for (int i = 0; i < keyType.length; i++) {
212: if (alg.equals(keyType[i])) {
213: if (issuers != null && issuers.length != 0) {
214: // check that certificate was issued by specified issuer
215: loop: for (int ii = 0; ii < certs.length; ii++) {
216: if (certs[ii] instanceof X509Certificate) {
217: X500Principal issuer = ((X509Certificate) certs[ii])
218: .getIssuerX500Principal();
219: for (int iii = 0; iii < issuers.length; iii++) {
220: if (issuer.equals(issuers[iii])) {
221: found.add(alias);
222: count++;
223: break loop;
224: }
225: }
226: }
227:
228: }
229: } else {
230: found.add(alias);
231: count++;
232: }
233: }
234: }
235: }
236: if (count > 0) {
237: String[] result = new String[count];
238: found.toArray(result);
239: return result;
240: } else {
241: return null;
242: }
243: }
244:
245: }
|