/*

(C) Copyright 2008.  All rights reserved.
Matthew William Coan

This uses Cryptix 3.2 java class library to 
3DES encrypt/decrypt a file with one private key.

java -classpath .:cryptix32.jar cryptix.provider.Install

Password protect the 3DES key.

Author: Matthew William Coan
Version: Tue Nov  6 13:31:29 EST 2007

*/

import java.io.*;
import java.security.*;
import sun.misc.*;
import xjava.security.*;
import cryptix.provider.key.*;

public class SecretWriting {
   private static int size = 0;

   public static void usage() {
      System.err.println("Usage: SecretWriting [<key-file>] -e | -d <input-data-file> <output-data-file>");
      System.exit(1);
   }

   public static byte[] read64bit(DataInputStream in) 
   throws IOException {
      byte block[] = new byte[8];

      for(int i = 0; i < 8; i++) {
         block[i] = (byte)('\0');
      }

      boolean error = false;
      int ch, i;

      for(i = 0; i < 8; i++) {
         ch = in.read();

         if(ch < 0) {
            if(i == 0) {
               error = true;
            }

            break;            
         }

         block[i] = (byte)(ch);
      }

      size = i;

      if(error) {
         block = null;
      }

      return block;
   }

   public static void main(String args[]) throws Exception {
      String keyFileName = "SecretKey.ser";

      if(args.length != 4 && args.length != 3) {
         usage();
      }

      if(args.length == 4) {
         keyFileName = args[0];

         for(int i = 1; i < args.length; i++) {
            args[i - 1] = args[i];
         }
      }

      java.security.Security.addProvider(new cryptix.provider.Cryptix());

      Key key;

      try {
         ObjectInputStream in = new ObjectInputStream(
         new FileInputStream(keyFileName));

         key = (Key)in.readObject();

         in.close();
      }
      catch (FileNotFoundException fnf) {
         KeyGenerator generator = KeyGenerator.getInstance(
         "DES-EDE3");
 
         generator.initialize(new SecureRandom());

         key = generator.generateKey();

         ObjectOutputStream out = new ObjectOutputStream(
            new FileOutputStream("SecretKey.ser"));

         out.writeObject(key);

         out.flush();

         out.close();
      }

      Cipher cipher = Cipher.getInstance(
      "DES-EDE3/CBC/PKCS#5", "Cryptix");

      String inputfile = args[1];

      if(args[0].compareTo("-e") == 0) {
         cipher.initEncrypt(key);

         DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(inputfile))); 

         byte[] stringBytes = null;

         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(args[2])));

         while((stringBytes = read64bit(in)) != null) {
            byte[] temp = new byte[size];

            for(int x = 0; x < size; x++) {
               temp[x] = stringBytes[x];
            }

            stringBytes = temp;

            byte[] raw = cipher.doFinal(stringBytes);

            BASE64Encoder encoder = new BASE64Encoder();

            String base64 = encoder.encode(raw);

            out.println(base64);

            out.flush();
         }

         out.close();

         in.close();
      }
      else if(args[0].compareTo("-d") == 0) {
         cipher.initDecrypt(key);

         BASE64Decoder decoder = new BASE64Decoder();

         BufferedReader in = new BufferedReader(new FileReader(inputfile));

         DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(args[2])));

         String line = null;

         while((line = in.readLine()) != null) {
            byte[] raw = decoder.decodeBuffer(line);

            byte[] stringBytes = cipher.doFinal(raw);

            out.write(stringBytes, 0, stringBytes.length);

            out.flush();
         }

         out.close();

         in.close();
      }
      else {
         usage();
      }

      System.exit(0);
   }
}

