Author: remm Date: Tue Apr 26 17:09:16 2016 New Revision: 1741061 URL: http://svn.apache.org/viewvc?rev=1741061&view=rev Log: 59295: Add support for using pem encoded certificates with JSSE SSL. Submitted by Emmanuel Bourg with additional tweaks.
Added: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/PEMFile.java - copied unchanged from r1740969, tomcat/trunk/java/org/apache/tomcat/util/net/jsse/PEMFile.java Modified: tomcat/tc8.5.x/trunk/ (props changed) tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml Propchange: tomcat/tc8.5.x/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Apr 26 17:09:16 2016 @@ -1 +1 @@ -/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740980,1740991,1741015 +/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741058,1741060 Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties Tue Apr 26 17:09:16 2016 @@ -122,6 +122,7 @@ sslHostConfig.certificateVerificationInv sslHostConfig.certificate.notype=Multiple certificates were specified and at least one is missing the required attribute type sslHostConfig.mismatch=The property [{0}] was set on the SSLHostConfig named [{1}] and is for connectors of type [{2}] but the SSLHostConfig is being used with a connector of type [{3}] sslHostConfig.prefix_missing=The protocol [{0}] was added to the list of protocols on the SSLHostConfig named [{1}]. Check if a +/- prefix is missing. +sslHostConfigCertificate.mismatch=The property [{0}] was set on the SSLHostConfigCertificate named [{1}] and is for certificate storage type [{2}] but the certificate is being used with a storage of type [{3}] sslImplementation.cnfe= Unable to create SSLImplementation for class [{0}] Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java Tue Apr 26 17:09:16 2016 @@ -19,11 +19,17 @@ package org.apache.tomcat.util.net; import java.util.HashSet; import java.util.Set; +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.net.openssl.ciphers.Authentication; +import org.apache.tomcat.util.res.StringManager; public class SSLHostConfigCertificate { + private static final Log log = LogFactory.getLog(SSLHostConfigCertificate.class); + private static final StringManager sm = StringManager.getManager(SSLHostConfigCertificate.class); + public static final Type DEFAULT_TYPE = Type.UNDEFINED; static final String DEFAULT_KEYSTORE_PROVIDER = @@ -53,6 +59,8 @@ public class SSLHostConfigCertificate { private String certificateFile; private String certificateKeyFile; + // Certificate store type + private StoreType storeType = null; public SSLHostConfigCertificate() { this(null, Type.UNDEFINED); @@ -113,6 +121,7 @@ public class SSLHostConfigCertificate { public void setCertificateKeystoreFile(String certificateKeystoreFile) { sslHostConfig.setProperty( "Certificate.certificateKeystoreFile", SSLHostConfig.Type.JSSE); + setStoreType("Certificate.certificateKeystoreFile", StoreType.KEYSTORE); this.certificateKeystoreFile = certificateKeystoreFile; } @@ -125,6 +134,7 @@ public class SSLHostConfigCertificate { public void setCertificateKeystorePassword(String certificateKeystorePassword) { sslHostConfig.setProperty( "Certificate.certificateKeystorePassword", SSLHostConfig.Type.JSSE); + setStoreType("Certificate.certificateKeystorePassword", StoreType.KEYSTORE); this.certificateKeystorePassword = certificateKeystorePassword; } @@ -137,6 +147,7 @@ public class SSLHostConfigCertificate { public void setCertificateKeystoreProvider(String certificateKeystoreProvider) { sslHostConfig.setProperty( "Certificate.certificateKeystoreProvider", SSLHostConfig.Type.JSSE); + setStoreType("Certificate.certificateKeystoreProvider", StoreType.KEYSTORE); this.certificateKeystoreProvider = certificateKeystoreProvider; } @@ -149,6 +160,7 @@ public class SSLHostConfigCertificate { public void setCertificateKeystoreType(String certificateKeystoreType) { sslHostConfig.setProperty( "Certificate.certificateKeystoreType", SSLHostConfig.Type.JSSE); + setStoreType("Certificate.certificateKeystoreType", StoreType.KEYSTORE); this.certificateKeystoreType = certificateKeystoreType; } @@ -161,8 +173,7 @@ public class SSLHostConfigCertificate { // OpenSSL public void setCertificateChainFile(String certificateChainFile) { - sslHostConfig.setProperty( - "Certificate.certificateChainFile", SSLHostConfig.Type.OPENSSL); + setStoreType("Certificate.certificateChainFile", StoreType.PEM); this.certificateChainFile = certificateChainFile; } @@ -173,8 +184,7 @@ public class SSLHostConfigCertificate { public void setCertificateFile(String certificateFile) { - sslHostConfig.setProperty( - "Certificate.certificateFile", SSLHostConfig.Type.OPENSSL); + setStoreType("Certificate.certificateFile", StoreType.PEM); this.certificateFile = certificateFile; } @@ -185,8 +195,7 @@ public class SSLHostConfigCertificate { public void setCertificateKeyFile(String certificateKeyFile) { - sslHostConfig.setProperty( - "Certificate.certificateKeyFile", SSLHostConfig.Type.OPENSSL); + setStoreType("Certificate.certificateKeyFile", StoreType.PEM); this.certificateKeyFile = certificateKeyFile; } @@ -196,6 +205,15 @@ public class SSLHostConfigCertificate { } + private void setStoreType(String name, StoreType type) { + if (storeType == null) { + storeType = type; + } else if (storeType != type) { + log.warn(sm.getString("sslHostConfigCertificate.mismatch", + name, sslHostConfig.getHostName(), type, this.storeType)); + } + } + // Nested types public static enum Type { @@ -220,4 +238,9 @@ public class SSLHostConfigCertificate { return compatibleAuthentications.contains(au); } } + + private enum StoreType { + KEYSTORE, + PEM + } } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java Tue Apr 26 17:09:16 2016 @@ -28,11 +28,13 @@ import java.security.cert.CRLException; import java.security.cert.CertPathParameters; import java.security.cert.CertStore; import java.security.cert.CertStoreParameters; +import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.CollectionCertStoreParameters; import java.security.cert.PKIXBuilderParameters; import java.security.cert.X509CertSelector; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; @@ -275,7 +277,31 @@ public class JSSEUtil extends SSLUtilBas KeyManager[] kms = null; - KeyStore ks = getStore(keystoreType, keystoreProvider, keystoreFile, keystorePass); + KeyStore ks; + + if (certificate.getCertificateFile() == null) { + ks = getStore(keystoreType, keystoreProvider, keystoreFile, keystorePass); + } else { + // create an in-memory keystore and import the private key + // and the certificate chain from the PEM files + ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + + PEMFile privateKeyFile = new PEMFile(SSLHostConfig.adjustRelativePath + (certificate.getCertificateKeyFile() != null ? certificate.getCertificateKeyFile() : certificate.getCertificateFile()), + keyPass); + PEMFile certificateFile = new PEMFile(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile())); + + Collection<Certificate> chain = new ArrayList<>(); + chain.addAll(certificateFile.getCertificates()); + if (certificate.getCertificateChainFile() != null) { + PEMFile certificateChainFile = new PEMFile(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile())); + chain.addAll(certificateChainFile.getCertificates()); + } + + ks.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), keyPass.toCharArray(), chain.toArray(new Certificate[chain.size()])); + } + if (keyAlias != null && !ks.isKeyEntry(keyAlias)) { throw new IOException(sm.getString("jsse.alias_no_key_entry", keyAlias)); } Modified: tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties Tue Apr 26 17:09:16 2016 @@ -25,6 +25,8 @@ jsse.excludeDefaultProtocol=The SSL prot jsse.noDefaultCiphers=Unable to determine a default for ciphers for [{0}]. Set an explicit value to ensure the connector can start. jsse.noDefaultProtocols=Unable to determine a default for sslEnabledProtocols. Set an explicit value to ensure the connector can start. jsse.exceptionOnClose=Failure to close socket. +jsse.pemParseError=Unable to parse the key from [{0}] + jsseSupport.clientCertError=Error trying to obtain a certificate from the client jseeSupport.certTranslationError=Error translating certificate [{0}] jsseSupport.noCertWant=No client certificate sent for want Modified: tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Tue Apr 26 17:09:16 2016 @@ -198,6 +198,10 @@ the <code>Content-Langauge</code> HTTP header to ensure the locale is correctly represented. Patch provided by zikfat. (markt) </fix> + <update> + <bug>59295</bug>: Add support for using pem encoded certificates with + JSSE SSL. Submitted by Emmanuel Bourg with additional tweaks. (remm) + </update> </changelog> </subsection> <subsection name="WebSocket"> Modified: tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml?rev=1741061&r1=1741060&r2=1741061&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml (original) +++ tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml Tue Apr 26 17:09:16 2016 @@ -1256,7 +1256,6 @@ <attributes> <attribute name="certificateFile" required="true"> - <p>OpenSSL only.</p> <p>Name of the file that contains the server certificate. The format is PEM-encoded. Relative paths will be resolved against <code>$CATALINA_BASE</code>.</p> @@ -1268,7 +1267,6 @@ </attribute> <attribute name="certificateChainFile" required="false"> - <p>OpenSSL only.</p> <p>Name of the file that contains the certificate chain associated with the server certificate used. The format is PEM-encoded. Relative paths will be resolved against @@ -1291,7 +1289,6 @@ </attribute> <attribute name="certificateKeyFile" required="false"> - <p>OpenSSL only.</p> <p>Name of the file that contains the server private key. The format is PEM-encoded. The default value is the value of <strong>certificateFile</strong> and in this case both certificate and --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org