/**
   * Speichert die PIN temporaer fuer diese Session.
   *
   * @param passport der Passport.
   * @param pin die PIN.
   * @throws Exception
   */
  private static void setCachedPIN(HBCIPassport passport, String pin) throws Exception {
    String key = getCacheKey(passport);

    // Kein Key, dann muessen wir nicht cachen
    if (key == null) return;

    ByteArrayInputStream bis = new ByteArrayInputStream(pin.getBytes());
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Application.getSSLFactory().encrypt(bis, bos);
    byte[] crypted = bos.toByteArray();

    if (Settings.getCachePin()) {
      pinCache.put(key, crypted);
    }

    // Permanentes Speichern der PIN gibts nur bei PIN/TAN, da dort ueber
    // die TAN eine weitere Autorisierung bei der Ausfuehrung von Geschaeftsvorfaellen
    // mit Geldfluss stattfindet. Bei DDV/RDH koennte man sonst beliebig Geld
    // transferieren, ohne jemals wieder nach einem Passwort gefragt zu werden.
    if (Settings.getStorePin() && (passport instanceof HBCIPassportPinTan)) {
      // Nicht direkt das Byte-Array speichern sondern einen Base64-String.
      // Grund: Bei einem Byte-Array wuerde der XML-Serializer fuer jedes
      // Byte ein einzelnes XML-Element anlegen und damit das Wallet aufblasen
      Settings.getWallet().set(key, Base64.encode(crypted));
    }
  }
  /**
   * Prueft, ob eine gespeicherte PIN fuer diesen Passport vorliegt.
   *
   * @param passport der Passport.
   * @return die PIN oder null, wenn keine gefunden wurde.
   * @throws Exception
   */
  private static String getCachedPIN(HBCIPassport passport) throws Exception {
    String key = getCacheKey(passport);

    // Kein Key - dann brauchen wir auch nicht im Cache schauen
    if (key == null) return null;

    byte[] data = null;

    // Cache checken
    if (Settings.getCachePin()) {
      data = pinCache.get(key);
    }

    // Wenn wir noch nichts im Cache haben, schauen wir im Wallet - wenn das erlaubt ist
    if (data == null && Settings.getStorePin() && (passport instanceof HBCIPassportPinTan)) {
      String s = (String) Settings.getWallet().get(key);
      if (s != null) {
        data = Base64.decode(s);

        // Wenn diese Meldung im Log erscheint, gibts keinen Support mehr von mir.
        // Wer die PIN permament speichert, tut das auf eigenes Risiko
        Logger.info("pin loaded from wallet");
        // Uebernehmen wir gleich in den Cache, damit wir beim
        // naechsten Mal direkt im Cache schauen koennen und nicht
        // mehr im Wallet
        pinCache.put(key, data);
      }
    }

    // Haben wir Daten?
    if (data != null) {
      ByteArrayInputStream bis = new ByteArrayInputStream(data);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      Application.getSSLFactory().decrypt(bis, bos);
      String s = bos.toString();
      if (s != null && s.length() > 0) return s;
    }

    return null;
  }
 /** @see de.willuhn.datasource.serialize.AbstractXmlIO.Value#unserialize(java.lang.String) */
 public Object unserialize(String s) throws IOException {
   if (s == null || s.length() == 0) return null;
   return Base64.decode(s);
 }
 /** @see de.willuhn.datasource.serialize.AbstractXmlIO.Value#serialize(java.lang.Object) */
 public String serialize(Object o) throws IOException {
   if (o == null) return "";
   if (!(o instanceof byte[])) throw new IOException("unable to serialize " + o);
   return Base64.encode((byte[]) o);
 }