diff options
| author | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2008-12-04 10:00:31 +0000 | 
|---|---|---|
| committer | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2008-12-04 10:00:31 +0000 | 
| commit | 3aadcf8f877a560bed75af7e0db918aa26ef2a03 (patch) | |
| tree | 66e382b6f87b0034046e4fb906497ed6aed74198 /bkucommon/src/main/java | |
| parent | 99134c1be5db0fedadc051922e70c9bf563ce16d (diff) | |
| download | mocca-3aadcf8f877a560bed75af7e0db918aa26ef2a03.tar.gz mocca-3aadcf8f877a560bed75af7e0db918aa26ef2a03.tar.bz2 mocca-3aadcf8f877a560bed75af7e0db918aa26ef2a03.zip | |
Refactoring of infobox implementation. 
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@232 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'bkucommon/src/main/java')
22 files changed, 1864 insertions, 681 deletions
| 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 d462ac60..531772cf 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 @@ -65,5 +65,6 @@ public class DataUrl {    public static void setConfiguration(Properties props) {      configuration = props; +    defaultDataUrlConnection.setConfiguration(configuration);    }
  }
\ No newline at end of file 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 new file mode 100644 index 00000000..5339d689 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/binding/LegacyDataUrlConnectionImpl.java @@ -0,0 +1,230 @@ +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.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.HttpsURLConnection; +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(DataUrlConnectionImpl.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<String, String> requestHttpHeaders; +  protected Map<String, String> formParams; +  protected String boundary; +  protected Properties config = null; + +  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(); +    connection.setDoOutput(true); +    Set<String> headers = requestHttpHeaders.keySet(); +    Iterator<String> 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<String> 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<String, String> responseHttpHeaders = new HashMap<String, String>(); +    Map<String, List<String>> httpHeaders = connection.getHeaderFields(); +    for (Iterator<String> 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<String, String>(); +    if ((config != null) +        && (config.getProperty(USER_AGENT_PROPERTY_KEY) != null)) { +      requestHttpHeaders.put(HttpUtil.HTTP_HEADER_USER_AGENT, config +          .getProperty(USER_AGENT_PROPERTY_KEY)); +    } else { +      requestHttpHeaders +          .put(HttpUtil.HTTP_HEADER_USER_AGENT, DEFAULT_USERAGENT); + +    } +    requestHttpHeaders.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, +        HttpUtil.APPLICATION_URL_ENCODED); +     +    formParams = new HashMap<String, String>(); +  } + +  @Override +  public DataUrlConnectionSPI newInstance() { +    DataUrlConnectionSPI uc = new LegacyDataUrlConnectionImpl(); +    uc.setConfiguration(config); +    return uc; +  } + +  @Override +  public URL getUrl() { +    return url; +  } + +  @Override +  public void setConfiguration(Properties config) { +    this.config = config; +  } +}
\ No newline at end of file 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 9ed99190..6078de36 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 @@ -187,28 +187,29 @@ public abstract class Configurator {    }
    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);
 +    if (properties.getProperty(DataUrlConnection.USER_AGENT_PROPERTY_KEY) == null) {
 +      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);
 +          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");
 +        }
 +      } catch (IOException e) {
 +        log.error(e);
        }
 -    } catch (IOException e) {
 -      log.error(e);
      }
 +    DataUrl.setConfiguration(properties);
    }
    public void configure() {
 diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateCommand.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateCommand.java new file mode 100644 index 00000000..c2974785 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateCommand.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.slcommands; + +public interface InfoboxUpdateCommand extends SLCommand { + +  public String getInfoboxIdentifier(); +   +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateResult.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateResult.java new file mode 100644 index 00000000..d180facf --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/InfoboxUpdateResult.java @@ -0,0 +1,21 @@ +/* +* 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; + +public interface InfoboxUpdateResult extends SLResult { + +} 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 new file mode 100644 index 00000000..e49ed6c0 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractAssocArrayInfobox.java @@ -0,0 +1,284 @@ +/* + * 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.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.buergerkarte.namespaces.securitylayer._1.InfoboxAssocArrayPairType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadDataAssocArrayType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; +import at.buergerkarte.namespaces.securitylayer._1.XMLContentType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadKeys; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadPairs; +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.slexceptions.SLCommandException; + +/** + * An abstract base class for {@link Infobox} implementations of type associative array. + *  + * @author mcentner + */ +public abstract class AbstractAssocArrayInfobox extends AbstractInfoboxImpl +    implements AssocArrayInfobox { +   +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(AbstractAssocArrayInfobox.class); + +  /** +   * The search string pattern. +   */ +  public static final String SEARCH_STRING_PATTERN = ".&&[^/](/.&&[^/])*"; +   +  /** +   * @return the keys available in this infobox. +   */ +  public abstract String[] getKeys(); +   +  /** +   * @return <code>true</code> if the values are XML entities, or <code>false</code> otherwise. +   */ +  public abstract boolean isValuesAreXMLEntities(); +   +  /** +   * Returns a key to value mapping for the given <code>keys</code>. +   *  +   * @param keys a list of keys +   * @param cmdCtx the command context +   *  +   * @return a key to value mapping for the given <code>keys</code>. +   *  +   * @throws SLCommandException if obtaining the values fails +   */ +  public abstract Map<String, Object> getValues(List<String> keys, SLCommandContext cmdCtx) throws SLCommandException; + +  /** +   * Returns all keys that match the given <code>searchString</code>. +   *  +   * @param searchString the search string  +   *  +   * @return all keys that match the given <code>searchString</code> +   *  +   * @throws SLCommandException if the given search string is invalid +   */ +  protected List<String> selectKeys(String searchString) throws SLCommandException { +     +    if ("*".equals(searchString) || "**".equals(searchString)) { +      return Arrays.asList(getKeys()); +    } +     +    if (Pattern.matches(SEARCH_STRING_PATTERN, searchString)) { +       +//      for (int i = 0; i < searchString.length(); i++) { +//        int codePoint = searchString.codePointAt(i); +//         +//      } +       +      // TODO : build pattern +      return Collections.emptyList(); +    } else { +      log.info("Got invalid search string '" + searchString + "'"); +      throw new SLCommandException(4010); +    } +     +  } + +  /** +   * Read all keys specified by <code>readKeys</code>. +   *  +   * @param readKeys +   *          the ReadKeys element +   * @param cmdCtx +   *          the command context +   * @return a corresponding InfoboxReadResult +   *  +   * @throws SLCommandException +   *           if the ReadKeys element is invalid or obtaining the corresponding +   *           values fails +   */ +  protected InfoboxReadResult readKeys(ReadKeys readKeys, SLCommandContext cmdCtx) throws SLCommandException { +     +    List<String> selectedKeys = selectKeys(readKeys.getSearchString()); +     +    if (readKeys.isUserMakesUnique() && selectedKeys.size() > 1) { +      log.info("UserMakesUnique not supported"); +      // TODO: give more specific error message +      throw new SLCommandException(4010); +    } +     +    ObjectFactory objectFactory = new ObjectFactory(); +     +    InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory +        .createInfoboxReadDataAssocArrayType(); + +    List<String> keys = infoboxReadDataAssocArrayType.getKey(); +    keys.addAll(selectedKeys); + +    return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); +     +  } +   +  /** +   * Read all pairs specified by <code>readPairs</code>. +   *  +   * @param readPairs +   *          the readPairs element +   * @param cmdCtx +   *          the command context +   * @return a corresponding InfoboxReadResult +   *  +   * @throws SLCommandException +   *           if the ReadPairs element is invalid or obtaining the corresponding +   *           values fails +   */ +  protected InfoboxReadResult readPairs(ReadPairs readPairs, SLCommandContext cmdCtx) throws SLCommandException { +     +    if (readPairs.isValuesAreXMLEntities() && !isValuesAreXMLEntities()) { +      log.info("Got valuesAreXMLEntities=" + readPairs + " but infobox type is binary."); +      throw new SLCommandException(4010); +    } +     +    if (!readPairs.isValuesAreXMLEntities() && isValuesAreXMLEntities()) { +      log.info("Got valuesAreXMLEntities=" + readPairs + " but infobox type is XML."); +      throw new SLCommandException(4010); +    } + +    List<String> selectedKeys = selectKeys(readPairs.getSearchString()); +     +    if (readPairs.isUserMakesUnique() && selectedKeys.size() > 1) { +      log.info("UserMakesUnique not supported"); +      // TODO: give more specific error message +      throw new SLCommandException(4010); +    } +     +    ObjectFactory objectFactory = new ObjectFactory(); + +    InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory.createInfoboxReadDataAssocArrayType(); + +    Map<String, Object> values = getValues(selectedKeys, cmdCtx); +    for (String key : selectedKeys) { +      InfoboxAssocArrayPairType infoboxAssocArrayPairType = objectFactory.createInfoboxAssocArrayPairType(); +      infoboxAssocArrayPairType.setKey(key); +      Object value = values.get(key); +      if (value instanceof byte[]) { +        infoboxAssocArrayPairType.setBase64Content((byte[]) value); +      } else { +        infoboxAssocArrayPairType.setXMLContent((XMLContentType) value); +      } +      infoboxReadDataAssocArrayType.getPair().add(infoboxAssocArrayPairType); +    } +     +    return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); +  } + +  /** +   * Read the value specified by <code>readPairs</code>. +   *  +   * @param readValue +   *          the readValue element +   * @param cmdCtx +   *          the command context +   * @return a corresponding InfoboxReadResult +   *  +   * @throws SLCommandException +   *           if the ReadValue element is invalid or obtaining the corresponding +   *           values fails +   */ +  protected InfoboxReadResult readValue(ReadValue readValue, SLCommandContext cmdCtx) throws SLCommandException { +     +    if (readValue.isValueIsXMLEntity() && !isValuesAreXMLEntities()) { +      log.info("Got valuesAreXMLEntities=" + readValue + " but infobox type is binary."); +      throw new SLCommandException(4010); +    } +     +    if (!readValue.isValueIsXMLEntity() && isValuesAreXMLEntities()) { +      log.info("Got valuesAreXMLEntities=" + readValue + " but infobox type is XML."); +      throw new SLCommandException(4010); +    } +     +    List<String> selectedKeys; + +    if (Arrays.asList(getKeys()).contains(readValue.getKey())) { +      selectedKeys = Collections.singletonList(readValue.getKey()); +    } else { +      selectedKeys = Collections.emptyList(); +    } +     +    ObjectFactory objectFactory = new ObjectFactory(); + +    InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory.createInfoboxReadDataAssocArrayType(); +     +    Map<String, Object> values = getValues(selectedKeys, cmdCtx); +    for (String key : selectedKeys) { +      InfoboxAssocArrayPairType infoboxAssocArrayPairType = objectFactory.createInfoboxAssocArrayPairType(); +      infoboxAssocArrayPairType.setKey(key); +      Object value = values.get(key); +      if (value instanceof byte[]) { +        infoboxAssocArrayPairType.setBase64Content((byte[]) value); +      } else { +        infoboxAssocArrayPairType.setXMLContent((XMLContentType) value); +      } +      infoboxReadDataAssocArrayType.getPair().add(infoboxAssocArrayPairType); +    } +     +    return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); +  } + +  @Override +  public InfoboxReadResult read(InfoboxReadRequestType req, +      SLCommandContext cmdCtx) throws SLCommandException { + +    InfoboxReadParamsAssocArrayType assocArrayParameters = req +        .getAssocArrayParameters(); + +    if (assocArrayParameters == null) { +      log.info("Infobox type is AssocArray but got no AssocArrayParameters."); +      throw new SLCommandException(4010); +    } + +    if (assocArrayParameters.getReadKeys() != null) { +      return readKeys(assocArrayParameters.getReadKeys(), cmdCtx); +    } + +    if (assocArrayParameters.getReadPairs() != null) { +      return readPairs(assocArrayParameters.getReadPairs(), cmdCtx); +    } + +    // ReadValue +    if (assocArrayParameters.getReadValue() != null) { +      return readValue(assocArrayParameters.getReadValue(), cmdCtx); +    } + +    log +        .info("Infobox type is AssocArray but got invalid AssocArrayParameters."); +    throw new SLCommandException(4010); +     +  } + +} 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 new file mode 100644 index 00000000..07ca639c --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractBinaryFileInfobox.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. +*/ +package at.gv.egiz.bku.slcommands.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsBinaryFileType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; + +/** + * An abstract base class for {@link Infobox} implementations of type binary file. + *  + * @author mcentner + */ +public abstract class AbstractBinaryFileInfobox extends AbstractInfoboxImpl implements BinaryFileInfobox { + +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(AbstractBinaryFileInfobox.class); +   +  /** +   * Is this infobox' content an XML entity? +   */ +  private boolean isXMLEntity = false; +   +  /** +   * @return <code>true</code> if this infobox' content is an XML entity or <code>false</code> otherwise. +   */ +  public boolean isXMLEntity() { +    return isXMLEntity; +  } + +  /** +   * Sets the value returned by {@link #isXMLEntity()} according to the given +   * <code>request</code>. +   *  +   * @param request the InfoboxReadRequest +   */ +  public void setIsXMLEntity(InfoboxReadRequestType request) { +     +    InfoboxReadParamsBinaryFileType binaryFileParameters = request.getBinaryFileParameters(); +    if (binaryFileParameters != null) { +      isXMLEntity = binaryFileParameters.isContentIsXMLEntity(); +      log.debug("Got ContentIsXMLEntity=" + isXMLEntity + "."); +    } +     +  } + +   +   + +} 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 new file mode 100644 index 00000000..305769a8 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxCommandImpl.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.slcommands.impl; + +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +/** + * An abstract base class for implementations of security layer infobox requests. + *  + * @author mcentner + * + * @param <T> + */ +public abstract class AbstractInfoboxCommandImpl<T> extends SLCommandImpl<T> { + +  /** +   * The infobox implementation. +   */ +  protected Infobox infobox; +   +  @Override +  public void init(SLCommandContext ctx, Object request) +      throws SLCommandException { +    super.init(ctx, request); +     +    String infoboxIdentifier = getInfoboxIdentifier(getRequestValue()); +     +    infobox = InfoboxFactory.getInstance().createInfobox(infoboxIdentifier); +  } +   +  /** +   * Returns the infobox identifier given in <code>request</code>. +   *  +   * @param request the request value +   *  +   * @return the infobox identifier givne in <code>request</code> +   */ +  protected abstract String getInfoboxIdentifier(T request); + +} 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 new file mode 100644 index 00000000..e5c7afcc --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AbstractInfoboxImpl.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.slcommands.impl; + +/** + * An abstract base class for {@link Infobox} implementations. + *  + * @author mcentner + */ +public abstract class AbstractInfoboxImpl implements Infobox { + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AssocArrayInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AssocArrayInfobox.java new file mode 100644 index 00000000..908d95da --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/AssocArrayInfobox.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.slcommands.impl; + +/** + * An {@link Infobox} of type associative array as defined in Security Layer + * 1.2. + *  + * @author mcentner + */ +public interface AssocArrayInfobox extends Infobox { + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BinaryFileInfobox.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BinaryFileInfobox.java new file mode 100644 index 00000000..c27f9446 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/BinaryFileInfobox.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.slcommands.impl; + +/** + * An {@link Infobox} of type binary file as defined in Security Layer + * 1.2. + *  + * @author mcentner + */ +public interface BinaryFileInfobox extends Infobox { + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java new file mode 100644 index 00000000..0208f137 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CertificatesInfoboxImpl.java @@ -0,0 +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.slcommands.impl; + +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.stal.InfoboxReadRequest; +import at.gv.egiz.stal.STALRequest; + +/** + * An implementation of the {@link Infobox} <em>Certificates</em> as  + * specified in Security Layer 1.2.  + *  + * @author mcentner + */ +public class CertificatesInfoboxImpl extends AbstractAssocArrayInfobox { +   +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(CertificatesInfoboxImpl.class); + +  /** +   * The valid keys. +   */ +  public static final String[] CERTIFICATES_KEYS = new String[] { +    "SecureSignatureKeypair",  +    "CertifiedKeypair" }; +   +  @Override +  public String getIdentifier() { +    return "Certificates"; +  } + +  @Override +  public String[] getKeys() { +    return CERTIFICATES_KEYS; +  } + +  @Override +  public boolean isValuesAreXMLEntities() { +    return false; +  } + +  @Override +  public Map<String, Object> getValues(List<String> certificates, SLCommandContext cmdCtx) throws SLCommandException { +     +    STALHelper stalHelper = new STALHelper(cmdCtx.getSTAL()); +     +    if (certificates != null && !certificates.isEmpty()) { +       +      List<STALRequest> stalRequests = new ArrayList<STALRequest>(); + +      // get certificates +      InfoboxReadRequest infoboxReadRequest; +      for (int i = 0; i < certificates.size(); i++) { +        infoboxReadRequest = new InfoboxReadRequest(); +        infoboxReadRequest.setInfoboxIdentifier(certificates.get(i)); +        stalRequests.add(infoboxReadRequest); +      } + +      stalHelper.transmitSTALRequest(stalRequests); + +      List<X509Certificate> x509Certs = stalHelper.getCertificatesFromResponses(); +       +      Map<String, Object> values = new HashMap<String, Object>(); + +      for (int i = 0; i < certificates.size(); i++) { +        try { +          values.put(certificates.get(i), x509Certs.get(i).getEncoded()); +        } catch (CertificateEncodingException e) { +          log.error("Failed to encode certificate.", e); +          throw new SLCommandException(4000); +        } +      } +       +      return values; +       +    } else { +       +      return new HashMap<String, Object>(); +       +    } +     +     +  } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java index b2e3b303..01686641 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/CreateXMLSignatureCommandImpl.java @@ -16,13 +16,11 @@   */  package at.gv.egiz.bku.slcommands.impl; -import java.io.ByteArrayInputStream;  import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory;  import java.security.cert.X509Certificate;  import java.util.Collections;  import java.util.Date; +import java.util.List;  import javax.xml.crypto.MarshalException;  import javax.xml.crypto.URIReferenceException; @@ -48,11 +46,8 @@ import at.gv.egiz.bku.slexceptions.SLException;  import at.gv.egiz.bku.slexceptions.SLRequestException;  import at.gv.egiz.bku.slexceptions.SLViewerException;  import at.gv.egiz.dom.DOMUtils; -import at.gv.egiz.stal.ErrorResponse;  import at.gv.egiz.stal.InfoboxReadRequest; -import at.gv.egiz.stal.InfoboxReadResponse;  import at.gv.egiz.stal.STALRequest; -import at.gv.egiz.stal.STALResponse;  /**   * This class implements the security layer command @@ -147,33 +142,13 @@ public class CreateXMLSignatureCommandImpl extends      InfoboxReadRequest stalRequest = new InfoboxReadRequest();      stalRequest.setInfoboxIdentifier(keyboxIdentifier); -    requestSTAL(Collections.singletonList((STALRequest) stalRequest)); - -    STALResponse stalResponse = stalResponses.next(); - -    if (stalResponse instanceof InfoboxReadResponse) { -      byte[] infobox = ((InfoboxReadResponse) stalResponse).getInfoboxValue(); - -      try { -        CertificateFactory certFactory = CertificateFactory.getInstance("X509"); -        signingCertificate = (X509Certificate) certFactory -            .generateCertificate(new ByteArrayInputStream(infobox)); -      } catch (CertificateException e) { -        log.info("Failed to decode signing certificate.", e); -        // TODO: issue appropriate error
 -        throw new SLCommandException(4000); -      } - -    } else if (stalResponse instanceof ErrorResponse) { -      ErrorResponse err = (ErrorResponse) stalResponse; -      log.info("Received an error response from STAL with code: " -          + err.getErrorCode()); -      throw new SLCommandException(err.getErrorCode()); - -    } else { -      log.info("Failed to get signing certificate."); +    stalHelper.transmitSTALRequest(Collections.singletonList((STALRequest) stalRequest)); +    List<X509Certificate> certificates = stalHelper.getCertificatesFromResponses(); +    if (certificates == null || certificates.size() != 1) { +      log.info("Got an unexpected number of certificates from STAL.");        throw new SLCommandException(4000);      } +    signingCertificate = certificates.get(0);    } 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 new file mode 100644 index 00000000..20d20c9d --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/IdentityLinkInfoboxImpl.java @@ -0,0 +1,291 @@ +/* +* 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.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Result; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; + +import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; +import at.buergerkarte.namespaces.securitylayer._1.AnyChildrenType; +import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLExceptionMessages; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.idlink.CompressedIdentityLinkFactory; +import at.gv.egiz.idlink.IdentityLinkTransformer; +import at.gv.egiz.idlink.ans1.IdentityLink; +import at.gv.egiz.stal.InfoboxReadRequest; +import at.gv.egiz.stal.STALRequest; + +/** + * An implementation of the {@link Infobox} <em>IdentityLink</em> as + * specified in Security Layer 1.2 + *  + * @author mcentner + */ +public class IdentityLinkInfoboxImpl extends AbstractBinaryFileInfobox { + +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(IdentityLinkInfoboxImpl.class); + +  /** +   * The box specific parameter <code>IdentityLinkDomainIdentifier</code>. +   */ +  public static final String BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER = "IdentityLinkDomainIdentifier"; +   +  /** +   * The value of the box specific parameter <code>IdentityLinkDomainIdentifier</code>. +   */ +  private String domainIdentifier; +   +  @Override +  public String getIdentifier() { +    return "IdentityLink"; +  } + +  /** +   * @return the value of the box specific parameter <code>IdentityLinkDomainIdentifier</code> +   */ +  public String getDomainIdentifier() { +    return domainIdentifier; +  } + +  @Override +  public InfoboxReadResult read(InfoboxReadRequestType req, SLCommandContext cmdCtx) throws SLCommandException { +     +    AnyChildrenType boxSpecificParameters = req.getBoxSpecificParameters(); + +    if (boxSpecificParameters != null) { +      // check BoxSpecificParameters +      List<Object> parameter = boxSpecificParameters.getAny(); +      JAXBElement<?> element; +      if (parameter != null  +          && parameter.size() == 1  +          && parameter.get(0) instanceof JAXBElement<?> +          && SLCommand.NAMESPACE_URI.equals((element = (JAXBElement<?>) parameter.get(0)).getName().getNamespaceURI()) +          && BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER.equals(element.getName().getLocalPart()) +          && element.getValue() instanceof String) { +        domainIdentifier = (String) element.getValue(); +        log.debug("Got sl:IdentityLinkDomainIdentifier: " + domainIdentifier); +      } else { +        log.info("Got invalid BoxSpecificParameters."); +        throw new SLCommandException(4010); +      } +    } +     +    setIsXMLEntity(req); +     +    STALHelper stalHelper = new STALHelper(cmdCtx.getSTAL()); +     +    List<STALRequest> stalRequests = new ArrayList<STALRequest>(); + +    InfoboxReadRequest infoboxReadRequest; +    // get raw identity link +    infoboxReadRequest = new InfoboxReadRequest(); +    infoboxReadRequest.setInfoboxIdentifier(getIdentifier()); +    infoboxReadRequest.setDomainIdentifier(domainIdentifier); +    stalRequests.add(infoboxReadRequest); +     +    // get certificates +    infoboxReadRequest = new InfoboxReadRequest(); +    infoboxReadRequest.setInfoboxIdentifier("SecureSignatureKeypair"); +    stalRequests.add(infoboxReadRequest); +    infoboxReadRequest = new InfoboxReadRequest(); +    infoboxReadRequest.setInfoboxIdentifier("CertifiedKeypair"); +    stalRequests.add(infoboxReadRequest); + +    stalHelper.transmitSTALRequest(stalRequests); +    log.trace("Got STAL response"); + +    IdentityLink identityLink = stalHelper.getIdentityLinkFromResponses(); +    List<X509Certificate> certificates = stalHelper.getCertificatesFromResponses(); +     +     +    CompressedIdentityLinkFactory idLinkFactory = CompressedIdentityLinkFactory.getInstance(); +    JAXBElement<CompressedIdentityLinkType> compressedIdentityLink = idLinkFactory +        .createCompressedIdentityLink(identityLink, certificates, getDomainIdentifier()); + +    IdentityLinkTransformer identityLinkTransformer = IdentityLinkTransformer.getInstance(); +    String issuerTemplate = identityLink.getIssuerTemplate(); +     +    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); +    DocumentBuilder db; +    try { +      db = dbf.newDocumentBuilder(); +    } catch (ParserConfigurationException e) { +      log.error("Failed to create XML document.", e); +      throw new SLRuntimeException(e); +    } +     +    Document document = db.newDocument(); +    try { +      idLinkFactory.marshallCompressedIdentityLink(compressedIdentityLink, document, null, true); +    } catch (JAXBException e) { +      log.info("Failed to marshall CompressedIdentityLink.", e); +      throw new SLCommandException(4000, +          SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, +          new Object[] { getIdentifier() }); +    } +     +    InfoboxReadResultFileImpl result = new InfoboxReadResultFileImpl(); +    ByteArrayOutputStream resultBytes = null; +    Result xmlResult = (isXMLEntity() || getDomainIdentifier() != null)  +          ? result.getXmlResult(true)  +          : new StreamResult((resultBytes = new ByteArrayOutputStream())); +    try { +      log.trace("Trying to transform identitylink"); +      identityLinkTransformer.transformIdLink(issuerTemplate, new DOMSource(document), xmlResult); +    } catch (MalformedURLException e) { +      log.warn("Malformed issuer template URL '" + issuerTemplate + "'."); +      throw new SLCommandException(4000, +          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +          new Object[] { issuerTemplate }); +    } catch (IOException e) { +      log.warn("Failed to dereferene issuer template URL '" + issuerTemplate + "'." ,e); +      throw new SLCommandException(4000, +          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +          new Object[] { issuerTemplate }); +    } catch (TransformerConfigurationException e) { +      log.warn("Failed to create transformation template from issuer template URL '" + issuerTemplate + "'", e); +      throw new SLCommandException(4000, +          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +          new Object[] { issuerTemplate }); +    } catch (TransformerException e) { +      log.info("Faild to transform CompressedIdentityLink.", e); +      throw new SLCommandException(4000, +          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +          new Object[] { issuerTemplate }); +    } +     +    // TODO: Report BUG in IssuerTemplates +    // Some IssuerTemplate stylesheets do not consider the pr:Type-Element of the CompressedIdentityLink ... +    if (getDomainIdentifier() != null) { +      if (xmlResult instanceof DOMResult) { +        Node node = ((DOMResult) xmlResult).getNode(); +        Node nextSibling = ((DOMResult) xmlResult).getNextSibling(); +        Node idLinkNode; +        if (nextSibling != null) { +          idLinkNode = nextSibling.getPreviousSibling(); +        } else if (node != null) { +          idLinkNode = node.getFirstChild(); +        } else { +          log +              .error("An IdentityLinkDomainIdentifier of '" +                  + getDomainIdentifier() +                  + "' has been given. However, it cannot be set, as the transformation result does not contain a node."); +          throw new SLCommandException(4000, +              SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +              new Object[] { issuerTemplate }); +        } +        IdentityLinkTransformer.setDomainIdentifier(idLinkNode, getDomainIdentifier()); +      } else { +        log +            .error("An IdentityLinkDomainIdentifier of '" +                + getDomainIdentifier() +                + "' has been given. However, it cannot be set, as the transformation result is not of type DOM."); +        throw new SLCommandException(4000, +            SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +            new Object[] { issuerTemplate }); +      } +    } +     +    if (!isXMLEntity()) { +      if (resultBytes == null) { +        resultBytes = new ByteArrayOutputStream(); + +        if (xmlResult instanceof DOMResult) { +          Node node = ((DOMResult) xmlResult).getNode(); +          Node nextSibling = ((DOMResult) xmlResult).getNextSibling(); +           +          DOMSource xmlSource; +          if (nextSibling != null) { +            xmlSource = new DOMSource(nextSibling.getPreviousSibling()); +          } else if (node != null) { +            xmlSource = new DOMSource(node.getFirstChild()); +          } else { +            log +                .error("IssuerTemplate transformation returned no node."); +            throw new SLCommandException(4000, +                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +                new Object[] { issuerTemplate }); +          } +          TransformerFactory transformerFactory = TransformerFactory.newInstance(); +          try { +            Transformer transformer = transformerFactory.newTransformer(); +            transformer.transform(xmlSource, new StreamResult(resultBytes)); +          } catch (TransformerConfigurationException e) { +            log.error(e); +            throw new SLCommandException(4000, +                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +                new Object[] { issuerTemplate }); +          } catch (TransformerException e) { +            log.error(e); +            throw new SLCommandException(4000, +                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +                new Object[] { issuerTemplate }); +          } +        } else if (xmlResult instanceof StreamResult) { +          OutputStream outputStream = ((StreamResult) xmlResult).getOutputStream(); +          if (outputStream instanceof ByteArrayOutputStream) { +            result.setResultBytes(((ByteArrayOutputStream) outputStream).toByteArray()); +          } else { +            log.error("ContentIsXMLEntity is set to 'false'. However, an XMLResult has already been set."); +            throw new SLCommandException(4000, +                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, +                new Object[] { issuerTemplate }); +          } +        } +      } else { +        result.setResultBytes(resultBytes.toByteArray()); +      } +    } +     +    return result; + +  } +   + +} 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 new file mode 100644 index 00000000..a6f8cbb2 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/Infobox.java @@ -0,0 +1,53 @@ +/* + * 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 at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; +import at.gv.egiz.bku.slcommands.InfoboxReadResult; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException; + +/** + * An implementation of this interface represents a infobox as defined in + * Security-Layer 1.2. + *  + * @author mcentner + */ +public interface Infobox { + +  /** +   * @return the identifier of this infobox +   */ +  public String getIdentifier(); + +  /** +   * Read data from this infobox. +   *  +   * @param request +   *          the InfoboxReadRequest +   * @param cmdCtx +   *          the command context +   *  +   * @return the data read from this infobox as InfoboxReadResult +   *  +   * @throws SLCommandException +   *           if reading from this infobox fails +   */ +  public InfoboxReadResult read(InfoboxReadRequestType request, +      SLCommandContext cmdCtx) throws SLCommandException; + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java new file mode 100644 index 00000000..4a03fe74 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxFactory.java @@ -0,0 +1,151 @@ +/* +* 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.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLExceptionMessages; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; + +/** + * A factory for creating {@link Infobox}es. + *  + * @author mcentner + */ +public class InfoboxFactory { +   +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(InfoboxFactory.class); +   +  /** +   * The singleton instance of this InfoboxFactory. +   */ +  private static InfoboxFactory instance; + +  /** +   * @return an instance of this InfoboxFactory +   */ +  public synchronized static InfoboxFactory getInstance() { +    if (instance == null) { +      instance = new InfoboxFactory(); +    } +    return instance; +  } +  +  /** +   * The mapping of infobox identifier to implementation class. +   */ +  private HashMap<String, Class<? extends Infobox>> implementations; + +  /** +   * Private constructor. +   */ +  private InfoboxFactory() { +  } + +  /** +   * Sets the mapping of infobox identifier to implementation class name. +   *  +   * @param infoboxImplMap +   *          a mapping of infobox identifiers to implementation class names +   *  +   * @throws ClassNotFoundException +   *           if implementation class is not an instance of {@link Infobox} +   */ +  @SuppressWarnings("unchecked") +  public void setInfoboxImpl(Map<String, String> infoboxImplMap) throws ClassNotFoundException { +    HashMap<String, Class<? extends Infobox>> implMap = new HashMap<String, Class<? extends Infobox>>(); +    ClassLoader cl = getClass().getClassLoader(); +    for (String key : infoboxImplMap.keySet()) { +      Class<? extends Infobox> impl = (Class<? extends Infobox>) cl.loadClass(infoboxImplMap.get(key)); +      log.debug("Registering infobox '" + key + "' implementation '" + impl.getCanonicalName() + "'."); +      implementations.put(key, impl); +    } +    implementations = implMap; +  } + +  /** +   * Returns the configured implementation class for the given +   * <code>infoboxIdentifier</code>. +   *  +   * @param infoboxIdentifier +   *          the infobox identifier +   *  +   * @return the implementation class for the given infobox identifier or +   *         <code>null</code> if there is no implementation class configured +   */ +  public Class<? extends Infobox> getImplClass(String infoboxIdentifier) { +    if (implementations != null) { +      return implementations.get(infoboxIdentifier); +    } else { +      return null; +    } +  } + +  /** +   * Create a new {@link Infobox} instance for the given +   * <code>infoboxIdentifier</code>. +   *  +   * @param infoboxIdentifier +   *          the infobox identifier +   *  +   * @return an {@link Infobox} implementation for the given infobox identifier +   *  +   * @throws SLCommandException +   *           if there is no implementation for the given infobox identifier +   * @throws SLRuntimeException +   *           if creating an {@link Infobox} instance fails +   */ +  public Infobox createInfobox(String infoboxIdentifier) throws SLCommandException, SLRuntimeException { +     +    Class<? extends Infobox> implClass = getImplClass(infoboxIdentifier); +    if (implClass == null) { +      // infobox not supported +      log.info("Unsupported infobox '" + infoboxIdentifier + "."); +      throw new SLCommandException(4002, +          SLExceptionMessages.EC4002_INFOBOX_UNKNOWN, +          new Object[] { infoboxIdentifier }); +    } +     +    // try to instantiate +    Infobox infobox; +    try { +      infobox = implClass.newInstance(); +      log.debug("Infobox '" + infobox.getIdentifier() + "' created."); +    } catch (InstantiationException e) { +      // unexpected error +      log.error("Failed to instantiate infobox implementation.", e); +      throw new SLRuntimeException(e); +    } catch (IllegalAccessException e) { +      // unexpected error +      log.error("Failed to instantiate infobox implementation.", e); +      throw new SLRuntimeException(e); +    } +     +    return infobox; +     +  } +   + +} 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 c7bb5205..aaa786a6 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 @@ -16,67 +16,14 @@  */  package at.gv.egiz.bku.slcommands.impl;
 -import iaik.asn1.CodingException; -import iaik.asn1.DerCoder; - -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; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.regex.Pattern; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.JAXBException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMResult; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -  import org.apache.commons.logging.Log;  import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import at.buergerkarte.namespaces.personenbindung._20020506_.CompressedIdentityLinkType; -import at.buergerkarte.namespaces.securitylayer._1.AnyChildrenType; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxAssocArrayPairType; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadDataAssocArrayType; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsBinaryFileType;  import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadRequestType; -import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadKeys; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadPairs; -import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadParamsAssocArrayType.ReadValue;  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.SLResult;  import at.gv.egiz.bku.slexceptions.SLCommandException; -import at.gv.egiz.bku.slexceptions.SLExceptionMessages; -import at.gv.egiz.bku.slexceptions.SLRuntimeException; -import at.gv.egiz.idlink.CompressedIdentityLinkFactory; -import at.gv.egiz.idlink.IdentityLinkTransformer; -import at.gv.egiz.idlink.ans1.IdentityLink; -import at.gv.egiz.stal.InfoboxReadRequest; -import at.gv.egiz.stal.InfoboxReadResponse; -import at.gv.egiz.stal.STALRequest;  /**
   * This class implements the security layer command
 @@ -88,7 +35,7 @@ import at.gv.egiz.stal.STALRequest;   * 
   * @author mcentner
   */
 -public class InfoboxReadCommandImpl extends SLCommandImpl<InfoboxReadRequestType> implements
 +public class InfoboxReadCommandImpl extends AbstractInfoboxCommandImpl<InfoboxReadRequestType> implements
      InfoboxReadCommand {
    /**
 @@ -96,511 +43,63 @@ public class InfoboxReadCommandImpl extends SLCommandImpl<InfoboxReadRequestType     */
    protected static Log log = LogFactory.getLog(InfoboxReadCommandImpl.class); -  public static final String SEARCH_STRING_PATTERN = ".&&[^/](/.&&[^/])*";
 -
 -  public static final String INFOBOX_IDENTIFIER_CERTIFICATES = "Certificates"; -   -  public static final String BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER = "IdentityLinkDomainIdentifier"; -   -  public static final String INFOBOX_IDENTIFIER_IDENTITY_LINK = "IdentityLink"; - -  public static final String[] INFOXBOX_CERTIFICATES_KEYS = new String[] { -      "SecureSignatureKeypair",  -      "CertifiedKeypair" }; -   -  private static final int ASSOC_ARRAY_READ_KEYS = 1; -   -  private static final int ASSOC_ARRAY_READ_PAIRS = 2; -   -  private static final int ASSOC_ARRAY_READ_VALUE = 3;
 -   -  /**
 -   * The <code>InfoboxIdentifier</code>
 -   */
 -  protected String infoboxIdentifier;
 -  
 -  /**
 -   * The <code>IdentityLinkDomainIdentifier</code> value of an <code>IdentyLink</code> infobox.
 -   */
 -  protected String identityLinkDomainIdentifier; -   -  /** -   * The list of certificates to be read from an <code>Certificates</code> infobox. -   */ -  protected List<String> certificates; -   -  /** -   * The result type. -   */ -  protected int assocArrayResult;
 -
 -  /**
 -   * Is content XML entity?
 -   */
 -  protected boolean isXMLEntity;
 -  
    @Override
    public String getName() {
      return "InfoboxReadRequest";
    }
 -  /**
 -   * @return the infoboxIdentifier
 -   */
 -  public String getInfoboxIdentifier() {
 -    return infoboxIdentifier;
 -  }
 -
 +  @Override +  protected String getInfoboxIdentifier(InfoboxReadRequestType request) { +    return request.getInfoboxIdentifier(); +  } +    @Override
    public void init(SLCommandContext ctx, Object request) throws SLCommandException {
      super.init(ctx, request);
      InfoboxReadRequestType req = getRequestValue();
 -    
 -    infoboxIdentifier = req.getInfoboxIdentifier();
 -    
 -    if (INFOBOX_IDENTIFIER_IDENTITY_LINK.equals(infoboxIdentifier)) {
 -      
 -      if (req.getAssocArrayParameters() != null) {
 -        log.info("Got AssocArrayParameters but Infobox type is BinaryFile.");
 -        throw new SLCommandException(4010);
 -      }
 -      
 -      InfoboxReadParamsBinaryFileType binaryFileParameters = req.getBinaryFileParameters(); -      if (binaryFileParameters != null) { -        isXMLEntity = binaryFileParameters.isContentIsXMLEntity(); -        log.debug("Got ContentIsXMLEntity=" + isXMLEntity + "."); -      } -      
 -      AnyChildrenType boxSpecificParameters = req.getBoxSpecificParameters();
 -
 -      if (boxSpecificParameters != null) {
 -        // check BoxSpecificParameters
 -        List<Object> parameter = boxSpecificParameters.getAny();
 -        JAXBElement<?> element;
 -        if (parameter != null 
 -            && parameter.size() == 1 
 -            && parameter.get(0) instanceof JAXBElement<?>
 -            && SLCommand.NAMESPACE_URI.equals((element = (JAXBElement<?>) parameter.get(0)).getName().getNamespaceURI())
 -            && BOX_SPECIFIC_PARAMETER_IDENTITY_LINK_DOMAIN_IDENTIFIER.equals(element.getName().getLocalPart())
 -            && element.getValue() instanceof String) {
 -          identityLinkDomainIdentifier = (String) element.getValue();
 -          log.debug("Got sl:IdentityLinkDomainIdentifier: " + identityLinkDomainIdentifier);
 -        } else {
 -          log.info("Got invalid BoxSpecificParameters.");
 -          throw new SLCommandException(4010);
 -        }
 -      }
 -    } else if (INFOBOX_IDENTIFIER_CERTIFICATES.equals(infoboxIdentifier)) { -       -      if (req.getBinaryFileParameters() != null) { -        log.info("Got BinaryFileParameters but Infobox type is AssocArray."); -        throw new SLCommandException(4010); -      } -       -      if (req.getBoxSpecificParameters() != null) { -        log.info("Got invalid BoxSpecificParameters."); -        throw new SLCommandException(4010); -      } -       -      InfoboxReadParamsAssocArrayType assocArrayParameters = req -          .getAssocArrayParameters(); -      if (assocArrayParameters == null) { -        log.info("Infobox type is AssocArray but got no AssocArrayParameters."); -        throw new SLCommandException(4010); -      } -       -      // RreadKeys? -      if (assocArrayParameters.getReadKeys() != null) { -        assocArrayResult = ASSOC_ARRAY_READ_KEYS; -        ReadKeys readKeys = assocArrayParameters.getReadKeys(); -        certificates = findCertificates(readKeys.getSearchString()); -        if (readKeys.isUserMakesUnique() && certificates.size() > 1) { -          log.info("UserMakesUnique not supported"); -          // TODO: give more specific error message -          throw new SLCommandException(4010); -        } -      } - -      // ReadPairs? -      if (assocArrayParameters.getReadPairs() != null) { -        assocArrayResult = ASSOC_ARRAY_READ_PAIRS; -        ReadPairs readPairs = assocArrayParameters.getReadPairs(); -        if (readPairs.isValuesAreXMLEntities()) { -          log.info("Got valuesAreXMLEntities but infobox type is binary."); -          throw new SLCommandException(4010); -        } -        certificates = findCertificates(readPairs.getSearchString()); -        if (readPairs.isUserMakesUnique() && certificates.size() > 1) { -          log.info("UserMakesUnique not supported"); -          // TODO: give more specific error message -          throw new SLCommandException(4010); -        } -      } - -      // ReadValue -      if (assocArrayParameters.getReadValue() != null) { -        assocArrayResult = ASSOC_ARRAY_READ_VALUE; -        ReadValue readValue = assocArrayParameters.getReadValue(); -        if (readValue.isValueIsXMLEntity()) { -          log.info("Got valuesAreXMLEntities but infobox type is binary."); -          throw new SLCommandException(4010); -        } -        String key = readValue.getKey(); -        if (Arrays.asList(INFOXBOX_CERTIFICATES_KEYS).contains(key)) { -          certificates = Collections.singletonList(key); -        } else { -          certificates = Collections.emptyList(); -        } -      } - -      if (assocArrayResult == 0) { -        log.info("Infobox type is AssocArray but got invalid AssocArrayParameters."); -        throw new SLCommandException(4010); -      } -      
 -    } else {
 -      throw new SLCommandException(4002,
 -          SLExceptionMessages.EC4002_INFOBOX_UNKNOWN,
 -          new Object[] { infoboxIdentifier });
 -    }
 +    if (req.getAssocArrayParameters() != null &&  +        !(infobox instanceof AssocArrayInfobox)) { +      log.info("Got AssocArrayParameters but Infobox type is not AssocArray."); +      throw new SLCommandException(4010); +    } +     +    if (req.getBinaryFileParameters() != null && +        !(infobox instanceof BinaryFileInfobox)) { +      log.info("Got BinaryFileParameters but Infobox type is not BinaryFile."); +      throw new SLCommandException(4010); +    }    }
    @Override
    public SLResult execute() { -    try {
 -      if (INFOBOX_IDENTIFIER_IDENTITY_LINK.equals(infoboxIdentifier)) { -        return readIdentityLink(); -      } else if (INFOBOX_IDENTIFIER_CERTIFICATES.equals(infoboxIdentifier)) { -        return readCertificates(); -      } else { -        throw new SLCommandException(4000); -      } -    } catch (SLCommandException e) {
 -      return new ErrorResultImpl(e, cmdCtx.getLocale());
 -    }
 -  }
 - 
 -  /**
 -   * Gets the IdentitiyLink form the next STAL response.
 -   * 
 -   * @return the IdentityLink
 -   * 
 -   * @throws SLCommandException if getting the IdentitiyLink fails
 -   */
 -  private IdentityLink getIdentityLinkFromResponses() throws SLCommandException {
 -
 -    // IdentityLink
 -    InfoboxReadResponse response;
 -    if (hasNextResponse()) {
 -      response = (InfoboxReadResponse) nextResponse(InfoboxReadResponse.class);
 -      byte[] idLink = response.getInfoboxValue();
 -      try {
 -        return new IdentityLink(DerCoder.decode(idLink));
 -      } catch (CodingException e) {
 -        log.info("Failed to decode infobox '" + INFOBOX_IDENTIFIER_IDENTITY_LINK + "'.", e);
 -        throw new SLCommandException(4000,
 -            SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID,
 -            new Object[] { INFOBOX_IDENTIFIER_IDENTITY_LINK });
 -      }
 -    } else {
 -      log.info("No infobox '" + INFOBOX_IDENTIFIER_IDENTITY_LINK + "' returned from STAL.");
 -      throw new SLCommandException(4000);
 -    }
 -    
 -  }
 -  
 -  /**
 -   * Gets the list of certificates from the next STAL responses.
 -   * 
 -   * @return the list of certificates
 -   * 
 -   * @throws SLCommandException if getting the list of certificates fails
 -   */
 -  private List<X509Certificate> getCertificatesFromResponses() throws SLCommandException {
 -    
 -    List<X509Certificate> certificates = new ArrayList<X509Certificate>();
 -
 -    CertificateFactory certFactory;
 -    try {
 -      certFactory = CertificateFactory.getInstance("X509");
 -    } catch (CertificateException e) {
 -      // we should always be able to get an X509 certificate factory
 -      log.error("CertificateFactory.getInstance(\"X509\") failed.", e);
 -      throw new SLRuntimeException(e);
 -    }
 -    
 -    InfoboxReadResponse response;
 -    while(hasNextResponse()) {
 -      response = (InfoboxReadResponse) nextResponse(InfoboxReadResponse.class);
 -      byte[] cert = response.getInfoboxValue();
 -      try {
 -        certificates.add((X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(cert)));
 -      } catch (CertificateException e) {
 -        log.info("Failed to decode certificate.", e);
 -        throw new SLCommandException(4000,
 -            SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID,
 -            new Object[] { INFOBOX_IDENTIFIER_CERTIFICATES });
 -      }
 -    }
 -    
 -    return certificates;
 -
 -  }
 -
 -  /**
 -   * Uses STAL to read the IdentityLink.
 -   * 
 -   * @return the corresponding security layer result
 -   * 
 -   * @throws SLCommandException if reading the IdentityLink fails
 -   */
 -  private SLResult readIdentityLink() throws SLCommandException {
 -    
 -    List<STALRequest> stalRequests = new ArrayList<STALRequest>();
 -
 -    InfoboxReadRequest infoboxReadRequest;
 -    // get raw identity link
 -    infoboxReadRequest = new InfoboxReadRequest();
 -    infoboxReadRequest.setInfoboxIdentifier(INFOBOX_IDENTIFIER_IDENTITY_LINK);
 -    infoboxReadRequest.setDomainIdentifier(identityLinkDomainIdentifier);
 -    stalRequests.add(infoboxReadRequest);
 -    
 -    // get certificates
 -    infoboxReadRequest = new InfoboxReadRequest();
 -    infoboxReadRequest.setInfoboxIdentifier("SecureSignatureKeypair");
 -    stalRequests.add(infoboxReadRequest);
 -    infoboxReadRequest = new InfoboxReadRequest();
 -    infoboxReadRequest.setInfoboxIdentifier("CertifiedKeypair");
 -    stalRequests.add(infoboxReadRequest);
 -
 -    requestSTAL(stalRequests);
 -    log.trace("Got STAL response");
 -
 -    IdentityLink identityLink = getIdentityLinkFromResponses();
 -    List<X509Certificate> certificates = getCertificatesFromResponses();
 -    
 -    
 -    CompressedIdentityLinkFactory idLinkFactory = CompressedIdentityLinkFactory.getInstance();
 -    JAXBElement<CompressedIdentityLinkType> compressedIdentityLink = idLinkFactory
 -        .createCompressedIdentityLink(identityLink, certificates, identityLinkDomainIdentifier);
 -
 -    IdentityLinkTransformer identityLinkTransformer = IdentityLinkTransformer.getInstance();
 -    String issuerTemplate = identityLink.getIssuerTemplate();
 -    
 -    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 -    DocumentBuilder db;
 -    try {
 -      db = dbf.newDocumentBuilder();
 -    } catch (ParserConfigurationException e) {
 -      log.error("Failed to create XML document.", e);
 -      throw new SLRuntimeException(e);
 -    }
 -    
 -    Document document = db.newDocument();
 -    try {
 -      idLinkFactory.marshallCompressedIdentityLink(compressedIdentityLink, document, null, true);
 -    } catch (JAXBException e) {
 -      log.info("Failed to marshall CompressedIdentityLink.", e);
 -      throw new SLCommandException(4000,
 -          SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID,
 -          new Object[] { INFOBOX_IDENTIFIER_IDENTITY_LINK });
 -    }
 -    
 -    InfoboxReadResultFileImpl result = new InfoboxReadResultFileImpl();
 -    ByteArrayOutputStream resultBytes = null;
 -    Result xmlResult = (isXMLEntity || identityLinkDomainIdentifier != null) 
 -          ? result.getXmlResult(true) 
 -          : new StreamResult((resultBytes = new ByteArrayOutputStream()));
 +          try { -      log.trace("Trying to transform identitylink");
 -      identityLinkTransformer.transformIdLink(issuerTemplate, new DOMSource(document), xmlResult); -    } catch (MalformedURLException e) { -      log.warn("Malformed issuer template URL '" + issuerTemplate + "'."); -      throw new SLCommandException(4000, -          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, -          new Object[] { issuerTemplate }); -    } catch (IOException e) {
 -      log.warn("Failed to dereferene issuer template URL '" + issuerTemplate + "'." ,e);
 -      throw new SLCommandException(4000, -          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, -          new Object[] { issuerTemplate }); -    } catch (TransformerConfigurationException e) { -      log.warn("Failed to create transformation template from issuer template URL '" + issuerTemplate + "'", e); -      throw new SLCommandException(4000, -          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED, -          new Object[] { issuerTemplate }); -    } catch (TransformerException e) {
 -      log.info("Faild to transform CompressedIdentityLink.", e);
 -      throw new SLCommandException(4000,
 -          SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -          new Object[] { issuerTemplate });
 -    }
 -    
 -    // TODO: Report BUG in IssuerTemplates
 -    // Some IssuerTemplate stylesheets do not consider the pr:Type-Element of the CompressedIdentityLink ...
 -    if (identityLinkDomainIdentifier != null) {
 -      if (xmlResult instanceof DOMResult) {
 -        Node node = ((DOMResult) xmlResult).getNode();
 -        Node nextSibling = ((DOMResult) xmlResult).getNextSibling();
 -        Node idLinkNode;
 -        if (nextSibling != null) {
 -          idLinkNode = nextSibling.getPreviousSibling();
 -        } else if (node != null) {
 -          idLinkNode = node.getFirstChild();
 -        } else {
 -          log
 -              .error("An IdentityLinkDomainIdentifier of '"
 -                  + identityLinkDomainIdentifier
 -                  + "' has been given. However, it cannot be set, as the transformation result does not contain a node.");
 -          throw new SLCommandException(4000,
 -              SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -              new Object[] { issuerTemplate });
 -        }
 -        IdentityLinkTransformer.setDomainIdentifier(idLinkNode, identityLinkDomainIdentifier);
 -      } else {
 -        log
 -            .error("An IdentityLinkDomainIdentifier of '"
 -                + identityLinkDomainIdentifier
 -                + "' has been given. However, it cannot be set, as the transformation result is not of type DOM.");
 -        throw new SLCommandException(4000,
 -            SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -            new Object[] { issuerTemplate });
 -      }
 -    }
 -    
 -    if (!isXMLEntity) {
 -      if (resultBytes == null) {
 -        resultBytes = new ByteArrayOutputStream();
 -
 -        if (xmlResult instanceof DOMResult) {
 -          Node node = ((DOMResult) xmlResult).getNode();
 -          Node nextSibling = ((DOMResult) xmlResult).getNextSibling();
 -          
 -          DOMSource xmlSource;
 -          if (nextSibling != null) {
 -            xmlSource = new DOMSource(nextSibling.getPreviousSibling());
 -          } else if (node != null) {
 -            xmlSource = new DOMSource(node.getFirstChild());
 -          } else {
 -            log
 -                .error("IssuerTemplate transformation returned no node.");
 -            throw new SLCommandException(4000,
 -                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -                new Object[] { issuerTemplate });
 -          }
 -          TransformerFactory transformerFactory = TransformerFactory.newInstance();
 -          try {
 -            Transformer transformer = transformerFactory.newTransformer();
 -            transformer.transform(xmlSource, new StreamResult(resultBytes));
 -          } catch (TransformerConfigurationException e) {
 -            log.error(e);
 -            throw new SLCommandException(4000,
 -                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -                new Object[] { issuerTemplate });
 -          } catch (TransformerException e) {
 -            log.error(e);
 -            throw new SLCommandException(4000,
 -                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -                new Object[] { issuerTemplate });
 -          }
 -        } else if (xmlResult instanceof StreamResult) {
 -          OutputStream outputStream = ((StreamResult) xmlResult).getOutputStream();
 -          if (outputStream instanceof ByteArrayOutputStream) {
 -            result.setResultBytes(((ByteArrayOutputStream) outputStream).toByteArray());
 -          } else {
 -            log.error("ContentIsXMLEntity is set to 'false'. However, an XMLResult has already been set.");
 -            throw new SLCommandException(4000,
 -                SLExceptionMessages.EC4000_UNCLASSIFIED_IDLINK_TRANSFORMATION_FAILED,
 -                new Object[] { issuerTemplate });
 -          }
 -        }
 -      } else {
 -        result.setResultBytes(resultBytes.toByteArray());
 -      }
 -    }
 -    
 -    
 -    return result;
 -    
 -  } -   -  protected List<String> findCertificates(String searchString) throws SLCommandException { - -    if ("*".equals(searchString) || "**".equals(searchString)) { -      return Arrays.asList(INFOXBOX_CERTIFICATES_KEYS); +      return infobox.read(getRequestValue(), getCmdCtx()); +    } catch (SLCommandException e) { +      return new ErrorResultImpl(e, getCmdCtx().getLocale());      } -    if (Pattern.matches(SEARCH_STRING_PATTERN, searchString)) { -       -//      for (int i = 0; i < searchString.length(); i++) { -//        int codePoint = searchString.codePointAt(i); -//         -//      } -       -      // TODO : build pattern -      return Collections.emptyList(); +  }
 + 
 +
 +  @Override +  public String getIdentityLinkDomainId() { +    if (infobox instanceof IdentityLinkInfoboxImpl) { +      return ((IdentityLinkInfoboxImpl) infobox).getDomainIdentifier();      } else { -      log.info("Got invalid search string '" + searchString + "'"); -      throw new SLCommandException(4010); +      return null;      } -        } -  private SLResult readCertificates() throws SLCommandException { -     -    ObjectFactory objectFactory = new ObjectFactory(); -     -    InfoboxReadDataAssocArrayType infoboxReadDataAssocArrayType = objectFactory -        .createInfoboxReadDataAssocArrayType(); - -    if (assocArrayResult == ASSOC_ARRAY_READ_KEYS) { - -      List<String> keys = infoboxReadDataAssocArrayType.getKey(); -      keys.addAll(certificates); -       +  @Override +  public String getInfoboxIdentifier() { +    if (infobox != null) { +      return infobox.getIdentifier();      } else { - -      if (certificates != null && !certificates.isEmpty()) { -         -        List<STALRequest> stalRequests = new ArrayList<STALRequest>(); - -        // get certificates -        InfoboxReadRequest infoboxReadRequest; -        for (int i = 0; i < certificates.size(); i++) { -          infoboxReadRequest = new InfoboxReadRequest(); -          infoboxReadRequest.setInfoboxIdentifier(certificates.get(i)); -          stalRequests.add(infoboxReadRequest); -        } - -        requestSTAL(stalRequests); - -        List<X509Certificate> x509Certs = getCertificatesFromResponses(); - -        for (int i = 0; i < certificates.size(); i++) { -          InfoboxAssocArrayPairType infoboxAssocArrayPairType = objectFactory.createInfoboxAssocArrayPairType(); -          infoboxAssocArrayPairType.setKey(certificates.get(i)); -          try { -            infoboxAssocArrayPairType.setBase64Content(x509Certs.get(i).getEncoded()); -          } catch (CertificateEncodingException e) { -            log.error("Failed to encode certificate.", e); -            throw new SLCommandException(4000); -          } -          infoboxReadDataAssocArrayType.getPair().add(infoboxAssocArrayPairType); -        } -         -      } -       +      return null;      } -     -    return new InfoboxReadResultImpl(infoboxReadDataAssocArrayType); -     -  } -   -  @Override -  public String getIdentityLinkDomainId() { -    return identityLinkDomainIdentifier;    }  }
 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 8904eac6..a2b8ac9f 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 @@ -23,8 +23,9 @@ import javax.xml.transform.Templates;  import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadDataAssocArrayType;  import at.buergerkarte.namespaces.securitylayer._1.InfoboxReadResponseType;  import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; +import at.gv.egiz.bku.slcommands.InfoboxReadResult; -public class InfoboxReadResultImpl extends SLResultImpl { +public class InfoboxReadResultImpl extends SLResultImpl implements InfoboxReadResult {    /**     * The <code>InfoboxReadResponse</code> diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java new file mode 100644 index 00000000..6d281686 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateCommandImpl.java @@ -0,0 +1,158 @@ +/* +* 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.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.buergerkarte.namespaces.cardchannel.CommandAPDUType; +import at.buergerkarte.namespaces.cardchannel.ResetType; +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.InfoboxUpdateRequestType; +import at.gv.egiz.bku.slcommands.InfoboxUpdateCommand; +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.SLExceptionMessages; + +public class InfoboxUpdateCommandImpl extends +    SLCommandImpl<InfoboxUpdateRequestType> implements InfoboxUpdateCommand { +   +  private static Log log = LogFactory.getLog(InfoboxUpdateCommandImpl.class); + +  public static final String INFOBOX_IDENTIFIER_CARD_CHANNEL = "CardChannel"; + +  protected String infoboxIdentifier; +   +  protected List<Object> cardChannelScript; +   +  @Override +  public String getInfoboxIdentifier() { +    return infoboxIdentifier; +  } +   +  @Override +  public void init(SLCommandContext ctx, Object request) +      throws SLCommandException { +    super.init(ctx, request); +     +    InfoboxUpdateRequestType req = getRequestValue(); +     +    infoboxIdentifier = req.getInfoboxIdentifier(); +     +    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<Object> 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 }); +    } +     +  } + +  public List<Object> getCardChannelScript() { +    return cardChannelScript; +  } + +  public void setCardChannelScript(List<Object> 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 }); +      } +    } catch (SLCommandException e) { +      return new ErrorResultImpl(e, cmdCtx.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/InfoboxUpdateResultImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java new file mode 100644 index 00000000..15064756 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/InfoboxUpdateResultImpl.java @@ -0,0 +1,43 @@ +/* +* 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 javax.xml.bind.JAXBElement; +import javax.xml.transform.Result; +import javax.xml.transform.Templates; + +import at.buergerkarte.namespaces.securitylayer._1.InfoboxUpdateResponseType; +import at.buergerkarte.namespaces.securitylayer._1.ObjectFactory; +import at.gv.egiz.bku.slcommands.InfoboxUpdateResult; + +public class InfoboxUpdateResultImpl extends SLResultImpl implements +    InfoboxUpdateResult { +   +  protected static JAXBElement<InfoboxUpdateResponseType> RESPONSE; + +  static { +    ObjectFactory factory = new ObjectFactory(); +    InfoboxUpdateResponseType type = factory.createInfoboxUpdateResponseType(); +    RESPONSE = factory.createInfoboxUpdateResponse(type); +  } +   +  @Override +  public void writeTo(Result result, Templates templates) { +    writeTo(RESPONSE, result, templates); +  } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java index 9a3a2984..ed055b69 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/SLCommandImpl.java @@ -16,22 +16,11 @@  */  package at.gv.egiz.bku.slcommands.impl;
 -import java.util.Iterator;
 -import java.util.List;
 -import java.util.NoSuchElementException;
 -
 -import javax.xml.bind.JAXBElement;
 -
 -import org.apache.commons.logging.Log;
 -import org.apache.commons.logging.LogFactory;
 -
 -import at.gv.egiz.bku.slcommands.SLCommand;
 -import at.gv.egiz.bku.slcommands.SLCommandContext;
 -import at.gv.egiz.bku.slexceptions.SLCommandException;
 -import at.gv.egiz.stal.ErrorResponse;
 -import at.gv.egiz.stal.STAL;
 -import at.gv.egiz.stal.STALRequest;
 -import at.gv.egiz.stal.STALResponse;
 +import javax.xml.bind.JAXBElement; + +import at.gv.egiz.bku.slcommands.SLCommand; +import at.gv.egiz.bku.slcommands.SLCommandContext; +import at.gv.egiz.bku.slexceptions.SLCommandException;  /**
   * This class serves as abstract base class for the implementation of a security
 @@ -47,19 +36,18 @@ public abstract class SLCommandImpl<T> implements SLCommand {    /**
     * The <code>SLCommandContext</code> for this <code>SLCommand</code>.
     */
 -  protected SLCommandContext cmdCtx;
 +  protected SLCommandContext cmdCtx; +   +  /** +   * The STAL helper. +   */ +  protected STALHelper stalHelper;
    /**
     * The request element of this command.
     */
    protected JAXBElement<T> request;
 -  /**
 -   * An iterator over the <code>STALResponse</code>s received in
 -   * {@link SLCommandImpl#requestSTAL(List)}.
 -   */
 -  protected Iterator<STALResponse> stalResponses;
 -
    @SuppressWarnings("unchecked")
    @Override
    public void init(SLCommandContext ctx, Object request)
 @@ -67,8 +55,8 @@ public abstract class SLCommandImpl<T> implements SLCommand {      this.request = (JAXBElement<T>) request;
 -    this.cmdCtx = ctx;
 -    assert this.cmdCtx != null;
 +    this.cmdCtx = ctx; +    stalHelper = new STALHelper(cmdCtx.getSTAL());
    }
 @@ -90,73 +78,4 @@ public abstract class SLCommandImpl<T> implements SLCommand {    protected SLCommandContext getCmdCtx() {
      return cmdCtx;
    }
 -
 -  /**
 -   * Calls {@link STAL#handleRequest(List)} with the given
 -   * <code>stalRequests</code>.
 -   * 
 -   * @param stalRequests
 -   * @throws SLCommandException
 -   */
 -     protected void requestSTAL(List<STALRequest> stalRequests) throws SLCommandException {
 -    List<STALResponse> responses = cmdCtx.getSTAL().handleRequest(stalRequests);
 -    if (responses == null) {
 -      Log log = LogFactory.getLog(this.getClass());
 -      log.info("Received no responses from STAL.");
 -      throw new SLCommandException(4000);
 -    } else if (responses.size() != stalRequests.size()) {
 -      Log log = LogFactory.getLog(this.getClass());
 -      log.info("Received invalid count of responses from STAL. Expected "
 -          + stalRequests.size() + ", but got " + responses.size() + ".");
 -      // throw new SLCommandException(4000);
 -    }
 -    stalResponses = responses.iterator();
 -  }
 -
 -  /**
 -   * @return <code>true</code> if there are more {@link STALResponse}s to be
 -   *         fetched with {@link #nextResponse(Class)}, or <code>false</code>
 -   *         otherwise.
 -   */
 -  protected boolean hasNextResponse() {
 -    return (stalResponses != null) ? stalResponses.hasNext() : false;
 -  }
 -
 -  /**
 -   * Returns the next response of type <code>responseClass</code> that has been
 -   * received by {@link #requestSTAL(List)}.
 -   * 
 -   * @param responseClass
 -   *          the response must be an instance of
 -   * @return the next response of type <code>responseClass</code>
 -   * 
 -   * @throws NoSuchElementException
 -   *           if there is no more response
 -   * @throws SLCommandException
 -   *           if the next response is of type {@link ErrorResponse} or not of
 -   *           type <code>responseClass</code>
 -   */
 -  protected STALResponse nextResponse(
 -      Class<? extends STALResponse> responseClass) throws SLCommandException {
 -
 -    if (stalResponses == null) {
 -      throw new NoSuchElementException();
 -    }
 -
 -    STALResponse response = stalResponses.next();
 -
 -    if (response instanceof ErrorResponse) {
 -      throw new SLCommandException(((ErrorResponse) response).getErrorCode());
 -    }
 -
 -    if (!(responseClass.isAssignableFrom(response.getClass()))) {
 -      Log log = LogFactory.getLog(this.getClass());
 -      log.info("Received " + response.getClass() + " from STAL but expected "
 -          + responseClass);
 -      throw new SLCommandException(4000);
 -    }
 -
 -    return response;
 -
 -  }
  }
 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 new file mode 100644 index 00000000..969288c1 --- /dev/null +++ b/bkucommon/src/main/java/at/gv/egiz/bku/slcommands/impl/STALHelper.java @@ -0,0 +1,218 @@ +/* +* 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 iaik.asn1.CodingException; +import iaik.asn1.DerCoder; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import at.gv.egiz.bku.slexceptions.SLCommandException; +import at.gv.egiz.bku.slexceptions.SLExceptionMessages; +import at.gv.egiz.bku.slexceptions.SLRuntimeException; +import at.gv.egiz.idlink.ans1.IdentityLink; +import at.gv.egiz.stal.ErrorResponse; +import at.gv.egiz.stal.InfoboxReadResponse; +import at.gv.egiz.stal.STAL; +import at.gv.egiz.stal.STALRequest; +import at.gv.egiz.stal.STALResponse; + +/** + * A helper class for transmitting {@link STALRequest}s and obtaining their + * respective {@link STALResponse}s. + *  + * @author mcentner + */ +public class STALHelper { + +  /** +   * Logging facility. +   */ +  private static Log log = LogFactory.getLog(STALHelper.class); +   +  /** +   * The STAL implementation. +   */ +  private STAL stal; +   +  /** +   * An iterator over the <code>STALResponse</code>s received in +   * {@link SLCommandImpl#transmitSTALRequest(List)}. +   */ +  protected Iterator<STALResponse> stalResponses; +   +  /** +   * Creates a new instance of this STALHelper with the given +   * <code>stal</code>.  +   *  +   * @param stal the STAL to be used +   */ +  public STALHelper(STAL stal) { +    if (stal == null) { +      throw new NullPointerException("Argument 'stal' must not be null."); +    } +    this.stal = stal; +  } + +  /** +   * Calls {@link STAL#handleRequest(List)} with the given +   * <code>stalRequests</code>. +   *  +   * @param stalRequests +   * @throws SLCommandException +   */ +   public void transmitSTALRequest(List<STALRequest> stalRequests) throws SLCommandException { +    List<STALResponse> responses = stal.handleRequest(stalRequests); +    if (responses == null) { +      Log log = LogFactory.getLog(this.getClass()); +      log.info("Received no responses from STAL."); +      throw new SLCommandException(4000); +    } else if (responses.size() != stalRequests.size()) { +      Log log = LogFactory.getLog(this.getClass()); +      log.info("Received invalid count of responses from STAL. Expected " +          + stalRequests.size() + ", but got " + responses.size() + "."); +      // throw new SLCommandException(4000); +    } +    stalResponses = responses.iterator(); +  } + +  /** +   * @return <code>true</code> if there are more {@link STALResponse}s to be +   *         fetched with {@link #nextResponse(Class)}, or <code>false</code> +   *         otherwise. +   */ +  public boolean hasNextResponse() { +    return (stalResponses != null) ? stalResponses.hasNext() : false; +  } + +  /** +   * Returns the next response of type <code>responseClass</code> that has been +   * received by {@link #transmitSTALRequest(List)}. +   *  +   * @param responseClass +   *          the response must be an instance of +   * @return the next response of type <code>responseClass</code> +   *  +   * @throws NoSuchElementException +   *           if there is no more response +   * @throws SLCommandException +   *           if the next response is of type {@link ErrorResponse} or not of +   *           type <code>responseClass</code> +   */ +  public STALResponse nextResponse( +      Class<? extends STALResponse> responseClass) throws SLCommandException { + +    if (stalResponses == null) { +      throw new NoSuchElementException(); +    } + +    STALResponse response = stalResponses.next(); + +    if (response instanceof ErrorResponse) { +      throw new SLCommandException(((ErrorResponse) response).getErrorCode()); +    } + +    if (!(responseClass.isAssignableFrom(response.getClass()))) { +      Log log = LogFactory.getLog(this.getClass()); +      log.info("Received " + response.getClass() + " from STAL but expected " +          + responseClass); +      throw new SLCommandException(4000); +    } + +    return response; + +  } + +  /** +   * Gets the list of certificates from the next STAL responses. +   *  +   * @return the list of certificates +   *  +   * @throws SLCommandException if getting the list of certificates fails +   */ +  public List<X509Certificate> getCertificatesFromResponses() throws SLCommandException { +     +    List<X509Certificate> certificates = new ArrayList<X509Certificate>(); + +    CertificateFactory certFactory; +    try { +      certFactory = CertificateFactory.getInstance("X509"); +    } catch (CertificateException e) { +      // we should always be able to get an X509 certificate factory +      log.error("CertificateFactory.getInstance(\"X509\") failed.", e); +      throw new SLRuntimeException(e); +    } +     +    InfoboxReadResponse response; +    while(hasNextResponse()) { +      response = (InfoboxReadResponse) nextResponse(InfoboxReadResponse.class); +      byte[] cert = response.getInfoboxValue(); +      try { +        certificates.add((X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(cert))); +      } catch (CertificateException e) { +        log.info("Failed to decode certificate.", e); +        throw new SLCommandException(4000, +            SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, +            new Object[] { "Certificates" }); +      } +    } +     +    return certificates; + +  } +   +  /** +   * Gets the IdentitiyLink form the next STAL response. +   *  +   * @return the IdentityLink +   *  +   * @throws SLCommandException if getting the IdentitiyLink fails +   */ +  public IdentityLink getIdentityLinkFromResponses() throws SLCommandException { + +    // IdentityLink +    InfoboxReadResponse response; +    if (hasNextResponse()) { +      response = (InfoboxReadResponse) nextResponse(InfoboxReadResponse.class); +      byte[] idLink = response.getInfoboxValue(); +      try { +        return new IdentityLink(DerCoder.decode(idLink)); +      } catch (CodingException e) { +        log.info("Failed to decode infobox 'IdentityLink'.", e); +        throw new SLCommandException(4000, +            SLExceptionMessages.EC4000_UNCLASSIFIED_INFOBOX_INVALID, +            new Object[] { "IdentityLink" }); +      } +    } else { +      log.info("No infobox 'IdentityLink' returned from STAL."); +      throw new SLCommandException(4000); +    } +     +  } +   + +} | 
