Java tutorial
/************************************************************************* * * * EJBCA Community: 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.beans.XMLEncoder; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; 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.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; 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.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; import javax.xml.bind.DatatypeConverter; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.ws.WebServiceContext; import javax.xml.ws.handler.MessageContext; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.jce.X509Principal; import org.cesecore.CesecoreException; import org.cesecore.ErrorCode; import org.cesecore.audit.enums.EventStatus; import org.cesecore.audit.enums.EventType; import org.cesecore.audit.log.SecurityEventsLoggerSessionLocal; import org.cesecore.authentication.tokens.AlwaysAllowLocalAuthenticationToken; import org.cesecore.authentication.tokens.AuthenticationToken; import org.cesecore.authentication.tokens.UsernamePrincipal; import org.cesecore.authentication.tokens.X509CertificateAuthenticationToken; import org.cesecore.authorization.AuthorizationDeniedException; import org.cesecore.authorization.control.AccessControlSessionLocal; import org.cesecore.authorization.control.AuditLogRules; import org.cesecore.authorization.control.StandardRules; import org.cesecore.certificates.ca.CAConstants; import org.cesecore.certificates.ca.CADoesntExistsException; import org.cesecore.certificates.ca.CAInfo; import org.cesecore.certificates.ca.CAOfflineException; import org.cesecore.certificates.ca.CaSessionLocal; import org.cesecore.certificates.ca.SignRequestException; import org.cesecore.certificates.ca.SignRequestSignatureException; import org.cesecore.certificates.certificate.CertificateConstants; import org.cesecore.certificates.certificate.CertificateInfo; import org.cesecore.certificates.certificate.CertificateStatus; import org.cesecore.certificates.certificate.CertificateStoreSessionLocal; import org.cesecore.certificates.certificate.IllegalKeyException; import org.cesecore.certificates.certificate.certextensions.CertificateExtensionException; import org.cesecore.certificates.certificate.request.PKCS10RequestMessage; import org.cesecore.certificates.certificate.request.RequestMessage; import org.cesecore.certificates.certificate.request.RequestMessageUtils; import org.cesecore.certificates.certificate.request.ResponseMessage; import org.cesecore.certificates.certificate.request.X509ResponseMessage; import org.cesecore.certificates.certificateprofile.CertificateProfile; import org.cesecore.certificates.certificateprofile.CertificateProfileDoesNotExistException; import org.cesecore.certificates.certificateprofile.CertificateProfileSessionLocal; import org.cesecore.certificates.crl.CrlStoreSessionLocal; import org.cesecore.certificates.crl.RevokedCertInfo; import org.cesecore.certificates.endentity.EndEntityConstants; import org.cesecore.certificates.endentity.EndEntityInformation; import org.cesecore.certificates.endentity.ExtendedInformation; import org.cesecore.configuration.GlobalConfigurationSessionLocal; import org.cesecore.internal.UpgradeableDataHashMap; import org.cesecore.keys.token.CryptoTokenAuthenticationFailedException; import org.cesecore.keys.token.CryptoTokenManagementSessionLocal; import org.cesecore.keys.token.CryptoTokenOfflineException; import org.cesecore.keys.token.p11.exception.NoSuchSlotException; import org.cesecore.keys.util.KeyTools; import org.cesecore.roles.RoleNotFoundException; import org.cesecore.util.Base64; import org.cesecore.util.CertTools; import org.ejbca.config.GlobalConfiguration; import org.ejbca.config.WebServiceConfiguration; import org.ejbca.core.EjbcaException; import org.ejbca.core.ejb.EnterpriseEditionWSBridgeSessionLocal; import org.ejbca.core.ejb.ServiceLocatorException; import org.ejbca.core.ejb.approval.ApprovalSessionLocal; import org.ejbca.core.ejb.audit.enums.EjbcaEventTypes; import org.ejbca.core.ejb.audit.enums.EjbcaModuleTypes; import org.ejbca.core.ejb.audit.enums.EjbcaServiceTypes; import org.ejbca.core.ejb.authentication.web.WebAuthenticationProviderSessionLocal; import org.ejbca.core.ejb.ca.auth.EndEntityAuthenticationSessionLocal; import org.ejbca.core.ejb.ca.caadmin.CAAdminSessionLocal; 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.CertReqHistorySessionLocal; import org.ejbca.core.ejb.crl.PublishingCrlSessionLocal; 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.EndEntityAccessSessionLocal; import org.ejbca.core.ejb.ra.EndEntityExistsException; import org.ejbca.core.ejb.ra.EndEntityManagementSessionLocal; import org.ejbca.core.ejb.ra.raadmin.EndEntityProfileSessionLocal; import org.ejbca.core.ejb.ra.userdatasource.UserDataSourceSessionLocal; import org.ejbca.core.model.InternalEjbcaResources; 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.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.ca.AuthLoginException; import org.ejbca.core.model.ca.AuthStatusException; import org.ejbca.core.model.ca.publisher.PublisherException; import org.ejbca.core.model.ca.store.CertReqHistory; import org.ejbca.core.model.hardtoken.HardTokenConstants; import org.ejbca.core.model.hardtoken.HardTokenDoesntExistsException; import org.ejbca.core.model.hardtoken.HardTokenExistsException; import org.ejbca.core.model.hardtoken.HardTokenInformation; 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.ra.AlreadyRevokedException; import org.ejbca.core.model.ra.NotFoundException; import org.ejbca.core.model.ra.RevokeBackDateNotAllowedForProfileException; import org.ejbca.core.model.ra.raadmin.EndEntityProfile; import org.ejbca.core.model.ra.raadmin.EndEntityProfileNotFoundException; 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.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.ExtendedInformationWS; 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.IPatternLogger; import org.ejbca.util.KeyValuePair; 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; /** * Implementor of the IEjbcaWS interface. * Keep this class free of other helper methods, and implement them in the helper classes instead. * * The WebService name below is important because it determines the webservice URL on JBoss 7.1. * * @version $Id: EjbcaWS.java 21005 2015-03-25 12:30:23Z aveen4711 $ */ @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 EndEntityAuthenticationSessionLocal authenticationSession; @EJB private AccessControlSessionLocal authorizationSession; @EJB private CAAdminSessionLocal caAdminSession; @EJB private CaSessionLocal caSession; @EJB private CertificateRequestSessionLocal certificateRequestSession; @EJB private CertificateStoreSessionLocal certificateStoreSession; @EJB private CrlStoreSessionLocal crlStoreSession; @EJB private CertificateProfileSessionLocal certificateProfileSession; @EJB private CertReqHistorySessionLocal certreqHistorySession; @EJB private CryptoTokenManagementSessionLocal cryptoTokenManagementSession; @EJB private EndEntityAccessSessionLocal endEntityAccessSession; @EJB private EndEntityManagementSessionLocal endEntityManagementSession; @EJB private EndEntityProfileSessionLocal endEntityProfileSession; @EJB private GlobalConfigurationSessionLocal globalConfigurationSession; @EJB private HardTokenSessionLocal hardTokenSession; @EJB private KeyRecoverySessionLocal keyRecoverySession; @EJB private SecurityEventsLoggerSessionLocal auditSession; @EJB private PublisherQueueSessionLocal publisherQueueSession; @EJB private PublisherSessionLocal publisherSession; @EJB private PublishingCrlSessionLocal publishingCrlSession; @EJB private SignSessionLocal signSession; @EJB private UserDataSourceSessionLocal userDataSourceSession; @EJB private WebAuthenticationProviderSessionLocal webAuthenticationSession; @EJB private EnterpriseEditionWSBridgeSessionLocal enterpriseWSBridgeSession; /** The maximum number of rows returned in array responses. */ private static final int MAXNUMBEROFROWS = 100; private static final Logger log = Logger.getLogger(EjbcaWS.class); /** Internal localization of logs and errors */ private static final InternalEjbcaResources intres = InternalEjbcaResources.getInstance(); private void logAdminName(final AuthenticationToken admin, final IPatternLogger logger) { // Log certificate info final X509Certificate cert = ((X509CertificateAuthenticationToken) admin).getCertificate(); logger.paramPut(TransactionTags.ADMIN_DN.toString(), cert.getSubjectDN().toString()); logger.paramPut(TransactionTags.ADMIN_ISSUER_DN.toString(), cert.getIssuerDN().toString()); // Log IP address MessageContext msgctx = wsContext.getMessageContext(); HttpServletRequest request = (HttpServletRequest) msgctx.get(MessageContext.SERVLET_REQUEST); logger.paramPut(TransactionTags.ADMIN_REMOTE_IP.toString(), request.getRemoteAddr()); String addr = request.getHeader("X-Forwarded-For"); if (addr != null) addr = addr.replaceAll("[^a-zA-Z0-9.:-_]", "?"); logger.paramPut(TransactionTags.ADMIN_FORWARDED_IP.toString(), addr); } /** * @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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); final EndEntityInformation endEntityInformation = ejbhelper.convertUserDataVOWS(admin, userdata); if (endEntityManagementSession.existsUser(endEntityInformation.getUsername())) { if (log.isDebugEnabled()) { log.debug("User " + userdata.getUsername() + " exists, update the userdata. New status of user '" + userdata.getStatus() + "'."); } endEntityManagementSession.changeUser(admin, endEntityInformation, userdata.isClearPwd(), true); } else { if (log.isDebugEnabled()) { log.debug("New User " + userdata.getUsername() + ", adding userdata. New status of user '" + userdata.getStatus() + "'."); } endEntityManagementSession.addUserFromWS(admin, endEntityInformation, 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 (EndEntityExistsException e) { 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(); } } /** * @throws EndEntityProfileNotFoundException * @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, EndEntityProfileNotFoundException { 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); final Query query = ejbhelper.convertUserMatch(admin, usermatch); final Collection<EndEntityInformation> result = endEntityManagementSession.query(admin, query, null, null, MAXNUMBEROFROWS); // also checks authorization if (result.size() > 0) { retval = new ArrayList<UserDataVOWS>(result.size()); for (final EndEntityInformation userdata : result) { retval.add(ejbhelper.convertEndEntityInformation(userdata)); } } } catch (CesecoreException e) { // Convert cesecore exception to EjbcaException EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); if (endEntityAccessSession.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(username, CertificateConstants.CERT_ACTIVE); } else { certs = certificateStoreSession.findCertificatesByUsername(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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { if (endEntityAccessSession.findUser(admin, username) != null) { // checks authorization on CA and profiles and view_end_entity Collection<java.security.cert.Certificate> certs = certificateStoreSession .findCertificatesByUsername(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(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; } @Override public void createCryptoToken(String tokenName, String tokenType, String activationPin, boolean autoActivate, List<KeyValuePair> cryptotokenProperties) throws AuthorizationDeniedException, EjbcaException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(ejbhelper.getAdmin(), logger); try { enterpriseWSBridgeSession.createCryptoToken(ejbhelper.getAdmin(), tokenName, tokenType, activationPin, autoActivate, cryptotokenProperties); } catch (AuthorizationDeniedException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR); } catch (CesecoreException e) { throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (RuntimeException e) { // ClassCastException, EJBException ... throw EjbcaWSHelper.getInternalException(e, logger); } catch (NoSuchSlotException e) { throw EjbcaWSHelper.getInternalException(e, TransactionLogger.getPatternLogger()); } finally { logger.writeln(); logger.flush(); } } @Override public void generateCryptoTokenKeys(String cryptoTokenName, String keyPairAlias, String keySpecification) throws AuthorizationDeniedException, EjbcaException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(ejbhelper.getAdmin(), logger); try { enterpriseWSBridgeSession.generateCryptoTokenKeys(ejbhelper.getAdmin(), cryptoTokenName, keyPairAlias, keySpecification); } catch (AuthorizationDeniedException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR); } catch (CesecoreException e) { throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (RuntimeException e) { // ClassCastException, EJBException ... throw EjbcaWSHelper.getInternalException(e, logger); } catch (InvalidKeyException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.INVALID_KEY, Level.INFO); } catch (InvalidAlgorithmParameterException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.INVALID_KEY_SPEC, Level.INFO); } finally { logger.writeln(); logger.flush(); } } @Override public void createCA(String caname, String cadn, String catype, long validityInDays, String certprofile, String signAlg, int signedByCAId, String cryptoTokenName, List<KeyValuePair> purposeKeyMapping, List<KeyValuePair> caProperties) throws EjbcaException, AuthorizationDeniedException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(ejbhelper.getAdmin(), logger); try { enterpriseWSBridgeSession.createCA(ejbhelper.getAdmin(), caname, cadn, catype, validityInDays, certprofile, signAlg, signedByCAId, cryptoTokenName, purposeKeyMapping, caProperties); } catch (AuthorizationDeniedException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR); } catch (CesecoreException e) { throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (RuntimeException e) { // ClassCastException, EJBException ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } } @Override public void addSubjectToRole(String roleName, String caName, String matchWith, String matchType, String matchValue) throws EjbcaException, AuthorizationDeniedException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(ejbhelper.getAdmin(), logger); try { enterpriseWSBridgeSession.addSubjectToRole(ejbhelper.getAdmin(), roleName, caName, matchWith, matchType, matchValue); } catch (AuthorizationDeniedException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR); } catch (CesecoreException e) { throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (RuntimeException e) { // ClassCastException, EJBException ... throw EjbcaWSHelper.getInternalException(e, logger); } catch (RoleNotFoundException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.ROLE_DOES_NOT_EXIST, Level.INFO); } finally { logger.writeln(); logger.flush(); } } @Override public void removeSubjectFromRole(String roleName, String caName, String matchWith, String matchType, String matchValue) throws EjbcaException, AuthorizationDeniedException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(ejbhelper.getAdmin(), logger); try { enterpriseWSBridgeSession.removeSubjectFromRole(ejbhelper.getAdmin(), roleName, caName, matchWith, matchType, matchValue); } catch (AuthorizationDeniedException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.NOT_AUTHORIZED, Level.ERROR); } catch (CesecoreException e) { throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (RuntimeException e) { // ClassCastException, EJBException ... throw EjbcaWSHelper.getInternalException(e, logger); } catch (RoleNotFoundException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.ROLE_DOES_NOT_EXIST, Level.INFO); } finally { logger.writeln(); logger.flush(); } } public List<Certificate> getCertificatesByExpirationTime(long days, int maxNumberOfResults) throws EjbcaException { Date findDate = new Date(); long millis = (days * 24 * 60 * 60 * 1000); findDate.setTime(findDate.getTime() + millis); Collection<java.security.cert.Certificate> certs = certificateStoreSession .findCertificatesByExpireTimeWithLimit(findDate, maxNumberOfResults); ArrayList<Certificate> ret = new ArrayList<Certificate>(); for (java.security.cert.Certificate cert : certs) { try { ret.add(new Certificate(cert)); } catch (CertificateEncodingException e) { throw EjbcaWSHelper.getInternalException(e, TransactionLogger.getPatternLogger()); } } return ret; } public List<Certificate> getCertificatesByExpirationTimeAndIssuer(long days, String issuer, int maxNumberOfResults) throws EjbcaException { Date findDate = new Date(); long millis = (days * 24 * 60 * 60 * 1000); findDate.setTime(findDate.getTime() + millis); Collection<java.security.cert.Certificate> certs = certificateStoreSession .findCertificatesByExpireTimeAndIssuerWithLimit(findDate, issuer, maxNumberOfResults); ArrayList<Certificate> ret = new ArrayList<Certificate>(); for (java.security.cert.Certificate cert : certs) { try { ret.add(new Certificate(cert)); } catch (CertificateEncodingException e) { throw EjbcaWSHelper.getInternalException(e, TransactionLogger.getPatternLogger()); } } return ret; } public List<Certificate> getCertificatesByExpirationTimeAndType(long days, int certificateType, int maxNumberOfResults) throws EjbcaException { Date findDate = new Date(); long millis = (days * 24 * 60 * 60 * 1000); findDate.setTime(findDate.getTime() + millis); Collection<java.security.cert.Certificate> certs = certificateStoreSession .findCertificatesByExpireTimeAndTypeWithLimit(findDate, certificateType, maxNumberOfResults); ArrayList<Certificate> ret = new ArrayList<Certificate>(); for (java.security.cert.Certificate cert : certs) { try { ret.add(new Certificate(cert)); } catch (CertificateEncodingException e) { throw EjbcaWSHelper.getInternalException(e, TransactionLogger.getPatternLogger()); } } return ret; } /** * @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, CesecoreException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { return new CertificateResponse(responseType, processCertReq(username, password, crmf, CertificateConstants.CERT_REQ_TYPE_CRMF, hardTokenSN, responseType, logger)); } 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, CesecoreException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { return new CertificateResponse(responseType, processCertReq(username, password, spkac, CertificateConstants.CERT_REQ_TYPE_SPKAC, hardTokenSN, responseType, logger)); } 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 AuthorizationDeniedException * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @throws InvalidKeySpecException */ private PublicKey getCVPublicKey(AuthenticationToken admin, java.security.cert.Certificate cert) throws CADoesntExistsException, AuthorizationDeniedException { 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 = caSession.getCAInfo(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); } } } } 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, CesecoreException, ApprovalException, WaitingForApprovalException, SignRequestException, CertificateExpiredException { log.trace(">cvcRequest"); EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken 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 = EndEntityConstants.STATUS_GENERATED; final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { EndEntityInformation user = endEntityAccessSession.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 == EndEntityConstants.STATUS_REVOKED) || (olduserStatus == EndEntityConstants.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(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(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); try { CAInfo info = caSession.getCAInfo(admin, CertTools.stringToBCDNString(dn).hashCode()); 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); } } catch (CADoesntExistsException e) { 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, CertificateConstants.CERT_REQ_TYPE_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(); caSession.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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken 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 (CryptoTokenOfflineException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_OFFLINE, Level.INFO); } catch (CryptoTokenAuthenticationFailedException 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 /** * @throws CesecoreException * @see org.ejbca.core.protocol.ws.common.IEjbcaWS#caCertResponse */ public void caCertResponse(String caname, byte[] cert, List<byte[]> cachain, String keystorepwd) throws AuthorizationDeniedException, EjbcaException, ApprovalException, WaitingForApprovalException, CesecoreException { log.trace(">caCertResponse"); log.info("Import certificate response for CA " + caname + ", keystorepwd: " + (keystorepwd == null ? "null" : "hidden")); EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken 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 (CryptoTokenOfflineException e) { throw EjbcaWSHelper.getEjbcaException(e, null, ErrorCode.CA_OFFLINE, Level.INFO); } catch (CryptoTokenAuthenticationFailedException 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(final String username, final String password, final String pkcs10, final String hardTokenSN, final String responseType) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, CesecoreException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { if (log.isDebugEnabled()) { log.debug("PKCS10 from user '" + username + "'."); } return new CertificateResponse(responseType, processCertReq(username, password, pkcs10, CertificateConstants.CERT_REQ_TYPE_PKCS10, hardTokenSN, responseType, logger)); } 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, CesecoreException, CADoesntExistsException, AuthorizationDeniedException { byte[] retval = null; try { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); // check authorization to CAID final EndEntityInformation userdata = endEntityAccessSession.findUser(admin, username); if (userdata == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", username)); String msg = intres.getLocalizedMessage("ra.wrongusernameorpassword"); throw new NotFoundException(msg); } final int caid = userdata.getCAId(); caSession.verifyExistenceOfCA(caid); // 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); } // Authorization for {StandardRules.CAACCESS.resource() +caid, StandardRules.CREATECERT.resource()} is done in the // CertificateCreateSessionBean.createCertificate call which is called in the end RequestMessage imsg = RequestMessageUtils.getSimpleRequestMessageFromType(username, password, req, reqType); if (imsg != null) { retval = getCertResponseFromPublicKey(admin, imsg, hardTokenSN, responseType); } } catch (CertificateExtensionException e) { throw EjbcaWSHelper.getInternalException(e, logger); } 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 AuthenticationToken admin, final RequestMessage msg, final String hardTokenSN, final String responseType) throws AuthorizationDeniedException, CertificateEncodingException, EjbcaException, CesecoreException, CertificateExtensionException, CertificateParsingException { byte[] retval = null; final ResponseMessage resp = signSession.createCertificate(admin, msg, 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); // check CAID EndEntityInformation userdata = endEntityAccessSession.findUser(admin, username); if (userdata == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", username)); throw new NotFoundException(intres.getLocalizedMessage("ra.wrongusernameorpassword")); } int caid = userdata.getCAId(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorized(admin, StandardRules.CAACCESS.resource() + caid, StandardRules.CREATECERT.resource())) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid + "," + StandardRules.CREATECERT.resource(), null); throw new AuthorizationDeniedException(msg); } // 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 = ((GlobalConfiguration) globalConfigurationSession .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID)).getEnableKeyRecovery(); log.debug("usekeyrecovery: " + usekeyrecovery); boolean savekeys = userdata.getKeyRecoverable() && usekeyrecovery && (userdata.getStatus() != EndEntityConstants.STATUS_KEYRECOVERY); log.debug("userdata.getKeyRecoverable(): " + userdata.getKeyRecoverable()); log.debug("userdata.getStatus(): " + userdata.getStatus()); log.debug("savekeys: " + savekeys); boolean loadkeys = (userdata.getStatus() == EndEntityConstants.STATUS_KEYRECOVERY) && usekeyrecovery; log.debug("loadkeys: " + loadkeys); int endEntityProfileId = userdata.getEndEntityProfileId(); EndEntityProfile endEntityProfile = endEntityProfileSession.getEndEntityProfile(endEntityProfileId); boolean reusecertificate = endEntityProfile.getReUseKeyRecoveredCertificate(); log.debug("reusecertificate: " + reusecertificate); try { GenerateToken tgen = new GenerateToken(authenticationSession, endEntityAccessSession, endEntityManagementSession, caSession, 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) { // NOPMD, since we catch wide below throw e; } catch (AuthStatusException e) { // NOPMD, since we catch wide below throw e; } catch (Exception e) { throw EjbcaWSHelper.getInternalException(e, logger); } } 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 (RuntimeException e) { // EJBException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } } private void revokeCert(final String issuerDN, final String certificateSN, final int reason, Date date, IPatternLogger logger) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException, AlreadyRevokedException, RevokeBackDateNotAllowedForProfileException { if (log.isDebugEnabled()) { log.debug("Revoke cert with serial number '" + certificateSN + "' from issuer '" + issuerDN + "' with reason '" + reason + "'."); } try { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); final int caid = CertTools.stringToBCDNString(issuerDN).hashCode(); caSession.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 endEntityManagementSession.revokeCert(admin, serno, date, issuerDN, reason, true); } catch (FinderException e) { throw new NotFoundException(e.getMessage()); } catch (RuntimeException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getInternalException(e, logger); } } @Override public void revokeCert(final String issuerDN, final String certificateSN, final int reason) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException, AlreadyRevokedException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { try { revokeCert(issuerDN, certificateSN, reason, (Date) null, logger); } catch (RevokeBackDateNotAllowedForProfileException e) { throw new Error("This is should not happen since there is no back dating.", e); } } finally { logger.writeln(); logger.flush(); } } @Override public void revokeCertBackdated(final String issuerDN, final String certificateSN, final int reason, String sDate) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException, AlreadyRevokedException, RevokeBackDateNotAllowedForProfileException, DateNotValidException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { if (sDate == null) { revokeCert(issuerDN, certificateSN, reason); return; } final Date date; try { date = DatatypeConverter.parseDateTime(sDate).getTime(); } catch (IllegalArgumentException e) { throw new DateNotValidException(intres.getLocalizedMessage("ra.bad.date", sDate)); } if (date.after(new Date())) { throw new DateNotValidException("Revocation date in the future: '" + sDate + "'."); } revokeCert(issuerDN, certificateSN, reason, date, logger); } finally { logger.writeln(); logger.flush(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); // check username EndEntityInformation userdata = endEntityAccessSession.findUser(admin, username); if (userdata == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", username)); String msg = intres.getLocalizedMessage("ra.wrongusernameorpassword"); throw new NotFoundException(msg); } // Check caid int caid = userdata.getCAId(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } if (deleteUser) { endEntityManagementSession.revokeAndDeleteUser(admin, username, reason); } else { endEntityManagementSession.revokeUser(admin, username, reason); } } 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(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); boolean usekeyrecovery = ((GlobalConfiguration) globalConfigurationSession .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID)).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); } EndEntityInformation userdata = endEntityAccessSession.findUser(admin, username); if (userdata == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", username)); String msg = intres.getLocalizedMessage("ra.wrongusernameorpassword"); throw new NotFoundException(msg); } if (keyRecoverySession.isUserMarked(username)) { // User is already marked for recovery. return; } // check CAID int caid = userdata.getCAId(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } // Do the work, mark user for key recovery endEntityManagementSession.prepareForKeyRecovery(admin, userdata.getUsername(), userdata.getEndEntityProfileId(), null); } catch (RuntimeException e) { // EJBException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } log.trace("<keyRecoverNewest"); } @Override public void keyRecover(String username, String certSNinHex, String issuerDN) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, EjbcaException, ApprovalException, WaitingForApprovalException { if (log.isTraceEnabled()) { log.trace(">keyRecover"); } final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); final boolean usekeyrecovery = ((GlobalConfiguration) globalConfigurationSession .getCachedConfiguration(GlobalConfiguration.GLOBAL_CONFIGURATION_ID)).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); } final EndEntityInformation userdata = endEntityAccessSession.findUser(admin, username); if (userdata == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", username)); final String msg = intres.getLocalizedMessage("ra.wrongusernameorpassword"); throw new NotFoundException(msg); } if (keyRecoverySession.isUserMarked(username)) { // User is already marked for recovery. return; } // check CAID final int caid = userdata.getCAId(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } // find certificate to recover final Certificate wsCert = getCertificate(certSNinHex, issuerDN); if (wsCert == null) { throw new EjbcaException(ErrorCode.CERT_PATH_INVALID); } java.security.cert.Certificate cert = null; try { cert = CertificateHelper.getCertificate(wsCert.getCertificateData()); } catch (CertificateException e) { throw EjbcaWSHelper.getInternalException(e, logger); } // Do the work, mark user for key recovery endEntityManagementSession.prepareForKeyRecovery(admin, userdata.getUsername(), userdata.getEndEntityProfileId(), cert); } catch (RuntimeException e) { // EJBException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } if (log.isTraceEnabled()) { log.trace("<keyRecover"); } } @Override public void revokeToken(String hardTokenSN, int reason) throws CADoesntExistsException, AuthorizationDeniedException, NotFoundException, AlreadyRevokedException, EjbcaException, ApprovalException, WaitingForApprovalException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); 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(AuthenticationToken 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(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(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } try { // Revoke or unrevoke, will throw appropriate exceptions if parameters are wrong, such as trying to unrevoke a certificate // that was permanently revoked endEntityManagementSession.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 (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); } } @Override public RevokeStatus checkRevokationStatus(String issuerDN, String certificateSN) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); // check that admin is autorized to CA int caid = CertTools.stringToBCDNString(issuerDN).hashCode(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } CertificateStatus certinfo = certificateStoreSession.getStatus(issuerDN, new BigInteger(certificateSN, 16)); if (certinfo != null) { return new RevokeStatus(certinfo, issuerDN, certificateSN); } return null; } catch (DatatypeConfigurationException e) { throw EjbcaWSHelper.getInternalException(e, logger); } catch (RuntimeException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } } @Override @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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken 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(); } } @Override public List<UserDataSourceVOWS> fetchUserData(List<String> userDataSourceNames, String searchString) throws UserDataSourceException, EjbcaException, AuthorizationDeniedException { final AuthenticationToken admin; EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); if (WebServiceConfiguration.getNoAuthorizationOnFetchUserData()) { final AuthenticationToken tmp = ejbhelper.getAdmin(true); // We know client certificate is needed, so no other authentication tokens can exist X509Certificate admincert = ((X509CertificateAuthenticationToken) tmp).getCertificate(); admin = new AlwaysAllowLocalAuthenticationToken(new X509Principal(admincert.getSubjectDN().getName())); } 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.convertEndEntityInformation(next.getEndEntityInformation()), next.getIsFieldModifyableSet())); } } } catch (CADoesntExistsException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.CA_NOT_EXISTS, Level.INFO); } catch (RuntimeException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } return retval; } @Override 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 EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); int endEntityProfileId = 0; boolean hardTokenExists = false; boolean userExists = false; 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); final AuthenticationToken intAdmin = new AlwaysAllowLocalAuthenticationToken( new UsernamePrincipal("EJBCAWS.genTokenCertificates")); try { significantcAInfo = caSession.getCAInfo(intAdmin, userDataWS.getCaName()); if (significantcAInfo == null) { throw EjbcaWSHelper.getEjbcaException( "Error the given CA : " + userDataWS.getCaName() + " could not be found.", logger, ErrorCode.CA_NOT_EXISTS, null); } EndEntityInformation endEntityInformation = endEntityAccessSession.findUser(intAdmin, userDataWS.getUsername()); if (endEntityInformation != null) { endEntityProfileId = endEntityInformation.getEndEntityProfileId(); userExists = true; } else { try { endEntityProfileId = endEntityProfileSession .getEndEntityProfileId(userDataWS.getEndEntityProfileName()); } catch (EndEntityProfileNotFoundException e) { throw EjbcaWSHelper.getEjbcaException("Error given end entity profile : " + userDataWS.getEndEntityProfileName() + " could not be found", logger, ErrorCode.EE_PROFILE_NOT_EXISTS, null); } } // Approval request if we require approvals to generate token certificates ApprovalRequest ar = null; if (ejbhelper.isAdmin()) { final List<String> rules = new ArrayList<String>(); rules.add(StandardRules.CREATECERT.resource()); rules.add(AccessRulesConstants.HARDTOKEN_ISSUEHARDTOKENS); rules.add(StandardRules.CAACCESS.resource() + significantcAInfo.getCAId()); if (overwriteExistingSN) { rules.add(AccessRulesConstants.REGULAR_REVOKEENDENTITY); rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId + AccessRulesConstants.REVOKE_END_ENTITY); } if (userExists) { rules.add(AccessRulesConstants.REGULAR_EDITENDENTITY); rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId + AccessRulesConstants.EDIT_END_ENTITY); } else { rules.add(AccessRulesConstants.REGULAR_CREATEENDENTITY); rules.add(AccessRulesConstants.ENDENTITYPROFILEPREFIX + endEntityProfileId + AccessRulesConstants.CREATE_END_ENTITY); } String[] rulesArray = rules.toArray(new String[rules.size()]); if (!authorizationSession.isAuthorizedNoLogging(admin, rulesArray)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", Arrays.toString(rulesArray), null); throw new AuthorizationDeniedException(msg); } } 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); isRejectedStep1 = (status == ApprovalDataVO.STATUS_REJECTED); if (status == ApprovalDataVO.STATUS_APPROVED) { 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. } else if (status == ApprovalDataVO.STATUS_REJECTED) { throw new ApprovalRequestExecutionException( "The approval for id " + ar.generateApprovalId() + " has been rejected."); } else if (status == ApprovalDataVO.STATUS_EXPIREDANDNOTIFIED || status == ApprovalDataVO.STATUS_EXPIRED) { throw new ApprovalException( "The approval for id " + ar.generateApprovalId() + " has expired."); } else { throw new WaitingForApprovalException("The approval for id " + ar.generateApprovalId() + " have not yet been approved", ar.generateApprovalId()); } } catch (ApprovalException e) { approvalSession.addApprovalRequest(admin, ar); 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() + " has been rejected."); } if (ar != null && !approvalSuccessfullStep1) { throw new WaitingForApprovalException( "The approval for id " + ar.generateApprovalId() + " has not yet been approved", ar.generateApprovalId()); } if (ar != null) { // We need to create a new AuthenticationToken here that has the "name" of the admin making the request, but that // behaves like an "AlwaysAllowedAuthenticationToken". This is because the request admin does not have privileges, // but we want to log as if the requesting admin performed actions below. final Set<? extends Principal> principals = admin.getPrincipals(); Principal p = null; if (!principals.isEmpty()) { p = principals.iterator().next(); } else { final Set<?> credentials = admin.getCredentials(); if (!credentials.isEmpty()) { final Object o = credentials.iterator().next(); if (o instanceof X509Certificate) { final X509Certificate cert = (X509Certificate) o; p = new X500Principal(cert.getSubjectDN().getName()); } } else { log.error("Admin does not have neither Principals nor Credentials"); } } admin = new AlwaysAllowLocalAuthenticationToken(p); } hardTokenExists = hardTokenSession.existsHardToken(hardTokenDataWS.getHardTokenSN()); if (hardTokenExists) { if (overwriteExistingSN) { // fetch all old certificates and revoke them. Collection<java.security.cert.Certificate> currentCertificates = hardTokenSession .findCertificatesInHardToken(hardTokenDataWS.getHardTokenSN()); HardTokenInformation 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 { endEntityManagementSession.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(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())) { endEntityManagementSession.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); EndEntityInformation userData = ejbhelper.convertUserDataVOWS(admin, userDataWS); userData.setPassword(password); if (userExists) { endEntityManagementSession.changeUser(admin, userData, true); } else { endEntityManagementSession.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(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 = caSession.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.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + cAInfo.getCAId())) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + cAInfo.getCAId(), null); throw new AuthorizationDeniedException(msg); } if (next.getType() == HardTokenConstants.REQUESTTYPE_PKCS10_REQUEST) { userData.setCertificateProfileId(certificateProfileId); userData.setCAId(cAInfo.getCAId()); userData.setPassword(password); userData.setStatus(EndEntityConstants.STATUS_NEW); endEntityManagementSession.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(EndEntityConstants.STATUS_NEW); endEntityManagementSession.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 = caSession .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 { endEntityManagementSession.setUserStatus(admin, userDataWS.getUsername(), EndEntityConstants.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 (FinderException e) { throw EjbcaWSHelper.getInternalException(e, logger); } catch (RuntimeException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } return retval; } @Override public boolean existsHardToken(String hardTokenSN) throws EjbcaException { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { final AuthenticationToken admin = ejbhelper.getAdmin(); logAdminName(admin, logger); return hardTokenSession.existsHardToken(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(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); ApprovalRequest ar = null; boolean isApprovedStep0 = false; boolean isRejectedStep0 = false; HardTokenInformation 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()) { if (log.isDebugEnabled()) { log.debug("Checking for approvals for getHardTokenData(" + hardTokenSN + ")"); } // Check Approvals // Exists an GenTokenCertificates AuthenticationToken intAdmin = new AlwaysAllowLocalAuthenticationToken( new UsernamePrincipal("EJBCAWS.getHardTokenData")); EndEntityInformation userData = endEntityAccessSession.findUser(intAdmin, hardTokenData.getUsername()); if (userData == null) { log.info(intres.getLocalizedMessage("ra.errorentitynotexist", hardTokenData.getUsername())); String msg = intres.getLocalizedMessage("ra.wrongusernameorpassword"); throw new NotFoundException(msg); } int caid = userData.getCAId(); caSession.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(""); } if (log.isDebugEnabled()) { log.debug("A GenerateTokenApprovalRequest exists for " + userData.getUsername() + ", " + ar.generateApprovalId()); } } catch (ApprovalException e2) { if (log.isTraceEnabled()) { log.trace( "GenTokenCertificates approval does not exist, try a getHardTokenData request"); } if (!WebServiceConfiguration.getApprovalForHardTokenData()) { throw new AuthorizationDeniedException( "EjbcaWS is not 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 (log.isDebugEnabled()) { log.debug("Will generate a ViewHardTokenDataApprovalRequest for " + userData.getUsername() + ", " + ar.generateApprovalId()); } if (genNewRequest) { if (log.isDebugEnabled()) { log.debug("Adding an approval request for " + userData.getUsername()); } // Add approval Request try { approvalSession.addApprovalRequest(admin, ar); 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 { if (log.isDebugEnabled()) { log.debug("Not generating any approval request for: " + hardTokenSN); } 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(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; } @Override public List<HardTokenDataWS> getHardTokenDatas(String username, boolean viewPUKData, boolean onlyValidCertificates) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); final AuthenticationToken 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(AuthenticationToken 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); try { ejbhelper.isAuthorizedToHardTokenData(admin, username, viewPUKData); Collection<HardTokenInformation> hardtokens = hardTokenSession.getHardTokens(admin, username, viewPUKData); Iterator<HardTokenInformation> iter = hardtokens.iterator(); while (iter.hasNext()) { HardTokenInformation next = (HardTokenInformation) iter.next(); int caid = next.getSignificantIssuerDN().hashCode(); caSession.verifyExistenceOfCA(caid); if (!authorizationSession.isAuthorizedNoLogging(admin, StandardRules.CAACCESS.resource() + caid)) { final String msg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", StandardRules.CAACCESS.resource() + caid, null); throw new AuthorizationDeniedException(msg); } Collection<java.security.cert.Certificate> certs = hardTokenSession .findCertificatesInHardToken(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; } @Override public void republishCertificate(String serialNumberInHex, String issuerDN) throws CADoesntExistsException, AuthorizationDeniedException, PublisherException, EjbcaException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { String bcIssuerDN = CertTools.stringToBCDNString(issuerDN); caSession.verifyExistenceOfCA(bcIssuerDN.hashCode()); CertReqHistory certreqhist = certreqHistorySession .retrieveCertReqHistory(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(certreqhist.getEndEntityInformation().getCertificateProfileId()); java.security.cert.Certificate cert = certificateStoreSession .findCertificateByFingerprint(certreqhist.getFingerprint()); if (certprofile != null) { CertificateInfo certinfo = certificateStoreSession .getCertificateInfo(certreqhist.getFingerprint()); if (certprofile.getPublisherList().size() > 0) { if (publisherSession.storeCertificate(admin, certprofile.getPublisherList(), cert, certreqhist.getEndEntityInformation().getUsername(), certreqhist.getEndEntityInformation().getPassword(), certreqhist.getEndEntityInformation().getCertificateDN(), certinfo.getCAFingerprint(), certinfo.getStatus(), certinfo.getType(), certinfo.getRevocationDate().getTime(), certinfo.getRevocationReason(), certinfo.getTag(), certinfo.getCertificateProfileId(), certinfo.getUpdateTime().getTime(), certreqhist.getEndEntityInformation().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(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { // Check authorization to perform custom logging if (!authorizationSession.isAuthorized(admin, AuditLogRules.LOG_CUSTOM.resource())) { final String authmsg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", AuditLogRules.LOG_CUSTOM.resource(), null); throw new AuthorizationDeniedException(authmsg); } EventType event = EjbcaEventTypes.CUSTOMLOG_ERROR; switch (level) { case IEjbcaWS.CUSTOMLOG_LEVEL_ERROR: break; case IEjbcaWS.CUSTOMLOG_LEVEL_INFO: event = EjbcaEventTypes.CUSTOMLOG_INFO; 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 = 0; if (cAName != null) { CAInfo cAInfo = caSession.getCAInfo(admin, cAName); caId = cAInfo.getCAId(); } else { caId = ((X509CertificateAuthenticationToken) admin).getCertificate().getSubjectDN().getName() .hashCode(); } String comment = type + " : " + msg; Map<String, Object> details = new LinkedHashMap<String, Object>(); details.put("msg", comment); String certstring = null; if (logCert != null) { certstring = CertTools.getSerialNumberAsString(logCert); } auditSession.log(event, EventStatus.SUCCESS, EjbcaModuleTypes.CUSTOM, EjbcaServiceTypes.EJBCA, admin.toString(), String.valueOf(caId), username, certstring, details); //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(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { AuthenticationToken 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; } @Override public int isApproved(int approvalId) throws ApprovalException, EjbcaException, ApprovalRequestExpiredException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { final AuthenticationToken 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(); } } @Override public Certificate getCertificate(String certSNinHex, String issuerDN) throws CADoesntExistsException, AuthorizationDeniedException, EjbcaException { Certificate retval = null; EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); String bcString = CertTools.stringToBCDNString(issuerDN); int caid = bcString.hashCode(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { caSession.verifyExistenceOfCA(caid); final String[] rules = { StandardRules.CAFUNCTIONALITY.resource() + "/view_certificate", StandardRules.CAACCESS.resource() + caid }; if (!authorizationSession.isAuthorizedNoLogging(admin, rules)) { final String authmsg = intres.getLocalizedMessage("authorization.notuathorizedtoresource", Arrays.toString(rules), null); throw new AuthorizationDeniedException(authmsg); } java.security.cert.Certificate cert = certificateStoreSession.findCertificateByIssuerAndSerno(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; } @Override public NameAndId[] getAvailableCAs() throws EjbcaException, AuthorizationDeniedException { TreeMap<String, Integer> ret = new TreeMap<String, Integer>(); EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { Collection<Integer> caids = caSession.getAuthorizedCaIds(admin); HashMap<Integer, String> map = caSession.getCAIdToNameMap(); 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); } @Override public NameAndId[] getAuthorizedEndEntityProfiles() throws AuthorizationDeniedException, EjbcaException { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken 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(); 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); } @Override public NameAndId[] getAvailableCertificateProfiles(final int entityProfileId) throws AuthorizationDeniedException, EjbcaException { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); final TreeMap<String, Integer> ret = new TreeMap<String, Integer>(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { final EndEntityProfile profile = endEntityProfileSession.getEndEntityProfileNoClone(entityProfileId); if (profile != null) { final String value = profile.getValue(EndEntityProfile.AVAILCERTPROFILES, 0); if (value != null) { final String[] availablecertprofilesId = value.split(EndEntityProfile.SPLITCHAR); for (String id : availablecertprofilesId) { int i = Integer.parseInt(id); ret.put(certificateProfileSession.getCertificateProfileName(i), i); } } } } catch (RuntimeException e) { // EJBException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } return ejbhelper.convertTreeMapToArray(ret); } @Override public NameAndId[] getAvailableCAsInProfile(final int entityProfileId) throws AuthorizationDeniedException, EjbcaException { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); final TreeMap<String, Integer> ret = new TreeMap<String, Integer>(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { final EndEntityProfile profile = endEntityProfileSession.getEndEntityProfileNoClone(entityProfileId); if (profile != null) { final Collection<String> cas = profile.getAvailableCAs(); // list of CA ids available in profile final HashMap<Integer, String> map = caSession.getCAIdToNameMap(); 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); } @Override public byte[] getProfile(int profileId, String profileType) throws AuthorizationDeniedException, EjbcaException, UnknownProfileTypeException { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); UpgradeableDataHashMap profile = null; if (StringUtils.equalsIgnoreCase(profileType, "eep")) { profile = endEntityProfileSession.getEndEntityProfileNoClone(profileId); if (profile == null) { throw EjbcaWSHelper.getEjbcaException( new EndEntityProfileNotFoundException( "Could not find end entity profile with ID '" + profileId + "' in the database."), null, ErrorCode.EE_PROFILE_NOT_EXISTS, null); } } else if (StringUtils.equalsIgnoreCase(profileType, "cp")) { profile = certificateProfileSession.getCertificateProfile(profileId); if (profile == null) { throw EjbcaWSHelper.getEjbcaException( new CertificateProfileDoesNotExistException( "Could not find certificate profile with ID '" + profileId + "' in the database."), null, ErrorCode.CERT_PROFILE_NOT_EXISTS, null); } } else { throw new UnknownProfileTypeException("Unknown profile type '" + profileType + "'. Recognized types are 'eep' for End Entity Profiles and 'cp' for Certificate Profiles"); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMLEncoder encoder = new XMLEncoder(baos); encoder.writeObject(profile.saveData()); encoder.close(); byte[] ba = baos.toByteArray(); try { baos.close(); } catch (IOException e) { throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } return ba; } @Override public void createCRL(String caname) throws CADoesntExistsException, ApprovalException, EjbcaException, ApprovalRequestExpiredException, CryptoTokenOfflineException, CAOfflineException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); logAdminName(admin, logger); CAInfo cainfo = caSession.getCAInfo(admin, caname); publishingCrlSession.forceCRL(admin, cainfo.getCAId()); publishingCrlSession.forceDeltaCRL(admin, cainfo.getCAId()); } 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(); } } @Override public byte[] getLatestCRL(final String caname, final boolean deltaCRL) throws CADoesntExistsException, EjbcaException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(true); logAdminName(admin, logger); CAInfo cainfo = caSession.getCAInfo(admin, caname); byte[] ret = crlStoreSession.getLastCRL(cainfo.getSubjectDN(), deltaCRL); return ret; } 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(); } } @Override public String getEjbcaVersion() { return GlobalConfiguration.EJBCA_VERSION; } @Override public int getPublisherQueueLength(String name) throws EjbcaException { final IPatternLogger logger = TransactionLogger.getPatternLogger(); try { final EjbcaWSHelper ejbhelper = new EjbcaWSHelper(wsContext, authorizationSession, caAdminSession, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbhelper.getAdmin(true); logAdminName(admin, logger); final int id = publisherSession.getPublisherId(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); } @Override public CertificateResponse certificateRequest(final UserDataVOWS userdata, final String requestData, final int requestType, final String hardTokenSN, final String responseType) throws 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbcawshelper.getAdmin(false); logAdminName(admin, logger); enrichUserDataWithRawSubjectDn(userdata); final EndEntityInformation endEntityInformation = ejbcawshelper.convertUserDataVOWS(admin, userdata); int responseTypeInt = CertificateConstants.CERT_RES_TYPE_CERTIFICATE; if (!responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_CERTIFICATE)) { if (responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7)) { responseTypeInt = CertificateConstants.CERT_RES_TYPE_PKCS7; } else if (responseType.equalsIgnoreCase(CertificateHelper.RESPONSETYPE_PKCS7WITHCHAIN)) { responseTypeInt = CertificateConstants.CERT_RES_TYPE_PKCS7WITHCHAIN; } else { throw new NoSuchAlgorithmException("Bad responseType:" + responseType); } } return new CertificateResponse(responseType, certificateRequestSession.processCertReq(admin, endEntityInformation, requestData, requestType, hardTokenSN, responseTypeInt)); } catch (CADoesntExistsException t) { logger.paramPut(TransactionTags.ERROR_MESSAGE.toString(), t.toString()); throw new EjbcaException(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 (CertificateExtensionException e) { throw EjbcaWSHelper.getInternalException(e, logger); } 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 (CesecoreException e) { // Will convert the CESecore exception to an EJBCA exception with the same error code throw EjbcaWSHelper.getEjbcaException(e, null, e.getErrorCode(), null); } catch (FinderException e) { throw new NotFoundException(e.getMessage()); } catch (RuntimeException e) { // EJBException, ClassCastException, ... throw EjbcaWSHelper.getInternalException(e, logger); } finally { logger.writeln(); logger.flush(); } } /** Add the raw subject DN as requested (used if we allow override from request End Entity Information) */ private void enrichUserDataWithRawSubjectDn(final UserDataVOWS userdata) { if (userdata.getExtendedInformation() == null) { userdata.setExtendedInformation(new ArrayList<ExtendedInformationWS>()); } userdata.getExtendedInformation() .add(new ExtendedInformationWS(ExtendedInformation.RAWSUBJECTDN, userdata.getSubjectDN())); } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); final AuthenticationToken admin = ejbcawshelper.getAdmin(false); logAdminName(admin, logger); enrichUserDataWithRawSubjectDn(userdata); final EndEntityInformation endEntityInformation = ejbcawshelper.convertUserDataVOWS(admin, userdata); final boolean createJKS = userdata.getTokenType().equals(UserDataVOWS.TOKEN_TYPE_JKS); final byte[] encodedKeyStore = certificateRequestSession.processSoftTokenReq(admin, endEntityInformation, 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 (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 (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); } catch (EndEntityExistsException e) { throw EjbcaWSHelper.getEjbcaException(e, logger, ErrorCode.USER_ALREADY_EXISTS, Level.INFO); } finally { logger.writeln(); logger.flush(); } } @Override 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, caSession, certificateProfileSession, certificateStoreSession, endEntityAccessSession, endEntityProfileSession, hardTokenSession, endEntityManagementSession, webAuthenticationSession, cryptoTokenManagementSession); AuthenticationToken admin = ejbhelper.getAdmin(); final IPatternLogger logger = TransactionLogger.getPatternLogger(); logAdminName(admin, logger); try { CAInfo info = caSession.getCAInfo(admin, caname); if (info.getStatus() == CAConstants.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; } }