001/* 002 * The MIT License 003 * Copyright (c) 2012 Microsoft Corporation 004 * 005 * Permission is hereby granted, free of charge, to any person obtaining a copy 006 * of this software and associated documentation files (the "Software"), to deal 007 * in the Software without restriction, including without limitation the rights 008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 009 * copies of the Software, and to permit persons to whom the Software is 010 * furnished to do so, subject to the following conditions: 011 * 012 * The above copyright notice and this permission notice shall be included in 013 * all copies or substantial portions of the Software. 014 * 015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 021 * THE SOFTWARE. 022 */ 023 024package microsoft.exchange.webservices.data.core; 025 026import org.apache.http.conn.ssl.DefaultHostnameVerifier; 027import org.apache.http.conn.ssl.SSLConnectionSocketFactory; 028import org.apache.http.ssl.SSLContexts; 029 030import javax.net.ssl.HostnameVerifier; 031import javax.net.ssl.SSLContext; 032import javax.net.ssl.TrustManager; 033 034import java.security.GeneralSecurityException; 035 036/** 037 * <p> 038 * EwsSSLProtocolSocketFactory can be used to create SSL {@link java.net.Socket}s 039 * that accept self-signed certificates. 040 * </p> 041 * <p> 042 * This socket factory SHOULD NOT be used for productive systems 043 * due to security reasons, unless it is a conscious decision and 044 * you are perfectly aware of security implications of accepting 045 * self-signed certificates 046 * </p> 047 * Example of using custom protocol socket factory for a specific host: 048 * <pre> 049 * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); 050 * 051 * URI uri = new URI("https://localhost/", true); 052 * // use relative url only 053 * GetMethod httpget = new GetMethod(uri.getPathQuery()); 054 * HostConfiguration hc = new HostConfiguration(); 055 * hc.setHost(uri.getHost(), uri.getPort(), easyhttps); 056 * HttpClient client = new HttpClient(); 057 * client.executeMethod(hc, httpget); 058 * </pre> 059 * </p> 060 * <p> 061 * Example of using custom protocol socket factory per default instead of the standard one: 062 * <pre> 063 * Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); 064 * Protocol.registerProtocol("https", easyhttps); 065 * 066 * HttpClient client = new HttpClient(); 067 * GetMethod httpget = new GetMethod("https://localhost/"); 068 * client.executeMethod(httpget); 069 * </pre> 070 * </p> 071 * 072 * <p> 073 * DISCLAIMER: HttpClient developers DO NOT actively support this component. 074 * The component is provided as a reference material, which may be inappropriate 075 * for use without additional customization. 076 * </p> 077 */ 078 079public class EwsSSLProtocolSocketFactory extends SSLConnectionSocketFactory { 080 081 /** 082 * Default hostname verifier. 083 */ 084 private static final HostnameVerifier DEFAULT_HOSTNAME_VERIFIER = new DefaultHostnameVerifier(); 085 086 087 /** 088 * The SSL Context. 089 */ 090 private final SSLContext sslcontext; 091 092 093 /** 094 * Constructor for EasySSLProtocolSocketFactory. 095 * 096 * @param context SSL context 097 * @param hostnameVerifier hostname verifier 098 */ 099 public EwsSSLProtocolSocketFactory( 100 SSLContext context, HostnameVerifier hostnameVerifier 101 ) { 102 super(context, hostnameVerifier); 103 this.sslcontext = context; 104 } 105 106 107 /** 108 * Create and configure SSL protocol socket factory using default hostname verifier. 109 * {@link EwsSSLProtocolSocketFactory#DEFAULT_HOSTNAME_VERIFIER} 110 * 111 * @param trustManager trust manager 112 * @return socket factory for SSL protocol 113 * @throws GeneralSecurityException on security error 114 */ 115 public static EwsSSLProtocolSocketFactory build(TrustManager trustManager) 116 throws GeneralSecurityException { 117 return build(trustManager, DEFAULT_HOSTNAME_VERIFIER); 118 } 119 120 /** 121 * Create and configure SSL protocol socket factory using trust manager and hostname verifier. 122 * 123 * @param trustManager trust manager 124 * @param hostnameVerifier hostname verifier 125 * @return socket factory for SSL protocol 126 * @throws GeneralSecurityException on security error 127 */ 128 public static EwsSSLProtocolSocketFactory build( 129 TrustManager trustManager, HostnameVerifier hostnameVerifier 130 ) throws GeneralSecurityException { 131 SSLContext sslContext = createSslContext(trustManager); 132 return new EwsSSLProtocolSocketFactory(sslContext, hostnameVerifier); 133 } 134 135 /** 136 * Create SSL context and initialize it using specific trust manager. 137 * 138 * @param trustManager trust manager 139 * @return initialized SSL context 140 * @throws GeneralSecurityException on security error 141 */ 142 public static SSLContext createSslContext(TrustManager trustManager) 143 throws GeneralSecurityException { 144 EwsX509TrustManager x509TrustManager = new EwsX509TrustManager(null, trustManager); 145 SSLContext sslContext = SSLContexts.createDefault(); 146 sslContext.init( 147 null, 148 new TrustManager[] { x509TrustManager }, 149 null 150 ); 151 return sslContext; 152 } 153 154 155 /** 156 * @return SSL context 157 */ 158 public SSLContext getContext() { 159 return sslcontext; 160 } 161 162 public boolean equals(Object obj) { 163 return ((obj != null) && obj.getClass().equals(EwsSSLProtocolSocketFactory.class)); 164 } 165 166 public int hashCode() { 167 return EwsSSLProtocolSocketFactory.class.hashCode(); 168 } 169 170}