mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Add certificate validation to check headers (#9255)
This commit is contained in:
		
							parent
							
								
									674129cd58
								
							
						
					
					
						commit
						48e745cad2
					
				| @ -18,6 +18,7 @@ package org.apache.cloudstack.framework.security.keystore; | ||||
| 
 | ||||
| import com.cloud.agent.api.LogLevel; | ||||
| import com.cloud.agent.api.LogLevel.Log4jLevel; | ||||
| import com.cloud.utils.Pair; | ||||
| import com.cloud.utils.component.Manager; | ||||
| 
 | ||||
| public interface KeystoreManager extends Manager { | ||||
| @ -59,7 +60,7 @@ public interface KeystoreManager extends Manager { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     boolean validateCertificate(String certificate, String key, String domainSuffix); | ||||
|     Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix); | ||||
| 
 | ||||
|     void saveCertificate(String name, String certificate, String key, String domainSuffix); | ||||
| 
 | ||||
|  | ||||
| @ -30,6 +30,7 @@ import java.util.regex.Pattern; | ||||
| 
 | ||||
| import javax.inject.Inject; | ||||
| 
 | ||||
| import com.cloud.utils.Pair; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.log4j.Logger; | ||||
| import org.springframework.stereotype.Component; | ||||
| @ -47,24 +48,28 @@ public class KeystoreManagerImpl extends ManagerBase implements KeystoreManager | ||||
|     private KeystoreDao _ksDao; | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean validateCertificate(String certificate, String key, String domainSuffix) { | ||||
|     public Pair<Boolean, String> validateCertificate(String certificate, String key, String domainSuffix) { | ||||
|         String errMsg = null; | ||||
|         if (StringUtils.isAnyEmpty(certificate, key, domainSuffix)) { | ||||
|             s_logger.error("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: " + domainSuffix); | ||||
|             return false; | ||||
|             errMsg = String.format("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: %s", domainSuffix); | ||||
|             s_logger.error(errMsg); | ||||
|             return new Pair<>(false, errMsg); | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             String ksPassword = "passwordForValidation"; | ||||
|             byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword); | ||||
|             KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword); | ||||
|             if (ks != null) | ||||
|                 return true; | ||||
| 
 | ||||
|             s_logger.error("Unabled to construct keystore for domain: " + domainSuffix); | ||||
|         } catch (Exception e) { | ||||
|             s_logger.error("Certificate validation failed due to exception for domain: " + domainSuffix, e); | ||||
|             if (ks != null) { | ||||
|                 return new Pair<>(true, errMsg); | ||||
|             } | ||||
|         return false; | ||||
|             errMsg = String.format("Unable to construct keystore for domain: %s", domainSuffix); | ||||
|             s_logger.error(errMsg); | ||||
|         } catch (Exception e) { | ||||
|             errMsg = String.format("Certificate validation failed due to exception for domain: %s", domainSuffix); | ||||
|             s_logger.error(errMsg, e); | ||||
|         } | ||||
|         return new Pair<>(false, errMsg); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | ||||
| @ -17,6 +17,7 @@ | ||||
| package com.cloud.server; | ||||
| 
 | ||||
| import java.lang.reflect.Field; | ||||
| import java.security.cert.CertificateException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.Calendar; | ||||
| @ -43,6 +44,7 @@ import javax.crypto.spec.SecretKeySpec; | ||||
| import javax.inject.Inject; | ||||
| import javax.naming.ConfigurationException; | ||||
| 
 | ||||
| import com.cloud.utils.security.CertificateHelper; | ||||
| import org.apache.cloudstack.acl.ControlledEntity; | ||||
| import org.apache.cloudstack.acl.SecurityChecker; | ||||
| import org.apache.cloudstack.affinity.AffinityGroupProcessor; | ||||
| @ -4484,13 +4486,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
| 
 | ||||
|         final String certificate = cmd.getCertificate(); | ||||
|         final String key = cmd.getPrivateKey(); | ||||
|         String domainSuffix = cmd.getDomainSuffix(); | ||||
| 
 | ||||
|         if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) { | ||||
|             throw new InvalidParameterValueException("Failed to pass certificate validation check"); | ||||
|         } | ||||
|         validateCertificate(certificate, key, domainSuffix); | ||||
| 
 | ||||
|         if (cmd.getPrivateKey() != null) { | ||||
|             _ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, cmd.getDomainSuffix()); | ||||
|             _ksMgr.saveCertificate(ConsoleProxyManager.CERTIFICATE_NAME, certificate, key, domainSuffix); | ||||
| 
 | ||||
|             // Reboot ssvm here since private key is present - meaning server cert being passed | ||||
|             final List<SecondaryStorageVmVO> alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(null, State.Running, State.Migrating, State.Starting); | ||||
| @ -4507,6 +4508,24 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|         + "please give a few minutes for console access and storage services service to be up and working again"; | ||||
|     } | ||||
| 
 | ||||
|     private void validateCertificate(String certificate, String key, String domainSuffix) { | ||||
|         if (key != null) { | ||||
|             Pair<Boolean, String> result = _ksMgr.validateCertificate(certificate, key, domainSuffix); | ||||
|             if (!result.first()) { | ||||
|                 throw new InvalidParameterValueException(String.format("Failed to pass certificate validation check with error: %s", result.second())); | ||||
|             } | ||||
|         } else { | ||||
|             try { | ||||
|                 s_logger.debug(String.format("Trying to validate the root certificate format")); | ||||
|                 CertificateHelper.buildCertificate(certificate); | ||||
|             } catch (CertificateException e) { | ||||
|                 String errorMsg = String.format("Failed to pass certificate validation check with error: Certificate validation failed due to exception: %s", e.getMessage()); | ||||
|                 s_logger.error(errorMsg); | ||||
|                 throw new InvalidParameterValueException(errorMsg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public List<String> getHypervisors(final Long zoneId) { | ||||
|         final List<String> result = new ArrayList<String>(); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user