//package IM;

import java.io.*;
import java.security.*;
import java.math.BigInteger;

class Register {
    public static void main(String args[]) {
        try {
            if (args.length < 1) {
                System.out.println("Usage: register <username>");
                return;
            }
            String username = args[0];

            String privatefile = username + ".priv";
            String publicfile = username + ".pub";

            //You'll need to load the CA's private key "ca.priv" at some stage

            //TODO:
            //1. Generate user's private key (e.g. "alice.priv").
            //2. Generate user's public key and certificate (e.g. "alice.pub").

            helper_register(username);


        } catch (Exception e) {
            System.out.print("Error\n");
        }

    }

    public static void helper_register(String username) {
        try {
            PrivateKey privateKey = null;
            PublicKey publicKey = null;

            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(1024);
            KeyPair keypair = keyGen.generateKeyPair();
            privateKey = keypair.getPrivate();
            publicKey = keypair.getPublic();


            //read CA's private key from file and sign (username,public key)
            PrivateKey CA_PrivateKey = Helper.readPrivateKey("ca");
            SignedObject certificate = null;
            Signature sig = Signature.getInstance(Helper.RSA_SIGN);
            UserKeyPair pair = new UserKeyPair(username,publicKey);
            certificate = new SignedObject(pair, CA_PrivateKey, sig);


            //private key file for user
            FileOutputStream fos = new FileOutputStream(username + ".priv");
            ObjectOutputStream objout = new ObjectOutputStream(fos);
            objout.writeObject(privateKey);
            objout.close();
            fos.close();

            //public key file for user, contains signature and public key
            fos = new FileOutputStream(username + ".pub");
            objout = new ObjectOutputStream(fos);
            objout.writeObject(certificate);
            objout.close();
            fos.close();

            //Here we generate public and private keys for redactive signatures
            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
            BigInteger p = BigInteger.probablePrime(512,sr);
            BigInteger q = BigInteger.probablePrime(512,sr);
            BigInteger N = p.multiply(q);
            sr = SecureRandom.getInstance("SHA1PRNG");

            //Here we specify a as a 64 bytes number
            byte[] rawA = new byte[64];
            sr.nextBytes(rawA);
            BigInteger a = new BigInteger(rawA);


            System.out.println("p=" + p.toString(10));
            System.out.println("q=" + q.toString(10));
            System.out.println("a=" + a.toString(10));

            //Now p, q are private key, and N, a are public key.
            //Write private key to file;
            fos = new FileOutputStream(username + ".rdpriv");
            objout = new ObjectOutputStream(fos);
            objout.writeObject(p);
            objout.writeObject(q);
            fos.close();
            objout.close();

            //Write public key to file;
            UserKeyPair_RD rd = new UserKeyPair_RD(a,N,username);
            SignedObject certificate_RD = new SignedObject(rd, CA_PrivateKey, sig);
            fos = new FileOutputStream(username + ".rdpublic");
            objout = new ObjectOutputStream(fos);
            objout.writeObject(certificate_RD);
            fos.close();
            objout.close();


        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }

    }


}
