1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.ldap.handlers.extended;
21
22
23 import java.security.KeyStore;
24 import java.security.Provider;
25 import java.security.SecureRandom;
26 import java.security.Security;
27 import java.security.cert.CertificateException;
28 import java.security.cert.X509Certificate;
29 import java.util.Collections;
30 import java.util.HashSet;
31 import java.util.Set;
32
33 import javax.net.ssl.KeyManagerFactory;
34 import javax.net.ssl.SSLContext;
35 import javax.net.ssl.TrustManager;
36 import javax.net.ssl.X509TrustManager;
37
38 import org.apache.directory.server.core.security.CoreKeyStoreSpi;
39 import org.apache.directory.server.ldap.ExtendedOperationHandler;
40 import org.apache.directory.server.ldap.LdapService;
41 import org.apache.directory.server.ldap.LdapSession;
42 import org.apache.directory.shared.ldap.message.ExtendedRequest;
43 import org.apache.directory.shared.ldap.message.ExtendedResponse;
44 import org.apache.directory.shared.ldap.message.ExtendedResponseImpl;
45 import org.apache.directory.shared.ldap.message.LdapResult;
46 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
47 import org.apache.mina.common.IoFilterChain;
48 import org.apache.mina.filter.SSLFilter;
49
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53
54
55
56
57
58
59
60
61
62 public class StartTlsHandler implements ExtendedOperationHandler
63 {
64 public static final String EXTENSION_OID = "1.3.6.1.4.1.1466.20037";
65
66 private static final Set<String> EXTENSION_OIDS;
67 private static final Logger LOG = LoggerFactory.getLogger( StartTlsHandler.class );
68
69 private SSLContext sslContext;
70
71
72 static
73 {
74 Set<String> set = new HashSet<String>( 3 );
75 set.add( EXTENSION_OID );
76 EXTENSION_OIDS = Collections.unmodifiableSet( set );
77 }
78
79
80 public void handleExtendedOperation( LdapSession session, ExtendedRequest req ) throws Exception
81 {
82 LOG.info( "Handling StartTLS request." );
83
84 IoFilterChain chain = session.getIoSession().getFilterChain();
85 SSLFilter sslFilter = ( SSLFilter ) chain.get( "sslFilter" );
86 if( sslFilter == null )
87 {
88 sslFilter = new SSLFilter( sslContext );
89 chain.addFirst( "sslFilter", sslFilter );
90 }
91 else
92 {
93 sslFilter.startSSL( session.getIoSession() );
94 }
95
96 ExtendedResponse res = new ExtendedResponseImpl( req.getMessageId() );
97 LdapResult result = res.getLdapResult();
98 result.setResultCode( ResultCodeEnum.SUCCESS );
99 res.setResponseName( EXTENSION_OID );
100 res.setResponse( new byte[ 0 ] );
101
102
103 session.getIoSession().setAttribute( SSLFilter.DISABLE_ENCRYPTION_ONCE );
104 session.getIoSession().write( res );
105 }
106
107
108 class ServerX509TrustManager implements X509TrustManager
109 {
110 public void checkClientTrusted( X509Certificate[] chain, String authType ) throws CertificateException
111 {
112 LOG.debug( "checkClientTrusted() called" );
113 }
114
115 public void checkServerTrusted( X509Certificate[] chain, String authType ) throws CertificateException
116 {
117 LOG.debug( "checkServerTrusted() called" );
118 }
119
120 public X509Certificate[] getAcceptedIssuers()
121 {
122 LOG.debug( "getAcceptedIssuers() called" );
123 return new X509Certificate[0];
124 }
125 }
126
127
128 public final Set<String> getExtensionOids()
129 {
130 return EXTENSION_OIDS;
131 }
132
133
134 public final String getOid()
135 {
136 return EXTENSION_OID;
137 }
138
139
140 public void setLdapServer( LdapService ldapService )
141 {
142 LOG.debug( "Setting LDAP Service" );
143 Provider provider = Security.getProvider( "SUN" );
144 LOG.debug( "provider = {}", provider );
145 CoreKeyStoreSpi coreKeyStoreSpi = new CoreKeyStoreSpi( ldapService.getDirectoryService() );
146 KeyStore keyStore = new KeyStore( coreKeyStoreSpi, provider, "JKS" ) {};
147
148 try
149 {
150 keyStore.load( null, null );
151 }
152 catch ( Exception e1 )
153 {
154 throw new RuntimeException( "Failed on keystore load which should never really happen." );
155 }
156
157 KeyManagerFactory keyManagerFactory = null;
158 try
159 {
160 keyManagerFactory = KeyManagerFactory.getInstance( "SunX509" );
161 }
162 catch ( Exception e )
163 {
164 throw new RuntimeException( "Failed to create KeyManagerFactory", e );
165 }
166
167 try
168 {
169 keyManagerFactory.init( keyStore, null );
170 }
171 catch ( Exception e )
172 {
173 throw new RuntimeException( "Failed to initialize KeyManagerFactory", e );
174 }
175
176 try
177 {
178 sslContext = SSLContext.getInstance( "TLS" );
179 }
180 catch ( Exception e )
181 {
182 throw new RuntimeException( "Failed to create SSLContext", e );
183 }
184
185 try
186 {
187 sslContext.init( keyManagerFactory.getKeyManagers(),
188 new TrustManager[] { new ServerX509TrustManager() },
189 new SecureRandom() );
190 }
191 catch ( Exception e )
192 {
193 throw new RuntimeException( "Failed to initialize SSLContext", e );
194 }
195 }
196 }