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.
This applies from Java 8 to 21.
Switched to: openssl genrsa -out key.crt -aes128 -passout file:key-password 4096 openssl req -x509 -key key.crt -out cert.crt -sha256 -days 5 -passout file:key-password Now I see: 11-Oct-2023 09:34:54.412 SCHWERWIEGEND [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector["https-jsse-nio-20001"]] org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:1011) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:554) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1039) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.startup.Catalina.load(Catalina.java:724) at org.apache.catalina.startup.Catalina.load(Catalina.java:746) 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:307) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:477) Caused by: java.lang.IllegalArgumentException: Cannot find any provider supporting AES-128-CBC at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:107) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:71) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:236) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1326) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1339) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:654) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:75) at org.apache.catalina.connector.Connector.initInternal(Connector.java:1009) ... 13 more Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES-128-CBC at javax.crypto.Cipher.getInstance(Cipher.java:543) at org.apache.tomcat.util.net.jsse.PEMFile$Part.toPrivateKey(PEMFile.java:292) at org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:186) 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) ... 20 more Seems not to be sufficient. It needs now: mv key.crt key-rsa.crt cp key-password key-password.2 openssl pkcs8 -in key-rsa.crt -out key.crt -topk8 -passin file:key-password -outform pem -passout file:key-password.2 openssl req -x509 -key key.crt -out cert.crt -sha256 -days 5 -passout file:key-password Quite some obstacles for users...
It seems that very few (no?) users are creating keys with pass-phrases this way as this isn't an issue that has been reported previously and we went through a phase of getting reports of unsupported formats when we added the "try and use an in-memory keystore for everything" code. I'm not adverse to trying to fix this as it is an OpenSSL default (which version by the way?). My only reservation at this point is how complex the fix might get. That depends on how much of the fix can use the standard Java APIs and how much we end up having to hand-craft.
(In reply to Mark Thomas from comment #3) > It seems that very few (no?) users are creating keys with pass-phrases this > way as this isn't an issue that has been reported previously and we went > through a phase of getting reports of unsupported formats when we added the > "try and use an in-memory keystore for everything" code. Well, we say that people can use any combination, therefore I'd expect this either just to work or documented NOT to work. > I'm not adverse to trying to fix this as it is an OpenSSL default (which > version by the way?). My only reservation at this point is how complex the > fix might get. That depends on how much of the fix can use the standard Java > APIs and how much we end up having to hand-craft. This applies to any OpenSSL version 1.1.1+ since DES3 is hardcoded and the cipher cannot be changed unless you do the separate commands. Unfortunately, I cannot judge what the effort is to implement this in Java, but at least we can figure out combos which do not work and document meanwhile.
We may end up supporting a subset of the OpenSSL functionality (and documenting that). For me the target is not to support everything OpenSSL does (although it would be great if we could) but to support the format of certificates that our users want to use. I suspect that is a smaller subset of what is possible with OpenSSL.
It looks like handling OID 1.2.840.113549.3.7 is something I was working on a while back in my project on GitHub. When running this through my own code, I get some debug output saying something about "Rainer's weird thing" which must have been a PEM file from him that I was trying to decode. This appears to be ANSI X9.52 which requires payment to get a copy of the specification, but I've been picking my way through it. I have it parsing everything correctly, but the decryption doesn't seem to be working as expected. It succeeds but then produces garbage plaintext.
Is that in your pem-utils project?
I have uncommitted work locally which can read the ASN.1 and perform the decryption, which does not fail (i.e. no exception is thrown). But when interpreting the decrypted data as an ASN.1 stream, the tags don't make any sense. I haven't looked that hard at the outbound ASN.1 stream. My immediate assumption was that it was complete garbage, but it's possible there is a bug in the parser which is trying to interpret some byte as a tag-id when it should be something else. I'd be happy to look more into it. The fun part with X9.52 is that it doesn't specify a padding method for the cipher. Using PKCS5Padding results in a BadPaddingException from the Cipher, and using Nopadding results in garbage ciphertext. :(
I'm working on this now. I don't think I am as far forward as you. It would be useful if I could see that code you have so far. My current thinking is that the PKCS8 branch in PEMFile is going to need to parse the input and figure out of this is a format Java can handle and if not, handle it somehow.
(In reply to Mark Thomas from comment #9) > I'm working on this now. I don't think I am as far forward as you. It would > be useful if I could see that code you have so far. > > My current thinking is that the PKCS8 branch in PEMFile is going to need to > parse the input and figure out of this is a format Java can handle and if > not, handle it somehow. Mark, are my instructions sufficient to reproduce the issue on your end?
Yes. The steps to reproduce this worked perfectly. Thanks. Currently working through the ASN.1 and relevant RFCs to see what we have and if I can get Java to work with it.
My current assessment is that it is possible to handle this. We are going to need to do a little more by hand. I think some refactoring will be required for the ASN.1 parser to make it more robust.
(In reply to Mark Thomas from comment #12) > I think some refactoring will be required > for the ASN.1 parser to make it more robust. I managed to do OCSP using it ( https://github.com/apache/tomcat/blob/main/modules/openssl-foreign/src/main/java/org/apache/tomcat/util/net/openssl/panama/OpenSSLEngine.java#L1327 ), but it really felt more like an accident !
I have this working with the current test cases and a default OpenSSL self-signed key as per the original report. The code needs to be cleaned up rather so I am currently expecting to commit the fix early next week.
(In reply to Mark Thomas from comment #14) > I have this working with the current test cases and a default OpenSSL > self-signed key as per the original report. > > The code needs to be cleaned up rather so I am currently expecting to commit > the fix early next week. Magic, if you want me to test it with real certs before you merge just let me know and point me to the branch or go with a PR on GH.
See https://github.com/apache/tomcat/pull/674 That should support any cert the current code supports plus the OpenSSL defaults. It is possible there are other combinations that need to be supported. It should be easy to add those as required.
Fixed in: - 11.0.x for 11.0.0-M14 onwards - 10.1.x for 10.1.16 onwards - 9.0.x for 9.0.83 onwards - 8.5.x for 8.5.96 onwards
Is it expected for PEM cert/key created with OpenSSL 1.0.2zh (or any 1.0.2) to stop working after this change? It seems to work fine with items generated through OpenSSL 1.1.1. Here's an example of the command we use: openssl req -new -sha256 -x509 -out servercert.pem -keyout serverkey.pem -subj /"/CN=localhost" -days 90 -passout pass:test I'm seeing the following error after upgrading to 9.0.83: 13-Dec-2023 02:04:34.337 SEVERE [main] org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to initialize component [Connector["https-openssl-apr-443"]] org.apache.catalina.LifecycleException: Protocol handler initialization failed at org.apache.catalina.connector.Connector.initInternal(Connector.java:1011) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.core.StandardService.initInternal(StandardService.java:554) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:1039) at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) at org.apache.catalina.startup.Catalina.load(Catalina.java:724) at org.apache.catalina.startup.Catalina.load(Catalina.java:746) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:307) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:477) Caused by: java.lang.IllegalArgumentException: The pseudo random function with DER encoded OID of [2a864886f70d0307] was not recognised at org.apache.tomcat.util.net.AprEndpoint.createSSLContext(AprEndpoint.java:467) at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:433) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1332) at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1345) at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:654) at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:75) at org.apache.catalina.connector.Connector.initInternal(Connector.java:1009) ... 13 more Caused by: java.security.NoSuchAlgorithmException: The pseudo random function with DER encoded OID of [2a864886f70d0307] was not recognised at org.apache.tomcat.util.net.jsse.PEMFile$Part.toPrivateKey(PEMFile.java:411) at org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:213) at org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:141) at org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:355) at org.apache.tomcat.util.net.openssl.OpenSSLUtil.getKeyManagers(OpenSSLUtil.java:108) at org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:268) at org.apache.tomcat.util.net.AprEndpoint.createSSLContext(AprEndpoint.java:465) ... 19 more 13-Dec-2023 02:04:34.352 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [2478] milliseconds The thrown error seems to have been added with this fix and that's why I'm writing here. That's my first post so I'm sorry if I should be opening a new report instead (couldn't find anything specific in the guidelines).
(In reply to ggar from comment #18) > Is it expected for PEM cert/key created with OpenSSL 1.0.2zh (or any 1.0.2) > to stop working after this change? It seems to work fine with items > generated through OpenSSL 1.1.1. Here's an example of the command we use: > openssl req -new -sha256 -x509 -out servercert.pem -keyout serverkey.pem > -subj /"/CN=localhost" -days 90 -passout pass:test > > > I'm seeing the following error after upgrading to 9.0.83: > 13-Dec-2023 02:04:34.337 SEVERE [main] > org.apache.catalina.util.LifecycleBase.handleSubClassException Failed to > initialize component [Connector["https-openssl-apr-443"]] > org.apache.catalina.LifecycleException: Protocol handler initialization > failed > at > org.apache.catalina.connector.Connector.initInternal(Connector.java:1011) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) > at > org.apache.catalina.core.StandardService.initInternal(StandardService.java: > 554) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) > at > org.apache.catalina.core.StandardServer.initInternal(StandardServer.java: > 1039) > at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:127) > at org.apache.catalina.startup.Catalina.load(Catalina.java:724) > at org.apache.catalina.startup.Catalina.load(Catalina.java:746) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native > Method) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown > Source) > at > java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown > Source) > at java.base/java.lang.reflect.Method.invoke(Unknown Source) > at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:307) > at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:477) > Caused by: java.lang.IllegalArgumentException: The pseudo random function > with DER encoded OID of [2a864886f70d0307] was not recognised > at > org.apache.tomcat.util.net.AprEndpoint.createSSLContext(AprEndpoint.java:467) > at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:433) > at > org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint. > java:1332) > at > org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:1345) > at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:654) > at > org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol. > java:75) > at > org.apache.catalina.connector.Connector.initInternal(Connector.java:1009) > ... 13 more > Caused by: java.security.NoSuchAlgorithmException: The pseudo random > function with DER encoded OID of [2a864886f70d0307] was not recognised > at > org.apache.tomcat.util.net.jsse.PEMFile$Part.toPrivateKey(PEMFile.java:411) > at org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:213) > at org.apache.tomcat.util.net.jsse.PEMFile.<init>(PEMFile.java:141) > at > org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:355) > at > org.apache.tomcat.util.net.openssl.OpenSSLUtil.getKeyManagers(OpenSSLUtil. > java:108) > at > org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:268) > at > org.apache.tomcat.util.net.AprEndpoint.createSSLContext(AprEndpoint.java:465) > ... 19 more > 13-Dec-2023 02:04:34.352 INFO [main] > org.apache.catalina.startup.Catalina.load Server initialization in [2478] > milliseconds > > The thrown error seems to have been added with this fix and that's why I'm > writing here. That's my first post so I'm sorry if I should be opening a new > report instead (couldn't find anything specific in the guidelines). Likely a regression, but I wonder whether we should care about keys from OpenSSL 1.0.2 at all. It has been dead for a long time now. For the sake of completeness, please file an new issue and upload the faulty material. One needs to look at the ASN.1 dump compared to 1.1.1.
If I have decoded it correctly, the OID is 1.2.840.113549.3.7 http://oid-info.com/get/1.2.840.113549.3.7 I need to look into why Tomcat isn't able to handle this.
The algorithm is being read as the pseudo random function and failing. I need to see if I can find (or build) an OpenSSL 1.0.2 binary.
(In reply to Mark Thomas from comment #21) > The algorithm is being read as the pseudo random function and failing. > > I need to see if I can find (or build) an OpenSSL 1.0.2 binary. Mark, there are several links to precompiled ones on the OpenSSL wiki (https://wiki.openssl.org/index.php/Binaries). I was able to reproduce the issue with the ones at https://indy.fulgan.com/SSL/. Not sure if you can use those. I saw that you reopened this bug, should I create a new one as Michael suggested or there's no need? And I agree with what Michael said - 1.0.2 is very old and maybe not worth supporting. We already started moving towards something newer but since we might have people out there with the "broken" certs we wanted to make sure this change was here to stay.
Tomcat ships OpenSSL binaries are part of the Tomcat Native distribution. I need to go back a bit but we have 1.0.2 binaries. For now, this looks like a regression so I'm happy handling it here. While 1.0.2 has been EOL for a while it would not surprise me at all to find lots of 1.0.2 generated keys and certs still in use.
Confirmed. It is a regression. OpenSSL 1.0.2 doesn't specify the PRF so the default should apply.
That was fast! Does this mean that it will be fixed in an upcoming release? By the way, thank you for being so responsive and reproducing this so quickly. (In reply to Mark Thomas from comment #24) > Confirmed. It is a regression. OpenSSL 1.0.2 doesn't specify the PRF so the > default should apply. That was fast! Does this mean that it will be fixed in an upcoming release? By the way, thank you for being so responsive and reproducing this so quickly.
Yes, this should be fixed for the next release round which is currently scheduled for January.
(In reply to Mark Thomas from comment #23) > While 1.0.2 has been EOL for a while it would not surprise me at all to find > lots of 1.0.2 generated keys and certs still in use. +1 The issue is not whether or not anyone is still using OpenSSL 1.0.2 today, but whether or not anyone still have keys and certs when when they /were/ using it in the past.
(In reply to Christopher Schultz from comment #27) > (In reply to Mark Thomas from comment #23) > > While 1.0.2 has been EOL for a while it would not surprise me at all to find > > lots of 1.0.2 generated keys and certs still in use. > > +1 > > The issue is not whether or not anyone is still using OpenSSL 1.0.2 today, > but whether or not anyone still have keys and certs when when they /were/ > using it in the past. That would also mean that they are years old and still valid...
If the keys were long to start with, it isn't impossible that they would still be in use. Regression fixed in: - 11.0.x for 11.0.0-M16 onwards - 10.1.x for 10.1.18 onwards - 9.0.x for 9.0.85 onwards - 8.5.x for 8.5.98 onwards
(In reply to Michael Osipov from comment #28) > (In reply to Christopher Schultz from comment #27) > > The issue is not whether or not anyone is still using OpenSSL 1.0.2 today, > > but whether or not anyone still have keys and certs when when they /were/ > > using it in the past. > > That would also mean that they are years old and still valid... Sure, but there is nothing wrong with that. What if a CA used OpenSSL 1.0.2 in 2019 (the year of the last release in that line) to mint their most-recent intermediate certificate(s)? Intermediate certificates are typically valid for 10 years or so. On the other hand, I think this is only a problem for keys and not certificates, and it's very unlikely that Tomcat would be used to handle CA key material. Those keys ought to be in HSMs and only used for signing, not for typical web traffic. Since it's already fixed (thanks, Mark!) this is an academic conversation, but I do still think that supporting these types of files is reasonable.
Hey, is there a scheduled date for the January release?