use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.
the class ChipGateway method processSignRequest.
private CommandType processSignRequest(final SignRequestType signReq) throws ConnectionError, JsonProcessingException, InvalidRedirectUrlException, ChipGatewayDataError {
// check if we have been interrupted
checkProcessCancelled();
BigInteger waitSecondsBig = signReq.getMaxWaitSeconds();
long waitMillis = getWaitMillis(waitSecondsBig);
// run the actual stuff in the background, so we can wait and terminate if needed
FutureTask<SignResponseType> action = new FutureTask<>(new Callable<SignResponseType>() {
@Override
public SignResponseType call() throws Exception {
SignResponseType signResp = new SignResponseType();
signResp.setSessionIdentifier(sessionId);
byte[] slotHandle = signReq.getSlotHandle();
String didName = signReq.getDIDName();
char[] pin = null;
try {
pin = getPin(signReq.getPIN());
Signer signer = new Signer(tokenCache, slotHandle, didName, pin);
byte[] signature = signer.sign(signReq.getMessage());
signResp.setSignature(signature);
signResp.setResult(ChipGatewayStatusCodes.OK);
return signResp;
} finally {
if (pin != null) {
Arrays.fill(pin, ' ');
}
}
}
});
Thread t = new Thread(action, "SignRequest-Task-" + TASK_THREAD_NUM.getAndIncrement());
t.setDaemon(true);
t.start();
SignResponseType signResp = new SignResponseType();
signResp.setSessionIdentifier(sessionId);
try {
// wait for thread to finish
signResp = 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();
signResp.setResult(ChipGatewayStatusCodes.TIMEOUT);
} catch (InterruptedException ignore) {
// send stop message
signResp.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.", cause);
signResp.setResult(ChipGatewayStatusCodes.INCORRECT_PARAMETER);
} else if (cause instanceof ParameterInvalid) {
LOG.error("Error while processing the certificate filter parameters.", cause);
signResp.setResult(ChipGatewayStatusCodes.INCORRECT_PARAMETER);
} else if (cause instanceof SlotHandleInvalid) {
LOG.error("No token for the given slot handle found.", cause);
signResp.setResult(ChipGatewayStatusCodes.UNKNOWN_SLOT);
} else if (cause instanceof NoSuchDid) {
LOG.error("DID does not exist.", cause);
signResp.setResult(ChipGatewayStatusCodes.UNKNOWN_DID);
} else if (cause instanceof PinBlocked) {
LOG.error("PIN is blocked.", ex);
signResp.setResult(ChipGatewayStatusCodes.PIN_BLOCKED);
} else if (cause instanceof SecurityConditionUnsatisfiable) {
LOG.error("DID can not be authenticated.", cause);
signResp.setResult(ChipGatewayStatusCodes.SECURITY_NOT_SATISFIED);
} else if (cause instanceof WSHelper.WSException) {
LOG.error("Unknown error.", cause);
signResp.setResult(ChipGatewayStatusCodes.OTHER);
} else if (cause instanceof ThreadTerminateException) {
LOG.error("Chipgateway process interrupted.", cause);
signResp.setResult(ChipGatewayStatusCodes.STOPPED);
} else {
LOG.error("Unknown error during sign operation.", cause);
signResp.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
signResp.setResult(ChipGatewayStatusCodes.STOPPED);
}
return sendMessageInterruptableAndCheckTermination(getResource(signUrl), signResp);
}
use of org.openecard.common.ThreadTerminateException in project open-ecard by ecsec.
the class ActivateCGAction method execute.
@Override
public BindingResult execute(RequestBody body, Map<String, String> params, Headers headers, List<Attachment> att) {
BindingResult response;
boolean aquired = false;
try {
checkMethod(headers);
final TCToken token = TCToken.generateToken(params);
Runnable cgAction = new Runnable() {
@Override
public void run() {
try {
tokenHandler.handleNoCardActivate(token);
// run a full GC to free some heap memory
System.gc();
System.runFinalization();
System.gc();
} catch (ThreadTerminateException ex) {
LOG.debug("Activation task terminated by an interrupt.", ex);
} catch (RuntimeException ex) {
LOG.error("Unhandled exception in activation process.", ex);
} finally {
currentTaskThread = null;
// in some cases an error does not lead to a removal of the dynamic context so remove it here
DynamicContext.remove();
}
}
};
// guard thread creation
MUTEX.acquire();
aquired = true;
Thread t = currentTaskThread;
if (t != null) {
if (token.isForceProcessing()) {
LOG.info("Stopping already running ChipGateway Protocol instance.");
t.interrupt();
// wait for other task to complete
t.join();
} else {
LOG.info("Another ChipGateway Protocol instance is already running, return status=busy.");
response = new BindingResult(BindingResultCode.REDIRECT);
response.getAuxResultData().put(AuxDataKeys.REDIRECT_LOCATION, token.finalizeBusyAddress());
return response;
}
}
// perform ChipGateway Protocol in background thread, so that we can return directly
currentTaskThread = new Thread(cgAction);
currentTaskThread.setDaemon(true);
currentTaskThread.setName("ChipGateway-Activation-" + THREAD_NUM.getAndIncrement());
currentTaskThread.start();
// create redirect
response = new BindingResult(BindingResultCode.REDIRECT);
response.getAuxResultData().put(AuxDataKeys.REDIRECT_LOCATION, token.finalizeOkAddress());
} catch (WrongMethodException ex) {
LOG.warn(ex.getMessage());
response = new BindingResult(BindingResultCode.WRONG_PARAMETER);
response.setResultMessage(ex.getMessage());
} catch (NoMethodException ex) {
LOG.error("No method given in headers, maybe wrong binging.", ex);
response = new BindingResult(BindingResultCode.INTERNAL_ERROR);
response.setResultMessage(ex.getMessage());
} catch (InvalidRedirectUrlException | InvalidTCTokenElement ex) {
LOG.error("Failed to create TCToken.", ex);
response = ex.getBindingResult();
} catch (InterruptedException ex) {
LOG.info("ChipGateway activation interrupted.");
response = new BindingResult(BindingResultCode.INTERNAL_ERROR);
response.setResultMessage(ex.getMessage());
} finally {
if (aquired) {
MUTEX.release();
}
}
return response;
}
Aggregations