ClickHouse / ClickHouse/clickhouse-java

ClickHouseDefaultSslContextProvider expect an invalid PKCS8-encoded PEM file

Đang mở
#1,589 2 bình luận 0 reaction 1 người được giao Được @polyglotAI-bot nhận Xem trên GitHub
bug client-api-v2 module-client usability
Ngôn ngữ chính
Java
Star
1.6k
Fork
637
Merge trung bình
2 ngày 23 giờ
Pull request đã merge (30 ngày)
29

Mô tả

### Describe the bug

clickhouse-java expects mTLS private keys to be provided as a PEM file with PKCS8 data.
See https://github.com/ClickHouse/clickhouse-java/blob/2ca52fc91a57d3e313c2ea26b9ee249fe9c6e442/clickhouse-client/src/main/java/com/clickhouse/client/config/ClickHouseDefaultSslContextProvider.java#L89

But clickhouse-java _also_ expects the key algorithm (RSA, DSA, EC, etc.) to be in the PEM header (i.e. `-----BEGIN $ALGO PRIVATE KEY-----`).
See https://github.com/ClickHouse/clickhouse-java/blob/2ca52fc91a57d3e313c2ea26b9ee249fe9c6e442/clickhouse-client/src/main/java/com/clickhouse/client/config/ClickHouseDefaultSslContextProvider.java#L76

This is an unreasonable expectation. PKCS8 encoding should never include the algorithm in the header. The only two allowable headers are `BEGIN PRIVATE KEY` and `BEGIN ENCRYPTED PRIVATE KEY`.
See https://datatracker.ietf.org/doc/html/rfc7468#section-10

**No compliant tool will produce a PEM/PKCS8 file with the format expected by this library.**
This is a problem when the PKCS8 data represents anything but an RSA key (which the library assumes as default). For example, the library is unable to read properly represented EC private keys.

With PEM/PKCS8, the algorithm is encoded in the PKCS8 data itself and can be read from the encoded data. Java/JCA does not give a good way of doing this (though there is a proposal - https://openjdk.org/jeps/8300911) but BouncyCastle does.

```
PEMParser pemParser = new PEMParser(Files.newBufferedReader(Paths.get("private.key")));
var privateKeyInfo = (PrivateKeyInfo) pemParser.readObject();
PrivateKey privateKey = new JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
String algorithm = privateKey.getAlgorithm();
```

### Steps to reproduce
1. Create a PEM/PKCS8 file for an EC private key.
2. Specify it via `ClickHouseClientBuilder.option(ClickHouseClientOption.SSL_KEY, "path/to/private.key")`
3. Execute a ClickHouseRequest from the resulting client.

### Expected behaviour

An SSL context is established and the request succeeds.

### Error log

```
java.util.concurrent.CompletionException: javax.net.ssl.SSLException: Failed to get SSL context
at com.clickhouse.client.ClickHouseClientBuilder$Agent.handle(ClickHouseClientBuilder.java:272)
at com.clickhouse.client.ClickHouseClientBuilder$Agent.lambda$execute$0(ClickHouseClientBuilder.java:348)
at java.base/java.util.concurrent.CompletableFuture.uniHandle(CompletableFuture.java:934)
at java.base/java.util.concurrent.CompletableFuture$UniHandle.tryFire(CompletableFuture.java:911)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1773)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: javax.net.ssl.SSLException: Failed to get SSL context
at com.clickhouse.client.config.ClickHouseDefaultSslContextProvider.getJavaSslContext(ClickHouseDefaultSslContextProvider.java:176)
at com.clickhouse.client.config.ClickHouseDefaultSslContextProvider.getSslContext(ClickHouseDefaultSslContextProvider.java:186)
at com.clickhouse.client.http.HttpUrlConnectionImpl.newConnection(HttpUrlConnectionImpl.java:118)
at com.clickhouse.client.http.HttpUrlConnectionImpl.(HttpUrlConnectionImpl.java:200)
at com.clickhouse.client.http.ClickHouseHttpConnectionFactory.createConnection(ClickHouseHttpConnectionFactory.java:30)
at com.clickhouse.client.http.ClickHouseHttpClient.newConnection(ClickHouseHttpClient.java:56)
at com.clickhouse.client.http.ClickHouseHttpClient.newConnection(ClickHouseHttpClient.java:26)
at com.clickhouse.client.AbstractClient.getConnection(AbstractClient.java:198)
at com.clickhouse.client.http.ClickHouseHttpClient.send(ClickHouseHttpClient.java:90)
at com.clickhouse.client.AbstractClient.sendAsync(AbstractClient.java:161)
at com.clickhouse.client.AbstractClient.lambda$execute$0(AbstractClient.java:273)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
... 3 more
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: Invalid RSA private key
at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:253)
at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:389)
at com.clickhouse.client.config.ClickHouseDefaultSslContextProvider.getPrivateKey(ClickHouseDefaultSslContextProvider.java:90)
at com.clickhouse.client.config.ClickHouseDefaultSslContextProvider.getKeyStore(ClickHouseDefaultSslContextProvider.java:114)
at com.clickhouse.client.config.ClickHouseDefaultSslContextProvider.getJavaSslContext(ClickHouseDefaultSslContextProvider.java:156)
... 14 more
Caused by: java.security.InvalidKeyException: Invalid RSA private key
at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:356)
at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.(RSAPrivateCrtKeyImpl.java:161)
at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:90)
at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:348)
at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:249)
... 18 more
Caused by: java.io.IOException: Version must be 0
at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.parseASN1(RSAPrivateCrtKeyImpl.java:321)
at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.parseKeyBits(RSAPrivateCrtKeyImpl.java:346)
... 22 more
```

### Configuration
#### Environment
* Client version: 0.6.0-patch1
* Language version: 21
* OS: Linux

#### ClickHouse server
* ClickHouse Server version: N/A
* ClickHouse Server non-default settings, if any: N/A

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.