/*************************************************************************
* *
* EJBCA: The OpenSource Certificate Authority *
* *
* This software is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or any later version. *
* *
* See terms of license at gnu.org. *
* *
*************************************************************************/
package org.ejbca.core.protocol.ws;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Resource;
import javax.ejb.CreateException;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jws.WebService;
import javax.persistence.PersistenceException;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.ws.WebServiceContext;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.netscape.NetscapeCertRequest;
import org.cesecore.core.ejb.ca.crl.CrlCreateSessionLocal;
import org.cesecore.core.ejb.ca.store.CertificateProfileSessionLocal;
import org.cesecore.core.ejb.log.LogSessionLocal;
import org.cesecore.core.ejb.ra.raadmin.EndEntityProfileSessionLocal;
import org.ejbca.config.GlobalConfiguration;
import org.ejbca.config.WebServiceConfiguration;
import org.ejbca.core.EjbcaException;
import org.ejbca.core.ErrorCode;
import org.ejbca.core.ejb.ServiceLocatorException;
import org.ejbca.core.ejb.approval.ApprovalSessionLocal;
import org.ejbca.core.ejb.authorization.AuthorizationSessionLocal;
import org.ejbca.core.ejb.ca.auth.AuthenticationSessionLocal;
import org.ejbca.core.ejb.ca.caadmin.CAAdminSessionLocal;
import org.ejbca.core.ejb.ca.caadmin.CaSessionLocal;
import org.ejbca.core.ejb.ca.publisher.PublisherQueueSessionLocal;
import org.ejbca.core.ejb.ca.publisher.PublisherSessionLocal;
import org.ejbca.core.ejb.ca.sign.SignSessionLocal;
import org.ejbca.core.ejb.ca.store.CertificateStatus;
import org.ejbca.core.ejb.ca.store.CertificateStoreSessionLocal;
import org.ejbca.core.ejb.config.GlobalConfigurationSessionLocal;
import org.ejbca.core.ejb.hardtoken.HardTokenSessionLocal;
import org.ejbca.core.ejb.keyrecovery.KeyRecoverySessionLocal;
import org.ejbca.core.ejb.ra.CertificateRequestSessionLocal;
import org.ejbca.core.ejb.ra.UserAdminSessionLocal;
import org.ejbca.core.ejb.ra.userdatasource.UserDataSourceSessionLocal;
import org.ejbca.core.model.InternalResources;
import org.ejbca.core.model.SecConst;
import org.ejbca.core.model.approval.ApprovalDataVO;
import org.ejbca.core.model.approval.ApprovalException;
import org.ejbca.core.model.approval.ApprovalRequest;
import org.ejbca.core.model.approval.ApprovalRequestExecutionException;
import org.ejbca.core.model.approval.ApprovalRequestExpiredException;
import org.ejbca.core.model.approval.ApprovedActionAdmin;
import org.ejbca.core.model.approval.WaitingForApprovalException;
import org.ejbca.core.model.approval.approvalrequests.GenerateTokenApprovalRequest;
import org.ejbca.core.model.approval.approvalrequests.ViewHardTokenDataApprovalRequest;
import org.ejbca.core.model.authorization.AccessRulesConstants;
import org.ejbca.core.model.authorization.AuthorizationDeniedException;
import org.ejbca.core.model.authorization.Authorizer;
import org.ejbca.core.model.ca.AuthLoginException;
import org.ejbca.core.model.ca.AuthStatusException;
import org.ejbca.core.model.ca.IllegalKeyException;
import org.ejbca.core.model.ca.SignRequestException;
import org.ejbca.core.model.ca.SignRequestSignatureException;
import org.ejbca.core.model.ca.caadmin.CA;
import org.ejbca.core.model.ca.caadmin.CADoesntExistsException;
import org.ejbca.core.model.ca.caadmin.CAInfo;
import org.ejbca.core.model.ca.catoken.CATokenAuthenticationFailedException;
import org.ejbca.core.model.ca.catoken.CATokenOfflineException;
import org.ejbca.core.model.ca.certificateprofiles.CertificateProfile;
import org.ejbca.core.model.ca.crl.RevokedCertInfo;
import org.ejbca.core.model.ca.publisher.PublisherException;
import org.ejbca.core.model.ca.store.CertReqHistory;
import org.ejbca.core.model.ca.store.CertificateInfo;
import org.ejbca.core.model.hardtoken.HardTokenConstants;
import org.ejbca.core.model.hardtoken.HardTokenData;
import org.ejbca.core.model.hardtoken.HardTokenDoesntExistsException;
import org.ejbca.core.model.hardtoken.HardTokenExistsException;
import org.ejbca.core.model.hardtoken.types.EnhancedEIDHardToken;
import org.ejbca.core.model.hardtoken.types.HardToken;
import org.ejbca.core.model.hardtoken.types.SwedishEIDHardToken;
import org.ejbca.core.model.log.Admin;
import org.ejbca.core.model.log.LogConstants;
import org.ejbca.core.model.ra.AlreadyRevokedException;
import org.ejbca.core.model.ra.NotFoundException;
import org.ejbca.core.model.ra.UserDataConstants;
import org.ejbca.core.model.ra.UserDataVO;
import org.ejbca.core.model.ra.raadmin.EndEntityProfile;
import org.ejbca.core.model.ra.raadmin.UserDoesntFullfillEndEntityProfile;
import org.ejbca.core.model.ra.userdatasource.MultipleMatchException;
import org.ejbca.core.model.ra.userdatasource.UserDataSourceException;
import org.ejbca.core.model.ra.userdatasource.UserDataSourceVO;
import org.ejbca.core.model.util.GenerateToken;
import org.ejbca.core.protocol.CVCRequestMessage;
import org.ejbca.core.protocol.IRequestMessage;
import org.ejbca.core.protocol.IResponseMessage;
import org.ejbca.core.protocol.PKCS10RequestMessage;
import org.ejbca.core.protocol.SimpleRequestMessage;
import org.ejbca.core.protocol.ws.common.CertificateHelper;
import org.ejbca.core.protocol.ws.common.IEjbcaWS;
import org.ejbca.core.protocol.ws.logger.TransactionLogger;
import org.ejbca.core.protocol.ws.logger.TransactionTags;
import org.ejbca.core.protocol.ws.objects.Certificate;
import org.ejbca.core.protocol.ws.objects.CertificateResponse;
import org.ejbca.core.protocol.ws.objects.HardTokenDataWS;
import org.ejbca.core.protocol.ws.objects.KeyStore;
import org.ejbca.core.protocol.ws.objects.NameAndId;
import org.ejbca.core.protocol.ws.objects.PinDataWS;
import org.ejbca.core.protocol.ws.objects.RevokeStatus;
import org.ejbca.core.protocol.ws.objects.TokenCertificateRequestWS;
import org.ejbca.core.protocol.ws.objects.TokenCertificateResponseWS;
import org.ejbca.core.protocol.ws.objects.UserDataSourceVOWS;
import org.ejbca.core.protocol.ws.objects.UserDataVOWS;
import org.ejbca.core.protocol.ws.objects.UserMatch;
import org.ejbca.cvc.AlgorithmUtil;
import org.ejbca.cvc.CAReferenceField;
import org.ejbca.cvc.CVCAuthenticatedRequest;
import org.ejbca.cvc.CVCObject;
import org.ejbca.cvc.CVCPublicKey;
import org.ejbca.cvc.CVCertificate;
import org.ejbca.cvc.CardVerifiableCertificate;
import org.ejbca.cvc.CertificateParser;
import org.ejbca.cvc.HolderReferenceField;
import org.ejbca.cvc.PublicKeyEC;
import org.ejbca.cvc.exception.ConstructionException;
import org.ejbca.cvc.exception.ParseException;
import org.ejbca.util.Base64;
import org.ejbca.util.CertTools;
import org.ejbca.util.IPatternLogger;
import org.ejbca.util.RequestMessageUtils;
import org.ejbca.util.keystore.KeyTools;
import org.ejbca.util.passgen.AllPrintableCharPasswordGenerator;
import org.ejbca.util.passgen.IPasswordGenerator;
import org.ejbca.util.passgen.PasswordGeneratorFactory;
import org.ejbca.util.query.IllegalQueryException;
import org.ejbca.util.query.Query;
import com.novosec.pkix.asn1.crmf.CertRequest;
/**
* Implementor of the IEjbcaWS interface.
* Keep this class free of other helper methods, and implement them in the helper classes instead.
*
* @author Philip Vendil
* @version $Id: EjbcaWS.java 12065 2011-05-23 08:24:31Z anatom $
*/
@Stateless
@WebService(name="EjbcaWS", serviceName="EjbcaWSService", targetNamespace="http://ws.protocol.core.ejbca.org/", portName="EjbcaWSPort") //portName="EjbcaWSPort" default
public class EjbcaWS implements IEjbcaWS {
@Resource
private WebServiceContext wsContext;
@EJB
private ApprovalSessionLocal approvalSession;
@EJB
private AuthenticationSessionLocal authenticationSession;
@EJB
private AuthorizationSessionLocal authorizationSession;
@EJB
private CAAdminSessionLocal caAdminSession;
@EJB
private CaSessionLocal caSession;
@EJB
private CertificateRequestSessionLocal certificateRequestSession;
@EJB
private CertificateStoreSessionLocal certificateStoreSession;
@EJB
private CertificateProfileSessionLocal certificateProfileSession;
@EJB
private CrlCreateSessionLocal crlStoreSession;
@EJB
private EndEntityProfileSessionLocal endEntityProfileSession;
@EJB
private HardTokenSessionLocal hardTokenSession;
@EJB
private KeyRecoverySessionLocal keyRecoverySession;
@EJB
private LogSessionLocal logSession;
@EJB
private PublisherQueueSessionLocal publisherQueueSession;
@EJB
private PublisherSessionLocal publisherSession;
@EJB
private GlobalConfigurationSessionLocal globalConfigurationSession;
@EJB
private SignSessionLocal signSession;
@EJB
private UserAdminSessionLocal userAdminSession;
@EJB
private UserDataSourceSessionLocal userDataSourceSession;
/** The maximum number of rows returned in array responses. */
private static final int MAXNUMBEROFROWS = 100;
private static final int REQTYPE_PKCS10 = 1;
private static final int REQTYPE_CRMF = 2;
private static final int REQTYPE_SPKAC = 3;
private static final int REQTYPE_CVC = 4;
private static final Logger log = Logger.getLogger(EjbcaWS.class);
/** Internal localization of logs and errors */
private static final InternalResources intres = InternalResources.getInstance();
private void logAdminName(Admin admin, IPatternLogger logger) {
final X509Certificate cert = (X509Certificate)admin.getAdminInformation().getX509Certificate();
logger.paramPut(TransactionTags.ADMIN_DN.toString(), cert.getSubjectDN().toString());
logger.paramPut(TransactionTags.ADMIN_ISSUER_DN.toString(), cert.getIssuerDN().toString());
}
/**
* @throws IllegalQueryException
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#editUser(org.ejbca.core.protocol.ws.objects.UserDataVOWS)
*/
public void editUser(final UserDataVOWS userdata)
throws CADoesntExistsException, AuthorizationDeniedException, UserDoesntFullfillEndEntityProfile, EjbcaException, ApprovalException, WaitingForApprovalException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
final UserDataVO userdatavo = ejbhelper.convertUserDataVOWS(admin, userdata);
if (userAdminSession.existsUser(admin, userdatavo.getUsername())) {
if (log.isDebugEnabled()) {
log.debug("User " + userdata.getUsername() + " exists, update the userdata. New status of user '"+userdata.getStatus()+"'." );
}
userAdminSession.changeUser(admin,userdatavo,userdata.isClearPwd(), true);
} else {
if (log.isDebugEnabled()) {
log.debug("New User " + userdata.getUsername() + ", adding userdata. New status of user '"+userdata.getStatus()+"'." );
}
userAdminSession.addUserFromWS(admin,userdatavo,userdata.isClearPwd());
}
} catch (UserDoesntFullfillEndEntityProfile e) {
log.debug(e.toString());
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), e.toString());
throw e;
} catch (AuthorizationDeniedException e) {
final String errorMessage = "AuthorizationDeniedException when editing user "+userdata.getUsername()+": "+e.getMessage();
log.info(errorMessage);
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), errorMessage);
throw e;
} catch (PersistenceException e) {
// The most likely reason is that the user already existed.
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_ALREADY_EXISTS, Level.INFO);
} catch (RuntimeException e) { // ClassCastException, EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#findUser(org.ejbca.core.protocol.ws.objects.UserMatch)
*/
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public List<UserDataVOWS> findUser(UserMatch usermatch) throws AuthorizationDeniedException, IllegalQueryException, EjbcaException {
List<UserDataVOWS> retval = null;
if (log.isDebugEnabled()) {
log.debug("Find user with match '"+usermatch.getMatchvalue()+"'.");
}
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
final Query query = ejbhelper.convertUserMatch(admin, usermatch);
final Collection<UserDataVO> result = userAdminSession.query(admin, query, null,null, MAXNUMBEROFROWS); // also checks authorization
if (result.size() > 0) {
retval = new ArrayList<UserDataVOWS>(result.size());
for (final UserDataVO userdata : result) {
retval.add(ejbhelper.convertUserDataVO(admin,userdata));
}
}
} catch(AuthorizationDeniedException e) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), e.toString());
throw e;
} catch (RuntimeException e) { // ClassCastException, EJBException ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#findCerts(java.lang.String, boolean)
*/
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public List<Certificate> findCerts(String username, boolean onlyValid) throws AuthorizationDeniedException, EjbcaException {
if (log.isDebugEnabled()) {
log.debug("Find certs for user '"+username+"'.");
}
final IPatternLogger logger = TransactionLogger.getPatternLogger();
List<Certificate> retval = new ArrayList<Certificate>(0);
try{
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
if (userAdminSession.findUser(admin,username) != null) { // checks authorization on CA and profiles and view_end_entity
Collection<java.security.cert.Certificate> certs;
if (onlyValid) {
certs = certificateStoreSession.findCertificatesByUsernameAndStatus(admin, username, SecConst.CERT_ACTIVE);
} else {
certs = certificateStoreSession.findCertificatesByUsername(admin, username);
}
retval = ejbhelper.returnAuthorizedCertificates(admin, certs, onlyValid);
} else {
if (log.isDebugEnabled()) {
log.debug(intres.getLocalizedMessage("ra.errorentitynotexist", username));
}
}
} catch (RuntimeException e) { // EJBException ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getLastCertChain(java.lang.String)
*/
public List<Certificate> getLastCertChain(String username) throws AuthorizationDeniedException, EjbcaException {
if (log.isTraceEnabled()) {
log.trace(">getLastCertChain: "+username);
}
final List<Certificate> retval = new ArrayList<Certificate>();
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
if (userAdminSession.findUser(admin, username) != null) { // checks authorization on CA and profiles and view_end_entity
Collection<java.security.cert.Certificate> certs = certificateStoreSession.findCertificatesByUsername(admin,username);
if (certs.size() > 0) {
// The latest certificate will be first
java.security.cert.Certificate lastcert = certs.iterator().next();
if (lastcert != null) {
log.debug("Found certificate for user with subjectDN: "+CertTools.getSubjectDN(lastcert)+" and serialNo: "+CertTools.getSerialNumberAsString(lastcert));
retval.add(new Certificate(lastcert));
// If we added a certificate, we will also append the CA certificate chain
boolean selfSigned = false;
int bar = 0; // to control so we don't enter an infinite loop. Max chain length is 10
while ( (!selfSigned) && (bar < 10) ) {
bar++;
String issuerDN = CertTools.getIssuerDN(lastcert);
Collection<java.security.cert.Certificate> cacerts = certificateStoreSession.findCertificatesBySubject(admin, issuerDN);
if ( (cacerts == null) || (cacerts.size() == 0) ) {
log.info("No certificate found for CA with subjectDN: "+issuerDN);
break;
}
Iterator<java.security.cert.Certificate> iter = cacerts.iterator();
while (iter.hasNext()) {
java.security.cert.Certificate cert = (java.security.cert.Certificate)iter.next();
try {
lastcert.verify(cert.getPublicKey());
// this was the right certificate
retval.add(new Certificate(cert));
// To determine if we have found the last certificate or not
selfSigned = CertTools.isSelfSigned(cert);
// Find the next certificate in the chain now
lastcert = cert;
break; // Break of iteration over this CAs certs
} catch (Exception e) {
log.debug("Failed verification when looking for CA certificate, this was not the correct CA certificate. IssuerDN: "+issuerDN+", serno: "+CertTools.getSerialNumberAsString(cert));
}
}
}
} else {
log.debug("Found no certificate (in non null list??) for user "+username);
}
} else {
log.debug("Found no certificate for user "+username);
}
} else {
String msg = intres.getLocalizedMessage("ra.errorentitynotexist", username);
log.debug(msg);
}
} catch (CertificateEncodingException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
if (log.isTraceEnabled()) {
log.trace("<getLastCertChain: "+username);
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#crmfRequest(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public CertificateResponse crmfRequest(String username, String password,
String crmf, String hardTokenSN, String responseType)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
return new CertificateResponse(responseType, processCertReq(username, password,
crmf, REQTYPE_CRMF, hardTokenSN, responseType, logger));
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (RuntimeException e) { // ClassCastException, EJBException ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#spkacRequest(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public CertificateResponse spkacRequest(String username, String password,
String spkac, String hardTokenSN, String responseType)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
return new CertificateResponse(responseType, processCertReq(username, password,
spkac, REQTYPE_SPKAC, hardTokenSN, responseType, logger));
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (RuntimeException e) { // EJBException ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/** Method called from cvcRequest that simply verifies a CVCertificate with a public key and throws AuthorizationDeniedException
* if verification works. Used to check if a request is sent containing the same public key.
* this could be replaced by enforcing unique public key on the CA (from EJBCA 3.10) actually...
*
* @param pk
* @param innerreq
* @param holderref
* @throws AuthorizationDeniedException
*/
private void checkInnerCollision(PublicKey pk, CVCertificate innerreq, String holderref) throws AuthorizationDeniedException {
// Check to see that the inner signature does not verify using an old certificate (public key)
// because that means the same keys were used, and that is not allowed according to the EU policy
CardVerifiableCertificate innercert = new CardVerifiableCertificate(innerreq);
try {
innercert.verify(pk);
String msg = intres.getLocalizedMessage("cvc.error.renewsamekeys", holderref);
log.info(msg);
throw new AuthorizationDeniedException(msg);
} catch (SignatureException e) {
// It was good if the verification failed
} catch (NoSuchProviderException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderref, e.getMessage());
log.warn(msg, e);
throw new AuthorizationDeniedException(msg);
} catch (InvalidKeyException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderref, e.getMessage());
log.warn(msg, e);
throw new AuthorizationDeniedException(msg);
} catch (NoSuchAlgorithmException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderref, e.getMessage());
log.info(msg, e);
throw new AuthorizationDeniedException(msg);
} catch (CertificateException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderref, e.getMessage());
log.warn(msg, e);
throw new AuthorizationDeniedException(msg);
}
}
/** Method that gets the public key from a CV certificate, possibly enriching it with domain parameters from the CVCA certificate if it is an EC public key.
* @param ejbhelper
* @param admin
* @param cert
* @return
* @throws CADoesntExistsException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InvalidKeySpecException
*/
private PublicKey getCVPublicKey(Admin admin, java.security.cert.Certificate cert) throws CADoesntExistsException {
PublicKey pk = cert.getPublicKey();
if (pk instanceof PublicKeyEC) {
// The public key of IS and DV certificate do not have any EC parameters so we have to do some magic to get a complete EC public key
// First get to the CVCA certificate that has the parameters
CAInfo info = caAdminSession.getCAInfoOrThrowException(admin, CertTools.getIssuerDN(cert).hashCode());
Collection<java.security.cert.Certificate> cacerts = info.getCertificateChain();
if (cacerts != null) {
log.debug("Found CA certificate chain of length: "+cacerts.size());
// Get the last cert in the chain, it is the CVCA cert
Iterator<java.security.cert.Certificate> i = cacerts.iterator();
java.security.cert.Certificate cvcacert = null;
while (i.hasNext()) {
cvcacert = i.next();
}
if (cvcacert != null) {
// Do the magic adding of parameters, if they don't exist in the pk
try {
pk = KeyTools.getECPublicKeyWithParams(pk, cvcacert.getPublicKey());
} catch (InvalidKeySpecException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", CertTools.getSubjectDN(cert), e.getMessage());
log.warn(msg, e);
} catch (NoSuchProviderException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", CertTools.getSubjectDN(cert), e.getMessage());
log.warn(msg, e);
} catch (NoSuchAlgorithmException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", CertTools.getSubjectDN(cert), e.getMessage());
log.info(msg, e);
}
}
}
}
return pk;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#cvcRequest
*/
public List<Certificate> cvcRequest(String username, String password, String cvcreq)
throws CADoesntExistsException, AuthorizationDeniedException, UserDoesntFullfillEndEntityProfile, NotFoundException,
EjbcaException, ApprovalException, WaitingForApprovalException, SignRequestException, CertificateExpiredException {
log.trace(">cvcRequest");
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
// If password is empty we can generate a big random one to use instead
if (StringUtils.isEmpty(password)) {
AllPrintableCharPasswordGenerator gen = new AllPrintableCharPasswordGenerator();
password = gen.getNewPassword(15, 20);
log.debug("Using a long random password");
}
// get and old status that we can remember so we can reset status if this fails in the last step
int olduserStatus = UserDataConstants.STATUS_GENERATED;
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
UserDataVO user = userAdminSession.findUser(admin, username);
// See if this user already exists.
// We allow renewal of certificates for IS's that are not revoked
// In that case look for it's last old certificate and try to authenticate the request using an outer signature.
// If this verification is correct, set status to NEW and continue process the request.
if (user != null) {
olduserStatus = user.getStatus();
// If user is revoked, we can not proceed
if ( (olduserStatus == UserDataConstants.STATUS_REVOKED) || (olduserStatus == UserDataConstants.STATUS_HISTORICAL) ) {
throw new AuthorizationDeniedException("User '"+username+"' is revoked.");
}
CVCObject parsedObject = CertificateParser.parseCVCObject(Base64.decode(cvcreq.getBytes()));
if (parsedObject instanceof CVCAuthenticatedRequest) {
log.debug("Received an authenticated request, could be an initial DV request signed by CVCA or a renewal for DV or IS.");
CVCAuthenticatedRequest authreq = (CVCAuthenticatedRequest)parsedObject;
CVCPublicKey cvcKey = authreq.getRequest().getCertificateBody().getPublicKey();
String algorithm = AlgorithmUtil.getAlgorithmName(cvcKey.getObjectIdentifier());
log.debug("Received request has a public key with algorithm: "+algorithm);
HolderReferenceField holderRef = authreq.getRequest().getCertificateBody().getHolderReference();
CAReferenceField caRef = authreq.getAuthorityReference();
// Check to see that the inner signature does not also verify using an old certificate
// because that means the same keys were used, and that is not allowed according to the EU policy
// This must be done whether it is signed by CVCA or a renewal request
Collection<java.security.cert.Certificate> oldcerts = certificateStoreSession.findCertificatesByUsername(admin, username);
if (oldcerts != null) {
log.debug("Found "+oldcerts.size()+" old certificates for user "+username);
Iterator<java.security.cert.Certificate> iterator = oldcerts.iterator();
while (iterator.hasNext()) {
java.security.cert.Certificate cert = iterator.next();
PublicKey pk = getCVPublicKey(admin, cert);
CVCertificate innerreq = authreq.getRequest();
checkInnerCollision(pk, innerreq, holderRef.getConcatenated()); // Throws AuthorizationDeniedException
}
}
boolean verifiedOuter = false; // So we can throw an error if we could not verify
if (StringUtils.equals(holderRef.getMnemonic(), caRef.getMnemonic()) && StringUtils.equals(holderRef.getCountry(), caRef.getCountry())) {
log.debug("Authenticated request is self signed, we will try to verify it using user's old certificate.");
Collection<java.security.cert.Certificate> certs = certificateStoreSession.findCertificatesByUsername(admin, username);
// certs contains certificates ordered with last expire date first. Last expire date should be last issued cert
// We have to iterate over available user certificates, because we don't know which on signed the old one
// and cv certificates have very coarse grained validity periods so we can't really know which one is the latest one
// if 2 certificates are issued the same day.
if (certs != null) {
log.debug("Found "+certs.size()+" old certificates for user "+username);
Iterator<java.security.cert.Certificate> iterator = certs.iterator();
while (iterator.hasNext()) {
java.security.cert.Certificate cert = iterator.next();
try {
// Only allow renewal if the old certificate is valid
PublicKey pk = getCVPublicKey(admin, cert);
if (log.isDebugEnabled()) {
log.debug("Trying to verify the outer signature with an old certificate, fp: "+CertTools.getFingerprintAsString(cert));
}
authreq.verify(pk);
log.debug("Verified outer signature");
// Yes we did it, we can move on to the next step because the outer signature was actually created with some old certificate
verifiedOuter = true;
if (ejbhelper.checkValidityAndSetUserPassword(admin, cert, username, password)) {
// If we managed to verify the certificate we will break out of the loop
break;
}
// If verification of outer signature fails because the signature is invalid we will break and deny the request...with a message
} catch (InvalidKeyException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (CertificateExpiredException e) { // thrown by checkValidityAndSetUserPassword
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
// Only log this with DEBUG since it will be a common case that happens, nothing that should cause any alerts
log.debug(msg);
// This exception we want to throw on, because we want to give this error if there was a certificate suitable for
// verification, but it had expired. This is thrown by checkValidityAndSetUserPassword after the request has already been
// verified using the public key of the certificate.
throw e;
} catch (CertificateException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (NoSuchAlgorithmException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.info(msg, e);
} catch (NoSuchProviderException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (SignatureException e) {
// Failing to verify the outer signature will be normal, since we must try all old certificates
if (log.isDebugEnabled()) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.debug(msg);
}
}
} // while (iterator.hasNext()) {
// if verification failed because the old cert was not yet valid, continue processing as usual, using the sent in username/password hoping the
// status is NEW and password is correct. If old certificate was expired a CertificateExpiredException is thrown above.
} // if (certs != null) {
// If there are no old certificate, continue processing as usual, using the sent in username/password hoping the
// status is NEW and password is correct.
} else { // if (StringUtils.equals(holderRef, caRef))
// Subject and issuerDN is CN=Mnemonic,C=Country
String dn = "CN="+caRef.getMnemonic()+",C="+caRef.getCountry();
log.debug("Authenticated request is not self signed, we will try to verify it using a CVCA certificate: "+dn);
CAInfo info = caAdminSession.getCAInfoOrThrowException(admin, CertTools.stringToBCDNString(dn).hashCode());
if (info != null) {
Collection<java.security.cert.Certificate> certs = info.getCertificateChain();
if (certs != null) {
log.debug("Found "+certs.size()+" certificates in chain for CA with DN: "+dn);
Iterator<java.security.cert.Certificate> iterator = certs.iterator();
if (iterator.hasNext()) {
// The CA certificate is first in chain
java.security.cert.Certificate cert = iterator.next();
if (log.isDebugEnabled()) {
log.debug("Trying to verify the outer signature with a CVCA certificate, fp: "+CertTools.getFingerprintAsString(cert));
}
try {
// The CVCA certificate always contains the full key parameters, no need to du any EC curve parameter magic here
authreq.verify(cert.getPublicKey());
log.debug("Verified outer signature");
verifiedOuter = true;
// Yes we did it, we can move on to the next step because the outer signature was actually created with some old certificate
if (!ejbhelper.checkValidityAndSetUserPassword(admin, cert, username, password)) {
// If the CA certificate was not valid, we are not happy
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), "CA certificate not valid for CA: "+info.getCAId());
log.info(msg);
throw new AuthorizationDeniedException(msg);
}
} catch (InvalidKeyException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (CertificateException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (NoSuchAlgorithmException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (NoSuchProviderException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
} catch (SignatureException e) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), e.getMessage());
log.warn(msg, e);
}
}
} else {
log.info("No CA certificate found to authenticate request: "+dn);
}
} else {
log.info("No CA found to authenticate request: "+dn);
}
}
// if verification failed because we could not verify the outer signature at all it is an error
if (!verifiedOuter) {
String msg = intres.getLocalizedMessage("cvc.error.outersignature", holderRef.getConcatenated(), "No certificate found that could authenticate request");
log.info(msg);
throw new AuthorizationDeniedException(msg);
}
} // if (parsedObject instanceof CVCAuthenticatedRequest)
// If it is not an authenticated request, with an outer signature, continue processing as usual,
// using the sent in username/password hoping the status is NEW and password is correct.
} else {
// If there are no old user, continue processing as usual... it will fail
log.debug("No existing user with username: "+username);
}
// Finally generate the certificate (assuming status is NEW and password is correct
byte[] response = processCertReq(username, password, cvcreq, REQTYPE_CVC, null, CertificateHelper.RESPONSETYPE_CERTIFICATE, logger);
CertificateResponse ret = new CertificateResponse(CertificateHelper.RESPONSETYPE_CERTIFICATE, response);
byte[] b64cert = ret.getData();
CVCertificate certObject = CertificateParser.parseCertificate(Base64.decode(b64cert));
java.security.cert.Certificate iscert = new CardVerifiableCertificate(certObject);
ArrayList<Certificate> retval = new ArrayList<Certificate>();
retval.add(new Certificate((java.security.cert.Certificate)iscert));
// Get the certificate chain
if (user != null) {
int caid = user.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
Collection<java.security.cert.Certificate> certs = signSession.getCertificateChain(admin, caid);
Iterator<java.security.cert.Certificate> iter = certs.iterator();
while (iter.hasNext()) {
java.security.cert.Certificate cert = iter.next();
retval.add(new Certificate(cert));
}
}
log.trace("<cvcRequest");
return retval;
} catch (EjbcaException e) {
// Have this first, if processReq throws an EjbcaException we want to reset status
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw e;
} catch (ServiceLocatorException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (FinderException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (ParseException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (ConstructionException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (NoSuchFieldException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CertificateEncodingException e) {
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ...
ejbhelper.resetUserPasswordAndStatus(admin, username, olduserStatus);
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
} // cvcRequest
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#caRenewCertRequest
*/
public byte[] caRenewCertRequest(String caname, List<byte[]> cachain, boolean regenerateKeys, boolean usenextkey, boolean activatekey, String keystorepwd) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException, ApprovalException, WaitingForApprovalException {
if (log.isTraceEnabled()) {
log.trace(">caRenewCertRequest");
}
log.debug("Create certificate request for CA "+caname+", regeneratekeys="+regenerateKeys+", usenextkey="+usenextkey+", activatekey="+activatekey+", keystorepwd: "+(keystorepwd==null?"null":"hidden"));
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
byte[] ret = null;
try {
ret = ejbhelper.caRenewCertRequest(ejbhelper, admin, caname, cachain, regenerateKeys, usenextkey, activatekey, keystorepwd);
} catch (CertPathValidatorException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CERT_PATH_INVALID, Level.DEBUG);
} catch (CATokenOfflineException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_OFFLINE, Level.INFO);
} catch (CATokenAuthenticationFailedException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_INVALID_TOKEN_PIN, Level.INFO);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, null);
}
if (log.isTraceEnabled()) {
log.trace("<caRenewCertRequest");
}
return ret;
} // caRenewCertRequest
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#caCertResponse
*/
public void caCertResponse(String caname, byte[] cert, List<byte[]> cachain, String keystorepwd) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException, ApprovalException, WaitingForApprovalException {
log.trace(">caCertResponse");
log.info("Import certificate response for CA "+caname+", keystorepwd: "+(keystorepwd==null?"null":"hidden"));
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
try {
ejbhelper.caCertResponse(ejbhelper, admin, caname, cert, cachain, keystorepwd);
} catch (CertPathValidatorException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CERT_PATH_INVALID, Level.DEBUG);
} catch (CATokenOfflineException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_OFFLINE, Level.INFO);
} catch (CATokenAuthenticationFailedException e) {
throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_INVALID_TOKEN_PIN, Level.INFO);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, null);
}
log.trace("<caCertResponse");
} // caCertResponse
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#pkcs10Request(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public CertificateResponse pkcs10Request(String username, String password, String pkcs10, String hardTokenSN, String responseType)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
if (log.isDebugEnabled()) {
log.debug("PKCS10 from user '"+username+"'.");
}
return new CertificateResponse(responseType, processCertReq(username, password,
pkcs10, REQTYPE_PKCS10, hardTokenSN, responseType, logger));
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
private byte[] processCertReq(final String username, final String password, final String req, final int reqType,
final String hardTokenSN, final String responseType, final IPatternLogger logger) throws EjbcaException, AuthorizationDeniedException {
byte[] retval = null;
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
// check authorization to CAID
final UserDataVO userdata = userAdminSession.findUser(admin, username);
if (userdata == null) {
throw new NotFoundException(intres.getLocalizedMessage("ra.errorentitynotexist", username));
}
final int caid = userdata.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX +caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX +caid, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE, null);
}
// Check tokentype
if (userdata.getTokenType() != SecConst.TOKEN_SOFT_BROWSERGEN) {
throw EjbcaWSHelper.getEjbcaException("Error: Wrong Token Type of user, must be 'USERGENERATED' for PKCS10/SPKAC/CRMF/CVC requests",
logger, ErrorCode.BAD_USER_TOKEN_TYPE, null);
}
IRequestMessage imsg = null;
if (reqType == REQTYPE_PKCS10) {
final IRequestMessage pkcs10req = RequestMessageUtils.genPKCS10RequestMessage(req.getBytes());
final PublicKey pubKey = pkcs10req.getRequestPublicKey();
imsg = new SimpleRequestMessage(pubKey, username, password);
} else if (reqType == REQTYPE_SPKAC) {
// parts copied from request helper.
byte[] reqBytes = req.getBytes();
if (reqBytes != null) {
log.debug("Received NS request: "+new String(reqBytes));
byte[] buffer = Base64.decode(reqBytes);
if (buffer == null) {
return null;
}
ASN1InputStream in = new ASN1InputStream(new ByteArrayInputStream(buffer));
ASN1Sequence spkacSeq = (ASN1Sequence) in.readObject();
in.close();
NetscapeCertRequest nscr = new NetscapeCertRequest(spkacSeq);
// Verify POPO, we don't care about the challenge, it's not important.
nscr.setChallenge("challenge");
if (nscr.verify("challenge") == false) {
log.debug("SPKAC POPO verification Failed");
throw new SignRequestSignatureException("Invalid signature in NetscapeCertRequest, popo-verification failed.");
}
log.debug("POPO verification successful");
PublicKey pubKey = nscr.getPublicKey();
imsg = new SimpleRequestMessage(pubKey, username, password);
}
} else if (reqType == REQTYPE_CRMF) {
byte[] request = Base64.decode(req.getBytes());
ASN1InputStream in = new ASN1InputStream(request);
ASN1Sequence crmfSeq = (ASN1Sequence) in.readObject();
ASN1Sequence reqSeq = (ASN1Sequence) ((ASN1Sequence) crmfSeq.getObjectAt(0)).getObjectAt(0);
CertRequest certReq = new CertRequest( reqSeq );
SubjectPublicKeyInfo pKeyInfo = certReq.getCertTemplate().getPublicKey();
KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC");
KeySpec keySpec = new X509EncodedKeySpec( pKeyInfo.getEncoded() );
PublicKey pubKey = keyFact.generatePublic(keySpec); // just check it's ok
imsg = new SimpleRequestMessage(pubKey, username, password);
// a simple crmf is not a complete PKI message, as desired by the CrmfRequestMessage class
//PKIMessage msg = PKIMessage.getInstance(new ASN1InputStream(new ByteArrayInputStream(request)).readObject());
//CrmfRequestMessage reqmsg = new CrmfRequestMessage(msg, null, true, null);
//imsg = reqmsg;
} else if (reqType == REQTYPE_CVC) {
CVCObject parsedObject = CertificateParser.parseCVCObject(Base64.decode(req.getBytes()));
// We will handle both the case if the request is an authenticated request, i.e. with an outer signature
// and when the request is missing the (optional) outer signature.
CVCertificate cvccert = null;
if (parsedObject instanceof CVCAuthenticatedRequest) {
CVCAuthenticatedRequest cvcreq = (CVCAuthenticatedRequest)parsedObject;
cvccert = cvcreq.getRequest();
} else {
cvccert = (CVCertificate)parsedObject;
}
CVCRequestMessage reqmsg = new CVCRequestMessage(cvccert.getDEREncoded());
reqmsg.setUsername(username);
reqmsg.setPassword(password);
// Popo is really actually verified by the CA (in RSASignSessionBean) as well
if (reqmsg.verify() == false) {
log.debug("CVC POPO verification Failed");
throw new SignRequestSignatureException("Invalid inner signature in CVCRequest, popo-verification failed.");
} else {
log.debug("POPO verification successful");
}
imsg = reqmsg;
}
if (imsg != null) {
retval = getCertResponseFromPublicKey(admin, imsg, hardTokenSN, responseType);
}
} catch (AuthorizationDeniedException ade) {
throw ade;
} catch (InvalidKeyException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY, Level.ERROR);
} catch (IllegalKeyException e) {
// Don't log a bad error for this (user's key length too small)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.ILLEGAL_KEY, Level.DEBUG);
} catch (AuthStatusException e) {
// Don't log a bad error for this (user wrong status)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_WRONG_STATUS, Level.DEBUG);
} catch (AuthLoginException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.LOGIN_ERROR, Level.ERROR);
} catch (SignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.SIGNATURE_ERROR, Level.ERROR);
} catch (SignRequestSignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e.getMessage(), logger, null, Level.ERROR);
} catch (InvalidKeySpecException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY_SPEC, Level.ERROR);
} catch (NoSuchAlgorithmException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (NoSuchProviderException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CertificateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (IOException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (ParseException e) {
// CVC error
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (ConstructionException e) {
// CVC error
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (NoSuchFieldException e) {
// CVC error
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
}
return retval;
}
private byte[] getCertResponseFromPublicKey(final Admin admin, final IRequestMessage msg,
final String hardTokenSN, final String responseType) throws EjbcaException, CertificateEncodingException, CertificateException, IOException {
byte[] retval = null;
final IResponseMessage resp = signSession.createCertificate(admin, msg, org.ejbca.core.protocol.X509ResponseMessage.class, null);
final java.security.cert.Certificate cert = CertTools.getCertfromByteArray(resp.getResponseMessage());
if (responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_CERTIFICATE)) {
retval = cert.getEncoded();
} else if(responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7)) {
retval = signSession.createPKCS7(admin, cert, false);
} else if(responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7WITHCHAIN)) {
retval = signSession.createPKCS7(admin, cert, true);
}
if(hardTokenSN != null){
hardTokenSession.addHardTokenCertificateMapping(admin,hardTokenSN,cert);
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#pkcs12Req(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public KeyStore pkcs12Req(String username, String password, String hardTokenSN, String keyspec, String keyalg)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
// check CAID
UserDataVO userdata = userAdminSession.findUser(admin,username);
if(userdata == null){
String msg = intres.getLocalizedMessage("ra.errorentitynotexist", username);
throw new NotFoundException(msg);
}
int caid = userdata.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.CAPREFIX +caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX +caid, null);
}
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE, null);
}
// Check tokentype
if(userdata.getTokenType() != SecConst.TOKEN_SOFT_P12){
throw EjbcaWSHelper.getEjbcaException("Error: Wrong Token Type of user, must be 'P12' for PKCS12 requests", logger, ErrorCode.BAD_USER_TOKEN_TYPE, null);
}
boolean usekeyrecovery = globalConfigurationSession.getCachedGlobalConfiguration(admin).getEnableKeyRecovery();
log.debug("usekeyrecovery: "+usekeyrecovery);
boolean savekeys = userdata.getKeyRecoverable() && usekeyrecovery && (userdata.getStatus() != UserDataConstants.STATUS_KEYRECOVERY);
log.debug("userdata.getKeyRecoverable(): "+userdata.getKeyRecoverable());
log.debug("userdata.getStatus(): "+userdata.getStatus());
log.debug("savekeys: "+savekeys);
boolean loadkeys = (userdata.getStatus() == UserDataConstants.STATUS_KEYRECOVERY) && usekeyrecovery;
log.debug("loadkeys: "+loadkeys);
int endEntityProfileId = userdata.getEndEntityProfileId();
EndEntityProfile endEntityProfile = endEntityProfileSession.getEndEntityProfile(admin, endEntityProfileId);
boolean reusecertificate = endEntityProfile.getReUseKeyRecoveredCertificate();
log.debug("reusecertificate: "+reusecertificate);
try {
GenerateToken tgen = new GenerateToken(authenticationSession, userAdminSession, caAdminSession, keyRecoverySession, signSession);
java.security.KeyStore pkcs12 = tgen.generateOrKeyRecoverToken(admin, username, password, caid, keyspec, keyalg, false, loadkeys, savekeys, reusecertificate, endEntityProfileId);
final KeyStore retval = new KeyStore(pkcs12, password);
final Enumeration<String> en = pkcs12.aliases();
final String alias = en.nextElement();
final X509Certificate cert = (X509Certificate) pkcs12.getCertificate(alias);
if ( (hardTokenSN != null) && (cert != null) ) {
hardTokenSession.addHardTokenCertificateMapping(admin,hardTokenSN,cert);
}
return retval;
} catch (AuthLoginException e) {
throw e;
} catch (AuthStatusException e) {
throw e;
} catch (Exception e) {
throw EjbcaWSHelper.getInternalException(e, logger);
}
}catch(AuthorizationDeniedException ade){
throw ade;
} catch (ClassCastException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (EJBException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (AuthStatusException e) {
// Don't log a bad error for this (user wrong status)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_WRONG_STATUS, Level.DEBUG);
} catch (AuthLoginException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.LOGIN_ERROR, Level.ERROR);
} catch (IllegalKeyException e) {
// Don't log a bad error for this (user's key length too small)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.ILLEGAL_KEY, Level.DEBUG);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#revokeCert(java.lang.String, java.lang.String, int)
*/
public void revokeCert(final String issuerDN, final String certificateSN, final int reason) throws CADoesntExistsException, AuthorizationDeniedException,
NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException, AlreadyRevokedException {
if (log.isDebugEnabled()) {
log.debug("Revoke cert with serial number '"+certificateSN+"' from issuer '"+issuerDN+"' with reason '"+reason+"'.");
}
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
final int caid = CertTools.stringToBCDNString(issuerDN).hashCode();
caAdminSession.verifyExistenceOfCA(caid);
final BigInteger serno = new BigInteger(certificateSN, 16);
// Revoke or unrevoke, will throw appropriate exceptions if parameters are wrong, such as trying to unrevoke a certificate
// that was permanently revoked
userAdminSession.revokeCert(admin, serno, issuerDN, reason);
} catch (AuthorizationDeniedException e) {
throw e;
} catch (FinderException e) {
throw new NotFoundException(e.getMessage());
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#revokeUser(java.lang.String, int, boolean)
*/
public void revokeUser(String username, int reason, boolean deleteUser)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, AlreadyRevokedException, EjbcaException, ApprovalException, WaitingForApprovalException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
// check username
UserDataVO userdata = userAdminSession.findUser(admin,username);
if(userdata == null){
String msg = intres.getLocalizedMessage("ra.errorentitynotexist", username);
throw new NotFoundException(msg);
}
// Check caid
int caid = userdata.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX +caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX +caid, null);
}
if (deleteUser) {
userAdminSession.revokeAndDeleteUser(admin,username,reason);
} else {
userAdminSession.revokeUser(admin,username,reason);
}
}catch(AuthorizationDeniedException e){
throw e;
} catch (FinderException e) {
throw new NotFoundException(e.getMessage());
} catch (RemoveException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#keyRecoverNewest(java.lang.String)
*/
public void keyRecoverNewest(String username) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException {
log.trace(">keyRecoverNewest");
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
boolean usekeyrecovery = globalConfigurationSession.getCachedGlobalConfiguration(admin).getEnableKeyRecovery();
if(!usekeyrecovery){
throw EjbcaWSHelper.getEjbcaException("Keyrecovery have to be enabled in the system configuration in order to use this command.",
logger, ErrorCode.KEY_RECOVERY_NOT_AVAILABLE, null);
}
UserDataVO userdata = userAdminSession.findUser(admin, username);
if(userdata == null){
String msg = intres.getLocalizedMessage("ra.errorentitynotexist", username);
throw new NotFoundException(msg);
}
if(keyRecoverySession.isUserMarked(admin, username)){
// User is already marked for recovery.
return;
}
// check CAID
int caid = userdata.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX + caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX + caid, null);
}
// Do the work, mark user for key recovery
userAdminSession.prepareForKeyRecovery(admin, userdata.getUsername(), userdata.getEndEntityProfileId(), null);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
log.trace("<keyRecoverNewest");
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#revokeToken(java.lang.String, int)
*/
public void revokeToken(String hardTokenSN, int reason)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, AlreadyRevokedException, EjbcaException, ApprovalException, WaitingForApprovalException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
revokeToken(ejbhelper.getAdmin(), hardTokenSN, reason, logger);
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
private void revokeToken(Admin admin, String hardTokenSN, int reason, IPatternLogger logger) throws CADoesntExistsException, AuthorizationDeniedException,
NotFoundException, EjbcaException, AlreadyRevokedException, ApprovalException, WaitingForApprovalException {
ApprovalException lastApprovalException = null;
WaitingForApprovalException lastWaitingForApprovalException = null;
AuthorizationDeniedException lastAuthorizationDeniedException = null;
AlreadyRevokedException lastAlreadyRevokedException = null;
boolean success = false;
try{
logAdminName(admin,logger);
Collection<java.security.cert.Certificate> certs = hardTokenSession.findCertificatesInHardToken(admin,hardTokenSN);
Iterator<java.security.cert.Certificate> iter = certs.iterator();
while(iter.hasNext()){
X509Certificate next = (X509Certificate) iter.next();
// check that admin is authorized to CA
int caid = CertTools.getIssuerDN(next).hashCode();
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX +caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX +caid, null);
}
try {
// Revoke or unrevoke, will throw appropriate exceptions if parameters are wrong, such as trying to unrevoke a certificate
// that was permanently revoked
userAdminSession.revokeCert(admin,CertTools.getSerialNumber(next),CertTools.getIssuerDN(next),reason);
success = true;
} catch (WaitingForApprovalException e) {
lastWaitingForApprovalException = e;
} catch (ApprovalException e) {
lastApprovalException = e;
} catch(AuthorizationDeniedException e) {
lastAuthorizationDeniedException = e;
} catch (AlreadyRevokedException e) {
lastAlreadyRevokedException = e;
}
}
if (lastWaitingForApprovalException != null ) {
throw lastWaitingForApprovalException;
}
if (lastApprovalException != null) {
throw lastApprovalException;
}
if (!success && lastAuthorizationDeniedException != null) {
throw lastAuthorizationDeniedException;
}
if (!success && lastAlreadyRevokedException != null) {
throw lastAlreadyRevokedException;
}
}catch(AuthorizationDeniedException e){
throw e;
} catch (AlreadyRevokedException e) {
throw EjbcaWSHelper.getEjbcaException(e.getMessage(), logger, ErrorCode.CERT_WRONG_STATUS, null);
} catch (FinderException e) {
throw new NotFoundException(e.getMessage());
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#checkRevokationStatus(java.lang.String, java.lang.String)
*/
public RevokeStatus checkRevokationStatus(String issuerDN, String certificateSN) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
// check that admin is autorized to CA
int caid = CertTools.stringToBCDNString(issuerDN).hashCode();
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX +caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX +caid, null);
}
CertificateStatus certinfo = certificateStoreSession.getStatus(issuerDN, new BigInteger(certificateSN,16));
if(certinfo != null){
return new RevokeStatus(certinfo, issuerDN, certificateSN);
}
return null;
}catch(AuthorizationDeniedException ade){
throw ade;
} catch (DatatypeConfigurationException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#isAuthorized(java.lang.String)
*/
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public boolean isAuthorized(String resource) throws EjbcaException{
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
return authorizationSession.isAuthorized(admin, resource);
} catch (AuthorizationDeniedException ade) {
return false;
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#fetchUserData(java.util.List, java.lang.String)
*/
public List<UserDataSourceVOWS> fetchUserData(List<String> userDataSourceNames, String searchString) throws UserDataSourceException, EjbcaException, AuthorizationDeniedException{
final Admin admin;
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
if(WebServiceConfiguration.getNoAuthorizationOnFetchUserData()){
final Admin tmp = ejbhelper.getAdmin(true);
admin = new ApprovedActionAdmin(tmp.getAdminInformation().getX509Certificate(), tmp.getUsername(), tmp.getEmail());
}else{
admin = ejbhelper.getAdmin();
}
final ArrayList<UserDataSourceVOWS> retval = new ArrayList<UserDataSourceVOWS>();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
final ArrayList<Integer> userDataSourceIds = new ArrayList<Integer>();
{
final Iterator<String> iter = userDataSourceNames.iterator();
while(iter.hasNext()){
final String name = iter.next();
final int id = userDataSourceSession.getUserDataSourceId(admin, name);
if(id != 0){
userDataSourceIds.add(Integer.valueOf(id));
}else{
log.error("Error User Data Source with name : " + name + " doesn't exist.");
}
}
}
{
final Iterator<UserDataSourceVO> iter = userDataSourceSession.fetch(admin, userDataSourceIds, searchString).iterator();
while(iter.hasNext()){
UserDataSourceVO next = iter.next();
retval.add(new UserDataSourceVOWS(ejbhelper.convertUserDataVO(admin, next.getUserDataVO()),next.getIsFieldModifyableSet()));
}
}
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#genTokenCertificates(org.ejbca.core.protocol.ws.objects.UserDataVOWS, java.util.List, org.ejbca.core.protocol.ws.objects.HardTokenDataWS)
*/
public List<TokenCertificateResponseWS> genTokenCertificates(UserDataVOWS userDataWS, List<TokenCertificateRequestWS> tokenRequests, HardTokenDataWS hardTokenDataWS, boolean overwriteExistingSN, boolean revokePreviousCards)
throws CADoesntExistsException, AuthorizationDeniedException, WaitingForApprovalException, HardTokenExistsException,UserDoesntFullfillEndEntityProfile, ApprovalException, EjbcaException, ApprovalRequestExpiredException, ApprovalRequestExecutionException {
final ArrayList<TokenCertificateResponseWS> retval = new ArrayList<TokenCertificateResponseWS>();
final Admin intAdmin = Admin.getInternalAdmin();
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin(true);
int endEntityProfileId = 0;
boolean hardTokenExists = false;
boolean userExists = false;
ApprovalRequest ar = null;
boolean approvalSuccessfullStep1 = false;
boolean isRejectedStep1 = false;
// Get Significant user Id
final CAInfo significantcAInfo;
final ArrayList<java.security.cert.Certificate> genCertificates = new ArrayList<java.security.cert.Certificate>();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
significantcAInfo = caAdminSession.getCAInfoOrThrowException(intAdmin, userDataWS.getCaName());
if(significantcAInfo == null){
throw EjbcaWSHelper.getEjbcaException("Error the given CA : " + userDataWS.getCaName() + " couldn't be found.",
logger, ErrorCode.CA_NOT_EXISTS, null);
}
UserDataVO userDataVO = userAdminSession.findUser(intAdmin, userDataWS.getUsername());
if(userDataVO != null){
endEntityProfileId = userDataVO.getEndEntityProfileId();
userExists = true;
}else{
endEntityProfileId = endEntityProfileSession.getEndEntityProfileId(intAdmin, userDataWS.getEndEntityProfileName());
if(endEntityProfileId == 0){
throw EjbcaWSHelper.getEjbcaException("Error given end entity profile : " + userDataWS.getEndEntityProfileName() +" couldn't be found",
logger, ErrorCode.EE_PROFILE_NOT_EXISTS, null);
}
}
if(ejbhelper.isAdmin()){
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_CREATECERTIFICATE, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.HARDTOKEN_ISSUEHARDTOKENS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.HARDTOKEN_ISSUEHARDTOKENS, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX + significantcAInfo.getCAId())) {
throw new AuthorizationDeniedException("Admin " + admin + " was not authorized to resource " + AccessRulesConstants.CAPREFIX
+ significantcAInfo.getCAId());
}
if (userExists) {
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_EDITENDENTITY)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_EDITENDENTITY, null);
}
endEntityProfileId = userDataVO.getEndEntityProfileId();
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.EDIT_RIGHTS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.EDIT_RIGHTS, null);
}
if (overwriteExistingSN) {
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_REVOKEENDENTITY)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_REVOKEENDENTITY, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.REVOKE_RIGHTS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.REVOKE_RIGHTS, null);
}
}
} else {
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_CREATEENDENTITY)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_CREATEENDENTITY, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.CREATE_RIGHTS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.CREATE_RIGHTS, null);
}
if (overwriteExistingSN) {
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_REVOKEENDENTITY)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_REVOKEENDENTITY, null);
}
if (!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.REVOKE_RIGHTS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId
+ AccessRulesConstants.REVOKE_RIGHTS, null);
}
}
}
}else{
if(WebServiceConfiguration.getApprovalForGenTokenCertificates()){
ar = new GenerateTokenApprovalRequest(userDataWS.getUsername(), userDataWS.getSubjectDN(), hardTokenDataWS.getLabel(),admin,null,WebServiceConfiguration.getNumberOfRequiredApprovals(),significantcAInfo.getCAId(),endEntityProfileId);
int status = ApprovalDataVO.STATUS_REJECTED;
try{
status = approvalSession.isApproved(admin, ar.generateApprovalId(), 1);
approvalSuccessfullStep1 = status == ApprovalDataVO.STATUS_APPROVED;
if(approvalSuccessfullStep1){
ApprovalDataVO approvalDataVO = approvalSession.findNonExpiredApprovalRequest(intAdmin, ar.generateApprovalId());
String originalDN = ((GenerateTokenApprovalRequest) approvalDataVO.getApprovalRequest()).getDN();
userDataWS.setSubjectDN(originalDN); // replace requested DN with original DN to make sure nothing have changed.
}
isRejectedStep1 = status == ApprovalDataVO.STATUS_REJECTED;
if( status == ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED
|| status == ApprovalDataVO.STATUS_EXPIRED){
throw new ApprovalException("");
}
}catch(ApprovalException e){
approvalSession.addApprovalRequest(admin, ar, globalConfigurationSession.getCachedGlobalConfiguration(admin));
throw new WaitingForApprovalException("Approval request with id " + ar.generateApprovalId() + " have been added for approval.",ar.generateApprovalId());
}
}else{
throw new AuthorizationDeniedException();
}
}
if(ar != null && isRejectedStep1){
throw new ApprovalRequestExecutionException("The approval for id " + ar.generateApprovalId() + " have been rejected.");
}
if(ar != null && !approvalSuccessfullStep1){
throw new WaitingForApprovalException("The approval for id " + ar.generateApprovalId() + " have not yet been approved", ar.generateApprovalId());
}
if(ar != null){
admin = new ApprovedActionAdmin(admin.getAdminInformation().getX509Certificate(), admin.getUsername(), admin.getEmail());
}
hardTokenExists = hardTokenSession.existsHardToken(admin, hardTokenDataWS.getHardTokenSN());
if(hardTokenExists){
if(overwriteExistingSN){
// fetch all old certificates and revoke them.
Collection<java.security.cert.Certificate> currentCertificates = hardTokenSession.findCertificatesInHardToken(admin, hardTokenDataWS.getHardTokenSN());
HardTokenData currentHardToken = hardTokenSession.getHardToken(admin, hardTokenDataWS.getHardTokenSN(), false);
Iterator<java.security.cert.Certificate> iter = currentCertificates.iterator();
while(iter.hasNext()){
java.security.cert.X509Certificate nextCert = (java.security.cert.X509Certificate) iter.next();
try {
userAdminSession.revokeCert(admin, CertTools.getSerialNumber(nextCert), CertTools.getIssuerDN(nextCert), RevokedCertInfo.REVOCATION_REASON_SUPERSEDED);
} catch (AlreadyRevokedException e) {
// Ignore previously revoked certificates
} catch (FinderException e) {
throw EjbcaWSHelper.getEjbcaException("Error revoking old certificate, the user : " + currentHardToken.getUsername() + " of the old certificate couldn't be found in database.",
logger, ErrorCode.USER_NOT_FOUND, null);
}
}
}else{
throw new HardTokenExistsException("Error hard token with sn " + hardTokenDataWS.getHardTokenSN() + " already exists.");
}
}
if(revokePreviousCards){
List<HardTokenDataWS> htd = getHardTokenDatas(admin,userDataWS.getUsername(), false, true, logger);
Iterator<HardTokenDataWS> htdIter = htd.iterator();
while(htdIter.hasNext()) {
HardTokenDataWS toRevoke = htdIter.next();
try{
if(hardTokenDataWS.getLabel().equals(HardTokenConstants.LABEL_TEMPORARYCARD) && toRevoke.getLabel() != null && !toRevoke.getLabel().equals(HardTokenConstants.LABEL_TEMPORARYCARD)){
// Token have extended key usage MS Logon, don't revoke it
Iterator<java.security.cert.Certificate> revokeCerts = hardTokenSession.findCertificatesInHardToken(admin, toRevoke.getHardTokenSN()).iterator();
while(revokeCerts.hasNext()){
X509Certificate next = (X509Certificate) revokeCerts.next();
try{
if(WebServiceConfiguration.getSuspendAllCertificates() || next.getExtendedKeyUsage() == null || !next.getExtendedKeyUsage().contains(KeyPurposeId.id_kp_smartcardlogon.getId())){
userAdminSession.revokeCert(admin,next.getSerialNumber(), CertTools.getIssuerDN(next), RevokedCertInfo.REVOCATION_REASON_CERTIFICATEHOLD);
}
}catch(CertificateParsingException e){
log.error(e);
} catch (FinderException e) {
log.error(e);
}
}
}else{
revokeToken(admin, toRevoke.getHardTokenSN(), RevokedCertInfo.REVOCATION_REASON_UNSPECIFIED, logger);
}
}catch(AlreadyRevokedException e){
// Do nothing
}
}
}
try{
// Check if the userdata exist and edit/add it depending on which
String password = PasswordGeneratorFactory.getInstance(PasswordGeneratorFactory.PASSWORDTYPE_ALLPRINTABLE).getNewPassword(8, 8);
UserDataVO userData = ejbhelper.convertUserDataVOWS(admin, userDataWS);
userData.setPassword(password);
if(userExists){
userAdminSession.changeUser(admin, userData, true);
}else{
userAdminSession.addUser(admin, userData, true);
}
Date bDate = new Date(System.currentTimeMillis() - (10 * 60 * 1000));
Iterator<TokenCertificateRequestWS> iter = tokenRequests.iterator();
while(iter.hasNext()){
TokenCertificateRequestWS next = iter.next();
int certificateProfileId = certificateProfileSession.getCertificateProfileId(admin, next.getCertificateProfileName());
if(certificateProfileId == 0){
EjbcaWSHelper.getEjbcaException("Error the given Certificate Profile : " + next.getCertificateProfileName() + " couldn't be found.",
logger, ErrorCode.CERT_PROFILE_NOT_EXISTS, null);
}
Date eDate = null;
if(next.getValidityIdDays() != null ){
try{
long validity = Long.parseLong(next.getValidityIdDays());
eDate = new Date(System.currentTimeMillis() + (validity * 3600 *24 * 1000));
}catch (NumberFormatException e){
EjbcaWSHelper.getEjbcaException("Error : Validity in Days must be a number",
logger, ErrorCode.BAD_VALIDITY_FORMAT, null);
}
}
CAInfo cAInfo = caAdminSession.getCAInfo(admin, next.getCAName());
if(cAInfo == null){
throw EjbcaWSHelper.getEjbcaException("Error the given CA : " + next.getCAName() + " couldn't be found.",
logger, ErrorCode.CA_NOT_EXISTS, null);
}
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX + cAInfo.getCAId())) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX + cAInfo.getCAId(), null);
}
if(next.getType() == HardTokenConstants.REQUESTTYPE_PKCS10_REQUEST){
userData.setCertificateProfileId(certificateProfileId);
userData.setCAId(cAInfo.getCAId());
userData.setPassword(password);
userData.setStatus(UserDataConstants.STATUS_NEW);
userAdminSession.changeUser(admin, userData, false);
PKCS10RequestMessage pkcs10req = new PKCS10RequestMessage(next.getPkcs10Data());
java.security.cert.Certificate cert;
if(eDate == null){
cert = signSession.createCertificate(admin,userData.getUsername(),password, pkcs10req.getRequestPublicKey());
}else{
cert = signSession.createCertificate(admin,userData.getUsername(),password, pkcs10req.getRequestPublicKey(), -1, bDate, eDate);
}
genCertificates.add(cert);
retval.add(new TokenCertificateResponseWS(new Certificate(cert)));
}else
if(next.getType() == HardTokenConstants.REQUESTTYPE_KEYSTORE_REQUEST){
if(!next.getTokenType().equals(HardTokenConstants.TOKENTYPE_PKCS12)){
throw EjbcaWSHelper.getEjbcaException("Unsupported Key Store Type : " + next.getTokenType() + " only " + HardTokenConstants.TOKENTYPE_PKCS12 + " is supported",
logger, ErrorCode.NOT_SUPPORTED_KEY_STORE, null);
}
KeyPair keys = KeyTools.genKeys(next.getKeyspec(), next.getKeyalg());
userData.setCertificateProfileId(certificateProfileId);
userData.setCAId(cAInfo.getCAId());
userData.setPassword(password);
userData.setStatus(UserDataConstants.STATUS_NEW);
userAdminSession.changeUser(admin, userData, true);
X509Certificate cert;
if(eDate == null){
cert = (X509Certificate) signSession.createCertificate(admin,userData.getUsername(),password, keys.getPublic());
}else{
cert = (X509Certificate) signSession.createCertificate(admin,userData.getUsername(),password, keys.getPublic(), -1, bDate, eDate);
}
genCertificates.add(cert);
// Generate Keystore
// Fetch CA Cert Chain.
Collection<java.security.cert.Certificate> chain = caAdminSession.getCAInfo(admin, cAInfo.getCAId()).getCertificateChain();
String alias = CertTools.getPartFromDN(CertTools.getSubjectDN(cert), "CN");
if (alias == null){
alias = userData.getUsername();
}
java.security.KeyStore pkcs12 = KeyTools.createP12(alias, keys.getPrivate(), cert, chain);
retval.add(new TokenCertificateResponseWS(new KeyStore(pkcs12, userDataWS.getPassword())));
}else{
throw EjbcaWSHelper.getEjbcaException("Error in request, only REQUESTTYPE_PKCS10_REQUEST and REQUESTTYPE_KEYSTORE_REQUEST are supported token requests.",
logger, ErrorCode.NOT_SUPPORTED_REQUEST_TYPE, null);
}
}
} catch(Exception e){
throw EjbcaWSHelper.getInternalException(e, logger);
} finally{
userAdminSession.setUserStatus(admin, userDataWS.getUsername(), UserDataConstants.STATUS_GENERATED);
}
// Add hard token data
HardToken hardToken;
String signatureInitialPIN = "";
String signaturePUK = "";
String basicInitialPIN = "";
String basicPUK = "";
Iterator<PinDataWS> iter = hardTokenDataWS.getPinDatas().iterator();
while(iter.hasNext()){
PinDataWS pinData = iter.next();
switch(pinData.getType()){
case HardTokenConstants.PINTYPE_BASIC :
basicInitialPIN = pinData.getInitialPIN();
basicPUK = pinData.getPUK();
break;
case HardTokenConstants.PINTYPE_SIGNATURE :
signatureInitialPIN = pinData.getInitialPIN();
signaturePUK = pinData.getPUK();
break;
default :
throw EjbcaWSHelper.getEjbcaException("Unsupported PIN Type " + pinData.getType(),
logger, ErrorCode.NOT_SUPPORTED_PIN_TYPE, null);
}
}
int tokenType = SwedishEIDHardToken.THIS_TOKENTYPE;
switch (hardTokenDataWS.getTokenType()){
case HardTokenConstants.TOKENTYPE_SWEDISHEID :
hardToken = new SwedishEIDHardToken(basicInitialPIN,basicPUK,signatureInitialPIN,signaturePUK,0);
break;
case HardTokenConstants.TOKENTYPE_ENHANCEDEID :
hardToken = new EnhancedEIDHardToken(signatureInitialPIN,signaturePUK,basicInitialPIN,basicPUK,false,0);
tokenType = EnhancedEIDHardToken.THIS_TOKENTYPE;
break;
default:
throw EjbcaWSHelper.getEjbcaException("Unsupported Token Type : " + hardTokenDataWS.getTokenType(),
logger, ErrorCode.NOT_SUPPORTED_TOKEN_TYPE, null);
}
hardToken.setLabel(hardTokenDataWS.getLabel());
if(overwriteExistingSN){
if(hardTokenExists){
try {
hardTokenSession.removeHardToken(admin, hardTokenDataWS.getHardTokenSN());
} catch (HardTokenDoesntExistsException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.HARD_TOKEN_NOT_EXISTS, Level.ERROR);
}
}
}
hardTokenSession.addHardToken(admin, hardTokenDataWS.getHardTokenSN(), userDataWS.getUsername(), significantcAInfo.getSubjectDN(), tokenType, hardToken, genCertificates, hardTokenDataWS.getCopyOfSN());
if(ar!= null){
approvalSession.markAsStepDone(admin, ar.generateApprovalId(), GenerateTokenApprovalRequest.STEP_1_GENERATETOKEN);
}
} catch( EjbcaException e) {
throw e;
} catch (FinderException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#existsHardToken(java.lang.String)
*/
public boolean existsHardToken(String hardTokenSN) throws EjbcaException{
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
return hardTokenSession.existsHardToken(admin, hardTokenSN);
} catch (AuthorizationDeniedException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getHardTokenData(java.lang.String)
*/
public HardTokenDataWS getHardTokenData(String hardTokenSN, boolean viewPUKData, boolean onlyValidCertificates)
throws CADoesntExistsException, AuthorizationDeniedException, HardTokenDoesntExistsException, NotFoundException, ApprovalRequestExpiredException, WaitingForApprovalException, ApprovalRequestExecutionException, EjbcaException {
HardTokenDataWS retval = null;
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin(true);
ApprovalRequest ar = null;
boolean isApprovedStep0 = false;
boolean isRejectedStep0 = false;
HardTokenData hardTokenData = null;
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
try{
hardTokenData = hardTokenSession.getHardToken(admin, hardTokenSN, viewPUKData);
if(hardTokenData == null){
throw new HardTokenDoesntExistsException("Error, hard token with SN " + hardTokenSN + " doesn't exist.");
}
ejbhelper.isAuthorizedToHardTokenData(admin, hardTokenData.getUsername(), viewPUKData);
}catch(AuthorizationDeniedException e){
boolean genNewRequest = false;
if(WebServiceConfiguration.getApprovalForHardTokenData()){
// Check Approvals
// Exists an GenTokenCertificates
Admin intAdmin = Admin.getInternalAdmin();
UserDataVO userData = userAdminSession.findUser(intAdmin, hardTokenData.getUsername());
if (userData == null) {
String msg = intres.getLocalizedMessage("ra.errorentitynotexist", hardTokenData.getUsername());
throw new NotFoundException(msg);
}
int caid = userData.getCAId();
caAdminSession.verifyExistenceOfCA(caid);
ar = new GenerateTokenApprovalRequest(userData.getUsername(), userData.getDN(), hardTokenData.getHardToken().getLabel(),admin,null,WebServiceConfiguration.getNumberOfRequiredApprovals(),caid,userData.getEndEntityProfileId());
int status = ApprovalDataVO.STATUS_REJECTED;
try{
if(!WebServiceConfiguration.getApprovalForGenTokenCertificates()){
throw new ApprovalException("");
}
status = approvalSession.isApproved(admin, ar.generateApprovalId(), 0);
isApprovedStep0 = status == ApprovalDataVO.STATUS_APPROVED;
if( status == ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED
|| status == ApprovalDataVO.STATUS_EXPIRED
|| status == ApprovalDataVO.STATUS_REJECTED){
throw new ApprovalException("");
}
}catch(ApprovalException e2){
// GenTokenCertificates approval doesn't exists, try a getHardTokenData request
if(!WebServiceConfiguration.getApprovalForHardTokenData()){
throw new AuthorizationDeniedException("JaxWS isn't configured for getHardTokenData approvals.");
}
ar = new ViewHardTokenDataApprovalRequest(userData.getUsername(), userData.getDN(), hardTokenSN, true,admin,null,WebServiceConfiguration.getNumberOfRequiredApprovals(),userData.getCAId(),userData.getEndEntityProfileId());
try{
status = approvalSession.isApproved(admin, ar.generateApprovalId());
isApprovedStep0 = status == ApprovalDataVO.STATUS_APPROVED;
isRejectedStep0 = status == ApprovalDataVO.STATUS_REJECTED;
if( status == ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED
|| status == ApprovalDataVO.STATUS_EXPIRED){
throw new ApprovalException("");
}
}catch(ApprovalException e3){
genNewRequest = true;
}catch(ApprovalRequestExpiredException e3){
genNewRequest = true;
}
if(genNewRequest){
// Add approval Request
try{
approvalSession.addApprovalRequest(admin, ar, globalConfigurationSession.getCachedGlobalConfiguration(admin));
throw new WaitingForApprovalException("Adding approval to view hard token data with id " + ar.generateApprovalId(), ar.generateApprovalId());
}catch(ApprovalException e4){
throw EjbcaWSHelper.getEjbcaException(e4, logger, ErrorCode.APPROVAL_ALREADY_EXISTS, null);
}
}
}
}else{
throw e;
}
}
if(ar != null && isRejectedStep0){
throw new ApprovalRequestExecutionException("The approval for id " + ar.generateApprovalId() + " have been rejected.");
}
if(ar != null && ! isApprovedStep0){
throw new WaitingForApprovalException("The approval for id " + ar.generateApprovalId() + " have not yet been approved", ar.generateApprovalId());
}
Collection<java.security.cert.Certificate> certs = hardTokenSession.findCertificatesInHardToken(admin, hardTokenSN);
if(onlyValidCertificates){
certs = ejbhelper.returnOnlyValidCertificates(admin, certs);
}
retval = ejbhelper.convertHardTokenToWS(hardTokenData,certs,viewPUKData);
if(ar != null){
try {
approvalSession.markAsStepDone(admin, ar.generateApprovalId(), 0);
} catch (ApprovalException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.APPROVAL_REQUEST_ID_NOT_EXIST, null);
}
}
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getHardTokenDatas(java.lang.String)
*/
public List<HardTokenDataWS> getHardTokenDatas(String username, boolean viewPUKData, boolean onlyValidCertificates)
throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
final Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
try {
return getHardTokenDatas(admin,username, viewPUKData, onlyValidCertificates, logger);
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
private List<HardTokenDataWS> getHardTokenDatas(Admin admin, String username, boolean viewPUKData, boolean onlyValidCertificates, IPatternLogger logger)
throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException {
List<HardTokenDataWS> retval = new ArrayList<HardTokenDataWS>();
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
try {
ejbhelper.isAuthorizedToHardTokenData(admin, username, viewPUKData);
Collection<HardTokenData> hardtokens = hardTokenSession.getHardTokens(admin, username, viewPUKData);
Iterator<HardTokenData> iter = hardtokens.iterator();
while(iter.hasNext()){
HardTokenData next = (HardTokenData) iter.next();
int caid = next.getSignificantIssuerDN().hashCode();
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX + caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX + caid, null);
}
Collection<java.security.cert.Certificate> certs = hardTokenSession.findCertificatesInHardToken(admin, next.getTokenSN());
if(onlyValidCertificates){
certs = ejbhelper.returnOnlyValidCertificates(admin, certs);
}
retval.add(ejbhelper.convertHardTokenToWS(next,certs, viewPUKData));
}
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#republishCertificate(java.lang.String, java.lang.String)
*/
public void republishCertificate(String serialNumberInHex,String issuerDN) throws CADoesntExistsException, AuthorizationDeniedException, PublisherException, EjbcaException{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try{
String bcIssuerDN = CertTools.stringToBCDNString(issuerDN);
caAdminSession.verifyExistenceOfCA(bcIssuerDN.hashCode());
CertReqHistory certreqhist = certificateStoreSession.getCertReqHistory(admin,new BigInteger(serialNumberInHex,16), bcIssuerDN);
if(certreqhist == null){
throw new PublisherException("Error: the certificate with serialnumber : " + serialNumberInHex +" and issuerdn " + issuerDN + " couldn't be found in database.");
}
ejbhelper.isAuthorizedToRepublish(admin, certreqhist.getUsername(),bcIssuerDN.hashCode());
if(certreqhist != null){
CertificateProfile certprofile = certificateProfileSession.getCertificateProfile(admin,certreqhist.getUserDataVO().getCertificateProfileId());
java.security.cert.Certificate cert = certificateStoreSession.findCertificateByFingerprint(admin, certreqhist.getFingerprint());
if(certprofile != null){
CertificateInfo certinfo = certificateStoreSession.getCertificateInfo(admin, certreqhist.getFingerprint());
if(certprofile.getPublisherList().size() > 0){
if(publisherSession.storeCertificate(admin, certprofile.getPublisherList(), cert, certreqhist.getUserDataVO().getUsername(), certreqhist.getUserDataVO().getPassword(), certreqhist.getUserDataVO().getDN(),
certinfo.getCAFingerprint(), certinfo.getStatus() , certinfo.getType(), certinfo.getRevocationDate().getTime(), certinfo.getRevocationReason(), certinfo.getTag(), certinfo.getCertificateProfileId(), certinfo.getUpdateTime().getTime(), certreqhist.getUserDataVO().getExtendedinformation())){
}else{
throw new PublisherException("Error: publication failed to at least one of the defined publishers.");
}
}else{
throw new PublisherException("Error no publisher defined for the given certificate.");
}
}else{
throw new PublisherException("Error : Certificate profile couldn't be found for the given certificate.");
}
}
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#customLog(int, String, String)
*/
public void customLog(int level, String type, String cAName, String username, Certificate certificate, String msg)
throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try{
// Check authorization to perform custom logging
if(!authorizationSession.isAuthorized(admin, AccessRulesConstants.REGULAR_LOG_CUSTOM_EVENTS)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_LOG_CUSTOM_EVENTS, null);
}
int event = LogConstants.EVENT_ERROR_CUSTOMLOG;
switch (level) {
case IEjbcaWS.CUSTOMLOG_LEVEL_ERROR:
break;
case IEjbcaWS.CUSTOMLOG_LEVEL_INFO:
event = LogConstants.EVENT_INFO_CUSTOMLOG;
break;
default:
throw EjbcaWSHelper.getEjbcaException("Illegal level "+ level + " sent to customLog call.", logger, ErrorCode.INVALID_LOG_LEVEL, null);
}
java.security.cert.Certificate logCert = null;
if(certificate != null){
logCert = CertificateHelper.getCertificate(certificate.getCertificateData());
}
int caId = admin.getCaId();
if(cAName != null){
CAInfo cAInfo = caAdminSession.getCAInfoOrThrowException(admin, cAName);
caId = cAInfo.getCAId();
}
String comment = type + " : " + msg;
logSession.log(admin, caId, LogConstants.MODULE_CUSTOM, new Date(), username, (X509Certificate) logCert, event, comment);
} catch (CertificateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#deleteUserDataFromSource(List, String, boolean)
*/
public boolean deleteUserDataFromSource(List<String> userDataSourceNames, String searchString, boolean removeMultipleMatch) throws AuthorizationDeniedException, MultipleMatchException, UserDataSourceException, EjbcaException {
boolean ret = false;
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
Admin admin = ejbhelper.getAdmin();
logAdminName(admin,logger);
ArrayList<Integer> userDataSourceIds = new ArrayList<Integer>();
Iterator<String> iter = userDataSourceNames.iterator();
while(iter.hasNext()){
String nextName = iter.next();
int id = userDataSourceSession.getUserDataSourceId(admin, nextName);
if(id == 0){
throw new UserDataSourceException("Error: User Data Source with name : " + nextName + " couldn't be found, aborting operation.");
}
userDataSourceIds.add(Integer.valueOf(id));
}
ret = userDataSourceSession.removeUserData(admin, userDataSourceIds, searchString, removeMultipleMatch);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return ret;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#isApproved(int)
*/
public int isApproved(int approvalId) throws ApprovalException, EjbcaException, ApprovalRequestExpiredException{
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final Admin admin = ejbhelper.getAdmin(true);
logAdminName(admin,logger);
return approvalSession.isApproved(admin, approvalId);
} catch (AuthorizationDeniedException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR);
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getCertificate(String, String)
*/
public Certificate getCertificate(String certSNinHex, String issuerDN) throws CADoesntExistsException,
AuthorizationDeniedException, EjbcaException {
Certificate retval = null;
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin(true);
String bcString = CertTools.stringToBCDNString(issuerDN);
int caid = bcString.hashCode();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
caAdminSession.verifyExistenceOfCA(caid);
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.REGULAR_VIEWCERTIFICATE)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.REGULAR_VIEWCERTIFICATE, null);
}
if(!authorizationSession.isAuthorizedNoLog(admin, AccessRulesConstants.CAPREFIX + caid)) {
Authorizer.throwAuthorizationException(admin, AccessRulesConstants.CAPREFIX + caid, null);
}
java.security.cert.Certificate cert = certificateStoreSession.findCertificateByIssuerAndSerno(admin, issuerDN, new BigInteger(certSNinHex,16));
if(cert != null){
retval = new Certificate(cert);
}
} catch (CertificateEncodingException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return retval;
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getAvailableCAs()
*/
public NameAndId[] getAvailableCAs() throws EjbcaException, AuthorizationDeniedException {
TreeMap<String,Integer> ret = new TreeMap<String,Integer>();
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin(true);
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
Collection<Integer> caids = caSession.getAvailableCAs(admin);
HashMap<Integer, String> map = caAdminSession.getCAIdToNameMap(admin);
for (Integer id : caids ) {
String name = (String)map.get(id);
if (name != null) {
ret.put(name, id);
}
}
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return ejbhelper.convertTreeMapToArray(ret);
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getAuthorizedEndEntityProfiles()
*/
public NameAndId[] getAuthorizedEndEntityProfiles()
throws AuthorizationDeniedException, EjbcaException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
TreeMap<String,Integer> ret = new TreeMap<String,Integer>();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
Collection<Integer> ids = endEntityProfileSession.getAuthorizedEndEntityProfileIds(admin);
final Map<Integer,String> idtonamemap = endEntityProfileSession.getEndEntityProfileIdToNameMap(admin);
for (final Integer id : ids) {
ret.put(idtonamemap.get(id), id);
}
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return ejbhelper.convertTreeMapToArray(ret);
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getAvailableCertificateProfiles()
*/
public NameAndId[] getAvailableCertificateProfiles(int entityProfileId) throws AuthorizationDeniedException, EjbcaException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
TreeMap<String,Integer> ret = new TreeMap<String,Integer>();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
EndEntityProfile profile = endEntityProfileSession.getEndEntityProfile(admin, entityProfileId);
if (profile != null) {
String value = profile.getValue(EndEntityProfile.AVAILCERTPROFILES,0);
if (value != null) {
String[] availablecertprofilesId = value.split(EndEntityProfile.SPLITCHAR);
for (String id : availablecertprofilesId) {
int i = Integer.parseInt(id);
ret.put(certificateProfileSession.getCertificateProfileName(admin,i), i);
}
}
}
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return ejbhelper.convertTreeMapToArray(ret);
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getAvailableCAsInProfile()
*/
public NameAndId[] getAvailableCAsInProfile(int entityProfileId) throws AuthorizationDeniedException, EjbcaException {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
TreeMap<String,Integer> ret = new TreeMap<String,Integer>();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
EndEntityProfile profile = endEntityProfileSession.getEndEntityProfile(admin, entityProfileId);
if (profile != null) {
Collection<String> cas = profile.getAvailableCAs(); // list of CA ids available in profile
HashMap<Integer,String> map = caAdminSession.getCAIdToNameMap(admin);
for (String id : cas ) {
Integer i = Integer.valueOf(id);
String name = (String)map.get(i);
if (name != null) {
ret.put(name, i);
}
}
}
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
return ejbhelper.convertTreeMapToArray(ret);
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#createCRL(String)
*/
public void createCRL(String caname) throws CADoesntExistsException, ApprovalException, EjbcaException, ApprovalRequestExpiredException{
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin(true);
logAdminName(admin,logger);
CA ca = caSession.getCA(admin, caname);
crlStoreSession.run(admin, ca);
} catch (AuthorizationDeniedException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getEjbcaVersion()
*/
public String getEjbcaVersion() {
return GlobalConfiguration.EJBCA_VERSION;
}
/* (non-Javadoc)
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getPublisherQueueLength(java.lang.String)
*/
public int getPublisherQueueLength(String name) throws EjbcaException{
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbhelper.getAdmin(true);
logAdminName(admin,logger);
final int id = publisherSession.getPublisherId(admin, name);
if ( id==0 ) {
return -4;// no publisher with this name
}
return publisherQueueSession.getPendingEntriesCountForPublisher(id);
} catch (AuthorizationDeniedException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
private void setUserDataVOWS(UserDataVOWS userdata) {
userdata.setStatus(UserDataVOWS.STATUS_NEW);
if (userdata.getPassword() == null) {
final IPasswordGenerator pwdgen = PasswordGeneratorFactory.getInstance(PasswordGeneratorFactory.PASSWORDTYPE_ALLPRINTABLE);
final String pwd = pwdgen.getNewPassword(12, 12);
userdata.setPassword(pwd);
}
userdata.setClearPwd(false);
userdata.setTokenType(UserDataVOWS.TOKEN_TYPE_USERGENERATED);
}
/**
* @throws IllegalQueryException
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#certificateRequest(org.ejbca.core.protocol.ws.objects.UserDataVOWS, String, int, String, String)
*/
public CertificateResponse certificateRequest(UserDataVOWS userdata, String requestData, int requestType, String hardTokenSN, String responseType)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, UserDoesntFullfillEndEntityProfile,
ApprovalException, WaitingForApprovalException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
if (log.isDebugEnabled()) {
log.debug("CertReq for user '" + userdata.getUsername() + "'.");
}
setUserDataVOWS (userdata);
final EjbcaWSHelper ejbcawshelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbcawshelper.getAdmin(false);
logAdminName(admin,logger);
final UserDataVO userdatavo = ejbcawshelper.convertUserDataVOWS(admin, userdata);
int responseTypeInt = SecConst.CERT_RES_TYPE_CERTIFICATE;
if (!responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_CERTIFICATE)) {
if (responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7)) {
responseTypeInt = SecConst.CERT_RES_TYPE_PKCS7;
}
else if (responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7WITHCHAIN)) {
responseTypeInt = SecConst.CERT_RES_TYPE_PKCS7WITHCHAIN;
}
else{
throw new NoSuchAlgorithmException ("Bad responseType:" + responseType);
}
}
return new CertificateResponse(responseType, certificateRequestSession.processCertReq(admin, userdatavo, requestData, requestType, hardTokenSN, responseTypeInt));
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (InvalidKeyException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY, Level.ERROR);
} catch (IllegalKeyException e) {
// Don't log a bad error for this (user's key length too small)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.ILLEGAL_KEY, Level.DEBUG);
} catch (AuthStatusException e) {
// Don't log a bad error for this (user wrong status)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_WRONG_STATUS, Level.DEBUG);
} catch (AuthLoginException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.LOGIN_ERROR, Level.ERROR);
} catch (SignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.SIGNATURE_ERROR, Level.ERROR);
} catch (SignRequestSignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e.getMessage(), logger, null, Level.ERROR);
} catch (InvalidKeySpecException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY_SPEC, Level.ERROR);
} catch (NoSuchAlgorithmException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (NoSuchProviderException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CertificateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CreateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (IOException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (FinderException e) {
throw new NotFoundException(e.getMessage());
} catch (RuntimeException e) { // EJBException, ClassCastException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @throws IllegalQueryException
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#softTokenRequest(org.ejbca.core.protocol.ws.objects.UserDataVOWS, String, String, String)
*/
public KeyStore softTokenRequest(UserDataVOWS userdata, String hardTokenSN, String keyspec, String keyalg)
throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, UserDoesntFullfillEndEntityProfile,
ApprovalException, WaitingForApprovalException, EjbcaException {
final IPatternLogger logger = TransactionLogger.getPatternLogger();
try {
log.debug("Soft token req for user '" + userdata.getUsername() + "'.");
userdata.setStatus(UserDataVOWS.STATUS_NEW);
userdata.setClearPwd(true);
final EjbcaWSHelper ejbcawshelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
final Admin admin = ejbcawshelper.getAdmin(false);
logAdminName(admin,logger);
final UserDataVO userdatavo = ejbcawshelper.convertUserDataVOWS(admin, userdata);
final boolean createJKS = userdata.getTokenType().equals(UserDataVOWS.TOKEN_TYPE_JKS);
final byte[] encodedKeyStore = certificateRequestSession.processSoftTokenReq(admin, userdatavo, hardTokenSN, keyspec, keyalg, createJKS);
// Convert encoded KeyStore to the proper return type
final java.security.KeyStore ks;
if (createJKS) {
ks = java.security.KeyStore.getInstance("JKS");
} else {
ks = java.security.KeyStore.getInstance("PKCS12", "BC");
}
ks.load(new ByteArrayInputStream(encodedKeyStore), userdata.getPassword().toCharArray());
return new KeyStore(ks, userdata.getPassword());
} catch( CADoesntExistsException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( AuthorizationDeniedException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch( NotFoundException t ) {
logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString());
throw t;
} catch (InvalidKeyException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY, Level.ERROR);
} catch (IllegalKeyException e) {
// Don't log a bad error for this (user's key length too small)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.ILLEGAL_KEY, Level.DEBUG);
} catch (AuthStatusException e) {
// Don't log a bad error for this (user wrong status)
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_WRONG_STATUS, Level.DEBUG);
} catch (AuthLoginException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.LOGIN_ERROR, Level.ERROR);
} catch (SignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.SIGNATURE_ERROR, Level.ERROR);
} catch (SignRequestSignatureException e) {
throw EjbcaWSHelper.getEjbcaException(e.getMessage(), logger, null, Level.ERROR);
} catch (InvalidKeySpecException e) {
throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.INVALID_KEY_SPEC, Level.ERROR);
} catch (NoSuchAlgorithmException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (NoSuchProviderException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch( KeyStoreException e ) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CertificateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (CreateException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (IOException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (FinderException e) {
throw new NotFoundException(e.getMessage());
} catch (InvalidAlgorithmParameterException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
}
/**
* @see org.ejbca.core.protocol.ws.common.IEjbcaWS#getLastCAChain(java.lang.String)
*/
public List<Certificate> getLastCAChain(String caname)
throws AuthorizationDeniedException, CADoesntExistsException, EjbcaException {
if (log.isTraceEnabled()) {
log.trace(">getLastCAChain: "+caname);
}
final List<Certificate> retval = new ArrayList<Certificate>();
EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, certificateProfileSession, certificateStoreSession, endEntityProfileSession, hardTokenSession, userAdminSession);
Admin admin = ejbhelper.getAdmin();
final IPatternLogger logger = TransactionLogger.getPatternLogger();
logAdminName(admin,logger);
try {
CAInfo info = caAdminSession.getCAInfoOrThrowException(admin, caname);
if (info.getStatus() == SecConst.CA_WAITING_CERTIFICATE_RESPONSE){
return retval;
}
Collection<java.security.cert.Certificate> certs = info.getCertificateChain();
Iterator<java.security.cert.Certificate> iter = certs.iterator();
while (iter.hasNext()){
retval.add(new Certificate (iter.next ()));
}
} catch (CertificateEncodingException e) {
throw EjbcaWSHelper.getInternalException(e, logger);
} catch (RuntimeException e) { // EJBException, ...
throw EjbcaWSHelper.getInternalException(e, logger);
} finally {
logger.writeln();
logger.flush();
}
if (log.isTraceEnabled()) {
log.trace("<getLastCAChain: "+caname);
}
return retval;
}
}