Skip to content

Commit 4d6e190

Browse files
Add certificate validation to check headers
1 parent 8d02e5f commit 4d6e190

File tree

3 files changed

+30
-11
lines changed

3 files changed

+30
-11
lines changed

framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import com.cloud.agent.api.LogLevel;
2020
import com.cloud.agent.api.LogLevel.Log4jLevel;
21+
import com.cloud.utils.Pair;
2122
import com.cloud.utils.component.Manager;
2223

2324
public interface KeystoreManager extends Manager {
@@ -59,7 +60,7 @@ public String getRootCACert() {
5960
}
6061
}
6162

62-
boolean validateCertificate(String certificate, String key, String domainSuffix);
63+
Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix);
6364

6465
void saveCertificate(String name, String certificate, String key, String domainSuffix);
6566

framework/security/src/main/java/org/apache/cloudstack/framework/security/keystore/KeystoreManagerImpl.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import javax.inject.Inject;
3232

33+
import com.cloud.utils.Pair;
3334
import org.apache.commons.lang3.StringUtils;
3435
import org.apache.log4j.Logger;
3536
import org.springframework.stereotype.Component;
@@ -47,24 +48,38 @@ public class KeystoreManagerImpl extends ManagerBase implements KeystoreManager
4748
private KeystoreDao _ksDao;
4849

4950
@Override
50-
public boolean validateCertificate(String certificate, String key, String domainSuffix) {
51+
public Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix) {
52+
String errMsg = null;
5153
if (StringUtils.isAnyEmpty(certificate, key, domainSuffix)) {
52-
s_logger.error("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: " + domainSuffix);
53-
return false;
54+
errMsg = String.format("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: %s", domainSuffix);
55+
s_logger.error(errMsg);
56+
return new Pair<>(false, errMsg);
57+
}
58+
59+
if (!verifyCertificateHeaders(certificate)) {
60+
errMsg = "Certificate headers verification failed: Invalid PEM format.";
61+
s_logger.error(errMsg);
62+
return new Pair<>(false, errMsg);
5463
}
5564

5665
try {
5766
String ksPassword = "passwordForValidation";
5867
byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword);
5968
KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword);
6069
if (ks != null)
61-
return true;
62-
63-
s_logger.error("Unabled to construct keystore for domain: " + domainSuffix);
70+
return new Pair<>(true, errMsg);
71+
errMsg = String.format("Unable to construct keystore for domain: %s", domainSuffix);
72+
s_logger.error(errMsg);
6473
} catch (Exception e) {
65-
s_logger.error("Certificate validation failed due to exception for domain: " + domainSuffix, e);
74+
errMsg = String.format("Certificate validation failed due to exception for domain: %d", domainSuffix);
75+
s_logger.error(errMsg, e);
6676
}
67-
return false;
77+
return new Pair<>(false, errMsg);
78+
}
79+
80+
public boolean verifyCertificateHeaders(String certificate) {
81+
return certificate.startsWith("-----BEGIN CERTIFICATE-----") &&
82+
certificate.endsWith("-----END CERTIFICATE-----");
6883
}
6984

7085
@Override

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4484,8 +4484,11 @@ public String uploadCertificate(final UploadCustomCertificateCmd cmd) {
44844484
final String certificate = cmd.getCertificate();
44854485
final String key = cmd.getPrivateKey();
44864486

4487-
if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) {
4488-
throw new InvalidParameterValueException("Failed to pass certificate validation check");
4487+
if (key != null) {
4488+
Pair<Boolean, String> result = _ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix());
4489+
if (!result.first()) {
4490+
throw new InvalidParameterValueException(String.format("Failed to pass certificate validation check with error: %s", result.second()));
4491+
}
44894492
}
44904493

44914494
if (cmd.getPrivateKey() != null) {

0 commit comments

Comments
 (0)