diff --git a/pom.xml b/pom.xml index 17e8de0..4c7c850 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ 3.3.9 1.8 - 1.78 + 0.6.0 5.9.0 1.2.0 @@ -68,14 +68,9 @@ - org.bouncycastle - bcprov-jdk18on - ${bouncycastle.version} - - - org.bouncycastle - bcpkix-jdk18on - ${bouncycastle.version} + com.hierynomus + asn-one + ${asn.one.version} diff --git a/src/main/java/de/dentrassi/crypto/pem/PemReader.java b/src/main/java/de/dentrassi/crypto/pem/PemReader.java new file mode 100644 index 0000000..b75aaa6 --- /dev/null +++ b/src/main/java/de/dentrassi/crypto/pem/PemReader.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2024 Red Hat Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Domenico Francesco Bruscino - initial PemReader implementation + */ + +package de.dentrassi.crypto.pem; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.Reader; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.interfaces.ECPrivateKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.ECPoint; +import java.security.spec.ECPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; + +import com.hierynomus.asn1.ASN1InputStream; +import com.hierynomus.asn1.ASN1OutputStream; +import com.hierynomus.asn1.encodingrules.der.DERDecoder; +import com.hierynomus.asn1.encodingrules.der.DEREncoder; +import com.hierynomus.asn1.types.ASN1Object; +import com.hierynomus.asn1.types.constructed.ASN1Sequence; +import com.hierynomus.asn1.types.constructed.ASN1TaggedObject; +import com.hierynomus.asn1.types.primitive.ASN1Integer; +import com.hierynomus.asn1.types.primitive.ASN1ObjectIdentifier; +import com.hierynomus.asn1.types.string.ASN1BitString; +import com.hierynomus.asn1.types.string.ASN1OctetString; + +public class PemReader extends BufferedReader { + + private static final String BEGIN = "-----BEGIN "; + private static final String CERTIFICATE = "CERTIFICATE"; + private static final String X509_CERTIFICATE = "X509 CERTIFICATE"; + private static final String EC_PRIVATE_KEY = "EC PRIVATE KEY"; + private static final String EC_PUBLIC_KEY_OBJ_ID = "1.2.840.10045.2.1"; + private static final String DSA_PRIVATE_KEY = "DSA PRIVATE KEY"; + private static final String RSA_PRIVATE_KEY = "RSA PRIVATE KEY"; + private static final String PRIVATE_KEY = "PRIVATE KEY"; + private static final String END = "-----END "; + private static final List KEY_ALGORITHMS = Arrays.asList("RSA", "DSA", "EC"); + + private static List keyFactories; + + private static List getKeyFactories() { + if (keyFactories == null) { + keyFactories = new ArrayList<>(); + + KEY_ALGORITHMS.forEach(s -> { + try { + keyFactories.add(KeyFactory.getInstance(s)); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + + return keyFactories; + } + + public PemReader(Reader in) { + super(in); + } + + public Object readObject() throws CertificateException, IOException { + byte[] objectContent = null; + String objectType = null; + + String line = readLine(); + + while (line != null && !line.startsWith(BEGIN)) { + line = readLine(); + } + + if (line != null) { + line = line.substring(BEGIN.length()).trim(); + int index = line.indexOf('-'); + + if (index > 0 && line.endsWith("-----") && (line.length() - index) == 5) { + objectType = line.substring(0, index); + + StringBuffer buffer = new StringBuffer(); + String endMarker = END + objectType + "-----"; + while ((line = readLine()) != null && line.indexOf(endMarker) != 0) { + if (line.indexOf(':') < 0) { + buffer.append(line.trim()); + } + } + objectContent = Base64.getDecoder().decode(buffer.toString()); + } + } + + if (objectContent != null) { + if (CERTIFICATE.equals(objectType) || X509_CERTIFICATE.equals(objectType)) { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + try (ByteArrayInputStream contentInputStream = new ByteArrayInputStream(objectContent)) { + return certificateFactory.generateCertificate(contentInputStream); + } + } else if (EC_PRIVATE_KEY.equals(objectType)) { + /* + https://datatracker.ietf.org/doc/html/rfc5915 + ECPrivateKey ::= SEQUENCE { + version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + privateKey OCTET STRING, + parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + publicKey [1] BIT STRING OPTIONAL + } + */ + try (ASN1InputStream asn1In = new ASN1InputStream(new DERDecoder(), objectContent)) { + ASN1Sequence pkcs1Sequence = asn1In.readObject(); + try (ByteArrayOutputStream pkcs8Out = new ByteArrayOutputStream()) { + try (ASN1OutputStream asn1Out = new ASN1OutputStream(new DEREncoder(), pkcs8Out)) { + List outObjects = new ArrayList<>(); + outObjects.add(new ASN1Integer(0)); + outObjects.add(new ASN1Sequence(Arrays.asList(new ASN1ObjectIdentifier(EC_PUBLIC_KEY_OBJ_ID), ((ASN1TaggedObject) pkcs1Sequence.get(2)).getObject()))); + outObjects.add(new ASN1OctetString(objectContent)); + asn1Out.writeObject(new ASN1Sequence(outObjects)); + } + + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8Out.toByteArray()); + try { + KeyFactory ecKeyFactory = KeyFactory.getInstance("EC"); + + PublicKey ecPublicKey = null; + ECPrivateKey ecPrivateKey = (ECPrivateKey) ecKeyFactory.generatePrivate(keySpec); + + if (pkcs1Sequence.size() > 3) { + byte[] ecPointBytes = ((ASN1BitString) ((ASN1TaggedObject) pkcs1Sequence.get(3)).getObject()).getValueBytes(); + if (ecPointBytes[0] == 4) { + byte[] ecPointXBytes = new byte[32]; + byte[] ecPointYBytes = new byte[32]; + System.arraycopy(ecPointBytes, 1, ecPointXBytes, 0, 32); + System.arraycopy(ecPointBytes, 33, ecPointYBytes, 0, 32); + ECPoint ecPoint = new ECPoint(new BigInteger(1, ecPointXBytes), new BigInteger(1, ecPointYBytes)); + ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(ecPoint, ecPrivateKey.getParams()); + ecPublicKey = ecKeyFactory.generatePublic(publicKeySpec); + } + } + + return new KeyPair(ecPublicKey, ecPrivateKey); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new IOException(e); + } + } + } + } else if (DSA_PRIVATE_KEY.equals(objectType)) { + /* + https://datatracker.ietf.org/doc/html/draft-woodhouse-cert-best-practice-01 + DSAPrivateKey ::= SEQUENCE { + version INTEGER, -- should be zero + p INTEGER, + q INTEGER, + g INTEGER, + pub INTEGER, -- public + priv INTEGER, -- private + } + */ + try (ASN1InputStream asn1InputStream = new ASN1InputStream(new DERDecoder(), objectContent)) { + ASN1Sequence pkcs1Sequence = asn1InputStream.readObject(); + + //BigInteger y, BigInteger p, BigInteger q, BigInteger g) + DSAPublicKeySpec publicKeySpec = new DSAPublicKeySpec(((ASN1Integer) pkcs1Sequence.get(4)).getValue(), ((ASN1Integer) pkcs1Sequence.get(1)).getValue(), ((ASN1Integer) pkcs1Sequence.get(2)).getValue(), ((ASN1Integer) pkcs1Sequence.get(3)).getValue()); + + //BigInteger x, BigInteger p, BigInteger q, BigInteger g + DSAPrivateKeySpec privateKeySpec = new DSAPrivateKeySpec(((ASN1Integer) pkcs1Sequence.get(5)).getValue(), ((ASN1Integer) pkcs1Sequence.get(1)).getValue(), ((ASN1Integer) pkcs1Sequence.get(2)).getValue(), ((ASN1Integer) pkcs1Sequence.get(3)).getValue()); + + try { + KeyFactory dsaKeyFactory = KeyFactory.getInstance("DSA"); + PublicKey dsaPublicKey = dsaKeyFactory.generatePublic(publicKeySpec); + PrivateKey dsaPrivateKey = dsaKeyFactory.generatePrivate(privateKeySpec); + return new KeyPair(dsaPublicKey, dsaPrivateKey); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new IOException(e); + } + } + } else if (RSA_PRIVATE_KEY.equals(objectType)) { + /* + https://datatracker.ietf.org/doc/html/rfc8017 + RSAPrivateKey ::= SEQUENCE { + version Version, + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER, -- (inverse of q) mod p + otherPrimeInfos OtherPrimeInfos OPTIONAL + } + */ + try (ASN1InputStream asn1InputStream = new ASN1InputStream(new DERDecoder(), objectContent)) { + ASN1Sequence pkcs1Sequence = asn1InputStream.readObject(); + + //BigInteger modulus, BigInteger publicExponent + RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(((ASN1Integer) pkcs1Sequence.get(1)).getValue(), ((ASN1Integer) pkcs1Sequence.get(2)).getValue()); + + //BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP, BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ, BigInteger crtCoefficient + RSAPrivateCrtKeySpec privateKeySpec = new RSAPrivateCrtKeySpec(((ASN1Integer) pkcs1Sequence.get(1)).getValue(), ((ASN1Integer) pkcs1Sequence.get(2)).getValue(), ((ASN1Integer) pkcs1Sequence.get(3)).getValue(), ((ASN1Integer) pkcs1Sequence.get(4)).getValue(), ((ASN1Integer) pkcs1Sequence.get(5)).getValue(), ((ASN1Integer) pkcs1Sequence.get(6)).getValue(), ((ASN1Integer) pkcs1Sequence.get(7)).getValue(), ((ASN1Integer) pkcs1Sequence.get(8)).getValue()); + + try { + KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA"); + PublicKey rsaPublicKey = rsaKeyFactory.generatePublic(publicKeySpec); + PrivateKey rsaPrivateKey = rsaKeyFactory.generatePrivate(privateKeySpec); + return new KeyPair(rsaPublicKey, rsaPrivateKey); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new IOException(e); + } + } + } else if (PRIVATE_KEY.equals(objectType)) { + PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(objectContent); + + InvalidKeySpecException firstException = null; + for (KeyFactory factory : getKeyFactories()) { + try { + return factory.generatePrivate(keySpec); + } catch (InvalidKeySpecException e) { + if (firstException == null) + firstException = e; + } + } + throw new IOException("Private key could not be loaded", firstException); + } else { + throw new IOException("Invalid object: " + objectType); + } + } + + return null; + } +} diff --git a/src/main/java/de/dentrassi/crypto/pem/PemUtils.java b/src/main/java/de/dentrassi/crypto/pem/PemUtils.java index 93406cc..a3b46fa 100644 --- a/src/main/java/de/dentrassi/crypto/pem/PemUtils.java +++ b/src/main/java/de/dentrassi/crypto/pem/PemUtils.java @@ -11,31 +11,23 @@ package de.dentrassi.crypto.pem; -import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.security.Key; +import java.security.KeyPair; +import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; -import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; -import org.bouncycastle.cert.X509CertificateHolder; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMKeyPair; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; - import de.dentrassi.crypto.pem.AbstractPemKeyStore.Entry; public class PemUtils { @@ -85,27 +77,18 @@ private static InputStream openResource(final String uri) throws IOException { private static void loadFrom(final Map result, final String alias, final boolean chained, final InputStream stream) throws CertificateException, IOException { - final CertificateFactory factory = CertificateFactory.getInstance("X.509"); - final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(new BouncyCastleProvider()); - - @SuppressWarnings("resource") - final PEMParser reader = new PEMParser(new InputStreamReader(stream, StandardCharsets.UTF_8)); - final List chain = new ArrayList<>(); Key key = null; int counter = 0; Object object; - while ((object = reader.readObject()) != null) { - - if (object instanceof X509CertificateHolder) { + try (PemReader pemReader = new PemReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) { + while ((object = pemReader.readObject()) != null) { - final X509CertificateHolder certHolder = (X509CertificateHolder) object; + if (object instanceof Certificate) { - final Collection certs = factory - .generateCertificates(new ByteArrayInputStream(certHolder.getEncoded())); + final Certificate cert = (Certificate)object; - for (final Certificate cert : certs) { if (chained) { if (cert instanceof X509Certificate) { chain.add(cert); @@ -113,16 +96,16 @@ private static void loadFrom(final Map result, final String alias } else { result.put(alias + "-" + counter++, new Entry(null, new Certificate[] { cert })); } - } - } else if (object instanceof PEMKeyPair) { + } else if (object instanceof KeyPair) { - key = converter.getKeyPair((PEMKeyPair) object).getPrivate(); + key = ((KeyPair)object).getPrivate(); - } else if (object instanceof PrivateKeyInfo) { + } else if (object instanceof PrivateKey) { - key = converter.getPrivateKey((PrivateKeyInfo) object); + key = (PrivateKey)object; + } } } @@ -140,5 +123,4 @@ private static void loadFrom(final Map result, final String alias }); } - } diff --git a/src/test/java/de/dentrassi/crypto/pem/PemReaderTest.java b/src/test/java/de/dentrassi/crypto/pem/PemReaderTest.java new file mode 100644 index 0000000..f03953b --- /dev/null +++ b/src/test/java/de/dentrassi/crypto/pem/PemReaderTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2024 Red Hat Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Domenico Francesco Bruscino - initial PemReader implementation + *******************************************************************************/ + +package de.dentrassi.crypto.pem; + +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.cert.CertPath; +import java.security.cert.CertPathValidator; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.PKIXCertPathValidatorResult; +import java.security.cert.PKIXParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; + +public class PemReaderTest { + + private static final String TEST_TEXT = "TEST"; + + @Test + public void testCertificate() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/test1.crt")))) { + Certificate certificate = (Certificate) pemReader.readObject(); + Assertions.assertTrue(certificate instanceof X509Certificate); + Assertions.assertEquals("CN=Test 1", ((X509Certificate)certificate).getSubjectX500Principal().getName()); + } + } + + @Test + public void testCertificateChain() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/tls.crt")))) { + Certificate cert1 = (Certificate) pemReader.readObject(); + Assertions.assertTrue(cert1 instanceof X509Certificate); + Assertions.assertEquals("CN=Test 1", ((X509Certificate)cert1).getSubjectX500Principal().getName()); + + Certificate cert2 = (Certificate) pemReader.readObject(); + Assertions.assertTrue(cert2 instanceof X509Certificate); + Assertions.assertEquals("CN=Intermediate", ((X509Certificate)cert2).getSubjectX500Principal().getName()); + + Certificate cert3 = (Certificate) pemReader.readObject(); + Assertions.assertTrue(cert3 instanceof X509Certificate); + Assertions.assertEquals("CN=CA", ((X509Certificate)cert3).getSubjectX500Principal().getName()); + + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + CertPath certPath = certificateFactory.generateCertPath(Arrays.asList(cert1, cert2)); + TrustAnchor anchor = new TrustAnchor((X509Certificate)cert3, null); + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + PKIXParameters params = new PKIXParameters(Collections.singleton(anchor)); + params.setRevocationEnabled(false); + PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) validator.validate(certPath, params); + Assertions.assertEquals(cert3, result.getTrustAnchor().getTrustedCert()); + } + } + + @Test + public void testECPrivateKey() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/ec-private-key.pem")))) { + KeyPair keyPair = (KeyPair) pemReader.readObject(); + testSignature("SHA512withECDSA", keyPair); + } + } + + @Test + public void testDSAPrivateKey() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/dsa-private-key.pem")))) { + KeyPair keyPair = (KeyPair) pemReader.readObject(); + testSignature("SHA512WithDSA", keyPair); + } + } + + @Test + public void testRSAPrivateKey() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/privkey1.pem")))) { + KeyPair keyPair = (KeyPair) pemReader.readObject(); + testSignature("SHA512WithRSA", keyPair); + } + } + + @Test + public void testPrivateKey() throws Exception { + try (PemReader pemReader = new PemReader(new InputStreamReader(PemReaderTest.class.getResourceAsStream("/private-key.pem")))) { + Assertions.assertTrue(pemReader.readObject() instanceof PrivateKey); + } + } + + private void testSignature(String algorithm, KeyPair keyPair) throws Exception { + Assumptions.assumeTrue(() -> { + try { + Signature.getInstance(algorithm); + } catch (Throwable t) { + return t == null; + } + return true; + }, "Cannot find any provider supporting " + algorithm); + + byte[] messageBytes = TEST_TEXT.getBytes(StandardCharsets.UTF_8); + + Signature signer = Signature.getInstance(algorithm); + signer.initSign(keyPair.getPrivate()); + signer.update(messageBytes); + byte[] signature = signer.sign(); + + Signature verifier = Signature.getInstance(algorithm); + verifier.initVerify(keyPair.getPublic()); + verifier.update(messageBytes); + Assertions.assertTrue(verifier.verify(signature)); + } +} diff --git a/src/test/resources/dsa-private-key.pem b/src/test/resources/dsa-private-key.pem new file mode 100644 index 0000000..96fc204 --- /dev/null +++ b/src/test/resources/dsa-private-key.pem @@ -0,0 +1,20 @@ +-----BEGIN DSA PRIVATE KEY----- +MIIDTgIBAAKCAQEAkhV3fPm+yC3TRzGbnCTqKvpNWcQ+ZHx9aBv9Iw8wtH+z5POC +p09AQt+SK6MHm9PrLsfeSB80guAGni55LTFFlEWscrBoE9pHtTdqz7I/mvTt7caz +9YlJrByJ1pXj1Dunaswbf9gTLsPjIZDKItaQagKQl8QV3kAXVcvp7yI4aaml9b2V +3xpvLuUIL21mVvjyidYo1UWGXAxc3AJLGkCUA+cr9F7BqCGkKKBxTGrzy8WT/ki9 +CEKeE52kND35DKml7x5B0eU0JjwVTwaIytCooEibwEnirnarOsasBFPssmD+21a6 +2wG/pdgbfydMIEXmquZetddCTTZQvki61cJaDQIdAPdQXDy4ZxLD8023NFPW/yw6 +uP5NGrhUTyc/lNUCggEAJOYkLEMD3MK7PNFoKh4fwiTpmRieSyPH33EiskEFFBxy +mD8EjcP89qiKZFxItAZV2A9JHVGHWnt95+simIMN1rS563HlXzOWUg1u2K2TTQF9 +H4MsFKTHgl1YEs1MwjsBSn/k9cipOjR99o/xTXwouqtx8TrpCEndNOyJmmg98QG1 +cEKcgELr8QdEek9DJCX0PDHEDu+BScS/Sp6CmMeFH+3GuxzJ1vbGLb83I+ELq2dr +kuid8LsKvqPVLrdVGaniLxWlb7jiqcXg1g6U1xF8lO33T9fT7zRFwagzvyEghsHW +Gx2ia6dLm4xiAT/n82kyUTkzRyH4PZAM6TwcIclP+gKCAQAE55vvsLs+jxj77QIA +Bi5Qx857q+P2aejyOsdkMYmbqTbbs6VBSWD2G0BnodXsxj907oNBmEoQJJtktmpe +9acXlAuHKhxXkan7HpUylc9oV3MYPEVnEfG/kSvHLs7Uk/Ca/ZNQ8iTBbAujpDKZ +8wuQ6Kl72ryIDPKgM5DsuRcBDhzu08tZ3how3HwGVKqwnaEDQXvImeeitwH87nqr +M4YJ3T+8wiR+u/ZBIoiJHEWpFDcE5rhduafhLv38qm0vA632mD8sJMeMd47VSK/c +UnbOpmbAexSdj6ZfoiWH4Yp+ReQwXtsiK10GYsQDq+QtGMiLUlfyJOHFWSTHNdnA +b4eIAh0A9X6697lJYHsw4cJKr7LtcBIWQsVa+VDjH+hvzQ== +-----END DSA PRIVATE KEY----- diff --git a/src/test/resources/ec-private-key.pem b/src/test/resources/ec-private-key.pem new file mode 100644 index 0000000..bf2bbd0 --- /dev/null +++ b/src/test/resources/ec-private-key.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIPeF+duprCstov+goD+vp+YEjEBpGmmhamtwAqFigMWvoAoGCCqGSM49 +AwEHoUQDQgAErq7/AhOEzWTkBzJO5zoccBNBMof0q4z/CD8QkCqzRABUPVZmy7GG ++g16Btr7WEEe1WyxzaQod6mB8Om4VauFlg== +-----END EC PRIVATE KEY----- diff --git a/src/test/resources/private-key.pem b/src/test/resources/private-key.pem new file mode 100644 index 0000000..7d875f0 --- /dev/null +++ b/src/test/resources/private-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrPo05c9I1Qla1 +SQ+C3/w3WGPtLTXMUzAs5TCGVs/CMuXJZ3Hv/G1U1UPNCpS76xx6esY57pNBubRO +KuMosU+uz5ckgJJsr/mvbGioh6CTLQnZzHCFYJPEGCACcFXSL7cQ21ze+2Z7fq7E +dOHuLJIj8OFaLsE5DZMeUAkNmrw18cTCUeVNF633B46HZMiL/WSUcI6Y835kYbd0 +XMTF3G3gWEI374v/w67P7dmJSQcTPaBFqvBX6to8b9dSW/+jl/bVVkHvnD47unp1 +Q534Si7O5RKF7SDZP7US+VKicmSoo8njhjzzznE8zzHY32KzwB991TUkHhxknvkQ +97ZLmhV3AgMBAAECggEACso6fYSJUNASIEvTpGDgD83VIFM9zESnUd8nFrkFmRoV +nstuHruQxt7FyXemETtziMePpDrVjjd9ll4oSXobzKaSwpZT7LpotpZl0vHNX4HN +j6rMofGtVLs2IkN9xNoWiN7OJmat+ZBawix8WjAbDTlEmcuGrCDE1uhoG+lWoOUi +6rbMzh2RVVJGksjv4QWVyKnmIJqhyELIFjfTV/QcucBjGUDEZZJvUy/n6PQyJe1y +60gk3KoBPlU885WkgDLLgzsiCvfUioLGPNYh58Smz1U/db9pTn6G6ymZfIyl8J49 +Ojlty+ckYCTcRIiN8VMOfJ6W8hu2nfV7AKTOYeNtcQKBgQDvr8o/KAOUpZ6MBFmR +0OQrfw2l1yqOPWdTsHQEPzzP1+rNDZrfQ7VIuhMfUfDpvU7ZSNj97h3O64Gdr0Ik +7uEgdlpyjKJbdIf9sjQA6oHbVOMJu0F6ICNtFOAGuWXbF4LYQae7PNtr7cNabWQ6 +YY/yN5L62seyKCW9jKCtIOj86wKBgQC25j+Nm/pKWC7UmyC6lf0LoqVsj4FESOp2 +VkGJeJx1MjajPYoeHArWCN2ZhMJkg9DKYOayeVELS5G4o3Qu51hSv0hI8RwaAKVp +0N8fox5EYuzD+D5+fGbsS8od0B53tHjO0OiVeF2dkzLRruEwGrildOrzBVnpnCsq +qiH+bOC2pQKBgQDcZ9FaHEiWo2nVJZbcALQgz1fUfbTTUeG3UpaM5T3dfpaa8vzM +e+2zL/Cvp2Ea/4sHQfbQIuvkQCpTvzrazZPVjyADIBGYeeMnxnwNr5e0Ai4436oJ +TI5nG4Aajtf8DXWzuUQtaHv5lo1ClT9KdDazLKmK5i4mRMbXs/541b+J+wKBgC4a +jBqeHtFuuR9Om0ltVYQBU8GxytvzpWZ/B7YneQjxx2QOtyov12tsgK+aD4ZW0+Kv +2ndSrWMzgWARk8/e8RyqqwX4ASVs1EWAKT5IV/DVHumnQdmQckFOOXyaYZO7Ili/ +wGEtHiwCVuUUOB9wHOtYNYFc7/U7MIZorHj96QchAoGBALEa1MaxarxluZa5lM7x +R5GE4btBEgwXO3V01tN2swlJQHv9mvRfV5YM3CrNRNdlkWE7Aj6UTJkw39e/TVxL ++BHqW3Ui1/7yuoLAWIznItHQhCrMN1nNt7gKxI1gB/3zP8idLM/5QC1Gq+14zu/B +zZ3Z6ERLM4huRkX4mNu8XHI4 +-----END PRIVATE KEY-----