mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-5296: Add certificate chain support for netscaler
This patch adds support for trust chains in the netscaler. I initially planned on using the 10.1 API's "bundle" feature but during my testing I found that was not working. So I am doing the chain linking myself. Also NS can have only one entity of a certificate ie lets say two different users try to add the same certificate on the netscaler only one of them will go through. The other one says resouce already exists even though they have different files. This can be a problem in trust chains where the chain can be shared between multiple accounts/certificates. So, I am using the figerprint as an identifier of a certificate and making sure that we delete it only when no one references it.
This commit is contained in:
parent
04b48ae04e
commit
ee7380ace2
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
G# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
|
||||
@ -437,13 +437,15 @@ public class LoadBalancingRule {
|
||||
private String key;
|
||||
private String password = null;
|
||||
private String chain = null;
|
||||
private String fingerprint;
|
||||
private boolean revoked;
|
||||
|
||||
public LbSslCert(String cert, String key, String password, String chain, boolean revoked) {
|
||||
public LbSslCert(String cert, String key, String password, String chain, String fingerprint, boolean revoked) {
|
||||
this.cert = cert;
|
||||
this.key = key;
|
||||
this.password = password;
|
||||
this.chain = chain;
|
||||
this.fingerprint = fingerprint;
|
||||
this.revoked = revoked;
|
||||
}
|
||||
|
||||
@ -464,6 +466,10 @@ public class LoadBalancingRule {
|
||||
return chain;
|
||||
}
|
||||
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
public boolean isRevoked() {
|
||||
return revoked;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ public class SslCertDaoImpl extends GenericDaoBase<SslCertVO, Long> implements S
|
||||
listByAccountId = createSearchBuilder();
|
||||
listByAccountId.and("accountId", listByAccountId.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
listByAccountId.done();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SslCertVO> listByAccountId(Long accountId) {
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
// under the License.
|
||||
package com.cloud.network.resource;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
@ -25,6 +28,15 @@ import java.util.Map;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey;
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey_sslvserver_binding;
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslcertlink;
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
|
||||
import com.cloud.utils.security.CertificateHelper;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.citrix.netscaler.nitro.exception.nitro_exception;
|
||||
@ -61,8 +73,6 @@ import com.citrix.netscaler.nitro.resource.config.ns.nshardware;
|
||||
import com.citrix.netscaler.nitro.resource.config.ns.nsip;
|
||||
import com.citrix.netscaler.nitro.resource.config.ns.nstimer;
|
||||
import com.citrix.netscaler.nitro.resource.config.ns.nstimer_autoscalepolicy_binding;
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslcertkey;
|
||||
import com.citrix.netscaler.nitro.resource.config.ssl.sslvserver_sslcertkey_binding;
|
||||
import com.citrix.netscaler.nitro.resource.stat.lb.lbvserver_stats;
|
||||
import com.citrix.netscaler.nitro.service.nitro_service;
|
||||
import com.citrix.netscaler.nitro.util.filtervalue;
|
||||
@ -111,7 +121,6 @@ import com.cloud.agent.api.to.LoadBalancerTO.StickinessPolicyTO;
|
||||
import com.cloud.agent.api.to.StaticNatRuleTO;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.Host.Type;
|
||||
import com.cloud.network.lb.LoadBalancingRule.LbSslCert;
|
||||
import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType;
|
||||
import com.cloud.resource.ServerResource;
|
||||
import com.cloud.serializer.GsonHelper;
|
||||
@ -119,7 +128,7 @@ import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.exception.ExecutionException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
|
||||
class NitroError {
|
||||
static final int NS_RESOURCE_EXISTS = 273;
|
||||
@ -665,23 +674,61 @@ public class NetscalerResource implements ServerResource {
|
||||
|
||||
}
|
||||
|
||||
if (sslCert != null && lbProtocol.equals(NetUtils.SSL_PROTO)) {
|
||||
if (sslCert != null && lbProtocol.equalsIgnoreCase(NetUtils.SSL_PROTO)) {
|
||||
if (sslCert.isRevoked()) {
|
||||
deleteCert = true;
|
||||
} else {
|
||||
|
||||
String certName = generateSslCertName(srcIp, srcPort);
|
||||
String keyName = generateSslKeyName(srcIp, srcPort);
|
||||
String certKeyName = generateSslCertKeyName(srcIp, srcPort);
|
||||
// If there is a chain, that should go first to the NS
|
||||
|
||||
if (SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
|
||||
SSL.deleteSslCertKey(_netscalerService, certKeyName);
|
||||
String previousCertKeyName = null;
|
||||
|
||||
if ( sslCert.getChain() != null ) {
|
||||
List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
|
||||
// go from ROOT to intermediate CAs
|
||||
for ( Certificate intermediateCert : Lists.reverse(chainList)){
|
||||
|
||||
String fingerPrint=CertificateHelper.generateFingerPrint(intermediateCert);
|
||||
String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
|
||||
String intermediateCertFileName = intermediateCertKeyName + ".pem";
|
||||
|
||||
if (! SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName)) {
|
||||
byte[] certData= intermediateCert.getEncoded();
|
||||
StringWriter textWriter = new StringWriter();
|
||||
PEMWriter pemWriter = new PEMWriter(textWriter);
|
||||
pemWriter.writeObject(intermediateCert);
|
||||
pemWriter.flush();
|
||||
|
||||
SSL.uploadCert(_ip, _username, _password, intermediateCertFileName, textWriter.toString().getBytes());
|
||||
SSL.createSslCertKey(_netscalerService, intermediateCertFileName, null, intermediateCertKeyName, null);
|
||||
}
|
||||
|
||||
if ( previousCertKeyName != null && ! SSL.certLinkExists(_netscalerService, intermediateCertKeyName, previousCertKeyName)){
|
||||
SSL.linkCerts(_netscalerService, intermediateCertKeyName, previousCertKeyName);
|
||||
}
|
||||
|
||||
previousCertKeyName = intermediateCertKeyName;
|
||||
}
|
||||
}
|
||||
|
||||
SSL.uploadCert(_ip, _username, _password, certName, sslCert.getCert().getBytes());
|
||||
SSL.uploadKey(_ip, _username, _password, keyName, sslCert.getKey().getBytes());
|
||||
String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
|
||||
String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
|
||||
String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
|
||||
|
||||
ByteArrayOutputStream certDataStream = new ByteArrayOutputStream( );
|
||||
certDataStream.write(sslCert.getCert().getBytes());
|
||||
|
||||
if (! SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
|
||||
|
||||
SSL.uploadCert(_ip, _username, _password, certFilename, certDataStream.toByteArray());
|
||||
SSL.uploadKey(_ip, _username, _password, keyFilename, sslCert.getKey().getBytes());
|
||||
SSL.createSslCertKey(_netscalerService, certFilename, keyFilename, certKeyName, sslCert.getPassword());
|
||||
}
|
||||
|
||||
if (previousCertKeyName != null && ! SSL.certLinkExists(_netscalerService, certKeyName, previousCertKeyName)){
|
||||
SSL.linkCerts(_netscalerService, certKeyName, previousCertKeyName);
|
||||
}
|
||||
|
||||
SSL.createSslCertKey(_netscalerService, certName, keyName, certKeyName, sslCert.getPassword());
|
||||
SSL.bindCertKeyToVserver(_netscalerService, certKeyName, nsVirtualServerName);
|
||||
}
|
||||
|
||||
@ -778,18 +825,50 @@ public class NetscalerResource implements ServerResource {
|
||||
}
|
||||
if (sslCert != null && deleteCert) {
|
||||
|
||||
String certName = generateSslCertName(srcIp, srcPort);
|
||||
String keyName = generateSslKeyName(srcIp, srcPort);
|
||||
String certKeyName = generateSslCertKeyName(srcIp, srcPort);
|
||||
String certFilename = generateSslCertName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
|
||||
String keyFilename = generateSslKeyName(sslCert.getFingerprint()) + ".pem"; //netscaler uses ".pem" format for "bundle" files
|
||||
String certKeyName = generateSslCertKeyName(sslCert.getFingerprint());
|
||||
|
||||
// unbind before deleting
|
||||
if (nsVirtualServerExists(nsVirtualServerName)) {
|
||||
if (nsVirtualServerExists(nsVirtualServerName) &&
|
||||
SSL.isSslCertKeyPresent(_netscalerService, certKeyName) &&
|
||||
SSL.isBoundToVserver(_netscalerService, certKeyName, nsVirtualServerName)) {
|
||||
SSL.unbindCertKeyFromVserver(_netscalerService, certKeyName, nsVirtualServerName);
|
||||
}
|
||||
|
||||
SSL.deleteSslCertKey(_netscalerService, certKeyName);
|
||||
SSL.deleteCertFile(_ip, _username, _password, certName);
|
||||
SSL.deleteKeyFile(_ip, _username, _password, keyName);
|
||||
if (SSL.isSslCertKeyPresent(_netscalerService, certKeyName)) {
|
||||
|
||||
SSL.deleteSslCertKey(_netscalerService, certKeyName);
|
||||
SSL.deleteCertFile(_ip, _username, _password, certFilename);
|
||||
SSL.deleteKeyFile(_ip, _username, _password, keyFilename);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check and delete intermediate certs:
|
||||
* we can delete an intermediate cert if no other
|
||||
* cert references it as the athority
|
||||
*/
|
||||
|
||||
if ( sslCert.getChain() != null ) {
|
||||
List<Certificate> chainList = CertificateHelper.parseChain(sslCert.getChain());
|
||||
//go from intermediate CAs to ROOT
|
||||
for ( Certificate intermediateCert : chainList){
|
||||
|
||||
String fingerPrint=CertificateHelper.generateFingerPrint(intermediateCert);
|
||||
String intermediateCertKeyName = generateSslCertKeyName(fingerPrint);
|
||||
String intermediateCertFileName = intermediateCertKeyName + ".pem";
|
||||
|
||||
if (SSL.isSslCertKeyPresent(_netscalerService, intermediateCertKeyName) &&
|
||||
! SSL.isCaforCerts(_netscalerService, intermediateCertKeyName)) {
|
||||
SSL.deleteSslCertKey(_netscalerService, intermediateCertKeyName);
|
||||
SSL.deleteCertFile(_ip, _username, _password, intermediateCertFileName);
|
||||
}else {
|
||||
break;// if this cert has another certificate as a child then stop at this point because we need the whole chain
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1718,7 +1797,7 @@ public class NetscalerResource implements ServerResource {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void deleteSslCertKey(nitro_service ns, String certKeyName) throws ExecutionException {
|
||||
private static void deleteSslCertKey(nitro_service ns, String certKeyName) throws ExecutionException {
|
||||
try {
|
||||
|
||||
sslcertkey certkey = new sslcertkey();
|
||||
@ -1733,21 +1812,23 @@ public class NetscalerResource implements ServerResource {
|
||||
|
||||
}
|
||||
|
||||
private static void deleteCertFile(String nsIp, String username, String password, String certName) throws Exception {
|
||||
SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + certName);
|
||||
private static void deleteCertFile(String nsIp, String username, String password, String certFilename) throws Exception {
|
||||
SshHelper.sshExecute(nsIp,SSH_PORT,username,null,password,"shell rm " + SSL_CERT_PATH + certFilename);
|
||||
}
|
||||
|
||||
private static void deleteKeyFile(String nsIp, String username, String password, String keyName) throws Exception {
|
||||
SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + keyName);
|
||||
private static void deleteKeyFile(String nsIp, String username, String password, String keyFilename) throws Exception {
|
||||
SshHelper.sshExecute(nsIp, SSH_PORT, username, null, password, "shell rm " + SSL_CERT_PATH + keyFilename);
|
||||
}
|
||||
|
||||
private static void createSslCertKey(nitro_service ns, String certName, String keyName, String certKeyName, String password) throws ExecutionException {
|
||||
private static void createSslCertKey(nitro_service ns, String certFilename, String keyFilename, String certKeyName, String password) throws ExecutionException {
|
||||
s_logger.debug("Adding cert to netscaler");
|
||||
try {
|
||||
sslcertkey certkey = new sslcertkey();
|
||||
certkey.set_certkey(certKeyName);
|
||||
certkey.set_cert(SSL_CERT_PATH + certName);
|
||||
certkey.set_key(SSL_CERT_PATH + keyName);
|
||||
certkey.set_cert(SSL_CERT_PATH + certFilename);
|
||||
|
||||
if ( keyFilename != null )
|
||||
certkey.set_key(SSL_CERT_PATH + keyFilename);
|
||||
|
||||
if (password != null) {
|
||||
certkey.set_passplain(password);
|
||||
@ -1813,17 +1894,17 @@ public class NetscalerResource implements ServerResource {
|
||||
|
||||
}
|
||||
|
||||
private static void uploadCert(String nsIp, String user, String password, String certName, byte[] certData) throws ExecutionException {
|
||||
private static void uploadCert(String nsIp, String user, String password, String certFilename, byte[] certData) throws ExecutionException {
|
||||
try {
|
||||
SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, certData, certName, null);
|
||||
} catch (Exception e) {
|
||||
SshHelper.scpTo(nsIp,SSH_PORT,user,null,password, SSL_CERT_PATH, certData, certFilename, null);
|
||||
} catch (Exception e){
|
||||
throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void uploadKey(String nsIp, String user, String password, String keyName, byte[] keyData) throws ExecutionException {
|
||||
private static void uploadKey(String nsIp, String user, String password, String keyFilename, byte[] keyData) throws ExecutionException {
|
||||
try {
|
||||
SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, keyData, keyName, null);
|
||||
SshHelper.scpTo(nsIp, SSH_PORT, user, null, password, SSL_CERT_PATH, keyData, keyFilename, null);
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException("Failed to copy private key to device " + e.getMessage());
|
||||
}
|
||||
@ -1831,7 +1912,7 @@ public class NetscalerResource implements ServerResource {
|
||||
|
||||
private static void enableSslFeature(nitro_service ns) throws ExecutionException {
|
||||
try {
|
||||
base_response result = ns.enable_features(new String[] {"SSL"});
|
||||
base_response result = ns.enable_features(new String[]{"SSL"});
|
||||
if (result.errorcode != 0)
|
||||
throw new ExecutionException("Unable to enable SSL on LB");
|
||||
} catch (nitro_exception e) {
|
||||
@ -1859,6 +1940,80 @@ public class NetscalerResource implements ServerResource {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean certLinkExists(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
|
||||
try {
|
||||
// check if there is a link from userCertName to caCertName
|
||||
|
||||
sslcertkey userCert = sslcertkey.get(ns,userCertName);
|
||||
String nsCaCert = userCert.get_linkcertkeyname();
|
||||
|
||||
if (nsCaCert != null && nsCaCert.equals(caCertName))
|
||||
return true;
|
||||
|
||||
} catch (nitro_exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void linkCerts(nitro_service ns, String userCertName, String caCertName) throws ExecutionException {
|
||||
try {
|
||||
|
||||
// the assumption is that that both userCertName and caCertName are present on NS
|
||||
|
||||
sslcertkey caCert = sslcertkey.get(ns, caCertName);
|
||||
sslcertkey userCert = sslcertkey.get(ns, userCertName);
|
||||
|
||||
sslcertkey linkResource = new sslcertkey();
|
||||
|
||||
// link user cert to CA cert
|
||||
linkResource.set_certkey(userCert.get_certkey());
|
||||
linkResource.set_linkcertkeyname(caCert.get_certkey());
|
||||
sslcertkey.link(ns, linkResource);
|
||||
|
||||
} catch (nitro_exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isCaforCerts(nitro_service ns, String caCertName) throws ExecutionException {
|
||||
// check if this certificate serves as a CA for other certificates
|
||||
try {
|
||||
sslcertlink[] childLinks = sslcertlink.get_filtered(ns,"linkcertkeyname:" + caCertName);
|
||||
if(childLinks != null && childLinks.length > 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (nitro_exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static boolean isBoundToVserver(nitro_service ns, String certKeyName, String nsVirtualServerName) throws ExecutionException {
|
||||
try {
|
||||
|
||||
sslcertkey_sslvserver_binding[] cert_vs_binding = sslcertkey_sslvserver_binding.get_filtered(ns, certKeyName, "vservername:" + nsVirtualServerName);
|
||||
if(cert_vs_binding != null && cert_vs_binding.length > 0){
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (nitro_exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer to " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException("Failed to check cert link on load balancer due to " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void enableVPXInterfaces(String publicIf, String privateIf, ns ns_obj) {
|
||||
@ -3588,17 +3743,22 @@ public class NetscalerResource implements ServerResource {
|
||||
return counterName.replace(' ', '_');
|
||||
}
|
||||
|
||||
private String generateSslCertName(String srcIp, long srcPort) {
|
||||
private String generateSslCertName(String fingerPrint) {
|
||||
// maximum length supported by NS is 31
|
||||
return genObjectName("Cloud-Cert", srcIp, srcPort);
|
||||
// the first 20 characters of the SHA-1 checksum are the unique id
|
||||
String uniqueId = fingerPrint.replace(":","").substring(0,20);
|
||||
|
||||
return genObjectName("Cloud-Cert", uniqueId);
|
||||
}
|
||||
|
||||
private String generateSslKeyName(String srcIp, long srcPort) {
|
||||
return genObjectName("Cloud-Key", srcIp, srcPort);
|
||||
private String generateSslKeyName(String fingerPrint) {
|
||||
String uniqueId = fingerPrint.replace(":","").substring(0,20);
|
||||
return genObjectName("Cloud-Key", uniqueId);
|
||||
}
|
||||
|
||||
private String generateSslCertKeyName(String srcIp, long srcPort) {
|
||||
return genObjectName("Cloud-CertKey", srcIp, srcPort);
|
||||
private String generateSslCertKeyName(String fingerPrint){
|
||||
String uniqueId = fingerPrint.replace(":","").substring(0,20);
|
||||
return genObjectName("Cloud-Cert", uniqueId);
|
||||
}
|
||||
|
||||
private String genObjectName(Object... args) {
|
||||
|
||||
@ -1074,7 +1074,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LbSslCert(certVO.getCertificate(), certVO.getKey(), certVO.getChain(), certVO.getPassword(), lbCertMap.isRevoke());
|
||||
return new LbSslCert(certVO.getCertificate(), certVO.getKey(), certVO.getPassword(), certVO.getChain(), certVO.getFingerPrint(), lbCertMap.isRevoke());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1124,11 +1124,6 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
|
||||
LoadBalancerCertMapVO certMap = new LoadBalancerCertMapVO(lbRuleId, certId, false);
|
||||
_lbCertMapDao.persist(certMap);
|
||||
applyLoadBalancerConfig(loadBalancer.getId());
|
||||
/*s_logger.warn("Failed to apply Ssl Cert to LB " + loadBalancer.getId());
|
||||
CloudRuntimeException ex = new CloudRuntimeException(
|
||||
"Failed to apply Ssl Cert to LB " + loadBalancer.getId());
|
||||
ex.addProxyObject(loadBalancer.getUuid(), "loadBalancerId");
|
||||
throw ex;*/
|
||||
success = true;
|
||||
} catch (ResourceUnavailableException e) {
|
||||
if (isRollBackAllowedForProvider(loadBalancer)) {
|
||||
|
||||
@ -25,6 +25,7 @@ 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;
|
||||
@ -115,6 +116,7 @@ public class CertServiceImpl implements CertService {
|
||||
|
||||
validate(cert, key, password, chain);
|
||||
s_logger.debug("Certificate Validation succeeded");
|
||||
|
||||
String fingerPrint = generateFingerPrint(parseCertificate(cert));
|
||||
|
||||
Long accountId = CallContext.current().getCallingAccount().getId();
|
||||
@ -379,14 +381,17 @@ 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");
|
||||
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) {
|
||||
throw new CloudRuntimeException("No provider for certificate validation", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,21 +20,28 @@ import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
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,
|
||||
@ -106,4 +113,53 @@ public class CertificateHelper {
|
||||
PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64EncodedKeyContent));
|
||||
return kf.generatePrivate(keysp);
|
||||
}
|
||||
|
||||
public static List<Certificate> parseChain(String chain) throws IOException {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static 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 CloudRuntimeException("Bad certificate encoding");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new CloudRuntimeException("Bad certificate algorithm");
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user