This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit e3222ae8bac52e8b3c0be8c66d98f13b58551fc1 Author: Mark Thomas <ma...@apache.org> AuthorDate: Fri Oct 20 15:54:33 2023 +0100 Fix BZ 67675 - Expand the PBKDF2 and cipher combinations supported Java only directly supports a sub-set of the possible combinations. Process the PBKDF2 configuration and cipher configuration separately thereby increasing the range or supported combinations. --- java/org/apache/tomcat/util/buf/Asn1Parser.java | 48 ++- .../tomcat/util/net/jsse/LocalStrings.properties | 5 + java/org/apache/tomcat/util/net/jsse/PEMFile.java | 326 ++++++++++++++++----- .../apache/tomcat/util/net/jsse/TestPEMFile.java | 20 +- .../key-encrypted-pkcs8-hmacsha256-aes-128-cbc.pem | 54 ++++ ...key-encrypted-pkcs8-hmacsha256-aes-256-cbc.pem} | 0 ...key-encrypted-pkcs8-hmacsha256-des-ede3-cbc.pem | 54 ++++ 7 files changed, 430 insertions(+), 77 deletions(-) diff --git a/java/org/apache/tomcat/util/buf/Asn1Parser.java b/java/org/apache/tomcat/util/buf/Asn1Parser.java index e32e71886f..92d13c02a8 100644 --- a/java/org/apache/tomcat/util/buf/Asn1Parser.java +++ b/java/org/apache/tomcat/util/buf/Asn1Parser.java @@ -30,6 +30,13 @@ public class Asn1Parser { private static final StringManager sm = StringManager.getManager(Asn1Parser.class); + public static final int TAG_INTEGER = 0x02; + public static final int TAG_OCTET_STRING = 0x04; + public static final int TAG_NULL = 0x05; + public static final int TAG_OID = 0x06; + public static final int TAG_SEQUENCE = 0x30; + public static final int TAG_ATTRIBUTE_BASE = 0xA0; + private final byte[] source; private int pos = 0; @@ -50,6 +57,11 @@ public class Asn1Parser { } + public void parseTagSequence() { + parseTag(TAG_SEQUENCE); + } + + public void parseTag(int tag) { int value = next(); if (value != tag) { @@ -83,15 +95,41 @@ public class Asn1Parser { public BigInteger parseInt() { - parseTag(0x02); - int len = parseLength(); - byte[] val = new byte[len]; - System.arraycopy(source, pos, val, 0, len); - pos += len; + byte[] val = parseBytes(TAG_INTEGER); return new BigInteger(val); } + public byte[] parseOctetString() { + return parseBytes(TAG_OCTET_STRING); + } + + + public void parseNull() { + parseBytes(TAG_NULL); + } + + + public byte[] parseOIDAsBytes() { + return parseBytes(TAG_OID); + } + + + public byte[] parseAttributeAsBytes(int index) { + return parseBytes(TAG_ATTRIBUTE_BASE + index); + } + + + private byte[] parseBytes(int tag) { + parseTag(tag); + int len = parseLength(); + byte[] result = new byte[len]; + System.arraycopy(source, pos, result, 0, result.length); + pos += result.length; + return result; + } + + public void parseBytes(byte[] dest) { System.arraycopy(source, pos, dest, 0, dest.length); pos += dest.length; diff --git a/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties b/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties index b276db95ab..888a2a6761 100644 --- a/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties +++ b/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties @@ -21,4 +21,9 @@ jsseUtil.noDefaultProtocols=Unable to determine a default for sslEnabledProtocol pemFile.noMultiPrimes=The PKCS#1 certificate is in multi-prime format and Java does not provide an API for constructing an RSA private key object from that format pemFile.notValidRFC5915=The provided key file does not conform to RFC 5915 +pemFile.notPbkdf2=The OID [{0}] is not the correct OID for PKBDF2 which is the only permitted KDF for PBES2 pemFile.parseError=Unable to parse the key from [{0}] +pemFile.unknownEncryptedFormat=The format [{0}] is not a recognised encrypted PEM file format +pemFile.unknownEncryptionAlgorithm=The encryption algorithm with DER encoded OID of [{0}] was not recognised +pemFile.unknownPrfAlgorithm=The pseudo random function with DER encoded OID of [{0}] was not recognised +pemFile.unknownPkcs8Algorithm=The PKCS#8 encryption algorithm with DER encoded OID of [{0}] was not recognised \ No newline at end of file diff --git a/java/org/apache/tomcat/util/net/jsse/PEMFile.java b/java/org/apache/tomcat/util/net/jsse/PEMFile.java index d7f196bb3a..2785f9761c 100644 --- a/java/org/apache/tomcat/util/net/jsse/PEMFile.java +++ b/java/org/apache/tomcat/util/net/jsse/PEMFile.java @@ -23,7 +23,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; import java.nio.charset.StandardCharsets; -import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -39,10 +38,12 @@ import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.crypto.Cipher; -import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; @@ -51,6 +52,7 @@ import javax.crypto.spec.SecretKeySpec; import org.apache.tomcat.util.buf.Asn1Parser; import org.apache.tomcat.util.buf.Asn1Writer; +import org.apache.tomcat.util.buf.HexUtils; import org.apache.tomcat.util.codec.binary.Base64; import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.res.StringManager; @@ -64,9 +66,40 @@ public class PEMFile { private static final byte[] OID_EC_PUBLIC_KEY = new byte[] { 0x06, 0x07, 0x2A, (byte) 0x86, 0x48, (byte) 0xCE, 0x3D, 0x02, 0x01 }; + // 1.2.840.113549.1.5.13 + private static final byte[] OID_PBES2 = + new byte[] { 0x2A, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xF7, 0x0D, 0x01, 0x05, 0x0D }; + // 1.2.840.113549.1.5.12 + private static final byte[] OID_PBKDF2 = + new byte[] { 0x2A, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xF7, 0x0D, 0x01, 0x05, 0x0C }; + + private static final Map<String,String> OID_TO_PRF = new HashMap<>(); + static { + // 1.2.840.113549.2.7 + OID_TO_PRF.put("2a864886f70d0207", "HmacSHA1"); + // 1.2.840.113549.2.8 + OID_TO_PRF.put("2a864886f70d0208", "HmacSHA224"); + // 1.2.840.113549.2.9 + OID_TO_PRF.put("2a864886f70d0209", "HmacSHA256"); + // 1.2.840.113549.2.10 + OID_TO_PRF.put("2a864886f70d020a", "HmacSHA384"); + // 1.2.840.113549.2.11 + OID_TO_PRF.put("2a864886f70d020b", "HmacSHA512"); + // 1.2.840.113549.2.12 + OID_TO_PRF.put("2a864886f70d020c", "HmacSHA512/224"); + // 1.2.840.113549.2.13 + OID_TO_PRF.put("2a864886f70d020d", "HmacSHA512/256"); + } - private static final String OID_PKCS5_PBES2 = "1.2.840.113549.1.5.13"; - private static final String PBES2 = "PBES2"; + private static final Map<String,Algorithm> OID_TO_ALGORITHM = new HashMap<>(); + static { + // 1.2.840.113549.3.7 + OID_TO_ALGORITHM.put("2a864886f70d0307", Algorithm.DES_EDE3_CBC); + // 2.16.840.1.101.3.4.1.2 + OID_TO_ALGORITHM.put("608648016503040102", Algorithm.AES128_CBC_PAD); + // 2.16.840.1.101.3.4.1.42 + OID_TO_ALGORITHM.put("60864801650304012a", Algorithm.AES256_CBC_PAD); + } public static String toPEM(X509Certificate certificate) throws CertificateEncodingException { StringBuilder result = new StringBuilder(); @@ -169,10 +202,10 @@ public class PEMFile { for (Part part : parts) { switch (part.type) { case Part.PRIVATE_KEY: - privateKey = part.toPrivateKey(null, keyAlgorithm, Format.PKCS8, filename); + privateKey = part.toPrivateKey(keyAlgorithm, Format.PKCS8, filename); break; case Part.EC_PRIVATE_KEY: - privateKey = part.toPrivateKey(null, "EC", Format.RFC5915, filename); + privateKey = part.toPrivateKey("EC", Format.RFC5915, filename); break; case Part.ENCRYPTED_PRIVATE_KEY: privateKey = part.toPrivateKey(passwordToUse, keyAlgorithm, Format.PKCS8, filename); @@ -181,7 +214,7 @@ public class PEMFile { if (part.algorithm == null) { // If no encryption algorithm was detected, ignore any // (probably default) key password provided. - privateKey = part.toPrivateKey(null, keyAlgorithm, Format.PKCS1, filename); + privateKey = part.toPrivateKey(keyAlgorithm, Format.PKCS1, filename); } else { privateKey = part.toPrivateKey(passwordToUse, keyAlgorithm, Format.PKCS1, filename); } @@ -194,7 +227,7 @@ public class PEMFile { } } - private class Part { + private static class Part { public static final String BEGIN_BOUNDARY = "-----BEGIN "; public static final String END_BOUNDARY = "-----END "; public static final String FINISH_BOUNDARY = "-----"; @@ -220,45 +253,46 @@ public class PEMFile { return (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(decode())); } + + /** + * Extracts the private key from an unencrypted PEMFile. + * + * @param keyAlgorithm Key algorithm if known or null if it needs to be obtained from the PEM file + * @param format The format used to encode the private key + * @param filename The name of the PEM file + * + * @return The clear text private key extracted from the PEM file + * + * @throws GeneralSecurityException If there is a cryptographic error processing the PEM file + */ + public PrivateKey toPrivateKey(String keyAlgorithm, Format format, String filename) throws GeneralSecurityException { + return toPrivateKey(keyAlgorithm, format, filename, decode()); + } + + + /** + * Extracts the private key from an encrypted PEMFile. + * + * @param password Password to decrypt the private key + * @param keyAlgorithm Key algorithm if known or null if it needs to be obtained from the PEM file + * @param format The format used to encode the private key + * @param filename The name of the PEM file + * + * @return The clear text private key extracted from the PEM file + * + * @throws GeneralSecurityException If there is a cryptographic error processing the PEM file + * @throws IOException If there is an I/O error reading the PEM file + */ public PrivateKey toPrivateKey(String password, String keyAlgorithm, Format format, String filename) throws GeneralSecurityException, IOException { - KeySpec keySpec = null; - if (password == null) { - switch (format) { - case PKCS1: { - keySpec = parsePKCS1(decode()); - break; - } - case PKCS8: { - keySpec = new PKCS8EncodedKeySpec(decode()); - break; - } - case RFC5915: { - keySpec = new PKCS8EncodedKeySpec(rfc5915ToPkcs8(decode())); - break; - } - } - } else { - 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? + String secretKeyAlgorithm; + String cipherTransformation; + int keyLength; + + switch (format) { + case PKCS1: { + switch (algorithm) { case "DES-CBC": { secretKeyAlgorithm = "DES"; @@ -288,12 +322,147 @@ public class PEMFile { byte[] iv = fromHex(ivHex); // The IV is also used as salt for the password generation - byte[] key = deriveKey(keyLength, password, iv); + byte[] key = deriveKeyPBKDF1(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); + return toPrivateKey(keyAlgorithm, format, filename, pkcs1); + } + case PKCS8: { + // Encrypted PEM file is PKCS8 + Asn1Parser p = new Asn1Parser(decode()); + + //@formatter:off + /* + * RFC 5208 - PKCS #8 + * RFC 8108 - PKCS #5 + * + * SEQ - PKCS #8 + * SEQ - PKCS #8 encryptionAlgorithm + * OID - PKCS #5 PBES2 OID + * SEQ - PKCS #5 PBES2-params + * SEQ - PKCS #5 PBES2 key derivation function + * OID - PKCS #5 PBES2 KDF OID - must be PBKDF2 + * SEQ - PKCS #5 PBKDF2-params + * OCTET STRING - PKCS #5 PBKDF2 salt + * INT - PKCS #5 PBKDF2 interationCount + * INT - PKCS #5 PBKDF2 key length OPTIONAL + * SEQ - PKCS #5 PBKDF2 PRF + * OID - PKCS #5 PBKDF2 PRF OID + * NULL - PKCS #5 PBKDF2 PRF parameters + * SEQ - PKCS #5 PBES2 encryption scheme + * OID - PKCS #5 PBES2 algorithm OID + * OCTET STRING - PKCS #5 PBES2 algorithm iv + * OCTET STRING - PKCS #8 encryptedData + */ + //@formatter:on + + // Parse the PKCS #8 outer sequence and validate the length + p.parseTagSequence(); + p.parseFullLength(); + + // Parse the PKCS #8 encryption algorithm + p.parseTagSequence(); + p.parseLength(); + + // PBES2 OID + byte[] oidEncryptionAlgorithm = p.parseOIDAsBytes(); + /* + * Implementation note. If other algorithms are ever supported, the KDF check below is likely to + * need to be adjusted. + */ + if (!Arrays.equals(oidEncryptionAlgorithm, OID_PBES2)) { + throw new NoSuchAlgorithmException(sm.getString("pemFile.unknownPkcs8Algorithm", + HexUtils.toHexString(oidEncryptionAlgorithm))); + } + + // PBES2-params + p.parseTagSequence(); + p.parseLength(); + + // PBES2 KDF + p.parseTagSequence(); + p.parseLength(); + byte[] oidKDF = p.parseOIDAsBytes(); + if (!Arrays.equals(oidKDF, OID_PBKDF2)) { + throw new NoSuchAlgorithmException(sm.getString("pemFile.notPbkdf2", + HexUtils.toHexString(oidKDF))); + } + + // PBES2 KDF-params + p.parseTagSequence(); + p.parseLength(); + byte[] salt = p.parseOctetString(); + int iterationCount = p.parseInt().intValue(); + if (p.peekTag() == Asn1Parser.TAG_INTEGER) { + keyLength = p.parseInt().intValue(); + } + + // PBKDF2 PRF + p.parseTagSequence(); + p.parseLength(); + byte[] oidPRF = p.parseOIDAsBytes(); + String prf = OID_TO_PRF.get(HexUtils.toHexString(oidPRF)); + if (prf == null) { + throw new NoSuchAlgorithmException(sm.getString("pemFile.unknownPrfAlgorithm", prf)); + } + p.parseNull(); + + // PBES2 encryption scheme + p.parseTagSequence(); + p.parseLength(); + byte[] oidCipher = p.parseOIDAsBytes(); + Algorithm algorithm = OID_TO_ALGORITHM.get(HexUtils.toHexString(oidCipher)); + if (algorithm == null) { + throw new NoSuchAlgorithmException(sm.getString("pemFile.unknownEncryptionAlgorithm", + HexUtils.toHexString(oidCipher))); + } + + byte[] iv = p.parseOctetString(); + + // Encrypted data + byte[] encryptedData = p.parseOctetString(); + + // ASN.1 parsing complete + + // Build secret key to decrypt encrypted data + byte[] key = deriveKeyPBKDF2("PBKDF2With" + prf, password, salt, iterationCount, algorithm.getKeyLength()); + SecretKey secretKey = new SecretKeySpec(key, algorithm.getSecretKeyAlgorithm()); + + // Configure algorithm to decrypt encrypted data + Cipher cipher = Cipher.getInstance(algorithm.getTransformation()); + cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); + + // Decrypt the encrypted key and call this method again to process the key + byte[] decryptedData = cipher.doFinal(encryptedData); + return toPrivateKey(keyAlgorithm, format, filename, decryptedData); + } + default: { + // Expected to be unencrypted + throw new NoSuchAlgorithmException(sm.getString("pemFile.unknownEncryptedFormat", format)); + } + } + } + + + private PrivateKey toPrivateKey(String keyAlgorithm, Format format, String filename, byte[] source) + throws GeneralSecurityException { + + KeySpec keySpec = null; + + switch (format) { + case PKCS1: { + keySpec = parsePKCS1(source); + break; + } + case PKCS8: { + keySpec = new PKCS8EncodedKeySpec(source); + break; + } + case RFC5915: { + keySpec = new PKCS8EncodedKeySpec(rfc5915ToPkcs8(source)); + break; } } @@ -318,29 +487,7 @@ public class PEMFile { } - private String getPBEAlgorithm(EncryptedPrivateKeyInfo privateKeyInfo) { - AlgorithmParameters parameters = privateKeyInfo.getAlgParameters(); - String algName = privateKeyInfo.getAlgName(); - // Java 11 returns OID_PKCS5_PBES2 - // Java 17 returns PBES2 - if (parameters != null && (OID_PKCS5_PBES2.equals(algName) || PBES2.equals(algName))) { - /* - * This should be "PBEWith<prf>And<encryption>". - * Relying on the toString() implementation is potentially - * fragile but acceptable in this case since the JRE depends on - * the toString() implementation as well. - * In the future, if necessary, we can parse the value of - * parameters.getEncoded() but the associated complexity and - * unlikeliness of the JRE implementation changing means that - * Tomcat will use to toString() approach for now. - */ - return parameters.toString(); - } - return privateKeyInfo.getAlgName(); - } - - - private byte[] deriveKey(int keyLength, String password, byte[] salt) throws NoSuchAlgorithmException { + private byte[] deriveKeyPBKDF1(int keyLength, String password, byte[] salt) throws NoSuchAlgorithmException { // PBKDF1-MD5 as specified by PKCS#5 byte[] key = new byte[keyLength]; @@ -363,6 +510,17 @@ public class PEMFile { } + private byte[] deriveKeyPBKDF2(String algorithm, String password, byte[] salt, int iterations, int keyLength) + throws GeneralSecurityException { + SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algorithm); + KeySpec keySpec; + keySpec = new PBEKeySpec(password.toCharArray(), salt, iterations, keyLength); + SecretKey secretKey = secretKeyFactory.generateSecret(keySpec); + return secretKey.getEncoded(); + } + + + //@formatter:off /* * RFC5915: SEQ * INT value = 1 @@ -385,6 +543,7 @@ public class PEMFile { * BIT STRING len = 520 bits * */ + //@formatter:on private byte[] rfc5915ToPkcs8(byte[] source) { // Parse RFC 5915 format EC private key Asn1Parser p = new Asn1Parser(source); @@ -481,4 +640,33 @@ public class PEMFile { PKCS8, RFC5915 } + + + private enum Algorithm { + AES128_CBC_PAD("AES/CBC/PKCS5PADDING", "AES", 128), + AES256_CBC_PAD("AES/CBC/PKCS5PADDING", "AES", 256), + DES_EDE3_CBC("DESede/CBC/PKCS5Padding", "DESede", 192); + + private final String transformation; + private final String secretKeyAlgorithm; + private final int keyLength; + + Algorithm(String transformation, String secretKeyAlgorithm, int keyLength) { + this.transformation = transformation; + this.secretKeyAlgorithm = secretKeyAlgorithm; + this.keyLength = keyLength; + } + + public String getTransformation() { + return transformation; + } + + public String getSecretKeyAlgorithm() { + return secretKeyAlgorithm; + } + + public int getKeyLength() { + return keyLength; + } + } } diff --git a/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java b/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java index dc10b2b9dc..9a0941bb9a 100644 --- a/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java +++ b/test/org/apache/tomcat/util/net/jsse/TestPEMFile.java @@ -39,7 +39,9 @@ public class TestPEMFile { 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"; + private static final String KEY_ENCRYPTED_PKCS8_HMACSHA256_AES_128_CBC = "key-encrypted-pkcs8-hmacsha256-aes-128-cbc.pem"; + private static final String KEY_ENCRYPTED_PKCS8_HMACSHA256_AES_256_CBC = "key-encrypted-pkcs8-hmacsha256-aes-256-cbc.pem"; + private static final String KEY_ENCRYPTED_PKCS8_HMACSHA256_DES_EDE3_CBC = "key-encrypted-pkcs8-hmacsha256-des-ede3-cbc.pem"; @Parameterized.Parameters public static Collection<Object[]> parameters() { @@ -91,8 +93,20 @@ public class TestPEMFile { @Test - public void testKeyEncryptedPkcs8() throws Exception { - testKeyEncrypted(KEY_ENCRYPTED_PKCS8); + public void testKeyEncryptedPkcs8HmacSha256Aes128() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS8_HMACSHA256_AES_128_CBC); + } + + + @Test + public void testKeyEncryptedPkcs8HmacSha256Aes256() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS8_HMACSHA256_AES_256_CBC); + } + + + @Test + public void testKeyEncryptedPkcs8HmacSha256DesEde3Cbc() throws Exception { + testKeyEncrypted(KEY_ENCRYPTED_PKCS8_HMACSHA256_DES_EDE3_CBC); } diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-aes-128-cbc.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-aes-128-cbc.pem new file mode 100644 index 0000000000..dfefd75707 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-aes-128-cbc.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +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 +-----END ENCRYPTED 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-hmacsha256-aes-256-cbc.pem similarity index 100% rename from test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8.pem rename to test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-aes-256-cbc.pem diff --git a/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-des-ede3-cbc.pem b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-des-ede3-cbc.pem new file mode 100644 index 0000000000..dd5c196613 --- /dev/null +++ b/test/org/apache/tomcat/util/net/jsse/key-encrypted-pkcs8-hmacsha256-des-ede3-cbc.pem @@ -0,0 +1,54 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +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 +XRdksDlwnGCCHdhG7YfRuQ== +-----END ENCRYPTED PRIVATE KEY----- --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org