This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new 1709d67737 Add support for encrypted PKCS#1 keys. Based on #511. Thanks to jfclere 1709d67737 is described below commit 1709d6773799afb12a7421d0b1bd3bd766540faa Author: Mark Thomas <ma...@apache.org> AuthorDate: Tue May 10 13:02:01 2022 +0100 Add support for encrypted PKCS#1 keys. Based on #511. Thanks to jfclere --- java/org/apache/tomcat/util/net/jsse/PEMFile.java | 115 +++++++++++++++++++-- .../apache/tomcat/util/net/jsse/TestPEMFile.java | 89 ++++++++++++++++ .../util/net/jsse/key-encrypted-pkcs1-aes256.pem | 18 ++++ .../util/net/jsse/key-encrypted-pkcs1-des-cbc.pem | 18 ++++ .../net/jsse/key-encrypted-pkcs1-des-ede3-cbc.pem | 18 ++++ .../tomcat/util/net/jsse/key-encrypted-pkcs8.pem | 18 ++++ test/org/apache/tomcat/util/net/jsse/key-pkcs1.pem | 15 +++ webapps/docs/changelog.xml | 5 + 8 files changed, 286 insertions(+), 10 deletions(-) diff --git a/java/org/apache/tomcat/util/net/jsse/PEMFile.java b/java/org/apache/tomcat/util/net/jsse/PEMFile.java index 5db30d9e19..ab02cc8f7d 100644 --- a/java/org/apache/tomcat/util/net/jsse/PEMFile.java +++ b/java/org/apache/tomcat/util/net/jsse/PEMFile.java @@ -27,6 +27,8 @@ import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; @@ -43,7 +45,9 @@ import javax.crypto.Cipher; import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; import org.apache.tomcat.util.buf.Asn1Parser; import org.apache.tomcat.util.buf.Asn1Writer; @@ -113,7 +117,16 @@ public class PEMFile { part = null; } else if (part != null && !line.contains(":") && !line.startsWith(" ")) { part.content += line; - } + } else if (part != null && line.contains(":") && !line.startsWith(" ")) { + /* Something like DEK-Info: DES-EDE3-CBC,B5A53CB8B7E50064 */ + if (line.startsWith("DEK-Info: ")) { + String[] pieces = line.split(" "); + pieces = pieces[1].split(","); + if (pieces.length == 2) { + part.algorithm = pieces[0]; + part.ivHex = pieces[1]; + } + } } } } @@ -129,7 +142,7 @@ public class PEMFile { privateKey = part.toPrivateKey(password, keyAlgorithm, Format.PKCS8); break; case Part.RSA_PRIVATE_KEY: - privateKey = part.toPrivateKey(null, keyAlgorithm, Format.PKCS1); + privateKey = part.toPrivateKey(password, keyAlgorithm, Format.PKCS1); break; case Part.CERTIFICATE: case Part.X509_CERTIFICATE: @@ -153,6 +166,8 @@ public class PEMFile { public String type; public String content = ""; + public String algorithm = null; + public String ivHex = null; private byte[] decode() { return Base64.decodeBase64(content); @@ -183,15 +198,60 @@ public class PEMFile { } } } else { - EncryptedPrivateKeyInfo privateKeyInfo = new EncryptedPrivateKeyInfo(decode()); - String pbeAlgorithm = getPBEAlgorithm(privateKeyInfo); - SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(pbeAlgorithm); - SecretKey secretKey = secretKeyFactory.generateSecret(new PBEKeySpec(password.toCharArray())); - - Cipher cipher = Cipher.getInstance(pbeAlgorithm); - cipher.init(Cipher.DECRYPT_MODE, secretKey, privateKeyInfo.getAlgParameters()); + if (algorithm == null) { + // PKCS 8 + EncryptedPrivateKeyInfo privateKeyInfo = new EncryptedPrivateKeyInfo(decode()); + String pbeAlgorithm = getPBEAlgorithm(privateKeyInfo); + SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(pbeAlgorithm); + SecretKey secretKey = secretKeyFactory.generateSecret(new PBEKeySpec(password.toCharArray())); + + Cipher cipher = Cipher.getInstance(pbeAlgorithm); + cipher.init(Cipher.DECRYPT_MODE, secretKey, privateKeyInfo.getAlgParameters()); + + keySpec = privateKeyInfo.getKeySpec(cipher); + } else { + // PKCS 1 + String secretKeyAlgorithm; + String cipherTransformation; + int keyLength; + + // Is there a generic way to derive these three values from + // just the algorithm name? + switch (algorithm) { + case "DES-CBC": { + secretKeyAlgorithm = "DES"; + cipherTransformation = "DES/CBC/PKCS5Padding"; + keyLength = 8; + break; + } + case "DES-EDE3-CBC": { + secretKeyAlgorithm = "DESede"; + cipherTransformation = "DESede/CBC/PKCS5Padding"; + keyLength = 24; + break; + } + case "AES-256-CBC": { + secretKeyAlgorithm = "AES"; + cipherTransformation = "AES/CBC/PKCS5Padding"; + keyLength = 32; + break; + } + default: + // This will almost certainly trigger errors + secretKeyAlgorithm = algorithm; + cipherTransformation = algorithm; + keyLength = 8; + break; + } - keySpec = privateKeyInfo.getKeySpec(cipher); + byte[] iv = fromHex(ivHex); + byte[] key = deriveKey(keyLength, password, iv); + SecretKey secretKey = new SecretKeySpec(key, secretKeyAlgorithm); + Cipher cipher = Cipher.getInstance(cipherTransformation); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); + byte[] pkcs1 = cipher.doFinal(decode()); + keySpec = parsePKCS1(pkcs1); + } } InvalidKeyException exception = new InvalidKeyException(sm.getString("pemFile.parseError", filename)); @@ -234,6 +294,29 @@ public class PEMFile { } + private byte[] deriveKey(int keyLength, String password, byte[] iv) throws NoSuchAlgorithmException { + // PBKDF1-MD5 as specified by PKCS#5 + byte[] key = new byte[keyLength]; + + int insertPosition = 0; + + MessageDigest digest = MessageDigest.getInstance("MD5"); + byte[] pw = password.getBytes(StandardCharsets.UTF_8); + + while (insertPosition < keyLength) { + digest.update(pw); + digest.update(iv, 0, 8); + byte[] round = digest.digest(); + digest.update(round); + + System.arraycopy(round, 0, key, insertPosition, Math.min(keyLength - insertPosition, round.length)); + insertPosition += round.length; + } + + return key; + } + + /* * RFC5915: SEQ * INT value = 1 @@ -332,6 +415,18 @@ public class PEMFile { return new RSAPrivateCrtKeySpec(p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt()); } + + + + private byte[] fromHex(String hexString) { + byte[] bytes = new byte[hexString.length() / 2]; + for (int i = 0; i < hexString.length(); i += 2) + { + bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + + Character.digit(hexString.charAt(i + 1), 16)); + } + return bytes; + } } diff --git a/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java b/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java new file mode 100644 index 0000000000..1be9419d58 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tomcat.util.net.jsse; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.PrivateKey; + +import org.junit.Assert; +import org.junit.Test; + +public class TestPEMFile { + + private static final String KEY_PASSWORD = "changeit"; + + private static final String KEY_PKCS1 = "key-pkcs1.pem"; + private static final String KEY_ENCRYPTED_PKCS1_DES_CBC = "key-encrypted-pkcs1-des-cbc.pem"; + private static final String KEY_ENCRYPTED_PKCS1_DES_EDE3_CBC = "key-encrypted-pkcs1-des-ede3-cbc.pem"; + private static final String KEY_ENCRYPTED_PKCS1_AES256 = "key-encrypted-pkcs1-aes256.pem"; + private static final String KEY_ENCRYPTED_PKCS8 = "key-encrypted-pkcs8.pem"; + + + @Test + public void testKeyPkcs1() throws Exception { + testKey(KEY_PKCS1, null); + } + + + @Test + public void testKeyEncryptedPkcs1DesEde3Cbc() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS1_DES_EDE3_CBC); + } + + + @Test + public void testKeyEncryptedPkcs1DesCbc() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS1_DES_CBC); + } + + + @Test + public void testKeyEncryptedPkcs1Aes256() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS1_AES256); + } + + + @Test + public void testKeyEncryptedPkcs8() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS8); + } + + + private void testKeyEncrypted(String file) throws Exception { + testKey(file, KEY_PASSWORD); + } + + + private void testKey(String file, String password) throws Exception { + PEMFile pemFile = new PEMFile(getPath(file), password); + PrivateKey pk = pemFile.getPrivateKey(); + Assert.assertNotNull(pk); + } + + + private String getPath(String file) throws URISyntaxException, IOException { + URL url = this.getClass().getResource(file); + URI uri = url.toURI(); + File f = new File(uri); + + return f.getCanonicalPath(); + } +} diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-aes256.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-aes256.pem new file mode 100644 index 0000000000..ce7df89fb8 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-aes256.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,27A5EA847546F673F91037D067581427 + +OkmT+rurr+LlEAMBYUfHBm1Phv5+bP3891iXciYozdQrus7Nhk2ZD1RX8fCL9A2a +8I/8/0KRgOvPXbi9ZioBMSCRGObjT1qFXnviN9hQ+6dXrYRDjALkvV3I1mUmxF/H +Q3PE6M8uEt2X0ioiyzmbrD3Lrmd6lfuQ7dPpWUQ2zrnUNslF1DgaGyw6FvhWpzqW +PVN+lTdvHsv1HxkwW5npWYSF97d55D93k6FyIB09Ns/jh6snuM7iGzU7OeAT5jz7 +XBprlNQhFkZGVu0qq/cYjDkrPqX3dhEy89zQ0Rv7Fff5IsIumPY8vIkpF0k9PCVp +tqYhXAt8Tl9TR8cu+fdzgVkkCR2vutMPPjArp5wrd9jrmHNek4jlknsE2rvQACvo +gfJu0o+Ll5d/+BHE7pvB3z9QeqUKUshm//8XzOY76IfzbASwZI6V1EejLx+kc+u6 +/fr25xWw3Fzojq2uME+lh+JrFgial4eNY4EMP4uP6nqH7Gri5toonbW+yUC+J9oH +mbm+T4VGsrYBja2L0ckLOURCCX9gpZn8JLpLiuh1rN+opVpEy4qi0/2cvXDlLJVw +igCBUen8q4Yv7uubD60uxgnKXqO/SE26LOn+NHC+p/ESDh4Qhob2ejrgckX6wAyP +tMcqBYHDI9cKgMlFjR3a8aJ15pedUOQONyCnfE1e6CHduJta7Geqh/eQuP1lf3/B +IpD6WieNzLYr6Yg/5iCUoPnLdcmP5hWHcBAukSNNWQKIV7aKD86vwl5WU+tag2hx +0eMSw9VeZeWx/03plDro2EeltNPsycHcB8n7MhgrdiyS3Z0DNeSqh0thjMr4GWnh +-----END RSA PRIVATE KEY----- diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-cbc.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-cbc.pem new file mode 100644 index 0000000000..54c16d3829 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-cbc.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-CBC,B516994DD363C185 + +sG4BzUe/TJCntL2nizUtbLjPzsW6+SIRgwC07V1iJs1JeYw7SsobfHl4DiAKO9CW +86DT9hd4XCgCYGPvK6vUpFLk6Ms05eRrUx00clUk29MD18radLzwJyalYrbhXGOW +6m+dHm4dKXwpy9CFWudIFpotsCRPZnTiEa5/A2yjIyMFz/iAN4V+sGLLQJHjO/Nv +Cf5saTaRri5goYAIIVgetBx6D4B+dR8IqUdcfry3yhPAtxsBPd4QN5+wjLuf8mCV +LCG13+tfG1uM0FP8srAc/b1B+DDexsRwb/sLUDABofsmme7mRsUyZlm6dGbDuchx +RyMRzgBy5zmp0Okxafi94jInT9uiaaHFgn+BRpnA+rSoBNHtVEAPpHpeI2l3LYjJ +XPeobWgMS4e80kZJdOrwHEpsc0z5jUHdd/0puzoJs/H5UqeNRW+1Rgr5kPiIEj/H +JHc8xgKHumDfejxF3jhIIGOXHuav0PaCxR30t2aCz28wS8+c/j3EWzzA7Mfn8XTL +jxn3pUa57iDYcnmvjWk9KkZgnUBabIW3Q5CTK9UE2eIHEVoKYitXQ/DUoFGe94LB +Ip+7lSnfn/Cp5HhP1mhFcYIx6OfDCXTsbf1wu86Qy6ykHluYDRx3lQHxVzO7uJ3x +Mb1MzeqG4ojmlWl+Siew2fuinbDvH48sR+R9Oc/Xa6H/2UFwWkq40Z9fqERTumU5 +ES3KN1ah9RLSeAJWryOF4ngw3mywgPGjFGxBURXcQ8gQSG0zizEpvPWTataDp/3I +P/2V2YIjD1fH77DKBFfVjGvnL0mgQ7vPqzF3+cFHFB2XV17MehqkLA== +-----END RSA PRIVATE KEY----- diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-ede3-cbc.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-ede3-cbc.pem new file mode 100644 index 0000000000..2746f9dc61 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs1-des-ede3-cbc.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,23913AE126BDAFA4 + +nyKtTN/WFNPLUujp5ZSg2iPkLZ2y6yCbzr/tXjzTvxJNzw+XwfZepUc3pYFpNNdI +QVGrgXngjubQAk9E3m2xmlV+70hvT7huqrKaQ1ForySuCk8xCGyA8xedFFs9o5hB +mIttqRYjKcFhIqdmZ1XfS/ecenghiLB/e2cpN6jEXQQXfM79soAQUb4VZx72aIjq +vYMJbro/InOcz7xz+PH1dnP/5Z4t/Ze5Bp1v23PwXaqMBQeP4buQhfLjtGqn0Kr8 +N/EW+88TEhD/BL42FeJCBfMMAkZb+QGu10qtOx6LN1ijeuI+sY0Vzbu2orgoXNL5 +1iyagdeCfmMqEGUhIHlPTkmbf5L0f9Y7rfrno33obC5cNH7x9Kpfg95ORz+GKk6H +VVXBR8aUgWHVxoEVnBSWO0karQ6yFXZq6rfiA9Y8qisi3uTL7jmdVaii4fDfGzhu +JThC+HeZMoFebrS1bj1ak8D/imDZRpf7ww7jmrvmZhTpVVn9z/6MnQ9yziUb9eM+ +0HyUx4aTKbKqUSZQnV1QByg9eqYHv1pZcd3lvPy0MCWixYYFU76tone0iSQRUb8K +1b6Onlyi479Bbgwx/QNi7vvQo5CpPwqLJe1zrwrZ1iwV+FdNZ96QAew1dHgah/1E +s8ZYYyPMNxE3KiMXFpdh2JoakvFA+FM2c51Jh5joY2rCc8rKwa1o9lElNlMaGY4q +bTx88a6Wdn0dsWU3iuZ6EavquLnAYD2qvkbVs0LCDTBifplTYy/2KcZwKh2MIFXh +IxsatIfnVnR3joR3qzarkIs74GyDBGHAqRMJ/eFWwaEaG6P68Wwq8w== +-----END RSA PRIVATE KEY----- diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8.pem new file mode 100644 index 0000000000..ff8bfc048c --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8.pem @@ -0,0 +1,18 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI4iggy9PsVlkCAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDIg7tqUopcrjfAUxiYMJl3BIIC +gBfRSHed9lR7I3vdkETPKb9BgCeG/iDnM1jIfoDI9iuWs/vXtxF4x/c7bdZWRM7j +gM1XYuL3+9afC27imlaW9qdwz2aBHJ3EJiHx/bip8J0NY3U3mHWkalGM3cNXJoui +g0tTJ5BHhappQsDLdU/dV1uj0UzPupNQDbUv7UwrfgcfZlJDiQqKUgxLOjb/RiJN +k38HtEERAo6GQtHUQVSe5Oidqq0xMq3AAgV/Cd6SHFA6m5NbTjvIqr/vijCFbYag +Iw3F2wvwC0OPpE5RpTfu8Yw8x/ydgES4fgUJQC8oZUDGSPpI39otZFLCYoaSapKq +ptJfdY8jFstyfIaH5o8XYMsZpQ85nwsC4Fxf3BVM2qFJ4GhQ8/W/Ccu3WxfmuNeU +LeNIYvA5SW/iHNFM9aiR4bgFGdsJxqoYi38QUA0K9wb2sqp4Mxwhe7R7jennaWhV +sl/6vXlgZOWz0m5QFrWUdACYhkNeIUeHapyzEv0drWX4gjUilQtV9djvz89FlQO4 +8sijrJae8Z8+P57yZBRxZHdOt+UGVu+96QGlxh/2PuYBR8pe4df0zCR0U7oLE0by +EetkeyB1WsH+orHqyYuxlJEfTk2Ms5TYiF5qHR/ABsq0ABF2SBklb8FfevZzJmHh +8TZ5df1pKlMqfmbed+ICE3pVhXAbpkwzOOwQ5I7POlxr1VaIe/zk9kHVSX/7SFkw +aLdov4jjqDw6t0peEmTU1Oz5Z8Yw1VSv0c3HGpfekapPPD8Th6lDG8/g4luxW0dT +EdLcAsrZILnKFgQQqLSSVuNCqkHQrV6mIlYlYU0+1HnVXIaELR9Vqxl4c6VVxI0K +OlILOMmTFx6lHeeIU2LKsnw= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/test/org/apache/tomcat/util/net/jsse/key-pkcs1.pem b/test/org/apache/tomcat/util/net/jsse/key-pkcs1.pem new file mode 100644 index 0000000000..c2e3422252 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-pkcs1.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXgIBAAKBgQDYX3+ogFJtAt/gGmoYb1CpYu4O1jmQ22OefAsEzQSlCqlhe7Lx +Gf1/IjZgjBX+oIJ4LR/irpsxIbXRQsF4NYj1jK+VVZpxmXp9sLYNhDsb2XECKBSQ +qGCOv8hqTdMaLg5LqclpgHV1NX2YwEjYcYWzbxeRT8F4OmalYO3L91k+qQIDAQAB +AoGBAMT/DadITcNaXqIW6omcr3/Ixp1Thc3RMP3WSeHxF018S4KpsN26oAXkDEYS +xOOzF5Z63xDvj/RHkNYZRTRA6ZOaFztfDtqiU01vz4ljNP13Zp3g7kC2abkDmMfD +I8G3l63kt5CRButL4hoRqwzSjziXbsT+YDGcHEF/G2pWDkpBAkEA69czNfridqhY +1LAdvqlUORNxHBQQ/mvSV/eOheR0K3IAnMr4qv9dkiZDDDKtgZh/+q0uUk+BIFVh +JX3FzzM6RQJBAOreTDuNiDtjVRZivdY5IxiiQlQUiVKyIlcGKlAcnuzcWeTUVniV +s+H1OwSjct8xnGL/z6cMZx1NkMr9nlKaixUCQQCAR2J8hwUtI26F6XGUZkgAb5nD +ewqvSHh2DppAK74gb3bz0dcmM5Zyy0sG1H3ZkthxwkcC0Gnc63PWz62LgUK9AkAo +ma7x6IBxS7WMvhr06kGf44S1xisK6ZI4Gu+7k4cBiQHdJbug8rf6yoqePacA4DGZ +h4Ec7m7wyNTL0lXJD8AVAkEAvzwfeKpisNMu+ZmBsNb+0xWx9UKG6bg2UYYzwNdj +bhitdcU2ON62TnFyGhIYIqI3o5BSgoOPtZeKZfa380SQEg== +-----END RSA PRIVATE KEY----- diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 8efa7baa54..c259287aa4 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -163,6 +163,11 @@ <bug>66035</bug>: Add NULL check on the SSL session reference in the Panama code before accessing the session id and creation time. (remm) </fix> + <add> + Add support for encrypted PKCS#1 formatted private keys when configuring + the internal, in memory key store. Based on <pr>511</pr>. + (jfclere/markt) + </add> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org