use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class EacNavigator method next.
@Override
public StepResult next() {
// if cancel call has been issued, abort the whole process
if (this.guiService.isCancelled()) {
// prevent index out of bounds
int i = idx == -1 ? 0 : idx > steps.size() ? steps.size() - 1 : idx;
return new AndroidResult(steps.get(i), ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
// handle step display
if (idx == -1) {
idx++;
return new AndroidResult(steps.get(idx), ResultStatus.OK, Collections.EMPTY_LIST);
} else if (idx == 0) {
idx++;
Step cvcStep = steps.get(0);
Step chatStep = steps.get(1);
try {
this.guiService.loadValuesFromSteps(cvcStep, chatStep);
List<OutputInfoUnit> outInfo = this.guiService.getSelection();
return new AndroidResult(chatStep, ResultStatus.OK, outInfo);
} catch (InterruptedException ex) {
return new AndroidResult(chatStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else if (idx == 1) {
idx++;
Step pinStep = steps.get(2);
if (pinFirstUse) {
pinFirstUse = false;
} else {
this.guiService.setPinCorrect(false);
}
// get blocked status from dynamic context
DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
this.guiService.sendPinStatus(blockedStatus);
return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
// ask user for the pin
try {
List<OutputInfoUnit> outInfo = this.guiService.getPinResult(pinStep);
writeBackValues(pinStep.getInputInfoUnits(), outInfo);
return new AndroidResult(pinStep, ResultStatus.OK, outInfo);
} catch (InterruptedException ex) {
return new AndroidResult(pinStep, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else if (idx == 2) {
idx++;
Step s = steps.get(idx);
// get blocked status from dynamic context
DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
EacPinStatus blockedStatus = (EacPinStatus) ctx.get(EACProtocol.PIN_STATUS);
if (blockedStatus == EacPinStatus.BLOCKED || blockedStatus == EacPinStatus.DEACTIVATED) {
this.guiService.setPinCorrect(false);
this.guiService.sendPinStatus(blockedStatus);
return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
if ("PROTOCOL_GUI_STEP_PROCESSING".equals(s.getID())) {
this.guiService.setPinCorrect(true);
return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
} else {
this.guiService.setPinCorrect(false);
return new AndroidResult(s, ResultStatus.CANCEL, Collections.EMPTY_LIST);
}
} else {
Step s = steps.get(idx);
idx++;
return new AndroidResult(s, ResultStatus.OK, Collections.EMPTY_LIST);
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenHandler method handleActivate.
/**
* Activates the client according to the received TCToken.
*
* @param request The activation request containing the TCToken.
* @return The response containing the result of the activation process.
* @throws InvalidRedirectUrlException Thrown in case no redirect URL could be determined.
* @throws SecurityViolationException
* @throws NonGuiException
*/
public TCTokenResponse handleActivate(TCTokenRequest request) throws InvalidRedirectUrlException, SecurityViolationException, NonGuiException {
TCToken token = request.getTCToken();
if (LOG.isDebugEnabled()) {
try {
WSMarshaller m = WSMarshallerFactory.createInstance();
LOG.debug("TCToken:\n{}", m.doc2str(m.marshal(token)));
} catch (TransformerException | WSMarshallerException ex) {
// it's no use
}
}
final DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
boolean performChecks = isPerformTR03112Checks(request);
if (!performChecks) {
LOG.warn("Checks according to BSI TR03112 3.4.2, 3.4.4 (TCToken specific) and 3.4.5 are disabled.");
}
boolean isObjectActivation = request.getTCTokenURL() == null;
if (isObjectActivation) {
LOG.warn("Checks according to BSI TR03112 3.4.4 (TCToken specific) are disabled.");
}
dynCtx.put(TR03112Keys.TCTOKEN_CHECKS, performChecks);
dynCtx.put(TR03112Keys.OBJECT_ACTIVATION, isObjectActivation);
dynCtx.put(TR03112Keys.TCTOKEN_SERVER_CERTIFICATES, request.getCertificates());
ConnectionHandleType connectionHandle = null;
TCTokenResponse response = new TCTokenResponse();
response.setTCToken(token);
byte[] requestedContextHandle = request.getContextHandle();
String ifdName = request.getIFDName();
BigInteger requestedSlotIndex = request.getSlotIndex();
// we know exactly which card we want
ConnectionHandleType requestedHandle = new ConnectionHandleType();
requestedHandle.setContextHandle(requestedContextHandle);
requestedHandle.setIFDName(ifdName);
requestedHandle.setSlotIndex(requestedSlotIndex);
Set<CardStateEntry> matchingHandles = cardStates.getMatchingEntries(requestedHandle);
if (!matchingHandles.isEmpty()) {
connectionHandle = matchingHandles.toArray(new CardStateEntry[] {})[0].handleCopy();
}
if (connectionHandle == null) {
String msg = LANG_TOKEN.translationForKey("cancel");
LOG.error(msg);
response.setResult(WSHelper.makeResultError(ResultMinor.CANCELLATION_BY_USER, msg));
// fill in values, so it is usuable by the transport module
response = determineRefreshURL(request, response);
response.finishResponse(true);
return response;
}
try {
// process binding and follow redirect addresses afterwards
response = processBinding(request, connectionHandle);
// fill in values, so it is usuable by the transport module
response = determineRefreshURL(request, response);
response.finishResponse(isObjectActivation);
return response;
} catch (DispatcherException w) {
LOG.error(w.getMessage(), w);
response.setResultCode(BindingResultCode.INTERNAL_ERROR);
response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, w.getMessage()));
showErrorMessage(w.getMessage());
throw new NonGuiException(response, w.getMessage(), w);
} catch (PAOSException w) {
LOG.error(w.getMessage(), w);
// find actual error to display to the user
Throwable innerException = w.getCause();
if (innerException == null) {
innerException = w;
} else if (innerException instanceof ExecutionException) {
innerException = innerException.getCause();
}
String errorMsg = innerException.getLocalizedMessage();
// fix NPE when null is returned instead of a message
errorMsg = errorMsg == null ? "" : errorMsg;
switch(errorMsg) {
case "The target server failed to respond":
errorMsg = LANG_TR.translationForKey(NO_RESPONSE_FROM_SERVER);
break;
case ECardConstants.Minor.App.INT_ERROR + " ==> Unknown eCard exception occurred.":
errorMsg = LANG_TR.translationForKey(UNKNOWN_ECARD_ERROR);
break;
case "Internal TLS error, this could be an attack":
errorMsg = LANG_TR.translationForKey(INTERNAL_TLS_ERROR);
break;
}
if (innerException instanceof WSException) {
WSException ex = (WSException) innerException;
errorMsg = createResponseFromWsEx(ex, response);
} else if (innerException instanceof PAOSConnectionException) {
response.setResult(WSHelper.makeResultError(ResultMinor.TRUSTED_CHANNEL_ESTABLISCHMENT_FAILED, w.getLocalizedMessage()));
} else {
errorMsg = createMessageFromUnknownError(w);
response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, w.getMessage()));
}
showErrorMessage(errorMsg);
try {
// fill in values, so it is usuable by the transport module
response = determineRefreshURL(request, response);
response.finishResponse(true);
} catch (InvalidRedirectUrlException ex) {
LOG.error(ex.getMessage(), ex);
response.setResultCode(BindingResultCode.INTERNAL_ERROR);
response.setResult(WSHelper.makeResultError(ResultMinor.CLIENT_ERROR, ex.getLocalizedMessage()));
throw new NonGuiException(response, ex.getMessage(), ex);
} catch (SecurityViolationException ex) {
String msg2 = "The RefreshAddress contained in the TCToken is invalid. Redirecting to the " + "CommunicationErrorAddress.";
LOG.error(msg2, ex);
response.setResultCode(BindingResultCode.REDIRECT);
response.setResult(WSHelper.makeResultError(ResultMinor.COMMUNICATION_ERROR, msg2));
response.addAuxResultData(AuxDataKeys.REDIRECT_LOCATION, ex.getBindingResult().getAuxResultData().get(AuxDataKeys.REDIRECT_LOCATION));
}
return response;
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenRequest method parseTCTokenRequestURI.
private static TCTokenRequest parseTCTokenRequestURI(Map<String, String> queries, Context ctx) throws InvalidTCTokenException, MissingActivationParameterException, AuthServerException, InvalidRedirectUrlException, InvalidTCTokenElement, InvalidTCTokenUrlException, SecurityViolationException, InvalidAddressException, UserCancellationException {
TCTokenRequest tcTokenRequest = new TCTokenRequest();
try {
if (queries.containsKey("cardTypes") || queries.containsKey("cardType")) {
String[] types;
if (queries.containsKey("cardType")) {
types = new String[] { queries.get("cardType") };
} else {
types = queries.get("cardTypes").split(",");
}
ConnectionHandleType handle = findCard(types, ctx);
setIfdName(queries, handle.getIFDName());
setContextHandle(queries, handle.getContextHandle());
setSlotIndex(queries, handle.getSlotIndex());
addTokenUrlParameter(queries, handle.getRecognitionInfo());
} else {
String[] types = new String[] { tcTokenRequest.cardType };
ConnectionHandleType handle = findCard(types, ctx);
setIfdName(queries, handle.getIFDName());
setContextHandle(queries, handle.getContextHandle());
setSlotIndex(queries, handle.getSlotIndex());
}
} catch (UserCancellationException ex) {
if (queries.containsKey("cardTypes")) {
addTokenUrlParameter(queries, queries.get("cardTypes").split(",")[0]);
}
LOG.warn("The user aborted the CardInsertion dialog.", ex);
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
dynCtx.put(TR03112Keys.CARD_SELECTION_CANCELLATION, ex);
}
String activationTokenUrl = null;
for (Map.Entry<String, String> next : queries.entrySet()) {
String k = next.getKey();
k = k == null ? "" : k;
String v = next.getValue();
if (v == null || v.isEmpty()) {
LOG.info("Skipping query parameter '{}' because it does not contain a value.", k);
} else {
switch(k) {
case "tcTokenURL":
activationTokenUrl = v;
break;
case "ifdName":
tcTokenRequest.ifdName = v;
break;
case "contextHandle":
tcTokenRequest.contextHandle = StringUtils.toByteArray(v);
break;
case "slotIndex":
tcTokenRequest.slotIndex = new BigInteger(v);
break;
case "cardType":
tcTokenRequest.cardType = v;
break;
default:
LOG.info("Unknown query element: {}", k);
break;
}
}
}
// cardType determined! set in dynamic context, so the information is available in ResourceContext
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
dynCtx.put(TR03112Keys.ACTIVATION_CARD_TYPE, tcTokenRequest.cardType);
if (activationTokenUrl != null) {
try {
URL tokenUrl = new URL(activationTokenUrl);
TCTokenContext tokenCtx = TCTokenContext.generateTCToken(tokenUrl);
tcTokenRequest.tokenCtx = tokenCtx;
tcTokenRequest.token = tokenCtx.getToken();
tcTokenRequest.certificates = tokenCtx.getCerts();
tcTokenRequest.tcTokenURL = tokenUrl;
} catch (MalformedURLException ex) {
// TODO: check if the error type is correct, was WRONG_PARAMETER before
throw new InvalidTCTokenUrlException(INVALID_TCTOKEN_URL, ex, activationTokenUrl);
}
}
if (tcTokenRequest.token == null) {
throw new MissingActivationParameterException(NO_TOKEN);
}
return tcTokenRequest;
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenVerifier method checkUserCancellation.
private void checkUserCancellation() throws InvalidRedirectUrlException, InvalidTCTokenElement, UserCancellationException {
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
UserCancellationException ex = (UserCancellationException) dynCtx.get(TR03112Keys.CARD_SELECTION_CANCELLATION);
if (ex != null) {
determineRefreshAddress(ex);
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class RedirectCertificateValidator method validate.
@Override
public VerifierResult validate(URL url, TlsServerCertificate cert) throws ValidationError {
try {
// disable certificate checks according to BSI TR03112-7 in some situations
if (redirectChecks) {
CertificateDescription desc = (CertificateDescription) descPromise.derefNonblocking();
certDescExists = desc != null;
String host = url.getProtocol() + "://" + url.getHost() + (url.getPort() == -1 ? "" : (":" + url.getPort()));
// check points certificate (but just in case we have a certificate description)
if (certDescExists && !TR03112Utils.isInCommCertificates(cert, desc.getCommCertificates(), host)) {
LOG.error("The retrieved server certificate is NOT contained in the CommCertificates of " + "the CertificateDescription extension of the eService certificate.");
throw new ValidationError(INVALID_REDIRECT);
}
// check if we match the SOP
URL sopUrl;
if (certDescExists && desc.getSubjectURL() != null && !desc.getSubjectURL().isEmpty()) {
sopUrl = new URL(desc.getSubjectURL());
} else {
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
sopUrl = (URL) dynCtx.get(TR03112Keys.TCTOKEN_URL);
}
// on th efirst invocation this is the current URL, on the following invocations this is the last used
if (lastURL == null) {
lastURL = url;
}
// check SOP for last URL and update the URL
boolean SOP = TR03112Utils.checkSameOriginPolicy(lastURL, sopUrl);
lastURL = url;
if (!SOP) {
// there is more to come
return VerifierResult.CONTINUE;
} else {
// SOP fulfilled
return VerifierResult.FINISH;
}
} else {
// in that case its equally valid to let the browser do the redirects
return VerifierResult.FINISH;
}
} catch (MalformedURLException ex) {
throw new ValidationError(REDIRECT_MALFORMED_URL, ex);
}
}
Aggregations