

import java.util.*;
import java.io.*;

public class Sig {

	private static final String keystore = "/home/rose/src/email/";

	public Sig() {
	
	}
	
	private String md5() throws Exception {
		Runtime runtime = Runtime.getRuntime();
	
		Process proc = runtime.exec("md5sum");
		
		OutputStream os = proc.getOutputStream();
		for(int b = System.in.read(); b != -1; b = System.in.read()) {
			os.write(b);
		}
		os.close();
		
		proc.waitFor();
		
		InputStream is = proc.getInputStream();
		InputStreamReader isr2 = new InputStreamReader(is);
		BufferedReader br2 = new BufferedReader(isr2);
		String md5 = br2.readLine();

		String parts[] = md5.split(" ");		
		return parts[0];
	}
	
	public void verify(String keyfile) throws Exception {
		Runtime runtime = Runtime.getRuntime();
	
		Process proc = runtime.exec("openssl rsautl -verify -inkey " + keyfile + " -pubin");
		
		OutputStream os = proc.getOutputStream();
		
		InputStreamReader isr = new InputStreamReader(System.in);
		BufferedReader br = new BufferedReader(isr);
		String sig = br.readLine();
		String ints[] = sig.split(":");
		byte bytes[] = new byte[ints.length];
		for(int i = 0; i < bytes.length; i++) {
			bytes[i] = (byte) Integer.parseInt(ints[i]);
		}
		os.write(bytes);
		os.close();
		
		proc.waitFor();
		
		InputStream is = proc.getInputStream();
		InputStreamReader isr2 = new InputStreamReader(is);
		BufferedReader br2 = new BufferedReader(isr2);
		String result = br2.readLine();
		//System.out.println(br2.readLine());

		String parts[] = result.split(" ");
		System.out.println(parts[0]);
	}
	
	public void sign(String keyfile) throws Exception {

		Runtime runtime = Runtime.getRuntime();
	
		Process proc = runtime.exec("openssl rsautl -sign -inkey " + keyfile);
		
		OutputStream os = proc.getOutputStream();
		os.write(md5().getBytes());
		os.write((new String(" ")).getBytes());
		os.write(Integer.toString((int) (Math.random() * 999999)).getBytes());
		os.close();
		
		proc.waitFor();
		
		InputStream is = proc.getInputStream();
		boolean first = true;
		while(is.available() > 0) {
				int b = is.read();
				if(first) {
					first = false;
				} else {
					System.out.print(":");
				}
				System.out.print(Integer.toString(b));
		}
		
	}
	
	public String getPrivKeyFile(String email) throws Exception {

		String user[] = email.split("@");

		String keystore = "/home/" + user[0];

		String keyfile = keystore + "/.sig.priv";
		
		return keyfile;
	}

	public String getPubKeyFile(String email) throws Exception {

		Runtime runtime = Runtime.getRuntime();

		Process proc = runtime.exec("/home/rose/src/email/digmail.pl " + email);
		proc.waitFor();

		InputStream is = proc.getInputStream();  
                InputStreamReader isr2 = new InputStreamReader(is); 
                BufferedReader br2 = new BufferedReader(isr2);
                String mailhost = br2.readLine();

		String keyfile = "/tmp/" + email;
                return keyfile;
	}

	public static void main(String args[]) throws Exception {
	
		Sig sig = new Sig();
		
		if(args[0].equals("sign")) {
			sig.sign(sig.getPrivKeyFile(args[1]));
		} else if(args[0].equals("verify")) {
			sig.verify(sig.getPubKeyFile(args[1]));
		} else if(args[0].equals("md5")) {
			System.out.println(sig.md5());
		}
	}

}

