/*
 * DSASignGen.java
 *
 * Created on August 31, 2003, 4:20 PM
 */

/**
 *
 * @author  mandar
 */
import java.io.*;
import java.security.*;
import java.util.*;
import java.sql.*;

class DSASignGen {
    
    public static void main(String args[]) {
        if(args.length!=1){
            System.out.println("Usage: DSASignGen <name_of_file_to_sign>");
            System.exit(0);
        }
        try{
            String algo = "DSA";
            String Hashfn = "SHA1withDSA";
            String DigestAlgo = "SHA1";
	    int KeySize = 1024;
            
            /************************* BEGIN Generate a key pair ***************************/
            KeyPairGenerator keygen = KeyPairGenerator.getInstance(algo);
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG","SUN");
            keygen.initialize(KeySize,random);
            KeyPair keypair = keygen.generateKeyPair();
            PrivateKey privatekey = keypair.getPrivate();
            PublicKey publickey = keypair.getPublic();
            System.out.println("Keys Generated..");
            
            /************* Create a Signature object and initialize it with private key **************/
            Signature dsa = Signature.getInstance(Hashfn);
            dsa.initSign(privatekey);
            
            /************************* Get the data from file***************************/
            System.out.println("Getting data from file : args[0]");
            FileInputStream fis = new FileInputStream(args[0]);
            BufferedInputStream bis = new BufferedInputStream(fis);
            
            long start_time = getCurrentTime();            
            byte buffer[] = new byte[1024];
            int length;
            while(bis.available() != 0){
                length = bis.read(buffer);
                dsa.update(buffer,0,length);
            }
            bis.close();
            
            
            /**************************** Signing data *******************************/
            System.out.println("Signing data ..");
            byte[] realsign = dsa.sign();
            long end_time = getCurrentTime();
            System.out.println("Time required : "+(end_time-start_time));
            
                        
            /************************* Digest calculation ***************************/
            System.out.println("Generating Digest ..");
            start_time = getCurrentTime();
            MessageDigest algorithm = MessageDigest.getInstance(DigestAlgo);
            algorithm.reset();
            algorithm.update(buffer);
            
            byte digest[] = algorithm.digest();
            end_time = getCurrentTime();
            System.out.println("Time required : "+(end_time-start_time));
            FileOutputStream digestfile = new FileOutputStream(args[0]+"."+DigestAlgo+"digest");
            digestfile.write(digest);
            digestfile.close();
            
            
            /*************************** Verifying Signature *************************/ 
            System.out.println("Verifying Signature ..");
            Signature sig = Signature.getInstance(Hashfn);
            // To verify the data, you must initialize the Signature with the sender's PublicKey. Normally, this would be acquired from a Certificate (Certificate.getPublicKey()), which will be described shortly. However, if everything were done within the same program, you would acquire it from the generated KeyPair. 
            
            start_time = getCurrentTime();
            sig.initVerify(publickey);
            // Finally, using the message content and digest, verify the data: 
	    fis = new FileInputStream(args[0]);
            bis = new BufferedInputStream(fis);
            
            start_time = getCurrentTime();            
            while(bis.available() != 0){
                length = bis.read(buffer);
                sig.update(buffer,0,length);
            }
            bis.close();

            if (sig.verify(realsign)) {
                System.out.println ("Valid");
            } else {
                System.out.println ("Invalid");
            }
            end_time = getCurrentTime();
            System.out.println("Time required : "+(end_time-start_time));
            
            /*********** Save signature in a file *************/
            FileOutputStream sigfos = new FileOutputStream(args[0]+"."+algo+"signed");
            sigfos.write(realsign);
            sigfos.close();
            /*********** Save Public key in a file *************/
            FileOutputStream pubkeyfos = new FileOutputStream(args[0]+"."+algo+"public_key");
            pubkeyfos.write(publickey.getEncoded());
            pubkeyfos.close();
            /*********** Save Private key in a file *************/
            FileOutputStream prikeyfos = new FileOutputStream(args[0]+"."+algo+"private_key");
            prikeyfos.write(privatekey.getEncoded());
            prikeyfos.close();
            System.out.println("Done.");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static long getCurrentTime() {
        java.util.Date date=Calendar.getInstance().getTime();
        Timestamp a=new Timestamp(date.getTime());
        long currentTime=Calendar.getInstance().getTimeInMillis();
        //System.out.println("Time: "+currentTime);
        return currentTime;
    }
}
