summaryrefslogtreecommitdiff
path: root/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile
diff options
context:
space:
mode:
Diffstat (limited to 'pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile')
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java793
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustStatus.java68
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUHelper.java318
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java27
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java220
-rw-r--r--pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java191
6 files changed, 1617 insertions, 0 deletions
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java
new file mode 100644
index 00000000..2e69e779
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustHandler.java
@@ -0,0 +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.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/OLDmobile/ATrustStatus.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustStatus.java
new file mode 100644
index 00000000..22e53a57
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/ATrustStatus.java
@@ -0,0 +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.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/OLDmobile/MobileBKUHelper.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUHelper.java
new file mode 100644
index 00000000..f258fc05
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUHelper.java
@@ -0,0 +1,318 @@
+/*
+ * 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.net.URL;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.jsoup.nodes.Document;
+import org.jsoup.select.Elements;
+import org.jsoup.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asit.pdfover.gui.bku.BKUHelper;
+import at.asit.pdfover.gui.exceptions.InvalidPasswordException;
+import at.asit.pdfover.gui.exceptions.PasswordTooLongException;
+import at.asit.pdfover.gui.exceptions.PasswordTooShortException;
+
+/**
+ *
+ */
+public class MobileBKUHelper {
+ /**
+ * SLF4J Logger instance
+ **/
+ private static final Logger log = LoggerFactory.getLogger(MobileBKUHelper.class);
+
+ /**
+ * Regular expression for mobile phone numbers: this allows the entry of
+ * mobile numbers in the following formats:
+ *
+ * +(countryCode)99999999999 00(countryCode)99999999999 099999999999
+ * 1030199999999999 (A-Trust Test bku)
+ */
+ private static final String NUMBER_REGEX = "^((\\+[\\d]{2})|(00[\\d]{2})|(0)|(10301))([1-9][\\d]+)$";
+
+ /**
+ * Extracts a substring from data starting after start and ending with end
+ *
+ * @param data
+ * the whole data string
+ * @param start
+ * the start marker
+ * @param end
+ * the end marker
+ * @return the substring
+ * @throws Exception
+ * not found
+ */
+ public static String extractSubstring(String data, String start, String end)
+ throws Exception {
+ int startidx = data.indexOf(start);
+ if (startidx > 0) {
+ startidx = startidx + start.length();
+ int endidx = data.indexOf(end, startidx);
+ if (endidx > startidx) {
+ return data.substring(startidx, endidx);
+ }
+ log.error("extracting substring: end not valid!: " + start + " ... " + end); ////
+ throw new Exception("End string not available! Mobile BKU site changed?");
+ }
+ log.error("extracting substring: start not valid!: " + start + " ... " + end); ////
+ throw new Exception("Start string not available! Mobile BKU site changed?");
+ }
+
+ /**
+ * Extracts an XML tag from data with the given param="value"
+ *
+ * @param data
+ * the whole data string
+ * @param tag
+ * the tag name (empty string to match all tags)
+ * @param param
+ * the parameter to look for
+ * @param value
+ * the parameter value to look for
+ * @return the found tag
+ * @throws Exception
+ * not found
+ */
+ public static String extractTagWithParam(String data, String tag,
+ String param, String value) throws Exception {
+ String start = '<' + tag;
+ int startidx, endidx = 0;
+ while ((startidx = data.indexOf(start, endidx)) != -1) {
+ endidx = data.indexOf('>', startidx);
+ if (endidx == -1) {
+ log.error("extracting tag: unterminated tag! " + tag + " (" + param + "=" + value + ")"); ////
+ throw new Exception("Tag not found! Mobile BKU site changed?");
+ }
+ String found = data.substring(startidx, endidx + 1);
+ if (found.contains(param + "='" + value + "'") ||
+ found.contains(param + "=\"" + value + "\""))
+ return found;
+ }
+ log.info("extracting tag: not found!: " + tag + " (" + param + "='" + value + "')"); ////
+ throw new Exception("Tag not found! Mobile BKU site changed?");
+ }
+
+ /**
+ * Extracts a parameter value from an XML tag from data with the given param="value"
+ *
+ * @param data
+ * the whole data string
+ * @param tag
+ * the tag name (empty string to match all tags)
+ * @param param
+ * the parameter to look for
+ * @param value
+ * the parameter value to look for
+ * @param returnparam
+ * the parameter whose value to return
+ * @return the found tag
+ * @throws Exception
+ * not found
+ */
+ public static String extractValueFromTagWithParam(String data, String tag,
+ String param, String value, String returnparam) throws Exception {
+ String found = extractTagWithParam(data, tag, param, value);
+ int startidx = found.indexOf(returnparam + '=');
+ if (startidx == -1) {
+ log.error("extracting tag: param not found! " + tag + " (" + param + "=" + value + ") - " + returnparam); ////
+ throw new Exception("Tag not found! Mobile BKU site changed?");
+ }
+ startidx += returnparam.length() + 1;
+ int endidx = found.indexOf(found.charAt(startidx), startidx + 1);
+ if (endidx == -1) {
+ log.error("extracting tag: unterminated param value! " + tag + " (" + param + "=" + value + ") - " + returnparam); ////
+ throw new Exception("Tag not found! Mobile BKU site changed?");
+ }
+ return found.substring(startidx + 1, endidx);
+ }
+
+ /**
+ * This method is the same as the non optional method but instead of throwing the exception it returns null
+ * @return the string or null
+ */
+ public static String extractValueFromTagWithParamOptional(String data, String tag,
+ String param, String value, String returnparam) {
+ String str;
+ try {
+ str = extractValueFromTagWithParam(data, tag, param, value, returnparam);
+ } catch (Exception e) {
+ log.debug("Optional value is not available");
+ str = null;
+ }
+ return str;
+
+ }
+
+ /**
+ * Extracts the content from an XML tag from data with the given param="value"
+ *
+ * @param data
+ * the whole data string
+ * @param tag
+ * the tag name
+ * @param param
+ * the parameter to look for
+ * @param value
+ * the parameter value to look for
+ * @return the found tag's content
+ * @throws Exception
+ * not found
+ */
+ public static String extractContentFromTagWithParam(String data, String tag,
+ String param, String value) throws Exception {
+ String found = extractTagWithParam(data, tag, param, value);
+ int startidx = data.indexOf(found) + found.length();
+ int endidx = data.indexOf("</" + tag + ">", startidx);
+ if (endidx == -1) {
+ log.error("extracting tag: closing tag not found! " + tag + " (" + param + "=" + value + ")"); ////
+ throw new Exception("Tag not found! Mobile BKU site changed?");
+ }
+ return data.substring(startidx, endidx);
+ }
+
+ /**
+ * Validates the Mobile phone number
+ *
+ * @param number
+ * @return the normalized Phone number
+ */
+ public static String normalizeMobileNumber(String number) {
+ // Verify number and normalize
+
+ number = number.trim();
+
+ String numberWithoutWhitespace = number.replaceAll("\\s","");
+ // Compile and use regular expression
+ Pattern pattern = Pattern.compile(NUMBER_REGEX);
+ Matcher matcher = pattern.matcher(numberWithoutWhitespace);
+
+ if (!matcher.find())
+ return number; /* might be an idA username, return unchanged */
+
+ if (matcher.groupCount() != 6) {
+ return number;
+ }
+
+ String countryCode = matcher.group(1);
+
+ String normalNumber = matcher.group(6);
+
+ if (countryCode.equals("10301")) {
+ // A-Trust Testnumber! Don't change
+ return numberWithoutWhitespace;
+ }
+
+ countryCode = countryCode.replace("00", "+");
+
+ if (countryCode.equals("0")) {
+ countryCode = "+43";
+ }
+
+ return countryCode + normalNumber;
+ }
+
+ /**
+ * Validate given Password for Mobile BKU
+ *
+ * @param password
+ * @throws InvalidPasswordException
+ */
+ public static void validatePassword(String password)
+ throws InvalidPasswordException {
+ if (password.length() < 5 || password.length() > 200) {
+ if (password.length() < 6) {
+ throw new PasswordTooShortException();
+ }
+ throw new PasswordTooLongException();
+ }
+ }
+
+ /**
+ * Removes file extension from URL
+ *
+ * @param url
+ * the url string
+ * @return the stripped url
+ */
+ public static String stripQueryString(String url) {
+ int pathidx = url.lastIndexOf('/');
+ if (pathidx > 0) {
+ return url.substring(0, pathidx);
+ }
+ return url;
+ }
+
+ /**
+ * Build a fully qualified URL out of a base URL plus a URL fragment
+ * @param fragment the URL fragment
+ * @param base the base URL
+ * @return the fully qualified URL
+ */
+ public static String getQualifiedURL(String fragment, URL base) {
+ if (fragment.startsWith("http:") || fragment.startsWith("https:"))
+ return fragment;
+ int p = base.getPort();
+ String port = ((p != -1) && (p != base.getDefaultPort())) ? ":" + p : "";
+ if (fragment.startsWith("/")) {
+ return base.getProtocol() + "://" + base.getHost() + port + fragment;
+ }
+ return stripQueryString(base.toString()) + "/" + fragment;
+ }
+
+ /**
+ * Register our TrustedSocketFactory for https connections
+ */
+ @SuppressWarnings("deprecation")
+ public static void registerTrustedSocketFactory() {
+ Protocol.registerProtocol("https",
+ new Protocol("https", new TrustedSocketFactory(), 443));
+ }
+
+ /**
+ * Get a HTTP Client instance
+ * @param status the mobile BKU status
+ * @return the HttpClient
+ */
+ public static HttpClient getHttpClient(ATrustStatus status) {
+ return BKUHelper.getHttpClient(true);
+ }
+
+ /***
+ *
+ * @param htmlString describes the html data in String representation
+ * @param attributeName is the attribute which should be selected
+ * @return returns the attribute name or null otherswise
+ */
+ public static String getDynamicNameAttribute(String htmlString, String attributeName) {
+
+ Document doc = Jsoup.parse(htmlString);
+ Elements inputs = doc.select("div input#" + attributeName);
+
+ if (inputs.size() == 0 ) return null;
+
+ String name = inputs.get(0).attr("name");
+ return name;
+ }
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java
new file mode 100644
index 00000000..31339d9f
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/MobileBKUs.java
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+/**
+ * Available mobile BKUs
+ */
+public enum MobileBKUs {
+ /** A-Trust BKU */
+ A_TRUST,
+
+ /** IAIK */
+ IAIK
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java
new file mode 100644
index 00000000..5f8bec31
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/SimpleXMLTrustManager.java
@@ -0,0 +1,220 @@
+/*
+ * 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.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.asit.pdfover.commons.Constants;
+
+/**
+ *
+ */
+public class SimpleXMLTrustManager implements X509TrustManager {
+ /**
+ * SLF4J Logger instance
+ **/
+ private static final Logger log = LoggerFactory.getLogger(SimpleXMLTrustManager.class);
+
+ /*
+ * The default X509TrustManager returned by SunX509. We'll delegate
+ * decisions to it, and fall back to the logic in this class if the default
+ * X509TrustManager doesn't trust it.
+ */
+ X509TrustManager sunJSSEX509TrustManager;
+
+ /**
+ * Trust Manager for A-Trust Certificates
+ */
+ X509TrustManager atrustTrustManager;
+
+ /**
+ * Constructs the TrustManager
+ *
+ * @throws Exception
+ */
+ public SimpleXMLTrustManager() throws Exception {
+ // create a "default" JSSE X509TrustManager.
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init((KeyStore) null);
+
+ TrustManager tms[] = tmf.getTrustManagers();
+
+ /*
+ * Iterate over the returned trustmanagers, look for an instance of
+ * X509TrustManager. If found, use that as our "default" trust manager.
+ */
+ for (int i = 0; i < tms.length; i++) {
+ if (tms[i] instanceof X509TrustManager) {
+ this.sunJSSEX509TrustManager = (X509TrustManager) tms[i];
+ break;
+ }
+ }
+
+ /*
+ * Certificates
+ */
+
+ KeyStore myKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+ myKeyStore.load(null);
+
+ Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
+ .parse(this.getClass().getResourceAsStream(Constants.RES_CERT_LIST));
+ Node certificates = doc.getFirstChild();
+ NodeList certificateList = certificates.getChildNodes();
+
+ try {
+ if (!certificates.getNodeName().equals("certificates")) {
+ throw new Exception("Used certificates xml is invalid! no certificates node");
+ }
+
+ //add trusted certificates to certStore//
+ for (int i = 0; i < certificateList.getLength(); i++) {
+ try {
+
+ Node certificateNode = certificateList.item(i);
+
+ if (certificateNode.getNodeName().equals("#text")) {
+ continue; // Ignore dummy text node ..
+ }
+
+ if (!certificateNode.getNodeName().equals("certificate")) {
+ log.warn("Ignoring XML node: " + certificateNode.getNodeName());
+ continue;
+ }
+
+ String certResource = Constants.RES_CERT_PATH + certificateNode.getTextContent();
+
+ X509Certificate cert = (X509Certificate) CertificateFactory.getInstance("X509").
+ generateCertificate(this.getClass().getResourceAsStream(certResource));
+
+ myKeyStore.setCertificateEntry(certificateNode.getTextContent(), cert);
+
+ log.debug("Loaded certificate : " + certResource);
+
+ } catch (Exception ex) {
+ log.error("Failed to load certificate [" + "]", ex);
+ }
+ }
+
+ }
+
+ catch (Exception e) {
+ e.toString();
+ }
+
+ tmf.init(myKeyStore);
+
+ tms = tmf.getTrustManagers();
+
+ /*
+ * Iterate over the returned trustmanagers, look for an instance of
+ * X509TrustManager. If found, use that as our "default" trust manager.
+ */
+ for (int i = 0; i < tms.length; i++) {
+ if (tms[i] instanceof X509TrustManager) {
+ this.atrustTrustManager = (X509TrustManager) tms[i];
+ break;
+ }
+ }
+
+ if (this.sunJSSEX509TrustManager != null && this.atrustTrustManager != null) {
+ return;
+ }
+
+ /*
+ * Find some other way to initialize, or else we have to fail the
+ * constructor.
+ */
+ throw new Exception("Couldn't initialize ASITTrustManager");
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.
+ * X509Certificate[], java.lang.String)
+ */
+ @Override
+ public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ try {
+ this.atrustTrustManager.checkServerTrusted(arg0, arg1);
+ } catch (CertificateException ex) {
+ try {
+ this.sunJSSEX509TrustManager.checkClientTrusted(arg0, arg1);
+ } catch (CertificateException ex2) {
+ log.info("checkClientTrusted: ", ex2);
+ throw ex2;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.
+ * X509Certificate[], java.lang.String)
+ */
+ @Override
+ public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+ try {
+ this.atrustTrustManager.checkServerTrusted(arg0, arg1);
+ } catch (CertificateException ex) {
+ try {
+ this.sunJSSEX509TrustManager.checkServerTrusted(arg0, arg1);
+ } catch (CertificateException ex2) {
+ log.info("checkServerTrusted: ", ex2);
+ throw ex2;
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
+ */
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+
+ X509Certificate[] default_certs = this.sunJSSEX509TrustManager.getAcceptedIssuers();
+
+ X509Certificate[] atrust_certs = this.atrustTrustManager.getAcceptedIssuers();
+
+ X509Certificate[] all_certs = Arrays.copyOf(default_certs, default_certs.length + atrust_certs.length);
+ System.arraycopy(atrust_certs, 0, all_certs, default_certs.length, atrust_certs.length);
+ return all_certs;
+ }
+
+}
diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java
new file mode 100644
index 00000000..e6402a9d
--- /dev/null
+++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/bku/OLDmobile/TrustedSocketFactory.java
@@ -0,0 +1,191 @@
+/*
+ * 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.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.apache.commons.httpclient.ConnectTimeoutException;
+import org.apache.commons.httpclient.params.HttpConnectionParams;
+import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import at.asit.pdfover.commons.Messages;
+
+/**
+ *
+ */
+public class TrustedSocketFactory implements SecureProtocolSocketFactory {
+ /**
+ * SLF4J Logger instance
+ **/
+ private static final Logger log = LoggerFactory.getLogger(TrustedSocketFactory.class);
+
+ private static final String ENABLED_CS[] = {
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
+ "SSL_RSA_WITH_RC4_128_SHA",
+ "SSL_RSA_WITH_3DES_EDE_CBC_SHA",
+ "SSL_RSA_WITH_RC4_128_MD5"
+ };
+
+ private static SSLSocketFactory getFactory() throws NoSuchAlgorithmException,
+ KeyManagementException, Exception {
+ SSLContext sslContext = SSLContext.getInstance("TLS");
+ sslContext.init(null, new TrustManager[] { new SimpleXMLTrustManager() },
+ new java.security.SecureRandom());
+
+ return sslContext.getSocketFactory();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket
+ * (java.lang.String, int)
+ */
+ @Override
+ public Socket createSocket(String host, int port) throws IOException,
+ UnknownHostException {
+ try {
+ SSLSocket sslSocket = (SSLSocket) getFactory().createSocket(host,
+ port);
+ sslSocket.setEnabledCipherSuites(ENABLED_CS);
+ return sslSocket;
+ } catch (Exception ex) {
+ log.error("TrustedSocketFactory: ", ex);
+ if (ex instanceof IOException) {
+ throw (IOException) ex;
+ } else if (ex instanceof UnknownHostException) {
+ throw (UnknownHostException) ex;
+ } else {
+ throw new IOException(
+ Messages.getString("TrustedSocketFactory.FailedToCreateSecureConnection"), ex);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket
+ * (java.lang.String, int, java.net.InetAddress, int)
+ */
+ @Override
+ public Socket createSocket(String host, int port, InetAddress clientHost,
+ int clientPort) throws IOException, UnknownHostException {
+ try {
+ SSLSocket sslSocket = (SSLSocket) getFactory().createSocket(host,
+ port, clientHost, clientPort);
+ sslSocket.setEnabledCipherSuites(ENABLED_CS);
+ return sslSocket;
+ } catch (Exception ex) {
+ log.error("TrustedSocketFactory: ", ex);
+ if (ex instanceof IOException) {
+ throw (IOException) ex;
+ } else if (ex instanceof UnknownHostException) {
+ throw (UnknownHostException) ex;
+ } else {
+ throw new IOException(
+ Messages.getString("TrustedSocketFactory.FailedToCreateSecureConnection"), ex);
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.apache.commons.httpclient.protocol.ProtocolSocketFactory#createSocket
+ * (java.lang.String, int, java.net.InetAddress, int,
+ * org.apache.commons.httpclient.params.HttpConnectionParams)
+ */
+ @Override
+ public Socket createSocket(String host, int port, InetAddress clientHost,
+ int clientPort, HttpConnectionParams params) throws IOException,
+ UnknownHostException, ConnectTimeoutException {
+ try {
+ if (params == null) {
+ throw new IllegalArgumentException("Parameters may not be null");
+ }
+ int timeout = params.getConnectionTimeout();
+ SSLSocket sslSocket = null;
+
+ SSLSocketFactory socketfactory = getFactory();
+ if (timeout == 0) {
+ sslSocket = (SSLSocket) socketfactory.createSocket(host, port, clientHost,
+ clientPort);
+ } else {
+ sslSocket = (SSLSocket) socketfactory.createSocket();
+ SocketAddress localaddr = new InetSocketAddress(clientHost,
+ clientPort);
+ SocketAddress remoteaddr = new InetSocketAddress(host, port);
+ sslSocket.bind(localaddr);
+ sslSocket.connect(remoteaddr, timeout);
+ }
+ sslSocket.setEnabledCipherSuites(ENABLED_CS);
+ return sslSocket;
+ } catch (Exception ex) {
+ log.error("TrustedSocketFactory: ", ex);
+ if (ex instanceof IOException) {
+ throw (IOException) ex;
+ } else if (ex instanceof UnknownHostException) {
+ throw (UnknownHostException) ex;
+ } else {
+ throw new IOException(
+ Messages.getString("TrustedSocketFactory.FailedToCreateSecureConnection"), ex);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory#createSocket(java.net.Socket, java.lang.String, int, boolean)
+ */
+ @Override
+ public Socket createSocket(Socket socket, String host, int port,
+ boolean autoClose) throws IOException, UnknownHostException {
+ try {
+ SSLSocket sslSocket = (SSLSocket) getFactory().createSocket(socket, host, port, autoClose);
+ sslSocket.setEnabledCipherSuites(ENABLED_CS);
+ return sslSocket;
+ } catch (Exception ex) {
+ log.error("TrustedSocketFactory: ", ex);
+ if (ex instanceof IOException) {
+ throw (IOException) ex;
+ } else if (ex instanceof UnknownHostException) {
+ throw (UnknownHostException) ex;
+ } else {
+ throw new IOException(
+ Messages.getString("TrustedSocketFactory.FailedToCreateSecureConnection"), ex);
+ }
+ }
+ }
+
+}