@Override
public IResponseMessage processRequest(Admin admin, CAInfo cainfo, IRequestMessage requestmessage) throws CAExistsException, CADoesntExistsException,
AuthorizationDeniedException, CATokenOfflineException {
final CA ca;
Collection<Certificate> certchain = null;
IResponseMessage returnval = null;
// check authorization
if(!authorizationSession.isAuthorizedNoLog(admin, "/super_administrator")) {
String msg = intres.getLocalizedMessage("caadmin.notauthorizedtocertresp", cainfo.getName());
logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new java.util.Date(), null, null, LogConstants.EVENT_ERROR_NOTAUTHORIZEDTORESOURCE,
msg);
throw new AuthorizationDeniedException(msg);
}
// Check that CA doesn't already exists
CAData oldcadata = null;
int caid = cainfo.getCAId();
if (caid >= 0 && caid <= CAInfo.SPECIALCAIDBORDER) {
String msg = intres.getLocalizedMessage("caadmin.errorcaexists", cainfo.getName());
logSession.log(admin, admin.getCaId(), LogConstants.MODULE_CA, new java.util.Date(), null, null, LogConstants.EVENT_ERROR_CAEDITED, msg);
throw new CAExistsException(msg);
}
oldcadata = CAData.findById(entityManager, Integer.valueOf(caid));
// If it did not exist with a certain DN (caid) perhaps a CA with the
// same CA name exists?
if (oldcadata == null) {
oldcadata = CAData.findByName(entityManager, cainfo.getName());
}
boolean processinternalca = false;
if (oldcadata != null) {
// If we find an already existing CA, there is a good chance that we
// should throw an exception
// Saying that the CA already exists.
// However, if we have the same DN, and give the same name, we
// simply assume that the admin actually wants
// to treat an internal CA as an external CA, perhaps there is
// different HSMs connected for root CA and sub CA?
if (log.isDebugEnabled()) {
log.debug("Old castatus=" + oldcadata.getStatus() + ", oldcaid=" + oldcadata.getCaId().intValue() + ", caid=" + cainfo.getCAId()
+ ", oldcaname=" + oldcadata.getName() + ", name=" + cainfo.getName());
}
if (((oldcadata.getStatus() == SecConst.CA_WAITING_CERTIFICATE_RESPONSE) || (oldcadata.getStatus() == SecConst.CA_ACTIVE) || (oldcadata.getStatus() == SecConst.CA_EXTERNAL))
&& (oldcadata.getCaId().intValue() == cainfo.getCAId()) && (oldcadata.getName().equals(cainfo.getName()))) {
// Yes, we have all the same DN, CAName and the old CA is either
// waiting for a certificate response or is active
// (new CA or active CA that we want to renew)
// or it is an external CA that we want to issue a new
// certificate to
processinternalca = true;
if (oldcadata.getStatus() == SecConst.CA_EXTERNAL) {
log.debug("Renewing an external CA.");
} else {
log.debug("Processing an internal CA, as an external.");
}
} else {
String msg = intres.getLocalizedMessage("caadmin.errorcaexists", cainfo.getName());
log.info(msg);
throw new CAExistsException(msg);
}
}
// get signing CA
if (cainfo.getSignedBy() > CAInfo.SPECIALCAIDBORDER || cainfo.getSignedBy() < 0) {
try {
CAData signcadata = CAData.findByIdOrThrow(entityManager, Integer.valueOf(cainfo.getSignedBy()));
CA signca = signcadata.getCA();
try {
// Check that the signer is valid
checkSignerValidity(admin, signcadata);
// Get public key from request
PublicKey publickey = requestmessage.getRequestPublicKey();
// Create cacertificate
Certificate cacertificate = null;
String subjectAltName = null;
if (cainfo instanceof X509CAInfo) {
subjectAltName = ((X509CAInfo) cainfo).getSubjectAltName();
}
UserDataVO cadata = new UserDataVO("nobody", cainfo.getSubjectDN(), cainfo.getSubjectDN().hashCode(), subjectAltName, null, 0, 0, 0, cainfo
.getCertificateProfileId(), null, null, 0, 0, null);
// We can pass the PKCS10 request message as extra
// parameters
if (requestmessage instanceof PKCS10RequestMessage) {
ExtendedInformation extInfo = new ExtendedInformation();
PKCS10CertificationRequest pkcs10 = ((PKCS10RequestMessage) requestmessage).getCertificationRequest();
extInfo.setCustomData(ExtendedInformation.CUSTOM_PKCS10, new String(Base64.encode(pkcs10.getEncoded())));
cadata.setExtendedinformation(extInfo);
}
CertificateProfile certprofile = certificateProfileSession.getCertificateProfile(admin, cainfo.getCertificateProfileId());
String sequence = null;
byte[] ki = requestmessage.getRequestKeyInfo();
if ((ki != null) && (ki.length > 0)) {
sequence = new String(ki);
}
cacertificate = signca.generateCertificate(cadata, publickey, -1, cainfo.getValidity(), certprofile, sequence);
// X509ResponseMessage works for both X509 CAs and CVC CAs
// here...pure luck? I don't think so!
returnval = new X509ResponseMessage();
returnval.setCertificate(cacertificate);
// Build Certificate Chain
Collection<Certificate> rootcachain = signca.getCertificateChain();
certchain = new ArrayList<Certificate>();
certchain.add(cacertificate);