You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2022/05/10 12:07:30 UTC

[tomcat] branch 8.5.x updated: Add support for encrypted PKCS#1 keys. Based on #511. Thanks to jfclere

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new 48d8df33c1 Add support for encrypted PKCS#1 keys. Based on #511. Thanks to jfclere
48d8df33c1 is described below

commit 48d8df33c1e02dd9c6c06b8caaf4b3949987642d
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 ca030cfa00..4a6185a520 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 77dff10b0a..51f90a0df8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -158,6 +158,11 @@
         <bug>66023</bug>: Improve the fix for <bug>65726</bug> and support HTTP
         upgrade with a request body for a wider set of use cases. (markt)
       </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="Webapps">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org