Bug 56021

Summary: SSL connector using windows-my keystore
Product: Tomcat 7 Reporter: Asanka <samare>
Component: ConnectorsAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: enhancement CC: samare
Priority: P2    
Version: 7.0.50   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Asanka 2014-01-16 19:37:09 UTC
Was trying to configure SSL on tomcat 7 to use Windows-MY keystore (provider that wraps the MSCAPI to access certificates in the keystore of Windows cert manager) but didn't get to work. Tomcat startup fails to load the connector since it looks for a empty file for the keystore inside catalina_home directory.

But I got it working with a small code change in org.apache.tomcat.util.net.AbstractEndpoint.adjustRelativePath() method. When Windows-MY keystore is used there is no physical keystore file. To be able to pass in empty value for the keyStoreFile in the connector I added a check for not empty path before adjusting the path.

    public String adjustRelativePath(String path, String relativeTo) {
        String newPath = path;
        if (!"".equalsIgnoreCase(newPath)) { 
            File f = new File(newPath);
            if ( !f.isAbsolute()) {
                newPath = relativeTo + File.separator + newPath;
                f = new File(newPath);
            }
            if (!f.exists()) {
                getLog().warn("configured file:["+newPath+"] does not exist.");
            }
        }
        return newPath;
    }

java version "1.7.0_07"

To reproduce (on windows):
1. Install a cert to the windows cert manager (start run certmgr.msc).
2. Configure the SSL connector with cert alias ('issued to' column value of the cert in the cermgr)
   <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keyAlias="ssl.cert.alias"
               keystoreFile=""
               keystoreType="Windows-My"
               clientAuth="false" sslProtocol="TLS" />
3. Start tomcat

The fix has been tested on windows 7 and windows server 2012.
Comment 1 Mark Thomas 2014-01-19 20:02:24 UTC
Thanks for the report and the suggested fix.

I applied a slightly different patch that allowed some additional code clean-up.

The patch has been applied to 8.0.x for 8.0.0 onwards and to 7.0.x for 7.0.51 onwards.

Thanks again for your support of the Apache Tomcat community.
Comment 2 joakim_ganse 2014-12-17 13:56:03 UTC
Does this work now? and how do I set it up?

My current setup is on Windows 2012 R2 with Tomcat 7.0.55.
Tomcat is installed as a service.
I have verified that the certificate exists in the windows cert manager.

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" 
               KeyAlias="server.my.domain"
               keystoreFile=""
               keystoreType="Windows-MY"
               
                />

Error:
2014-12-17 14:45:14,306 [main] INFO  org.apache.coyote.http11.Http11Protocol- Initializing ProtocolHandler ["http-bio-8180"]
2014-12-17 14:45:14,322 [main] INFO  org.apache.coyote.http11.Http11NioProtocol- Initializing ProtocolHandler ["http-nio-443"]
2014-12-17 14:45:14,759 [main] ERROR org.apache.coyote.http11.Http11NioProtocol- Failed to initialize end point associated with ProtocolHandler ["http-nio-443"]
java.io.IOException: Alias name server.my.domain does not identify a key entry
Comment 3 Asanka 2014-12-18 11:33:03 UTC
1. Make sure you have the correct keyAlias, following openssl command should show alias as the common name (CN) - openssl pkcs12 -info -in filename.pfx
2. Certificate needs to be installed to the LocalMachine\My store if the tomcat service runs with log on as local system. The CurrentUser\My store is not accessible from other user accounts. You can use powershell to install and verify the cert in the LocalMachine\My store.
Comment 4 Martin Stenderup 2019-08-22 07:58:58 UTC
(In reply to joakim_ganse from comment #2)

Try by setting keystorePassword="" in your connector configuration (it defaults to "changeit" if not set).
This worked for me.

I had to step-debug through Tomcats code to figure it out.
Comment 5 Martin Stenderup 2019-08-27 07:01:47 UTC
(In reply to Martin Stenderup from comment #4)
It seems to be called "keystorePass" some versions of Tomcat 8.
Comment 6 Christopher Schultz 2019-08-28 19:10:47 UTC
(In reply to Martin Stenderup from comment #5)
> It seems to be called "keystorePass" some versions of Tomcat 8.

Yes, it's "keystorePass" in all currently supported versions of Tomcat. "keystorePassword" is not a valid configuration attribute for any version of Tomcat.
Comment 7 Alexn 2019-12-07 00:17:42 UTC
I am using Apache Tomcat Version 8.5.27 on windows server 2016, but cannot get this to work. Can somebody take a look and tell me if I am missing something or this is a bug?.

1. I have the certificate in certmgr.msc (under Personal>Certificates) Issued by CJISeProbApp02. I use this value as the alias. 
2. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true" 
	clientAuth="false" sslProtocol="TLS" keyAlias="CJISeProbApp02"
               keystoreFile=""
               keystorePass=""
			   keystoreType="Windows-My"/>
3. I am running tomcat as logged in user. An I belong to administrator group.
4. Error Log
06-Dec-2019 16:11:07.236 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-nio-8443"]
06-Dec-2019 16:11:07.392 SEVERE [main] org.apache.catalina.core.StandardService.initInternal Failed to initialize connector [Connector[HTTP/1.1-8443]]
 org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:113)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:621)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:644)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:996)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        ... 12 more
Caused by: java.lang.IllegalArgumentException: java.io.IOException: Alias name [CJISeProbApp02] does not identify a key entry
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:116)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:87)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1086)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:268)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:581)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:68)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:993)
        ... 13 more
Caused by: java.io.IOException: Alias name [CJISeProbApp02] does not identify a key entry
        at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:225)
        at org.apache.tomcat.util.net.openssl.OpenSSLUtil.getKeyManagers(OpenSSLUtil.java:79)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114)
        ... 20 more

06-Dec-2019 16:11:07.392 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
Comment 8 Alexn 2019-12-07 00:20:37 UTC
I am using Apache Tomcat Version 8.5.27 on windows server 2016, but cannot get this to work. Can somebody take a look and tell me if I am missing something or this is a bug?.

1. I have the certificate in certmgr.msc (under Personal>Certificates) Issued to says --> CJISeProbApp02. I use this value as the alias. 
2. <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true" 
	clientAuth="false" sslProtocol="TLS" keyAlias="CJISeProbApp02"
               keystoreFile=""
               keystorePass=""
			   keystoreType="Windows-My"/>
3. I am running tomcat as logged in user. An I belong to administrator group.
4. Error Log
06-Dec-2019 16:11:07.236 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-openssl-nio-8443"]
06-Dec-2019 16:11:07.392 SEVERE [main] org.apache.catalina.core.StandardService.initInternal Failed to initialize connector [Connector[HTTP/1.1-8443]]
 org.apache.catalina.LifecycleException: Failed to initialize component [Connector[HTTP/1.1-8443]]
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:113)
        at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:875)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:621)
        at org.apache.catalina.startup.Catalina.load(Catalina.java:644)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: org.apache.catalina.LifecycleException: Protocol handler initialization failed
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:996)
        at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
        ... 12 more
Caused by: java.lang.IllegalArgumentException: java.io.IOException: Alias name [CJISeProbApp02] does not identify a key entry
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:116)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:87)
        at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:225)
        at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1086)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:268)
        at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:581)
        at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:68)
        at org.apache.catalina.connector.Connector.initInternal(Connector.java:993)
        ... 13 more
Caused by: java.io.IOException: Alias name [CJISeProbApp02] does not identify a key entry
        at org.apache.tomcat.util.net.jsse.JSSEUtil.getKeyManagers(JSSEUtil.java:225)
        at org.apache.tomcat.util.net.openssl.OpenSSLUtil.getKeyManagers(OpenSSLUtil.java:79)
        at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:114)
        ... 20 more

06-Dec-2019 16:11:07.392 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
Comment 9 Mark Thomas 2019-12-07 09:45:07 UTC
Bugzilla is not a support forum. Please use the users mailing list.