diff options
| author | Jakob Heher <jakob.heher@iaik.tugraz.at> | 2022-10-03 17:36:36 +0200 | 
|---|---|---|
| committer | Jakob Heher <jakob.heher@iaik.tugraz.at> | 2022-10-03 17:36:36 +0200 | 
| commit | e2ab585fc4cfc165dc02ea9142f33dd308979e49 (patch) | |
| tree | 5ef74454e3b17dfe966d20dfe594f2259fd2a488 /pdf-over-gui/src/main | |
| parent | 58db0733866b26411c07b7b17e741663d2f1c438 (diff) | |
| download | pdf-over-e2ab585fc4cfc165dc02ea9142f33dd308979e49.tar.gz pdf-over-e2ab585fc4cfc165dc02ea9142f33dd308979e49.tar.bz2 pdf-over-e2ab585fc4cfc165dc02ea9142f33dd308979e49.zip | |
start untangling BKU handler from GUI logic
Diffstat (limited to 'pdf-over-gui/src/main')
14 files changed, 1156 insertions, 1121 deletions
| diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/LocalBKUConnector.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/LocalBKUConnector.java index ffd924f6..fe1e3a29 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/LocalBKUConnector.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/LocalBKUConnector.java @@ -69,7 +69,7 @@ public class LocalBKUConnector implements BkuSlConnector {  			HttpClient client = BKUHelper.getHttpClient();
  			PostMethod method = new PostMethod(Constants.LOCAL_BKU_URL);
 -			String sl_request = request.request;
 +			String sl_request = request.xmlRequest;
  			if (request.signatureData == null) {
  				method.addParameter("XMLRequest", sl_request);
  			} else {
 diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDMobileBKUConnector.java index c17451ed..a71f37df 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/MobileBKUConnector.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDMobileBKUConnector.java @@ -1,207 +1,207 @@ -/*
 - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
 - *
 - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 - * the European Commission - subsequent versions of the EUPL (the "Licence");
 - * You may not use this work except in compliance with the Licence.
 - * You may obtain a copy of the Licence at:
 - * http://joinup.ec.europa.eu/software/page/eupl
 - *
 - * Unless required by applicable law or agreed to in writing, software
 - * distributed under the Licence is distributed on an "AS IS" basis,
 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - * See the Licence for the specific language governing permissions and
 - * limitations under the Licence.
 - */
 -package at.asit.pdfover.gui.bku;
 -
 -// Imports
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -
 -import at.asit.pdfover.commons.Constants;
 -import at.asit.pdfover.gui.bku.mobile.ATrustHandler;
 -import at.asit.pdfover.gui.bku.mobile.ATrustStatus;
 -import at.asit.pdfover.gui.workflow.states.MobileBKUState;
 -import at.asit.pdfover.signer.BkuSlConnector;
 -import at.asit.pdfover.signer.SignatureException;
 -import at.asit.pdfover.signer.pdfas.PdfAs4SLRequest;
 -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState;
 -
 -/**
 - *
 - */
 -public class MobileBKUConnector implements BkuSlConnector {
 -	/**
 -	 * SLF4J Logger instance
 -	 **/
 -	private static final Logger log = LoggerFactory.getLogger(MobileBKUConnector.class);
 -
 -	private MobileBKUState state;
 -
 -	/**
 -	 *
 -	 * @param state
 -	 */
 -	public MobileBKUConnector(MobileBKUState state) {
 -		this.state = state;
 -	}
 -
 -	/** (non-Javadoc)
 -	 * @see at.asit.pdfover.signer.BkuSlConnector#handleSLRequest(java.lang.String)
 -	 */
 -	@Override
 -	public String handleSLRequest(PdfAs4SLRequest request) throws SignatureException {
 -		PdfAs4SigningState signingState = this.state.getSigningState();
 -		signingState.signatureRequest = request;
 -
 -		ATrustHandler handler = this.state.handler;
 -
 -		do {
 -			// Post SL Request
 -			try {
 -				String responseData = handler.postSLRequest(Constants.MOBILE_BKU_URL, request);
 -
 -				// Now we have received some data lets check it:
 -				log.trace("Response from mobile BKU: " + responseData);
 -
 -				handler.handleSLRequestResponse(responseData);
 -			} catch (Exception ex) {
 -				log.error("Error in PostSLRequestThread", ex);
 -				this.state.threadException = ex;
 -				this.state.displayError(ex);
 -				throw new SignatureException(ex);
 -			}
 -
 -			do {
 -				// Check if credentials are available, get them from user if not
 -				this.state.checkCredentials();
 -
 -				if (consumeCancelError())
 -					throw new SignatureException(new IllegalStateException());
 -
 -				// Post credentials
 -				try {
 -					String responseData = handler.postCredentials();
 -
 -					if (responseData.contains("undecided.aspx?sid=")) {
 -						// handle polling
 -						this.state.showOpenAppMessageWithSMSandCancel();
 -
 -						if (this.state.status.isSMSTan) {
 -							String response = handler.postSMSRequest();
 -							handler.handleCredentialsResponse(response);
 -						} else if (consumeCancelError()) {
 -							throw new SignatureException(new IllegalStateException());
 -						}
 -					} else {
 -
 -					    // Now we have received some data lets check it:
 -						log.trace("Response from mobile BKU: " + responseData);
 -						handler.handleCredentialsResponse(responseData);
 -					}
 -
 -				} catch (Exception ex) {
 -					log.error("Error in PostCredentialsThread", ex);
 -					this.state.threadException = new IllegalStateException();
 -					throw new SignatureException(new IllegalStateException());
 -				}
 -			} while(this.state.status.errorMessage != null);
 -
 -			// Check if response is already available
 -			if (signingState.signatureResponse != null) {
 -				String response = signingState.signatureResponse;
 -				signingState.signatureResponse = null;
 -				return response;
 -			}
 -
 -			do {
 -				ATrustStatus status = this.state.status;
 -				boolean enterTAN = true;
 -				String responseData = null;
 -				if (status.qrCodeURL != null) {
 -					this.state.showQR();
 -					if ("cancel".equals(this.state.status.errorMessage))
 -						throw new SignatureException(new IllegalStateException());
 -					if (status.qrCodeURL == null) {
 -						try {
 -							String response = handler.postSMSRequest();
 -							log.trace("Response from mobile BKU: " + response);
 -							handler.handleCredentialsResponse(response);
 -						} catch (Exception ex) {
 -							log.error("Error in PostCredentialsThread", ex);
 -							this.state.threadException = new IllegalStateException();
 -							throw new SignatureException(new IllegalStateException());
 -						}
 -					} else {
 -						enterTAN = false;
 -					}
 -				}
 -				if (enterTAN && !status.tanField) {
 -					try {
 -
 -						this.state.showFingerPrintInformation();
 -						if ("cancel".equals(this.state.status.errorMessage))
 -							throw new SignatureException(new IllegalStateException());
 -					} catch (Exception ex) {
 -						log.error("Error in PostCredentialsThread", ex);
 -						this.state.threadException = new IllegalStateException();
 -						//this.state.displayError(ex);
 -						throw new SignatureException(new IllegalStateException());
 -					}
 -
 -					if (this.state.getSMSStatus()) {
 -						String response;
 -						try {
 -							response = handler.postSMSRequest();
 -							handler.handleCredentialsResponse(response);
 -						} catch (Exception e) {
 -							log.error("Error in PostCredentialsThread", e);
 -							this.state.threadException = e;
 -							this.state.displayError(e);
 -							throw new SignatureException(e);
 -						}
 -					}
 -					else {
 -						enterTAN = false;
 -					}
 -				}
 -
 -				if (enterTAN) {
 -					// Get TAN
 -					this.state.checkTAN();
 -
 -					if ("cancel".equals(this.state.status.errorMessage))
 -						throw new SignatureException(new IllegalStateException());
 -
 -					// Post TAN
 -					try {
 -						responseData = handler.postTAN();
 -						log.trace("Response from mobile BKU: " + responseData);
 -
 -						// Now we have received some data lets check it:
 -						handler.handleTANResponse(responseData);
 -					} catch (Exception ex) {
 -						log.error("Error in PostTanThread", ex);
 -						this.state.threadException = ex;
 -						this.state.displayError(ex);
 -						throw new SignatureException(ex);
 -					}
 -				}
 -			} while (this.state.status.errorMessage != null);
 -			if (this.state.status.tanTries == -1)
 -				throw new SignatureException(new IllegalStateException());
 -		} while (this.state.status.tanTries == -2);
 -
 -		return signingState.signatureResponse;
 -	}
 -
 -	private boolean consumeCancelError() {
 -		if ("cancel".equals(this.state.status.errorMessage)) {
 -				this.state.status.errorMessage = null;
 -				return true;
 -		}
 -		return false;
 -	}
 -
 -}
 +/* + * Copyright 2012 by A-SIT, Secure Information Technology Center Austria + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + */ +package at.asit.pdfover.gui.bku; + +// Imports +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.commons.Constants; +import at.asit.pdfover.gui.bku.OLDmobile.ATrustHandler; +import at.asit.pdfover.gui.bku.OLDmobile.ATrustStatus; +import at.asit.pdfover.gui.workflow.states.MobileBKUState; +import at.asit.pdfover.signer.BkuSlConnector; +import at.asit.pdfover.signer.SignatureException; +import at.asit.pdfover.signer.pdfas.PdfAs4SLRequest; +import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; + +/** + * + */ +public class OLDMobileBKUConnector implements BkuSlConnector { +	/** +	 * SLF4J Logger instance +	 **/ +	private static final Logger log = LoggerFactory.getLogger(OLDMobileBKUConnector.class); + +	private MobileBKUState state; + +	/** +	 * +	 * @param state +	 */ +	public OLDMobileBKUConnector(MobileBKUState state) { +		this.state = state; +	} + +	/** (non-Javadoc) +	 * @see at.asit.pdfover.signer.BkuSlConnector#handleSLRequest(java.lang.String) +	 */ +	@Override +	public String handleSLRequest(PdfAs4SLRequest request) throws SignatureException { +		PdfAs4SigningState signingState = this.state.getSigningState(); +		signingState.signatureRequest = request; + +		ATrustHandler handler = this.state.handler; + +		do { +			// Post SL Request +			try { +				String responseData = handler.postSLRequest(Constants.MOBILE_BKU_URL.toString(), request); + +				// Now we have received some data lets check it: +				log.trace("Response from mobile BKU: " + responseData); + +				handler.handleSLRequestResponse(responseData); +			} catch (Exception ex) { +				log.error("Error in PostSLRequestThread", ex); +				this.state.threadException = ex; +				this.state.displayError(ex); +				throw new SignatureException(ex); +			} + +			do { +				// Check if credentials are available, get them from user if not +				this.state.checkCredentials(); + +				if (consumeCancelError()) +					throw new SignatureException(new IllegalStateException()); + +				// Post credentials +				try { +					String responseData = handler.postCredentials(); + +					if (responseData.contains("undecided.aspx?sid=")) { +						// handle polling +						this.state.showOpenAppMessageWithSMSandCancel(); + +						if (this.state.status.isSMSTan) { +							String response = handler.postSMSRequest(); +							handler.handleCredentialsResponse(response); +						} else if (consumeCancelError()) { +							throw new SignatureException(new IllegalStateException()); +						} +					} else { + +					    // Now we have received some data lets check it: +						log.trace("Response from mobile BKU: " + responseData); +						handler.handleCredentialsResponse(responseData); +					} + +				} catch (Exception ex) { +					log.error("Error in PostCredentialsThread", ex); +					this.state.threadException = new IllegalStateException(); +					throw new SignatureException(new IllegalStateException()); +				} +			} while(this.state.status.errorMessage != null); + +			// Check if response is already available +			if (signingState.signatureResponse != null) { +				String response = signingState.signatureResponse; +				signingState.signatureResponse = null; +				return response; +			} + +			do { +				ATrustStatus status = this.state.status; +				boolean enterTAN = true; +				String responseData = null; +				if (status.qrCodeURL != null) { +					this.state.showQR(); +					if ("cancel".equals(this.state.status.errorMessage)) +						throw new SignatureException(new IllegalStateException()); +					if (status.qrCodeURL == null) { +						try { +							String response = handler.postSMSRequest(); +							log.trace("Response from mobile BKU: " + response); +							handler.handleCredentialsResponse(response); +						} catch (Exception ex) { +							log.error("Error in PostCredentialsThread", ex); +							this.state.threadException = new IllegalStateException(); +							throw new SignatureException(new IllegalStateException()); +						} +					} else { +						enterTAN = false; +					} +				} +				if (enterTAN && !status.tanField) { +					try { + +						this.state.showFingerPrintInformation(); +						if ("cancel".equals(this.state.status.errorMessage)) +							throw new SignatureException(new IllegalStateException()); +					} catch (Exception ex) { +						log.error("Error in PostCredentialsThread", ex); +						this.state.threadException = new IllegalStateException(); +						//this.state.displayError(ex); +						throw new SignatureException(new IllegalStateException()); +					} + +					if (this.state.getSMSStatus()) { +						String response; +						try { +							response = handler.postSMSRequest(); +							handler.handleCredentialsResponse(response); +						} catch (Exception e) { +							log.error("Error in PostCredentialsThread", e); +							this.state.threadException = e; +							this.state.displayError(e); +							throw new SignatureException(e); +						} +					} +					else { +						enterTAN = false; +					} +				} + +				if (enterTAN) { +					// Get TAN +					this.state.checkTAN(); + +					if ("cancel".equals(this.state.status.errorMessage)) +						throw new SignatureException(new IllegalStateException()); + +					// Post TAN +					try { +						responseData = handler.postTAN(); +						log.trace("Response from mobile BKU: " + responseData); + +						// Now we have received some data lets check it: +						handler.handleTANResponse(responseData); +					} catch (Exception ex) { +						log.error("Error in PostTanThread", ex); +						this.state.threadException = ex; +						this.state.displayError(ex); +						throw new SignatureException(ex); +					} +				} +			} while (this.state.status.errorMessage != null); +			if (this.state.status.tanTries == -1) +				throw new SignatureException(new IllegalStateException()); +		} while (this.state.status.tanTries == -2); + +		return signingState.signatureResponse; +	} + +	private boolean consumeCancelError() { +		if ("cancel".equals(this.state.status.errorMessage)) { +				this.state.status.errorMessage = null; +				return true; +		} +		return false; +	} + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java index 8697399d..2e69e779 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustHandler.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java @@ -1,793 +1,793 @@ -/*
 - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
 - *
 - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 - * the European Commission - subsequent versions of the EUPL (the "Licence");
 - * You may not use this work except in compliance with the Licence.
 - * You may obtain a copy of the Licence at:
 - * http://joinup.ec.europa.eu/software/page/eupl
 - *
 - * Unless required by applicable law or agreed to in writing, software
 - * distributed under the Licence is distributed on an "AS IS" basis,
 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - * See the Licence for the specific language governing permissions and
 - * limitations under the Licence.
 - */
 -package at.asit.pdfover.gui.bku.mobile;
 -
 -// Imports
 -import java.awt.Desktop;
 -import java.io.BufferedInputStream;
 -import java.io.ByteArrayOutputStream;
 -import java.io.IOException;
 -import java.io.InputStream;
 -import java.net.URI;
 -import java.net.URL;
 -import java.util.regex.Matcher;
 -import java.util.regex.Pattern;
 -
 -import org.apache.commons.httpclient.Header;
 -import org.apache.commons.httpclient.HttpClient;
 -import org.apache.commons.httpclient.HttpException;
 -import org.apache.commons.httpclient.HttpStatus;
 -import org.apache.commons.httpclient.methods.GetMethod;
 -import org.apache.commons.httpclient.methods.PostMethod;
 -import org.apache.commons.httpclient.methods.multipart.FilePart;
 -import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
 -import org.apache.commons.httpclient.methods.multipart.Part;
 -import org.apache.commons.httpclient.methods.multipart.StringPart;
 -import org.apache.commons.io.IOUtils;
 -import org.eclipse.swt.SWT;
 -import org.eclipse.swt.program.Program;
 -import org.eclipse.swt.widgets.Display;
 -import org.eclipse.swt.widgets.Shell;
 -import org.jsoup.Jsoup;
 -import org.jsoup.nodes.Document;
 -import org.jsoup.nodes.Element;
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -
 -import com.google.gson.JsonElement;
 -import com.google.gson.JsonObject;
 -import com.google.gson.JsonParser;
 -
 -import at.asit.pdfover.commons.Constants;
 -import at.asit.pdfover.gui.controls.Dialog;
 -import at.asit.pdfover.gui.controls.Dialog.BUTTONS;
 -import at.asit.pdfover.gui.controls.Dialog.ICON;
 -import at.asit.pdfover.gui.exceptions.ATrustConnectionException;
 -import at.asit.pdfover.gui.utils.FileUploadSource;
 -import at.asit.pdfover.commons.Messages;
 -import at.asit.pdfover.gui.workflow.states.LocalBKUState;
 -import at.asit.pdfover.gui.workflow.states.MobileBKUState;
 -import at.asit.pdfover.signer.pdfas.PdfAs4SLRequest;
 -import at.asit.pdfover.signer.pdfas.PdfAs4SigningState;
 -
 -/**
 - * A-Trust mobile BKU handler
 - */
 -public class ATrustHandler {
 -	public final MobileBKUState state;
 -	public final Shell shell;
 -
 -	/**
 -	 * @param state
 -	 * @param shell
 -	 */
 -	public ATrustHandler(MobileBKUState state, Shell shell) {
 -		this.state = state;
 -		this.shell = shell;
 -	}
 -
 -	/**
 -	 * SLF4J Logger instance
 -	 **/
 -	static final Logger log = LoggerFactory.getLogger(ATrustHandler.class);
 -
 -	private static boolean expiryNoticeDisplayed = false;
 -
 -	private static final String ACTIVATION_URL = "https://www.handy-signatur.at/";
 -
 -	/**
 -	 * Get the MobileBKUStatus
 -	 * @return the MobileBKUStatus
 -	 */
 -	protected ATrustStatus getStatus() {
 -		return this.state.status;
 -	}
 -
 -	/**
 -	 * Get the SigningState
 -	 * @return the SigningState
 -	 */
 -	protected PdfAs4SigningState getSigningState() {
 -		return state.getSigningState();
 -	}
 -
 -	/**
 -	 * Execute a post to the mobile BKU, following redirects
 -	 * @param client the HttpClient
 -	 * @param post the PostMethod
 -	 * @return the response
 -	 * @throws IOException IO error
 -	 */
 -	protected String executePost(HttpClient client, PostMethod post) throws IOException {
 -		if (log.isDebugEnabled()) {
 -			String req;
 -			if (post.getRequestEntity().getContentLength() < 1024) {
 -				ByteArrayOutputStream os = new ByteArrayOutputStream();
 -				post.getRequestEntity().writeRequest(os);
 -				req = os.toString();
 -				if (req.contains("passwort="))
 -					req = req.replaceAll("passwort=[^&]*", "passwort=******");
 -				if (req.contains(":pwd="))
 -					req = req.replaceAll(":pwd=[^&]*", ":pwd=******");
 -				os.close();
 -			} else {
 -				req = post.getRequestEntity().getContentLength() + " bytes";
 -			}
 -			log.debug("Posting to " + post.getURI() + ": " + req);
 -		}
 -		int returnCode = client.executeMethod(post);
 -
 -		String redirectLocation = null;
 -		GetMethod get = null;
 -
 -
 -		String responseData = null;
 -
 -		String server = null;
 -
 -		// Follow redirects
 -		do {
 -			// check return code
 -			if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY ||
 -				returnCode == HttpStatus.SC_MOVED_PERMANENTLY) {
 -
 -				Header locationHeader = post.getResponseHeader("location");
 -				if (locationHeader != null) {
 -					redirectLocation = locationHeader.getValue();
 -				} else {
 -					throw new IOException(
 -							"Got HTTP 302 but no location to follow!");
 -				}
 -			} else if (returnCode == HttpStatus.SC_OK) {
 -				if (get != null) {
 -					responseData = get.getResponseBodyAsString();
 -					Header serverHeader = get.getResponseHeader(
 -							LocalBKUState.BKU_RESPONSE_HEADER_SERVER);
 -					if (serverHeader != null)
 -						server = serverHeader.getValue();
 -				} else {
 -					responseData = post.getResponseBodyAsString();
 -
 -					Header serverHeader = post.getResponseHeader(
 -							LocalBKUState.BKU_RESPONSE_HEADER_SERVER);
 -					if (serverHeader != null)
 -						server = serverHeader.getValue();
 -				}
 -				redirectLocation = null;
 -				String p = "<meta [^>]*http-equiv=\"refresh\" [^>]*content=\"([^\"]*)\"";
 -				Pattern pat = Pattern.compile(p);
 -				Matcher m = pat.matcher(responseData);
 -				if (m.find()) {
 -					String content = m.group(1);
 -					int start = content.indexOf("URL=");
 -					if (start != -1) {
 -						start += 9;
 -						redirectLocation  = content.substring(start, content.length() - 5);
 -					}
 -				}
 -			} else {
 -				throw new HttpException(
 -						HttpStatus.getStatusText(returnCode));
 -			}
 -
 -			if (redirectLocation != null) {
 -				redirectLocation = MobileBKUHelper.getQualifiedURL(redirectLocation, new URL(post.getURI().toString()));
 -				log.debug("Redirected to " + redirectLocation);
 -				get = new GetMethod(redirectLocation);
 -				get.setFollowRedirects(true);
 -				returnCode = client.executeMethod(get);
 -			}
 -		} while (redirectLocation != null);
 -
 -		getStatus().server = server;
 -		if (server != null)
 -			log.debug("Server: " + server);
 -
 -		return responseData;
 -	}
 -
 -	/**
 -	 * Execute a get from the mobile BKU, following redirects
 -	 * @param client the HttpClient
 -	 * @param get the GetMethod
 -	 * @return the response
 -	 * @throws IOException IO error
 -	 */
 -	protected String executeGet(HttpClient client, GetMethod get) throws IOException {
 -		log.debug("Getting " + get.getURI());
 -
 -		int returnCode = client.executeMethod(get);
 -
 -		String redirectLocation = null;
 -
 -		GetMethod get2 = null;
 -
 -		String responseData = null;
 -
 -		String server = null;
 -
 -		// Follow redirects
 -		do {
 -			// check return code
 -			if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY ||
 -				returnCode == HttpStatus.SC_MOVED_PERMANENTLY) {
 -
 -				Header locationHeader = get.getResponseHeader("location");
 -				if (locationHeader != null) {
 -					redirectLocation = locationHeader.getValue();
 -				} else {
 -					throw new IOException(
 -							"Got HTTP 302 but no location to follow!");
 -				}
 -			} else if (returnCode == HttpStatus.SC_OK) {
 -				if (get2 != null) {
 -					responseData = get2.getResponseBodyAsString();
 -					Header serverHeader = get2.getResponseHeader(
 -							LocalBKUState.BKU_RESPONSE_HEADER_SERVER);
 -					if (serverHeader != null)
 -						server = serverHeader.getValue();
 -				} else {
 -					responseData = get.getResponseBodyAsString();
 -
 -					Header serverHeader = get.getResponseHeader(
 -							LocalBKUState.BKU_RESPONSE_HEADER_SERVER);
 -					if (serverHeader != null)
 -						server = serverHeader.getValue();
 -				}
 -				redirectLocation = null;
 -				String p = "<meta [^>]*http-equiv=\"refresh\" [^>]*content=\"([^\"]*)\"";
 -				Pattern pat = Pattern.compile(p);
 -				Matcher m = pat.matcher(responseData);
 -				if (m.find()) {
 -					String content = m.group(1);
 -					int start = content.indexOf("URL=");
 -					if (start != -1) {
 -						start += 9;
 -						redirectLocation  = content.substring(start, content.length() - 5);
 -					}
 -				}
 -			} else {
 -				throw new HttpException(
 -						HttpStatus.getStatusText(returnCode));
 -			}
 -
 -			if (redirectLocation != null) {
 -				redirectLocation = MobileBKUHelper.getQualifiedURL(redirectLocation, new URL(get.getURI().toString()));
 -				log.debug("Redirected to " + redirectLocation);
 -				get2 = new GetMethod(redirectLocation);
 -				get2.setFollowRedirects(true);
 -				returnCode = client.executeMethod(get2);
 -			}
 -		} while (redirectLocation != null);
 -
 -		getStatus().server = server;
 -		if (server != null)
 -			log.debug("Server: " + server);
 -
 -		return responseData;
 -	}
 -
 -	/**
 -	 * Post the SL request
 -	 * @param mobileBKUUrl mobile BKU URL
 -	 * @param request SLRequest
 -	 * @return the response
 -	 * @throws IOException IO error
 -	 */
 -	public String postSLRequest(String mobileBKUUrl, PdfAs4SLRequest request) throws IOException {
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		PostMethod post = new PostMethod(mobileBKUUrl);
 -		String sl_request;
 -		if (request.signatureData != null) {
 -			sl_request = request.request;
 -			StringPart xmlpart = new StringPart(
 -					"XMLRequest", sl_request, "UTF-8");
 -
 -			FilePart filepart = new FilePart("fileupload",
 -					new FileUploadSource(request.signatureData),
 -					"application/pdf", "UTF-8");
 -
 -			Part[] parts = { xmlpart, filepart };
 -
 -			post.setRequestEntity(new MultipartRequestEntity(parts, post
 -					.getParams()));
 -		} else {
 -			sl_request = request.request;
 -			post.addParameter("XMLRequest", sl_request);
 -		}
 -		log.trace("SL Request: " + sl_request);
 -
 -		state.status.baseURL = MobileBKUHelper.stripQueryString(mobileBKUUrl);
 -
 -		return executePost(client, post);
 -	}
 -
 -	/* (non-Javadoc)
 -	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleSLRequestResponse(java.lang.String)
 -	 */
 -	public void handleSLRequestResponse(String responseData) throws Exception {
 -		ATrustStatus status = getStatus();
 -
 -		if (responseData.contains("<sl:ErrorResponse")) {
 -			String errorCode = MobileBKUHelper.extractSubstring(responseData,
 -					"<sl:ErrorCode>", "</sl:ErrorCode>");
 -			String errorMsg = MobileBKUHelper.extractSubstring(responseData,
 -					"<sl:Info>", "</sl:Info>");
 -			throw new Exception("Error from mobile BKU: " +
 -					errorCode + " - " + errorMsg);
 -		}
 -
 -		// Extract infos:
 -		String sessionID = MobileBKUHelper.extractSubstring(responseData,
 -				"identification.aspx?sid=", "\"");
 -
 -		String viewState = MobileBKUHelper.extractValueFromTagWithParam(
 -				responseData, "", "id", "__VIEWSTATE", "value");
 -
 -		String eventValidation = MobileBKUHelper.extractValueFromTagWithParam(
 -				responseData, "", "id", "__EVENTVALIDATION", "value");
 -
 -		String viewstateGenerator = MobileBKUHelper.extractValueFromTagWithParamOptional(responseData, "", "id", "__VIEWSTATEGENERATOR", "value");
 -
 -		String dynamicAttrPhonenumber = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_PHONE_NUMBER);
 -		String dynamicAttrPassword = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_PASS);
 -		String dynamicAttrButtonId = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_BTN_IDF);
 -		String dynamicAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN);
 -
 -
 -		log.debug("sessionID: " + sessionID);
 -		log.debug("viewState: " + viewState);
 -		log.debug("eventValidation: " + eventValidation);
 -
 -		status.sessionID = sessionID;
 -		status.viewState = viewState;
 -		status.eventValidation = eventValidation;
 -		if (viewstateGenerator != null ) { status.viewStateGenerator = viewstateGenerator; }
 -		status.dynAttrPhoneNumber = dynamicAttrPhonenumber;
 -		status.dynAttrPassword = dynamicAttrPassword;
 -		status.dynAttrBtnId = dynamicAttrButtonId;
 -		status.dynAttrTan = dynamicAttrTan;
 -	}
 -
 -	/* (non-Javadoc)
 -	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#postCredentials()
 -	 */
 -	public String postCredentials() throws IOException {
 -		ATrustStatus status = getStatus();
 -
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		PostMethod post = new PostMethod(status.baseURL + "/identification.aspx?sid=" + status.sessionID);
 -		post.getParams().setContentCharset("utf-8");
 -		post.addParameter("__VIEWSTATE", status.viewState);
 -		post.addParameter("__VIEWSTATEGENERATOR", status.viewStateGenerator);
 -		post.addParameter("__EVENTVALIDATION", status.eventValidation);
 -		post.addParameter(status.dynAttrPhoneNumber, status.phoneNumber);
 -		post.addParameter(status.dynAttrPassword, status.mobilePassword);
 -		post.addParameter(status.dynAttrBtnId, "Identifizieren");
 -
 -		return executePost(client, post);
 -	}
 -
 -	/* (non-Javadoc)
 -	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleCredentialsResponse(java.lang.String)
 -	 */
 -	public void handleCredentialsResponse(final String responseData) throws Exception {
 -		ATrustStatus status = getStatus();
 -		String viewState = status.viewState;
 -		String eventValidation = status.eventValidation;
 -		String sessionID = status.sessionID;
 -		String refVal = null;
 -		String signatureDataURL = null;
 -		String viewstateGenerator = status.viewStateGenerator;
 -
 -		status.errorMessage = null;
 -
 -		final Document responseDocument = Jsoup.parse(responseData);
 -
 -		if (responseData.contains("ExpiresInfo.aspx?sid=")) {
 -			// Certificate expiration interstitial - skip
 -			if (!expiryNoticeDisplayed) {
 -				Display.getDefault().syncExec(()->  {
 -					Dialog d = new Dialog(ATrustHandler.this.shell, Messages.getString("common.info"), Messages.getString("mobileBKU.certExpiresSoon"), BUTTONS.YES_NO, ICON.WARNING);
 -					if (d.open() == SWT.YES) {
 -						log.debug("Trying to open " + ACTIVATION_URL);
 -						if (Desktop.isDesktopSupported()) {
 -							try {
 -								Desktop.getDesktop().browse(new URI(ACTIVATION_URL));
 -								return;
 -							} catch (Exception e) {
 -								log.debug("Error opening URL", e);
 -							}
 -						}
 -						log.info("SWT Desktop is not supported on this platform");
 -						Program.launch(ACTIVATION_URL);
 -					}
 -				});
 -				expiryNoticeDisplayed = true;
 -			}
 -
 -			String t_sessionID = MobileBKUHelper.extractSubstring(responseData, "ExpiresInfo.aspx?sid=", "\"");
 -			String t_viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value");
 -			String t_eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value");
 -
 -			// Post again to skip
 -			MobileBKUHelper.registerTrustedSocketFactory();
 -			HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -			PostMethod post = new PostMethod(status.baseURL + "/ExpiresInfo.aspx?sid=" + t_sessionID);
 -			post.getParams().setContentCharset("utf-8");
 -			post.addParameter("__VIEWSTATE", t_viewState);
 -			post.addParameter("__EVENTVALIDATION", t_eventValidation);
 -			post.addParameter("Button_Next", "Weiter");
 -
 -			handleCredentialsResponse(executePost(client, post));
 -			return;
 -		} else if (responseData.contains("tanAppInfo.aspx?sid=")) {
 -			// App info interstitial - skip
 -			log.info("Skipping tan app interstitial");
 -
 -			String t_sessionID = MobileBKUHelper.extractSubstring(responseData, "tanAppInfo.aspx?sid=", "\"");
 -			String t_viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value");
 -			String t_eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value");
 -
 -			// Post again to skip
 -			MobileBKUHelper.registerTrustedSocketFactory();
 -			HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -			PostMethod post = new PostMethod(status.baseURL + "/tanAppInfo.aspx?sid=" + t_sessionID);
 -			post.getParams().setContentCharset("utf-8");
 -			post.addParameter("__VIEWSTATE", t_viewState);
 -			post.addParameter("__EVENTVALIDATION", t_eventValidation);
 -			post.addParameter("NextBtn", "Weiter");
 -
 -			handleCredentialsResponse(executePost(client, post));
 -			return;
 -		}
 -
 -		if (responseData.contains("signature.aspx?sid=")) {
 -			// credentials ok! TAN entry
 -			state.rememberCredentialsIfNecessary();
 -			log.debug("Credentials accepted - TAN required");
 -			sessionID = MobileBKUHelper.extractSubstring(responseData, "signature.aspx?sid=", "\"");
 -			viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value");
 -			eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value");
 -			refVal = MobileBKUHelper.extractSubstring(responseData, "id='vergleichswert'><b>Vergleichswert:</b>", "</div>");
 -			signatureDataURL = status.baseURL + "/ShowSigobj.aspx" +
 -					MobileBKUHelper.extractSubstring(responseData, "ShowSigobj.aspx", "'");
 -			try {
 -				String qrCode = MobileBKUHelper.extractValueFromTagWithParam(responseData, "img", "class", "qrcode", "src");
 -				log.debug("QR Code found: " + qrCode);
 -				status.qrCodeURL = qrCode;
 -			} catch (Exception e) {
 -				log.debug("No QR Code found");
 -			}
 -			try {
 -				String tanTextTan = MobileBKUHelper.extractValueFromTagWithParam(responseData, "label", "id", "label_for_input_tan", "for");
 -				status.tanField = tanTextTan.equals("input_tan");
 -				status.dynAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN);
 -				status.dynAttrSignButton = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_BTN);
 -			} catch (Exception e) {
 -				log.debug("No tan field found");
 -			}
 -			try {
 -				String tanTextTan = MobileBKUHelper.extractContentFromTagWithParam(responseData, "span", "id", "text_tan");
 -				status.isAPPTan = !tanTextTan.toLowerCase().contains("sms");
 -				status.dynAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN);
 -				status.dynAttrSignButton = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_BTN);
 -			}catch (Exception e) {
 -				log.debug("No text_tan tag");
 -			}
 -			try {
 -				String webauthnLink = MobileBKUHelper.extractValueFromTagWithParam(responseData, "a", "id", "FidoButton", "href");
 -				log.info("Webauthn link: {}", webauthnLink);
 -			} catch (Exception e) {
 -				log.info("No webauthnLink");
 -			}
 -			try {
 -				String webauthnData = MobileBKUHelper.extractValueFromTagWithParam(responseData, "input", "id", "credentialOptions", "value");
 -				log.info("Fido credential options: {}", webauthnData);
 -			} catch (Exception e) {
 -				log.info("No webauthnData");
 -			}
 -
 -		} else if (responseData.contains("sl:InfoboxReadResponse")) {
 -			// credentials ok! InfoboxReadResponse
 -			state.rememberCredentialsIfNecessary();
 -			log.debug("Credentials accepted - Response given");
 -			getSigningState().signatureResponse = responseData;
 -			return;
 -		} else if (responseData.contains("undecided.aspx?sid=")) {
 -			// skip intermediate page
 -			log.debug("Page Undecided");
 -			getSigningState().signatureResponse = responseData;
 -			status.errorMessage = "waiting..."; // TODO: this looks incorrect...?
 -			return;
 -		}else {
 -			// error page
 -
 -			// force UI again!
 -			state.clearRememberedCredentials();
 -			// extract error text!
 -			try {
 -				String errorMessage = MobileBKUHelper.extractContentFromTagWithParam(responseData, "span", "id", "Label1");
 -				if (errorMessage.startsWith("Fehler: "))
 -					errorMessage = errorMessage.substring(8);
 -				status.errorMessage = errorMessage.strip();
 -			} catch (Exception e) {
 -				log.error("Failed to get credentials error message", e);
 -				String msg = null;
 -				try
 -				{
 -					msg = MobileBKUHelper.extractSubstring(responseData, "<sl:ErrorCode>", "</sl:ErrorCode>") + ": " +
 -					  MobileBKUHelper.extractSubstring(responseData, "<sl:Info>", "</sl:Info>");
 -				} catch (Exception e2) {
 -					log.error("Failed to get credentials error code", e2);
 -					msg = Messages.getString("error.Unexpected");
 -				}
 -				status.errorMessage = msg.strip();
 -			}
 -		}
 -
 -		log.debug("sessionID: " + sessionID);
 -		log.debug("Vergleichswert: " + refVal);
 -		log.debug("viewState: " + viewState);
 -		log.debug("eventValidation: " + eventValidation);
 -		log.debug("signatureDataURL: " + signatureDataURL);
 -
 -		status.sessionID = sessionID;
 -		status.refVal = refVal;
 -		status.viewState = viewState;
 -		status.eventValidation = eventValidation;
 -		status.signatureDataURL = signatureDataURL;
 -		status.viewStateGenerator = viewstateGenerator;
 -	}
 -
 -	/* (non-Javadoc)
 -	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#postTAN()
 -	 */
 -	public String postTAN() throws IOException {
 -		ATrustStatus status = getStatus();
 -
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		PostMethod post = new PostMethod(status.baseURL
 -				+ "/signature.aspx?sid=" + status.sessionID);
 -		post.getParams().setContentCharset("utf-8");
 -		post.addParameter("__VIEWSTATE", status.viewState);
 -		post.addParameter(
 -				"__EVENTVALIDATION", status.eventValidation);
 -		post.addParameter(status.dynAttrTan, status.tan);
 -		post.addParameter(status.dynAttrSignButton, "Signieren");
 -		post.addParameter("Button1", "Identifizieren");
 -
 -		return executePost(client, post);
 -	}
 -
 -	/* (non-Javadoc)
 -	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleTANResponse(java.lang.String)
 -	 */
 -	public void handleTANResponse(String responseData) {
 -		getStatus().errorMessage = null;
 -		if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl") ||
 -		    responseData.contains("sl:CreateCMSSignatureResponse xmlns:sl")) {
 -			// success !!
 -
 -			getSigningState().signatureResponse = responseData;
 -		} else {
 -			try {
 -				String tries = MobileBKUHelper.extractSubstring(
 -						responseData, "Sie haben noch", "Versuch");
 -				getStatus().tanTries = Integer.parseInt(tries.trim());
 -				getStatus().errorMessage = "mobileBKU.wrong_tan";
 -			} catch (Exception e) {
 -				getStatus().tanTries = (getStatus().tanTries - 1);
 -				log.debug("Error parsing TAN response", e);
 -			}
 -
 -			if (getStatus().tanTries <= 0) {
 -				getStatus().errorMessage = null;
 -				Display.getDefault().syncExec(() -> {
 -					Dialog dialog = new Dialog(ATrustHandler.this.shell, Messages.getString("common.warning"),
 -							Messages.getString("mobileBKU.tan_tries_exceeded"),
 -							BUTTONS.OK_CANCEL, ICON.QUESTION);
 -
 -					// TODO: THIS IS A COLOSSAL HACK
 -					if (dialog.open() == SWT.CANCEL) {
 -						// Go back to BKU Selection
 -						getStatus().tanTries = -1;
 -					} else {
 -						// Start signature process over
 -						getStatus().tanTries = -2;
 -					}
 -				});
 -			}
 -		}
 -	}
 -
 -	/**
 -	 * Cancel QR process, request SMS TAN
 -	 * @return the response
 -	 * @throws IOException Error during posting
 -	 */
 -	public String postSMSRequest() throws IOException {
 -		ATrustStatus status = getStatus();
 -
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		GetMethod get = new GetMethod(status.baseURL
 -				+ "/sendsms.aspx?sid=" + status.sessionID);
 -		get.getParams().setContentCharset("utf-8");
 -
 -		return executeGet(client, get);
 -	}
 -
 -	/**
 -	 * Get the QR code image
 -	 * @return the QR code image as a String
 -	 */
 -	public InputStream getQRCode() {
 -		//TODO: Update HTTPClient here
 -
 -		ATrustStatus status = getStatus();
 -
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		GetMethod get = new GetMethod(status.baseURL + "/" + status.qrCodeURL);
 -
 -		try {
 -			log.debug("Getting " + get.getURI());
 -			int returnCode = client.executeMethod(get);
 -
 -			if (returnCode != HttpStatus.SC_OK) {
 -				log.error("Error getting QR code");
 -				return null;
 -			}
 -
 -			return get.getResponseBodyAsStream();
 -		} catch (Exception e) {
 -			log.error("Error getting QR code", e);
 -			return null;
 -		}
 -	}
 -
 -	/**
 -	 * Get Signature page after scanning QR code
 -	 * @return the response
 -	 * @throws IOException Error during get
 -	 */
 -	public String getSignaturePage() throws IOException {
 -		ATrustStatus status = getStatus();
 -
 -		MobileBKUHelper.registerTrustedSocketFactory();
 -		HttpClient client = MobileBKUHelper.getHttpClient(getStatus());
 -
 -		//TODO check
 -		//String baseURL = "https://www.a-trust.at/mobile/https-security-layer-request";
 -		GetMethod get = new GetMethod(status.baseURL
 -				+ "/signature.aspx?sid=" + status.sessionID);
 -
 -		return executeGet(client, get);
 -	}
 -
 -	/**
 -	 * Parse QR code response
 -	 * @param responseData
 -	 * @return whether a SL response was received
 -	 */
 -	public boolean handleQRResponse(String responseData) {
 -		getStatus().errorMessage = null;
 -		if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl") ||
 -		    responseData.contains("sl:CreateCMSSignatureResponse xmlns:sl")) {
 -			// success !!
 -
 -			getSigningState().signatureResponse = responseData;
 -			return true;
 -		}
 -		return false;
 -	}
 -
 -	/*
 -	 * (non-Javadoc)
 -	 *
 -	 */
 -	public boolean handlePolling() throws ATrustConnectionException {
 -
 -		ATrustStatus status = getStatus();
 -		String isReady = null;
 -		Status serverStatus = null;
 -		HttpClient client;
 -		try {
 -			do {
 -				client = MobileBKUHelper.getHttpClient(getStatus());
 -				String uri = status.baseURL  + "/UndecidedPolling.aspx?sid=" + status.sessionID;
 -				GetMethod get = new GetMethod(uri);
 -
 -				//client.setTimeout(35000);
 -				//client.setConnectionTimeout(35000);
 -				get.addRequestHeader("Accept", "application/json, text/javascript");
 -				get.addRequestHeader("Connection", "keep-alive");
 -				get.addRequestHeader("Referer", uri);
 -
 -
 -				client.executeMethod(get);
 -				InputStream in = new BufferedInputStream(get.getResponseBodyAsStream());
 -
 -				isReady = IOUtils.toString(in, "utf-8");
 -				serverStatus = new Status(isReady);
 -
 -				if (serverStatus.isFin()) {
 -					return true;
 -				} else if (serverStatus.isError()) {
 -					log.error("A-Trust returned Error code during polling");
 -					throw new ATrustConnectionException();
 -				}
 -
 -			} while (serverStatus.isWait());
 -
 -			if (serverStatus.isFin()) {
 -				return true;
 -			}
 -			//else error
 -			status.errorMessage = "Server reponded ERROR during polling";
 -			log.error("Server reponded ERROR during polling");
 -			throw new ATrustConnectionException();
 -
 -		} catch (Exception e) {
 -			log.error("handle polling failed" + e.getMessage());
 -			throw new ATrustConnectionException();
 -		}
 -	}
 -
 -	private class Status {
 -		private final boolean fin;
 -		private final boolean error;
 -		private final boolean wait;
 -
 -		public Status(String status) {
 -			 JsonElement jelement = JsonParser.parseString(status.toLowerCase());
 -			 JsonObject  jobject = jelement.getAsJsonObject();
 -			 this.fin = jobject.get("fin").getAsBoolean();
 -			 this.error = jobject.get("error").getAsBoolean();
 -			 this.wait = jobject.get("wait").getAsBoolean();
 -		}
 -
 -		public boolean isFin() {
 -			return fin;
 -		}
 -
 -		public boolean isError() {
 -			return error;
 -		}
 -
 -		public boolean isWait() {
 -			return wait;
 -		}
 -
 -
 -
 -
 -	}
 -
 -}
 -
 -
 +/* + * Copyright 2012 by A-SIT, Secure Information Technology Center Austria + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + */ +package at.asit.pdfover.gui.bku.OLDmobile; + +// Imports +import java.awt.Desktop; +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.multipart.FilePart; +import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; +import org.apache.commons.httpclient.methods.multipart.Part; +import org.apache.commons.httpclient.methods.multipart.StringPart; +import org.apache.commons.io.IOUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.program.Program; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import at.asit.pdfover.commons.Constants; +import at.asit.pdfover.gui.controls.Dialog; +import at.asit.pdfover.gui.controls.Dialog.BUTTONS; +import at.asit.pdfover.gui.controls.Dialog.ICON; +import at.asit.pdfover.gui.exceptions.ATrustConnectionException; +import at.asit.pdfover.gui.utils.FileUploadSource; +import at.asit.pdfover.commons.Messages; +import at.asit.pdfover.gui.workflow.states.LocalBKUState; +import at.asit.pdfover.gui.workflow.states.MobileBKUState; +import at.asit.pdfover.signer.pdfas.PdfAs4SLRequest; +import at.asit.pdfover.signer.pdfas.PdfAs4SigningState; + +/** + * A-Trust mobile BKU handler + */ +public class ATrustHandler { +	public final MobileBKUState state; +	public final Shell shell; + +	/** +	 * @param state +	 * @param shell +	 */ +	public ATrustHandler(MobileBKUState state, Shell shell) { +		this.state = state; +		this.shell = shell; +	} + +	/** +	 * SLF4J Logger instance +	 **/ +	static final Logger log = LoggerFactory.getLogger(ATrustHandler.class); + +	private static boolean expiryNoticeDisplayed = false; + +	private static final String ACTIVATION_URL = "https://www.handy-signatur.at/"; + +	/** +	 * Get the MobileBKUStatus +	 * @return the MobileBKUStatus +	 */ +	protected ATrustStatus getStatus() { +		return this.state.status; +	} + +	/** +	 * Get the SigningState +	 * @return the SigningState +	 */ +	protected PdfAs4SigningState getSigningState() { +		return state.getSigningState(); +	} + +	/** +	 * Execute a post to the mobile BKU, following redirects +	 * @param client the HttpClient +	 * @param post the PostMethod +	 * @return the response +	 * @throws IOException IO error +	 */ +	protected String executePost(HttpClient client, PostMethod post) throws IOException { +		if (log.isDebugEnabled()) { +			String req; +			if (post.getRequestEntity().getContentLength() < 1024) { +				ByteArrayOutputStream os = new ByteArrayOutputStream(); +				post.getRequestEntity().writeRequest(os); +				req = os.toString(); +				if (req.contains("passwort=")) +					req = req.replaceAll("passwort=[^&]*", "passwort=******"); +				if (req.contains(":pwd=")) +					req = req.replaceAll(":pwd=[^&]*", ":pwd=******"); +				os.close(); +			} else { +				req = post.getRequestEntity().getContentLength() + " bytes"; +			} +			log.debug("Posting to " + post.getURI() + ": " + req); +		} +		int returnCode = client.executeMethod(post); + +		String redirectLocation = null; +		GetMethod get = null; + + +		String responseData = null; + +		String server = null; + +		// Follow redirects +		do { +			// check return code +			if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY || +				returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + +				Header locationHeader = post.getResponseHeader("location"); +				if (locationHeader != null) { +					redirectLocation = locationHeader.getValue(); +				} else { +					throw new IOException( +							"Got HTTP 302 but no location to follow!"); +				} +			} else if (returnCode == HttpStatus.SC_OK) { +				if (get != null) { +					responseData = get.getResponseBodyAsString(); +					Header serverHeader = get.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} else { +					responseData = post.getResponseBodyAsString(); + +					Header serverHeader = post.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} +				redirectLocation = null; +				String p = "<meta [^>]*http-equiv=\"refresh\" [^>]*content=\"([^\"]*)\""; +				Pattern pat = Pattern.compile(p); +				Matcher m = pat.matcher(responseData); +				if (m.find()) { +					String content = m.group(1); +					int start = content.indexOf("URL="); +					if (start != -1) { +						start += 9; +						redirectLocation  = content.substring(start, content.length() - 5); +					} +				} +			} else { +				throw new HttpException( +						HttpStatus.getStatusText(returnCode)); +			} + +			if (redirectLocation != null) { +				redirectLocation = MobileBKUHelper.getQualifiedURL(redirectLocation, new URL(post.getURI().toString())); +				log.debug("Redirected to " + redirectLocation); +				get = new GetMethod(redirectLocation); +				get.setFollowRedirects(true); +				returnCode = client.executeMethod(get); +			} +		} while (redirectLocation != null); + +		getStatus().server = server; +		if (server != null) +			log.debug("Server: " + server); + +		return responseData; +	} + +	/** +	 * Execute a get from the mobile BKU, following redirects +	 * @param client the HttpClient +	 * @param get the GetMethod +	 * @return the response +	 * @throws IOException IO error +	 */ +	protected String executeGet(HttpClient client, GetMethod get) throws IOException { +		log.debug("Getting " + get.getURI()); + +		int returnCode = client.executeMethod(get); + +		String redirectLocation = null; + +		GetMethod get2 = null; + +		String responseData = null; + +		String server = null; + +		// Follow redirects +		do { +			// check return code +			if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY || +				returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + +				Header locationHeader = get.getResponseHeader("location"); +				if (locationHeader != null) { +					redirectLocation = locationHeader.getValue(); +				} else { +					throw new IOException( +							"Got HTTP 302 but no location to follow!"); +				} +			} else if (returnCode == HttpStatus.SC_OK) { +				if (get2 != null) { +					responseData = get2.getResponseBodyAsString(); +					Header serverHeader = get2.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} else { +					responseData = get.getResponseBodyAsString(); + +					Header serverHeader = get.getResponseHeader( +							LocalBKUState.BKU_RESPONSE_HEADER_SERVER); +					if (serverHeader != null) +						server = serverHeader.getValue(); +				} +				redirectLocation = null; +				String p = "<meta [^>]*http-equiv=\"refresh\" [^>]*content=\"([^\"]*)\""; +				Pattern pat = Pattern.compile(p); +				Matcher m = pat.matcher(responseData); +				if (m.find()) { +					String content = m.group(1); +					int start = content.indexOf("URL="); +					if (start != -1) { +						start += 9; +						redirectLocation  = content.substring(start, content.length() - 5); +					} +				} +			} else { +				throw new HttpException( +						HttpStatus.getStatusText(returnCode)); +			} + +			if (redirectLocation != null) { +				redirectLocation = MobileBKUHelper.getQualifiedURL(redirectLocation, new URL(get.getURI().toString())); +				log.debug("Redirected to " + redirectLocation); +				get2 = new GetMethod(redirectLocation); +				get2.setFollowRedirects(true); +				returnCode = client.executeMethod(get2); +			} +		} while (redirectLocation != null); + +		getStatus().server = server; +		if (server != null) +			log.debug("Server: " + server); + +		return responseData; +	} + +	/** +	 * Post the SL request +	 * @param mobileBKUUrl mobile BKU URL +	 * @param request SLRequest +	 * @return the response +	 * @throws IOException IO error +	 */ +	public String postSLRequest(String mobileBKUUrl, PdfAs4SLRequest request) throws IOException { +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		PostMethod post = new PostMethod(mobileBKUUrl); +		String sl_request; +		if (request.signatureData != null) { +			sl_request = request.xmlRequest; +			StringPart xmlpart = new StringPart( +					"XMLRequest", sl_request, "UTF-8"); + +			FilePart filepart = new FilePart("fileupload", +					new FileUploadSource(request.signatureData), +					"application/pdf", "UTF-8"); + +			Part[] parts = { xmlpart, filepart }; + +			post.setRequestEntity(new MultipartRequestEntity(parts, post +					.getParams())); +		} else { +			sl_request = request.xmlRequest; +			post.addParameter("XMLRequest", sl_request); +		} +		log.trace("SL Request: " + sl_request); + +		state.status.baseURL = MobileBKUHelper.stripQueryString(mobileBKUUrl); + +		return executePost(client, post); +	} + +	/* (non-Javadoc) +	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleSLRequestResponse(java.lang.String) +	 */ +	public void handleSLRequestResponse(String responseData) throws Exception { +		ATrustStatus status = getStatus(); + +		if (responseData.contains("<sl:ErrorResponse")) { +			String errorCode = MobileBKUHelper.extractSubstring(responseData, +					"<sl:ErrorCode>", "</sl:ErrorCode>"); +			String errorMsg = MobileBKUHelper.extractSubstring(responseData, +					"<sl:Info>", "</sl:Info>"); +			throw new Exception("Error from mobile BKU: " + +					errorCode + " - " + errorMsg); +		} + +		// Extract infos: +		String sessionID = MobileBKUHelper.extractSubstring(responseData, +				"identification.aspx?sid=", "\""); + +		String viewState = MobileBKUHelper.extractValueFromTagWithParam( +				responseData, "", "id", "__VIEWSTATE", "value"); + +		String eventValidation = MobileBKUHelper.extractValueFromTagWithParam( +				responseData, "", "id", "__EVENTVALIDATION", "value"); + +		String viewstateGenerator = MobileBKUHelper.extractValueFromTagWithParamOptional(responseData, "", "id", "__VIEWSTATEGENERATOR", "value"); + +		String dynamicAttrPhonenumber = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_PHONE_NUMBER); +		String dynamicAttrPassword = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_PASS); +		String dynamicAttrButtonId = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_BTN_IDF); +		String dynamicAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN); + + +		log.debug("sessionID: " + sessionID); +		log.debug("viewState: " + viewState); +		log.debug("eventValidation: " + eventValidation); + +		status.sessionID = sessionID; +		status.viewState = viewState; +		status.eventValidation = eventValidation; +		if (viewstateGenerator != null ) { status.viewStateGenerator = viewstateGenerator; } +		status.dynAttrPhoneNumber = dynamicAttrPhonenumber; +		status.dynAttrPassword = dynamicAttrPassword; +		status.dynAttrBtnId = dynamicAttrButtonId; +		status.dynAttrTan = dynamicAttrTan; +	} + +	/* (non-Javadoc) +	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#postCredentials() +	 */ +	public String postCredentials() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		PostMethod post = new PostMethod(status.baseURL + "/identification.aspx?sid=" + status.sessionID); +		post.getParams().setContentCharset("utf-8"); +		post.addParameter("__VIEWSTATE", status.viewState); +		post.addParameter("__VIEWSTATEGENERATOR", status.viewStateGenerator); +		post.addParameter("__EVENTVALIDATION", status.eventValidation); +		post.addParameter(status.dynAttrPhoneNumber, status.phoneNumber); +		post.addParameter(status.dynAttrPassword, status.mobilePassword); +		post.addParameter(status.dynAttrBtnId, "Identifizieren"); + +		return executePost(client, post); +	} + +	/* (non-Javadoc) +	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleCredentialsResponse(java.lang.String) +	 */ +	public void handleCredentialsResponse(final String responseData) throws Exception { +		ATrustStatus status = getStatus(); +		String viewState = status.viewState; +		String eventValidation = status.eventValidation; +		String sessionID = status.sessionID; +		String refVal = null; +		String signatureDataURL = null; +		String viewstateGenerator = status.viewStateGenerator; + +		status.errorMessage = null; + +		final Document responseDocument = Jsoup.parse(responseData); + +		if (responseData.contains("ExpiresInfo.aspx?sid=")) { +			// Certificate expiration interstitial - skip +			if (!expiryNoticeDisplayed) { +				Display.getDefault().syncExec(()->  { +					Dialog d = new Dialog(ATrustHandler.this.shell, Messages.getString("common.info"), Messages.getString("mobileBKU.certExpiresSoon"), BUTTONS.YES_NO, ICON.WARNING); +					if (d.open() == SWT.YES) { +						log.debug("Trying to open " + ACTIVATION_URL); +						if (Desktop.isDesktopSupported()) { +							try { +								Desktop.getDesktop().browse(new URI(ACTIVATION_URL)); +								return; +							} catch (Exception e) { +								log.debug("Error opening URL", e); +							} +						} +						log.info("SWT Desktop is not supported on this platform"); +						Program.launch(ACTIVATION_URL); +					} +				}); +				expiryNoticeDisplayed = true; +			} + +			String t_sessionID = MobileBKUHelper.extractSubstring(responseData, "ExpiresInfo.aspx?sid=", "\""); +			String t_viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value"); +			String t_eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value"); + +			// Post again to skip +			MobileBKUHelper.registerTrustedSocketFactory(); +			HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +			PostMethod post = new PostMethod(status.baseURL + "/ExpiresInfo.aspx?sid=" + t_sessionID); +			post.getParams().setContentCharset("utf-8"); +			post.addParameter("__VIEWSTATE", t_viewState); +			post.addParameter("__EVENTVALIDATION", t_eventValidation); +			post.addParameter("Button_Next", "Weiter"); + +			handleCredentialsResponse(executePost(client, post)); +			return; +		} else if (responseData.contains("tanAppInfo.aspx?sid=")) { +			// App info interstitial - skip +			log.info("Skipping tan app interstitial"); + +			String t_sessionID = MobileBKUHelper.extractSubstring(responseData, "tanAppInfo.aspx?sid=", "\""); +			String t_viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value"); +			String t_eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value"); + +			// Post again to skip +			MobileBKUHelper.registerTrustedSocketFactory(); +			HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +			PostMethod post = new PostMethod(status.baseURL + "/tanAppInfo.aspx?sid=" + t_sessionID); +			post.getParams().setContentCharset("utf-8"); +			post.addParameter("__VIEWSTATE", t_viewState); +			post.addParameter("__EVENTVALIDATION", t_eventValidation); +			post.addParameter("NextBtn", "Weiter"); + +			handleCredentialsResponse(executePost(client, post)); +			return; +		} + +		if (responseData.contains("signature.aspx?sid=")) { +			// credentials ok! TAN entry +			state.rememberCredentialsIfNecessary(status.phoneNumber, status.mobilePassword); +			log.debug("Credentials accepted - TAN required"); +			sessionID = MobileBKUHelper.extractSubstring(responseData, "signature.aspx?sid=", "\""); +			viewState = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__VIEWSTATE", "value"); +			eventValidation = MobileBKUHelper.extractValueFromTagWithParam(responseData, "", "id", "__EVENTVALIDATION", "value"); +			refVal = MobileBKUHelper.extractSubstring(responseData, "id='vergleichswert'><b>Vergleichswert:</b>", "</div>"); +			signatureDataURL = status.baseURL + "/ShowSigobj.aspx" + +					MobileBKUHelper.extractSubstring(responseData, "ShowSigobj.aspx", "'"); +			try { +				String qrCode = MobileBKUHelper.extractValueFromTagWithParam(responseData, "img", "class", "qrcode", "src"); +				log.debug("QR Code found: " + qrCode); +				status.qrCodeURL = qrCode; +			} catch (Exception e) { +				log.debug("No QR Code found"); +			} +			try { +				String tanTextTan = MobileBKUHelper.extractValueFromTagWithParam(responseData, "label", "id", "label_for_input_tan", "for"); +				status.tanField = tanTextTan.equals("input_tan"); +				status.dynAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN); +				status.dynAttrSignButton = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_BTN); +			} catch (Exception e) { +				log.debug("No tan field found"); +			} +			try { +				String tanTextTan = MobileBKUHelper.extractContentFromTagWithParam(responseData, "span", "id", "text_tan"); +				status.isAPPTan = !tanTextTan.toLowerCase().contains("sms"); +				status.dynAttrTan = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_TAN); +				status.dynAttrSignButton = MobileBKUHelper.getDynamicNameAttribute(responseData, Constants.LABEL_SIGN_BTN); +			}catch (Exception e) { +				log.debug("No text_tan tag"); +			} +			try { +				String webauthnLink = MobileBKUHelper.extractValueFromTagWithParam(responseData, "a", "id", "FidoButton", "href"); +				log.info("Webauthn link: {}", webauthnLink); +			} catch (Exception e) { +				log.info("No webauthnLink"); +			} +			try { +				String webauthnData = MobileBKUHelper.extractValueFromTagWithParam(responseData, "input", "id", "credentialOptions", "value"); +				log.info("Fido credential options: {}", webauthnData); +			} catch (Exception e) { +				log.info("No webauthnData"); +			} + +		} else if (responseData.contains("sl:InfoboxReadResponse")) { +			// credentials ok! InfoboxReadResponse +			state.rememberCredentialsIfNecessary(status.phoneNumber, status.mobilePassword); +			log.debug("Credentials accepted - Response given"); +			getSigningState().signatureResponse = responseData; +			return; +		} else if (responseData.contains("undecided.aspx?sid=")) { +			// skip intermediate page +			log.debug("Page Undecided"); +			getSigningState().signatureResponse = responseData; +			status.errorMessage = "waiting..."; // TODO: this looks incorrect...? +			return; +		}else { +			// error page + +			// force UI again! +			state.clearRememberedPassword(); +			// extract error text! +			try { +				String errorMessage = MobileBKUHelper.extractContentFromTagWithParam(responseData, "span", "id", "Label1"); +				if (errorMessage.startsWith("Fehler: ")) +					errorMessage = errorMessage.substring(8); +				status.errorMessage = errorMessage.strip(); +			} catch (Exception e) { +				log.error("Failed to get credentials error message", e); +				String msg = null; +				try +				{ +					msg = MobileBKUHelper.extractSubstring(responseData, "<sl:ErrorCode>", "</sl:ErrorCode>") + ": " + +					  MobileBKUHelper.extractSubstring(responseData, "<sl:Info>", "</sl:Info>"); +				} catch (Exception e2) { +					log.error("Failed to get credentials error code", e2); +					msg = Messages.getString("error.Unexpected"); +				} +				status.errorMessage = msg.strip(); +			} +		} + +		log.debug("sessionID: " + sessionID); +		log.debug("Vergleichswert: " + refVal); +		log.debug("viewState: " + viewState); +		log.debug("eventValidation: " + eventValidation); +		log.debug("signatureDataURL: " + signatureDataURL); + +		status.sessionID = sessionID; +		status.refVal = refVal; +		status.viewState = viewState; +		status.eventValidation = eventValidation; +		status.signatureDataURL = signatureDataURL; +		status.viewStateGenerator = viewstateGenerator; +	} + +	/* (non-Javadoc) +	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#postTAN() +	 */ +	public String postTAN() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		PostMethod post = new PostMethod(status.baseURL +				+ "/signature.aspx?sid=" + status.sessionID); +		post.getParams().setContentCharset("utf-8"); +		post.addParameter("__VIEWSTATE", status.viewState); +		post.addParameter( +				"__EVENTVALIDATION", status.eventValidation); +		post.addParameter(status.dynAttrTan, status.tan); +		post.addParameter(status.dynAttrSignButton, "Signieren"); +		post.addParameter("Button1", "Identifizieren"); + +		return executePost(client, post); +	} + +	/* (non-Javadoc) +	 * @see at.asit.pdfover.gui.workflow.states.mobilebku.MobileBKUHandler#handleTANResponse(java.lang.String) +	 */ +	public void handleTANResponse(String responseData) { +		getStatus().errorMessage = null; +		if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl") || +		    responseData.contains("sl:CreateCMSSignatureResponse xmlns:sl")) { +			// success !! + +			getSigningState().signatureResponse = responseData; +		} else { +			try { +				String tries = MobileBKUHelper.extractSubstring( +						responseData, "Sie haben noch", "Versuch"); +				getStatus().tanTries = Integer.parseInt(tries.trim()); +				getStatus().errorMessage = "mobileBKU.wrong_tan"; +			} catch (Exception e) { +				getStatus().tanTries = (getStatus().tanTries - 1); +				log.debug("Error parsing TAN response", e); +			} + +			if (getStatus().tanTries <= 0) { +				getStatus().errorMessage = null; +				Display.getDefault().syncExec(() -> { +					Dialog dialog = new Dialog(ATrustHandler.this.shell, Messages.getString("common.warning"), +							Messages.getString("mobileBKU.tan_tries_exceeded"), +							BUTTONS.OK_CANCEL, ICON.QUESTION); + +					// TODO: THIS IS A COLOSSAL HACK +					if (dialog.open() == SWT.CANCEL) { +						// Go back to BKU Selection +						getStatus().tanTries = -1; +					} else { +						// Start signature process over +						getStatus().tanTries = -2; +					} +				}); +			} +		} +	} + +	/** +	 * Cancel QR process, request SMS TAN +	 * @return the response +	 * @throws IOException Error during posting +	 */ +	public String postSMSRequest() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		GetMethod get = new GetMethod(status.baseURL +				+ "/sendsms.aspx?sid=" + status.sessionID); +		get.getParams().setContentCharset("utf-8"); + +		return executeGet(client, get); +	} + +	/** +	 * Get the QR code image +	 * @return the QR code image as a String +	 */ +	public InputStream getQRCode() { +		//TODO: Update HTTPClient here + +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		GetMethod get = new GetMethod(status.baseURL + "/" + status.qrCodeURL); + +		try { +			log.debug("Getting " + get.getURI()); +			int returnCode = client.executeMethod(get); + +			if (returnCode != HttpStatus.SC_OK) { +				log.error("Error getting QR code"); +				return null; +			} + +			return get.getResponseBodyAsStream(); +		} catch (Exception e) { +			log.error("Error getting QR code", e); +			return null; +		} +	} + +	/** +	 * Get Signature page after scanning QR code +	 * @return the response +	 * @throws IOException Error during get +	 */ +	public String getSignaturePage() throws IOException { +		ATrustStatus status = getStatus(); + +		MobileBKUHelper.registerTrustedSocketFactory(); +		HttpClient client = MobileBKUHelper.getHttpClient(getStatus()); + +		//TODO check +		//String baseURL = "https://www.a-trust.at/mobile/https-security-layer-request"; +		GetMethod get = new GetMethod(status.baseURL +				+ "/signature.aspx?sid=" + status.sessionID); + +		return executeGet(client, get); +	} + +	/** +	 * Parse QR code response +	 * @param responseData +	 * @return whether a SL response was received +	 */ +	public boolean handleQRResponse(String responseData) { +		getStatus().errorMessage = null; +		if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl") || +		    responseData.contains("sl:CreateCMSSignatureResponse xmlns:sl")) { +			// success !! + +			getSigningState().signatureResponse = responseData; +			return true; +		} +		return false; +	} + +	/* +	 * (non-Javadoc) +	 * +	 */ +	public boolean handlePolling() throws ATrustConnectionException { + +		ATrustStatus status = getStatus(); +		String isReady = null; +		Status serverStatus = null; +		HttpClient client; +		try { +			do { +				client = MobileBKUHelper.getHttpClient(getStatus()); +				String uri = status.baseURL  + "/UndecidedPolling.aspx?sid=" + status.sessionID; +				GetMethod get = new GetMethod(uri); + +				//client.setTimeout(35000); +				//client.setConnectionTimeout(35000); +				get.addRequestHeader("Accept", "application/json, text/javascript"); +				get.addRequestHeader("Connection", "keep-alive"); +				get.addRequestHeader("Referer", uri); + + +				client.executeMethod(get); +				InputStream in = new BufferedInputStream(get.getResponseBodyAsStream()); + +				isReady = IOUtils.toString(in, "utf-8"); +				serverStatus = new Status(isReady); + +				if (serverStatus.isFin()) { +					return true; +				} else if (serverStatus.isError()) { +					log.error("A-Trust returned Error code during polling"); +					throw new ATrustConnectionException(); +				} + +			} while (serverStatus.isWait()); + +			if (serverStatus.isFin()) { +				return true; +			} +			//else error +			status.errorMessage = "Server reponded ERROR during polling"; +			log.error("Server reponded ERROR during polling"); +			throw new ATrustConnectionException(); + +		} catch (Exception e) { +			log.error("handle polling failed" + e.getMessage()); +			throw new ATrustConnectionException(); +		} +	} + +	private class Status { +		private final boolean fin; +		private final boolean error; +		private final boolean wait; + +		public Status(String status) { +			 JsonElement jelement = JsonParser.parseString(status.toLowerCase()); +			 JsonObject  jobject = jelement.getAsJsonObject(); +			 this.fin = jobject.get("fin").getAsBoolean(); +			 this.error = jobject.get("error").getAsBoolean(); +			 this.wait = jobject.get("wait").getAsBoolean(); +		} + +		public boolean isFin() { +			return fin; +		} + +		public boolean isError() { +			return error; +		} + +		public boolean isWait() { +			return wait; +		} + + + + +	} + +} + + diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustStatus.java index 51c08992..22e53a57 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/ATrustStatus.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustStatus.java @@ -1,68 +1,68 @@ -/*
 - * Copyright 2012 by A-SIT, Secure Information Technology Center Austria
 - *
 - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
 - * the European Commission - subsequent versions of the EUPL (the "Licence");
 - * You may not use this work except in compliance with the Licence.
 - * You may obtain a copy of the Licence at:
 - * http://joinup.ec.europa.eu/software/page/eupl
 - *
 - * Unless required by applicable law or agreed to in writing, software
 - * distributed under the Licence is distributed on an "AS IS" basis,
 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - * See the Licence for the specific language governing permissions and
 - * limitations under the Licence.
 - */
 -package at.asit.pdfover.gui.bku.mobile;
 -
 -// Imports
 -import org.slf4j.Logger;
 -import org.slf4j.LoggerFactory;
 -
 -import at.asit.pdfover.gui.workflow.config.ConfigurationManager;
 -
 -/**
 - * A-Trust MobileBKUStatus implementation
 - */
 -public class ATrustStatus {
 -	/**
 -	 * SLF4J Logger instance
 -	 **/
 -	@SuppressWarnings("unused")
 -	private static final Logger log = LoggerFactory.getLogger(ATrustStatus.class);
 -
 -	/** Maximum number of TAN tries */
 -	public static final int MOBILE_MAX_TAN_TRIES = 3;
 -
 -	public String sessionID;
 -	public String phoneNumber;
 -	public String mobilePassword;
 -	public String baseURL;
 -	public String refVal;
 -	public String errorMessage;
 -	public String tan;
 -	public String server;
 -	public String signatureDataURL;
 -	public int tanTries = MOBILE_MAX_TAN_TRIES;
 -	public String viewState;
 -	public String eventValidation;
 -	public String qrCodeURL = null;
 -	public boolean tanField = false;
 -	public boolean isAPPTan = false;
 -	public String viewStateGenerator;
 -	public String dynAttrPhoneNumber;
 -	public String dynAttrPassword;
 -	public String dynAttrBtnId;
 -	public String dynAttrTan;
 -	public String dynAttrSignButton;
 -	public boolean isSMSTan = false;
 -
 -	/**
 -	 * Constructor
 -	 * @param provider the ConfigProvider
 -	 */
 -	public ATrustStatus(ConfigurationManager provider) {
 -		this.phoneNumber = provider.getDefaultMobileNumber();
 -		this.mobilePassword = provider.getDefaultMobilePassword();
 -	}
 -}
 +/* + * Copyright 2012 by A-SIT, Secure Information Technology Center Austria + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://joinup.ec.europa.eu/software/page/eupl + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + */ +package at.asit.pdfover.gui.bku.OLDmobile; + +// Imports +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.gui.workflow.config.ConfigurationManager; + +/** + * A-Trust MobileBKUStatus implementation + */ +public class ATrustStatus { +	/** +	 * SLF4J Logger instance +	 **/ +	@SuppressWarnings("unused") +	private static final Logger log = LoggerFactory.getLogger(ATrustStatus.class); + +	/** Maximum number of TAN tries */ +	public static final int MOBILE_MAX_TAN_TRIES = 3; + +	public String sessionID; +	public String phoneNumber; +	public String mobilePassword; +	public String baseURL; +	public String refVal; +	public String errorMessage; +	public String tan; +	public String server; +	public String signatureDataURL; +	public int tanTries = MOBILE_MAX_TAN_TRIES; +	public String viewState; +	public String eventValidation; +	public String qrCodeURL = null; +	public boolean tanField = false; +	public boolean isAPPTan = false; +	public String viewStateGenerator; +	public String dynAttrPhoneNumber; +	public String dynAttrPassword; +	public String dynAttrBtnId; +	public String dynAttrTan; +	public String dynAttrSignButton; +	public boolean isSMSTan = false; + +	/** +	 * Constructor +	 * @param provider the ConfigProvider +	 */ +	public ATrustStatus(ConfigurationManager provider) { +		this.phoneNumber = provider.getDefaultMobileNumber(); +		this.mobilePassword = provider.getDefaultMobilePassword(); +	} +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHelper.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUHelper.java index bb607be2..f258fc05 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUHelper.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUHelper.java @@ -13,7 +13,7 @@   * See the Licence for the specific language governing permissions and   * limitations under the Licence.   */ -package at.asit.pdfover.gui.bku.mobile; +package at.asit.pdfover.gui.bku.OLDmobile;  // Imports  import java.net.URL; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUs.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java index e0c890da..31339d9f 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/MobileBKUs.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java @@ -13,7 +13,7 @@   * See the Licence for the specific language governing permissions and   * limitations under the Licence.   */ -package at.asit.pdfover.gui.bku.mobile; +package at.asit.pdfover.gui.bku.OLDmobile;  /**   * Available mobile BKUs diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/SimpleXMLTrustManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java index ca57dc87..5f8bec31 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/SimpleXMLTrustManager.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java @@ -13,7 +13,7 @@   * See the Licence for the specific language governing permissions and   * limitations under the Licence.   */ -package at.asit.pdfover.gui.bku.mobile; +package at.asit.pdfover.gui.bku.OLDmobile;  // Imports  import java.security.KeyStore; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/TrustedSocketFactory.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java index 3dae25c9..e6402a9d 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/mobile/TrustedSocketFactory.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java @@ -13,7 +13,7 @@   * See the Licence for the specific language governing permissions and   * limitations under the Licence.   */ -package at.asit.pdfover.gui.bku.mobile; +package at.asit.pdfover.gui.bku.OLDmobile;  // Imports  import java.io.IOException; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PasswordArgument.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PasswordArgument.java index aef07e1f..3ffb57b4 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PasswordArgument.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PasswordArgument.java @@ -19,7 +19,7 @@ package at.asit.pdfover.gui.cliarguments;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; -import at.asit.pdfover.gui.bku.mobile.MobileBKUHelper; +import at.asit.pdfover.gui.bku.OLDmobile.MobileBKUHelper;  import at.asit.pdfover.gui.exceptions.InitializationException;  import at.asit.pdfover.commons.Messages; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PhoneNumberArgument.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PhoneNumberArgument.java index a4eff37a..c9ae045c 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PhoneNumberArgument.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/cliarguments/PhoneNumberArgument.java @@ -19,7 +19,7 @@ package at.asit.pdfover.gui.cliarguments;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; -import at.asit.pdfover.gui.bku.mobile.MobileBKUHelper; +import at.asit.pdfover.gui.bku.OLDmobile.MobileBKUHelper;  import at.asit.pdfover.gui.exceptions.InitializationException;  import at.asit.pdfover.commons.Messages; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUEnterNumberComposite.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUEnterNumberComposite.java index 2a5b3e9c..5f228bcb 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUEnterNumberComposite.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/composites/MobileBKUEnterNumberComposite.java @@ -32,7 +32,7 @@ import org.slf4j.Logger;  import org.slf4j.LoggerFactory;
  import at.asit.pdfover.commons.Constants;
 -import at.asit.pdfover.gui.bku.mobile.MobileBKUHelper;
 +import at.asit.pdfover.gui.bku.OLDmobile.MobileBKUHelper;
  import at.asit.pdfover.gui.exceptions.InvalidPasswordException;
  import at.asit.pdfover.gui.utils.SWTUtils;
  import at.asit.pdfover.commons.Messages;
 diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java index 71cf5567..75fe5f89 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationDataInMemory.java @@ -30,7 +30,7 @@ import org.slf4j.LoggerFactory;  import at.asit.pdfover.commons.BKUs;  import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.bku.mobile.MobileBKUHelper; +import at.asit.pdfover.gui.bku.OLDmobile.MobileBKUHelper;  import at.asit.pdfover.gui.exceptions.InvalidEmblemFile;  import at.asit.pdfover.gui.exceptions.InvalidPortException; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java index ada3970f..37a44e71 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/config/ConfigurationManager.java @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory;  import at.asit.pdfover.commons.BKUs;  import at.asit.pdfover.commons.Constants; -import at.asit.pdfover.gui.bku.mobile.MobileBKUs; +import at.asit.pdfover.gui.bku.OLDmobile.MobileBKUs;  import at.asit.pdfover.gui.exceptions.InvalidEmblemFile;  import at.asit.pdfover.gui.exceptions.InvalidPortException;  import at.asit.pdfover.gui.utils.LocaleSerializer; diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java index d84d5a50..26be4626 100644 --- a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/MobileBKUState.java @@ -21,9 +21,14 @@ import java.net.UnknownHostException;  import java.util.Timer;
  import java.util.TimerTask;
 +import javax.annotation.CheckForNull;
 +import javax.annotation.Nonnull;
 +import javax.annotation.Nullable;
 +
  // Imports
  import at.asit.pdfover.gui.exceptions.ATrustConnectionException;
  import at.asit.pdfover.signer.SignatureException;
 +import at.asit.pdfover.signer.UserCancelledException;
  import at.asit.pdfover.signer.pdfas.PdfAs4SigningState;
  import org.eclipse.swt.SWT;
 @@ -34,8 +39,9 @@ import org.slf4j.LoggerFactory;  import at.asit.pdfover.gui.MainWindow.Buttons;
  import at.asit.pdfover.gui.MainWindowBehavior;
  import at.asit.pdfover.gui.bku.MobileBKUConnector;
 -import at.asit.pdfover.gui.bku.mobile.ATrustHandler;
 -import at.asit.pdfover.gui.bku.mobile.ATrustStatus;
 +import at.asit.pdfover.gui.bku.OLDMobileBKUConnector;
 +import at.asit.pdfover.gui.bku.OLDmobile.ATrustHandler;
 +import at.asit.pdfover.gui.bku.OLDmobile.ATrustStatus;
  import at.asit.pdfover.gui.composites.MobileBKUEnterNumberComposite;
  import at.asit.pdfover.gui.composites.MobileBKUEnterTANComposite;
  import at.asit.pdfover.gui.composites.MobileBKUFingerprintComposite;
 @@ -175,53 +181,59 @@ public class MobileBKUState extends State {  		});
  	}
 -	public void rememberCredentialsIfNecessary() {
 +	public static class UsernameAndPassword {
 +		public @CheckForNull String username;
 +		public @CheckForNull String password;
 +		public UsernameAndPassword() {}
 +		public UsernameAndPassword(@Nullable String u, @Nullable String p) { this.username = u; this.password = p; }
 +	}
 +	public @Nonnull UsernameAndPassword getRememberedCredentials() {
 +		UsernameAndPassword r = new UsernameAndPassword();
 +		storeRememberedCredentialsTo(r);
 +		return r;
 +	}
 +	public void storeRememberedCredentialsTo(@Nonnull UsernameAndPassword output) {
 +		output.username = getStateMachine().configProvider.getDefaultMobileNumber();
 +		output.password = getStateMachine().configProvider.getDefaultMobilePassword();
 +	}
 +
 +	public void rememberCredentialsIfNecessary(@Nullable String username, @Nullable String password) {
  		if (getStateMachine().configProvider.getRememberMobilePassword())
  		{
 -			getStateMachine().configProvider.setDefaultMobileNumberOverlay(status.phoneNumber);
 -			getStateMachine().configProvider.setDefaultMobilePasswordOverlay(status.mobilePassword);
 +			getStateMachine().configProvider.setDefaultMobileNumberOverlay(username);
 +			getStateMachine().configProvider.setDefaultMobilePasswordOverlay(password);
  		}
  	}
 +	public void rememberCredentialsIfNecessary(@Nonnull UsernameAndPassword credentials) {
 +		rememberCredentialsIfNecessary(credentials.username, credentials.password);
 +	}
 -	public void clearRememberedCredentials() {
 +	public void clearRememberedPassword() {
  		getStateMachine().configProvider.setDefaultMobilePasswordOverlay(null);
  		status.mobilePassword = null;
  	}
 -	/**
 -	 * Make sure phone number and password are set in the MobileBKUStatus
 -	 */
 -	public void checkCredentials() {
 -		final ATrustStatus mobileStatus = this.status;
 -		// check if we have everything we need!
 -		if (mobileStatus.phoneNumber != null && !mobileStatus.phoneNumber.isEmpty() &&
 -		    mobileStatus.mobilePassword != null && !mobileStatus.mobilePassword.isEmpty())
 -			return;
 +	public @Nonnull UsernameAndPassword getCredentialsFromUser(@Nullable String currentUsername, @Nullable String errorMessage) throws UserCancelledException {
 +		UsernameAndPassword r = new UsernameAndPassword(currentUsername, null);
 +		getCredentialsFromUserTo(r, errorMessage);
 +		return r;
 +	}
 +	public void getCredentialsFromUserTo(@Nonnull UsernameAndPassword credentials, @Nullable String errorMessage) throws UserCancelledException {
 +		boolean[] cancelState = new boolean[1];
  		Display.getDefault().syncExec(() -> {
  			MobileBKUEnterNumberComposite ui = this.getMobileBKUEnterNumberComposite();
 -			if (!ui.userAck) {
 -				// We need number and password => show UI!
 -				if (mobileStatus.errorMessage != null
 -						&& !mobileStatus.errorMessage.isEmpty()) {
 -					// set possible error message
 -					ui.setErrorMessage(mobileStatus.errorMessage);
 -					mobileStatus.errorMessage = null;
 -				} else {
 +			if (!ui.userAck) { // We need number and password => show UI!
 +				
 +				if (errorMessage != null)
 +					ui.setErrorMessage(errorMessage);
 +				else
  					ui.setErrorMessage(Messages.getString("mobileBKU.aTrustDisclaimer"));
 -				}
 -				if (ui.getMobileNumber() == null
 -						|| ui.getMobileNumber().isEmpty()) {
 +				if ((ui.getMobileNumber() == null) || ui.getMobileNumber().isEmpty()) {
  					// set possible phone number
 -					ui.setMobileNumber(mobileStatus.phoneNumber);
 -				}
 -
 -				if (ui.getMobilePassword() == null
 -						|| ui.getMobilePassword().isEmpty()) {
 -					// set possible password
 -					ui.setMobilePassword(mobileStatus.mobilePassword);
 +					ui.setMobileNumber(credentials.username);
  				}
  				ui.setRememberPassword(getStateMachine().configProvider.getRememberMobilePassword());
 @@ -240,22 +252,45 @@ public class MobileBKUState extends State {  			if (!(ui.userCancel && ui.isRememberPassword())) /* don't allow "remember" to be enabled via cancel button */
  				getStateMachine().configProvider.setRememberMobilePasswordPersistent(ui.isRememberPassword());
 -			if (ui.userCancel) {
 -				ui.userCancel = false;
 -				mobileStatus.errorMessage = "cancel";
 +			cancelState[0] = ui.userCancel;
 +			ui.userCancel = false;
 +			if (cancelState[0])
  				return;
 -			}
  			// user hit ok
  			ui.userAck = false;
  			// get number and password from UI
 -			mobileStatus.phoneNumber = ui.getMobileNumber();
 -			mobileStatus.mobilePassword = ui.getMobilePassword();
 +			credentials.username = ui.getMobileNumber();
 +			credentials.password = ui.getMobilePassword();
  			// show waiting composite
  			getStateMachine().display(this.getWaitingComposite());
  		});
 +		if (cancelState[0])
 +			throw new UserCancelledException();
 +	}
 +
 +	/**
 +	 * Make sure phone number and password are set in the MobileBKUStatus
 +	 * OLD METHOD (todo for nuking)
 +	 */
 +	public void checkCredentials() {
 +		final ATrustStatus mobileStatus = this.status;
 +		// check if we have everything we need!
 +		if (mobileStatus.phoneNumber != null && !mobileStatus.phoneNumber.isEmpty() &&
 +		    mobileStatus.mobilePassword != null && !mobileStatus.mobilePassword.isEmpty())
 +			return;
 +
 +		try {
 +			String errorMessage = mobileStatus.errorMessage;
 +			mobileStatus.errorMessage = null;
 +			UsernameAndPassword creds = getCredentialsFromUser(mobileStatus.phoneNumber, errorMessage);
 +			mobileStatus.phoneNumber = creds.username;
 +			mobileStatus.mobilePassword = creds.password;
 +		} catch (UserCancelledException e) {
 +			mobileStatus.errorMessage = "cancel";
 +		}
  	}
  	/**
 @@ -292,7 +327,7 @@ public class MobileBKUState extends State {  			if (tan.isUserCancel()) {
  				tan.setUserCancel(false);
 -				clearRememberedCredentials();
 +				clearRememberedPassword();
  				mobileStatus.errorMessage = "cancel";
  				return;
  			}
 @@ -360,7 +395,7 @@ public class MobileBKUState extends State {  			if (qr.isUserCancel()) {
  				qr.setUserCancel(false);
 -				clearRememberedCredentials();
 +				clearRememberedPassword();
  				status.errorMessage = "cancel";
  				return;
  			}
 @@ -497,7 +532,7 @@ public class MobileBKUState extends State {  			if (fingerprintComposite.isUserCancel()) {
  				fingerprintComposite.setUserCancel(false);
 -				clearRememberedCredentials();
 +				clearRememberedPassword();
  				status.errorMessage = "cancel";
  				return;
  			}
 @@ -534,7 +569,7 @@ public class MobileBKUState extends State {  	public void run() {
  		this.signingState = getStateMachine().status.signingState;
 -		this.signingState.bkuConnector = new MobileBKUConnector(this);
 +		this.signingState.bkuConnector = new OLDMobileBKUConnector(this);
  		this.signingState.useBase64Request = false;
  		if (this.threadException != null) {
 | 
