Skip to content

Commit 97cb7fe

Browse files
committed
fix bc fips issue
1 parent 0b68521 commit 97cb7fe

File tree

5 files changed

+67
-70
lines changed

5 files changed

+67
-70
lines changed

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@
310310
<groupId>org.bouncycastle</groupId>
311311
<artifactId>bcpkix-fips</artifactId>
312312
<version>1.0.3</version>
313+
<scope>provided</scope>
313314
</dependency>
314315
<!-- https://mvnrepository.com/artifact/org.apache.kafka/connect-api -->
315316
<dependency>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.snowflake.kafka.connector.internal;
2+
3+
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
4+
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
5+
import org.bouncycastle.openssl.PEMParser;
6+
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
7+
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
8+
import org.bouncycastle.operator.InputDecryptorProvider;
9+
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
10+
11+
import java.io.StringReader;
12+
import java.security.PrivateKey;
13+
import java.security.Security;
14+
15+
public class EncryptionUtils
16+
{
17+
static PrivateKey parseEncryptedPrivateKey(String key, String passphrase)
18+
{
19+
//remove header, footer, and line breaks
20+
key = key.replaceAll("-+[A-Za-z ]+-+", "");
21+
key = key.replaceAll("\\s", "");
22+
23+
StringBuilder builder = new StringBuilder();
24+
builder.append("-----BEGIN ENCRYPTED PRIVATE KEY-----");
25+
for (int i = 0; i < key.length(); i++)
26+
{
27+
if (i % 64 == 0)
28+
{
29+
builder.append("\n");
30+
}
31+
builder.append(key.charAt(i));
32+
}
33+
builder.append("\n-----END ENCRYPTED PRIVATE KEY-----");
34+
key = builder.toString();
35+
Security.addProvider(new BouncyCastleFipsProvider());
36+
try
37+
{
38+
PEMParser pemParser = new PEMParser(new StringReader(key));
39+
PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo =
40+
(PKCS8EncryptedPrivateKeyInfo) pemParser.readObject();
41+
pemParser.close();
42+
InputDecryptorProvider pkcs8Prov =
43+
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passphrase.toCharArray());
44+
JcaPEMKeyConverter converter =
45+
new JcaPEMKeyConverter().setProvider(BouncyCastleFipsProvider.PROVIDER_NAME);
46+
PrivateKeyInfo decryptedPrivateKeyInfo =
47+
encryptedPrivateKeyInfo.decryptPrivateKeyInfo(pkcs8Prov);
48+
return converter.getPrivateKey(decryptedPrivateKeyInfo);
49+
} catch (Exception e)
50+
{
51+
throw SnowflakeErrors.ERROR_0018.getException(e);
52+
}
53+
}
54+
}

src/main/java/com/snowflake/kafka/connector/internal/InternalUtils.java

Lines changed: 10 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
package com.snowflake.kafka.connector.internal;
22

33
import com.snowflake.kafka.connector.Utils;
4+
import net.snowflake.client.jdbc.internal.apache.commons.codec.binary.Base64;
5+
import net.snowflake.client.jdbc.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
46
import net.snowflake.ingest.connection.IngestStatus;
5-
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
6-
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
7-
import org.bouncycastle.openssl.PEMKeyPair;
8-
import org.bouncycastle.openssl.PEMParser;
9-
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
10-
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
11-
import org.bouncycastle.operator.InputDecryptorProvider;
12-
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
137
import org.slf4j.Logger;
148
import org.slf4j.LoggerFactory;
159

16-
import java.io.StringReader;
1710
import java.security.KeyFactory;
1811
import java.security.PrivateKey;
19-
import java.security.Security;
2012
import java.security.spec.PKCS8EncodedKeySpec;
2113
import java.sql.ResultSet;
2214
import java.sql.SQLException;
@@ -82,70 +74,19 @@ static void assertNotEmpty(String name, Object value)
8274
}
8375
}
8476

85-
static PrivateKey parseEncryptedPrivateKey(String key, String passphrase)
86-
{
87-
//remove header, footer, and line breaks
88-
key = key.replaceAll("-+[A-Za-z ]+-+", "");
89-
key = key.replaceAll("\\s", "");
90-
91-
StringBuilder builder = new StringBuilder();
92-
builder.append("-----BEGIN ENCRYPTED PRIVATE KEY-----");
93-
for (int i = 0; i < key.length(); i++)
94-
{
95-
if (i % 64 == 0)
96-
{
97-
builder.append("\n");
98-
}
99-
builder.append(key.charAt(i));
100-
}
101-
builder.append("\n-----END ENCRYPTED PRIVATE KEY-----");
102-
key = builder.toString();
103-
Security.addProvider(new BouncyCastleFipsProvider());
104-
try
105-
{
106-
PEMParser pemParser = new PEMParser(new StringReader(key));
107-
PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo =
108-
(PKCS8EncryptedPrivateKeyInfo) pemParser.readObject();
109-
pemParser.close();
110-
InputDecryptorProvider pkcs8Prov =
111-
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passphrase.toCharArray());
112-
JcaPEMKeyConverter converter =
113-
new JcaPEMKeyConverter().setProvider(BouncyCastleFipsProvider.PROVIDER_NAME);
114-
PrivateKeyInfo decryptedPrivateKeyInfo =
115-
encryptedPrivateKeyInfo.decryptPrivateKeyInfo(pkcs8Prov);
116-
return converter.getPrivateKey(decryptedPrivateKeyInfo);
117-
} catch (Exception e)
118-
{
119-
throw SnowflakeErrors.ERROR_0018.getException(e);
120-
}
121-
}
122-
12377
static PrivateKey parsePrivateKey(String key)
12478
{
12579
//remove header, footer, and line breaks
12680
key = key.replaceAll("-+[A-Za-z ]+-+", "");
12781
key = key.replaceAll("\\s", "");
12882

129-
StringBuilder builder = new StringBuilder();
130-
builder.append("-----BEGIN RSA PRIVATE KEY-----");
131-
for (int i = 0; i < key.length(); i++)
132-
{
133-
if (i % 64 == 0)
134-
{
135-
builder.append("\n");
136-
}
137-
builder.append(key.charAt(i));
138-
}
139-
builder.append("\n-----END RSA PRIVATE KEY-----");
140-
key = builder.toString();
83+
java.security.Security.addProvider(new BouncyCastleProvider());
84+
byte[] encoded = Base64.decodeBase64(key);
14185
try
14286
{
143-
PEMParser pemParser = new PEMParser(new StringReader(key));
144-
PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject();
145-
PKCS8EncodedKeySpec keySpec =
146-
new PKCS8EncodedKeySpec(pemKeyPair.getPrivateKeyInfo().getEncoded());
147-
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
148-
return keyFactory.generatePrivate(keySpec);
87+
KeyFactory kf = KeyFactory.getInstance("RSA");
88+
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
89+
return kf.generatePrivate(keySpec);
14990
} catch (Exception e)
15091
{
15192
throw SnowflakeErrors.ERROR_0002.getException(e);
@@ -217,8 +158,9 @@ static Properties createProperties(Map<String, String> conf)
217158

218159
if (!privateKeyPassphrase.isEmpty())
219160
{
220-
properties.put(JDBC_PRIVATE_KEY, parseEncryptedPrivateKey(privateKey,
221-
privateKeyPassphrase));
161+
properties.put(JDBC_PRIVATE_KEY,
162+
EncryptionUtils.parseEncryptedPrivateKey(privateKey,
163+
privateKeyPassphrase));
222164
}
223165
else if (!privateKey.isEmpty())
224166
{

src/main/java/com/snowflake/kafka/connector/internal/SnowflakeErrors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public enum SnowflakeErrors
118118
ERROR_0018(
119119
"0018",
120120
"Invalid encrypted private key or passphrase",
121-
"failed to decrypt private key. Please verify input private key and passphrase. Currently, Snowflake Kafka Connector only supports 'PBE-MD5-DES' encryption algorithm."
121+
"failed to decrypt private key. Please verify input private key and passphrase. Snowflake Kafka Connector only supports encryption algorithms in FIPS 140-2"
122122
),
123123
ERROR_0019(
124124
"0019",

src/test/java/com/snowflake/kafka/connector/internal/InternalUtilsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public void testPrivateKey()
4242
public void testEncryptedPrivateKey()
4343
{
4444
assert InternalUtils.parsePrivateKey(TestUtils.getKeyString()).equals(
45-
InternalUtils.parseEncryptedPrivateKey(TestUtils.getEncryptedPrivateKey(),
45+
EncryptionUtils.parseEncryptedPrivateKey(TestUtils.getEncryptedPrivateKey(),
4646
TestUtils.getPrivateKeyPassphrase())
4747
);
4848
}

0 commit comments

Comments
 (0)