Source Code Cross Referenced for JsseSSLManager.java in  » Testing » jakarta-jmeter » org » apache » jmeter » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » jakarta jmeter » org.apache.jmeter.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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:        package org.apache.jmeter.util;
020:
021:        import java.net.HttpURLConnection;
022:        import java.net.Socket;
023:        import java.security.GeneralSecurityException;
024:        import java.security.Principal;
025:        import java.security.PrivateKey;
026:        import java.security.Provider;
027:        import java.security.SecureRandom;
028:        import java.security.cert.X509Certificate;
029:
030:        import javax.net.ssl.HostnameVerifier;
031:        import javax.net.ssl.HttpsURLConnection;
032:        import javax.net.ssl.KeyManager;
033:        import javax.net.ssl.KeyManagerFactory;
034:        import javax.net.ssl.SSLContext;
035:        import javax.net.ssl.SSLSession;
036:        import javax.net.ssl.TrustManager;
037:        import javax.net.ssl.TrustManagerFactory;
038:        import javax.net.ssl.X509KeyManager;
039:        import javax.net.ssl.X509TrustManager;
040:
041:        import org.apache.commons.httpclient.protocol.Protocol;
042:        import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
043:        import org.apache.jmeter.util.keystore.JmeterKeyStore;
044:        import org.apache.jorphan.logging.LoggingManager;
045:        import org.apache.log.Logger;
046:
047:        /**
048:         * The SSLManager handles the KeyStore information for JMeter. Basically, it
049:         * handles all the logic for loading and initializing all the JSSE parameters
050:         * and selecting the alias to authenticate against if it is available.
051:         * SSLManager will try to automatically select the client certificate for you,
052:         * but if it can't make a decision, it will pop open a dialog asking you for
053:         * more information.
054:         * 
055:         * TODO: does not actually prompt
056:         * 
057:         */
058:        public class JsseSSLManager extends SSLManager {
059:            private static final Logger log = LoggingManager
060:                    .getLoggerForClass();
061:
062:            private static final String HTTPS = "https"; // $NON-NLS-1$
063:
064:            // Temporary fix to allow default protocol to be changed
065:            private static final String DEFAULT_SSL_PROTOCOL = JMeterUtils
066:                    .getPropDefault("https.default.protocol", "TLS"); // $NON-NLS-1$ // $NON-NLS-2$
067:
068:            // Allow reversion to original shared session context
069:            private static final boolean SHARED_SESSION_CONTEXT = JMeterUtils
070:                    .getPropDefault("https.sessioncontext.shared", false); // $NON-NLS-1$
071:
072:            private static final int cps;
073:
074:            static {
075:                log.info("Using default SSL protocol: " + DEFAULT_SSL_PROTOCOL);
076:                log.info("SSL session context: "
077:                        + (SHARED_SESSION_CONTEXT ? "shared" : "per-thread"));
078:                cps = JMeterUtils.getPropDefault("httpclient.socket.https.cps",
079:                        0); // $NON-NLS-1$        
080:
081:                if (cps > 0) {
082:                    log.info("Setting up HTTPS SlowProtocol, cps=" + cps);
083:                }
084:
085:            }
086:
087:            /**
088:             * Cache the SecureRandom instance because it takes a long time to create
089:             */
090:            private SecureRandom rand;
091:
092:            private Provider pro = null;
093:
094:            private SSLContext defaultContext; // If we are using a single session
095:            private ThreadLocal threadlocal; // Otherwise
096:
097:            /**
098:             * Create the SSLContext, and wrap all the X509KeyManagers with
099:             * our X509KeyManager so that we can choose our alias.
100:             * 
101:             * @param provider
102:             *            Description of Parameter
103:             */
104:            public JsseSSLManager(Provider provider) {
105:                log.debug("ssl Provider =  " + provider);
106:                setProvider(provider);
107:                if (null == this .rand) { // Surely this is always null in the constructor?
108:                    this .rand = new SecureRandom();
109:                }
110:                try {
111:                    if (SHARED_SESSION_CONTEXT) {
112:                        log.debug("Creating shared context");
113:                        this .defaultContext = createContext();
114:                    } else {
115:                        this .threadlocal = new ThreadLocal();
116:                    }
117:
118:                    /*
119:                     * Set up Java defaults.
120:                     * N.B. does not allow SlowSocket - fails with:
121:                     * java.lang.RuntimeException: Export restriction: this JSSE implementation is non-pluggable.
122:                     */
123:
124:                    HttpsURLConnection
125:                            .setDefaultSSLSocketFactory(new HttpSSLProtocolSocketFactory(
126:                                    this ));
127:                    HttpsURLConnection
128:                            .setDefaultHostnameVerifier(new HostnameVerifier() {
129:                                public boolean verify(String hostname,
130:                                        SSLSession session) {
131:                                    return true;
132:                                }
133:                            });
134:
135:                    /*
136:                     * Also set up HttpClient defaults
137:                     */
138:                    Protocol protocol = new Protocol(
139:                            JsseSSLManager.HTTPS,
140:                            (ProtocolSocketFactory) new HttpSSLProtocolSocketFactory(
141:                                    this , cps), 443);
142:                    Protocol.registerProtocol(JsseSSLManager.HTTPS, protocol);
143:                    log.debug("SSL stuff all set");
144:                } catch (GeneralSecurityException ex) {
145:                    log.error("Could not set up SSLContext", ex);
146:                }
147:                log.debug("JsseSSLManager installed");
148:            }
149:
150:            /**
151:             * Sets the Context attribute of the JsseSSLManager object
152:             * 
153:             * @param conn
154:             *            The new Context value
155:             */
156:            public void setContext(HttpURLConnection conn) {
157:                if (conn instanceof  HttpsURLConnection) {
158:                    /*
159:                     * No point doing this on a per-connection basis, as there is currently no way to configure it.
160:                     * So we leave it to the defaults set up in the SSL Context
161:                     * 
162:                     */
163:                    //			HttpsURLConnection secureConn = (HttpsURLConnection) conn;
164:                    //			secureConn.setSSLSocketFactory(this.getContext().getSocketFactory());
165:                } else {
166:                    log.warn("Unexpected HttpURLConnection class: "
167:                            + conn.getClass().getName());
168:                }
169:            }
170:
171:            /**
172:             * Sets the Provider attribute of the JsseSSLManager object
173:             * 
174:             * @param p
175:             *            The new Provider value
176:             */
177:            protected final void setProvider(Provider p) {
178:                super .setProvider(p);
179:                if (null == this .pro) {
180:                    this .pro = p;
181:                }
182:            }
183:
184:            /**
185:             * Returns the SSLContext we are using.
186:             * This is either a context per thread,
187:             * or, for backwards compatibility, a single shared context.
188:             * 
189:             * @return The Context value
190:             */
191:            public SSLContext getContext() throws GeneralSecurityException {
192:                if (SHARED_SESSION_CONTEXT) {
193:                    if (log.isDebugEnabled()) {
194:                        log.debug("Using shared SSL context for: "
195:                                + Thread.currentThread().getName());
196:                    }
197:                    return this .defaultContext;
198:                }
199:
200:                SSLContext sslContext = (SSLContext) this .threadlocal.get();
201:                if (sslContext == null) {
202:                    if (log.isDebugEnabled()) {
203:                        log.debug("Creating threadLocal SSL context for: "
204:                                + Thread.currentThread().getName());
205:                    }
206:                    sslContext = createContext();
207:                    this .threadlocal.set(sslContext);
208:                }
209:                if (log.isDebugEnabled()) {
210:                    log.debug("Using threadLocal SSL context for: "
211:                            + Thread.currentThread().getName());
212:                }
213:                return sslContext;
214:            }
215:
216:            /**
217:             * Resets the SSLContext if using per-thread contexts.
218:             *
219:             */
220:            public void resetContext() {
221:                if (!SHARED_SESSION_CONTEXT) {
222:                    log.debug("Clearing session context for current thread");
223:                    this .threadlocal.set(null);
224:                }
225:            }
226:
227:            /*
228:             * 
229:             * Creates new SSL context
230:             * @return SSL context
231:             * @throws GeneralSecurityException
232:             */
233:            private SSLContext createContext() throws GeneralSecurityException {
234:                SSLContext context;
235:                if (pro != null) {
236:                    context = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL, pro); // $NON-NLS-1$
237:                } else {
238:                    context = SSLContext.getInstance(DEFAULT_SSL_PROTOCOL); // $NON-NLS-1$
239:                }
240:                KeyManagerFactory managerFactory = KeyManagerFactory
241:                        .getInstance(KeyManagerFactory.getDefaultAlgorithm());
242:                JmeterKeyStore keys = this .getKeyStore();
243:                managerFactory.init(null, defaultpw == null ? new char[] {}
244:                        : defaultpw.toCharArray());
245:                KeyManager[] managers = managerFactory.getKeyManagers();
246:                log.debug(keys.getClass().toString());
247:
248:                // Now wrap the default managers with our key manager
249:                for (int i = 0; i < managers.length; i++) {
250:                    if (managers[i] instanceof  X509KeyManager) {
251:                        X509KeyManager manager = (X509KeyManager) managers[i];
252:                        managers[i] = new WrappedX509KeyManager(manager, keys);
253:                    }
254:                }
255:
256:                // Get the default trust managers
257:                TrustManagerFactory tmfactory = TrustManagerFactory
258:                        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
259:                tmfactory.init(this .getTrustStore());
260:
261:                // Wrap the defaults in our custom trust manager
262:                TrustManager[] trustmanagers = tmfactory.getTrustManagers();
263:                for (int i = 0; i < trustmanagers.length; i++) {
264:                    if (trustmanagers[i] instanceof  X509TrustManager) {
265:                        trustmanagers[i] = new CustomX509TrustManager(
266:                                (X509TrustManager) trustmanagers[i]);
267:                    }
268:                }
269:                context.init(managers, trustmanagers, this .rand);
270:                if (log.isDebugEnabled()) {
271:                    String[] dCiphers = context.getSocketFactory()
272:                            .getDefaultCipherSuites();
273:                    String[] sCiphers = context.getSocketFactory()
274:                            .getSupportedCipherSuites();
275:                    int len = (dCiphers.length > sCiphers.length) ? dCiphers.length
276:                            : sCiphers.length;
277:                    for (int i = 0; i < len; i++) {
278:                        if (i < dCiphers.length) {
279:                            log.debug("Default Cipher: " + dCiphers[i]);
280:                        }
281:                        if (i < sCiphers.length) {
282:                            log.debug("Supported Cipher: " + sCiphers[i]);
283:                        }
284:                    }
285:                }
286:                return context;
287:            }
288:
289:            /**
290:             * This is the X509KeyManager we have defined for the sole purpose of
291:             * selecting the proper key and certificate based on the keystore available.
292:             * 
293:             * @author MStover Created March 21, 2002
294:             */
295:            private static class WrappedX509KeyManager implements 
296:                    X509KeyManager {
297:                /**
298:                 * The parent X509KeyManager
299:                 */
300:                private final X509KeyManager manager;
301:
302:                /**
303:                 * The KeyStore this KeyManager uses
304:                 */
305:                private final JmeterKeyStore store;
306:
307:                /**
308:                 * Instantiate a new WrappedX509KeyManager.
309:                 * 
310:                 * @param parent
311:                 *            The parent X509KeyManager
312:                 * @param ks
313:                 *            The KeyStore we derive our client certs and keys from
314:                 */
315:                public WrappedX509KeyManager(X509KeyManager parent,
316:                        JmeterKeyStore ks) {
317:                    this .manager = parent;
318:                    this .store = ks;
319:                }
320:
321:                /**
322:                 * Compiles the list of all client aliases with a private key.
323:                 * Currently, keyType and issuers are both ignored.
324:                 * 
325:                 * @param keyType
326:                 *            the type of private key the server expects (RSA, DSA,
327:                 *            etc.)
328:                 * @param issuers
329:                 *            the CA certificates we are narrowing our selection on.
330:                 * @return the ClientAliases value
331:                 */
332:                public String[] getClientAliases(String keyType,
333:                        Principal[] issuers) {
334:                    log.debug("WrappedX509Manager: getClientAliases: ");
335:                    log.debug(this .store.getAlias());
336:                    return new String[] { this .store.getAlias() };
337:                }
338:
339:                /**
340:                 * Get the list of server aliases for the SSLServerSockets. This is not
341:                 * used in JMeter.
342:                 * 
343:                 * @param keyType
344:                 *            the type of private key the server expects (RSA, DSA,
345:                 *            etc.)
346:                 * @param issuers
347:                 *            the CA certificates we are narrowing our selection on.
348:                 * @return the ServerAliases value
349:                 */
350:                public String[] getServerAliases(String keyType,
351:                        Principal[] issuers) {
352:                    log.debug("WrappedX509Manager: getServerAliases: ");
353:                    return this .manager.getServerAliases(keyType, issuers);
354:                }
355:
356:                /**
357:                 * Get the Certificate chain for a particular alias
358:                 * 
359:                 * @param alias
360:                 *            The client alias
361:                 * @return The CertificateChain value
362:                 */
363:                public X509Certificate[] getCertificateChain(String alias) {
364:                    log.debug("WrappedX509Manager: getCertificateChain("
365:                            + alias + ")");
366:                    return this .store.getCertificateChain();
367:                }
368:
369:                /**
370:                 * Get the Private Key for a particular alias
371:                 * 
372:                 * @param alias
373:                 *            The client alias
374:                 * @return The PrivateKey value
375:                 */
376:                public PrivateKey getPrivateKey(String alias) {
377:                    log.debug("WrappedX509Manager: getPrivateKey: "
378:                            + this .store.getPrivateKey());
379:                    return this .store.getPrivateKey();
380:                }
381:
382:                /**
383:                 * Select the Alias we will authenticate as if Client authentication is
384:                 * required by the server we are connecting to. We get the list of
385:                 * aliases, and if there is only one alias we automatically select it.
386:                 * If there are more than one alias that has a private key, we prompt
387:                 * the user to choose which alias using a combo box. Otherwise, we
388:                 * simply provide a text box, which may or may not work. The alias does
389:                 * have to match one in the keystore.
390:                 * 
391:                 * TODO? - does not actually allow the user to choose an alias at present
392:                 * 
393:                 * @see javax.net.ssl.X509KeyManager#chooseClientAlias(String[], Principal[], Socket)
394:                 */
395:                public String chooseClientAlias(String[] keyType,
396:                        Principal[] issuers, Socket socket) {
397:                    String alias = this .store.getAlias();
398:                    log.debug("ClientAlias: " + alias);
399:                    if (alias == null || alias.length() == 0) {
400:                        log.debug("ClientAlias not found.");
401:                    }
402:                    return alias;
403:                }
404:
405:                /**
406:                 * Choose the server alias for the SSLServerSockets. This are not used
407:                 * in JMeter.
408:                 * 
409:                 * @see javax.net.ssl.X509KeyManager#chooseServerAlias(String, Principal[], Socket)
410:                 */
411:                public String chooseServerAlias(String arg0, Principal[] arg1,
412:                        Socket arg2) {
413:                    return this.manager.chooseServerAlias(arg0, arg1, arg2);
414:                }
415:            }
416:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.