use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenHandler method determineRefreshURL.
/**
* Follow the URL in the RefreshAddress and update it in the response.
* The redirect is followed as long as the response is a redirect (302, 303 or 307) AND is a
* https-URL AND the hash of the retrieved server certificate is contained in the CertificateDescrioption, else
* return 400. If the URL and the subjectURL in the CertificateDescription conform to the SOP we reached our final
* destination.
*
* @param request TCToken request used to determine which security checks to perform.
* @param response The TCToken response in which the original refresh address is defined and where it will be
* updated.
* @return Modified response with the final address the browser should be redirected to.
* @throws InvalidRedirectUrlException Thrown in case no redirect URL could be determined.
*/
private static TCTokenResponse determineRefreshURL(TCTokenRequest request, TCTokenResponse response) throws InvalidRedirectUrlException, SecurityViolationException {
try {
String endpointStr = response.getRefreshAddress();
URL endpoint = new URL(endpointStr);
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
// omit checks completely if this is an object tag activation
Object objectActivation = dynCtx.get(TR03112Keys.OBJECT_ACTIVATION);
if (objectActivation instanceof Boolean && ((Boolean) objectActivation) == true) {
return response;
}
// disable certificate checks according to BSI TR03112-7 in some situations
boolean redirectChecks = isPerformTR03112Checks(request);
RedirectCertificateValidator verifier = new RedirectCertificateValidator(redirectChecks);
ResourceContext ctx = ResourceContext.getStream(endpoint, verifier);
ctx.closeStream();
// using this verifier no result must be present, meaning no status code different than a redirect occurred
// if (result.p1 != null) {
// // TODO: this error is expected according the spec, handle it in a different way
// String msg = "Return-To-Websession yielded a non-redirect response.";
// throw new IOException(msg);
// }
// determine redirect
List<Pair<URL, TlsServerCertificate>> resultPoints = ctx.getCerts();
Pair<URL, TlsServerCertificate> last = resultPoints.get(resultPoints.size() - 1);
endpoint = last.p1;
dynCtx.put(TR03112Keys.IS_REFRESH_URL_VALID, true);
LOG.debug("Setting redirect address to '{}'.", endpoint);
response.setRefreshAddress(endpoint.toString());
return response;
} catch (MalformedURLException ex) {
throw new IllegalStateException(LANG_TR.translationForKey(REFRESH_URL_ERROR), ex);
} catch (ResourceException | InvalidAddressException | ValidationError | IOException ex) {
String code = ECardConstants.Minor.App.COMMUNICATION_ERROR;
String communicationErrorAddress = response.getTCToken().getComErrorAddressWithParams(code);
if (communicationErrorAddress != null && !communicationErrorAddress.isEmpty()) {
throw new SecurityViolationException(communicationErrorAddress, REFRESH_DETERMINATION_FAILED, ex);
}
throw new InvalidRedirectUrlException(REFRESH_DETERMINATION_FAILED, ex);
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenHandler method ensureHandleIsUsable.
private ConnectionHandleType ensureHandleIsUsable(ConnectionHandleType connectionHandle) throws WSException {
connectionHandle = prepareHandle(connectionHandle);
// save handle for later use
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
dynCtx.put(TR03112Keys.CONNECTION_HANDLE, HandlerUtils.copyHandle(connectionHandle));
return connectionHandle;
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenHandler method killUserConsent.
public static void killUserConsent() {
// kill any open dialog
DynamicContext ctx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
Object navObj = ctx.get(TR03112Keys.OPEN_USER_CONSENT_NAVIGATOR);
if (navObj instanceof UserConsentNavigator) {
UserConsentNavigator nav = (UserConsentNavigator) navObj;
nav.close();
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class TCTokenResponse method finishResponse.
/**
* Completes the response, so that it can be used in the binding.
* The values extended include result code, result message and the redirect address.
*
* @param clearContext If {@code true} then delete context. Keep it otherwise.
* @throws InvalidRedirectUrlException Thrown in case the error redirect URL could not be determined.
*/
public void finishResponse(boolean clearContext) throws InvalidRedirectUrlException {
try {
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
UrlBuilder ub = UrlBuilder.fromUrl(getRefreshAddress());
if (ECardConstants.Major.OK.equals(result.getResultMajor())) {
setResultCode(BindingResultCode.REDIRECT);
String refreshURL = ub.queryParam("ResultMajor", "ok").build().toString();
getAuxResultData().put(AuxDataKeys.REDIRECT_LOCATION, refreshURL);
} else {
boolean isRefreshAddressValid = (Boolean) dynCtx.get(TR03112Keys.IS_REFRESH_URL_VALID);
setResultCode(BindingResultCode.REDIRECT);
String refreshURL;
String fixedMinor = TCTokenHacks.fixResultMinor(result.getResultMinor());
if (isRefreshAddressValid) {
refreshURL = ub.queryParam("ResultMajor", "error").queryParamUrl("ResultMinor", fixedMinor).build().toString();
} else {
refreshURL = token.getComErrorAddressWithParams(result.getResultMinor());
}
getAuxResultData().put(AuxDataKeys.REDIRECT_LOCATION, refreshURL);
if (result.getResultMessage().getValue() != null) {
setResultMessage(result.getResultMessage().getValue());
}
}
// clear and remove the DynamicContext
if (!clearContext) {
dynCtx.clear();
DynamicContext.remove();
}
} catch (URISyntaxException ex) {
// TODO: translate when exception changes
throw new IllegalArgumentException(lang.getOriginalMessage(INVALID_URL), ex);
}
}
use of org.openecard.common.DynamicContext in project open-ecard by ecsec.
the class ActivateAction method processTcToken.
/**
* Process the tcTokenURL or the activation object and perform a authentication.
*
* @param params Parameters of the request.
* @return A {@link BindingResult} representing the result of the authentication.
*/
private BindingResult processTcToken(Map<String, String> params) {
BindingResult response;
DynamicContext dynCtx = DynamicContext.getInstance(TR03112Keys.INSTANCE_KEY);
dynCtx.put(TR03112Keys.COOKIE_MANAGER, new CookieManager());
try {
TCTokenRequest tcTokenRequest = null;
try {
tcTokenRequest = TCTokenRequest.convert(params, ctx);
response = tokenHandler.handleActivate(tcTokenRequest);
// Show success message. If we get here we have a valid StartPAOSResponse and a valid refreshURL
showFinishMessage((TCTokenResponse) response);
} catch (ActivationError ex) {
if (ex instanceof NonGuiException) {
// error already displayed to the user so do not repeat it here
} else {
if (ex.getMessage().equals("Invalid HTTP message received.")) {
showErrorMessage(lang.translationForKey(ACTIVATION_INVALID_REFRESH_ADDRESS));
} else {
showErrorMessage(ex.getLocalizedMessage());
}
}
LOG.error(ex.getMessage());
// stack trace only in debug level
LOG.debug(ex.getMessage(), ex);
LOG.debug("Returning result: \n{}", ex.getBindingResult());
if (ex instanceof FatalActivationError) {
LOG.info("Authentication failed, displaying error in Browser.");
} else {
LOG.info("Authentication failed, redirecting to with errors attached to the URL.");
}
response = ex.getBindingResult();
} finally {
if (tcTokenRequest != null && tcTokenRequest.getTokenContext() != null) {
// close connection to tctoken server in case PAOS didn't already perform this action
tcTokenRequest.getTokenContext().closeStream();
}
}
} catch (RuntimeException e) {
response = new BindingResult(BindingResultCode.INTERNAL_ERROR);
LOG.error(e.getMessage(), e);
}
return response;
}
Aggregations