weizhouapache commented on code in PR #11468: URL: https://github.com/apache/cloudstack/pull/11468#discussion_r2291186546
########## 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(); Review Comment: added method `parsePEMEncryptedKeyPair` -- 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