This is an automated email from the ASF dual-hosted git repository. lgoldstein pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit d14a99bb5504198111cbe5514063747a98e8d2f5 Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Fri May 22 16:08:28 2020 +0300 [SSHD-989] Fixed parsing of PKCS8 encoded PEM private key files --- CHANGES.md | 2 +- .../loader/pem/ECDSAPEMResourceKeyPairParser.java | 113 ++++++++++++++------- .../loader/pem/PKCS8PEMResourceKeyPairParser.java | 15 ++- .../keys/loader/pem/PKCS8PrivateKeyInfo.java | 39 ++++++- .../apache/sshd/common/util/io/der/DERParser.java | 6 ++ .../sshd/common/config/keys/KeyUtilsCloneTest.java | 1 - .../pem/PKCS8PEMResourceKeyPairParserTest.java | 40 ++++---- .../common/config/keys/loader/pem/pkcs8-ec-256.pem | 5 + .../common/config/keys/loader/pem/pkcs8-ec-384.pem | 6 ++ .../common/config/keys/loader/pem/pkcs8-ec-521.pem | 8 ++ .../config/keys/loader/pem/pkcs8-rsa-1024.pem | 16 +++ .../config/keys/loader/pem/pkcs8-rsa-2048.pem | 28 +++++ .../config/keys/loader/pem/pkcs8-rsa-3072.pem | 40 ++++++++ .../config/keys/loader/pem/pkcs8-rsa-4096.pem | 52 ++++++++++ 14 files changed, 307 insertions(+), 64 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1495950..001985f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -57,4 +57,4 @@ as much of the available functionality as possible. * [SSHD-998](https://issues.apache.org/jira/browse/SSHD-998) - Take into account SFTP version preference when establishing initial channel -* [SSHD-989](https://issues.apache.org/jira/browse/SSHD-989) - Implement ECDSA public key recovery for PKCS8 encoded data +* [SSHD-989](https://issues.apache.org/jira/browse/SSHD-989) - Read correctly ECDSA key pair from PKCS8 encoded data diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/ECDSAPEMResourceKeyPairParser.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/ECDSAPEMResourceKeyPairParser.java index 0fe9b15..08fe839 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/ECDSAPEMResourceKeyPairParser.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/ECDSAPEMResourceKeyPairParser.java @@ -87,14 +87,23 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar InputStream inputStream, boolean okToClose) throws IOException, GeneralSecurityException { try (DERParser parser = new DERParser(NoCloseInputStream.resolveInputStream(inputStream, okToClose))) { - return parseECKeyPair(parser); + return parseECKeyPair(null, parser); } } - public static KeyPair parseECKeyPair(DERParser parser) + /** + * @param curve The {@link ECCurves curve} represented by this data (in case it was optional and + * somehow known externally) if {@code null} then it is assumed to be part of the + * parsed data. then it is assumed to be part of the data. + * @param parser The {@link DERParser} for the data + * @return The parsed {@link KeyPair} + * @throws IOException If failed to parse the data + * @throws GeneralSecurityException If failed to generate the keys + */ + public static KeyPair parseECKeyPair(ECCurves curve, DERParser parser) throws IOException, GeneralSecurityException { ASN1Object sequence = parser.readObject(); - Map.Entry<ECPublicKeySpec, ECPrivateKeySpec> spec = decodeECPrivateKeySpec(sequence); + Map.Entry<ECPublicKeySpec, ECPrivateKeySpec> spec = decodeECPrivateKeySpec(curve, sequence); if (!SecurityUtils.isECCSupported()) { throw new NoSuchProviderException("ECC not supported"); } @@ -136,12 +145,14 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar * </CODE> * </PRE> * + * @param curve The {@link ECCurves curve} represented by this data (in case it was optional and somehow + * known externally) if {@code null} then it is assumed to be part of the parsed data. * @param sequence The {@link ASN1Object} sequence containing the DER encoded data * @return The decoded {@link SimpleImmutableEntry} of {@link ECPublicKeySpec} and * {@link ECPrivateKeySpec} * @throws IOException If failed to to decode the DER stream */ - public static SimpleImmutableEntry<ECPublicKeySpec, ECPrivateKeySpec> decodeECPrivateKeySpec(ASN1Object sequence) + public static Map.Entry<ECPublicKeySpec, ECPrivateKeySpec> decodeECPrivateKeySpec(ECCurves curve, ASN1Object sequence) throws IOException { ASN1Type objType = (sequence == null) ? null : sequence.getObjType(); if (!ASN1Type.SEQUENCE.equals(objType)) { @@ -149,13 +160,10 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar } try (DERParser parser = sequence.createParser()) { - ECPrivateKeySpec prvSpec = decodeECPrivateKeySpec(parser); - ECCurves curve = ECCurves.fromCurveParameters(prvSpec.getParams()); - if (curve == null) { - throw new StreamCorruptedException("Unknown curve"); - } - - ECPoint w = decodeECPublicKeyValue(curve, parser); + Map.Entry<ECPrivateKeySpec, ASN1Object> result = decodeECPrivateKeySpec(curve, parser); + ECPrivateKeySpec prvSpec = result.getKey(); + ASN1Object publicData = result.getValue(); + ECPoint w = (publicData == null) ? decodeECPublicKeyValue(parser) : decodeECPointData(publicData); ECPublicKeySpec pubSpec = new ECPublicKeySpec(w, prvSpec.getParams()); return new SimpleImmutableEntry<>(pubSpec, prvSpec); } @@ -171,7 +179,8 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar * publicKey [1] BIT STRING OPTIONAL * } */ - public static final ECPrivateKeySpec decodeECPrivateKeySpec(DERParser parser) throws IOException { + public static Map.Entry<ECPrivateKeySpec, ASN1Object> decodeECPrivateKeySpec(ECCurves curve, DERParser parser) + throws IOException { // see openssl asn1parse -inform PEM -in ...file... -dump ASN1Object versionObject = parser.readObject(); if (versionObject == null) { @@ -208,12 +217,36 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar * curve domain parameters. Though the ASN.1 indicates that the parameters field is OPTIONAL, implementations * that conform to this document MUST always include the parameters field. */ - ASN1Object paramsObject = parser.readObject(); + Map.Entry<ECCurves, ASN1Object> result = parseCurveParameter(parser); + ECCurves namedParam = (result == null) ? null : result.getKey(); + if (namedParam == null) { + if (curve == null) { + throw new StreamCorruptedException("Cannot determine curve type"); + } + } else if (curve == null) { + curve = namedParam; + } else if (namedParam != curve) { + throw new StreamCorruptedException("Mismatched provide (" + curve + ") vs. parsed curve (" + namedParam + ")"); + } + + BigInteger s = ECCurves.octetStringToInteger(keyObject.getPureValueBytes()); + ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, curve.getParameters()); + return new SimpleImmutableEntry<>(keySpec, (result == null) ? null : result.getValue()); + } + + public static Map.Entry<ECCurves, ASN1Object> parseCurveParameter(DERParser parser) throws IOException { + return parseCurveParameter(parser.readObject()); + } + + public static Map.Entry<ECCurves, ASN1Object> parseCurveParameter(ASN1Object paramsObject) throws IOException { if (paramsObject == null) { - throw new StreamCorruptedException("No parameters value"); + return null; } - // TODO make sure params object tag is 0xA0 + ASN1Type objType = paramsObject.getObjType(); + if (objType == ASN1Type.NULL) { + return null; + } List<Integer> curveOID; try (DERParser paramsParser = paramsObject.createParser()) { @@ -223,10 +256,13 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar } /* - * SSHD-989 - if object type is BIT STRING then this is the public - * key - in which case we need to figure out some other way to recover - * the curve parameters + * The curve OID is OPTIONAL - if it is not there then the + * public key data replaces it */ + objType = namedCurve.getObjType(); + if (objType == ASN1Type.BIT_STRING) { + return new SimpleImmutableEntry<>(null, namedCurve); + } curveOID = namedCurve.asOID(); } @@ -236,8 +272,7 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar throw new StreamCorruptedException("Unknown curve OID: " + curveOID); } - BigInteger s = ECCurves.octetStringToInteger(keyObject.getPureValueBytes()); - return new ECPrivateKeySpec(s, curve.getParameters()); + return new SimpleImmutableEntry<>(curve, null); } /** @@ -252,14 +287,16 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar * </code> * </pre> * - * @param curve The {@link ECCurves} curve * @param parser The {@link DERParser} assumed to be positioned at the start of the data * @return The encoded {@link ECPoint} * @throws IOException If failed to create the point */ - public static final ECPoint decodeECPublicKeyValue(ECCurves curve, DERParser parser) throws IOException { + public static final ECPoint decodeECPublicKeyValue(DERParser parser) throws IOException { + return decodeECPublicKeyValue(parser.readObject()); + } + + public static final ECPoint decodeECPublicKeyValue(ASN1Object dataObject) throws IOException { // see openssl asn1parse -inform PEM -in ...file... -dump - ASN1Object dataObject = parser.readObject(); if (dataObject == null) { throw new StreamCorruptedException("No public key data bytes"); } @@ -267,24 +304,26 @@ public class ECDSAPEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar /* * According to https://tools.ietf.org/html/rfc5915 * - * Though the ASN.1 indicates publicKey is OPTIONAL, implementations that conform to this document SHOULD always - * include the publicKey field + * Though the ASN.1 indicates publicKey is OPTIONAL, implementations + * that conform to this document SHOULD always include the publicKey field */ try (DERParser dataParser = dataObject.createParser()) { - ASN1Object pointData = dataParser.readObject(); - if (pointData == null) { - throw new StreamCorruptedException("Missing public key data parameter"); - } + return decodeECPointData(dataParser.readObject()); + } + } - ASN1Type objType = pointData.getObjType(); - if (!ASN1Type.BIT_STRING.equals(objType)) { - throw new StreamCorruptedException("Non-matching public key object type: " + objType); - } + public static final ECPoint decodeECPointData(ASN1Object pointData) throws IOException { + if (pointData == null) { + throw new StreamCorruptedException("Missing public key data parameter"); + } - // see https://tools.ietf.org/html/rfc5480#section-2.2 - byte[] octets = pointData.getValue(); - return ECCurves.octetStringToEcPoint(octets); + ASN1Type objType = pointData.getObjType(); + if (!ASN1Type.BIT_STRING.equals(objType)) { + throw new StreamCorruptedException("Non-matching public key object type: " + objType); } - } + // see https://tools.ietf.org/html/rfc5480#section-2.2 + byte[] octets = pointData.getValue(); + return ECCurves.octetStringToEcPoint(octets); + } } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParser.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParser.java index f871a3a..3207c38 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParser.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParser.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; import org.apache.sshd.common.NamedResource; +import org.apache.sshd.common.cipher.ECCurves; import org.apache.sshd.common.config.keys.FilePasswordProvider; import org.apache.sshd.common.config.keys.KeyUtils; import org.apache.sshd.common.session.SessionContext; @@ -41,6 +42,7 @@ import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.common.util.io.IoUtils; import org.apache.sshd.common.util.io.der.ASN1Object; +import org.apache.sshd.common.util.io.der.ASN1Type; import org.apache.sshd.common.util.io.der.DERParser; import org.apache.sshd.common.util.security.SecurityUtils; @@ -91,8 +93,19 @@ public class PKCS8PEMResourceKeyPairParser extends AbstractPEMResourceKeyPairPar if (SecurityUtils.isECCSupported() && ECDSAPEMResourceKeyPairParser.ECDSA_OID.equals(oid)) { ASN1Object privateKeyBytes = pkcs8Info.getPrivateKeyBytes(); + ASN1Object extraInfo = pkcs8Info.getAlgorithmParameter(); + ASN1Type objType = (extraInfo == null) ? ASN1Type.NULL : extraInfo.getObjType(); + List<Integer> oidCurve = (objType == ASN1Type.NULL) ? Collections.emptyList() : extraInfo.asOID(); + ECCurves curve = null; + if (GenericUtils.isNotEmpty(oidCurve)) { + curve = ECCurves.fromOIDValue(oidCurve); + if (curve == null) { + throw new NoSuchAlgorithmException("Cannot match EC curve OID=" + oidCurve); + } + } + try (DERParser parser = privateKeyBytes.createParser()) { - kp = ECDSAPEMResourceKeyPairParser.parseECKeyPair(parser); + kp = ECDSAPEMResourceKeyPairParser.parseECKeyPair(curve, parser); } } else { PrivateKey prvKey = decodePEMPrivateKeyPKCS8(oidAlgorithm, encBytes); diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PrivateKeyInfo.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PrivateKeyInfo.java index 48917a5..b8732b5 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PrivateKeyInfo.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PrivateKeyInfo.java @@ -55,6 +55,7 @@ import org.apache.sshd.common.util.io.der.DERParser; public class PKCS8PrivateKeyInfo /* TODO Cloneable */ { private BigInteger version; private List<Integer> algorithmIdentifier; + private ASN1Object algorithmParameter; private ASN1Object privateKeyBytes; public PKCS8PrivateKeyInfo() { @@ -89,6 +90,14 @@ public class PKCS8PrivateKeyInfo /* TODO Cloneable */ { this.algorithmIdentifier = algorithmIdentifier; } + public ASN1Object getAlgorithmParameter() { + return algorithmParameter; + } + + public void setAlgorithmParameter(ASN1Object algorithmParameter) { + this.algorithmParameter = algorithmParameter; + } + public ASN1Object getPrivateKeyBytes() { return privateKeyBytes; } @@ -115,6 +124,21 @@ public class PKCS8PrivateKeyInfo /* TODO Cloneable */ { * @throws IOException If failed to parse the encoding */ public void decode(ASN1Object privateKeyInfo) throws IOException { + /* + * SEQUENCE { + * INTEGER 0x00 (0 decimal) + * SEQUENCE { + * OBJECTIDENTIFIER encryption type + * OBJECTIDENTIFIER extra info - may be NULL + * } + * OCTETSTRING private key + * } + */ + ASN1Type objType = privateKeyInfo.getObjType(); + if (objType != ASN1Type.SEQUENCE) { + throw new StreamCorruptedException("Not a top level sequence: " + objType); + } + try (DERParser parser = privateKeyInfo.createParser()) { ASN1Object versionObject = parser.readObject(); if (versionObject == null) { @@ -128,10 +152,21 @@ public class PKCS8PrivateKeyInfo /* TODO Cloneable */ { throw new StreamCorruptedException("No private key algorithm"); } + objType = privateKeyInfo.getObjType(); + if (objType != ASN1Type.SEQUENCE) { + throw new StreamCorruptedException("Not an algorithm parameters sequence: " + objType); + } + try (DERParser oidParser = privateKeyAlgorithm.createParser()) { ASN1Object oid = oidParser.readObject(); setAlgorithmIdentifier(oid.asOID()); - // TODO add optional algorithm identifier parameters parsing + + // Extra information is OPTIONAL + ASN1Object extraInfo = oidParser.readObject(); + objType = (extraInfo == null) ? ASN1Type.NULL : extraInfo.getObjType(); + if (objType != ASN1Type.NULL) { + setAlgorithmParameter(extraInfo); + } } ASN1Object privateKeyData = parser.readObject(); @@ -139,7 +174,7 @@ public class PKCS8PrivateKeyInfo /* TODO Cloneable */ { throw new StreamCorruptedException("No private key data"); } - ASN1Type objType = privateKeyData.getObjType(); + objType = privateKeyData.getObjType(); if (objType != ASN1Type.OCTET_STRING) { throw new StreamCorruptedException("Private key data not an " + ASN1Type.OCTET_STRING + ": " + objType); } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERParser.java b/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERParser.java index 4a4536e..a9fde49 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERParser.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/util/io/der/DERParser.java @@ -27,6 +27,7 @@ import java.io.StreamCorruptedException; import java.math.BigInteger; import java.util.Arrays; +import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.NumberUtils; import org.apache.sshd.common.util.buffer.BufferUtils; @@ -122,6 +123,11 @@ public class DERParser extends FilterInputStream { return null; } + ASN1Type objType = ASN1Type.fromDERValue(tag); + if (objType == ASN1Type.NULL) { + return new ASN1Object((byte) tag, 0, GenericUtils.EMPTY_BYTE_ARRAY); + } + int length = readLength(); byte[] value = new byte[length]; int n = read(value); diff --git a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsCloneTest.java b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsCloneTest.java index 0b64d08..5b3e9e6 100644 --- a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsCloneTest.java +++ b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/KeyUtilsCloneTest.java @@ -116,5 +116,4 @@ public class KeyUtilsCloneTest extends JUnitTestSupport { assertTrue(prefix + ": Cloned private key not equals", KeyUtils.compareKeys(k1, k2)); } } - } diff --git a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java index 6d62616..76b9224 100644 --- a/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java +++ b/sshd-common/src/test/java/org/apache/sshd/common/config/keys/loader/pem/PKCS8PEMResourceKeyPairParserTest.java @@ -26,7 +26,6 @@ import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; -import java.security.PublicKey; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -43,7 +42,6 @@ import org.apache.sshd.util.test.JUnitTestSupport; import org.apache.sshd.util.test.NoIoTestCase; import org.junit.Assume; import org.junit.FixMethodOrder; -import org.junit.Ignore; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; @@ -81,6 +79,11 @@ public class PKCS8PEMResourceKeyPairParserTest extends JUnitTestSupport { } if (SecurityUtils.isECCSupported()) { for (ECCurves curve : ECCurves.VALUES) { + if (!curve.isSupported()) { + outputDebugMessage("Skip unsupported curve=%s", curve); + continue; + } + params.add(new Object[] { KeyUtils.EC_ALGORITHM, curve.getKeySize() }); } } @@ -88,7 +91,7 @@ public class PKCS8PEMResourceKeyPairParserTest extends JUnitTestSupport { } @Test // see SSHD-760 - public void testPkcs8() throws IOException, GeneralSecurityException { + public void testLocallyGeneratedPkcs8() throws IOException, GeneralSecurityException { KeyPairGenerator generator = SecurityUtils.getKeyPairGenerator(algorithm); if (keySize > 0) { generator.initialize(keySize); @@ -114,14 +117,18 @@ public class PKCS8PEMResourceKeyPairParserTest extends JUnitTestSupport { } } - // see https://gist.github.com/briansmith/2ee42439923d8e65a266994d0f70180b - // openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out pkcs8-ecdsa-256.pem - // openssl ecparam -genkey -name prime256v1 -noout -out pkcs8-ec-256.key - // openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs8-ec-256.key -out pkcs8-ec-256.pem - // openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:1024 -out pkcs8-rsa-1024.pem - // openssl asn1parse -inform PEM -in ...file... -dump + /* + * See https://gist.github.com/briansmith/2ee42439923d8e65a266994d0f70180b + * + * openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:1024 -out pkcs8-rsa-1024.pem + * openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -pkeyopt ec_param_enc:named_curve -out pkcs8-ecdsa-256.pem + * + * openssl ecparam -genkey -name prime256v1 -noout -out pkcs8-ec-256.key + * openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs8-ec-256.key -out pkcs8-ec-256.pem + * + * openssl asn1parse -inform PEM -in ...file... -dump + */ @Test // see SSHD-989 - @Ignore("WIP") public void testPKCS8FileParsing() throws Exception { String resourceKey = "pkcs8-" + algorithm.toLowerCase() + "-" + keySize + ".pem"; URL url = getClass().getResource(resourceKey); @@ -129,18 +136,7 @@ public class PKCS8PEMResourceKeyPairParserTest extends JUnitTestSupport { Collection<KeyPair> pairs = PKCS8PEMResourceKeyPairParser.INSTANCE.loadKeyPairs(null, url, null); assertEquals("Mismatched extract keys count", 1, GenericUtils.size(pairs)); - - assertSignatureMatch("Cannot sign with recovered key pair", GenericUtils.head(pairs)); - } - - private static void assertSignatureMatch(String message, KeyPair kp) throws GeneralSecurityException { - assertSignatureMatch(message, kp.getPrivate(), kp.getPublic()); - } - - private static void assertSignatureMatch( - String message, PrivateKey privateKey, PublicKey publicKey) - throws GeneralSecurityException { - // TODO + validateKeyPairSignable(algorithm + "/" + keySize, GenericUtils.head(pairs)); } @Override diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-256.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-256.pem new file mode 100644 index 0000000..d7727e1 --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-256.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgs6QE06EskVFA/o7i +HrNnF9In14QcJC9EgkXsVFk+SWWhRANCAAT8lGjPLQVdmwglhBP9refqp9Mrr7AN +pGSOy3cCDtG4JeRr25s+EXavossaZ9U8MWe39wWUV7yvz5BT5hA3HSig +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-384.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-384.pem new file mode 100644 index 0000000..e552dfa --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-384.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAKagn5+JY4/pjeHLUX +IORdDtAd8l//84hnzxiWR80AHLnyI8N4YUp7zPGUY0n5/VehZANiAAQacLGO21zt +XkO/jijS+1BMxfuZyvtDE0fyENi6FNsYz92s+szssUxLl1XPO1Bv7+xdX/nkqjbi +V26a3G8VzoNUl8KNrYUfH+fcukhVKCU3A9VP8u1HZBhOIn+ouKUSj5E= +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-521.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-521.pem new file mode 100644 index 0000000..4281d87 --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-ec-521.pem @@ -0,0 +1,8 @@ +-----BEGIN PRIVATE KEY----- +MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIAliKmTYJEBwcWV4a+ +nbS69ht7d3mvUrp60m7T+gAXxUpb5XNWwaxa3PxRY9Mm4Or8mOfPa8d6rSlNARFP +mU/zOFuhgYkDgYYABAAmm+nrn29TxAonRop25S9DFRX30ci2E+b3qDBy94N+A06n +Q+wLo+vK95KbG461R9JUXBlH2qLQnLhUle5KpNw9nwAy5vZgrwqmCB1cdDarkTGr +FpkVsrovB6mD7nxY/13wws1Ll1or3Bsb6ZQfnZ9VloaEVnnc0QLeO8HaRxif865D +tA== +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-1024.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-1024.pem new file mode 100644 index 0000000..6f6df20 --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-1024.pem @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALpizZejDUx5l83q +I9Kg75KhYvj5mRVBdTRS8aN/bjiDNOn+yXeRVIB5Vw/r+V6N+1UzTcD+t4sC1b61 +mFgOqn5d9adDWw//zROovmCujqvJCDWTZPpuj/05u2BzlDzrkgTXQ/k4Owu9SjQQ +hcrbkaHtvc1/Cfi1DfEv+n7FxABRAgMBAAECgYB9t9ku99cnhziittSU5OLTh7IH +d+wOz0ksEupUOsbwrWeKkcX4tXlG8xGLdsKMSb6GWIWQsP7CcBYWfcyVUMckL4HP +0jx+6hx7Y3uFtM1/MkucM0D+UAB6cQXHRr2xoRqpiQWBcOAL7dT7IBRMaB4iOGyI +sDnsrucoX2hQU6kXQQJBAO8M4+XZgH2t/4HHA3Upmi5j0L7JmWusnq5Lhf8Va8mO +fLIO0AuKuUtvhWlne3cyUZbaSBOE13DTwNn57LcGjikCQQDHmfpOXDrJCcOjKjQ5 +9g6oVWwU9SgZ51J3lVr83GaMCBdx0zMz5V7eGRsXudAHk6iVHdrznZBEdzWHAlmX +8VXpAkEA1TqwRiQ+wtxj3wUABpA3YU3Ts3rsCOmPGXVwbtpSrRUWEVW5KbJyGeG+ +JQkTTn1p3Z+TTyXdblzT1xthlNiaEQJABHlaF/mPQ8RZQ0YF56qxR2qqwomAPZxm +x9FsObDDB66CwAVo52fjyXysk8qRdCoGJFmH99/3ROGbLIyL75D0SQJBAI/EHfWS +n3+A/S0R+rQ9GIKXa1Y5wEgVPYKk+YPLfxdOUEj5ZLI5jrE2mHn7ILFnyZpgci6l +wxLeAa68VX4lp7g= +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-2048.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-2048.pem new file mode 100644 index 0000000..4942fb1 --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-2048.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDJqeUR4mteSX3c +UuZdaYOwdVcck2X9Ce02wxrUM/xa3NokhjQ+tNJY9FU8/fEYRASHMtUm3lBtnJkV +XWHlA2BKl8oUbkFzfDCk3B1iXGjAZTVkSzImmhhqtgWcKZmGoL5Irf+8w4jHf8rQ +5mp9hK3nQkTiAlELhAP2cEdDQcmynxN7zFkY0sMZQUeEQO1hHo+plwn3H33Cxq87 +XiyFKAJArqPmOEVkl/6oUY4MX5DRCPaYXGnINsAFY0PfmSPk1iV8HlevaeeiOmx2 +MNKiOw+PtlCr97QymmcdxKJzwmVKTLXrK9NHC8A/SJD6WUdY1aF1mjSVqeo/1y3f +GfUF9MKZAgMBAAECggEBAKFhon1DcqTLrzsH5G5QqCAoZwPpOS7cKMcwL2IuD/8u +yit8cobT8ZlaPnRGzA+dLvp6xXULZ9WwAhnE1ziMERzgh8j9ysb+VXc45xL13KZK +2AVg38tgebW74JVt/Pxt2pkTFZsb53OvYsD2A7Za3Ug6EiHDtNPAW+N1SrIaDa0w +kB+VMVVnaua+OuNBkrXEbhB14CJG/DGNiMvm6PkVNd9oQkbxykp1c6PU2ZQ4jJos +6oKeqMwXSSvwWhen9YoYtSaff2bJRy6HWaPiRAHKFw1WQMoAksmAvBsU/nwA6c/t +AOpzKcvX8b/VFlZpY9vdylXS/2ysK5lDTmXX9FWjhRkCgYEA73V7fnXJ10avbd85 +2/oTFmTB4rOg4a5VBqSy/AZiOwlLUyadUkyLR8gF7vsVB7PSnwH5HlGRORC+COnH +GVj+44gq3EbjwucqeYlSizW8hjLFOpYcm0AP1naQCiiBG0xUxFwc8xyE0zu+V9KX +8uHQTGejMEnz7Nx7j+LWxJchsEcCgYEA15gNeCaPb6TMR7LtUxtZ5+Rt0zLdG44Q +yMmrReT79via7HkFyxOZaO+8tk6APBNGx1mU8IXYpZWK0CPIHeKlqI8roqlfWQdp +XzQ7Zz1A4f02/o6DQtZthhTSg5K/iZ6Tb3KrKTuh0EO7yUfG+ybzfszwz8GJGdGt +uIOY4gNrRh8CgYA2qwmgm1+TSE3wtY/OCs+kwygIi53lKBm9RIigRQzUEZEi0KQG +D/eUUbQZFTV95q3lI1wucczHzGy2ODj+LnUymPnABGcnLgNib9lqcsAxmxGwCGlL +gFqdScAksY6YHtsTYTwyvIYOe4s/HZMXHjqh1t9IvPl1T/jdppoFk8NbLQKBgQDU +JymiAXgGqgnnyFgn/vNC8ZNtUFEqq2sy2tky53lW+B8j8pfT1c6R59AxKiCgfWua +AjpBUcT2dKjr1zo2xnCz5WdQIxHTvype6DxIhItTl2TFrKHYZL/UQKtDlGXtW+HD +uvhZk/fQxMaG9J4HSbY1IiEaoF10zdQAjWclia3HiwKBgQDX1piVYGI4c5HtC50h +NXdbPH+jxgdr3Hj43cki4OaXTg5drX8ZVFc0/fUhASAEG6WbFg9nDU0mH8o+5zoJ +JehiL/RQOK2s70fitgBYF6RBc+znBp5OEqdQiWn1UlTZ/CdSPfR4vkMADzFEYGxZ +YVsrUwMSVO65vmGmyfvmIL682g== +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-3072.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-3072.pem new file mode 100644 index 0000000..9d6a219 --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-3072.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +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 +uvn49/VWU7/8Ppw/Wg7C+L0B +-----END PRIVATE KEY----- diff --git a/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-4096.pem b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-4096.pem new file mode 100644 index 0000000..f625c8e --- /dev/null +++ b/sshd-common/src/test/resources/org/apache/sshd/common/config/keys/loader/pem/pkcs8-rsa-4096.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +18uzMDlMbqOoq+IErsvMbHs/fl8GtJ5S +-----END PRIVATE KEY-----