package org.cryptonit.cloud.keystore;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.PKCS8EncodedKeySpec;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.util.Base64;
import org.cryptonit.cloud.Database;
import org.cryptonit.cloud.interfaces.KeyStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SqlKeyStore implements KeyStore {
    private static final Logger LOGGER = LoggerFactory.getLogger(SqlKeyStore.class);
    private static final SecureRandom random = new SecureRandom();
    Database database;

    public SqlKeyStore(Database database) throws Exception {
        this.database = database;
    }

    private String generateKeyPair(String domain, KeyParameters params) throws Exception {
        KeyFactory keyFactory;
        KeyPair kp;
        if(params.getAlgorithm().equalsIgnoreCase("RSA")) {
            keyFactory = KeyFactory.getInstance("RSA", "BC");
            KeyPairGenerator rsaKeyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
            rsaKeyPairGenerator.initialize(params.getSize(), random);
            kp = rsaKeyPairGenerator.generateKeyPair();
        } else {
            return null;
        }

        byte[] buf = keyFactory.getKeySpec(kp.getPrivate(), PKCS8EncodedKeySpec.class).getEncoded();
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(kp.getPublic().getEncoded());
        byte[] digest = md.digest();

        String keyId = String.format("%064x", new java.math.BigInteger(1, digest));

        Connection c = database.getConnection();
        CallableStatement cs = c.prepareCall("INSERT INTO keystore(domain, keyId, type, created, private, public) " + 
                "VALUES (?, ?, ?, NOW(), ?, ?)");
        cs.setString(1, domain);
        cs.setString(2, keyId);
        cs.setString(3, params.getAlgorithm());
        cs.setString(4, Base64.getEncoder().encodeToString(buf));
        cs.setString(5, Base64.getEncoder().encodeToString(kp.getPublic().getEncoded()));
        cs.execute();

        return keyId;
    }
    
    @Override
    public String generateKey(String domain, KeyParameters params) {
        String r = null;
        try {
            r = generateKeyPair(domain, params);
        } catch(Exception e) {
            LOGGER.error("Error generating key", e);
        }
        return r;
    }

    @Override
    public PrivateKey getPrivateKey(String domain, String keyIdentifier) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public PublicKey getPublicKey(String domain, String keyIdentifier) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

@@ -405,16 +405,63 @@
 Base64;%0A
+import org.bouncycastle.jce.ECNamedCurveTable;%0A
 import o
@@ -1400,24 +1400,412 @@
 eKeyPair();%0A
+        %7D else if (params.getAlgorithm().equalsIgnoreCase(%22EC%22)) %7B%0A            KeyPairGenerator ecKeyPairGenerator = KeyPairGenerator.getInstance(%22ECDSA%22, %22BC%22);%0A            keyFactory = KeyFactory.getInstance(%22EC%22, %22BC%22);%0A            ecKeyPairGenerator.initialize(ECNamedCurveTable.getParameterSpec(params.getParameter()), random);%0A            kp = ecKeyPairGenerator.generateKeyPair();%0A
         %7D el

Add support for EC keys