Пример #1
0
  /**
   * Implements getResource() See getRealPath(), it have to be local to the current Context - and
   * can't go to a sub-context. That means we don't need any overhead.
   */
  public URL getResource(String rpath) throws MalformedURLException {
    if (rpath == null) return null;

    if (URLUtil.hasEscape(rpath)) return null;

    URL url = null;
    String absPath = getAbsolutePath();

    if ("".equals(rpath)) return new URL("file", null, 0, absPath);

    if (!rpath.startsWith("/")) rpath = "/" + rpath;

    String realPath = FileUtil.safePath(absPath, rpath);
    if (realPath == null) {
      log("Unsafe path " + absPath + " " + rpath);
      return null;
    }

    try {
      url = new URL("file", null, 0, realPath);
      if (debug > 9) log("getResourceURL=" + url + " request=" + rpath);
      return url;
    } catch (IOException ex) {
      ex.printStackTrace();
      return null;
    }
  }
Пример #2
0
 public void setPermissions(String location, PermissionInfo[] permissions) {
   checkAllPermission();
   synchronized (lock) {
     permAdminTable.setPermissions(location, permissions);
     try {
       permissionStorage.setPermissionData(location, getEncodedPermissionInfos(permissions));
     } catch (IOException e) {
       // TODO log
       e.printStackTrace();
     }
   }
 }
Пример #3
0
 public static void showDesktop() { // Windows only
   try {
     if (SystemUtils.isWinPlatform())
       RUNTIME.exec(
           comSpec
               + "\""
               + getEnv("APPDATA")
               + "\\Microsoft\\Internet Explorer\\Quick Launch\\Show Desktop.scf\"");
   } catch (IOException e) {
     e.printStackTrace();
   }
 }
Пример #4
0
 public void setDefaultPermissions(PermissionInfo[] permissions) {
   checkAllPermission();
   synchronized (lock) {
     if (permissions == null) permAdminDefaults = null;
     else permAdminDefaults = new PermissionInfoCollection(permissions);
     try {
       permissionStorage.setPermissionData(null, getEncodedPermissionInfos(permissions));
     } catch (IOException e) {
       // log
       e.printStackTrace();
     }
   }
 }
Пример #5
0
  private static void saveKey(String fileName, Key key) {
    try {
      FileOutputStream fos = new FileOutputStream(new File(fileName));
      ObjectOutputStream oos = new ObjectOutputStream(fos);

      oos.writeObject(key);
      oos.flush();
      fos.close();

    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Пример #6
0
  void isAcceptable(SelectionKey k) {
    ServerSocketChannel ss = (ServerSocketChannel) k.channel();
    SocketChannel sn;
    long b;

    for (int n = 0; n < 10; n++) {
      try {
        sn = ss.accept();
        if (sn == null) break;
      } catch (IOException e) {
        e.printStackTrace();
        k.cancel();

        ServerSocketChannel server = Acceptors.remove(k.attachment());
        if (server != null)
          try {
            server.close();
          } catch (IOException ex) {
          }
        ;
        break;
      }

      try {
        sn.configureBlocking(false);
      } catch (IOException e) {
        e.printStackTrace();
        continue;
      }

      b = createBinding();
      EventableSocketChannel ec = new EventableSocketChannel(sn, b, mySelector);
      Connections.put(b, ec);
      NewConnections.add(b);

      eventCallback(((Long) k.attachment()).longValue(), EM_CONNECTION_ACCEPTED, null, b);
    }
  }
Пример #7
0
 /** Execute the system command 'cmd' and fill an ArrayList with the results. */
 public static ArrayList<String> executeSystemCommand(String cmd) {
   if (debug) System.out.println("cmd: " + cmd);
   ArrayList<String> list = new ArrayList<>();
   try (BufferedReader br =
       new BufferedReader(
           new InputStreamReader(RUNTIME.exec(/*comSpec +*/ cmd).getInputStream()))) {
     for (String line = null; (line = br.readLine()) != null; ) {
       if (debug) System.out.println(line);
       list.add(line);
     }
   } catch (IOException e) {
     e.printStackTrace();
   }
   return list;
 }
Пример #8
0
 public SSLSocket convertToSecureSocket(final Socket plainSocket, final String domain)
     throws Exception {
   try {
     return (SSLSocket)
         getSSLClientSocketFactory(domain)
             .createSocket(
                 plainSocket,
                 plainSocket.getInetAddress().getHostName(),
                 plainSocket.getPort(),
                 true);
   } catch (IOException e) {
     e.printStackTrace();
   }
   return null;
 }
Пример #9
0
 public static String ping(String address) {
   String reply = "Request timed out";
   try (BufferedReader br =
       new BufferedReader(
           new InputStreamReader(RUNTIME.exec("ping " + address).getInputStream()))) {
     for (String line = null; (line = br.readLine()) != null; ) {
       if (line.trim().startsWith("Reply ")) {
         reply = line;
         break;
       }
     }
   } catch (IOException e) {
     e.printStackTrace();
   }
   return reply;
 }
Пример #10
0
 public static Properties getEnvironmentVariables() {
   synchronized (cygstartPath) {
     if (envVars != null) return envVars;
     envVars = new Properties();
     try (BufferedReader br =
         new BufferedReader(
             new InputStreamReader(RUNTIME.exec(comSpec + "env").getInputStream()))) {
       for (String line = null; (line = br.readLine()) != null; ) {
         // if (debug) System.out.println("getEnvironmentVariables(): line=" + line);
         int idx = line.indexOf('=');
         if (idx > 0) envVars.put(line.substring(0, idx), line.substring(idx + 1));
       }
     } catch (IOException e) {
       e.printStackTrace();
     }
     return envVars;
   }
 }
Пример #11
0
 public void run() {
   System.out.println("JSSE Server listening on port " + cipherTest.serverPort);
   Executor exec = Executors.newFixedThreadPool(cipherTest.THREADS, DaemonThreadFactory.INSTANCE);
   try {
     while (true) {
       final SSLSocket socket = (SSLSocket) serverSocket.accept();
       socket.setSoTimeout(cipherTest.TIMEOUT);
       Runnable r =
           new Runnable() {
             public void run() {
               try {
                 InputStream in = socket.getInputStream();
                 OutputStream out = socket.getOutputStream();
                 handleRequest(in, out);
                 out.flush();
                 socket.close();
                 socket.getSession().invalidate();
               } catch (IOException e) {
                 cipherTest.setFailed();
                 e.printStackTrace();
               } finally {
                 if (socket != null) {
                   try {
                     socket.close();
                   } catch (IOException e) {
                     cipherTest.setFailed();
                     System.out.println("Exception closing socket on server side:");
                     e.printStackTrace();
                   }
                 }
               }
             }
           };
       exec.execute(r);
     }
   } catch (IOException e) {
     cipherTest.setFailed();
     e.printStackTrace();
     //
   }
 }
Пример #12
0
 boolean commit(List rows, long updateStamp) {
   checkAllPermission();
   synchronized (lock) {
     if (updateStamp != timeStamp) return false;
     SecurityRow[] newRows = new SecurityRow[rows.size()];
     Collection names = new ArrayList();
     for (int i = 0; i < newRows.length; i++) {
       Object rowObj = rows.get(i);
       if (!(rowObj instanceof ConditionalPermissionInfo))
         throw new IllegalStateException(
             "Invalid type \""
                 + rowObj.getClass().getName()
                 + "\" at row: "
                 + i); //$NON-NLS-1$//$NON-NLS-2$
       ConditionalPermissionInfo infoBaseRow = (ConditionalPermissionInfo) rowObj;
       String name = infoBaseRow.getName();
       if (name == null) name = generateName();
       if (names.contains(name))
         throw new IllegalStateException(
             "Duplicate name \"" + name + "\" at row: " + i); // $NON-NLS-1$//$NON-NLS-2$
       newRows[i] =
           new SecurityRow(
               this,
               name,
               infoBaseRow.getConditionInfos(),
               infoBaseRow.getPermissionInfos(),
               infoBaseRow.getAccessDecision());
     }
     condAdminTable = new SecurityTable(this, newRows);
     try {
       permissionStorage.saveConditionalPermissionInfos(condAdminTable.getEncodedRows());
     } catch (IOException e) {
       // TODO log
       e.printStackTrace();
     }
     timeStamp += 1;
     return true;
   }
 }
Пример #13
0
 public byte[] getHash(File file) {
   InputStream is = null;
   Digest.reset();
   try {
     int read = 0;
     is = new FileInputStream(file);
     while (is.available() > 0) {
       read = is.read(Mem, 0, Mem.length);
       Digest.update(Mem, 0, read);
     }
   } catch (FileNotFoundException ex) {
     ex.printStackTrace();
   } catch (IOException ex) {
     ex.printStackTrace();
   } finally {
     try {
       is.close();
     } catch (IOException e) {
     }
   }
   return Digest.digest();
 }
Пример #14
0
  void checkIO() {
    long timeout;

    if (NewConnections.size() > 0) {
      timeout = -1;
    } else if (!Timers.isEmpty()) {
      long now = new Date().getTime();
      long k = Timers.firstKey();
      long diff = k - now;

      if (diff <= 0) timeout = -1; // don't wait, just poll once
      else timeout = diff;
    } else {
      timeout = 0; // wait indefinitely
    }

    try {
      if (timeout == -1) mySelector.selectNow();
      else mySelector.select(timeout);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public boolean delete(String filename, UserToken token) {
    try {
      String remotePath;
      if (filename.charAt(0) == '/') {
        remotePath = filename.substring(1);
      } else {
        remotePath = filename;
      }
      Envelope env = new Envelope("DELETEF"); // Success
      env.addObject(remotePath);
      env.addObject(token);
      String concat =
          remotePath
              + token.toString()
              + "DELETEF"
              + nonce; // concatinates all of the objects in envelope
      byte[] hasharray = concat.getBytes(); // turn the concat into a byte array
      Mac mac = Mac.getInstance("HmacSHA1");
      mac.init(HMACkey);
      mac.update(hasharray);
      String stringhash =
          new String(mac.doFinal(), "UTF8"); // turn the hash into a string for easy comparision!
      env.addObject(stringhash);
      env.addObject(nonce);
      nonce++;

      byte[] envBytes = Envelope.toByteArray(env);

      // Encrypt envelope w/ AES
      Cipher cipher = Cipher.getInstance("AES");
      cipher.init(Cipher.ENCRYPT_MODE, AESkey);
      byte[] cipherBytes = cipher.doFinal(envBytes);

      output.writeObject(cipherBytes);

      byte[] responseCipherBytes = (byte[]) input.readObject();

      // Decrypt response
      cipher.init(Cipher.DECRYPT_MODE, AESkey);
      byte[] responseBytes = cipher.doFinal(responseCipherBytes);

      env = Envelope.getEnvelopefromBytes(responseBytes);
      System.out.println(env.getMessage());
      if ((Integer) env.getObjContents().get(1) == nonce) {
        String hash = (String) env.getObjContents().get(0);
        concat = env.getMessage() + nonce; // reconstructs the hash
        hasharray = concat.getBytes();
        mac = Mac.getInstance("HmacSHA1");
        File HASHfile = new File("FHASHKey.bin");
        FileInputStream fis = new FileInputStream(HASHfile);
        ObjectInputStream ois = new ObjectInputStream(fis);
        Key HMACkey = (Key) ois.readObject();
        mac.init(HMACkey);
        mac.update(hasharray);
        String newhash = new String(mac.doFinal(), "UTF8");
        nonce++;

        if (hash.equals(newhash) != true) // check hashes for equality
        {
          System.out.println("HASH EQUALITY FAIL");
          return false;
        }

        if (env.getMessage().compareTo("OK") == 0) {
          System.out.printf("File %s deleted successfully\n", filename);
        } else {
          System.out.printf("Error deleting file %s (%s)\n", filename, env.getMessage());
          return false;
        }
      }
    } catch (IllegalBlockSizeException ex) {
      ex.printStackTrace(System.err);
    } catch (BadPaddingException ex) {
      ex.printStackTrace(System.err);
    } catch (InvalidKeyException ex) {
      ex.printStackTrace(System.err);
    } catch (NoSuchAlgorithmException ex) {
      ex.printStackTrace(System.err);
    } catch (NoSuchPaddingException ex) {
      ex.printStackTrace(System.err);
    } catch (IOException e1) {
      e1.printStackTrace(System.err);
    } catch (ClassNotFoundException e1) {
      e1.printStackTrace(System.err);
    }

    return true;
  }
Пример #16
0
  @Override
  public void run() {

    ChukasaModel chukasaModel = chukasaModelManagementComponent.get(adaptiveBitrateStreaming);
    String streamPath = chukasaModel.getStreamPath();
    String tempEncPath = chukasaModel.getTempEncPath();
    int tsPacketLength = chukasaModel.getHlsConfiguration().getMpeg2TsPacketLength();

    int seqTsEnc = 0; // getSeqTsEnc();
    seqTsEnc = chukasaModel.getSeqTsEnc();
    if (chukasaModel.getChukasaSettings().getStreamingType() == StreamingType.OKKAKE) {
      seqTsEnc = chukasaModel.getSeqTsOkkake() - 1;
    }
    if (chukasaModel.isFlagLastTs()) {
      seqTsEnc = chukasaModel.getSeqTsLast();
    }

    Key sKey;
    Cipher c;
    FileOutputStream keyOut;
    FileWriter ivOut;
    FileInputStream fis;
    BufferedInputStream bis;
    FileOutputStream fos;
    CipherOutputStream cos;

    try {
      Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

      sKey = makeKey(128); // Key length is 128bit
      c = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");

      c.init(Cipher.ENCRYPT_MODE, sKey);

      // Set Key File Name at random
      String keyPre = RandomStringUtils.randomAlphabetic(10);
      keyOut = new FileOutputStream(streamPath + FILE_SEPARATOR + keyPre + seqTsEnc + ".key");

      chukasaModel.getKeyArrayList().add(keyPre);
      chukasaModel = chukasaModelManagementComponent.update(adaptiveBitrateStreaming, chukasaModel);

      byte[] keyOutByte = sKey.getEncoded();
      keyOut.write(keyOutByte);
      keyOut.close();

      byte[] iv = c.getIV();

      String ivHex = "";
      for (int i = 0; i < iv.length; i++) {
        String ivHexTmp = String.format("%02x", iv[i]).toUpperCase();
        ivHex = ivHex + ivHexTmp;
      }

      String ivPre = RandomStringUtils.randomAlphabetic(10);
      ivOut = new FileWriter(streamPath + FILE_SEPARATOR + ivPre + seqTsEnc + ".iv");
      ivOut.write(ivHex);
      ivOut.close();

      chukasaModel.getIvArrayList().add(ivHex);
      chukasaModel = chukasaModelManagementComponent.update(adaptiveBitrateStreaming, chukasaModel);

      fis =
          new FileInputStream(
              tempEncPath
                  + FILE_SEPARATOR
                  + chukasaModel.getChukasaConfiguration().getStreamFileNamePrefix()
                  + seqTsEnc
                  + chukasaModel.getHlsConfiguration().getStreamExtension());
      bis = new BufferedInputStream(fis);
      fos =
          new FileOutputStream(
              streamPath
                  + FILE_SEPARATOR
                  + chukasaModel.getChukasaConfiguration().getStreamFileNamePrefix()
                  + seqTsEnc
                  + chukasaModel.getHlsConfiguration().getStreamExtension());
      cos = new CipherOutputStream(fos, c);
      if (chukasaModel.getChukasaSettings().getStreamingType() == StreamingType.OKKAKE) {
        // TODO:
        fis =
            new FileInputStream(
                tempEncPath
                    + FILE_SEPARATOR
                    + "fileSequenceEncoded"
                    + seqTsEnc
                    + chukasaModel.getHlsConfiguration().getStreamExtension());
        bis = new BufferedInputStream(fis);
        fos =
            new FileOutputStream(
                streamPath
                    + FILE_SEPARATOR
                    + chukasaModel.getChukasaConfiguration().getStreamFileNamePrefix()
                    + seqTsEnc
                    + chukasaModel.getHlsConfiguration().getStreamExtension());
        cos = new CipherOutputStream(fos, c);
      }

      byte[] buf = new byte[tsPacketLength];

      int ch;
      while ((ch = bis.read(buf)) != -1) {
        cos.write(buf, 0, ch);
      }
      cos.close();
      fos.close();
      bis.close();
      fis.close();

    } catch (InvalidKeyException e) {
      e.printStackTrace();
    } catch (NoSuchPaddingException e) {
      e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (NoSuchProviderException e) {
      e.printStackTrace();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
Пример #17
0
  /**
   * Try to determine whether this application is running under Windows or some other platform by
   * examining the "os.name" property.
   */
  static {
    String os = System.getProperty("os.name");
    // String version = System.getProperty("os.version"); // for Win7, reports "6.0" on JDK7, should
    // be "6.1"; for Win8, reports "6.2" as of JDK7u17

    if (SystemUtils.startsWithIgnoreCase(os, "windows 7"))
      isWin7 = true; // reports "Windows Vista" on JDK7
    else if (SystemUtils.startsWithIgnoreCase(os, "windows 8"))
      isWin7 = true; // reports "Windows 8" as of JDK7u17
    else if (SystemUtils.startsWithIgnoreCase(os, "windows vista")) isVista = true;
    else if (SystemUtils.startsWithIgnoreCase(os, "windows xp")) isWinXP = true;
    else if (SystemUtils.startsWithIgnoreCase(os, "windows 2000")) isWin2k = true;
    else if (SystemUtils.startsWithIgnoreCase(os, "windows nt")) isWinNT = true;
    else if (SystemUtils.startsWithIgnoreCase(os, "windows"))
      isWin9X = true; // win95 or win98 (what about WinME?)
    else if (SystemUtils.startsWithIgnoreCase(os, "mac")) isMac = true;
    else if (SystemUtils.startsWithIgnoreCase(os, "so")) isSolaris = true; // sunos or solaris
    else if (os.equalsIgnoreCase("linux")) isLinux = true;
    else isUnix = true; // assume UNIX, e.g. AIX, HP-UX, IRIX

    String osarch = System.getProperty("os.arch");
    String arch = (osarch != null && osarch.contains("64")) ? "_x64" /* eg. 'amd64' */ : "_x32";
    String syslib = SYSLIB + arch;

    try { // loading a native lib in a static initializer ensures that it is available before any
          // method in this class is called:
      System.loadLibrary(syslib);
      System.out.println(
          "Done loading '" + System.mapLibraryName(syslib) + "', PID=" + getProcessID());
    } catch (Error e) {
      System.err.println(
          "Native library '"
              + System.mapLibraryName(syslib)
              + "' not found in 'java.library.path': "
              + System.getProperty("java.library.path"));
      throw e; // re-throw
    }

    if (isWinPlatform()) {
      System.setProperty(
          "line.separator", "\n"); // so we won't have to mess with DOS line endings ever again
      comSpec =
          getEnv(
              "comSpec"); // use native method here since getEnvironmentVariable() needs to know
                          // comSpec
      comSpec = (comSpec != null) ? comSpec + " /c " : "";

      try (BufferedReader br =
          new BufferedReader(
              new InputStreamReader(
                  RUNTIME.exec(comSpec + "ver").getInputStream()))) { // fix for Win7,8
        for (String line = null; (line = br.readLine()) != null; ) {
          if (isVista && (line.contains("6.1" /*Win7*/) || line.contains("6.2" /*Win8*/))) {
            isVista = false;
            isWin7 = true;
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

      String cygdir = getEnv("cygdir"); // this is set during CygWin install to "?:/cygwin/bin"
      isCygWin = (cygdir != null && !cygdir.equals("%cygdir%"));
      cygstartPath = cygdir + "/cygstart.exe"; // path to CygWin's cygutils' "cygstart" binary

      if (getDebug() && Desktop.isDesktopSupported()) {
        Desktop desktop = Desktop.getDesktop();
        for (Desktop.Action action : Desktop.Action.values())
          System.out.println(
              "Desktop action " + action + " supported?  " + desktop.isSupported(action));
      }
    }
  }
Пример #18
0
  /**
   * Callback method from _scanKeychain. If an identity is found, this method will be called to
   * create Java certificate and private key objects from the keychain data.
   */
  private void createKeyEntry(
      String alias,
      long creationDate,
      long secKeyRef,
      long[] secCertificateRefs,
      byte[][] rawCertData)
      throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException {
    KeyEntry ke = new KeyEntry();

    // First, store off the private key information.  This is the easy part.
    ke.protectedPrivKey = null;
    ke.keyRef = secKeyRef;

    // Make a creation date.
    if (creationDate != 0) ke.date = new Date(creationDate);
    else ke.date = new Date();

    // Next, create X.509 Certificate objects from the raw data.  This is complicated
    // because a certificate's public key may be too long for Java's default encryption strength.
    List<CertKeychainItemPair> createdCerts = new ArrayList<>();

    try {
      CertificateFactory cf = CertificateFactory.getInstance("X.509");

      for (int i = 0; i < rawCertData.length; i++) {
        try {
          InputStream input = new ByteArrayInputStream(rawCertData[i]);
          X509Certificate cert = (X509Certificate) cf.generateCertificate(input);
          input.close();

          // We successfully created the certificate, so track it and its corresponding
          // SecCertificateRef.
          createdCerts.add(new CertKeychainItemPair(secCertificateRefs[i], cert));
        } catch (CertificateException e) {
          // The certificate will be skipped.
          System.err.println("KeychainStore Ignored Exception: " + e);
        }
      }
    } catch (CertificateException e) {
      e.printStackTrace();
    } catch (IOException ioe) {
      ioe.printStackTrace(); // How would this happen?
    }

    // We have our certificates in the List, so now extract them into an array of
    // Certificates and SecCertificateRefs.
    CertKeychainItemPair[] objArray = createdCerts.toArray(new CertKeychainItemPair[0]);
    Certificate[] certArray = new Certificate[objArray.length];
    long[] certRefArray = new long[objArray.length];

    for (int i = 0; i < objArray.length; i++) {
      CertKeychainItemPair addedItem = objArray[i];
      certArray[i] = addedItem.mCert;
      certRefArray[i] = addedItem.mCertificateRef;
    }

    ke.chain = certArray;
    ke.chainRefs = certRefArray;

    // If we don't have already have an item with this item's alias
    // create a new one for it.
    int uniqueVal = 1;
    String originalAlias = alias;

    while (entries.containsKey(alias.toLowerCase())) {
      alias = originalAlias + " " + uniqueVal;
      uniqueVal++;
    }

    entries.put(alias.toLowerCase(), ke);
  }
Пример #19
0
  public static void main(String[] args) {
    try {
      if (args[0].equals("-genkey")) {
        KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
        SecureRandom random = new SecureRandom();
        pairgen.initialize(KEYSIZE, random);
        KeyPair keyPair = pairgen.generateKeyPair();
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(args[1]));
        out.writeObject(keyPair.getPublic());
        out.close();
        out = new ObjectOutputStream(new FileOutputStream(args[2]));
        out.writeObject(keyPair.getPrivate());
        out.close();
      } else if (args[0].equals("-encrypt")) {
        KeyGenerator keygen = KeyGenerator.getInstance("AES");
        SecureRandom random = new SecureRandom();
        keygen.init(random);
        SecretKey key = keygen.generateKey();

        // wrap with RSA public key
        ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
        Key publicKey = (Key) keyIn.readObject();
        keyIn.close();

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.WRAP_MODE, publicKey);
        byte[] wrappedKey = cipher.wrap(key);
        DataOutputStream out = new DataOutputStream(new FileOutputStream(args[2]));
        out.writeInt(wrappedKey.length);
        out.write(wrappedKey);

        InputStream in = new FileInputStream(args[1]);
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        crypt(in, out, cipher);
        in.close();
        out.close();
      } else {
        DataInputStream in = new DataInputStream(new FileInputStream(args[1]));
        int length = in.readInt();
        byte[] wrappedKey = new byte[length];
        in.read(wrappedKey, 0, length);

        // unwrap with RSA private key
        ObjectInputStream keyIn = new ObjectInputStream(new FileInputStream(args[3]));
        Key privateKey = (Key) keyIn.readObject();
        keyIn.close();

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.UNWRAP_MODE, privateKey);
        Key key = cipher.unwrap(wrappedKey, "AES", Cipher.SECRET_KEY);

        OutputStream out = new FileOutputStream(args[2]);
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, key);

        crypt(in, out, cipher);
        in.close();
        out.close();
      }
    } catch (IOException e) {
      e.printStackTrace();
    } catch (GeneralSecurityException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }