package com.millipad.util;

import java.rmi.*;
import javax.crypto.*;
import java.security.*;
import java.security.spec.*;

/**
 * Allows for distribution of SecretKeys.  This class is handy for RMI calls.
 */
public class KeyDistributor {

	//server
	PublicKey pk;
	String algorithm;
	AlgorithmParameterSpec spec;
	RemoteBlockingStack resultStack;
	PublicKey input;

	/**
	 * the resultStack must be exported and unexported manually
	 * the owner of the stack will receive the generators public key.
	 * @param resultStack the stack that the remote listener will be accepting public keys
	 */
	public KeyDistributor(PublicKey input, String algorithm, AlgorithmParameterSpec spec,
        RemoteBlockingStack resultStack) {
		this.input = input;
		this.algorithm = algorithm;
		this.spec = spec;
		this.resultStack = resultStack;
		}

	/**
	 * server call
	 * blocks on key generation
	 */
	public synchronized PublicKey getPublicKey(long timeout) {
		try {
			if(pk==null) pk = (PublicKey )resultStack.pop(timeout);
			return pk;
			}
		catch(RemoteException e) {
			}
		return null;
		}

	/**
	 * called by the client to generate keys
	 */
	public Key generate() {
                try {
                        String dh = "DiffieHellman";
                        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(dh);
                        keyGen.initialize(spec);
                        KeyPair pair = keyGen.generateKeyPair();
			//rmi call
			resultStack.push(pair.getPublic());
                        KeyAgreement mediator = KeyAgreement.getInstance(dh);
                        mediator.init(pair.getPrivate());
                        mediator.doPhase(input, true);
                        return mediator.generateSecret(algorithm);
                        }
                catch(Exception e) {e.printStackTrace();}
                return null;
                }
	}

