I have been struggling in getting Start Tls to work for my ldap server. I have configured a keystore and password in a spring context file. My configuration seems to work for SSL but Star Tls is causing goosebumps. I have added StarTlsHandler as an ExtendedOperationHandler in wrapper of my LDAP Server. Do I need to configure anything else as well.
I am using JDK 1.6.0_15
Keystore and password are hard coded at the moment, they seem OK when I use SSL or debug.
I am using JLdap Client to test my implementation.
Here is a code snippet I have added for Handler: ldapServer.setKeystoreFile("C:/jdk/dgekey.ks"); ldapServer.setCertificatePassword("secret"); ldapServer.addExtendedOperationHandler(new StartTlsHandler());
Below you can see stack trace on the server side, client trace is further down:
2011-05-10 12:51:29,345 [rThread-4861-21] DEBUG [org.apache.directory.server.ldap.handlers.extended.StartTlsHandler] Setting LDAP Service 2011-05-10 12:51:29,345 [rThread-4861-21] DEBUG [org.apache.directory.server.ldap.handlers.extended.StartTlsHandler] provider = SUN version 1.6 2011-05-10 12:58:31,029 [rThread-4861-21] ERROR [org.apache.directory.server.core.security.CoreKeyStoreSpi] ERR_68 Failed on attempt to extract key. java.lang.IllegalStateException: ERR_436 Names used for principals must be normalized! at org.apache.directory.server.core.LdapPrincipal.(LdapPrincipal.java:76) at org.apache.directory.server.core.security.CoreKeyStoreSpi.getTlsEntry(CoreKeyStoreSpi.java:84) at org.apache.directory.server.core.security.CoreKeyStoreSpi.engineGetKey(CoreKeyStoreSpi.java:231) at java.security.KeyStore.getKey(KeyStore.java:763) at com.sun.net.ssl.internal.ssl.SunX509KeyManagerImpl.(SunX509KeyManagerImpl.java:113) at com.sun.net.ssl.internal.ssl.KeyManagerFactoryImpl$SunX509.engineInit(KeyManagerFactoryImpl.java:48) at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:239) at org.apache.directory.server.ldap.handlers.extended.StartTlsHandler.setLdapServer(StartTlsHandler.java:170) at org.apache.directory.server.ldap.LdapServer.startNetwork(LdapServer.java:542) at org.apache.directory.server.ldap.LdapServer.start(LdapServer.java:446) at com..ldap.apacheds.LdapServerWrapper.afterPropertiesSet(LdapServerWrapper.java:103) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1469) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1409) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:574) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4655) at org.apache.catalina.core.StandardContext.start(StandardContext.java:5364) at com.sun.enterprise.web.WebModule.start(WebModule.java:345) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:986) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:970) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:704) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1649) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1254) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:182) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:278) at com.sun.enterprise.admin.event.AdminEventMulticaster.invokeModuleDeployEventListener(AdminEventMulticaster.java:1005) at com.sun.enterprise.admin.event.AdminEventMulticaster.handleModuleDeployEvent(AdminEventMulticaster.java:992) at com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(AdminEventMulticaster.java:470) at com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(AdminEventMulticaster.java:182) at com.sun.enterprise.admin.server.core.DeploymentNotificationHelper.multicastEvent(DeploymentNotificationHelper.java:308) at com.sun.enterprise.deployment.phasing.DeploymentServiceUtils.multicastEvent(DeploymentServiceUtils.java:231) at com.sun.enterprise.deployment.phasing.ServerDeploymentTarget.sendStartEvent(ServerDeploymentTarget.java:298) at com.sun.enterprise.deployment.phasing.ApplicationStartPhase.runPhase(ApplicationStartPhase.java:132) at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108) at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:966) at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:609) at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:653) at com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.start(ApplicationsConfigMBean.java:773) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:390) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:373) at com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:477) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761) at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90) at $Proxy1.invoke(Unknown Source) at com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304) at com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:170) at com.sun.enterprise.admin.jmx.remote.server.callers.InvokeCaller.call(InvokeCaller.java:69) at com.sun.enterprise.admin.jmx.remote.server.MBeanServerRequestHandler.handle(MBeanServerRequestHandler.java:155) at com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.processRequest(RemoteJmxConnectorServlet.java:122) at com.sun.enterprise.admin.jmx.remote.server.servlet.RemoteJmxConnectorServlet.doPost(RemoteJmxConnectorServlet.java:193) at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) at org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:427) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:315) at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:287) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:94) at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:98) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:222) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:166) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:648) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:593) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:587) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:1093) at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:291) at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:666) at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:597) at com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process(DefaultProcessorTask.java:872) at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask(DefaultReadTask.java:341) at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:263) at com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask(DefaultReadTask.java:214) at com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:264) at com.sun.enterprise.web.connector.grizzly.WorkerThreadImpl.run(WorkerThreadImpl.java:117)
****Client Trace via javax.net.debug=all;****
keyStore is : C:/jdk/cacerts keyStore type is : jks keyStore provider is : init keystore init keymanager of type SunX509 trustStore is: C:\jdk\cacerts trustStore type is : jks trustStore provider is : init truststore adding as trusted cert: Subject: CN=SwissSign Platinum CA - G2, O=SwissSign AG, C=CH Issuer: CN=SwissSign Platinum CA - G2, O=SwissSign AG, C=CH Algorithm: RSA; Serial number: 0x4eb200670c035d4f Valid from Wed Oct 25 10:36:00 CEST 2006 until Sat Oct 25 10:36:00 CEST 2036
trigger seeding of SecureRandom done seeding SecureRandom %% No cached client session *** ClientHello, TLSv1 RandomCookie: GMT: 1288255192 bytes = { 100, 146, 27, 29, 47, 10, 97, 247, 253, 145, 49, 147, 239, 157, 90, 4, 34, 15, 99, 243, 191, 156, 251, 25, 64, 42, 210, 231 } Session ID: {} Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA] Compression Methods: { 0 }
[write] MD5 and SHA1 hashes: len = 73 0000: 01 00 00 45 03 01 4D C9 37 D8 64 92 1B 1D 2F 0A ...E..M.7.d.../. 0010: 61 F7 FD 91 31 93 EF 9D 5A 04 22 0F 63 F3 BF 9C a...1...Z.".c... 0020: FB 19 40 2A D2 E7 00 00 1E 00 04 00 05 00 2F 00 ..@........../. 0030: 33 00 32 00 0A 00 16 00 13 00 09 00 15 00 12 00 3.2............. 0040: 03 00 08 00 14 00 11 01 00 ......... main, WRITE: TLSv1 Handshake, length = 73 [write] MD5 and SHA1 hashes: len = 98 0000: 01 03 01 00 39 00 00 00 20 00 00 04 01 00 80 00 ....9... ....... 0010: 00 05 00 00 2F 00 00 33 00 00 32 00 00 0A 07 00 ..../..3..2..... 0020: C0 00 00 16 00 00 13 00 00 09 06 00 40 00 00 15 ............@... 0030: 00 00 12 00 00 03 02 00 80 00 00 08 00 00 14 00 ................ 0040: 00 11 4D C9 37 D8 64 92 1B 1D 2F 0A 61 F7 FD 91 ..M.7.d.../.a... 0050: 31 93 EF 9D 5A 04 22 0F 63 F3 BF 9C FB 19 40 2A 1...Z.".c.....@ 0060: D2 E7 .. main, WRITE: SSLv2 client hello message, length = 98 main, READ: TLSv1 Alert, length = 2 main, RECV TLSv1 ALERT: fatal, handshake_failure main, called closeSocket() main, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure Error: LDAPException: Could not negotiate a secure connection (91) Connect Error javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
Currently TlsHandler can only read the certificate from the uid=admin,ou=system entry. Can you try after setting your certificate and keys to the appropriate attribute values of the admin entry (uid=admin,ou=system). I will try to fix this in the latest trunk. (Appreciate if you can file a bug report).