https://bz.apache.org/bugzilla/show_bug.cgi?id=67675

            Bug ID: 67675
           Summary: Tomcat or Java do not read encrypted private keys with
                    DES-EDE3-CBC by openssl-req(1)
           Product: Tomcat 9
           Version: 9.0.81
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Catalina
          Assignee: dev@tomcat.apache.org
          Reporter: micha...@apache.org
  Target Milestone: -----

Generate a cert/key pair with OpenSSL:
openssl req -x509 -newkey rsa:4096 -keyout key.crt -out cert.crt -sha256 -days
5 -passout file:key-password

This key will have DES-EDE3-CBC as encryption algorithm by default
(1.2.840.113549.3.7).

Load this:
    <Connector port="20001"
protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true"
               maxParameterCount="1000"
              
sslImplementationName="org.apache.tomcat.util.net.jsse.JSSEImplementation">
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/certs-localhost/key.crt"
                         certificateKeyPassword="..."
                         certificateFile="conf/certs-localhost/cert.crt"
                         certificateChainFile="conf/cacerts.crt"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
Tomcat will say:
10-Oct-2023 21:02:12.966 SCHWERWIEGEND [Catalina-utility-1]
org.apache.catalina.security.TLSCertificateReloadListener.checkCertificatesForRenewal
[Connector["https-jsse-nio-20001"]], TLS virtual host [_default_] reload of TLS
configuration failed
        java.lang.IllegalArgumentException: PBE parameter parsing error:
expecting the object identifier for AES cipher
                at
org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:107)
                at
org.apache.tomcat.util.net.AbstractEndpoint.addSslHostConfig(AbstractEndpoint.java:280)
                at
org.apache.coyote.http11.AbstractHttp11Protocol.addSslHostConfig(AbstractHttp11Protocol.java:798)
                at
org.apache.catalina.security.TLSCertificateReloadListener.checkCertificatesForRenewal(TLSCertificateReloadListener.java:152)
                at
org.apache.catalina.security.TLSCertificateReloadListener.lifecycleEvent(TLSCertificateReloadListener.java:116)
                at
org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:114)
                at
org.apache.catalina.core.StandardServer.lambda$startPeriodicLifecycleEvent$0(StandardServer.java:943)
                at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
                at
java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
                at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
                at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
                at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
                at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
                at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
                at java.lang.Thread.run(Thread.java:750)
        Caused by: java.io.IOException: PBE parameter parsing error: expecting
the object identifier for AES cipher
                at
com.sun.crypto.provider.PBES2Parameters.parseES(PBES2Parameters.java:381)
                at
com.sun.crypto.provider.PBES2Parameters.engineInit(PBES2Parameters.java:284)
                at
java.security.AlgorithmParameters.init(AlgorithmParameters.java:293)
                at
sun.security.x509.AlgorithmId.decodeParams(AlgorithmId.java:151)
                at sun.security.x509.AlgorithmId.<init>(AlgorithmId.java:133)
                at sun.security.x509.AlgorithmId.parse(AlgorithmId.java:413)
                at
javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:98)
                at
org.apache.tomcat.util.net.jsse.PEMFile$Part.toPrivateKey(PEMFile.java:245)
                at
org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:178)
                at
org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:107)
                at
org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:355)
                at
org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:268)
                at
org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:105)
                ... 14 more

The reason is that Java does not support non-AES encrypted keys at least in
this class. I won't argue why OpenSSL does use this as default or whether 3DES
is secure or not. Just stating facts.

openssl-req(1) does not provide the option to pass the algorithm, one must
generate the key separately then invoke another command to create the pair.

A few references on the topic:
* https://bugs.openjdk.org/browse/JDK-8221936
* https://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art050
* https://stackoverflow.com/a/60020403/696632
* https://security.stackexchange.com/q/92593/298430
* https://github.com/openssl/openssl/issues/7313
* https://github.com/openssl/openssl/issues/5258

I think we have two options:
(a) Maybe we can put more effort into our code to read such keys and pass on to
JSSE
(b) Document that this combination is not supported for technical reasons and
how the user can solve this himself

In any case, there should be no surprise since this key is perfectly accepted
by OpenSSL.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to