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

Fixed CertUtils.handleOtherKeys() behavior with Cavium #4556

Merged
merged 2 commits into from
Nov 15, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
import java.util.stream.Collectors;

public class CertUtils {
private CertUtils() { }
private CertUtils() {
}

private static final Logger LOG = LoggerFactory.getLogger(CertUtils.class);
private static final String TRUST_STORE_SYSTEM_PROPERTY = "javax.net.ssl.trustStore";
Expand All @@ -70,7 +71,8 @@ public static InputStream getInputStreamFromDataOrFile(String data, String file)
return null;
}

public static KeyStore createTrustStore(String caCertData, String caCertFile, String trustStoreFile, String trustStorePassphrase) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
public static KeyStore createTrustStore(String caCertData, String caCertFile, String trustStoreFile,
String trustStorePassphrase) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
try (InputStream pemInputStream = getInputStreamFromDataOrFile(caCertData, caCertFile)) {
return createTrustStore(pemInputStream, trustStoreFile, getTrustStorePassphrase(trustStorePassphrase));
}
Expand All @@ -84,7 +86,7 @@ private static char[] getTrustStorePassphrase(String trustStorePassphrase) {
}

private static KeyStore createTrustStore(InputStream pemInputStream, String trustStoreFile, char[] trustStorePassphrase)
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {

final String trustStoreType = System.getProperty(TRUST_STORE_TYPE_SYSTEM_PROPERTY, KeyStore.getDefaultType());
KeyStore trustStore = KeyStore.getInstance(trustStoreType);
Expand All @@ -106,37 +108,41 @@ private static KeyStore createTrustStore(InputStream pemInputStream, String trus
return trustStore;
}

public static KeyStore createKeyStore(InputStream certInputStream, InputStream keyInputStream, String clientKeyAlgo, char[] clientKeyPassphrase, String keyStoreFile, char[] keyStorePassphrase) throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException {
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
Collection<? extends Certificate> certificates = certFactory.generateCertificates(certInputStream);
PrivateKey privateKey = loadKey(keyInputStream, clientKeyAlgo);

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
if (Utils.isNotNullOrEmpty(keyStoreFile)){
try (FileInputStream fis = new FileInputStream(keyStoreFile)) {
keyStore.load(fis, keyStorePassphrase);
}
} else {
loadDefaultKeyStoreFile(keyStore, keyStorePassphrase);
public static KeyStore createKeyStore(InputStream certInputStream, InputStream keyInputStream, String clientKeyAlgo,
char[] clientKeyPassphrase, String keyStoreFile, char[] keyStorePassphrase)
throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException {
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
Collection<? extends Certificate> certificates = certFactory.generateCertificates(certInputStream);
PrivateKey privateKey = loadKey(keyInputStream, clientKeyAlgo);

KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
if (Utils.isNotNullOrEmpty(keyStoreFile)) {
try (FileInputStream fis = new FileInputStream(keyStoreFile)) {
keyStore.load(fis, keyStorePassphrase);
}
} else {
loadDefaultKeyStoreFile(keyStore, keyStorePassphrase);
}

String alias = certificates.stream().map(cert->((X509Certificate)cert).getIssuerX500Principal().getName()).collect(Collectors.joining("_"));
keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, certificates.toArray(new Certificate[0]));
String alias = certificates.stream().map(cert -> ((X509Certificate) cert).getIssuerX500Principal().getName())
.collect(Collectors.joining("_"));
keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, certificates.toArray(new Certificate[0]));

return keyStore;
return keyStore;
}

private static PrivateKey loadKey(InputStream keyInputStream, String clientKeyAlgo) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
if(clientKeyAlgo == null) {
clientKeyAlgo = "RSA"; // by default let's assume it's RSA
}
if(clientKeyAlgo.equals("EC")) {
return handleECKey(keyInputStream);
} else if(clientKeyAlgo.equals("RSA")) {
return handleOtherKeys(keyInputStream, clientKeyAlgo);
}
private static PrivateKey loadKey(InputStream keyInputStream, String clientKeyAlgo)
throws IOException, InvalidKeySpecException, NoSuchAlgorithmException {
if (clientKeyAlgo == null) {
clientKeyAlgo = "RSA"; // by default let's assume it's RSA
}
if (clientKeyAlgo.equals("EC")) {
return handleECKey(keyInputStream);
} else if (clientKeyAlgo.equals("RSA")) {
return handleOtherKeys(keyInputStream, clientKeyAlgo);
}

throw new InvalidKeySpecException("Unknown type of PKCS8 Private Key, tried RSA and ECDSA");
throw new InvalidKeySpecException("Unknown type of PKCS8 Private Key, tried RSA and ECDSA");
}

private static PrivateKey handleECKey(InputStream keyInputStream) {
Expand All @@ -150,37 +156,34 @@ public PrivateKey call() {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
}
PEMKeyPair keys = (PEMKeyPair) new PEMParser(new InputStreamReader(keyInputStream)).readObject();
return new
JcaPEMKeyConverter().
getKeyPair(keys).
getPrivate();
return new JcaPEMKeyConverter().getKeyPair(keys).getPrivate();
} catch (IOException exception) {
exception.printStackTrace();
}
return null;
}
}.call();
} catch (NoClassDefFoundError e) {
throw new KubernetesClientException("JcaPEMKeyConverter is provided by BouncyCastle, an optional dependency. To use support for EC Keys you must explicitly add this dependency to classpath.");
throw new KubernetesClientException(
"JcaPEMKeyConverter is provided by BouncyCastle, an optional dependency. To use support for EC Keys you must explicitly add this dependency to classpath.");
}
}

private static PrivateKey handleOtherKeys(InputStream keyInputStream, String clientKeyAlgo) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
private static PrivateKey handleOtherKeys(InputStream keyInputStream, String clientKeyAlgo)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
byte[] keyBytes = decodePem(keyInputStream);
KeyFactory keyFactory = KeyFactory.getInstance(clientKeyAlgo);
try {
// First let's try PKCS8
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
return KeyFactory.getInstance(clientKeyAlgo).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
} catch (InvalidKeySpecException e) {
// Otherwise try PKCS8
RSAPrivateCrtKeySpec keySpec = PKCS1Util.decodePKCS1(keyBytes);
return keyFactory.generatePrivate(keySpec);
return KeyFactory.getInstance(clientKeyAlgo).generatePrivate(keySpec);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is brittle without a test that ensures this won't be reverted in the future.
A test would be good, but at least a comment pointing to the issue should be added here.

}
}


private static void loadDefaultTrustStoreFile(KeyStore keyStore, char[] trustStorePassphrase)
throws CertificateException, NoSuchAlgorithmException, IOException {
throws CertificateException, NoSuchAlgorithmException, IOException {

File trustStoreFile = getDefaultTrustStoreFile();

Expand All @@ -190,8 +193,8 @@ private static void loadDefaultTrustStoreFile(KeyStore keyStore, char[] trustSto
}

private static File getDefaultTrustStoreFile() {
String securityDirectory =
System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator;
String securityDirectory = System.getProperty("java.home") + File.separator + "lib" + File.separator + "security"
+ File.separator;

String trustStorePath = System.getProperty(TRUST_STORE_SYSTEM_PROPERTY);
if (Utils.isNotNullOrEmpty(trustStorePath)) {
Expand All @@ -207,7 +210,7 @@ private static File getDefaultTrustStoreFile() {
}

private static void loadDefaultKeyStoreFile(KeyStore keyStore, char[] keyStorePassphrase)
throws CertificateException, NoSuchAlgorithmException, IOException {
throws CertificateException, NoSuchAlgorithmException, IOException {

String keyStorePath = System.getProperty(KEY_STORE_SYSTEM_PROPERTY);
if (Utils.isNotNullOrEmpty(keyStorePath)) {
Expand All @@ -223,7 +226,7 @@ private static void loadDefaultKeyStoreFile(KeyStore keyStore, char[] keyStorePa
private static boolean loadDefaultStoreFile(KeyStore keyStore, File fileToLoad, char[] passphrase) {

String notLoadedMessage = "There is a problem with reading default keystore/truststore file %s with the passphrase %s "
+ "- the file won't be loaded. The reason is: %s";
+ "- the file won't be loaded. The reason is: %s";

if (fileToLoad.exists() && fileToLoad.isFile() && fileToLoad.length() > 0) {
try {
Expand All @@ -240,12 +243,13 @@ private static boolean loadDefaultStoreFile(KeyStore keyStore, File fileToLoad,
}

public static KeyStore createKeyStore(String clientCertData, String clientCertFile, String clientKeyData,
String clientKeyFile, String clientKeyAlgo, String clientKeyPassphrase, String keyStoreFile,
String keyStorePassphrase)
throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException {
try (InputStream certInputStream = getInputStreamFromDataOrFile(clientCertData, clientCertFile); InputStream keyInputStream = getInputStreamFromDataOrFile(clientKeyData, clientKeyFile)) {
String clientKeyFile, String clientKeyAlgo, String clientKeyPassphrase, String keyStoreFile,
String keyStorePassphrase)
throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException {
try (InputStream certInputStream = getInputStreamFromDataOrFile(clientCertData, clientCertFile);
InputStream keyInputStream = getInputStreamFromDataOrFile(clientKeyData, clientKeyFile)) {
return createKeyStore(certInputStream, keyInputStream, clientKeyAlgo, clientKeyPassphrase.toCharArray(),
keyStoreFile, getKeyStorePassphrase(keyStorePassphrase));
keyStoreFile, getKeyStorePassphrase(keyStorePassphrase));
}
}

Expand Down