Skip to content

Commit d0b6c55

Browse files
authored
Merge pull request #1275 from zhicwu/main
Fix incorrect algorithm extracted from PEM
2 parents 3c8927d + 82ebf74 commit d0b6c55

File tree

4 files changed

+91
-32
lines changed

4 files changed

+91
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### Bug Fixes
44
* error while converting Nested values to Java maps.
5+
* incorrect algorithm extracted from PEM. [#1274](https://github.com/ClickHouse/clickhouse-java/issues/1274)
56

67
## 0.4.1, 2023-02-19
78
### Breaking Changes

clickhouse-client/src/main/java/com/clickhouse/client/config/ClickHouseDefaultSslContextProvider.java

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.security.KeyStore;
1010
import java.security.KeyStoreException;
1111
import java.security.NoSuchAlgorithmException;
12+
import java.security.PrivateKey;
1213
import java.security.SecureRandom;
1314
import java.security.UnrecoverableKeyException;
1415
import java.security.cert.Certificate;
@@ -32,8 +33,9 @@
3233
import com.clickhouse.data.ClickHouseUtils;
3334

3435
public class ClickHouseDefaultSslContextProvider implements ClickHouseSslContextProvider {
35-
static final String PEM_BEGIN_PART1 = "---BEGIN ";
36-
static final String PEM_BEGIN_PART2 = " PRIVATE KEY---";
36+
static final String PEM_HEADER_PREFIX = "---BEGIN ";
37+
static final String PEM_HEADER_SUFFIX = " PRIVATE KEY---";
38+
static final String PEM_FOOTER_PREFIX = "---END ";
3739

3840
/**
3941
* An insecure {@link javax.net.ssl.TrustManager}, that don't validate the
@@ -58,10 +60,41 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) {
5860
}
5961
}
6062

61-
protected KeyStore getKeyStore(String cert, String key)
62-
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException,
63-
KeyStoreException {
64-
KeyStore ks;
63+
static String getAlgorithm(String header, String defaultAlg) {
64+
int startIndex = header.indexOf(PEM_HEADER_PREFIX);
65+
int endIndex = startIndex < 0 ? startIndex
66+
: header.indexOf(PEM_HEADER_SUFFIX, (startIndex += PEM_HEADER_PREFIX.length()));
67+
return startIndex < endIndex ? header.substring(startIndex, endIndex) : defaultAlg;
68+
}
69+
70+
static PrivateKey getPrivateKey(String keyFile)
71+
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
72+
String algorithm = (String) ClickHouseDefaults.SSL_KEY_ALGORITHM.getEffectiveDefaultValue();
73+
StringBuilder builder = new StringBuilder();
74+
try (BufferedReader reader = new BufferedReader(
75+
new InputStreamReader(ClickHouseUtils.getFileInputStream(keyFile)))) {
76+
String line = reader.readLine();
77+
if (line != null) {
78+
algorithm = getAlgorithm(line, algorithm);
79+
80+
while ((line = reader.readLine()) != null) {
81+
if (line.indexOf(PEM_FOOTER_PREFIX) >= 0) {
82+
break;
83+
}
84+
85+
builder.append(line);
86+
}
87+
}
88+
}
89+
byte[] encoded = Base64.getDecoder().decode(builder.toString());
90+
KeyFactory kf = KeyFactory.getInstance(algorithm);
91+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
92+
return kf.generatePrivate(keySpec);
93+
}
94+
95+
protected KeyStore getKeyStore(String cert, String key) throws NoSuchAlgorithmException, InvalidKeySpecException,
96+
IOException, CertificateException, KeyStoreException {
97+
final KeyStore ks;
6598
try {
6699
ks = KeyStore.getInstance(KeyStore.getDefaultType());
67100
ks.load(null, null); // needed to initialize the key store
@@ -79,33 +112,8 @@ protected KeyStore getKeyStore(String cert, String key)
79112
ks.setCertificateEntry("cert" + (index++), c);
80113
}
81114
} else {
82-
String algorithm = (String) ClickHouseDefaults.SSL_KEY_ALGORITHM.getEffectiveDefaultValue();
83-
StringBuilder builder = new StringBuilder();
84-
try (BufferedReader reader = new BufferedReader(
85-
new InputStreamReader(ClickHouseUtils.getFileInputStream(key)))) {
86-
String str;
87-
boolean started = false;
88-
while ((str = reader.readLine()) != null) {
89-
if (!started) {
90-
int startIndex = str.indexOf(PEM_BEGIN_PART1);
91-
int endIndex = startIndex < 0 ? -1
92-
: str.indexOf(PEM_BEGIN_PART2, (startIndex += PEM_BEGIN_PART1.length() - 1));
93-
if (startIndex < endIndex) {
94-
algorithm = str.substring(startIndex, endIndex);
95-
}
96-
started = true;
97-
} else if (str.indexOf("---END ") < 0) {
98-
builder.append(str);
99-
} else {
100-
break;
101-
}
102-
}
103-
}
104-
byte[] encoded = Base64.getDecoder().decode(builder.toString());
105-
KeyFactory kf = KeyFactory.getInstance(algorithm);
106-
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
107115
Certificate[] certChain = factory.generateCertificates(in).toArray(new Certificate[0]);
108-
ks.setKeyEntry("key", kf.generatePrivate(keySpec), null, certChain);
116+
ks.setKeyEntry("key", getPrivateKey(key), null, certChain);
109117
}
110118
}
111119
return ks;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.clickhouse.client.config;
2+
3+
import org.testng.Assert;
4+
import org.testng.annotations.Test;
5+
6+
public class ClickHouseDefaultSslContextProviderTest {
7+
@Test(groups = { "unit" })
8+
public void testGetAlgorithm() {
9+
Assert.assertEquals(ClickHouseDefaultSslContextProvider.getAlgorithm("", null), null);
10+
Assert.assertEquals(ClickHouseDefaultSslContextProvider.getAlgorithm("---BEGIN ", "x"), "x");
11+
Assert.assertEquals(ClickHouseDefaultSslContextProvider.getAlgorithm("---BEGIN PRIVATE KEY---", "x"), "x");
12+
Assert.assertEquals(ClickHouseDefaultSslContextProvider.getAlgorithm("---BEGIN PRIVATE KEY---", "x"), "x");
13+
Assert.assertEquals(ClickHouseDefaultSslContextProvider.getAlgorithm("-----BEGIN RSA PRIVATE KEY-----", ""),
14+
"RSA");
15+
}
16+
17+
@Test(groups = { "unit" })
18+
public void testGetPrivateKey() throws Exception {
19+
// openssl genpkey -out pkey4test.pem -algorithm RSA -pkeyopt rsa_keygen_bits:2048
20+
Assert.assertNotNull(ClickHouseDefaultSslContextProvider.getPrivateKey("pkey4test.pem"));
21+
}
22+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDFmoBf9QrRl8Hs
3+
9i3CBxkg+nqc56S7/zK1tCNBma8/DVzMnZlSBRNxrR2xydRp76Yq3ZWcsjZs/UNv
4+
RTWQDnTrzbJgyOLixTwOWHcGBRI1YmZmg1PtCfzMW7dE3het5ayBuv8chtfkF/cZ
5+
II0uSm55C9txDBkGLCnRtxN25GFbS+1kgBQIAUBWUWRjij7xY/J8Kdl1j8SVRp3D
6+
x8kBRp1Obdt2m33j3bw9kX5D5b0GYI1e2t4E5EZcjaMgd0fuXuCYvdYciGCXBXh5
7+
hVVDIj+OUSqT3hLIsLx+4Y2g5geMvg7RPWv+lJava4EHdx1loQTxSQjqm2Oyt7Zw
8+
sxkxOfI/AgMBAAECggEBALj899tdQoCOiqy0lofDL2IxO6IyNYUN1sJGXo8mOepU
9+
LyEbFRK0z8wm3dq38NQv1ybgBBUKvWrw+jVr3EX9UrYB/lEfH1BehueDKAIJs08o
10+
zGaB4YrSQ8howDyHkjFpB0L39aYWEnxldx0d3S2N3rgRQqElSzP9GjVLJ7yw9veI
11+
iNkopo5+iJS5481EJfn4qcseD86nejmU197wLVEvqSI24vXlLp00Ycb6q1FefLb3
12+
Naa2q4meETO0EdkDocluOcqCxg3W6mDUiIINB646KK0H+rEh9SzpJgiMRSZJNJlv
13+
KK0tSrQz1zHFsJpLEBikSQ3YDoIWVQ32FBCtxOGlGBkCgYEA+Wozm8Ci0RzuBGac
14+
/BI523sTOT3OOAVsSwQjCS7DvrIQmbxO8PeHVpYSoMVSWcvFCJ5ypICtvI47pmWN
15+
gJoObHOoGNotiJkzYrbmetZ9KlRp9L+nZ+Iyp+/cjyw+Z5nIEQFF9bD8c4YZJvSj
16+
DReC/fe6CNco7dRcz1hdfmxbzusCgYEAytIbPBFjTbV+y393TS+TW0fwdrsnRuaJ
17+
rH9YDmpY3foibUgv1StynLOZLR2H4itXIbQNALbIOXn6lyCo0Q89zSWhEUvlzVTk
18+
8ZGtmrmLzCnhxTgStQCx5lYN4xGZvSvODiaZCHdicFbHOE4SbfbIoOAkmjKhIl61
19+
BZoNVl/mXP0CgYB+kvnr4h/+tYrJKvYiKnG4Q8Zmt0nvPjlN/KR3JYdrQFySWHFL
20+
cqL5OyHq+ximv3WXwSl2+GKzHQ+Ci2j7SbNmMG+vZRHUj8L3JtDip/VPRRWcgqLH
21+
YpDIjz7EXfSxiOZyUs4ZOJ91VSlwjpgsrbDpiA2eLOr1f182Tqbr4LvazwKBgBXx
22+
GQUslGOpyOfXCF8PUI/Ffpw5rwwakLZaqHoWwzpwfxz3fEVBiAqv21hoI3UyXyDE
23+
S8vR+mNNcPC8lcbYMUVqVrx6S4glMQd5TSC6Bge2WDhv0oZGZviWQrZYBxvSC164
24+
ikHCOKISoUbUG2ZOFnJhDVSpOYlwWYEbo2m+wjs5AoGBAOZVvkBTE8276EyZl6K/
25+
x589Cs2y2o6PHpWlyJtrDdK5mE8D3c6ptu40/QTwPhclGi/r7C+FWRR2y/uV3DEa
26+
OVXWxSC3+auv/ZeprB3Gy0U+B0DdZFBVgDWo4KvHc3d+kNLvYyovZi9Hz+qE6qRW
27+
g/eCnIZBYF2ujc0yjK/lGhyC
28+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)