.pvk
- * for PVK files, .pem
for PEM files).
- *
+ * encrypted or not. The type of the file is inferred by trying the supported formats
+ * in sequence until one parses successfully.
+ *
* @param file the file to load the key from
* @param password the password protecting the key
* @return the private key loaded
* @throws KeyException if the key cannot be loaded
*/
public static PrivateKey load(File file, String password) throws KeyException {
+ Exception pemParseException;
try {
- if (file.getName().endsWith(".pvk")) {
- return PVK.parse(file, password);
- } else if (file.getName().endsWith(".pem")) {
- return readPrivateKeyPEM(file, password != null ? password.toCharArray() : null);
- }
+ return readPrivateKeyPEM(file, password != null ? password.toCharArray() : null);
+ } catch (Exception e) {
+ pemParseException = e;
+ }
+
+ Exception pvkParseException;
+ try {
+ return PVK.parse(file, password);
} catch (Exception e) {
- throw new KeyException("Failed to load the private key from " + file, e);
+ pvkParseException = e;
}
-
- throw new IllegalArgumentException("Unsupported private key format (PEM or PVK file expected");
+
+ KeyException keyException = new KeyException("Failed to load the private key from " + file + " (valid PEM or PVK file expected)");
+ keyException.addSuppressed(pemParseException);
+ keyException.addSuppressed(pvkParseException);
+ throw keyException;
}
/**
diff --git a/jsign-crypto/src/test/java/net/jsign/PrivateKeyUtilsTest.java b/jsign-crypto/src/test/java/net/jsign/PrivateKeyUtilsTest.java
index cbcac906..f5af2ec7 100644
--- a/jsign-crypto/src/test/java/net/jsign/PrivateKeyUtilsTest.java
+++ b/jsign-crypto/src/test/java/net/jsign/PrivateKeyUtilsTest.java
@@ -19,6 +19,8 @@
import java.io.File;
import java.io.FileWriter;
import java.math.BigInteger;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.security.KeyException;
import java.security.PrivateKey;
import java.security.interfaces.ECPrivateKey;
@@ -54,6 +56,14 @@ public void testLoadPKCS1PEM() throws Exception {
testLoadPEM(new File("target/test-classes/keystores/privatekey.pkcs1.pem"), null);
}
+ @Test
+ public void testLoadPKCS1PEMNonPEMExtension() throws Exception {
+ File targetFile = new File("target/test-classes/keystores/privatekey.pkcs1.pem.key");
+ Files.copy(new File("target/test-classes/keystores/privatekey.pkcs1.pem").toPath(), targetFile.toPath());
+
+ testLoadPEM(targetFile, null);
+ }
+
@Test
public void testLoadEncryptedPKCS1PEM() throws Exception {
testLoadPEM(new File("target/test-classes/keystores/privatekey-encrypted.pkcs1.pem"), "password");
@@ -71,7 +81,7 @@ private void testLoadPEM(File file, String password) throws Exception {
@Test
public void testLoadWrongPEMObject() {
Exception e = assertThrows(KeyException.class, () -> PrivateKeyUtils.load(new File("target/test-classes/keystores/jsign-test-certificate.pem"), null));
- assertEquals("message", "Unsupported PEM object: X509CertificateHolder", e.getCause().getMessage());
+ assertEquals("message", "Unsupported PEM object: X509CertificateHolder", e.getSuppressed()[0].getMessage());
}
@Test
@@ -82,7 +92,7 @@ public void testLoadEmptyPEM() throws Exception {
writer.close();
Exception e = assertThrows(KeyException.class, () -> PrivateKeyUtils.load(file, null));
- assertTrue(e.getCause().getMessage().startsWith("No key found in"));
+ assertTrue(e.getSuppressed()[0].getMessage().startsWith("No key found in"));
}
@Test