Skip to content

Commit ccd46a5

Browse files
committed
use newly introduced PKCS1 and PKCS8 support for pem files (#2)
Signed-off-by: Andreas Schmid <[email protected]>
1 parent ed442a5 commit ccd46a5

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

src/main/java/de/aaschmid/taskwarrior/client/KeyStoreBuilder.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.FileInputStream;
66
import java.io.IOException;
77
import java.math.BigInteger;
8+
import java.nio.charset.StandardCharsets;
89
import java.nio.file.Files;
910
import java.security.KeyFactory;
1011
import java.security.KeyStore;
@@ -25,6 +26,8 @@
2526
import java.util.Base64;
2627
import java.util.List;
2728
import java.util.concurrent.atomic.AtomicInteger;
29+
import java.util.regex.Matcher;
30+
import java.util.regex.Pattern;
2831

2932
import static java.util.Objects.requireNonNull;
3033

@@ -33,6 +36,9 @@ class KeyStoreBuilder {
3336
private static final String TYPE_CERTIFICATE = "X.509";
3437
private static final String ALGORITHM_PRIVATE_KEY = "RSA";
3538

39+
private static final Pattern PATTERN_PKCS1_PEM = Pattern.compile("-----BEGIN RSA PRIVATE KEY-----(.*)-----END RSA PRIVATE KEY-----");
40+
private static final Pattern PATTERN_PKCS8_PEM = Pattern.compile("-----BEGIN PRIVATE KEY-----(.*)-----END PRIVATE KEY-----");
41+
3642
private ProtectionParameter keyStoreProtection;
3743
private File caCertFile;
3844
private File privateKeyCertFile;
@@ -65,17 +71,6 @@ KeyStoreBuilder withPrivateKeyCertFile(File privateKeyCertFile) {
6571
return this;
6672
}
6773

68-
/**
69-
* Provide the private key file to use. It must be in {@code *.DER} format. If you have a *.PME private key, you can create it using
70-
* {@code openssl}.
71-
* <p>
72-
* The required command looks like following:<br>
73-
* <code>$ openssl pkcs8 -topk8 -nocrypt -in key.pem -inform PEM -out key.der -outform DER</code>
74-
* </p>
75-
*
76-
* @param privateKeyFile private key file in {@code *.DER} format (must not be {@code null}
77-
* @return the {@link KeyStore} builder itself
78-
*/
7974
KeyStoreBuilder withPrivateKeyFile(File privateKeyFile) {
8075
requireNonNull(privateKeyFile, "'privateKeyFile' must not be null.");
8176
if (!privateKeyFile.exists()) {
@@ -132,6 +127,21 @@ private List<Certificate> createCertificatesFor(File certFile) {
132127
private PrivateKey createPrivateKeyFor(File privateKeyFile) {
133128
try {
134129
byte[] bytes = Files.readAllBytes(privateKeyFile.toPath());
130+
if (privateKeyFile.getName().endsWith("pem")) {
131+
String content = new String(bytes, StandardCharsets.UTF_8).replaceAll("\\n", "");
132+
133+
Matcher pkcs1Matcher = PATTERN_PKCS1_PEM.matcher(content);
134+
if (pkcs1Matcher.find()) {
135+
return createPrivateKeyFromPemPkcs1(pkcs1Matcher.group(1));
136+
}
137+
138+
Matcher pkcs8Matcher = PATTERN_PKCS8_PEM.matcher(content);
139+
if (pkcs8Matcher.find()) {
140+
return createPrivateKeyFromPemPkcs8(pkcs8Matcher.group(1));
141+
}
142+
143+
throw new TaskwarriorKeyStoreException("Could not detect key algorithm for '%s'.", privateKeyFile);
144+
}
135145
return createPrivateKeyFromPkcs8Der(bytes);
136146
} catch (IOException e) {
137147
throw new TaskwarriorKeyStoreException(e, "Could not read private key of '%s' via input stream.", privateKeyFile);

src/test/java/de/aaschmid/taskwarrior/TaskwarriorClientIntegrationTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import de.aaschmid.taskwarrior.message.TaskwarriorMessage;
88
import de.aaschmid.taskwarrior.message.TaskwarriorRequestHeader;
99
import de.aaschmid.taskwarrior.test.IntegrationTest;
10-
import org.junit.jupiter.api.Test;
1110
import org.junit.jupiter.params.ParameterizedTest;
1211
import org.junit.jupiter.params.provider.Arguments;
1312
import org.junit.jupiter.params.provider.MethodSource;
@@ -24,8 +23,7 @@ class TaskwarriorClientIntegrationTest {
2423
private static final String SYNC_KEY = "f92d5c8d-4cf9-4cf5-b72f-1f4a70cf9b20";
2524

2625
static Stream<Arguments> configs() {
27-
return Stream.of("pkcs8-der")
28-
// return Stream.of("pkcs1", "pkcs8", "pkcs8-der") // TODO use to test all key type to be supported
26+
return Stream.of("pkcs1", "pkcs8", "pkcs8-der")
2927
.map(keyType -> format("/taskwarrior.%s.properties", keyType))
3028
.map(TaskwarriorClientIntegrationTest.class::getResource)
3129
.map(TaskwarriorConfiguration::taskwarriorPropertiesConfiguration)

0 commit comments

Comments
 (0)