Skip to content

Commit

Permalink
Use only public APIs to read PKCS#1 keys (#5240)
Browse files Browse the repository at this point in the history
Co-authored-by: Weijun Wang <[email protected]>
  • Loading branch information
tomas-langer and wangweij authored Oct 26, 2022
1 parent c8676ac commit 0e879fe
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 113 deletions.
48 changes: 5 additions & 43 deletions common/key-util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,54 +56,16 @@
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<!-- needed to enable use of com.sun packages that we need to parse PKCS#1 keys -->
<release combine.self="override"/>
<compilerArgs>
<compilerArg>--add-exports=java.base/sun.security.util=io.helidon.common.pki</compilerArg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>javadoc</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<release combine.self="override"/>
<additionalJOptions combine.children="append">
<additionalJOption>--add-exports=java.base/sun.security.util=io.helidon.common.pki
</additionalJOption>
</additionalJOptions>
</configuration>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
61 changes: 0 additions & 61 deletions common/key-util/src/main/java/io/helidon/common/pki/DerUtils.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static PrivateKey readPrivateKey(InputStream input, char[] password) {

switch (pkInfo.type) {
case "PKCS1-RSA":
return rsaPrivateKey(pkcs1RsaKeySpec(pkInfo.bytes));
return rsaPrivateKey(Pkcs1Util.pkcs1RsaKeySpec(pkInfo.bytes));
case "PKCS1-DSA":
throw new UnsupportedOperationException("PKCS#1 DSA private key is not supported");
case "PKCS1-EC":
Expand All @@ -106,11 +106,6 @@ static PrivateKey readPrivateKey(InputStream input, char[] password) {
}
}

private static KeySpec pkcs1RsaKeySpec(byte[] bytes) {
DerUtils.checkEnabled();
return DerUtils.pkcs1RsaKeySpec(bytes);
}

private static PrivateKey pkcs8(KeySpec keySpec) {
try {
return rsaPrivateKey(keySpec);
Expand Down Expand Up @@ -222,7 +217,7 @@ private static X509EncodedKeySpec generatePublicKeySpec(byte[] bytes) {
return new X509EncodedKeySpec(bytes);
}

private static PrivateKeyInfo readPrivateKeyBytes(InputStream in) {
static PrivateKeyInfo readPrivateKeyBytes(InputStream in) {
String content;
try {
content = readContent(in);
Expand Down
69 changes: 69 additions & 0 deletions common/key-util/src/main/java/io/helidon/common/pki/Pkcs1Util.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2021, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.helidon.common.pki;

import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.HexFormat;

final class Pkcs1Util {
// this is a constant for RSA (and we only support RSA)
private static final byte[] RSA_ALG = HexFormat.of().parseHex("020100300D06092A864886F70D0101010500");

private Pkcs1Util() {
}

static KeySpec pkcs1RsaKeySpec(byte[] bytes) {
return new PKCS8EncodedKeySpec(pkcs1ToPkcs8(bytes));
}

// Code provided by Weijun Wang
private static byte[] pkcs1ToPkcs8(byte[] pkcs1Bytes) {

// PKCS #8 key will look like
// 30 len1
// 02 01 00 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00
// 04 len2
// p1

byte[] len2 = encodeLen(pkcs1Bytes.length);
int p8len = pkcs1Bytes.length + len2.length + 1 + RSA_ALG.length;
byte[] len1 = encodeLen(p8len);
byte[] pkcs8bytes = new byte[1 + len1.length + p8len];

pkcs8bytes[0] = 0x30;
System.arraycopy(len1, 0, pkcs8bytes, 1, len1.length);
System.arraycopy(RSA_ALG, 0, pkcs8bytes, 1 + len1.length, RSA_ALG.length);
pkcs8bytes[1 + len1.length + RSA_ALG.length] = 0x04;
System.arraycopy(len2, 0, pkcs8bytes, 1 + len1.length + RSA_ALG.length + 1, len2.length);
System.arraycopy(pkcs1Bytes, 0, pkcs8bytes, 1 + len1.length + RSA_ALG.length + 1 + len2.length, pkcs1Bytes.length);

return pkcs8bytes;
}

private static byte[] encodeLen(int len) {
if (len < 128) {
return new byte[] {(byte) len};
} else if (len < (1 << 8)) {
return new byte[] {(byte) 0x081, (byte) len};
} else if (len < (1 << 16)) {
return new byte[] {(byte) 0x082, (byte) (len >> 8), (byte) len};
} else {
throw new PkiException("PKCS#1 key of unexpected size: " + len);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020 Oracle and/or its affiliates.
* Copyright (c) 2017, 2022 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package io.helidon.common.pki;

import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
Expand All @@ -27,10 +28,13 @@

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

Expand All @@ -55,6 +59,15 @@ void testConfigPublicKey() {
assertThat(publicKey.publicKey().isPresent(), is(true));
}

@ParameterizedTest
@CsvSource({"512", "1024","2048"})
void testPkcs1(String length) {
PrivateKey privateKey = PemReader.readPrivateKey(KeyConfigTest.class.getResourceAsStream("/keystore/pkcs1-" + length +
".pem"), null);
assertThat(privateKey, notNullValue());
assertThat(privateKey.getAlgorithm(), is("RSA"));
}

@Test
void testOldPublicKey() {
KeyConfig publicKey = KeyConfig.create(config.get("unit-2"));
Expand Down
15 changes: 15 additions & 0 deletions common/key-util/src/test/resources/keystore/pkcs1-1024.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCvkRPTPbnOGP3r+AJieU4HKocaDAGP3AyASrCfhAC3DJB5RL7Y
3yhUqzwILbvE6wcbngZZkHka7Fzh7ZMtNdTsMI8UfsXtVtn0hNN1a/s9yt5J38xR
LJAedA2XJQNJ5Cay4YkJbntegtO07sPu8JPBoiODn1/GMWez3URp6JJW1wIDAQAB
AoGAbsL2YPS2PkIiIDatOncRNRAtf89HRP0snduBJoHe+ZzhoMAwLx5KkXAeRYKk
zY0BRPkjRGoTHVs1FgwOKB2oH/aTyuEJ3nupFgvW2eLH3MQAL8yLc2YCufogBRMT
3L1OskTk6XeaHLK2RWv1IilkY6WKERZf0/2FtipSC+adTcECQQDd3HjV/rX4yyHR
wJ/zIZ4lzko1uzT4dSndDf9dWD/fzq6w8hnsyxJDTVS5m00FqVIhjzoKMrvJUJGC
FPmPmMjRAkEAypT6aUJ1NmjDyMakIHwCN3oM70ghKQJTOuqL1e2J4TQYU9zAGaJm
5FQJb7px9C/8cw73BUBkvAOLto91Je+PJwJAXTeVTdSHgNFYlFjq26z0Vc4nQAw4
ZWxU+pw2/3Fk5RRiMdaHLgbk1YJYZuPpqMdLyu3y5PYMELnZaV6GvN7lAQJALkVS
4OHuFcxeE6jTahwJAZTeCXVnJY/DZOyXnfhQiuC0QctlETXX3IUZVqy2RHkFZ15e
q5Nmrs78hWlE77JE9wJBAJC2MaObm6grGEuWfe8NoBg8QC6sI0i6lOVpXUDvYV2e
mixgnByUBbgu5MG0OEP95OpVxQTd7OubX9qwVemTRhU=
-----END RSA PRIVATE KEY-----
27 changes: 27 additions & 0 deletions common/key-util/src/test/resources/keystore/pkcs1-2048.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEArznMqI0bdj8vXaEKoLhrG/NT8eo5aIlRPQnM3819iSjgrS+0
/3iRZg0LghTgUSm6czeFzeuKzDvOlV83n+NZUPWWZH3LlMmxJMN523IAJpT54ORC
wjyo6bSoTxHEjYTWO5yMtdJfR+uozd8aAX876R7Shq9YlBKoNKyzFSEvgPVEuA8V
sSpekeksEMw2HR4Izh2GSBCto2WOXe9lJFWMtjRBGbOiD62Z0qpJ6i+lCEr9wnwl
ToT4f3P0hfpmmjZX0X8N4h+dAm/N1WRTeQw6VSbTztNtYNaJdX6p3T2PViagd9xF
gUAf7cmyx7SnAc3GOiRNko6Yt5INekOvkMyPrwIDAQABAoIBAANgesg4x/G0cAY+
50SHqVDFlLWRzP9tvgoOGUuq2yN8jS/pPnS57xtnXvRn0Jbf1f8Ib+SzCF69PFL2
nczQBdWglgBjyDua03Yg6kVHYidcMaCa5Yp2vs6aM7AqaH5NtA88Ch4q6rkpGny1
MvwaZp4sgOQllvBrl6BEP8NFe3PhvgJDCABfQXvnDA7q2HiK9MahBcNkQaOHwXgK
L9Ssvn6UF9Z0LSvt+0SWvqckPSbncTJN1FIGGnHv+jHZVeMjSe6/aX/rjwjp1qGu
gGbB3vNLUUj71LlF1rCsPj3Na2NA4TZxXS3lNGjHiP19UHav7RDa7f9ELftIEaKP
ndElMDkCgYEA1q1kYXu0h5g0G/Cal+Kz3YKNDHsFQ9sRmfqQ6Isk6QEeEVR4hrZi
lJBAXDRRKcLIwVMAATSHRF/1liF2mYfTITg/IrDLhTNE2adHPWw+yx6PuI/uQpOd
jxiuVK024rl6DzSg7casORrwhnN6qgS7zf5men/KH33pbRABp+3LCyUCgYEA0PRc
0RyuA7z+pewfGCuIGlpm2CvmhGDgA9WN8WCFvF7Szvm5qZ35f5Hd0cMQ5HCPy8pJ
I4XwouLNmDHv461pR54LXxCu6Hx+wgKCAooCzTqW/S+rdZLvnGmY0AJ9NeaaOw2a
rz08esrAfc5jWM7HBg+OOMjzpojmqtPPOsNvgUMCgYEAxWUYKP7bh9avC4XYUJK2
+pZBZdl0hOlZrPEV742KOem6IQs/6/amfJ6LX30HqFOfzwuntHP9cSSfKBXK/O9E
doZGn3pbGTaEN3I18kenEZQfaQCHf5ZGST7Tha7kCeOsVXD6DMkisTuRML/caZsC
qS4kQr1gOEbJrWwLacMgcTUCgYA5i+L4ED74dpdnGMVjgbGlGFqUlFqTAJ8RT0Id
ROjv/Olv6SSxyvkIoiKF/4PqdfmUNWy5JM0l/vKCRNZ9TKfe+m7FSrHxA0BhrBEk
I+Arp0QoDHXbFpF48TgNqXHUY2L8en2sX2AFrUsgGrQPpDr5t1UC3I0Fw1RLnbPH
ykUuQwKBgQDVIkquG3SybEHEdruwf7qOa3yFNO3G+8A7DrsyMJWltlaoeAfp+aUY
jXPBisQEyPaXT/wWuk9WqPotw0UKEDxcmXbkbsZvcc2G+CnUpOsdhTJAX28ggUJN
d1ix5Xm4Px0Djcsoq7C7NYwvAepQfK6RfucFdE6XvJpZ/dUY1cBs8w==
-----END RSA PRIVATE KEY-----
9 changes: 9 additions & 0 deletions common/key-util/src/test/resources/keystore/pkcs1-512.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBAMqJuM6TvqUEb0UlQDSQF2aXgD4JH7hojJ01m/1f3q91lnOpMzab
+kBre1u3vtoGnl2+FqDKr/tthys8vkenyTMCAwEAAQJBAK78mkzwXTBZSoFlE7nW
HEGo90WhwGQlAAf7f1BD+jOAS4XM5bBui4m77Qr0e3GaRd7EeYnW5yAZoKy+nrmb
dwECIQD4nxUsEf4B6DWwdzctWKdx0iCxrIomR9Oe1aHI+5tKQQIhANCMhGxJGiiq
f6N0YNrUeRCZfk4cjVuiizXKQ8hYne5zAiEAlKjyzPY5LsS9jbXLHWc8QDfH6tVj
ib47EGdnJLklwsECIDXHRo61+yzpaqi35hIIIIALVOrHqhwrOkLQudH8KB3JAiEA
w4vdFCrQlE3C+RfkK/TVn+r7kZ/hIqb99rTsbI6cnZ8=
-----END RSA PRIVATE KEY-----
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@
</offlineLinks>
<additionalJOptions combine.children="append">
<additionalJOption>-J-Dhttp.agent=maven-javadoc-plugin</additionalJOption>
<additionalJOption>--add-exports=java.base/sun.security.util=io.helidon.common.pki</additionalJOption>
</additionalJOptions>
<additionalOptions>
<additionalOption>--enable-preview</additionalOption>
Expand Down

0 comments on commit 0e879fe

Please sign in to comment.