-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 All,
I've been writing a Java-based certification-expiration checking utility that can handle all kinds of file formats like PEM and the various keystore formats supported by the JVM. Since it's not possible to tell what type of keystore is being loaded without writing a bunch of magic-checking code or implementing an ASN.1 parser (no thank you), I simply try all keystore types until I find one that works. I'm using a rewindable InputStream which works well . Until you try to use the JCEKS keystore loader, specifically in Java versions 8 - 13. I haven't checked that later versions, and it appears that it's been fixed in Java 14. The API call is KeyStore.load(InputStream, char[]) and usually it behaves well. Unfortunately, in these affected versions, the JCEKS provider (which happens to be com.sun.crypto.provider.JceKeyStore, in the public engineLoad method) calls InputStream.close on the stream passed-into it. Yuck. JCEKS is a little-used keystore format, but it is required to store secret keys (different from private keys) because JKS can't support those. So it's possible that some users have been forced to use JCEKS keystore format. I haven't looked-through the Tomcat code yet to see if there could be places where this could cause a problem. Sane code usually looks like this: try(FileInputStream fin = new FileInputStream("keystore.jceks")) { KeyStore ks = KeyStore.getInstance("JCEKS"); ks.load(fin); } This code will fail with "java.io.IOException: Stream closed", which is of course incorrect resource management. My solution was to simply wrap the InputStream in one that will simply ignore any attempts to close it: try(FileInputStream fin = new UnclosableInputStream(new FileInputStream("keystore.jceks"))) { KeyStore ks = KeyStore.getInstance("JCEKS"); ks.load(fin); } public class UnclosableInputStream extends java.io.FilterInputStream { protected UnclosableInputStream(InputStream in) { super(in); } @Override public void close() throws IOException { // System.out.println("DEBUG: Ignoring attempt to close InputStream by provider of keystore type " + keystoreType); // new Throwable("trace").printStackTrace(); } } I'll be looking at Tomcat's keystore-loading code to see if this would be helpful, as not many people are running Tomcat on Java 14 yet, I would guess. - -chris P.S. I'll probably be releasing this tool on GitHub, soon, if anyone wants to have a look. -----BEGIN PGP SIGNATURE----- Comment: Using GnuPG with Thunderbird - https://www.enigmail.net/ iQIzBAEBCAAdFiEEMmKgYcQvxMe7tcJcHPApP6U8pFgFAl7j+XgACgkQHPApP6U8 pFgUPQ/+L7DQhP19ELBKYUbXQgdKN+aieiJoQap5wID+QZSXBJmbEgnUvrRcLdte oBaTgOJc3pKc6lV2K6PYIzT2HTpB4420h9cbn6vtFAuTdbN08RTxO5e6IGBUovtT o/Y0iVSy4m3aQfOg7nISqGoaVggDffTrr/ZQDPgjxbTbAeTHEhk7eCN0nNMWmzFD V2jn7b7IOowZoXRSWlMZ4FqmjPIugckmIs1qDfzooPQhdplLpbJn1ucLikG/j5jj kmeCRaiPtNCC3FmhlBgkU5Ac50LksoY4uR0dROzpxyZbClyUnq2zAIY/9paygG8s ZK/FZIaTdzJU3VeemaE3mMuCIDtTwzmRJH29kMTz1X4GOvsL3PbHFqeav9KGmUWO H3ASkTe27jhXSzxLrbxIsaQDRTAjscMMBAjy11Nsp5Qism7JQ7OgKiX0nOnR2Vne hP7cgk9snAkI9QhnTnyqnSd7dYKjMqEmmIa58YuRc+OaUeNf3wwmljSpKYvI2D31 ldBCEVF4PE+GNT0DXGfX2osTLMkglkDkgElHWennTDkHko72aexNX7c3Ut3+ldRu ho6CG2Fwaugw/QS3uk9E/ZfXwl5ZU2Rn4ysWac17FHgOA7A/yHrPkJxDxKGZHSHI rzMgeyquIpizAJEj6NKNQJdwujcZeVAhvUae+mQyoaJYplEpKRs= =AakA -----END PGP SIGNATURE----- --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org