Search in sources :

Example 6 with ThreadTerminateException

use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.

the class ChipGateway method processCertificatesRequest.

private CommandType processCertificatesRequest(final ListCertificatesRequestType certReq) throws ConnectionError, JsonProcessingException, InvalidRedirectUrlException, ChipGatewayDataError {
    // check if we have been interrupted
    checkProcessCancelled();
    BigInteger waitSecondsBig = certReq.getMaxWaitSeconds();
    long waitMillis = getWaitMillis(waitSecondsBig);
    // run the actual stuff in the background, so we can wait and terminate if needed
    FutureTask<ListCertificatesResponseType> action = new FutureTask<>(new Callable<ListCertificatesResponseType>() {

        @Override
        public ListCertificatesResponseType call() throws Exception {
            ListCertificatesResponseType certResp = new ListCertificatesResponseType();
            certResp.setSessionIdentifier(sessionId);
            char[] pin = null;
            try {
                pin = getPin(certReq.getPIN());
                byte[] slotHandle = certReq.getSlotHandle();
                ListCertificates helper = new ListCertificates(tokenCache, slotHandle, certReq.getCertificateFilter(), pin);
                List<CertificateInfoType> certInfos = helper.getCertificates();
                certResp.getCertificateInfo().addAll(certInfos);
                certResp.setResult(ChipGatewayStatusCodes.OK);
                return certResp;
            } finally {
                if (pin != null) {
                    Arrays.fill(pin, ' ');
                }
            }
        }
    });
    Thread t = new Thread(action, "CertificatesRequest-Task-" + TASK_THREAD_NUM.getAndIncrement());
    t.setDaemon(true);
    t.start();
    ListCertificatesResponseType certResp = new ListCertificatesResponseType();
    certResp.setSessionIdentifier(sessionId);
    try {
        // wait for thread to finish
        certResp = action.get(waitMillis, TimeUnit.MILLISECONDS);
    } catch (TimeoutException ex) {
        LOG.info("Background task took longer than the timeout value permitted.", ex);
        // cancel task
        action.cancel(true);
        // wait for task to finish, so the SC stack can not get confused
        try {
            t.join();
            certResp.setResult(ChipGatewayStatusCodes.TIMEOUT);
        } catch (InterruptedException ignore) {
            // send stop message
            certResp.setResult(ChipGatewayStatusCodes.STOPPED);
        }
    } catch (ExecutionException ex) {
        LOG.error("Background task produced an exception.", ex);
        Throwable cause = ex.getCause();
        if (cause instanceof RemotePinException) {
            LOG.error("Error getting encrypted PIN.", ex);
            certResp.setResult(ChipGatewayStatusCodes.INCORRECT_PARAMETER);
        } else if (cause instanceof ParameterInvalid) {
            LOG.error("Error while processing the certificate filter parameters.", ex);
            certResp.setResult(ChipGatewayStatusCodes.INCORRECT_PARAMETER);
        } else if (cause instanceof SlotHandleInvalid) {
            LOG.error("No token for the given slot handle found.", cause);
            certResp.setResult(ChipGatewayStatusCodes.UNKNOWN_SLOT);
        } else if (cause instanceof NoSuchDid) {
            LOG.error("DID does not exist.", cause);
            certResp.setResult(ChipGatewayStatusCodes.UNKNOWN_DID);
        } else if (cause instanceof SecurityConditionUnsatisfiable) {
            LOG.error("DID can not be authenticated.", cause);
            certResp.setResult(ChipGatewayStatusCodes.SECURITY_NOT_SATISFIED);
        } else if (cause instanceof CertificateException) {
            LOG.error("Certificate could not be processed.", cause);
            certResp.setResult(ChipGatewayStatusCodes.OTHER);
        } else if (cause instanceof WSHelper.WSException) {
            LOG.error("Unknown error.", cause);
            certResp.setResult(ChipGatewayStatusCodes.OTHER);
        } else if (cause instanceof ThreadTerminateException) {
            LOG.error("Chipgateway process interrupted.", cause);
            certResp.setResult(ChipGatewayStatusCodes.STOPPED);
        } else {
            LOG.error("Unknown error during list certificate operation.", cause);
            certResp.setResult(ChipGatewayStatusCodes.OTHER);
        }
    } catch (InterruptedException ex) {
        String msg = "Interrupted while waiting for background task.";
        if (LOG.isDebugEnabled()) {
            LOG.debug(msg, ex);
        } else {
            LOG.info(msg);
        }
        // cancel task
        action.cancel(true);
        // send stop message
        certResp.setResult(ChipGatewayStatusCodes.STOPPED);
    }
    return sendMessageInterruptableAndCheckTermination(getResource(listCertsUrl), certResp);
}
Also used : ListCertificatesResponseType(org.openecard.ws.chipgateway.ListCertificatesResponseType) SecurityConditionUnsatisfiable(org.openecard.common.SecurityConditionUnsatisfiable) CertificateException(java.security.cert.CertificateException) RemotePinException(org.openecard.addons.cg.ex.RemotePinException) FutureTask(java.util.concurrent.FutureTask) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) ThreadTerminateException(org.openecard.common.ThreadTerminateException) TimeoutException(java.util.concurrent.TimeoutException) WSHelper(org.openecard.common.WSHelper) SlotHandleInvalid(org.openecard.addons.cg.ex.SlotHandleInvalid) KeyStoreException(java.security.KeyStoreException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) RemotePinException(org.openecard.addons.cg.ex.RemotePinException) ThreadTerminateException(org.openecard.common.ThreadTerminateException) HttpException(org.openecard.apache.http.HttpException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) InvalidRedirectUrlException(org.openecard.addons.cg.ex.InvalidRedirectUrlException) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) JoseException(org.jose4j.lang.JoseException) AuthServerException(org.openecard.addons.cg.ex.AuthServerException) UnsupportedAlgorithmException(org.openecard.crypto.common.UnsupportedAlgorithmException) MalformedURLException(java.net.MalformedURLException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) CertificateException(java.security.cert.CertificateException) BigInteger(java.math.BigInteger) ParameterInvalid(org.openecard.addons.cg.ex.ParameterInvalid) NoSuchDid(org.openecard.crypto.common.sal.did.NoSuchDid)

Example 7 with ThreadTerminateException

use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.

the class MwSession method findObjects.

private List<Long> findObjects(CK_ATTRIBUTE pTemplate) throws CryptokiException {
    try (MiddleWareWrapper.LockedMiddlewareWrapper lmw = mw.lock()) {
        lmw.findObjectsInit(sessionHandle, pTemplate, 1);
        List<Long> res = lmw.findObjects(sessionHandle);
        lmw.findObjectsFinalize(sessionHandle);
        return res;
    } catch (InterruptedException ex) {
        throw new ThreadTerminateException("Thread interrupted while waiting for Middleware lock.", ex);
    }
}
Also used : NativeLong(com.sun.jna.NativeLong) ThreadTerminateException(org.openecard.common.ThreadTerminateException)

Example 8 with ThreadTerminateException

use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.

the class MiddleWareWrapper method login.

public void login(final long hSession, final long userType, @Nullable byte[] pPin) throws CryptokiException {
    ByteBuffer pinBytesTmp = null;
    final NativeLong pinLen = new NativeLong(0);
    if (pPin != null) {
        pinBytesTmp = ByteBuffer.wrap(pPin);
        pinLen.setValue(pPin.length);
    }
    final ByteBuffer pinBytes = pinBytesTmp;
    try (LockedObject lo = lockInternal()) {
        FutureTask<Void> task = new FutureTask<>(new Callable<Void>() {

            @Override
            public Void call() throws Exception {
                // login to session with pin and usertype
                check("C_Login", MiddleWareWrapper.this.lib.C_Login(new NativeLong(hSession), new NativeLong(userType), pinBytes, pinLen), (long) CryptokiLibrary.CKR_OK, (long) CryptokiLibrary.CKR_USER_ALREADY_LOGGED_IN);
                return null;
            }
        });
        Thread t = new Thread(task, "Middleware-Login");
        t.setDaemon(true);
        t.start();
        try {
            task.get();
        } catch (ExecutionException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof CryptokiException) {
                throw (CryptokiException) cause;
            } else if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else {
                throw new RuntimeException("Unexpected error received during C_Login call.", cause);
            }
        } catch (InterruptedException ex) {
            task.cancel(true);
            LOG.info("Interrupted while waiting for C_Login task.", ex);
            throw new ThreadTerminateException("Waiting interrupted by an external thread.", ex);
        }
    } catch (InterruptedException ex) {
        throw new IllegalStateException("Failed to release lock for middleware access.");
    }
}
Also used : NativeLong(com.sun.jna.NativeLong) ByteBuffer(java.nio.ByteBuffer) SessionException(org.openecard.mdlw.sal.exceptions.SessionException) TokenException(org.openecard.mdlw.sal.exceptions.TokenException) CryptographicException(org.openecard.mdlw.sal.exceptions.CryptographicException) ThreadTerminateException(org.openecard.common.ThreadTerminateException) PinBlockedException(org.openecard.mdlw.sal.exceptions.PinBlockedException) CancellationException(org.openecard.mdlw.sal.exceptions.CancellationException) UnsupportedAlgorithmException(org.openecard.crypto.common.UnsupportedAlgorithmException) DataInvalidException(org.openecard.mdlw.sal.exceptions.DataInvalidException) PinIncorrectException(org.openecard.mdlw.sal.exceptions.PinIncorrectException) AlreadyInitializedException(org.openecard.mdlw.sal.exceptions.AlreadyInitializedException) InvalidArgumentsException(org.openecard.mdlw.sal.exceptions.InvalidArgumentsException) ExecutionException(java.util.concurrent.ExecutionException) CryptokiException(org.openecard.mdlw.sal.exceptions.CryptokiException) AuthenticationException(org.openecard.mdlw.sal.exceptions.AuthenticationException) FutureTask(java.util.concurrent.FutureTask) CryptokiException(org.openecard.mdlw.sal.exceptions.CryptokiException) ExecutionException(java.util.concurrent.ExecutionException) ThreadTerminateException(org.openecard.common.ThreadTerminateException)

Example 9 with ThreadTerminateException

use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.

the class ExecutionEngine method process.

/**
 * Processes the user consent associated with this instance. <br>
 * The following algorithm is used to process the dialog.
 * <ol>
 * <li>Display the first step.</li>
 * <li>Evaluate step result. Break execution on CANCEL.</li>
 * <li>Execute step action. Break execution on CANCEL.</li>
 * <li>Display either next previous or current step, or a replacement according to result.</li>
 * <li>Proceed with point 2.</li>
 * </ol>
 *
 * @return Overall result of the execution.
 * @throws ThreadTerminateException Thrown in case the GUI has been closed externally (interrupted).
 */
public ResultStatus process() throws ThreadTerminateException {
    // get first step
    StepResult next = navigator.next();
    // loop over steps. break inside loop
    while (true) {
        ResultStatus result = next.getStatus();
        // close dialog on cancel and interrupt
        if (result == ResultStatus.INTERRUPTED || Thread.currentThread().isInterrupted()) {
            navigator.close();
            throw new ThreadTerminateException("GUI has been interrupted.");
        } else if (result == ResultStatus.CANCEL) {
            navigator.close();
            return result;
        }
        // get result and put it in resultmap
        List<OutputInfoUnit> stepResults = next.getResults();
        Map<String, ExecutionResults> oldResults = Collections.unmodifiableMap(results);
        results.put(next.getStepID(), new ExecutionResults(next.getStepID(), stepResults));
        // replace InfoInputUnit values in live list
        if (!next.getStep().isResetOnLoad()) {
            Step s = next.getStep();
            List<InputInfoUnit> inputInfo = s.getInputInfoUnits();
            Map<String, InputInfoUnit> infoMap = new HashMap<>();
            // create index over infos
            for (InputInfoUnit nextInfo : inputInfo) {
                infoMap.put(nextInfo.getID(), nextInfo);
            }
            for (OutputInfoUnit nextOut : stepResults) {
                InputInfoUnit matchingInfo = infoMap.get(nextOut.getID());
                // an entry must exist, otherwise this is an error in the GUI implementation
                // this type of error should be found in tests
                matchingInfo.copyContentFrom(nextOut);
            }
        }
        // replace step if told by result value
        if (next.getReplacement() != null) {
            switch(next.getStatus()) {
                case BACK:
                    next = navigator.replacePrevious(next.getReplacement());
                    break;
                case OK:
                    if (navigator.hasNext()) {
                        next = navigator.replaceNext(next.getReplacement());
                    } else {
                        navigator.close();
                        return convertStatus(StepActionResultStatus.NEXT);
                    }
                    break;
                case RELOAD:
                    next = navigator.replaceCurrent(next.getReplacement());
                    break;
                default:
                    // fallthrough because CANCEL and INTERRUPTED are already handled
                    break;
            }
        } else {
            // step replacement did not happen, so we can execute the action
            StepAction action = next.getStep().getAction();
            StepActionCallable actionCallable = new StepActionCallable(action, oldResults, next);
            // use separate thread or tasks running outside the JVM context, like PCSC calls, won't stop on cancellation
            ExecutorService execService = Executors.newSingleThreadExecutor();
            Future<StepActionResult> actionFuture = execService.submit(actionCallable);
            navigator.setRunningAction(actionFuture);
            StepActionResult actionResult;
            try {
                actionResult = actionFuture.get();
            } catch (CancellationException ex) {
                LOG.info("StepAction was canceled.", ex);
                navigator.close();
                return ResultStatus.CANCEL;
            } catch (InterruptedException ex) {
                LOG.info("StepAction was interrupted.", ex);
                navigator.close();
                throw new ThreadTerminateException("GUI has been interrupted.");
            } catch (ExecutionException ex) {
                // there are some special kinds we need to handle here
                if (ex.getCause() instanceof InvocationTargetExceptionUnchecked) {
                    InvocationTargetExceptionUnchecked iex = (InvocationTargetExceptionUnchecked) ex.getCause();
                    if (iex.getCause() instanceof ThreadTerminateException) {
                        LOG.info("StepAction was interrupted.", ex);
                        navigator.close();
                        throw new ThreadTerminateException("GUI has been interrupted.");
                    }
                }
                // all other types
                LOG.error("StepAction failed with error.", ex.getCause());
                navigator.close();
                return ResultStatus.CANCEL;
            }
            // break out if cancel was returned
            if (actionResult.getStatus() == StepActionResultStatus.CANCEL) {
                LOG.info("StepAction was canceled.");
                navigator.close();
                return ResultStatus.CANCEL;
            }
            // replace step if told by result value
            if (actionResult.getReplacement() != null) {
                switch(actionResult.getStatus()) {
                    case BACK:
                        next = navigator.replacePrevious(actionResult.getReplacement());
                        break;
                    case NEXT:
                        if (navigator.hasNext()) {
                            next = navigator.replaceNext(actionResult.getReplacement());
                        } else {
                            navigator.close();
                            return convertStatus(StepActionResultStatus.NEXT);
                        }
                        break;
                    case REPEAT:
                        next = navigator.replaceCurrent(actionResult.getReplacement());
                        break;
                    default:
                        // fallthrough because CANCEL is already handled
                        break;
                }
            } else {
                // no replacement just proceed
                switch(actionResult.getStatus()) {
                    case BACK:
                        next = navigator.previous();
                        break;
                    case NEXT:
                        if (navigator.hasNext()) {
                            next = navigator.next();
                        } else {
                            navigator.close();
                            return convertStatus(StepActionResultStatus.NEXT);
                        }
                        break;
                    case REPEAT:
                        next = navigator.current();
                        break;
                    default:
                        // fallthrough because CANCEL is already handled
                        break;
                }
            }
        }
    }
}
Also used : InvocationTargetExceptionUnchecked(org.openecard.common.interfaces.InvocationTargetExceptionUnchecked) ResultStatus(org.openecard.gui.ResultStatus) HashMap(java.util.HashMap) Step(org.openecard.gui.definition.Step) InputInfoUnit(org.openecard.gui.definition.InputInfoUnit) CancellationException(java.util.concurrent.CancellationException) ExecutorService(java.util.concurrent.ExecutorService) OutputInfoUnit(org.openecard.gui.definition.OutputInfoUnit) StepResult(org.openecard.gui.StepResult) ThreadTerminateException(org.openecard.common.ThreadTerminateException) ExecutionException(java.util.concurrent.ExecutionException)

Example 10 with ThreadTerminateException

use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.

the class ChipGateway method sendHello.

public TerminateType sendHello() throws VersionTooOld, ChipGatewayDataError, ConnectionError, InvalidRedirectUrlException, AuthServerException {
    try {
        byte[] challenge = ValueGenerators.generateRandom(32);
        helloReq = new HelloRequestType();
        helloReq.setSessionIdentifier(sessionId);
        helloReq.setVersion(String.format("%s.%s.%s", AppVersion.getMajor(), AppVersion.getMinor(), AppVersion.getPatch()));
        helloReq.setChallenge(challenge);
        // send Hello
        String helloReqMsg = mapper.writeValueAsString(helloReq);
        HelloResponseType helloResp = sendMessageInterruptable(getResource(helloUrl), helloReqMsg, HelloResponseType.class);
        processHelloResponse(helloResp);
        // send GetCommand
        GetCommandType cmdReq = createGetCommandRequest();
        String cmdReqMsg = mapper.writeValueAsString(cmdReq);
        CommandType cmdResp;
        try {
            cmdResp = sendMessageInterruptable(getResource(getCommandUrl), cmdReqMsg, CommandType.class);
        } catch (ThreadTerminateException ex) {
            performProcessCancelled();
            throw ex;
        }
        // send messages to the server as long as there is no termination response
        while (cmdResp.getTerminate() == null) {
            ListTokensRequestType tokensReq = cmdResp.getListTokensRequest();
            ListCertificatesRequestType certReq = cmdResp.getListCertificatesRequest();
            SignRequestType signReq = cmdResp.getSignRequest();
            if (tokensReq != null) {
                cmdResp = processTokensRequest(tokensReq);
            } else if (certReq != null) {
                cmdResp = processCertificatesRequest(certReq);
            } else if (signReq != null) {
                cmdResp = processSignRequest(signReq);
            } else {
                throw new ChipGatewayDataError(token.finalizeErrorAddress(ResultMinor.SERVER_ERROR), INVALID_CHIPGATEWAY_MSG);
            }
        }
        // return the last message (terminate type)
        return cmdResp.getTerminate();
    } catch (JsonProcessingException ex) {
        throw new ChipGatewayDataError(token.finalizeErrorAddress(ResultMinor.CLIENT_ERROR), INVALID_CHIPGATEWAY_MSG, ex);
    } finally {
        // clear token cache and delete all pins in it
        tokenCache.clearPins();
        // display GUI if needed
        if (showDialogThread != null) {
            showDialogThread.start();
        }
        try {
            // in case we are interrupted, terminate is sent in the background, so don't close just yet
            if (conn != null && !isInterrupted) {
                conn.close();
            }
        } catch (IOException ex) {
            LOG.error("Failed to close connection to server.", ex);
        }
        // disconnect all slots which have been connected in the process
        for (byte[] nextSlot : connectedSlots) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Disconnecting card with slotHandle={}.", ByteUtils.toHexString(nextSlot));
            }
            CardApplicationDisconnect req = new CardApplicationDisconnect();
            // req.setAction(ActionType.RESET);
            ConnectionHandleType handle = HandlerBuilder.create().setSlotHandle(nextSlot).buildConnectionHandle();
            req.setConnectionHandle(handle);
            dispatcher.safeDeliver(req);
        }
    }
}
Also used : ListTokensRequestType(org.openecard.ws.chipgateway.ListTokensRequestType) ConnectionHandleType(iso.std.iso_iec._24727.tech.schema.ConnectionHandleType) CardApplicationDisconnect(iso.std.iso_iec._24727.tech.schema.CardApplicationDisconnect) ChipGatewayDataError(org.openecard.addons.cg.ex.ChipGatewayDataError) GetCommandType(org.openecard.ws.chipgateway.GetCommandType) IOException(java.io.IOException) SignRequestType(org.openecard.ws.chipgateway.SignRequestType) HelloResponseType(org.openecard.ws.chipgateway.HelloResponseType) CommandType(org.openecard.ws.chipgateway.CommandType) GetCommandType(org.openecard.ws.chipgateway.GetCommandType) ListCertificatesRequestType(org.openecard.ws.chipgateway.ListCertificatesRequestType) HelloRequestType(org.openecard.ws.chipgateway.HelloRequestType) ThreadTerminateException(org.openecard.common.ThreadTerminateException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Aggregations

ThreadTerminateException (org.openecard.common.ThreadTerminateException)12 UnsupportedAlgorithmException (org.openecard.crypto.common.UnsupportedAlgorithmException)7 IOException (java.io.IOException)5 ExecutionException (java.util.concurrent.ExecutionException)5 WSHelper (org.openecard.common.WSHelper)5 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)4 FutureTask (java.util.concurrent.FutureTask)4 TimeoutException (java.util.concurrent.TimeoutException)4 InvalidRedirectUrlException (org.openecard.addons.cg.ex.InvalidRedirectUrlException)4 ParameterInvalid (org.openecard.addons.cg.ex.ParameterInvalid)4 SlotHandleInvalid (org.openecard.addons.cg.ex.SlotHandleInvalid)4 SecurityConditionUnsatisfiable (org.openecard.common.SecurityConditionUnsatisfiable)4 NativeLong (com.sun.jna.NativeLong)3 MalformedURLException (java.net.MalformedURLException)3 URISyntaxException (java.net.URISyntaxException)3 KeyStoreException (java.security.KeyStoreException)3 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)3 CertificateException (java.security.cert.CertificateException)3 JoseException (org.jose4j.lang.JoseException)3 AuthServerException (org.openecard.addons.cg.ex.AuthServerException)3