From 32d17447a258188b2d534bcb0bf65a659ba7b7d0 Mon Sep 17 00:00:00 2001 From: mcentner Date: Fri, 29 Aug 2008 12:11:34 +0000 Subject: Initial import. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@1 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../egiz/bku/local/ui/BKUControllerInterface.java | 23 ++ .../at/gv/egiz/bku/local/ui/TrayIconDialog.java | 202 ++++++++++ .../egiz/bku/local/ui/TrayIconDialogInterface.java | 33 ++ .../main/java/at/gv/egiz/bku/utils/HexDump.java | 75 ++++ .../main/java/at/gv/egiz/bku/utils/StreamUtil.java | 101 +++++ .../at/gv/egiz/bku/utils/binding/Protocol.java | 41 ++ .../utils/urldereferencer/FormDataURLSupplier.java | 26 ++ .../HTTPURLProtocolHandlerImpl.java | 76 ++++ .../urldereferencer/SimpleFormDataContextImpl.java | 41 ++ .../egiz/bku/utils/urldereferencer/StreamData.java | 61 +++ .../utils/urldereferencer/URIResolverAdapter.java | 96 +++++ .../bku/utils/urldereferencer/URLDereferencer.java | 90 +++++ .../urldereferencer/URLDereferencerContext.java | 27 ++ .../utils/urldereferencer/URLProtocolHandler.java | 32 ++ utils/src/main/java/at/gv/egiz/dom/DOMUtils.java | 115 ++++++ .../egiz/idlink/CompressedIdentityLinkFactory.java | 416 +++++++++++++++++++++ .../at/gv/egiz/idlink/IdentityLinkTransformer.java | 285 ++++++++++++++ .../at/gv/egiz/idlink/ans1/CitizenPublicKey.java | 92 +++++ .../java/at/gv/egiz/idlink/ans1/IdentityLink.java | 315 ++++++++++++++++ .../java/at/gv/egiz/idlink/ans1/PersonData.java | 91 +++++ .../at/gv/egiz/idlink/ans1/PhysicalPersonData.java | 143 +++++++ .../apache/tomcat/util/http/AcceptLanguage.java | 151 ++++++++ .../egiz/slbinding/NamespaceContextCallback.java | 41 ++ .../at/gv/egiz/slbinding/RedirectCallback.java | 42 +++ .../at/gv/egiz/slbinding/RedirectEventFilter.java | 259 +++++++++++++ .../slbinding/RedirectUnmarshallerListener.java | 68 ++++ .../egiz/slbinding/impl/SignatureLocationType.java | 50 +++ .../gv/egiz/slbinding/impl/TransformsInfoType.java | 70 ++++ .../at/gv/egiz/slbinding/impl/XMLContentType.java | 60 +++ .../egiz/xades/QualifyingPropertiesException.java | 40 ++ .../gv/egiz/xades/QualifyingPropertiesFactory.java | 225 +++++++++++ .../egiz/xmldsig/KeyTypeNotSupportedException.java | 65 ++++ .../java/at/gv/egiz/xmldsig/KeyValueFactory.java | 279 ++++++++++++++ 33 files changed, 3731 insertions(+) create mode 100644 utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/HexDump.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/StreamUtil.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/binding/Protocol.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FormDataURLSupplier.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/SimpleFormDataContextImpl.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/StreamData.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URIResolverAdapter.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencerContext.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java create mode 100644 utils/src/main/java/at/gv/egiz/dom/DOMUtils.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/ans1/CitizenPublicKey.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/ans1/IdentityLink.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/ans1/PersonData.java create mode 100644 utils/src/main/java/at/gv/egiz/idlink/ans1/PhysicalPersonData.java create mode 100644 utils/src/main/java/at/gv/egiz/org/apache/tomcat/util/http/AcceptLanguage.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/NamespaceContextCallback.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/RedirectCallback.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/RedirectUnmarshallerListener.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/impl/SignatureLocationType.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java create mode 100644 utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java create mode 100644 utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesException.java create mode 100644 utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/xmldsig/KeyTypeNotSupportedException.java create mode 100644 utils/src/main/java/at/gv/egiz/xmldsig/KeyValueFactory.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java new file mode 100644 index 00000000..5e191c79 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java @@ -0,0 +1,23 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.local.ui; + +public interface BKUControllerInterface { + + public void shutDown(); + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java new file mode 100644 index 00000000..5aa74d99 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java @@ -0,0 +1,202 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.local.ui; + +import java.awt.AWTException; +import java.awt.Image; +import java.awt.MenuItem; +import java.awt.PopupMenu; +import java.awt.SystemTray; +import java.awt.TrayIcon; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ResourceBundle; + +import javax.imageio.ImageIO; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class TrayIconDialog implements TrayIconDialogInterface { + + private static Log log = LogFactory.getLog(TrayIconDialog.class); + private static TrayIconDialogInterface instance; + private boolean isSupported; + private BKUControllerInterface shutDown; + private TrayIcon trayIcon = null; + private ResourceBundle resourceBundle = null; + + private TrayIconDialog() { + } + + private void displayTrayMsg(String captionID, String messageID, + TrayIcon.MessageType type) { + if ((isSupported) && (resourceBundle != null)) { + try { + trayIcon.displayMessage(resourceBundle.getString(captionID), + resourceBundle.getString(messageID), type); + } catch (Exception ex) { + log.error(ex); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayInfo(java.lang.String + * , java.lang.String) + */ + public void displayInfo(String captionID, String messageID) { + displayTrayMsg(captionID, messageID, TrayIcon.MessageType.INFO); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayWarning(java.lang + * .String, java.lang.String) + */ + public void displayWarning(String captionID, String messageID) { + displayTrayMsg(captionID, messageID, TrayIcon.MessageType.WARNING); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayError(java.lang. + * String, java.lang.String) + */ + public void displayError(String captionID, String messageID) { + displayTrayMsg(captionID, messageID, TrayIcon.MessageType.ERROR); + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#init(java.util.ResourceBundle + * ) + */ + public void init(ResourceBundle resourceBundel) { + this.resourceBundle = resourceBundel; + isSupported = SystemTray.isSupported(); + log.info("Trayicon supported: " + isSupported); + try { + if (isSupported) { + SystemTray tray = SystemTray.getSystemTray(); + Image image = ImageIO.read(getClass().getClassLoader() + .getResourceAsStream("at/gv/egiz/bku/local/ui/chipperling.png")); + PopupMenu popup = new PopupMenu(); + MenuItem exitItem = new MenuItem(resourceBundel + .getString("TrayMenu.Shutdown")); + popup.add(exitItem); + exitItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + log.info("Calling Shutdown"); + if (shutDown != null) { + shutDown.shutDown(); + } + } + }); + + trayIcon = new TrayIcon(image, "BKULogo", popup); + trayIcon.setImageAutoSize(true); + trayIcon.setToolTip(resourceBundel.getString("TrayMenu.Tooltip")); + try { + tray.add(trayIcon); + } catch (AWTException e) { + log.error("TrayIcon could not be added.", e); + isSupported = false; + } + } + } catch (IOException e) { + log.error(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#setShutdownHook(at.gv.egiz + * .bku.local.ui.BKUControllerInterface) + */ + public void setShutdownHook(BKUControllerInterface shutDown) { + this.shutDown = shutDown; + } + + @SuppressWarnings("unchecked") + public synchronized static TrayIconDialogInterface getInstance() { + ClassLoader cl = TrayIconDialog.class.getClassLoader(); + if (instance == null) { + if (cl.toString().startsWith("sun.")) { + instance = new TrayIconDialog(); + return instance; + } + ClassLoader parent = cl; + while (!parent.toString().startsWith("sun.")) { + parent = parent.getParent(); + } + try { + Class otherClassInstance = (Class) parent + .loadClass(TrayIconDialog.class.getName()); + Method getInstanceMethod = otherClassInstance.getDeclaredMethod( + "getInstance", new Class[] {}); + Object otherSingleton = getInstanceMethod.invoke(null, new Object[] {}); + instance = (TrayIconDialogInterface) Proxy.newProxyInstance(cl, + new Class[] { TrayIconDialogInterface.class }, + new PassThroughProxyHandler(otherSingleton)); + } catch (ClassNotFoundException ce) { + instance = new TrayIconDialog(); + } catch (Exception e) { + log.error(e); + instance = new TrayIconDialog(); + } + return instance; + } + return instance; + } + + /** + * + * Only works for public methods + * + */ + static class PassThroughProxyHandler implements InvocationHandler { + private final Object delegate; + + public PassThroughProxyHandler(Object delegate) { + this.delegate = delegate; + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + Method delegateMethod = delegate.getClass().getMethod(method.getName(), + method.getParameterTypes()); + return delegateMethod.invoke(delegate, args); + } + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java new file mode 100644 index 00000000..87c64102 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java @@ -0,0 +1,33 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.local.ui; + +import java.util.ResourceBundle; + +public interface TrayIconDialogInterface { + + public abstract void displayInfo(String captionID, String messageID); + + public abstract void displayWarning(String captionID, String messageID); + + public abstract void displayError(String captionID, String messageID); + + public abstract void init(ResourceBundle resourceBundel); + + public abstract void setShutdownHook(BKUControllerInterface shutDown); + +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/HexDump.java b/utils/src/main/java/at/gv/egiz/bku/utils/HexDump.java new file mode 100644 index 00000000..88d49bad --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/HexDump.java @@ -0,0 +1,75 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.io.Writer; + +public class HexDump { + + public static String hexDump(InputStream is) throws IOException { + StringWriter writer = new StringWriter(); + hexDump(is, writer); + return writer.toString(); + } + + public static void hexDump(InputStream is, Writer writer) throws IOException { + hexDump(is, writer, 16); + } + + public static void hexDump(InputStream is, Writer writer, int chunkSize) throws IOException { + + byte[] chunk = new byte[chunkSize]; + long adr = 0; + for (int l; (l = is.read(chunk)) != -1;) { + + writer.append(String.format("[%06x]", adr)); + for (int i = 0; i < l; i++) { + if (i % 8 == 0) { + writer.append(" "); + } else { + writer.append(":"); + } + writer.append(Integer.toHexString((chunk[i] & 240) >> 4)); + writer.append(Integer.toHexString(chunk[i] & 15)); + } + + for (int i = 0; i < (chunkSize - l); i++) { + writer.append(" "); + } + + for (int i = 0; i < l; i++) { + if (i % 8 == 0) { + writer.append(" "); + } + if (chunk[i] > 31 && chunk[i] < 127) { + writer.append((char) chunk[i]); + } else { + writer.append("."); + } + } + + writer.append("\n"); + adr += l; + + } + + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/StreamUtil.java b/utils/src/main/java/at/gv/egiz/bku/utils/StreamUtil.java new file mode 100644 index 00000000..a774df2b --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/StreamUtil.java @@ -0,0 +1,101 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +public class StreamUtil { + + /** + * Copies data. None of the streams will be closed. + * + * @param is + * @param os + * @throws IOException + */ + public static void copyStream(InputStream is, OutputStream os) + throws IOException { + copyStream(is, os, 1024); + } + + /** + * Copies data. None of the streams will be closed. + * + * @param is + * @param os + * @throws IOException + */ + public static void copyStream(InputStream is, OutputStream os, int bufferSize) + throws IOException { + byte[] buffer = new byte[bufferSize]; + copyStream(is, os, buffer); + } + + /** + * Copies data. None of the streams will be closed. + * + * @param is + * @param os + * @throws IOException + */ + public static void copyStream(InputStream is, OutputStream os, byte[] buffer) + throws IOException { + for (int i = is.read(buffer); i > -1; i = is.read(buffer)) { + os.write(buffer, 0, i); + } + } + + /** + * Copies data. None of the streams will be closed. + * + * @param is + * @param os + * @throws IOException + */ + public static void copyStream(Reader is, Writer os) + throws IOException { + copyStream(is, os, 1024); + } + + /** + * Copies data. None of the streams will be closed. + * + * @param is + * @param os + * @throws IOException + */ + public static void copyStream(Reader is, Writer os, int bufferSize) + throws IOException { + char[] chars = new char[bufferSize]; + for (int i = is.read(chars); i > -1; i = is.read(chars)) { + os.write(chars, 0, i); + } + } + + + public static String asString(InputStream is, String charset) + throws IOException { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + copyStream(is, os); + return new String(os.toByteArray(), charset); + } +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/binding/Protocol.java b/utils/src/main/java/at/gv/egiz/bku/utils/binding/Protocol.java new file mode 100644 index 00000000..f0504697 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/binding/Protocol.java @@ -0,0 +1,41 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.binding; + +public enum Protocol { + HTTP("http"), HTTPS("https"); + + private String name; + + Protocol(String s) { + name = s; + } + + public String toString() { + return name; + } + + public static Protocol fromString(String protocol) { + if (HTTP.toString().equalsIgnoreCase(protocol)) { + return HTTP; + } + if (HTTPS.toString().equalsIgnoreCase(protocol)) { + return HTTPS; + } + return null; + } +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FormDataURLSupplier.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FormDataURLSupplier.java new file mode 100644 index 00000000..7272f1bb --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/FormDataURLSupplier.java @@ -0,0 +1,26 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.InputStream; + +public interface FormDataURLSupplier { + public static final String PROPERTY_KEY_NAME = "at.gv.egiz.bku.util.urldereferencer.FormDataURLSupplier"; + + public InputStream getFormData(String aParameterName); + public String getFormDataContentType(String aParameterName); +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java new file mode 100644 index 00000000..5cba2e1d --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java @@ -0,0 +1,76 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.InvalidParameterException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class HTTPURLProtocolHandlerImpl implements URLProtocolHandler { + + private static Log log = LogFactory.getLog(HTTPURLProtocolHandlerImpl.class); + + public final static String HTTP = "http"; + public final static String HTTPS = "https"; + public final static String FORMDATA = "formdata"; + public final static String[] PROTOCOLS = { HTTP, HTTPS, FORMDATA }; + + public StreamData dereference(String aUrl, URLDereferencerContext aContext) + throws IOException { + String urlString = aUrl.toLowerCase().trim(); + if (urlString.startsWith(FORMDATA)) { + log.debug("Requested to dereference a formdata url"); + return dereferenceFormData(aUrl, aContext); + } + + URL url = new URL(aUrl); + if ((!HTTP.equalsIgnoreCase(url.getProtocol()) && (!HTTPS + .equalsIgnoreCase(url.getProtocol())))) { + throw new InvalidParameterException("Url " + aUrl + " not supported"); + } + return dereferenceHTTP(url); + } + + protected StreamData dereferenceHTTP(URL url) throws IOException { + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + return new StreamData(url.toString(), httpConn.getContentType(), httpConn + .getInputStream()); + } + + protected StreamData dereferenceFormData(String aUrl, + URLDereferencerContext aContext) throws IOException { + log.debug("Dereferencing formdata url: " + aUrl); + String[] parts = aUrl.split(":", 2); + FormDataURLSupplier supplier = (FormDataURLSupplier) aContext + .getProperty(FormDataURLSupplier.PROPERTY_KEY_NAME); + if (supplier == null) { + throw new NullPointerException( + "No FormdataUrlSupplier found in provided context"); + } + String contentType = supplier.getFormDataContentType(parts[1]); + InputStream is = supplier.getFormData(parts[1]); + if (is != null) { + return new StreamData(aUrl, contentType, is); + } + return null; + } +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/SimpleFormDataContextImpl.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/SimpleFormDataContextImpl.java new file mode 100644 index 00000000..e9da9c81 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/SimpleFormDataContextImpl.java @@ -0,0 +1,41 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +public class SimpleFormDataContextImpl implements URLDereferencerContext { + protected FormDataURLSupplier formdata; + + /** + * + * @param formdata must not be null + */ + public SimpleFormDataContextImpl(FormDataURLSupplier formdata) { + if (formdata == null) { + throw new NullPointerException("FormdataURLSupplier must not be null"); + } + this.formdata = formdata; + } + + @Override + public Object getProperty(Object key) { + if (key.equals(FormDataURLSupplier.PROPERTY_KEY_NAME)) { + return formdata; + } + return null; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/StreamData.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/StreamData.java new file mode 100644 index 00000000..541c6878 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/StreamData.java @@ -0,0 +1,61 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.InputStream; + +/** + * This class models the result when dereferencing an URL. + * + */ +public class StreamData { + + protected InputStream inputStream; + protected String url; + protected String contentType; + + /** + * + * @param url + * @param contentType + * @param stream must not be null + */ + public StreamData(String url, String contentType, InputStream stream) { + if (stream == null) { + throw new NullPointerException("Parameter inputstream must not be null"); + } + inputStream = stream; + this.contentType = contentType; + this.url = url; + } + + public String getUrl() { + return url; + } + + /** + * + * @return the returned stream must be closed + */ + public InputStream getStream() { + return inputStream; + } + + public String getContentType() { + return contentType; + } +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URIResolverAdapter.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URIResolverAdapter.java new file mode 100644 index 00000000..2d11010e --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URIResolverAdapter.java @@ -0,0 +1,96 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.stream.StreamSource; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Adapter to make the Urldereferencer work as URIResolver for + * Stylesheettransforms. + * + * @author wbauer + * + */ +public class URIResolverAdapter implements URIResolver { + + private static Log log = LogFactory.getLog(URIResolverAdapter.class); + + private URLDereferencer urlDereferencer; + private URLDereferencerContext ctx; + + /** + * + * @param deferecencer + * must not be null + * @param ctx may be null + */ + public URIResolverAdapter(URLDereferencer deferecencer, + URLDereferencerContext ctx) { + if (deferecencer == null) { + throw new NullPointerException("Urlderefencer must not be set to null"); + } + this.urlDereferencer = deferecencer; + this.ctx = ctx; + } + + @Override + public Source resolve(String href, String base) throws TransformerException { + log.debug("Resolving href: "+href+" base: "+base); + try { + URI baseUri = null; + URI hrefUri = new URI(href); + if (base != null) { + baseUri = new URI(base); + } + URI abs; + if (baseUri != null) { + abs = baseUri.resolve(hrefUri); + } else { + abs = hrefUri; + } + if (!abs.isAbsolute()) { + throw new TransformerException("Only absolute URLs are supported"); + } + return new StreamSource(urlDereferencer.dereference(abs.toString(), ctx) + .getStream()); + } catch (URISyntaxException e) { + throw new TransformerException("Cannot resolve URI: base:" + base + + " href:" + href, e); + } catch (IOException iox) { + throw new TransformerException("Cannot resolve URI: base:" + base + + " href:" + href, iox); + } + } + + public URLDereferencerContext getCtx() { + return ctx; + } + + public void setCtx(URLDereferencerContext ctx) { + this.ctx = ctx; + } +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java new file mode 100644 index 00000000..d747753f --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java @@ -0,0 +1,90 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Class used to dereference (external URLs). + * + * @author wbauer + * + */ +public class URLDereferencer { + + private static Log log = LogFactory.getLog(URLDereferencer.class); + + private static URLDereferencer instance = new URLDereferencer(); + + private Map handlerMap = new HashMap(); + + private URLDereferencer() { + registerHandlers(); + } + + /** + * + * @param aUrl + * must not be null + * @param aContext + * @throws MalformedURLException + * if the protocol is not supported + */ + public StreamData dereference(String aUrl, URLDereferencerContext aContext) + throws IOException { + log.debug("Looking for handler for URL: " + aUrl); + int i = aUrl.indexOf(":"); + if (i == -1) { + throw new MalformedURLException("Invalid url: " + aUrl); + } + String protocol = aUrl.substring(0, i).toLowerCase().trim(); + URLProtocolHandler handler = handlerMap.get(protocol); + if (handler == null) { + throw new MalformedURLException("No handler for protocol: " + protocol + + " found"); + } + return handler.dereference(aUrl, aContext); + } + + /** + * Registers a handler for a protocol. + * + * @param aProtocol + * @param aHandler + * may be set to null to disable this protocol + */ + public void registerHandler(String aProtocol, URLProtocolHandler aHandler) { + handlerMap.put(aProtocol.toLowerCase(), aHandler); + } + + public static URLDereferencer getInstance() { + return instance; + } + + protected void registerHandlers() { + URLProtocolHandler handler = new HTTPURLProtocolHandlerImpl(); + for (String proto : HTTPURLProtocolHandlerImpl.PROTOCOLS) { + handlerMap.put(proto, handler); + } + } +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencerContext.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencerContext.java new file mode 100644 index 00000000..6befd5b3 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencerContext.java @@ -0,0 +1,27 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +public interface URLDereferencerContext { + + /** + * + * @param key + * @return may return null + */ + public Object getProperty(Object key); +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java new file mode 100644 index 00000000..f584f450 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java @@ -0,0 +1,32 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.IOException; +import java.net.MalformedURLException; + + +public interface URLProtocolHandler { + /** + * + * @param aUrl + * @param aContext + * @return the streamdata of this url or null if the url cannot be resolved. + * @throws IOException + */ + public StreamData dereference(String aUrl, URLDereferencerContext aContext) throws IOException; +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/dom/DOMUtils.java b/utils/src/main/java/at/gv/egiz/dom/DOMUtils.java new file mode 100644 index 00000000..32c7c5e6 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/dom/DOMUtils.java @@ -0,0 +1,115 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.dom; + +import iaik.utils.Base64OutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Text; +import org.w3c.dom.bootstrap.DOMImplementationRegistry; +import org.w3c.dom.ls.DOMImplementationLS; + +public final class DOMUtils { + + /** + * DOM Implementation. + */ + private static String DOM_LS_3_0 = "LS 3.0"; + + private static DOMImplementationLS domImplLS; + + private DOMUtils() { + } + + private static synchronized void ensureDOMImplementation() { + + if (domImplLS == null) { + + DOMImplementationRegistry registry; + try { + registry = DOMImplementationRegistry.newInstance(); + } catch (Exception e) { + throw new RuntimeException("Failed to get DOMImplementationRegistry."); + } + + domImplLS = (DOMImplementationLS) registry.getDOMImplementation(DOM_LS_3_0); + if (domImplLS == null) { + throw new RuntimeException("Failed to get DOMImplementation " + DOM_LS_3_0); + } + + } + + } + + public static DOMImplementationLS getDOMImplementationLS() { + + if (domImplLS == null) { + ensureDOMImplementation(); + } + + return domImplLS; + } + + public static Document createDocument() { + + // This does not work with the Xerces-J version (2.6.2) included in Java 6 + //document = ((DOMImplementation) domImplLS).createDocument(null, null, null); + // Therefore we have to employ the good old DocumentBuilderFactory + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + DocumentBuilder db; + try { + db = dbf.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + throw new RuntimeException(e); + } + return db.newDocument(); + + } + + public static Text createBase64Text(byte[] bytes, Document doc) throws IOException { + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Base64OutputStream base64OutputStream = new Base64OutputStream(outputStream); + base64OutputStream.write(bytes); + base64OutputStream.flush(); + return doc.createTextNode(outputStream.toString("ASCII")); + + } + + public static Text createBase64Text(InputStream bytes, Document doc) throws IOException { + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Base64OutputStream base64OutputStream = new Base64OutputStream(outputStream, new byte[] {0xa}); + + byte[] b = new byte[2^8]; + for(int l; (l = bytes.read(b)) != -1;) { + base64OutputStream.write(b, 0, l); + } + + base64OutputStream.flush(); + return doc.createTextNode(outputStream.toString("ASCII")); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java new file mode 100644 index 00000000..5f4e5d92 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/CompressedIdentityLinkFactory.java @@ -0,0 +1,416 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.bind.Unmarshaller; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; + +import org.w3._2000._09.xmldsig_.KeyValueType; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; +import at.gv.e_government.reference.namespace.persondata._20020228_.AbstractPersonType; +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; +import at.gv.egiz.idlink.ans1.CitizenPublicKey; +import at.gv.egiz.idlink.ans1.IdentityLink; +import at.gv.egiz.idlink.ans1.PersonData; +import at.gv.egiz.idlink.ans1.PhysicalPersonData; +import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; +import at.gv.egiz.xmldsig.KeyValueFactory; + +public class CompressedIdentityLinkFactory { + + /** + * The instance returned by {@link #getInstance()}. + */ + private static CompressedIdentityLinkFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + /** + * The KeyValueFactory. + */ + private static KeyValueFactory keyValueFactory; + + /** + * Get an instance of this CompressedIdentityLinkFactory. + * + * @return an instance of this CompressedIdentityLinkFactory + */ + public synchronized static CompressedIdentityLinkFactory getInstance() { + if (instance == null) { + instance = new CompressedIdentityLinkFactory(); + } + return instance; + } + + /** + * Private constructor. + */ + private CompressedIdentityLinkFactory() { + + keyValueFactory = new KeyValueFactory(); + + StringBuffer packageNames = new StringBuffer(); + packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + + } + + public IdentityLink createIdLink(CompressedIdentityLinkType compressedIdentityLinkType) { + + // IssuerTemplate + String issuerTemplate = compressedIdentityLinkType.getIssuerTemplate(); + + // AssertionId + String assertionID = compressedIdentityLinkType.getAssertionID(); + + // IssueInstant + String issueInstant = compressedIdentityLinkType.getIssueInstant(); + + AbstractPersonType personDataType = compressedIdentityLinkType.getPersonData(); + + String baseId = null; + + List identifications = personDataType.getIdentification(); + for (IdentificationType identificationType : identifications) { + String type = identificationType.getType(); + if ("urn:publicid:gv.at:baseid".equals(type)) { + baseId = identificationType.getValue().getValue(); + } + } + + String givenName = null; + String familyName = null; + String dateOfBirth = null; + + if (personDataType instanceof PhysicalPersonType) { + PhysicalPersonType physicalPersonType = (PhysicalPersonType) personDataType; + PersonNameType name = physicalPersonType.getName(); + List givenNames = name.getGivenName(); + if (!givenNames.isEmpty()) { + givenName = givenNames.get(0); + } + List familyNames = name.getFamilyName(); + if (!familyNames.isEmpty()) { + familyName = familyNames.get(0).getValue(); + } + dateOfBirth = physicalPersonType.getDateOfBirth(); + } + + PhysicalPersonData physicalPersonData = new PhysicalPersonData(baseId, givenName, familyName, dateOfBirth); + PersonData personData = new PersonData(physicalPersonData); + + int numKeys = compressedIdentityLinkType.getCitizenPublicKey().size(); + CitizenPublicKey[] citizenPublicKeys = new CitizenPublicKey[numKeys]; + for (int i = 0; i < numKeys;) { + citizenPublicKeys[i] = new CitizenPublicKey(++i); + } + + byte[] signatureValue = compressedIdentityLinkType.getSignatureValue(); + byte[] referenceDigest = compressedIdentityLinkType.getReferenceDigest(); + byte[] referenceManifestDigest = compressedIdentityLinkType.getReferenceManifestDigest(); + byte[] manifestReferenceDigest = compressedIdentityLinkType.getManifestReferenceDigest(); + + IdentityLink idLink = new IdentityLink(issuerTemplate, assertionID, issueInstant, personData, citizenPublicKeys, signatureValue); + idLink.setReferenceDigest(referenceDigest); + idLink.setReferenceManifestDigest(referenceManifestDigest); + idLink.setManifestReferenceDigest(manifestReferenceDigest); + + return idLink; + + } + + /** + * Creates a new CompressedIdentityLink element from the given + * ASN.1 representation of an idLink. + * + * @param idLink + * the ASN.1 representation of an IdentityLink + * @param certificates + * a list of {@link X509Certificate}s containing the corresponding + * public keys + * @param domainId TODO + * @return a new CompressedIdentityLink element + * + * @throws NullPointerException + * if idLink or certificates is + * null + * @throws IllegalArgumentException + * if idLink references certificates not in the range + * of the certificates list + */ + public JAXBElement createCompressedIdentityLink( + at.gv.egiz.idlink.ans1.IdentityLink idLink, + List certificates, String domainId) { + + at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory prFactory = + new at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory(); + + at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory pbFactory = + new at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory(); + + org.w3._2000._09.xmldsig_.ObjectFactory dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); + + // PersonData + PhysicalPersonData __physicalPersonData = idLink.getPersonData() + .getPhysicalPerson(); + + Value identificationTypeValue = prFactory.createIdentificationTypeValue(); + identificationTypeValue.setValue(__physicalPersonData.getBaseId()); + IdentificationType identificationType = prFactory + .createIdentificationType(); + identificationType.setValue(identificationTypeValue); + if (domainId != null) { + identificationType.setType(domainId); + } else { + identificationType.setType("urn:publicid:gv.at:baseid"); + } + + PersonNameType personNameType = prFactory.createPersonNameType(); + FamilyName personNameTypeFamilyName = prFactory + .createPersonNameTypeFamilyName(); + personNameTypeFamilyName.setValue(__physicalPersonData.getFamilyName()); + personNameType.getFamilyName().add(personNameTypeFamilyName); + personNameType.getGivenName().add(__physicalPersonData.getGivenName()); + + PhysicalPersonType physicalPersonType = prFactory + .createPhysicalPersonType(); + physicalPersonType.getIdentification().add(identificationType); + physicalPersonType.setName(personNameType); + physicalPersonType.setDateOfBirth(__physicalPersonData.getDateOfBirth()); + + // CompressedIdentityLink + CompressedIdentityLinkType compressedIdentityLinkType = pbFactory + .createCompressedIdentityLinkType(); + compressedIdentityLinkType.setIssuerTemplate(idLink.getIssuerTemplate()); + compressedIdentityLinkType.setAssertionID(idLink.getAssertionID()); + compressedIdentityLinkType.setIssueInstant(idLink.getIssueInstant()); + compressedIdentityLinkType.setPersonData(physicalPersonType); + + // CitizenPublicKey + CitizenPublicKey[] __citizenPublicKeys = idLink.getCitizenPublicKeys(); + for (CitizenPublicKey __citizenPublicKey : __citizenPublicKeys) { + + X509Certificate certificate = certificates.get(__citizenPublicKey.getOnToken()); + PublicKey publicKey = certificate.getPublicKey(); + + JAXBElement keyValue; + try { + keyValue = keyValueFactory.createKeyValue(publicKey); + } catch (KeyTypeNotSupportedException e) { + // TODO: handle exception properly + throw new RuntimeException(e); + } + + KeyValueType keyValueType = dsFactory.createKeyValueType(); + keyValueType.getContent().add(keyValue); + + compressedIdentityLinkType.getCitizenPublicKey().add(keyValueType); + } + + compressedIdentityLinkType.setSignatureValue(idLink.getSignatureValue()); + compressedIdentityLinkType.setReferenceDigest(idLink.getReferenceDigest()); + compressedIdentityLinkType.setReferenceManifestDigest(idLink + .getReferenceManifestDigest()); + compressedIdentityLinkType.setManifestReferenceDigest(idLink + .getManifestReferenceDigest()); + JAXBElement compressedIdentityLink = pbFactory + .createCompressedIdentityLink(compressedIdentityLinkType); + + return compressedIdentityLink; + + } + + /** + * Marshall the given compressedIdentityLink into a DOM document + * with the given Nodes as parent and nextSibling + * nodes. + * + * @param compressedIdentityLink + * the CompressedIdentityLink element + * @param parent + * the parent node + * @param nextSibling + * the next sibling node (may be null) + * @param applyWorkarounds + * apply workarounds as spefiyed by + * {@link #applyWorkarounds(Element, int)} + * + * @throws JAXBException + * if an unexpected error occurs while marshalling + * @throws NullPointerException + * if compressdIdentityLink or parent is + * null + */ + public void marshallCompressedIdentityLink( + JAXBElement compressedIdentityLink, + Node parent, Node nextSibling, boolean applyWorkarounds) throws JAXBException { + + DOMResult result = new DOMResult(parent, nextSibling); + + + try { + Marshaller marshaller = jaxbContext.createMarshaller(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + marshaller.marshal(compressedIdentityLink, result); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + + if (applyWorkarounds) { + Element element = (Element) ((nextSibling != null) + ? nextSibling.getPreviousSibling() + : parent.getFirstChild()); + applyWorkarounds(element, 76); + } + + } + + @SuppressWarnings("unchecked") + public CompressedIdentityLinkType unmarshallCompressedIdentityLink(Source source) throws JAXBException { + + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + + return ((JAXBElement) unmarshaller.unmarshal(source)).getValue(); + + } + + /** + * Apply some workarounds to the given CompressedIdentityLink + * element to achieve compatibility with IdentityLink + * transformation stylesheets that have been designed for a (buggy) form of + * the CompressedIdentityLink as produced by a well-known citizen card + * environment implementation. + * + *
    + *
  1. Replace the attribute node URN of the + * NamedCurve element of an ECDSAKeyValue element by + * a child text-node with the same content.
  2. + *
  3. Replace the attribute nodes Value of the X + * and Y elements of an ECDSAKeyValue element by a + * child text-node with the same content.
  4. + *
  5. Insert "\n" at base64LineLength into the Base64 + * content of the Modulus element of an RSAKeyValue + * element. + *
+ * + * @param element + * the CompressedIdentityLink element + * @param base64LineLength + * the line length of Base64 content + */ + public void applyWorkarounds(Element element, int base64LineLength) { + + Document document = element.getOwnerDocument(); + + NodeList nodeList = element.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "NamedCurve"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node ecdsaNameCurve = nodeList.item(i); + Attr attrNode = ((Element) ecdsaNameCurve).getAttributeNodeNS(null, + "URN"); + ecdsaNameCurve + .appendChild(document.createTextNode(attrNode.getValue())); + ((Element) ecdsaNameCurve).removeAttributeNode(attrNode); + } + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "X"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node x = nodeList.item(i); + Attr attrNode = ((Element) x).getAttributeNodeNS(null, "Value"); + x.appendChild(document.createTextNode(attrNode.getValue())); + ((Element) x).removeAttributeNode(attrNode); + } + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2001/04/xmldsig-more#", "Y"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node y = nodeList.item(i); + Attr attrNode = ((Element) y).getAttributeNodeNS(null, "Value"); + y.appendChild(document.createTextNode(attrNode.getValue())); + ((Element) y).removeAttributeNode(attrNode); + } + + if (base64LineLength > 0) { + nodeList = document.getElementsByTagNameNS( + "http://www.w3.org/2000/09/xmldsig#", "Modulus"); + for (int i = 0; i < nodeList.getLength(); i++) { + Node modulus = nodeList.item(i); + String value = ((Element) modulus).getTextContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader( + new ByteArrayInputStream(value.getBytes()))); + char[] buff = new char[base64LineLength]; + StringBuffer newValue = new StringBuffer(); + int found = 0; + try { + while ((found = reader.read(buff)) > 0) { + newValue.append(buff, 0, found); + if (found == base64LineLength) + newValue.append('\n'); + } + } catch (IOException e) { + // this should never happen, as we are reading from a ByteArrayInputStream + throw new RuntimeException(e); + } + ((Element) modulus).setTextContent(newValue.toString()); + } + + } + + + } + +} diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java new file mode 100644 index 00000000..7886b07d --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java @@ -0,0 +1,285 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamSource; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +public class IdentityLinkTransformer { + + private class IdLTransformer { + + /** + * Is transformer in use? + */ + private boolean inUse = false; + + /** + * How often has this transformer been used? + */ + private int timesUsed = 0; + + /** + * The time this transformer has been created. + */ + private long created; + + /** + * When has this transformer been used the last time? + */ + private long lastTimeUsed; + + /** + * Average performance in milliseconds. + */ + private long time; + + /** + * Time used for initialization. + */ + private long initTime; + + /** + * The stylesheet transformer. + */ + private Transformer transformer; + + /** + * Stylesheet URL. + */ + private String stylesheetURL; + + /** + * + * @param stylesheetURL + * @throws IOException + * @throws TransformerConfigurationException + */ + public IdLTransformer(String stylesheetURL) throws IOException, TransformerConfigurationException { + + created = System.currentTimeMillis(); + + // TODO: implement stylesheet cache + this.stylesheetURL = stylesheetURL; + URL url = new URL(stylesheetURL); + + if (!"http".equalsIgnoreCase(url.getProtocol()) && !"https".equalsIgnoreCase(url.getProtocol())) { + throw new MalformedURLException("Protocol " + url.getProtocol() + " not supported for IssuerTemplate URL."); + } + StreamSource source = new StreamSource(url.openStream()); + + transformer = factory.newTransformer(source); + + initTime = System.currentTimeMillis() - created; + + } + + public void transform(Source xmlSource, Result outputTarget) throws TransformerException { + long t0 = System.currentTimeMillis(); + try { + transformer.transform(xmlSource, outputTarget); + } catch (TransformerException e) { + throw e; + } finally { + inUse = false; + long t1 = System.currentTimeMillis(); + time += (t1 - t0); + timesUsed++; + lastTimeUsed = System.currentTimeMillis(); + } + } + + /** + * @return true if this transformer is in use, or false otherwise + */ + public boolean isInUse() { + return inUse; + } + + @Override + public String toString() { + StringBuffer str = new StringBuffer(); + str.append("Transformer ").append(stylesheetURL) + .append("\n created ").append(new Date(created)).append(" used ").append( + timesUsed).append(" times, (init ").append(initTime).append("ms / ") + .append(((float) time) / timesUsed).append("ms avg) last time ").append(new Date(lastTimeUsed)); + return str.toString(); + } + + } + + /** + * The transfomer factory. + */ + private static TransformerFactory factory; + + /** + * The instance to be returned by {@link #getInstance()}. + */ + private static IdentityLinkTransformer instance; + + /** + * Returns an instance of this IdentityLinkTransfomer. + * + * @return an instance of this IdentityLinkTransformer + */ + public static IdentityLinkTransformer getInstance() { + if (instance == null) { + instance = new IdentityLinkTransformer(); + factory = TransformerFactory.newInstance(); + } + return instance; + } + + /** + * Sets the given domainIdentifier on the corresponding + * node of the given idLink. + *

This method may be used to cope with a flaw in the IssuerTemplate-Stylesheets + * used to transform a CompressedIdentitiyLink into an + * IdentityLink. Some IssuerTemplate-Stylesheets do not + * consider the pr:Type element value of the + * CompressedIdentityLink and render a pr:Type + * element value of urn:publicid:gv.at:baseid + * into the IdentityLink structure. This method allows to + * set the pr:Type element value on the given idLink + * after the transformation. + *

+ * + * @param idLink the IdentityLink element or one of it's ancestors. + * Must not be null. + * + * @param domainIdentifier the value to be set for the pr:Type element + * + * @throws NullPointerException if idLink is null. + */ + public static void setDomainIdentifier(Node idLink, String domainIdentifier) { + + Element element; + if (idLink instanceof Element) { + element = (Element) idLink; + } else if (idLink instanceof Document) { + element = ((Document) idLink).getDocumentElement(); + } else if (idLink != null) { + Document document = idLink.getOwnerDocument(); + element = document.getDocumentElement(); + } else { + throw new NullPointerException("Parameter 'idLink' must no be null."); + } + + NodeList nodeList = element.getElementsByTagNameNS( + "http://reference.e-government.gv.at/namespace/persondata/20020228#", + "Type"); + + for (int i = 0; i < nodeList.getLength(); i++) { + if (nodeList.item(i) instanceof Element) { + Element typeElement = (Element) nodeList.item(i); + NodeList children = typeElement.getChildNodes(); + for (int j = 0; j < children.getLength(); j++) { + if (children.item(j) instanceof Text) { + ((Text) children.item(j)).setNodeValue(domainIdentifier); + } + } + } + } + + } + + /** + * The pool of Transformer. + */ + private Map> pool; + + /** + * Private constructor. + */ + private IdentityLinkTransformer() { + pool = new HashMap>(); + } + + private synchronized IdLTransformer getFreeTransfomer(String stylesheetURL) throws TransformerConfigurationException, IOException { + + IdLTransformer transformer = null; + + List transfomerList = pool.get(stylesheetURL); + if (transfomerList == null) { + transfomerList = new ArrayList(); + pool.put(stylesheetURL, transfomerList); + } + + for (IdLTransformer candTransformer : transfomerList) { + if (!candTransformer.inUse) { + transformer = candTransformer; + break; + } + } + + if (transformer == null) { + transformer = new IdLTransformer(stylesheetURL); + transfomerList.add(transformer); + } + + transformer.inUse = true; + return transformer; + + } + + public void transformIdLink(String stylesheetURL, Source source, Result result) throws IOException, TransformerException { + IdLTransformer transformer = getFreeTransfomer(stylesheetURL); + transformer.transform(source, result); + } + + public String getStatistics() { + + StringBuffer str = new StringBuffer(); + Iterator keys = pool.keySet().iterator(); + int count = 0; + while (keys.hasNext()) { + String stylesheetURL = (String) keys.next(); + str.append("Stylesheet URL: ").append(stylesheetURL); + Iterator transformer = pool.get(stylesheetURL).iterator(); + while (transformer.hasNext()) { + IdLTransformer idLTransformer = (IdLTransformer) transformer.next(); + str.append("\n ").append(idLTransformer); + count++; + } + } + str.append("\n(").append(count).append(" transformer)"); + return str.toString(); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/idlink/ans1/CitizenPublicKey.java b/utils/src/main/java/at/gv/egiz/idlink/ans1/CitizenPublicKey.java new file mode 100644 index 00000000..c32cf2b9 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/ans1/CitizenPublicKey.java @@ -0,0 +1,92 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink.ans1; + +import java.math.BigInteger; + +import iaik.asn1.*; + +/** + * This class implements the ASN.1 representation of the + * CitizenPublicKey of a compressed identity link. + * + *
CitizenPublicKey ::= CHOICE { 
+    onToken [0] INTEGER, 
+    referenceURL [1] UTF8String, 
+    x509Data [2] SubjectPublicKeyInfo 
+}  
+
+ * + * @author mivkovic@egiz.gv.at, mcentner@egiz.gv.at + */ +public class CitizenPublicKey implements ASN1Type { + + /** + * onToken + */ + private int onToken; // INTEGER + + /** + * Creates a new CitizenPublicKey with the given + * onToken value. + * + * @param onToken + */ + public CitizenPublicKey(int onToken) { + this.onToken = onToken; + } + + /** + * Creates a new CitizenPublicKey from the given ASN.1 representation. + * + * @param obj + * @throws CodingException + */ + public CitizenPublicKey(ASN1Object obj) throws CodingException { + decode(obj); + } + + @Override + public void decode(ASN1Object obj) throws CodingException { + try { + BigInteger Value = (BigInteger)(obj.getValue()); + onToken = Value.intValue(); + } catch (Exception ex) { + throw new CodingException(ex.toString()); + } + } + + @Override + public ASN1Object toASN1Object() { + INTEGER ot = new INTEGER(onToken); + return ot; + } + + /** + * Returns the DER encoding of this CitizenPublicKey. + * + * @return the DER encoding of this CitizenPublicKey + */ + public byte[] getEncoded() { + return DerCoder.encode(toASN1Object()); + } + + public int getOnToken() { + return onToken; + } + +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/idlink/ans1/IdentityLink.java b/utils/src/main/java/at/gv/egiz/idlink/ans1/IdentityLink.java new file mode 100644 index 00000000..37e4b240 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/ans1/IdentityLink.java @@ -0,0 +1,315 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink.ans1; + +import iaik.asn1.ASN1Object; +import iaik.asn1.ASN1Type; +import iaik.asn1.BIT_STRING; +import iaik.asn1.CON_SPEC; +import iaik.asn1.CodingException; +import iaik.asn1.DerCoder; +import iaik.asn1.INTEGER; +import iaik.asn1.SEQUENCE; +import iaik.asn1.UTF8String; + +/** + * This class impelments an ASN.1 representation of the compressed IdentiyLink. + *
+PersonenBindung ::= SEQUENCE { 
+    version INTEGER, 
+    issuerTemplate UTF8String, 
+    assertionID UTF8String, 
+    issueInstant UTF8String, 
+    personData PersonData, 
+    citizenPublicKey SEQUENCE SIZE (1..MAX) OF CitizenPublicKey, 
+    signatureValue BIT STRING, 
+    referenceDigest [0] BIT STRING OPTIONAL, 
+    referenceManifestDigest [1] BIT STRING OPTIONAL, 
+    manifestReferenceDigest [2] BIT STRING OPTIONAL 
+} 
+
+ * + * @author mivkovic@egiz.gv.at, mcentner@egiz.gv.at + */ +public class IdentityLink implements ASN1Type { + + private int version = 1; // INTEGER + private String issuerTemplate; // UTF8String + private String assertionID; // UTF8String + private String issueInstant; // UTF8String + private PersonData personData; // PersonData + private CitizenPublicKey[] citizenPublicKeys; // SEQUENCE SIZE (1..MAX) OF + private byte[] signatureValue; // BIT STRING + private byte[] referenceDigest; // BIT STRING OPTIONAL + private byte[] referenceManifestDigest; // BIT STRING OPTIONAL + private byte[] manifestReferenceDigest; // BIT STRING OPTIONAL + + /** + * Creates a new IdentityLink with the given + * issuerTemplate, assertionID, + * issueInstant, personData, + * citizenPublicKeys and signatureValue. + * + * @param issuerTemplate + * @param assertionID + * @param issueInstant + * @param personData + * @param citizenPublicKeys + * @param signatureValue + */ + public IdentityLink(String issuerTemplate, String assertionID, + String issueInstant, PersonData personData, + CitizenPublicKey[] citizenPublicKeys, byte[] signatureValue) { + this.issuerTemplate = issuerTemplate; + this.assertionID = assertionID; + this.issueInstant = issueInstant; + this.personData = personData; + this.citizenPublicKeys = citizenPublicKeys; + this.signatureValue = signatureValue; + } + + /** + * Create a new IdentityLink from an ASN1Object. + * + * @param identiyLink + * @throws CodingException + */ + public IdentityLink(ASN1Object identiyLink) throws CodingException { + decode(identiyLink); + } + + @Override + public void decode(ASN1Object obj) throws CodingException { + issuerTemplate = (String) ((ASN1Object) obj.getComponentAt(1)).getValue(); + assertionID = (String) ((ASN1Object) obj.getComponentAt(2)).getValue(); + issueInstant = (String) ((ASN1Object) obj.getComponentAt(3)).getValue(); + + if (((CON_SPEC) obj.getComponentAt(4)).getAsnType().getTag() == 0) + personData = new PersonData((ASN1Object) obj.getComponentAt(4).getValue()); + else { + throw new CodingException("CorporateBodyData currently not supported."); + } + + SEQUENCE publicKeySequence = (SEQUENCE) obj.getComponentAt(5); + int anz = publicKeySequence.countComponents(); + citizenPublicKeys = new CitizenPublicKey[anz]; + for (int i = 0; i < citizenPublicKeys.length; i++) { + CON_SPEC tmp = (CON_SPEC) publicKeySequence.getComponentAt(i); + if (tmp.getAsnType().getTag() == 0) { + citizenPublicKeys[i] = new CitizenPublicKey((ASN1Object) tmp.getValue()); + } else { + throw new CodingException( + "Currently only PublicKeys on token are supported."); + } + } + + signatureValue = (byte[]) ((ASN1Object) obj.getComponentAt(6)).getValue(); + + for (int i = 7; i < obj.countComponents(); i++) { + CON_SPEC tmp = (CON_SPEC) obj.getComponentAt(i); + switch (tmp.getAsnType().getTag()) { + case 0: + referenceDigest = (byte[]) ((BIT_STRING) tmp.getValue()).getValue(); + break; + case 1: + referenceManifestDigest = (byte[]) ((BIT_STRING) tmp.getValue()) + .getValue(); + break; + case 2: + manifestReferenceDigest = (byte[]) ((BIT_STRING) tmp.getValue()) + .getValue(); + break; + } + + } + + } + + @Override + public ASN1Object toASN1Object() { + SEQUENCE pb = new SEQUENCE(); + pb.addComponent(new INTEGER(version)); + pb.addComponent(new UTF8String(issuerTemplate)); + pb.addComponent(new UTF8String(assertionID)); + pb.addComponent(new UTF8String(issueInstant)); + + pb.addComponent(new CON_SPEC(0, personData.toASN1Object())); + SEQUENCE seq = new SEQUENCE(); + for (int i = 0; i < citizenPublicKeys.length; i++) { + seq.addComponent(new CON_SPEC(0, citizenPublicKeys[i].toASN1Object())); + } + pb.addComponent(seq); + pb.addComponent(new BIT_STRING(signatureValue)); + if (referenceDigest != null) + pb.addComponent(new CON_SPEC(0, new BIT_STRING(referenceDigest))); + if (referenceManifestDigest != null) + pb.addComponent(new CON_SPEC(1, new BIT_STRING(referenceManifestDigest))); + if (manifestReferenceDigest != null) + pb.addComponent(new CON_SPEC(2, new BIT_STRING(manifestReferenceDigest))); + return pb; + } + + /** + * Returns the DER encoding of this IdentityLink. + * + * @return the DER encoding of this IdentityLink + */ + public byte[] toByteArray() { + return DerCoder.encode(toASN1Object()); + } + + /** + * @return the version + */ + public int getVersion() { + return version; + } + + /** + * @param version the version to set + */ + public void setVersion(int version) { + this.version = version; + } + + /** + * @return the issuerTemplate + */ + public String getIssuerTemplate() { + return issuerTemplate; + } + + /** + * @param issuerTemplate the issuerTemplate to set + */ + public void setIssuerTemplate(String issuerTemplate) { + this.issuerTemplate = issuerTemplate; + } + + /** + * @return the assertionID + */ + public String getAssertionID() { + return assertionID; + } + + /** + * @param assertionID the assertionID to set + */ + public void setAssertionID(String assertionID) { + this.assertionID = assertionID; + } + + /** + * @return the issueInstant + */ + public String getIssueInstant() { + return issueInstant; + } + + /** + * @param issueInstant the issueInstant to set + */ + public void setIssueInstant(String issueInstant) { + this.issueInstant = issueInstant; + } + + /** + * @return the personData + */ + public PersonData getPersonData() { + return personData; + } + + /** + * @param personData the personData to set + */ + public void setPersonData(PersonData personData) { + this.personData = personData; + } + + /** + * @return the citizenPublicKeys + */ + public CitizenPublicKey[] getCitizenPublicKeys() { + return citizenPublicKeys; + } + + /** + * @param citizenPublicKeys the citizenPublicKeys to set + */ + public void setCitizenPublicKeys(CitizenPublicKey[] citizenPublicKeys) { + this.citizenPublicKeys = citizenPublicKeys; + } + + /** + * @return the signatureValue + */ + public byte[] getSignatureValue() { + return signatureValue; + } + + /** + * @param signatureValue the signatureValue to set + */ + public void setSignatureValue(byte[] signatureValue) { + this.signatureValue = signatureValue; + } + + /** + * @return the referenceDigest + */ + public byte[] getReferenceDigest() { + return referenceDigest; + } + + /** + * @param referenceDigest the referenceDigest to set + */ + public void setReferenceDigest(byte[] referenceDigest) { + this.referenceDigest = referenceDigest; + } + + /** + * @return the referenceManifestDigest + */ + public byte[] getReferenceManifestDigest() { + return referenceManifestDigest; + } + + /** + * @param referenceManifestDigest the referenceManifestDigest to set + */ + public void setReferenceManifestDigest(byte[] referenceManifestDigest) { + this.referenceManifestDigest = referenceManifestDigest; + } + + /** + * @return the manifestReferenceDigest + */ + public byte[] getManifestReferenceDigest() { + return manifestReferenceDigest; + } + + /** + * @param manifestReferenceDigest the manifestReferenceDigest to set + */ + public void setManifestReferenceDigest(byte[] manifestReferenceDigest) { + this.manifestReferenceDigest = manifestReferenceDigest; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/idlink/ans1/PersonData.java b/utils/src/main/java/at/gv/egiz/idlink/ans1/PersonData.java new file mode 100644 index 00000000..2a537eb3 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/ans1/PersonData.java @@ -0,0 +1,91 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink.ans1; + +import iaik.asn1.*; + +/** + * This class represents the ASN.1 version of the PersonData + * of a compressed identity link. + * + *
+PersonData ::= CHOICE { 
+    physcialPerson [0] PhysicalPersonData, 
+    corporateBody [1] CorporateBodyData 
+} 
+ * + * @author mivkovic@egiz.gv.at, mcentner@egiz.gv.at + * + */ +public class PersonData implements ASN1Type { + + /** + * physicalPerson + */ + private PhysicalPersonData physicalPerson; // PhysicalPersonData + + /** + * Creates a new PersonData with the given + * physicalPersonData. + * + * @param physicalPersonData + */ + public PersonData(PhysicalPersonData physicalPersonData) { + physicalPerson = physicalPersonData; + } + + /** + * Creates a new PersonData from its ASN.1 representation. + * + * @param obj + * @throws CodingException + */ + public PersonData(ASN1Object obj) throws CodingException { + decode(obj); + } + + @Override + public void decode(ASN1Object obj) throws CodingException { + try { + physicalPerson = new PhysicalPersonData(obj); + } catch (Exception ex) { + throw new CodingException(ex.toString()); + } + } + + @Override + public ASN1Object toASN1Object() { + return physicalPerson.toASN1Object(); + } + + /** + * Returns the DER encoded representation of this PersonData. + * + * @return the DER encoded representation of this PersonData + */ + public byte[] getEncoded() { + return DerCoder.encode(toASN1Object()); + } + + /** + * @return the physicalPerson + */ + public PhysicalPersonData getPhysicalPerson() { + return physicalPerson; + } + +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/idlink/ans1/PhysicalPersonData.java b/utils/src/main/java/at/gv/egiz/idlink/ans1/PhysicalPersonData.java new file mode 100644 index 00000000..a6aea97e --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/ans1/PhysicalPersonData.java @@ -0,0 +1,143 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink.ans1; + +import iaik.asn1.*; + +/** + * This class represents the ASN.1 version of the PhysicalPersonData + * of an compressed identity link. + * + *
PhysicalPersonData ::= SEQUENCE { 
+    baseId UTF8String, 
+    givenName UTF8String, 
+    familyName UTF8String, 
+    dateOfBirth UTF8String
+}
+ * + * @author mivkovic@egiz.gv.at, mcentner@eigz.gv.at + */ +public class PhysicalPersonData implements ASN1Type { + + /** + * baseId + */ + private String baseId; // UTF8String + + /** + * givenName + */ + private String givenName; // UTF8String + + /** + * familyName + */ + private String familyName; // UTF8String + + /** + * dataOfBirth + */ + private String dateOfBirth; // UTF8String + + /** + * Creates a new PhysicalPersonData with the + * given baseId, givenName, familyName + * and dataOfBirth. + * + * @param baseId + * @param givenName + * @param familyName + * @param dateOfBirth + */ + public PhysicalPersonData(String baseId, String givenName, String familyName, String dateOfBirth) { + this.baseId = baseId; + this.givenName = givenName; + this.familyName = familyName; + this.dateOfBirth = dateOfBirth; + } + + /** + * Creates a new PhysicalPersonData from its ASN.1 representation. + * + * @param obj + * + * @throws CodingException + */ + public PhysicalPersonData(ASN1Object obj) throws CodingException { + decode(obj); + } + + @Override + public void decode(ASN1Object obj) throws CodingException { + try { + baseId = (String) ((ASN1Object) obj.getComponentAt(0)).getValue(); + givenName = (String) ((ASN1Object) obj.getComponentAt(1)).getValue(); + familyName = (String) ((ASN1Object) obj.getComponentAt(2)).getValue(); + dateOfBirth = (String) ((ASN1Object) obj.getComponentAt(3)).getValue(); + } catch (Exception ex) { + throw new CodingException(ex.toString()); + } + } + + @Override + public ASN1Object toASN1Object() { + SEQUENCE ppd = new SEQUENCE(); + ppd.addComponent(new UTF8String(baseId)); + ppd.addComponent(new UTF8String(givenName)); + ppd.addComponent(new UTF8String(familyName)); + ppd.addComponent(new UTF8String(dateOfBirth)); + return ppd; + } + + /** + * Returns the DER encoding of this PhysicalPersonData. + * + * @return the DER encoding of this PhysicalPersonData + */ + public byte[] toByteArray() { + return DerCoder.encode(toASN1Object()); + } + + /** + * @return the baseId + */ + public String getBaseId() { + return baseId; + } + + /** + * @return the givenName + */ + public String getGivenName() { + return givenName; + } + + /** + * @return the familyName + */ + public String getFamilyName() { + return familyName; + } + + /** + * @return the dateOfBirth + */ + public String getDateOfBirth() { + return dateOfBirth; + } + +} \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/org/apache/tomcat/util/http/AcceptLanguage.java b/utils/src/main/java/at/gv/egiz/org/apache/tomcat/util/http/AcceptLanguage.java new file mode 100644 index 00000000..231966ac --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/org/apache/tomcat/util/http/AcceptLanguage.java @@ -0,0 +1,151 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package at.gv.egiz.org.apache.tomcat.util.http; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Locale; +import java.util.StringTokenizer; +import java.util.Vector; + +/** + * Util to process the "Accept-Language" header. Used by facade to implement + * getLocale() and by StaticInterceptor. + * + * Not optimized - it's very slow. + * + * @author James Duncan Davidson [duncan@eng.sun.com] + * @author James Todd [gonzo@eng.sun.com] + * @author Jason Hunter [jch@eng.sun.com] + * @author Harish Prabandham + * @author costin@eng.sun.com + */ +public class AcceptLanguage { + + public static Locale getLocale(String acceptLanguage) { + if( acceptLanguage == null ) return Locale.getDefault(); + + Hashtable> languages = + new Hashtable>(); + Vector quality = new Vector(); + processAcceptLanguage(acceptLanguage, languages, quality); + + if (languages.size() == 0) return Locale.getDefault(); + + Vector l = new Vector(); + extractLocales( languages,quality, l); + + return (Locale)l.elementAt(0); + } + + public static Enumeration getLocales(String acceptLanguage) { + // Short circuit with an empty enumeration if null header + if (acceptLanguage == null) { + Vector v = new Vector(); + v.addElement(Locale.getDefault()); + return v.elements(); + } + + Hashtable> languages = + new Hashtable>(); + Vector quality=new Vector(); + processAcceptLanguage(acceptLanguage, languages , quality); + + if (languages.size() == 0) { + Vector v = new Vector(); + v.addElement(Locale.getDefault()); + return v.elements(); + } + Vector l = new Vector(); + extractLocales( languages, quality , l); + return l.elements(); + } + + private static void processAcceptLanguage( String acceptLanguage, + Hashtable> languages, Vector q) + { + StringTokenizer languageTokenizer = + new StringTokenizer(acceptLanguage, ","); + + while (languageTokenizer.hasMoreTokens()) { + String language = languageTokenizer.nextToken().trim(); + int qValueIndex = language.indexOf(';'); + int qIndex = language.indexOf('q'); + int equalIndex = language.indexOf('='); + Double qValue = new Double(1); + + if (qValueIndex > -1 && + qValueIndex < qIndex && + qIndex < equalIndex) { + String qValueStr = language.substring(qValueIndex + 1); + language = language.substring(0, qValueIndex); + qValueStr = qValueStr.trim().toLowerCase(); + qValueIndex = qValueStr.indexOf('='); + qValue = new Double(0); + if (qValueStr.startsWith("q") && + qValueIndex > -1) { + qValueStr = qValueStr.substring(qValueIndex + 1); + try { + qValue = new Double(qValueStr.trim()); + } catch (NumberFormatException nfe) { + } + } + } + + // XXX + // may need to handle "*" at some point in time + + if (! language.equals("*")) { + String key = qValue.toString(); + Vector v; + if (languages.containsKey(key)) { + v = languages.get(key) ; + } else { + v= new Vector(); + q.addElement(qValue); + } + v.addElement(language); + languages.put(key, v); + } + } + } + + private static void extractLocales(Hashtable languages, Vector q, + Vector l) + { + // XXX We will need to order by q value Vector in the Future ? + Enumeration e = q.elements(); + while (e.hasMoreElements()) { + Vector v = + (Vector)languages.get(((Double)e.nextElement()).toString()); + Enumeration le = v.elements(); + while (le.hasMoreElements()) { + String language = (String)le.nextElement(); + String country = ""; + int countryIndex = language.indexOf("-"); + if (countryIndex > -1) { + country = language.substring(countryIndex + 1).trim(); + language = language.substring(0, countryIndex).trim(); + } + l.addElement(new Locale(language, country)); + } + } + } + + +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/NamespaceContextCallback.java b/utils/src/main/java/at/gv/egiz/slbinding/NamespaceContextCallback.java new file mode 100644 index 00000000..08c075ac --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/NamespaceContextCallback.java @@ -0,0 +1,41 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding; + +import javax.xml.namespace.NamespaceContext; + +/** + * + * @author clemens + */ +public interface NamespaceContextCallback { + + /** + * preserves the current namespace context from the XMLEventFilter + * @param filter + */ + void preserveNamespaceContext(RedirectEventFilter filter); + + /** + * @return the namespace context if preserveNamespaceContext() was called on this object before, null otherwise + */ + NamespaceContext getNamespaceContext(); +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/RedirectCallback.java b/utils/src/main/java/at/gv/egiz/slbinding/RedirectCallback.java new file mode 100644 index 00000000..80fb56dc --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/RedirectCallback.java @@ -0,0 +1,42 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding; + +import java.io.ByteArrayOutputStream; +import javax.xml.stream.XMLStreamException; + +/** + * + * The beforeUnmarshal(Unmarshaller um, Object parent) methods don't allow to pass the RedirectEventFilter, + * so we implement a callback interface common to all generated classes + * @author clemens + */ +public interface RedirectCallback { + + void enableRedirect(RedirectEventFilter filter) throws XMLStreamException; + + void disableRedirect(RedirectEventFilter filter) throws XMLStreamException; + + /** + * @return the redirected stream or null if enableRedirect() was not called before + */ + ByteArrayOutputStream getRedirectedStream(); +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java new file mode 100644 index 00000000..d2a7fb30 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java @@ -0,0 +1,259 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding; + +import java.io.OutputStream; +import java.util.Set; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.EventFilter; +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.events.XMLEvent; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class RedirectEventFilter implements EventFilter { + + public static final String DEFAULT_ENCODING = "UTF-8"; + private static Log log = LogFactory.getLog(RedirectEventFilter.class); + protected XMLEventWriter redirectWriter = null; + protected Set redirectTriggers = null; + private int depth = -1; + protected NamespaceContext currentNamespaceContext = null; + + /** + * Event redirection is disabled, set a redirect stream to enable. + */ + public RedirectEventFilter() { + redirectWriter = null; + // redirectTriggers = null; + } + + /** + * + * @param redirectStream + * if null, no events are redirected + * @param redirectTriggers + * if null, all events are redirected + */ + public RedirectEventFilter(OutputStream redirectStream, String encoding) + throws XMLStreamException { // , List redirectTriggers + if (redirectStream != null) { + XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); + if (encoding == null) { + encoding = DEFAULT_ENCODING; + } + this.redirectWriter = outputFactory.createXMLEventWriter(redirectStream, + encoding); + } + // this.redirectTriggers = redirectTriggers; + } + + /** + * All startElement events occuring in the redirectTriggers list will trigger + * redirection of the entire (sub-)fragment. + * + * @param event + * @return false if an event is redirected + */ + @Override + public boolean accept(XMLEvent event) { + int eventType = event.getEventType(); + + if (eventType == XMLStreamConstants.START_ELEMENT) { + currentNamespaceContext = event.asStartElement().getNamespaceContext(); + } + if (redirectWriter == null) { + return true; + } + if (eventType == XMLStreamConstants.START_ELEMENT) { + if (depth >= 0 || triggersRedirect(event.asStartElement().getName())) { + depth++; + } + } else if (eventType == XMLStreamConstants.END_ELEMENT) { + if (depth >= 0 && --depth < 0) { + // redirect the end element of the trigger, + // but do not redirect the end element of the calling type + if (redirectTriggers != null) { + redirectEvent(event); + return false; + } + } + } + if (depth >= 0) { //|| (depth == 0 && redirectTriggers == null)) { + redirectEvent(event); + return false; + } + return true; // depth < 0; + +// switch (event.getEventType()) { +// case XMLStreamConstants.START_ELEMENT: +// StartElement startElt = event.asStartElement(); +// if (depth >= 0 || triggersRedirect(startElt.getName())) { +// depth++; +// } +// // namespace context changes only on start elements +// // (first event might not be startElement, but we don't need CDATA's +// // namespace context) +// currentNamespaceContext = startElt.getNamespaceContext(); +// break; +// case XMLStreamConstants.END_ELEMENT: +// // if depth switches from positive to negative, this is the closing tag of +// // the trigger (redirect as well!) +// if (depth >= 0 && --depth < 0) { +// redirectEvent(event); +// return false; +// } +// break; +// } +// if (depth >= 0) { +// redirectEvent(event); +// return false; +// } +// return true; // depth < 0; + } + + /** + * @param startElt + * @return true if the set of triggers contains startElement + * (or no triggers are registered, i.e. everything is redirected) + */ + private boolean triggersRedirect(QName startElement) { + if (redirectTriggers != null) { + return redirectTriggers.contains(startElement); + } + return true; + } + + private void redirectEvent(XMLEvent event) { + try { + if (log.isTraceEnabled()) { + log.trace("redirecting StAX event " + event); + } + redirectWriter.add(event); + } catch (XMLStreamException ex) { + ex.printStackTrace(); + } + } + + /** + * Enable/disable redirection of all events from now on. + * The redirected events will be UTF-8 encoded and written to the stream. + * + * @param redirectstream + * if null, redirection is disabled + */ + public void setRedirectStream(OutputStream redirectStream) throws XMLStreamException { + setRedirectStream(redirectStream, DEFAULT_ENCODING, null); + } + + /** + * Enable/disable redirection of all events from now on. + * + * @param redirectStream if null, redirection is disabled + * @param encoding The encoding for the redirect stream + * @throws javax.xml.stream.XMLStreamException + */ + public void setRedirectStream(OutputStream redirectStream, String encoding) throws XMLStreamException { + setRedirectStream(redirectStream, encoding, null); + } + + /** + * Enable/disable redirection of all (child) elements contained in redirect triggers. + * The redirected events will be UTF-8 encoded and written to the stream. + * + * @param redirectstream + * if null, redirection is disabled + * @param redirectTriggers elements that trigger the redirection + */ + public void setRedirectStream(OutputStream redirectStream, Set redirectTriggers) throws XMLStreamException { + setRedirectStream(redirectStream, DEFAULT_ENCODING, redirectTriggers); + } + + /** + * Enable/disable redirection of all (child) elements contained in redirect triggers. + * + * @param redirectstream + * if null, redirection is disabled + * @param encoding The encoding for the redirect stream + * @param redirectTriggers elements that trigger the redirection + */ + public void setRedirectStream(OutputStream redirectStream, String encoding, Set redirectTriggers) throws XMLStreamException { + if (redirectStream != null) { + XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); + if (encoding == null) { + encoding = DEFAULT_ENCODING; + } + redirectWriter = outputFactory.createXMLEventWriter(redirectStream, + encoding); + if (redirectTriggers == null) { + // start redirecting + depth = 0; + } + this.redirectTriggers = redirectTriggers; + } else { + redirectWriter = null; + this.redirectTriggers = null; + } + } + + /** + * Enable/disable redirection of fragments (defined by elements in + * redirectTriggers) + * + * @param redirectStream + * if null, redirection is disabled + * @param redirectTriggers + * All startElement events occuring in this list will trigger + * redirection of the entire fragment. If null, all events are + * redirected + */ + // public void setRedirectStream(OutputStream redirectStream, List + // redirectTriggers) throws XMLStreamException { + // if (redirectStream != null) { + // XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); + // redirectWriter = outputFactory.createXMLEventWriter(redirectStream); + // } else { + // redirectWriter = null; + // } + // this.redirectTriggers = (redirectStream == null) ? null : redirectTriggers; + // } + /** + * flushes the internal EventWriter + * + * @throws javax.xml.stream.XMLStreamException + */ + public void flushRedirectStream() throws XMLStreamException { + redirectWriter.flush(); + } + + /** + * the namespaceContext of the last startelement event read + * + * @return + */ + public NamespaceContext getCurrentNamespaceContext() { + return currentNamespaceContext; + } +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/RedirectUnmarshallerListener.java b/utils/src/main/java/at/gv/egiz/slbinding/RedirectUnmarshallerListener.java new file mode 100644 index 00000000..08c12146 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/RedirectUnmarshallerListener.java @@ -0,0 +1,68 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding; + +import javax.xml.bind.Unmarshaller; +import javax.xml.stream.XMLStreamException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Enables event redirection before marshalling a target of type RedirectCallback. + * It is up to the target class to implement the redirection (default implementation in RedirectCallback). + * Disables event redirection after marshalling (when the closing tag occurs). + * @author clemens + */ +public class RedirectUnmarshallerListener extends Unmarshaller.Listener { + + private static Log log = LogFactory.getLog(RedirectUnmarshallerListener.class); + protected RedirectEventFilter eventFilter; + + public RedirectUnmarshallerListener(RedirectEventFilter eventFilter) { + this.eventFilter = eventFilter; + } + + @Override + public void beforeUnmarshal(Object target, Object parent) { + if (target instanceof RedirectCallback) { + try { + ((RedirectCallback) target).enableRedirect(eventFilter); + } catch (XMLStreamException ex) { + log.error("failed to enable event redirection for " + target.getClass().getName() + ": " + ex.getMessage(), ex); + } + } + if (target instanceof NamespaceContextCallback) { + ((NamespaceContextCallback) target).preserveNamespaceContext(eventFilter); + } + } + + @Override + public void afterUnmarshal(Object target, Object parent) { + if (target instanceof RedirectCallback) { + try { + ((RedirectCallback) target).disableRedirect(eventFilter); + } catch (XMLStreamException ex) { + log.error("failed to disable event redirection for " + target.getClass().getName() + ": " + ex.getMessage(), ex); + } + } + } +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/SignatureLocationType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/SignatureLocationType.java new file mode 100644 index 00000000..494e6972 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/SignatureLocationType.java @@ -0,0 +1,50 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding.impl; + +import at.gv.egiz.slbinding.*; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.namespace.NamespaceContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author clemens + */ +public class SignatureLocationType extends at.buergerkarte.namespaces.securitylayer._1.SignatureLocationType implements NamespaceContextCallback { + + @XmlTransient + private static Log log = LogFactory.getLog(SignatureLocationType.class); + @XmlTransient + protected NamespaceContext namespaceContext; + + @Override + public NamespaceContext getNamespaceContext() { + return namespaceContext; + } + + @Override + public void preserveNamespaceContext(RedirectEventFilter filter) { + log.debug("preserving namespace context for SignatureLocationType"); + namespaceContext = filter.getCurrentNamespaceContext(); + } +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java new file mode 100644 index 00000000..b4e988f0 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java @@ -0,0 +1,70 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding.impl; + +import at.gv.egiz.slbinding.*; +import java.io.ByteArrayOutputStream; +import java.util.HashSet; +import java.util.Set; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author clemens + */ +public class TransformsInfoType extends at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType implements RedirectCallback { + + @XmlTransient + private static Log log = LogFactory.getLog(TransformsInfoType.class); + @XmlTransient + private static final Set redirectTriggers = initRedirectTriggers(); + @XmlTransient + protected ByteArrayOutputStream redirectOS = null; + + private static Set initRedirectTriggers() { + HashSet dsigTransforms = new HashSet(); + dsigTransforms.add(new QName("http://www.w3.org/2000/09/xmldsig#", "Transforms")); + return dsigTransforms; + } + + @Override + public void enableRedirect(RedirectEventFilter filter) throws XMLStreamException { + log.debug("enabling event redirection for TransformsInfoType"); + redirectOS = new ByteArrayOutputStream(); + filter.setRedirectStream(redirectOS, redirectTriggers); + } + + @Override + public void disableRedirect(RedirectEventFilter filter) throws XMLStreamException { + log.debug("disabling event redirection for TransformsInfoType"); + filter.flushRedirectStream(); + filter.setRedirectStream(null); + } + + @Override + public ByteArrayOutputStream getRedirectedStream() { + return redirectOS; + } +} diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java new file mode 100644 index 00000000..c32542aa --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java @@ -0,0 +1,60 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package at.gv.egiz.slbinding.impl; + +import at.gv.egiz.slbinding.RedirectCallback; +import at.gv.egiz.slbinding.RedirectEventFilter; +import java.io.ByteArrayOutputStream; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.stream.XMLStreamException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author clemens + */ +public class XMLContentType extends at.buergerkarte.namespaces.securitylayer._1.XMLContentType implements RedirectCallback { + + @XmlTransient + private static Log log = LogFactory.getLog(TransformsInfoType.class); + @XmlTransient + protected ByteArrayOutputStream redirectOS = null; + + @Override + public void enableRedirect(RedirectEventFilter filter) throws XMLStreamException { + log.debug("enabling event redirection for XMLContentType"); + redirectOS = new ByteArrayOutputStream(); + filter.setRedirectStream(redirectOS); + } + + @Override + public void disableRedirect(RedirectEventFilter filter) throws XMLStreamException { + log.debug("disabling event redirection for XMLContentType"); + filter.flushRedirectStream(); + filter.setRedirectStream(null); + } + + @Override + public ByteArrayOutputStream getRedirectedStream() { + return redirectOS; + } +} diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesException.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesException.java new file mode 100644 index 00000000..e892a13b --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesException.java @@ -0,0 +1,40 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.xades; + +public class QualifyingPropertiesException extends Exception { + + public QualifyingPropertiesException() { + // TODO Auto-generated constructor stub + } + + public QualifyingPropertiesException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + public QualifyingPropertiesException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + public QualifyingPropertiesException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java new file mode 100644 index 00000000..ae159215 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java @@ -0,0 +1,225 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.xades; + +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; +import java.util.TimeZone; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.etsi.uri._01903.v1_1.CertIDListType; +import org.etsi.uri._01903.v1_1.CertIDType; +import org.etsi.uri._01903.v1_1.DataObjectFormatType; +import org.etsi.uri._01903.v1_1.DigestAlgAndValueType; +import org.etsi.uri._01903.v1_1.QualifyingPropertiesType; +import org.etsi.uri._01903.v1_1.SignaturePolicyIdentifierType; +import org.etsi.uri._01903.v1_1.SignedDataObjectPropertiesType; +import org.etsi.uri._01903.v1_1.SignedPropertiesType; +import org.etsi.uri._01903.v1_1.SignedSignaturePropertiesType; +import org.w3._2000._09.xmldsig_.DigestMethodType; +import org.w3._2000._09.xmldsig_.X509IssuerSerialType; +import org.w3c.dom.Node; + +public class QualifyingPropertiesFactory { + + public static String NS_URI_V1_1_1 = "http://uri.etsi.org/01903/v1.1.1#"; + + public static String SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1 = NS_URI_V1_1_1 + "SignedProperties"; + + private static QualifyingPropertiesFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + public static synchronized QualifyingPropertiesFactory getInstance() { + if (instance == null) { + instance = new QualifyingPropertiesFactory(); + } + return instance; + } + + private DatatypeFactory datatypeFactory; + + private org.etsi.uri._01903.v1_1.ObjectFactory qpFactory; + + private org.w3._2000._09.xmldsig_.ObjectFactory dsFactory; + + public QualifyingPropertiesFactory() { + + try { + datatypeFactory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + throw new RuntimeException(e); + } + + qpFactory = new org.etsi.uri._01903.v1_1.ObjectFactory(); + + dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); + + StringBuffer packageNames = new StringBuffer(); + + packageNames.append(org.etsi.uri._01903.v1_1.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + + } + + public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate) throws QualifyingPropertiesException { + + DigestMethodType digestMethodType = dsFactory.createDigestMethodType(); + digestMethodType.setAlgorithm(DigestMethod.SHA1); + + byte[] digest; + try { + MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); + digest = messageDigest.digest(certificate.getEncoded()); + } catch (CertificateEncodingException e) { + throw new QualifyingPropertiesException(e); + } catch (NoSuchAlgorithmException e) { + throw new QualifyingPropertiesException(e); + } + + DigestAlgAndValueType digestAlgAndValueType = qpFactory.createDigestAlgAndValueType(); + digestAlgAndValueType.setDigestMethod(digestMethodType); + digestAlgAndValueType.setDigestValue(digest); + + return digestAlgAndValueType; + + } + + public X509IssuerSerialType createX509IssuerSerialType(X509Certificate certificate) { + + String name = certificate.getIssuerX500Principal().getName("RFC2253"); + BigInteger serialNumber = certificate.getSerialNumber(); + + X509IssuerSerialType issuerSerialType = dsFactory.createX509IssuerSerialType(); + issuerSerialType.setX509IssuerName(name); + issuerSerialType.setX509SerialNumber(serialNumber); + + return issuerSerialType; + + } + + public DataObjectFormatType createDataObjectFormatType(String objectReference, String mimeType, String description) { + + DataObjectFormatType dataObjectFormatType = qpFactory.createDataObjectFormatType(); + dataObjectFormatType.setObjectReference(objectReference); + + if (mimeType != null) { + dataObjectFormatType.setMimeType(mimeType); + } + if (description != null) { + dataObjectFormatType.setDescription(description); + } + + return dataObjectFormatType; + } + + public JAXBElement createQualifyingProperties111(Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { + + GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); + gregorianCalendar.setTime(signingTime); + + SignedSignaturePropertiesType signedSignaturePropertiesType = qpFactory.createSignedSignaturePropertiesType(); + + // SigningTime + XMLGregorianCalendar xmlGregorianCalendar = datatypeFactory.newXMLGregorianCalendar(gregorianCalendar); + xmlGregorianCalendar.setFractionalSecond(null); + signedSignaturePropertiesType.setSigningTime(xmlGregorianCalendar); + + // SigningCertificate + CertIDListType certIDListType = qpFactory.createCertIDListType(); + List certIDs = certIDListType.getCert(); + + for (X509Certificate certificate : certificates) { + + CertIDType certIDType = qpFactory.createCertIDType(); + certIDType.setCertDigest(createDigestAlgAndValueType(certificate)); + certIDType.setIssuerSerial(createX509IssuerSerialType(certificate)); + + certIDs.add(certIDType); + + } + signedSignaturePropertiesType.setSigningCertificate(certIDListType); + + // SignaturePolicy + SignaturePolicyIdentifierType signaturePolicyIdentifierType = qpFactory.createSignaturePolicyIdentifierType(); + signaturePolicyIdentifierType.setSignaturePolicyImplied(new SignaturePolicyIdentifierType.SignaturePolicyImplied()); + signedSignaturePropertiesType.setSignaturePolicyIdentifier(signaturePolicyIdentifierType); + + // SignedProperties + SignedPropertiesType signedPropertiesType = qpFactory.createSignedPropertiesType(); + signedPropertiesType.setSignedSignatureProperties(signedSignaturePropertiesType); + + // DataObjectFormat + if (dataObjectFormats != null && !dataObjectFormats.isEmpty()) { + SignedDataObjectPropertiesType signedDataObjectPropertiesType = qpFactory.createSignedDataObjectPropertiesType(); + List dataObjectFormatTypes = signedDataObjectPropertiesType.getDataObjectFormat(); + dataObjectFormatTypes.addAll(dataObjectFormats); + signedPropertiesType.setSignedDataObjectProperties(signedDataObjectPropertiesType); + } + + signedPropertiesType.setId(idValue); + + // QualifyingProperties + QualifyingPropertiesType qualifyingPropertiesType = qpFactory.createQualifyingPropertiesType(); + qualifyingPropertiesType.setSignedProperties(signedPropertiesType); + + return qpFactory.createQualifyingProperties(qualifyingPropertiesType); + + } + + public void marshallQualifyingProperties(JAXBElement qualifyingProperties, Node parent) throws JAXBException { + + try { + Marshaller marshaller = jaxbContext.createMarshaller(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + marshaller.marshal(qualifyingProperties, parent); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + + } + +} diff --git a/utils/src/main/java/at/gv/egiz/xmldsig/KeyTypeNotSupportedException.java b/utils/src/main/java/at/gv/egiz/xmldsig/KeyTypeNotSupportedException.java new file mode 100644 index 00000000..3afa6d51 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/xmldsig/KeyTypeNotSupportedException.java @@ -0,0 +1,65 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +/** + * + */ +package at.gv.egiz.xmldsig; + +/** + * @author mcentner + * + */ +public class KeyTypeNotSupportedException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public KeyTypeNotSupportedException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public KeyTypeNotSupportedException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public KeyTypeNotSupportedException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public KeyTypeNotSupportedException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/utils/src/main/java/at/gv/egiz/xmldsig/KeyValueFactory.java b/utils/src/main/java/at/gv/egiz/xmldsig/KeyValueFactory.java new file mode 100644 index 00000000..c1772312 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/xmldsig/KeyValueFactory.java @@ -0,0 +1,279 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.xmldsig; + +import iaik.security.ecc.interfaces.ECDSAParams; +import iaik.security.ecc.interfaces.ECDSAPublicKey; +import iaik.security.ecc.math.ecgroup.Coordinate; +import iaik.security.ecc.math.ecgroup.ECPoint; +import iaik.security.ecc.math.ecgroup.EllipticCurve; +import iaik.security.ecc.math.field.BinaryField; +import iaik.security.ecc.math.field.Field; +import iaik.security.ecc.math.field.FieldElement; +import iaik.security.ecc.math.field.PrimeField; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.PublicKey; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.RSAPublicKey; + +import javax.xml.bind.JAXBElement; + +import org.w3._2000._09.xmldsig_.DSAKeyValueType; +import org.w3._2000._09.xmldsig_.RSAKeyValueType; +import org.w3._2001._04.xmldsig_more_.BasePointParamsType; +import org.w3._2001._04.xmldsig_more_.CharTwoFieldElemType; +import org.w3._2001._04.xmldsig_more_.CurveParamsType; +import org.w3._2001._04.xmldsig_more_.DomainParamsType; +import org.w3._2001._04.xmldsig_more_.ECDSAKeyValueType; +import org.w3._2001._04.xmldsig_more_.ECPointType; +import org.w3._2001._04.xmldsig_more_.ExplicitParamsType; +import org.w3._2001._04.xmldsig_more_.FieldElemType; +import org.w3._2001._04.xmldsig_more_.FieldParamsType; +import org.w3._2001._04.xmldsig_more_.PnBFieldParamsType; +import org.w3._2001._04.xmldsig_more_.PrimeFieldElemType; +import org.w3._2001._04.xmldsig_more_.PrimeFieldParamsType; +import org.w3._2001._04.xmldsig_more_.TnBFieldParamsType; +import org.w3._2001._04.xmldsig_more_.DomainParamsType.NamedCurve; + +public class KeyValueFactory { + + private static byte[] bigInteger2byteArray(BigInteger bigPositiveInt) { + if (bigPositiveInt == null) + throw new NullPointerException("Argument 'bigPositiveInt' must not be null"); + if (bigPositiveInt.signum() != 1) + throw new IllegalArgumentException("Argument 'bigPositiveInt' must not be negative"); + + byte[] byteRepresentation = bigPositiveInt.toByteArray(); + if (byteRepresentation[0] == 0) { + byte[] oldByteRepresentation = byteRepresentation; + byteRepresentation = new byte[oldByteRepresentation.length - 1]; + System.arraycopy(oldByteRepresentation, 1, byteRepresentation, 0, oldByteRepresentation.length - 1); + } + return byteRepresentation; + } + + org.w3._2001._04.xmldsig_more_.ObjectFactory ecFactory = new org.w3._2001._04.xmldsig_more_.ObjectFactory(); + + org.w3._2000._09.xmldsig_.ObjectFactory dsFactory = new org.w3._2000._09.xmldsig_.ObjectFactory(); + + public JAXBElement createKeyValue(PublicKey publicKey) throws KeyTypeNotSupportedException { + + if (publicKey instanceof RSAPublicKey) { + RSAKeyValueType keyValueType = createRSAKeyValueType((RSAPublicKey) publicKey); + return dsFactory.createRSAKeyValue(keyValueType); + } else if (publicKey instanceof DSAPublicKey) { + DSAKeyValueType keyValueType = createKeyValueType((DSAPublicKey) publicKey); + return dsFactory.createDSAKeyValue(keyValueType); + } else if (publicKey instanceof ECDSAPublicKey) { + ECDSAKeyValueType keyValueType = createKeyValueType((ECDSAPublicKey) publicKey); + return ecFactory.createECDSAKeyValue(keyValueType); + } else if ("EC".equals(publicKey.getAlgorithm())) { + byte[] encoded = publicKey.getEncoded(); + try { + iaik.security.ecc.ecdsa.ECPublicKey key = new iaik.security.ecc.ecdsa.ECPublicKey(encoded); + ECDSAKeyValueType keyValueType = createKeyValueType(key); + return ecFactory.createECDSAKeyValue(keyValueType); + } catch (InvalidKeyException e) { + throw new KeyTypeNotSupportedException("Public key of type " + + publicKey.getAlgorithm() + " (" + publicKey.getClass() + + ") not supported."); + } + } else { + throw new KeyTypeNotSupportedException("Public key of type " + + publicKey.getAlgorithm() + " (" + publicKey.getClass() + + ") not supported."); + } + + } + + public RSAKeyValueType createRSAKeyValueType(RSAPublicKey publicKey) { + + RSAKeyValueType keyValueType = dsFactory.createRSAKeyValueType(); + keyValueType.setExponent(bigInteger2byteArray(publicKey.getPublicExponent())); + keyValueType.setModulus(bigInteger2byteArray(publicKey.getModulus())); + + return keyValueType; + } + + public DSAKeyValueType createKeyValueType(DSAPublicKey publicKey) { + + DSAKeyValueType keyValueType = dsFactory.createDSAKeyValueType(); + + if (publicKey.getParams() != null) { + // P, Q, G + DSAParams params = publicKey.getParams(); + if (params.getP() != null && params.getQ() != null) { + keyValueType.setP(bigInteger2byteArray(params.getP())); + keyValueType.setQ(bigInteger2byteArray(params.getQ())); + } + if (params.getG() != null) { + keyValueType.setG(bigInteger2byteArray(params.getG())); + } + } + // + keyValueType.setY(bigInteger2byteArray(publicKey.getY())); + + return keyValueType; + } + + public ECDSAKeyValueType createKeyValueType(ECDSAPublicKey publicKey) throws KeyTypeNotSupportedException { + + ECDSAKeyValueType keyValueType = ecFactory.createECDSAKeyValueType(); + + ECDSAParams params = publicKey.getParameter(); + if (params != null) { + keyValueType.setDomainParameters(createDomainParamsType(params)); + } + + if (!publicKey.getW().isInfinity()) { + keyValueType.setPublicKey(createPointType(publicKey.getW())); + } + + return keyValueType; + } + + public ECPointType createPointType(ECPoint point) throws KeyTypeNotSupportedException { + ECPointType pointType = ecFactory.createECPointType(); + Coordinate affine = point.getCoordinates().toAffine(); + pointType.setX(createFieldElemType(affine.getX())); + pointType.setY(createFieldElemType(affine.getY())); + return pointType; + } + + public FieldElemType createFieldElemType(FieldElement fieldElement) throws KeyTypeNotSupportedException { + int fieldId = fieldElement.getField().getFieldId(); + if (fieldId == PrimeField.PRIME_FIELD_ID) { + PrimeFieldElemType fieldElemType = ecFactory.createPrimeFieldElemType(); + fieldElemType.setValue(fieldElement.toBigInt()); + return fieldElemType; + } else if (fieldId == BinaryField.BINARY_FIELD_ID) { + CharTwoFieldElemType fieldElemType = ecFactory.createCharTwoFieldElemType(); + fieldElemType.setValue(fieldElement.toByteArray()); + return fieldElemType; + } else { + throw new KeyTypeNotSupportedException("Field element of type " + fieldId + " not supported."); + } + } + + public FieldParamsType createFieldParamsType(Field field) throws KeyTypeNotSupportedException { + + if (field.getFieldId() == PrimeField.PRIME_FIELD_ID) { + // PrimeFieldParamsType + PrimeFieldParamsType primeFieldParamsType = ecFactory.createPrimeFieldParamsType(); + primeFieldParamsType.setP(field.getSize()); + return primeFieldParamsType; + } else if (field.getFieldId() == BinaryField.BINARY_FIELD_ID && field instanceof BinaryField) { + // CharTwoFieldParamsType + + BinaryField binaryField = (BinaryField) field; + int[] irreduciblePolynomial = binaryField.getIrreduciblePolynomial(); + + // The irreducible polynomial as a BinaryFieldValue + FieldElement irreducible = binaryField.newElement(irreduciblePolynomial); + + int order = binaryField.getOrder(); + int[] coeffPositions = new int[3]; + + // Get coefficients of irreducible polynomial + int coeffCount = 2; + for (int i = 1; i < order -1; i++) { + if (irreducible.testBit(i)) { + coeffPositions[coeffCount - 2] = i; + coeffCount++; + if (coeffCount == 5) + break; + } + } + // detect if trinomial or pentanomial base is present... + switch (coeffCount) { + case 3: + // trinomial base + TnBFieldParamsType tnBFieldParamsType = ecFactory.createTnBFieldParamsType(); + tnBFieldParamsType.setM(BigInteger.valueOf(binaryField.getOrder())); + tnBFieldParamsType.setK(BigInteger.valueOf(coeffPositions[0])); + return tnBFieldParamsType; + + case 5: + // pentanomial base + PnBFieldParamsType pnBFieldParamsType = ecFactory.createPnBFieldParamsType(); + pnBFieldParamsType.setM(BigInteger.valueOf(binaryField.getOrder())); + pnBFieldParamsType.setK1(BigInteger.valueOf(coeffPositions[0])); + pnBFieldParamsType.setK2(BigInteger.valueOf(coeffPositions[1])); + pnBFieldParamsType.setK3(BigInteger.valueOf(coeffPositions[2])); + return pnBFieldParamsType; + + default: + throw new KeyTypeNotSupportedException("Only trinomial and pentanomial base is supported."); + } + + } else { + throw new KeyTypeNotSupportedException("Field element of type " + field.getFieldId() + " not supported."); + } + + } + + public DomainParamsType createDomainParamsType(ECDSAParams params) throws KeyTypeNotSupportedException { + + DomainParamsType domainParamsType = ecFactory.createDomainParamsType(); + EllipticCurve curve = params.getG().getCurve(); + + String oid = params.getOID(); + if (oid != null) { + // NamedCurve + NamedCurve namedCurve = ecFactory.createDomainParamsTypeNamedCurve(); + namedCurve.setURN("urn:oid:" + oid); + domainParamsType.setNamedCurve(namedCurve); + } else { + // Explicit parameters + ExplicitParamsType explicitParamsType = ecFactory.createExplicitParamsType(); + explicitParamsType.setFieldParams(createFieldParamsType(curve.getField())); + + CurveParamsType curveParamsType = ecFactory.createCurveParamsType(); + + // curve coefficients + curveParamsType.setA(createFieldElemType(curve.getA())); + curveParamsType.setB(createFieldElemType(curve.getB())); + + // seed + if (params.getS() != null) { + curveParamsType.setSeed(bigInteger2byteArray(params.getS())); + } + explicitParamsType.setCurveParams(curveParamsType); + + + // BasePoint parameters + BasePointParamsType basePointParamsType = ecFactory.createBasePointParamsType(); + if (!params.getG().isInfinity()) { + basePointParamsType.setBasePoint(createPointType(params.getG())); + } + basePointParamsType.setOrder(params.getR()); + if(params.getK() != null) { + basePointParamsType.setCofactor(params.getK()); + } + explicitParamsType.setBasePointParams(basePointParamsType); + + domainParamsType.setExplicitParams(explicitParamsType); + } + + return domainParamsType; + + } + +} -- cgit v1.2.3 From fbaf0232de8db3f51c97162b484e2bc17f465999 Mon Sep 17 00:00:00 2001 From: wbauer Date: Wed, 24 Sep 2008 13:54:17 +0000 Subject: Added log message git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@65 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java index 5cba2e1d..600e5605 100644 --- a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java @@ -50,7 +50,8 @@ public class HTTPURLProtocolHandlerImpl implements URLProtocolHandler { return dereferenceHTTP(url); } - protected StreamData dereferenceHTTP(URL url) throws IOException { + protected StreamData dereferenceHTTP(URL url) throws IOException { + log.debug("Dereferencing url: "+url); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); return new StreamData(url.toString(), httpConn.getContentType(), httpConn .getInputStream()); -- cgit v1.2.3 From 81eb1e485a03a6bd1efb726892631ab037d59fdb Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 24 Sep 2008 14:04:18 +0000 Subject: Modified IdentityLinkTransformer to use cached Templates instead of cached Transformers. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@67 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/idlink/IdentityLinkTransformer.java | 58 +++++++++++----------- 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java index 7886b07d..060ccef5 100644 --- a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkTransformer.java @@ -16,29 +16,30 @@ */ package at.gv.egiz.idlink; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stream.StreamSource; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Templates; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.stream.StreamSource; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; public class IdentityLinkTransformer { @@ -77,7 +78,7 @@ public class IdentityLinkTransformer { /** * The stylesheet transformer. */ - private Transformer transformer; + private Templates templates; /** * Stylesheet URL. @@ -103,7 +104,7 @@ public class IdentityLinkTransformer { } StreamSource source = new StreamSource(url.openStream()); - transformer = factory.newTransformer(source); + templates = factory.newTemplates(source); initTime = System.currentTimeMillis() - created; @@ -111,7 +112,8 @@ public class IdentityLinkTransformer { public void transform(Source xmlSource, Result outputTarget) throws TransformerException { long t0 = System.currentTimeMillis(); - try { + try { + Transformer transformer = templates.newTransformer(); transformer.transform(xmlSource, outputTarget); } catch (TransformerException e) { throw e; @@ -146,7 +148,7 @@ public class IdentityLinkTransformer { /** * The transfomer factory. */ - private static TransformerFactory factory; + private static SAXTransformerFactory factory; /** * The instance to be returned by {@link #getInstance()}. @@ -161,7 +163,7 @@ public class IdentityLinkTransformer { public static IdentityLinkTransformer getInstance() { if (instance == null) { instance = new IdentityLinkTransformer(); - factory = TransformerFactory.newInstance(); + factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); } return instance; } -- cgit v1.2.3 From e21dd5249d5fa19c5619847922cf8cdea95e3145 Mon Sep 17 00:00:00 2001 From: wbauer Date: Thu, 25 Sep 2008 07:29:47 +0000 Subject: improved robustness of http binding processor git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@70 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../gv/egiz/bku/local/conf/SpringConfigurator.java | 6 +++- .../gv/egiz/bku/local/conf/defaultConf.properties | 1 + .../gv/egiz/stal/service/impl/STALServiceImpl.java | 2 +- BKUOnline/src/main/webapp/META-INF/MANIFEST.MF | 7 ++-- .../at/gv/egiz/bku/binding/BindingProcessor.java | 4 ++- .../gv/egiz/bku/binding/HTTPBindingProcessor.java | 9 ++++- .../slcommands/impl/InfoboxReadCommandImpl.java | 8 +++-- .../gv/egiz/smcc/utils/SingletonPINProvider.java | 38 ---------------------- .../HTTPURLProtocolHandlerImpl.java | 3 +- .../at/gv/egiz/idlink/IdentityLinkTransformer.java | 30 ++++++++++++----- 10 files changed, 52 insertions(+), 56 deletions(-) delete mode 100644 smcc/src/main/java/at/gv/egiz/smcc/utils/SingletonPINProvider.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java index 43dbf745..46668667 100644 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java +++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java @@ -128,10 +128,14 @@ public class SpringConfigurator extends Configurator implements if ((proxy == null) || (proxy.equals(""))) { log.info("No proxy configured"); } else { - log.info("Setting proxy to: "+proxy+":"+portString); + log.info("Setting proxy to: " + proxy + ":" + portString); System.setProperty("proxyHost", proxy); System.setProperty("proxyPort", portString); } + String timeout = getProperty("DefaultSocketTimeout"); + if ((timeout != null) && (!timeout.equals(""))) { + System.setProperty("sun.net.client.defaultConnectTimeout", timeout); + } } private Set getCACerts() throws IOException, diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties index 6d59ec21..29bdd1ed 100644 --- a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties +++ b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties @@ -54,6 +54,7 @@ ValidateHashDataInputs=true HTTPProxyHost= HTTPProxyPort= +DefaultSocketTimeout=200 diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java index 385888e9..d3d6c8db 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java @@ -248,6 +248,6 @@ public class STALServiceImpl implements STALPortType { ServletContext sCtx = (ServletContext) mCtx.get(MessageContext.SERVLET_CONTEXT); BindingProcessorManager bpMgr = (BindingProcessorManager) sCtx.getAttribute(BINDING_PROCESSOR_MANAGER); BindingProcessor bp = bpMgr.getBindingProcessor(sessionId); - return (bp == null) ? null : (STALRequestBroker) bp.getSTAL(); + return (bp == null) ? null : (bp.isFinished() ? null : (STALRequestBroker) bp.getSTAL()); } } diff --git a/BKUOnline/src/main/webapp/META-INF/MANIFEST.MF b/BKUOnline/src/main/webapp/META-INF/MANIFEST.MF index 5e949512..ca7c7604 100644 --- a/BKUOnline/src/main/webapp/META-INF/MANIFEST.MF +++ b/BKUOnline/src/main/webapp/META-INF/MANIFEST.MF @@ -1,3 +1,6 @@ Manifest-Version: 1.0 -Class-Path: - +Archiver-Version: Plexus Archiver +Created-By: Apache Maven +Built-By: wbauer +Build-Jdk: 1.6.0_10-beta +Implementation-Build: 1.0-SNAPSHOT-r31 \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java index c386508d..2569bf85 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/BindingProcessor.java @@ -71,5 +71,7 @@ public interface BindingProcessor extends Runnable { * If the locale is not set the default locale will be used. * @param locale must not be null. */ - public void setLocale(Locale locale); + public void setLocale(Locale locale); + + public boolean isFinished(); } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java index 8f72c3ee..5e44e82b 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java @@ -115,6 +115,7 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements protected int responseCode = 200; protected Map responseHeaders = Collections.EMPTY_MAP; protected Locale locale = Locale.getDefault(); + protected boolean finished = false; /** * @@ -246,6 +247,7 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements commandInvoker.setCommand(slCommand); responseCode = 200; responseHeaders = Collections.EMPTY_MAP; + dataUrlResponse = null; try { commandInvoker.invoke(srcContex); } catch (SLException e) { @@ -253,7 +255,6 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements bindingProcessorError = e; currentState = State.TRANSFORM; } - dataUrlResponse = null; if (getDataUrl() != null) { log.debug("Data Url set to: " + getDataUrl()); currentState = State.DATAURL; @@ -495,6 +496,7 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements sendSTALQuit(); log.info("Terminating Bindingprocessor; Thread: " + Thread.currentThread().getId()); + finished = true; } // -- END Methods that handle the http binding activities as defined in the @@ -620,6 +622,7 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements currentState = State.FINISHED; } log.debug("Terminated http binding processor"); + finished = true; } @Override @@ -805,4 +808,8 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements this.locale = locale; } + @Override + public boolean isFinished() { + return finished; + } } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java index 4d64ae36..b6c89e5b 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java @@ -371,12 +371,12 @@ public class InfoboxReadCommandImpl extends SLCommandImpl certificates = getCertificatesFromResponses(); @@ -413,10 +413,12 @@ public class InfoboxReadCommandImpl extends SLCommandImpl>(); } - private synchronized IdLTransformer getFreeTransfomer(String stylesheetURL) throws TransformerConfigurationException, IOException { + private IdLTransformer getFreeTransfomer(String stylesheetURL) throws TransformerConfigurationException, IOException { IdLTransformer transformer = null; @@ -260,9 +271,12 @@ public class IdentityLinkTransformer { } - public void transformIdLink(String stylesheetURL, Source source, Result result) throws IOException, TransformerException { - IdLTransformer transformer = getFreeTransfomer(stylesheetURL); - transformer.transform(source, result); + public void transformIdLink(String stylesheetURL, Source source, Result result) throws IOException, TransformerException { + log.trace("Trying to get free IdentityLinkTransformer for issuer template '" + stylesheetURL + "'."); + IdLTransformer transformer = getFreeTransfomer(stylesheetURL); + log.trace("Trying to transform IdentityLink."); + transformer.transform(source, result); + log.trace("IdentityLink transformed successfully. " + getStatistics()); } public String getStatistics() { -- cgit v1.2.3 From 7d3f6235a46f70323defa9910da240e61ca684b3 Mon Sep 17 00:00:00 2001 From: wbauer Date: Wed, 1 Oct 2008 07:30:55 +0000 Subject: Moved main parts of the configuration to bkucommon git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@78 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- BKULocal/pom.xml | 48 ++- .../accesscontroller/SpringSecurityManager.java | 86 ++--- .../at/gv/egiz/bku/local/conf/Configurator.java | 103 ------ .../gv/egiz/bku/local/conf/SpringConfigurator.java | 320 ++++--------------- .../gv/egiz/bku/local/conf/defaultConf.properties | 7 +- .../src/main/webapp/WEB-INF/applicationContext.xml | 6 +- BKULocalApp/keystore.ks | Bin 0 -> 5635 bytes BKULocalApp/pom.xml | 131 ++++++++ .../java/at/gv/egiz/bku/local/app/BKULauncher.java | 222 +++++++++++++ .../src/main/java/at/gv/egiz/bku/local/app/CA.java | 117 +++++++ .../java/at/gv/egiz/bku/local/app/Container.java | 98 ++++++ .../at/gv/egiz/bku/local/defaultConf/template.zip | Bin 0 -> 17759 bytes .../at/gv/egiz/bku/local/ui/UIMessages.properties | 13 + .../resources/at/gv/egiz/bku/local/ui/favicon.png | Bin 0 -> 2149 bytes BKULocalApp/src/main/resources/log4j.properties | 16 + .../accesscontroller/SpringSecurityManager.java | 3 +- .../at/gv/egiz/bku/online/conf/Configurator.java | 98 ------ .../egiz/bku/online/conf/SpringConfigurator.java | 209 +++--------- .../gv/egiz/bku/online/webapp/ResultServlet.java | 6 +- .../egiz/bku/online/webapp/SpringBKUServlet.java | 14 +- .../gv/egiz/bku/online/conf/defaultConf.properties | 5 + .../src/main/webapp/WEB-INF/applicationContext.xml | 4 +- .../java/at/gv/egiz/bku/conf/Configurator.java | 351 +++++++++++++++++++++ pom.xml | 1 + .../at/gv/egiz/bku/local/ui/TrayIconDialog.java | 2 +- 25 files changed, 1169 insertions(+), 691 deletions(-) delete mode 100644 BKULocal/src/main/java/at/gv/egiz/bku/local/conf/Configurator.java create mode 100644 BKULocalApp/keystore.ks create mode 100644 BKULocalApp/pom.xml create mode 100644 BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/BKULauncher.java create mode 100644 BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/CA.java create mode 100644 BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/Container.java create mode 100644 BKULocalApp/src/main/resources/at/gv/egiz/bku/local/defaultConf/template.zip create mode 100644 BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/UIMessages.properties create mode 100644 BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/favicon.png create mode 100644 BKULocalApp/src/main/resources/log4j.properties delete mode 100644 BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKULocal/pom.xml b/BKULocal/pom.xml index 49ec95a0..204fa6b9 100644 --- a/BKULocal/pom.xml +++ b/BKULocal/pom.xml @@ -13,7 +13,53 @@ war BKU Local 1.0-SNAPSHOT - + + + + scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKULocal + scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKULocal + scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKULocal + + + + + maven-war-plugin + 2.0.2 + + + + true + + + + + + ${project.version}-r${buildNumber} + + + + + + + org.codehaus.mojo + maven-buildnumber-plugin + 0.9.6 + + + validate + + create + + + + + false + false + + + + + at.gv.egiz diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/accesscontroller/SpringSecurityManager.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/accesscontroller/SpringSecurityManager.java index b547bf6a..3f50fc78 100644 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/accesscontroller/SpringSecurityManager.java +++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/accesscontroller/SpringSecurityManager.java @@ -1,65 +1,65 @@ /* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package at.gv.egiz.bku.local.accesscontroller; import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade; -import at.gv.egiz.bku.local.conf.Configurator; +import at.gv.egiz.bku.conf.Configurator; public class SpringSecurityManager extends SecurityManagerFacade implements - ResourceLoaderAware { + ResourceLoaderAware { - private ResourceLoader resourceLoader; + private ResourceLoader resourceLoader; - private static Log log = LogFactory.getLog(SpringSecurityManager.class); + private static Log log = LogFactory.getLog(SpringSecurityManager.class); - protected Configurator config; + protected Configurator config; - public void setConfig(Configurator config) { - this.config = config; - } + public void setConfig(Configurator config) { + this.config = config; + } - public void init() { - String noMatch = config.getProperty("AccessController.acceptNoMatch"); - if (noMatch != null) { - log.debug("Setting allow now match to: " + noMatch); - setAllowUnmatched(Boolean.getBoolean(noMatch)); - } - String policy = config.getProperty("AccessController.policyResource"); - log.info("Loading resource: " + policy); - try { - Resource res = resourceLoader.getResource(policy); - init(res.getInputStream()); - } catch (IOException e) { - log.error(e); - } - } + public void init() { + String noMatch = config.getProperty("AccessController.acceptNoMatch"); + if (noMatch != null) { + log.debug("Setting allow now match to: " + noMatch); + setAllowUnmatched(Boolean.getBoolean(noMatch)); + } + String policy = config.getProperty("AccessController.policyResource"); + policy = policy.replace("${user.home}", System.getProperty("user.home")); + log.info("Loading resource: " + policy); + try { + Resource res = resourceLoader.getResource(policy); + init(res.getInputStream()); + } catch (IOException e) { + log.error(e); + } + } - @Override - public void setResourceLoader(ResourceLoader loader) { - this.resourceLoader = loader; - } + @Override + public void setResourceLoader(ResourceLoader loader) { + this.resourceLoader = loader; + } } diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/Configurator.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/Configurator.java deleted file mode 100644 index 57a0f84f..00000000 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/Configurator.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package at.gv.egiz.bku.local.conf; - -import iaik.security.ecc.provider.ECCProvider; -import iaik.security.provider.IAIK; -import iaik.xml.crypto.XSecProvider; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.security.Provider; -import java.security.Security; -import java.util.Properties; - -import javax.net.ssl.HttpsURLConnection; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.binding.DataUrl; -import at.gv.egiz.bku.binding.DataUrlConnection; -import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; -import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; - -/** - * - * TODO currently only the code to get started. - */ -public abstract class Configurator { - - private Log log = LogFactory.getLog(Configurator.class); - - private static Configurator instance = new SpringConfigurator(); - - protected Properties properties; - - protected Configurator() { - } - - public static Configurator getInstance() { - return instance; - } - - protected void configUrlConnections() { - HttpsURLConnection.setFollowRedirects(false); - HttpURLConnection.setFollowRedirects(false); - } - - protected void configureProviders() { - log.debug("Registering security providers"); - Security.insertProviderAt(new IAIK(), 1); - Security.insertProviderAt(new ECCProvider(false), 2); - Security.addProvider(new STALProvider()); - XSecProvider.addAsProvider(false); - StringBuilder sb = new StringBuilder(); - sb.append("Registered providers: "); - int i = 1; - for (Provider prov : Security.getProviders()) { - sb.append((i++) + ". : " + prov); - } - log.debug(sb.toString()); - } - - protected void configViewer() { - String bv = properties.getProperty("ValidateHashDataInputs"); - if (bv != null) { - DataObject.enableHashDataInputValidation(Boolean.parseBoolean(bv)); - } else { - log.warn("ValidateHashDataInputs not set, falling back to default"); - } - } - - public void configure() { - configureProviders(); - configUrlConnections(); - configViewer(); - } - - public void setConfiguration(Properties props) { - this.properties = props; - } - - public String getProperty(String key) { - if (properties != null) { - return properties.getProperty(key); - } - return null; - } -} diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java index 46668667..bcb96c2f 100644 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java +++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/conf/SpringConfigurator.java @@ -19,41 +19,8 @@ package at.gv.egiz.bku.local.conf; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.Security; -import java.security.cert.CertPathBuilder; -import java.security.cert.CertStore; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.LDAPCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.PKIXCertPathBuilderResult; -import java.security.cert.TrustAnchor; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.io.InputStream; import java.util.Properties; -import java.util.Set; - -import javax.naming.ldap.LdapContext; -import javax.naming.ldap.LdapReferralException; -import javax.net.ssl.CertPathTrustManagerParameters; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.ManagerFactoryParameters; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -61,8 +28,7 @@ import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; -import at.gv.egiz.bku.binding.DataUrl; -import at.gv.egiz.bku.binding.DataUrlConnection; +import at.gv.egiz.bku.conf.Configurator; import at.gv.egiz.bku.slexceptions.SLRuntimeException; public class SpringConfigurator extends Configurator implements @@ -73,15 +39,16 @@ public class SpringConfigurator extends Configurator implements private ResourceLoader resourceLoader; public SpringConfigurator() { - File configDir = new File(System.getProperty("user.home") + "/.bku/conf"); - if (configDir.exists()) { - log.debug("Found existing config directory: " + configDir); - } else { - log.info("Config dir not existing, creating new"); - if (!configDir.mkdirs()) { - log.error("Cannot create directory: " + configDir); - } - } + // File configDir = new File(System.getProperty("user.home") + + // "/.bku/conf"); + // if (configDir.exists()) { + // log.debug("Found existing config directory: " + configDir); + // } else { + // log.info("Config dir not existing, creating new"); + // if (!configDir.mkdirs()) { + // log.error("Cannot create directory: " + configDir); + // } + // } } public void setResource(Resource resource) { @@ -99,248 +66,75 @@ public class SpringConfigurator extends Configurator implements } } - public void configureVersion() { - Properties p = new Properties(); - try { - p.load(resourceLoader.getResource("META-INF/MANIFEST.MF") - .getInputStream()); - String version = p.getProperty("Implementation-Build"); - properties.setProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY, - "citizen-card-environment/1.2 MOCCA " + version); - DataUrl.setConfiguration(properties); - log.debug("Setting user agent to: " - + properties.getProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY)); - } catch (IOException e) { - log.error(e); - } - } - + @Override public void configure() { + if (properties == null) { + defaultInit(); + } super.configure(); - configureSSL(); - configureVersion(); - configureNetwork(); } - public void configureNetwork() { - String proxy = getProperty("HTTPProxyHost"); - String portString = getProperty("HTTPProxyPort"); - if ((proxy == null) || (proxy.equals(""))) { - log.info("No proxy configured"); - } else { - log.info("Setting proxy to: " + proxy + ":" + portString); - System.setProperty("proxyHost", proxy); - System.setProperty("proxyPort", portString); - } - String timeout = getProperty("DefaultSocketTimeout"); - if ((timeout != null) && (!timeout.equals(""))) { - System.setProperty("sun.net.client.defaultConnectTimeout", timeout); + public void defaultInit() { + Properties props = new Properties(); + try { + props.load(new FileInputStream(System.getProperty("user.home") + + "/.mocca/war/mocca.war")); + super.setConfiguration(props); + } catch (IOException e) { + log.error("Cannot load config", e); } } - private Set getCACerts() throws IOException, - CertificateException { - Set caCerts = new HashSet(); - String caDirectory = getProperty("SSL.caDirectory"); - if (caDirectory != null) { - Resource caDirRes = resourceLoader.getResource(caDirectory); - File caDir = caDirRes.getFile(); - if (!caDir.isDirectory()) { - log.error("Expecting directory as SSL.caDirectory parameter"); - throw new SLRuntimeException( - "Expecting directory as SSL.caDirectory parameter"); - } - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : caDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - fis.close(); - log.debug("Adding trusted cert " + cert.getSubjectDN()); - caCerts.add(new TrustAnchor(cert, null)); - } catch (Exception e) { - log.error("Cannot add trusted ca", e); - } - } - return caCerts; - - } else { - log.warn("No CA certificates configured"); - } - return null; + @Override + public void setResourceLoader(ResourceLoader loader) { + this.resourceLoader = loader; } - private List getCertstore() throws IOException, - CertificateException, InvalidAlgorithmParameterException, - NoSuchAlgorithmException { - List resultList = new ArrayList(); - String certDirectory = getProperty("SSL.certDirectory"); - if (certDirectory != null) { - Resource certDirRes = resourceLoader.getResource(certDirectory); - - File certDir = certDirRes.getFile(); + private File getDirectory(String property) { + property = property + .replace("${user.home}", System.getProperty("user.home")); + if (property != null) { + Resource certDirRes = resourceLoader.getResource(property); + File certDir; + try { + certDir = certDirRes.getFile(); + } catch (IOException e) { + log.error("Cannot get cert directory", e); + throw new SLRuntimeException(e); + } if (!certDir.isDirectory()) { log.error("Expecting directory as SSL.certDirectory parameter"); throw new SLRuntimeException( "Expecting directory as SSL.certDirectory parameter"); } - List certCollection = new LinkedList(); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : certDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - certCollection.add(cert); - fis.close(); - log - .trace("Added following cert to certstore: " - + cert.getSubjectDN()); - } catch (Exception ex) { - log.error("Cannot add certificate", ex); - } - } - CollectionCertStoreParameters csp = new CollectionCertStoreParameters( - certCollection); - resultList.add(CertStore.getInstance("Collection", csp)); - log.info("Added collection certstore"); - } else { - log.warn("No certstore directory configured"); - } - String ldapHost = getProperty("SSL.ldapServer"); - if ((ldapHost != null) && (!"".equals(ldapHost))) { - String ldapPortString = getProperty("SSL.ldapPort"); - int ldapPort = 389; - if (ldapPortString != null) { - try { - ldapPort = Integer.parseInt(ldapPortString); - } catch (NumberFormatException nfe) { - log.error("Invalid ldap port, using default 389"); - } - } else { - log.warn("ldap port not specified, using default 389"); - } - LDAPCertStoreParameters ldapParams = new LDAPCertStoreParameters( - ldapHost, ldapPort); - resultList.add(CertStore.getInstance("LDAP", ldapParams)); - log.info("Added LDAP certstore"); + return certDir; } - return resultList; - } - - public void configureSSL() { - Set caCerts = null; - try { - caCerts = getCACerts(); - } catch (Exception e1) { - log.error("Cannot load CA certificates", e1); - } - List certStoreList = null; - try { - certStoreList = getCertstore(); - } catch (Exception e1) { - log.error("Cannot load certstore certificates", e1); - } - String aia = getProperty("SSL.useAIA"); - if ((aia == null) || (aia.equals(""))) { - System.setProperty("com.sun.security.enableAIAcaIssuers", "true"); - } else { - System.setProperty("com.sun.security.enableAIAcaIssuers", aia); - } - String lifetime = getProperty("SSL.cache.lifetime"); - if ((lifetime == null) || (lifetime.equals(""))) { - System.setProperty("sun.security.certpath.ldap.cache.lifetime", "0"); - } else { - System.setProperty("sun.security.certpath.ldap.cache.lifetime", lifetime); - } - X509CertSelector selector = new X509CertSelector(); - PKIXBuilderParameters pkixParams; - try { - pkixParams = new PKIXBuilderParameters(caCerts, selector); - if ((getProperty("SSL.doRevocationChecking") != null) - && (Boolean.valueOf(getProperty("SSL.doRevocationChecking")))) { - log.info("Enable revocation checking"); - System.setProperty("com.sun.security.enableCRLDP", "true"); - Security.setProperty("ocsp.enable", "true"); - } else { - log.warn("Revocation checking disabled"); - } - for (CertStore cs : certStoreList) { - pkixParams.addCertStore(cs); - } - ManagerFactoryParameters trustParams = new CertPathTrustManagerParameters( - pkixParams); - TrustManagerFactory trustFab; - trustFab = TrustManagerFactory.getInstance("PKIX"); - trustFab.init(trustParams); - KeyManager[] km = null; - SSLContext sslCtx = SSLContext - .getInstance(getProperty("SSL.sslProtocol")); - String disableAll = getProperty("SSL.disableAllChecks"); - if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) { - log.warn("--------------------------------------"); - log.warn(" Disabling SSL Certificate Validation "); - log.warn("--------------------------------------"); - - sslCtx.init(km, new TrustManager[] { new MyTrustManager(caCerts, - certStoreList) }, null); - } else { - sslCtx.init(km, trustFab.getTrustManagers(), null); - } - HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory()); - } catch (Exception e) { - log.error("Cannot configure SSL", e); - } - String disableAll = getProperty("SSL.disableAllChecks"); - if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) { - log.warn("---------------------------------"); - log.warn(" Disabling Hostname Verification "); - log.warn("---------------------------------"); - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }); - } - } - - @Override - public void setResourceLoader(ResourceLoader loader) { - this.resourceLoader = loader; - } -} - -class MyTrustManager implements X509TrustManager { - private static Log log = LogFactory.getLog(MyTrustManager.class); - private X509Certificate[] trustedCerts; + return null; - public MyTrustManager(Set caCerts, List cs) { - trustedCerts = new X509Certificate[caCerts.size()]; - int i = 0; - for (Iterator it = caCerts.iterator(); it.hasNext();) { - TrustAnchor ta = it.next(); - trustedCerts[i++] = ta.getTrustedCert(); - } } @Override - public void checkClientTrusted(X509Certificate[] arg0, String arg1) - throws CertificateException { - log.error("Did not expect this method to get called"); - throw new CertificateException("Method not implemented"); + protected File getCADir() { + String caDirectory = getProperty("SSL.caDirectory"); + return getDirectory(caDirectory); } @Override - public void checkServerTrusted(X509Certificate[] certs, String arg1) - throws CertificateException { - log.warn("-------------------------------------"); - log.warn("SSL Certificate Validation Disabled !"); - log.warn("-------------------------------------"); + protected File getCertDir() { + String certDirectory = getProperty("SSL.certDirectory"); + return getDirectory(certDirectory); } @Override - public X509Certificate[] getAcceptedIssuers() { - return trustedCerts; + protected InputStream getManifest() { + Resource r = resourceLoader.getResource("META-INF/MANIFEST.MF"); + if ((r != null) && r.isReadable()) { + try { + return r.getInputStream(); + } catch (IOException e) { + log.error("Cannot read manifest data:" + e); + } + } + return null; } - } \ No newline at end of file diff --git a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties index 29bdd1ed..8ae5bf6d 100644 --- a/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties +++ b/BKULocal/src/main/resources/at/gv/egiz/bku/local/conf/defaultConf.properties @@ -51,10 +51,11 @@ SSL.disableAllChecks=false # ------------ END SSL Config -------------------- ValidateHashDataInputs=true +AppletTimeout=300000 -HTTPProxyHost= -HTTPProxyPort= -DefaultSocketTimeout=200 +#HTTPProxyHost= +#HTTPProxyPort= +#DefaultSocketTimeout=200 diff --git a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml index c6a5088a..a4003a2a 100644 --- a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml +++ b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml @@ -21,6 +21,7 @@ + @@ -47,10 +48,11 @@ - - + diff --git a/BKULocalApp/keystore.ks b/BKULocalApp/keystore.ks new file mode 100644 index 00000000..824c3a40 Binary files /dev/null and b/BKULocalApp/keystore.ks differ diff --git a/BKULocalApp/pom.xml b/BKULocalApp/pom.xml new file mode 100644 index 00000000..e2d17d7c --- /dev/null +++ b/BKULocalApp/pom.xml @@ -0,0 +1,131 @@ + + + bku + at.gv.egiz + 1.0-SNAPSHOT + + 4.0.0 + at.gv.egiz.bku + BKULocalApp + + 1.0-SNAPSHOT + + + + + + maven-compiler-plugin + org.apache.maven.plugins + 2.0.2 + + 1.6 + 1.6 + true + true + + + + + + + maven-dependency-plugin + + + + copywar + + copy + + + + + at.gv.egiz + BKULocal + 1.0-SNAPSHOT + war + + + + ${project.build.directory}/classes + + + + + unpack-dependencies + + unpack-dependencies + + + javax/xml/crypto/**, demo/**, + junit/**, w3/**, org/etsi/**, META-INF/** + ${project.build.directory}/classes + true + true + + + + + + + + maven-jar-plugin + + + + sign + + + + + + false + false + + false + true + + + test-applet signer + ./keystore.ks + storepass + keypass + true + + + + + + + + + commons-logging + commons-logging + 1.1.1 + compile + + + at.gv.egiz + BKULocal + 1.0-SNAPSHOT + war + + + utils + at.gv.egiz + 1.0-SNAPSHOT + compile + + + commons-cli + commons-cli + 1.0 + + + org.mortbay.jetty + jetty + 6.1.10 + + + + \ No newline at end of file diff --git a/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/BKULauncher.java b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/BKULauncher.java new file mode 100644 index 00000000..091843e1 --- /dev/null +++ b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/BKULauncher.java @@ -0,0 +1,222 @@ +package at.gv.egiz.bku.local.app; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.KeyStore; +import java.util.Enumeration; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.local.ui.BKUControllerInterface; +import at.gv.egiz.bku.local.ui.TrayIconDialog; +import at.gv.egiz.bku.utils.StreamUtil; + +public class BKULauncher implements BKUControllerInterface { + private static Log log = LogFactory.getLog(BKULauncher.class); + + private ResourceBundle resourceBundle = null; + private Container server; + + private void startUpServer() throws Exception { + server = new Container(); + // XmlConfiguration xcfg = new XmlConfiguration(getClass().getClassLoader() + // .getResourceAsStream("at/gv/egiz/bku/local/app/jetty.xml")); + // xcfg.configure(server); + server.init(); + server.start(); + } + + private void initTrayIcon() { + Locale loc = Locale.getDefault(); + try { + resourceBundle = ResourceBundle.getBundle( + "at/gv/egiz/bku/local/ui/UIMessages", loc); + } catch (MissingResourceException mx) { + resourceBundle = ResourceBundle.getBundle( + "at/gv/egiz/bku/local/ui/UIMessages", Locale.ENGLISH); + } + TrayIconDialog.getInstance().init(resourceBundle); + TrayIconDialog.getInstance().setShutdownHook(this); + TrayIconDialog.getInstance().displayInfo("Greetings.Caption", + "Greetings.Message"); + } + + private void initFinished() { + try { + server.join(); + } catch (InterruptedException e) { + log.info(e); + } + } + + private void copyDirs(File srcDir, File dstDir) { + for (File cf : srcDir.listFiles()) { + File of = new File(dstDir, cf.getName()); + if (cf.isDirectory()) { + log.debug("Creating directory: " + of); + of.mkdir(); + copyDirs(cf, of); + } else { + log.debug("Writing file: " + of); + try { + FileInputStream fis = new FileInputStream(cf); + FileOutputStream fos = new FileOutputStream(of); + StreamUtil.copyStream(fis, fos); + fis.close(); + fos.close(); + } catch (IOException e) { + log.error("Cannot copy default configuration", e); + } + } + } + } + + private void unzip(File zipfile) throws IOException { + File dir = zipfile.getParentFile(); + ZipFile zipFile = new ZipFile(zipfile); + Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + File eF = new File(dir, entry.getName()); + if (entry.isDirectory()) { + eF.mkdirs(); + continue; + } + File f = new File(eF.getParent()); + f.mkdirs(); + StreamUtil.copyStream(zipFile.getInputStream(entry), + new FileOutputStream(eF)); + } + zipFile.close(); + } + + private void checkConfig(String[] args) { + CommandLineParser parser = new PosixParser(); + Options options = new Options(); + options.addOption("c", true, "the configuration's base directory"); + options.addOption("h", false, "print this message"); + try { + File cfgDir = new File(System.getProperty("user.home") + "/.mocca/conf"); + CommandLine cmd = parser.parse(options, args); + if (cmd.hasOption("h")) { + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("BKULauncher", options); + System.exit(0); + } + + if (cmd.hasOption("c")) { + cfgDir = new File(cmd.getOptionValue("c")); + } + log.debug("using config directory: " + cfgDir); + if (cfgDir.exists() && cfgDir.isFile()) { + log.error("Configuration directory must not be a file"); + } + if (!cfgDir.exists()) { + log.debug("Creating config directory: " + cfgDir); + cfgDir.mkdirs(); + try { + InputStream is = getClass().getClassLoader().getResourceAsStream( + "at/gv/egiz/bku/local/defaultConf/template.zip"); + OutputStream os = new FileOutputStream(new File(cfgDir, + "template.zip")); + StreamUtil.copyStream(is, os); + os.close(); + unzip(new File(cfgDir, "template.zip")); + } catch (IOException iox) { + log.error("Cannot create user directory", iox); + return; + } + CA ca = new CA(); + char[] password = "changeMe".toCharArray(); + KeyStore ks = ca.generateKeyStore(password); + if (ks != null) { + File ksdir = new File(cfgDir, "keystore"); + ksdir.mkdirs(); + FileOutputStream fos; + try { + fos = new FileOutputStream(new File(ksdir, "keystore.ks")); + ks.store(fos, password); + fos.close(); + } catch (Exception e) { + log.error("Cannot store keystore", e); + } + } else { + log.error("Cannot create ssl certificate"); + } + } + } catch (ParseException e1) { + log.error(e1); + HelpFormatter formatter = new HelpFormatter(); + formatter.printHelp("BKULauncher", options); + System.exit(0); + } + } + + public void jwsHack() { + InputStream is = getClass().getClassLoader().getResourceAsStream( + "BKULocal-1.0-SNAPSHOT.war"); + File f = new File(System.getProperty("user.home") + "/.mocca/war"); + f.mkdirs(); + try { + OutputStream os = new FileOutputStream(new File(f, "mocca.war")); + StreamUtil.copyStream(is, os); + os.close(); + } catch (Exception e) { + log.error(e); + } + } + + /** + * @param args + */ + public static void main(String[] args) { + + try { + BKULauncher launcher = new BKULauncher(); + //launcher.jwsHack(); + launcher.checkConfig(args); + launcher.startUpServer(); + launcher.initTrayIcon(); + launcher.initFinished(); + } catch (Exception e) { + log.fatal("Cannot launch BKU", e); + System.exit(-1000); + } + + } + + public void shutDown() { + log.info("Shutting down server"); + if ((server != null) && (server.isRunning())) { + try { + if (server.isRunning()) { + server.stop(); + } + } catch (Exception e) { + log.debug(e.toString()); + } finally { + if (server.isRunning()) { + server.destroy(); + } + } + } + System.exit(0); + } + +} diff --git a/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/CA.java b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/CA.java new file mode 100644 index 00000000..31d21ef7 --- /dev/null +++ b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/CA.java @@ -0,0 +1,117 @@ +package at.gv.egiz.bku.local.app; + +import iaik.asn1.ObjectID; +import iaik.asn1.structures.AlgorithmID; +import iaik.asn1.structures.Name; +import iaik.x509.X509Certificate; +import iaik.x509.extensions.BasicConstraints; +import iaik.x509.extensions.KeyUsage; + +import java.math.BigInteger; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.GeneralSecurityException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Random; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class CA { + private final static Log log = LogFactory.getLog(CA.class); + + private KeyPair caKeyPair; + private X509Certificate caCert; + + private KeyPair serverKeyPair; + private X509Certificate serverCert; + + public CA() { + } + + private KeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA"); + gen.initialize(2048); + return gen.generateKeyPair(); + } + + private void generateCA() throws GeneralSecurityException { + log.debug("Generating CA certificate"); + Name subject = new Name(); + subject.addRDN(ObjectID.country, "AT"); + subject.addRDN(ObjectID.organization, "MOCCA"); + subject.addRDN(ObjectID.organizationalUnit, "MOCCA-CA"); + + caKeyPair = generateKeyPair(); + caCert = new X509Certificate(); + caCert.setSerialNumber(new BigInteger(20, new Random())); + caCert.setSubjectDN(subject); + caCert.setPublicKey(caKeyPair.getPublic()); + caCert.setIssuerDN(subject); + + caCert.addExtension(new BasicConstraints(true)); + caCert.addExtension(new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign + | KeyUsage.digitalSignature)); + + GregorianCalendar date = new GregorianCalendar(); + date.add(Calendar.HOUR_OF_DAY, -1); + caCert.setValidNotBefore(date.getTime()); + date.add(Calendar.YEAR, 7); + caCert.setValidNotAfter(date.getTime()); + caCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); + log.debug("Successfully signed CA certificate"); + } + + private void generateServerCert() throws GeneralSecurityException { + log.debug("Generating SSL certificate"); + Name subject = new Name(); + subject.addRDN(ObjectID.country, "AT"); + subject.addRDN(ObjectID.organization, "MOCCA"); + try { + subject.addRDN(ObjectID.commonName, InetAddress.getLocalHost() + .getHostName()); + } catch (UnknownHostException e) { + subject.addRDN(ObjectID.commonName, "localhost"); + } + serverKeyPair = generateKeyPair(); + serverCert = new X509Certificate(); + serverCert.setSerialNumber(new BigInteger(20, new Random())); + serverCert.setSubjectDN(subject); + serverCert.setPublicKey(serverKeyPair.getPublic()); + serverCert.setIssuerDN(caCert.getSubjectDN()); + + serverCert.addExtension(new BasicConstraints(false)); + serverCert.addExtension(new KeyUsage(KeyUsage.keyEncipherment + | KeyUsage.digitalSignature)); + + GregorianCalendar date = new GregorianCalendar(); + date.add(Calendar.HOUR_OF_DAY, -1); + serverCert.setValidNotBefore(date.getTime()); + date.add(Calendar.YEAR, 7); + date.add(Calendar.HOUR_OF_DAY, -1); + serverCert.setValidNotAfter(date.getTime()); + serverCert.sign(AlgorithmID.sha1WithRSAEncryption, caKeyPair.getPrivate()); + log.debug("Successfully signed server certificate"); + caKeyPair = null; + } + + public KeyStore generateKeyStore(char[] password) { + try { + generateCA(); + generateServerCert(); + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + ks.setKeyEntry("server", serverKeyPair.getPrivate(), password, new X509Certificate[]{serverCert, caCert}); + return ks; + } catch (Exception e) { + log.error("Cannot generate certificate", e); + } + return null; + } + +} diff --git a/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/Container.java b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/Container.java new file mode 100644 index 00000000..690639f4 --- /dev/null +++ b/BKULocalApp/src/main/java/at/gv/egiz/bku/local/app/Container.java @@ -0,0 +1,98 @@ +package at.gv.egiz.bku.local.app; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Handler; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.handler.DefaultHandler; +import org.mortbay.jetty.handler.HandlerCollection; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.security.SslSocketConnector; +import org.mortbay.jetty.webapp.WebAppClassLoader; +import org.mortbay.jetty.webapp.WebAppContext; +import org.mortbay.thread.QueuedThreadPool; + +public class Container { + + private static Log log = LogFactory.getLog(Container.class); + + private Server server; + + public Container() { + } + + public void init() { + Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); + log.debug("-----------------> "+ClassLoader.getSystemClassLoader()); + server = new Server(); + QueuedThreadPool qtp = new QueuedThreadPool(); + qtp.setMaxThreads(5); + qtp.setMinThreads(2); + qtp.setLowThreads(0); + server.setThreadPool(qtp); + server.setStopAtShutdown(true); + server.setGracefulShutdown(3000); + + SelectChannelConnector connector = new SelectChannelConnector(); + connector.setPort(3495); + connector.setAcceptors(1); + connector.setConfidentialPort(3496); + + SslSocketConnector sslConnector = new SslSocketConnector(); + sslConnector.setPort(3496); + sslConnector.setAcceptors(1); + sslConnector.setKeystore(System.getProperty("user.home") + + "/.mocca/conf/keystore/keystore.ks"); + sslConnector.setPassword("changeMe"); + sslConnector.setKeyPassword("changeMe"); + + server.setConnectors(new Connector[] { connector, sslConnector }); + HandlerCollection handlers = new HandlerCollection(); + + WebAppContext webappcontext = new WebAppContext(); + webappcontext.setContextPath("/"); + webappcontext.setExtractWAR(false); + + File tmpDir = new File(System.getProperty("user.home") + "/.mocca/tmp"); + // tmpDir.mkdirs(); + // webappcontext.setTempDirectory(tmpDir); + try { + File f = new File(System.getProperty("user.home") + + "/.mocca/war/mocca.war"); + log.debug("Deploying war: " + f.getCanonicalPath()); + if (!f.exists()) { + log.error("WAR file does not exist, cannot run MOCCA"); + } + webappcontext.setWar(f.getParent()); + } catch (IOException e) { + log.error(e); + } + handlers.setHandlers(new Handler[] { webappcontext, new DefaultHandler() }); + + server.setHandler(handlers); + } + + public void start() throws Exception { + server.start(); + } + + public boolean isRunning() { + return server.isRunning(); + } + + public void stop() throws Exception { + server.stop(); + } + + public void destroy() { + server.destroy(); + } + + public void join() throws InterruptedException { + server.join(); + } +} \ No newline at end of file diff --git a/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/defaultConf/template.zip b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/defaultConf/template.zip new file mode 100644 index 00000000..f57e8930 Binary files /dev/null and b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/defaultConf/template.zip differ diff --git a/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/UIMessages.properties b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/UIMessages.properties new file mode 100644 index 00000000..873d03ef --- /dev/null +++ b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/UIMessages.properties @@ -0,0 +1,13 @@ +#-------- tray icon messages ------- +TrayMenu.Tooltip=MOCCA +TrayMenu.Shutdown=MOCCA Beenden + +Greetings.Message=MOCCA up and running +Greetings.Caption=MOCCA Started + +Message.RequestCaption=New Request +Message.InfoboxReadRequest=Reading Infobox +Message.SecureSignatureKeypair=Reading secure signature certificate +Message.CertifiedKeypair=Reading certified certificate +Message.IdentityLink=Reading Identitylink +Message.SignRequest=Creating Signature \ No newline at end of file diff --git a/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/favicon.png b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/favicon.png new file mode 100644 index 00000000..2d0276de Binary files /dev/null and b/BKULocalApp/src/main/resources/at/gv/egiz/bku/local/ui/favicon.png differ diff --git a/BKULocalApp/src/main/resources/log4j.properties b/BKULocalApp/src/main/resources/log4j.properties new file mode 100644 index 00000000..fcdcb8e8 --- /dev/null +++ b/BKULocalApp/src/main/resources/log4j.properties @@ -0,0 +1,16 @@ +# loglever DEBUG, appender STDOUT +log4j.rootLogger=TRACE, STDOUT, file + +# STDOUT appender +log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender +log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout +#log4j.appender.STDOUT.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %20c | %10t | %m%n +#log4j.appender.STDOUT.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n +log4j.appender.STDOUT.layout.ConversionPattern=%-5p |%d | %t | %c %x- %m%n + +### FILE appender +log4j.appender.file=org.apache.log4j.DailyRollingFileAppender +log4j.appender.file.datePattern='.'yyyy-MM-dd +log4j.appender.file.File=${user.home}/.mocca/logs/mocca.log +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/accesscontroller/SpringSecurityManager.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/accesscontroller/SpringSecurityManager.java index 3d0df8c4..5795478b 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/accesscontroller/SpringSecurityManager.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/accesscontroller/SpringSecurityManager.java @@ -25,7 +25,7 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import at.gv.egiz.bku.accesscontroller.SecurityManagerFacade; -import at.gv.egiz.bku.online.conf.Configurator; +import at.gv.egiz.bku.conf.Configurator; public class SpringSecurityManager extends SecurityManagerFacade implements ResourceLoaderAware { @@ -60,5 +60,4 @@ public class SpringSecurityManager extends SecurityManagerFacade implements public void setResourceLoader(ResourceLoader loader) { this.resourceLoader = loader; } - } diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java deleted file mode 100644 index c09abcc1..00000000 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/Configurator.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package at.gv.egiz.bku.online.conf; - -import iaik.security.ecc.provider.ECCProvider; -import iaik.security.provider.IAIK; -import iaik.xml.crypto.XSecProvider; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.security.Provider; -import java.security.Security; -import java.util.Properties; - -import javax.net.ssl.HttpsURLConnection; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.binding.DataUrl; -import at.gv.egiz.bku.binding.DataUrlConnection; -import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; -import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; - -/** - * - * TODO currently only the code to get started. - */ -public abstract class Configurator { - - private Log log = LogFactory.getLog(Configurator.class); - - private static Configurator instance = new SpringConfigurator(); - - protected Properties properties; - - protected Configurator() { - } - - public static Configurator getInstance() { - return instance; - } - - protected void configUrlConnections() { - HttpsURLConnection.setFollowRedirects(false); - HttpURLConnection.setFollowRedirects(false); - } - - protected void configureProviders() { - log.debug("Registering security providers"); - Security.insertProviderAt(new IAIK(), 1); - Security.insertProviderAt(new ECCProvider(false), 2); - Security.addProvider(new STALProvider()); - XSecProvider.addAsProvider(false); - StringBuilder sb = new StringBuilder(); - sb.append("Registered providers: "); - int i = 1; - for (Provider prov : Security.getProviders()) { - sb.append((i++) + ". : " + prov); - } - log.debug(sb.toString()); - } - - protected void configViewer() { - DataObject.enableHashDataInputValidation(Boolean.parseBoolean(properties.getProperty("ValidateHashDataInputs"))); - } - - public void configure() { - configureProviders(); - configUrlConnections(); - configViewer(); - } - - public void setConfiguration(Properties props) { - this.properties = props; - } - - public String getProperty(String key) { - if (properties != null) { - return properties.getProperty(key); - } - return null; - } -} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/SpringConfigurator.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/SpringConfigurator.java index d213dd36..a369d829 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/SpringConfigurator.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/conf/SpringConfigurator.java @@ -17,31 +17,9 @@ package at.gv.egiz.bku.online.conf; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.Security; -import java.security.cert.CertStore; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.CollectionCertStoreParameters; -import java.security.cert.PKIXBuilderParameters; -import java.security.cert.TrustAnchor; -import java.security.cert.X509CertSelector; -import java.security.cert.X509Certificate; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; +import java.io.InputStream; import java.util.Properties; -import java.util.Set; - -import javax.net.ssl.CertPathTrustManagerParameters; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.KeyManager; -import javax.net.ssl.ManagerFactoryParameters; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -49,8 +27,8 @@ import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; -import at.gv.egiz.bku.binding.DataUrl; -import at.gv.egiz.bku.binding.DataUrlConnection; +import at.gv.egiz.bku.conf.Configurator; +import at.gv.egiz.bku.online.webapp.SpringBKUServlet; import at.gv.egiz.bku.slexceptions.SLRuntimeException; import at.gv.egiz.stal.service.impl.RequestBrokerSTALFactory; @@ -76,41 +54,8 @@ public class SpringConfigurator extends Configurator implements } } - public void configureVersion() { - Properties p = new Properties(); - try { - p.load(resourceLoader.getResource("META-INF/MANIFEST.MF") - .getInputStream()); - String version = p.getProperty("Implementation-Build"); - properties.setProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY, - "citizen-card-environment/1.2 MOCCA " + version); - DataUrl.setConfiguration(properties); - log.debug("Setting user agent to: " - + properties.getProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY)); - } catch (IOException e) { - log.error(e); - } - } - - public void configure() { - super.configure(); - configureSSL(); - configureVersion(); - configureNetwork(); - } - public void configureNetwork() { - String proxyHost = getProperty("HTTPProxyHost"); - String proxyPort = getProperty("HTTPProxyPort"); - if (proxyPort == null) { - proxyPort = "80"; - } - if (proxyHost != null) { - log.debug("Setting proxy server to: " + proxyHost + ":" + proxyPort); - System.setProperty("http.proxyHost", proxyHost); - System.setProperty("http.proxyPort", proxyPort); - } - log.debug("No proxy specified"); + super.configureNetwork(); String appletTimeout = getProperty("AppletTimeout"); if ((appletTimeout != null)) { try { @@ -122,128 +67,60 @@ public class SpringConfigurator extends Configurator implements } } - - private Set getCACerts() throws IOException, - CertificateException { - Set caCerts = new HashSet(); - String caDirectory = getProperty("SSL.caDirectory"); - if (caDirectory != null) { - Resource caDirRes = resourceLoader.getResource(caDirectory); - File caDir = caDirRes.getFile(); - if (!caDir.isDirectory()) { - log.error("Expecting directory as SSL.caDirectory parameter"); - throw new SLRuntimeException( - "Expecting directory as SSL.caDirectory parameter"); - } - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : caDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - fis.close(); - log.debug("Adding trusted cert " + cert.getSubjectDN()); - caCerts.add(new TrustAnchor(cert, null)); - } catch (Exception e) { - log.error("Cannot add trusted ca", e); - } - } - return caCerts; - - } else { - log.warn("No CA certificates configured"); - } - return null; + + public void configure() { + super.configure(); + SpringBKUServlet.setConfigurator(this); } - private CertStore getCertstore() throws IOException, CertificateException, - InvalidAlgorithmParameterException, NoSuchAlgorithmException { - String certDirectory = getProperty("SSL.certDirectory"); - if (certDirectory != null) { - Resource certDirRes = resourceLoader.getResource(certDirectory); + @Override + public void setResourceLoader(ResourceLoader loader) { + this.resourceLoader = loader; + } - File certDir = certDirRes.getFile(); + private File getDirectory(String property) { + if (property != null) { + Resource certDirRes = resourceLoader.getResource(property); + File certDir; + try { + certDir = certDirRes.getFile(); + } catch (IOException e) { + log.error("Cannot get cert directory", e); + throw new SLRuntimeException(e); + } if (!certDir.isDirectory()) { log.error("Expecting directory as SSL.certDirectory parameter"); throw new SLRuntimeException( "Expecting directory as SSL.certDirectory parameter"); } - List certCollection = new LinkedList(); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - for (File f : certDir.listFiles()) { - try { - FileInputStream fis = new FileInputStream(f); - X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); - certCollection.add(cert); - fis.close(); - log - .trace("Added following cert to certstore: " - + cert.getSubjectDN()); - } catch (Exception ex) { - log.error("Cannot add certificate", ex); - } - } - CollectionCertStoreParameters csp = new CollectionCertStoreParameters( - certCollection); - return CertStore.getInstance("Collection", csp); - - } else { - log.warn("No certstore configured"); + return certDir; } return null; + } - public void configureSSL() { - Set caCerts = null; - try { - caCerts = getCACerts(); - } catch (Exception e1) { - log.error("Cannot load CA certificates", e1); - } - CertStore certStore = null; - try { - certStore = getCertstore(); - } catch (Exception e1) { - log.error("Cannot load certstore certificates", e1); - } - System.setProperty("com.sun.security.enableAIAcaIssuers", "true"); - try { - X509CertSelector selector = new X509CertSelector(); - PKIXBuilderParameters pkixParams; - pkixParams = new PKIXBuilderParameters(caCerts, selector); - if ((getProperty("SSL.doRevocationChecking") != null) - && (Boolean.valueOf(getProperty("SSL.doRevocationChecking")))) { - log.info("Enable revocation checking"); - pkixParams.setRevocationEnabled(true); - System.setProperty("com.sun.security.enableCRLDP", "true"); - Security.setProperty("ocsp.enable", "true"); - } else { - log.warn("Revocation checking disabled"); - pkixParams.setRevocationEnabled(false); - } - pkixParams.addCertStore(certStore); - ManagerFactoryParameters trustParams = new CertPathTrustManagerParameters( - pkixParams); - TrustManagerFactory trustFab; - try { - trustFab = TrustManagerFactory.getInstance("PKIX"); - trustFab.init(trustParams); - KeyManager[] km = null; - SSLContext sslCtx = SSLContext - .getInstance(getProperty("SSL.sslProtocol")); - sslCtx.init(km, trustFab.getTrustManagers(), null); - HttpsURLConnection - .setDefaultSSLSocketFactory(sslCtx.getSocketFactory()); - } catch (Exception e) { - log.error("Cannot configure SSL", e); - } + @Override + protected File getCADir() { + String caDirectory = getProperty("SSL.caDirectory"); + return getDirectory(caDirectory); + } - } catch (InvalidAlgorithmParameterException e) { - log.error("Cannot configure SSL", e); - } + @Override + protected File getCertDir() { + String certDirectory = getProperty("SSL.certDirectory"); + return getDirectory(certDirectory); } @Override - public void setResourceLoader(ResourceLoader loader) { - this.resourceLoader = loader; + protected InputStream getManifest() { + Resource r = resourceLoader.getResource("META-INF/MANIFEST.MF"); + if (r != null) { + try { + return r.getInputStream(); + } catch (IOException e) { + log.error("Cannot read manifest data:", e); + } + } + return null; } } \ No newline at end of file diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java index b70a6274..9e69099d 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java @@ -31,7 +31,7 @@ import org.apache.commons.logging.LogFactory; import at.gv.egiz.bku.binding.HTTPBindingProcessor; import at.gv.egiz.bku.binding.HttpUtil; import at.gv.egiz.bku.binding.IdFactory; -import at.gv.egiz.bku.online.conf.Configurator; +import at.gv.egiz.bku.conf.Configurator; /** * Delivers the result to the browser @@ -108,8 +108,8 @@ public class ResultServlet extends SpringBKUServlet { resp.setHeader("Cache-Control", "no-store"); // HTTP 1.1 resp.setHeader("Pragma", "no-cache"); // HTTP 1.0 resp.setDateHeader("Expires", 0); - if (Configurator.getInstance().getProperty(USER_AGENT_PROPERTY_KEY) != null) { - resp.setHeader(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.getInstance().getProperty( + if (configurator.getProperty(USER_AGENT_PROPERTY_KEY) != null) { + resp.setHeader(HttpUtil.HTTP_HEADER_USER_AGENT, configurator.getProperty( USER_AGENT_PROPERTY_KEY)); } else { resp.setHeader(HttpUtil.HTTP_HEADER_USER_AGENT, diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java index ec062e42..2c6f522e 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java @@ -16,16 +16,22 @@ */ package at.gv.egiz.bku.online.webapp; -import javax.servlet.http.HttpServlet; - -import at.gv.egiz.bku.binding.BindingProcessorManager; -import at.gv.egiz.bku.online.conf.Configurator; +import javax.servlet.http.HttpServlet; + +import at.gv.egiz.bku.binding.BindingProcessorManager; +import at.gv.egiz.bku.conf.Configurator; public abstract class SpringBKUServlet extends HttpServlet { public final static String BEAN_NAME="bindingProcessorManager"; + protected static Configurator configurator; + protected BindingProcessorManager getBindingProcessorManager() { return (BindingProcessorManager) getServletContext().getAttribute(BEAN_NAME); + } + + public static void setConfigurator(Configurator conf) { + configurator = conf; } } diff --git a/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/defaultConf.properties b/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/defaultConf.properties index 73d89f22..d7fc5ae9 100644 --- a/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/defaultConf.properties +++ b/BKUOnline/src/main/resources/at/gv/egiz/bku/online/conf/defaultConf.properties @@ -36,6 +36,10 @@ SSL.caDirectory=classpath:at/gv/egiz/bku/online/conf/certs/CACerts SSL.doRevocationChecking=true SSL.sslProtocol=TLS +SSL.cache.lifetime=3600 + +# use authority info access extension to find ca certs. +SSL.useAIA=true # ------------ END SSL Config -------------------- @@ -44,3 +48,4 @@ AppletTimeout=300000 #HTTPProxyHost=taranis.iaik.tugraz.at #HTTPProxyPort=8888 +#DefaultSocketTimeout=200 diff --git a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml index 04b07ba4..b074da59 100644 --- a/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml +++ b/BKUOnline/src/main/webapp/WEB-INF/applicationContext.xml @@ -45,8 +45,8 @@ - + diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java new file mode 100644 index 00000000..9a1e7020 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java @@ -0,0 +1,351 @@ +package at.gv.egiz.bku.conf; + +import iaik.security.ecc.provider.ECCProvider; +import iaik.security.provider.IAIK; +import iaik.xml.crypto.XSecProvider; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; +import java.security.cert.CertStore; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.CollectionCertStoreParameters; +import java.security.cert.LDAPCertStoreParameters; +import java.security.cert.PKIXBuilderParameters; +import java.security.cert.TrustAnchor; +import java.security.cert.X509CertSelector; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import javax.net.ssl.CertPathTrustManagerParameters; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.ManagerFactoryParameters; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.binding.DataUrl; +import at.gv.egiz.bku.binding.DataUrlConnection; +import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; +import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +public abstract class Configurator { + private Log log = LogFactory.getLog(Configurator.class); + + protected Properties properties; + + protected Configurator() { + } + + protected abstract File getCertDir(); + + protected abstract File getCADir(); + + protected abstract InputStream getManifest(); + + private Set getCACerts() throws IOException, + CertificateException { + Set caCerts = new HashSet(); + File caDir = getCADir(); + if (caDir != null) { + if (!caDir.isDirectory()) { + log.error("Expecting directory as SSL.caDirectory parameter"); + throw new SLRuntimeException( + "Expecting directory as SSL.caDirectory parameter"); + } + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + for (File f : caDir.listFiles()) { + try { + FileInputStream fis = new FileInputStream(f); + X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); + fis.close(); + log.debug("Adding trusted cert " + cert.getSubjectDN()); + caCerts.add(new TrustAnchor(cert, null)); + } catch (Exception e) { + log.error("Cannot add trusted ca", e); + } + } + return caCerts; + + } else { + log.warn("No CA certificates configured"); + } + return null; + } + + protected List getCertstore() throws IOException, + CertificateException, InvalidAlgorithmParameterException, + NoSuchAlgorithmException { + List resultList = new ArrayList(); + File certDir = getCertDir(); + if (certDir != null) { + if (!certDir.isDirectory()) { + log.error("Expecting directory as SSL.certDirectory parameter"); + throw new SLRuntimeException( + "Expecting directory as SSL.certDirectory parameter"); + } + List certCollection = new LinkedList(); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + for (File f : certDir.listFiles()) { + try { + FileInputStream fis = new FileInputStream(f); + X509Certificate cert = (X509Certificate) cf.generateCertificate(fis); + certCollection.add(cert); + fis.close(); + log + .trace("Added following cert to certstore: " + + cert.getSubjectDN()); + } catch (Exception ex) { + log.error("Cannot add certificate", ex); + } + } + CollectionCertStoreParameters csp = new CollectionCertStoreParameters( + certCollection); + resultList.add(CertStore.getInstance("Collection", csp)); + log.info("Added collection certstore"); + } else { + log.warn("No certstore directory configured"); + } + String ldapHost = getProperty("SSL.ldapServer"); + if ((ldapHost != null) && (!"".equals(ldapHost))) { + String ldapPortString = getProperty("SSL.ldapPort"); + int ldapPort = 389; + if (ldapPortString != null) { + try { + ldapPort = Integer.parseInt(ldapPortString); + } catch (NumberFormatException nfe) { + log.error("Invalid ldap port, using default 389"); + } + } else { + log.warn("ldap port not specified, using default 389"); + } + LDAPCertStoreParameters ldapParams = new LDAPCertStoreParameters( + ldapHost, ldapPort); + resultList.add(CertStore.getInstance("LDAP", ldapParams)); + log.info("Added LDAP certstore"); + } + return resultList; + } + + protected void configUrlConnections() { + HttpsURLConnection.setFollowRedirects(false); + HttpURLConnection.setFollowRedirects(false); + } + + protected void configureProviders() { + log.debug("Registering security providers"); + Security.insertProviderAt(new IAIK(), 1); + Security.insertProviderAt(new ECCProvider(false), 2); + Security.addProvider(new STALProvider()); + XSecProvider.addAsProvider(false); + StringBuilder sb = new StringBuilder(); + sb.append("Registered providers: "); + int i = 1; + for (Provider prov : Security.getProviders()) { + sb.append((i++) + ". : " + prov); + } + log.debug(sb.toString()); + } + + protected void configViewer() { + String bv = properties.getProperty("ValidateHashDataInputs"); + if (bv != null) { + DataObject.enableHashDataInputValidation(Boolean.parseBoolean(bv)); + } else { + log.warn("ValidateHashDataInputs not set, falling back to default"); + } + } + + public void configureNetwork() { + String proxy = getProperty("HTTPProxyHost"); + String portString = getProperty("HTTPProxyPort"); + if ((proxy == null) || (proxy.equals(""))) { + log.info("No proxy configured"); + } else { + log.info("Setting proxy to: " + proxy + ":" + portString); + System.setProperty("proxyHost", proxy); + System.setProperty("proxyPort", portString); + } + String timeout = getProperty("DefaultSocketTimeout"); + if ((timeout != null) && (!timeout.equals(""))) { + System.setProperty("sun.net.client.defaultConnectTimeout", timeout); + } + } + + public void configureVersion() { + Properties p = new Properties(); + try { + InputStream is = getManifest(); + if (is != null) { + p.load(getManifest()); + String version = p.getProperty("Implementation-Build"); + properties.setProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY, + "citizen-card-environment/1.2 MOCCA " + version); + DataUrl.setConfiguration(properties); + log + .debug("Setting user agent to: " + + properties + .getProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY)); + } else { + log.warn("Cannot read manifest"); + properties.setProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY, + "citizen-card-environment/1.2 MOCCA UNKNOWN"); + DataUrl.setConfiguration(properties); + } + } catch (IOException e) { + log.error(e); + } + } + + public void configure() { + configureProviders(); + configUrlConnections(); + configViewer(); + configureSSL(); + configureVersion(); + configureNetwork(); + } + + public void setConfiguration(Properties props) { + this.properties = props; + } + + public String getProperty(String key) { + if (properties != null) { + return properties.getProperty(key); + } + return null; + } + + public void configureSSL() { + Set caCerts = null; + try { + caCerts = getCACerts(); + } catch (Exception e1) { + log.error("Cannot load CA certificates", e1); + } + List certStoreList = null; + try { + certStoreList = getCertstore(); + } catch (Exception e1) { + log.error("Cannot load certstore certificates", e1); + } + String aia = getProperty("SSL.useAIA"); + if ((aia == null) || (aia.equals(""))) { + System.setProperty("com.sun.security.enableAIAcaIssuers", "true"); + } else { + System.setProperty("com.sun.security.enableAIAcaIssuers", aia); + } + String lifetime = getProperty("SSL.cache.lifetime"); + if ((lifetime == null) || (lifetime.equals(""))) { + System.setProperty("sun.security.certpath.ldap.cache.lifetime", "0"); + } else { + System.setProperty("sun.security.certpath.ldap.cache.lifetime", lifetime); + } + X509CertSelector selector = new X509CertSelector(); + PKIXBuilderParameters pkixParams; + try { + pkixParams = new PKIXBuilderParameters(caCerts, selector); + if ((getProperty("SSL.doRevocationChecking") != null) + && (Boolean.valueOf(getProperty("SSL.doRevocationChecking")))) { + log.info("Enable revocation checking"); + System.setProperty("com.sun.security.enableCRLDP", "true"); + Security.setProperty("ocsp.enable", "true"); + } else { + log.warn("Revocation checking disabled"); + } + for (CertStore cs : certStoreList) { + pkixParams.addCertStore(cs); + } + ManagerFactoryParameters trustParams = new CertPathTrustManagerParameters( + pkixParams); + TrustManagerFactory trustFab; + trustFab = TrustManagerFactory.getInstance("PKIX"); + trustFab.init(trustParams); + KeyManager[] km = null; + SSLContext sslCtx = SSLContext + .getInstance(getProperty("SSL.sslProtocol")); + String disableAll = getProperty("SSL.disableAllChecks"); + if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) { + log.warn("--------------------------------------"); + log.warn(" Disabling SSL Certificate Validation "); + log.warn("--------------------------------------"); + + sslCtx.init(km, new TrustManager[] { new MyTrustManager(caCerts, + certStoreList) }, null); + } else { + sslCtx.init(km, trustFab.getTrustManagers(), null); + } + HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory()); + } catch (Exception e) { + log.error("Cannot configure SSL", e); + } + String disableAll = getProperty("SSL.disableAllChecks"); + if ((disableAll != null) && (Boolean.parseBoolean(disableAll))) { + log.warn("---------------------------------"); + log.warn(" Disabling Hostname Verification "); + log.warn("---------------------------------"); + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + } + } + + private static class MyTrustManager implements X509TrustManager { + private static Log log = LogFactory.getLog(MyTrustManager.class); + private X509Certificate[] trustedCerts; + + public MyTrustManager(Set caCerts, List cs) { + trustedCerts = new X509Certificate[caCerts.size()]; + int i = 0; + for (Iterator it = caCerts.iterator(); it.hasNext();) { + TrustAnchor ta = it.next(); + trustedCerts[i++] = ta.getTrustedCert(); + } + } + + @Override + public void checkClientTrusted(X509Certificate[] arg0, String arg1) + throws CertificateException { + log.error("Did not expect this method to get called"); + throw new CertificateException("Method not implemented"); + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String arg1) + throws CertificateException { + log.warn("-------------------------------------"); + log.warn("SSL Certificate Validation Disabled !"); + log.warn("-------------------------------------"); + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return trustedCerts; + } + } +} diff --git a/pom.xml b/pom.xml index dbe2812e..c18a4c2c 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ STALService BKUCommonGUI BKUViewer + BKULocalApp diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java index 5aa74d99..c7aae215 100644 --- a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java +++ b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java @@ -107,7 +107,7 @@ public class TrayIconDialog implements TrayIconDialogInterface { if (isSupported) { SystemTray tray = SystemTray.getSystemTray(); Image image = ImageIO.read(getClass().getClassLoader() - .getResourceAsStream("at/gv/egiz/bku/local/ui/chipperling.png")); + .getResourceAsStream("at/gv/egiz/bku/local/ui/favicon.png")); PopupMenu popup = new PopupMenu(); MenuItem exitItem = new MenuItem(resourceBundel .getString("TrayMenu.Shutdown")); -- cgit v1.2.3 From bd7c3ec609f1527db42601c65c3990423300ceca Mon Sep 17 00:00:00 2001 From: mcentner Date: Tue, 21 Oct 2008 15:00:33 +0000 Subject: Simplified IdentityLinkTransformer. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@124 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../slcommands/impl/InfoboxReadCommandImpl.java | 20 +- .../at/gv/egiz/idlink/IdentityLinkTransformer.java | 223 +++++---------------- 2 files changed, 71 insertions(+), 172 deletions(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java index b6c89e5b..d23c0598 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java @@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.net.MalformedURLException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; @@ -415,11 +416,22 @@ public class InfoboxReadCommandImpl extends SLCommandImpltrue if this transformer is in use, or false otherwise - */ - public boolean isInUse() { - return inUse; - } - - @Override - public String toString() { - StringBuffer str = new StringBuffer(); - str.append("Transformer ").append(stylesheetURL) - .append("\n created ").append(new Date(created)).append(" used ").append( - timesUsed).append(" times, (init ").append(initTime).append("ms / ") - .append(((float) time) / timesUsed).append("ms avg) last time ").append(new Date(lastTimeUsed)); - return str.toString(); - } - - } - /** - * The transfomer factory. + * The transformer factory. */ private static SAXTransformerFactory factory; @@ -232,70 +122,67 @@ public class IdentityLinkTransformer { } - /** - * The pool of Transformer. - */ - private Map> pool; + /** + * Mapping of issuer template URIs to transformation templates. + */ + private Map templates = new HashMap(); /** * Private constructor. */ private IdentityLinkTransformer() { - pool = new HashMap>(); - } - - private IdLTransformer getFreeTransfomer(String stylesheetURL) throws TransformerConfigurationException, IOException { - - IdLTransformer transformer = null; - - List transfomerList = pool.get(stylesheetURL); - if (transfomerList == null) { - transfomerList = new ArrayList(); - pool.put(stylesheetURL, transfomerList); - } - - for (IdLTransformer candTransformer : transfomerList) { - if (!candTransformer.inUse) { - transformer = candTransformer; - break; - } - } - - if (transformer == null) { - transformer = new IdLTransformer(stylesheetURL); - transfomerList.add(transformer); - } - - transformer.inUse = true; - return transformer; - - } - + } + + /** + * Transforms an identity link source to result with + * the given issuer template from the stylesheetURL. + * + * @param stylesheetURL + * the URL of the issuer template to be used for transformation + * @param source + * the compressed identity link source + * @param result + * the transformed identity link result + * + * @throws MalformedURLException + * if the given stylesheetURL is not a valid + * http or https URL. + * @throws IOException + * if dereferencing the stylesheetURL fails. + * @throws TransformerConfigurationException + * if creating a transformation template from the dereferenced + * stylesheet fails. + * @throws TransformerException + * if transforming the identity link fails. + */ public void transformIdLink(String stylesheetURL, Source source, Result result) throws IOException, TransformerException { - log.trace("Trying to get free IdentityLinkTransformer for issuer template '" + stylesheetURL + "'."); - IdLTransformer transformer = getFreeTransfomer(stylesheetURL); - log.trace("Trying to transform IdentityLink."); + + Templates templ = templates.get(stylesheetURL); + + if (templ == null) { + + // TODO: implement stylesheet cache + URL url = new URL(stylesheetURL); + + if (!"http".equalsIgnoreCase(url.getProtocol()) && !"https".equalsIgnoreCase(url.getProtocol())) { + throw new MalformedURLException("Protocol " + url.getProtocol() + " not supported for IssuerTemplate URL."); + } + + URLDereferencer dereferencer = URLDereferencer.getInstance(); + StreamData data = dereferencer.dereference(url.toExternalForm(), null); + + log.trace("Trying to create issuer template."); + templ = factory.newTemplates(new StreamSource(data.getStream())); + log.trace("Successfully created issuer template"); + + templates.put(stylesheetURL, templ); + + } + + Transformer transformer = templ.newTransformer(); + transformer.transform(source, result); - log.trace("IdentityLink transformed successfully. " + getStatistics()); - } - - public String getStatistics() { - - StringBuffer str = new StringBuffer(); - Iterator keys = pool.keySet().iterator(); - int count = 0; - while (keys.hasNext()) { - String stylesheetURL = (String) keys.next(); - str.append("Stylesheet URL: ").append(stylesheetURL); - Iterator transformer = pool.get(stylesheetURL).iterator(); - while (transformer.hasNext()) { - IdLTransformer idLTransformer = (IdLTransformer) transformer.next(); - str.append("\n ").append(idLTransformer); - count++; - } - } - str.append("\n(").append(count).append(" transformer)"); - return str.toString(); + } } -- cgit v1.2.3 From 9952e18beb578a1a52cc18957a0b5eb17943045d Mon Sep 17 00:00:00 2001 From: mcentner Date: Fri, 31 Oct 2008 09:15:18 +0000 Subject: Added IdentityLinkFactory to utils. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@131 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/idlink/IdentityLinkFactory.java | 421 +++++++++++++++++++++ .../at/gv/egiz/idlink/CompressIdentityLink.java | 23 +- .../test/java/at/gv/egiz/idlink/IdentityLink.java | 153 ++++++++ .../at/gv/egiz/idlink/IdentityLinkTest.p12 | Bin 0 -> 4222 bytes .../test/resources/at/gv/egiz/idlink/certified.cer | Bin 0 -> 1279 bytes .../test/resources/at/gv/egiz/idlink/secure.cer | Bin 0 -> 1269 bytes 6 files changed, 584 insertions(+), 13 deletions(-) create mode 100644 utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java create mode 100644 utils/src/test/java/at/gv/egiz/idlink/IdentityLink.java create mode 100644 utils/src/test/resources/at/gv/egiz/idlink/IdentityLinkTest.p12 create mode 100644 utils/src/test/resources/at/gv/egiz/idlink/certified.cer create mode 100644 utils/src/test/resources/at/gv/egiz/idlink/secure.cer (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java new file mode 100644 index 00000000..a5ceeafc --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java @@ -0,0 +1,421 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink; + +import iaik.xml.crypto.XmldsigMore; + +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.math.BigInteger; +import java.nio.charset.Charset; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; +import javax.xml.crypto.MarshalException; +import javax.xml.crypto.dsig.CanonicalizationMethod; +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.crypto.dsig.Manifest; +import javax.xml.crypto.dsig.Reference; +import javax.xml.crypto.dsig.SignatureMethod; +import javax.xml.crypto.dsig.SignedInfo; +import javax.xml.crypto.dsig.Transform; +import javax.xml.crypto.dsig.XMLObject; +import javax.xml.crypto.dsig.XMLSignature; +import javax.xml.crypto.dsig.XMLSignatureException; +import javax.xml.crypto.dsig.XMLSignatureFactory; +import javax.xml.crypto.dsig.dom.DOMSignContext; +import javax.xml.crypto.dsig.keyinfo.KeyInfo; +import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; +import javax.xml.crypto.dsig.keyinfo.X509Data; +import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; +import javax.xml.crypto.dsig.spec.TransformParameterSpec; +import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import oasis.names.tc.saml._1_0.assertion.AssertionType; +import oasis.names.tc.saml._1_0.assertion.AttributeStatementType; +import oasis.names.tc.saml._1_0.assertion.AttributeType; +import oasis.names.tc.saml._1_0.assertion.SubjectConfirmationType; +import oasis.names.tc.saml._1_0.assertion.SubjectType; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; +import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; +import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType.Value; +import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; +import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; +import at.gv.egiz.xmldsig.KeyValueFactory; + +public class IdentityLinkFactory { + + private static Log log = LogFactory.getLog(IdentityLinkFactory.class); + + /** + * The instance returned by {@link #getInstance()}. + */ + private static IdentityLinkFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + /** + * The KeyValueFactory. + */ + private static KeyValueFactory keyValueFactory; + + /** + * Get an instance of this CompressedIdentityLinkFactory. + * + * @return an instance of this CompressedIdentityLinkFactory + */ + public synchronized static IdentityLinkFactory getInstance() { + if (instance == null) { + instance = new IdentityLinkFactory(); + } + return instance; + } + + /** + * Private constructor. + */ + private IdentityLinkFactory() { + + keyValueFactory = new KeyValueFactory(); + + StringBuffer packageNames = new StringBuffer(); + packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(oasis.names.tc.saml._1_0.assertion.ObjectFactory.class.getPackage().getName()); + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + + } + + public JAXBElement createAssertion(String assertionId, + Date issueInstant, String issuer, long majorVersion, long minorVersion, AttributeStatementType attributeStatement) { + + oasis.names.tc.saml._1_0.assertion.ObjectFactory asFactory = + new oasis.names.tc.saml._1_0.assertion.ObjectFactory(); + + AssertionType assertionType = asFactory.createAssertionType(); + + assertionType.setAssertionID(assertionId); + + GregorianCalendar gregorianCalendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); + gregorianCalendar.setTime(issueInstant); + try { + DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); + assertionType.setIssueInstant(datatypeFactory.newXMLGregorianCalendar(gregorianCalendar)); + } catch (DatatypeConfigurationException e) { + throw new RuntimeException(e); + } + + assertionType.setIssuer(issuer); + + assertionType.setMajorVersion(BigInteger.valueOf(majorVersion)); + assertionType.setMinorVersion(BigInteger.valueOf(minorVersion)); + + assertionType.getStatementOrSubjectStatementOrAuthenticationStatement().add(attributeStatement); + + return asFactory.createAssertion(assertionType); + + } + + public AttributeStatementType createAttributeStatement(String idValue, String idType, + String givenName, String familyName, String dateOfBirth, + PublicKey[] publicKeys) throws KeyTypeNotSupportedException { + + oasis.names.tc.saml._1_0.assertion.ObjectFactory asFactory = + new oasis.names.tc.saml._1_0.assertion.ObjectFactory(); + + at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory prFactory = + new at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory(); + + AttributeStatementType attributeStatementType = asFactory.createAttributeStatementType(); + + // saml:Subject + SubjectConfirmationType subjectConfirmationType = asFactory.createSubjectConfirmationType(); + + subjectConfirmationType.getConfirmationMethod().add("urn:oasis:names:tc:SAML:1.0:cm:sender-vouches"); + + // pr:Person + Value identificationTypeValue = prFactory.createIdentificationTypeValue(); + identificationTypeValue.setValue(idValue); + IdentificationType identificationType = prFactory + .createIdentificationType(); + identificationType.setValue(identificationTypeValue); + identificationType.setType(idType); + + PersonNameType personNameType = prFactory.createPersonNameType(); + FamilyName personNameTypeFamilyName = prFactory + .createPersonNameTypeFamilyName(); + personNameTypeFamilyName.setValue(familyName); + personNameTypeFamilyName.setPrimary("undefined"); + personNameType.getFamilyName().add(personNameTypeFamilyName); + personNameType.getGivenName().add(givenName); + + PhysicalPersonType physicalPersonType = prFactory + .createPhysicalPersonType(); + physicalPersonType.getIdentification().add(identificationType); + physicalPersonType.setName(personNameType); + physicalPersonType.setDateOfBirth(dateOfBirth); + + subjectConfirmationType.setSubjectConfirmationData(physicalPersonType); + + JAXBElement subjectConfirmation = asFactory.createSubjectConfirmation(subjectConfirmationType); + + SubjectType subjectType = asFactory.createSubjectType(); + subjectType.getContent().add(subjectConfirmation); + + attributeStatementType.setSubject(subjectType); + + // saml:Attribute CitizenPublicKey + for (int i = 0; i < publicKeys.length; i++) { + + JAXBElement createKeyValue = keyValueFactory.createKeyValue(publicKeys[i]); + AttributeType attributeType = asFactory.createAttributeType(); + attributeType.setAttributeName("CitizenPublicKey"); + attributeType.setAttributeNamespace("urn:publicid:gv.at:namespaces:identitylink:1.2"); + attributeType.getAttributeValue().add(createKeyValue.getValue()); + + attributeStatementType.getAttribute().add(attributeType); + + } + + return attributeStatementType; + } + + /** + * Marshall the given compressedIdentityLink into a DOM document + * with the given Nodes as parent and nextSibling + * nodes. + * + * @param identityLink + * the CompressedIdentityLink element + * @param parent + * the parent node + * @param nextSibling + * the next sibling node (may be null) + * @param applyWorkarounds + * apply workarounds as spefiyed by + * {@link #applyWorkarounds(Element, int)} + * + * @throws JAXBException + * if an unexpected error occurs while marshalling + * @throws NullPointerException + * if compressdIdentityLink or parent is + * null + */ + public void marshallIdentityLink( + JAXBElement identityLink, + Node parent, Node nextSibling) throws JAXBException { + + DOMResult result = new DOMResult(parent, nextSibling); + + try { + Marshaller marshaller = jaxbContext.createMarshaller(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + marshaller.marshal(identityLink, result); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + + } + + public void signIdentityLink(Element assertion, X509Certificate certificate, + PrivateKey key) throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException, XMLSignatureException, + MarshalException { + + XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance(); + + KeyInfoFactory keyInfoFactory = KeyInfoFactory.getInstance(); + + List references = new ArrayList(); + + // Reference #1 + + Map prefixMap = new HashMap(); + prefixMap.put("pr", "http://reference.e-government.gv.at/namespace/persondata/20020228#"); + List transforms1 = new ArrayList(); + transforms1.add(signatureFactory.newTransform(Transform.XPATH, + new XPathFilterParameterSpec( + "not(ancestor-or-self::pr:Identification)", prefixMap))); + transforms1.add(signatureFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)); + DigestMethod digestMethod1 = signatureFactory.newDigestMethod(DigestMethod.SHA1, null); + references.add(signatureFactory.newReference("", digestMethod1, transforms1, null, null)); + + // Reference (Manifest) + + DigestMethod digestMethod2 = signatureFactory.newDigestMethod(DigestMethod.SHA1, null); + references.add(signatureFactory.newReference("#manifest", digestMethod2, null, Manifest.TYPE, null)); + + CanonicalizationMethod canonicalizationMethod = signatureFactory + .newCanonicalizationMethod(CanonicalizationMethod.EXCLUSIVE, + (C14NMethodParameterSpec) null); + + SignatureMethod signatureMethod; + String algorithm = key.getAlgorithm(); + if ("RSA".equalsIgnoreCase(algorithm)) { + signatureMethod = signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null); + } else if ("ECDSA".equalsIgnoreCase(algorithm) || "EC".equalsIgnoreCase(algorithm)) { + signatureMethod = signatureFactory.newSignatureMethod(XmldsigMore.SIGNATURE_ECDSA_SHA1, null); + } else if ("DSA".equalsIgnoreCase(algorithm)) { + signatureMethod = signatureFactory.newSignatureMethod(SignatureMethod.DSA_SHA1, null); + } else { + throw new NoSuchAlgorithmException("Algorithm '" + algorithm + "' not supported."); + } + + SignedInfo signedInfo = signatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, references); + + + X509Data x509Data = keyInfoFactory.newX509Data(Collections.singletonList(certificate)); + KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data)); + + // Manifest + + Map manifestPrefixMap = new HashMap(); + manifestPrefixMap.put("dsig", XMLSignature.XMLNS); + List manifestTransforms = Collections + .singletonList(signatureFactory.newTransform(Transform.XPATH, + new XPathFilterParameterSpec( + "not(ancestor-or-self::dsig:Signature)", manifestPrefixMap))); + Reference manifestReference = signatureFactory.newReference("", + signatureFactory.newDigestMethod(DigestMethod.SHA1, null), + manifestTransforms, null, null); + + Manifest manifest = signatureFactory.newManifest(Collections + .singletonList(manifestReference), "manifest"); + + XMLObject xmlObject = signatureFactory.newXMLObject(Collections + .singletonList(manifest), null, null, null); + + XMLSignature xmlSignature = signatureFactory.newXMLSignature(signedInfo, + keyInfo, Collections.singletonList(xmlObject), null, null); + + DOMSignContext signContext = new DOMSignContext(key, assertion); + + if (log.isTraceEnabled()) { + signContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE); + } + + xmlSignature.sign(signContext); + + if (log.isDebugEnabled()) { + + try { + + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + + StringWriter writer = new StringWriter(); + + transformer.transform(new DOMSource(assertion), new StreamResult(writer)); + + log.debug(writer.toString()); + + } catch (Exception e) { + log.debug(e); + } + + } + + if (log.isTraceEnabled()) { + + StringBuilder sb = new StringBuilder(); + + sb.append("Digest input data:\n\n"); + + try { + + Iterator refs = references.iterator(); + for (int i = 0; refs.hasNext(); i++) { + Reference reference = (Reference) refs.next(); + sb.append("Reference " + i + "\n"); + + Reader reader = new InputStreamReader(reference + .getDigestInputStream(), Charset.forName("UTF-8")); + char c[] = new char[512]; + for (int l; (l = reader.read(c)) != -1;) { + sb.append(c, 0, l); + } + sb.append("\n"); + } + + sb.append("Manifest Reference\n"); + + Reader reader = new InputStreamReader(manifestReference + .getDigestInputStream(), Charset.forName("UTF-8")); + char c[] = new char[512]; + for (int l; (l = reader.read(c)) != -1;) { + sb.append(c, 0, l); + } + + } catch (Exception e) { + sb.append(e.getMessage()); + } + + log.trace(sb.toString()); + } + + } + +} diff --git a/utils/src/test/java/at/gv/egiz/idlink/CompressIdentityLink.java b/utils/src/test/java/at/gv/egiz/idlink/CompressIdentityLink.java index e89f6137..e040d7e8 100644 --- a/utils/src/test/java/at/gv/egiz/idlink/CompressIdentityLink.java +++ b/utils/src/test/java/at/gv/egiz/idlink/CompressIdentityLink.java @@ -16,19 +16,16 @@ */ package at.gv.egiz.idlink; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; - -import javax.xml.bind.JAXBException; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; - -import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; -import at.gv.egiz.bku.utils.HexDump; -import at.gv.egiz.idlink.ans1.IdentityLink; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.xml.bind.JAXBException; +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; +import at.gv.egiz.idlink.ans1.IdentityLink; public class CompressIdentityLink { diff --git a/utils/src/test/java/at/gv/egiz/idlink/IdentityLink.java b/utils/src/test/java/at/gv/egiz/idlink/IdentityLink.java new file mode 100644 index 00000000..a97a468e --- /dev/null +++ b/utils/src/test/java/at/gv/egiz/idlink/IdentityLink.java @@ -0,0 +1,153 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.idlink; + +import iaik.xml.crypto.XSecProvider; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Enumeration; +import java.util.List; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.crypto.MarshalException; +import javax.xml.crypto.dsig.XMLSignatureException; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import oasis.names.tc.saml._1_0.assertion.AssertionType; +import oasis.names.tc.saml._1_0.assertion.AttributeStatementType; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.w3c.dom.Document; + +import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; + +public class IdentityLink { + + private static String keyStoreType = "PKCS12"; + + private static String keyStoreFile = "at/gv/egiz/idlink/IdentityLinkTest.p12"; + + private static String keyStorePassword = "mocca"; + + private static String[] certificateFiles = new String [] { + "at/gv/egiz/idlink/certified.cer", + "at/gv/egiz/idlink/secure.cer" + }; + + private static PublicKey[] publicKeys; + + private static X509Certificate signerCert; + + private static PrivateKey signerKey; + + @BeforeClass + public static void setupClass() throws NoSuchAlgorithmException, IOException, + InvalidKeySpecException, KeyStoreException, CertificateException, + UnrecoverableKeyException { + + XSecProvider.addAsProvider(false); + + ClassLoader classLoader = IdentityLink.class.getClassLoader(); + + CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); + + List keys = new ArrayList(); + for (String certificateFile : certificateFiles) { + + InputStream certStream = classLoader.getResourceAsStream(certificateFile); + X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(certStream); + keys.add(cert.getPublicKey()); + + } + + publicKeys = keys.toArray(new PublicKey[0]); + + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + keyStore.load(classLoader.getResourceAsStream(keyStoreFile), keyStorePassword.toCharArray()); + + Enumeration aliases = keyStore.aliases(); + while (aliases.hasMoreElements()) { + String alias = (String) aliases.nextElement(); + if (keyStore.isKeyEntry(alias)) { + signerKey = (PrivateKey) keyStore.getKey(alias, keyStorePassword.toCharArray()); + signerCert = (X509Certificate) keyStore.getCertificate(alias); + } + } + + + } + + @Test + public void testCreateIdentityLink() throws KeyTypeNotSupportedException, ParserConfigurationException, JAXBException, TransformerException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, XMLSignatureException, MarshalException, FileNotFoundException { + + IdentityLinkFactory factory = IdentityLinkFactory.getInstance(); + + AttributeStatementType attributeStatement = factory.createAttributeStatement( + "3utiDdA4KaodrJOeMqu9PA==", + "urn:publicid:gv.at:baseid", + "Max Moritz", + "Mustermann-Fall", + "1900-01-01", + publicKeys + ); + + Calendar calendar = Calendar.getInstance(); + calendar.clear(); + calendar.set(2007, 8, 29, 18, 0, 0); + + JAXBElement assertion = factory.createAssertion( + "bka.gv.at-2007-08-29T16.41.17.442", + calendar.getTime(), + "http://www.bka.gv.at/datenschutz/Stammzahlenregisterbehoerde", + 1L, + 0L, + attributeStatement); + + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + Document doc = dbf.newDocumentBuilder().newDocument(); + + factory.marshallIdentityLink(assertion, doc, null); + + factory.signIdentityLink(doc.getDocumentElement(), signerCert, signerKey); + + } + +} diff --git a/utils/src/test/resources/at/gv/egiz/idlink/IdentityLinkTest.p12 b/utils/src/test/resources/at/gv/egiz/idlink/IdentityLinkTest.p12 new file mode 100644 index 00000000..574e1361 Binary files /dev/null and b/utils/src/test/resources/at/gv/egiz/idlink/IdentityLinkTest.p12 differ diff --git a/utils/src/test/resources/at/gv/egiz/idlink/certified.cer b/utils/src/test/resources/at/gv/egiz/idlink/certified.cer new file mode 100644 index 00000000..1e350d4d Binary files /dev/null and b/utils/src/test/resources/at/gv/egiz/idlink/certified.cer differ diff --git a/utils/src/test/resources/at/gv/egiz/idlink/secure.cer b/utils/src/test/resources/at/gv/egiz/idlink/secure.cer new file mode 100644 index 00000000..30ac4330 Binary files /dev/null and b/utils/src/test/resources/at/gv/egiz/idlink/secure.cer differ -- cgit v1.2.3 From 824e24da5cfab839fa6b0ba34565dba74e3c258d Mon Sep 17 00:00:00 2001 From: clemenso Date: Mon, 1 Dec 2008 13:32:39 +0000 Subject: CardChannel schema git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@228 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/stal/cardchannel/ATRType.java | 100 ++++++++ .../at/gv/egiz/stal/cardchannel/AttributeList.java | 71 ++++++ .../at/gv/egiz/stal/cardchannel/AttributeType.java | 264 ++++++++++++++++++++ .../gv/egiz/stal/cardchannel/CommandAPDUType.java | 154 ++++++++++++ .../at/gv/egiz/stal/cardchannel/ObjectFactory.java | 170 +++++++++++++ .../at/gv/egiz/stal/cardchannel/ResetType.java | 64 +++++ .../gv/egiz/stal/cardchannel/ResponseAPDUType.java | 161 +++++++++++++ .../at/gv/egiz/stal/cardchannel/ResponseType.java | 78 ++++++ .../at/gv/egiz/stal/cardchannel/ScriptType.java | 80 +++++++ .../gv/egiz/stal/cardchannel/VerifyAPDUType.java | 266 +++++++++++++++++++++ 10 files changed, 1408 insertions(+) create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java create mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java new file mode 100644 index 00000000..d9f2b8a7 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java @@ -0,0 +1,100 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + * Contains the ATR received as reponse to a Reset + * command + * + *

Java class for ATRType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ATRType">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
+ *       <attribute name="rc" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ATRType", propOrder = { + "value" +}) +public class ATRType { + + @XmlValue + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] value; + @XmlAttribute + protected BigInteger rc; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the rc property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getRc() { + if (rc == null) { + return new BigInteger("0"); + } else { + return rc; + } + } + + /** + * Sets the value of the rc property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setRc(BigInteger value) { + this.rc = value; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java new file mode 100644 index 00000000..da0ac66c --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java @@ -0,0 +1,71 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + * Contains a list of attributes + * + *

Java class for AttributeList complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="AttributeList">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Attribute" type="{}AttributeType" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "AttributeList", propOrder = { + "attribute" +}) +public class AttributeList { + + @XmlElement(name = "Attribute") + protected List attribute; + + /** + * Gets the value of the attribute property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the attribute property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAttribute().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AttributeType } + * + * + */ + public List getAttribute() { + if (attribute == null) { + attribute = new ArrayList(); + } + return this.attribute; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java new file mode 100644 index 00000000..3666c92b --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java @@ -0,0 +1,264 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + * Contains an attribute converted from ASN.1 + * + *

Java class for AttributeType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="AttributeType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="Integer" type="{http://www.w3.org/2001/XMLSchema}integer" minOccurs="0"/>
+ *         <element name="Latin1String" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="UTF8String" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="NumericString" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="PrintableString" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="GeneralizedTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="Date" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *       <attribute name="oid" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "AttributeType", propOrder = { + "integer", + "latin1String", + "utf8String", + "numericString", + "printableString", + "generalizedTime", + "date" +}) +public class AttributeType { + + @XmlElement(name = "Integer") + protected BigInteger integer; + @XmlElement(name = "Latin1String") + protected String latin1String; + @XmlElement(name = "UTF8String") + protected String utf8String; + @XmlElement(name = "NumericString") + protected String numericString; + @XmlElement(name = "PrintableString") + protected String printableString; + @XmlElement(name = "GeneralizedTime") + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar generalizedTime; + @XmlElement(name = "Date") + protected String date; + @XmlAttribute(required = true) + protected String oid; + + /** + * Gets the value of the integer property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getInteger() { + return integer; + } + + /** + * Sets the value of the integer property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setInteger(BigInteger value) { + this.integer = value; + } + + /** + * Gets the value of the latin1String property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLatin1String() { + return latin1String; + } + + /** + * Sets the value of the latin1String property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLatin1String(String value) { + this.latin1String = value; + } + + /** + * Gets the value of the utf8String property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUTF8String() { + return utf8String; + } + + /** + * Sets the value of the utf8String property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUTF8String(String value) { + this.utf8String = value; + } + + /** + * Gets the value of the numericString property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNumericString() { + return numericString; + } + + /** + * Sets the value of the numericString property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNumericString(String value) { + this.numericString = value; + } + + /** + * Gets the value of the printableString property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPrintableString() { + return printableString; + } + + /** + * Sets the value of the printableString property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPrintableString(String value) { + this.printableString = value; + } + + /** + * Gets the value of the generalizedTime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getGeneralizedTime() { + return generalizedTime; + } + + /** + * Sets the value of the generalizedTime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setGeneralizedTime(XMLGregorianCalendar value) { + this.generalizedTime = value; + } + + /** + * Gets the value of the date property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getDate() { + return date; + } + + /** + * Sets the value of the date property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setDate(String value) { + this.date = value; + } + + /** + * Gets the value of the oid property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getOid() { + return oid; + } + + /** + * Sets the value of the oid property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setOid(String value) { + this.oid = value; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java new file mode 100644 index 00000000..d835ef11 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java @@ -0,0 +1,154 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + * Contains a sequence of bytes send as command APDU to the + * icc + * + *

Java class for CommandAPDUType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="CommandAPDUType">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
+ *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
+ *       <attribute name="of" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
+ *       <attribute name="expectedSW" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CommandAPDUType", propOrder = { + "value" +}) +public class CommandAPDUType { + + @XmlValue + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] value; + @XmlAttribute(required = true) + @XmlSchemaType(name = "positiveInteger") + protected BigInteger sequence; + @XmlAttribute(required = true) + @XmlSchemaType(name = "positiveInteger") + protected BigInteger of; + @XmlAttribute + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] expectedSW; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the sequence property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getSequence() { + return sequence; + } + + /** + * Sets the value of the sequence property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setSequence(BigInteger value) { + this.sequence = value; + } + + /** + * Gets the value of the of property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getOf() { + return of; + } + + /** + * Sets the value of the of property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setOf(BigInteger value) { + this.of = value; + } + + /** + * Gets the value of the expectedSW property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getExpectedSW() { + return expectedSW; + } + + /** + * Sets the value of the expectedSW property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setExpectedSW(byte[] value) { + this.expectedSW = ((byte[]) value); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java new file mode 100644 index 00000000..7738bfdd --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java @@ -0,0 +1,170 @@ + +package at.gv.egiz.stal.cardchannel; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the at.gv.egiz.stal.cardchannel package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _Grunddaten_QNAME = new QName("", "Grunddaten"); + private final static QName _Script_QNAME = new QName("", "Script"); + private final static QName _Response_QNAME = new QName("", "Response"); + private final static QName _SVPersonenbindung_QNAME = new QName("", "SV-Personenbindung"); + private final static QName _Status_QNAME = new QName("", "Status"); + private final static QName _EHIC_QNAME = new QName("", "EHIC"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: at.gv.egiz.stal.cardchannel + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link VerifyAPDUType } + * + */ + public VerifyAPDUType createVerifyAPDUType() { + return new VerifyAPDUType(); + } + + /** + * Create an instance of {@link ResponseType } + * + */ + public ResponseType createResponseType() { + return new ResponseType(); + } + + /** + * Create an instance of {@link ResponseAPDUType } + * + */ + public ResponseAPDUType createResponseAPDUType() { + return new ResponseAPDUType(); + } + + /** + * Create an instance of {@link CommandAPDUType } + * + */ + public CommandAPDUType createCommandAPDUType() { + return new CommandAPDUType(); + } + + /** + * Create an instance of {@link ATRType } + * + */ + public ATRType createATRType() { + return new ATRType(); + } + + /** + * Create an instance of {@link ScriptType } + * + */ + public ScriptType createScriptType() { + return new ScriptType(); + } + + /** + * Create an instance of {@link ResetType } + * + */ + public ResetType createResetType() { + return new ResetType(); + } + + /** + * Create an instance of {@link AttributeType } + * + */ + public AttributeType createAttributeType() { + return new AttributeType(); + } + + /** + * Create an instance of {@link AttributeList } + * + */ + public AttributeList createAttributeList() { + return new AttributeList(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "Grunddaten") + public JAXBElement createGrunddaten(AttributeList value) { + return new JAXBElement(_Grunddaten_QNAME, AttributeList.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ScriptType }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "Script") + public JAXBElement createScript(ScriptType value) { + return new JAXBElement(_Script_QNAME, ScriptType.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ResponseType }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "Response") + public JAXBElement createResponse(ResponseType value) { + return new JAXBElement(_Response_QNAME, ResponseType.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link byte[]}{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "SV-Personenbindung") + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + public JAXBElement createSVPersonenbindung(byte[] value) { + return new JAXBElement(_SVPersonenbindung_QNAME, byte[].class, null, ((byte[]) value)); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "Status") + public JAXBElement createStatus(AttributeList value) { + return new JAXBElement(_Status_QNAME, AttributeList.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} + * + */ + @XmlElementDecl(namespace = "", name = "EHIC") + public JAXBElement createEHIC(AttributeList value) { + return new JAXBElement(_EHIC_QNAME, AttributeList.class, null, value); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java new file mode 100644 index 00000000..9918473e --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java @@ -0,0 +1,64 @@ + +package at.gv.egiz.stal.cardchannel; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + + +/** + * Reset the icc and sequence counter + * + *

Java class for ResetType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ResetType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <attribute name="cold" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ResetType") +public class ResetType { + + @XmlAttribute + protected Boolean cold; + + /** + * Gets the value of the cold property. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public boolean isCold() { + if (cold == null) { + return true; + } else { + return cold; + } + } + + /** + * Sets the value of the cold property. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setCold(Boolean value) { + this.cold = value; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java new file mode 100644 index 00000000..1e7b19d5 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java @@ -0,0 +1,161 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + * Contains a sequence of bytes received from the card as response + * APDU + * + *

Java class for ResponseAPDUType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ResponseAPDUType">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
+ *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
+ *       <attribute name="rc" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
+ *       <attribute name="sw" type="{http://www.w3.org/2001/XMLSchema}hexBinary" default="9000" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ResponseAPDUType", propOrder = { + "value" +}) +public class ResponseAPDUType { + + @XmlValue + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] value; + @XmlAttribute(required = true) + @XmlSchemaType(name = "positiveInteger") + protected BigInteger sequence; + @XmlAttribute + protected BigInteger rc; + @XmlAttribute + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] sw; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the sequence property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getSequence() { + return sequence; + } + + /** + * Sets the value of the sequence property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setSequence(BigInteger value) { + this.sequence = value; + } + + /** + * Gets the value of the rc property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getRc() { + if (rc == null) { + return new BigInteger("0"); + } else { + return rc; + } + } + + /** + * Sets the value of the rc property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setRc(BigInteger value) { + this.rc = value; + } + + /** + * Gets the value of the sw property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getSw() { + if (sw == null) { + return new HexBinaryAdapter().unmarshal("9000"); + } else { + return sw; + } + } + + /** + * Sets the value of the sw property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSw(byte[] value) { + this.sw = ((byte[]) value); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java new file mode 100644 index 00000000..ee25550f --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java @@ -0,0 +1,78 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlType; + + +/** + * Contains the result of the script executed by the + * BKU + * + *

Java class for ResponseType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ResponseType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice maxOccurs="unbounded">
+ *         <element name="ATR" type="{}ATRType"/>
+ *         <element name="ResponseAPDU" type="{}ResponseAPDUType"/>
+ *       </choice>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ResponseType", propOrder = { + "atrOrResponseAPDU" +}) +public class ResponseType { + + @XmlElements({ + @XmlElement(name = "ATR", type = ATRType.class), + @XmlElement(name = "ResponseAPDU", type = ResponseAPDUType.class) + }) + protected List atrOrResponseAPDU; + + /** + * Gets the value of the atrOrResponseAPDU property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the atrOrResponseAPDU property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getATROrResponseAPDU().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ATRType } + * {@link ResponseAPDUType } + * + * + */ + public List getATROrResponseAPDU() { + if (atrOrResponseAPDU == null) { + atrOrResponseAPDU = new ArrayList(); + } + return this.atrOrResponseAPDU; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java new file mode 100644 index 00000000..326791e3 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java @@ -0,0 +1,80 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlType; + + +/** + * Contains the script to be executed by the BKU + * + *

Java class for ScriptType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ScriptType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <choice maxOccurs="unbounded">
+ *         <element name="Reset" type="{}ResetType"/>
+ *         <element name="CommandAPDU" type="{}CommandAPDUType"/>
+ *         <element name="VerifyAPDU" type="{}VerifyAPDUType"/>
+ *       </choice>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ScriptType", propOrder = { + "resetOrCommandAPDUOrVerifyAPDU" +}) +public class ScriptType { + + @XmlElements({ + @XmlElement(name = "CommandAPDU", type = CommandAPDUType.class), + @XmlElement(name = "VerifyAPDU", type = VerifyAPDUType.class), + @XmlElement(name = "Reset", type = ResetType.class) + }) + protected List resetOrCommandAPDUOrVerifyAPDU; + + /** + * Gets the value of the resetOrCommandAPDUOrVerifyAPDU property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the resetOrCommandAPDUOrVerifyAPDU property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getResetOrCommandAPDUOrVerifyAPDU().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link CommandAPDUType } + * {@link VerifyAPDUType } + * {@link ResetType } + * + * + */ + public List getResetOrCommandAPDUOrVerifyAPDU() { + if (resetOrCommandAPDUOrVerifyAPDU == null) { + resetOrCommandAPDUOrVerifyAPDU = new ArrayList(); + } + return this.resetOrCommandAPDUOrVerifyAPDU; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java new file mode 100644 index 00000000..d5f1dba0 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java @@ -0,0 +1,266 @@ + +package at.gv.egiz.stal.cardchannel; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import javax.xml.bind.annotation.adapters.HexBinaryAdapter; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + + +/** + * Contains a sequence of bytes send as command APDU to the icc after a + * PIN entered by the user has been incorporated into the APDU + * + *

Java class for VerifyAPDUType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="VerifyAPDUType">
+ *   <simpleContent>
+ *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
+ *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
+ *       <attribute name="of" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
+ *       <attribute name="expectedSW" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
+ *       <attribute name="message" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *       <attribute name="format" use="required" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
+ *       <attribute name="offset" use="required" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" />
+ *       <attribute name="timeout" use="required" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" />
+ *     </extension>
+ *   </simpleContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "VerifyAPDUType", propOrder = { + "value" +}) +public class VerifyAPDUType { + + @XmlValue + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] value; + @XmlAttribute(required = true) + @XmlSchemaType(name = "positiveInteger") + protected BigInteger sequence; + @XmlAttribute(required = true) + @XmlSchemaType(name = "positiveInteger") + protected BigInteger of; + @XmlAttribute + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] expectedSW; + @XmlAttribute(required = true) + protected String message; + @XmlAttribute(required = true) + @XmlJavaTypeAdapter(HexBinaryAdapter.class) + @XmlSchemaType(name = "hexBinary") + protected byte[] format; + @XmlAttribute(required = true) + @XmlSchemaType(name = "nonNegativeInteger") + protected BigInteger offset; + @XmlAttribute(required = true) + @XmlSchemaType(name = "nonNegativeInteger") + protected BigInteger timeout; + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(byte[] value) { + this.value = ((byte[]) value); + } + + /** + * Gets the value of the sequence property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getSequence() { + return sequence; + } + + /** + * Sets the value of the sequence property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setSequence(BigInteger value) { + this.sequence = value; + } + + /** + * Gets the value of the of property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getOf() { + return of; + } + + /** + * Sets the value of the of property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setOf(BigInteger value) { + this.of = value; + } + + /** + * Gets the value of the expectedSW property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getExpectedSW() { + return expectedSW; + } + + /** + * Sets the value of the expectedSW property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setExpectedSW(byte[] value) { + this.expectedSW = ((byte[]) value); + } + + /** + * Gets the value of the message property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getMessage() { + return message; + } + + /** + * Sets the value of the message property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setMessage(String value) { + this.message = value; + } + + /** + * Gets the value of the format property. + * + * @return + * possible object is + * {@link String } + * + */ + public byte[] getFormat() { + return format; + } + + /** + * Sets the value of the format property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFormat(byte[] value) { + this.format = ((byte[]) value); + } + + /** + * Gets the value of the offset property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getOffset() { + return offset; + } + + /** + * Sets the value of the offset property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setOffset(BigInteger value) { + this.offset = value; + } + + /** + * Gets the value of the timeout property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getTimeout() { + return timeout; + } + + /** + * Sets the value of the timeout property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setTimeout(BigInteger value) { + this.timeout = value; + } + +} -- cgit v1.2.3 From ebe9877959d6994cf1dbd9b943a7d5115e03318a Mon Sep 17 00:00:00 2001 From: clemenso Date: Mon, 1 Dec 2008 13:37:35 +0000 Subject: CardChannel schema git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@229 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/stal/cardchannel/ATRType.java | 100 -------- .../at/gv/egiz/stal/cardchannel/AttributeList.java | 71 ------ .../at/gv/egiz/stal/cardchannel/AttributeType.java | 264 -------------------- .../gv/egiz/stal/cardchannel/CommandAPDUType.java | 154 ------------ .../at/gv/egiz/stal/cardchannel/ObjectFactory.java | 170 ------------- .../at/gv/egiz/stal/cardchannel/ResetType.java | 64 ----- .../gv/egiz/stal/cardchannel/ResponseAPDUType.java | 161 ------------- .../at/gv/egiz/stal/cardchannel/ResponseType.java | 78 ------ .../at/gv/egiz/stal/cardchannel/ScriptType.java | 80 ------- .../gv/egiz/stal/cardchannel/VerifyAPDUType.java | 266 --------------------- 10 files changed, 1408 deletions(-) delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java delete mode 100644 utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java deleted file mode 100644 index d9f2b8a7..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ATRType.java +++ /dev/null @@ -1,100 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.math.BigInteger; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - * Contains the ATR received as reponse to a Reset - * command - * - *

Java class for ATRType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ATRType">
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
- *       <attribute name="rc" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ATRType", propOrder = { - "value" -}) -public class ATRType { - - @XmlValue - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] value; - @XmlAttribute - protected BigInteger rc; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(byte[] value) { - this.value = ((byte[]) value); - } - - /** - * Gets the value of the rc property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getRc() { - if (rc == null) { - return new BigInteger("0"); - } else { - return rc; - } - } - - /** - * Sets the value of the rc property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setRc(BigInteger value) { - this.rc = value; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java deleted file mode 100644 index da0ac66c..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeList.java +++ /dev/null @@ -1,71 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlType; - - -/** - * Contains a list of attributes - * - *

Java class for AttributeList complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="AttributeList">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="Attribute" type="{}AttributeType" maxOccurs="unbounded" minOccurs="0"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "AttributeList", propOrder = { - "attribute" -}) -public class AttributeList { - - @XmlElement(name = "Attribute") - protected List attribute; - - /** - * Gets the value of the attribute property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the attribute property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getAttribute().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link AttributeType } - * - * - */ - public List getAttribute() { - if (attribute == null) { - attribute = new ArrayList(); - } - return this.attribute; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java deleted file mode 100644 index 3666c92b..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/AttributeType.java +++ /dev/null @@ -1,264 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.math.BigInteger; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.datatype.XMLGregorianCalendar; - - -/** - * Contains an attribute converted from ASN.1 - * - *

Java class for AttributeType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="AttributeType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element name="Integer" type="{http://www.w3.org/2001/XMLSchema}integer" minOccurs="0"/>
- *         <element name="Latin1String" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *         <element name="UTF8String" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *         <element name="NumericString" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *         <element name="PrintableString" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *         <element name="GeneralizedTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
- *         <element name="Date" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
- *       </sequence>
- *       <attribute name="oid" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "AttributeType", propOrder = { - "integer", - "latin1String", - "utf8String", - "numericString", - "printableString", - "generalizedTime", - "date" -}) -public class AttributeType { - - @XmlElement(name = "Integer") - protected BigInteger integer; - @XmlElement(name = "Latin1String") - protected String latin1String; - @XmlElement(name = "UTF8String") - protected String utf8String; - @XmlElement(name = "NumericString") - protected String numericString; - @XmlElement(name = "PrintableString") - protected String printableString; - @XmlElement(name = "GeneralizedTime") - @XmlSchemaType(name = "dateTime") - protected XMLGregorianCalendar generalizedTime; - @XmlElement(name = "Date") - protected String date; - @XmlAttribute(required = true) - protected String oid; - - /** - * Gets the value of the integer property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getInteger() { - return integer; - } - - /** - * Sets the value of the integer property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setInteger(BigInteger value) { - this.integer = value; - } - - /** - * Gets the value of the latin1String property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getLatin1String() { - return latin1String; - } - - /** - * Sets the value of the latin1String property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setLatin1String(String value) { - this.latin1String = value; - } - - /** - * Gets the value of the utf8String property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUTF8String() { - return utf8String; - } - - /** - * Sets the value of the utf8String property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUTF8String(String value) { - this.utf8String = value; - } - - /** - * Gets the value of the numericString property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getNumericString() { - return numericString; - } - - /** - * Sets the value of the numericString property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setNumericString(String value) { - this.numericString = value; - } - - /** - * Gets the value of the printableString property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getPrintableString() { - return printableString; - } - - /** - * Sets the value of the printableString property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setPrintableString(String value) { - this.printableString = value; - } - - /** - * Gets the value of the generalizedTime property. - * - * @return - * possible object is - * {@link XMLGregorianCalendar } - * - */ - public XMLGregorianCalendar getGeneralizedTime() { - return generalizedTime; - } - - /** - * Sets the value of the generalizedTime property. - * - * @param value - * allowed object is - * {@link XMLGregorianCalendar } - * - */ - public void setGeneralizedTime(XMLGregorianCalendar value) { - this.generalizedTime = value; - } - - /** - * Gets the value of the date property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDate() { - return date; - } - - /** - * Sets the value of the date property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDate(String value) { - this.date = value; - } - - /** - * Gets the value of the oid property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getOid() { - return oid; - } - - /** - * Sets the value of the oid property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setOid(String value) { - this.oid = value; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java deleted file mode 100644 index d835ef11..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/CommandAPDUType.java +++ /dev/null @@ -1,154 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.math.BigInteger; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - * Contains a sequence of bytes send as command APDU to the - * icc - * - *

Java class for CommandAPDUType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="CommandAPDUType">
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
- *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
- *       <attribute name="of" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
- *       <attribute name="expectedSW" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "CommandAPDUType", propOrder = { - "value" -}) -public class CommandAPDUType { - - @XmlValue - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] value; - @XmlAttribute(required = true) - @XmlSchemaType(name = "positiveInteger") - protected BigInteger sequence; - @XmlAttribute(required = true) - @XmlSchemaType(name = "positiveInteger") - protected BigInteger of; - @XmlAttribute - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] expectedSW; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(byte[] value) { - this.value = ((byte[]) value); - } - - /** - * Gets the value of the sequence property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getSequence() { - return sequence; - } - - /** - * Sets the value of the sequence property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setSequence(BigInteger value) { - this.sequence = value; - } - - /** - * Gets the value of the of property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getOf() { - return of; - } - - /** - * Sets the value of the of property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setOf(BigInteger value) { - this.of = value; - } - - /** - * Gets the value of the expectedSW property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getExpectedSW() { - return expectedSW; - } - - /** - * Sets the value of the expectedSW property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setExpectedSW(byte[] value) { - this.expectedSW = ((byte[]) value); - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java deleted file mode 100644 index 7738bfdd..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ObjectFactory.java +++ /dev/null @@ -1,170 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the at.gv.egiz.stal.cardchannel package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Grunddaten_QNAME = new QName("", "Grunddaten"); - private final static QName _Script_QNAME = new QName("", "Script"); - private final static QName _Response_QNAME = new QName("", "Response"); - private final static QName _SVPersonenbindung_QNAME = new QName("", "SV-Personenbindung"); - private final static QName _Status_QNAME = new QName("", "Status"); - private final static QName _EHIC_QNAME = new QName("", "EHIC"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: at.gv.egiz.stal.cardchannel - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link VerifyAPDUType } - * - */ - public VerifyAPDUType createVerifyAPDUType() { - return new VerifyAPDUType(); - } - - /** - * Create an instance of {@link ResponseType } - * - */ - public ResponseType createResponseType() { - return new ResponseType(); - } - - /** - * Create an instance of {@link ResponseAPDUType } - * - */ - public ResponseAPDUType createResponseAPDUType() { - return new ResponseAPDUType(); - } - - /** - * Create an instance of {@link CommandAPDUType } - * - */ - public CommandAPDUType createCommandAPDUType() { - return new CommandAPDUType(); - } - - /** - * Create an instance of {@link ATRType } - * - */ - public ATRType createATRType() { - return new ATRType(); - } - - /** - * Create an instance of {@link ScriptType } - * - */ - public ScriptType createScriptType() { - return new ScriptType(); - } - - /** - * Create an instance of {@link ResetType } - * - */ - public ResetType createResetType() { - return new ResetType(); - } - - /** - * Create an instance of {@link AttributeType } - * - */ - public AttributeType createAttributeType() { - return new AttributeType(); - } - - /** - * Create an instance of {@link AttributeList } - * - */ - public AttributeList createAttributeList() { - return new AttributeList(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "Grunddaten") - public JAXBElement createGrunddaten(AttributeList value) { - return new JAXBElement(_Grunddaten_QNAME, AttributeList.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link ScriptType }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "Script") - public JAXBElement createScript(ScriptType value) { - return new JAXBElement(_Script_QNAME, ScriptType.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link ResponseType }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "Response") - public JAXBElement createResponse(ResponseType value) { - return new JAXBElement(_Response_QNAME, ResponseType.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link byte[]}{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "SV-Personenbindung") - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - public JAXBElement createSVPersonenbindung(byte[] value) { - return new JAXBElement(_SVPersonenbindung_QNAME, byte[].class, null, ((byte[]) value)); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "Status") - public JAXBElement createStatus(AttributeList value) { - return new JAXBElement(_Status_QNAME, AttributeList.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link AttributeList }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "EHIC") - public JAXBElement createEHIC(AttributeList value) { - return new JAXBElement(_EHIC_QNAME, AttributeList.class, null, value); - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java deleted file mode 100644 index 9918473e..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResetType.java +++ /dev/null @@ -1,64 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlType; - - -/** - * Reset the icc and sequence counter - * - *

Java class for ResetType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ResetType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="cold" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ResetType") -public class ResetType { - - @XmlAttribute - protected Boolean cold; - - /** - * Gets the value of the cold property. - * - * @return - * possible object is - * {@link Boolean } - * - */ - public boolean isCold() { - if (cold == null) { - return true; - } else { - return cold; - } - } - - /** - * Sets the value of the cold property. - * - * @param value - * allowed object is - * {@link Boolean } - * - */ - public void setCold(Boolean value) { - this.cold = value; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java deleted file mode 100644 index 1e7b19d5..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseAPDUType.java +++ /dev/null @@ -1,161 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.math.BigInteger; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - * Contains a sequence of bytes received from the card as response - * APDU - * - *

Java class for ResponseAPDUType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ResponseAPDUType">
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
- *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
- *       <attribute name="rc" type="{http://www.w3.org/2001/XMLSchema}integer" default="0" />
- *       <attribute name="sw" type="{http://www.w3.org/2001/XMLSchema}hexBinary" default="9000" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ResponseAPDUType", propOrder = { - "value" -}) -public class ResponseAPDUType { - - @XmlValue - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] value; - @XmlAttribute(required = true) - @XmlSchemaType(name = "positiveInteger") - protected BigInteger sequence; - @XmlAttribute - protected BigInteger rc; - @XmlAttribute - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] sw; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(byte[] value) { - this.value = ((byte[]) value); - } - - /** - * Gets the value of the sequence property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getSequence() { - return sequence; - } - - /** - * Sets the value of the sequence property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setSequence(BigInteger value) { - this.sequence = value; - } - - /** - * Gets the value of the rc property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getRc() { - if (rc == null) { - return new BigInteger("0"); - } else { - return rc; - } - } - - /** - * Sets the value of the rc property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setRc(BigInteger value) { - this.rc = value; - } - - /** - * Gets the value of the sw property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getSw() { - if (sw == null) { - return new HexBinaryAdapter().unmarshal("9000"); - } else { - return sw; - } - } - - /** - * Sets the value of the sw property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setSw(byte[] value) { - this.sw = ((byte[]) value); - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java deleted file mode 100644 index ee25550f..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ResponseType.java +++ /dev/null @@ -1,78 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlType; - - -/** - * Contains the result of the script executed by the - * BKU - * - *

Java class for ResponseType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ResponseType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <choice maxOccurs="unbounded">
- *         <element name="ATR" type="{}ATRType"/>
- *         <element name="ResponseAPDU" type="{}ResponseAPDUType"/>
- *       </choice>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ResponseType", propOrder = { - "atrOrResponseAPDU" -}) -public class ResponseType { - - @XmlElements({ - @XmlElement(name = "ATR", type = ATRType.class), - @XmlElement(name = "ResponseAPDU", type = ResponseAPDUType.class) - }) - protected List atrOrResponseAPDU; - - /** - * Gets the value of the atrOrResponseAPDU property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the atrOrResponseAPDU property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getATROrResponseAPDU().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link ATRType } - * {@link ResponseAPDUType } - * - * - */ - public List getATROrResponseAPDU() { - if (atrOrResponseAPDU == null) { - atrOrResponseAPDU = new ArrayList(); - } - return this.atrOrResponseAPDU; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java deleted file mode 100644 index 326791e3..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/ScriptType.java +++ /dev/null @@ -1,80 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlElements; -import javax.xml.bind.annotation.XmlType; - - -/** - * Contains the script to be executed by the BKU - * - *

Java class for ScriptType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="ScriptType">
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <choice maxOccurs="unbounded">
- *         <element name="Reset" type="{}ResetType"/>
- *         <element name="CommandAPDU" type="{}CommandAPDUType"/>
- *         <element name="VerifyAPDU" type="{}VerifyAPDUType"/>
- *       </choice>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "ScriptType", propOrder = { - "resetOrCommandAPDUOrVerifyAPDU" -}) -public class ScriptType { - - @XmlElements({ - @XmlElement(name = "CommandAPDU", type = CommandAPDUType.class), - @XmlElement(name = "VerifyAPDU", type = VerifyAPDUType.class), - @XmlElement(name = "Reset", type = ResetType.class) - }) - protected List resetOrCommandAPDUOrVerifyAPDU; - - /** - * Gets the value of the resetOrCommandAPDUOrVerifyAPDU property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the resetOrCommandAPDUOrVerifyAPDU property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getResetOrCommandAPDUOrVerifyAPDU().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link CommandAPDUType } - * {@link VerifyAPDUType } - * {@link ResetType } - * - * - */ - public List getResetOrCommandAPDUOrVerifyAPDU() { - if (resetOrCommandAPDUOrVerifyAPDU == null) { - resetOrCommandAPDUOrVerifyAPDU = new ArrayList(); - } - return this.resetOrCommandAPDUOrVerifyAPDU; - } - -} diff --git a/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java b/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java deleted file mode 100644 index d5f1dba0..00000000 --- a/utils/src/main/java/at/gv/egiz/stal/cardchannel/VerifyAPDUType.java +++ /dev/null @@ -1,266 +0,0 @@ - -package at.gv.egiz.stal.cardchannel; - -import java.math.BigInteger; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.HexBinaryAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - * Contains a sequence of bytes send as command APDU to the icc after a - * PIN entered by the user has been incorporated into the APDU - * - *

Java class for VerifyAPDUType complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType name="VerifyAPDUType">
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>hexBinary">
- *       <attribute name="sequence" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
- *       <attribute name="of" use="required" type="{http://www.w3.org/2001/XMLSchema}positiveInteger" />
- *       <attribute name="expectedSW" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
- *       <attribute name="message" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
- *       <attribute name="format" use="required" type="{http://www.w3.org/2001/XMLSchema}hexBinary" />
- *       <attribute name="offset" use="required" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" />
- *       <attribute name="timeout" use="required" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "VerifyAPDUType", propOrder = { - "value" -}) -public class VerifyAPDUType { - - @XmlValue - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] value; - @XmlAttribute(required = true) - @XmlSchemaType(name = "positiveInteger") - protected BigInteger sequence; - @XmlAttribute(required = true) - @XmlSchemaType(name = "positiveInteger") - protected BigInteger of; - @XmlAttribute - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] expectedSW; - @XmlAttribute(required = true) - protected String message; - @XmlAttribute(required = true) - @XmlJavaTypeAdapter(HexBinaryAdapter.class) - @XmlSchemaType(name = "hexBinary") - protected byte[] format; - @XmlAttribute(required = true) - @XmlSchemaType(name = "nonNegativeInteger") - protected BigInteger offset; - @XmlAttribute(required = true) - @XmlSchemaType(name = "nonNegativeInteger") - protected BigInteger timeout; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setValue(byte[] value) { - this.value = ((byte[]) value); - } - - /** - * Gets the value of the sequence property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getSequence() { - return sequence; - } - - /** - * Sets the value of the sequence property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setSequence(BigInteger value) { - this.sequence = value; - } - - /** - * Gets the value of the of property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getOf() { - return of; - } - - /** - * Sets the value of the of property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setOf(BigInteger value) { - this.of = value; - } - - /** - * Gets the value of the expectedSW property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getExpectedSW() { - return expectedSW; - } - - /** - * Sets the value of the expectedSW property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setExpectedSW(byte[] value) { - this.expectedSW = ((byte[]) value); - } - - /** - * Gets the value of the message property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getMessage() { - return message; - } - - /** - * Sets the value of the message property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setMessage(String value) { - this.message = value; - } - - /** - * Gets the value of the format property. - * - * @return - * possible object is - * {@link String } - * - */ - public byte[] getFormat() { - return format; - } - - /** - * Sets the value of the format property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFormat(byte[] value) { - this.format = ((byte[]) value); - } - - /** - * Gets the value of the offset property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getOffset() { - return offset; - } - - /** - * Sets the value of the offset property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setOffset(BigInteger value) { - this.offset = value; - } - - /** - * Gets the value of the timeout property. - * - * @return - * possible object is - * {@link BigInteger } - * - */ - public BigInteger getTimeout() { - return timeout; - } - - /** - * Sets the value of the timeout property. - * - * @param value - * allowed object is - * {@link BigInteger } - * - */ - public void setTimeout(BigInteger value) { - this.timeout = value; - } - -} -- cgit v1.2.3 From 2df9621154ad057f6cace73efe49c9ef42515fde Mon Sep 17 00:00:00 2001 From: mcentner Date: Tue, 9 Dec 2008 08:14:43 +0000 Subject: Refactored STAL interface. Additional infobox functionality. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@236 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/bku/local/stal/LocalBKUWorker.java | 4 +- .../src/main/webapp/WEB-INF/applicationContext.xml | 9 +- .../stal/service/impl/STALRequestBrokerImpl.java | 2 +- STAL/src/main/java/at/gv/egiz/stal/STAL.java | 2 +- .../gv/egiz/bku/slcommands/SLCommandFactory.java | 38 +++- .../slcommands/impl/AbstractBinaryFileInfobox.java | 4 +- .../impl/AbstractInfoboxCommandImpl.java | 9 + .../bku/slcommands/impl/AbstractInfoboxImpl.java | 19 ++ .../slcommands/impl/CardChannelInfoboxImpl.java | 235 +++++++++++++++++++++ .../at/gv/egiz/bku/slcommands/impl/Infobox.java | 21 +- .../slcommands/impl/InfoboxReadCommandImpl.java | 9 - .../bku/slcommands/impl/InfoboxReadResultImpl.java | 12 ++ .../slcommands/impl/InfoboxUpdateCommandImpl.java | 124 ++--------- .../gv/egiz/bku/slcommands/impl/SLResultImpl.java | 56 +++++ .../at/gv/egiz/bku/slcommands/impl/STALHelper.java | 2 +- .../test/java/at/gv/egiz/stal/dummy/DummySTAL.java | 2 +- .../at/gv/egiz/smcc/AbstractSignatureCard.java | 30 ++- smcc/src/main/java/at/gv/egiz/smcc/SWCard.java | 12 +- .../main/java/at/gv/egiz/smcc/SignatureCard.java | 12 +- .../java/at/gv/egiz/smcc/SignatureCardFactory.java | 8 +- .../main/java/at/gv/egiz/smcc/util/SMCCHelper.java | 4 +- .../java/at/gv/egiz/smcc/util/SmartCardIO.java | 9 +- .../at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java | 2 +- .../java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java | 15 +- .../at/gv/egiz/bku/utils/DebugOutputStream.java | 48 +++++ .../java/at/gv/egiz/bku/utils/DebugReader.java | 58 +++++ .../java/at/gv/egiz/bku/utils/DebugWriter.java | 55 +++++ 27 files changed, 657 insertions(+), 144 deletions(-) create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/DebugOutputStream.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/DebugReader.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/DebugWriter.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java index 57b159ad..91d0aba0 100644 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java +++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java @@ -22,6 +22,8 @@ import at.gv.egiz.stal.QuitRequest; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; +import at.gv.egiz.stal.ext.APDUScriptRequest; + import java.util.List; import javax.swing.JDialog; @@ -40,7 +42,7 @@ public class LocalBKUWorker extends AbstractBKUWorker { } @Override - public List handleRequest(List requestList) { + public List handleRequest(List requestList) { signatureCard = null; List responses = super.handleRequest(requestList); // container.setVisible(false); diff --git a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml index 5ac12ece..eb7d5b7a 100644 --- a/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml +++ b/BKULocal/src/main/webapp/WEB-INF/applicationContext.xml @@ -59,6 +59,9 @@ + @@ -76,9 +79,9 @@ - - - + diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java index e7fb928a..5e3a1a99 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java @@ -85,7 +85,7 @@ public class STALRequestBrokerImpl implements STALRequestBroker { * @pre requests: either single SignRequest, QuitRequest or multiple ReadInfoboxRequests */ @Override - public List handleRequest(List stalRequests) { + public List handleRequest(List stalRequests) { if (interrupted) { return null; } diff --git a/STAL/src/main/java/at/gv/egiz/stal/STAL.java b/STAL/src/main/java/at/gv/egiz/stal/STAL.java index de29de9a..7fa7cb45 100644 --- a/STAL/src/main/java/at/gv/egiz/stal/STAL.java +++ b/STAL/src/main/java/at/gv/egiz/stal/STAL.java @@ -32,7 +32,7 @@ public interface STAL { * @param aRequestList * @return */ - public List handleRequest(List aRequestList); + public List handleRequest(List aRequestList); /** * Sets the preferred locale for userinteraction (e.g. PIN dialogs). diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java index 9c98ef8a..bec2b253 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java @@ -17,6 +17,7 @@ package at.gv.egiz.bku.slcommands; import java.io.IOException; +import java.io.Reader; import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -41,10 +42,12 @@ import org.apache.commons.logging.LogFactory; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import at.buergerkarte.namespaces.cardchannel.ObjectFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLExceptionMessages; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.DebugReader; import at.gv.egiz.slbinding.RedirectEventFilter; import at.gv.egiz.slbinding.RedirectUnmarshallerListener; @@ -163,8 +166,9 @@ public class SLCommandFactory { if (jaxbContext == null) { try { String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName(); - String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); - setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg)); + String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); + String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); + setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg)); } catch (JAXBException e) { log.error("Failed to setup JAXBContext security layer request.", e); throw new SLRuntimeException(e); @@ -325,12 +329,31 @@ public class SLCommandFactory { */ @SuppressWarnings("unchecked") public SLCommand createSLCommand(Source source, SLCommandContext context) - throws SLCommandException, SLRuntimeException, SLRequestException { + throws SLCommandException, SLRuntimeException, SLRequestException { + + DebugReader dr = null; + if (log.isTraceEnabled() && source instanceof StreamSource) { + StreamSource streamSource = (StreamSource) source; + if (streamSource.getReader() != null) { + dr = new DebugReader(streamSource.getReader(), "SLCommand unmarshalled from:\n"); + streamSource.setReader(dr); + } + } - Object object = unmarshal(source); + Object object; + try { + object = unmarshal(source); + } catch (SLRequestException e) { + throw e; + } finally { + if (dr != null) { + log.trace(dr.getCachedString()); + } + } + if (!(object instanceof JAXBElement)) { // invalid request - log.info("Invalid security layer request. " + object.toString()); + log.info("Invalid security layer request. " + object.toString()); throw new SLRequestException(3002, SLExceptionMessages.EC3002_INVALID, new Object[]{object.toString()}); } @@ -343,7 +366,9 @@ public class SLCommandFactory { throw new SLCommandException(4011, SLExceptionMessages.EC4011_NOTIMPLEMENTED, new Object[]{qName.toString()}); } - + + + // try to instantiate SLCommand slCommand; try { @@ -360,6 +385,7 @@ public class SLCommandFactory { e); throw new SLRuntimeException(e); } + slCommand.init(context, (JAXBElement) object); return slCommand; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java index 07ca639c..23394bd5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.java @@ -37,7 +37,7 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl /** * Is this infobox' content an XML entity? */ - private boolean isXMLEntity = false; + protected boolean isXMLEntity = false; /** * @return true if this infobox' content is an XML entity or false otherwise. @@ -61,8 +61,6 @@ public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl impl } } - - } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java index 305769a8..8a7edb71 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.java @@ -52,4 +52,13 @@ public abstract class AbstractInfoboxCommandImpl extends SLCommandImpl { */ protected abstract String getInfoboxIdentifier(T request); + + public String getInfoboxIdentifier() { + if (infobox != null) { + return infobox.getIdentifier(); + } else { + return null; + } + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxImpl.java index e5c7afcc..564cb8ff 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxImpl.java @@ -16,6 +16,13 @@ */ package at.gv.egiz.bku.slcommands.impl; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateRequestType; +import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.InfoboxUpdateResult; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; + /** * An abstract base class for {@link Infobox} implementations. * @@ -23,4 +30,16 @@ package at.gv.egiz.bku.slcommands.impl; */ public abstract class AbstractInfoboxImpl implements Infobox { + @Override + public InfoboxReadResult read(InfoboxReadRequestType request, + SLCommandContext cmdCtx) throws SLCommandException { + throw new SLCommandException(4011); + } + + @Override + public InfoboxUpdateResult update(InfoboxUpdateRequestType request, + SLCommandContext cmdCtx) throws SLCommandException { + throw new SLCommandException(4011); + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java new file mode 100644 index 00000000..4b1cc779 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CardChannelInfoboxImpl.java @@ -0,0 +1,235 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.slcommands.impl; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.WeakHashMap; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.buergerkarte.namespaces.cardchannel.ATRType; +import at.buergerkarte.namespaces.cardchannel.CommandAPDUType; +import at.buergerkarte.namespaces.cardchannel.ObjectFactory; +import at.buergerkarte.namespaces.cardchannel.ResetType; +import at.buergerkarte.namespaces.cardchannel.ResponseAPDUType; +import at.buergerkarte.namespaces.cardchannel.ResponseType; +import at.buergerkarte.namespaces.cardchannel.ScriptType; +import at.buergerkarte.namespaces.cardchannel.VerifyAPDUType; +import at.buergerkarte.namespaces.securitylayer._1.Base64XMLContentType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateRequestType; +import at.buergerkarte.namespaces.securitylayer._1.XMLContentType; +import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.InfoboxUpdateResult; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.stal.STAL; +import at.gv.egiz.stal.ext.APDUScriptRequest; +import at.gv.egiz.stal.ext.APDUScriptResponse; +import at.gv.egiz.stal.ext.APDUScriptRequest.RequestScriptElement; +import at.gv.egiz.stal.ext.APDUScriptResponse.ResponseScriptElement; + +public class CardChannelInfoboxImpl extends AbstractBinaryFileInfobox { + + private static Log log = LogFactory.getLog(CardChannelInfoboxImpl.class); + + private static WeakHashMap> scriptResults = new WeakHashMap>(); + + private static JAXBContext jaxbContext; + + static { + try { + jaxbContext = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName()); + } catch (JAXBException e) { + throw new SLRuntimeException("Failed to initalize CardChannel infobox.", e); + } + } + + public CardChannelInfoboxImpl() { + isXMLEntity = true; + } + + @Override + public String getIdentifier() { + return "CardChannel"; + } + + @Override + public InfoboxReadResult read(InfoboxReadRequestType request, + SLCommandContext cmdCtx) throws SLCommandException { + + at.buergerkarte.namespaces.securitylayer._1.ObjectFactory objectFactory + = new at.buergerkarte.namespaces.securitylayer._1.ObjectFactory(); + + Base64XMLContentType content = objectFactory.createBase64XMLContentType(); + XMLContentType xmlContent = objectFactory.createXMLContentType(); + content.setXMLContent(xmlContent); + + JAXBElement response = scriptResults.get(cmdCtx.getSTAL()); + if (response != null) { + xmlContent.getContent().add(response); + } + + return new InfoboxReadResultImpl(content); + + } + + @SuppressWarnings("unchecked") + @Override + public InfoboxUpdateResult update(InfoboxUpdateRequestType request, + SLCommandContext cmdCtx) throws SLCommandException { + + Base64XMLContentType binaryFileParameters = request.getBinaryFileParameters(); + + if (binaryFileParameters.getBase64Content() != null) { + log.info("Got Base64Content but ContentIsXMLEntity is true."); + throw new SLCommandException(4010); + } + + XMLContentType content = binaryFileParameters.getXMLContent(); + if (content instanceof at.gv.egiz.slbinding.impl.XMLContentType) { + + ByteArrayOutputStream redirectedStream = ((at.gv.egiz.slbinding.impl.XMLContentType) content).getRedirectedStream(); + if (redirectedStream != null) { + + if (log.isDebugEnabled()) { + + StringBuilder sb = new StringBuilder(); + sb.append("CardChannel script:\n"); + try { + sb.append(new String(redirectedStream.toByteArray(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + sb.append(e.getMessage()); + } + log.debug(sb.toString()); + } + + Object object; + try { + Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); + object = unmarshaller.unmarshal(new ByteArrayInputStream(redirectedStream.toByteArray())); + } catch (JAXBException e) { + log.info("Failed to parse CardChannel script.", e); + throw new SLCommandException(4011); + } + + if (object instanceof JAXBElement) { + executeCardChannelScript(((JAXBElement) object).getValue(), cmdCtx); + return new InfoboxUpdateResultImpl(); + } + + } + + + } + log.info("Infobox identifier is '" + getIdentifier() + "' but XMLContent does not contain 'Script'."); + throw new SLCommandException(4010); + + } + + protected void executeCardChannelScript(ScriptType script, + SLCommandContext cmdCtx) throws SLCommandException { + + List resetOrCommandAPDUOrVerifyAPDU = script.getResetOrCommandAPDUOrVerifyAPDU(); + List requestScript = new ArrayList(); + + for (Object element : resetOrCommandAPDUOrVerifyAPDU) { + + if (element instanceof ResetType) { + + requestScript.add(new APDUScriptRequest.Reset()); + + } else if (element instanceof CommandAPDUType) { + + CommandAPDUType commandAPDU = (CommandAPDUType) element; + int sequence = (commandAPDU.getSequence() != null) + ? commandAPDU.getSequence().intValue() + : 0; + + requestScript.add( + new APDUScriptRequest.Command( + sequence, + commandAPDU.getValue(), + commandAPDU.getExpectedSW())); + + } else if (element instanceof VerifyAPDUType) { + log.warn("CardChannel script command 'VerifyAPDU' not implemented."); + throw new SLCommandException(4011); + } + } + + APDUScriptRequest scriptRequest = new APDUScriptRequest(requestScript); + + STAL stal = cmdCtx.getSTAL(); + STALHelper helper = new STALHelper(stal); + + helper.transmitSTALRequest(Collections.singletonList(scriptRequest)); + + List responseScript = ((APDUScriptResponse) helper + .nextResponse(APDUScriptResponse.class)).getScript(); + + ObjectFactory objectFactory = new ObjectFactory(); + + ResponseType responseType = objectFactory.createResponseType(); + + + for (ResponseScriptElement element : responseScript) { + + if (element instanceof APDUScriptResponse.ATR) { + + byte[] atr = ((APDUScriptResponse.ATR) element).getAtr(); + + ATRType atrType = objectFactory.createATRType(); + atrType.setValue(atr); + atrType.setRc(BigInteger.ZERO); + responseType.getATROrResponseAPDU().add(atrType); + + } else if (element instanceof APDUScriptResponse.Response) { + + APDUScriptResponse.Response response = (APDUScriptResponse.Response) element; + + ResponseAPDUType responseAPDUType = objectFactory.createResponseAPDUType(); + responseAPDUType.setSequence(BigInteger.valueOf(response.getSequence())); +// if (response.getRc() != 0) { + responseAPDUType.setRc(BigInteger.valueOf(response.getRc())); +// } + responseAPDUType.setSw(response.getSw()); + responseAPDUType.setValue(response.getApdu()); + + responseType.getATROrResponseAPDU().add(responseAPDUType); + } + + } + + scriptResults.put(stal, objectFactory.createResponse(responseType)); + } + + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/Infobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/Infobox.java index a6f8cbb2..99d62721 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/Infobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/Infobox.java @@ -17,7 +17,9 @@ package at.gv.egiz.bku.slcommands.impl; import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateRequestType; import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.InfoboxUpdateResult; import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slexceptions.SLCommandException; @@ -44,10 +46,25 @@ public interface Infobox { * * @return the data read from this infobox as InfoboxReadResult * - * @throws SLCommandException - * if reading from this infobox fails + * @throws SLCommandException + * + * if reading from this infobox fails */ public InfoboxReadResult read(InfoboxReadRequestType request, SLCommandContext cmdCtx) throws SLCommandException; + /** + * Update data in this infobox. + * + * @param request + * the InfoboxUpdateRequest + * @param cmdCtx + * the command context + * @return a corresponding InfoboxUpdateResult + * @throws SLCommandException + * if updating this infobox fails + */ + public InfoboxUpdateResult update(InfoboxUpdateRequestType request, + SLCommandContext cmdCtx) throws SLCommandException; + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java index aaa786a6..693f444f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadCommandImpl.java @@ -83,7 +83,6 @@ public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl implements InfoboxUpdateCommand { + AbstractInfoboxCommandImpl implements InfoboxUpdateCommand { private static Log log = LogFactory.getLog(InfoboxUpdateCommandImpl.class); - public static final String INFOBOX_IDENTIFIER_CARD_CHANNEL = "CardChannel"; + @Override + public String getName() { + return "InfoboxUpdateRequest"; + } - protected String infoboxIdentifier; - - protected List cardChannelScript; - @Override - public String getInfoboxIdentifier() { - return infoboxIdentifier; + protected String getInfoboxIdentifier(InfoboxUpdateRequestType request) { + return request.getInfoboxIdentifier(); } - + @Override - public void init(SLCommandContext ctx, Object request) - throws SLCommandException { + public void init(SLCommandContext ctx, Object request) throws SLCommandException { super.init(ctx, request); InfoboxUpdateRequestType req = getRequestValue(); - infoboxIdentifier = req.getInfoboxIdentifier(); + if (req.getAssocArrayParameters() != null && + !(infobox instanceof AssocArrayInfobox)) { + log.info("Got AssocArrayParameters but Infobox type is not AssocArray."); + throw new SLCommandException(4010); + } - if (INFOBOX_IDENTIFIER_CARD_CHANNEL.equals(infoboxIdentifier)) { - - if (req.getAssocArrayParameters() != null) { - log.info("Got AssocArrayParameters but Infobox type is BinaryFile."); - throw new SLCommandException(4010); - } - - Base64XMLContentType binaryFileParameters = req.getBinaryFileParameters(); - if (binaryFileParameters == null) { - log.info("Got no BinaryFileParameters but Infobox type is BinaryFile."); - throw new SLCommandException(4010); - } - - if (binaryFileParameters.getBase64Content() == null) { - log.info("Got Base64Content but ContentIsXMLEntity is true."); - throw new SLCommandException(4010); - } - - List content = binaryFileParameters.getXMLContent().getContent(); - if (content.isEmpty()) { - log.info("Got no XMLContent but ContentIsXMLEntity is true."); - throw new SLCommandException(4010); - } - - for (Object element : content) { - if (!(element instanceof ScriptType)) { - log.info("Infobox identifier is '" + infoboxIdentifier + "' but XMLContent does not contain 'Script'."); - throw new SLCommandException(4010); - } - - setCardChannelScript(((ScriptType) element).getResetOrCommandAPDUOrVerifyAPDU()); - } - - if (getCardChannelScript() == null) { - log.info("Infobox identifier is '" + infoboxIdentifier + "' but XMLContent does not contain 'Script'."); - throw new SLCommandException(4010); - } - - } else { - throw new SLCommandException(4002, - SLExceptionMessages.EC4002_INFOBOX_UNKNOWN, - new Object[] { infoboxIdentifier }); + if (req.getBinaryFileParameters() != null && + !(infobox instanceof BinaryFileInfobox)) { + log.info("Got BinaryFileParameters but Infobox type is not BinaryFile."); + throw new SLCommandException(4010); } } - public List getCardChannelScript() { - return cardChannelScript; - } - - public void setCardChannelScript(List cardChannelScript) { - this.cardChannelScript = cardChannelScript; - } - @Override public SLResult execute() { try { - if (INFOBOX_IDENTIFIER_CARD_CHANNEL.equals(getInfoboxIdentifier())) { - - executeCardChannelScript(); - return new InfoboxUpdateResultImpl(); - - } else { - throw new SLCommandException(4002, - SLExceptionMessages.EC4002_INFOBOX_UNKNOWN, - new Object[] { infoboxIdentifier }); - } + return infobox.update(getRequestValue(), getCmdCtx()); } catch (SLCommandException e) { - return new ErrorResultImpl(e, cmdCtx.getLocale()); + return new ErrorResultImpl(e, getCmdCtx().getLocale()); } } - - protected void executeCardChannelScript() throws SLCommandException { - - if (cardChannelScript != null) { - - for (Object element : cardChannelScript) { - if (element instanceof ResetType) { - - } else if (element instanceof CommandAPDUType) { - - } else if (element instanceof VerifyAPDUType) { - - } - } - - } - - } - - @Override - public String getName() { - return "InfoboxUpdateRequest"; - } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java index 80bbdca8..99a3b119 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java @@ -16,6 +16,7 @@ */ package at.gv.egiz.bku.slcommands.impl; +import java.io.UnsupportedEncodingException; import java.util.Locale; import javax.xml.bind.JAXBContext; @@ -32,6 +33,7 @@ import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -45,6 +47,8 @@ import at.gv.egiz.bku.slexceptions.SLBindingException; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.DebugOutputStream; +import at.gv.egiz.bku.utils.DebugWriter; /** * This class serves as an abstract base class for the implementation of a @@ -128,6 +132,20 @@ public abstract class SLResultImpl implements SLResult { * @param templates */ protected void writeTo(JAXBElement response, Result result, Templates templates) { + + DebugWriter dw = null; + DebugOutputStream ds = null; + if (log.isTraceEnabled() && result instanceof StreamResult) { + StreamResult streamResult = (StreamResult) result; + if (streamResult.getOutputStream() != null) { + ds = new DebugOutputStream(streamResult.getOutputStream()); + streamResult.setOutputStream(ds); + } + if (streamResult.getWriter() != null) { + dw = new DebugWriter(streamResult.getWriter()); + streamResult.setWriter(dw); + } + } TransformerHandler transformerHandler = null; if (templates != null) { @@ -151,10 +169,36 @@ public abstract class SLResultImpl implements SLResult { writeErrorTo(commandException, result, templates); } + if (ds != null) { + try { + log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + log.trace(e.getMessage()); + } + } + + if (dw != null) { + log.trace("Marshalled result:\n" + dw.getBufferedString()); + } + } protected void writeTo(Node node, Result result, Templates templates) { + DebugWriter dw = null; + DebugOutputStream ds = null; + if (log.isTraceEnabled() && result instanceof StreamResult) { + StreamResult streamResult = (StreamResult) result; + if (streamResult.getOutputStream() != null) { + ds = new DebugOutputStream(streamResult.getOutputStream()); + streamResult.setOutputStream(ds); + } + if (streamResult.getWriter() != null) { + dw = new DebugWriter(streamResult.getWriter()); + streamResult.setWriter(dw); + } + } + if (templates == null) { try { TransformerFactory transformerFactory = TransformerFactory.newInstance(); @@ -179,7 +223,19 @@ public abstract class SLResultImpl implements SLResult { writeErrorTo(new SLException(2008), result, templates); } } + + if (ds != null) { + try { + log.trace("Marshalled result:\n" + new String(ds.getBufferedBytes(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + log.trace(e.getMessage()); + } + } + if (dw != null) { + log.trace("Marshalled result:\n" + dw.getBufferedString()); + } + } protected void writeErrorTo(SLException slException, Result result, Templates templates) { diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java index 969288c1..0c7ce3f5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java @@ -85,7 +85,7 @@ public class STALHelper { * @param stalRequests * @throws SLCommandException */ - public void transmitSTALRequest(List stalRequests) throws SLCommandException { + public void transmitSTALRequest(List stalRequests) throws SLCommandException { List responses = stal.handleRequest(stalRequests); if (responses == null) { Log log = LogFactory.getLog(this.getClass()); diff --git a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java index 2ea0bae0..dd8b8c8f 100644 --- a/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java +++ b/bkucommon/src/test/java/at/gv/egiz/stal/dummy/DummySTAL.java @@ -71,7 +71,7 @@ public class DummySTAL implements STAL { } @Override - public List handleRequest(List requestList) { + public List handleRequest(List requestList) { List responses = new ArrayList(); for (STALRequest request : requestList) { diff --git a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java index b828e8cd..e34c4899 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/AbstractSignatureCard.java @@ -36,6 +36,7 @@ import javax.smartcardio.ATR; import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; @@ -53,7 +54,12 @@ public abstract class AbstractSignatureCard implements SignatureCard { int ifs_ = 254; - Card card_; + private Card card_; + + /** + * The card terminal that connects the {@link #card_}. + */ + private CardTerminal cardTerminal; protected AbstractSignatureCard(String resourceBundleName) { this.resourceBundleName = resourceBundleName; @@ -331,8 +337,9 @@ public abstract class AbstractSignatureCard implements SignatureCard { } - public void init(Card card) { + public void init(Card card, CardTerminal cardTerminal) { card_ = card; + this.cardTerminal = cardTerminal; ATR atr = card.getATR(); byte[] atrBytes = atr.getBytes(); if (atrBytes.length >= 6) { @@ -340,6 +347,11 @@ public abstract class AbstractSignatureCard implements SignatureCard { log.trace("Setting IFS (information field size) to " + ifs_); } } + + @Override + public Card getCard() { + return card_; + } protected CardChannel getCardChannel() { return card_.getBasicChannel(); @@ -372,4 +384,18 @@ public abstract class AbstractSignatureCard implements SignatureCard { } } + @Override + public void reset() throws SignatureCardException { + try { + log.debug("Disconnect and reset smart card."); + card_.disconnect(true); + log.debug("Reconnect smart card."); + if (cardTerminal != null) { + card_ = cardTerminal.connect("*"); + } + } catch (CardException e) { + throw new SignatureCardException("Failed to reset card.", e); + } + } + } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java index 42943541..439be034 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java @@ -40,6 +40,7 @@ import java.util.Enumeration; import java.util.Locale; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -102,7 +103,12 @@ public class SWCard implements SignatureCard { SWCard.swCardDir = swCardDir; } - public void init(Card card) { + public void init(Card card, CardTerminal cardTerminal) { + } + + @Override + public Card getCard() { + return null; } private String getFileName(String fileName) { @@ -379,4 +385,8 @@ public class SWCard implements SignatureCard { public void disconnect(boolean reset) { } + @Override + public void reset() throws SignatureCardException { + } + } diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java index b6a453df..d7e76dd8 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java @@ -31,6 +31,7 @@ package at.gv.egiz.smcc; import java.util.Locale; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; public interface SignatureCard { @@ -75,12 +76,21 @@ public interface SignatureCard { } - public void init(Card card); + public void init(Card card, CardTerminal cardTerminal); + + public Card getCard(); public byte[] getCertificate(KeyboxName keyboxName) throws SignatureCardException, InterruptedException; public void disconnect(boolean reset); + + /** + * Performs a reset of the card. + * + * @throws SignatureCardException if reset fails. + */ + public void reset() throws SignatureCardException; /** * diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java index 777299d9..ab66e9a1 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java @@ -34,6 +34,7 @@ import java.util.List; import javax.smartcardio.ATR; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -204,6 +205,7 @@ public class SignatureCardFactory { * @param card * the smart card, or null if a software card should be * created + * @param cardTerminal TODO * * @return a SignatureCard instance * @@ -211,12 +213,12 @@ public class SignatureCardFactory { * if no implementation of the given card could be * found */ - public SignatureCard createSignatureCard(Card card) + public SignatureCard createSignatureCard(Card card, CardTerminal cardTerminal) throws CardNotSupportedException { if(card == null) { SignatureCard sCard = new SWCard(); - sCard.init(card); + sCard.init(card, cardTerminal); return sCard; } @@ -231,7 +233,7 @@ public class SignatureCardFactory { try { Class scClass = cl.loadClass(supportedCard.getImplementationClassName()); sc = (SignatureCard) scClass.newInstance(); - sc.init(card); + sc.init(card, cardTerminal); return sc; } catch (ClassNotFoundException e) { diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java b/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java index 4dae7975..f7d3bab7 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/SMCCHelper.java @@ -57,7 +57,7 @@ public class SMCCHelper { SignatureCardFactory factory = SignatureCardFactory.getInstance(); if (useSWCard) { try { - signatureCard = factory.createSignatureCard(null); + signatureCard = factory.createSignatureCard(null, null); resultCode = CARD_FOUND; } catch (CardNotSupportedException e) { resultCode = CARD_NOT_SUPPORTED; @@ -83,7 +83,7 @@ public class SMCCHelper { if (c == null) { throw new CardNotSupportedException(); } - signatureCard = factory.createSignatureCard(c); + signatureCard = factory.createSignatureCard(c, cardTerminal); ATR atr = newCards.get(cardTerminal).getATR(); log.trace("Found supported card (" + signatureCard.toString() + ") " + "in terminal '" + cardTerminal.getName() + "', ATR = " diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java b/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java index b70b44a7..b1866894 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/SmartCardIO.java @@ -16,6 +16,7 @@ */ package at.gv.egiz.smcc.util; +import java.security.NoSuchAlgorithmException; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -54,7 +55,13 @@ public class SmartCardIO { CardTerminals cardTerminals_; private void updateTerminalFactory() { - TerminalFactory terminalFactory = TerminalFactory.getDefault(); + TerminalFactory terminalFactory; + try { + terminalFactory = TerminalFactory.getInstance("PC/SC", null); + } catch (NoSuchAlgorithmException e) { + log.info("Failed to get TerminalFactory of type 'PC/SC'.", e); + terminalFactory = TerminalFactory.getDefault(); + } log.debug("TerminalFactory : " + terminalFactory); if ("PC/SC".equals(terminalFactory.getType())) { terminalFactory_ = terminalFactory; diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java index 55f51b22..6f08a135 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java @@ -121,7 +121,7 @@ public abstract class AbstractSMCCSTAL implements STAL { } @Override - public List handleRequest(List requestList) { + public List handleRequest(List requestList) { log.debug("Got request list containing " + requestList.size() + " STAL requests"); List responseList = new ArrayList(requestList diff --git a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java index 59ea141c..77997217 100644 --- a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java +++ b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Locale; import javax.smartcardio.Card; +import javax.smartcardio.CardTerminal; import org.junit.Assert; import org.junit.Before; @@ -61,7 +62,7 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements } @Override - public void init(Card card) { + public void init(Card card, CardTerminal cardTerminal) { // TODO Auto-generated method stub } @@ -71,6 +72,18 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements // TODO Auto-generated method stub } + + @Override + public Card getCard() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void reset() throws SignatureCardException { + // TODO Auto-generated method stub + + } }; return false; diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/DebugOutputStream.java b/utils/src/main/java/at/gv/egiz/bku/utils/DebugOutputStream.java new file mode 100644 index 00000000..8516b76c --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/DebugOutputStream.java @@ -0,0 +1,48 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.ByteArrayOutputStream; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class DebugOutputStream extends FilterOutputStream { + + private ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + public DebugOutputStream(OutputStream out) { + super(out); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + buffer.write(b, off, len); + super.write(b, off, len); + } + + @Override + public void write(int b) throws IOException { + buffer.write(b); + super.write(b); + } + + public byte[] getBufferedBytes() { + return buffer.toByteArray(); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/DebugReader.java b/utils/src/main/java/at/gv/egiz/bku/utils/DebugReader.java new file mode 100644 index 00000000..cafe4a72 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/DebugReader.java @@ -0,0 +1,58 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringWriter; + +public class DebugReader extends FilterReader { + + private StringWriter buffer = new StringWriter(); + + public DebugReader(Reader in) { + super(in); + } + + public DebugReader(Reader in, String start) { + super(in); + buffer.write(start); + } + + @Override + public int read() throws IOException { + int c = super.read(); + if (c != -1) + buffer.write(c); + return c; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + int l = super.read(cbuf, off, len); + if (l != -1 ) { + buffer.write(cbuf, off, l); + } + return l; + } + + public String getCachedString() { + return buffer.toString(); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/DebugWriter.java b/utils/src/main/java/at/gv/egiz/bku/utils/DebugWriter.java new file mode 100644 index 00000000..5566f927 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/DebugWriter.java @@ -0,0 +1,55 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.FilterWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +public class DebugWriter extends FilterWriter { + + private Writer buffer = new StringWriter(); + + public DebugWriter(Writer out) { + super(out); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + buffer.write(cbuf, off, len); + super.write(cbuf, off, len); + } + + @Override + public void write(String str, int off, int len) throws IOException { + buffer.write(str, off, len); + super.write(str, off, len); + } + + @Override + public void write(int c) throws IOException { + buffer.write(c); + super.write(c); + } + + public String getBufferedString() { + return buffer.toString(); + } + + +} -- cgit v1.2.3 From 5f85e3741395a4b2e8f04037372c59a27fae2665 Mon Sep 17 00:00:00 2001 From: wbauer Date: Thu, 18 Dec 2008 10:51:45 +0000 Subject: Added Nulldevice git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@256 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- utils/src/main/java/at/gv/egiz/bku/utils/NullOutputStream.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/NullOutputStream.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/NullOutputStream.java b/utils/src/main/java/at/gv/egiz/bku/utils/NullOutputStream.java new file mode 100644 index 00000000..edbd9c01 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/NullOutputStream.java @@ -0,0 +1,10 @@ +package at.gv.egiz.bku.utils; + +import java.io.IOException; +import java.io.OutputStream; + +public class NullOutputStream extends OutputStream { + @Override + public void write(int b) throws IOException { + } +} -- cgit v1.2.3 From b97b768ba705935caf67352a143586faa0b2371f Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 23 Dec 2008 16:12:09 +0000 Subject: saml:AnyType workaround for xs:anyType (SubjectConfirmationData und AttributeValue) git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@257 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/idlink/IdentityLinkFactory.java | 212 +++++++++++---------- .../names/tc/saml/_1_0/assertion/ActionType.java | 4 +- .../names/tc/saml/_1_0/assertion/AdviceType.java | 12 +- .../names/tc/saml/_1_0/assertion/AnyType.java | 79 ++++++++ .../tc/saml/_1_0/assertion/AssertionType.java | 14 +- .../_1_0/assertion/AttributeDesignatorType.java | 4 +- .../_1_0/assertion/AttributeStatementType.java | 4 +- .../tc/saml/_1_0/assertion/AttributeType.java | 12 +- .../AudienceRestrictionConditionType.java | 4 +- .../assertion/AuthenticationStatementType.java | 4 +- .../saml/_1_0/assertion/AuthorityBindingType.java | 4 +- .../AuthorizationDecisionStatementType.java | 4 +- .../saml/_1_0/assertion/ConditionAbstractType.java | 4 +- .../tc/saml/_1_0/assertion/ConditionsType.java | 4 +- .../names/tc/saml/_1_0/assertion/DecisionType.java | 4 +- .../names/tc/saml/_1_0/assertion/EvidenceType.java | 4 +- .../tc/saml/_1_0/assertion/NameIdentifierType.java | 4 +- .../tc/saml/_1_0/assertion/ObjectFactory.java | 108 ++++++----- .../saml/_1_0/assertion/StatementAbstractType.java | 4 +- .../_1_0/assertion/SubjectConfirmationType.java | 14 +- .../saml/_1_0/assertion/SubjectLocalityType.java | 4 +- .../assertion/SubjectStatementAbstractType.java | 4 +- .../names/tc/saml/_1_0/assertion/SubjectType.java | 4 +- .../names/tc/saml/_1_0/assertion/package-info.java | 4 +- .../test/java/saml/KeyValueAttributeTypeTest.java | 129 +++++++++++++ 25 files changed, 435 insertions(+), 213 deletions(-) create mode 100644 utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AnyType.java create mode 100644 utils/src/test/java/saml/KeyValueAttributeTypeTest.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java index a5ceeafc..28f421a4 100644 --- a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java @@ -14,8 +14,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package at.gv.egiz.idlink; - +package at.gv.egiz.idlink; + import iaik.xml.crypto.XmldsigMore; import java.io.InputStreamReader; @@ -88,63 +88,64 @@ import at.gv.e_government.reference.namespace.persondata._20020228_.Identificati import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType.FamilyName; import at.gv.egiz.xmldsig.KeyTypeNotSupportedException; import at.gv.egiz.xmldsig.KeyValueFactory; - +import oasis.names.tc.saml._1_0.assertion.AnyType; + public class IdentityLinkFactory { - private static Log log = LogFactory.getLog(IdentityLinkFactory.class); - - /** - * The instance returned by {@link #getInstance()}. - */ - private static IdentityLinkFactory instance; - - /** - * The JAXBContext. - */ - private static JAXBContext jaxbContext; - - /** - * The KeyValueFactory. - */ - private static KeyValueFactory keyValueFactory; - - /** - * Get an instance of this CompressedIdentityLinkFactory. - * - * @return an instance of this CompressedIdentityLinkFactory - */ - public synchronized static IdentityLinkFactory getInstance() { - if (instance == null) { - instance = new IdentityLinkFactory(); - } - return instance; - } - - /** - * Private constructor. - */ - private IdentityLinkFactory() { - - keyValueFactory = new KeyValueFactory(); - - StringBuffer packageNames = new StringBuffer(); - packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); - packageNames.append(":"); - packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); + private static Log log = LogFactory.getLog(IdentityLinkFactory.class); + + /** + * The instance returned by {@link #getInstance()}. + */ + private static IdentityLinkFactory instance; + + /** + * The JAXBContext. + */ + private static JAXBContext jaxbContext; + + /** + * The KeyValueFactory. + */ + private static KeyValueFactory keyValueFactory; + + /** + * Get an instance of this CompressedIdentityLinkFactory. + * + * @return an instance of this CompressedIdentityLinkFactory + */ + public synchronized static IdentityLinkFactory getInstance() { + if (instance == null) { + instance = new IdentityLinkFactory(); + } + return instance; + } + + /** + * Private constructor. + */ + private IdentityLinkFactory() { + + keyValueFactory = new KeyValueFactory(); + + StringBuffer packageNames = new StringBuffer(); + packageNames.append(at.gv.e_government.reference.namespace.persondata._20020228_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(org.w3._2001._04.xmldsig_more_.ObjectFactory.class.getPackage().getName()); + packageNames.append(":"); + packageNames.append(at.buergerkarte.namespaces.personenbindung._20020506_.ObjectFactory.class.getPackage().getName()); packageNames.append(":"); packageNames.append(oasis.names.tc.saml._1_0.assertion.ObjectFactory.class.getPackage().getName()); - - try { - jaxbContext = JAXBContext.newInstance(packageNames.toString()); - } catch (JAXBException e) { - // we should not get an JAXBException initializing the JAXBContext - throw new RuntimeException(e); - } - + + try { + jaxbContext = JAXBContext.newInstance(packageNames.toString()); + } catch (JAXBException e) { + // we should not get an JAXBException initializing the JAXBContext + throw new RuntimeException(e); + } + } public JAXBElement createAssertion(String assertionId, @@ -175,11 +176,11 @@ public class IdentityLinkFactory { return asFactory.createAssertion(assertionType); - } - + } + public AttributeStatementType createAttributeStatement(String idValue, String idType, String givenName, String familyName, String dateOfBirth, - PublicKey[] publicKeys) throws KeyTypeNotSupportedException { + PublicKey[] publicKeys) throws KeyTypeNotSupportedException { oasis.names.tc.saml._1_0.assertion.ObjectFactory asFactory = new oasis.names.tc.saml._1_0.assertion.ObjectFactory(); @@ -215,8 +216,11 @@ public class IdentityLinkFactory { physicalPersonType.getIdentification().add(identificationType); physicalPersonType.setName(personNameType); physicalPersonType.setDateOfBirth(dateOfBirth); - - subjectConfirmationType.setSubjectConfirmationData(physicalPersonType); + JAXBElement physicalPerson = prFactory.createPhysicalPerson(physicalPersonType); + + AnyType personType = asFactory.createAnyType(); + personType.getContent().add(physicalPerson); + subjectConfirmationType.setSubjectConfirmationData(personType); JAXBElement subjectConfirmation = asFactory.createSubjectConfirmation(subjectConfirmationType); @@ -232,52 +236,54 @@ public class IdentityLinkFactory { AttributeType attributeType = asFactory.createAttributeType(); attributeType.setAttributeName("CitizenPublicKey"); attributeType.setAttributeNamespace("urn:publicid:gv.at:namespaces:identitylink:1.2"); - attributeType.getAttributeValue().add(createKeyValue.getValue()); + AnyType attributeValueType = asFactory.createAnyType(); + attributeValueType.getContent().add(createKeyValue); + attributeType.getAttributeValue().add(attributeValueType); attributeStatementType.getAttribute().add(attributeType); } return attributeStatementType; - } - - /** - * Marshall the given compressedIdentityLink into a DOM document - * with the given Nodes as parent and nextSibling - * nodes. - * - * @param identityLink - * the CompressedIdentityLink element - * @param parent - * the parent node - * @param nextSibling - * the next sibling node (may be null) - * @param applyWorkarounds - * apply workarounds as spefiyed by - * {@link #applyWorkarounds(Element, int)} - * - * @throws JAXBException - * if an unexpected error occurs while marshalling - * @throws NullPointerException - * if compressdIdentityLink or parent is - * null - */ - public void marshallIdentityLink( - JAXBElement identityLink, - Node parent, Node nextSibling) throws JAXBException { - - DOMResult result = new DOMResult(parent, nextSibling); - - try { - Marshaller marshaller = jaxbContext.createMarshaller(); - - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); - - marshaller.marshal(identityLink, result); - } catch (PropertyException e) { - throw new RuntimeException(e); - } - + } + + /** + * Marshall the given compressedIdentityLink into a DOM document + * with the given Nodes as parent and nextSibling + * nodes. + * + * @param identityLink + * the CompressedIdentityLink element + * @param parent + * the parent node + * @param nextSibling + * the next sibling node (may be null) + * @param applyWorkarounds + * apply workarounds as spefiyed by + * {@link #applyWorkarounds(Element, int)} + * + * @throws JAXBException + * if an unexpected error occurs while marshalling + * @throws NullPointerException + * if compressdIdentityLink or parent is + * null + */ + public void marshallIdentityLink( + JAXBElement identityLink, + Node parent, Node nextSibling) throws JAXBException { + + DOMResult result = new DOMResult(parent, nextSibling); + + try { + Marshaller marshaller = jaxbContext.createMarshaller(); + + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + marshaller.marshal(identityLink, result); + } catch (PropertyException e) { + throw new RuntimeException(e); + } + } public void signIdentityLink(Element assertion, X509Certificate certificate, @@ -416,6 +422,6 @@ public class IdentityLinkFactory { log.trace(sb.toString()); } - } - -} + } + +} diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ActionType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ActionType.java index 144b4e17..d2b96381 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ActionType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ActionType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AdviceType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AdviceType.java index e5342409..d2630fac 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AdviceType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AdviceType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @@ -32,7 +32,7 @@ import org.w3c.dom.Element; * <choice maxOccurs="unbounded" minOccurs="0"> * <element ref="{urn:oasis:names:tc:SAML:1.0:assertion}AssertionIDReference"/> * <element ref="{urn:oasis:names:tc:SAML:1.0:assertion}Assertion"/> - * <any/> + * <any processContents='lax' namespace='##other'/> * </choice> * </restriction> * </complexContent> @@ -72,10 +72,10 @@ public class AdviceType { * *

* Objects of the following type(s) are allowed in the list - * {@link Object } - * {@link JAXBElement }{@code <}{@link String }{@code >} - * {@link JAXBElement }{@code <}{@link AssertionType }{@code >} * {@link Element } + * {@link JAXBElement }{@code <}{@link AssertionType }{@code >} + * {@link JAXBElement }{@code <}{@link String }{@code >} + * {@link Object } * * */ diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AnyType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AnyType.java new file mode 100644 index 00000000..82a221a7 --- /dev/null +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AnyType.java @@ -0,0 +1,79 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2008.12.23 at 03:26:53 PM GMT +// + + +package oasis.names.tc.saml._1_0.assertion; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAnyElement; +import javax.xml.bind.annotation.XmlMixed; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for AnyType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="AnyType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence maxOccurs="unbounded" minOccurs="0">
+ *         <any/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "AnyType", propOrder = { + "content" +}) +public class AnyType { + + @XmlMixed + @XmlAnyElement(lax = true) + protected List content; + + /** + * Gets the value of the content property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the content property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getContent().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Object } + * {@link String } + * + * + */ + public List getContent() { + if (content == null) { + content = new ArrayList(); + } + return this.content; + } + +} diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AssertionType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AssertionType.java index 2157dd67..2a108984 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AssertionType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AssertionType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @@ -70,10 +70,10 @@ public class AssertionType { protected AdviceType advice; @XmlElements({ @XmlElement(name = "Statement"), - @XmlElement(name = "AuthorizationDecisionStatement", type = AuthorizationDecisionStatementType.class), - @XmlElement(name = "AuthenticationStatement", type = AuthenticationStatementType.class), + @XmlElement(name = "AttributeStatement", type = AttributeStatementType.class), @XmlElement(name = "SubjectStatement", type = SubjectStatementAbstractType.class), - @XmlElement(name = "AttributeStatement", type = AttributeStatementType.class) + @XmlElement(name = "AuthorizationDecisionStatement", type = AuthorizationDecisionStatementType.class), + @XmlElement(name = "AuthenticationStatement", type = AuthenticationStatementType.class) }) protected List statementOrSubjectStatementOrAuthenticationStatement; @XmlElement(name = "Signature", namespace = "http://www.w3.org/2000/09/xmldsig#") @@ -157,10 +157,10 @@ public class AssertionType { *

* Objects of the following type(s) are allowed in the list * {@link StatementAbstractType } + * {@link AttributeStatementType } + * {@link SubjectStatementAbstractType } * {@link AuthorizationDecisionStatementType } * {@link AuthenticationStatementType } - * {@link SubjectStatementAbstractType } - * {@link AttributeStatementType } * * */ diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeDesignatorType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeDesignatorType.java index f96815d8..12bd8738 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeDesignatorType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeDesignatorType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeStatementType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeStatementType.java index 71faeffb..f710b74b 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeStatementType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeStatementType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeType.java index 68e41ab4..31d258a9 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AttributeType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @@ -44,7 +44,7 @@ public class AttributeType { @XmlElement(name = "AttributeValue", required = true) - protected List attributeValue; + protected List attributeValue; /** * Gets the value of the attributeValue property. @@ -64,13 +64,13 @@ public class AttributeType * *

* Objects of the following type(s) are allowed in the list - * {@link Object } + * {@link AnyType } * * */ - public List getAttributeValue() { + public List getAttributeValue() { if (attributeValue == null) { - attributeValue = new ArrayList(); + attributeValue = new ArrayList(); } return this.attributeValue; } diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AudienceRestrictionConditionType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AudienceRestrictionConditionType.java index aa95892a..61091b73 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AudienceRestrictionConditionType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AudienceRestrictionConditionType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthenticationStatementType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthenticationStatementType.java index 5f22ea2d..93c24117 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthenticationStatementType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthenticationStatementType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorityBindingType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorityBindingType.java index 32ccb3f6..8663f35a 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorityBindingType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorityBindingType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorizationDecisionStatementType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorizationDecisionStatementType.java index 5678a373..b6b37c90 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorizationDecisionStatementType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/AuthorizationDecisionStatementType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionAbstractType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionAbstractType.java index 6952e51f..965bb4bd 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionAbstractType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionAbstractType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionsType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionsType.java index 8160779f..42c1e1af 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionsType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ConditionsType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/DecisionType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/DecisionType.java index 4fa36320..e5efbf0a 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/DecisionType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/DecisionType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/EvidenceType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/EvidenceType.java index a2fc049c..74f74440 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/EvidenceType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/EvidenceType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/NameIdentifierType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/NameIdentifierType.java index 1970e6f8..34fed5d2 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/NameIdentifierType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/NameIdentifierType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ObjectFactory.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ObjectFactory.java index fe0982ef..d5165b71 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ObjectFactory.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/ObjectFactory.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @@ -64,43 +64,43 @@ public class ObjectFactory { } /** - * Create an instance of {@link AuthorityBindingType } + * Create an instance of {@link AnyType } * */ - public AuthorityBindingType createAuthorityBindingType() { - return new AuthorityBindingType(); + public AnyType createAnyType() { + return new AnyType(); } /** - * Create an instance of {@link AttributeDesignatorType } + * Create an instance of {@link ActionType } * */ - public AttributeDesignatorType createAttributeDesignatorType() { - return new AttributeDesignatorType(); + public ActionType createActionType() { + return new ActionType(); } /** - * Create an instance of {@link AuthenticationStatementType } + * Create an instance of {@link AttributeDesignatorType } * */ - public AuthenticationStatementType createAuthenticationStatementType() { - return new AuthenticationStatementType(); + public AttributeDesignatorType createAttributeDesignatorType() { + return new AttributeDesignatorType(); } /** - * Create an instance of {@link EvidenceType } + * Create an instance of {@link SubjectConfirmationType } * */ - public EvidenceType createEvidenceType() { - return new EvidenceType(); + public SubjectConfirmationType createSubjectConfirmationType() { + return new SubjectConfirmationType(); } /** - * Create an instance of {@link SubjectConfirmationType } + * Create an instance of {@link SubjectLocalityType } * */ - public SubjectConfirmationType createSubjectConfirmationType() { - return new SubjectConfirmationType(); + public SubjectLocalityType createSubjectLocalityType() { + return new SubjectLocalityType(); } /** @@ -112,11 +112,11 @@ public class ObjectFactory { } /** - * Create an instance of {@link SubjectLocalityType } + * Create an instance of {@link AuthenticationStatementType } * */ - public SubjectLocalityType createSubjectLocalityType() { - return new SubjectLocalityType(); + public AuthenticationStatementType createAuthenticationStatementType() { + return new AuthenticationStatementType(); } /** @@ -128,67 +128,75 @@ public class ObjectFactory { } /** - * Create an instance of {@link ActionType } + * Create an instance of {@link AuthorityBindingType } * */ - public ActionType createActionType() { - return new ActionType(); + public AuthorityBindingType createAuthorityBindingType() { + return new AuthorityBindingType(); } /** - * Create an instance of {@link AttributeStatementType } + * Create an instance of {@link AttributeType } * */ - public AttributeStatementType createAttributeStatementType() { - return new AttributeStatementType(); + public AttributeType createAttributeType() { + return new AttributeType(); } /** - * Create an instance of {@link NameIdentifierType } + * Create an instance of {@link AdviceType } * */ - public NameIdentifierType createNameIdentifierType() { - return new NameIdentifierType(); + public AdviceType createAdviceType() { + return new AdviceType(); } /** - * Create an instance of {@link AuthorizationDecisionStatementType } + * Create an instance of {@link EvidenceType } * */ - public AuthorizationDecisionStatementType createAuthorizationDecisionStatementType() { - return new AuthorizationDecisionStatementType(); + public EvidenceType createEvidenceType() { + return new EvidenceType(); } /** - * Create an instance of {@link AttributeType } + * Create an instance of {@link ConditionsType } * */ - public AttributeType createAttributeType() { - return new AttributeType(); + public ConditionsType createConditionsType() { + return new ConditionsType(); } /** - * Create an instance of {@link SubjectType } + * Create an instance of {@link AttributeStatementType } * */ - public SubjectType createSubjectType() { - return new SubjectType(); + public AttributeStatementType createAttributeStatementType() { + return new AttributeStatementType(); } /** - * Create an instance of {@link AdviceType } + * Create an instance of {@link NameIdentifierType } * */ - public AdviceType createAdviceType() { - return new AdviceType(); + public NameIdentifierType createNameIdentifierType() { + return new NameIdentifierType(); } /** - * Create an instance of {@link ConditionsType } + * Create an instance of {@link AuthorizationDecisionStatementType } * */ - public ConditionsType createConditionsType() { - return new ConditionsType(); + public AuthorizationDecisionStatementType createAuthorizationDecisionStatementType() { + return new AuthorizationDecisionStatementType(); + } + + /** + * Create an instance of {@link SubjectType } + * + */ + public SubjectType createSubjectType() { + return new SubjectType(); } /** @@ -363,12 +371,12 @@ public class ObjectFactory { } /** - * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * Create an instance of {@link JAXBElement }{@code <}{@link AnyType }{@code >}} * */ @XmlElementDecl(namespace = "urn:oasis:names:tc:SAML:1.0:assertion", name = "SubjectConfirmationData") - public JAXBElement createSubjectConfirmationData(Object value) { - return new JAXBElement(_SubjectConfirmationData_QNAME, Object.class, null, value); + public JAXBElement createSubjectConfirmationData(AnyType value) { + return new JAXBElement(_SubjectConfirmationData_QNAME, AnyType.class, null, value); } /** @@ -399,12 +407,12 @@ public class ObjectFactory { } /** - * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * Create an instance of {@link JAXBElement }{@code <}{@link AnyType }{@code >}} * */ @XmlElementDecl(namespace = "urn:oasis:names:tc:SAML:1.0:assertion", name = "AttributeValue") - public JAXBElement createAttributeValue(Object value) { - return new JAXBElement(_AttributeValue_QNAME, Object.class, null, value); + public JAXBElement createAttributeValue(AnyType value) { + return new JAXBElement(_AttributeValue_QNAME, AnyType.class, null, value); } } diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/StatementAbstractType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/StatementAbstractType.java index efe8faae..eabd815f 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/StatementAbstractType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/StatementAbstractType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectConfirmationType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectConfirmationType.java index 094e8840..d7bd8856 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectConfirmationType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectConfirmationType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @@ -51,7 +51,7 @@ public class SubjectConfirmationType { @XmlSchemaType(name = "anyURI") protected List confirmationMethod; @XmlElement(name = "SubjectConfirmationData") - protected Object subjectConfirmationData; + protected AnyType subjectConfirmationData; @XmlElement(name = "KeyInfo", namespace = "http://www.w3.org/2000/09/xmldsig#") protected KeyInfoType keyInfo; @@ -89,10 +89,10 @@ public class SubjectConfirmationType { * * @return * possible object is - * {@link Object } + * {@link AnyType } * */ - public Object getSubjectConfirmationData() { + public AnyType getSubjectConfirmationData() { return subjectConfirmationData; } @@ -101,10 +101,10 @@ public class SubjectConfirmationType { * * @param value * allowed object is - * {@link Object } + * {@link AnyType } * */ - public void setSubjectConfirmationData(Object value) { + public void setSubjectConfirmationData(AnyType value) { this.subjectConfirmationData = value; } diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectLocalityType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectLocalityType.java index 8c59d4ae..1515d535 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectLocalityType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectLocalityType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectStatementAbstractType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectStatementAbstractType.java index 38e9bcbd..07916c14 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectStatementAbstractType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectStatementAbstractType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectType.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectType.java index 453713a1..646339c8 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectType.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/SubjectType.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // diff --git a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/package-info.java b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/package-info.java index 9de42741..4eb7ece2 100644 --- a/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/package-info.java +++ b/utils/src/main/java/oasis/names/tc/saml/_1_0/assertion/package-info.java @@ -1,8 +1,8 @@ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-520 +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vhudson-jaxb-ri-2.1-661 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2008.10.29 at 09:14:07 AM GMT +// Generated on: 2008.12.23 at 03:26:53 PM GMT // @javax.xml.bind.annotation.XmlSchema(namespace = "urn:oasis:names:tc:SAML:1.0:assertion", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) diff --git a/utils/src/test/java/saml/KeyValueAttributeTypeTest.java b/utils/src/test/java/saml/KeyValueAttributeTypeTest.java new file mode 100644 index 00000000..2df04ce6 --- /dev/null +++ b/utils/src/test/java/saml/KeyValueAttributeTypeTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package saml; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.List; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; +import oasis.names.tc.saml._1_0.assertion.AnyType; +import oasis.names.tc.saml._1_0.assertion.AssertionType; +import oasis.names.tc.saml._1_0.assertion.AttributeStatementType; +import oasis.names.tc.saml._1_0.assertion.AttributeType; +import oasis.names.tc.saml._1_0.assertion.NameIdentifierType; +import oasis.names.tc.saml._1_0.assertion.ObjectFactory; +import oasis.names.tc.saml._1_0.assertion.StatementAbstractType; +import oasis.names.tc.saml._1_0.assertion.SubjectType; +import org.junit.Ignore; +import org.junit.Test; +import org.w3._2000._09.xmldsig_.KeyValueType; +import org.w3._2000._09.xmldsig_.RSAKeyValueType; +import org.w3c.dom.Element; + +/** + * + * @author Clemens Orthacker + */ +@Ignore +public class KeyValueAttributeTypeTest { + + @Test + public void testAttrStatement() throws FileNotFoundException, JAXBException { + JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class, org.w3._2000._09.xmldsig_.ObjectFactory.class); + Unmarshaller um = ctx.createUnmarshaller(); + + JAXBElement assertion = (JAXBElement) um.unmarshal(new File("/home/clemens/workspace/schema-base/src/main/schema/test/saml10.xml")); + List statements = assertion.getValue().getStatementOrSubjectStatementOrAuthenticationStatement(); + for (StatementAbstractType stmt : statements) { + if (stmt instanceof AttributeStatementType) { + System.out.println("AttributeStatement"); + List attrs = ((AttributeStatementType) stmt).getAttribute(); + for (AttributeType attr : attrs) { + List attrValue = attr.getAttributeValue(); + System.out.println(attrValue.size() + " AttributeValue(s)"); + for (AnyType attrValueT : attrValue) { + List attrValueContent = attrValueT.getContent(); + System.out.println(" AttributeValue: " + attrValueContent.size() + " child nodes"); + for (Object node : attrValueContent) { + if (node instanceof String) { + System.out.println(" - CDATA: " + node); + } else if (node instanceof Element) { + System.out.println(" - DOM Element: " + ((Element)node).getTagName()); + } else { + System.out.println(" - " + node.getClass()); + } + } + } + + } + } + } + } + + @Test + public void testAttributeStatement() throws JAXBException { + + org.w3._2000._09.xmldsig_.ObjectFactory dsOF = new org.w3._2000._09.xmldsig_.ObjectFactory(); + RSAKeyValueType rsaKeyValueType = dsOF.createRSAKeyValueType(); + rsaKeyValueType.setExponent("1234".getBytes()); + rsaKeyValueType.setModulus("5678".getBytes()); + + JAXBElement rsaKeyValue = dsOF.createRSAKeyValue(rsaKeyValueType); + + +// KeyValueType kvT = dsOF.createKeyValueType(); +// kvT.getContent().add(rsaKeyValue); +// JAXBElement kv = dsOF.createKeyValue(kvT); + + ObjectFactory saml10OF = new ObjectFactory(); + AssertionType assertionT = saml10OF.createAssertionType(); + + AttributeStatementType attrStatementT = saml10OF.createAttributeStatementType(); + NameIdentifierType nameIdT = saml10OF.createNameIdentifierType(); + nameIdT.setFormat("format"); + nameIdT.setNameQualifier("qualifier"); + nameIdT.setValue("value"); + JAXBElement subjNameId = saml10OF.createNameIdentifier(nameIdT); + SubjectType subjT = saml10OF.createSubjectType(); + subjT.getContent().add(subjNameId); + attrStatementT.setSubject(subjT); + + + AttributeType attrT = saml10OF.createAttributeType(); +// QName keyVal = new QName("testNS", "keyVal"); + attrT.setAttributeName("RSAkeyvalue"); + attrT.setAttributeNamespace("lskdfjlk"); + AnyType attrValueT = saml10OF.createAnyType(); + attrValueT.getContent().add(rsaKeyValue); + attrT.getAttributeValue().add(attrValueT); //kv); //keyValue); //new JAXBElement(keyVal, declaredType, attrT)) + attrStatementT.getAttribute().add(attrT); + assertionT.getStatementOrSubjectStatementOrAuthenticationStatement().add(attrStatementT); + JAXBElement assertion = saml10OF.createAssertion(assertionT); + + JAXBContext ctx = JAXBContext.newInstance(saml10OF.getClass()); + Marshaller m = ctx.createMarshaller(); + m.marshal(assertion, System.out); + } +} -- cgit v1.2.3 From d0a8dd9ddc945b19209075be6d66350bac16f051 Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 20 Jan 2009 14:19:45 +0000 Subject: IdLink FIX git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@266 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java index 28f421a4..fb7943dc 100644 --- a/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java +++ b/utils/src/main/java/at/gv/egiz/idlink/IdentityLinkFactory.java @@ -81,6 +81,7 @@ import org.apache.commons.logging.LogFactory; import org.w3c.dom.Element; import org.w3c.dom.Node; +import at.gv.e_government.reference.namespace.persondata._20020228_.AbstractPersonType; import at.gv.e_government.reference.namespace.persondata._20020228_.IdentificationType; import at.gv.e_government.reference.namespace.persondata._20020228_.PersonNameType; import at.gv.e_government.reference.namespace.persondata._20020228_.PhysicalPersonType; @@ -216,7 +217,7 @@ public class IdentityLinkFactory { physicalPersonType.getIdentification().add(identificationType); physicalPersonType.setName(personNameType); physicalPersonType.setDateOfBirth(dateOfBirth); - JAXBElement physicalPerson = prFactory.createPhysicalPerson(physicalPersonType); + JAXBElement physicalPerson = prFactory.createPerson(physicalPersonType); AnyType personType = asFactory.createAnyType(); personType.getContent().add(physicalPerson); -- cgit v1.2.3 From 3d0112fcd64ea80ad698861ce5d16e6de93c0bd5 Mon Sep 17 00:00:00 2001 From: wbauer Date: Wed, 21 Jan 2009 11:22:03 +0000 Subject: Fixed Bug #371 git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@278 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../java/at/gv/egiz/bku/conf/Configurator.java | 8 + .../bku/slcommands/impl/xsect/SignatureTest.java | 14 ++ .../HTTPURLProtocolHandlerImpl.java | 182 ++++++++++++--------- .../bku/utils/urldereferencer/URLDereferencer.java | 20 ++- .../utils/urldereferencer/URLProtocolHandler.java | 9 +- 5 files changed, 156 insertions(+), 77 deletions(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java index 733b47dc..7f180ad0 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java @@ -43,6 +43,7 @@ import at.gv.egiz.bku.binding.DataUrlConnection; import at.gv.egiz.bku.slcommands.impl.xsect.DataObject; import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; public abstract class Configurator { private Log log = LogFactory.getLog(Configurator.class); @@ -270,6 +271,7 @@ public abstract class Configurator { sslCtx.init(km, new TrustManager[] { pkixTM }, null); } DataUrl.setSSLSocketFactory(sslCtx.getSocketFactory()); + URLDereferencer.getInstance().setSSLSocketFactory(sslCtx.getSocketFactory()); } catch (Exception e) { log.error("Cannot configure SSL", e); } @@ -283,6 +285,12 @@ public abstract class Configurator { return true; } }); + URLDereferencer.getInstance().setHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); } } diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java index 9e34d9ae..78172dcb 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java @@ -33,6 +33,8 @@ import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; @@ -191,6 +193,18 @@ public class SignatureTest { } + } + + @Override + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + // TODO Auto-generated method stub + + } + + @Override + public void setSSLSocketFactory(SSLSocketFactory socketFactory) { + // TODO Auto-generated method stub + } }); diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java index 8d01fad1..99f804b7 100644 --- a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/HTTPURLProtocolHandlerImpl.java @@ -1,78 +1,112 @@ /* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.bku.utils.urldereferencer; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.security.InvalidParameterException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class HTTPURLProtocolHandlerImpl implements URLProtocolHandler { - - private static Log log = LogFactory.getLog(HTTPURLProtocolHandlerImpl.class); - - public final static String HTTP = "http"; - public final static String HTTPS = "https"; - public final static String FORMDATA = "formdata"; - public final static String[] PROTOCOLS = { HTTP, HTTPS, FORMDATA }; - - public StreamData dereference(String aUrl, URLDereferencerContext aContext) - throws IOException { - String urlString = aUrl.toLowerCase().trim(); - if (urlString.startsWith(FORMDATA)) { - log.debug("Requested to dereference a formdata url"); - return dereferenceFormData(aUrl, aContext); - } - - URL url = new URL(aUrl); - if ((!HTTP.equalsIgnoreCase(url.getProtocol()) && (!HTTPS - .equalsIgnoreCase(url.getProtocol())))) { - throw new InvalidParameterException("Url " + aUrl + " not supported"); - } - return dereferenceHTTP(url); - } - + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.bku.utils.urldereferencer; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.security.InvalidParameterException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class HTTPURLProtocolHandlerImpl implements URLProtocolHandler { + + private static Log log = LogFactory.getLog(HTTPURLProtocolHandlerImpl.class); + + public final static String HTTP = "http"; + public final static String HTTPS = "https"; + public final static String FORMDATA = "formdata"; + public final static String[] PROTOCOLS = { HTTP, HTTPS, FORMDATA }; + + private HostnameVerifier hostnameVerifier; + private SSLSocketFactory sslSocketFactory; + + public StreamData dereference(String aUrl, URLDereferencerContext aContext) + throws IOException { + String urlString = aUrl.toLowerCase().trim(); + if (urlString.startsWith(FORMDATA)) { + log.debug("Requested to dereference a formdata url"); + return dereferenceFormData(aUrl, aContext); + } + + URL url = new URL(aUrl); + if ((!HTTP.equalsIgnoreCase(url.getProtocol()) && (!HTTPS + .equalsIgnoreCase(url.getProtocol())))) { + throw new InvalidParameterException("Url " + aUrl + " not supported"); + } + return dereferenceHTTP(url); + } + protected StreamData dereferenceHTTP(URL url) throws IOException { - log.debug("Dereferencing url: "+url); + log.debug("Dereferencing url: " + url); HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); - log.trace("Successfully opened connection"); - return new StreamData(url.toString(), httpConn.getContentType(), httpConn - .getInputStream()); - } - - protected StreamData dereferenceFormData(String aUrl, - URLDereferencerContext aContext) throws IOException { - log.debug("Dereferencing formdata url: " + aUrl); - String[] parts = aUrl.split(":", 2); - FormDataURLSupplier supplier = (FormDataURLSupplier) aContext - .getProperty(FormDataURLSupplier.PROPERTY_KEY_NAME); - if (supplier == null) { - throw new NullPointerException( - "No FormdataUrlSupplier found in provided context"); - } - String contentType = supplier.getFormDataContentType(parts[1]); - InputStream is = supplier.getFormData(parts[1]); - if (is != null) { - return new StreamData(aUrl, contentType, is); - } - return null; - } + if (httpConn instanceof HttpsURLConnection) { + log.trace("Detected ssl connection"); + HttpsURLConnection https = (HttpsURLConnection) httpConn; + if (sslSocketFactory != null) { + log.debug("Setting custom ssl socket factory for ssl connection"); + https.setSSLSocketFactory(sslSocketFactory); + } else { + log.trace("No custom socket factory set"); + } + if (hostnameVerifier != null) { + log.debug("Setting custom hostname verifier"); + https.setHostnameVerifier(hostnameVerifier); + } + } else { + log.trace("No secure connection with: "+url+ " class="+httpConn.getClass()); + } + log.trace("Successfully opened connection"); + return new StreamData(url.toString(), httpConn.getContentType(), httpConn + .getInputStream()); + } + + protected StreamData dereferenceFormData(String aUrl, + URLDereferencerContext aContext) throws IOException { + log.debug("Dereferencing formdata url: " + aUrl); + String[] parts = aUrl.split(":", 2); + FormDataURLSupplier supplier = (FormDataURLSupplier) aContext + .getProperty(FormDataURLSupplier.PROPERTY_KEY_NAME); + if (supplier == null) { + throw new NullPointerException( + "No FormdataUrlSupplier found in provided context"); + } + String contentType = supplier.getFormDataContentType(parts[1]); + InputStream is = supplier.getFormData(parts[1]); + if (is != null) { + return new StreamData(aUrl, contentType, is); + } + return null; + } + + @Override + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + } + + @Override + public void setSSLSocketFactory(SSLSocketFactory socketFactory) { + this.sslSocketFactory = socketFactory; + } + } \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java index d747753f..8853a9c1 100644 --- a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLDereferencer.java @@ -20,6 +20,9 @@ import java.io.IOException; import java.net.MalformedURLException; import java.util.HashMap; import java.util.Map; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,7 +40,10 @@ public class URLDereferencer { private static URLDereferencer instance = new URLDereferencer(); private Map handlerMap = new HashMap(); - + + private HostnameVerifier hostnameVerifier; + private SSLSocketFactory sslSocketFactory; + private URLDereferencer() { registerHandlers(); } @@ -62,7 +68,9 @@ public class URLDereferencer { if (handler == null) { throw new MalformedURLException("No handler for protocol: " + protocol + " found"); - } + } + handler.setHostnameVerifier(hostnameVerifier); + handler.setSSLSocketFactory(sslSocketFactory); return handler.dereference(aUrl, aContext); } @@ -86,5 +94,13 @@ public class URLDereferencer { for (String proto : HTTPURLProtocolHandlerImpl.PROTOCOLS) { handlerMap.put(proto, handler); } + } + + public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { + this.hostnameVerifier = hostnameVerifier; + } + + public void setSSLSocketFactory(SSLSocketFactory socketFactory) { + this.sslSocketFactory = socketFactory; } } \ No newline at end of file diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java index f584f450..f886bd4e 100644 --- a/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java +++ b/utils/src/main/java/at/gv/egiz/bku/utils/urldereferencer/URLProtocolHandler.java @@ -18,6 +18,9 @@ package at.gv.egiz.bku.utils.urldereferencer; import java.io.IOException; import java.net.MalformedURLException; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSocketFactory; public interface URLProtocolHandler { @@ -28,5 +31,9 @@ public interface URLProtocolHandler { * @return the streamdata of this url or null if the url cannot be resolved. * @throws IOException */ - public StreamData dereference(String aUrl, URLDereferencerContext aContext) throws IOException; + public StreamData dereference(String aUrl, URLDereferencerContext aContext) throws IOException; + + public void setSSLSocketFactory(SSLSocketFactory socketFactory); + + public void setHostnameVerifier(HostnameVerifier hostnameVerifier); } \ No newline at end of file -- cgit v1.2.3 From 54aa4703e3d66c5b1a63b8d925fd4c9c1766687c Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 28 Jan 2009 19:40:11 +0000 Subject: activation git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@291 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- BKUApplet/pom.xml | 74 +- .../gv/egiz/bku/online/applet/AppletBKUWorker.java | 74 +- .../bku/online/applet/AppletParameterProvider.java | 57 -- .../at/gv/egiz/bku/online/applet/BKUApplet.java | 106 ++- BKUApplet/src/test/resources/appletTest.html | 2 +- BKULocal/pom.xml | 2 +- .../at/gv/egiz/bku/local/stal/LocalBKUWorker.java | 1 - BKULocalApp/pom.xml | 6 +- BKUOnline/pom.xml | 108 ++- .../egiz/bku/online/webapp/BKURequestHandler.java | 3 + .../stal/service/impl/STALRequestBrokerImpl.java | 8 +- .../gv/egiz/stal/service/impl/STALServiceImpl.java | 18 +- .../stal/service/impl/STALXJAXBContextFactory.java | 10 +- BKUOnline/src/main/webapp/applet.jsp | 14 +- BKUOnline/src/main/webapp/slRequestForm.html | 3 +- STALExt/pom.xml | 2 +- .../java/at/gv/egiz/stal/service/STALPortType.java | 2 +- .../stal/service/translator/STALTranslator.java | 5 +- STALXService/pom.xml | 25 + .../namespaces/cardchannel/service/ATRType.java | 100 +++ .../cardchannel/service/AttributeList.java | 71 ++ .../cardchannel/service/AttributeType.java | 264 +++++++ .../cardchannel/service/CommandAPDUType.java | 154 ++++ .../cardchannel/service/ObjectFactory.java | 172 +++++ .../namespaces/cardchannel/service/ResetType.java | 64 ++ .../cardchannel/service/ResponseAPDUType.java | 161 +++++ .../cardchannel/service/ResponseType.java | 82 +++ .../namespaces/cardchannel/service/ScriptType.java | 85 +++ .../cardchannel/service/VerifyAPDUType.java | 266 +++++++ .../cardchannel/service/package-info.java | 2 + .../at/gv/egiz/stalx/service/STALPortType.java | 45 ++ .../java/at/gv/egiz/stalx/service/STALService.java | 73 ++ .../translator/STALXTranslationHandler.java | 217 ++++++ .../src/main/resources/wsdl/CardChannel.xsd | 148 ++++ STALXService/src/main/resources/wsdl/stal.xsd | 162 +++++ STALXService/src/main/resources/wsdl/stalx.wsdl | 123 ++++ .../stalx/service/ClientJAXBContextFactory.java | 52 ++ .../at/gv/egiz/stalx/service/STALServiceTest.java | 112 +++ bkucommon/pom.xml | 7 +- .../slcommands/impl/AbstractAssocArrayInfobox.java | 6 +- .../impl/CreateXMLSignatureResultImpl.java | 145 ++-- .../slcommands/impl/InfoboxReadResultFileImpl.java | 197 ++--- .../gv/egiz/bku/slcommands/impl/SLResultImpl.java | 6 +- pom.xml | 7 + .../at/gv/egiz/bku/smccstal/AbstractSMCCSTAL.java | 5 +- utils/pom.xml | 5 + .../egiz/idlink/CompressedIdentityLinkFactory.java | 800 ++++++++++----------- .../at/gv/egiz/idlink/IdentityLinkFactory.java | 6 +- .../java/at/gv/egiz/marshal/MarshallerFactory.java | 52 ++ .../gv/egiz/marshal/NamespacePrefixMapperImpl.java | 86 +++ .../gv/egiz/xades/QualifyingPropertiesFactory.java | 418 +++++------ 51 files changed, 3519 insertions(+), 1094 deletions(-) delete mode 100644 BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletParameterProvider.java create mode 100644 STALXService/pom.xml create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ATRType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/AttributeList.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/AttributeType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/CommandAPDUType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ObjectFactory.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ResetType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ResponseAPDUType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ResponseType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/ScriptType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/VerifyAPDUType.java create mode 100644 STALXService/src/main/java/at/buergerkarte/namespaces/cardchannel/service/package-info.java create mode 100644 STALXService/src/main/java/at/gv/egiz/stalx/service/STALPortType.java create mode 100644 STALXService/src/main/java/at/gv/egiz/stalx/service/STALService.java create mode 100644 STALXService/src/main/java/at/gv/egiz/stalx/service/translator/STALXTranslationHandler.java create mode 100644 STALXService/src/main/resources/wsdl/CardChannel.xsd create mode 100644 STALXService/src/main/resources/wsdl/stal.xsd create mode 100644 STALXService/src/main/resources/wsdl/stalx.wsdl create mode 100644 STALXService/src/test/java/at/gv/egiz/stalx/service/ClientJAXBContextFactory.java create mode 100644 STALXService/src/test/java/at/gv/egiz/stalx/service/STALServiceTest.java create mode 100644 utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKUApplet/pom.xml b/BKUApplet/pom.xml index 3b115399..da5dbc6f 100644 --- a/BKUApplet/pom.xml +++ b/BKUApplet/pom.xml @@ -23,35 +23,23 @@ at.gv.egiz true ${project.build.outputDirectory} - META-INF\/ + META-INF\/ + + + + + copy_testapplet + + copy-dependencies + + + ${project.build.directory}/test-classes + at.gv.egiz,commons-logging,iaik + commons-logging,iaik_jce_me4se + true + @@ -80,30 +68,6 @@ true - - maven-dependency-plugin - - - copytestlibs - - copy - - - - - commons-logging - commons-logging - - - iaik - iaik_jce_me4se - - - ${project.build.directory}/test-libs - - - - @@ -132,9 +96,5 @@ BKUCommonGUI 1.0.5-SNAPSHOT - - commons-logging - commons-logging - \ No newline at end of file diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java index 6ac892ec..388f045f 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletBKUWorker.java @@ -22,7 +22,6 @@ import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; import at.gv.egiz.stal.service.STALPortType; -import at.gv.egiz.stal.service.STALService; import at.gv.egiz.stal.service.translator.STALTranslator; import at.gv.egiz.stal.service.translator.TranslationException; import at.gv.egiz.stal.service.types.ErrorResponseType; @@ -31,13 +30,10 @@ import at.gv.egiz.stal.service.types.GetNextRequestType; import at.gv.egiz.stal.service.types.ObjectFactory; import at.gv.egiz.stal.service.types.RequestType; import at.gv.egiz.stal.service.types.ResponseType; -import java.applet.AppletContext; import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBElement; -import javax.xml.namespace.QName; import javax.xml.ws.WebServiceException; /** @@ -46,29 +42,19 @@ import javax.xml.ws.WebServiceException; */ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { - protected AppletContext ctx; - protected AppletParameterProvider params; + protected BKUApplet applet; protected String sessionId; - protected STALPortType stalPort; + private ObjectFactory stalObjFactory = new ObjectFactory(); - private STALTranslator translator = new STALTranslator(); - public AppletBKUWorker(BKUGUIFacade gui, AppletContext ctx, - AppletParameterProvider paramProvider) { + public AppletBKUWorker(BKUApplet applet, BKUGUIFacade gui) { super(gui); - if (ctx == null) { - throw new NullPointerException("Applet context not provided"); - } - if (paramProvider == null) { - throw new NullPointerException("No applet parameters provided"); - } - this.ctx = ctx; - this.params = paramProvider; - - sessionId = params.getAppletParameter(BKUApplet.SESSION_ID); + this.applet = applet; + + sessionId = applet.getParameter(BKUApplet.SESSION_ID); if (sessionId == null) { sessionId = "TestSession"; - log.info("using dummy sessionId " + sessionId); + log.warn("using dummy sessionId " + sessionId); } } @@ -77,9 +63,11 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { gui.showWelcomeDialog(); try { - stalPort = getSTALPort(); + STALPortType stalPort = applet.getSTALPort(); + STALTranslator stalTranslator = applet.getSTALTranslator(); - registerSignRequestHandler(stalPort, sessionId); + addRequestHandler(SignRequest.class, + new AppletHashDataDisplay(stalPort, sessionId)); GetNextRequestResponseType nextRequestResp = stalPort.connect(sessionId); @@ -111,7 +99,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { List stalRequests = new ArrayList(); for (JAXBElement req : requests) { try { - stalRequests.add(translator.translate(req)); + stalRequests.add(stalTranslator.translate(req)); } catch (TranslationException ex) { log.error("Received unknown request from server STAL: " + ex.getMessage()); throw new RuntimeException(ex); @@ -123,7 +111,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { List stalResponses = handleRequest(stalRequests); for (STALResponse stalResponse : stalResponses) { try { - responses.add(translator.translate(stalResponse)); + responses.add(stalTranslator.translate(stalResponse)); } catch (TranslationException ex) { log.error("Received unknown response from STAL: " + ex.getMessage()); throw new RuntimeException(ex); @@ -184,7 +172,7 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { } } - sendRedirect(); + applet.sendRedirect(sessionId); } /** @@ -218,38 +206,4 @@ public class AppletBKUWorker extends AbstractBKUWorker implements Runnable { log.error(e); } } - - protected void sendRedirect() { - try { - URL redirectURL = params.getURLParameter(BKUApplet.REDIRECT_URL, - sessionId); - String redirectTarget = params.getAppletParameter(BKUApplet.REDIRECT_TARGET); - if (redirectTarget == null) { - log.info("Done. Redirecting to " + redirectURL + " ..."); - ctx.showDocument(redirectURL); - } else { - log.info("Done. Redirecting to " + redirectURL + " (target=" + redirectTarget + ") ..."); - ctx.showDocument(redirectURL, redirectTarget); - } - } catch (MalformedURLException ex) { - log.warn("Failed to redirect: " + ex.getMessage(), ex); - // gui.showErrorDialog(errorMsg, okListener, actionCommand) - } - } - - private STALPortType getSTALPort() throws MalformedURLException { - URL wsdlURL = params.getURLParameter(BKUApplet.WSDL_URL); - log.debug("STAL WSDL at " + wsdlURL); - QName endpointName = new QName(BKUApplet.STAL_WSDL_NS, - BKUApplet.STAL_SERVICE); - STALService stal = new STALService(wsdlURL, endpointName); - return stal.getSTALPort(); - } - - private void registerSignRequestHandler(STALPortType stalPort, String sessionId) { - log.debug("register SignRequestHandler (resolve hashdata via STAL Webservice)"); - AppletHashDataDisplay handler = new AppletHashDataDisplay(stalPort, - sessionId); - addRequestHandler(SignRequest.class, handler); - } } diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletParameterProvider.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletParameterProvider.java deleted file mode 100644 index 42e2d6ff..00000000 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletParameterProvider.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package at.gv.egiz.bku.online.applet; - -import java.net.MalformedURLException; -import java.net.URL; - -/** - * - * @author Clemens Orthacker - */ -public interface AppletParameterProvider { - - /** - * Applet configuration parameters - * - * @param paramKey - * @return null if no parameter is provided for the given key - */ - String getAppletParameter(String paramKey); - - /** - * Get applet configuration parameter as (absolute) URL - * - * @param paramKey - * @return a URL - * @throws MalformedURLException if configured URL is invalid - * or no parameter is provided for the given key - */ - URL getURLParameter(String paramKey) throws MalformedURLException; - - /** - * Get applet configuration parameter as (absolute) URL - * - * @param paramKey - * @param sessionId adds the jsessionid to the URL - * @return a URL - * @throws MalformedURLException if configured URL is invalid - * or no parameter is provided for the given key - */ - URL getURLParameter(String paramKey, String sessionId) throws MalformedURLException; -} diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java index 5e60ed3e..d4b2018d 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/BKUApplet.java @@ -16,8 +16,10 @@ */ package at.gv.egiz.bku.online.applet; +import at.gv.egiz.bku.gui.BKUGUIFacade.Style; import at.gv.egiz.bku.gui.DefaultHelpListener; import at.gv.egiz.bku.gui.AbstractHelpListener; +import at.gv.egiz.stal.service.translator.STALTranslator; import java.net.MalformedURLException; import java.net.URL; import java.util.Locale; @@ -30,15 +32,18 @@ import org.apache.commons.logging.LogFactory; import at.gv.egiz.bku.gui.BKUGUIFacade; import at.gv.egiz.bku.gui.BKUGUIFactory; +import at.gv.egiz.stal.service.STALPortType; +import at.gv.egiz.stal.service.STALService; +import java.awt.Container; +import javax.xml.namespace.QName; /** * Note: all swing code is executed by the event dispatch thread (see * BKUGUIFacade) */ -public class BKUApplet extends JApplet implements AppletParameterProvider { +public class BKUApplet extends JApplet { private static Log log = LogFactory.getLog(BKUApplet.class); - /** * Applet parameter keys */ @@ -55,18 +60,15 @@ public class BKUApplet extends JApplet implements AppletParameterProvider { // public static final String HASHDATA_DISPLAY_INTERNAL = "internal"; // public static final String HASHDATA_DISPLAY_BROWSER = "browser"; public static final String HASHDATA_DISPLAY_FRAME = "frame"; - /** * STAL WSDL namespace and service name */ public static final String STAL_WSDL_NS = "http://www.egiz.gv.at/wsdl/stal"; public static final String STAL_SERVICE = "STALService"; - /** * Dummy session id, used if no sessionId parameter is provided */ protected static final String TEST_SESSION_ID = "TestSession"; - /** * STAL */ @@ -81,17 +83,17 @@ public class BKUApplet extends JApplet implements AppletParameterProvider { public void init() { log.info("Welcome to MOCCA"); log.debug("Called init()"); - + HttpsURLConnection.setDefaultSSLSocketFactory(InternalSSLSocketFactory.getInstance()); - String locale = getAppletParameter(LOCALE); + String locale = getParameter(LOCALE); if (locale != null) { this.setLocale(new Locale(locale)); } - log.debug("setting locale to " + getLocale()); + log.debug("setting locale: " + getLocale()); BKUGUIFacade.Style guiStyle; - String guiStyleParam = getAppletParameter(GUI_STYLE); + String guiStyleParam = getParameter(GUI_STYLE); if ("advanced".equals(guiStyleParam)) { guiStyle = BKUGUIFacade.Style.advanced; } else if ("tiny".equals(guiStyleParam)) { @@ -99,30 +101,33 @@ public class BKUApplet extends JApplet implements AppletParameterProvider { } else { guiStyle = BKUGUIFacade.Style.simple; } - + log.debug("setting gui-style: " + guiStyle); + URL backgroundImgURL = null; try { - backgroundImgURL = getURLParameter(BACKGROUND_IMG); + backgroundImgURL = getURLParameter(BACKGROUND_IMG, null); + log.debug("setting background: " + backgroundImgURL); } catch (MalformedURLException ex) { log.warn("failed to load applet background image: " + ex.getMessage() + ", using default"); } - + AbstractHelpListener helpListener = null; try { - URL helpURL = getURLParameter(HELP_URL); -// helpListener = new BrowserHelpListener(getAppletContext(), helpURL, getLocale()); - helpListener = new DefaultHelpListener(getAppletContext(), helpURL, getLocale()); + helpListener = new DefaultHelpListener(getAppletContext(), + getURLParameter(HELP_URL, null), getLocale()); + if (log.isDebugEnabled()) { + log.debug("setting helpURL: " + getURLParameter(HELP_URL, null)); + } } catch (MalformedURLException ex) { log.warn("failed to load help URL: " + ex.getMessage() + ", disabling help"); } - - BKUGUIFacade gui = BKUGUIFactory.createGUI(getContentPane(), - getLocale(), - guiStyle, - backgroundImgURL, + + BKUGUIFacade gui = createGUI(getContentPane(), getLocale(), + guiStyle, + backgroundImgURL, helpListener); - worker = new AppletBKUWorker(gui, getAppletContext(), this); + worker = new AppletBKUWorker(this, gui); } @Override @@ -145,15 +150,7 @@ public class BKUApplet extends JApplet implements AppletParameterProvider { log.debug("Called destroy()"); } - @Override - public String getAppletParameter(String paramKey) { - String param = getParameter(paramKey); - log.info("applet parameter: " + paramKey + ": " + param); - return param; - } - - @Override - public URL getURLParameter(String paramKey, String sessionId) throws MalformedURLException { + protected URL getURLParameter(String paramKey, String sessionId) throws MalformedURLException { String urlParam = getParameter(paramKey); if (urlParam != null) { URL codebase = getCodeBase(); @@ -173,15 +170,54 @@ public class BKUApplet extends JApplet implements AppletParameterProvider { } catch (MalformedURLException ex) { log.error("applet paremeter " + urlParam + " is not a valid URL: " + ex.getMessage()); throw ex; - } + } } else { log.error("applet paremeter " + urlParam + " not set"); throw new MalformedURLException(urlParam + " not set"); } } - - @Override - public URL getURLParameter(String paramKey) throws MalformedURLException { - return getURLParameter(paramKey, null); + + /** + * provides a means to for subclasses to inject a different GUI + */ + protected BKUGUIFacade createGUI(Container contentPane, + Locale locale, + Style guiStyle, + URL backgroundImgURL, + AbstractHelpListener helpListener) { + return BKUGUIFactory.createGUI(contentPane, + locale, + guiStyle, + backgroundImgURL, + helpListener); + } + + protected STALPortType getSTALPort() throws MalformedURLException { + URL wsdlURL = getURLParameter(WSDL_URL, null); + log.debug("setting STAL WSDL: " + wsdlURL); + QName endpointName = new QName(STAL_WSDL_NS, STAL_SERVICE); + STALService stal = new STALService(wsdlURL, endpointName); + return stal.getSTALPort(); + } + + protected STALTranslator getSTALTranslator() { + return new STALTranslator(); + } + + protected void sendRedirect(String sessionId) { + try { + URL redirectURL = getURLParameter(REDIRECT_URL, sessionId); + String redirectTarget = getParameter(REDIRECT_TARGET); + if (redirectTarget == null) { + log.info("Done. Redirecting to " + redirectURL + " ..."); + getAppletContext().showDocument(redirectURL); + } else { + log.info("Done. Redirecting to " + redirectURL + " (target=" + redirectTarget + ") ..."); + getAppletContext().showDocument(redirectURL, redirectTarget); + } + } catch (MalformedURLException ex) { + log.warn("Failed to redirect: " + ex.getMessage(), ex); + // gui.showErrorDialog(errorMsg, okListener, actionCommand) + } } } diff --git a/BKUApplet/src/test/resources/appletTest.html b/BKUApplet/src/test/resources/appletTest.html index c8bd99d3..4a768f91 100644 --- a/BKUApplet/src/test/resources/appletTest.html +++ b/BKUApplet/src/test/resources/appletTest.html @@ -18,7 +18,7 @@
diff --git a/BKULocal/pom.xml b/BKULocal/pom.xml index 0f5757b8..5fd142a2 100644 --- a/BKULocal/pom.xml +++ b/BKULocal/pom.xml @@ -9,7 +9,7 @@ BKULocal war BKU Local - 1.0.4-SNAPSHOT + 1.0.2-SNAPSHOT scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKULocal diff --git a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java index 91d0aba0..61cc7c4c 100644 --- a/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java +++ b/BKULocal/src/main/java/at/gv/egiz/bku/local/stal/LocalBKUWorker.java @@ -22,7 +22,6 @@ import at.gv.egiz.stal.QuitRequest; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; -import at.gv.egiz.stal.ext.APDUScriptRequest; import java.util.List; import javax.swing.JDialog; diff --git a/BKULocalApp/pom.xml b/BKULocalApp/pom.xml index 52bc4e36..79a270d8 100644 --- a/BKULocalApp/pom.xml +++ b/BKULocalApp/pom.xml @@ -5,10 +5,10 @@ 1.0.5-SNAPSHOT 4.0.0 - at.gv.egiz.bku + at.gv.egiz BKULocalApp BKU Local App - 1.0.4-SNAPSHOT + 1.0.2-SNAPSHOT @@ -76,7 +76,7 @@ at.gv.egiz BKULocal - 1.0.4-SNAPSHOT + 1.0.2-SNAPSHOT war diff --git a/BKUOnline/pom.xml b/BKUOnline/pom.xml index c82cfc1e..fc5f04fa 100644 --- a/BKUOnline/pom.xml +++ b/BKUOnline/pom.xml @@ -1,4 +1,4 @@ - + bku @@ -56,25 +56,20 @@ 1.0.5-SNAPSHOT compile - - - at.gv.egiz - BKUApplet - 1.0.5-SNAPSHOT - provided - - + at.gv.egiz STALService 1.0.5-SNAPSHOT - at.gv.egiz STALXService 1.0.2-SNAPSHOT - + @@ -102,10 +97,30 @@ com.sun.xml.stream 1.0.1 + + + at.gv.egiz + BKUApplet + 1.0.5-SNAPSHOT + provided + + + at.gv.egiz + BKUAppletExt + 1.0.2-SNAPSHOT + provided + + + iaik + iaik_jce_me4se + provided + + - - Tomcat60 - scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKUOnline scm:svn:svn://svn.egovlabs.gv.at/svnroot/mocca/trunk/BKUOnline @@ -117,75 +132,31 @@ maven-dependency-plugin - copyapplet-dependencies + copy_applet copy-dependencies ${project.build.directory}/${project.build.finalName}/applet - - at.gv.egiz - BKUApplet - true + at.gv.egiz,commons-logging,iaik + BKUApplet,BKUAppletExt,commons-logging,iaik_jce_me4se true - - - - copyapplet - - copy - - - ${project.build.directory}/${project.build.finalName}/applet - - - commons-logging - commons-logging - - - iaik - iaik_jce_me4se - - + true - + maven-war-plugin 2.0.2 - - true - + true - - ${project.version}-r${buildNumber} - + ${project.version}-r${buildNumber} @@ -211,7 +182,7 @@ - jaxb-generate + jaxb-generate-stal @@ -245,4 +216,7 @@ - \ No newline at end of file + + Tomcat60 + + diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java index d9be0981..c758bcee 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java @@ -133,6 +133,9 @@ public class BKURequestHandler extends SpringBKUServlet { .getFormData("appletHashDataDisplay"), charset); String localeFormParam = getStringFromStream(bindingProcessor .getFormData("locale"), charset); + String extension = getStringFromStream(bindingProcessor + .getFormData("appletExtension"), charset); + if (width != null) { try { log.trace("Found applet width parameter: " + width); diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java index a617c61f..81b70b7c 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALRequestBrokerImpl.java @@ -19,19 +19,17 @@ package at.gv.egiz.stal.service.impl; import at.gv.egiz.stal.ErrorResponse; import at.gv.egiz.stal.HashDataInput; -import at.gv.egiz.stal.InfoboxReadRequest; import at.gv.egiz.stal.QuitRequest; import at.gv.egiz.stal.STALRequest; import at.gv.egiz.stal.STALResponse; import at.gv.egiz.stal.SignRequest; import at.gv.egiz.stal.service.translator.STALTranslator; import at.gv.egiz.stal.service.translator.TranslationException; -import at.gv.egiz.stal.service.types.InfoboxReadRequestType; import at.gv.egiz.stal.service.types.ObjectFactory; import at.gv.egiz.stal.service.types.QuitRequestType; import at.gv.egiz.stal.service.types.RequestType; import at.gv.egiz.stal.service.types.ResponseType; -import at.gv.egiz.stal.service.types.SignRequestType; +import at.gv.egiz.stalx.service.translator.STALXTranslationHandler; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -71,10 +69,12 @@ public class STALRequestBrokerImpl implements STALRequestBroker { if (timeoutMillisec <= 0) timeoutMillisec = DEFAULT_TIMEOUT_MS; timeout = timeoutMillisec; -// translator.registerTranslationHandler(handler); requests = new ArrayList>(); responses = new ArrayList>(); hashDataInputs = new ArrayList(); + + // register handler for STAL-X + translator.registerTranslationHandler(new STALXTranslationHandler()); } /** diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java index afeba9cb..a30c6bb2 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java @@ -18,6 +18,8 @@ package at.gv.egiz.stal.service.impl; //import at.buergerkarte.namespaces.cardchannel.service.CommandAPDUType; //import at.buergerkarte.namespaces.cardchannel.service.ScriptType; +import at.buergerkarte.namespaces.cardchannel.service.CommandAPDUType; +import at.buergerkarte.namespaces.cardchannel.service.ScriptType; import at.gv.egiz.bku.binding.BindingProcessor; import at.gv.egiz.bku.binding.BindingProcessorManager; import at.gv.egiz.bku.binding.Id; @@ -78,8 +80,10 @@ public class STALServiceImpl implements STALPortType { @Resource protected WebServiceContext wsContext; protected IdFactory idF = IdFactory.getInstance(); + /** JAXB ObjectFactories */ private at.gv.egiz.stal.service.types.ObjectFactory stalObjFactory = new at.gv.egiz.stal.service.types.ObjectFactory(); -// private at.buergerkarte.namespaces.cardchannel.service.ObjectFactory ccObjFactory = new at.buergerkarte.namespaces.cardchannel.service.ObjectFactory(); + /** don't confuse with at.buergerkarte.namespaces.cardchannel */ + private at.buergerkarte.namespaces.cardchannel.service.ObjectFactory ccObjFactory = new at.buergerkarte.namespaces.cardchannel.service.ObjectFactory(); @Override public GetNextRequestResponseType connect(String sessId) { @@ -331,12 +335,12 @@ public class STALServiceImpl implements STALPortType { if (responsesIn == null) { log.info("[TestSession] received CONNECT, return dummy requests "); -// ScriptType scriptT = ccObjFactory.createScriptType(); -// CommandAPDUType cmd = ccObjFactory.createCommandAPDUType(); -// cmd.setValue("TestSession CardChannelCMD 1234".getBytes()); -// scriptT.getResetOrCommandAPDUOrVerifyAPDU().add(cmd); -// reqs.add(ccObjFactory.createScript(scriptT)); - addDummyRequests(reqs); +// addDummyRequests(reqs); + ScriptType scriptT = ccObjFactory.createScriptType(); + CommandAPDUType cmd = ccObjFactory.createCommandAPDUType(); + cmd.setValue("TestSession CardChannelCMD 1234".getBytes()); + scriptT.getResetOrCommandAPDUOrVerifyAPDU().add(cmd); + reqs.add(ccObjFactory.createScript(scriptT)); } else if (responsesIn != null && responsesIn.size() > 0 && responsesIn.get(0).getValue() instanceof ErrorResponseType) { log.info("[TestSession] received ErrorResponse, return QUIT request"); QuitRequestType quitT = stalObjFactory.createQuitRequestType(); diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALXJAXBContextFactory.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALXJAXBContextFactory.java index 92559254..9caf950f 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALXJAXBContextFactory.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALXJAXBContextFactory.java @@ -47,11 +47,11 @@ public class STALXJAXBContextFactory implements JAXBContextFactory { } List classes = new ArrayList(); classes.addAll(classesToBind); -// Class ccOF = at.buergerkarte.namespaces.cardchannel.service.ObjectFactory.class; -// if (!classes.contains(ccOF)) { -// log.debug("adding " + ccOF + " to JAXBContext seed"); -// classes.add(ccOF); -// } + Class ccOF = at.buergerkarte.namespaces.cardchannel.service.ObjectFactory.class; + if (!classes.contains(ccOF)) { + log.debug("adding " + ccOF + " to JAXBContext seed"); + classes.add(ccOF); + } //TODO add typeReference? diff --git a/BKUOnline/src/main/webapp/applet.jsp b/BKUOnline/src/main/webapp/applet.jsp index 3bf0ff40..ada48f22 100644 --- a/BKUOnline/src/main/webapp/applet.jsp +++ b/BKUOnline/src/main/webapp/applet.jsp @@ -39,6 +39,16 @@ String backgroundImg = (String) session.getAttribute("appletBackground"); String guiStyle = (String) session.getAttribute("appletGuiStyle"); String locale = (String) session.getAttribute("locale"); + + String appletClass, appletArchive; + //if (Boolean.parseBoolean((String) session.getAttribute("appletExtension"))) { + if ("activation".equals(guiStyle)) { + appletArchive = "BKUAppletExt.jar"; + appletClass = "at.gv.egiz.bku.online.applet.ext.BKUAppletExt.class"; + } else { + appletArchive = "BKUApplet.jar"; + appletClass = "at.gv.egiz.bku.online.applet.BKUApplet.class"; + } %> + + + diff --git a/BKUWebStart/src/main/webapp/launch.jnlp b/BKUWebStart/src/main/webapp/launch.jnlp new file mode 100644 index 00000000..d51d9d21 --- /dev/null +++ b/BKUWebStart/src/main/webapp/launch.jnlp @@ -0,0 +1,30 @@ + + + + BKU Web Start + EGIZ + + BKU WebStart (aka. Lokale BKU) + BKU WebStart + + + + + + + + + + + + + + + + + + + + + + diff --git a/BKUWebStart/src/main/webapp/mocca_tiny.png b/BKUWebStart/src/main/webapp/mocca_tiny.png new file mode 100644 index 00000000..1f125d9b Binary files /dev/null and b/BKUWebStart/src/main/webapp/mocca_tiny.png differ diff --git a/BKUWebStart/src/main/webapp/splash.png b/BKUWebStart/src/main/webapp/splash.png new file mode 100644 index 00000000..72c1d868 Binary files /dev/null and b/BKUWebStart/src/main/webapp/splash.png differ diff --git a/pom.xml b/pom.xml index 10765f01..ec3465b9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,3 +1,4 @@ + 4.0.0 at.gv.egiz @@ -22,7 +23,9 @@ STALExt STALXService BKUAppletExt - + BKUWebStart + + mcentner @@ -239,4 +242,4 @@ - \ No newline at end of file + diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java deleted file mode 100644 index 5e191c79..00000000 --- a/utils/src/main/java/at/gv/egiz/bku/local/ui/BKUControllerInterface.java +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.bku.local.ui; - -public interface BKUControllerInterface { - - public void shutDown(); - -} diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java deleted file mode 100644 index fef113fd..00000000 --- a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialog.java +++ /dev/null @@ -1,202 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.bku.local.ui; - -import java.awt.AWTException; -import java.awt.Image; -import java.awt.MenuItem; -import java.awt.PopupMenu; -import java.awt.SystemTray; -import java.awt.TrayIcon; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.IOException; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.ResourceBundle; - -import javax.imageio.ImageIO; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class TrayIconDialog implements TrayIconDialogInterface { - - private static Log log = LogFactory.getLog(TrayIconDialog.class); - private static TrayIconDialogInterface instance; - private boolean isSupported; - private BKUControllerInterface shutDown; - private TrayIcon trayIcon = null; - private ResourceBundle resourceBundle = null; - - private TrayIconDialog() { - } - - private void displayTrayMsg(String captionID, String messageID, - TrayIcon.MessageType type) { - if ((isSupported) && (resourceBundle != null)) { - try { - trayIcon.displayMessage(resourceBundle.getString(captionID), - resourceBundle.getString(messageID), type); - } catch (Exception ex) { - log.error(ex); - } - } - } - - /* - * (non-Javadoc) - * - * @see - * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayInfo(java.lang.String - * , java.lang.String) - */ - public void displayInfo(String captionID, String messageID) { - displayTrayMsg(captionID, messageID, TrayIcon.MessageType.INFO); - } - - /* - * (non-Javadoc) - * - * @see - * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayWarning(java.lang - * .String, java.lang.String) - */ - public void displayWarning(String captionID, String messageID) { - displayTrayMsg(captionID, messageID, TrayIcon.MessageType.WARNING); - } - - /* - * (non-Javadoc) - * - * @see - * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#displayError(java.lang. - * String, java.lang.String) - */ - public void displayError(String captionID, String messageID) { - displayTrayMsg(captionID, messageID, TrayIcon.MessageType.ERROR); - } - - /* - * (non-Javadoc) - * - * @see - * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#init(java.util.ResourceBundle - * ) - */ - public void init(ResourceBundle resourceBundel) { - this.resourceBundle = resourceBundel; - isSupported = SystemTray.isSupported(); - log.info("Trayicon supported: " + isSupported); - try { - if (isSupported) { - SystemTray tray = SystemTray.getSystemTray(); - Image image = ImageIO.read(getClass().getClassLoader() - .getResourceAsStream("at/gv/egiz/bku/local/ui/favicon.png")); - PopupMenu popup = new PopupMenu(); - MenuItem exitItem = new MenuItem(resourceBundel - .getString("TrayMenu.Shutdown")); - popup.add(exitItem); - exitItem.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - log.info("Calling Shutdown"); - if (shutDown != null) { - shutDown.shutDown(); - } - } - }); - - trayIcon = new TrayIcon(image, "BKULogo", popup); - trayIcon.setImageAutoSize(true); - trayIcon.setToolTip(resourceBundel.getString("TrayMenu.Tooltip")); - try { - tray.add(trayIcon); - } catch (AWTException e) { - log.error("TrayIcon could not be added.", e); - isSupported = false; - } - } - } catch (IOException e) { - log.error(e); - } - } - - /* - * (non-Javadoc) - * - * @see - * at.gv.egiz.bku.local.ui.TrayIconDialogInterface#setShutdownHook(at.gv.egiz - * .bku.local.ui.BKUControllerInterface) - */ - public void setShutdownHook(BKUControllerInterface shutDown) { - this.shutDown = shutDown; - } - - @SuppressWarnings("unchecked") - public synchronized static TrayIconDialogInterface getInstance() { - ClassLoader cl = TrayIconDialog.class.getClassLoader(); - if (instance == null) { - if (cl.toString().equals(cl.getParent().toString())) { - instance = new TrayIconDialog(); - return instance; - } - ClassLoader parent = cl; - while (!parent.toString().equals(cl.getParent().toString())) { - parent = parent.getParent(); - } - try { - Class otherClassInstance = (Class) parent - .loadClass(TrayIconDialog.class.getName()); - Method getInstanceMethod = otherClassInstance.getDeclaredMethod( - "getInstance", new Class[] {}); - Object otherSingleton = getInstanceMethod.invoke(null, new Object[] {}); - instance = (TrayIconDialogInterface) Proxy.newProxyInstance(cl, - new Class[] { TrayIconDialogInterface.class }, - new PassThroughProxyHandler(otherSingleton)); - } catch (ClassNotFoundException ce) { - instance = new TrayIconDialog(); - } catch (Exception e) { - log.error(e); - instance = new TrayIconDialog(); - } - return instance; - } - return instance; - } - - /** - * - * Only works for public methods - * - */ - static class PassThroughProxyHandler implements InvocationHandler { - private final Object delegate; - - public PassThroughProxyHandler(Object delegate) { - this.delegate = delegate; - } - - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable { - Method delegateMethod = delegate.getClass().getMethod(method.getName(), - method.getParameterTypes()); - return delegateMethod.invoke(delegate, args); - } - } - -} diff --git a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java b/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java deleted file mode 100644 index 87c64102..00000000 --- a/utils/src/main/java/at/gv/egiz/bku/local/ui/TrayIconDialogInterface.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.bku.local.ui; - -import java.util.ResourceBundle; - -public interface TrayIconDialogInterface { - - public abstract void displayInfo(String captionID, String messageID); - - public abstract void displayWarning(String captionID, String messageID); - - public abstract void displayError(String captionID, String messageID); - - public abstract void init(ResourceBundle resourceBundel); - - public abstract void setShutdownHook(BKUControllerInterface shutDown); - -} \ No newline at end of file -- cgit v1.2.3 From b5eef23539b60eb2cc835fa264fddeba3a63d3b2 Mon Sep 17 00:00:00 2001 From: clemenso Date: Fri, 12 Jun 2009 12:40:58 +0000 Subject: typo git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@359 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java index ccebcc81..112de2b6 100644 --- a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java +++ b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java @@ -39,7 +39,7 @@ public class MarshallerFactory { m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); } log.trace("setting marshaller property NamespacePrefixMapper"); - m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperImpl()); + m.setProperty("com.sun.xml.bind.NamespacePrefixMapper", new NamespacePrefixMapperImpl()); } catch (PropertyException ex) { log.info("failed to set marshaller property: " + ex.getMessage()); } -- cgit v1.2.3 From 3d19a8ff1e34409b2de683cf603a4fd902efda34 Mon Sep 17 00:00:00 2001 From: clemenso Date: Wed, 17 Jun 2009 09:15:13 +0000 Subject: typo: correct property name com.sun.xml.bind.namespacePrefixMapper git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@365 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java index 112de2b6..ccebcc81 100644 --- a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java +++ b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java @@ -39,7 +39,7 @@ public class MarshallerFactory { m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); } log.trace("setting marshaller property NamespacePrefixMapper"); - m.setProperty("com.sun.xml.bind.NamespacePrefixMapper", new NamespacePrefixMapperImpl()); + m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperImpl()); } catch (PropertyException ex) { log.info("failed to set marshaller property: " + ex.getMessage()); } -- cgit v1.2.3 From 696f0c337fdfa533ea3398c60a3d6ae4d0748d6c Mon Sep 17 00:00:00 2001 From: clemenso Date: Thu, 9 Jul 2009 12:07:07 +0000 Subject: validationEventLogger git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@402 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../gv/egiz/bku/slcommands/SLCommandFactory.java | 4 ++ .../gv/egiz/validation/ValidationEventLogger.java | 55 ++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java index 1ef94e81..fe27bc54 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java @@ -27,6 +27,7 @@ import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; +import javax.xml.bind.ValidationEvent; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; @@ -48,6 +49,8 @@ import at.gv.egiz.bku.slexceptions.SLRuntimeException; import at.gv.egiz.bku.utils.DebugReader; import at.gv.egiz.slbinding.RedirectEventFilter; import at.gv.egiz.slbinding.RedirectUnmarshallerListener; +import at.gv.egiz.validation.ValidationEventLogger; +import javax.xml.bind.ValidationEventHandler; public class SLCommandFactory { @@ -276,6 +279,7 @@ public class SLCommandFactory { unmarshaller.setSchema(slSchema); } log.trace("Before unmarshal()."); + unmarshaller.setEventHandler(new ValidationEventLogger()); object = unmarshaller.unmarshal(filteredReader); log.trace("After unmarshal()."); } catch (UnmarshalException e) { diff --git a/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java b/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java new file mode 100644 index 00000000..0fafdd7f --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.validation; + +import javax.xml.bind.ValidationEvent; +import javax.xml.bind.ValidationEventHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author Clemens Orthacker + */ +public class ValidationEventLogger implements ValidationEventHandler { + + protected static final Log log = LogFactory.getLog(ValidationEventLogger.class); + + /** + * + * @param event + * @return false, terminate the current unmarshal, validate, or marshal operation after handling this warning/error + * (except for WARNING validation events) + */ + @Override + public boolean handleEvent(ValidationEvent event) { + switch (event.getSeverity()) { + case ValidationEvent.WARNING: + log.info(event.getMessage()); + return true; + case ValidationEvent.ERROR: + log.warn(event.getMessage()); + return false; + case ValidationEvent.FATAL_ERROR: + log.error(event.getMessage()); + return false; + default: + log.debug(event.getMessage()); + return false; + } + } +} -- cgit v1.2.3 From bd070e82c276afb8c1c3a9ddc3b5712783760881 Mon Sep 17 00:00:00 2001 From: mcentner Date: Tue, 29 Sep 2009 17:36:06 +0000 Subject: Logging issues fixed: - Added possibility to configure logging of BKUWebstart. Logging is now configured from log4j configuration deployed with BKUWebstart in a first step. In a second step the webstart launcher looks for a log4j configuration file in the user's mooca configuration directory and updates the log4j configuration. - Logging of IAIK PKI properly initialized. IAIK PKI does not mess with the log4j configuration any longer. - Changed log4j accordingly (an appender is now needed as IAIK PKI does not reconfigure log4j any longer). Added css-stylesheet to ErrorResponses issued by the BKU to improve the presentation to the user. Changed dependencies of BKUWebStart (see Issue#469 https://egovlabs.gv.at/tracker/index.php?func=detail&aid=469&group_id=13&atid=134). DataURLConnection now uses the request encoding of SL < 1.2. application/x-www-form-urlencoded is now used as default encoding method. multipart/form-data is used only if transfer parameters are present in the request that require a Content-Type parameter. This can only be set with multipart/form-data. This is not in conformance with SL 1.2, however it should improve compatibility with applications. Therefore, removed the ability to configure the DataURLConnection implementation class. DataURLConnection now uses a streaming implementation for encoding of application/x-www-form-urlencoded requests. XWWWFormUrlImputDecoder now uses a streaming implementation for decoding of application/x-www-form-urlencoded requests. Fixed Bug in SLResultPart that caused a binary response to be provided as parameter "XMLResponse" in a multipart/form-data encoded request to DataURL. SLCommandFactory now supports unmarshalling of SL < 1.2 requests in order issue meaningful error messages. Therefore, the marshaling context for response marshaling had to be separated from the marshaling context for requests in order to avoid the marshaling of SL < 1.2 namespace prefixes in SL 1.2 responses. Target attribute in QualifiedProperties is now marshaled. (see Issue#470 https://egovlabs.gv.at/tracker/index.php?func=detail&aid=470&group_id=13&atid=134) Reporting of XML validation errors improved. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@510 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- BKULocal/src/main/resources/log4j.properties | 2 +- BKULocal/src/main/webapp/errorresponse.css | 12 + BKUOnline/src/main/webapp/errorresponse.css | 12 + BKUWebStart/pom.xml | 14 +- .../java/at/gv/egiz/bku/webstart/Configurator.java | 26 +- .../java/at/gv/egiz/bku/webstart/Container.java | 11 +- .../java/at/gv/egiz/bku/webstart/Launcher.java | 22 +- .../gv/egiz/bku/webstart/LogSecurityManager.java | 9 +- .../java/at/gv/egiz/bku/webstart/TLSServerCA.java | 9 +- .../at/gv/egiz/bku/webstart/gui/AboutDialog.java | 7 +- .../bku/webstart/gui/PINManagementInvoker.java | 7 +- BKUWebStart/src/main/resources/log4j.properties | 20 +- .../at/gv/egiz/bku/webstart/ConfiguratorTest.java | 2 - BKUWebStartPackage/pom.xml | 3 +- .../main/java/at/gv/egiz/bku/binding/DataUrl.java | 9 +- .../at/gv/egiz/bku/binding/DataUrlConnection.java | 2 +- .../gv/egiz/bku/binding/DataUrlConnectionImpl.java | 342 ++++++- .../gv/egiz/bku/binding/HTTPBindingProcessor.java | 29 +- .../bku/binding/LegacyDataUrlConnectionImpl.java | 259 ----- .../egiz/bku/binding/XWWWFormUrlInputDecoder.java | 83 +- .../egiz/bku/binding/XWWWFormUrlInputIterator.java | 376 +++++++ .../egiz/bku/binding/multipart/SLResultPart.java | 41 +- .../at/gv/egiz/bku/conf/CertValidatorImpl.java | 24 + .../java/at/gv/egiz/bku/conf/IAIKCommonsLog.java | 144 +++ .../at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java | 59 ++ .../gv/egiz/bku/slcommands/SLCommandFactory.java | 51 +- .../egiz/bku/slcommands/SLMarshallerFactory.java | 172 ++++ .../java/at/gv/egiz/bku/slcommands/SLResult.java | 8 +- .../slcommands/impl/AbstractAssocArrayInfobox.java | 13 +- .../impl/CreateXMLSignatureResultImpl.java | 15 +- .../egiz/bku/slcommands/impl/ErrorResultImpl.java | 6 +- .../bku/slcommands/impl/GetStatusCommandImpl.java | 2 - .../bku/slcommands/impl/GetStatusResultImpl.java | 4 +- .../slcommands/impl/IdentityLinkInfoboxImpl.java | 1 - .../slcommands/impl/InfoboxReadResultFileImpl.java | 15 +- .../bku/slcommands/impl/InfoboxReadResultImpl.java | 4 +- .../slcommands/impl/InfoboxUpdateResultImpl.java | 4 +- .../slcommands/impl/NullOperationResultImpl.java | 4 +- .../gv/egiz/bku/slcommands/impl/SLResultImpl.java | 94 +- .../egiz/bku/slcommands/impl/xsect/DataObject.java | 1 - .../egiz/bku/slcommands/impl/xsect/Signature.java | 18 +- .../egiz/bku/slexceptions/SLExceptionMessages.java | 6 + .../egiz/bku/slexceptions/SLVersionException.java | 28 + .../egiz/bku/slcommands/schema/Core.20020225.xsd | 33 + .../egiz/bku/slcommands/schema/Core.20020831.xsd | 10 + .../slexceptions/SLExceptionMessages.properties | 7 +- .../slexceptions/SLExceptionMessages_en.properties | 4 + .../bku/binding/XWWWFormUrlInputIteratorTest.java | 152 +++ .../egiz/bku/slcommands/SLCommandFactoryTest.java | 7 +- .../impl/CreateXMLSignatureComandImplTest.java | 9 +- .../bku/slcommands/impl/ErrorResultImplTest.java | 2 +- .../slcommands/impl/InfoboxReadComandImplTest.java | 9 +- .../impl/NullOperationResultImplTest.java | 2 +- .../impl/SVPersonendatenInfoboxImplTest.java | 15 +- .../securitylayer/_1/TransformsInfoType.java | 21 +- .../_20020225_/ErrorResponseType.java | 98 ++ .../securitylayer/_20020225_/ObjectFactory.java | 280 ++++++ .../securitylayer/_20020225_/package-info.java | 9 + .../securitylayer/_20020831_/ObjectFactory.java | 112 +++ .../gv/egiz/bku/utils/URLEncodingInputStream.java | 62 ++ .../gv/egiz/bku/utils/URLEncodingOutputStream.java | 134 +++ .../at/gv/egiz/bku/utils/URLEncodingWriter.java | 57 ++ .../java/at/gv/egiz/marshal/MarshallerFactory.java | 12 +- .../java/at/gv/egiz/marshal/NamespacePrefix.java | 34 - .../gv/egiz/marshal/NamespacePrefixMapperImpl.java | 54 +- .../ReportingValidationEventHandler.java | 64 ++ .../gv/egiz/validation/ValidationEventLogger.java | 55 - .../gv/egiz/xades/QualifyingPropertiesFactory.java | 8 +- .../bku/utils/URLEncodingOutputStreamTest.java | 147 +++ utils/src/test/resources/BigRequest.xml | 1060 ++++++++++++++++++++ 70 files changed, 3704 insertions(+), 723 deletions(-) create mode 100644 BKULocal/src/main/webapp/errorresponse.css create mode 100644 BKUOnline/src/main/webapp/errorresponse.css delete mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java create mode 100644 bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd create mode 100644 bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd create mode 100644 bkucommon/src/test/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIteratorTest.java create mode 100644 utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ErrorResponseType.java create mode 100644 utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ObjectFactory.java create mode 100644 utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/package-info.java create mode 100644 utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020831_/ObjectFactory.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingInputStream.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingOutputStream.java create mode 100644 utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingWriter.java delete mode 100644 utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java create mode 100644 utils/src/main/java/at/gv/egiz/validation/ReportingValidationEventHandler.java delete mode 100644 utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java create mode 100644 utils/src/test/java/at/gv/egiz/bku/utils/URLEncodingOutputStreamTest.java create mode 100644 utils/src/test/resources/BigRequest.xml (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKULocal/src/main/resources/log4j.properties b/BKULocal/src/main/resources/log4j.properties index 8dc8644c..86ddc7b4 100644 --- a/BKULocal/src/main/resources/log4j.properties +++ b/BKULocal/src/main/resources/log4j.properties @@ -15,7 +15,7 @@ # assume log4j to be configured by servlet container (java web start) # loglever DEBUG, appender STDOUT -#log4j.rootLogger=DEBUG, STDOUT +log4j.rootLogger=DEBUG, STDOUT # STDOUT appender log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender diff --git a/BKULocal/src/main/webapp/errorresponse.css b/BKULocal/src/main/webapp/errorresponse.css new file mode 100644 index 00000000..41402e71 --- /dev/null +++ b/BKULocal/src/main/webapp/errorresponse.css @@ -0,0 +1,12 @@ +@CHARSET "UTF-8"; +sl\:ErrorResponse {margin: 0.5em; display: block;} +sl\:ErrorCode {display: inline;} +sl\:Info {display: inline;} + +ErrorResponse:lang(de):before {content: "Bei der Verarbeitung der Anfrage durch die Bürgerkartenumgebung ist ein Fehler aufgetreten: "; font-weight: bolder;} +ErrorResponse:before {content: "An error has occoured upon request processing by the citizen card software: "; font-weight: bold;} +ErrorResponse {margin: 0.5em; display: block;} +ErrorCode:lang(de):before {content: "Fehler-Code: ";} +ErrorCode:before {content: "Error Code: ";} +ErrorCode {display: block;} +Info {display: block;} \ No newline at end of file diff --git a/BKUOnline/src/main/webapp/errorresponse.css b/BKUOnline/src/main/webapp/errorresponse.css new file mode 100644 index 00000000..41402e71 --- /dev/null +++ b/BKUOnline/src/main/webapp/errorresponse.css @@ -0,0 +1,12 @@ +@CHARSET "UTF-8"; +sl\:ErrorResponse {margin: 0.5em; display: block;} +sl\:ErrorCode {display: inline;} +sl\:Info {display: inline;} + +ErrorResponse:lang(de):before {content: "Bei der Verarbeitung der Anfrage durch die Bürgerkartenumgebung ist ein Fehler aufgetreten: "; font-weight: bolder;} +ErrorResponse:before {content: "An error has occoured upon request processing by the citizen card software: "; font-weight: bold;} +ErrorResponse {margin: 0.5em; display: block;} +ErrorCode:lang(de):before {content: "Fehler-Code: ";} +ErrorCode:before {content: "Error Code: ";} +ErrorCode {display: block;} +Info {display: block;} \ No newline at end of file diff --git a/BKUWebStart/pom.xml b/BKUWebStart/pom.xml index ca19a0b3..f51f1332 100644 --- a/BKUWebStart/pom.xml +++ b/BKUWebStart/pom.xml @@ -172,6 +172,12 @@ BKUCertificates 1.0 + + iaik + iaik_jce_full_signed + compile + + + @@ -215,6 +222,11 @@ slf4j-log4j12 1.5.8 + + log4j + log4j + compile + diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java index 923a70d9..d8fe3e70 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Configurator.java @@ -16,8 +16,9 @@ */ package at.gv.egiz.bku.webstart; -import at.gv.egiz.bku.utils.StreamUtil; import iaik.asn1.CodingException; +import iaik.utils.StreamCopier; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -42,8 +43,10 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; + +import org.apache.log4j.PropertyConfigurator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -71,7 +74,7 @@ public class Configurator { public static final String KEYSTORE_FILE = "keystore.ks"; public static final String PASSWD_FILE = ".secret"; - private static final Log log = LogFactory.getLog(Configurator.class); + private static final Logger log = LoggerFactory.getLogger(Configurator.class); /** currently installed configuration version */ private String version; @@ -110,6 +113,11 @@ public class Configurator { } else { initConfig(configDir); } + // re-configure logging + // TODO: move to appropriate place + String log4jconfig = configDir.getPath() + File.separatorChar + "log4j.properties"; + log.debug("Reconfiguring logging with " + log4jconfig); + PropertyConfigurator.configureAndWatch(log4jconfig); } /** @@ -312,7 +320,7 @@ public class Configurator { ZipEntry entry = new ZipEntry(relativePath.toString()); zip.putNextEntry(entry); BufferedInputStream entryIS = new BufferedInputStream(new FileInputStream(dir)); - StreamUtil.copyStream(entryIS, zip); + new StreamCopier(entryIS, zip).copyStream(); entryIS.close(); zip.closeEntry(); dir.delete(); @@ -341,7 +349,7 @@ public class Configurator { File confTemplateFile = new File(configDir, CONF_TEMPLATE_FILE); InputStream is = Configurator.class.getClassLoader().getResourceAsStream(CONF_TEMPLATE_RESOURCE); OutputStream os = new BufferedOutputStream(new FileOutputStream(confTemplateFile)); - StreamUtil.copyStream(is, os); + new StreamCopier(is, os).copyStream(); os.close(); unzip(confTemplateFile, configDir); confTemplateFile.delete(); @@ -374,7 +382,7 @@ public class Configurator { new File(certsDir, f.substring(0, f.lastIndexOf('/'))).mkdirs(); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(certsDir, f))); log.debug(f); - StreamUtil.copyStream(Configurator.class.getClassLoader().getResourceAsStream(entry), bos); + new StreamCopier(Configurator.class.getClassLoader().getResourceAsStream(entry), bos).copyStream(); bos.close(); } else { log.trace("ignore " + entry); @@ -399,8 +407,8 @@ public class Configurator { } File f = new File(eF.getParent()); f.mkdirs(); - StreamUtil.copyStream(zipFile.getInputStream(entry), - new FileOutputStream(eF)); + new StreamCopier(zipFile.getInputStream(entry), + new FileOutputStream(eF)).copyStream(); } zipFile.close(); } diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java index 2feae267..4d1fe658 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Container.java @@ -1,6 +1,7 @@ package at.gv.egiz.bku.webstart; -import at.gv.egiz.bku.utils.StreamUtil; +import iaik.utils.StreamCopier; + import java.awt.AWTPermission; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -24,20 +25,20 @@ import java.security.SecurityPermission; import java.security.cert.Certificate; import java.util.PropertyPermission; import javax.smartcardio.CardPermission; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Server; import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.security.SslSocketConnector; import org.mortbay.jetty.webapp.WebAppContext; import org.mortbay.thread.QueuedThreadPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Container { public static final String HTTP_PORT_PROPERTY = "mocca.http.port"; public static final String HTTPS_PORT_PROPERTY = "mocca.http.port"; - private static Log log = LogFactory.getLog(Container.class); + private static Logger log = LoggerFactory.getLogger(Container.class); static { if (log.isDebugEnabled()) { @@ -166,7 +167,7 @@ public class Container { log.debug("copying BKULocal classpath resource to " + webapp); InputStream is = getClass().getClassLoader().getResourceAsStream("BKULocal.war"); OutputStream os = new BufferedOutputStream(new FileOutputStream(webapp)); - StreamUtil.copyStream(is, os); + new StreamCopier(is, os).copyStream(); os.close(); return webapp.getPath(); } diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java index 2bf42ccb..ef7edef1 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/Launcher.java @@ -10,8 +10,6 @@ import java.util.Locale; import java.util.ResourceBundle; import javax.jnlp.UnavailableServiceException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import com.sun.javaws.security.JavaWebStartSecurity; import java.awt.AWTException; @@ -37,6 +35,8 @@ import javax.jnlp.BasicService; import javax.jnlp.ServiceManager; import javax.swing.JFrame; import org.mortbay.util.MultiException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Launcher implements BKUControllerInterface, ActionListener { public static final String HELP_COMMAND = "help"; @@ -71,9 +71,10 @@ public class Launcher implements BKUControllerInterface, ActionListener { public static final String SHUTDOWN_COMMAND = "shutdown"; public static final String PIN_COMMAND = "pin"; public static final String ABOUT_COMMAND = "about"; + + private static Logger log = LoggerFactory.getLogger(Launcher.class); - private static Log log = LogFactory.getLog(Launcher.class); - + /** local bku uri */ public static final URL HTTP_SECURITY_LAYER_URL; public static final URL HTTPS_SECURITY_LAYER_URL; @@ -93,7 +94,7 @@ public class Launcher implements BKUControllerInterface, ActionListener { cert = new URL(http, "/installCertificate"); help = new URL(http, "/help"); } catch (MalformedURLException ex) { - log.error(ex); + log.error("Failed to create URL.", ex); } finally { HTTP_SECURITY_LAYER_URL = http; HTTPS_SECURITY_LAYER_URL = https; @@ -132,6 +133,7 @@ public class Launcher implements BKUControllerInterface, ActionListener { public Launcher() { + log.info("Initializing Launcher"); if (log.isTraceEnabled()) { SecurityManager sm = System.getSecurityManager(); if (sm instanceof JavaWebStartSecurity) { @@ -147,7 +149,7 @@ public class Launcher implements BKUControllerInterface, ActionListener { try { initConfig(); } catch (Exception ex) { - log.fatal("Failed to initialize configuration", ex); + log.error("Failed to initialize configuration", ex); trayIcon.displayMessage(messages.getString(CAPTION_ERROR), messages.getString(ERROR_CONFIG), TrayIcon.MessageType.ERROR); throw ex; @@ -156,12 +158,12 @@ public class Launcher implements BKUControllerInterface, ActionListener { startServer(); initFinished(); } catch (BindException ex) { - log.fatal("Failed to launch server, " + ex.getMessage(), ex); + log.error("Failed to launch server, " + ex.getMessage(), ex); trayIcon.displayMessage(messages.getString(CAPTION_ERROR), messages.getString(ERROR_BIND), TrayIcon.MessageType.ERROR); throw ex; } catch (MultiException ex) { - log.fatal("Failed to launch server, " + ex.getMessage(), ex); + log.error("Failed to launch server, " + ex.getMessage(), ex); if (ex.getThrowable(0) instanceof BindException) { trayIcon.displayMessage(messages.getString(CAPTION_ERROR), messages.getString(ERROR_BIND), TrayIcon.MessageType.ERROR); @@ -172,7 +174,7 @@ public class Launcher implements BKUControllerInterface, ActionListener { throw ex; } catch (Exception ex) { ex.printStackTrace(); - log.fatal("Failed to launch server, " + ex.getMessage(), ex); + log.error("Failed to launch server, " + ex.getMessage(), ex); trayIcon.displayMessage(messages.getString(CAPTION_ERROR), messages.getString(ERROR_START), TrayIcon.MessageType.ERROR); throw ex; @@ -379,7 +381,7 @@ public class Launcher implements BKUControllerInterface, ActionListener { launcher.launch(); } catch (Exception ex) { ex.printStackTrace(); - log.debug(ex); + log.debug("Caught exception " + ex.getMessage(), ex); log.info("waiting to shutdown..."); Thread.sleep(5000); log.info("exit"); diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java index 99fd403b..d589812e 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/LogSecurityManager.java @@ -20,8 +20,9 @@ import com.sun.javaws.security.JavaWebStartSecurity; import java.io.FileDescriptor; import java.net.InetAddress; import java.security.Permission; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * JVM argument -Djava.security.debug=access,failure @@ -31,7 +32,7 @@ import org.apache.commons.logging.LogFactory; */ public class LogSecurityManager extends SecurityManager { - protected static final Log log = LogFactory.getLog(LogSecurityManager.class); + protected static final Logger log = LoggerFactory.getLogger(LogSecurityManager.class); JavaWebStartSecurity sm; public LogSecurityManager(JavaWebStartSecurity sm) { @@ -182,6 +183,7 @@ public class LogSecurityManager extends SecurityManager { } } + @SuppressWarnings("deprecation") @Override public void checkMulticast(InetAddress maddr, byte ttl) { try { @@ -399,6 +401,7 @@ public class LogSecurityManager extends SecurityManager { // protected Class[] getClassContext() { // log.info("getClassContext"); return sm.getClassContext(); // } + @SuppressWarnings("deprecation") @Override public boolean getInCheck() { log.info("getInCheck"); diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java index 08a06570..745042f8 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/TLSServerCA.java @@ -16,8 +16,6 @@ import iaik.x509.extensions.SubjectAltName; import iaik.x509.extensions.SubjectKeyIdentifier; import java.io.IOException; import java.math.BigInteger; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.security.GeneralSecurityException; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -27,14 +25,15 @@ import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Random; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class TLSServerCA { public static final int CA_VALIDITY_Y = 3; public static final String MOCCA_TLS_SERVER_ALIAS = "server"; public static final int SERVER_VALIDITY_Y = 3; - private final static Log log = LogFactory.getLog(TLSServerCA.class); + private final static Logger log = LoggerFactory.getLogger(TLSServerCA.class); private KeyPair caKeyPair; private X509Certificate caCert; diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/AboutDialog.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/AboutDialog.java index 1e35af58..ba2c007d 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/AboutDialog.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/AboutDialog.java @@ -11,7 +11,6 @@ package at.gv.egiz.bku.webstart.gui; -import java.text.Format; import java.text.MessageFormat; import java.util.ResourceBundle; @@ -21,6 +20,11 @@ import java.util.ResourceBundle; */ public class AboutDialog extends javax.swing.JDialog { + /** + * + */ + private static final long serialVersionUID = 1L; + /** Creates new form AboutDialog */ public AboutDialog(java.awt.Frame parent, boolean modal, String version) { super(parent, modal); @@ -33,7 +37,6 @@ public class AboutDialog extends javax.swing.JDialog { * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ - @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { diff --git a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/PINManagementInvoker.java b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/PINManagementInvoker.java index 55e26313..1f14d751 100644 --- a/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/PINManagementInvoker.java +++ b/BKUWebStart/src/main/java/at/gv/egiz/bku/webstart/gui/PINManagementInvoker.java @@ -21,8 +21,9 @@ import java.awt.TrayIcon; import java.io.IOException; import java.net.HttpURLConnection; import java.util.ResourceBundle; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * GUI is painted using SwingUtilities.invokeLater, but TrayIcon ActionListener Thread (== webstart thread) joined Jetty Thread @@ -31,7 +32,7 @@ import org.apache.commons.logging.LogFactory; */ public class PINManagementInvoker implements Runnable { - private static final Log log = LogFactory.getLog(PINManagementInvoker.class); + private static final Logger log = LoggerFactory.getLogger(PINManagementInvoker.class); TrayIcon trayIcon; ResourceBundle messages; diff --git a/BKUWebStart/src/main/resources/log4j.properties b/BKUWebStart/src/main/resources/log4j.properties index 76562ccf..81832418 100644 --- a/BKUWebStart/src/main/resources/log4j.properties +++ b/BKUWebStart/src/main/resources/log4j.properties @@ -13,23 +13,15 @@ # See the License for the specific language governing permissions and # limitations under the License. -# loglever DEBUG, appender STDOUT -log4j.rootLogger=DEBUG, file -log4j.logger.org.mortbay.log=INFO -log4j.logger.pki=INFO - -#log4j.additivity.pki=false +# root log level INFO, appender file +log4j.rootLogger=INFO, file -# STDOUT appender -log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender -log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout -#log4j.appender.STDOUT.layout.ConversionPattern=%5p | %d{dd HH:mm:ss,SSS} | %20c | %10t | %m%n -#log4j.appender.STDOUT.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n -log4j.appender.STDOUT.layout.ConversionPattern=%-5p |%d | %t | %c %x- %m%n +# jetty's log level +log4j.logger.org.mortbay.log=INFO -### FILE appender +# file appender log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.datePattern='.'yyyy-MM-dd log4j.appender.file.File=${user.home}/.mocca/logs/webstart.log log4j.appender.file.layout=org.apache.log4j.PatternLayout -log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %-5p %c{1}:%L - %m%n \ No newline at end of file +log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %-5p %c{2} - %m%n \ No newline at end of file diff --git a/BKUWebStart/src/test/java/at/gv/egiz/bku/webstart/ConfiguratorTest.java b/BKUWebStart/src/test/java/at/gv/egiz/bku/webstart/ConfiguratorTest.java index 0ea126cb..4f5798d5 100644 --- a/BKUWebStart/src/test/java/at/gv/egiz/bku/webstart/ConfiguratorTest.java +++ b/BKUWebStart/src/test/java/at/gv/egiz/bku/webstart/ConfiguratorTest.java @@ -8,8 +8,6 @@ package at.gv.egiz.bku.webstart; import java.io.File; import java.net.URI; import java.util.zip.ZipOutputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; diff --git a/BKUWebStartPackage/pom.xml b/BKUWebStartPackage/pom.xml index 63725fc3..0b226785 100644 --- a/BKUWebStartPackage/pom.xml +++ b/BKUWebStartPackage/pom.xml @@ -1,3 +1,4 @@ + 4.0.0 @@ -22,7 +23,7 @@ process-resources - jnlp-download-servlet + jnlp-single diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java index 1db8c836..d3945253 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrl.java @@ -16,7 +16,6 @@ */ package at.gv.egiz.bku.binding; -import at.gv.egiz.bku.conf.Configuration; import at.gv.egiz.bku.conf.Configurator; import java.net.MalformedURLException; import java.net.URL; @@ -89,13 +88,7 @@ public class DataUrl { if (configuration != null) { String className = configuration.getProperty(Configurator.DATAURLCONNECTION_CONFIG_P); if (className != null) { - try { - log.info("set DataURLConnection class: " + className); - Class c = Class.forName(className); - connection = (DataUrlConnectionSPI) c.newInstance(); - } catch (Exception ex) { - log.error("failed to instantiate DataURL connection " + className, ex); - } + log.warn("Set DataURLConnection class not supported!"); } } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java index f954a017..384cf71c 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnection.java @@ -62,7 +62,7 @@ public interface DataUrlConnection { * @param transferEncoding may be null */ public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding); - + /** * @pre httpHeaders != null * @throws java.net.SocketTimeoutException diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java index 4f2d2e00..b092ba41 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/DataUrlConnectionImpl.java @@ -18,10 +18,14 @@ package at.gv.egiz.bku.binding; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.Charset; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashMap; @@ -34,6 +38,7 @@ import java.util.Set; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; +import javax.xml.transform.stream.StreamResult; import org.apache.commons.httpclient.methods.multipart.FilePart; import org.apache.commons.httpclient.methods.multipart.Part; @@ -47,32 +52,92 @@ import at.gv.egiz.bku.conf.Configurator; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slcommands.SLResult.SLResultType; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.utils.URLEncodingWriter; import at.gv.egiz.bku.utils.binding.Protocol; /** - * not thread-safe thus newInsance always returns a new object + * An implementation of the DataUrlConnectionSPI that supports + * multipart/form-data encoding and + * application/x-www-form-urlencoded for compatibility with legacy + * systems. * */ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { private final static Log log = LogFactory.getLog(DataUrlConnectionImpl.class); + + public static final byte[] B_DEFAULT_RESPONSETYPE = DEFAULT_RESPONSETYPE.getBytes(Charset.forName("UTF-8")); + /** + * Supported protocols are HTTP and HTTPS. + */ public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP, Protocol.HTTPS }; + /** + * The X509 certificate of the DataURL server. + */ protected X509Certificate serverCertificate; + + /** + * The protocol of the DataURL. + */ protected Protocol protocol; + + /** + * Use application/x-www-form-urlencoded instead of + * standard conform application/x-www-form-urlencoded. + */ + protected boolean urlEncoded = true; + + /** + * The value of the DataURL. + */ protected URL url; + + /** + * The URLConnection used for communication with the DataURL server. + */ private HttpURLConnection connection; + + /** + * The HTTP request headers. + */ protected Map requestHttpHeaders; - protected ArrayList formParams; + + /** + * The HTTP form parameters. + */ + protected ArrayList httpFormParameter; + + /** + * The boundary for multipart/form-data requests. + */ protected String boundary; + + /** + * The configuration properties. + */ protected Properties config = null; + + /** + * The SSLSocketFactory for HTTPS connections. + */ protected SSLSocketFactory sslSocketFactory; + + /** + * The HostnameVerifier for HTTPS connections. + */ protected HostnameVerifier hostnameVerifier; + /** + * The response of the DataURL server. + */ protected DataUrlResponse result; + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#getProtocol() + */ public String getProtocol() { if (protocol == null) { return null; @@ -80,13 +145,8 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { return protocol.toString(); } - /** - * opens a connection sets the headers gets the server certificate - * - * @throws java.net.SocketTimeoutException - * @throws java.io.IOException - * @pre url != null - * @pre httpHeaders != null + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#connect() */ public void connect() throws SocketTimeoutException, IOException { connection = (HttpURLConnection) url.openConnection(); @@ -104,9 +164,26 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { https.setHostnameVerifier(hostnameVerifier); } } else { - log.trace("No secure connection with: "+url+ " class="+connection.getClass()); + log.trace("No secure connection with: " + url + " class=" + + connection.getClass()); } connection.setDoOutput(true); + // Transfer-Encoding: chunked is problematic ... + // e.g. https://issues.apache.org/bugzilla/show_bug.cgi?id=37794 + // ... therefore disabled. + // connection.setChunkedStreamingMode(5*1024); + if (urlEncoded) { + log.debug("Setting DataURL Content-Type to " + + HttpUtil.APPLICATION_URL_ENCODED); + connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE, + HttpUtil.APPLICATION_URL_ENCODED); + } else { + log.debug("Setting DataURL Content-Type to " + + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY); + connection.addRequestProperty(HttpUtil.HTTP_HEADER_CONTENT_TYPE, + HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0] + + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary); + } Set headers = requestHttpHeaders.keySet(); Iterator headerIt = headers.iterator(); while (headerIt.hasNext()) { @@ -125,51 +202,128 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { } } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#getServerCertificate() + */ public X509Certificate getServerCertificate() { return serverCertificate; } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPHeader(java.lang.String, java.lang.String) + */ public void setHTTPHeader(String name, String value) { if (name != null && value != null) { requestHttpHeaders.put(name, value); } } + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#setHTTPFormParameter(java.lang.String, java.io.InputStream, java.lang.String, java.lang.String, java.lang.String) + */ public void setHTTPFormParameter(String name, InputStream data, String contentType, String charSet, String transferEncoding) { - InputStreamPartSource source = new InputStreamPartSource(null, data); - FilePart formParam = new FilePart(name, source, contentType, charSet); - if (transferEncoding != null) { - formParam.setTransferEncoding(transferEncoding); - } else { - formParam.setTransferEncoding(null); + // if a content type is specified we have to switch to multipart/formdata encoding + if (contentType != null && contentType.length() > 0) { + urlEncoded = false; } - formParams.add(formParam); + httpFormParameter.add(new HTTPFormParameter(name, data, contentType, + charSet, transferEncoding)); } - /** - * send all formParameters - * - * @throws java.io.IOException + + + /* (non-Javadoc) + * @see at.gv.egiz.bku.binding.DataUrlConnection#transmit(at.gv.egiz.bku.slcommands.SLResult) */ public void transmit(SLResult slResult) throws IOException { - SLResultPart slResultPart = new SLResultPart(slResult, - XML_RESPONSE_ENCODING); - if (slResult.getResultType() == SLResultType.XML) { - slResultPart.setTransferEncoding(null); - slResultPart.setContentType(slResult.getMimeType()); - slResultPart.setCharSet(XML_RESPONSE_ENCODING); + log.trace("Sending data"); + if (urlEncoded) { + // + // application/x-www-form-urlencoded (legacy, SL < 1.2) + // + + OutputStream os = connection.getOutputStream(); + OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET); + + // ResponseType + streamWriter.write(FORMPARAM_RESPONSETYPE); + streamWriter.write("="); + streamWriter.write(URLEncoder.encode(DEFAULT_RESPONSETYPE, "UTF-8")); + streamWriter.write("&"); + + // XMLResponse / Binary Response + if (slResult.getResultType() == SLResultType.XML) { + streamWriter.write(DataUrlConnection.FORMPARAM_XMLRESPONSE); + } else { + streamWriter.write(DataUrlConnection.FORMPARAM_BINARYRESPONSE); + } + streamWriter.write("="); + streamWriter.flush(); + URLEncodingWriter urlEnc = new URLEncodingWriter(streamWriter); + slResult.writeTo(new StreamResult(urlEnc), false); + urlEnc.flush(); + + // transfer parameters + char[] cbuf = new char[512]; + int len; + for (HTTPFormParameter formParameter : httpFormParameter) { + streamWriter.write("&"); + streamWriter.write(URLEncoder.encode(formParameter.getName(), "UTF-8")); + streamWriter.write("="); + InputStreamReader reader = new InputStreamReader(formParameter.getData(), + (formParameter.getCharSet() != null) + ? formParameter.getCharSet() + : null); + while ((len = reader.read(cbuf)) != -1) { + urlEnc.write(cbuf, 0, len); + } + urlEnc.flush(); + } + streamWriter.close(); + } else { - slResultPart.setTransferEncoding(null); - slResultPart.setContentType(slResult.getMimeType()); - } - formParams.add(slResultPart); + // + // multipart/form-data (conforming to SL 1.2) + // - OutputStream os = connection.getOutputStream(); - log.trace("Sending data"); - Part[] parts = new Part[formParams.size()]; - Part.sendParts(os, formParams.toArray(parts), boundary.getBytes()); - os.close(); + ArrayList parts = new ArrayList(); + + // ResponseType + StringPart responseType = new StringPart(FORMPARAM_RESPONSETYPE, + DEFAULT_RESPONSETYPE, "UTF-8"); + responseType.setTransferEncoding(null); + parts.add(responseType); + + // XMLResponse / Binary Response + SLResultPart slResultPart = new SLResultPart(slResult, + XML_RESPONSE_ENCODING); + if (slResult.getResultType() == SLResultType.XML) { + slResultPart.setTransferEncoding(null); + slResultPart.setContentType(slResult.getMimeType()); + slResultPart.setCharSet(XML_RESPONSE_ENCODING); + } else { + slResultPart.setTransferEncoding(null); + slResultPart.setContentType(slResult.getMimeType()); + } + parts.add(slResultPart); + + // transfer parameters + for (HTTPFormParameter formParameter : httpFormParameter) { + InputStreamPartSource source = new InputStreamPartSource(null, + formParameter.getData()); + FilePart part = new FilePart(formParameter.getName(), source, + formParameter.getContentType(), formParameter.getCharSet()); + part.setTransferEncoding(formParameter.getTransferEncoding()); + parts.add(part); + } + + OutputStream os = connection.getOutputStream(); + Part.sendParts(os, parts.toArray(new Part[parts.size()]), boundary.getBytes()); + os.close(); + + } + // MultipartRequestEntity PostMethod InputStream is = null; try { @@ -241,16 +395,9 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { .put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT); } - requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, - HttpUtil.MULTIPART_FOTMDATA + HttpUtil.SEPERATOR[0] - + HttpUtil.MULTIPART_FOTMDATA_BOUNDARY + "=" + boundary); - - formParams = new ArrayList(); - StringPart responseType = new StringPart(FORMPARAM_RESPONSETYPE, - DEFAULT_RESPONSETYPE); - responseType.setCharSet("UTF-8"); - responseType.setTransferEncoding(null); - formParams.add(responseType); + + httpFormParameter = new ArrayList(); + } @Override @@ -281,4 +428,107 @@ public class DataUrlConnectionImpl implements DataUrlConnectionSPI { public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { this.hostnameVerifier = hostnameVerifier; } + + public class HTTPFormParameter { + + private String name; + + private InputStream data; + + private String contentType; + + private String charSet; + + private String transferEncoding; + + /** + * @param name + * @param data + * @param contentType + * @param charSet + * @param transferEncoding + */ + public HTTPFormParameter(String name, InputStream data, String contentType, + String charSet, String transferEncoding) { + super(); + this.name = name; + this.data = data; + this.contentType = contentType; + this.charSet = charSet; + this.transferEncoding = transferEncoding; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @return the data + */ + public InputStream getData() { + return data; + } + + /** + * @param data the data to set + */ + public void setData(InputStream data) { + this.data = data; + } + + /** + * @return the contentType + */ + public String getContentType() { + return contentType; + } + + /** + * @param contentType the contentType to set + */ + public void setContentType(String contentType) { + this.contentType = contentType; + } + + /** + * @return the charSet + */ + public String getCharSet() { + return charSet; + } + + /** + * @param charSet the charSet to set + */ + public void setCharSet(String charSet) { + this.charSet = charSet; + } + + /** + * @return the transferEncoding + */ + public String getTransferEncoding() { + return transferEncoding; + } + + /** + * @param transferEncoding the transferEncoding to set + */ + public void setTransferEncoding(String transferEncoding) { + this.transferEncoding = transferEncoding; + } + + + + } } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java index ef603fc7..a1c4d5fc 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java @@ -22,6 +22,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.Writer; import java.net.URL; import java.security.cert.X509Certificate; import java.util.ArrayList; @@ -46,6 +47,7 @@ import javax.xml.transform.stream.StreamSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import at.gv.egiz.bku.slcommands.ErrorResult; import at.gv.egiz.bku.slcommands.SLCommand; import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLCommandFactory; @@ -635,7 +637,6 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements throw new SLBindingException(2006); } InputDecoder id = InputDecoderFactory.getDecoder(cl, is); - id.setContentType(cl); if (id == null) { log.error("Cannot get inputdecoder for is"); throw new SLException(2006); @@ -730,9 +731,20 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements Templates templates) throws IOException { log.debug("Writing error as result"); ErrorResultImpl error = new ErrorResultImpl(bindingProcessorError, locale); - error.writeTo(new StreamResult(new OutputStreamWriter(os, encoding)), templates); + Writer writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); + error.writeTo(new StreamResult(writer), templates, true); } + protected Writer writeXMLDeclarationAndProcessingInstruction(OutputStream os, String encoding) throws IOException { + if (encoding == null) { + encoding = HttpUtil.DEFAULT_CHARSET; + } + OutputStreamWriter writer = new OutputStreamWriter(os, encoding); + writer.write("\n"); + writer.write("\n"); + return writer; + } + @Override public void writeResultTo(OutputStream os, String encoding) throws IOException { @@ -772,9 +784,16 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements return; } else { log.debug("Getting result from invoker"); - OutputStreamWriter osw = new OutputStreamWriter(os, encoding); - slResult.writeTo(new StreamResult(osw), templates); - osw.flush(); + boolean fragment = false; + Writer writer; + if (slResult instanceof ErrorResult) { + writer = writeXMLDeclarationAndProcessingInstruction(os, encoding); + fragment = true; + } else { + writer = new OutputStreamWriter(os, encoding); + } + slResult.writeTo(new StreamResult(writer), templates, fragment); + writer.flush(); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java deleted file mode 100644 index cfccb7f1..00000000 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java +++ /dev/null @@ -1,259 +0,0 @@ -package at.gv.egiz.bku.binding; - - -import at.gv.egiz.bku.conf.Configurator; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.StringWriter; -import java.net.HttpURLConnection; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLEncoder; -import java.security.cert.X509Certificate; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSocketFactory; -import javax.xml.transform.stream.StreamResult; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import at.gv.egiz.bku.slcommands.SLResult; -import at.gv.egiz.bku.slcommands.SLResult.SLResultType; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.bku.utils.binding.Protocol; - -/** - * not thread-safe thus newInsance always returns a new object - * - */ -public class LegacyDataUrlConnectionImpl implements DataUrlConnectionSPI { - - private final static Log log = LogFactory.getLog(LegacyDataUrlConnectionImpl.class); - - public final static Protocol[] SUPPORTED_PROTOCOLS = { Protocol.HTTP, - Protocol.HTTPS }; - protected X509Certificate serverCertificate; - protected Protocol protocol; - protected URL url; - private HttpURLConnection connection; - protected Map requestHttpHeaders; - protected Map formParams; - protected String boundary; - protected Properties config = null; - protected SSLSocketFactory sslSocketFactory; - protected HostnameVerifier hostnameVerifier; - - protected DataUrlResponse result; - - public String getProtocol() { - if (protocol == null) { - return null; - } - return protocol.toString(); - } - - /** - * opens a connection sets the headers gets the server certificate - * - * @throws java.net.SocketTimeoutException - * @throws java.io.IOException - * @pre url != null - * @pre httpHeaders != null - */ - public void connect() throws SocketTimeoutException, IOException { - connection = (HttpURLConnection) url.openConnection(); - if (connection instanceof HttpsURLConnection) { - HttpsURLConnection https = (HttpsURLConnection) connection; - if (sslSocketFactory != null) { - log.debug("Setting custom ssl socket factory for ssl connection"); - https.setSSLSocketFactory(sslSocketFactory); - } - if (hostnameVerifier != null) { - log.debug("Setting custom hostname verifier"); - https.setHostnameVerifier(hostnameVerifier); - } - } - connection.setDoOutput(true); - Set headers = requestHttpHeaders.keySet(); - Iterator headerIt = headers.iterator(); - while (headerIt.hasNext()) { - String name = headerIt.next(); - connection.setRequestProperty(name, requestHttpHeaders.get(name)); - } - log.trace("Connecting to: "+url); - connection.connect(); - if (connection instanceof HttpsURLConnection) { - HttpsURLConnection ssl = (HttpsURLConnection) connection; - X509Certificate[] certs = (X509Certificate[]) ssl.getServerCertificates(); - if ((certs != null) && (certs.length >= 1)) { - log.trace("Server certificate: "+certs[0]); - serverCertificate = certs[0]; - } - } - } - - public X509Certificate getServerCertificate() { - return serverCertificate; - } - - public void setHTTPHeader(String name, String value) { - if (name != null && value != null) { - requestHttpHeaders.put(name, value); - } - } - - public void setHTTPFormParameter(String name, InputStream data, - String contentType, String charSet, String transferEncoding) { - StringBuilder sb = new StringBuilder(); - try { - InputStreamReader reader = new InputStreamReader(data, (charSet != null) ? charSet : "UTF-8"); - char[] c = new char[512]; - for (int l; (l = reader.read(c)) != -1;) { - sb.append(c, 0, l); - } - } catch (IOException e) { - throw new SLRuntimeException("Failed to set HTTP form parameter.", e); - } - formParams.put(name, sb.toString()); - } - - /** - * send all formParameters - * - * @throws java.io.IOException - */ - public void transmit(SLResult slResult) throws IOException { - StringWriter writer = new StringWriter(); - slResult.writeTo(new StreamResult(writer)); - formParams.put( - (slResult.getResultType() == SLResultType.XML) - ? DataUrlConnection.FORMPARAM_XMLRESPONSE - : DataUrlConnection.FORMPARAM_BINARYRESPONSE, - writer.toString()); - - OutputStream os = connection.getOutputStream(); - OutputStreamWriter streamWriter = new OutputStreamWriter(os, HttpUtil.DEFAULT_CHARSET); - - log.trace("Sending data"); - Iterator keys = formParams.keySet().iterator(); - while(keys.hasNext()) { - String key = keys.next(); - streamWriter.write(URLEncoder.encode(key, "UTF-8")); - streamWriter.write("="); - streamWriter.write(URLEncoder.encode(formParams.get(key), "UTF-8")); - if (keys.hasNext()) { - streamWriter.write("&"); - } - } - streamWriter.flush(); - os.close(); - - // MultipartRequestEntity PostMethod - InputStream is = null; - try { - is = connection.getInputStream(); - } catch (IOException iox) { - log.info(iox); - } - log.trace("Reading response"); - result = new DataUrlResponse(url.toString(), connection.getResponseCode(), is); - Map responseHttpHeaders = new HashMap(); - Map> httpHeaders = connection.getHeaderFields(); - for (Iterator keyIt = httpHeaders.keySet().iterator(); keyIt - .hasNext();) { - String key = keyIt.next(); - StringBuffer value = new StringBuffer(); - for (String val : httpHeaders.get(key)) { - value.append(val); - value.append(HttpUtil.SEPERATOR[0]); - } - String valString = value.substring(0, value.length() - 1); - if ((key != null) && (value.length() > 0)) { - responseHttpHeaders.put(key, valString); - } - } - result.setResponseHttpHeaders(responseHttpHeaders); - } - - @Override - public DataUrlResponse getResponse() throws IOException { - return result; - } - - /** - * inits protocol, url, httpHeaders, formParams - * - * @param url - * must not be null - */ - @Override - public void init(URL url) { - - for (int i = 0; i < SUPPORTED_PROTOCOLS.length; i++) { - if (SUPPORTED_PROTOCOLS[i].toString().equalsIgnoreCase(url.getProtocol())) { - protocol = SUPPORTED_PROTOCOLS[i]; - break; - } - } - if (protocol == null) { - throw new SLRuntimeException("Protocol " + url.getProtocol() - + " not supported for data url"); - } - this.url = url; - requestHttpHeaders = new HashMap(); - if ((config != null) - && (config.getProperty(Configurator.USERAGENT_CONFIG_P) != null)) { - log.debug("setting User-Agent header: " + config.getProperty(Configurator.USERAGENT_CONFIG_P)); - requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, config - .getProperty(Configurator.USERAGENT_CONFIG_P)); - } else { - requestHttpHeaders - .put(HttpUtil.HTTP_HEADER_USER_AGENT, Configurator.USERAGENT_DEFAULT); - - } - requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, - HttpUtil.APPLICATION_URL_ENCODED); - - formParams = new HashMap(); - } - - @Override - public DataUrlConnectionSPI newInstance() { - DataUrlConnectionSPI uc = new LegacyDataUrlConnectionImpl(); - uc.setConfiguration(config); - uc.setSSLSocketFactory(sslSocketFactory); - uc.setHostnameVerifier(hostnameVerifier); - return uc; - } - - @Override - public URL getUrl() { - return url; - } - - @Override - public void setConfiguration(Properties config) { - this.config = config; - } - - @Override - public void setSSLSocketFactory(SSLSocketFactory socketFactory) { - this.sslSocketFactory = socketFactory; - } - - @Override - public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { - this.hostnameVerifier = hostnameVerifier; - } -} \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java index f4ebe288..69c659e1 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputDecoder.java @@ -16,86 +16,43 @@ */ package at.gv.egiz.bku.binding; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URLDecoder; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.io.InputStream; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.fileupload.ParameterParser; -import org.apache.commons.fileupload.ParameterParser; - -import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.bku.utils.StreamUtil; - -/** - * Implementation based on Java's URLDecoder class - * - */ -// FIXME replace this code by a streaming variant public class XWWWFormUrlInputDecoder implements InputDecoder { - - public final static String CHAR_SET = "charset"; - public final static String NAME_VAL_SEP = "="; - public final static String SEP = "\\&"; - - private String contentType; - private InputStream dataStream; - private String charset = "UTF-8"; - - protected List decodeInput(InputStream is) throws IOException { - List result = new LinkedList(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - StreamUtil.copyStream(is, bos); - String inputString = new String(bos.toByteArray()); - String[] nameValuePairs = inputString.split(SEP); - //inputString = URLDecoder.decode(inputString, charset); - for (int i = 0; i < nameValuePairs.length; i++) { - String[] fields = nameValuePairs[i].split(NAME_VAL_SEP, 2); - if (fields.length != 2) { - throw new SLRuntimeException("Invalid form encoding, missing value"); - } - String name = URLDecoder.decode(fields[0], charset); - String value =URLDecoder.decode(fields[1], charset); - ByteArrayInputStream bais = new ByteArrayInputStream(value - .getBytes(charset)); - FormParameterImpl fpi = new FormParameterImpl(contentType, name, bais, null); - result.add(fpi); - } - return result; - } - - @SuppressWarnings("unchecked") + + /** + * The MIME type 'application/x-www-form-urlencoded'. + */ + public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; + + /** + * The form parameter iterator. + */ + protected XWWWFormUrlInputIterator iterator; + + @SuppressWarnings("unchecked") @Override public void setContentType(String contentType) { ParameterParser pp = new ParameterParser(); pp.setLowerCaseNames(true); Map params = pp.parse(contentType, new char[] { ':', ';' }); - if (!params.containsKey("application/x-www-form-urlencoded")) { + if (!params.containsKey(CONTENT_TYPE)) { throw new IllegalArgumentException( "not a url encoded content type specification: " + contentType); } - String cs = params.get(CHAR_SET); - if (cs != null) { - charset = cs; - } - this.contentType = contentType; } @Override public Iterator getFormParameterIterator() { - try { - return decodeInput(dataStream).iterator(); - } catch (IOException e) { - throw new SLRuntimeException(e); - } + return iterator; } @Override public void setInputStream(InputStream is) { - dataStream = is; + iterator = new XWWWFormUrlInputIterator(is); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java new file mode 100644 index 00000000..f052ce05 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIterator.java @@ -0,0 +1,376 @@ +package at.gv.egiz.bku.binding; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +public class XWWWFormUrlInputIterator implements Iterator { + + public static final byte NAME_VALUE_SEP = '='; + + public static final byte PARAM_SEP = '&'; + + public static final Charset UTF_8 = Charset.forName("UTF-8"); + + /** + * The default buffer size. + */ + protected static final int DEFAULT_BUFFER_SIZE = 4096; + + /** + * Are we done with parsing the input. + */ + protected boolean done = false; + + /** + * The x-www-formdata-urlencoded input stream to be parsed. + */ + protected final InputStream in; + + /** + * The buffer size. + */ + protected int bufferSize = DEFAULT_BUFFER_SIZE; + + /** + * The read buffer. + */ + protected final byte[] buf = new byte[bufferSize]; + + /** + * The read position. + */ + protected int pos; + + /** + * The number of valid bytes in the buffer; + */ + protected int count; + + /** + * The parameter returned by the last call of {@link #next()}; + */ + protected XWWWFormUrlEncodedParameter currentParameter; + + /** + * An IOException that cannot be reported immediately. + */ + protected IOException deferredIOException; + + /** + * Creates a new instance of this x-www-formdata-urlencoded input iterator + * with the given InputStream in to be parsed. + * + * @param in the InputStream to be parsed + */ + public XWWWFormUrlInputIterator(InputStream in) { + this.in = in; + } + + /* (non-Javadoc) + * @see java.util.Iterator#hasNext() + */ + @Override + public boolean hasNext() { + if (done) { + return false; + } + if (currentParameter != null) { + // we have to disconnect the current parameter + // to look for further parameters + try { + currentParameter.formParameterValue.disconnect(); + // fill buffer if empty + if (pos >= count) { + if ((count = in.read(buf)) == -1) { + // done + done = true; + return false; + } + pos = 0; + } + } catch (IOException e) { + deferredIOException = e; + } + } + return true; + } + + @Override + public FormParameter next() { + if (hasNext()) { + // skip separator + pos++; + currentParameter = new XWWWFormUrlEncodedParameter(); + return currentParameter; + } else { + throw new NoSuchElementException(); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public class XWWWFormUrlEncodedParameter implements FormParameter { + + /** + * The list of header names. + */ + // x-www-form-urlencoded parameters do not provide headers + protected final List headers = Collections.emptyList(); + + /** + * The name of the form parameter. + */ + protected String formParameterName; + + /** + * The value of the form parameter. + */ + protected URLDecodingInputStream formParameterValue; + + public XWWWFormUrlEncodedParameter() { + // parse parameter name + URLDecodingInputStream urldec = new URLDecodingInputStream(in, NAME_VALUE_SEP); + InputStreamReader reader = new InputStreamReader(urldec, UTF_8); + try { + StringBuilder sb = new StringBuilder(); + char[] b = new char[128]; + for (int l = 0; (l = reader.read(b)) != -1;) { + sb.append(b, 0, l); + } + formParameterName = sb.toString(); + // fill buffer if empty + if (pos >= count) { + if ((count = in.read(buf)) == -1) { + throw new IOException("Invalid URL encoding."); + } + pos = 0; + } + // skip separator + pos++; + } catch (IOException e) { + deferredIOException = e; + formParameterName = ""; + } + formParameterValue = new URLDecodingInputStream(in, PARAM_SEP); + } + + @Override + public String getFormParameterContentType() { + // x-www-form-urlencoded parameters do not specify a content type + return null; + } + + @Override + public String getFormParameterName() { + return formParameterName; + } + + @Override + public InputStream getFormParameterValue() { + if (deferredIOException != null) { + final IOException e = deferredIOException; + deferredIOException = null; + return new InputStream() { + @Override + public int read() throws IOException { + throw e; + } + }; + } else { + return formParameterValue; + } + } + + @Override + public Iterator getHeaderNames() { + return headers.iterator(); + } + + @Override + public String getHeaderValue(String headerName) { + return null; + } + + } + + public class URLDecodingInputStream extends FilterInputStream { + + /** + * Has this stream already been closed. + */ + private boolean closed = false; + + /** + * Has this stream been disconnected. + */ + private boolean disconnected = false; + + /** + * Read until this byte occurs. + */ + protected final byte term; + + /** + * Creates a new instance of this URLDecodingInputStream. + * + * @param in + * @param separator + */ + protected URLDecodingInputStream(InputStream in, byte separator) { + super(in); + this.term = separator; + } + + /* (non-Javadoc) + * @see java.io.FilterInputStream#read() + */ + @Override + public int read() throws IOException { + if (closed) { + throw new IOException("The stream has already been closed."); + } + if (disconnected) { + return in.read(); + } + + if (pos >= count) { + if ((count = in.read(buf)) == -1) { + return -1; + } + pos = 0; + } if (buf[pos] == term) { + return -1; + } else if (buf[pos] == '+') { + pos++; + return ' '; + } else if (buf[pos] == '%') { + if (++pos == count) { + if ((count = in.read(buf)) == -1) { + throw new IOException("Invalid URL encoding."); + } + pos = 0; + } + int c1 = Character.digit(buf[pos], 16); + if (++pos == count) { + if ((count = in.read(buf)) == -1) { + throw new IOException("Invalid URL encoding."); + } + pos = 0; + } + int c2 = Character.digit(buf[pos], 16); + return ((c1 << 4) | c2); + } else { + return buf[pos++]; + } + } + + /* (non-Javadoc) + * @see java.io.FilterInputStream#read(byte[], int, int) + */ + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (closed) { + throw new IOException("The stream has already been closed."); + } + if (disconnected) { + return in.read(b, off, len); + } + + if ((off | len | (off + len) | (b.length - (off + len))) < 0) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + + if (pos >= count) { + if ((count = in.read(buf)) == -1) { + return -1; + } + pos = 0; + } + if (buf[pos] == term) { + return -1; + } + + int l = 0; + for (;;) { + while (pos < count) { + if (l == len || buf[pos] == term) { + return l; + } else if (buf[pos] == '+') { + b[off] = ' '; + } else if (buf[pos] == '%') { + if (++pos == count && (count = in.read(buf)) == -1) { + throw new IOException("Invalid URL encoding."); + } + int c1 = Character.digit(buf[pos], 16); + if (++pos == count && (count = in.read(buf)) == -1) { + throw new IOException("Invalid URL encoding."); + } + int c2 = Character.digit(buf[pos], 16); + b[off] = (byte) ((c1 << 4) | c2); + } else { + b[off] = buf[pos]; + } + pos++; + off++; + l++; + } + if ((count = in.read(buf)) == -1) { + return l; + } + pos = 0; + } + } + + /** + * Disconnect from the InputStream and buffer all remaining data. + * + * @throws IOException + */ + public void disconnect() throws IOException { + if (!disconnected) { + // don't waste space for a buffer if end of stream has already been + // reached + byte[] b = new byte[1]; + if ((read(b)) != -1) { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + os.write(b); + b = new byte[1024]; + for (int l; (l = read(b, 0, b.length)) != -1;) { + os.write(b, 0, l); + } + super.in = new ByteArrayInputStream(os.toByteArray()); + } + disconnected = true; + } + } + + /* (non-Javadoc) + * @see java.io.FilterInputStream#close() + */ + @Override + public void close() throws IOException { + if (!hasNext()) { + // don't close the underlying stream until all parts are read + super.close(); + } + disconnect(); + closed = true; + } + + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java index 5585f02e..d896ea9f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/multipart/SLResultPart.java @@ -16,37 +16,56 @@ */ package at.gv.egiz.bku.binding.multipart; +import at.gv.egiz.bku.binding.DataUrlConnection; import at.gv.egiz.bku.slcommands.SLResult; +import at.gv.egiz.bku.slcommands.SLResult.SLResultType; + import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import javax.xml.transform.stream.StreamResult; -import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; import org.apache.commons.httpclient.methods.multipart.FilePart; +import org.apache.commons.httpclient.methods.multipart.PartSource; -/** - * - * @author clemens - */ public class SLResultPart extends FilePart { protected SLResult slResult; protected String encoding; public SLResultPart(SLResult slResult, String encoding) { - super("XMLResponse", - new ByteArrayPartSource(null, "dummySource".getBytes())); + super((slResult.getResultType() == SLResultType.XML) + ? DataUrlConnection.FORMPARAM_XMLRESPONSE + : DataUrlConnection.FORMPARAM_BINARYRESPONSE, + new PartSource() { + + @Override + public long getLength() { + // may return null, as sendData() is overridden + return 0; + } + + @Override + public String getFileName() { + // return null, to prevent content-disposition header + return null; + } + + @Override + public InputStream createInputStream() throws IOException { + // may return null, as sendData() is overridden below + return null; + } + } + ); this.slResult = slResult; this.encoding = encoding; } @Override protected void sendData(OutputStream out) throws IOException { - slResult.writeTo(new StreamResult(new OutputStreamWriter(out, encoding))); - // slResult.writeTo(new StreamResult(new OutputStreamWriter(System.out, - // encoding))); - // super.sendData(out); + slResult.writeTo(new StreamResult(new OutputStreamWriter(out, encoding)), false); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java index 125233c1..3b2d1b99 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/CertValidatorImpl.java @@ -1,7 +1,9 @@ package at.gv.egiz.bku.conf; +import iaik.logging.LogConfigurationException; import iaik.logging.TransactionId; import iaik.logging.impl.TransactionIdImpl; +import iaik.logging.LoggerConfig; import iaik.pki.DefaultPKIConfiguration; import iaik.pki.DefaultPKIProfile; import iaik.pki.PKIConfiguration; @@ -18,6 +20,7 @@ import iaik.x509.X509Certificate; import java.io.File; import java.util.Date; +import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -37,6 +40,27 @@ public class CertValidatorImpl implements CertValidator { * @see at.gv.egiz.bku.conf.CertValidator#init(java.io.File, java.io.File) */ public void init(File certDir, File caDir) { + // initialize IAIK logging for PKI module + log.debug("Configuring logging for IAIK PKI module"); + iaik.logging.LogFactory.configure(new LoggerConfig() { + + @Override + public Properties getProperties() throws LogConfigurationException { + return null; + } + + @Override + public String getNodeId() { + return "pki"; + } + + @Override + public String getFactory() { + return IAIKCommonsLogFactory.class.getName(); + } + }); + + // the parameters specifying the directory certstore CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters( "CS-001", certDir.getAbsolutePath(), true, false) }; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java new file mode 100644 index 00000000..1b7dd189 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLog.java @@ -0,0 +1,144 @@ +/** + * + */ +package at.gv.egiz.bku.conf; + +import iaik.logging.Log; +import iaik.logging.TransactionId; + +/** + * @author mcentner + * + */ +public class IAIKCommonsLog implements Log { + + /** + * The id that will be written to the log if the transactionid == null + */ + public final static String NO_ID = "Null-ID"; + + protected org.apache.commons.logging.Log commonsLog; + + protected String nodeId; + + public IAIKCommonsLog(org.apache.commons.logging.Log log) { + this.commonsLog = log; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#debug(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void debug(TransactionId transactionId, Object message, Throwable t) { + if (commonsLog.isDebugEnabled()) { + commonsLog.debug(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#info(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void info(TransactionId transactionId, Object message, Throwable t) { + if (commonsLog.isInfoEnabled()) { + commonsLog.info(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#warn(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void warn(TransactionId transactionId, Object message, Throwable t) { + if (commonsLog.isWarnEnabled()) { + commonsLog.warn(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#error(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void error(TransactionId transactionId, Object message, Throwable t) { + if (commonsLog.isErrorEnabled()) { + commonsLog.error(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#fatal(iaik.logging.TransactionId, java.lang.Object, java.lang.Throwable) + */ + @Override + public void fatal(TransactionId transactionId, Object message, Throwable t) { + if (commonsLog.isFatalEnabled()) { + commonsLog.fatal(nodeId + ": " + + ((transactionId != null) ? transactionId.getLogID() : NO_ID) + ": " + + message, t); + } + } + + /* (non-Javadoc) + * @see iaik.logging.Log#setNodeId(java.lang.String) + */ + @Override + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#getNodeId() + */ + @Override + public String getNodeId() { + return nodeId; + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isDebugEnabled() + */ + @Override + public boolean isDebugEnabled() { + return commonsLog.isDebugEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isInfoEnabled() + */ + @Override + public boolean isInfoEnabled() { + return commonsLog.isInfoEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isWarnEnabled() + */ + @Override + public boolean isWarnEnabled() { + return commonsLog.isWarnEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isErrorEnabled() + */ + @Override + public boolean isErrorEnabled() { + return commonsLog.isErrorEnabled(); + } + + /* (non-Javadoc) + * @see iaik.logging.Log#isFatalEnabled() + */ + @Override + public boolean isFatalEnabled() { + return commonsLog.isFatalEnabled(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java new file mode 100644 index 00000000..14e2c757 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/IAIKCommonsLogFactory.java @@ -0,0 +1,59 @@ +/** + * + */ +package at.gv.egiz.bku.conf; + +import org.apache.commons.logging.impl.WeakHashtable; + +import iaik.logging.Log; +import iaik.logging.LogConfigurationException; +import iaik.logging.LogFactory; + +/** + * @author mcentner + * + */ +public class IAIKCommonsLogFactory extends LogFactory { + + protected WeakHashtable instances = new WeakHashtable(); + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#getInstance(java.lang.String) + */ + @Override + public Log getInstance(String name) throws LogConfigurationException { + org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(name); + Log log = (Log) instances.get(commonsLog); + if (log == null) { + log = new IAIKCommonsLog(commonsLog); + log.setNodeId(node_id_); + instances.put(commonsLog, log); + } + return log; + } + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#getInstance(java.lang.Class) + */ + @SuppressWarnings("unchecked") + @Override + public Log getInstance(Class clazz) throws LogConfigurationException { + org.apache.commons.logging.Log commonsLog = org.apache.commons.logging.LogFactory.getLog(clazz); + Log log = (Log) instances.get(commonsLog); + if (log == null) { + log = new IAIKCommonsLog(commonsLog); + log.setNodeId(node_id_); + instances.put(commonsLog, log); + } + return log; + } + + /* (non-Javadoc) + * @see iaik.logging.LogFactory#release() + */ + @Override + public void release() { + instances.clear(); + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java index fe27bc54..8e3f6ece 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLCommandFactory.java @@ -28,6 +28,7 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; +import javax.xml.bind.ValidationEventLocator; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; @@ -46,11 +47,11 @@ import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLExceptionMessages; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.bku.utils.DebugReader; import at.gv.egiz.slbinding.RedirectEventFilter; import at.gv.egiz.slbinding.RedirectUnmarshallerListener; -import at.gv.egiz.validation.ValidationEventLogger; -import javax.xml.bind.ValidationEventHandler; +import at.gv.egiz.validation.ReportingValidationEventHandler; public class SLCommandFactory { @@ -60,7 +61,9 @@ public class SLCommandFactory { public static final String[] SCHEMA_FILES = new String[]{ "at/gv/egiz/bku/slcommands/schema/xml.xsd", "at/gv/egiz/bku/slcommands/schema/xmldsig-core-schema.xsd", - "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd" + "at/gv/egiz/bku/slcommands/schema/Core-1.2.xsd", + "at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd", + "at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd" }; /** * Logging facility. @@ -169,7 +172,10 @@ public class SLCommandFactory { String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName(); String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); - setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg)); + String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName(); + String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName(); + setJaxbContext(JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg + + ":" + slPkgLegacy1_0 + ":" + slPkgLegacy1_1)); } catch (JAXBException e) { log.error("Failed to setup JAXBContext security layer request.", e); throw new SLRuntimeException(e); @@ -248,26 +254,9 @@ public class SLCommandFactory { SLRequestException { Object object; + ReportingValidationEventHandler validationEventHandler = new ReportingValidationEventHandler(); try { -// ValidatorHandler validator = slSchema.newValidatorHandler(); -// validator.getContentHandler(); -// -// SAXParserFactory spf = SAXParserFactory.newInstance(); -// spf.setNamespaceAware(true); -// XMLReader saxReader = spf.newSAXParser().getXMLReader(); -// //TODO extend validator to implement redirectContentHandler (validate+redirect) -// saxReader.setContentHandler(validator); -// //TODO get a InputSource -// SAXSource saxSource = new SAXSource(saxReader, source); -// -// Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); -// //turn off duplicate jaxb validation -// unmarshaller.setSchema(null); -// unmarshaller.setListener(listener); -// unmarshaller.unmarshal(saxSource); - - XMLInputFactory inputFactory = XMLInputFactory.newInstance(); XMLEventReader eventReader = inputFactory.createXMLEventReader(source); RedirectEventFilter redirectEventFilter = new RedirectEventFilter(); @@ -279,7 +268,7 @@ public class SLCommandFactory { unmarshaller.setSchema(slSchema); } log.trace("Before unmarshal()."); - unmarshaller.setEventHandler(new ValidationEventLogger()); + unmarshaller.setEventHandler(validationEventHandler); object = unmarshaller.unmarshal(filteredReader); log.trace("After unmarshal()."); } catch (UnmarshalException e) { @@ -288,6 +277,13 @@ public class SLCommandFactory { } else { log.info("Failed to unmarshall security layer request." + e.getMessage()); } + if (validationEventHandler.getErrorEvent() != null) { + // Validation Error + ValidationEvent errorEvent = validationEventHandler.getErrorEvent(); + ValidationEventLocator locator = errorEvent.getLocator(); + throw new SLRequestException(3002, + SLExceptionMessages.EC3002_INVALID, new Object[]{errorEvent.getMessage()}); + } Throwable cause = e.getCause(); if (cause instanceof SAXParseException) { throw new SLRequestException(3000, @@ -328,10 +324,11 @@ public class SLCommandFactory { * if an unexpected error occurs configuring the unmarshaller, if * unmarshalling fails with an unexpected error or if the * corresponding SLCommand could not be instantiated + * @throws SLVersionException */ @SuppressWarnings("unchecked") public SLCommand createSLCommand(Source source, SLCommandContext context) - throws SLCommandException, SLRuntimeException, SLRequestException { + throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { DebugReader dr = null; if (log.isTraceEnabled() && source instanceof StreamSource) { @@ -361,6 +358,12 @@ public class SLCommandFactory { } QName qName = ((JAXBElement) object).getName(); + if (!SLCommand.NAMESPACE_URI.equals(qName.getNamespaceURI())) { + // security layer request version not supported + log.info("Unsupported security layer request version : " + qName.getNamespaceURI()); + throw new SLVersionException(qName.getNamespaceURI()); + } + Class implClass = getImplClass(qName); if (implClass == null) { // command not supported diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java new file mode 100644 index 00000000..e0a375cf --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLMarshallerFactory.java @@ -0,0 +1,172 @@ +/* +* Copyright 2009 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.slcommands; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.marshal.MarshallerFactory; + +public class SLMarshallerFactory { + + static Log log = LogFactory.getLog(SLMarshallerFactory.class); + + /** + * The JAXBContext used for result marshaling. + *

+ * Note: Different contexts are used for marshaling and unmarshaling of + * security layer requests and responses to avoid propagation of namespace + * declarations of legacy namespaces into marshaled results. + *

+ * @see #jaxbContextLegacy + */ + protected static JAXBContext context; + + /** + * The JAXBContext used for marshaling of of results in the legacy namespace. + */ + protected static JAXBContext legacyContext; + + // ------------------- initialization on demand idiom ------------------- + // see http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom + // ---------------------------------------------------------------------- + + /** + * Private constructor called by {@link SLMarshallerFactoryInstanceHolder}. + */ + private SLMarshallerFactory() { + // context is initialized immediately while the legacy context is initialized only on demand + try { + String slPkg = at.buergerkarte.namespaces.securitylayer._1.ObjectFactory.class.getPackage().getName(); + String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); + String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); + context = JAXBContext.newInstance(slPkg + ":" + xmldsigPkg + ":" + cardChannelPkg); + } catch (JAXBException e) { + log.error("Failed to setup JAXBContext security layer request.", e); + throw new SLRuntimeException(e); + } + } + + /** + * The lazy instance holder for this SLMarshallerFactory. + */ + private static class SLMarshallerFactoryInstanceHolder { + /** + * The instance returned by {@link SLMarshallerFactory#getInstance()} + */ + private static final SLMarshallerFactory instance = new SLMarshallerFactory(); + } + + /** + * Get an instance of the SLMarshallerFactory. + */ + public static SLMarshallerFactory getInstance() { + return SLMarshallerFactoryInstanceHolder.instance; + } + + // ---------------------------------------------------------------------- + + /** + * Initialize the JAXBContext for the legacy namespace. + */ + private static synchronized void ensureLegacyContext() { + // legacy marshaller is initialized only on demand + if (legacyContext == null) { + try { + String slPkgLegacy1_0 = at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory.class.getPackage().getName(); + String slPkgLegacy1_1 = at.buergerkarte.namespaces.securitylayer._20020831_.ObjectFactory.class.getPackage().getName(); + String xmldsigPkg = org.w3._2000._09.xmldsig_.ObjectFactory.class.getPackage().getName(); + String cardChannelPkg = at.buergerkarte.namespaces.cardchannel.ObjectFactory.class.getPackage().getName(); + legacyContext = JAXBContext.newInstance(slPkgLegacy1_0 + ":" + slPkgLegacy1_1 + ":" + xmldsigPkg + ":" + cardChannelPkg); + } catch (JAXBException e) { + log.error("Failed to setup JAXBContext security layer request.", e); + throw new SLRuntimeException(e); + } + } + } + + /** + * Creates an SL marshaller. + * + * @param formattedOutput + * true if the marshaller should produce formated + * output, false otherwise + * @return an SL marshaller + */ + public Marshaller createMarshaller(boolean formattedOutput) { + return createMarshaller(formattedOutput, false); + } + + /** + * Creates an SL marshaller. + * + * @param formattedOutput + * true if the marshaller should produce formated + * output, false otherwise + * @param fragment + * true if the marshaller should produce a XML fragment + * (omit XML declaration), false otherwise + * @return an SL marshaller + */ + public Marshaller createMarshaller(boolean formattedOutput, boolean fragment) { + try { + return MarshallerFactory.createMarshaller(context, formattedOutput, fragment); + } catch (JAXBException e) { + log.fatal("Failed to marshall error response.", e); + throw new SLRuntimeException("Failed to marshall error response.", e); + } + } + + /** + * Creates a legacy SL marshaller. + * + * @param formattedOutput + * true if the marshaller should produce formated + * output, false otherwise + * @return a legacy SL marshaller + */ + public Marshaller createLegacyMarshaller(boolean formattedOutput) { + return createLegacyMarshaller(formattedOutput, false); + } + + /** + * Creates a legacy SL marshaller. + * + * @param formattedOutput + * true if the marshaller should produce formated + * output, false otherwise + * @param fragment + * true if the marshaller should produce a XML fragment + * (omit XML declaration), false otherwise + * @return a legacy SL marshaller + */ + public Marshaller createLegacyMarshaller(boolean formattedOutput, boolean fragment) { + try { + ensureLegacyContext(); + return MarshallerFactory.createMarshaller(legacyContext, formattedOutput, fragment); + } catch (JAXBException e) { + log.fatal("Failed to marshall error response.", e); + throw new SLRuntimeException("Failed to marshall error response.", e); + } + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java index 7989a771..e9e483c5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/SLResult.java @@ -32,12 +32,14 @@ public interface SLResult { */ public String getMimeType(); - public void writeTo(Result aResult); + public void writeTo(Result aResult, boolean fragment); /** * - * @param result + * @param result + * @param fragment TODO * @param transformer may be null. */ - public void writeTo(Result result, Templates templates); + public void writeTo(Result result, Templates templates, boolean fragment); + } \ No newline at end of file diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java index ce03dcf9..9a4536e6 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java @@ -16,7 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import java.io.ByteArrayOutputStream; import java.util.Arrays; import java.util.Collections; @@ -24,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.regex.Pattern; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -42,10 +40,8 @@ import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayTy import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadValue; import at.gv.egiz.bku.slcommands.InfoboxReadResult; import at.gv.egiz.bku.slcommands.SLCommandContext; -import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slexceptions.SLCommandException; -import at.gv.egiz.marshal.MarshallerFactory; -import javax.xml.bind.PropertyException; /** * An abstract base class for {@link Infobox} implementations of type associative array. @@ -255,13 +251,10 @@ public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl } protected byte[] marshallValue(Object jaxbElement) throws SLCommandException { - SLCommandFactory commandFactory = SLCommandFactory.getInstance(); - JAXBContext jaxbContext = commandFactory.getJaxbContext(); - ByteArrayOutputStream result; + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false); + ByteArrayOutputStream result = new ByteArrayOutputStream(); try { - Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext); - result = new ByteArrayOutputStream(); marshaller.marshal(jaxbElement, result); } catch (JAXBException e) { log.info("Failed to marshall infobox content.", e); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java index b352a51e..19df4334 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureResultImpl.java @@ -16,8 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -33,10 +31,8 @@ import org.w3c.dom.Node; import at.buergerkarte.namespaces.securitylayer._1.CreateXMLSignatureResponseType; import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; -import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.marshal.MarshallerFactory; -import javax.xml.bind.PropertyException; /** * This calls implements the result of the security layer command CreateXMLSignature. @@ -86,10 +82,9 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { JAXBElement createCreateXMLSignatureResponse = factory.createCreateXMLSignatureResponse(createCreateXMLSignatureResponseType); DocumentFragment fragment = doc.createDocumentFragment(); - - JAXBContext jaxbContext = SLCommandFactory.getInstance().getJaxbContext(); + + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false); try { - Marshaller marshaller = MarshallerFactory.createMarshaller(jaxbContext); marshaller.marshal(createCreateXMLSignatureResponse, fragment); } catch (JAXBException e) { log.error("Failed to marshall 'CreateXMLSignatureResponse'", e); @@ -105,8 +100,8 @@ public class CreateXMLSignatureResultImpl extends SLResultImpl { } @Override - public void writeTo(Result result, Templates templates) { - writeTo(doc, result, templates); + public void writeTo(Result result, Templates templates, boolean fragment) { + writeTo(doc, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java index 5d0f0de0..aedde238 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImpl.java @@ -56,11 +56,11 @@ public class ErrorResultImpl extends SLResultImpl implements ErrorResult { } @Override - public void writeTo(Result result, Templates templates) { + public void writeTo(Result result, Templates templates, boolean fragment) { if (locale == null) { - writeErrorTo(slException, result, templates); + writeErrorTo(slException, result, templates, fragment); } else { - writeErrorTo(slException, result, templates, locale); + writeErrorTo(slException, result, templates, locale, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java index 46bfe18b..0c2b96f9 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusCommandImpl.java @@ -19,10 +19,8 @@ package at.gv.egiz.bku.slcommands.impl; import at.buergerkarte.namespaces.securitylayer._1.GetStatusRequestType; import at.gv.egiz.bku.slcommands.GetStatusCommand; -import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLCommandException; -import at.gv.egiz.bku.slexceptions.SLException; import at.gv.egiz.stal.ErrorResponse; import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.STALResponse; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java index fddd3b0b..fb1f627f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/GetStatusResultImpl.java @@ -45,8 +45,8 @@ public class GetStatusResultImpl extends SLResultImpl implements GetStatusResult } @Override - public void writeTo(Result result, Templates templates) { + public void writeTo(Result result, Templates templates, boolean fragment) { JAXBElement response = of.createGetStatusResponse(responseType); - writeTo(response, result, templates); + writeTo(response, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java index 7a82e43f..160e9589 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java @@ -18,7 +18,6 @@ package at.gv.egiz.bku.slcommands.impl; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.net.MalformedURLException; import java.security.cert.X509Certificate; import java.util.ArrayList; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java index 75e44afa..422b424f 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultFileImpl.java @@ -16,8 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -39,10 +37,8 @@ import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; import at.buergerkarte.namespaces.securitylayer._1.XMLContentType; import at.gv.egiz.bku.slcommands.InfoboxReadResult; import at.gv.egiz.bku.slcommands.SLCommand; -import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.marshal.MarshallerFactory; -import javax.xml.bind.PropertyException; /** * This class implements the result of the security layer command InfoboxReadRequest. @@ -98,10 +94,9 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements infoboxReadResponseType.setBinaryFileData(base64XMLContentType); JAXBElement infoboxReadResponse = factory.createInfoboxReadResponse(infoboxReadResponseType); - - JAXBContext context = SLCommandFactory.getInstance().getJaxbContext(); + + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false); try { - Marshaller marshaller = MarshallerFactory.createMarshaller(context); marshaller.marshal(infoboxReadResponse, doc); } catch (JAXBException e) { log.error("Failed to marshal 'InfoboxReadResponse' document.", e); @@ -158,8 +153,8 @@ public class InfoboxReadResultFileImpl extends SLResultImpl implements } @Override - public void writeTo(Result result, Templates templates) { - writeTo(xmlDocument, result, templates); + public void writeTo(Result result, Templates templates, boolean fragment) { + writeTo(xmlDocument, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java index e508941d..271ec955 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadResultImpl.java @@ -55,10 +55,10 @@ public class InfoboxReadResultImpl extends SLResultImpl implements InfoboxReadRe } @Override - public void writeTo(Result result, Templates templates) { + public void writeTo(Result result, Templates templates, boolean fragment) { ObjectFactory objectFactory = new ObjectFactory(); JAXBElement response = objectFactory.createInfoboxReadResponse(infoboxReadResponse); - writeTo(response, result, templates); + writeTo(response, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java index 15064756..e12536ba 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java @@ -36,8 +36,8 @@ public class InfoboxUpdateResultImpl extends SLResultImpl implements } @Override - public void writeTo(Result result, Templates templates) { - writeTo(RESPONSE, result, templates); + public void writeTo(Result result, Templates templates, boolean fragment) { + writeTo(RESPONSE, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java index 05986f85..87733e39 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImpl.java @@ -41,8 +41,8 @@ public class NullOperationResultImpl extends SLResultImpl implements NullOperati } @Override - public void writeTo(Result result, Templates templates) { - writeTo(RESPONSE, result, templates); + public void writeTo(Result result, Templates templates, boolean fragment) { + super.writeTo(RESPONSE, result, templates, fragment); } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java index 0452bddf..0077b7b2 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLResultImpl.java @@ -17,12 +17,14 @@ package at.gv.egiz.bku.slcommands.impl; import java.io.UnsupportedEncodingException; +import java.math.BigInteger; import java.util.Locale; -import javax.xml.bind.JAXBContext; +import javax.xml.XMLConstants; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; +import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; @@ -41,17 +43,15 @@ import org.w3c.dom.Node; import at.buergerkarte.namespaces.securitylayer._1.ErrorResponseType; import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; -import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLBindingException; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.bku.utils.DebugOutputStream; import at.gv.egiz.bku.utils.DebugWriter; -import at.gv.egiz.marshal.MarshallerFactory; -import javax.xml.bind.PropertyException; /** * This class serves as an abstract base class for the implementation of a @@ -90,20 +90,18 @@ public abstract class SLResultImpl implements SLResult { return resultingMimeType; } - private Marshaller getMarshaller() { - try { - JAXBContext context = SLCommandFactory.getInstance().getJaxbContext(); - Marshaller marshaller = MarshallerFactory.createMarshaller(context, true); - return marshaller; - } catch (JAXBException e) { - log.fatal("Failed to marshall error response.", e); - throw new SLRuntimeException("Failed to marshall error response.", e); - } + @Override + public void writeTo(Result result, boolean fragment) { + writeTo(result, null, false); } + @Override + public abstract void writeTo(Result result, Templates templates, boolean fragment); + private TransformerHandler getTransformerHandler(Templates templates, Result result) throws SLException { try { SAXTransformerFactory transformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); TransformerHandler transformerHandler = transformerFactory.newTransformerHandler(templates); transformerHandler.setResult(result); return transformerHandler; @@ -119,12 +117,6 @@ public abstract class SLResultImpl implements SLResult { } } - @Override - public void writeTo(Result result) { - writeTo(result, null); - } - - /** * Writes the given response to the SAX result using * the given transform templates. @@ -133,7 +125,7 @@ public abstract class SLResultImpl implements SLResult { * @param result * @param templates */ - protected void writeTo(JAXBElement response, Result result, Templates templates) { + protected void writeTo(JAXBElement response, Result result, Templates templates, boolean fragment) { DebugWriter dw = null; DebugOutputStream ds = null; @@ -154,11 +146,11 @@ public abstract class SLResultImpl implements SLResult { try { transformerHandler = getTransformerHandler(templates, result); } catch (SLException e) { - writeErrorTo(e, result, templates); + writeErrorTo(e, result, templates, fragment); } } - Marshaller marshaller = getMarshaller(); + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(true); try { if (transformerHandler != null) { marshaller.marshal(response, transformerHandler); @@ -168,7 +160,7 @@ public abstract class SLResultImpl implements SLResult { } catch (JAXBException e) { log.info("Failed to marshall " + response.getName() + " result." , e); SLCommandException commandException = new SLCommandException(4000); - writeErrorTo(commandException, result, templates); + writeErrorTo(commandException, result, templates, fragment); } if (ds != null) { @@ -185,7 +177,7 @@ public abstract class SLResultImpl implements SLResult { } - protected void writeTo(Node node, Result result, Templates templates) { + protected void writeTo(Node node, Result result, Templates templates, boolean fragment) { DebugWriter dw = null; DebugOutputStream ds = null; @@ -205,24 +197,30 @@ public abstract class SLResultImpl implements SLResult { try { TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); + if (fragment) { + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + } transformer.transform(new DOMSource(node), result); } catch (TransformerConfigurationException e) { log.error("Failed to create Transformer.", e); - writeErrorTo(new SLException(4000), result, null); + writeErrorTo(new SLException(4000), result, null, fragment); } catch (TransformerException e) { log.error("Failed to transform result.", e); - writeErrorTo(new SLException(4000), result, null); + writeErrorTo(new SLException(4000), result, null, fragment); } } else { try { Transformer transformer = templates.newTransformer(); + if (fragment) { + transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + } transformer.transform(new DOMSource(node), result); } catch (TransformerConfigurationException e) { log.info("Failed to create transformer.", e); - writeErrorTo(new SLException(2008), result, templates); + writeErrorTo(new SLException(2008), result, templates, fragment); } catch (TransformerException e) { log.error("Failed to transform result.", e); - writeErrorTo(new SLException(2008), result, templates); + writeErrorTo(new SLException(2008), result, templates, fragment); } } @@ -240,11 +238,11 @@ public abstract class SLResultImpl implements SLResult { } - protected void writeErrorTo(SLException slException, Result result, Templates templates) { - writeErrorTo(slException, result, templates, Locale.getDefault()); + protected void writeErrorTo(SLException slException, Result result, Templates templates, boolean fragment) { + writeErrorTo(slException, result, templates, Locale.getDefault(), fragment); } - protected void writeErrorTo(SLException slException, Result result, Templates templates, Locale locale) { + protected void writeErrorTo(SLException slException, Result result, Templates templates, Locale locale, boolean fragment) { TransformerHandler transformerHandler = null; if (templates != null) { @@ -256,13 +254,33 @@ public abstract class SLResultImpl implements SLResult { } } - ObjectFactory factory = new ObjectFactory(); - ErrorResponseType responseType = factory.createErrorResponseType(); - responseType.setErrorCode(slException.getErrorCode()); - responseType.setInfo(slException.getLocalizedMessage(locale)); - JAXBElement response = factory.createErrorResponse(responseType); + Object response; + + Marshaller marshaller; + if (slException instanceof SLVersionException + && ("http://www.buergerkarte.at/namespaces/securitylayer/20020225#" + .equals(((SLVersionException) slException).getNamespaceURI()) || + "http://www.buergerkarte.at/namespaces/securitylayer/20020831#" + .equals(((SLVersionException) slException).getNamespaceURI()))) { + // issue ErrorResponse in the legacy namespace + at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory factory + = new at.buergerkarte.namespaces.securitylayer._20020225_.ObjectFactory(); + at.buergerkarte.namespaces.securitylayer._20020225_.ErrorResponseType errorResponseType = factory + .createErrorResponseType(); + errorResponseType.setErrorCode(BigInteger.valueOf(slException + .getErrorCode())); + errorResponseType.setInfo(slException.getLocalizedMessage(locale)); + response = factory.createErrorResponse(errorResponseType); + marshaller = SLMarshallerFactory.getInstance().createLegacyMarshaller(true, fragment); + } else { + ObjectFactory factory = new ObjectFactory(); + ErrorResponseType responseType = factory.createErrorResponseType(); + responseType.setErrorCode(slException.getErrorCode()); + responseType.setInfo(slException.getLocalizedMessage(locale)); + response = factory.createErrorResponse(responseType); + marshaller = SLMarshallerFactory.getInstance().createMarshaller(true, fragment); + } - Marshaller marshaller = getMarshaller(); try { if (transformerHandler != null) { marshaller.marshal(response, transformerHandler); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java index b64306aa..2088a684 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java @@ -81,7 +81,6 @@ import at.gv.egiz.bku.viewer.ValidationException; import at.gv.egiz.bku.viewer.Validator; import at.gv.egiz.bku.viewer.ValidatorFactory; import at.gv.egiz.dom.DOMUtils; -import at.gv.egiz.marshal.NamespacePrefix; import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import at.gv.egiz.slbinding.impl.XMLContentType; import javax.xml.namespace.NamespaceContext; diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java index 9182e824..26ddb153 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java @@ -16,7 +16,6 @@ */ package at.gv.egiz.bku.slcommands.impl.xsect; -import at.gv.egiz.stal.HashDataInput; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -31,9 +30,7 @@ import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; -import java.util.Map; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; @@ -87,8 +84,6 @@ import at.gv.egiz.bku.utils.urldereferencer.StreamData; import at.gv.egiz.bku.utils.urldereferencer.URLDereferencer; import at.gv.egiz.bku.utils.urldereferencer.URLDereferencerContext; import at.gv.egiz.dom.DOMUtils; -import at.gv.egiz.marshal.NamespacePrefix; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import at.gv.egiz.slbinding.impl.XMLContentType; import at.gv.egiz.stal.STAL; import at.gv.egiz.xades.QualifyingPropertiesException; @@ -327,6 +322,8 @@ public class Signature { */ public void buildXMLSignature() throws SLCommandException { + String signatureId = ctx.getIdValueFactory().createIdValue("Signature"); + List objects = new ArrayList(); List references = new ArrayList(); @@ -340,7 +337,7 @@ public class Signature { } } - addXAdESObjectAndReference(objects, references); + addXAdESObjectAndReference(objects, references, signatureId); XMLSignatureFactory signatureFactory = ctx.getSignatureFactory(); AlgorithmMethodFactory algorithmMethodFactory = ctx.getAlgorithmMethodFactory(); @@ -369,7 +366,6 @@ public class Signature { ki = kif.newKeyInfo(Collections.singletonList(x509Data)); } - String signatureId = ctx.getIdValueFactory().createIdValue("Signature"); String signatureValueId = ctx.getIdValueFactory().createIdValue("SignatureValue"); xmlSignature = signatureFactory.newXMLSignature(si, ki, objects, signatureId, signatureValueId); @@ -588,7 +584,7 @@ public class Signature { * @param references * the list of ds:References to add the created * ds:Reference to - * + * @param signatureId TODO * @throws SLCommandException * if creating and adding the XAdES * QualifyingProperties fails @@ -596,7 +592,7 @@ public class Signature { * if objects or references is * null */ - private void addXAdESObjectAndReference(List objects, List references) throws SLCommandException { + private void addXAdESObjectAndReference(List objects, List references, String signatureId) throws SLCommandException { QualifyingPropertiesFactory factory = QualifyingPropertiesFactory.getInstance(); @@ -630,9 +626,11 @@ public class Signature { } } + String target = "#" + signatureId; + JAXBElement qualifyingProperties; try { - qualifyingProperties = factory.createQualifyingProperties111(date, signingCertificates, idValue, dataObjectFormats); + qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats); } catch (QualifyingPropertiesException e) { log.error("Failed to create QualifyingProperties.", e); throw new SLCommandException(4000); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java index 5ce5cba1..73ac8d1b 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLExceptionMessages.java @@ -47,4 +47,10 @@ public final class SLExceptionMessages { public static final String EC4011_NOTIMPLEMENTED = "ec4011.notimplemented"; + // + // Legacy error codes + // + + public static final String LEC2901_NOTIMPLEMENTED = "lec2901.notimplemented"; + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java new file mode 100644 index 00000000..45501746 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slexceptions/SLVersionException.java @@ -0,0 +1,28 @@ +package at.gv.egiz.bku.slexceptions; + +public class SLVersionException extends SLException { + + private static final long serialVersionUID = 1L; + + protected String namespaceURI; + + public SLVersionException(String namespaceURI) { + super(2901, SLExceptionMessages.LEC2901_NOTIMPLEMENTED, new Object[] {namespaceURI}); + this.namespaceURI = namespaceURI; + } + + public SLVersionException(int errorCode, String namespaceURI) { + super(errorCode); + this.namespaceURI = namespaceURI; + } + + public SLVersionException(int errorCode, String namespaceURI, String message, Object[] arguments) { + super(errorCode, message, arguments); + this.namespaceURI = namespaceURI; + } + + public String getNamespaceURI() { + return namespaceURI; + } + +} diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd new file mode 100644 index 00000000..76d1d7cb --- /dev/null +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020225.xsd @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd new file mode 100644 index 00000000..6759d791 --- /dev/null +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slcommands/schema/Core.20020831.xsd @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties index 73409c8b..db56184e 100644 --- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties @@ -95,5 +95,10 @@ ec4000.infobox.invalid=Die Infobox '{0}' enth ec4000.idlink.transfomation.failed=Die komprimierte Personenbindung konnte mit dem Stylesheet {0} nicht transformiert werden. ec4002.infobox.unknown=Unbekannter Infoboxbezeichner {0}. ec4003.not.resolved=Zu signierendes Datum kann nicht aufgelöst werden (URI={0}). -ec4011.notimplemented=Befehl {0} ist nicht implementiert. +ec4011.notimplemented=Befehl {0} ist nicht implementiert. + +# Legacy error messages +# + +lec2901.notimplemented=Die in der Anfrage verwendete Version des Security-Layer Protokolls ({0}) wird nicht mehr unterstützt. diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties index 91ca20e8..6c67ba87 100644 --- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties @@ -96,3 +96,7 @@ ec4000.idlink.transfomation.failed=Failed to transform CompressedIdentityLink wi ec4002.infobox.unknown=Unknown info box identifier {0}. ec4003.not.resolved=Data to be signed cannot be resolved from URI={0}. ec4011.notimplemented=Command {0} not implemented. + +# Legacy error codes +# +lec2901.notimplemented=The version ({0}) of the security-layer protocol used in the request is not supported. diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIteratorTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIteratorTest.java new file mode 100644 index 00000000..703e4460 --- /dev/null +++ b/bkucommon/src/test/java/at/gv/egiz/bku/binding/XWWWFormUrlInputIteratorTest.java @@ -0,0 +1,152 @@ +package at.gv.egiz.bku.binding; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.URLEncoder; +import java.nio.charset.Charset; + +import org.junit.Ignore; +import org.junit.Test; +import static org.junit.Assert.*; + +public class XWWWFormUrlInputIteratorTest { + + @Test + public void testOneParam() throws IOException { + + final String name = "name"; + final String value = "value"; + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OutputStreamWriter w = new OutputStreamWriter(os, Charset.forName("UTF-8")); + w.write(name); + w.write("="); + w.write(value); + w.flush(); + w.close(); + + ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray()); + XWWWFormUrlInputIterator decoder = new XWWWFormUrlInputIterator(in); + + assertTrue(decoder.hasNext()); + FormParameter param = decoder.next(); + assertNotNull(param); + assertEquals(name, param.getFormParameterName()); + InputStream vis = param.getFormParameterValue(); + assertNotNull(vis); + InputStreamReader r = new InputStreamReader(vis); + char[] buf = new char[value.length() + 1]; + int len = r.read(buf); + assertEquals(value.length(), len); + assertEquals(value, new String(buf, 0, len)); + assertFalse(decoder.hasNext()); + Exception ex = null; + try { + decoder.next(); + } catch (Exception e) { + ex = e; + } + assertNotNull(ex); + + } + + @Test + public void testTwoParam() throws IOException { + + final String name1 = "name"; + final String value1 = "value"; + final String name2 = "Name_2"; + final String value2 = "Value 2"; + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OutputStreamWriter w = new OutputStreamWriter(os, Charset.forName("UTF-8")); + w.write(name1); + w.write("="); + w.write(value1); + w.write("&"); + w.write(URLEncoder.encode(name2, "UTF-8")); + w.write("="); + w.write(URLEncoder.encode(value2, "UTF-8")); + w.flush(); + w.close(); + + ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray()); + XWWWFormUrlInputIterator decoder = new XWWWFormUrlInputIterator(in); + + assertTrue(decoder.hasNext()); + FormParameter param = decoder.next(); + assertNotNull(param); + assertEquals(name1, param.getFormParameterName()); + InputStream vis = param.getFormParameterValue(); + assertNotNull(vis); + InputStreamReader r = new InputStreamReader(vis); + char[] buf = new char[value1.length() + 1]; + int len = r.read(buf); + assertEquals(value1.length(), len); + assertEquals(value1, new String(buf, 0, len)); + + assertTrue(decoder.hasNext()); + param = decoder.next(); + assertNotNull(param); + assertEquals(name2, param.getFormParameterName()); + vis = param.getFormParameterValue(); + assertNotNull(vis); + r = new InputStreamReader(vis); + buf = new char[value2.length() + 1]; + len = r.read(buf); + assertEquals(value2.length(), len); + assertEquals(value2, new String(buf, 0, len)); + + assertFalse(decoder.hasNext()); + } + + @Test + public void testURLEnc() throws IOException { + + String name = "name"; + byte[] value = new byte[128]; + for (int i = 0; i < value.length; i++) { + value[i] = (byte) i; + } + + String encValue = URLEncoder.encode(new String(value, "UTF-8"), "ASCII"); + System.out.println(encValue); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + OutputStreamWriter w = new OutputStreamWriter(os, Charset.forName("UTF-8")); + w.write(name); + w.write("="); + w.write(encValue); + w.flush(); + w.close(); + + ByteArrayInputStream in = new ByteArrayInputStream(os.toByteArray()); + XWWWFormUrlInputIterator decoder = new XWWWFormUrlInputIterator(in); + + assertTrue(decoder.hasNext()); + FormParameter param = decoder.next(); + assertNotNull(param); + assertEquals(name, param.getFormParameterName()); + InputStream vis = param.getFormParameterValue(); + assertNotNull(vis); + byte[] buf = new byte[value.length]; + int len = vis.read(buf); + assertArrayEquals(value, buf); + assertEquals(value.length, len); + assertFalse(decoder.hasNext()); + Exception ex = null; + try { + decoder.next(); + } catch (Exception e) { + ex = e; + } + assertNotNull(ex); + + } + + +} diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/SLCommandFactoryTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/SLCommandFactoryTest.java index cd931878..7a087b38 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/SLCommandFactoryTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/SLCommandFactoryTest.java @@ -33,6 +33,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.stal.dummy.DummySTAL; public class SLCommandFactoryTest { @@ -54,7 +55,7 @@ public class SLCommandFactoryTest { } @Test - public void createNullOperationCommand() throws SLCommandException, SLRuntimeException, SLRequestException { + public void createNullOperationCommand() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { Reader requestReader = new StringReader( ""); Source source = new StreamSource(requestReader); @@ -65,7 +66,7 @@ public class SLCommandFactoryTest { } @Test(expected=SLCommandException.class) - public void createUnsupportedCommand() throws SLCommandException, SLRuntimeException, SLRequestException { + public void createUnsupportedCommand() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { Reader requestReader = new StringReader( ""); Source source = new StreamSource(requestReader); @@ -75,7 +76,7 @@ public class SLCommandFactoryTest { } @Test(expected=SLRequestException.class) - public void createMalformedCommand() throws SLCommandException, SLRuntimeException, SLRequestException { + public void createMalformedCommand() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { Reader requestReader = new StringReader( "" + "missplacedContent" + diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureComandImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureComandImplTest.java index 8fdec375..4e9b4cd7 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureComandImplTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureComandImplTest.java @@ -41,6 +41,7 @@ import at.gv.egiz.bku.slcommands.impl.xsect.STALProvider; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.dummy.DummySTAL; //@Ignore @@ -66,7 +67,7 @@ public class CreateXMLSignatureComandImplTest { } @Test - public void testCreateXMLSignatureRequest() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testCreateXMLSignatureRequest() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/createxmlsignaturerequest/CreateXMLSignatureRequest.xml"); assertNotNull(inputStream); @@ -76,11 +77,11 @@ public class CreateXMLSignatureComandImplTest { assertTrue(command instanceof CreateXMLSignatureCommand); SLResult result = command.execute(); - result.writeTo(new StreamResult(System.out)); + result.writeTo(new StreamResult(System.out), false); } // @Test(expected=SLCommandException.class) - public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-1.xml"); assertNotNull(inputStream); @@ -90,7 +91,7 @@ public class CreateXMLSignatureComandImplTest { } // @Test(expected=SLCommandException.class) - public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-2.xml"); assertNotNull(inputStream); diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImplTest.java index f10ca520..aa2bcd62 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImplTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/ErrorResultImplTest.java @@ -36,7 +36,7 @@ public class ErrorResultImplTest { ByteArrayOutputStream stream = new ByteArrayOutputStream(); StreamResult result = new StreamResult(stream); - errorResult.writeTo(result); + errorResult.writeTo(result, false); System.out.println(stream.toString()); diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadComandImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadComandImplTest.java index b0d11d47..bfc784f7 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadComandImplTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/InfoboxReadComandImplTest.java @@ -39,6 +39,7 @@ import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.dummy.DummySTAL; @@ -63,7 +64,7 @@ public class InfoboxReadComandImplTest { } @Test - public void testInfboxReadRequest() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequest() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.xml"); assertNotNull(inputStream); @@ -73,11 +74,11 @@ public class InfoboxReadComandImplTest { assertTrue(command instanceof InfoboxReadCommand); SLResult result = command.execute(); - result.writeTo(new StreamResult(System.out)); + result.writeTo(new StreamResult(System.out), false); } @Test(expected=SLCommandException.class) - public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-1.xml"); assertNotNull(inputStream); @@ -87,7 +88,7 @@ public class InfoboxReadComandImplTest { assertTrue(command instanceof InfoboxReadCommand); } - public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-2.xml"); assertNotNull(inputStream); diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImplTest.java index 8632b67c..e9b0775f 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImplTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/NullOperationResultImplTest.java @@ -33,7 +33,7 @@ public class NullOperationResultImplTest { ByteArrayOutputStream stream = new ByteArrayOutputStream(); StreamResult result = new StreamResult(stream); - nullOperationResult.writeTo(result); + nullOperationResult.writeTo(result, false); System.out.println(stream.toString()); diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java index f9c60b86..a17f0797 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/SVPersonendatenInfoboxImplTest.java @@ -23,7 +23,6 @@ import iaik.asn1.CodingException; import java.io.IOException; import java.io.InputStream; -import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; @@ -42,10 +41,12 @@ import at.gv.egiz.bku.slcommands.InfoboxReadCommand; import at.gv.egiz.bku.slcommands.SLCommand; import at.gv.egiz.bku.slcommands.SLCommandContext; import at.gv.egiz.bku.slcommands.SLCommandFactory; +import at.gv.egiz.bku.slcommands.SLMarshallerFactory; import at.gv.egiz.bku.slcommands.SLResult; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.bku.slexceptions.SLVersionException; import at.gv.egiz.stal.STAL; import at.gv.egiz.stal.dummy.DummySTAL; @@ -93,9 +94,7 @@ public class SVPersonendatenInfoboxImplTest { JAXBElement ehic = new ObjectFactory().createEHIC(attributeList); - JAXBContext jaxbContext = SLCommandFactory.getInstance().getJaxbContext(); - - Marshaller marshaller = jaxbContext.createMarshaller(); + Marshaller marshaller = SLMarshallerFactory.getInstance().createMarshaller(false); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); @@ -105,7 +104,7 @@ public class SVPersonendatenInfoboxImplTest { @Ignore @Test - public void testInfboxReadRequest() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequest() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.xml"); assertNotNull(inputStream); @@ -115,12 +114,12 @@ public class SVPersonendatenInfoboxImplTest { assertTrue(command instanceof InfoboxReadCommand); SLResult result = command.execute(); - result.writeTo(new StreamResult(System.out)); + result.writeTo(new StreamResult(System.out), false); } @Ignore @Test(expected=SLCommandException.class) - public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid1() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-1.xml"); assertNotNull(inputStream); @@ -131,7 +130,7 @@ public class SVPersonendatenInfoboxImplTest { } @Ignore - public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException { + public void testInfboxReadRequestInvalid2() throws SLCommandException, SLRuntimeException, SLRequestException, SLVersionException { InputStream inputStream = getClass().getClassLoader().getResourceAsStream("at/gv/egiz/bku/slcommands/infoboxreadcommand/IdentityLink.Binary.Invalid-2.xml"); assertNotNull(inputStream); diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1/TransformsInfoType.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1/TransformsInfoType.java index 5ee40b95..e4a8f48e 100644 --- a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1/TransformsInfoType.java +++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_1/TransformsInfoType.java @@ -24,11 +24,15 @@ package at.buergerkarte.namespaces.securitylayer._1; +import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlType; import org.w3._2000._09.xmldsig_.TransformsType; +import org.w3c.dom.Element; /** @@ -58,8 +62,9 @@ import org.w3._2000._09.xmldsig_.TransformsType; }) public class TransformsInfoType { - @XmlElement(name = "Transforms", namespace = "http://www.w3.org/2000/09/xmldsig#") - protected TransformsType transforms; + @XmlElementRef(name = "Transforms", namespace = "http://www.w3.org/2000/09/xmldsig#", type = JAXBElement.class) + @XmlAnyElement(lax = true) + protected Object transforms; @XmlElement(name = "FinalDataMetaInfo", required = true) protected MetaInfoType finalDataMetaInfo; @@ -68,10 +73,12 @@ public class TransformsInfoType { * * @return * possible object is - * {@link TransformsType } + * {@link JAXBElement }{@code <}{@link String }{@code >} + * {@link Object } + * {@link Element } * */ - public TransformsType getTransforms() { + public Object getTransforms() { return transforms; } @@ -80,10 +87,12 @@ public class TransformsInfoType { * * @param value * allowed object is - * {@link TransformsType } + * {@link JAXBElement }{@code <}{@link String }{@code >} + * {@link Object } + * {@link Element } * */ - public void setTransforms(TransformsType value) { + public void setTransforms(Object value) { this.transforms = value; } diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ErrorResponseType.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ErrorResponseType.java new file mode 100644 index 00000000..69b5cd9d --- /dev/null +++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ErrorResponseType.java @@ -0,0 +1,98 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.2-b01-fcs +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.09.07 at 09:47:31 AM CEST +// + + +package at.buergerkarte.namespaces.securitylayer._20020225_; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for ErrorResponseType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="ErrorResponseType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="ErrorCode" type="{http://www.w3.org/2001/XMLSchema}integer"/>
+ *         <element name="Info" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ErrorResponseType", propOrder = { + "errorCode", + "info" +}) +public class ErrorResponseType { + + @XmlElement(name = "ErrorCode", required = true) + protected BigInteger errorCode; + @XmlElement(name = "Info", required = true) + protected String info; + + /** + * Gets the value of the errorCode property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getErrorCode() { + return errorCode; + } + + /** + * Sets the value of the errorCode property. + * + * @param value + * allowed object is + * {@link BigInteger } + * + */ + public void setErrorCode(BigInteger value) { + this.errorCode = value; + } + + /** + * Gets the value of the info property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getInfo() { + return info; + } + + /** + * Sets the value of the info property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setInfo(String value) { + this.info = value; + } + +} diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ObjectFactory.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ObjectFactory.java new file mode 100644 index 00000000..a02f9ca1 --- /dev/null +++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/ObjectFactory.java @@ -0,0 +1,280 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.2-b01-fcs +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.09.07 at 09:47:31 AM CEST +// + + +package at.buergerkarte.namespaces.securitylayer._20020225_; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the at.buergerkarte.namespaces.securitylayer._20020225_ package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _CreateXMLSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateXMLSignatureRequest"); + private final static QName _InfoboxUpdateRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxUpdateRequest"); + private final static QName _ErrorResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "ErrorResponse"); + private final static QName _VerifyXMLSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "VerifyXMLSignatureResponse"); + private final static QName _CreateSessionKeyResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateSessionKeyResponse"); + private final static QName _GetPropertiesRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "GetPropertiesRequest"); + private final static QName _GetPropertiesResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "GetPropertiesResponse"); + private final static QName _InfoboxAvailableResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxAvailableResponse"); + private final static QName _InfoboxAvailableRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxAvailableRequest"); + private final static QName _CreateSessionKeyRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateSessionKeyRequest"); + private final static QName _InfoboxUpdateResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxUpdateResponse"); + private final static QName _CreateXMLSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateXMLSignatureResponse"); + private final static QName _GetStatusResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "GetStatusResponse"); + private final static QName _CreateCMSSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateCMSSignatureRequest"); + private final static QName _CreateSymmetricSecretRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateSymmetricSecretRequest"); + private final static QName _VerifyXMLSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "VerifyXMLSignatureRequest"); + private final static QName _CreateSymmetricSecretResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateSymmetricSecretResponse"); + private final static QName _CreateCMSSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "CreateCMSSignatureResponse"); + private final static QName _VerifyCMSSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "VerifyCMSSignatureResponse"); + private final static QName _InfoboxReadResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxReadResponse"); + private final static QName _VerifyCMSSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "VerifyCMSSignatureRequest"); + private final static QName _InfoboxReadRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "InfoboxReadRequest"); + private final static QName _GetStatusRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "GetStatusRequest"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: at.buergerkarte.namespaces.securitylayer._20020225_ + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link ErrorResponseType } + * + */ + public ErrorResponseType createErrorResponseType() { + return new ErrorResponseType(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateXMLSignatureRequest") + public JAXBElement createCreateXMLSignatureRequest(Object value) { + return new JAXBElement(_CreateXMLSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxUpdateRequest") + public JAXBElement createInfoboxUpdateRequest(Object value) { + return new JAXBElement(_InfoboxUpdateRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link ErrorResponseType }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "ErrorResponse") + public JAXBElement createErrorResponse(ErrorResponseType value) { + return new JAXBElement(_ErrorResponse_QNAME, ErrorResponseType.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "VerifyXMLSignatureResponse") + public JAXBElement createVerifyXMLSignatureResponse(Object value) { + return new JAXBElement(_VerifyXMLSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateSessionKeyResponse") + public JAXBElement createCreateSessionKeyResponse(Object value) { + return new JAXBElement(_CreateSessionKeyResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "GetPropertiesRequest") + public JAXBElement createGetPropertiesRequest(Object value) { + return new JAXBElement(_GetPropertiesRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "GetPropertiesResponse") + public JAXBElement createGetPropertiesResponse(Object value) { + return new JAXBElement(_GetPropertiesResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxAvailableResponse") + public JAXBElement createInfoboxAvailableResponse(Object value) { + return new JAXBElement(_InfoboxAvailableResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxAvailableRequest") + public JAXBElement createInfoboxAvailableRequest(Object value) { + return new JAXBElement(_InfoboxAvailableRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateSessionKeyRequest") + public JAXBElement createCreateSessionKeyRequest(Object value) { + return new JAXBElement(_CreateSessionKeyRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxUpdateResponse") + public JAXBElement createInfoboxUpdateResponse(Object value) { + return new JAXBElement(_InfoboxUpdateResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateXMLSignatureResponse") + public JAXBElement createCreateXMLSignatureResponse(Object value) { + return new JAXBElement(_CreateXMLSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "GetStatusResponse") + public JAXBElement createGetStatusResponse(Object value) { + return new JAXBElement(_GetStatusResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateCMSSignatureRequest") + public JAXBElement createCreateCMSSignatureRequest(Object value) { + return new JAXBElement(_CreateCMSSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateSymmetricSecretRequest") + public JAXBElement createCreateSymmetricSecretRequest(Object value) { + return new JAXBElement(_CreateSymmetricSecretRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "VerifyXMLSignatureRequest") + public JAXBElement createVerifyXMLSignatureRequest(Object value) { + return new JAXBElement(_VerifyXMLSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateSymmetricSecretResponse") + public JAXBElement createCreateSymmetricSecretResponse(Object value) { + return new JAXBElement(_CreateSymmetricSecretResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "CreateCMSSignatureResponse") + public JAXBElement createCreateCMSSignatureResponse(Object value) { + return new JAXBElement(_CreateCMSSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "VerifyCMSSignatureResponse") + public JAXBElement createVerifyCMSSignatureResponse(Object value) { + return new JAXBElement(_VerifyCMSSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxReadResponse") + public JAXBElement createInfoboxReadResponse(Object value) { + return new JAXBElement(_InfoboxReadResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "VerifyCMSSignatureRequest") + public JAXBElement createVerifyCMSSignatureRequest(Object value) { + return new JAXBElement(_VerifyCMSSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "InfoboxReadRequest") + public JAXBElement createInfoboxReadRequest(Object value) { + return new JAXBElement(_InfoboxReadRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", name = "GetStatusRequest") + public JAXBElement createGetStatusRequest(Object value) { + return new JAXBElement(_GetStatusRequest_QNAME, Object.class, null, value); + } + +} diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/package-info.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/package-info.java new file mode 100644 index 00000000..084f6b11 --- /dev/null +++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020225_/package-info.java @@ -0,0 +1,9 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.2-b01-fcs +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.09.07 at 09:47:31 AM CEST +// + +@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020225#", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) +package at.buergerkarte.namespaces.securitylayer._20020225_; diff --git a/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020831_/ObjectFactory.java b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020831_/ObjectFactory.java new file mode 100644 index 00000000..17f6d4b4 --- /dev/null +++ b/utils/src/main/java/at/buergerkarte/namespaces/securitylayer/_20020831_/ObjectFactory.java @@ -0,0 +1,112 @@ +// +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.2-b01-fcs +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2009.09.07 at 09:47:31 AM CEST +// + + +package at.buergerkarte.namespaces.securitylayer._20020831_; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the at.buergerkarte.namespaces.securitylayer._20020831_ package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _CreateXMLSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "CreateXMLSignatureRequest"); + private final static QName _GetPropertiesResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "GetPropertiesResponse"); + private final static QName _VerifyXMLSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "VerifyXMLSignatureResponse"); + private final static QName _VerifyXMLSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "VerifyXMLSignatureRequest"); + private final static QName _VerifyCMSSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "VerifyCMSSignatureResponse"); + private final static QName _CreateXMLSignatureResponse_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "CreateXMLSignatureResponse"); + private final static QName _VerifyCMSSignatureRequest_QNAME = new QName("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "VerifyCMSSignatureRequest"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: at.buergerkarte.namespaces.securitylayer._20020831_ + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "CreateXMLSignatureRequest") + public JAXBElement createCreateXMLSignatureRequest(Object value) { + return new JAXBElement(_CreateXMLSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "GetPropertiesResponse") + public JAXBElement createGetPropertiesResponse(Object value) { + return new JAXBElement(_GetPropertiesResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "VerifyXMLSignatureResponse") + public JAXBElement createVerifyXMLSignatureResponse(Object value) { + return new JAXBElement(_VerifyXMLSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "VerifyXMLSignatureRequest") + public JAXBElement createVerifyXMLSignatureRequest(Object value) { + return new JAXBElement(_VerifyXMLSignatureRequest_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "VerifyCMSSignatureResponse") + public JAXBElement createVerifyCMSSignatureResponse(Object value) { + return new JAXBElement(_VerifyCMSSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "CreateXMLSignatureResponse") + public JAXBElement createCreateXMLSignatureResponse(Object value) { + return new JAXBElement(_CreateXMLSignatureResponse_QNAME, Object.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Object }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://www.buergerkarte.at/namespaces/securitylayer/20020831#", name = "VerifyCMSSignatureRequest") + public JAXBElement createVerifyCMSSignatureRequest(Object value) { + return new JAXBElement(_VerifyCMSSignatureRequest_QNAME, Object.class, null, value); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingInputStream.java b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingInputStream.java new file mode 100644 index 00000000..28ef6b88 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingInputStream.java @@ -0,0 +1,62 @@ +/** + * + */ +package at.gv.egiz.bku.utils; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.CharBuffer; + +/** + * @author mcentner + * + */ +public class URLEncodingInputStream extends InputStream { + + private char[] buffer = new char[1]; + + private CharBuffer charBuffer = CharBuffer.wrap(buffer); + + protected Readable in; + + /** + * @param in + */ + public URLEncodingInputStream(Readable in) { + this.in = in; + } + + /* (non-Javadoc) + * @see java.io.InputStream#read() + */ + @Override + public int read() throws IOException { + charBuffer.rewind(); + if (in.read(charBuffer) == -1) { + return -1; + } + if (buffer[0] == '+') { + return ' '; + } else if (buffer[0] == '%') { + charBuffer.rewind(); + if (in.read(charBuffer) == -1) { + throw new IOException("Invalid URL encoding."); + } + int c1 = Character.digit(buffer[0], 16); + charBuffer.rewind(); + if (in.read(charBuffer) == -1) { + throw new IOException("Invalid URL encoding."); + } + int c2 = Character.digit(buffer[0], 16); + if (c1 == -1 || c2 == -1) { + throw new IOException("Invalid URL encoding."); + } + return ((c1 << 4) | c2); + } else { + return buffer[0]; + } + } + + + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingOutputStream.java b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingOutputStream.java new file mode 100644 index 00000000..df42df6d --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingOutputStream.java @@ -0,0 +1,134 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.CharBuffer; +import java.util.BitSet; + +/** + * An URLEncoding RFC3986, Section 2.1 + * OutputStream. + * + * @author mcentner + */ +public class URLEncodingOutputStream extends OutputStream { + + private static final int MAX_BUFFER_SIZE = 512; + + private static final BitSet UNRESERVED = new BitSet(256); + + static { + for (int i = '0'; i <= '9'; i++) { + UNRESERVED.set(i); + } + for (int i = 'a'; i <= 'z'; i++) { + UNRESERVED.set(i); + } + for (int i = 'A'; i <= 'Z'; i++) { + UNRESERVED.set(i); + } + UNRESERVED.set('-'); + UNRESERVED.set('_'); + UNRESERVED.set('.'); + UNRESERVED.set('*'); + UNRESERVED.set(' '); + } + + private static final char[] HEX = new char[] { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + private char[] buf; + + protected Appendable out; + + /** + * Creates a new instance of this URLEncodingOutputStream that writes to the + * given Appendable. + *

+ * Note: According to + * http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars the input + * for the {@link #write()} methods should be the UTF-8. + *

+ * + * @param out + */ + public URLEncodingOutputStream(Appendable out) { + this.out = out; + } + + /* (non-Javadoc) + * @see java.io.OutputStream#write(int) + */ + @Override + public void write(int b) throws IOException { + b &= 0xFF; + if (UNRESERVED.get(b)) { + if (b == ' ') { + out.append('+'); + } else { + out.append((char) b); + } + } else { + out.append('%').append(HEX[b >>> 4]).append(HEX[b & 0xF]); + } + + } + + /* (non-Javadoc) + * @see java.io.OutputStream#write(byte[], int, int) + */ + @Override + public void write(byte[] b, int off, int len) throws IOException { + + // ensure a buffer at least double the size of end - start + 1 + // but max + int sz = Math.min(len + 1, MAX_BUFFER_SIZE); + if (buf == null || buf.length < sz) { + buf = new char[sz]; + } + + int bPos = 0; + for (int i = 0; i < len; i++) { + if (bPos + 3 > buf.length) { + // flush buffer + out.append(CharBuffer.wrap(buf, 0, bPos)); + bPos = 0; + } + int c = 0xFF & b[off + i]; + if (UNRESERVED.get(c)) { + if (c == ' ') { + buf[bPos++] = '+'; + } else { + buf[bPos++] = (char) c; + } + } else { + buf[bPos++] = '%'; + buf[bPos++] = HEX[c >>> 4]; + buf[bPos++] = HEX[c & 0xF]; + } + } + out.append(CharBuffer.wrap(buf, 0, bPos)); + + } + + +} diff --git a/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingWriter.java b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingWriter.java new file mode 100644 index 00000000..3ba90265 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/bku/utils/URLEncodingWriter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */package at.gv.egiz.bku.utils; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; + +/** + * An URLEncoding RFC3986, Section + * 2.1 Writer, that uses an UTF-8 encoding according to http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars for + * writing non-ASCII characters. + * + * @author mcentner + */ +public class URLEncodingWriter extends Writer { + + protected OutputStreamWriter osw; + + public URLEncodingWriter(Appendable out) { + URLEncodingOutputStream urlEnc = new URLEncodingOutputStream(out); + osw = new OutputStreamWriter(urlEnc, Charset.forName("UTF-8")); + } + + @Override + public void close() throws IOException { + osw.close(); + } + + @Override + public void flush() throws IOException { + osw.flush(); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + osw.write(cbuf, off, len); + } + +} diff --git a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java index ccebcc81..3ac0a86e 100644 --- a/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java +++ b/utils/src/main/java/at/gv/egiz/marshal/MarshallerFactory.java @@ -31,13 +31,17 @@ public class MarshallerFactory { private static final Log log = LogFactory.getLog(MarshallerFactory.class); - public static Marshaller createMarshaller(JAXBContext ctx, boolean formattedOutput) throws JAXBException { + public static Marshaller createMarshaller(JAXBContext ctx, boolean formattedOutput, boolean fragment) throws JAXBException { Marshaller m = ctx.createMarshaller(); try { if (formattedOutput) { log.trace("setting marshaller property FORMATTED_OUTPUT"); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); } + if (fragment) { + log.trace("setting marshaller property FRAGMENT"); + m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); + } log.trace("setting marshaller property NamespacePrefixMapper"); m.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NamespacePrefixMapperImpl()); } catch (PropertyException ex) { @@ -45,8 +49,12 @@ public class MarshallerFactory { } return m; } + + public static Marshaller createMarshaller(JAXBContext ctx, boolean formattedOutput) throws JAXBException { + return createMarshaller(ctx, formattedOutput, false); + } public static Marshaller createMarshaller(JAXBContext ctx) throws JAXBException { - return createMarshaller(ctx, false); + return createMarshaller(ctx, false, false); } } diff --git a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java deleted file mode 100644 index 3ae1d0ff..00000000 --- a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefix.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package at.gv.egiz.marshal; - -/** - * - * @author Clemens Orthacker - */ -public interface NamespacePrefix { - String CARDCHANNEL_PREFIX = "cc"; - String ECDSA_PREFIX = "ecdsa"; - String PERSONDATA_PREFIX = "pr"; - String SAML10_PREFIX = "saml"; - String SL_PREFIX = "sl"; - String XADES_PREFIX = "xades"; - String XMLDSIG_PREFIX = "dsig"; - String XSI_PREFIX = "xsi"; - -} diff --git a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java index 519f6b1f..e0698977 100644 --- a/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java +++ b/utils/src/main/java/at/gv/egiz/marshal/NamespacePrefixMapperImpl.java @@ -17,6 +17,9 @@ package at.gv.egiz.marshal; //import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper; +import java.util.HashMap; +import java.util.Map; + import com.sun.xml.bind.marshaller.NamespacePrefixMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -29,45 +32,32 @@ public class NamespacePrefixMapperImpl extends NamespacePrefixMapper { private static final Log log = LogFactory.getLog(NamespacePrefixMapperImpl.class); + protected static final Map prefixMap = new HashMap(); + + static { + prefixMap.put("http://www.w3.org/2001/XMLSchema-instance", "xsi"); + prefixMap.put("http://www.w3.org/2000/09/xmldsig#", "dsig"); + prefixMap.put("http://www.buergerkarte.at/namespaces/securitylayer/1.2#", "sl"); + prefixMap.put("http://www.buergerkarte.at/cardchannel", "cc"); + prefixMap.put("http://www.w3.org/2001/04/xmldsig-more#", "ecdsa"); + prefixMap.put("http://reference.e-government.gv.at/namespace/persondata/20020228#", "pr"); + prefixMap.put("urn:oasis:names:tc:SAML:1.0:assertion", "saml"); + prefixMap.put("http://uri.etsi.org/01903/v1.1.1#", "xades"); + prefixMap.put("http://www.buergerkarte.at/namespaces/securitylayer/20020225#", "sl10"); + prefixMap.put("http://www.buergerkarte.at/namespaces/securitylayer/20020831#", "sl11"); + } + + @Override public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { if (log.isTraceEnabled()) { log.trace("prefix for namespace " + namespaceUri + " requested"); } - if ("http://www.w3.org/2001/XMLSchema-instance".equals(namespaceUri)) { - return NamespacePrefix.XSI_PREFIX; - } - - if ("http://www.w3.org/2000/09/xmldsig#".equals(namespaceUri)) { - return NamespacePrefix.XMLDSIG_PREFIX; - } - - if ("http://www.buergerkarte.at/namespaces/securitylayer/1.2#".equals(namespaceUri)) { - return NamespacePrefix.SL_PREFIX; - } - - if ("http://www.buergerkarte.at/cardchannel".equals(namespaceUri)) { - return NamespacePrefix.CARDCHANNEL_PREFIX; - } - - if ("http://www.w3.org/2001/04/xmldsig-more#".equals(namespaceUri)) { - return NamespacePrefix.ECDSA_PREFIX; - } - - if ("http://reference.e-government.gv.at/namespace/persondata/20020228#".equals(namespaceUri)) { - return NamespacePrefix.PERSONDATA_PREFIX; - } - - if ("urn:oasis:names:tc:SAML:1.0:assertion".equals(namespaceUri)) { - return NamespacePrefix.SAML10_PREFIX; - } - - if ("http://uri.etsi.org/01903/v1.1.1#".equals(namespaceUri)) { - return NamespacePrefix.XADES_PREFIX; - } - return suggestion; + String prefix = prefixMap.get(namespaceUri); + + return (prefix != null) ? prefix : suggestion; } /** diff --git a/utils/src/main/java/at/gv/egiz/validation/ReportingValidationEventHandler.java b/utils/src/main/java/at/gv/egiz/validation/ReportingValidationEventHandler.java new file mode 100644 index 00000000..6543c333 --- /dev/null +++ b/utils/src/main/java/at/gv/egiz/validation/ReportingValidationEventHandler.java @@ -0,0 +1,64 @@ +/* + * Copyright 2008 Federal Chancellery Austria and + * Graz University of Technology + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package at.gv.egiz.validation; + +import javax.xml.bind.ValidationEvent; +import javax.xml.bind.ValidationEventHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * @author Clemens Orthacker + */ +public class ReportingValidationEventHandler implements ValidationEventHandler { + + protected static final Log log = LogFactory.getLog(ReportingValidationEventHandler.class); + + protected ValidationEvent errorEvent; + + /** + * + * @param event + * @return false, terminate the current unmarshal, validate, or marshal operation after handling this warning/error + * (except for WARNING validation events) + */ + @Override + public boolean handleEvent(ValidationEvent event) { + switch (event.getSeverity()) { + case ValidationEvent.WARNING: + log.info(event.getMessage()); + return true; + case ValidationEvent.ERROR: + log.warn(event.getMessage()); + errorEvent = event; + return false; + case ValidationEvent.FATAL_ERROR: + log.error(event.getMessage()); + errorEvent = event; + return false; + default: + log.debug(event.getMessage()); + return false; + } + } + + public ValidationEvent getErrorEvent() { + return errorEvent; + } + +} diff --git a/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java b/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java deleted file mode 100644 index 0fafdd7f..00000000 --- a/utils/src/main/java/at/gv/egiz/validation/ValidationEventLogger.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package at.gv.egiz.validation; - -import javax.xml.bind.ValidationEvent; -import javax.xml.bind.ValidationEventHandler; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * - * @author Clemens Orthacker - */ -public class ValidationEventLogger implements ValidationEventHandler { - - protected static final Log log = LogFactory.getLog(ValidationEventLogger.class); - - /** - * - * @param event - * @return false, terminate the current unmarshal, validate, or marshal operation after handling this warning/error - * (except for WARNING validation events) - */ - @Override - public boolean handleEvent(ValidationEvent event) { - switch (event.getSeverity()) { - case ValidationEvent.WARNING: - log.info(event.getMessage()); - return true; - case ValidationEvent.ERROR: - log.warn(event.getMessage()); - return false; - case ValidationEvent.FATAL_ERROR: - log.error(event.getMessage()); - return false; - default: - log.debug(event.getMessage()); - return false; - } - } -} diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java index 71ca1db9..82cba624 100644 --- a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java +++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java @@ -16,8 +16,6 @@ */ package at.gv.egiz.xades; -import at.gv.egiz.marshal.MarshallerFactory; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -51,6 +49,8 @@ import org.w3._2000._09.xmldsig_.DigestMethodType; import org.w3._2000._09.xmldsig_.X509IssuerSerialType; import org.w3c.dom.Node; +import at.gv.egiz.marshal.MarshallerFactory; + public class QualifyingPropertiesFactory { public static String NS_URI_V1_1_1 = "http://uri.etsi.org/01903/v1.1.1#"; @@ -155,7 +155,7 @@ public class QualifyingPropertiesFactory { return dataObjectFormatType; } - public JAXBElement createQualifyingProperties111(Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { + public JAXBElement createQualifyingProperties111(String target, Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { GregorianCalendar gregorianCalendar = new GregorianCalendar(); gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); @@ -206,6 +206,8 @@ public class QualifyingPropertiesFactory { QualifyingPropertiesType qualifyingPropertiesType = qpFactory.createQualifyingPropertiesType(); qualifyingPropertiesType.setSignedProperties(signedPropertiesType); + qualifyingPropertiesType.setTarget(target); + return qpFactory.createQualifyingProperties(qualifyingPropertiesType); } diff --git a/utils/src/test/java/at/gv/egiz/bku/utils/URLEncodingOutputStreamTest.java b/utils/src/test/java/at/gv/egiz/bku/utils/URLEncodingOutputStreamTest.java new file mode 100644 index 00000000..e92b9584 --- /dev/null +++ b/utils/src/test/java/at/gv/egiz/bku/utils/URLEncodingOutputStreamTest.java @@ -0,0 +1,147 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package at.gv.egiz.bku.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URLEncoder; +import java.nio.charset.Charset; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +public class URLEncodingOutputStreamTest { + + private static String buf; + + private static Charset UTF_8 = Charset.forName("UTF-8"); + + @BeforeClass + public static void setUpClass() throws IOException { + + ClassLoader cl = URLEncodingOutputStreamTest.class.getClassLoader(); + InputStream is = cl.getResourceAsStream("BigRequest.xml"); + + assertNotNull(is); + + InputStreamReader reader = new InputStreamReader(is, UTF_8); + + StringBuilder sb = new StringBuilder(); + + char[] b = new char[512]; + for (int l; (l = reader.read(b)) != -1;) { + sb.append(b, 0, l); + } + + buf = sb.toString(); + + } + + @Test + public void testCompareResults() throws IOException { + + String out1; + String out2; + + // new + StringWriter writer = new StringWriter(); + URLEncodingOutputStream urlEnc = new URLEncodingOutputStream(writer); + OutputStreamWriter streamWriter = new OutputStreamWriter(urlEnc, UTF_8); + streamWriter.append(buf); + streamWriter.flush(); + out1 = writer.toString(); + + // URLEncoder + out2 = URLEncoder.encode(buf, UTF_8.name()); + + for (int i = 0; i < out1.length(); i++) { + if (out1.charAt(i) != out2.charAt(i)) { + System.out.println(i + ": " + out1.substring(i)); + System.out.println(i + ": " + out2.substring(i)); + } + } + + assertEquals(out1, out2); + + } + + @Ignore + @Test + public void testURLEncodingOutputStream() throws IOException { + + NullWriter writer = new NullWriter(); + + URLEncodingOutputStream urlEnc = new URLEncodingOutputStream(writer); + OutputStreamWriter streamWriter = new OutputStreamWriter(urlEnc, UTF_8); + + long t0, t1, dt = 0; + for (int run = 0; run < 1000; run++) { + t0 = System.currentTimeMillis(); + streamWriter.append(buf); + t1 = System.currentTimeMillis(); + if (run > 1) { + dt += t1 - t0; + } + } + System.out.println("Time " + dt + "ms"); + + } + + @Ignore + @Test + public void testURLEncodingNaive() throws IOException { + + String in = new String(buf); + + long t0, t1, dt = 0; + for (int run = 0; run < 1000; run++) { + t0 = System.currentTimeMillis(); + URLEncoder.encode(in, "UTF-8"); + t1 = System.currentTimeMillis(); + if (run > 1) { + dt += t1 - t0; + } + } + System.out.println("Time (naive) " + dt + "ms"); + + } + + public class NullWriter extends Writer { + + @Override + public void close() throws IOException { + } + + @Override + public void flush() throws IOException { + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + } + + } + +} diff --git a/utils/src/test/resources/BigRequest.xml b/utils/src/test/resources/BigRequest.xml new file mode 100644 index 00000000..90eb1eb8 --- /dev/null +++ b/utils/src/test/resources/BigRequest.xml @@ -0,0 +1,1060 @@ + + +SecureSignatureKeypair + + + TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Np +bmcgZWxpdC4gTnVsbGFtIHZ1bHB1dGF0ZSwgcmlzdXMgaW1wZXJkaWV0IGNvbnNl +cXVhdCB2YXJpdXMsIHJpc3VzIGR1aSB0ZW1wdXMgbGVvLCBub24gbGFjaW5pYSBl +bmltIG51bmMgYSBzZW0uIERvbmVjIHBvcnRhLCBpcHN1bSB0aW5jaWR1bnQgdWx0 +cmljZXMgaW50ZXJkdW0sIGZlbGlzIGF1Z3VlIHNvZGFsZXMgYW50ZSwgdmVsIG9y +bmFyZSBsaWJlcm8gbnVsbGEgZXQgcHVydXMuIENyYXMgdGVtcHVzIHZhcml1cyBw +b3J0YS4gRG9uZWMgaWQgcHVydXMgdXQgdmVsaXQgYmliZW5kdW0gbHVjdHVzIGJs +YW5kaXQgc2l0IGFtZXQgbmVxdWUuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9z +cXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGlu +Y2VwdG9zIGhpbWVuYWVvcy4gQ3JhcyBmYWNpbGlzaXMgdGVtcHVzIGZlcm1lbnR1 +bS4gRG9uZWMgZmVybWVudHVtIG1hc3NhIGV0IHNhcGllbiBwb3N1ZXJlIHZlbmVu +YXRpcy4gSW4gcXVpcyB1cm5hIG9yY2kuIER1aXMgYSBsaWJlcm8gb3JjaS4gTnVs +bGEgcG9ydHRpdG9yIGF1Z3VlIHZpdGFlIGxpZ3VsYSB0ZW1wb3Igc2VkIHJ1dHJ1 +bSBtaSBjdXJzdXMuIEFlbmVhbiBpYWN1bGlzIG5pc2kgYXQgaXBzdW0gY29uc2Vj +dGV0dXIgZWdldCB2YXJpdXMgbWFnbmEgc29sbGljaXR1ZGluLiBVdCBmYWNpbGlz +aXMgdGVsbHVzIGEgbmVxdWUgZWdlc3RhcyBwbGFjZXJhdC4gRG9uZWMgdG9ydG9y +IHZlbGl0LCB0aW5jaWR1bnQgYSBtb2xsaXMgY3Vyc3VzLCBsdWN0dXMgYWxpcXVh +bSBsaWJlcm8uIER1aXMgbm9uIHRlbGx1cyBwcmV0aXVtIHRlbGx1cyB2YXJpdXMg +ZWxlaWZlbmQgaW4gc2VkIHNlbS4gU3VzcGVuZGlzc2UgZmVybWVudHVtIHRlbGx1 +cyBpZCBmZWxpcyB0ZW1wdXMgdml2ZXJyYS4gRG9uZWMgcG9ydHRpdG9yIHRpbmNp +ZHVudCBtYXVyaXMgbmVjIGV1aXNtb2QuCgpQcmFlc2VudCB1bGxhbWNvcnBlciB0 +cmlzdGlxdWUgbG9yZW0sIGV0IHBsYWNlcmF0IG51bmMgZWxlbWVudHVtIHV0LiBN +b3JiaSBldCBhZGlwaXNjaW5nIHNlbS4gTmFtIHZlbCBuaWJoIGV1IGxlbyBjb25k +aW1lbnR1bSByaG9uY3VzIHF1aXMgc2VkIHVybmEuIFBoYXNlbGx1cyBpZCBqdXN0 +byB1dCBvcmNpIHZlc3RpYnVsdW0gc2NlbGVyaXNxdWUuIE5hbSBtb2xsaXMgdG9y +dG9yIHB1cnVzLiBQZWxsZW50ZXNxdWUgaWFjdWxpcyBzZW1wZXIgbWFsZXN1YWRh +LiBJbnRlZ2VyIGJsYW5kaXQgZmVsaXMgYXQgbG9yZW0gZXVpc21vZCB2ZW5lbmF0 +aXMuIE1hZWNlbmFzIG5lYyBlbGVpZmVuZCBsZW8uIERvbmVjIGxvYm9ydGlzLCBy +aXN1cyBuZWMgdGVtcHVzIHZvbHV0cGF0LCBudWxsYSBlbGl0IGx1Y3R1cyBhcmN1 +LCBhYyBwb3N1ZXJlIGxhY3VzIG1hc3NhIGluIG1pLiBNYWVjZW5hcyBzaXQgYW1l +dCBudW5jIG5lYyB0ZWxsdXMgZWdlc3RhcyB2ZXN0aWJ1bHVtIHZpdGFlIGV0IGVs +aXQuIE51bGxhbSBjb25zZWN0ZXR1ciBydXRydW0gdGVsbHVzIGFjIGFjY3Vtc2Fu +LiBDdXJhYml0dXIgZ3JhdmlkYSBhdWd1ZSBldCBtZXR1cyBjdXJzdXMgZWxlaWZl +bmQuIENyYXMgb2RpbyBhcmN1LCB0aW5jaWR1bnQgdXQgZWdlc3RhcyB2ZWwsIGdy +YXZpZGEgaW4gZXJvcy4gTnVuYyBldCBtYWxlc3VhZGEgcXVhbS4gTWF1cmlzIGFj +IHRlbGx1cyBhcmN1LgoKQ3JhcyBuaXNsIHNhcGllbiwgdGluY2lkdW50IGVnZXQg +ZWxlaWZlbmQgdmVsLCBwcmV0aXVtIGlkIGxlY3R1cy4gQWxpcXVhbSB0b3J0b3Ig +dXJuYSwgcG9zdWVyZSBpZCBydXRydW0gbHVjdHVzLCBhdWN0b3Igc2VkIGFudGUu +IFByb2luIGZlcm1lbnR1bSwgbmliaCBhIHZvbHV0cGF0IHZvbHV0cGF0LCBlcm9z +IGRvbG9yIHNjZWxlcmlzcXVlIG1hZ25hLCB0ZW1wdXMgc29sbGljaXR1ZGluIGxp +YmVybyBkb2xvciBydXRydW0gZXN0LiBNYXVyaXMgcXVpcyBqdXN0byBhcmN1LiBQ +cm9pbiB2ZWhpY3VsYSBhZGlwaXNjaW5nIGVyb3Mgbm9uIGNvbmRpbWVudHVtLiBO +dW5jIHN1c2NpcGl0LCBsZWN0dXMgZXUgaWFjdWxpcyBtb2xlc3RpZSwgbWkgZG9s +b3IgcG9ydGEgZG9sb3IsIGV1IHNhZ2l0dGlzIG1hc3NhIGlwc3VtIGluIG1pLiBO +dW5jIHNlbXBlciBzY2VsZXJpc3F1ZSBsb3JlbSwgYSBzb2RhbGVzIHRvcnRvciBw +b3J0dGl0b3IgaWQuIE51bGxhIG1hdHRpcywgdG9ydG9yIG5lYyBpYWN1bGlzIHBy +ZXRpdW0sIGVyYXQgbGFjdXMgdnVscHV0YXRlIGR1aSwgdnVscHV0YXRlIGZhY2ls +aXNpcyBkb2xvciB0dXJwaXMgdXQgZmVsaXMuIE1hZWNlbmFzIHZpdGFlIHNlbSBl +dCBuaWJoIHNhZ2l0dGlzIHRpbmNpZHVudCBxdWlzIGluIHRvcnRvci4gQWxpcXVh +bSBpZCBzb2RhbGVzIHJpc3VzLiBJbnRlZ2VyIGZhY2lsaXNpcywgc2FwaWVuIHV0 +IHNhZ2l0dGlzIGNvbnNlY3RldHVyLCBkaWFtIGxvcmVtIHZpdmVycmEgZG9sb3Is +IHF1aXMgY29tbW9kbyBuaWJoIGVyYXQgcXVpcyBtZXR1cy4gUHJvaW4gZGljdHVt +IHJpc3VzIG1hdXJpcy4gTnVuYyBldSB1cm5hIHNpdCBhbWV0IHZlbGl0IHBsYWNl +cmF0IGVsZWlmZW5kLiBBZW5lYW4gc2l0IGFtZXQgcHVydXMgbnVuYy4gUHJvaW4g +bm9uIG5lcXVlIGEgdGVsbHVzIG1hdHRpcyBlZ2VzdGFzIGF0IHV0IG51bmMuIERv +bmVjIG5vbiBhbnRlIHZpdGFlIG9yY2kgcGVsbGVudGVzcXVlIHNjZWxlcmlzcXVl +LiBNYWVjZW5hcyBhYyBpYWN1bGlzIGZlbGlzLiBVdCBhZGlwaXNjaW5nIHN1c2Np +cGl0IGRpYW0gdXQgcG9ydGEuIERvbmVjIHZlc3RpYnVsdW0gbGFjaW5pYSBtYWdu +YSwgaWQgcnV0cnVtIG5pc2kgdmVuZW5hdGlzIHNlZC4KCk51bGxhIHNhZ2l0dGlz +IHBoYXJldHJhIGFudGUgZXUgb3JuYXJlLiBBbGlxdWFtIGV1IGRvbG9yIHV0IHVy +bmEgY29uZGltZW50dW0gcnV0cnVtLiBJbnRlZ2VyIHN1c2NpcGl0LCB2ZWxpdCBu +ZWMgc29sbGljaXR1ZGluIGN1cnN1cywgbGVjdHVzIHF1YW0gc2NlbGVyaXNxdWUg +bWksIGlkIGF1Y3RvciBzYXBpZW4gdG9ydG9yIHNlZCB0ZWxsdXMuIERvbmVjIHRp +bmNpZHVudCB0aW5jaWR1bnQgbGVjdHVzLCBxdWlzIHNvZGFsZXMgcHVydXMgaW1w +ZXJkaWV0IGV0LiBOdWxsYSBmYWNpbGlzaS4gTnVsbGFtIGlhY3VsaXMgZWxlbWVu +dHVtIGZlbGlzLCBlZ2V0IG1hdHRpcyBkb2xvciB0cmlzdGlxdWUgYWMuIFNlZCBl +Z2V0IHNlbSBuZXF1ZS4gVXQgZmVybWVudHVtLCBtaSBxdWlzIHZvbHV0cGF0IHZl +bmVuYXRpcywgbGFjdXMgbmVxdWUgY29udmFsbGlzIGVzdCwgdml0YWUgc3VzY2lw +aXQgdHVycGlzIGFudGUgYXQgcmlzdXMuIE51bmMgZmVybWVudHVtLCBtYWduYSBx +dWlzIHZlbmVuYXRpcyBldWlzbW9kLCBlbGl0IHZlbGl0IGZlcm1lbnR1bSBqdXN0 +bywgYSBkaWN0dW0gbGlndWxhIGp1c3RvIGFjIGxvcmVtLiBTZWQgZWdldCB0b3J0 +b3IgbWFnbmEsIHZpdmVycmEgaW50ZXJkdW0gbGVvLiBRdWlzcXVlIGluIGxhY3Vz +IGV0IGxlY3R1cyBhZGlwaXNjaW5nIGNvbnNlY3RldHVyIGluIHF1aXMgZXN0LiBN +YXVyaXMgZXQgZG9sb3IgZXQgbmVxdWUgbW9sZXN0aWUgY29uc2VjdGV0dXIgZXVp +c21vZCBldSBlbGl0LiBOdWxsYSBmYWNpbGlzaS4gUHJvaW4gYWMgdmVsaXQgaXBz +dW0sIHV0IHRyaXN0aXF1ZSBtYWduYS4gVmVzdGlidWx1bSBwb3N1ZXJlIG1hbGVz +dWFkYSBuaXNsIHNpdCBhbWV0IGFsaXF1YW0uIFN1c3BlbmRpc3NlIHNlZCBpcHN1 +bSBpZCB0ZWxsdXMgcG9ydGEgcG9zdWVyZSBlZ2V0IHNpdCBhbWV0IHR1cnBpcy4g +TnVuYyBhYyBkb2xvciB2ZWwgdXJuYSBkYXBpYnVzIGZlcm1lbnR1bSBuZWMgdmVo +aWN1bGEgdXJuYS4gRnVzY2UgdGluY2lkdW50IG1ldHVzIGV1IGlwc3VtIG1hdHRp +cyB0cmlzdGlxdWUuIFNlZCBmYXVjaWJ1cyBmcmluZ2lsbGEgYWRpcGlzY2luZy4g +Q3JhcyBwaGFyZXRyYSwgYW50ZSBzZWQgYWNjdW1zYW4gcmhvbmN1cywgZWxpdCBk +b2xvciBsYWNpbmlhIG1hdXJpcywgYXQgbGFvcmVldCBsaWJlcm8gYXVndWUgYXQg +bmlzbC4KClByb2luIGEgbGVvIHV0IHRvcnRvciBwb3J0YSBsdWN0dXMuIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBVdCBzZWQgbnVuYyB2 +ZWwgbWV0dXMgc3VzY2lwaXQgY29uZ3VlIGF0IGEgZG9sb3IuIE51bmMgZXUgdG9y +dG9yIGxvcmVtLCBuZWMgY29uZ3VlIGxpYmVyby4gTW9yYmkgbGFvcmVldCBsZWN0 +dXMgbmlzbCwgdml0YWUgcmhvbmN1cyBlbGl0LiBTdXNwZW5kaXNzZSBldCBxdWFt +IHF1aXMgZHVpIGxhY2luaWEgc29kYWxlcyBuZWMgZXUgbGlndWxhLiBQZWxsZW50 +ZXNxdWUgbm9uIGlwc3VtIGxlbywgc2l0IGFtZXQgbW9sZXN0aWUgZHVpLiBTZWQg +YSBhdWd1ZSBlZ2V0IG1hdXJpcyBncmF2aWRhIG1hbGVzdWFkYSBldCBxdWlzIGlw +c3VtLiBBbGlxdWFtIGFjIG5pYmggbGlndWxhLCBpbiBwb3J0dGl0b3IgZWxpdC4g +TWF1cmlzIHR1cnBpcyBvcmNpLCBhY2N1bXNhbiBpbiBpbnRlcmR1bSBhdCwgZmFj +aWxpc2lzIHZpdGFlIHR1cnBpcy4gUXVpc3F1ZSBtYXR0aXMgcGVsbGVudGVzcXVl +IGVyb3MgdmVsIHZpdmVycmEuIFZlc3RpYnVsdW0gbGFvcmVldCBjb25ndWUgYWxp +cXVhbS4gRG9uZWMgcG9zdWVyZSBtYXVyaXMgbmVjIGxpYmVybyBvcm5hcmUgZXQg +ZWdlc3RhcyBhbnRlIHB1bHZpbmFyLiBDdXJhYml0dXIgYW50ZSBhbnRlLCBtb2xl +c3RpZSB1dCBiaWJlbmR1bSB2aXRhZSwgcnV0cnVtIHZlbCByaXN1cy4gRG9uZWMg +ZXQgbmVxdWUgcHVydXMsIHNpdCBhbWV0IGFkaXBpc2NpbmcgZmVsaXMuIFBlbGxl +bnRlc3F1ZSBkaWduaXNzaW0gdmVzdGlidWx1bSBzYXBpZW4gbmVjIGZyaW5naWxs +YS4gUHJvaW4gbmVjIHB1cnVzIGV0IGVzdCBldWlzbW9kIHBoYXJldHJhLiBQZWxs +ZW50ZXNxdWUgZGFwaWJ1cyBkYXBpYnVzIG1ldHVzIHZlbCBmYWNpbGlzaXMuIFZp +dmFtdXMgdmVsIGVsaXQgbnVuYy4KCkV0aWFtIGFjIGVuaW0gZWdldCBtYXVyaXMg +ZmF1Y2lidXMgZGFwaWJ1cy4gTW9yYmkgdml0YWUgbGVjdHVzIG5lcXVlLiBNYXVy +aXMgc2FwaWVuIG1ldHVzLCBzdXNjaXBpdCBzaXQgYW1ldCBlZ2VzdGFzIHZpdGFl +LCBwaGFyZXRyYSBhIG1hc3NhLiBVdCB2YXJpdXMsIHRvcnRvciBzZWQgZnJpbmdp +bGxhIHBsYWNlcmF0LCBuZXF1ZSBkaWFtIGNvbmd1ZSBudW5jLCBpZCBhbGlxdWV0 +IG5pc2kgcmlzdXMgdXQgdXJuYS4gVml2YW11cyBwbGFjZXJhdCBwb3J0YSBhcmN1 +IHZpdGFlIGFjY3Vtc2FuLiBNYXVyaXMgaGVuZHJlcml0LCBlbmltIHZpdGFlIGFs +aXF1YW0gcG9ydHRpdG9yLCBwdXJ1cyBuZXF1ZSBncmF2aWRhIG1hZ25hLCBub24g +cHJldGl1bSBuZXF1ZSBsZWN0dXMgc2l0IGFtZXQgdG9ydG9yLiBEdWlzIHN1c2Np +cGl0IG9ybmFyZSBvZGlvIHZpdGFlIHBoYXJldHJhLiBEb25lYyBlbGVpZmVuZCwg +ZHVpIG5vbiBncmF2aWRhIGNvbnZhbGxpcywgb2RpbyBhcmN1IGJsYW5kaXQgbWFn +bmEsIG5vbiBwb3J0YSBsZW8gbGliZXJvIHBvcnRhIG1hZ25hLiBEdWlzIGVzdCB1 +cm5hLCBsdWN0dXMgZXUgaW50ZXJkdW0gbmVjLCBpYWN1bGlzIG5lYyBlbGl0LiBD +dXJhYml0dXIgZmFjaWxpc2lzIHRlbXB1cyB0ZW1wdXMuIFNlZCBzZW0gdXJuYSwg +dml2ZXJyYSBldSBpbXBlcmRpZXQgc2l0IGFtZXQsIGludGVyZHVtIGV0IGp1c3Rv +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gRG9uZWMgdGluY2lk +dW50IG1hc3NhIHV0IGR1aSBmZXJtZW50dW0gcG9zdWVyZSBldCBuZWMgdHVycGlz +LiBFdGlhbSBmZXJtZW50dW0gcG9ydGEgbWF1cmlzLiBTdXNwZW5kaXNzZSBsYWN1 +cyBsaWJlcm8sIHByZXRpdW0gaW4gZWdlc3RhcyB2ZWwsIHNhZ2l0dGlzIGV0IG1h +c3NhLiBOdWxsYSBhbGlxdWFtIGxhb3JlZXQgc2FwaWVuLCBhdCBwZWxsZW50ZXNx +dWUgZXJvcyB2ZW5lbmF0aXMgcXVpcy4gSW50ZWdlciBhY2N1bXNhbiwgbGFjdXMg +dXQgZGFwaWJ1cyBlZ2VzdGFzLCByaXN1cyBuaXNsIHNlbXBlciB0dXJwaXMsIHNp +dCBhbWV0IHZpdmVycmEgZmVsaXMgdHVycGlzIHNlZCB2ZWxpdC4KCkRvbmVjIHZl +aGljdWxhLCB0ZWxsdXMgcXVpcyBtb2xlc3RpZSBiaWJlbmR1bSwgYXVndWUgbmlz +bCB0ZW1wdXMgbG9yZW0sIHNpdCBhbWV0IGNvbmRpbWVudHVtIGp1c3RvIGF1Z3Vl +IHNpdCBhbWV0IGFudGUuIE51bGxhbSB0b3J0b3Igc2VtLCBtYXR0aXMgYWMgcG9y +dHRpdG9yIHZpdGFlLCBpYWN1bGlzIHNlZCBkdWkuIEN1bSBzb2NpaXMgbmF0b3F1 +ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFz +Y2V0dXIgcmlkaWN1bHVzIG11cy4gRXRpYW0gaW4gc2VtIGlwc3VtLiBJbiBldSBt +b2xlc3RpZSBtZXR1cy4gVml2YW11cyBsYW9yZWV0IGZhdWNpYnVzIG5pYmgsIGEg +c2VtcGVyIG5pYmggZnJpbmdpbGxhIHV0LiBNYWVjZW5hcyBsYW9yZWV0LCBwdXJ1 +cyBldSBzb2xsaWNpdHVkaW4gcGhhcmV0cmEsIGp1c3RvIHRlbGx1cyBjb21tb2Rv +IGF1Z3VlLCBpbiBmYXVjaWJ1cyBsZW8ganVzdG8gbmVjIG5pc2wuIE5hbSBldSBw +cmV0aXVtIGVzdC4gRnVzY2Ugc2l0IGFtZXQgcXVhbSBsb3JlbSwgdXQgc29kYWxl +cyB0ZWxsdXMuIE51bmMgZWxlbWVudHVtLCBzZW0gc2NlbGVyaXNxdWUgaWFjdWxp +cyBpbnRlcmR1bSwgZXJvcyBkdWkgb3JuYXJlIG9yY2ksIHNlZCBwbGFjZXJhdCBy +aXN1cyBlcmF0IGVnZXQgYXJjdS4gTW9yYmkgYWMgbWV0dXMgaWQgbGlndWxhIHBv +cnRhIGdyYXZpZGEuIE51bmMgY29udmFsbGlzIGRpYW0gaW4gbmlzaSBncmF2aWRh +IGFjIGNvbW1vZG8gbGFjdXMgZGlnbmlzc2ltLiBDdW0gc29jaWlzIG5hdG9xdWUg +cGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2Nl +dHVyIHJpZGljdWx1cyBtdXMuIEV0aWFtIHF1aXMgdmVsaXQgZXUgZmVsaXMgbHVj +dHVzIHBlbGxlbnRlc3F1ZSBub24gZWdlc3RhcyBuZXF1ZS4gTnVuYyBuaWJoIHRl +bGx1cywgcGxhY2VyYXQgbm9uIGZlcm1lbnR1bSBhdCwgb3JuYXJlIHF1aXMgZGlh +bS4gU3VzcGVuZGlzc2Ugc2l0IGFtZXQgcHVydXMgcXVpcyBkdWkgY29uc2VxdWF0 +IHByZXRpdW0uIEZ1c2NlIGV0IG1hZ25hIG5pc2ksIHZlbCB2ZXN0aWJ1bHVtIGVy +b3MuIEluIGZhdWNpYnVzLCBsYWN1cyBlZ2V0IGZhdWNpYnVzIGZldWdpYXQsIGxp +Z3VsYSBlbmltIHZlc3RpYnVsdW0gbG9yZW0sIGEgdml2ZXJyYSBsb3JlbSBlc3Qg +dml0YWUgcXVhbS4gTnVuYyBwdXJ1cyBuaXNsLCB2YXJpdXMgZXQgdGVtcG9yIHVs +dHJpY2llcywgaWFjdWxpcyBhIGxpYmVyby4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBz +b2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBw +ZXIgaW5jZXB0b3MgaGltZW5hZW9zLgoKRnVzY2UgdmVsIGp1c3RvIHNpdCBhbWV0 +IHF1YW0gbWFsZXN1YWRhIG9ybmFyZSBzaXQgYW1ldCBldCBhbnRlLiBOdWxsYW0g +cmhvbmN1cyBwb3J0YSBzZW0gcXVpcyBtYWxlc3VhZGEuIENsYXNzIGFwdGVudCB0 +YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5v +c3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRG9uZWMgYW50ZSBvZGlvLCB0 +aW5jaWR1bnQgYWMgbW9sbGlzIGluLCB1bHRyaWNlcyBuZWMgZHVpLiBOdW5jIGN1 +cnN1cyBtYWduYSBuZWMgcHVydXMgZnJpbmdpbGxhIGEgbW9sZXN0aWUgcHVydXMg +bG9ib3J0aXMuIEZ1c2NlIHJ1dHJ1bSwgbG9yZW0gZWdldCB1bGxhbWNvcnBlciBm +cmluZ2lsbGEsIGR1aSBsaWd1bGEgc29sbGljaXR1ZGluIHJpc3VzLCB2aXRhZSBw +b3N1ZXJlIG5lcXVlIGZlbGlzIHZpdGFlIHF1YW0uIEN1cmFiaXR1ciBjb25kaW1l +bnR1bSBsaWJlcm8gYXQgb3JjaSBhdWN0b3IgZXUgY29tbW9kbyBsaWJlcm8gc29s +bGljaXR1ZGluLiBDcmFzIHNlZCBwdXJ1cyBtaSwgc2VkIGNvbnZhbGxpcyBuaWJo +LiBOdWxsYW0gYWMgbG9yZW0gYSBpcHN1bSBsYWNpbmlhIHVsbGFtY29ycGVyIGlk +IHF1aXMgdG9ydG9yLiBNb3JiaSBlbGVpZmVuZCwgbnVsbGEgdmVsIHZlbmVuYXRp +cyBjb25kaW1lbnR1bSwgbGVjdHVzIHRvcnRvciB2ZW5lbmF0aXMgcmlzdXMsIGEg +bHVjdHVzIGxhY3VzIGlwc3VtIHV0IHNhcGllbi4KCk1hdXJpcyBsYW9yZWV0IG51 +bmMgc2l0IGFtZXQgZW5pbSBkaWN0dW0gbG9ib3J0aXMuIE1hdXJpcyBydXRydW0s +IGVsaXQgdXQgbW9sZXN0aWUgb3JuYXJlLCB0b3J0b3IgZXJvcyB2YXJpdXMgbnVu +YywgdHJpc3RpcXVlIHBlbGxlbnRlc3F1ZSB0dXJwaXMgYXVndWUgaW4gYW50ZS4g +QWVuZWFuIGZlbGlzIGR1aSwgZnJpbmdpbGxhIGluIGFsaXF1YW0gYXQsIG9ybmFy +ZSB1dCBudWxsYS4gSW4gbWkgbnVuYywgc2VtcGVyIGluIGNvbmRpbWVudHVtIG5v +biwgY29uZ3VlIGFjIG1hdXJpcy4gQ3VyYWJpdHVyIGltcGVyZGlldCByaG9uY3Vz +IHNlbSwgbW9sZXN0aWUgYWRpcGlzY2luZyBpcHN1bSBzb2xsaWNpdHVkaW4gYS4g +Vml2YW11cyB1dCBpcHN1bSBxdWlzIHR1cnBpcyBhbGlxdWV0IHRpbmNpZHVudCBh +Y2N1bXNhbiBhYyBxdWFtLiBDdXJhYml0dXIgcG9ydHRpdG9yLCBtYXVyaXMgYWMg +bHVjdHVzIHZpdmVycmEsIHB1cnVzIGVzdCBhZGlwaXNjaW5nIHNhcGllbiwgc2l0 +IGFtZXQgYWxpcXVhbSBxdWFtIG51bGxhIGF0IGVyYXQuIFZpdmFtdXMgdGVtcHVz +LCBqdXN0byBhIHByZXRpdW0gZGljdHVtLCBpcHN1bSBudW5jIGxhb3JlZXQgdGVs +bHVzLCBuZWMgdGVtcHVzIHNlbSBuaXNpIGFjIHF1YW0uIFZpdmFtdXMgaW4gbWFz +c2EgZW5pbS4gUXVpc3F1ZSBuZWMgdG9ydG9yIHZpdGFlIG51bGxhIHVsdHJpY2Vz +IGNvbnZhbGxpcy4gTnVsbGFtIHRvcnRvciBtYXVyaXMsIGF1Y3RvciB2aXRhZSB0 +ZW1wb3IgZXQsIGF1Y3RvciBuZWMgc2FwaWVuLiBRdWlzcXVlIHVsbGFtY29ycGVy +IHZpdmVycmEgdmVuZW5hdGlzLiBNYWVjZW5hcyBxdWlzIGdyYXZpZGEgbWFzc2Eu +IEludGVnZXIgdml0YWUganVzdG8gbGVjdHVzLCBhYyBtYWxlc3VhZGEgcXVhbS4g +TWFlY2VuYXMgc2l0IGFtZXQgbmVxdWUgbnVsbGEsIG5lYyBpbXBlcmRpZXQgaXBz +dW0uIFNlZCB0ZW1wdXMgYmliZW5kdW0gc2FwaWVuLCBub24gZnJpbmdpbGxhIG51 +bmMgZWxlbWVudHVtIGV1LiBOdW5jIGF1Y3RvciBhbGlxdWV0IGxlbywgYmliZW5k +dW0gcHJldGl1bSBkaWFtIHBsYWNlcmF0IGFjLiBOYW0gaW4gZW5pbSBkdWkuIFNl +ZCBldCBuaWJoIG5vbiBudW5jIHBsYWNlcmF0IHBoYXJldHJhLiBTZWQgb2RpbyBs +ZW8sIGNvbmRpbWVudHVtIGV1IHN1c2NpcGl0IGV1LCBtb2xsaXMgZWdldCBuaXNp +LgoKUHJvaW4gb3JuYXJlLCBpcHN1bSB2aXRhZSBsYW9yZWV0IHZhcml1cywgbGFj +dXMgbGVvIHBoYXJldHJhIG1hdXJpcywgc2VkIGNvbnZhbGxpcyBsaWJlcm8gbWV0 +dXMgcmhvbmN1cyBvcmNpLiBNYXVyaXMgcnV0cnVtIGxlbyB2ZWwgYW50ZSBlZ2Vz +dGFzIGEgYWRpcGlzY2luZyBlc3QgdmVuZW5hdGlzLiBJbiBldSBtaSB1dCBlbGl0 +IHRyaXN0aXF1ZSB2ZWhpY3VsYS4gTnVuYyBwb3N1ZXJlLCBlbmltIHF1aXMgc3Vz +Y2lwaXQgYWNjdW1zYW4sIGVsaXQgbGVvIHNlbXBlciBudW5jLCBub24gbGFvcmVl +dCBhbnRlIG5pYmggc2l0IGFtZXQgbWF1cmlzLiBBbGlxdWFtIGFjIHF1YW0gcXVp +cyBuaXNsIHNvbGxpY2l0dWRpbiBtb2xlc3RpZSBpZCBhYyBudWxsYS4gSW50ZWdl +ciBldSBkb2xvciBpcHN1bS4gUGhhc2VsbHVzIGludGVyZHVtIHZlaGljdWxhIHNl +bXBlci4gU3VzcGVuZGlzc2UgbmVjIGFyY3UgYWMgZXN0IGlhY3VsaXMgdmVoaWN1 +bGEuIE1hZWNlbmFzIHNlbXBlciBsaWJlcm8gaWFjdWxpcyBsb3JlbSBmZXVnaWF0 +IGF1Y3Rvci4gQWxpcXVhbSBibGFuZGl0IHNlbXBlciBibGFuZGl0LiBVdCBlZ2Vz +dGFzIGVyb3Mgc2VkIG5pc2kgZGFwaWJ1cyBhIHNlbXBlciBtZXR1cyBkYXBpYnVz +LiBNb3JiaSB2dWxwdXRhdGUgbGFvcmVldCB2ZWxpdCwgZXUgYmliZW5kdW0gYXJj +dSBjb21tb2RvIG5vbi4gTWFlY2VuYXMgZmVsaXMgbnVuYywgdm9sdXRwYXQgaWQg +dmVzdGlidWx1bSB2aXRhZSwgdmVzdGlidWx1bSB2aXRhZSBhbnRlLgoKU2VkIG51 +bmMgaXBzdW0sIGF1Y3RvciB2ZWwgZmV1Z2lhdCBzaXQgYW1ldCwgaW50ZXJkdW0g +YXQgbGlndWxhLiBNYXVyaXMgcXVpcyBuaXNpIGVnZXQgbGVjdHVzIGdyYXZpZGEg +c2VtcGVyIGluIHF1aXMgZW5pbS4gTnVsbGEgYXVjdG9yIGVsZW1lbnR1bSBqdXN0 +bywgbm9uIGJpYmVuZHVtIGR1aSBmZXJtZW50dW0gYWMuIEZ1c2NlIGxvcmVtIGF1 +Z3VlLCBjb21tb2RvIG5vbiB0aW5jaWR1bnQgc2l0IGFtZXQsIGFjY3Vtc2FuIHNl +ZCBtZXR1cy4gTmFtIHNhcGllbiBlbmltLCBkaWduaXNzaW0gZXQgdmFyaXVzIGV1 +LCBsdWN0dXMgYXQgb3JjaS4gTnVsbGFtIGxpYmVybyBvcmNpLCBiaWJlbmR1bSBh +IGxhY2luaWEgYWMsIHZ1bHB1dGF0ZSBmYXVjaWJ1cyBtaS4gTW9yYmkgY29uZGlt +ZW50dW0gZmVybWVudHVtIGRpZ25pc3NpbS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0 +IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gUXVpc3F1ZSBldCBu +ZXF1ZSBlcmF0LCB1dCB2b2x1dHBhdCBsZW8uIFZlc3RpYnVsdW0gdmVsIGxpZ3Vs +YSBuZXF1ZS4gTnVuYyBwaGFyZXRyYSBsaWJlcm8gaW4gbWF1cmlzIGRhcGlidXMg +aW4gbGFvcmVldCBkdWkgbHVjdHVzLiBQaGFzZWxsdXMgdmVsaXQgbmlzaSwgZGlj +dHVtIGF0IHZvbHV0cGF0IG5lYywgaGVuZHJlcml0IGZhY2lsaXNpcyBlc3QuIFN1 +c3BlbmRpc3NlIG1hdXJpcyBwdXJ1cywgZGlnbmlzc2ltIHNpdCBhbWV0IHRpbmNp +ZHVudCBhYywgaWFjdWxpcyBpZCBzZW0uIER1aXMgcmlzdXMganVzdG8sIGZyaW5n +aWxsYSBhdCB2dWxwdXRhdGUgYXQsIGxvYm9ydGlzIG5vbiBhcmN1LiBBbGlxdWFt +IGVyYXQgdm9sdXRwYXQuCgpWaXZhbXVzIGxlY3R1cyBtaSwgdWxsYW1jb3JwZXIg +ZXQgZmV1Z2lhdCBzaXQgYW1ldCwgZ3JhdmlkYSBxdWlzIHZlbGl0LiBDcmFzIHRp +bmNpZHVudCBtZXR1cyByaXN1cywgZWdldCB0cmlzdGlxdWUgYXJjdS4gTnVuYyBl +Z2V0IGxlbyBhIGVsaXQgdGVtcG9yIHBvcnR0aXRvci4gQ3VtIHNvY2lpcyBuYXRv +cXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBu +YXNjZXR1ciByaWRpY3VsdXMgbXVzLiBQcmFlc2VudCB0ZW1wdXMgbnVuYyBlZ2V0 +IG5pYmggY29uc2VjdGV0dXIgYWMgY29udmFsbGlzIGVuaW0gc2FnaXR0aXMuIEFs +aXF1YW0gaXBzdW0gdXJuYSwgZmF1Y2lidXMgYWMgdHJpc3RpcXVlIHZlbCwgbGFv +cmVldCBhIGxlby4gUGhhc2VsbHVzIGNvbmRpbWVudHVtIGVuaW0gZWdldCBpcHN1 +bSB2b2x1dHBhdCB1dCBhY2N1bXNhbiBuaWJoIHBlbGxlbnRlc3F1ZS4gTnVsbGFt +IGxhb3JlZXQsIHRvcnRvciBpbiB1bGxhbWNvcnBlciBmcmluZ2lsbGEsIGR1aSBv +ZGlvIHNjZWxlcmlzcXVlIHB1cnVzLCB1dCBpYWN1bGlzIGVyYXQgcmlzdXMgYWMg +bnVsbGEuIEFsaXF1YW0gZWdlc3RhcyBsYWNpbmlhIGFsaXF1YW0uIE1hdXJpcyBi +bGFuZGl0LCB0b3J0b3IgcXVpcyBtb2xsaXMgcGVsbGVudGVzcXVlLCBudWxsYSBt +YWduYSB2ZXN0aWJ1bHVtIGVyYXQsIGV0IHRyaXN0aXF1ZSBsaWd1bGEgc2VtIGVn +ZXQgdGVsbHVzLiBWZXN0aWJ1bHVtIGZlbGlzIHRvcnRvciwgc2VtcGVyIGluIHN1 +c2NpcGl0IGVnZXQsIHRpbmNpZHVudCB2ZWwgdmVsaXQuCgpNYWVjZW5hcyBzZW0g +dGVsbHVzLCBiaWJlbmR1bSBhYyBjdXJzdXMgdXQsIGZldWdpYXQgdmVsIHRvcnRv +ci4gU2VkIHZlbmVuYXRpcyBmZWxpcyBhIGF1Z3VlIHByZXRpdW0gZXUgbGFvcmVl +dCBkdWkgbWF0dGlzLiBNYWVjZW5hcyByaG9uY3VzIHZlc3RpYnVsdW0gbWFnbmEg +ZWdldCBjb252YWxsaXMuIE51bGxhIGZhY2lsaXNpLiBGdXNjZSBpbnRlcmR1bSBk +aWN0dW0gbGVvIG5lYyBhZGlwaXNjaW5nLiBOdW5jIHZpdGFlIGxvcmVtIHF1YW0u +IEluIHVsdHJpY2llcyBzZW0gZXUgbGlndWxhIGVsZWlmZW5kIGluIHNhZ2l0dGlz +IGFyY3UgcnV0cnVtLiBOdWxsYW0gZGlhbSBqdXN0bywgZmVybWVudHVtIG5lYyBs +dWN0dXMgZXUsIGltcGVyZGlldCBuZWMgbGliZXJvLiBJbnRlZ2VyIGhlbmRyZXJp +dCB0ZW1wb3IgZGFwaWJ1cy4gU3VzcGVuZGlzc2UgcG90ZW50aS4gRG9uZWMgdXQg +YXJjdSBuZWMgbG9yZW0gbHVjdHVzIHZhcml1cyB2aXRhZSBhIG51bmMuIEZ1c2Nl +IGEgc2FwaWVuIGxhb3JlZXQgdGVsbHVzIGFkaXBpc2NpbmcgdmVzdGlidWx1bS4g +QWxpcXVhbSB2YXJpdXMgZGljdHVtIG1pIGVnZXQgZmV1Z2lhdC4gRXRpYW0gc2Vk +IGxlbyBldCBtYXVyaXMgZmV1Z2lhdCBldWlzbW9kLiBTdXNwZW5kaXNzZSBxdWlz +IG1hZ25hIG1hZ25hLCBhIHRpbmNpZHVudCBvcmNpLiBMb3JlbSBpcHN1bSBkb2xv +ciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBEb25lYyBu +aXNpIHR1cnBpcywgYWxpcXVldCBldSBzb2xsaWNpdHVkaW4gdml0YWUsIGxhb3Jl +ZXQgbmVjIG5pc2kuIFZlc3RpYnVsdW0gdHJpc3RpcXVlLCB2ZWxpdCB2aXRhZSB1 +bGxhbWNvcnBlciBjb25kaW1lbnR1bSwgbGVjdHVzIG9yY2kgcG9ydHRpdG9yIGFy +Y3UsIGV1IHBsYWNlcmF0IGZlbGlzIHB1cnVzIG5lYyBvcmNpLiBOYW0gaXBzdW0g +YXVndWUsIHNjZWxlcmlzcXVlIGF0IGxhY2luaWEgc2l0IGFtZXQsIG1hdHRpcyBh +IGVyYXQuIFBoYXNlbGx1cyBhIG1hZ25hIHF1aXMgbGFjdXMgdmFyaXVzIHBsYWNl +cmF0LgoKUHJvaW4gb3JuYXJlIHZpdmVycmEgcGxhY2VyYXQuIFNlZCBpYWN1bGlz +IHVsdHJpY2VzIG1hZ25hLCBjb252YWxsaXMgYXVjdG9yIG1pIHRyaXN0aXF1ZSB2 +ZWwuIFBlbGxlbnRlc3F1ZSBhYyBuaXNpIHNpdCBhbWV0IG5pc2kgYWxpcXVhbSB0 +aW5jaWR1bnQgYWMgdXQgaXBzdW0uIFByYWVzZW50IGEgdGVsbHVzIG5vbiBudW5j +IGlhY3VsaXMgYWRpcGlzY2luZy4gUXVpc3F1ZSBmYWNpbGlzaXMganVzdG8gZWdl +dCBtZXR1cyBncmF2aWRhIHVsbGFtY29ycGVyLiBEb25lYyBzYWdpdHRpcywgdG9y +dG9yIGV1aXNtb2QgYWxpcXVhbSBpbnRlcmR1bSwgYXVndWUgYXVndWUgbGFvcmVl +dCBlbGl0LCBpbiBjb21tb2RvIHVybmEgbGFjdXMgdmVsIGVzdC4gVmVzdGlidWx1 +bSBkdWkgbmliaCwgdmFyaXVzIGEgaW50ZXJkdW0gYSwgcG9ydGEgdXQgbWV0dXMu +IFV0IGxlY3R1cyB1cm5hLCBwb3N1ZXJlIGluIGx1Y3R1cyBldCwgcnV0cnVtIGEg +ZXJhdC4gU3VzcGVuZGlzc2UgY3Vyc3VzLCB0b3J0b3Igdml0YWUgc2NlbGVyaXNx +dWUgdHJpc3RpcXVlLCBkb2xvciBlcmF0IGRpZ25pc3NpbSBsZWN0dXMsIG5lYyBz +b2RhbGVzIG1hdXJpcyB0ZWxsdXMgdmVsIHB1cnVzLiBEdWlzIGVsaXQgbWF1cmlz +LCBhY2N1bXNhbiB1dCBwb3N1ZXJlIHZ1bHB1dGF0ZSwgbWFsZXN1YWRhIGV0IGFu +dGUuIE1vcmJpIGJsYW5kaXQgbGFjdXMgYXQgbWF1cmlzIHNhZ2l0dGlzIHJ1dHJ1 +bS4gUGhhc2VsbHVzIGRvbG9yIG1hdXJpcywgY29uc2VxdWF0IHZlbCBmYXVjaWJ1 +cyB2ZWwsIHB1bHZpbmFyIG5lYyBhcmN1LiBOYW0gY29tbW9kbywgcHVydXMgdml0 +YWUgbW9sbGlzIHNjZWxlcmlzcXVlLCBzYXBpZW4gdHVycGlzIGJpYmVuZHVtIGFu +dGUsIGV1IGZhY2lsaXNpcyBpcHN1bSBpcHN1bSBuZWMgbmVxdWUuIENsYXNzIGFw +dGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251 +YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVl +IGNvbnZhbGxpcyBkaWduaXNzaW0gbWFnbmEgc2l0IGFtZXQgdnVscHV0YXRlLiBT +ZWQgY29uZGltZW50dW0gdmVoaWN1bGEgbWF0dGlzLiBWaXZhbXVzIHRpbmNpZHVu +dCBmYWNpbGlzaXMgaXBzdW0sIGV0IHBvcnRhIHJpc3VzIHVsdHJpY2VzIHZpdGFl +LiBRdWlzcXVlIG5vbiBjb25zZXF1YXQgbmlzbC4gQ3VyYWJpdHVyIGp1c3RvIG51 +bGxhLCBiaWJlbmR1bSBpbiB2ZW5lbmF0aXMgZWdldCwgcG9zdWVyZSBlZ2V0IHNl +bS4KClBlbGxlbnRlc3F1ZSBzaXQgYW1ldCByaXN1cyB2ZWwgbGliZXJvIGV1aXNt +b2Qgc3VzY2lwaXQgdmVsIHNpdCBhbWV0IG1ldHVzLiBEb25lYyBncmF2aWRhLCBs +ZW8gcXVpcyBpbnRlcmR1bSBjb25ndWUsIHF1YW0gbGVjdHVzIHRyaXN0aXF1ZSBu +aXNpLCBldSB1bHRyaWNlcyBzZW0gdHVycGlzIHRpbmNpZHVudCBlc3QuIFByYWVz +ZW50IHB1bHZpbmFyIGNvbnZhbGxpcyB1cm5hIHZpdGFlIGlhY3VsaXMuIFV0IGNv +bnZhbGxpcyBwdWx2aW5hciBmYWNpbGlzaXMuIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0 +dXIgcmlkaWN1bHVzIG11cy4gQWVuZWFuIGV0IGVyYXQgZG9sb3IsIGFjIHBvc3Vl +cmUgbWV0dXMuIFNlZCBjb25kaW1lbnR1bSBhZGlwaXNjaW5nIGlwc3VtLCBlZ2V0 +IHVsdHJpY2llcyBqdXN0byBmZXJtZW50dW0gc2l0IGFtZXQuIE5hbSBmZXJtZW50 +dW0gbGVvIHZpdGFlIGxlY3R1cyBtYXR0aXMgaW1wZXJkaWV0LiBFdGlhbSBkb2xv +ciBsYWN1cywgbWF0dGlzIGF0IHRlbXB1cyBldSwgY29uZ3VlIHZlbCB2ZWxpdC4g +UHJhZXNlbnQgYmxhbmRpdCB2aXZlcnJhIHJob25jdXMuIFBlbGxlbnRlc3F1ZSB2 +aXRhZSBsYWN1cyBsZW8uCgpRdWlzcXVlIGlkIGxvcmVtIHF1aXMgdHVycGlzIGx1 +Y3R1cyBjb25zZXF1YXQgaW4gc2l0IGFtZXQgZXN0LiBDdXJhYml0dXIgdHJpc3Rp +cXVlLCBhcmN1IGEgY3Vyc3VzIHZvbHV0cGF0LCBudWxsYSBlc3QgYXVjdG9yIHRl +bGx1cywgbmVjIGZhY2lsaXNpcyBuaWJoIGF1Z3VlIG5lYyBvcmNpLiBNYXVyaXMg +ZmV1Z2lhdCwgZXN0IGFjIGF1Y3RvciBldWlzbW9kLCBvZGlvIG5pYmggYWNjdW1z +YW4gbmVxdWUsIGluIGZlcm1lbnR1bSBvcmNpIG1hc3NhIHZpdGFlIGF1Z3VlLiBQ +ZWxsZW50ZXNxdWUgcXVpcyBtaSBhcmN1LCBub24gaW1wZXJkaWV0IGlwc3VtLiBO +dWxsYW0gZGFwaWJ1cyBoZW5kcmVyaXQgZmVsaXMsIGFjIHVsbGFtY29ycGVyIHRv +cnRvciBwaGFyZXRyYSBldC4gTnVsbGEgYWNjdW1zYW4sIGxhY3VzIHNlZCBlbGVt +ZW50dW0gaW50ZXJkdW0sIG1pIGFyY3UgdmVzdGlidWx1bSBuZXF1ZSwgZWdldCBm +YWNpbGlzaXMgZXJvcyBudW5jIGF0IGVsaXQuIFN1c3BlbmRpc3NlIGV1IG1hdXJp +cyBzdXNjaXBpdCBwdXJ1cyBkaWN0dW0gaWFjdWxpcy4gUHJhZXNlbnQgc2l0IGFt +ZXQgbnVuYyBuZWMgbGFjdXMgZmFjaWxpc2lzIHBvcnRhLiBNYXVyaXMgbnVuYyBp +cHN1bSwgc29sbGljaXR1ZGluIHNlZCBwb3N1ZXJlIGluLCBmZXJtZW50dW0gYWMg +dGVsbHVzLiBOdWxsYSBmcmluZ2lsbGEgc2NlbGVyaXNxdWUgZXJhdCBpZCBwbGFj +ZXJhdC4KCkludGVnZXIgZnJpbmdpbGxhIGZlcm1lbnR1bSB0dXJwaXMgZWdldCBs +YW9yZWV0LiBTdXNwZW5kaXNzZSBwb3N1ZXJlIGVzdCBhYyBlcm9zIGNvbnNlcXVh +dCBub24gZGlnbmlzc2ltIHB1cnVzIGFsaXF1ZXQuIE1hdXJpcyBwcmV0aXVtIHZl +bmVuYXRpcyBwdWx2aW5hci4gVXQgbmVxdWUgbWV0dXMsIGN1cnN1cyBpZCBkaWdu +aXNzaW0gc2l0IGFtZXQsIGNvbmRpbWVudHVtIGVnZXQgZXJvcy4gQWxpcXVhbSBl +cmF0IHZvbHV0cGF0LiBFdGlhbSBwb3J0YSBhbGlxdWFtIG5pc2ksIHNpdCBhbWV0 +IGNvbnNlY3RldHVyIHB1cnVzIGxvYm9ydGlzIG5lYy4gVmVzdGlidWx1bSB0aW5j +aWR1bnQgcGxhY2VyYXQgcXVhbSBhYyBjdXJzdXMuIFByYWVzZW50IGxhb3JlZXQg +ZXJvcyBub24gbmVxdWUgcmhvbmN1cyBhYyBoZW5kcmVyaXQgZHVpIHRlbXBvci4g +Q3JhcyBzb2RhbGVzIGVsaXQgdml0YWUgdXJuYSBpbnRlcmR1bSBhY2N1bXNhbi4g +TnVsbGFtIG5lYyBsYW9yZWV0IGFyY3UuIERvbmVjIGZyaW5naWxsYSBzY2VsZXJp +c3F1ZSByaXN1cywgbmVjIHNhZ2l0dGlzIG9kaW8gYWNjdW1zYW4gbm9uLiBRdWlz +cXVlIHJ1dHJ1bSBzb2RhbGVzIG9kaW8uIE1hdXJpcyBmYWNpbGlzaXMsIG5pYmgg +cXVpcyBlbGVpZmVuZCBzb2xsaWNpdHVkaW4sIGR1aSBvZGlvIGF1Y3RvciBvcmNp +LCBldSBwb3J0dGl0b3IgYXJjdSBudW5jIGFjIGxpZ3VsYS4gSW4gc2VkIG1pIG5l +cXVlLiBNYXVyaXMgZWdlc3RhcywgdGVsbHVzIHNlZCBldWlzbW9kIGVnZXN0YXMs +IGVyb3MgbGlndWxhIGdyYXZpZGEgcmlzdXMsIGF0IGFsaXF1YW0gbGVvIGxpZ3Vs +YSB1dCBvZGlvLiBBbGlxdWFtIHZlbCB2YXJpdXMgc2FwaWVuLiBFdGlhbSBldSBs +ZW8gZXJvcywgcXVpcyBjb25zZXF1YXQgbWkuIE51bGxhbSBzb2RhbGVzIHBlbGxl +bnRlc3F1ZSBvZGlvIG5vbiB0cmlzdGlxdWUuCgpBbGlxdWFtIGVyYXQgdm9sdXRw +YXQuIEFlbmVhbiBsYW9yZWV0LCBudW5jIGVnZXQgbW9sbGlzIGF1Y3RvciwgbWkg +bGlndWxhIGxvYm9ydGlzIGR1aSwgYSB1bHRyaWNpZXMgcXVhbSB2ZWxpdCB1dCBz +YXBpZW4uIFV0IHZlbCBpYWN1bGlzIG5pYmguIEV0aWFtIHV0IHJpc3VzIGR1aS4g +TWF1cmlzIGF0IGp1c3RvIGZlbGlzLiBNYXVyaXMgaWFjdWxpcyBiaWJlbmR1bSB2 +ZWxpdCBlZ2V0IGRhcGlidXMuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEg +c2l0IGFtZXQgb3JjaSBhbnRlLCBhIGVnZXN0YXMgc2FwaWVuLiBNb3JiaSB1bGxh +bWNvcnBlciBsZWN0dXMgdmVsIG1hdXJpcyB2ZXN0aWJ1bHVtIG1hbGVzdWFkYS4g +Q3JhcyB2ZWwgbGVjdHVzIGlwc3VtLiBEdWlzIGVnZXN0YXMgdmVuZW5hdGlzIHBy +ZXRpdW0uIE1vcmJpIHNlZCB0b3J0b3IgZXUgb2RpbyBzdXNjaXBpdCBydXRydW0u +IFNlZCB1bHRyaWNlcyBtYXNzYSBmZXJtZW50dW0gbGFjdXMgdGVtcHVzIHBoYXJl +dHJhLiBJbiBldCBtYXVyaXMgcXVhbSwgaWQgZnJpbmdpbGxhIG1ldHVzLgoKQWVu +ZWFuIG5lYyB2ZWxpdCBkdWkuIE51bGxhbSBlZ2VzdGFzIG1pIGV1IGlwc3VtIHVs +dHJpY2VzIGVnZXQgdmVuZW5hdGlzIHZlbGl0IGxhY2luaWEuIFZpdmFtdXMgbmVj +IGxpZ3VsYSBzaXQgYW1ldCBqdXN0byBhZGlwaXNjaW5nIHZhcml1cyB1dCB1dCBw +dXJ1cy4gQWVuZWFuIGx1Y3R1cyBuaXNsIGVnZXQgbmlzbCB1bHRyaWNlcyBpbXBl +cmRpZXQuIFZpdmFtdXMgYSBuaWJoIGF0IGVsaXQgc29kYWxlcyBldWlzbW9kLiBB +ZW5lYW4gaGVuZHJlcml0IG5pc2kgdmVsIG1ldHVzIGNvbnZhbGxpcyB2dWxwdXRh +dGUuIE1vcmJpIHVybmEgdHVycGlzLCB0ZW1wb3IgYXQgcHVsdmluYXIgdmVsLCBj +b25zZWN0ZXR1ciBldSBtZXR1cy4gTmFtIGZyaW5naWxsYSBtYXVyaXMgc2VkIG9y +Y2kgcG9ydGEgYWMgbW9sbGlzIG51bGxhIGJsYW5kaXQuIEluIHVsdHJpY2llcyB2 +ZWxpdCBhdWN0b3IgYXJjdSBncmF2aWRhIGZlcm1lbnR1bS4gVXQgdmVsIG5lcXVl +IGV0IHZlbGl0IHByZXRpdW0gYmxhbmRpdCBldSBpbiBhbnRlLiBWZXN0aWJ1bHVt +IHV0IGR1aSBtYWduYS4gTmFtIGV0IGxhY3VzIGlwc3VtLCBzZWQgdGluY2lkdW50 +IHRlbGx1cy4gRG9uZWMgZWxlbWVudHVtIGVsZWlmZW5kIHRvcnRvciB1dCB2ZXN0 +aWJ1bHVtLgoKRXRpYW0gdm9sdXRwYXQgbWV0dXMgc2VkIGxvcmVtIGRhcGlidXMg +bGFjaW5pYS4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEg +dG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5h +ZW9zLiBWZXN0aWJ1bHVtIGEgYmxhbmRpdCBuaWJoLiBQaGFzZWxsdXMgZXQgbG9y +ZW0gdmVsIGVyb3MgaWFjdWxpcyB1bHRyaWNpZXMuIFNlZCBzaXQgYW1ldCBtYWdu +YSBzaXQgYW1ldCBlc3QgbW9sZXN0aWUgcHJldGl1bSBzZWQgbmVjIG9yY2kuIFN1 +c3BlbmRpc3NlIHBvdGVudGkuIE51bGxhIGNvbnZhbGxpcyBhbnRlIHZpdGFlIGRv +bG9yIGNvbnZhbGxpcyBub24gdmFyaXVzIG5lcXVlIHBlbGxlbnRlc3F1ZS4gQ3Jh +cyBldWlzbW9kIG1hc3NhIGEgZXJvcyBhbGlxdWFtIHVsdHJpY2VzLiBTZWQgdml0 +YWUgcHVydXMgdXQgbmlzaSBmYXVjaWJ1cyBmZXVnaWF0LiBQcmFlc2VudCBhIGxl +Y3R1cyBldCB2ZWxpdCBlZ2VzdGFzIHBoYXJldHJhIGV0IHNpdCBhbWV0IGRvbG9y +LiBEdWlzIHF1aXMgbGFjaW5pYSBvZGlvLiBTZWQgc2VkIGVuaW0gbGVvLiBEb25l +YyBwdWx2aW5hciBzb2xsaWNpdHVkaW4gbmVxdWUgdXQgZnJpbmdpbGxhLiBFdGlh +bSBtYWxlc3VhZGEgbmlzbCBkaWN0dW0gZXJhdCBkaWN0dW0gZGFwaWJ1cy4gRnVz +Y2UgZmFjaWxpc2lzLCBtaSB2ZWwgdmFyaXVzIG9ybmFyZSwgdG9ydG9yIG51bGxh +IG9ybmFyZSBlcm9zLCBhdCBldWlzbW9kIG5pYmggbmlzaSBldCBhdWd1ZS4gTWFl +Y2VuYXMgZWdldCBzYXBpZW4gbWkuIFNlZCBzZWQgbnVsbGEgbGVjdHVzLiBOdW5j +IGRpZ25pc3NpbSBsdWN0dXMgbGVjdHVzLCBhdCBhbGlxdWV0IGRvbG9yIHZlbmVu +YXRpcyBxdWlzLiBVdCBwdWx2aW5hciwgdG9ydG9yIHNpdCBhbWV0IHNjZWxlcmlz +cXVlIHBoYXJldHJhLCBmZWxpcyBsZW8gcHJldGl1bSBmZWxpcywgZXQgbWF0dGlz +IHNhcGllbiBtYXVyaXMgbWF0dGlzIG51bGxhLgoKU3VzcGVuZGlzc2UgcG90ZW50 +aS4gTnVuYyBxdWlzIHB1bHZpbmFyIHF1YW0uIER1aXMgZGFwaWJ1cyBiaWJlbmR1 +bSBmYWNpbGlzaXMuIE51bGxhbSBsb2JvcnRpcyBlcmF0IHNpdCBhbWV0IHF1YW0g +YWRpcGlzY2luZyBldSBtb2xlc3RpZSB0b3J0b3IgYWNjdW1zYW4uIFByYWVzZW50 +IHB1bHZpbmFyIGVuaW0gZXUganVzdG8gZGFwaWJ1cyBpbiB2aXZlcnJhIG1hdXJp +cyBjb21tb2RvLiBFdGlhbSBtb2xsaXMgY29uc2VxdWF0IHZlbGl0LCBub24gbW9s +ZXN0aWUgZXJvcyBjb25kaW1lbnR1bSBhYy4gRXRpYW0gdml0YWUgZXJhdCBuZWMg +ZWxpdCBjb25ndWUgY29uZGltZW50dW0gYSB1bGxhbWNvcnBlciB0dXJwaXMuIFZl +c3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0 +dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWZXN0aWJ1bHVt +IHZpdGFlIGxvcmVtIGV0IGxlY3R1cyBjb252YWxsaXMgY29uc2VjdGV0dXIuIFN1 +c3BlbmRpc3NlIHNpdCBhbWV0IGZlbGlzIG5vbiBtZXR1cyBtYXR0aXMgbG9ib3J0 +aXMuIE1vcmJpIGV1IG51bGxhIHRvcnRvci4gTWFlY2VuYXMgaGVuZHJlcml0IG9y +Y2kgc2l0IGFtZXQgbGlndWxhIGludGVyZHVtIGV0IGlhY3VsaXMgbnVsbGEgcGxh +Y2VyYXQuIE5hbSBkaWN0dW0gbGFjdXMgYXQgYXJjdSByaG9uY3VzIGVsZWlmZW5k +LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4KCkN1cmFiaXR1ciBh +YyB2ZW5lbmF0aXMgZHVpLiBDbGFzcyBhcHRlbnQgdGFjaXRpIHNvY2lvc3F1IGFk +IGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJpYSBub3N0cmEsIHBlciBpbmNlcHRv +cyBoaW1lbmFlb3MuIEludGVnZXIgYXVjdG9yIHBvcnRhIG5lcXVlIHZlbCBwZWxs +ZW50ZXNxdWUuIEFlbmVhbiBhYyBwdXJ1cyBxdWlzIHZlbGl0IGlhY3VsaXMgcG9y +dHRpdG9yIGluIGluIHNlbS4gRHVpcyB0aW5jaWR1bnQgcmlzdXMgaW4gcmlzdXMg +ZmF1Y2lidXMgYSBhbGlxdWFtIGRpYW0gYXVjdG9yLiBOdWxsYW0gc2VtIGF1Z3Vl +LCBhZGlwaXNjaW5nIHNlZCB0aW5jaWR1bnQgcXVpcywgbW9sZXN0aWUgc2VkIGxp +YmVyby4gVmVzdGlidWx1bSBjb21tb2RvIG9kaW8gdGVtcG9yIG51bGxhIG9ybmFy +ZSBwbGFjZXJhdC4gTW9yYmkgZG9sb3IgbWFzc2EsIGJpYmVuZHVtIGluIGVsZWlm +ZW5kIGlkLCBtb2xlc3RpZSB1dCBqdXN0by4gUXVpc3F1ZSB2YXJpdXMgbnVuYyBz +aXQgYW1ldCBuaXNsIGRhcGlidXMgZmFjaWxpc2lzLiBEb25lYyB1dCBlcmF0IG1p +LiBEdWlzIGVnZXQgY29uc2VjdGV0dXIgbWFnbmEuIE1hdXJpcyBlZ2VzdGFzIHNl +bXBlciBlZ2VzdGFzLiBTZWQgZXQganVzdG8gc2VkIG51bGxhIGJsYW5kaXQgYWNj +dW1zYW4gYXQgbm9uIGxlby4gSW4gZWdldCBlc3QgaXBzdW0uIE51bGxhIHRlbGx1 +cyBsaWd1bGEsIGFsaXF1ZXQgc2l0IGFtZXQgdnVscHV0YXRlIHZpdGFlLCBtb2xs +aXMgZXUgZXJhdC4KCkFlbmVhbiBhYyBhdWd1ZSBvZGlvLiBQcm9pbiBtb2xsaXMs +IGRvbG9yIHV0IGZldWdpYXQgc3VzY2lwaXQsIGR1aSBhbnRlIGNvbnNlY3RldHVy +IG9kaW8sIHZpdGFlIGNvbmRpbWVudHVtIHRlbGx1cyBudWxsYSBhYyBmZWxpcy4g +UGVsbGVudGVzcXVlIGVnZXN0YXMgdWx0cmljZXMgbnVuYywgZXUgc2FnaXR0aXMg +c2FwaWVuIGV1aXNtb2Qgdml0YWUuIEludGVnZXIgc29sbGljaXR1ZGluIGZldWdp +YXQgbGVvIG5lYyBjb25zZWN0ZXR1ci4gUHJhZXNlbnQgc2l0IGFtZXQgc2VtIGVy +YXQsIG5lYyB2b2x1dHBhdCBsYWN1cy4gRXRpYW0gYSBsYWN1cyBudWxsYSwgbm9u +IGludGVyZHVtIGVyYXQuIE1hZWNlbmFzIHF1aXMgZGljdHVtIGxlY3R1cy4gUGVs +bGVudGVzcXVlIGFjIGxpYmVybyB2ZWwgZWxpdCB0cmlzdGlxdWUgc2VtcGVyLiBR +dWlzcXVlIGV1IHN1c2NpcGl0IGR1aS4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEg +ZGljdHVtc3QuIENyYXMgZXUgcG9ydGEgcXVhbS4gQ3VyYWJpdHVyIHBoYXJldHJh +LCBmZWxpcyB1dCByaG9uY3VzIHRpbmNpZHVudCwgbnVsbGEgYXVndWUgcGxhY2Vy +YXQgc2FwaWVuLCBpZCB2ZXN0aWJ1bHVtIG5pc2wgbmVxdWUgYXQgZGlhbS4KClF1 +aXNxdWUgbGFvcmVldCBkYXBpYnVzIGx1Y3R1cy4gTW9yYmkgZXJhdCBvZGlvLCBt +YXR0aXMgc2l0IGFtZXQgdWx0cmljaWVzIGV1LCBpbnRlcmR1bSBldCBudWxsYS4g +TmFtIHZ1bHB1dGF0ZSwgbWV0dXMgbm9uIGVsZW1lbnR1bSBoZW5kcmVyaXQsIHVy +bmEgcHVydXMgcGhhcmV0cmEgZWxpdCwgdml0YWUgc29kYWxlcyBwdXJ1cyBsaWd1 +bGEgbm9uIHF1YW0uIEV0aWFtIGlkIGxpZ3VsYSB0aW5jaWR1bnQgbGVvIHBlbGxl +bnRlc3F1ZSBibGFuZGl0LiBVdCBhbnRlIHVybmEsIHZlc3RpYnVsdW0gc2VkIGVs +ZW1lbnR1bSBhYywgcGVsbGVudGVzcXVlIHNpdCBhbWV0IHRvcnRvci4gRnVzY2Ug +dmVuZW5hdGlzIGNvbW1vZG8gYW50ZSBhdCB0ZW1wb3IuIE51bGxhIGluIG9kaW8g +bGVjdHVzLiBEb25lYyBsYWNpbmlhIGRhcGlidXMgdmVoaWN1bGEuIFN1c3BlbmRp +c3NlIHNjZWxlcmlzcXVlIG9kaW8gdXQgbG9yZW0gZGlnbmlzc2ltIGlkIHByZXRp +dW0gdG9ydG9yIHN1c2NpcGl0LiBOdWxsYW0gZmVsaXMgYW50ZSwgZmVybWVudHVt +IGVnZXQgc29sbGljaXR1ZGluIHNpdCBhbWV0LCBjb21tb2RvIGF0IGVuaW0uIERv +bmVjIGFsaXF1ZXQgbWF1cmlzIGluIGVsaXQgYXVjdG9yIGF0IGNvbnZhbGxpcyBx +dWFtIHVsbGFtY29ycGVyLiBEdWlzIGVuaW0gbmliaCwgdnVscHV0YXRlIGluIGZh +Y2lsaXNpcyBpZCwgYWRpcGlzY2luZyBpbnRlcmR1bSBsYWN1cy4gQWVuZWFuIHNv +bGxpY2l0dWRpbiBjb25ndWUgY29uc2VjdGV0dXIuIFByYWVzZW50IGxvYm9ydGlz +IG5pc2wgZXQgbWV0dXMgZXVpc21vZCBjb25ndWUuIFN1c3BlbmRpc3NlIGlkIHRl +bXB1cyBpcHN1bS4KCkRvbmVjIGV1IGF1Y3RvciBzYXBpZW4uIEluIHBsYWNlcmF0 +IGF1Y3RvciBtYXNzYSB1dCBwbGFjZXJhdC4gVml2YW11cyBhdCB0dXJwaXMgZWxp +dC4gRG9uZWMgY29uZ3VlIHJob25jdXMgZXN0IGEgdml2ZXJyYS4gTnVuYyBub24g +b2RpbyBlbmltLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25p +cyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMu +IE1hZWNlbmFzIHF1aXMgbWFzc2EgbGliZXJvLCBxdWlzIGVsZW1lbnR1bSBtYXVy +aXMuIFZlc3RpYnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3Jj +aSBsdWN0dXMgZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBWZXN0 +aWJ1bHVtIHZhcml1cyB2ZWxpdCBhIG9yY2kgZ3JhdmlkYSB1bHRyaWNpZXMgc2Vk +IHZlbCBsaWd1bGEuIFZlc3RpYnVsdW0gcHJldGl1bSB2ZWhpY3VsYSBhbGlxdWV0 +LiBTdXNwZW5kaXNzZSBhdWN0b3IgY29uZ3VlIG1hZ25hLCBhYyBjb252YWxsaXMg +ZGlhbSB1bGxhbWNvcnBlciB2ZWwuCgpBZW5lYW4gcGxhY2VyYXQgbW9sbGlzIGlw +c3VtLCBuZWMgdWxsYW1jb3JwZXIgcXVhbSBoZW5kcmVyaXQgZWdldC4gQWVuZWFu +IHNlZCBpcHN1bSBhIGFyY3UgbG9ib3J0aXMgdGluY2lkdW50LiBDbGFzcyBhcHRl +bnQgdGFjaXRpIHNvY2lvc3F1IGFkIGxpdG9yYSB0b3JxdWVudCBwZXIgY29udWJp +YSBub3N0cmEsIHBlciBpbmNlcHRvcyBoaW1lbmFlb3MuIEV0aWFtIGNvbnZhbGxp +cyB0b3J0b3Igc2FnaXR0aXMgbmlzbCBwb3J0YSBmZXJtZW50dW0uIFZpdmFtdXMg +YWNjdW1zYW4gbHVjdHVzIGNvbmd1ZS4gTWF1cmlzIGV0IGxlY3R1cyBsb3JlbS4g +TnVuYyBldCBudW5jIGV0IGF1Z3VlIGdyYXZpZGEgYmliZW5kdW0uIE51bGxhbSBz +dXNjaXBpdCBhcmN1IGV0IG1hdXJpcyBpYWN1bGlzIHZpdGFlIGNvbmd1ZSBuaXNs +IHRlbXB1cy4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEg +dG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5h +ZW9zLiBDcmFzIGRvbG9yIHRlbGx1cywgbHVjdHVzIHNlZCBpbXBlcmRpZXQgZXUs +IGFjY3Vtc2FuIG5lYyBsb3JlbS4gQ3JhcyBxdWlzIGlwc3VtIGFudGUuIFZlc3Rp +YnVsdW0gYW50ZSBpcHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMg +ZXQgdWx0cmljZXMgcG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBRdWlzcXVlIHZpdGFl +IGRpYW0gYXVndWUsIGV1IHVsdHJpY2VzIGFyY3UuIFByYWVzZW50IGFudGUgdmVs +aXQsIHZlaGljdWxhIGVnZXQgY3Vyc3VzIGV0LCBjb25zZXF1YXQgc2l0IGFtZXQg +dG9ydG9yLiBNYWVjZW5hcyB1bHRyaWNlcyBsaWd1bGEgaW4gb2RpbyB2ZWhpY3Vs +YSB0aW5jaWR1bnQuIEFlbmVhbiB1bHRyaWNpZXMgaXBzdW0gdXQgc2VtIHZ1bHB1 +dGF0ZSB2aXRhZSBwdWx2aW5hciBkaWFtIGNvbnNlY3RldHVyLiBOYW0gdmVsIGVn +ZXN0YXMgZXJvcy4KClByb2luIHVybmEgbmliaCwgYWxpcXVldCBuZWMgc2FnaXR0 +aXMgYSwgY29uZ3VlIHNlZCBqdXN0by4gTWF1cmlzIHJpc3VzIG5lcXVlLCBibGFu +ZGl0IGN1cnN1cyBzZW1wZXIgZXUsIGZlcm1lbnR1bSBlZ2V0IHB1cnVzLiBDdXJh +Yml0dXIgaW4gbGFjdXMgYXVndWUsIHNpdCBhbWV0IGNvbmRpbWVudHVtIG1pLiBN +YXVyaXMgZXUgc2VtIGlwc3VtLCBpbiB1bHRyaWNlcyBtZXR1cy4gUXVpc3F1ZSBm +cmluZ2lsbGEgc2VtIGEgbmlzaSBjb21tb2RvIHZhcml1cy4gTnVuYyB1bHRyaWNl +cyBwbGFjZXJhdCBwbGFjZXJhdC4gVml2YW11cyBub24gbGVjdHVzIGRvbG9yLCBl +Z2V0IGhlbmRyZXJpdCBhdWd1ZS4gTmFtIHV0IG1hdHRpcyBwdXJ1cy4gSW50ZWdl +ciB2ZWwgdXJuYSBldCB0ZWxsdXMgbGFjaW5pYSBmYWNpbGlzaXMgcGVsbGVudGVz +cXVlIHV0IHRlbGx1cy4gRXRpYW0gbGFvcmVldCByaXN1cyBxdWlzIGVsaXQgZGlj +dHVtIGlkIHRyaXN0aXF1ZSBsZW8gc2VtcGVyLiBVdCBvcm5hcmUgbmlzbCBldSBu +aXNsIHVsbGFtY29ycGVyIGluIHNvbGxpY2l0dWRpbiBtYXVyaXMgZ3JhdmlkYS4g +RXRpYW0gaW4gdGluY2lkdW50IHZlbGl0LiBVdCB0ZW1wdXMgdHVycGlzIHZpdGFl +IHVybmEgc2FnaXR0aXMgdmVsIHBvcnRhIHNlbSB2b2x1dHBhdC4gRHVpcyBub24g +anVzdG8gbWV0dXMsIHRlbXBvciBmYXVjaWJ1cyBxdWFtLiBBbGlxdWFtIGluIGxh +Y3VzIG5lYyBtaSB2ZXN0aWJ1bHVtIGZyaW5naWxsYS4gUHJhZXNlbnQgdGVtcG9y +IGxlY3R1cyBhdCBtZXR1cyBwb3J0YSB1dCBjb25ndWUgZHVpIGZyaW5naWxsYS4K +Ck5hbSBhYyBsZWN0dXMgc2VtLCBhdCB2aXZlcnJhIHJpc3VzLiBDcmFzIHNpdCBh +bWV0IHNvZGFsZXMgbWFzc2EuIFF1aXNxdWUgY29uc2VjdGV0dXIgbGlndWxhIHBv +c3VlcmUgdHVycGlzIGV1aXNtb2QgaW50ZXJkdW0uIFV0IGV1IHRlbGx1cyBldSBt +YXNzYSB1bHRyaWNpZXMgYmliZW5kdW0gdml0YWUgaWQgbWV0dXMuIEN1cmFiaXR1 +ciBpbXBlcmRpZXQgY29uc2VxdWF0IHRpbmNpZHVudC4gVXQgZW5pbSBxdWFtLCBj +b25zZWN0ZXR1ciBhdCBwb3J0dGl0b3IgaW4sIHZhcml1cyBldSBtYWduYS4gTnVu +YyBhcmN1IGVsaXQsIHNvZGFsZXMgbm9uIGRhcGlidXMgdnVscHV0YXRlLCBsYWNp +bmlhIGlkIGZlbGlzLiBDdXJhYml0dXIgbHVjdHVzLCByaXN1cyBxdWlzIHZpdmVy +cmEgY29udmFsbGlzLCBtYXNzYSBqdXN0byB0ZW1wdXMgbGliZXJvLCB2aXRhZSBw +b3J0dGl0b3IgbGlndWxhIHZlbGl0IGEgdHVycGlzLiBOdW5jIHZpdmVycmEsIG1l +dHVzIGEgbWFsZXN1YWRhIGNvbnZhbGxpcywgbmVxdWUgYW50ZSBiaWJlbmR1bSBu +aXNsLCBlZ2V0IGltcGVyZGlldCBlbmltIGxlY3R1cyBldSBlbmltLiBQZWxsZW50 +ZXNxdWUgZW5pbSBuaXNsLCBhZGlwaXNjaW5nIGVnZXQgbW9sZXN0aWUgYXQsIGNv +bnNlY3RldHVyIGV1IG9yY2kuIFNlZCBwb3J0YSB1bGxhbWNvcnBlciBlc3QsIG5l +YyBkaWN0dW0gdHVycGlzIHNlbXBlciBzaXQgYW1ldC4KClF1aXNxdWUgcG9ydGEg +bWkgYWMgdmVsaXQgcmhvbmN1cyBhIHZlaGljdWxhIGxlbyBjb25zZXF1YXQuIE1v +cmJpIGxhb3JlZXQgbWF1cmlzIGVsaXQuIEZ1c2NlIHNlbXBlciByaXN1cyB2ZWwg +bGFjdXMgZWdlc3RhcyByaG9uY3VzLiBQZWxsZW50ZXNxdWUgdGluY2lkdW50IG51 +bGxhIGp1c3RvLCB2aXRhZSB2ZWhpY3VsYSBsaWJlcm8uIE1hdXJpcyBkYXBpYnVz +IGR1aSBpbiBtYWduYSB0cmlzdGlxdWUgc2l0IGFtZXQgZmFjaWxpc2lzIHJpc3Vz +IGxvYm9ydGlzLiBBZW5lYW4gc2l0IGFtZXQgZG9sb3Igdml0YWUgbG9yZW0gZXVp +c21vZCBjb252YWxsaXMuIE51bGxhbSBzaXQgYW1ldCBhZGlwaXNjaW5nIGp1c3Rv +LiBWaXZhbXVzIHZlc3RpYnVsdW0gb3JuYXJlIHN1c2NpcGl0LiBWZXN0aWJ1bHVt +IG1hbGVzdWFkYSB1bHRyaWNlcyB2ZWxpdCBub24gZmV1Z2lhdC4gVmVzdGlidWx1 +bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1 +bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE1hdXJpcyBhcmN1IGlwc3Vt +LCBjb21tb2RvIGluIGlhY3VsaXMgc2VkLCBjb25zZXF1YXQgdXQgYXVndWUuIEFs +aXF1YW0gbGliZXJvIG1hdXJpcywgYWxpcXVldCBhdCBjb25kaW1lbnR1bSBub24s +IGhlbmRyZXJpdCBuZWMgZXJhdC4gSW4gdXQgbWF1cmlzIGxvcmVtLiBWaXZhbXVz +IGVnZXQgbGlndWxhIGlkIG5pc2kgc29sbGljaXR1ZGluIHBsYWNlcmF0IGlkIG5l +YyB0ZWxsdXMuIE51bGxhIG5vbiBmYXVjaWJ1cyBsb3JlbS4gTnVsbGEgbm9uIG5p +YmggZXUgZW5pbSB2aXZlcnJhIGNvbnNlY3RldHVyLiBNb3JiaSBsaWJlcm8gbmlz +bCwgY29udmFsbGlzIGlkIGFsaXF1YW0gaWQsIHN1c2NpcGl0IGFjIGRpYW0uIENs +YXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBl +ciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gSW50ZWdl +ciBlZ2V0IGFudGUgc2FwaWVuLiBTZWQgbm9uIGF1Y3RvciBtYXNzYS4KCk1hZWNl +bmFzIHRpbmNpZHVudCBncmF2aWRhIGNvbnZhbGxpcy4gVmVzdGlidWx1bSBldCBp +YWN1bGlzIGxpYmVyby4gU2VkIHVybmEgb3JjaSwgY29udmFsbGlzIGluIGNvbnNl +cXVhdCBpZCwgdWx0cmljaWVzIHF1aXMgc2VtLiBFdGlhbSBhbGlxdWV0IHNhZ2l0 +dGlzIGltcGVyZGlldC4gTWF1cmlzIG5lYyBuZXF1ZSBxdWFtLiBNb3JiaSB0aW5j +aWR1bnQgbW9sbGlzIHZlbGl0IGVnZXQgdWx0cmljZXMuIERvbmVjIGF0IHR1cnBp +cyBtYWduYSwgZXUgcGxhY2VyYXQgZXJvcy4gUXVpc3F1ZSB0b3J0b3IgbmlzbCwg +dGluY2lkdW50IGV1IGltcGVyZGlldCBxdWlzLCBwb3N1ZXJlIG5lYyBlbGl0LiBD +dW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVy +aWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFF1aXNxdWUgYWxp +cXVldCBsYW9yZWV0IGRpY3R1bS4KClF1aXNxdWUgdmVsIGJpYmVuZHVtIGxlby4g +RXRpYW0gZXQgbWF1cmlzIGxhY3VzLCBzZWQgc29sbGljaXR1ZGluIG5pc2kuIFF1 +aXNxdWUgaWQgcmlzdXMgaW4gbG9yZW0gbWF0dGlzIGRpY3R1bS4gU3VzcGVuZGlz +c2UgcG90ZW50aS4gRG9uZWMgbmVjIGp1c3RvIGFyY3UsIHV0IHBlbGxlbnRlc3F1 +ZSBzZW0uIFN1c3BlbmRpc3NlIHBvdGVudGkuIFBlbGxlbnRlc3F1ZSBlZ2V0IG5p +c2kgaWQgbmlzbCBsYWNpbmlhIGltcGVyZGlldC4gTmFtIGNvbnNlY3RldHVyIGZh +Y2lsaXNpcyBsZW8gbmVjIHRlbXBvci4gRHVpcyBmZXJtZW50dW0gbGFvcmVldCB0 +dXJwaXMgZXQgcHJldGl1bS4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBh +ZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0 +b3MgaGltZW5hZW9zLiBBZW5lYW4gbGFvcmVldCBlc3Qgc2l0IGFtZXQgZWxpdCBm +ZXVnaWF0IGRhcGlidXMuIEV0aWFtIHRlbXB1cyBzdXNjaXBpdCB2ZWxpdCwgb3Ju +YXJlIGRhcGlidXMgaXBzdW0gcG9ydGEgbm9uLiBOdW5jIHV0IGRvbG9yIHV0IGR1 +aSBwb3J0YSBhY2N1bXNhbi4gSW50ZWdlciBkaWN0dW0sIHNlbSBub24gc3VzY2lw +aXQgc29sbGljaXR1ZGluLCB0b3J0b3IgZXJhdCBsYW9yZWV0IHRlbGx1cywgc2l0 +IGFtZXQgcHJldGl1bSBkb2xvciBtaSB1dCBpcHN1bS4gVml2YW11cyBhdWN0b3Ig +ZGlhbSBkaWN0dW0gc2FwaWVuIGZlcm1lbnR1bSBhZGlwaXNjaW5nLiBQaGFzZWxs +dXMgc2NlbGVyaXNxdWUgb2RpbyBxdWlzIG9yY2kgY3Vyc3VzIGV0IHRlbXBvciBz +ZW0gdGluY2lkdW50LiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4g +QWVuZWFuIHNvZGFsZXMsIGVzdCBldCBtYXR0aXMgc29kYWxlcywgbG9yZW0gZGlh +bSBkYXBpYnVzIHF1YW0sIGFjIHByZXRpdW0gbGFjdXMgbGVjdHVzIGV1IHNhcGll +bi4gRG9uZWMgYWRpcGlzY2luZyBsb2JvcnRpcyBtaSBlZ2V0IHZlc3RpYnVsdW0u +CgpNYWVjZW5hcyBhdCBhbnRlIGVsaXQuIEluIHRlbXB1cyBydXRydW0gZXN0LCB2 +aXRhZSBlbGVtZW50dW0gbnVuYyBtb2xlc3RpZSBhYy4gQWxpcXVhbSB1dCBlbmlt +IGFyY3UsIG5lYyBzb2RhbGVzIG51bGxhLiBVdCBkaWduaXNzaW0gYWRpcGlzY2lu +ZyBvcm5hcmUuIER1aXMgZGljdHVtIGNvbW1vZG8gaXBzdW0sIGEgb3JuYXJlIHJp +c3VzIG1hbGVzdWFkYSBzZWQuIEV0aWFtIGlkIGFyY3UgbWF1cmlzLCBuZWMgcGhh +cmV0cmEgc2FwaWVuLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2Vj +dGV0dXIgYWRpcGlzY2luZyBlbGl0LiBBZW5lYW4gcnV0cnVtIGxlY3R1cyBzZWQg +dHVycGlzIHBvcnR0aXRvciBoZW5kcmVyaXQuIEludGVnZXIgbWV0dXMgbGVvLCBs +dWN0dXMgYWMgbGFjaW5pYSBpbiwgZWxlaWZlbmQgZXQgbmVxdWUuIFBlbGxlbnRl +c3F1ZSBiaWJlbmR1bSBudWxsYSBzaXQgYW1ldCB0ZWxsdXMgZXVpc21vZCB2ZWwg +c2NlbGVyaXNxdWUgbWFnbmEgcnV0cnVtLiBBZW5lYW4gdWx0cmljZXMgY29udmFs +bGlzIG5pc2wsIGlkIG9ybmFyZSB0ZWxsdXMgYXVjdG9yIGV1LiBRdWlzcXVlIGxv +Ym9ydGlzIGF1Y3RvciBqdXN0bywgc2l0IGFtZXQgdGluY2lkdW50IGR1aSBsYWNp +bmlhIG5lYy4gTnVsbGFtIGNvbmd1ZSBudW5jIGF0IGZlbGlzIHBvcnR0aXRvciBy +dXRydW0gbm9uIGF0IGVuaW0uCgpVdCBjb252YWxsaXMgY29uZGltZW50dW0gbGFj +dXMgc2VkIGZhY2lsaXNpcy4gQWxpcXVhbSBwcmV0aXVtIGxpZ3VsYSBlZ2V0IG1h +Z25hIHBsYWNlcmF0IHZvbHV0cGF0LiBEb25lYyBub24gbG9yZW0gcGVsbGVudGVz +cXVlIGlwc3VtIGxvYm9ydGlzIHVsbGFtY29ycGVyLiBTdXNwZW5kaXNzZSB2b2x1 +dHBhdCBmZXJtZW50dW0gbWFsZXN1YWRhLiBQcmFlc2VudCBtb2xlc3RpZSBtYWxl +c3VhZGEgbG9yZW0sIHNpdCBhbWV0IGVsZWlmZW5kIG1hc3NhIGVsZWlmZW5kIG5l +Yy4gTnVsbGEgZmFjaWxpc2lzIHRpbmNpZHVudCBlcmF0LCBpbiBwb3J0dGl0b3Ig +ZXJvcyBzYWdpdHRpcyBpZC4gU2VkIGxvYm9ydGlzLCBsaWJlcm8gYXVjdG9yIGlu +dGVyZHVtIGhlbmRyZXJpdCwgZmVsaXMgcXVhbSB2ZXN0aWJ1bHVtIG5pYmgsIGVn +ZXQgaW1wZXJkaWV0IG1hZ25hIGxpZ3VsYSBhdCBudWxsYS4gQWxpcXVhbSBlcmF0 +IHZvbHV0cGF0LiBBbGlxdWFtIG5lYyBuaXNsIHZlbGl0LiBOdW5jIGRhcGlidXMg +ZGlnbmlzc2ltIG1hc3NhIGFjIGx1Y3R1cy4gTWF1cmlzIG5vbiBvZGlvIHB1cnVz +LiBEdWlzIGVyYXQgYW50ZSwgY29uc2VjdGV0dXIgcXVpcyBjb21tb2RvIGEsIGlh +Y3VsaXMgc2VkIGVzdC4gQ3VyYWJpdHVyIGp1c3RvIGp1c3RvLCBiaWJlbmR1bSBp +biBzZW1wZXIgdmVsLCBmYXVjaWJ1cyBpbiBuaWJoLiBFdGlhbSBtYWduYSBhcmN1 +LCBldWlzbW9kIGF0IHRpbmNpZHVudCBxdWlzLCBzb2xsaWNpdHVkaW4gZXQgbGVj +dHVzLiBOdWxsYW0gcHVydXMgbWV0dXMsIGZlcm1lbnR1bSBlZ2V0IHVsdHJpY2ll +cyBuZWMsIGNvbmd1ZSBhIG5pYmguIFBoYXNlbGx1cyBhIGxhY3VzIGlwc3VtLCBp +ZCBzb2xsaWNpdHVkaW4gdmVsaXQuCgpQaGFzZWxsdXMgbm9uIHZlbGl0IG9yY2ks +IGFjIGZldWdpYXQgbGFjdXMuIEN1cmFiaXR1ciBzZWQgc2FwaWVuIG1hZ25hLiBJ +biB2ZWwgcHVsdmluYXIgZmVsaXMuIE1hdXJpcyBxdWlzIGRpYW0gcXVpcyBtYXNz +YSB2YXJpdXMgdmFyaXVzLiBQcmFlc2VudCB1dCBhdWd1ZSBsZW8sIGV0IGZhY2ls +aXNpcyBtYXNzYS4gSW50ZWdlciBhdCB2ZWxpdCBvcmNpLCBuZWMgbW9sZXN0aWUg +ZXN0LiBNb3JiaSBwb3J0YSBibGFuZGl0IHR1cnBpcyBhdCBmcmluZ2lsbGEuIFNl +ZCBsYW9yZWV0IG9kaW8gdXQgZWxpdCBmZXJtZW50dW0gc2VkIGFjY3Vtc2FuIHRv +cnRvciB2b2x1dHBhdC4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBm +YXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEg +Q3VyYWU7IEV0aWFtIGlkIG1hc3NhIHZpdGFlIGVyb3MgaWFjdWxpcyBmYWNpbGlz +aXMgc2VkIGFjIHNlbS4gRXRpYW0gdG9ydG9yIHF1YW0sIG1hbGVzdWFkYSBpbiBz +b2RhbGVzIGEsIHZ1bHB1dGF0ZSB0aW5jaWR1bnQgcXVhbS4gTnVsbGEgZmFjaWxp +c2kuIERvbmVjIGNvbmRpbWVudHVtIHZhcml1cyB1bHRyaWNlcy4gRnVzY2UgYmxh +bmRpdCwgdmVsaXQgdml0YWUgc2NlbGVyaXNxdWUgZXVpc21vZCwgbmliaCBudWxs +YSBpbnRlcmR1bSBhcmN1LCB2ZWwgdnVscHV0YXRlIGZlbGlzIGVzdCBpbiB0b3J0 +b3IuIFNlZCB1dCB1cm5hIGZlcm1lbnR1bSBkaWFtIGVsZWlmZW5kIGxvYm9ydGlz +LgoKQWxpcXVhbSBub24gbnVuYyBvZGlvLiBBbGlxdWFtIGlkIGRpYW0gdmVsIG1p +IHBvc3VlcmUgYXVjdG9yLiBQcmFlc2VudCB0ZW1wb3IgdGVsbHVzIHF1aXMgb2Rp +byB0aW5jaWR1bnQgcG9zdWVyZS4gSW50ZWdlciBhIG1hc3NhIHB1cnVzLCBhYyBn +cmF2aWRhIG1pLiBEb25lYyB2YXJpdXMgbmVxdWUgZXUgZXJvcyBzY2VsZXJpc3F1 +ZSBibGFuZGl0LiBNYWVjZW5hcyBjb25kaW1lbnR1bSB2b2x1dHBhdCBvZGlvIHBy +ZXRpdW0gY29udmFsbGlzLiBEdWlzIHBvc3VlcmUgdmVoaWN1bGEgdm9sdXRwYXQu +IFNlZCB0aW5jaWR1bnQgc2FwaWVuIGV1IGRpYW0gY3Vyc3VzIHZpdGFlIG9ybmFy +ZSBxdWFtIGFkaXBpc2NpbmcuIE5hbSBmYXVjaWJ1cyB0aW5jaWR1bnQgZWxlaWZl +bmQuIEFlbmVhbiBmYWNpbGlzaXMgY29uc2VxdWF0IHR1cnBpcywgYWMgbG9ib3J0 +aXMgdmVsaXQgZGljdHVtIHF1aXMuIE1hdXJpcyBpbXBlcmRpZXQgY29udmFsbGlz +IGxpZ3VsYSBtYXR0aXMgY29uZ3VlLiBOdWxsYW0gdWx0cmljaWVzIGNvbmd1ZSBs +YWN1cyBldCBwcmV0aXVtLiBQcmFlc2VudCBlcm9zIGFyY3UsIGxvYm9ydGlzIHV0 +IHBvcnR0aXRvciB1dCwgaW50ZXJkdW0gZXUgbGliZXJvLiBOYW0gbmVjIG9yY2kg +ZXJhdC4gQ3JhcyBoZW5kcmVyaXQgY29uc2VjdGV0dXIgbWFzc2EsIGlkIGxvYm9y +dGlzIGFyY3UgZXVpc21vZCBpZC4gU3VzcGVuZGlzc2UgcG90ZW50aS4gTnVsbGFt +IGVnZXN0YXMsIGVyb3MgYWMgc3VzY2lwaXQgbW9sZXN0aWUsIG5lcXVlIHRlbGx1 +cyBhZGlwaXNjaW5nIG1hdXJpcywgbm9uIGNvbW1vZG8gZmVsaXMgb2RpbyB1dCBz +ZW0uIE51bGxhbSBzYWdpdHRpcyBncmF2aWRhIHByZXRpdW0uIEZ1c2NlIHJ1dHJ1 +bSBjdXJzdXMgc2NlbGVyaXNxdWUuIFF1aXNxdWUgY29udmFsbGlzLCBkb2xvciBp +biBwdWx2aW5hciBhbGlxdWV0LCBzYXBpZW4gaXBzdW0gdGVtcG9yIGR1aSwgaWQg +dHJpc3RpcXVlIGVzdCBtYXVyaXMgYXVjdG9yIGp1c3RvLgoKQWVuZWFuIGFsaXF1 +ZXQgbWV0dXMgZXUgbWFnbmEgdHJpc3RpcXVlIGV1IGZlcm1lbnR1bSBtYWduYSB1 +bGxhbWNvcnBlci4gQWVuZWFuIHNjZWxlcmlzcXVlIGJsYW5kaXQgZWxlaWZlbmQu +IEludGVnZXIgYSBvcm5hcmUgb2Rpby4gTWFlY2VuYXMgZWxlaWZlbmQgaGVuZHJl +cml0IGFudGUgaWQgbW9sZXN0aWUuIE1hdXJpcyByaG9uY3VzIHBsYWNlcmF0IGFs +aXF1YW0uIFN1c3BlbmRpc3NlIGEgZWxpdCBkaWFtLCBldCBwaGFyZXRyYSBlc3Qu +IER1aXMgZWxlbWVudHVtIG9yY2kgZXUgYW50ZSBtYXR0aXMgYWMgY29uZ3VlIG5p +c2wgYWxpcXVldC4gSW50ZWdlciBzaXQgYW1ldCBkb2xvciBldCBtYXVyaXMgZWxl +aWZlbmQgbGFvcmVldC4gU2VkIGFsaXF1ZXQgcHJldGl1bSBudWxsYSwgaW4gZWxl +aWZlbmQgYXVndWUgcnV0cnVtIHF1aXMuIFF1aXNxdWUgZGFwaWJ1cyBuaXNsIHZp +dGFlIHRlbGx1cyBpbnRlcmR1bSBldSBibGFuZGl0IGFyY3UgY29uc2VxdWF0LiBF +dGlhbSBzZWQgcHVydXMgcmlzdXMuIEZ1c2NlIHR1cnBpcyBsaWJlcm8sIGFsaXF1 +YW0gbmVjIGxhY2luaWEgYXQsIGJsYW5kaXQgbmVjIG51bmMuIFByYWVzZW50IHZp +dmVycmEsIGxvcmVtIGFjIHBvcnR0aXRvciBtYWxlc3VhZGEsIGxvcmVtIHZlbGl0 +IHNvbGxpY2l0dWRpbiB2ZWxpdCwgc2l0IGFtZXQgdGluY2lkdW50IHVybmEgZHVp +IHZpdGFlIGxlby4KCkRvbmVjIHZpdGFlIGZlbGlzIHF1aXMgZW5pbSB2dWxwdXRh +dGUgcmhvbmN1cy4gUHJhZXNlbnQgZWxlbWVudHVtIHRyaXN0aXF1ZSBjb25ndWUu +IERvbmVjIHF1aXMgbWV0dXMgbmliaC4gTWFlY2VuYXMgYXJjdSBhbnRlLCBsYWNp +bmlhIGluIGRhcGlidXMgaWQsIGZlcm1lbnR1bSBzZWQgZXJhdC4gTW9yYmkgYWRp +cGlzY2luZyBncmF2aWRhIG1hZ25hLCB1dCBwb3N1ZXJlIG9kaW8gZmV1Z2lhdCB2 +aXRhZS4gU3VzcGVuZGlzc2UgcG9ydGEgbHVjdHVzIGxhb3JlZXQuIEFsaXF1YW0g +aW4gZXJhdCBzaXQgYW1ldCBvZGlvIHZlaGljdWxhIG9ybmFyZSBxdWlzIGF0IGR1 +aS4gU3VzcGVuZGlzc2Ugbm9uIGxvcmVtIHZpdGFlIGxpZ3VsYSBsdWN0dXMgY29u +c2VjdGV0dXIgYWMgaWQgcHVydXMuIE51bmMgdXQgbmlzaSBqdXN0by4gTnVsbGFt +IGVnZXQgc2FwaWVuIGNvbW1vZG8gZHVpIHN1c2NpcGl0IHBlbGxlbnRlc3F1ZS4g +Vml2YW11cyBzZW1wZXIgbWkgc2VkIGFyY3Ugc2VtcGVyIHZhcml1cy4gQ3JhcyBh +bGlxdWV0IHZlc3RpYnVsdW0gc2FwaWVuLCBhIGludGVyZHVtIG1pIHVsbGFtY29y +cGVyIHZlbC4gTW9yYmkgcHVydXMgZGlhbSwgb3JuYXJlIG5vbiB0ZW1wb3Igbm9u +LCBjb252YWxsaXMgbmVjIGVuaW0uIE51bGxhbSB0cmlzdGlxdWUgdnVscHV0YXRl +IGxlbyBuZWMgZmFjaWxpc2lzLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkg +dHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBh +YyB0dXJwaXMgZWdlc3Rhcy4KCk1vcmJpIGltcGVyZGlldCB2ZWhpY3VsYSBjb25n +dWUuIE1hdXJpcyBxdWlzIG51bGxhIG9kaW8sIGEgZmF1Y2lidXMgdXJuYS4gTnVs +bGEgZXQgZXJvcyBkb2xvci4gRnVzY2UgYSBmYXVjaWJ1cyBpcHN1bS4gTWF1cmlz +IGZlcm1lbnR1bSBmZXVnaWF0IGRpZ25pc3NpbS4gVXQgYSBqdXN0byBlbGl0LCBu +b24gYXVjdG9yIHF1YW0uIFNlZCBsYWN1cyBhdWd1ZSwgcGxhY2VyYXQgYXQgYWxp +cXVhbSBub24sIG1hdHRpcyBpZCBtaS4gQWVuZWFuIGEgbGFvcmVldCBlcm9zLiBD +cmFzIHVsdHJpY2llcyBlbGl0IGluIG51bmMgc3VzY2lwaXQgaWQgc29sbGljaXR1 +ZGluIGVuaW0gY29uZGltZW50dW0uIFBoYXNlbGx1cyBkaWduaXNzaW0gbmlzaSBx +dWlzIGxlbyBpbnRlcmR1bSBwaGFyZXRyYS4gRG9uZWMgc2l0IGFtZXQgbGVvIGEg +ZHVpIHZpdmVycmEgbW9sZXN0aWUuIEN1cmFiaXR1ciBsb2JvcnRpcyBzYXBpZW4g +cXVpcyBuZXF1ZSBwdWx2aW5hciBhdCBmcmluZ2lsbGEgbmlzaSB2ZWhpY3VsYS4K +ClByYWVzZW50IG5vbiBwdXJ1cyB0ZWxsdXMuIEludGVnZXIgaWFjdWxpcyBkYXBp +YnVzIG5pc2wsIHRyaXN0aXF1ZSB2ZXN0aWJ1bHVtIG1pIG1hbGVzdWFkYSBzaXQg +YW1ldC4gU2VkIGxvYm9ydGlzIGhlbmRyZXJpdCBsb2JvcnRpcy4gUXVpc3F1ZSB0 +ZW1wb3IsIGFyY3UgYWMgdGVtcHVzIGF1Y3RvciwgbmVxdWUgcXVhbSBkaWN0dW0g +cXVhbSwgdml0YWUgZ3JhdmlkYSBsaWd1bGEgbmliaCBldSBhdWd1ZS4gQWVuZWFu +IGV1aXNtb2QgdGVtcG9yIGlwc3VtIGEgaGVuZHJlcml0LiBDcmFzIGRvbG9yIGxp +Z3VsYSwgZmF1Y2lidXMgYWMgaGVuZHJlcml0IGVnZXQsIGFsaXF1YW0gYSBuaXNs +LiBJbnRlZ2VyIG5lYyBjb25zZXF1YXQganVzdG8uIEludGVnZXIgcGhhcmV0cmEg +c2NlbGVyaXNxdWUgbGVvLiBBZW5lYW4gZXVpc21vZCB2ZWhpY3VsYSBhbnRlIG5v +biBwaGFyZXRyYS4gVmVzdGlidWx1bSBzb2xsaWNpdHVkaW4ganVzdG8gZXUgc2Vt +IGxhb3JlZXQgaW4gdGVtcHVzIG5lcXVlIGNvbW1vZG8uCgpVdCBpbiBhcmN1IGFu +dGUuIEN1cmFiaXR1ciB1bHRyaWNpZXMgdmVsaXQgZGlhbS4gQWxpcXVhbSB2ZWxp +dCBlcm9zLCB2b2x1dHBhdCBxdWlzIGN1cnN1cyBpZCwgdmVoaWN1bGEgYWMgdG9y +dG9yLiBOdWxsYSBwcmV0aXVtLCBlcmF0IGlkIGZhY2lsaXNpcyBibGFuZGl0LCBy +aXN1cyB0ZWxsdXMgYWxpcXVldCBvcmNpLCB2ZWwgY29uZGltZW50dW0gbmliaCBl +bGl0IHZpdGFlIGVsaXQuIFBoYXNlbGx1cyB1bGxhbWNvcnBlciBjb25zZWN0ZXR1 +ciBhbnRlIHNpdCBhbWV0IGx1Y3R1cy4gTnVsbGEgdXQgbnVsbGEgZWdldCBlcm9z +IGRpY3R1bSBwZWxsZW50ZXNxdWUgdmVsIHV0IG51bGxhLiBEb25lYyBsYW9yZWV0 +IHZpdmVycmEgbWFnbmEgdXQgaW50ZXJkdW0uIFZpdmFtdXMgcHVsdmluYXIgc2Fw +aWVuIGNvbnZhbGxpcyBtYWduYSBzb2RhbGVzIGVnZXQgZWdlc3RhcyBlc3QgaW1w +ZXJkaWV0LiBRdWlzcXVlIGZhY2lsaXNpcyBhbGlxdWFtIHNvZGFsZXMuIEV0aWFt +IGZlcm1lbnR1bSwgb2RpbyBhYyBzZW1wZXIgc2NlbGVyaXNxdWUsIHB1cnVzIGVu +aW0gaW1wZXJkaWV0IGF1Z3VlLCBzaXQgYW1ldCBkaWduaXNzaW0gc2FwaWVuIHRv +cnRvciBuZWMgbWF1cmlzLiBTdXNwZW5kaXNzZSBlbGVpZmVuZCBjb21tb2RvIG51 +bmMgcXVpcyBjb25zZWN0ZXR1ci4gRG9uZWMgZWdldCB0cmlzdGlxdWUgbGVvLgoK +U3VzcGVuZGlzc2Ugc29sbGljaXR1ZGluIHBoYXJldHJhIHNlbXBlci4gU2VkIGp1 +c3RvIGVzdCwgZmF1Y2lidXMgaWQgY3Vyc3VzIGEsIHBlbGxlbnRlc3F1ZSBpbiBt +aS4gTWF1cmlzIHNhZ2l0dGlzLCBpcHN1bSBjdXJzdXMgYmxhbmRpdCBpbXBlcmRp +ZXQsIGVzdCBlc3QgbHVjdHVzIHJpc3VzLCBxdWlzIGZlcm1lbnR1bSBsZW8gb3Jj +aSBhIG9kaW8uIE51bmMgc2l0IGFtZXQgdmVsaXQgaXBzdW0uIE5hbSBldWlzbW9k +IHB1bHZpbmFyIG1ldHVzLCBhYyBhZGlwaXNjaW5nIGR1aSB1bGxhbWNvcnBlciBh +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgU2VkIG1v +bGVzdGllIHRpbmNpZHVudCBkb2xvciwgc2VkIHByZXRpdW0gbWFnbmEgY29uc2Vj +dGV0dXIgdXQuIExvcmVtIGlwc3VtIGRvbG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1 +ciBhZGlwaXNjaW5nIGVsaXQuIEFsaXF1YW0gbGVjdHVzIGxpZ3VsYSwgaW50ZXJk +dW0gYXQgbG9ib3J0aXMgaWQsIGNvbnZhbGxpcyBzaXQgYW1ldCBzZW0uIFNlZCBl +Z2V0IG5lcXVlIGluIGFyY3UgdWx0cmljZXMgZmV1Z2lhdC4gUHJvaW4gdnVscHV0 +YXRlIGxlbyBlZ2V0IGVyb3MgZGFwaWJ1cyBhbGlxdWV0LiBGdXNjZSBmYWNpbGlz +aXMgY29uc2VxdWF0IGRpYW0sIHNlZCB2ZXN0aWJ1bHVtIG1pIHVsdHJpY2llcyBl +Z2V0LiBVdCBwb3N1ZXJlIGNvbmd1ZSBsaWJlcm8gc2l0IGFtZXQgZGlnbmlzc2lt +LiBQcm9pbiBxdWlzIGFyY3UgbGliZXJvLgoKVmVzdGlidWx1bSBhdCBhdWd1ZSBt +YXVyaXMuIEFsaXF1YW0gc2FnaXR0aXMgcG9ydGEgYW50ZSBpbiB2YXJpdXMuIFZl +c3RpYnVsdW0gbHVjdHVzIGlhY3VsaXMgYXJjdSBhIGludGVyZHVtLiBVdCB2YXJp +dXMgaGVuZHJlcml0IGxhY3VzIG5lYyBzYWdpdHRpcy4gU2VkIHV0IHJpc3VzIGFj +IGxlY3R1cyB1bHRyaWNpZXMgbW9sbGlzLiBOdW5jIGZldWdpYXQgc3VzY2lwaXQg +bnVuYyBxdWlzIGVsZW1lbnR1bS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gRnVzY2Ug +bGFvcmVldCBlbGl0IGV1IG9kaW8gZnJpbmdpbGxhIHBlbGxlbnRlc3F1ZS4gRXRp +YW0gdml0YWUgYXJjdSBxdWlzIHF1YW0gc29kYWxlcyBmYWNpbGlzaXMgY29uc2Vx +dWF0IHV0IG9yY2kuIFBoYXNlbGx1cyB2aXRhZSBxdWFtIHF1aXMgbGVvIGNvbmd1 +ZSBpbnRlcmR1bSBzZWQgc3VzY2lwaXQgZXN0LiBNYWVjZW5hcyBjb25kaW1lbnR1 +bSwgbWFzc2EgZWdldCB0ZW1wb3IgcGhhcmV0cmEsIGVyYXQgbGVvIGxhY2luaWEg +b2Rpbywgc2l0IGFtZXQgZmV1Z2lhdCBtYXVyaXMgcmlzdXMgc2VkIHNhcGllbi4g +TW9yYmkgYXJjdSBsb3JlbSwgZGFwaWJ1cyBlZ2V0IHZlbmVuYXRpcyBzZWQsIHNl +bXBlciBlZ2V0IGVyb3MuIENyYXMgc2VtcGVyIHVsdHJpY2llcyBlcm9zIHZvbHV0 +cGF0IHZ1bHB1dGF0ZS4gTW9yYmkgYXQgbnVuYyBlZ2V0IG5pYmggZmV1Z2lhdCB0 +ZW1wdXMuCgpJbiBlZ2V0IGVsaXQgYSBkaWFtIHBsYWNlcmF0IHZvbHV0cGF0IHNl +ZCB0ZW1wdXMgZGlhbS4gTWFlY2VuYXMgdGVtcG9yIHNlbSBpZCBzZW0gdml2ZXJy +YSB2ZWwgZmVybWVudHVtIHJpc3VzIHBvcnR0aXRvci4gUHJvaW4gYSBtZXR1cyBt +ZXR1cy4gQWVuZWFuIHF1aXMgdGluY2lkdW50IG1hZ25hLiBEb25lYyBzaXQgYW1l +dCBwb3N1ZXJlIHJpc3VzLiBEb25lYyBlc3QganVzdG8sIGRhcGlidXMgaW4gc29s +bGljaXR1ZGluIGV1LCB2ZW5lbmF0aXMgc2l0IGFtZXQgZWxpdC4gQ2xhc3MgYXB0 +ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnVi +aWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBDcmFzIGluIHR1cnBp +cyBuZWMgbnVuYyBmcmluZ2lsbGEgaWFjdWxpcy4gRXRpYW0gc3VzY2lwaXQgbmli +aCB2aXRhZSBsaWJlcm8gcGVsbGVudGVzcXVlIHZpdmVycmEuIENyYXMgaWQgbGVj +dHVzIHF1aXMgZW5pbSBvcm5hcmUgbW9sZXN0aWUgdml0YWUgdmVsIHRlbGx1cy4g +SW4gdmVzdGlidWx1bSB2dWxwdXRhdGUgdHVycGlzIGlkIHBvc3VlcmUuCgpOYW0g +ZXN0IGVyYXQsIHJob25jdXMgbm9uIGltcGVyZGlldCBpbiwgc2FnaXR0aXMgdml0 +YWUgaXBzdW0uIE51bGxhIHJ1dHJ1bSB0aW5jaWR1bnQgbGVjdHVzIGV0IGJsYW5k +aXQuIFV0IHNlZCBsaWd1bGEgbmlzbCwgbm9uIGRpY3R1bSBlcmF0LiBBZW5lYW4g +bG9yZW0gZW5pbSwgbW9sbGlzIHV0IHRpbmNpZHVudCBpZCwgY29tbW9kbyBzaXQg +YW1ldCBuaXNsLiBNYWVjZW5hcyBibGFuZGl0IHJob25jdXMgc2VtcGVyLiBGdXNj +ZSBhIG1hc3NhIG9yY2ksIGV0IHZlbmVuYXRpcyBhcmN1LiBNYXVyaXMgbW9sbGlz +IGR1aSBxdWlzIGZlbGlzIGJpYmVuZHVtIHBoYXJldHJhLiBDcmFzIHNlZCBpcHN1 +bSBtYXNzYSwgcG9ydHRpdG9yIHB1bHZpbmFyIG5pc2kuIExvcmVtIGlwc3VtIGRv +bG9yIHNpdCBhbWV0LCBjb25zZWN0ZXR1ciBhZGlwaXNjaW5nIGVsaXQuIFZpdmFt +dXMgY3Vyc3VzIGVsaXQgc2FnaXR0aXMgbGliZXJvIGhlbmRyZXJpdCB2ZXN0aWJ1 +bHVtLiBTZWQgcG9ydHRpdG9yLCB0b3J0b3IgdGluY2lkdW50IHBvcnR0aXRvciBz +ZW1wZXIsIGRpYW0gbWFnbmEgZWxlaWZlbmQgbnVuYywgc2VkIGNvbmRpbWVudHVt +IG5pYmggZXJhdCBxdWlzIG9kaW8uIERvbmVjIHBvc3VlcmUgdmVoaWN1bGEgcHVy +dXMsIGluIHB1bHZpbmFyIG9kaW8gaW50ZXJkdW0gZXUuIFZlc3RpYnVsdW0gZmFj +aWxpc2lzIHRpbmNpZHVudCBkYXBpYnVzLiBGdXNjZSBsdWN0dXMgbG9yZW0gZWdl +dCBxdWFtIGFjY3Vtc2FuIGluIG1hdHRpcyBuaWJoIHZvbHV0cGF0LiBOdWxsYW0g +ZXQgbGVvIGEgdXJuYSBwb3J0YSB2YXJpdXMgbm9uIHZpdGFlIGR1aS4gU2VkIGlu +dGVyZHVtLCBtZXR1cyBldSBydXRydW0gcGhhcmV0cmEsIG5pc2wgc2VtIHRlbXB1 +cyBqdXN0bywgdmFyaXVzIGNvbnZhbGxpcyBpcHN1bSBkaWFtIHV0IGxlY3R1cy4K +CkluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBWZXN0aWJ1bHVtIGNv +bmd1ZSBzb2RhbGVzIG5pc2kgcXVpcyBvcm5hcmUuIEZ1c2NlIGN1cnN1cyBuaXNp +IGF0IHR1cnBpcyBjb25ndWUgaGVuZHJlcml0LiBWZXN0aWJ1bHVtIG5vbiBsYWN1 +cyB2ZWwgc2FwaWVuIHB1bHZpbmFyIHZlaGljdWxhIGF0IGluIGFudGUuIE51bGxh +IGZhY2lsaXNpLiBVdCB0cmlzdGlxdWUgdGluY2lkdW50IGVyYXQgaWQgbHVjdHVz +LiBDdXJhYml0dXIgcG9zdWVyZSBzb2RhbGVzIG5lcXVlIHF1aXMgdmFyaXVzLiBD +dXJhYml0dXIgY3Vyc3VzIGFjY3Vtc2FuIGlwc3VtLCB2ZWwgbHVjdHVzIGxpZ3Vs +YSBkYXBpYnVzIG5vbi4gQ3JhcyB2ZWhpY3VsYSBtYWduYSBpbiBsYWN1cyBvcm5h +cmUgZGFwaWJ1cy4gRG9uZWMgYWxpcXVldCBzb2xsaWNpdHVkaW4gbGFjdXMsIGV1 +IGlhY3VsaXMgZXJhdCBiaWJlbmR1bSBjb21tb2RvLiBEb25lYyBibGFuZGl0IGJp +YmVuZHVtIGZldWdpYXQuIFByYWVzZW50IGV1IGVzdCBqdXN0by4gUGVsbGVudGVz +cXVlIGF0IGVuaW0gc2VkIHNlbSB2aXZlcnJhIGNvbnZhbGxpcy4gTWFlY2VuYXMg +dmVuZW5hdGlzIG1ldHVzIHNhcGllbi4gU2VkIHBsYWNlcmF0IGZhY2lsaXNpcyBl +bGl0IG5lYyBtYWxlc3VhZGEuIEZ1c2NlIHNhcGllbiBlc3QsIGNvbnNlcXVhdCBh +IGNvbmd1ZSBlZ2V0LCBhY2N1bXNhbiBlZ2V0IGxvcmVtLiBTdXNwZW5kaXNzZSB0 +aW5jaWR1bnQgcHJldGl1bSBtYWduYSBlZ2V0IGRhcGlidXMuIEZ1c2NlIHZlbCBl +cm9zIGV0IGxvcmVtIGNvbnNlcXVhdCB0cmlzdGlxdWUgbmVjIGEgaXBzdW0uCgpQ +cm9pbiBxdWlzIGN1cnN1cyBhcmN1LiBNYWVjZW5hcyBlbGVpZmVuZCBsb3JlbSBp +ZCBuaXNsIHNjZWxlcmlzcXVlIHBsYWNlcmF0LiBGdXNjZSBpbXBlcmRpZXQgbG9y +ZW0gZXUgdXJuYSBkaWduaXNzaW0gZmVybWVudHVtLiBQZWxsZW50ZXNxdWUgbnVu +YyBuaXNsLCBpbXBlcmRpZXQgdXQgYWNjdW1zYW4gaWQsIGZlcm1lbnR1bSBub24g +bWF1cmlzLiBBZW5lYW4gZnJpbmdpbGxhIGxlY3R1cyB2aXRhZSB0dXJwaXMgZmVy +bWVudHVtIHZpdGFlIGZhY2lsaXNpcyBvZGlvIG1vbGxpcy4gQWVuZWFuIG5vbiBz +ZW0gZXQgZXJvcyBjb25ndWUgcG9ydGEgaWQgc2l0IGFtZXQgZGlhbS4gRG9uZWMg +ZnJpbmdpbGxhIGVyb3MgYXQgcXVhbSBpbXBlcmRpZXQgYXQgZ3JhdmlkYSB0b3J0 +b3IgdWxsYW1jb3JwZXIuIEZ1c2NlIGRvbG9yIHJpc3VzLCB2aXZlcnJhIGlkIGFs +aXF1ZXQgc2VkLCBkaWduaXNzaW0gcXVpcyBtYXVyaXMuIFF1aXNxdWUgYWMgbWV0 +dXMgaWQgcXVhbSBsb2JvcnRpcyB0cmlzdGlxdWUgYXQgdmVsIGVuaW0uIFBoYXNl +bGx1cyBpbiB0b3J0b3IgbWF1cmlzLiBTZWQgdGluY2lkdW50IGR1aSBub24gZXJv +cyBzb2xsaWNpdHVkaW4gdm9sdXRwYXQuIEN1cmFiaXR1ciB2aXZlcnJhIGVsZW1l +bnR1bSBhcmN1IGFjIHVsdHJpY2VzLiBOdWxsYSBmZWxpcyBsaWd1bGEsIGF1Y3Rv +ciBhdCBsYWNpbmlhIHNlZCwgdGluY2lkdW50IGF0IG1pLiBJbiB2ZWwgZWxpdCBv +cmNpLiBWZXN0aWJ1bHVtIGVyYXQgbmlzaSwgbW9sZXN0aWUgdmVsIGF1Y3RvciB2 +ZWwsIHNhZ2l0dGlzIGFjIGxlY3R1cy4gUGVsbGVudGVzcXVlIHVsdHJpY2llcyBj +b25kaW1lbnR1bSBudWxsYSBuZWMgZXVpc21vZC4KCkRvbmVjIGNvbnNlY3RldHVy +IHZlbmVuYXRpcyBzZW1wZXIuIFN1c3BlbmRpc3NlIHZlbCBkaWN0dW0gYXVndWUu +IFBlbGxlbnRlc3F1ZSBub24gbWF1cmlzIGp1c3RvLiBEb25lYyBhY2N1bXNhbiwg +bWV0dXMgdXQgcHJldGl1bSBtb2xlc3RpZSwgbGlndWxhIGp1c3RvIGx1Y3R1cyBv +cmNpLCBub24gdmFyaXVzIG1pIG5pYmggZXUganVzdG8uIFZlc3RpYnVsdW0gc2Vt +IHNlbSwgdGluY2lkdW50IGVnZXQgcG9ydGEgYSwgZmVybWVudHVtIGV0IHNhcGll +bi4gTnVsbGEgZmFjaWxpc2kuIFBlbGxlbnRlc3F1ZSBpbiB2ZXN0aWJ1bHVtIGFu +dGUuIE51bmMgaWFjdWxpcyBsaWd1bGEgbmVjIG9kaW8gc2FnaXR0aXMgbmVjIHBv +cnR0aXRvciBuaWJoIHNlbXBlci4gVXQgZWdldCBtZXR1cyBvcmNpLiBQcm9pbiBn +cmF2aWRhIG9yY2kgZGlnbmlzc2ltIGRpYW0gaWFjdWxpcyBhY2N1bXNhbi4gQWVu +ZWFuIGF1Z3VlIG9yY2ksIHBsYWNlcmF0IGV0IGNvbnZhbGxpcyBlZ2V0LCBzb2Rh +bGVzIHF1aXMgZGlhbS4gU2VkIHN1c2NpcGl0IG5pc2kgcXVpcyBsaWJlcm8gc29s +bGljaXR1ZGluIGV1IG1vbGxpcyBuZXF1ZSBtb2xlc3RpZS4gTWFlY2VuYXMgcHVy +dXMgbmlzbCwgY29uc2VjdGV0dXIgbm9uIHZlaGljdWxhIHNpdCBhbWV0LCB1bGxh +bWNvcnBlciBxdWlzIG5pYmguIFByYWVzZW50IHF1YW0gaXBzdW0sIG1vbGVzdGll +IGV1IHB1bHZpbmFyIGF0LCBpYWN1bGlzIGV1IHR1cnBpcy4gQ3JhcyBuZWMgZWxp +dCB1dCBsaWJlcm8gc3VzY2lwaXQgYWxpcXVldCBldCBuZWMgbGVjdHVzLiBWZXN0 +aWJ1bHVtIHB1cnVzIGF1Z3VlLCB0cmlzdGlxdWUgdml0YWUgY29udmFsbGlzIGF0 +LCB2ZWhpY3VsYSBub24gbWV0dXMuIEZ1c2NlIGx1Y3R1cyBjb25ndWUgbWksIHZl +bCBzYWdpdHRpcyBkb2xvciBtb2xsaXMgdmVsLiBQcmFlc2VudCBpbiBudW5jIGFj +Y3Vtc2FuIGxvcmVtIGxvYm9ydGlzIGlhY3VsaXMgdXQgdml0YWUgaXBzdW0uIFN1 +c3BlbmRpc3NlIHB1bHZpbmFyLCBudW5jIGFjIGFsaXF1ZXQgc2VtcGVyLCBsYWN1 +cyBsb3JlbSBldWlzbW9kIHB1cnVzLCB2ZWwgbW9sbGlzIG1ldHVzIHJpc3VzIG5l +YyBzYXBpZW4uCgpJbiB2ZW5lbmF0aXMgcG9zdWVyZSBzYXBpZW4sIHNpdCBhbWV0 +IGV1aXNtb2QgZG9sb3IgcGVsbGVudGVzcXVlIGV1LiBQcmFlc2VudCBsYW9yZWV0 +IGZlbGlzIHV0IG1ldHVzIHZlc3RpYnVsdW0gY29uZGltZW50dW0uIFV0IHNjZWxl +cmlzcXVlIGxlbyBhdWd1ZS4gU3VzcGVuZGlzc2Ugdml0YWUgZG9sb3IgcHVydXMs +IGlkIHJ1dHJ1bSBhbnRlLiBGdXNjZSBpbiB2ZWxpdCBhbnRlLCBhIHBlbGxlbnRl +c3F1ZSBtaS4gTWFlY2VuYXMgdmVsIHJpc3VzIGVnZXQgb3JjaSBmZXJtZW50dW0g +cHJldGl1bSBuZWMgdmVsIHNhcGllbi4gUGhhc2VsbHVzIGlwc3VtIG1hZ25hLCBi +aWJlbmR1bSBxdWlzIGZhdWNpYnVzIHZlbCwgcGxhY2VyYXQgaWQgbWFnbmEuIFZp +dmFtdXMgcXVhbSBkdWksIGNvbnNlY3RldHVyIHNlZCBwdWx2aW5hciBldSwgaW50 +ZXJkdW0gaWQgaXBzdW0uIENyYXMgbG9ib3J0aXMgZmFjaWxpc2lzIHJ1dHJ1bS4g +Q3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1 +cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBOYW0gdmVzdGli +dWx1bSBudW5jIHNlZCBqdXN0byBkaWduaXNzaW0gYWMgdGluY2lkdW50IHNhcGll +biBjb25ndWUuCgpQaGFzZWxsdXMgbm9uIGRpY3R1bSB0dXJwaXMuIFByb2luIGVn +ZXQgbWFzc2EgbGFjaW5pYSBsaWJlcm8gcnV0cnVtIHZlc3RpYnVsdW0uIE51bGxh +IGFsaXF1ZXQgbGliZXJvIGlkIHNhcGllbiBhbGlxdWFtIGZlcm1lbnR1bS4gVml2 +YW11cyBsZWN0dXMgaXBzdW0sIHBoYXJldHJhIHV0IGRhcGlidXMgdXQsIGFsaXF1 +YW0gYWMgbmVxdWUuIFZpdmFtdXMgZmF1Y2lidXMgbWkgcXVpcyBtYXVyaXMgcnV0 +cnVtIGFjIHBsYWNlcmF0IG5pc2kgc2NlbGVyaXNxdWUuIE1hdXJpcyBlbGl0IG9y +Y2ksIGFkaXBpc2NpbmcgZXUgY29uc2VxdWF0IGlkLCB2ZW5lbmF0aXMgaW4gbnVu +Yy4gQWVuZWFuIG5vbiBibGFuZGl0IGxpYmVyby4gU3VzcGVuZGlzc2UgaWQgYXVn +dWUgZHVpLiBRdWlzcXVlIG5lYyBvcmNpIHZlbCBvZGlvIG1hdHRpcyBncmF2aWRh +LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kg +bHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTWF1cmlz +IHZvbHV0cGF0IGR1aSB1dCBsYWN1cyBhZGlwaXNjaW5nIGJpYmVuZHVtLiBMb3Jl +bSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBl +bGl0LiBWaXZhbXVzIHZlbmVuYXRpcyBqdXN0byBldSBzYXBpZW4gZmVybWVudHVt +IGNvbmd1ZSBxdWlzIGluIG51bmMuIE51bGxhbSBsYWNpbmlhIGVyb3MgbG9yZW0s +IHV0IGFsaXF1YW0gb3JjaS4gUGhhc2VsbHVzIHN1c2NpcGl0LCBsYWN1cyBldCB0 +ZW1wb3Igc2VtcGVyLCBlc3QgbWF1cmlzIGNvbmd1ZSBtYXNzYSwgc2VkIHVsdHJp +Y2VzIG9yY2kgZGlhbSB2aXRhZSBpcHN1bS4KCk51bGxhIGZhY2lsaXNpLiBTZWQg +cG9zdWVyZSBmcmluZ2lsbGEgZmVsaXMsIGFjIHZlbmVuYXRpcyBkdWkgdnVscHV0 +YXRlIHV0LiBQcm9pbiBlbGVpZmVuZCB0ZW1wb3IgbW9sZXN0aWUuIE51bGxhIHRp +bmNpZHVudCBsZWN0dXMgdml0YWUgbmVxdWUgYmliZW5kdW0gcHJldGl1bS4gSW4g +bGliZXJvIG5pc2wsIHRyaXN0aXF1ZSBuZWMgYmliZW5kdW0gc2l0IGFtZXQsIHVs +bGFtY29ycGVyIG5lYyBlcmF0LiBTdXNwZW5kaXNzZSBpbnRlcmR1bSBwb3J0YSBv +cmNpLCBxdWlzIHZpdmVycmEgZXJhdCBhdWN0b3IgYXQuIER1aXMgYWMgZGlhbSBl +dCBsaWd1bGEgYmxhbmRpdCB0ZW1wb3IgbmVjIGV1IGxhY3VzLiBDdW0gc29jaWlz +IG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250 +ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIFByYWVzZW50IHBlbGxlbnRlc3F1 +ZSB2YXJpdXMgbnVsbGEgdmVsIGFsaXF1YW0uIEFsaXF1YW0gdXQgbGVjdHVzIG1h +dXJpcywgaWQgYWxpcXVldCBsYWN1cy4gSW50ZWdlciBzY2VsZXJpc3F1ZSBlbGVt +ZW50dW0gZHVpLCBldSBsYW9yZWV0IGF1Z3VlIGVsZW1lbnR1bSBzaXQgYW1ldC4g +VXQgdWxsYW1jb3JwZXIgdGVsbHVzIGNvbnZhbGxpcyBzYXBpZW4gdmVzdGlidWx1 +bSBub24gbGFvcmVldCBwdXJ1cyBhZGlwaXNjaW5nLiBOdW5jIG5lYyBxdWFtIG51 +bmMuIFZpdmFtdXMgdWx0cmljZXMgZmVybWVudHVtIG1hc3NhLCBzaXQgYW1ldCBz +Y2VsZXJpc3F1ZSBudW5jIGltcGVyZGlldCB1dC4KClZlc3RpYnVsdW0gYW50ZSBp +cHN1bSBwcmltaXMgaW4gZmF1Y2lidXMgb3JjaSBsdWN0dXMgZXQgdWx0cmljZXMg +cG9zdWVyZSBjdWJpbGlhIEN1cmFlOyBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBk +aWN0dW1zdC4gTnVsbGFtIHRpbmNpZHVudCBtb2xlc3RpZSBpcHN1bSB2ZWwgcmhv +bmN1cy4gSW50ZWdlciBlZ2V0IG51bmMgZXUgdGVsbHVzIHRpbmNpZHVudCBsYWNp +bmlhLiBJbnRlZ2VyIG5lYyBuaXNpIGVnZXQgYXVndWUgc2VtcGVyIHZhcml1cyBp +ZCBhYyBxdWFtLiBOYW0gdGluY2lkdW50LCB0ZWxsdXMgYWMgY29uZGltZW50dW0g +YWNjdW1zYW4sIGRvbG9yIGVyb3Mgdml2ZXJyYSBsZW8sIHBoYXJldHJhIHB1bHZp +bmFyIGxlY3R1cyBlcm9zIGluIG1pLiBEb25lYyBjb25zZXF1YXQsIHR1cnBpcyBp +ZCBjb252YWxsaXMgdm9sdXRwYXQsIGFudGUgc2VtIGVsZW1lbnR1bSBtYWduYSwg +cXVpcyB0ZW1wb3IgcmlzdXMgZGlhbSB2ZWwgdHVycGlzLiBNb3JiaSBhIG9yY2kg +b3JjaSwgZWdlc3RhcyBmZXVnaWF0IGxlY3R1cy4gTnVsbGEgbmVjIG5pYmggaWQg +YXVndWUgaW50ZXJkdW0gbW9sbGlzLiBTdXNwZW5kaXNzZSBwbGFjZXJhdCB0ZW1w +dXMgbnVuYyBhYyB2ZXN0aWJ1bHVtLiBEb25lYyBldCBtZXR1cyBkaWN0dW0gbGVv +IGJpYmVuZHVtIHVsdHJpY2VzIGluIG5lYyBsZWN0dXMuIFV0IHNlZCB2ZWxpdCBu +aWJoLCBzb2RhbGVzIHBvcnRhIG51bmMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVh +IGRpY3R1bXN0LiBTZWQgZWxpdCB0b3J0b3IsIGFsaXF1ZXQgdmVsIHZvbHV0cGF0 +IGEsIHRpbmNpZHVudCBzZWQgc2FwaWVuLiBTdXNwZW5kaXNzZSBlZ2V0IGxpYmVy +byBsYWN1cy4gVml2YW11cyBhdWN0b3IgYW50ZSBub24gbmVxdWUgcG9ydHRpdG9y +IHV0IHByZXRpdW0gbmlzbCB0ZW1wdXMuIE51bGxhIHNvZGFsZXMgcmlzdXMgZXQg +ZXJhdCB2YXJpdXMgbGFvcmVldC4gTWFlY2VuYXMgbHVjdHVzIGxvYm9ydGlzIGxp +Z3VsYSBlZ2V0IGZlcm1lbnR1bS4KClZpdmFtdXMgY29udmFsbGlzIG5pYmggdml0 +YWUgdHVycGlzIGZldWdpYXQgdWx0cmljZXMuIFF1aXNxdWUgdml0YWUgYmxhbmRp +dCBtYXNzYS4gTWF1cmlzIGV1aXNtb2QgdXJuYSB1dCBuZXF1ZSBmZXJtZW50dW0g +dml0YWUgaW1wZXJkaWV0IG1hdXJpcyBldWlzbW9kLiBJbiBhIGR1aSB0ZWxsdXMs +IG5lYyBwb3N1ZXJlIGRvbG9yLiBBZW5lYW4gdWxsYW1jb3JwZXIgYXVndWUgaWQg +ZXJhdCBsYWNpbmlhIHB1bHZpbmFyLiBQZWxsZW50ZXNxdWUgYXQgbnVsbGEgdGVs +bHVzLiBOYW0gZWxlbWVudHVtIGlhY3VsaXMgcHVsdmluYXIuIFZpdmFtdXMgdG9y +dG9yIGxlY3R1cywgZ3JhdmlkYSB1dCBjb21tb2RvIGEsIHZpdmVycmEgdXQgb2Rp +by4gUGhhc2VsbHVzIGVsZW1lbnR1bSBibGFuZGl0IG9kaW8sIG5lYyBkYXBpYnVz +IGFudGUgbWFsZXN1YWRhIGEuIE1hZWNlbmFzIGltcGVyZGlldCwgZmVsaXMgYSBz +ZW1wZXIgZmFjaWxpc2lzLCBtYXNzYSBudWxsYSBhbGlxdWV0IHRvcnRvciwgZXQg +bWFsZXN1YWRhIG1hZ25hIGxlY3R1cyBhYyBwdXJ1cy4gQWVuZWFuIGF1Y3RvciB0 +ZWxsdXMgaWQganVzdG8gY29uZGltZW50dW0gdHJpc3RpcXVlLiBDcmFzIHZpdGFl +IHJ1dHJ1bSBhcmN1LiBNYXVyaXMgdGVtcHVzLCBtYWduYSBlZ2V0IHZhcml1cyBp +bnRlcmR1bSwgbmlzbCBqdXN0byBwb3J0YSBhdWd1ZSwgc2VkIHBvcnRhIG5pc2wg +cXVhbSBhIG5pYmguIE1hZWNlbmFzIHZpdGFlIHB1cnVzIGRpYW0uIFByYWVzZW50 +IGJpYmVuZHVtIG5pYmggZHVpLCBpbiB0aW5jaWR1bnQgbnVuYy4gRHVpcyB2aXRh +ZSBzZW0gYW50ZS4KCk1hdXJpcyBwb3N1ZXJlIGZlbGlzIGV0IHR1cnBpcyBzb2Rh +bGVzIGhlbmRyZXJpdCB1dCBpZCBudW5jLiBEb25lYyBsYW9yZWV0IG1hbGVzdWFk +YSBlcm9zLiBOYW0gcXVpcyBkaWFtIGFyY3UsIGV1IHRyaXN0aXF1ZSB0ZWxsdXMu +IFBlbGxlbnRlc3F1ZSBxdWlzIGVsaXQgbnVuYy4gQ3JhcyBsZW8gbG9yZW0sIG9y +bmFyZSBjb21tb2RvIG1vbGVzdGllIHNpdCBhbWV0LCBjb25zZXF1YXQgdmVsIGVz +dC4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIENyYXMgcmlzdXMg +cXVhbSwgc3VzY2lwaXQgc2VtcGVyIGltcGVyZGlldCB1bHRyaWNlcywgdHJpc3Rp +cXVlIG5lYyBzYXBpZW4uIFBlbGxlbnRlc3F1ZSBjb25kaW1lbnR1bSwgdHVycGlz +IG5lYyBzb2RhbGVzIGNvbnNlY3RldHVyLCBkaWFtIHNlbSBiaWJlbmR1bSBkaWFt +LCB2aXRhZSBhbGlxdWV0IG1pIGFyY3UgYSBhcmN1LiBQaGFzZWxsdXMgaGVuZHJl +cml0LCBtYWduYSBxdWlzIGdyYXZpZGEgZmVybWVudHVtLCBtYWduYSBsZWN0dXMg +c2VtcGVyIG1hc3NhLCBzZWQgY29uZ3VlIHVybmEgbmliaCBhdCBudWxsYS4gQ3Jh +cyBzZWQgbmliaCBtaS4gTnVsbGEgdGVtcG9yIHByZXRpdW0gcG9ydGEuCgpVdCBp +ZCBqdXN0byB2aXRhZSB0dXJwaXMgY29udmFsbGlzIGNvbmd1ZS4gQ3VyYWJpdHVy +IG1hbGVzdWFkYSBwdXJ1cyBlZ2V0IGRpYW0gYXVjdG9yIGV0IHVsbGFtY29ycGVy +IHZlbGl0IG1hbGVzdWFkYS4gUGhhc2VsbHVzIHNjZWxlcmlzcXVlIGZlcm1lbnR1 +bSBsaWJlcm8uIE1vcmJpIGR1aSB0b3J0b3IsIGJsYW5kaXQgbWFsZXN1YWRhIGxv +Ym9ydGlzIHVsdHJpY2llcywgYmxhbmRpdCBldCBuaXNpLiBOdWxsYSBtYXR0aXMg +ZmFjaWxpc2lzIGxhY3VzLiBBbGlxdWFtIHNvZGFsZXMgZWxpdCBzaXQgYW1ldCBt +ZXR1cyB2ZW5lbmF0aXMgYSBjb21tb2RvIHF1YW0gYmliZW5kdW0uIFV0IG5vbiB0 +ZWxsdXMgdG9ydG9yLiBTZWQgc2VtcGVyLCBuaXNpIGluIHRlbXBvciB2ZXN0aWJ1 +bHVtLCBzZW0gbnVsbGEgZXVpc21vZCBhcmN1LCB1dCBzb2RhbGVzIGVzdCBudW5j +IGF0IHRlbGx1cy4gRG9uZWMgbm9uIG1ldHVzIG5vbiBkb2xvciBzY2VsZXJpc3F1 +ZSB2aXZlcnJhLiBQaGFzZWxsdXMgbmVjIG51bGxhIGp1c3RvLCB1dCBwb3J0dGl0 +b3IgbnVsbGEuIEZ1c2NlIGZldWdpYXQgZ3JhdmlkYSBzb2xsaWNpdHVkaW4uIFNl +ZCBpZCBoZW5kcmVyaXQgbWF1cmlzLiBEb25lYyBsZWN0dXMgdG9ydG9yLCBwb3J0 +YSBzaXQgYW1ldCBjb25kaW1lbnR1bSBzZWQsIHZhcml1cyBhIHZlbGl0LiBJbiBk +aWN0dW0gZG9sb3Igc2VkIGVzdCBkaWN0dW0gaW4gcnV0cnVtIG5lcXVlIHN1c2Np +cGl0LgoKTWFlY2VuYXMgaW1wZXJkaWV0IGNvbnZhbGxpcyB1bHRyaWNpZXMuIEN1 +bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJp +ZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUGVsbGVudGVzcXVl +IG51bmMgdHVycGlzLCBpYWN1bGlzIHF1aXMgZWxlaWZlbmQgZXUsIHRpbmNpZHVu +dCB1dCBsYWN1cy4gQ3VyYWJpdHVyIHZpdGFlIHRlbGx1cyBuaWJoLiBQZWxsZW50 +ZXNxdWUgZWdldCBjb21tb2RvIG5pYmguIE51bGxhIGxhb3JlZXQsIGVyb3MgaWQg +aW1wZXJkaWV0IG1vbGxpcywgbmlzaSBlc3QgZWdlc3RhcyBmZWxpcywgZWdldCBs +dWN0dXMgZW5pbSBsYWN1cyB2aXRhZSBhcmN1LiBOdWxsYW0gaXBzdW0gZGlhbSwg +ZmF1Y2lidXMgZmV1Z2lhdCBjb21tb2RvIGV0LCB0ZW1wb3IgYWMgbGFjdXMuIERv +bmVjIHZlbCBlcmF0IG1hc3NhLCBhdCBwcmV0aXVtIGVzdC4gUGVsbGVudGVzcXVl +IGx1Y3R1cyBuaXNpIG51bGxhLCBhYyBhbGlxdWV0IGF1Z3VlLiBNYWVjZW5hcyBp +ZCBwaGFyZXRyYSBkb2xvci4gUHJvaW4gZGFwaWJ1cyBtYXR0aXMgY3Vyc3VzLiBN +b3JiaSBpbnRlcmR1bSwgZW5pbSBxdWlzIGZlcm1lbnR1bSBwbGFjZXJhdCwgbmlz +aSBtaSBjb25ndWUgc2VtLCBhIHRlbXBvciBuaXNsIG1hdXJpcyBpbiBzZW0uIElu +IGNvbmRpbWVudHVtLCBpcHN1bSBuZWMgdmVuZW5hdGlzIHZlbmVuYXRpcywgbnVs +bGEgZW5pbSBsYW9yZWV0IGFudGUsIG5lYyBoZW5kcmVyaXQgaXBzdW0gbGVjdHVz +IGVnZXQgcmlzdXMuIFBlbGxlbnRlc3F1ZSBlbmltIGxpYmVybywgdGluY2lkdW50 +IHZpdGFlIG1vbGVzdGllIHNpdCBhbWV0LCBncmF2aWRhIG5lYyBsYWN1cy4gRHVp +cyBhYyBzYXBpZW4gbGliZXJvLCBpbiBhbGlxdWV0IHF1YW0uIE1vcmJpIHRlbXBv +ciBsaWJlcm8gcXVpcyBlc3QgZ3JhdmlkYSBzZWQgZWdlc3RhcyBudWxsYSB2dWxw +dXRhdGUuCgpEb25lYyBsYWNpbmlhIG1pIGF0IHRlbGx1cyB2aXZlcnJhIGxvYm9y +dGlzLiBOdWxsYSBpbnRlcmR1bSwgdXJuYSB1dCBmYXVjaWJ1cyBzZW1wZXIsIGR1 +aSBsZWN0dXMgZnJpbmdpbGxhIGVyYXQsIHV0IGFsaXF1YW0gbmlzbCBpcHN1bSBh +dCBlcm9zLiBWaXZhbXVzIGNvbnZhbGxpcyBoZW5kcmVyaXQgYXJjdSBxdWlzIGNv +bmRpbWVudHVtLiBQcmFlc2VudCBhdCBmZXVnaWF0IHNhcGllbi4gUXVpc3F1ZSBu +b24gb3JjaSBhcmN1LiBQZWxsZW50ZXNxdWUgZWdldCBtaSBhcmN1LCBzaXQgYW1l +dCBsdWN0dXMgbnVuYy4gQ3VyYWJpdHVyIGxlY3R1cyBsZW8sIGNvbnNlcXVhdCBz +ZW1wZXIgaW1wZXJkaWV0IGV0LCBlbGVtZW50dW0gdml0YWUgZGlhbS4gUHJvaW4g +cHVydXMgbnVsbGEsIHB1bHZpbmFyIGlkIGltcGVyZGlldCBzZWQsIGZldWdpYXQg +YSBudWxsYS4gUHJvaW4gc3VzY2lwaXQgZWxpdCB2ZWwgYXJjdSB2ZW5lbmF0aXMg +c29kYWxlcy4gQ3JhcyBhY2N1bXNhbiBtYXNzYSBhYyBudWxsYSBwdWx2aW5hciBm +ZXVnaWF0IGV1IGF0IHRlbGx1cy4gUXVpc3F1ZSB2aXRhZSBlcmF0IG9yY2ksIG5v +biB0ZW1wb3IgZW5pbS4gRG9uZWMgb3JuYXJlIGxvYm9ydGlzIG1pIHZpdGFlIGNv +bnNlcXVhdC4gSW50ZWdlciB2aXZlcnJhLCB2ZWxpdCB2ZWwgcGVsbGVudGVzcXVl +IGFjY3Vtc2FuLCBhdWd1ZSBsaWd1bGEgYmxhbmRpdCBuaXNsLCBlZ2V0IGNvbmRp +bWVudHVtIG5lcXVlIGFyY3UgaW4gZXJhdC4gTmFtIHF1aXMgbG9yZW0gbG9yZW0s +IHZlbCBjdXJzdXMgcmlzdXMuIEluIG5lYyBudW5jIGRvbG9yLCBxdWlzIHBvcnR0 +aXRvciBuZXF1ZS4gTWFlY2VuYXMgdHVycGlzIG9kaW8sIGRpY3R1bSB2aXRhZSBj +b21tb2RvIHRpbmNpZHVudCwgYWxpcXVhbSB1dCBhdWd1ZS4gUGhhc2VsbHVzIGF0 +IGp1c3RvIGxhY3VzLiBQaGFzZWxsdXMgc2l0IGFtZXQgdXJuYSBhdCBhbnRlIHZh +cml1cyBwZWxsZW50ZXNxdWUuIFBlbGxlbnRlc3F1ZSBpbiBsaWJlcm8gYWMgdXJu +YSBmcmluZ2lsbGEgdGluY2lkdW50IHZpdGFlIHNlZCB2ZWxpdC4KCkRvbmVjIGFj +IHJpc3VzIHNhcGllbi4gTnVsbGEgZmFjaWxpc2kuIERvbmVjIGF0IHZlbGl0IG5v +biBudW5jIHRlbXB1cyBmZXJtZW50dW0uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5h +dGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIg +cmlkaWN1bHVzIG11cy4gRnVzY2UgaW50ZXJkdW0gYWxpcXVhbSBsb3JlbSwgaW4g +c2NlbGVyaXNxdWUgZW5pbSB0aW5jaWR1bnQgaWQuIFByYWVzZW50IHNvbGxpY2l0 +dWRpbiBkdWkgbmVjIGxhY3VzIGxhY2luaWEgcGxhY2VyYXQuIFV0IGVnZXQgbWF0 +dGlzIG1ldHVzLiBJbiB2ZWwgc2VtIHVybmEsIGV1IGNvbnZhbGxpcyB0dXJwaXMu +IER1aXMgaGVuZHJlcml0IGlwc3VtIHVybmEsIG5vbiBwZWxsZW50ZXNxdWUgb3Jj +aS4gVXQgZXN0IG1ldHVzLCBlbGVtZW50dW0gaW4gYmliZW5kdW0gaWQsIHZpdmVy +cmEgZGlnbmlzc2ltIHRlbGx1cy4gRHVpcyBpZCBlcmF0IGxpYmVyby4gVmVzdGli +dWx1bSBpbiBsaWJlcm8gbm9uIHNlbSB0aW5jaWR1bnQgZWxlbWVudHVtIHNlZCBl +dCBuaXNpLiBQaGFzZWxsdXMgbGVjdHVzIGVyYXQsIGVsZWlmZW5kIGlkIHNhZ2l0 +dGlzIHV0LCBmcmluZ2lsbGEgc2VkIHR1cnBpcy4gQWxpcXVhbSB2ZWwgZXJvcyBp +ZCBudW5jIHZlbmVuYXRpcyB1bGxhbWNvcnBlci4gQWxpcXVhbSB0cmlzdGlxdWUg +bWFzc2EgYSBtYXVyaXMgc2NlbGVyaXNxdWUgbm9uIGZhdWNpYnVzIG5lcXVlIHVs +dHJpY2llcy4KCkFsaXF1YW0gY29uc2VxdWF0IGx1Y3R1cyBlbGl0LCBpZCBtYWxl +c3VhZGEgZXJvcyBsb2JvcnRpcyB1dC4gTnVsbGFtIGEgaGVuZHJlcml0IGxpYmVy +by4gTWFlY2VuYXMgZXQgc2VtIGF0IGVyYXQgbWF0dGlzIGVsZWlmZW5kIHNlZCBz +aXQgYW1ldCBzZW0uIE51bGxhIGxvYm9ydGlzIG5pYmggYSBvcmNpIGVsZWlmZW5k +IHRlbXBvci4gUHJvaW4gbnVsbGEgZmVsaXMsIHZlbmVuYXRpcyBxdWlzIHVsdHJp +Y2llcyB2ZWwsIGFsaXF1ZXQgaW4gZG9sb3IuIFBoYXNlbGx1cyB0aW5jaWR1bnQg +ZG9sb3IgZmVybWVudHVtIG1hc3NhIGlhY3VsaXMgZGlnbmlzc2ltIHZlbCB1dCBk +dWkuIFByb2luIHRpbmNpZHVudCBzYWdpdHRpcyBzb2RhbGVzLiBQcm9pbiBtYXR0 +aXMgdmFyaXVzIGVuaW0sIGF0IGx1Y3R1cyBzZW0gaGVuZHJlcml0IGV1LiBVdCB2 +aXRhZSBncmF2aWRhIG9kaW8uIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEg +ZnJpbmdpbGxhIHBsYWNlcmF0IHZlbGl0LCBzZWQgYWxpcXVldCBudWxsYSBpbXBl +cmRpZXQgYS4gRG9uZWMgZWxlaWZlbmQgcHVsdmluYXIgb3JjaSwgaW4gcG9ydGEg +ZGlhbSBwb3N1ZXJlIGJpYmVuZHVtLiBQcm9pbiBlZ2VzdGFzIHBvcnR0aXRvciBh +bGlxdWFtLiBRdWlzcXVlIHNhcGllbiBmZWxpcywgaGVuZHJlcml0IGlkIGNvbmd1 +ZSBldSwgdGluY2lkdW50IHNlZCBlc3QuIFZpdmFtdXMgY3Vyc3VzIHByZXRpdW0g +ZXJhdCB1dCBmYXVjaWJ1cy4gSW50ZWdlciBsaWJlcm8gZWxpdCwgdmVuZW5hdGlz +IHZlbCBhbGlxdWV0IG5lYywgaW50ZXJkdW0gaW4gZW5pbS4gTmFtIGEgdmVsaXQg +anVzdG8sIHZpdGFlIGlhY3VsaXMgdHVycGlzLgoKVml2YW11cyBuaWJoIGxpZ3Vs +YSwgaW50ZXJkdW0gdmVzdGlidWx1bSB2ZW5lbmF0aXMgdml0YWUsIGZlcm1lbnR1 +bSBpbiBtYWduYS4gU3VzcGVuZGlzc2UgZHVpIGFyY3UsIGdyYXZpZGEgYWMgZWdl +c3RhcyBub24sIGNvbmd1ZSBub24gZGlhbS4gUGVsbGVudGVzcXVlIGhhYml0YW50 +IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEg +ZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFBlbGxlbnRlc3F1ZSBwdWx2aW5hciBw +aGFyZXRyYSBsb3JlbSwgZXQgcG9zdWVyZSBzZW0gY29uZ3VlIHV0LiBTZWQgZWxl +bWVudHVtIGNvbnZhbGxpcyBkb2xvciBldSB2dWxwdXRhdGUuIEludGVnZXIgbmli +aCBqdXN0bywgcGVsbGVudGVzcXVlIGVnZXQgdWx0cmljaWVzIGF1Y3RvciwgZmVy +bWVudHVtIG5vbiBtaS4gUGVsbGVudGVzcXVlIGF0IG5lcXVlIGVzdC4gQ3VyYWJp +dHVyIHBlbGxlbnRlc3F1ZSBhcmN1IHNlZCBsYWN1cyBwbGFjZXJhdCBxdWlzIGRp +Z25pc3NpbSBvcmNpIHBsYWNlcmF0LiBOdWxsYW0gcGVsbGVudGVzcXVlIGxpYmVy +byBpZCBhbnRlIGRhcGlidXMgc2VkIGJpYmVuZHVtIG1ldHVzIHRyaXN0aXF1ZS4g +Vml2YW11cyBpZCBkdWkgcXVpcyBhcmN1IHVsdHJpY2VzIHZpdmVycmEuIFBlbGxl +bnRlc3F1ZSBhdWN0b3IgbmlzaSBzZWQgZXN0IGxhb3JlZXQgdml2ZXJyYS4gU3Vz +cGVuZGlzc2UgbGFjaW5pYSBsZWN0dXMgbWFzc2EuIEFsaXF1YW0gZXJhdCB2b2x1 +dHBhdC4KClF1aXNxdWUgdWxsYW1jb3JwZXIgYXVndWUgaW4ganVzdG8gdWx0cmlj +aWVzIHBvcnRhLiBTZWQgcXVpcyBhcmN1IGFjIGxvcmVtIGFjY3Vtc2FuIHBvc3Vl +cmUuIE1hdXJpcyBjb25zZXF1YXQsIGxpYmVybyBlZ2V0IGZldWdpYXQgbG9ib3J0 +aXMsIGlwc3VtIGZlbGlzIHZlc3RpYnVsdW0gdGVsbHVzLCB2ZWwgdWx0cmljZXMg +aXBzdW0gYXJjdSBldSBuaXNsLiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVz +IGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGlj +dWx1cyBtdXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBEdWlz +IHZpdmVycmEgdHVycGlzIHZlbCBlbGl0IGVsZWlmZW5kIGF0IHBvcnR0aXRvciB2 +ZWxpdCByaG9uY3VzLiBTZWQgYXQgZG9sb3IgcXVpcyBuaXNpIGNvbW1vZG8gcG9y +dHRpdG9yLiBNb3JiaSBsb3JlbSBvcmNpLCBjb21tb2RvIGEgbGFvcmVldCBuZWMs +IHZhcml1cyBhdCBsYWN1cy4gTWF1cmlzIHNlZCB2YXJpdXMgZW5pbS4gQWxpcXVh +bSBncmF2aWRhIGFkaXBpc2Npbmcgc2VtIG5vbiBzZW1wZXIuIFN1c3BlbmRpc3Nl +IGVnZXQgZ3JhdmlkYSBudW5jLgoKQ3JhcyB2ZXN0aWJ1bHVtIHRvcnRvciBuZWMg +bGlndWxhIG9ybmFyZSB0ZW1wb3IuIFV0IGlhY3VsaXMgbGlndWxhIGV0IGxlY3R1 +cyB0aW5jaWR1bnQgaWFjdWxpcy4gTWFlY2VuYXMgcHVsdmluYXIgdm9sdXRwYXQg +bGFjaW5pYS4gQ3VyYWJpdHVyIGhlbmRyZXJpdCBtYWxlc3VhZGEgbGVjdHVzLCBz +ZWQgbWFsZXN1YWRhIGVyb3MgZWdlc3RhcyBlZ2V0LiBBbGlxdWFtIGJpYmVuZHVt +IHZhcml1cyBvZGlvIHZhcml1cyBtYXR0aXMuIFByb2luIGFjIHJob25jdXMgYXJj +dS4gTnVsbGEgc3VzY2lwaXQgdG9ydG9yIGEgZXN0IHZpdmVycmEgdWxsYW1jb3Jw +ZXIuIEN1cmFiaXR1ciBldCBkdWkgZGlhbS4gU2VkIGF0IG5lcXVlIG5pc2wuIEN1 +cmFiaXR1ciBzYWdpdHRpcyBvcmNpIG5pc2wuIEN1bSBzb2NpaXMgbmF0b3F1ZSBw +ZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0 +dXIgcmlkaWN1bHVzIG11cy4KCkNyYXMgZmVsaXMgbWV0dXMsIHZhcml1cyBzaXQg +YW1ldCBjb25zZXF1YXQgZWdldCwgc2VtcGVyIHZpdGFlIGxlby4gTWF1cmlzIHV0 +IG5pc2kgbGFjdXMsIGEgcHJldGl1bSBsYWN1cy4gRHVpcyBlZ2V0IGVzdCBuZWMg +ZG9sb3Igc29sbGljaXR1ZGluIGZlcm1lbnR1bS4gTWFlY2VuYXMgb3JuYXJlIGFk +aXBpc2NpbmcgZHVpLCB2aXRhZSBwZWxsZW50ZXNxdWUgbmlzbCBhbGlxdWFtIGEu +IFZpdmFtdXMgYXVjdG9yIGZyaW5naWxsYSBsaWd1bGEsIGlkIHRlbXBvciBqdXN0 +byBjb25ndWUgYS4gUHJhZXNlbnQgcXVpcyBsYW9yZWV0IGF1Z3VlLiBEb25lYyBp +ZCBvcmNpIHV0IG5pc2kgdml2ZXJyYSBjb21tb2RvLiBQZWxsZW50ZXNxdWUgZGlj +dHVtIHZhcml1cyBvcmNpIHZlbCBwaGFyZXRyYS4gTnVuYyBsaWJlcm8gbmlzbCBt +YXNzYSBudW5jLg== + + + + text/plain + + + + + \ No newline at end of file -- cgit v1.2.3 From 68941b57df2caeead67a5bede2ef5a635d07db32 Mon Sep 17 00:00:00 2001 From: mcentner Date: Wed, 11 Nov 2009 15:51:08 +0000 Subject: Added support for SHA-256 and partial support for e-card G3, BELPIC and Italian cards. git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@540 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../at/gv/egiz/stal/util/JCEAlgorithmNames.java | 51 ---- .../java/at/gv/egiz/bku/conf/Configurator.java | 71 +++-- .../at/gv/egiz/bku/slcommands/impl/STALHelper.java | 26 +- .../impl/xsect/AlgorithmMethodFactoryImpl.java | 86 ++++-- .../bku/slcommands/impl/xsect/STALProvider.java | 6 +- .../egiz/bku/slcommands/impl/xsect/Signature.java | 23 +- .../slexceptions/SLExceptionMessages.properties | 2 +- .../slexceptions/SLExceptionMessages_en.properties | 2 +- smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java | 55 +++- smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java | 283 ++++++++++++++++++++ smcc/src/main/java/at/gv/egiz/smcc/ITCard.java | 297 +++++++++++++++++++++ .../src/main/java/at/gv/egiz/smcc/STARCOSCard.java | 192 +++++++++---- smcc/src/main/java/at/gv/egiz/smcc/SWCard.java | 8 +- .../main/java/at/gv/egiz/smcc/SignatureCard.java | 11 +- .../java/at/gv/egiz/smcc/SignatureCardFactory.java | 96 +++++-- .../java/at/gv/egiz/smcc/util/ISO7816Utils.java | 11 +- .../at/gv/egiz/smcc/BELPICCard.properties | 3 + .../resources/at/gv/egiz/smcc/ITCard.properties | 3 + smcc/src/test/java/at/gv/egiz/smcc/CardTest.java | 62 ++--- .../java/at/gv/egiz/smcc/acos/ACOSCardTest.java | 62 ++--- .../at/gv/egiz/smcc/starcos/STARCOSCardTest.java | 62 ++--- .../gv/egiz/bku/smccstal/SignRequestHandler.java | 21 +- .../java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java | 5 +- .../gv/egiz/xades/QualifyingPropertiesFactory.java | 15 +- 24 files changed, 1145 insertions(+), 308 deletions(-) delete mode 100644 STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java create mode 100644 smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java create mode 100644 smcc/src/main/java/at/gv/egiz/smcc/ITCard.java create mode 100644 smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties create mode 100644 smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java b/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java deleted file mode 100644 index c162eed4..00000000 --- a/STAL/src/main/java/at/gv/egiz/stal/util/JCEAlgorithmNames.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -package at.gv.egiz.stal.util; - -import java.util.HashMap; -import java.util.Map; - -/** - * Maps XML Algorithms to JCE Hash names. - * - */ -public class JCEAlgorithmNames { - - private Map hashNameMap = new HashMap(); - - public static String[] JCE_HASH_NAMES = { "SHA-1" }; - - public static String[] SHA_1_ALGORITMS = { - "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", - "http://www.w3.org/2000/09/xmldsig#rsa-sha1" }; - - private static JCEAlgorithmNames instance = new JCEAlgorithmNames(); - - private JCEAlgorithmNames() { - for (String alg : SHA_1_ALGORITMS) { - registerHash(alg, JCE_HASH_NAMES[0]); - } - } - - public static String getJCEHashName(String xmlAlgorithmURI) { - return instance.hashNameMap.get(xmlAlgorithmURI); - } - - public void registerHash(String xmlAlgorithmURI, String jceName) { - hashNameMap.put(xmlAlgorithmURI, jceName); - } -} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java index 41c2512f..50f5d2b4 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/conf/Configurator.java @@ -166,31 +166,62 @@ public abstract class Configurator { protected void configureProviders() { log.debug("Registering security providers"); - Security.insertProviderAt(new IAIK(), 1); - Security.insertProviderAt(new ECCProvider(false), 2); + + IAIK iaikProvider = new IAIK(); + if (Security.getProvider(iaikProvider.getName()) == null) { + // register IAIK provider at first position + Security.insertProviderAt(iaikProvider, 1); + } else { + // IAIK provider already registered + log.info("Provider " + iaikProvider.getName() + " already registered."); + } + + ECCProvider eccProvider = new ECCProvider(false); + if (Security.getProvider(eccProvider.getName()) == null) { + // register ECC Provider at second position + Security.insertProviderAt(eccProvider, 2); + } else { + // ECC Provider already registered + log.info("Provider " + eccProvider.getName() + " already registered."); + } // registering STALProvider as delegation provider for XSECT STALProvider stalProvider = new STALProvider(); - Set services = stalProvider.getServices(); - StringBuilder sb = new StringBuilder(); - for (Service service : services) { - String algorithm = service.getType() + "." + service.getAlgorithm(); - XSecProvider.setDelegationProvider(algorithm, stalProvider.getName()); - sb.append("\n" + algorithm); + if (Security.getProvider(stalProvider.getName()) == null) { + // register STAL provider + Set services = stalProvider.getServices(); + StringBuilder sb = new StringBuilder(); + for (Service service : services) { + String algorithm = service.getType() + "." + service.getAlgorithm(); + XSecProvider.setDelegationProvider(algorithm, stalProvider.getName()); + sb.append("\n" + algorithm); + } + log + .debug("Registered STALProvider as XSecProvider delegation provider for the following services : " + + sb.toString()); + + Security.addProvider(stalProvider); + } else { + // STAL Provider already registered + log.info("Provider " + stalProvider.getName() + " already registered."); } - log - .debug("Registered STALProvider as XSecProvider delegation provider for the following services : " - + sb.toString()); - - Security.addProvider(stalProvider); - XSecProvider.addAsProvider(false); - sb = new StringBuilder(); - sb.append("Registered providers: "); - int i = 1; - for (Provider prov : Security.getProviders()) { - sb.append((i++) + ". : " + prov); + + if (Security.getProvider(XSecProvider.NAME) == null) { + // register XML Security provider + XSecProvider.addAsProvider(false); + } else { + log.info("Provider " + XSecProvider.NAME + " already registered."); + } + + if (log.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Registered providers: "); + int i = 1; + for (Provider prov : Security.getProviders()) { + sb.append((i++) + ". : " + prov); + } + log.debug(sb.toString()); } - log.debug(sb.toString()); } protected void configViewer() { diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java index 0c7ce3f5..e903c608 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java @@ -18,8 +18,15 @@ package at.gv.egiz.bku.slcommands.impl; import iaik.asn1.CodingException; import iaik.asn1.DerCoder; +import iaik.utils.Base64OutputStream; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringWriter; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; @@ -174,7 +181,24 @@ public class STALHelper { try { certificates.add((X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(cert))); } catch (CertificateException e) { - log.info("Failed to decode certificate.", e); + if (log.isDebugEnabled()) { + ByteArrayOutputStream certDump = new ByteArrayOutputStream(); + OutputStreamWriter writer = new OutputStreamWriter(certDump); + try { + writer.write("-----BEGIN CERTIFICATE-----\n"); + writer.flush(); + Base64OutputStream b64os = new Base64OutputStream(certDump); + b64os.write(cert); + b64os.flush(); + writer.write("\n-----END CERTIFICATE-----"); + writer.flush(); + } catch (IOException e1) { + log.info("Failed to decode certificate.", e); + } + log.debug("Failed to decode certificate.\n" + certDump.toString(), e); + } else { + log.info("Failed to decode certificate.", e); + } throw new SLCommandException(4000, SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, new Object[] { "Certificates" }); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java index 6b963465..061fe707 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/AlgorithmMethodFactoryImpl.java @@ -16,18 +16,23 @@ */ package at.gv.egiz.bku.slcommands.impl.xsect; -import iaik.xml.crypto.XmldsigMore; - -import java.security.InvalidAlgorithmParameterException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.X509Certificate; - -import javax.xml.crypto.dsig.CanonicalizationMethod; -import javax.xml.crypto.dsig.DigestMethod; -import javax.xml.crypto.dsig.SignatureMethod; -import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; -import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec; -import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec; +import iaik.security.ecc.interfaces.ECDSAParams; +import iaik.xml.crypto.XmldsigMore; + +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.ECParameterSpec; + +import javax.xml.crypto.dsig.CanonicalizationMethod; +import javax.xml.crypto.dsig.DigestMethod; +import javax.xml.crypto.dsig.SignatureMethod; +import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; +import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec; +import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec; /** * An implementation of the AlgorithmMethod factory that uses the signing @@ -40,7 +45,12 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory { /** * The signature algorithm URI. */ - private String signatureAlgorithmURI; + private String signatureAlgorithmURI; + + /** + * the digest algorithm URI. + */ + private String digestAlgorithmURI = DigestMethod.SHA1; /** * The algorithm parameters for the signature algorithm. @@ -51,23 +61,55 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory { * Creates a new AlgrithmMethodFactory with the given * signingCertificate. * - * @param siginingCertificate + * @param signingCertificate * * @throws NoSuchAlgorithmException * if the public key algorithm of the given * signingCertificate is not supported */ - public AlgorithmMethodFactoryImpl(X509Certificate siginingCertificate) + public AlgorithmMethodFactoryImpl(X509Certificate signingCertificate) throws NoSuchAlgorithmException { - - String algorithm = siginingCertificate.getPublicKey().getAlgorithm(); + + PublicKey publicKey = signingCertificate.getPublicKey(); + String algorithm = publicKey.getAlgorithm(); if ("DSA".equals(algorithm)) { signatureAlgorithmURI = SignatureMethod.DSA_SHA1; - } else if ("RSA".equals(algorithm)) { - signatureAlgorithmURI = SignatureMethod.RSA_SHA1; - } else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) { - signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA1; + } else if ("RSA".equals(algorithm)) { + + int keyLength = 0; + if (publicKey instanceof RSAPublicKey) { + keyLength = ((RSAPublicKey) publicKey).getModulus().bitLength(); + } + + if (keyLength >= 2048) { + signatureAlgorithmURI = XmldsigMore.SIGNATURE_RSA_SHA256; + digestAlgorithmURI = DigestMethod.SHA256; + } else { + signatureAlgorithmURI = SignatureMethod.RSA_SHA1; + } + + } else if (("EC".equals(algorithm)) || ("ECDSA".equals(algorithm))) { + + int fieldSize = 0; + if (publicKey instanceof iaik.security.ecc.ecdsa.ECPublicKey) { + ECDSAParams params = ((iaik.security.ecc.ecdsa.ECPublicKey) publicKey).getParameter(); + fieldSize = params.getG().getCurve().getField().getSize().bitLength(); + } else if (publicKey instanceof ECPublicKey) { + ECParameterSpec params = ((ECPublicKey) publicKey).getParams(); + fieldSize = params.getCurve().getField().getFieldSize(); + } + + if (fieldSize < 256) { + signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA1; + } else if (fieldSize < 512) { + signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA256; + digestAlgorithmURI = DigestMethod.SHA256; + } else { + signatureAlgorithmURI = XmldsigMore.SIGNATURE_ECDSA_SHA512; + digestAlgorithmURI = DigestMethod.SHA512; + } + } else { throw new NoSuchAlgorithmException("Public key algorithm '" + algorithm + "' not supported."); @@ -104,7 +146,7 @@ public class AlgorithmMethodFactoryImpl implements AlgorithmMethodFactory { throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { return signatureContext.getSignatureFactory().newDigestMethod( - DigestMethod.SHA1, (DigestMethodParameterSpec) null); + digestAlgorithmURI, (DigestMethodParameterSpec) null); } /* diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java index 0ab30530..42c6a4c5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/STALProvider.java @@ -49,7 +49,11 @@ public class STALProvider extends Provider { map.put("Signature." + SignatureMethod.RSA_SHA1, IMPL_PACKAGE_NAME + ".STALSignature"); map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA1, - IMPL_PACKAGE_NAME + ".STALSignature"); + IMPL_PACKAGE_NAME + ".STALSignature"); + map.put("Signature." + XmldsigMore.SIGNATURE_RSA_SHA256, + IMPL_PACKAGE_NAME + ".STALSignature"); + map.put("Signature." + XmldsigMore.SIGNATURE_ECDSA_SHA256, + IMPL_PACKAGE_NAME + ".STALSignature"); AccessController.doPrivileged(new PrivilegedAction() { @Override diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java index 26ddb153..3cebb6a3 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/Signature.java @@ -628,9 +628,20 @@ public class Signature { String target = "#" + signatureId; + DigestMethod dm; + try { + dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } catch (InvalidAlgorithmParameterException e) { + log.error("Failed to get DigestMethod algorithm.", e); + throw new SLCommandException(4006); + } + JAXBElement qualifyingProperties; try { - qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats); + qualifyingProperties = factory.createQualifyingProperties111(target, date, signingCertificates, idValue, dataObjectFormats, dm); } catch (QualifyingPropertiesException e) { log.error("Failed to create QualifyingProperties.", e); throw new SLCommandException(4000); @@ -665,7 +676,10 @@ public class Signature { String referenceURI = "#xmlns(xades=http://uri.etsi.org/01903/v1.1.1%23)%20xpointer(id('" + objectIdValue + "')/child::xades:QualifyingProperties/child::xades:SignedProperties)"; - DigestMethod dm; + + String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference"); + String referenceType = QualifyingPropertiesFactory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1; + try { dm = ctx.getAlgorithmMethodFactory().createDigestMethod(ctx); } catch (NoSuchAlgorithmException e) { @@ -675,10 +689,7 @@ public class Signature { log.error("Failed to get DigestMethod algorithm.", e); throw new SLCommandException(4006); } - - String referenceIdValue = ctx.getIdValueFactory().createIdValue("Reference"); - String referenceType = QualifyingPropertiesFactory.SIGNED_PROPERTIES_REFERENCE_TYPE_V1_1_1; - + Reference reference = ctx.getSignatureFactory().newReference(referenceURI, dm, null, referenceType, referenceIdValue); references.add(reference); diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties index db56184e..c5bfce18 100644 --- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages.properties @@ -91,7 +91,7 @@ ec3002.invalid=XML-Struktur der Befehlsanfrage entspricht nicht dem Schema des S # 4xxx # -ec4000.infobox.invalid=Die Infobox '{0}' enthält ungültige Daten. +ec4000.infobox.invalid=Die Infobox {0} enthält ungültige Daten. ec4000.idlink.transfomation.failed=Die komprimierte Personenbindung konnte mit dem Stylesheet {0} nicht transformiert werden. ec4002.infobox.unknown=Unbekannter Infoboxbezeichner {0}. ec4003.not.resolved=Zu signierendes Datum kann nicht aufgelöst werden (URI={0}). diff --git a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties index 6c67ba87..a8bffdc6 100644 --- a/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties +++ b/bkucommon/src/main/resources/at/gv/egiz/bku/slexceptions/SLExceptionMessages_en.properties @@ -91,7 +91,7 @@ ec3002.invalid=XML structure of the command request does not comply with the Sec # 4xxx # -ec4000.infobox.invalid=The infobox '{0}' contains invalid content. +ec4000.infobox.invalid=The infobox {0} contains invalid content. ec4000.idlink.transfomation.failed=Failed to transform CompressedIdentityLink with Stylesheet {0}. ec4002.infobox.unknown=Unknown info box identifier {0}. ec4003.not.resolved=Data to be signed cannot be resolved from URI={0}. diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java index 414d4678..a63d4076 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/ACOSCard.java @@ -16,9 +16,13 @@ */ package at.gv.egiz.smcc; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.List; @@ -375,12 +379,46 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC @Override @Exclusive - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException, InterruptedException { + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException { - if (hash.length != 20) { - throw new IllegalArgumentException("Hash value must be of length 20."); + ByteArrayOutputStream dst = new ByteArrayOutputStream(); + // key ID + dst.write(new byte[]{(byte) 0x84, (byte) 0x01, (byte) 0x88}); + // algorithm ID + dst.write(new byte[]{(byte) 0x80, (byte) 0x01}); + + MessageDigest md; + try { + if ("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) { + dst.write((byte) 0x14); // SHA-1/ECC + md = MessageDigest.getInstance("SHA-1"); + } else if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) { + dst.write((byte) 0x12); // SHA-1 with padding according to PKCS#1 block type 01 + md = MessageDigest.getInstance("SHA-1"); + } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + && appVersion >= 2 + && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) { + dst.write((byte) 0x44); // SHA-256/ECC + md = MessageDigest.getInstance("SHA256"); + } else if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName) + && appVersion >= 2 + && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) { + dst.write((byte) 0x41); // SHA-256 with padding according to PKCS#1 + md = MessageDigest.getInstance("SHA256"); + } else { + throw new SignatureCardException("Card does not support signature algorithm " + alg + "."); + } + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get MessageDigest.", e); + throw new SignatureCardException(e); } + + byte[] digest = new byte[md.getDigestLength()]; + for (int l; (l = input.read(digest)) != -1;) { + md.update(digest, 0, l); + } + digest = md.digest(); try { @@ -393,11 +431,11 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC // SELECT application execSELECT_AID(channel, AID_SIG); // MANAGE SECURITY ENVIRONMENT : SET DST - execMSE(channel, 0x41, 0xb6, DST_SIG); + execMSE(channel, 0x41, 0xb6, dst.toByteArray()); // VERIFY verifyPINLoop(channel, spec, provider); // PERFORM SECURITY OPERATION : HASH - execPSO_HASH(channel, hash); + execPSO_HASH(channel, digest); // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATRE return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel); @@ -413,7 +451,7 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC while (true) { try { // INTERNAL AUTHENTICATE - return execINTERNAL_AUTHENTICATE(channel, hash); + return execINTERNAL_AUTHENTICATE(channel, digest); } catch (SecurityStatusNotSatisfiedException e) { verifyPINLoop(channel, spec, provider); } @@ -711,6 +749,9 @@ public class ACOSCard extends AbstractSignatureCard implements PINMgmtSignatureC ResponseAPDU resp = channel.transmit( new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256)); + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } if (resp.getSW() != 0x9000) { throw new SignatureCardException( "PSO - COMPUTE DIGITAL SIGNATRE failed: SW=" diff --git a/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java new file mode 100644 index 00000000..15b47fb0 --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/BELPICCard.java @@ -0,0 +1,283 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +package at.gv.egiz.smcc; + +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.smcc.util.ISO7816Utils; +import at.gv.egiz.smcc.util.SMCCHelper; + +public class BELPICCard extends AbstractSignatureCard implements SignatureCard { + + /** + * Logging facility. + */ + private static Log log = LogFactory.getLog(BELPICCard.class); + + public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 }; + + public static final byte[] DF_BELPIC = new byte[] { (byte) 0xDF, + (byte) 0x00 }; + + public static final byte[] DF_ID = new byte[] { (byte) 0xDF, (byte) 0x01 }; + + public static final byte[] SIGN_CERT = new byte[] { (byte) 0x50, + (byte) 0x39 }; + +// public static final byte MSE_SET_ALGO_REF = (byte) 0x02; + +// public static final byte MSE_SET_PRIV_KEY_REF = (byte) 0x83; + + public static final int SIGNATURE_LENGTH = (int) 0x80; + + public static final byte KID = (byte) 0x01; + + public static final int READ_BUFFER_LENGTH = 256; + + public static final int PINSPEC_SS = 0; + + private static final PINSpec SS_PIN_SPEC = + new PINSpec(4, 12, "[0-9]", + "at/gv/egiz/smcc/BelpicCard", "sig.pin", KID, DF_BELPIC); + + /** + * Creates a new instance. + */ + public BELPICCard() { + super("at/gv/egiz/smcc/BelpicCard"); + pinSpecs.add(SS_PIN_SPEC); + } + + @Override + @Exclusive + public byte[] getCertificate(KeyboxName keyboxName) + throws SignatureCardException { + + if (keyboxName != KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported"); + } + + try { + CardChannel channel = getCardChannel(); + // SELECT MF + execSELECT_FID(channel, MF); + // SELECT application + execSELECT_FID(channel, DF_BELPIC); + // SELECT file + execSELECT_FID(channel, SIGN_CERT); + // READ BINARY + byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, -1, (byte) 0x30); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (CardException e) { + log.info("Failed to get certificate.", e); + throw new SignatureCardException(e); + } + + } + + @Override + @Exclusive + public byte[] getInfobox(String infobox, PINProvider provider, String domainId) + throws SignatureCardException, InterruptedException { + + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); + } + + @Override + @Exclusive + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException { + + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) { + throw new SignatureCardException("Card does not support key " + keyboxName + "."); + } + if (!"http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) { + throw new SignatureCardException("Card does not support algorithm " + alg + "."); + } + + byte[] dst = new byte[] { (byte) 0x04, // number of following + // bytes + (byte) 0x80, // tag for algorithm reference + (byte) 0x02, // algorithm reference + (byte) 0x84, // tag for private key reference + (byte) 0x83 // private key reference + }; + + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get MessageDigest.", e); + throw new SignatureCardException(e); + } + // calculate message digest + byte[] digest = new byte[md.getDigestLength()]; + for (int l; (l = input.read(digest)) != -1;) { + md.update(digest, 0, l); + } + digest = md.digest(); + + try { + + CardChannel channel = getCardChannel(); + + // SELECT MF + execSELECT_FID(channel, MF); + // VERIFY + execMSE(channel, 0x41, 0xb6, dst); + // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE + verifyPINLoop(channel, SS_PIN_SPEC, provider); + // MANAGE SECURITY ENVIRONMENT : SET DST + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest); + + } catch (CardException e) { + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); + } + + } + + public String toString() { + return "Belpic Card"; + } + + protected void verifyPINLoop(CardChannel channel, PINSpec spec, + PINProvider provider) throws LockedException, NotActivatedException, + SignatureCardException, InterruptedException, CardException { + + int retries = -1; //verifyPIN(channel, spec, null, -1); + do { + retries = verifyPIN(channel, spec, provider, retries); + } while (retries > 0); + } + + protected int verifyPIN(CardChannel channel, PINSpec pinSpec, + PINProvider provider, int retries) throws SignatureCardException, + LockedException, NotActivatedException, InterruptedException, + CardException { + + VerifyAPDUSpec apduSpec = new VerifyAPDUSpec( + new byte[] { + (byte) 0x00, (byte) 0x20, (byte) 0x00, pinSpec.getKID(), (byte) 0x08, + (byte) 0x20, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff }, + 1, VerifyAPDUSpec.PIN_FORMAT_BCD, 7, 4, 4); + + ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries); + + if (resp.getSW() == 0x9000) { + return -1; + } + if (resp.getSW() >> 4 == 0x63c) { + return 0x0f & resp.getSW(); + } + + switch (resp.getSW()) { + case 0x6983: + // authentication method blocked + throw new LockedException(); + case 0x6984: + // reference data not usable + throw new NotActivatedException(); + case 0x6985: + // conditions of use not satisfied + throw new NotActivatedException(); + + default: + String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW()); + log.info(msg); + throw new SignatureCardException(msg); + } + + } + + protected byte[] execSELECT_FID(CardChannel channel, byte[] fid) + throws SignatureCardException, CardException { + + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0xA4, 0x02, 0x0C, fid, 256)); + + if (resp.getSW() == 0x6A82) { + String msg = "File or application not found FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.info(msg); + throw new FileNotFoundException(msg); + } else if (resp.getSW() != 0x9000) { + String msg = "Failed to select application FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.error(msg); + throw new SignatureCardException(msg); + } else { + return resp.getBytes(); + } + + } + + protected void execMSE(CardChannel channel, int p1, int p2, byte[] data) + throws CardException, SignatureCardException { + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0x22, p1, p2, data, 256)); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("MSE:SET failed: SW=" + + Integer.toHexString(resp.getSW())); + } + } + + protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel, byte[] hash) + throws CardException, SignatureCardException { + ResponseAPDU resp; + resp = channel.transmit( + new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, hash, 256)); + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } else if (resp.getSW() == 0x6983) { + throw new LockedException(); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException( + "PSO: COMPUTE DIGITAL SIGNATRE failed: SW=" + + Integer.toHexString(resp.getSW())); + } else { + return resp.getData(); + } + } + + + + +} \ No newline at end of file diff --git a/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java new file mode 100644 index 00000000..831a1f9b --- /dev/null +++ b/smcc/src/main/java/at/gv/egiz/smcc/ITCard.java @@ -0,0 +1,297 @@ +/* +* Copyright 2008 Federal Chancellery Austria and +* Graz University of Technology +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package at.gv.egiz.smcc; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.smartcardio.CardChannel; +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.smcc.util.ISO7816Utils; +import at.gv.egiz.smcc.util.SMCCHelper; + +public class ITCard extends AbstractSignatureCard { + + /** + * Logging facility. + */ + private static Log log = LogFactory.getLog(STARCOSCard.class); + + public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 }; + + public static final byte[] DF1 = new byte[] { (byte) 0x11, (byte) 0x00 }; + + public static final byte[] EF_C_Carta = new byte[] { (byte) 0x11, (byte) 0x01 }; + + private static final PINSpec SS_PIN_SPEC = + new PINSpec(5, 8, "[0-9]", + "at/gv/egiz/smcc/ITCard", "sig.pin", (byte) 0x10, + new byte[] { (byte) 0x11, (byte) 0x00 }); + + /** + * Creates a new instance. + */ + public ITCard() { + super("at/gv/egiz/smcc/ITCard"); + pinSpecs.add(SS_PIN_SPEC); + } + + @Override + @Exclusive + public byte[] getCertificate(KeyboxName keyboxName) + throws SignatureCardException, InterruptedException { + + if (keyboxName != KeyboxName.SECURE_SIGNATURE_KEYPAIR) { + throw new IllegalArgumentException("Keybox " + keyboxName + + " not supported"); + } + + try { + CardChannel channel = getCardChannel(); + // SELECT MF + execSELECT_FID(channel, MF); + // SELECT application + execSELECT_FID(channel, DF1); + // SELECT EF_C_Carta + byte[] fcx = execSELECT_FID(channel, EF_C_Carta); + int maxsize = ISO7816Utils.getLengthFromFCx(fcx); + // READ BINARY + byte[] certificate = ISO7816Utils.readTransparentFileTLV(channel, maxsize, (byte) 0x30); + if (certificate == null) { + throw new NotActivatedException(); + } + return certificate; + } catch (FileNotFoundException e) { + throw new NotActivatedException(); + } catch (CardException e) { + log.info("Failed to get certificate.", e); + throw new SignatureCardException(e); + } + + } + + @Override + @Exclusive + public byte[] getInfobox(String infobox, PINProvider provider, String domainId) + throws SignatureCardException, InterruptedException { + + throw new IllegalArgumentException("Infobox '" + infobox + + "' not supported."); + } + + @Override + @Exclusive + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, + InterruptedException, IOException { + + if (KeyboxName.SECURE_SIGNATURE_KEYPAIR != keyboxName) { + throw new SignatureCardException("Card does not support key " + keyboxName + "."); + } + if (!"http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(alg)) { + throw new SignatureCardException("Card does not support algorithm " + alg + "."); + } + + byte[] dst = new byte[] { + (byte) 0x83, // tag for algorithm reference + (byte) 0x01, // algorithm reference + (byte) 0x01 // private key reference + }; + + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get MessageDigest.", e); + throw new SignatureCardException(e); + } + // calculate message digest + byte[] digest = new byte[md.getDigestLength()]; + for (int l; (l = input.read(digest)) != -1;) { + md.update(digest, 0, l); + } + digest = md.digest(); + + try { + + CardChannel channel = getCardChannel(); + + // SELECT MF + execSELECT_FID(channel, MF); + // VERIFY + verifyPINLoop(channel, SS_PIN_SPEC, provider); + // MANAGE SECURITY ENVIRONMENT : RESTORE SE + execMSE(channel, 0xF3, 0x03, null); + // MANAGE SECURITY ENVIRONMENT : SET DST + execMSE(channel, 0xF1, 0xB8, dst); + // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest); + + } catch (CardException e) { + log.warn(e); + throw new SignatureCardException("Failed to access card.", e); + } + + } + + protected void verifyPINLoop(CardChannel channel, PINSpec spec, + PINProvider provider) throws LockedException, NotActivatedException, + SignatureCardException, InterruptedException, CardException { + + int retries = -1; + do { + retries = verifyPIN(channel, spec, provider, retries); + } while (retries >= -1); + } + + protected int verifyPIN(CardChannel channel, PINSpec pinSpec, + PINProvider provider, int retries) throws SignatureCardException, + LockedException, NotActivatedException, InterruptedException, + CardException { + + VerifyAPDUSpec apduSpec = new VerifyAPDUSpec( + new byte[] { + (byte) 0x00, (byte) 0x20, (byte) 0x00, pinSpec.getKID(), (byte) 0x08, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }, + 0, VerifyAPDUSpec.PIN_FORMAT_ASCII, 8); + + ResponseAPDU resp = reader.verify(channel, apduSpec, pinSpec, provider, retries); + + if (resp.getSW() == 0x9000) { + return -2; + } + if (resp.getSW() >> 4 == 0x63c) { + return 0x0f & resp.getSW(); + } + + switch (resp.getSW()) { + case 0x6300: + // incorrect PIN, number of retries not provided + return -1; + case 0x6983: + // authentication method blocked + throw new LockedException(); + case 0x6984: + // reference data not usable + throw new NotActivatedException(); + case 0x6985: + // conditions of use not satisfied + throw new NotActivatedException(); + + default: + String msg = "VERIFY failed. SW=" + Integer.toHexString(resp.getSW()); + log.info(msg); + throw new SignatureCardException(msg); + } + + } + + protected byte[] execSELECT_FID(CardChannel channel, byte[] fid) + throws SignatureCardException, CardException { + + ResponseAPDU resp = channel.transmit( + new CommandAPDU(0x00, 0xA4, 0x00, 0x00, fid, 256)); + + if (resp.getSW() == 0x6A82) { + String msg = "File or application not found FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.info(msg); + throw new FileNotFoundException(msg); + } else if (resp.getSW() != 0x9000) { + String msg = "Failed to select application FID=" + + SMCCHelper.toString(fid) + " SW=" + + Integer.toHexString(resp.getSW()) + "."; + log.error(msg); + throw new SignatureCardException(msg); + } else { + return resp.getBytes(); + } + + } + + protected void execMSE(CardChannel channel, int p1, int p2, byte[] data) + throws CardException, SignatureCardException { + + ResponseAPDU resp; + if (data == null) { + resp = channel.transmit(new CommandAPDU(0x00, 0x22, p1, p2)); + } else { + resp = channel.transmit(new CommandAPDU(0x00, 0x22, p1, p2, data)); + } + + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("MSE:SET failed: SW=" + + Integer.toHexString(resp.getSW())); + } + } + + protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel, + byte[] hash) throws CardException, SignatureCardException { + + byte[] oid = new byte[] { (byte) 0x30, (byte) 0x21, (byte) 0x30, + (byte) 0x09, (byte) 0x06, (byte) 0x05, (byte) 0x2b, + (byte) 0x0e, (byte) 0x03, (byte) 0x02, (byte) 0x1a, + (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x14 }; + + ByteArrayOutputStream data = new ByteArrayOutputStream(); + + try { + // header + data.write(new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x01 }); + // padding + for (int i = 0, len = 125 - hash.length - oid.length; i < len; i++) { + data.write((byte) 0xFF); + } + data.write((byte) 0x00); + // oid + data.write(oid); + // hash + data.write(hash); + } catch (IOException e) { + throw new SignatureCardException(e); + } + + ResponseAPDU resp = channel + .transmit(new CommandAPDU(0x00, 0x2A, 0x80, 0x86, data.toByteArray(), 0x81)); + + + if (resp.getSW() == 0x6982) { + throw new SecurityStatusNotSatisfiedException(); + } else if (resp.getSW() == 0x6983) { + throw new LockedException(); + } else if (resp.getSW() != 0x9000) { + throw new SignatureCardException( + "PSO: COMPUTE DIGITAL SIGNATRE failed: SW=" + + Integer.toHexString(resp.getSW())); + } else { + return resp.getData(); + } +} + +} diff --git a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java index a0c2391d..01de8a77 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/STARCOSCard.java @@ -19,11 +19,16 @@ package at.gv.egiz.smcc; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.List; +import javax.smartcardio.Card; import javax.smartcardio.CardChannel; import javax.smartcardio.CardException; +import javax.smartcardio.CardTerminal; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; @@ -41,6 +46,8 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu private static Log log = LogFactory.getLog(STARCOSCard.class); public static final byte[] MF = new byte[] { (byte) 0x3F, (byte) 0x00 }; + + public static final byte[] EF_VERSION = new byte[] { (byte) 0x00, (byte) 0x32 }; /** * Application ID SV-Personendaten. @@ -106,19 +113,6 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu public static final byte[] EF_C_X509_CA_CS_DS = new byte[] { (byte) 0xc6, (byte) 0x08 }; - public static final byte[] DST_SS = new byte[] { (byte) 0x84, (byte) 0x03, // tag - // , - // length - // ( - // key - // desc - // . - // ) - (byte) 0x80, (byte) 0x02, (byte) 0x00, // local, key ID, key version - (byte) 0x89, (byte) 0x03, // tag, length (algorithm ID) - (byte) 0x13, (byte) 0x35, (byte) 0x10 // ECDSA - }; - public static final byte KID_PIN_SS = (byte) 0x81; // Gewöhnliche Signatur (GS) @@ -133,19 +127,6 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu public static final byte[] EF_C_X509_CA_CS = new byte[] { (byte) 0x2f, (byte) 0x02 }; - public static final byte[] DST_GS = new byte[] { (byte) 0x84, (byte) 0x03, // tag - // , - // length - // ( - // key - // desc - // . - // ) - (byte) 0x80, (byte) 0x02, (byte) 0x00, // local, key ID, key version - (byte) 0x89, (byte) 0x03, // tag, length (algorithm ID) - (byte) 0x13, (byte) 0x35, (byte) 0x10 // ECDSA - }; - public static final byte KID_PIN_CARD = (byte) 0x01; private static final PINSpec CARD_PIN_SPEC = @@ -155,9 +136,11 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu private static final PINSpec SS_PIN_SPEC = new PINSpec(6, 12, "[0-9]", "at/gv/egiz/smcc/STARCOSCard", "sig.pin", KID_PIN_SS, AID_DF_SS); + + protected double version = 1.1; /** - * Creates an new instance. + * Creates a new instance. */ public STARCOSCard() { super("at/gv/egiz/smcc/STARCOSCard"); @@ -165,6 +148,35 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu pinSpecs.add(SS_PIN_SPEC); } + /* (non-Javadoc) + * @see at.gv.egiz.smcc.AbstractSignatureCard#init(javax.smartcardio.Card, javax.smartcardio.CardTerminal) + */ + @Override + public void init(Card card, CardTerminal cardTerminal) { + super.init(card, cardTerminal); + + // determine application version + CardChannel channel = getCardChannel(); + try { + // SELECT MF + execSELECT_MF(channel); + // SELECT EF_VERSION + execSELECT_FID(channel, EF_VERSION); + // READ BINARY + byte[] ver = ISO7816Utils.readRecord(channel, 1); + if (ver[0] == (byte) 0xa5 && ver[2] == (byte) 0x53) { + version = (0x0F & ver[4]) + (0xF0 & ver[5])/160.0 + (0x0F & ver[5])/100.0; + String generation = (version < 1.2) ? "<= G2" : "G3"; + log.info("e-card version=" + version + " (" + generation + ")"); + } + } catch (CardException e) { + log.warn(e); + } catch (SignatureCardException e) { + log.warn(e); + } + + } + @Override @Exclusive public byte[] getCertificate(KeyboxName keyboxName) @@ -281,19 +293,57 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu @Override @Exclusive - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException, InterruptedException { + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException { - if (hash.length != 20) { - throw new IllegalArgumentException("Hash value must be of length 20."); + ByteArrayOutputStream dst = new ByteArrayOutputStream(); + byte[] ht = null; + + MessageDigest md = null; + try { + if (version < 1.2 && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1".equals(alg)) { + // local key ID '02' version '00' + dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00}); + // algorithm ID ECDSA with SHA-1 + dst.write(new byte[] {(byte) 0x89, (byte) 0x03, (byte) 0x13, (byte) 0x35, (byte) 0x10}); + md = MessageDigest.getInstance("SHA-1"); + } else if (version >= 1.2 && "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256".equals(alg)) { + // local key ID '02' version '00' + dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x02, (byte) 0x00}); + // portable algorithm reference + dst.write(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x04}); + // hash template + ht = new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x40}; + md = MessageDigest.getInstance("SHA256"); + } else if (version >= 1.2 && "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256".equals(alg)) { + // local key ID '03' version '00' + dst.write(new byte[] {(byte) 0x84, (byte) 0x03, (byte) 0x80, (byte) 0x03, (byte) 0x00}); + // portable algorithm reference + dst.write(new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x02}); + // hash template + ht = new byte[] {(byte) 0x80, (byte) 0x01, (byte) 0x40}; + md = MessageDigest.getInstance("SHA256"); + } else { + throw new SignatureCardException("e-card versio " + version + " does not support signature algorithm " + alg + "."); + } + } catch (NoSuchAlgorithmException e) { + log.error("Failed to get MessageDigest.", e); + throw new SignatureCardException(e); } - + + // calculate message digest + byte[] digest = new byte[md.getDigestLength()]; + for (int l; (l = input.read(digest)) != -1;) { + md.update(digest, 0, l); + } + digest = md.digest(); + try { CardChannel channel = getCardChannel(); if (KeyboxName.SECURE_SIGNATURE_KEYPAIR.equals(keyboxName)) { - + PINSpec spec = SS_PIN_SPEC; // SELECT MF @@ -303,11 +353,21 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu // VERIFY verifyPINLoop(channel, spec, provider); // MANAGE SECURITY ENVIRONMENT : SET DST - execMSE(channel, 0x41, 0xb6, DST_SS); - // PERFORM SECURITY OPERATION : HASH - execPSO_HASH(channel, hash); - // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE - return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel); + execMSE(channel, 0x41, 0xb6, dst.toByteArray()); + if (ht != null) { + // PERFORM SECURITY OPERATION : SET HT + execMSE(channel, 0x41, 0xaa, ht); + } + if (version < 1.2) { + // PERFORM SECURITY OPERATION : HASH + execPSO_HASH(channel, digest); + // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, null); + } else { + // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, digest); + } + } else if (KeyboxName.CERITIFIED_KEYPAIR.equals(keyboxName)) { @@ -316,14 +376,17 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu // SELECT application execSELECT_AID(channel, AID_DF_GS); // MANAGE SECURITY ENVIRONMENT : SET DST - execMSE(channel, 0x41, 0xb6, DST_GS); + execMSE(channel, 0x41, 0xb6, dst.toByteArray()); + if (ht != null) { + // PERFORM SECURITY OPERATION : SET HT + execMSE(channel, 0x41, 0xaa, ht); + } // PERFORM SECURITY OPERATION : HASH - execPSO_HASH(channel, hash); - + execPSO_HASH(channel, digest); while (true) { try { // PERFORM SECURITY OPERATION : COMPUTE DIGITAL SIGNATURE - return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel); + return execPSO_COMPUTE_DIGITAL_SIGNATURE(channel, null); } catch (SecurityStatusNotSatisfiedException e) { verifyPINLoop(channel, spec, provider); } @@ -682,7 +745,7 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu ResponseAPDU resp = channel.transmit( new CommandAPDU(0x00, 0x22, p1, p2, data)); if (resp.getSW() != 0x9000) { - throw new SignatureCardException("MSE:SET DST failed: SW=" + throw new SignatureCardException("MSE:SET failed: SW=" + Integer.toHexString(resp.getSW())); } } @@ -701,10 +764,47 @@ public class STARCOSCard extends AbstractSignatureCard implements PINMgmtSignatu } } - protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel) + protected void execPSO_HASH(CardChannel channel, InputStream input) + throws SignatureCardException, CardException { + ResponseAPDU resp; + int blockSize = 64; + byte[] b = new byte[blockSize]; + try { + ByteArrayOutputStream data = new ByteArrayOutputStream(); + // initialize + data.write((byte) 0x90); + data.write((byte) 0x00); + resp = channel.transmit( + new CommandAPDU(0x10, 0x2A, 0x90, 0xA0, data.toByteArray())); + data.reset(); + for (int l; (l = input.read(b)) != -1;) { + data.write((byte) 0x80); + data.write(l); + data.write(b, 0, l); + resp = channel.transmit( + new CommandAPDU((l == blockSize) ? 0x10 : 0x00, 0x2A, 0x90, 0xA0, data.toByteArray())); + if (resp.getSW() != 0x9000) { + throw new SignatureCardException("PSO:HASH failed: SW=" + + Integer.toHexString(resp.getSW())); + } + data.reset(); + } + } catch (IOException e) { + throw new SignatureCardException(e); + } + + } + + protected byte[] execPSO_COMPUTE_DIGITAL_SIGNATURE(CardChannel channel, byte[] hash) throws CardException, SignatureCardException { - ResponseAPDU resp = channel.transmit( - new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256)); + ResponseAPDU resp; + if (hash != null) { + resp = channel.transmit( + new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, hash, 256)); + } else { + resp = channel.transmit( + new CommandAPDU(0x00, 0x2A, 0x9E, 0x9A, 256)); + } if (resp.getSW() == 0x6982) { throw new SecurityStatusNotSatisfiedException(); } else if (resp.getSW() == 0x6983) { diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java index 279362c0..670704d5 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SWCard.java @@ -20,6 +20,7 @@ import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.security.InvalidKeyException; @@ -308,7 +309,7 @@ public class SWCard implements SignatureCard { } @Override - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, PINProvider provider) throws SignatureCardException, InterruptedException { + public byte[] createSignature(InputStream input, KeyboxName keyboxName, PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException { // KeyStore password char[] password = getPassword(keyboxName); @@ -363,7 +364,10 @@ public class SWCard implements SignatureCard { try { Signature signature = Signature.getInstance(algorithm); signature.initSign(privateKey); - signature.update(hash); + int l; + for (byte[] b = new byte[20]; (l = input.read(b)) != -1;) { + signature.update(b, 0, l); + } return signature.sign(); } catch (NoSuchAlgorithmException e) { String msg = "Algorithm + '" + algorithm + "' not supported for signing."; diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java index 1a163783..3d56f97b 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCard.java @@ -18,6 +18,9 @@ package at.gv.egiz.smcc; import at.gv.egiz.smcc.ccid.CCID; + +import java.io.IOException; +import java.io.InputStream; import java.util.Locale; import javax.smartcardio.Card; @@ -101,15 +104,17 @@ public interface SignatureCard { /** * - * @param hash + * @param input * @param keyboxName * @param provider + * @param alg TODO * @return * @throws at.gv.egiz.smcc.SignatureCardException * @throws java.lang.InterruptedException if applet is destroyed while in pin dialog + * @throws IOException */ - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException, InterruptedException; + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException, InterruptedException, IOException; public CCID getReader(); diff --git a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java index 26844473..47053f98 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/SignatureCardFactory.java @@ -170,21 +170,21 @@ public class SignatureCardFactory { }, "at.gv.egiz.smcc.STARCOSCard")); -// // e-card G3 -// supportedCards.add(new SupportedCard( -// // ATR (3b:dd:96:ff:81:b1:fe:45:1f:03:80:31:b0:52:02:03:64:04:1b:b4:22:81:05:18) -// new byte[] { -// (byte) 0x3b, (byte) 0xdd, (byte) 0x96, (byte) 0xff, (byte) 0x81, (byte) 0xb1, (byte) 0xfe, (byte) 0x45, -// (byte) 0x1f, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 -// }, -// // mask ( -// new byte[] { -// (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, -// (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, -// (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 -// }, -// "at.gv.egiz.smcc.STARCOSCard")); + // e-card G3 + supportedCards.add(new SupportedCard( + // ATR (3b:dd:96:ff:81:b1:fe:45:1f:03:80:31:b0:52:02:03:64:04:1b:b4:22:81:05:18) + new byte[] { + (byte) 0x3b, (byte) 0xdd, (byte) 0x96, (byte) 0xff, (byte) 0x81, (byte) 0xb1, (byte) 0xfe, (byte) 0x45, + (byte) 0x1f, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + // mask ( + new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 + }, + "at.gv.egiz.smcc.STARCOSCard")); // a-sign premium supportedCards.add(new SupportedCard( @@ -202,6 +202,72 @@ public class SignatureCardFactory { }, "at.gv.egiz.smcc.ACOSCard")); + // BELPIC + supportedCards.add(new SupportedCard( + // ATR (3b:98:13:40:0A:A5:03:01:01:01:AD:13:11) + new byte[] { (byte) 0x3b, (byte) 0x98, (byte) 0x13, + (byte) 0x40, (byte) 0x0a, (byte) 0xa5, (byte) 0x03, + (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0xad, + (byte) 0x13, (byte) 0x11 }, + // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff) + new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff }, + "at.gv.egiz.smcc.BELPICCard")); + + // ITCards + supportedCards.add(new SupportedCard( + // ATR = + // [3b:ff:18:00:ff:81:31:fe:55:00:6b:02:09:02:00:01:11:01:43:4e:53:11:31:80:8e] + new byte[] { (byte) 0x3b, (byte) 0xff, (byte) 0x18, + (byte) 0x00, (byte) 0xff, (byte) 0x81, (byte) 0x31, + (byte) 0xfe, (byte) 0x55, (byte) 0x00, (byte) 0x6b, + (byte) 0x02, (byte) 0x09 /* + * , (byte) 0x02, (byte) 0x00, + * (byte) 0x01, (byte) 0x11, + * (byte) 0x01, (byte) 0x43, + * (byte) 0x4e, (byte) 0x53, + * (byte) 0x11, (byte) 0x31, + * (byte) 0x80, (byte) 0x8e + */ + }, + // mask (ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff) + new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff /* + * , (byte) 0xff, (byte) 0xff, + * (byte) 0xff, (byte) 0xff, + * (byte) 0xff, (byte) 0xff, + * (byte) 0xff, (byte) 0xff, + * (byte) 0xff, (byte) 0xff, + * (byte) 0xff, (byte) 0xff + */ + }, "at.gv.egiz.smcc.ITCard")); + supportedCards.add(new SupportedCard( + // ATR + // (3B:FF:18:00:FF:C1:0A:31:FE:55:00:6B:05:08:C8:05:01:01:01:43:4E:53:10:31:80:1C) + new byte[] { (byte) 0x3b, (byte) 0xff, (byte) 0x18, + (byte) 0x00, (byte) 0xFF, (byte) 0xC1, (byte) 0x0a, + (byte) 0x31, (byte) 0xfe, (byte) 0x55, (byte) 0x00, + (byte) 0x6B, (byte) 0x05, (byte) 0x08, (byte) 0xC8, + (byte) 0x05, (byte) 0x01, (byte) 0x01, (byte) 0x01, + (byte) 0x43, (byte) 0x4E, (byte) 0x53, (byte) 0x10, + (byte) 0x31, (byte) 0x80, (byte) 0x1C }, + // mask + // (ff:ff:ff:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00) + new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff }, + "at.gv.egiz.smcc.ITCard")); + + + } /** diff --git a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java index c5c7cbc9..fcd0b876 100644 --- a/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java +++ b/smcc/src/main/java/at/gv/egiz/smcc/util/ISO7816Utils.java @@ -103,6 +103,14 @@ public class ISO7816Utils { TransparentFileInputStream is = openTransparentFileInputStream(channel, maxSize); + + return readTransparentFileTLV(is, maxSize, expectedType); + + } + + public static byte[] readTransparentFileTLV(TransparentFileInputStream is, int maxSize, + byte expectedType) throws CardException, SignatureCardException { + try { @@ -170,7 +178,8 @@ public class ISO7816Utils { while (pos < (fcx[1] - 2)) { switch (fcx[pos]) { - case (byte) 0x80: { + case (byte) 0x80: + case (byte) 0x81: { len = 0xFF & fcx[pos + 2]; for (int i = 1; i < fcx[pos + 1]; i++) { len<<=8; diff --git a/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties b/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties new file mode 100644 index 00000000..71267394 --- /dev/null +++ b/smcc/src/main/resources/at/gv/egiz/smcc/BELPICCard.properties @@ -0,0 +1,3 @@ +#pin.name=PIN +sig.pin.name=PIN +sig.pin.length=4-12 \ No newline at end of file diff --git a/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties b/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties new file mode 100644 index 00000000..e0222a70 --- /dev/null +++ b/smcc/src/main/resources/at/gv/egiz/smcc/ITCard.properties @@ -0,0 +1,3 @@ +#pin.name=PIN +sig.pin.name=PIN +sig.pin.length=5-8 \ No newline at end of file diff --git a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java index 2a55357d..b3bd07ab 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/CardTest.java @@ -18,6 +18,8 @@ package at.gv.egiz.smcc; import static org.junit.Assert.*; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -178,13 +180,10 @@ public abstract class CardTest { @Test(expected = CancelledException.class) public void testSignSIGCancel() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -193,21 +192,19 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, pinProvider, + null); } @Test(expected = CancelledException.class) public void testSignDECCancel() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -216,21 +213,19 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } @Test(expected = InterruptedException.class) public void testSignSIGInterrrupted() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -239,21 +234,19 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = InterruptedException.class) public void testSignDECInterrrupted() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -262,21 +255,19 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } @Test(expected = CancelledException.class) public void testSignSIGConcurrent() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { final SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -294,21 +285,19 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = CancelledException.class) public void testSignDECConcurrent() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { final SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - PINProvider pinProvider = new PINProvider() { @Override public char[] providePIN(PINSpec spec, int retries) @@ -326,8 +315,9 @@ public abstract class CardTest { } }; - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } diff --git a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java index 90bb039e..56d1e4b2 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/acos/ACOSCardTest.java @@ -21,6 +21,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -125,7 +127,7 @@ public abstract class ACOSCardTest extends CardTest { @Test public void testSignSIG() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { char[] pin = "123456".toCharArray(); @@ -134,11 +136,9 @@ public abstract class ACOSCardTest extends CardTest { ACOSApplSIG appl = (ACOSApplSIG) card.getApplication(ACOSAppl.AID_SIG); appl.setPin(ACOSApplSIG.KID_PIN_SIG, pin); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - - byte[] signature = signatureCard.createSignature(hash, - KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin)); + byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), + KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null); assertNotNull(signature); @@ -147,7 +147,7 @@ public abstract class ACOSCardTest extends CardTest { @Test public void testSignDEC() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { char[] pin = "1234".toCharArray(); @@ -156,11 +156,9 @@ public abstract class ACOSCardTest extends CardTest { ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC); appl.setPin(ACOSApplDEC.KID_PIN_DEC, pin); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - - byte[] signature = signatureCard.createSignature(hash, - KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin)); + byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), + KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null); assertNotNull(signature); @@ -169,74 +167,66 @@ public abstract class ACOSCardTest extends CardTest { @Test(expected = LockedException.class) public void testSignSIGInvalidPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignDECInvalidPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignSIGBlockedPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); CardEmul card = (CardEmul) signatureCard.getCard(); ACOSApplSIG appl = (ACOSApplSIG) card.getApplication(ACOSAppl.AID_SIG); appl.setPin(ACOSApplSIG.KID_PIN_SIG, null); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignDECBlockedPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); CardEmul card = (CardEmul) signatureCard.getCard(); ACOSApplDEC appl = (ACOSApplDEC) card.getApplication(ACOSAppl.AID_DEC); appl.setPin(ACOSApplDEC.KID_PIN_DEC, null); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } diff --git a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java index 89e2ca65..b7dc9a0c 100644 --- a/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java +++ b/smcc/src/test/java/at/gv/egiz/smcc/starcos/STARCOSCardTest.java @@ -20,6 +20,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -147,7 +149,7 @@ public class STARCOSCardTest extends CardTest { @Test public void testSignSichereSignatur() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { char[] pin = "123456".toCharArray(); @@ -156,11 +158,9 @@ public class STARCOSCardTest extends CardTest { STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur); appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, pin); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - - byte[] signature = signatureCard.createSignature(hash, - KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin)); + byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), + KeyboxName.SECURE_SIGNATURE_KEYPAIR, new TestPINProvider(pin), null); assertNotNull(signature); @@ -169,7 +169,7 @@ public class STARCOSCardTest extends CardTest { @Test public void testSignGewoehnlicheSignatur() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { char[] pin = "1234".toCharArray(); @@ -178,11 +178,9 @@ public class STARCOSCardTest extends CardTest { STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel(); channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, pin); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - - byte[] signature = signatureCard.createSignature(hash, - KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin)); + byte[] signature = signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), + KeyboxName.CERITIFIED_KEYPAIR, new TestPINProvider(pin), null); assertNotNull(signature); @@ -191,75 +189,67 @@ public class STARCOSCardTest extends CardTest { @Test(expected = LockedException.class) public void testSignSichereSignaturInvalidPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignGewoehnlicheSignaturInvalidPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("1234".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignSichereSignaturBlockedPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); CardEmul card = (CardEmul) signatureCard.getCard(); STARCOSApplSichereSignatur appl = (STARCOSApplSichereSignatur) card.getApplication(STARCOSApplSichereSignatur.AID_SichereSignatur); appl.setPin(STARCOSApplSichereSignatur.KID_PIN_SS, null); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("000000".toCharArray()); assertTrue(pinProvider.getProvided() <= 0); - signatureCard.createSignature(hash, KeyboxName.SECURE_SIGNATURE_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.SECURE_SIGNATURE_KEYPAIR, + pinProvider, null); } @Test(expected = LockedException.class) public void testSignGewoehnlicheSignaturBlockedPin() throws SignatureCardException, InterruptedException, CardNotSupportedException, - NoSuchAlgorithmException, UnsupportedEncodingException { + NoSuchAlgorithmException, IOException { SignatureCard signatureCard = createSignatureCard(); CardEmul card = (CardEmul) signatureCard.getCard(); STARCOSCardChannelEmul channel = (STARCOSCardChannelEmul) card.getBasicChannel(); channel.setPin(STARCOSCardChannelEmul.KID_PIN_Glob, null); - MessageDigest md = MessageDigest.getInstance("SHA-1"); - byte[] hash = md.digest("MOCCA".getBytes("ASCII")); - TestPINProvider pinProvider = new TestPINProvider("0000".toCharArray()); - signatureCard.createSignature(hash, KeyboxName.CERITIFIED_KEYPAIR, - pinProvider); + signatureCard.createSignature(new ByteArrayInputStream("MOCCA" + .getBytes("ASCII")), KeyboxName.CERITIFIED_KEYPAIR, + pinProvider, null); } diff --git a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java index 560f1373..58d7b305 100644 --- a/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java +++ b/smccSTAL/src/main/java/at/gv/egiz/bku/smccstal/SignRequestHandler.java @@ -18,9 +18,8 @@ package at.gv.egiz.bku.smccstal; import at.gv.egiz.bku.gui.BKUGUIFacade; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; @@ -44,7 +43,6 @@ import at.gv.egiz.stal.SignRequest; import at.gv.egiz.stal.SignResponse; import at.gv.egiz.stal.signedinfo.ObjectFactory; import at.gv.egiz.stal.signedinfo.SignedInfoType; -import at.gv.egiz.stal.util.JCEAlgorithmNames; public class SignRequestHandler extends AbstractRequestHandler { @@ -77,18 +75,11 @@ public class SignRequestHandler extends AbstractRequestHandler { JAXBElement si = (JAXBElement) unmarshaller.unmarshal(is); String signatureMethod = si.getValue().getSignatureMethod().getAlgorithm(); log.debug("Found signature method: " + signatureMethod); - String jceName = JCEAlgorithmNames.getJCEHashName(signatureMethod); - if (jceName == null) { - log.error("Hash algorithm not supported:"); - return new ErrorResponse(4006); - } - MessageDigest md = MessageDigest.getInstance(jceName); - md.update(signReq.getSignedInfo()); KeyboxName kb = SignatureCard.KeyboxName.getKeyboxName(signReq.getKeyIdentifier()); - byte[] resp = card.createSignature(md.digest(), kb, + byte[] resp = card.createSignature(new ByteArrayInputStream(signReq.getSignedInfo()), kb, new PINProviderFactory(card.getReader(), gui) - .getSignaturePINProvider(secureViewer, si.getValue())); + .getSignaturePINProvider(secureViewer, si.getValue()), signatureMethod); if (resp == null) { return new ErrorResponse(6001); } @@ -127,9 +118,9 @@ public class SignRequestHandler extends AbstractRequestHandler { } catch (JAXBException e) { log.error("Cannot unmarshall signed info", e); return new ErrorResponse(1000); - } catch (NoSuchAlgorithmException e) { - log.error(e); - return new ErrorResponse(1000); + } catch (IOException e) { + log.error("Error while creating signature: " + e); + return new ErrorResponse(4000); } } else { log.fatal("Got unexpected STAL request: " + request); diff --git a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java index 36880e68..16d3efa9 100644 --- a/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java +++ b/smccSTAL/src/test/java/at/gv/egiz/smcc/AbstractSMCCSTALTest.java @@ -1,5 +1,6 @@ package at.gv.egiz.smcc; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -37,8 +38,8 @@ public class AbstractSMCCSTALTest extends AbstractSMCCSTAL implements signatureCard = new SignatureCard() { @Override - public byte[] createSignature(byte[] hash, KeyboxName keyboxName, - PINProvider provider) throws SignatureCardException { + public byte[] createSignature(InputStream input, KeyboxName keyboxName, + PINProvider provider, String alg) throws SignatureCardException { // TODO Auto-generated method stub return null; } diff --git a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java index 82cba624..6f694b91 100644 --- a/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java +++ b/utils/src/main/java/at/gv/egiz/xades/QualifyingPropertiesFactory.java @@ -104,14 +104,14 @@ public class QualifyingPropertiesFactory { } - public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate) throws QualifyingPropertiesException { + public DigestAlgAndValueType createDigestAlgAndValueType(X509Certificate certificate, DigestMethod dm) throws QualifyingPropertiesException { DigestMethodType digestMethodType = dsFactory.createDigestMethodType(); - digestMethodType.setAlgorithm(DigestMethod.SHA1); - + digestMethodType.setAlgorithm(dm.getAlgorithm()); + byte[] digest; try { - MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); + MessageDigest messageDigest = MessageDigest.getInstance(dm.getAlgorithm()); digest = messageDigest.digest(certificate.getEncoded()); } catch (CertificateEncodingException e) { throw new QualifyingPropertiesException(e); @@ -155,7 +155,10 @@ public class QualifyingPropertiesFactory { return dataObjectFormatType; } - public JAXBElement createQualifyingProperties111(String target, Date signingTime, List certificates, String idValue, List dataObjectFormats) throws QualifyingPropertiesException { + public JAXBElement createQualifyingProperties111( + String target, Date signingTime, List certificates, + String idValue, List dataObjectFormats, + DigestMethod digestMethod) throws QualifyingPropertiesException { GregorianCalendar gregorianCalendar = new GregorianCalendar(); gregorianCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); @@ -175,7 +178,7 @@ public class QualifyingPropertiesFactory { for (X509Certificate certificate : certificates) { CertIDType certIDType = qpFactory.createCertIDType(); - certIDType.setCertDigest(createDigestAlgAndValueType(certificate)); + certIDType.setCertDigest(createDigestAlgAndValueType(certificate, digestMethod)); certIDType.setIssuerSerial(createX509IssuerSerialType(certificate)); certIDs.add(certIDType); -- cgit v1.2.3 From 5af9b75dccc1b52d1382fe0f2df30affd509f5b9 Mon Sep 17 00:00:00 2001 From: clemenso Date: Tue, 24 Nov 2009 18:48:00 +0000 Subject: Filenames derived from reference URI git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@553 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4 --- .../egiz/bku/online/applet/AppletSecureViewer.java | 3 +- .../java/at/gv/egiz/bku/gui/HyperlinkRenderer.java | 10 ++- .../java/at/gv/egiz/bku/gui/viewer/MimeFilter.java | 56 +------------- .../java/at/gv/egiz/bku/gui/viewer/MimeTypes.java | 53 +++++++++++++ .../bku/gui/viewer/SecureViewerSaveDialog.java | 5 +- .../gv/egiz/stal/impl/ByteArrayHashDataInput.java | 9 ++- .../at/gv/egiz/bku/gui/Messages.properties | 3 +- .../at/gv/egiz/bku/gui/Messages_en.properties | 1 + .../test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java | 12 ++- .../at/gv/egiz/bku/gui/SecureViewerDialogTest.java | 6 +- BKUOnline/pom.xml | 2 +- .../gv/egiz/stal/service/impl/STALServiceImpl.java | 1 + BKUOnline/src/main/webapp/META-INF/context.xml | 2 +- BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd | 1 + BKUOnline/src/main/wsdl/stal-service.xsd | 1 + .../egiz/stal/service/STALRequestBrokerTest.java | 21 ++++++ .../main/java/at/gv/egiz/stal/HashDataInput.java | 2 + .../types/GetHashDataInputResponseType.java | 28 +++++++ .../gv/egiz/bku/binding/HTTPBindingProcessor.java | 1 + .../slcommands/impl/DataObjectHashDataInput.java | 6 ++ .../egiz/bku/slcommands/impl/xsect/DataObject.java | 88 ++++++++++++++++++++-- .../bku/slcommands/impl/xsect/SignatureTest.java | 50 +++++++++++- .../impl/DataObjectInfo_Detached_LocRefContent.xml | 13 ++++ .../impl/DataObjectInfo_LocRefContent_2.xml | 2 +- .../at/gv/egiz/slbinding/RedirectEventFilter.java | 3 - .../gv/egiz/slbinding/impl/TransformsInfoType.java | 8 ++ .../at/gv/egiz/slbinding/impl/XMLContentType.java | 9 +++ 27 files changed, 313 insertions(+), 83 deletions(-) create mode 100644 BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeTypes.java create mode 100644 bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_Detached_LocRefContent.xml (limited to 'utils/src/main/java/at/gv/egiz') diff --git a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java index 2e0cb331..c67699af 100644 --- a/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java +++ b/BKUApplet/src/main/java/at/gv/egiz/bku/online/applet/AppletSecureViewer.java @@ -180,6 +180,7 @@ public class AppletSecureViewer implements SecureViewer { byte[] hdi = hashDataInput.getValue(); String mimeType = hashDataInput.getMimeType(); String encoding = hashDataInput.getEncoding(); + String filename = hashDataInput.getFilename(); if (hdi == null) { throw new Exception("No hashdata input for reference " + signedRefId + " provided by service"); @@ -199,7 +200,7 @@ public class AppletSecureViewer implements SecureViewer { throw new DigestException("Bad digest value for reference " + signedRefId); } - verifiedHashDataInputs.add(new ByteArrayHashDataInput(hdi, signedRefId, mimeType, encoding)); + verifiedHashDataInputs.add(new ByteArrayHashDataInput(hdi, signedRefId, mimeType, encoding, filename)); } } diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java index 16024fcc..6af22815 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/HyperlinkRenderer.java @@ -39,10 +39,14 @@ public class HyperlinkRenderer extends DefaultTableCellRenderer { @Override protected void setValue(Object value) { String hrefText; - if (renderReferenceId) { - hrefText = ((HashDataInput) value).getReferenceId(); + if (((HashDataInput) value).getFilename() != null) { + hrefText = ((HashDataInput) value).getFilename(); } else { - hrefText = ((HashDataInput) value).getMimeType(); + if (renderReferenceId) { + hrefText = ((HashDataInput) value).getReferenceId(); + } else { + hrefText = ((HashDataInput) value).getMimeType(); + } } super.setText("" + hrefText + ""); setForeground(BKUGUIFacade.HYPERLINK_COLOR); diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java index c0385dce..5d64eb4f 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeFilter.java @@ -26,14 +26,6 @@ import javax.swing.filechooser.FileFilter; */ class MimeFilter extends FileFilter { - private static final String MIMETYPE_DESC_XML = "mimetype.desc.xml"; - private static final String MIMETYPE_DESC_HTML = "mimetype.desc.html"; - private static final String MIMETYPE_DESC_XHTML = "mimetype.desc.xhtml"; - private static final String MIMETYPE_DESC_TXT = "mimetype.desc.txt"; - private static final String MIMETYPE_DESC_PDF = "mimetype.desc.pdf"; - private static final String MIMETYPE_DESC_BIN = "mimetype.desc.bin"; - private static final String MIMETYPE_DESC_UNKNOWN = "mimetype.desc.unknown"; - protected String mimeType; protected ResourceBundle messages; @@ -48,21 +40,7 @@ class MimeFilter extends FileFilter { if (f.isDirectory()) { return true; } - - String ext = getExtension(f); - if ("text/xml".equals(mimeType)) { - return "xml".equalsIgnoreCase(ext); - } else if ("text/html".equals(mimeType)) { - return "html".equalsIgnoreCase(ext) || "htm".equalsIgnoreCase(ext); - } else if ("application/xhtml+xml".equals(mimeType)) { - return "xhtml".equalsIgnoreCase(ext); - } else if ("text/plain".equals(mimeType)) { - return "txt".equalsIgnoreCase(ext); - } else if ("application/pdf".equals(mimeType)) { - return "pdf".equalsIgnoreCase(ext); - } else { - return true; - } + return MimeTypes.getExtension(mimeType).equalsIgnoreCase(getExtension(f)); } private String getExtension(File f) { @@ -78,38 +56,10 @@ class MimeFilter extends FileFilter { @Override public String getDescription() { - if ("text/xml".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_XML); - } else if ("text/html".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_HTML); - } else if ("application/xhtml+xml".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_XHTML); - } else if ("text/plain".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_TXT); - } else if ("application/pdf".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_PDF); - } else if ("application/octet-stream".equals(mimeType)) { - return messages.getString(MIMETYPE_DESC_BIN); - } else { - return messages.getString(MIMETYPE_DESC_UNKNOWN); - } + return messages.getString(MimeTypes.getDescriptionKey(mimeType)); } public static String getExtension(String mimeType) { - if ("text/xml".equals(mimeType)) { - return ".xml"; - } else if ("text/html".equals(mimeType)) { - return ".html"; - } else if ("application/xhtml+xml".equals(mimeType)) { - return ".xhtml"; - } else if ("text/plain".equals(mimeType)) { - return ".txt"; - } else if ("application/pdf".equals(mimeType)) { - return ".pdf"; - } else if ("application/octet-stream".equals(mimeType)) { - return ".bin"; - } else { - return ""; - } + return MimeTypes.getExtension(mimeType); } } \ No newline at end of file diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeTypes.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeTypes.java new file mode 100644 index 00000000..4500fa71 --- /dev/null +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/MimeTypes.java @@ -0,0 +1,53 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package at.gv.egiz.bku.gui.viewer; + +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author clemens + */ +public class MimeTypes { + + private static final Map FILE_EXTENSIONS = new HashMap() {{ + put("application/msword", ".doc"); + put("application/octet-stream", ".bin"); + put("application/pdf", ".pdf"); + put("application/xhtml+xml", ".xhtml"); + put("text/html", ".html"); + put("text/plain", ".txt"); + put("text/xml", ".xml"); + }}; + + private static final Map DESCRIPTIONS = new HashMap() {{ + put("application/msword", "mimetype.desc.doc"); + put("application/octet-stream", "mimetype.desc.bin"); + put("application/pdf", "mimetype.desc.pdf"); + put("application/xhtml+xml", "mimetype.desc.xhtml"); + put("text/html", "mimetype.desc.html"); + put("text/plain", "mimetype.desc.txt"); + put("text/xml", "mimetype.desc.xml"); + }}; + + public static String getExtension(String mimetype) { + if (FILE_EXTENSIONS.containsKey(mimetype)) { + return FILE_EXTENSIONS.get(mimetype); + } + return ""; + } + + /** + * @return bundle key to be resolved in message resource bundle + */ + public static String getDescriptionKey(String mimetype) { + if (DESCRIPTIONS.containsKey(mimetype)) { + return DESCRIPTIONS.get(mimetype); + } + return "mimetype.desc.unknown"; + } +} diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java index 40133f95..3303d4ef 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/bku/gui/viewer/SecureViewerSaveDialog.java @@ -52,8 +52,9 @@ public class SecureViewerSaveDialog { String mimeType = hashDataInput.getMimeType(); MimeFilter mimeFilter = new MimeFilter(mimeType, messages); fileDialog.setFileFilter(mimeFilter); - String filename = messages - .getString(BKUGUIFacade.SAVE_HASHDATAINPUT_PREFIX) + String filename = (hashDataInput.getFilename() != null) ? + hashDataInput.getFilename() : + messages.getString(BKUGUIFacade.SAVE_HASHDATAINPUT_PREFIX) + MimeFilter.getExtension(mimeType); fileDialog.setSelectedFile(new File(userHome, filename)); diff --git a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java index 6ca9a0b2..b9416845 100644 --- a/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java +++ b/BKUCommonGUI/src/main/java/at/gv/egiz/stal/impl/ByteArrayHashDataInput.java @@ -36,8 +36,9 @@ public class ByteArrayHashDataInput implements HashDataInput { protected String id; protected String mimeType; protected String encoding; + protected String filename; - public ByteArrayHashDataInput(byte[] hashData, String id, String mimeType, String encoding) { + public ByteArrayHashDataInput(byte[] hashData, String id, String mimeType, String encoding, String filename) { if (hashData == null) { throw new NullPointerException("HashDataInput not provided."); } @@ -45,6 +46,7 @@ public class ByteArrayHashDataInput implements HashDataInput { this.id = id; this.mimeType = mimeType; this.encoding = encoding; + this.filename = filename; } /** @@ -96,5 +98,10 @@ public class ByteArrayHashDataInput implements HashDataInput { return encoding; } + @Override + public String getFilename() { + return filename; + } + } diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties index 7135b561..3e483fc8 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages.properties @@ -48,7 +48,7 @@ hashdatalink.tiny.focus=[Signaturdaten] #verwenden sie bitte die von ihrem System zur Verf\u00FCgung gestellte {0} Anwendung. hashdatalist={0} Signaturdaten: hashdata.viewer=Signaturdaten werden im Betrachter angezeigt -unsupported.mimetype=Signaturdaten können nicht angezeigt werden +unsupported.mimetype=Signaturdaten k\u00F6nnen nicht angezeigt werden retries.last=Letzter Versuch! retries=Noch {0} Versuche retries.pinpad.last=Eingabe wiederholen, letzter Versuch! @@ -71,6 +71,7 @@ mimetype.desc.xhtml=XHTML-Dateien (.xhtml) mimetype.desc.txt=Textdateien (.txt) mimetype.desc.pdf=Adobe PDF-Dateien (.pdf) mimetype.desc.bin=Bin\u00E4rdateien (.bin) +mimetype.desc.doc=Microsoft Word-Dateien (.doc) mimetype.desc.unknown=Alle Dateien (.*) save.hashdatainput.prefix=Signaturdaten alt.help=Hilfe diff --git a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties index 6e89510e..c553bcb5 100644 --- a/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties +++ b/BKUCommonGUI/src/main/resources/at/gv/egiz/bku/gui/Messages_en.properties @@ -69,6 +69,7 @@ mimetype.desc.xhtml=XHTML-files (.xhtml) mimetype.desc.txt=Textfiles (.txt) mimetype.desc.pdf=Adobe PDF-files (.pdf) mimetype.desc.bin=Binary files (.bin) +mimetype.desc.doc=Microsoft Word-files (.doc) mimetype.desc.unknown=All files (.*) save.hashdatainput.prefix=signaturedata alt.help=help diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java index 20654141..6e345ee3 100644 --- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java +++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/BKUGUIWorker.java @@ -85,25 +85,29 @@ public class BKUGUIWorker implements Runnable { "Ich bin ein einfacher Text mit Umlauten: öäüßéç@€\n123\n456\n\tHello, world!\n\nlkjsd\nnksdjf".getBytes(), "ref-id-0000000000000000000000001", "text/plain", - "UTF-8"); + "UTF-8", + "file.txt"); HashDataInput signedRef2 = new ByteArrayHashDataInput( "HashDataInput_002".getBytes(), "ref-id-000000002", "application/xhtml+xml", - "UTF-8"); + "UTF-8", + "file.xhtml"); HashDataInput signedRef3 = new ByteArrayHashDataInput( "HashDataInput_003".getBytes(), "ref-id-000000003", "application/xhtml+xml", - "UTF-8"); + "UTF-8", + "file2.xhtml"); HashDataInput signedRef4 = new ByteArrayHashDataInput( "HashDataInput_004".getBytes(), "ref-id-000000004", "text/xml", - "UTF-8"); + "UTF-8", + "file.xml"); // List signedRefs = new ArrayList(); diff --git a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java index 131a344f..9bbc1b1a 100644 --- a/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java +++ b/BKUCommonGUI/src/test/java/at/gv/egiz/bku/gui/SecureViewerDialogTest.java @@ -66,7 +66,7 @@ public class SecureViewerDialogTest { String s = new String(bytes, "iso-8859-1"); System.out.println("read iso-8859-1 bytes " + s); - secureViewer.setContent(new ByteArrayHashDataInput(s.getBytes("UTF-8"), "id-1", "text/plain", "iso-8859-1")); + secureViewer.setContent(new ByteArrayHashDataInput(s.getBytes("UTF-8"), "id-1", "text/plain", "iso-8859-1", "file.txt")); } @@ -87,7 +87,7 @@ public class SecureViewerDialogTest { } System.out.println(data.toString()); - secureViewer.setContent(new ByteArrayHashDataInput(data.toString().getBytes("UTF-8"), "id-1", "text/plain", "UTF-8")); + secureViewer.setContent(new ByteArrayHashDataInput(data.toString().getBytes("UTF-8"), "id-1", "text/plain", "UTF-8", "file.txt")); } @@ -146,7 +146,7 @@ public class SecureViewerDialogTest { // byte[] bytes2 = data.getBytes("cp1252"); // System.out.println(data + "\t" + SMCCHelper.toString(bytes2)); - secureViewer.setContent(new ByteArrayHashDataInput(data.toString().getBytes("UTF-8"), "id-1", "text/plain", "UTF-8")); + secureViewer.setContent(new ByteArrayHashDataInput(data.toString().getBytes("UTF-8"), "id-1", "text/plain", "UTF-8", "file.txt")); System.out.println("\n\n=============================\n"); // diff --git a/BKUOnline/pom.xml b/BKUOnline/pom.xml index ed7f228c..c7c40982 100644 --- a/BKUOnline/pom.xml +++ b/BKUOnline/pom.xml @@ -263,7 +263,7 @@ staltypes-custom.xml cardchannel-custom.xml - ${basedir}/src/main/webapp/WEB-INF/wsdl + ${basedir}/src/main/wsdl stal-service.wsdl diff --git a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java index eab9bed5..c8ab280f 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java +++ b/BKUOnline/src/main/java/at/gv/egiz/stal/service/impl/STALServiceImpl.java @@ -267,6 +267,7 @@ public class STALServiceImpl implements STALPortType { ref.setID(reqRefId); ref.setMimeType(reqHdi.getMimeType()); ref.setEncoding(reqHdi.getEncoding()); + ref.setFilename(reqHdi.getFilename()); ref.setValue(baos.toByteArray()); response.getReference().add(ref); } catch (IOException ex) { diff --git a/BKUOnline/src/main/webapp/META-INF/context.xml b/BKUOnline/src/main/webapp/META-INF/context.xml index f38215a1..2a2da79e 100644 --- a/BKUOnline/src/main/webapp/META-INF/context.xml +++ b/BKUOnline/src/main/webapp/META-INF/context.xml @@ -16,4 +16,4 @@ limitations under the License. --> - + diff --git a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd index 2389e043..a420035f 100644 --- a/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd +++ b/BKUOnline/src/main/webapp/WEB-INF/wsdl/stal.xsd @@ -151,6 +151,7 @@ + diff --git a/BKUOnline/src/main/wsdl/stal-service.xsd b/BKUOnline/src/main/wsdl/stal-service.xsd index 870e2db6..177b9e7f 100644 --- a/BKUOnline/src/main/wsdl/stal-service.xsd +++ b/BKUOnline/src/main/wsdl/stal-service.xsd @@ -166,6 +166,7 @@ + diff --git a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java index a1f3864e..741974eb 100644 --- a/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java +++ b/BKUOnline/src/test/java/at/gv/egiz/stal/service/STALRequestBrokerTest.java @@ -126,6 +126,12 @@ public class STALRequestBrokerTest { public String getEncoding() { return "UTF-8"; } + + + @Override + public String getFilename() { + return "file.txt"; + } }; r1.setHashDataInput(Collections.singletonList(hdi)); requests.add(r1); @@ -172,6 +178,11 @@ public class STALRequestBrokerTest { public String getEncoding() { return "UTF-8"; } + + @Override + public String getFilename() { + return "file.txt"; + } }; r1.setHashDataInput(Collections.singletonList(hdi)); requests.add(r1); @@ -231,6 +242,11 @@ public class STALRequestBrokerTest { public String getEncoding() { return "UTF-8"; } + + @Override + public String getFilename() { + return "file.txt"; + } }; r1.setHashDataInput(Collections.singletonList(hdi)); requests.add(r1); @@ -259,6 +275,11 @@ public class STALRequestBrokerTest { public String getEncoding() { return "UTF-8"; } + + @Override + public String getFilename() { + return "file.xml"; + } }; r2.setHashDataInput(Collections.singletonList(hdi2)); requests2.add(r2); diff --git a/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java b/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java index 62c25fc4..7092470c 100644 --- a/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java +++ b/STAL/src/main/java/at/gv/egiz/stal/HashDataInput.java @@ -31,6 +31,8 @@ public interface HashDataInput { public String getEncoding(); + public String getFilename(); + public InputStream getHashDataInput(); } diff --git a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputResponseType.java b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputResponseType.java index 7536d936..ad029757 100644 --- a/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputResponseType.java +++ b/STALService/src/main/java/at/gv/egiz/stal/service/types/GetHashDataInputResponseType.java @@ -28,6 +28,7 @@ import javax.xml.bind.annotation.XmlValue; * <attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="MimeType" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="Encoding" type="{http://www.w3.org/2001/XMLSchema}string" /> + * <attribute name="Filename" type="{http://www.w3.org/2001/XMLSchema}string" /> * </extension> * </simpleContent> * </complexType> @@ -118,6 +119,7 @@ public class GetHashDataInputResponseType { * <attribute name="ID" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="MimeType" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="Encoding" type="{http://www.w3.org/2001/XMLSchema}string" /> + * <attribute name="Filename" type="{http://www.w3.org/2001/XMLSchema}string" /> * </extension> * </simpleContent> * </complexType> @@ -139,6 +141,8 @@ public class GetHashDataInputResponseType { protected String mimeType; @XmlAttribute(name = "Encoding") protected String encoding; + @XmlAttribute(name = "Filename") + protected String filename; /** * Gets the value of the value property. @@ -234,6 +238,30 @@ public class GetHashDataInputResponseType { this.encoding = value; } + /** + * Gets the value of the filename property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFilename() { + return filename; + } + + /** + * Sets the value of the filename property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFilename(String value) { + this.filename = value; + } + } } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java index b1906666..e39addb5 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/HTTPBindingProcessor.java @@ -339,6 +339,7 @@ public class HTTPBindingProcessor extends AbstractBindingProcessor implements // process headers and request setHTTPHeaders(dataUrlResponse.getResponseHeaders()); consumeRequestStream(dataUrlResponse.getStream()); + //TODO check for bindingProcessorError closeDataUrlConnection(); srcContex.setSourceCertificate(conn.getServerCertificate()); srcContex.setSourceIsDataURL(true); diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java index 1a9b56fb..57358ba0 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/DataObjectHashDataInput.java @@ -50,4 +50,10 @@ public class DataObjectHashDataInput implements HashDataInput { return HttpUtil.getCharset(dataObject.getMimeType(), false); } + @Override + public String getFilename() { + //TODO obtain filename from dataObject, if not set return null or get filename (extension!) from mimetype + return dataObject.getFilename(); + } + } diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java index 89124d16..6e84081e 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/xsect/DataObject.java @@ -49,8 +49,6 @@ import javax.xml.crypto.dsig.spec.XPathType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.w3._2000._09.xmldsig_.TransformType; -import org.w3._2000._09.xmldsig_.TransformsType; import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMException; import org.w3c.dom.Document; @@ -71,6 +69,7 @@ import at.buergerkarte.namespaces.securitylayer._1.DataObjectInfoType; import at.buergerkarte.namespaces.securitylayer._1.MetaInfoType; import at.buergerkarte.namespaces.securitylayer._1.TransformsInfoType; import at.gv.egiz.bku.binding.HttpUtil; +import at.gv.egiz.bku.gui.viewer.MimeTypes; import at.gv.egiz.bku.slexceptions.SLCommandException; import at.gv.egiz.bku.slexceptions.SLRequestException; import at.gv.egiz.bku.slexceptions.SLRuntimeException; @@ -81,11 +80,11 @@ import at.gv.egiz.bku.viewer.ValidationException; import at.gv.egiz.bku.viewer.Validator; import at.gv.egiz.bku.viewer.ValidatorFactory; import at.gv.egiz.dom.DOMUtils; -import at.gv.egiz.marshal.NamespacePrefixMapperImpl; import at.gv.egiz.slbinding.impl.XMLContentType; -import javax.xml.namespace.NamespaceContext; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; /** * This class represents a DataObject of an XML-Signature @@ -184,7 +183,9 @@ public class DataObject { * An optional description of the digest input. */ private String description; - + + private String filename; + /** * Creates a new instance. * @@ -230,6 +231,10 @@ public class DataObject { return mimeType; } + public String getFilename() { + return filename; + } + /** * @return the description */ @@ -336,7 +341,74 @@ public class DataObject { } // other values are not allowed by the schema and are therefore ignored - + + this.filename = deriveFilename(); + } + + /** + * Extract filename from reference URI + * or propose reference Id with an apropriate (mime-type) file extension + * + * @return if neither reference nor id can be extracted return null (or data.extension?) + */ + private String deriveFilename() { + + String filename = null; + + if (reference != null) { + if (reference.getURI() != null && !"".equals(reference.getURI())) { + try { + log.info("deriving filename from reference URI " + reference.getURI()); + URI refURI = new URI(reference.getURI()); + + if (refURI.isOpaque()) { + // could check scheme component, but also allow other schemes (e.g. testlocal) + log.trace("opaque reference URI, use scheme-specific part as filename"); + filename = refURI.getSchemeSpecificPart(); + if (!hasExtension(filename)) { + filename += MimeTypes.getExtension(mimeType); + } + // else hierarchical URI: + // for shorthand xpointer use fragment as filename, + // for any other xpointer use reference Id and + // for any other hierarchical (absolute or relative) use filename (ignore fragment, see xmldsig section 4.3.3.2: fragments not recommendet) + } else if ("".equals(refURI.getPath()) && + refURI.getFragment() != null && + refURI.getFragment().indexOf('(') < 0) { // exclude (schemebased) xpointer expressions + log.trace("fragment (shorthand xpointer) URI, use fragment as filename"); + filename = refURI.getFragment(); + if(!hasExtension(filename)) { + filename += MimeTypes.getExtension(mimeType); + } + } else if (!"".equals(refURI.getPath())) { + log.trace("hierarchical URI with path component, use path as filename"); + File refFile = new File(refURI.getPath()); + filename = refFile.getName(); + if(!hasExtension(filename)) { + filename += MimeTypes.getExtension(mimeType); + } + } else { + log.info("failed to derive filename from URI '" + refURI + "', derive filename from reference ID"); + filename = reference.getId() + MimeTypes.getExtension(mimeType); + } + } catch (URISyntaxException ex) { + log.error("failed to derive filename from invalid URI " + ex.getMessage()); + filename = reference.getId() + MimeTypes.getExtension(mimeType); + } + } else { + log.info("same-document URI, derive filename from reference ID"); + filename = reference.getId() + MimeTypes.getExtension(mimeType); + } + } else { + log.error("failed to derive filename, no reference created"); + } + log.debug("derived filename for reference " + reference.getId() + ": " + filename); + return filename; + } + + private static boolean hasExtension(String filename) { + int extDelimiterInd = filename.lastIndexOf('.'); + return extDelimiterInd >= 0 && extDelimiterInd >= filename.length() - 4; } private byte[] getTransformsBytes(at.gv.egiz.slbinding.impl.TransformsInfoType ti) { diff --git a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java index 7ce7b42d..ccd29e85 100644 --- a/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java +++ b/bkucommon/src/test/java/at/gv/egiz/bku/slcommands/impl/xsect/SignatureTest.java @@ -443,8 +443,11 @@ public class SignatureTest { @SuppressWarnings("unchecked") @Test + public void testDataObject_XMLContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_XMLContent_1 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_1.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -485,6 +488,8 @@ public class SignatureTest { @Test public void testDataObject_XMLContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_XMLContent_2 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_XMLContent_2.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -526,6 +531,8 @@ public class SignatureTest { @Test public void testDataObject_LocRefContent_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_LocRefContent_1 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_1.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -535,7 +542,7 @@ public class SignatureTest { } signature.buildXMLSignature(); - + signAndMarshalSignature(signature); List references = signature.getReferences(); @@ -564,6 +571,8 @@ public class SignatureTest { @Test public void testDataObject_LocRefContent_2() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_LocRefContent_2 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_LocRefContent_2.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -602,6 +611,8 @@ public class SignatureTest { @Test public void testDataObject_Reference_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_Reference_1 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Reference_1.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -640,6 +651,8 @@ public class SignatureTest { @Test public void testDataObject_Detached_1() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_Detached_1 \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_1.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -671,6 +684,8 @@ public class SignatureTest { @Test public void testDataObject_Detached_Base64Content() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + System.out.println("\n ****************** testDataObject_Detached_Base64Content \n"); + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_Base64Content.xml"); Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); @@ -698,6 +713,39 @@ public class SignatureTest { } + @SuppressWarnings("unchecked") + @Test + public void testDataObject_Detached_LocRefContent() throws JAXBException, SLCommandException, XMLStreamException, SLRequestException, MarshalException, XMLSignatureException, SLViewerException { + + System.out.println("\n ****************** testDataObject_Detached_LocRefContent \n"); + + List dataObjectInfos = unmarshalDataObjectInfo("DataObjectInfo_Detached_LocRefContent.xml"); + + Signature signature = new Signature(null, new IdValueFactoryImpl(), new AlgorithmMethodFactoryImpl()); + + for (DataObjectInfoType dataObjectInfo : dataObjectInfos) { + signature.addDataObject(dataObjectInfo); + } + + signature.buildXMLSignature(); + + signAndMarshalSignature(signature); + + List references = signature.getReferences(); + assertTrue(references.size() == 2); + + Reference reference = references.get(0); + assertNotNull(reference.getId()); + + List transforms = reference.getTransforms(); + assertTrue(transforms.size() == 0); + + List objects = signature.getXMLObjects(); + assertNotNull(objects); + assertTrue(objects.size() == 1); + + } + // // // TransformsInfo diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_Detached_LocRefContent.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_Detached_LocRefContent.xml new file mode 100644 index 00000000..75f45ff0 --- /dev/null +++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_Detached_LocRefContent.xml @@ -0,0 +1,13 @@ + + + + + testlocal:DataObject1.bin + + + + application/octet-stream + + + + \ No newline at end of file diff --git a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_LocRefContent_2.xml b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_LocRefContent_2.xml index 852c115f..a94f51b6 100644 --- a/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_LocRefContent_2.xml +++ b/bkucommon/src/test/resources/at/gv/egiz/bku/slcommands/impl/DataObjectInfo_LocRefContent_2.xml @@ -6,7 +6,7 @@ - application/octetstream + application/octet-stream diff --git a/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java index 14c5ba48..5fe84aae 100644 --- a/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java +++ b/utils/src/main/java/at/gv/egiz/slbinding/RedirectEventFilter.java @@ -153,9 +153,6 @@ public class RedirectEventFilter implements EventFilter { private void redirectEvent(XMLEvent event) { try { - if (log.isTraceEnabled()) { - log.trace("redirecting StAX event " + event); - } redirectWriter.add(event); } catch (XMLStreamException ex) { ex.printStackTrace(); diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java index 1180e9fa..b1de9406 100644 --- a/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java +++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/TransformsInfoType.java @@ -22,6 +22,7 @@ package at.gv.egiz.slbinding.impl; import at.gv.egiz.slbinding.*; import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlTransient; @@ -62,6 +63,13 @@ public class TransformsInfoType extends at.buergerkarte.namespaces.securitylayer log.debug("disabling event redirection for TransformsInfoType"); filter.flushRedirectStream(); filter.setRedirectStream(null); + if (log.isDebugEnabled()) { + try { + log.debug("redirected events (UTF-8): " + redirectOS.toString("UTF-8")); + } catch (UnsupportedEncodingException ex) { + log.debug("failed to log redirected events", ex); + } + } } @Override diff --git a/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java index eb147f88..fd52e378 100644 --- a/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java +++ b/utils/src/main/java/at/gv/egiz/slbinding/impl/XMLContentType.java @@ -23,6 +23,8 @@ package at.gv.egiz.slbinding.impl; import at.gv.egiz.slbinding.RedirectCallback; import at.gv.egiz.slbinding.RedirectEventFilter; import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; + import javax.xml.bind.annotation.XmlTransient; import javax.xml.stream.XMLStreamException; import org.apache.commons.logging.Log; @@ -51,6 +53,13 @@ public class XMLContentType extends at.buergerkarte.namespaces.securitylayer._1. log.debug("disabling event redirection for XMLContentType"); filter.flushRedirectStream(); filter.setRedirectStream(null); + if (log.isDebugEnabled()) { + try { + log.debug("redirected events (UTF-8): " + redirectOS.toString("UTF-8")); + } catch (UnsupportedEncodingException ex) { + log.debug("failed to log redirected events", ex); + } + } } @Override -- cgit v1.2.3