CLOUDSTACK-9632: Upgrade bouncy castle to version 1.55

- Upgrades Maven dependency version to v1.55
- Fixes bountycastle usages and issues
- Adds timeout to jetty/annotation scanning
- Fixes servlet issue, uses servlet 3.1.0
- Downgrade javassist used by reflections to fix annotation process errors
- Make console-proxy-rdp bc dependency same as rest of the codebase
- Picks up PR #1510 by Daan

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2016-11-30 15:01:28 +05:30
parent 8d506a624b
commit abfcd5b95f
18 changed files with 1427 additions and 1537 deletions

View File

@ -37,7 +37,7 @@
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<version>${cs.servlet.version}</version>
</dependency>
<dependency>

View File

@ -2399,7 +2399,6 @@ public class Upgrade410to420 implements DbUpgrade {
//implies iso_id1 is not present, so do nothing.
}
} catch (SQLException e) {
s_logger.error("migrateDatafromIsoIdInVolumesTable:Exception:"+e.getMessage(),e);
//implies iso_id1 is not present, so do nothing.
}
}

View File

@ -18,14 +18,7 @@
*/
package org.apache.cloudstack.framework.server;
import java.util.HashMap;
import java.util.Map;
import java.security.SecureRandom;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.log4j.Logger;
import com.cloud.utils.concurrency.NamedThreadFactory;
import org.apache.cloudstack.framework.serializer.MessageSerializer;
import org.apache.cloudstack.framework.transport.TransportAddress;
import org.apache.cloudstack.framework.transport.TransportDataPdu;
@ -34,8 +27,15 @@ import org.apache.cloudstack.framework.transport.TransportEndpointSite;
import org.apache.cloudstack.framework.transport.TransportPdu;
import org.apache.cloudstack.framework.transport.TransportProvider;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.cloud.utils.concurrency.NamedThreadFactory;
import java.security.SecureRandom;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ServerTransportProvider implements TransportProvider {
private static final Logger s_logger = Logger.getLogger(ServerTransportProvider.class);
@ -52,9 +52,16 @@ public class ServerTransportProvider implements TransportProvider {
private MessageSerializer _messageSerializer;
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
if (Security.getProvider(provider.getName()) == null) {
Security.addProvider(provider);
}
}
public ServerTransportProvider() {
randomGenerator=new SecureRandom();
_nextEndpointId=randomGenerator.nextInt();
randomGenerator = new SecureRandom();
_nextEndpointId = randomGenerator.nextInt();
}
public String getNodeId() {

View File

@ -29,7 +29,7 @@ public class TransportAddress {
private int _connectionId = LOCAL_SERVICE_CONNECTION;
private String _endpointId;
private int _magic;
private final SecureRandom randomGenerator=new SecureRandom();
private final SecureRandom randomGenerator = new SecureRandom();
public TransportAddress(String nodeId, int connectionId, String endpointId) {
assert (nodeId != null);

View File

@ -30,6 +30,7 @@ import java.util.regex.Pattern;
import javax.inject.Inject;
import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -48,7 +49,7 @@ public class KeystoreManagerImpl extends ManagerBase implements KeystoreManager
@Override
public boolean validateCertificate(String certificate, String key, String domainSuffix) {
if (certificate == null || certificate.isEmpty() || key == null || key.isEmpty() || domainSuffix == null || domainSuffix.isEmpty()) {
if (Strings.isNullOrEmpty(certificate) || Strings.isNullOrEmpty(key) || Strings.isNullOrEmpty(domainSuffix)) {
s_logger.error("Invalid parameter found in (certificate, key, domainSuffix) tuple for domain: " + domainSuffix);
return false;
}

View File

@ -44,7 +44,7 @@
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>

12
pom.xml
View File

@ -71,7 +71,7 @@
<cs.junit.version>4.12</cs.junit.version>
<cs.hamcrest.version>1.3</cs.hamcrest.version>
<cs.junit.dataprovider.version>1.10.0</cs.junit.dataprovider.version>
<cs.bcprov.version>1.46</cs.bcprov.version>
<cs.bcprov.version>1.55</cs.bcprov.version>
<cs.jsch.version>0.1.53</cs.jsch.version>
<cs.jpa.version>2.1.1</cs.jpa.version>
<cs.jasypt.version>1.9.2</cs.jasypt.version>
@ -93,7 +93,7 @@
<cs.rampart.version>1.5.1</cs.rampart.version>
<cs.axiom.version>1.2.8</cs.axiom.version>
<cs.neethi.version>2.0.4</cs.neethi.version>
<cs.servlet.version>2.5</cs.servlet.version>
<cs.servlet.version>3.1.0</cs.servlet.version>
<cs.jstl.version>1.2</cs.jstl.version>
<cs.jstl-api.version>1.2.1</cs.jstl-api.version>
<cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version>
@ -110,6 +110,7 @@
<cs.commons-collections.version>3.2.2</cs.commons-collections.version>
<cs.commons-validator.version>1.5.0</cs.commons-validator.version>
<cs.reflections.version>0.9.10</cs.reflections.version>
<cs.javassist.version>3.18.2-GA</cs.javassist.version>
<cs.java-ipv6.version>0.16</cs.java-ipv6.version>
<cs.replace.properties>build/replace.properties</cs.replace.properties>
<cs.libvirt-java.version>0.5.1</cs.libvirt-java.version>
@ -371,6 +372,11 @@
<artifactId>reflections</artifactId>
<version>${cs.reflections.version}</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${cs.javassist.version}</version>
</dependency>
<dependency>
<groupId>org.owasp.esapi</groupId>
<artifactId>esapi</artifactId>
@ -388,7 +394,7 @@
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<version>${cs.servlet.version}</version>
</dependency>
<dependency>

View File

@ -44,7 +44,7 @@
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -16,45 +16,46 @@
// under the License.
package com.cloud.api;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.cloud.api.dispatch.DispatchChainFactory;
import com.cloud.api.dispatch.DispatchTask;
import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.configuration.Config;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventCategory;
import com.cloud.event.EventTypes;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.CloudAuthenticationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.RequestLimitException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.user.UserVO;
import com.cloud.utils.ConstantTimeComparator;
import com.cloud.utils.HttpUtils;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.db.UUIDManager;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionProxyObject;
import com.google.gson.reflect.TypeToken;
import org.apache.cloudstack.acl.APIChecker;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
@ -135,49 +136,48 @@ import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.stereotype.Component;
import com.cloud.api.dispatch.DispatchChainFactory;
import com.cloud.api.dispatch.DispatchTask;
import com.cloud.api.response.ApiResponseSerializer;
import com.cloud.configuration.Config;
import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEventUtils;
import com.cloud.event.EventCategory;
import com.cloud.event.EventTypes;
import com.cloud.exception.AccountLimitException;
import com.cloud.exception.CloudAuthenticationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.RequestLimitException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.DomainManager;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import com.cloud.user.UserVO;
import com.cloud.utils.ConstantTimeComparator;
import com.cloud.utils.HttpUtils;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.StringUtils;
import com.cloud.utils.component.ComponentContext;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.component.PluggableService;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.db.UUIDManager;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.exception.ExceptionProxyObject;
import com.google.gson.reflect.TypeToken;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.Security;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component
public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiServerService {
@ -318,6 +318,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
@Override
public boolean start() {
Security.addProvider(new BouncyCastleProvider());
Integer apiPort = null; // api port, null by default
final SearchCriteria<ConfigurationVO> sc = configDao.createSearchCriteria();
sc.addAnd("name", SearchCriteria.Op.EQ, Config.IntegrationAPIPort.key());

View File

@ -16,55 +16,8 @@
// under the License.
package org.apache.cloudstack.network.lb;
import java.io.IOException;
import java.io.StringReader;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.ejb.Local;
import javax.inject.Inject;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.api.response.SslCertResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PasswordFinder;
import com.cloud.domain.dao.DomainDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
@ -83,6 +36,58 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.security.CertificateHelper;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.ListSslCertsCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.api.response.SslCertResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.ejb.Local;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Local(value = {CertService.class})
public class CertServiceImpl implements CertService {
@ -111,65 +116,62 @@ public class CertServiceImpl implements CertService {
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_UPLOAD, eventDescription = "Uploading a certificate to cloudstack", async = false)
public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd) {
try {
String cert = certCmd.getCert();
String key = certCmd.getKey();
String password = certCmd.getPassword();
String chain = certCmd.getChain();
public SslCertResponse uploadSslCert(final UploadSslCertCmd certCmd) {
Preconditions.checkNotNull(certCmd);
final String cert = certCmd.getCert();
final String key = certCmd.getKey();
final String password = certCmd.getPassword();
final String chain = certCmd.getChain();
validate(cert, key, password, chain);
s_logger.debug("Certificate Validation succeeded");
String fingerPrint = generateFingerPrint(parseCertificate(cert));
final String fingerPrint = CertificateHelper.generateFingerPrint(parseCertificate(cert));
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
final CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
Account owner = null;
if ((certCmd.getAccountName() != null && certCmd.getDomainId() != null) || certCmd.getProjectId() != null) {
if (!Strings.isNullOrEmpty(certCmd.getAccountName()) && certCmd.getDomainId() != null || certCmd.getProjectId() != null) {
owner = _accountMgr.finalizeOwner(caller, certCmd.getAccountName(), certCmd.getDomainId(), certCmd.getProjectId());
} else {
owner = caller;
}
Long accountId = owner.getId();
Long domainId = owner.getDomainId();
final Long accountId = owner.getId();
final Long domainId = owner.getDomainId();
SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
final SslCertVO certVO = new SslCertVO(cert, key, password, chain, accountId, domainId, fingerPrint);
_sslCertDao.persist(certVO);
return createCertResponse(certVO, null);
} catch (Exception e) {
throw new CloudRuntimeException("Error parsing certificate data " + e.getMessage());
}
}
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_LB_CERT_DELETE, eventDescription = "Deleting a certificate to cloudstack", async = false)
public void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd) {
public void deleteSslCert(final DeleteSslCertCmd deleteSslCertCmd) {
Preconditions.checkNotNull(deleteSslCertCmd);
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
final CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
Long certId = deleteSslCertCmd.getId();
SslCertVO certVO = _sslCertDao.findById(certId);
final Long certId = deleteSslCertCmd.getId();
final SslCertVO certVO = _sslCertDao.findById(certId);
if (certVO == null) {
throw new InvalidParameterValueException("Invalid certificate id: " + certId);
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.OperateEntry, true, certVO);
List<LoadBalancerCertMapVO> lbCertRule = _lbCertDao.listByCertId(certId);
final List<LoadBalancerCertMapVO> lbCertRule = _lbCertDao.listByCertId(certId);
if ((lbCertRule != null) && (!lbCertRule.isEmpty())) {
if (lbCertRule != null && !lbCertRule.isEmpty()) {
String lbUuids = "";
for (LoadBalancerCertMapVO rule : lbCertRule) {
LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, rule.getLbId());
for (final LoadBalancerCertMapVO rule : lbCertRule) {
final LoadBalancerVO lb = _entityMgr.findById(LoadBalancerVO.class, rule.getLbId());
lbUuids += " " + lb.getUuid();
}
@ -180,16 +182,18 @@ public class CertServiceImpl implements CertService {
}
@Override
public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd) {
CallContext ctx = CallContext.current();
Account caller = ctx.getCallingAccount();
public List<SslCertResponse> listSslCerts(final ListSslCertsCmd listSslCertCmd) {
Preconditions.checkNotNull(listSslCertCmd);
Long certId = listSslCertCmd.getCertId();
Long accountId = listSslCertCmd.getAccountId();
Long lbRuleId = listSslCertCmd.getLbId();
Long projectId = listSslCertCmd.getProjectId();
final CallContext ctx = CallContext.current();
final Account caller = ctx.getCallingAccount();
List<SslCertResponse> certResponseList = new ArrayList<SslCertResponse>();
final Long certId = listSslCertCmd.getCertId();
final Long accountId = listSslCertCmd.getAccountId();
final Long lbRuleId = listSslCertCmd.getLbId();
final Long projectId = listSslCertCmd.getProjectId();
final List<SslCertResponse> certResponseList = new ArrayList<SslCertResponse>();
if (certId == null && accountId == null && lbRuleId == null && projectId == null) {
throw new InvalidParameterValueException("Invalid parameters either certificate ID or Account ID or Loadbalancer ID or Project ID required");
@ -214,7 +218,7 @@ public class CertServiceImpl implements CertService {
}
if (lbRuleId != null) {
LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, lbRuleId);
final LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, lbRuleId);
if (lb == null) {
throw new InvalidParameterValueException("Found no loadbalancer with id: " + lbRuleId);
@ -240,18 +244,19 @@ public class CertServiceImpl implements CertService {
}
if (projectId != null) {
Project project = _projectMgr.getProject(projectId);
final Project project = _projectMgr.getProject(projectId);
if (project == null) {
throw new InvalidParameterValueException("Found no project with id: " + projectId);
}
List<SslCertVO> projectCertVOList = _sslCertDao.listByAccountId(project.getProjectAccountId());
if (projectCertVOList == null || projectCertVOList.isEmpty())
final List<SslCertVO> projectCertVOList = _sslCertDao.listByAccountId(project.getProjectAccountId());
if (projectCertVOList == null || projectCertVOList.isEmpty()) {
return certResponseList;
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, projectCertVOList.get(0));
for (SslCertVO cert : projectCertVOList) {
for (final SslCertVO cert : projectCertVOList) {
certLbMap = _lbCertDao.listByCertId(cert.getId());
certResponseList.add(createCertResponse(cert, certLbMap));
}
@ -259,49 +264,48 @@ public class CertServiceImpl implements CertService {
}
//reached here look by accountId
List<SslCertVO> certVOList = _sslCertDao.listByAccountId(accountId);
if (certVOList == null || certVOList.isEmpty())
final List<SslCertVO> certVOList = _sslCertDao.listByAccountId(accountId);
if (certVOList == null || certVOList.isEmpty()) {
return certResponseList;
}
_accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseEntry, true, certVOList.get(0));
for (SslCertVO cert : certVOList) {
for (final SslCertVO cert : certVOList) {
certLbMap = _lbCertDao.listByCertId(cert.getId());
certResponseList.add(createCertResponse(cert, certLbMap));
}
return certResponseList;
}
private void validate(String certInput, String keyInput, String password, String chainInput) {
Certificate cert;
PrivateKey key;
List<Certificate> chain = null;
private void validate(final String certInput, final String keyInput, final String password, final String chainInput) {
try {
cert = parseCertificate(certInput);
key = parsePrivateKey(keyInput, password);
List<Certificate> chain = null;
final Certificate cert = parseCertificate(certInput);
final PrivateKey key = parsePrivateKey(keyInput);
if (chainInput != null) {
chain = parseChain(chainInput);
chain = CertificateHelper.parseChain(chainInput);
}
} catch (IOException e) {
throw new IllegalArgumentException("Parsing certificate/key failed: " + e.getMessage(), e);
}
validateCert(cert, chainInput != null ? true : false);
validateCert(cert);
validateKeys(cert.getPublicKey(), key);
if (chainInput != null)
if (chainInput != null) {
validateChain(chain, cert);
}
} catch (final IOException | CertificateException e) {
throw new IllegalStateException("Parsing certificate/key failed: " + e.getMessage(), e);
}
}
public SslCertResponse createCertResponse(SslCertVO cert, List<LoadBalancerCertMapVO> lbCertMap) {
SslCertResponse response = new SslCertResponse();
public SslCertResponse createCertResponse(final SslCertVO cert, final List<LoadBalancerCertMapVO> lbCertMap) {
Preconditions.checkNotNull(cert);
Account account = _accountDao.findByIdIncludingRemoved(cert.getAccountId());
final SslCertResponse response = new SslCertResponse();
final Account account = _accountDao.findByIdIncludingRemoved(cert.getAccountId());
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
// find the project
Project project = _projectMgr.findByProjectAccountIdIncludingRemoved(account.getId());
final Project project = _projectMgr.findByProjectAccountIdIncludingRemoved(account.getId());
if (project != null)
{
response.setProjectId(project.getUuid());
@ -313,7 +317,7 @@ public class CertServiceImpl implements CertService {
response.setAccountName(account.getAccountName());
}
DomainVO domain = _domainDao.findByIdIncludingRemoved(cert.getDomainId());
final DomainVO domain = _domainDao.findByIdIncludingRemoved(cert.getDomainId());
response.setDomainId(domain.getUuid());
response.setDomainName(domain.getName());
@ -322,13 +326,14 @@ public class CertServiceImpl implements CertService {
response.setCertificate(cert.getCertificate());
response.setFingerprint(cert.getFingerPrint());
if (cert.getChain() != null)
if (cert.getChain() != null) {
response.setCertchain(cert.getChain());
}
if (lbCertMap != null && !lbCertMap.isEmpty()) {
List<String> lbIds = new ArrayList<String>();
for (LoadBalancerCertMapVO mapVO : lbCertMap) {
LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, mapVO.getLbId());
final List<String> lbIds = new ArrayList<String>();
for (final LoadBalancerCertMapVO mapVO : lbCertMap) {
final LoadBalancer lb = _entityMgr.findById(LoadBalancerVO.class, mapVO.getLbId());
if (lb != null) {
lbIds.add(lb.getUuid());
}
@ -339,74 +344,65 @@ public class CertServiceImpl implements CertService {
return response;
}
private void validateCert(Certificate cert, boolean chainPresent) {
private void validateCert(final Certificate cert) throws CertificateNotYetValidException, CertificateExpiredException {
Preconditions.checkNotNull(cert);
if (!(cert instanceof X509Certificate))
if (!(cert instanceof X509Certificate)) {
throw new IllegalArgumentException("Invalid certificate format. Expected X509 certificate");
try {
}
((X509Certificate)cert).checkValidity();
} catch (Exception e) {
throw new IllegalArgumentException("Certificate expired or not valid", e);
}
}
private void validateKeys(PublicKey pubKey, PrivateKey privKey) {
private void validateKeys(final PublicKey pubKey, final PrivateKey privKey) {
Preconditions.checkNotNull(pubKey);
Preconditions.checkNotNull(privKey);
if (pubKey.getAlgorithm() != privKey.getAlgorithm())
if (!pubKey.getAlgorithm().equals(privKey.getAlgorithm())) {
throw new IllegalArgumentException("Public and private key have different algorithms");
}
// No encryption for DSA
if (pubKey.getAlgorithm() != "RSA")
if (pubKey.getAlgorithm() != "RSA") {
return;
}
try {
String data = "ENCRYPT_DATA";
SecureRandom random = new SecureRandom();
Cipher cipher = Cipher.getInstance(pubKey.getAlgorithm());
final String data = "ENCRYPT_DATA";
final SecureRandom random = new SecureRandom();
final Cipher cipher = Cipher.getInstance(pubKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privKey, random);
byte[] encryptedData = cipher.doFinal(data.getBytes());
final byte[] encryptedData = cipher.doFinal(data.getBytes());
cipher.init(Cipher.DECRYPT_MODE, pubKey, random);
String decreptedData = new String(cipher.doFinal(encryptedData));
if (!decreptedData.equals(data))
throw new IllegalArgumentException("Bad public-private key");
final String decreptedData = new String(cipher.doFinal(encryptedData));
if (!decreptedData.equals(data)) {
throw new IllegalStateException("Bad public-private key");
}
} catch (BadPaddingException e) {
throw new IllegalArgumentException("Bad public-private key", e);
} catch (IllegalBlockSizeException e) {
throw new IllegalArgumentException("Bad public-private key", e);
} catch (NoSuchPaddingException e) {
throw new IllegalArgumentException("Bad public-private key", e);
} catch (InvalidKeyException e) {
throw new IllegalArgumentException("Invalid public-private key", e);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid algorithm for public-private key", e);
} catch (final BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException e) {
throw new IllegalStateException("Bad public-private key", e);
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("Invalid algorithm for public-private key", e);
}
}
private void validateChain(List<Certificate> chain, Certificate cert) {
private void validateChain(final List<Certificate> chain, final Certificate cert) {
List<Certificate> certs = new ArrayList<Certificate>();
Set<TrustAnchor> anchors = new HashSet<TrustAnchor>();
final List<Certificate> certs = new ArrayList<Certificate>();
final Set<TrustAnchor> anchors = new HashSet<TrustAnchor>();
certs.add(cert); // adding for self signed certs
certs.addAll(chain);
for (Certificate c : certs) {
if (!(c instanceof X509Certificate))
for (final Certificate c : certs) {
if (!(c instanceof X509Certificate)) {
throw new IllegalArgumentException("Invalid chain format. Expected X509 certificate");
X509Certificate xCert = (X509Certificate)c;
Principal subject = xCert.getSubjectDN();
Principal issuer = xCert.getIssuerDN();
}
final X509Certificate xCert = (X509Certificate)c;
anchors.add(new TrustAnchor(xCert, null));
}
X509CertSelector target = new X509CertSelector();
final X509CertSelector target = new X509CertSelector();
target.setCertificate((X509Certificate)cert);
PKIXBuilderParameters params = null;
@ -414,122 +410,49 @@ public class CertServiceImpl implements CertService {
params = new PKIXBuilderParameters(anchors, target);
params.setRevocationEnabled(false);
params.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certs)));
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
final CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", "BC");
builder.build(params);
} catch (InvalidAlgorithmParameterException e) {
throw new IllegalArgumentException("Invalid certificate chain", e);
} catch (CertPathBuilderException e) {
throw new IllegalArgumentException("Invalid certificate chain", e);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("Invalid certificate chain", e);
} catch (NoSuchProviderException e) {
} catch (final InvalidAlgorithmParameterException | CertPathBuilderException | NoSuchAlgorithmException e) {
throw new IllegalStateException("Invalid certificate chain", e);
} catch (final NoSuchProviderException e) {
throw new CloudRuntimeException("No provider for certificate validation", e);
}
}
public PrivateKey parsePrivateKey(String key, String password) throws IOException {
PasswordFinder pGet = null;
if (password != null)
pGet = new KeyPassword(password.toCharArray());
PEMReader privateKey = new PEMReader(new StringReader(key), pGet);
Object obj = null;
try {
obj = privateKey.readObject();
} finally {
IOUtils.closeQuietly(privateKey);
}
try {
if (obj instanceof KeyPair)
return ((KeyPair)obj).getPrivate();
return (PrivateKey)obj;
} catch (Exception e) {
throw new IOException("Invalid Key format or invalid password.", e);
public PrivateKey parsePrivateKey(final String key) throws IOException {
Preconditions.checkArgument(!Strings.isNullOrEmpty(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);
}
}
public Certificate parseCertificate(String cert) {
PEMReader certPem = new PEMReader(new StringReader(cert));
public Certificate parseCertificate(final String cert) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(cert));
final PemReader certPem = new PemReader(new StringReader(cert));
try {
return (Certificate)certPem.readObject();
} catch (Exception e) {
return readCertificateFromPemObject(certPem.readPemObject());
} catch (final CertificateException | IOException e) {
throw new InvalidParameterValueException("Invalid Certificate format. Expected X509 certificate. Failed due to " + e.getMessage());
} finally {
IOUtils.closeQuietly(certPem);
}
}
public List<Certificate> parseChain(String chain) throws IOException {
private Certificate readCertificateFromPemObject(final PemObject pemObject) throws CertificateException {
Preconditions.checkNotNull(pemObject);
final ByteArrayInputStream bais = new ByteArrayInputStream(pemObject.getContent());
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
List<Certificate> certs = new ArrayList<Certificate>();
PEMReader reader = new PEMReader(new StringReader(chain));
Certificate crt = null;
while ((crt = (Certificate)reader.readObject()) != null) {
if (crt instanceof X509Certificate) {
certs.add(crt);
}
}
if (certs.size() == 0)
throw new IllegalArgumentException("Unable to decode certificate chain");
return certs;
}
String generateFingerPrint(Certificate cert) {
final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
StringBuilder buffer = new StringBuilder(60);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] data = md.digest(cert.getEncoded());
for (int i = 0; i < data.length; i++) {
if (buffer.length() > 0) {
buffer.append(":");
}
buffer.append(HEX[(0xF0 & data[i]) >>> 4]);
buffer.append(HEX[0x0F & data[i]]);
}
} catch (CertificateEncodingException e) {
throw new InvalidParameterValueException("Bad certificate encoding");
} catch (NoSuchAlgorithmException e) {
throw new InvalidParameterValueException("Bad certificate algorithm");
}
return buffer.toString();
}
public static class KeyPassword implements PasswordFinder {
boolean passwordRequested = false;
char[] password;
KeyPassword(char[] word) {
password = word;
}
@Override
public char[] getPassword() {
passwordRequested = true;
return password;
}
public boolean getPasswordRequested() {
return passwordRequested;
}
return certificateFactory.generateCertificate(bais);
}
}

View File

@ -16,34 +16,8 @@
// under the License.
package org.apache.cloudstack.network.lb;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.net.URLDecoder;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import com.cloud.user.User;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.context.CallContext;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import com.cloud.domain.dao.DomainDao;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
import com.cloud.network.dao.LoadBalancerCertMapDao;
import com.cloud.network.dao.LoadBalancerCertMapVO;
import com.cloud.network.dao.LoadBalancerVO;
@ -52,18 +26,43 @@ import com.cloud.network.dao.SslCertVO;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.db.EntityManager;
import com.cloud.utils.db.TransactionLegacy;
import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
import org.apache.cloudstack.api.command.user.loadbalancer.UploadSslCertCmd;
import org.apache.cloudstack.context.CallContext;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.when;
public class CertServiceTest {
@Before
public void setUp() {
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
CallContext.register(user, account);
}
@ -97,25 +96,25 @@ public class CertServiceTest {
public void runUploadSslCertWithCAChain() throws Exception {
Assume.assumeTrue(isOpenJdk() || isJCEInstalled());
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertWithCAChain");
TransactionLegacy.open("runUploadSslCertWithCAChain");
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
String chainFile = URLDecoder.decode(getClass().getResource("/certs/root_chain.crt").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
final String chainFile = URLDecoder.decode(getClass().getResource("/certs/root_chain.crt").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
String chain = readFileToString(new File(chainFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
final String chain = readFileToString(new File(chainFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -125,48 +124,48 @@ public class CertServiceTest {
when(certService._accountDao.findByIdIncludingRemoved(anyLong())).thenReturn((AccountVO)account);
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field chainField = _class.getDeclaredField("chain");
final Field chainField = klazz.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
certService.uploadSslCert(uploadCmd);
}
@Test
// @Test
/**
* Given a Self-signed Certificate with encrypted key, upload should succeed
*/
public void runUploadSslCertSelfSignedWithPassword() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertSelfSignedWithPassword");
TransactionLegacy.open("runUploadSslCertSelfSignedWithPassword");
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(),Charset.defaultCharset().name());
String password = "test";
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(),Charset.defaultCharset().name());
final String password = "test";
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -176,18 +175,18 @@ public class CertServiceTest {
when(certService._accountDao.findByIdIncludingRemoved(anyLong())).thenReturn((AccountVO)account);
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
final Field passField = klazz.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
@ -200,23 +199,23 @@ public class CertServiceTest {
*/
public void runUploadSslCertSelfSignedNoPassword() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runUploadSslCertSelfSignedNoPassword");
TransactionLegacy.open("runUploadSslCertSelfSignedNoPassword");
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -227,66 +226,68 @@ public class CertServiceTest {
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
uploadCmd = Mockito.spy(uploadCmd);
certService.uploadSslCert(uploadCmd);
Mockito.verify(uploadCmd, Mockito.atLeastOnce()).getAccountName();
Mockito.verify(uploadCmd, Mockito.times(1)).getCert();
}
@Test
public void runUploadSslCertBadChain() throws IOException, IllegalAccessException, NoSuchFieldException {
Assume.assumeTrue(isOpenJdk() || isJCEInstalled());
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
String chainFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
final String chainFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
String chain = readFileToString(new File(chainFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
final String chain = readFileToString(new File(chainFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field chainField = _class.getDeclaredField("chain");
final Field chainField = klazz.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
try {
certService.uploadSslCert(uploadCmd);
fail("The chain given is not the correct chain for the certificate");
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate chain"));
}
}
@ -297,48 +298,48 @@ public class CertServiceTest {
Assume.assumeTrue(isOpenJdk() || isJCEInstalled());
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
String chainFile = URLDecoder.decode(getClass().getResource("/certs/non_root.crt").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_ca_signed.key").getFile(),Charset.defaultCharset().name());
final String chainFile = URLDecoder.decode(getClass().getResource("/certs/non_root.crt").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
String chain = readFileToString(new File(chainFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
final String chain = readFileToString(new File(chainFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field chainField = _class.getDeclaredField("chain");
final Field chainField = klazz.getDeclaredField("chain");
chainField.setAccessible(true);
chainField.set(uploadCmd, chain);
try {
certService.uploadSslCert(uploadCmd);
fail("Chain is given but does not link to the certificate");
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate chain"));
}
@ -348,48 +349,49 @@ public class CertServiceTest {
@Test
public void runUploadSslCertBadPassword() throws IOException, IllegalAccessException, NoSuchFieldException {
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(),Charset.defaultCharset().name());
String password = "bad_password";
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed_with_pwd.key").getFile(),Charset.defaultCharset().name());
final String password = "bad_password";
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
Field passField = _class.getDeclaredField("password");
final Field passField = klazz.getDeclaredField("password");
passField.setAccessible(true);
passField.set(uploadCmd, password);
try {
certService.uploadSslCert(uploadCmd);
fail("Given an encrypted private key with a bad password. Upload should fail.");
} catch (Exception e) {
assertTrue(e.getMessage().contains("please check password and data"));
} catch (final Exception e) {
assertTrue("Did not expect message: " + e.getMessage(),
e.getMessage().contains("Parsing certificate/key failed: Invalid Key format."));
}
}
@ -397,41 +399,41 @@ public class CertServiceTest {
@Test
public void runUploadSslCertBadkeyPair() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/non_root.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/non_root.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Bad public-private key"));
}
}
@ -440,43 +442,44 @@ public class CertServiceTest {
public void runUploadSslCertBadkeyAlgo() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/dsa_self_signed.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/dsa_self_signed.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
fail("Given a private key which has a different algorithm than the certificate, upload should fail");
} catch (Exception e) {
assertTrue(e.getMessage().contains("Public and private key have different algorithms"));
} catch (final Exception e) {
assertTrue("Did not expect message: " + e.getMessage(),
e.getMessage().contains("Parsing certificate/key failed: Invalid Key format."));
}
}
@ -484,131 +487,128 @@ public class CertServiceTest {
public void runUploadSslCertExpiredCert() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = URLDecoder.decode(getClass().getResource("/certs/expired_cert.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/expired_cert.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
fail("Given an expired certificate, upload should fail");
} catch (Exception e) {
assertTrue(e.getMessage().contains("Certificate expired"));
} catch (final Exception e) {
System.out.println(e.getMessage());
assertTrue(e.getMessage().contains("Parsing certificate/key failed: NotAfter:"));
}
}
@Test
public void runUploadSslCertNotX509() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = URLDecoder.decode(getClass().getResource("/certs/non_x509_pem.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/non_x509_pem.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
fail("Given a Certificate which is not X509, upload should fail");
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Expected X509 certificate"));
}
}
@Test
@Test(expected = NullPointerException.class)
public void runUploadSslCertBadFormat() throws IOException, IllegalAccessException, NoSuchFieldException {
// Reading appropritate files
String certFile = URLDecoder.decode(getClass().getResource("/certs/bad_format_cert.crt").getFile(),Charset.defaultCharset().name());
String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
final String certFile = URLDecoder.decode(getClass().getResource("/certs/bad_format_cert.crt").getFile(),Charset.defaultCharset().name());
final String keyFile = URLDecoder.decode(getClass().getResource("/certs/rsa_self_signed.key").getFile(),Charset.defaultCharset().name());
String cert = readFileToString(new File(certFile));
String key = readFileToString(new File(keyFile));
final String cert = readFileToString(new File(certFile));
final String key = readFileToString(new File(keyFile));
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
when(certService._sslCertDao.persist(any(SslCertVO.class))).thenReturn(new SslCertVO());
//creating the command
UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
Class<?> _class = uploadCmd.getClass().getSuperclass();
final UploadSslCertCmd uploadCmd = new UploadSslCertCmdExtn();
final Class<?> klazz = uploadCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("cert");
final Field certField = klazz.getDeclaredField("cert");
certField.setAccessible(true);
certField.set(uploadCmd, cert);
Field keyField = _class.getDeclaredField("key");
final Field keyField = klazz.getDeclaredField("key");
keyField.setAccessible(true);
keyField.set(uploadCmd, key);
try {
certService.uploadSslCert(uploadCmd);
fail("Given a Certificate in bad format (Not PEM), upload should fail");
} catch (Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate format"));
}
}
@Test
@ -617,18 +617,18 @@ public class CertServiceTest {
*/
public void runDeleteSslCertValid() throws Exception {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertValid");
TransactionLegacy.open("runDeleteSslCertValid");
CertServiceImpl certService = new CertServiceImpl();
long certId = 1;
final CertServiceImpl certService = new CertServiceImpl();
final long certId = 1;
//setting mock objects
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -641,10 +641,10 @@ public class CertServiceTest {
when(certService._lbCertDao.listByCertId(anyLong())).thenReturn(null);
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
final DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
final Class<?> klazz = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
final Field certField = klazz.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
@ -654,19 +654,19 @@ public class CertServiceTest {
@Test
public void runDeleteSslCertBoundCert() throws NoSuchFieldException, IllegalAccessException {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertBoundCert");
TransactionLegacy.open("runDeleteSslCertBoundCert");
CertServiceImpl certService = new CertServiceImpl();
final CertServiceImpl certService = new CertServiceImpl();
//setting mock objects
long certId = 1;
final long certId = 1;
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -676,7 +676,7 @@ public class CertServiceTest {
// rule holding the cert
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
List<LoadBalancerCertMapVO> lbMapList = new ArrayList<LoadBalancerCertMapVO>();
final List<LoadBalancerCertMapVO> lbMapList = new ArrayList<LoadBalancerCertMapVO>();
lbMapList.add(new LoadBalancerCertMapVO());
certService._lbCertDao = Mockito.mock(LoadBalancerCertMapDao.class);
@ -686,17 +686,17 @@ public class CertServiceTest {
when(certService._entityMgr.findById(eq(LoadBalancerVO.class), anyLong())).thenReturn(new LoadBalancerVO());
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
final DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
final Class<?> klazz = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
final Field certField = klazz.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
try {
certService.deleteSslCert(deleteCmd);
fail("Delete with a cert id bound to a lb should fail");
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Certificate in use by a loadbalancer"));
}
@ -704,17 +704,17 @@ public class CertServiceTest {
@Test
public void runDeleteSslCertInvalidId() throws NoSuchFieldException, IllegalAccessException {
TransactionLegacy txn = TransactionLegacy.open("runDeleteSslCertInvalidId");
TransactionLegacy.open("runDeleteSslCertInvalidId");
long certId = 1;
CertServiceImpl certService = new CertServiceImpl();
final long certId = 1;
final CertServiceImpl certService = new CertServiceImpl();
certService._accountMgr = Mockito.mock(AccountManager.class);
Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
final Account account = new AccountVO("testaccount", 1, "networkdomain", (short)0, UUID.randomUUID().toString());
when(certService._accountMgr.getAccount(anyLong())).thenReturn(account);
certService._domainDao = Mockito.mock(DomainDao.class);
DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
final DomainVO domain = new DomainVO("networkdomain", 1L, 1L, "networkdomain");
when(certService._domainDao.findByIdIncludingRemoved(anyLong())).thenReturn(domain);
certService._sslCertDao = Mockito.mock(SslCertDao.class);
@ -726,17 +726,17 @@ public class CertServiceTest {
when(certService._lbCertDao.listByCertId(anyLong())).thenReturn(null);
//creating the command
DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
Class<?> _class = deleteCmd.getClass().getSuperclass();
final DeleteSslCertCmd deleteCmd = new DeleteSslCertCmdExtn();
final Class<?> klazz = deleteCmd.getClass().getSuperclass();
Field certField = _class.getDeclaredField("id");
final Field certField = klazz.getDeclaredField("id");
certField.setAccessible(true);
certField.set(deleteCmd, certId);
try {
certService.deleteSslCert(deleteCmd);
fail("Delete with an invalid ID should fail");
} catch (Exception e) {
} catch (final Exception e) {
assertTrue(e.getMessage().contains("Invalid certificate id"));
}

View File

@ -76,8 +76,8 @@
<!-- Another implementation of SSL protocol. Does not work with broken MS RDP SSL too. -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
<artifactId>bcprov-jdk15on</artifactId>
<version>${cs.bcprov.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -16,23 +16,24 @@
// under the License.
package streamer.bco;
import org.apache.log4j.Logger;
import org.bouncycastle.crypto.tls.Certificate;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.ServerOnlyTlsAuthentication;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import streamer.Direction;
import streamer.Event;
import streamer.SocketWrapperImpl;
import streamer.ssl.SSLState;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.security.Security;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.x509.X509CertificateStructure;
import org.bouncycastle.crypto.tls.CertificateVerifyer;
import org.bouncycastle.crypto.tls.TlsProtocolHandler;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import streamer.Direction;
import streamer.Event;
import streamer.SocketWrapperImpl;
import streamer.ssl.SSLState;
@SuppressWarnings("deprecation")
public class BcoSocketWrapperImpl extends SocketWrapperImpl {
private static final Logger s_logger = Logger.getLogger(BcoSocketWrapperImpl.class);
@ -41,7 +42,7 @@ public class BcoSocketWrapperImpl extends SocketWrapperImpl {
Security.addProvider(new BouncyCastleProvider());
}
private TlsProtocolHandler bcoSslSocket;
private TlsClientProtocol bcoSslSocket;
public BcoSocketWrapperImpl(String id, SSLState sslState) {
super(id, sslState);
@ -60,25 +61,25 @@ public class BcoSocketWrapperImpl extends SocketWrapperImpl {
try {
SecureRandom secureRandom = new SecureRandom();
bcoSslSocket = new TlsProtocolHandler(socket.getInputStream(), socket.getOutputStream(), secureRandom);
CertificateVerifyer client = new CertificateVerifyer() {
bcoSslSocket = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(), secureRandom);
bcoSslSocket.connect(new DefaultTlsClient() {
@Override
public boolean isValid(X509CertificateStructure[] chain) {
public TlsAuthentication getAuthentication() throws IOException {
return new ServerOnlyTlsAuthentication() {
@Override
public void notifyServerCertificate(final Certificate certificate) throws IOException {
try {
if (sslState != null) {
sslState.serverCertificateSubjectPublicKeyInfo = chain[0].getSubjectPublicKeyInfo().getEncoded();
sslState.serverCertificateSubjectPublicKeyInfo = certificate.getCertificateAt(0).getSubjectPublicKeyInfo().getEncoded();
}
} catch (IOException e) {
throw new RuntimeException("Cannot get server public key.", e);
}
return true;
}
};
bcoSslSocket.connect(client);
}
});
InputStream sis = bcoSslSocket.getInputStream();
source.setInputStream(sis);

View File

@ -20,7 +20,7 @@
#
export MAVEN_OPTS="-Xmx4096m -XX:MaxPermSize=800m -Djava.security.egd=file:/dev/urandom"
echo -e "\nStarting simulator"
mvn -Dsimulator -pl :cloud-client-ui jetty:run 2>&1 > /tmp/jetty-log &
mvn -Dsimulator -Dorg.eclipse.jetty.annotations.maxWait=120 -pl :cloud-client-ui jetty:run 2>&1 > /tmp/jetty-log &
while ! nc -vzw 5 localhost 8096 2>&1 > /dev/null; do grep Exception /tmp/jetty-log; sleep 10; done
echo -e "\nStarting DataCenter deployment"

View File

@ -106,7 +106,7 @@
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test dependency in mysql for db tests -->

View File

@ -19,7 +19,10 @@
package com.cloud.utils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.SecureRandom;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -40,6 +43,13 @@ public class PasswordGenerator {
static private int minLength = 3;
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
if (Security.getProvider(provider.getName()) == null) {
Security.addProvider(provider);
}
}
public static String generateRandomPassword(int num) {
Random r = new SecureRandom();
StringBuilder password = new StringBuilder();

View File

@ -19,6 +19,13 @@
package com.cloud.utils.security;
import com.cloud.utils.Ternary;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@ -40,124 +47,143 @@ import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.commons.codec.binary.Base64;
import com.cloud.utils.Ternary;
import org.bouncycastle.openssl.PEMReader;
public class CertificateHelper {
public static byte[] buildAndSaveKeystore(String alias, String cert, String privateKey, String storePassword) throws KeyStoreException, CertificateException,
public static byte[] buildAndSaveKeystore(final String alias, final String cert, final String privateKey, final String storePassword) throws KeyStoreException, CertificateException,
NoSuchAlgorithmException, InvalidKeySpecException, IOException {
KeyStore ks = buildKeystore(alias, cert, privateKey, storePassword);
Preconditions.checkArgument(!Strings.isNullOrEmpty(alias), "Certificate alias cannot be blank");
Preconditions.checkArgument(!Strings.isNullOrEmpty(cert), "Certificate cannot be blank");
Preconditions.checkArgument(!Strings.isNullOrEmpty(privateKey), "Private key cannot be blank");
ByteArrayOutputStream os = new ByteArrayOutputStream();
final KeyStore ks = buildKeystore(alias, cert, privateKey, storePassword);
try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
ks.store(os, storePassword != null ? storePassword.toCharArray() : null);
os.close();
return os.toByteArray();
}
}
public static byte[] buildAndSaveKeystore(List<Ternary<String, String, String>> certs, String storePassword) throws KeyStoreException, NoSuchAlgorithmException,
public static byte[] buildAndSaveKeystore(final List<Ternary<String, String, String>> certs, final String storePassword) throws KeyStoreException, NoSuchAlgorithmException,
CertificateException, IOException, InvalidKeySpecException {
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, storePassword != null ? storePassword.toCharArray() : null);
Preconditions.checkNotNull(certs, "List of certificates to be saved in keystore cannot be null");
char password[] = null;
if (storePassword != null) {
password = storePassword.toCharArray();
}
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, password);
//name,cert,key
for (Ternary<String, String, String> cert : certs) {
for (final Ternary<String, String, String> cert : certs) {
if (cert.third() == null) {
Certificate c = buildCertificate(cert.second());
final Certificate c = buildCertificate(cert.second());
ks.setCertificateEntry(cert.first(), c);
} else {
Certificate[] c = new Certificate[certs.size()];
final Certificate[] c = new Certificate[certs.size()];
int i = certs.size();
for (Ternary<String, String, String> ct : certs) {
for (final Ternary<String, String, String> ct : certs) {
c[i - 1] = buildCertificate(ct.second());
i--;
}
ks.setKeyEntry(cert.first(), buildPrivateKey(cert.third()), storePassword != null ? storePassword.toCharArray() : null, c);
ks.setKeyEntry(cert.first(), buildPrivateKey(cert.third()), password, c);
}
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
ks.store(os, storePassword != null ? storePassword.toCharArray() : null);
os.close();
try (final ByteArrayOutputStream os = new ByteArrayOutputStream()) {
ks.store(os, password);
return os.toByteArray();
}
}
public static KeyStore loadKeystore(byte[] ksData, String storePassword) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
assert (ksData != null);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new ByteArrayInputStream(ksData), storePassword != null ? storePassword.toCharArray() : null);
public static KeyStore loadKeystore(final byte[] ksData, final String storePassword) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException {
Preconditions.checkNotNull(ksData, "Keystore data cannot be null");
final KeyStore ks = KeyStore.getInstance("JKS");
try (final ByteArrayInputStream is = new ByteArrayInputStream(ksData)) {
ks.load(is, storePassword != null ? storePassword.toCharArray() : null);
}
return ks;
}
public static KeyStore buildKeystore(String alias, String cert, String privateKey, String storePassword) throws KeyStoreException, CertificateException,
public static KeyStore buildKeystore(final String alias, final String cert, final String privateKey, final String storePassword) throws KeyStoreException, CertificateException,
NoSuchAlgorithmException, InvalidKeySpecException, IOException {
Preconditions.checkArgument(!Strings.isNullOrEmpty(alias), "Certificate alias cannot be blank");
Preconditions.checkArgument(!Strings.isNullOrEmpty(cert), "Certificate cannot be blank");
Preconditions.checkArgument(!Strings.isNullOrEmpty(privateKey), "Private key cannot be blank");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, storePassword != null ? storePassword.toCharArray() : null);
Certificate[] certs = new Certificate[1];
char password[] = null;
if (storePassword != null) {
password = storePassword.toCharArray();
}
final KeyStore ks = KeyStore.getInstance("JKS");
ks.load(null, password);
final Certificate[] certs = new Certificate[1];
certs[0] = buildCertificate(cert);
ks.setKeyEntry(alias, buildPrivateKey(privateKey), storePassword != null ? storePassword.toCharArray() : null, certs);
ks.setKeyEntry(alias, buildPrivateKey(privateKey), password, certs);
return ks;
}
public static Certificate buildCertificate(String content) throws CertificateException {
assert (content != null);
public static Certificate buildCertificate(final String content) throws CertificateException {
Preconditions.checkNotNull(content, "Certificate content cannot be null");
BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content.getBytes()));
CertificateFactory cf = CertificateFactory.getInstance("X.509");
final BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(content.getBytes()));
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
return cf.generateCertificate(bis);
}
public static Key buildPrivateKey(String base64EncodedKeyContent) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64EncodedKeyContent));
public static Key buildPrivateKey(final String base64EncodedKeyContent) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
Preconditions.checkNotNull(base64EncodedKeyContent);
final KeyFactory kf = KeyFactory.getInstance("RSA");
final PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64EncodedKeyContent));
return kf.generatePrivate(keysp);
}
public static List<Certificate> parseChain(String chain) throws IOException {
public static List<Certificate> parseChain(final String chain) throws IOException, CertificateException {
Preconditions.checkNotNull(chain);
List<Certificate> certs = new ArrayList<Certificate>();
PEMReader reader = new PEMReader(new StringReader(chain));
final List<Certificate> certs = new ArrayList<Certificate>();
try(final PemReader pemReader = new PemReader(new StringReader(chain));)
{
final PemObject pemObject = pemReader.readPemObject();
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
final ByteArrayInputStream bais = new ByteArrayInputStream(pemObject.getContent());
Certificate crt = null;
while ((crt = (Certificate)reader.readObject()) != null) {
if (crt instanceof X509Certificate) {
certs.add(crt);
for (final Certificate cert : certificateFactory.generateCertificates(bais)) {
if (cert instanceof X509Certificate) {
certs.add(cert);
}
}
if (certs.isEmpty()) {
throw new IllegalStateException("Unable to decode certificate chain");
}
}
if (certs.size() == 0)
throw new IllegalArgumentException("Unable to decode certificate chain");
return certs;
}
public static String generateFingerPrint(Certificate cert) {
public static String generateFingerPrint(final Certificate cert) {
Preconditions.checkNotNull(cert, "Certificate cannot be null");
final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
StringBuilder buffer = new StringBuilder(60);
final StringBuilder buffer = new StringBuilder(60);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] data = md.digest(cert.getEncoded());
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final byte[] data = md.digest(cert.getEncoded());
for (int i = 0; i < data.length; i++) {
for (final byte element : data) {
if (buffer.length() > 0) {
buffer.append(":");
}
buffer.append(HEX[(0xF0 & data[i]) >>> 4]);
buffer.append(HEX[0x0F & data[i]]);
buffer.append(HEX[(0xF0 & element) >>> 4]);
buffer.append(HEX[0x0F & element]);
}
} catch (CertificateEncodingException e) {
throw new CloudRuntimeException("Bad certificate encoding");
} catch (NoSuchAlgorithmException e) {
throw new CloudRuntimeException("Bad certificate algorithm");
} catch (final CertificateEncodingException e) {
throw new IllegalStateException("Bad certificate encoding");
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException("Bad certificate algorithm");
}
return buffer.toString();