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; | ||||||
| import com.cloud.agent.api.LogLevel.Log4jLevel; | import com.cloud.agent.api.LogLevel.Log4jLevel; | ||||||
|  | import com.cloud.utils.Pair; | ||||||
| import com.cloud.utils.component.Manager; | import com.cloud.utils.component.Manager; | ||||||
| 
 | 
 | ||||||
| public interface KeystoreManager extends 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); |     void saveCertificate(String name, String certificate, String key, String domainSuffix); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ import java.util.regex.Pattern; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.Pair; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||||
| @ -47,24 +48,28 @@ public class KeystoreManagerImpl extends ManagerBase implements KeystoreManager | |||||||
|     private KeystoreDao _ksDao; |     private KeystoreDao _ksDao; | ||||||
| 
 | 
 | ||||||
|     @Override |     @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)) { |         if (StringUtils.isAnyEmpty(certificate, key, domainSuffix)) { | ||||||
|             s_logger.error("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: " + domainSuffix); |             errMsg = String.format("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: %s", domainSuffix); | ||||||
|             return false; |             s_logger.error(errMsg); | ||||||
|  |             return new Pair<>(false, errMsg); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|             String ksPassword = "passwordForValidation"; |             String ksPassword = "passwordForValidation"; | ||||||
|             byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword); |             byte[] ksBits = CertificateHelper.buildAndSaveKeystore(domainSuffix, certificate, getKeyContent(key), ksPassword); | ||||||
|             KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword); |             KeyStore ks = CertificateHelper.loadKeystore(ksBits, ksPassword); | ||||||
|             if (ks != null) |             if (ks != null) { | ||||||
|                 return true; |                 return new Pair<>(true, errMsg); | ||||||
| 
 |             } | ||||||
|             s_logger.error("Unabled to construct keystore for domain: " + domainSuffix); |             errMsg = String.format("Unable to construct keystore for domain: %s", domainSuffix); | ||||||
|  |             s_logger.error(errMsg); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             s_logger.error("Certificate validation failed due to exception for domain: " + domainSuffix, e); |             errMsg = String.format("Certificate validation failed due to exception for domain: %s", domainSuffix); | ||||||
|  |             s_logger.error(errMsg, e); | ||||||
|         } |         } | ||||||
|         return false; |         return new Pair<>(false, errMsg); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ | |||||||
| package com.cloud.server; | package com.cloud.server; | ||||||
| 
 | 
 | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
|  | import java.security.cert.CertificateException; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Calendar; | import java.util.Calendar; | ||||||
| @ -43,6 +44,7 @@ import javax.crypto.spec.SecretKeySpec; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.naming.ConfigurationException; | import javax.naming.ConfigurationException; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.security.CertificateHelper; | ||||||
| import org.apache.cloudstack.acl.ControlledEntity; | import org.apache.cloudstack.acl.ControlledEntity; | ||||||
| import org.apache.cloudstack.acl.SecurityChecker; | import org.apache.cloudstack.acl.SecurityChecker; | ||||||
| import org.apache.cloudstack.affinity.AffinityGroupProcessor; | import org.apache.cloudstack.affinity.AffinityGroupProcessor; | ||||||
| @ -4484,13 +4486,12 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | |||||||
| 
 | 
 | ||||||
|         final String certificate = cmd.getCertificate(); |         final String certificate = cmd.getCertificate(); | ||||||
|         final String key = cmd.getPrivateKey(); |         final String key = cmd.getPrivateKey(); | ||||||
|  |         String domainSuffix = cmd.getDomainSuffix(); | ||||||
| 
 | 
 | ||||||
|         if (cmd.getPrivateKey() != null && !_ksMgr.validateCertificate(certificate, key, cmd.getDomainSuffix())) { |         validateCertificate(certificate, key, domainSuffix); | ||||||
|             throw new InvalidParameterValueException("Failed to pass certificate validation check"); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (cmd.getPrivateKey() != null) { |         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 |             // 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); |             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"; |         + "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 |     @Override | ||||||
|     public List<String> getHypervisors(final Long zoneId) { |     public List<String> getHypervisors(final Long zoneId) { | ||||||
|         final List<String> result = new ArrayList<String>(); |         final List<String> result = new ArrayList<String>(); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user