Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use only public APIs to read PKCS#1 keys (#5240) #5258

Merged
merged 2 commits into from
Oct 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 5 additions & 43 deletions common/key-util/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
<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>
Expand All @@ -68,47 +73,4 @@
</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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021 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 Down Expand Up @@ -96,7 +96,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 @@ -107,11 +107,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 @@ -223,7 +218,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 @@ -387,7 +387,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> - -add-stylesheet ${top.parent.basedir}/etc/helidon-javadoc.css</additionalOption>-->
Expand Down