/*
 * Written by Dawid Kurzyniec and released to the public domain, as explained
 * at http://creativecommons.org/licenses/publicdomain
 */

package edu.emory.mathcs.util.security;

import java.security.*;
import java.security.spec.*;

/**
 * Utility methods to generate and manipulate keys.
 *
 * @see Key
 * @see KeyPair
 *
 * @author Dawid Kurzyniec
 * @version 1.0
 */

public class KeyUtils {

    private KeyUtils() {}

    /**
     * Generates an 1024-bit RSA key pair.
     * @return newly generated RSA key pair.
     */
    public static KeyPair generateRSAKeyPair() {
        return generateRSAKeyPair(1024);
    }

    /**
     * Generates RSA key pair of the specified size.
     *
     * @param keysize the RSA key size
     * @return newly generated RSA key pair.
     */
    public static KeyPair generateRSAKeyPair(int keysize) {
        try {
            KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
            gen.initialize(keysize);
            return gen.generateKeyPair();
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("FATAL: RSA not supported", e);
        }
    }

    /**
     * Decodes the RSA public key out of its X.509 encoding.
     *
     * @param encoded X.509 encoding of an RSA public key
     * @return the decoded public key
     */
    public static PublicKey decodeRSAPublicKey(byte[] encoded) {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
        try {
            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePublic(spec);
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("FATAL: RSA not supported", e);
        }
        catch (InvalidKeySpecException e) {
            throw new RuntimeException("FATAL: RSA does not support X509 encoding", e);
        }
    }

    /**
     * Generates an 1024-bit DSA key pair.
     * @return newly generated DSA key pair.
     */
    public static KeyPair generateDSAKeyPair() {
        return generateDSAKeyPair(1024);
    }

    /**
     * Generates DSA key pair of the specified size.
     *
     * @param keysize the DSA key size
     * @return newly generated DSA key pair.
     */
    public static KeyPair generateDSAKeyPair(int keysize) {
        try {
            KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
            gen.initialize(keysize);
            return gen.generateKeyPair();
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("FATAL: DSA not supported", e);
        }
    }

    /**
     * Decodes the DSA public key out of its X.509 encoding.
     *
     * @param encoded X.509 encoding of an DSA public key
     * @return the decoded public key
     */
    public static PublicKey decodeDSAPublicKey(byte[] encoded) {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded);
        try {
            KeyFactory kf = KeyFactory.getInstance("DSA");
            return kf.generatePublic(spec);
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("FATAL: DSA not supported", e);
        }
        catch (InvalidKeySpecException e) {
            throw new RuntimeException("FATAL: DSA does not support X509 encoding", e);
        }
    }
}
