weizhouapache commented on code in PR #11468:
URL: https://github.com/apache/cloudstack/pull/11468#discussion_r2291195205


##########
server/src/main/java/org/apache/cloudstack/network/ssl/CertServiceImpl.java:
##########
@@ -423,19 +432,47 @@ private void validateChain(final List<Certificate> chain, 
final Certificate cert
 
     }
 
-    public PrivateKey parsePrivateKey(final String key) throws IOException {
+    public PrivateKey parsePrivateKey(final String key, String password) 
throws IOException, OperatorCreationException, PKCSException, 
NoSuchAlgorithmException, InvalidKeySpecException {
         Preconditions.checkArgument(StringUtils.isNotEmpty(key));
-        try (final PemReader pemReader = new PemReader(new 
StringReader(key));) {
-            final PemObject pemObject = pemReader.readPemObject();
-            final byte[] content = pemObject.getContent();
-            final PKCS8EncodedKeySpec privKeySpec = new 
PKCS8EncodedKeySpec(content);
-            final KeyFactory factory = KeyFactory.getInstance("RSA", "BC");
-            return factory.generatePrivate(privKeySpec);
-        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
-            throw new IOException("No encryption provider available.", e);
-        } catch (final InvalidKeySpecException e) {
-            throw new IOException("Invalid Key format.", e);
+        PEMParser pemParser = new PEMParser(new StringReader(key));
+        Object privateKeyObj = pemParser.readObject();
+        if (privateKeyObj == null) {
+            throw new CloudRuntimeException("Cannot parse private key");
+        }
+        PrivateKey privateKey;
+        if (privateKeyObj instanceof PKCS8EncryptedPrivateKeyInfo) {
+            if (password == null) {
+                throw new CloudRuntimeException("Key is encrypted by PKCS#8 
but password is null");
+            }
+            PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = 
(PKCS8EncryptedPrivateKeyInfo)privateKeyObj;
+            JceOpenSSLPKCS8DecryptorProviderBuilder builder = new 
JceOpenSSLPKCS8DecryptorProviderBuilder();
+            InputDecryptorProvider decryptor = 
builder.build(password.toCharArray());
+
+            PrivateKeyInfo privateKeyInfo = 
encryptedPrivateKeyInfo.decryptPrivateKeyInfo(decryptor);
+            String algorithm = 
privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm().getId();
+            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
+            PKCS8EncodedKeySpec keySpec = new 
PKCS8EncodedKeySpec(privateKeyInfo.getEncoded());
+            return keyFactory.generatePrivate(keySpec);
+        } else if (privateKeyObj instanceof PEMEncryptedKeyPair) {
+            if (password == null) {
+                throw new CloudRuntimeException("Key is encrypted but password 
is null");
+            }
+            PEMEncryptedKeyPair encryptedKeyPair = 
(PEMEncryptedKeyPair)privateKeyObj;
+            privateKey = new JcaPEMKeyConverter().getKeyPair(
+                    encryptedKeyPair.decryptKeyPair(new 
JcePEMDecryptorProviderBuilder().build(password.toCharArray()))).getPrivate();
+        } else if (privateKeyObj instanceof PEMKeyPair) {
+            // Key pair
+            PEMKeyPair pemKeyPair = (PEMKeyPair) privateKeyObj;
+            privateKey = new 
JcaPEMKeyConverter().getKeyPair(pemKeyPair).getPrivate();
+        } else if (privateKeyObj instanceof PrivateKeyInfo) {
+            // Private key only
+            PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) privateKeyObj;
+            privateKey = new 
JcaPEMKeyConverter().getPrivateKey(privateKeyInfo);
+        } else {
+            throw new IllegalArgumentException("Unsupported PEM object: " + 
privateKeyObj.getClass());
         }

Review Comment:
   chatgpt says 
   ```
   To get the runtime type: obj.getClass() → works in Java 17 and 21.
   ```
   
   I guess it is ok ?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to