package com.intrbiz.bergamot.ui.action;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.apache.log4j.Logger;
import com.intrbiz.accounting.Accounting;
import com.intrbiz.bergamot.accounting.model.SignAgentAccountingEvent;
import com.intrbiz.bergamot.crypto.util.CertificatePair;
import com.intrbiz.bergamot.crypto.util.CertificateRequest;
import com.intrbiz.bergamot.crypto.util.PEMUtil;
import com.intrbiz.bergamot.crypto.util.RSAUtil;
import com.intrbiz.bergamot.model.Config;
import com.intrbiz.bergamot.model.message.agent.manager.AgentManagerRequest;
import com.intrbiz.bergamot.model.message.agent.manager.AgentManagerResponse;
import com.intrbiz.bergamot.model.message.agent.manager.request.GetRootCA;
import com.intrbiz.bergamot.model.message.agent.manager.request.GetSiteCA;
import com.intrbiz.bergamot.model.message.agent.manager.request.SignAgent;
import com.intrbiz.bergamot.model.message.agent.manager.request.SignTemplate;
import com.intrbiz.bergamot.model.message.agent.manager.response.GotRootCA;
import com.intrbiz.bergamot.model.message.agent.manager.response.GotSiteCA;
import com.intrbiz.bergamot.model.message.agent.manager.response.SignedAgent;
import com.intrbiz.bergamot.model.message.agent.manager.response.SignedTemplate;
import com.intrbiz.bergamot.queue.BergamotAgentManagerQueue;
import com.intrbiz.metadata.Action;
import com.intrbiz.queue.RPCClient;
import com.intrbiz.queue.name.RoutingKey;
public class BergamotAgentActions
{
private Logger logger = Logger.getLogger(BergamotAgentActions.class);
private BergamotAgentManagerQueue queue;
private RPCClient<AgentManagerRequest, AgentManagerResponse, RoutingKey> client;
private Accounting accounting = Accounting.create(BergamotAgentActions.class);
public BergamotAgentActions()
{
this.queue = BergamotAgentManagerQueue.open();
this.client = this.queue.createBergamotAgentManagerRPCClient();
}
@Action("sign-agent")
public Certificate signAgent(UUID siteId, UUID agentId, CertificateRequest req, UUID contactId)
{
try
{
// sign the cert
logger.info("Signing Bergamot Agent request for: " + req.getCommonName());
AgentManagerResponse response = this.client.publish(new SignAgent(siteId, agentId, req.getCommonName(), PEMUtil.savePublicKey(req.getKey()))).get(10, TimeUnit.SECONDS);
if (response instanceof SignedAgent)
{
Certificate crt = PEMUtil.loadCertificate(((SignedAgent) response).getCertificatePEM());
// account
this.accounting.account(new SignAgentAccountingEvent(siteId, agentId, req.getCommonName(), ((X509Certificate) crt).getSerialNumber().toString(), contactId));
// done
return crt;
}
throw new RuntimeException("Failed to sign agent");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to sign agent", e);
}
}
@Action("sign-agent-key")
public Certificate signAgentKey(UUID siteId, UUID agentId, String commonName, PublicKey key, UUID contactId)
{
try
{
// sign the cert
logger.info("Signing Bergamot Agent request for: " + commonName);
AgentManagerResponse response = this.client.publish(new SignAgent(siteId, agentId, commonName, PEMUtil.savePublicKey(key))).get(10, TimeUnit.SECONDS);
if (response instanceof SignedAgent)
{
Certificate crt = PEMUtil.loadCertificate(((SignedAgent) response).getCertificatePEM());
// account
this.accounting.account(new SignAgentAccountingEvent(siteId, agentId, commonName, ((X509Certificate) crt).getSerialNumber().toString(), contactId));
// done
return crt;
}
throw new RuntimeException("Failed to sign agent key");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to sign agent key", e);
}
}
@Action("generate-agent")
public CertificatePair generateAgent(UUID siteId, UUID agentId, String commonName, UUID contactId)
{
try
{
// generate the key pair
KeyPair pair = RSAUtil.generateRSAKeyPair(2048);
// sign the cert
logger.info("Generating Bergamot Agent certificate pair: " + commonName);
AgentManagerResponse response = this.client.publish(new SignAgent(siteId, agentId, commonName, PEMUtil.savePublicKey(pair.getPublic()))).get(10, TimeUnit.SECONDS);
if (response instanceof SignedAgent)
{
CertificatePair crtPair = new CertificatePair((X509Certificate) PEMUtil.loadCertificate(((SignedAgent) response).getCertificatePEM()), pair.getPrivate());
// account
this.accounting.account(new SignAgentAccountingEvent(siteId, agentId, commonName, ((X509Certificate) crtPair.getCertificate()).getSerialNumber().toString(), contactId));
// done
return crtPair;
}
throw new RuntimeException("Failed to sign agent");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to sign agent", e);
}
}
@Action("get-site-ca")
public Certificate getSiteCA(UUID siteId)
{
try
{
// get the site ca
AgentManagerResponse response = this.client.publish(new GetSiteCA(siteId)).get(10, TimeUnit.SECONDS);
if (response instanceof GotSiteCA)
{
return PEMUtil.loadCertificate(((GotSiteCA) response).getCertificatePEM());
}
throw new RuntimeException("Failed to get site CA");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to get site CA", e);
}
}
@Action("get-root-ca")
public Certificate getRootCA()
{
try
{
// get the site ca
AgentManagerResponse response = this.client.publish(new GetRootCA()).get(10, TimeUnit.SECONDS);
if (response instanceof GotRootCA)
{
return PEMUtil.loadCertificate(((GotRootCA) response).getCertificatePEM());
}
throw new RuntimeException("Failed to get root CA");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to get root CA", e);
}
}
@Action("generate-template")
public CertificatePair generateTemplate(UUID siteId, Config hostTemplate, UUID contactId)
{
try
{
String templateName = hostTemplate.getName();
UUID templateId = hostTemplate.getId();
// generate the key pair
KeyPair pair = RSAUtil.generateRSAKeyPair(2048);
// sign the cert
logger.info("Generating Bergamot Agent certificate pair: " + templateName);
AgentManagerResponse response = this.client.publish(new SignTemplate(siteId, templateId, templateName, PEMUtil.savePublicKey(pair.getPublic()))).get(10, TimeUnit.SECONDS);
if (response instanceof SignedTemplate)
{
CertificatePair crtPair = new CertificatePair((X509Certificate) PEMUtil.loadCertificate(((SignedTemplate) response).getCertificatePEM()), pair.getPrivate());
// account
this.accounting.account(new SignAgentAccountingEvent(siteId, templateId, templateName, ((X509Certificate) crtPair.getCertificate()).getSerialNumber().toString(), contactId));
// done
return crtPair;
}
throw new RuntimeException("Failed to sign template");
}
catch (IOException | InterruptedException | ExecutionException | TimeoutException e)
{
throw new RuntimeException("Failed to sign template", e);
}
}
}