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 Alexander Y. Kleymenov
020: * @version $Revision$
021: */package org.apache.harmony.xnet.provider.jsse;
022:
023: import org.apache.harmony.xnet.provider.jsse.SSLSessionContextImpl;
024:
025: import java.security.KeyManagementException;
026: import java.security.KeyStore;
027: import java.security.KeyStoreException;
028: import java.security.NoSuchAlgorithmException;
029: import java.security.SecureRandom;
030: import java.security.UnrecoverableKeyException;
031: import javax.net.ssl.KeyManager;
032: import javax.net.ssl.KeyManagerFactory;
033: import javax.net.ssl.TrustManager;
034: import javax.net.ssl.TrustManagerFactory;
035: import javax.net.ssl.X509KeyManager;
036: import javax.net.ssl.X509TrustManager;
037:
038: /**
039: * The instances of this class incapsulate all the info
040: * about enabled cipher suites and protocols,
041: * as well as the information about client/server mode of
042: * ssl socket, whether it require/want client authentication or not,
043: * and controls whether new SSL sessions may be established by this
044: * socket or not.
045: */
046: public class SSLParameters {
047:
048: // default source of authentication keys
049: private static X509KeyManager defaultKeyManager;
050: // default source of authentication trust decisions
051: private static X509TrustManager defaultTrustManager;
052: // default source of random numbers
053: private static SecureRandom defaultSecureRandom;
054: // default SSL parameters
055: private static SSLParameters defaultParameters;
056:
057: // client session context contains the set of reusable
058: // client-side SSL sessions
059: private SSLSessionContextImpl clientSessionContext;
060: // server session context contains the set of reusable
061: // server-side SSL sessions
062: private SSLSessionContextImpl serverSessionContext;
063: // source of authentication keys
064: private X509KeyManager keyManager;
065: // source of authentication trust decisions
066: private X509TrustManager trustManager;
067: // source of random numbers
068: private SecureRandom secureRandom;
069:
070: // cipher suites available for SSL connection
071: protected CipherSuite[] enabledCipherSuites;
072: // string representations of available cipher suites
073: private String[] enabledCipherSuiteNames = null;
074:
075: // protocols available for SSL connection
076: private String[] enabledProtocols = ProtocolVersion.supportedProtocols;
077:
078: // if the peer with this parameters tuned to work in client mode
079: private boolean client_mode = true;
080: // if the peer with this parameters tuned to require client authentication
081: private boolean need_client_auth = false;
082: // if the peer with this parameters tuned to request client authentication
083: private boolean want_client_auth = false;
084: // if the peer with this parameters allowed to cteate new SSL session
085: private boolean enable_session_creation = true;
086:
087: /**
088: * Creates an instance of SSLParameters.
089: */
090: private SSLParameters() {
091: this .enabledCipherSuites = CipherSuite.defaultCipherSuites;
092: }
093:
094: /**
095: * Initializes the parameters. Naturally this constructor is used
096: * in SSLContextImpl.engineInit method which dirrectly passes its
097: * parameters. In other words this constructor holds all
098: * the functionality provided by SSLContext.init method.
099: * @see SSLContext.init(KeyManager,TrustManager,SecureRandom)
100: * for more information
101: */
102: protected SSLParameters(KeyManager[] kms, TrustManager[] tms,
103: SecureRandom sr,
104: SSLSessionContextImpl clientSessionContext,
105: SSLSessionContextImpl serverSessionContext)
106: throws KeyManagementException {
107: this ();
108: this .serverSessionContext = serverSessionContext;
109: this .clientSessionContext = clientSessionContext;
110: try {
111: // initialize key manager
112: boolean initialize_default = false;
113: // It's not described by the spec of SSLContext what should happen
114: // if the arrays of length 0 are specified. This implementation
115: // behave as for null arrays (i.e. use installed security providers)
116: if ((kms == null) || (kms.length == 0)) {
117: if (defaultKeyManager == null) {
118: KeyManagerFactory kmf = KeyManagerFactory
119: .getInstance(KeyManagerFactory
120: .getDefaultAlgorithm());
121: kmf.init(null, null);
122: kms = kmf.getKeyManagers();
123: // tell that we are trying to initialize defaultKeyManager
124: initialize_default = true;
125: } else {
126: keyManager = defaultKeyManager;
127: }
128: }
129: if (keyManager == null) { // was not initialized by default
130: for (int i = 0; i < kms.length; i++) {
131: if (kms[i] instanceof X509KeyManager) {
132: keyManager = (X509KeyManager) kms[i];
133: break;
134: }
135: }
136: if (keyManager == null) {
137: throw new KeyManagementException(
138: "No X509KeyManager found");
139: }
140: if (initialize_default) {
141: // found keyManager is default key manager
142: defaultKeyManager = keyManager;
143: }
144: }
145:
146: // initialize trust manager
147: initialize_default = false;
148: if ((tms == null) || (tms.length == 0)) {
149: if (defaultTrustManager == null) {
150: TrustManagerFactory tmf = TrustManagerFactory
151: .getInstance(TrustManagerFactory
152: .getDefaultAlgorithm());
153: tmf.init((KeyStore) null);
154: tms = tmf.getTrustManagers();
155: initialize_default = true;
156: } else {
157: trustManager = defaultTrustManager;
158: }
159: }
160: if (trustManager == null) { // was not initialized by default
161: for (int i = 0; i < tms.length; i++) {
162: if (tms[i] instanceof X509TrustManager) {
163: trustManager = (X509TrustManager) tms[i];
164: break;
165: }
166: }
167: if (trustManager == null) {
168: throw new KeyManagementException(
169: "No X509TrustManager found");
170: }
171: if (initialize_default) {
172: // found trustManager is default trust manager
173: defaultTrustManager = trustManager;
174: }
175: }
176: } catch (NoSuchAlgorithmException e) {
177: throw new KeyManagementException(e);
178: } catch (KeyStoreException e) {
179: throw new KeyManagementException(e);
180: } catch (UnrecoverableKeyException e) {
181: throw new KeyManagementException(e);
182: }
183: // initialize secure random
184: if (sr == null) {
185: if (defaultSecureRandom == null) {
186: defaultSecureRandom = new SecureRandom();
187: }
188: secureRandom = defaultSecureRandom;
189: } else {
190: secureRandom = sr;
191: }
192: }
193:
194: protected static SSLParameters getDefault()
195: throws KeyManagementException {
196: if (defaultParameters == null) {
197: defaultParameters = new SSLParameters(null, null, null,
198: new SSLSessionContextImpl(),
199: new SSLSessionContextImpl());
200: }
201: return (SSLParameters) defaultParameters.clone();
202: }
203:
204: /**
205: * @return server session context
206: */
207: protected SSLSessionContextImpl getServerSessionContext() {
208: return serverSessionContext;
209: }
210:
211: /**
212: * @return client session context
213: */
214: protected SSLSessionContextImpl getClientSessionContext() {
215: return clientSessionContext;
216: }
217:
218: /**
219: * @return key manager
220: */
221: protected X509KeyManager getKeyManager() {
222: return keyManager;
223: }
224:
225: /**
226: * @return trust manager
227: */
228: protected X509TrustManager getTrustManager() {
229: return trustManager;
230: }
231:
232: /**
233: * @return secure random
234: */
235: protected SecureRandom getSecureRandom() {
236: return secureRandom;
237: }
238:
239: /**
240: * @return the names of enabled cipher suites
241: */
242: protected String[] getEnabledCipherSuites() {
243: if (enabledCipherSuiteNames == null) {
244: enabledCipherSuiteNames = new String[enabledCipherSuites.length];
245: for (int i = 0; i < enabledCipherSuites.length; i++) {
246: enabledCipherSuiteNames[i] = enabledCipherSuites[i]
247: .getName();
248: }
249: }
250: return (String[]) enabledCipherSuiteNames.clone();
251: }
252:
253: /**
254: * Sets the set of available cipher suites for use in SSL connection.
255: * @param suites: String[]
256: * @return
257: */
258: protected void setEnabledCipherSuites(String[] suites) {
259: if (suites == null) {
260: throw new IllegalArgumentException(
261: "Provided parameter is null");
262: }
263: CipherSuite[] cipherSuites = new CipherSuite[suites.length];
264: for (int i = 0; i < suites.length; i++) {
265: cipherSuites[i] = CipherSuite.getByName(suites[i]);
266: if (cipherSuites[i] == null || !cipherSuites[i].supported) {
267: throw new IllegalArgumentException(suites[i]
268: + " is not supported.");
269: }
270: }
271: enabledCipherSuites = cipherSuites;
272: enabledCipherSuiteNames = suites;
273: }
274:
275: /**
276: * @return the set of enabled protocols
277: */
278: protected String[] getEnabledProtocols() {
279: return (String[]) enabledProtocols.clone();
280: }
281:
282: /**
283: * Sets the set of available protocols for use in SSL connection.
284: * @param suites: String[]
285: */
286: protected void setEnabledProtocols(String[] protocols) {
287: if (protocols == null) {
288: throw new IllegalArgumentException(
289: "Provided parameter is null");
290: }
291: for (int i = 0; i < protocols.length; i++) {
292: if (!ProtocolVersion.isSupported(protocols[i])) {
293: throw new IllegalArgumentException("Protocol "
294: + protocols[i] + " is not supported.");
295: }
296: }
297: enabledProtocols = protocols;
298: }
299:
300: /**
301: * Tunes the peer holding this parameters to work in client mode.
302: * @param mode if the peer is configured to work in client mode
303: */
304: protected void setUseClientMode(boolean mode) {
305: client_mode = mode;
306: }
307:
308: /**
309: * Returns the value indicating if the parameters configured to work
310: * in client mode.
311: */
312: protected boolean getUseClientMode() {
313: return client_mode;
314: }
315:
316: /**
317: * Tunes the peer holding this parameters to require client authentication
318: */
319: protected void setNeedClientAuth(boolean need) {
320: need_client_auth = need;
321: // reset the want_client_auth setting
322: want_client_auth = false;
323: }
324:
325: /**
326: * Returns the value indicating if the peer with this parameters tuned
327: * to require client authentication
328: */
329: protected boolean getNeedClientAuth() {
330: return need_client_auth;
331: }
332:
333: /**
334: * Tunes the peer holding this parameters to request client authentication
335: */
336: protected void setWantClientAuth(boolean want) {
337: want_client_auth = want;
338: // reset the need_client_auth setting
339: need_client_auth = false;
340: }
341:
342: /**
343: * Returns the value indicating if the peer with this parameters
344: * tuned to request client authentication
345: * @return
346: */
347: protected boolean getWantClientAuth() {
348: return want_client_auth;
349: }
350:
351: /**
352: * Allows/disallows the peer holding this parameters to
353: * create new SSL session
354: */
355: protected void setEnableSessionCreation(boolean flag) {
356: enable_session_creation = flag;
357: }
358:
359: /**
360: * Returns the value indicating if the peer with this parameters
361: * allowed to cteate new SSL session
362: */
363: protected boolean getEnableSessionCreation() {
364: return enable_session_creation;
365: }
366:
367: /**
368: * Returns the clone of this object.
369: * @return the clone.
370: */
371: protected Object clone() {
372: SSLParameters parameters = new SSLParameters();
373:
374: parameters.clientSessionContext = clientSessionContext;
375: parameters.serverSessionContext = serverSessionContext;
376: parameters.keyManager = keyManager;
377: parameters.trustManager = trustManager;
378: parameters.secureRandom = secureRandom;
379:
380: parameters.enabledCipherSuites = enabledCipherSuites;
381: parameters.enabledProtocols = enabledProtocols;
382:
383: parameters.client_mode = client_mode;
384: parameters.need_client_auth = need_client_auth;
385: parameters.want_client_auth = want_client_auth;
386: parameters.enable_session_creation = enable_session_creation;
387:
388: return parameters;
389: }
390: }
|