if (log.isTraceEnabled()) {
log.trace(">signRequest: usepreviouskey="+usepreviouskey+", createlinkcert="+createlinkcert);
}
byte[] ret = request;
try {
CardVerifiableCertificate cacert = (CardVerifiableCertificate)getCACertificate();
if (cacert == null) {
// if we don't have a CA certificate, we can't sign any request, just return it
return request;
}
CATokenContainer catoken = getCAToken();
// Get either the current or the previous signing key for signing this request
int key = SecConst.CAKEYPURPOSE_CERTSIGN;
if (usepreviouskey) {
log.debug("Using previous CertSign key to sign request");
key = SecConst.CAKEYPURPOSE_CERTSIGN_PREVIOUS;
} else {
log.debug("Using current CertSign key to sign request");
}
KeyPair keyPair = new KeyPair(catoken.getPublicKey(key), catoken.getPrivateKey(key));
String signAlg = getCAToken().getCATokenInfo().getSignatureAlgorithm();
// Create the CA reference, should be from signing certificates holder field
HolderReferenceField caHolder = cacert.getCVCertificate().getCertificateBody().getHolderReference();
String sequence = caHolder.getSequence();
// See if we have a previous sequence to put in the CA reference instead of the same as we have from the request
String propdata = catoken.getCATokenInfo().getProperties();
Properties prop = new Properties();
if (propdata != null) {
prop.load(new ByteArrayInputStream(propdata.getBytes()));
}
String previousSequence = (String)prop.get(ICAToken.PREVIOUS_SEQUENCE_PROPERTY);
// Only use previous sequence if we also use previous key
if ( (previousSequence != null) && (usepreviouskey) ) {
sequence = previousSequence;
log.debug("Using previous sequence in caRef: "+sequence);
} else {
log.debug("Using current sequence in caRef: "+sequence);
}
// Set the CA reference field for the authentication signature
CAReferenceField caRef = new CAReferenceField(caHolder.getCountry(), caHolder.getMnemonic(), sequence);
CVCertificate cvcert = null;
try {
byte[] binbytes = request;
try {
// We don't know if this is a PEM or binary certificate or request request so we first try to
// decode it as a PEM certificate, and if it's not we try it as a PEM request and finally as a binary request
Collection<Certificate> col = CertTools.getCertsFromPEM(new ByteArrayInputStream(request));
Certificate cert = col.iterator().next();
if (cert != null) {
binbytes = cert.getEncoded();
}
} catch (Exception e) {
log.debug("This is not a PEM certificate?: "+e.getMessage());
try {
binbytes = RequestMessageUtils.getRequestBytes(request);
} catch (Exception e2) {
log.debug("This is not a PEM request?: "+e2.getMessage());
}
}
// This can be either a CV certificate, a CV certificate request, or an authenticated request that we should re-sign
CVCObject parsedObject;
parsedObject = CertificateParser.parseCVCObject(binbytes);
if (parsedObject instanceof CVCertificate) {
cvcert = (CVCertificate) parsedObject;
log.debug("This is a reqular CV request, or cert.");
} else if (parsedObject instanceof CVCAuthenticatedRequest) {
CVCAuthenticatedRequest authreq = (CVCAuthenticatedRequest)parsedObject;
cvcert = authreq.getRequest();
log.debug("This is an authenticated CV request, we will overwrite the old authentication with a new.");
}
} catch (ParseException e) {
String msg = intres.getLocalizedMessage("cvc.error.notcvcrequest");
log.info(msg, e);
return request;
} catch (ClassCastException e) {
String msg = intres.getLocalizedMessage("cvc.error.notcvcrequest");
log.info(msg, e);
return request;
}
// Check if the input was a CVCA certificate, which is the same CVCA as this. If all is true we should create a CVCA link certificate
// instead of an authenticated request
CardVerifiableCertificate cvccert = new CardVerifiableCertificate(cvcert);
HolderReferenceField cvccertholder = cvccert.getCVCertificate().getCertificateBody().getHolderReference();
AuthorizationRoleEnum authRole = null;
AccessRightEnum rights = null;
try {
authRole = cvccert.getCVCertificate().getCertificateBody().getAuthorizationTemplate().getAuthorizationField().getRole();
rights = cvccert.getCVCertificate().getCertificateBody().getAuthorizationTemplate().getAuthorizationField().getAccessRight();
} catch (NoSuchFieldException e) {
log.debug("No AuthorizationRoleEnum or AccessRightEnum, this is not a CV certificate so we can't make a link certificate: "+e.getMessage());
}
if (createlinkcert && (authRole != null) && (rights != null)) {
log.debug("We will create a link certificate.");
String msg = intres.getLocalizedMessage("cvc.info.createlinkcert", cvccertholder.getConcatenated(), caRef.getConcatenated());
log.info(msg);
PublicKey pk = cvccert.getPublicKey();
Date validFrom = cvccert.getCVCertificate().getCertificateBody().getValidFrom();
Date validTo = cvccert.getCVCertificate().getCertificateBody().getValidTo();
// Generate a new certificate with the same contents as the passed in certificate, but with new caRef and signature
CVCertificate retcert = CertificateGenerator.createCertificate(pk, keyPair.getPrivate(), signAlg, caRef, cvccertholder, authRole, rights, validFrom, validTo, catoken.getProvider());
ret = retcert.getDEREncoded();
log.debug("Signed a CardVerifiableCertificate CardVerifiableCertificate.");
} else {