From 6d3b9d99b0e708d2516caf0f098c58c8a9585114 Mon Sep 17 00:00:00 2001 From: tkellner Date: Wed, 10 Apr 2013 18:54:34 +0000 Subject: Mobile BKU first working (currently set to work with test mobile BKU from A-Trust git-svn-id: https://joinup.ec.europa.eu/svn/pdf-over/trunk@31 174cde9d-5d70-4d2a-aa98-46368bc2aaf7 --- .../states/mobilebku/ASITTrustManager.java | 65 +++++++ .../workflow/states/mobilebku/ATrustHelper.java | 67 +++++++ .../mobilebku/MobileBKUCommunicationState.java | 42 +++++ .../workflow/states/mobilebku/MobileBKUStatus.java | 203 +++++++++++++++++++++ .../states/mobilebku/PostCredentialsThread.java | 176 ++++++++++++++++++ .../states/mobilebku/PostSLRequestThread.java | 164 +++++++++++++++++ .../workflow/states/mobilebku/PostTanThread.java | 173 ++++++++++++++++++ .../states/mobilebku/TrustedSocketFactory.java | 159 ++++++++++++++++ 8 files changed, 1049 insertions(+) create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ASITTrustManager.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ATrustHelper.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUCommunicationState.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUStatus.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostCredentialsThread.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostSLRequestThread.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostTanThread.java create mode 100644 pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/TrustedSocketFactory.java (limited to 'pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku') diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ASITTrustManager.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ASITTrustManager.java new file mode 100644 index 00000000..38bdfc74 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ASITTrustManager.java @@ -0,0 +1,65 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class ASITTrustManager implements X509TrustManager { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(ASITTrustManager.class); + + /* (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 { + // Ignore client certificates ... + } + + /* (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 { + // TODO: Check trusted server certificate! + } + + /* (non-Javadoc) + * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() + */ + @Override + public X509Certificate[] getAcceptedIssuers() { + // TODO: Build accepted issuers + return null; + } + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ATrustHelper.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ATrustHelper.java new file mode 100644 index 00000000..c9254317 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/ATrustHelper.java @@ -0,0 +1,67 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class ATrustHelper { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(ATrustHelper.class); + + /** + * @param data + * @param start + * @param end + * @return + * @throws Exception + */ + public static String extractTag(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); + } else { + // TODO: throw exception + throw new Exception("end tag not available!"); + } + } else { + // TODO: throw exception + throw new Exception("start tag not available!"); + } + } + + /** + * @param query + * @return + */ + public static String stripQueryString(String query) { + int pathidx = query.lastIndexOf('/'); + if(pathidx > 0) { + return query.substring(0, pathidx); + } + return query; + } +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUCommunicationState.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUCommunicationState.java new file mode 100644 index 00000000..339f2db3 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUCommunicationState.java @@ -0,0 +1,42 @@ +/* + * 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.workflow.states.mobilebku; + +/** + * Communication states for Mobile BKU + */ +public enum MobileBKUCommunicationState { + + /** + * POST SL Request to A-Trust BKU + */ + POST_REQUEST, + + /** + * POST User informations (number, password) to A-Trust BKU + */ + POST_NUMBER, + + /** + * POST tan to A-Trust BKU and retrieve SL Response + */ + POST_TAN, + + /** + * Final state + */ + FINAL +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUStatus.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUStatus.java new file mode 100644 index 00000000..344eaf58 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/MobileBKUStatus.java @@ -0,0 +1,203 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class MobileBKUStatus { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(MobileBKUStatus.class); + + public static final int MOBILE_MAX_TAN_TRIES = 3; + + /** + * Constructor + */ + public MobileBKUStatus() { + // TODO: Fill number and password with possible config values! + } + + String viewstate; + + String eventvalidation; + + String sessionID; + + String phoneNumber; + + String mobilePassword; + + String baseURL; + + String vergleichswert; + + String errorMessage; + + String tan; + + int tanTries = MOBILE_MAX_TAN_TRIES; + + /** + * @return the tanTries + */ + public int getTanTries() { + return this.tanTries; + } + + /** + * Decreases the TAN Tries! + */ + public void decreaseTanTries() { + this.tanTries--; + } + + /** + * @return the tan + */ + public String getTan() { + return this.tan; + } + + /** + * @param tan the tan to set + */ + public void setTan(String tan) { + this.tan = tan; + } + + /** + * @return the errorMessage + */ + public String getErrorMessage() { + return this.errorMessage; + } + + /** + * @param errorMessage the errorMessage to set + */ + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + + /** + * @return the vergleichswert + */ + public String getVergleichswert() { + return this.vergleichswert; + } + + /** + * @param vergleichswert the vergleichswert to set + */ + public void setVergleichswert(String vergleichswert) { + this.vergleichswert = vergleichswert; + } + + /** + * @return the credentialsFormAction + */ + public String getBaseURL() { + return this.baseURL; + } + + /** + * @param credentialsFormAction the credentialsFormAction to set + */ + public void setBaseURL(String baseURL) { + this.baseURL = baseURL; + } + + /** + * @return the viewstate + */ + public String getViewstate() { + return this.viewstate; + } + + /** + * @param viewstate + * the viewstate to set + */ + public void setViewstate(String viewstate) { + this.viewstate = viewstate; + } + + /** + * @return the eventvalidation + */ + public String getEventvalidation() { + return this.eventvalidation; + } + + /** + * @param eventvalidation the eventvalidation to set + */ + public void setEventvalidation(String eventvalidation) { + this.eventvalidation = eventvalidation; + } + + /** + * @return the phoneNumber + */ + public String getPhoneNumber() { + return this.phoneNumber; + } + + /** + * @param phoneNumber the phoneNumber to set + */ + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + /** + * @return the mobilePassword + */ + public String getMobilePassword() { + return this.mobilePassword; + } + + /** + * @param mobilePassword the mobilePassword to set + */ + public void setMobilePassword(String mobilePassword) { + this.mobilePassword = mobilePassword; + } + + /** + * @return the identification_url + */ + public String getSessionID() { + return this.sessionID; + } + + /** + * @param sessionID the identification_url to set + */ + public void setSessionID(String sessionID) { + this.sessionID = sessionID; + } + + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostCredentialsThread.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostCredentialsThread.java new file mode 100644 index 00000000..df18c231 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostCredentialsThread.java @@ -0,0 +1,176 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import java.io.IOException; + +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.protocol.Protocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.gui.workflow.states.LocalBKUState; +import at.asit.pdfover.gui.workflow.states.MobileBKUState; + +/** + * + */ +public class PostCredentialsThread implements Runnable { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(PostCredentialsThread.class); + + private MobileBKUState state; + + /** + * Constructor + * + * @param state + */ + public PostCredentialsThread(MobileBKUState state) { + this.state = state; + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + MobileBKUStatus status = this.state.getStatus(); + + + Protocol.registerProtocol("https", //$NON-NLS-1$ + new Protocol("https", new TrustedSocketFactory(), 443)); //$NON-NLS-1$ + + HttpClient client = new HttpClient(); + client.getParams().setParameter("http.useragent", //$NON-NLS-1$ + LocalBKUState.PDF_OVER_USER_AGENT_STRING); + + PostMethod method = new PostMethod(status.getBaseURL() + "/identification.aspx?sid=" + status.getSessionID()); + + method.addParameter("__VIEWSTATE", status.getViewstate()); //$NON-NLS-1$ + method.addParameter("__EVENTVALIDATION", status.getEventvalidation()); //$NON-NLS-1$ + method.addParameter("handynummer", status.getPhoneNumber()); //$NON-NLS-1$ + method.addParameter("signaturpasswort", status.getMobilePassword()); //$NON-NLS-1$ + method.addParameter("Button_Identification", "Identifizieren"); //$NON-NLS-1$ //$NON-NLS-2$ + + int returnCode = client.executeMethod(method); + + String redirectLocation = null; + + GetMethod gmethod = null; + + String responseData = null; + + // Follow redirects + do { + // check return code + if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY || + returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + + Header locationHeader = method + .getResponseHeader("location"); //$NON-NLS-1$ + if (locationHeader != null) { + redirectLocation = locationHeader.getValue(); + } else { + throw new IOException( + "Got HTTP 302 but no location to follow!"); //$NON-NLS-1$ + } + } else if(returnCode == HttpStatus.SC_OK) { + if(gmethod != null) { + responseData = gmethod.getResponseBodyAsString(); + } else { + responseData = method.getResponseBodyAsString(); + } + redirectLocation = null; + } else { + throw new HttpException(HttpStatus.getStatusText(returnCode)); + } + + if(redirectLocation != null) { + gmethod = new GetMethod(redirectLocation); + gmethod.setFollowRedirects(true); + returnCode = client.executeMethod(gmethod); + } + + } while(redirectLocation != null); + + // Now we have received some data lets check it: + + log.debug("Repsonse from A-Trust: " + responseData); //$NON-NLS-1$ + + String viewState = status.getViewstate(); + String eventValidation = status.getEventvalidation(); + String sessionID = status.getSessionID(); + + String vergleichswert = null; + + status.setVergleichswert(null); + status.setErrorMessage(null); + + if(responseData.contains("signature.aspx?sid=")) { //$NON-NLS-1$ + // credentials ok! TAN eingabe + sessionID = ATrustHelper.extractTag(responseData, "signature.aspx?sid=", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + viewState = ATrustHelper.extractTag(responseData, "id=\"__VIEWSTATE\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + + eventValidation = ATrustHelper.extractTag(responseData, "id=\"__EVENTVALIDATION\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + + vergleichswert = ATrustHelper.extractTag(responseData, "id='vergleichswert'>Vergleichswert:", ""); //$NON-NLS-1$//$NON-NLS-2$ + + status.setVergleichswert(vergleichswert); + + this.state.setCommunicationState(MobileBKUCommunicationState.POST_TAN); + } else { + // error seite + // extract error text! + + String errorMessage = ATrustHelper.extractTag(responseData, "", ""); //$NON-NLS-1$ //$NON-NLS-2$ + + this.state.getStatus().setErrorMessage(errorMessage); + + // force UI again! + status.setMobilePassword(null); + } + + log.info("sessionID: " + sessionID); //$NON-NLS-1$ + log.info("Vergleichswert: " + vergleichswert); //$NON-NLS-1$ + log.info("viewState: " + viewState); //$NON-NLS-1$ + log.info("eventValidation: " + eventValidation); //$NON-NLS-1$ + + status.setSessionID(sessionID); + + status.setViewstate(viewState); + + status.setEventvalidation(eventValidation); + + } catch (Exception ex) { + log.error("Error in PostCredentialsThread", ex); //$NON-NLS-1$ + this.state.setThreadException(ex); + } finally { + this.state.invokeUpdate(); + } + } + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostSLRequestThread.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostSLRequestThread.java new file mode 100644 index 00000000..83f42574 --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostSLRequestThread.java @@ -0,0 +1,164 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import java.io.IOException; + +import javax.xml.ws.http.HTTPException; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpState; +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.protocol.Protocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.gui.workflow.states.LocalBKUState; +import at.asit.pdfover.gui.workflow.states.MobileBKUState; + +/** + * + */ +public class PostSLRequestThread implements Runnable { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(PostSLRequestThread.class); + + private MobileBKUState state; + + /** + * Constructor + * + * @param state + */ + public PostSLRequestThread(MobileBKUState state) { + this.state = state; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + String sl_request = this.state.getSigningState() + .getSignatureRequest().getBase64Request(); + + Protocol.registerProtocol("https", //$NON-NLS-1$ + new Protocol("https", new TrustedSocketFactory(), 443)); //$NON-NLS-1$ + + HttpClient client = new HttpClient(); + client.getParams().setParameter("http.useragent", //$NON-NLS-1$ + LocalBKUState.PDF_OVER_USER_AGENT_STRING); + + // TODO: move URL to config!! + + //String url = "https://www.a-trust.at/mobile/https-security-layer-request/default.aspx"; + String url = "https://test1.a-trust.at/https-security-layer-request/default.aspx"; + + PostMethod method = new PostMethod(url); + + method.addParameter("XMLRequest", sl_request); //$NON-NLS-1$ + + int returnCode = client.executeMethod(method); + + String redirectLocation = null; + + GetMethod gmethod = null; + + String responseData = null; + + this.state.getStatus().setBaseURL(ATrustHelper.stripQueryString(url)); + + // Follow redirects + do { + // check return code + if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY || + returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + + Header locationHeader = method + .getResponseHeader("location"); //$NON-NLS-1$ + if (locationHeader != null) { + redirectLocation = locationHeader.getValue(); + } else { + throw new IOException( + "Got HTTP 302 but no location to follow!"); //$NON-NLS-1$ + } + } else if(returnCode == HttpStatus.SC_OK) { + if(gmethod != null) { + responseData = gmethod.getResponseBodyAsString(); + } else { + responseData = method.getResponseBodyAsString(); + } + redirectLocation = null; + } else { + throw new HttpException(HttpStatus.getStatusText(returnCode)); + } + + if(redirectLocation != null) { + gmethod = new GetMethod(redirectLocation); + gmethod.setFollowRedirects(true); + returnCode = client.executeMethod(gmethod); + } + + } while(redirectLocation != null); + + // Now we have received some data lets check it: + + log.debug("Repsonse from A-Trust: " + responseData); //$NON-NLS-1$ + + // Extract infos: + + String sessionID = ATrustHelper.extractTag(responseData, "identification.aspx?sid=", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + + String viewState = ATrustHelper.extractTag(responseData, "id=\"__VIEWSTATE\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + + String eventValidation = ATrustHelper.extractTag(responseData, "id=\"__EVENTVALIDATION\" value=\"", "\""); //$NON-NLS-1$ //$NON-NLS-2$ + + log.info("sessionID: " + sessionID); //$NON-NLS-1$ + log.info("viewState: " + viewState); //$NON-NLS-1$ + log.info("eventValidation: " + eventValidation); //$NON-NLS-1$ + + this.state.getStatus().setSessionID(sessionID); + + this.state.getStatus().setViewstate(viewState); + + this.state.getStatus().setEventvalidation(eventValidation); + + /* + * If all went well we can set the communication state to the new + * state + */ + this.state + .setCommunicationState(MobileBKUCommunicationState.POST_NUMBER); + } catch (Exception ex) { + log.error("Error in PostSLRequestThread", ex); //$NON-NLS-1$ + this.state.setThreadException(ex); + } finally { + this.state.invokeUpdate(); + } + } + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostTanThread.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostTanThread.java new file mode 100644 index 00000000..e4a2242a --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/PostTanThread.java @@ -0,0 +1,173 @@ +/* + * 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.workflow.states.mobilebku; + +// Imports +import java.io.IOException; + +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.protocol.Protocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.asit.pdfover.gui.workflow.states.LocalBKUState; +import at.asit.pdfover.gui.workflow.states.MobileBKUState; +import at.asit.pdfover.signator.SLResponse; + +/** + * + */ +public class PostTanThread implements Runnable { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(PostTanThread.class); + + private MobileBKUState state; + + /** + * Constructor + * + * @param state + */ + public PostTanThread(MobileBKUState state) { + this.state = state; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + try { + MobileBKUStatus status = this.state.getStatus(); + + Protocol.registerProtocol("https", //$NON-NLS-1$ + new Protocol("https", new TrustedSocketFactory(), 443)); //$NON-NLS-1$ + + HttpClient client = new HttpClient(); + client.getParams().setParameter("http.useragent", //$NON-NLS-1$ + LocalBKUState.PDF_OVER_USER_AGENT_STRING); + + PostMethod method = new PostMethod(status.getBaseURL() + + "/signature.aspx?sid=" + status.getSessionID()); //$NON-NLS-1$ + + method.addParameter("__VIEWSTATE", status.getViewstate()); //$NON-NLS-1$ + method.addParameter( + "__EVENTVALIDATION", status.getEventvalidation()); //$NON-NLS-1$ + method.addParameter("input_tan", status.getTan()); //$NON-NLS-1$ + method.addParameter("SignButton", "Signieren"); //$NON-NLS-1$ //$NON-NLS-2$ + method.addParameter("Button1", "Identifizieren"); //$NON-NLS-1$ //$NON-NLS-2$ + + int returnCode = client.executeMethod(method); + + String redirectLocation = null; + + GetMethod gmethod = null; + + String responseData = null; + + String server = ""; //$NON-NLS-1$ + + // Follow redirects + do { + // check return code + if (returnCode == HttpStatus.SC_MOVED_TEMPORARILY + || returnCode == HttpStatus.SC_MOVED_PERMANENTLY) { + + Header locationHeader = method + .getResponseHeader("location"); //$NON-NLS-1$ + if (locationHeader != null) { + redirectLocation = locationHeader.getValue(); + } else { + throw new IOException( + "Got HTTP 302 but no location to follow!"); //$NON-NLS-1$ + } + } else if (returnCode == HttpStatus.SC_OK) { + + if (gmethod != null) { + responseData = gmethod.getResponseBodyAsString(); + + if (gmethod + .getResponseHeader(LocalBKUState.BKU_REPSONE_HEADER_SERVER) != null) { + server = gmethod.getResponseHeader( + LocalBKUState.BKU_REPSONE_HEADER_SERVER) + .getValue(); + } + + } else { + responseData = method.getResponseBodyAsString(); + + if (method + .getResponseHeader(LocalBKUState.BKU_REPSONE_HEADER_SERVER) != null) { + server = method.getResponseHeader( + LocalBKUState.BKU_REPSONE_HEADER_SERVER) + .getValue(); + } + + } + redirectLocation = null; + } else { + throw new HttpException( + HttpStatus.getStatusText(returnCode)); + } + + if (redirectLocation != null) { + gmethod = new GetMethod(redirectLocation); + gmethod.setFollowRedirects(true); + returnCode = client.executeMethod(gmethod); + } + + } while (redirectLocation != null); + + // Now we have received some data lets check it: + + log.debug("Repsonse from A-Trust: " + responseData); //$NON-NLS-1$ + + log.info("Server: " + server); //$NON-NLS-1$ + + if (responseData.contains("sl:CreateXMLSignatureResponse xmlns:sl")) { //$NON-NLS-1$ + // success !! + + this.state.getSigningState().setSignatureResponse( + new SLResponse(responseData, server, null, null)); + this.state + .setCommunicationState(MobileBKUCommunicationState.FINAL); + } else { + status.decreaseTanTries(); + + if (status.getTanTries() <= 0) { + // move to POST_REQUEST + this.state.setCommunicationState(MobileBKUCommunicationState.POST_REQUEST); + } + } + } catch (Exception ex) { + log.error("Error in PostTanThread", ex); //$NON-NLS-1$ + this.state.setThreadException(ex); + } finally { + this.state.invokeUpdate(); + } + } + +} diff --git a/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/TrustedSocketFactory.java b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/TrustedSocketFactory.java new file mode 100644 index 00000000..6b5a6fdd --- /dev/null +++ b/pdf-over-gui/src/main/java/at/asit/pdfover/gui/workflow/states/mobilebku/TrustedSocketFactory.java @@ -0,0 +1,159 @@ +/* + * 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.workflow.states.mobilebku; + +// 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.ProtocolSocketFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + */ +public class TrustedSocketFactory implements ProtocolSocketFactory { + /** + * SLF4J Logger instance + **/ + private static final Logger log = LoggerFactory + .getLogger(TrustedSocketFactory.class); + + private SSLSocketFactory getFactory() throws NoSuchAlgorithmException, + KeyManagementException { + SSLContext sslContext = SSLContext.getInstance("TLS"); //$NON-NLS-1$ + sslContext.init(null, new TrustManager[] { new ASITTrustManager() }, + 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); + + 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( + "Not really an IOException! See inner exception", 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); + + 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( + "Not really an IOException! See inner exception", 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(); + Socket socket = null; + + SSLSocketFactory socketfactory = getFactory(); + if (timeout == 0) { + socket = socketfactory.createSocket(host, port, clientHost, + clientPort); + } else { + socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(clientHost, + clientPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + } + return socket; + } 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( + "Not really an IOException! See inner exception", ex); + } + } + } + +} -- cgit v1.2.3