import iaik.asn1.structures.Name;
import iaik.pkcs.pkcs11.provider.IAIKPkcs11;
import iaik.pkcs.pkcs12.CertificateBag;
import iaik.pkcs.pkcs12.KeyBag;
import iaik.pkcs.pkcs12.PKCS12;
import iaik.security.provider.IAIK;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Properties;

/**
 * @author Administrator
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class ExportECDSA {

	public static void main(String[] args) throws Exception {
		iaik.security.provider.IAIK.addAsJDK14Provider();
        iaik.security.ecc.provider.ECCProvider.addAsProvider();
		
		PKCS12 input = new PKCS12(new FileInputStream("C:\\eclipse\\workspace\\spss.server\\data\\deploy\\conf\\moa-spss\\keys\\ecc(ego).p12"));
		input.decrypt("ego".toCharArray());
		KeyBag newkb = input.getKeyBag();
		System.out.println("KeyNew:"+newkb.getFriendlyName());
		System.out.println(newkb.getPrivateKey());
		CertificateBag newcbs[] = input.getCertificateBags();
		System.out.println(newcbs.length);
		System.out.println("CertNew:"+newcbs[0].getFriendlyName());
		System.out.println(newcbs[0]);
		System.out.println(newcbs[0].getCertificate().getSerialNumber().toString());
		System.out.println(((Name)newcbs[0].getCertificate().getSubjectDN()).getRFC2253String());
	}

	public static void main2(String[] args) throws Exception {
		
		
		
		/* Export P12 Cert in .Cer File *
		PKCS12 pkcs12 = new PKCS12(new FileInputStream("resources/ecc(ego).p12"));
		pkcs12.decrypt("ego".toCharArray());
		X509Certificate[] ret = CertificateBag.getCertificates(pkcs12.getCertificateBags());
		
		byte []cert = ret[0].getEncoded();
		FileOutputStream fos = new FileOutputStream("cert1.cer");
		fos.write(cert);
		fos.close();
		*/
		
		Properties config = new Properties();
		config.put("PKCS11_NATIVE_MODULE","cryptoki.dll");
		config.put("SLOT_ID","0");
		
		IAIK iaik = new IAIK();
		Security.addProvider(iaik);
	    IAIKPkcs11 pkcs11Provider_ = new IAIKPkcs11(config);
    	Security.addProvider(pkcs11Provider_);
    	
    	KeyStore tokenKeyStore = pkcs11Provider_.getTokenManager().getKeyStore();
	    tokenKeyStore.load(null,"0000".toCharArray());
	    
	    byte [] keyid = {0x01,0x02,0x03,0x04};
	    
	    PrivateKey k = (PrivateKey)tokenKeyStore.getKey("MOAHSMRSAKEY_cert",null);
	    KeyBag kb = new KeyBag(k,"MOAHSMRSAKEY_pri",keyid);
	    System.out.println("Key:"+k);
	    
	    java.security.cert.Certificate[] ret = tokenKeyStore.getCertificateChain("MOAHSMRSAKEY_cert");
	    
	    System.out.println(ret.getClass().getName());
	    
	    CertificateBag cb = new CertificateBag((iaik.x509.X509Certificate)ret[0],"MOAHSMRSAKEY_cert",keyid);
	    CertificateBag chain[] = new CertificateBag[1];
	    chain[0] = cb;
		System.out.println("Cert:"+cb);
		FileOutputStream fos = new FileOutputStream("hsm.p12");
		
		PKCS12 pkcs12 = new PKCS12(kb,chain);
		System.out.println("Encrypting...");
		pkcs12.encrypt("moa".toCharArray());
		System.out.println("Write...");
		pkcs12.writeTo(fos);
		fos.close();
		
		
		PKCS12 input = new PKCS12(new FileInputStream("hsm.p12"));
		input.decrypt("moa".toCharArray());
		KeyBag newkb = input.getKeyBag();
		System.out.println("KeyNew:"+newkb.getFriendlyName());
		System.out.println(newkb.getPrivateKey());
		CertificateBag newcbs[] = input.getCertificateBags();
		System.out.println("CertNew:"+newcbs[0].getFriendlyName());
		System.out.println(newcbs[0]);
		
	}
		
	public static void test(String[] args) throws Exception {
		iaik.security.provider.IAIK.addAsJDK14Provider();
        iaik.security.ecc.provider.ECCProvider.addAsProvider();
        
		Properties config = new Properties();
		config.put("PKCS11_NATIVE_MODULE","cryptoki.dll");
		config.put("SLOT_ID","0");
		
		IAIK iaik = new IAIK();
		Security.addProvider(iaik);
	    IAIKPkcs11 pkcs11Provider_ = new IAIKPkcs11(config);
    	Security.addProvider(pkcs11Provider_);
    	
    	KeyStore tokenKeyStore = pkcs11Provider_.getTokenManager().getKeyStore();
	    tokenKeyStore.load(null,"0000".toCharArray());
	    
	    FileInputStream inputStream = new FileInputStream("MOA.Serversignatur.TestECDSA.der");
    	CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "IAIK");
    	Collection certificateCollection = certificateFactory.generateCertificates(inputStream);
    	X509Certificate[] certificateChain = 
        (X509Certificate[]) certificateCollection.toArray(new X509Certificate[certificateCollection.size()]);

		System.out.println("Number of Cert:"+certificateCollection.size());

		tokenKeyStore.setCertificateEntry("ECDSA_cert",certificateChain[0]);
		
		System.out.println("DONE");
		
		Enumeration enum2 = tokenKeyStore.aliases();
		
		while (enum2.hasMoreElements()) {
	      String alias = enum2.nextElement().toString();
	      
	      if (tokenKeyStore.isKeyEntry(alias)) {
	        System.out.println("________________________________________________________________________________");
	        System.out.println("Key entry with alias: " + alias); 
	        Key key = tokenKeyStore.getKey(alias, null);
	        System.out.println(key);
	        java.security.cert.Certificate[] certificateChain2 = tokenKeyStore.getCertificateChain(alias);
	        if (certificateChain2 != null) {
	          System.out.println("Certificate chain of length: " + certificateChain2.length);
	          for (int i = 0; i < certificateChain2.length; i++) {
	            System.out.println("--------------------------------------------------------------------------------");
	            System.out.println(certificateChain2[i]);
	          }
	        } else {
	          System.out.println("Certificate chain is null!");
	        }
	        System.out.println("________________________________________________________________________________");
	      } else if (tokenKeyStore.isCertificateEntry(alias)) {
	        System.out.println("________________________________________________________________________________");
	        System.out.println("Certificate entry with alias: " + alias); 
	        java.security.cert.Certificate certificate = tokenKeyStore.getCertificate(alias);
	        System.out.println(certificate);
	        System.out.println("________________________________________________________________________________");
	      } else {
	        System.out.println("________________________________________________________________________________");
	        System.out.println("ERROR! Unknown entry type with alias: " + alias); 
	        System.out.println("________________________________________________________________________________");        
	      }
	    }
	    
	    //tokenKeyStore.setCertificateEntry()
	    
	    /*IAIKPKCS11PublicKey key = (IAIKPKCS11PublicKey)tokenKeyStore.getKey("ECDSA_pub",null);
	    
	    ECDSAPublicKey pkcs11EcDsaPublicKey = (ECDSAPublicKey)key.getKeyObject();
	    
        ByteArrayAttribute ecdsaParamsAttribute = (ByteArrayAttribute) pkcs11EcDsaPublicKey.getEcdsaParams();
	    ByteArrayAttribute ecPointAttribute = (ByteArrayAttribute) pkcs11EcDsaPublicKey.getEcPoint();
	
	    if (!ecdsaParamsAttribute.isPresent()) {
            throw new IAIKPkcs11Exception("The PKCS#11 ECDSA key object does not possess a ECDSA parameters attribute.");
          }
          if (!ecPointAttribute.isPresent()) {
            throw new IAIKPkcs11Exception("The PKCS#11 ECDSA key object does not possess a EC point attribute.");
          }

          byte[] x509encodedPublicKey;
          try {
            byte[] encodedParameters =	ecdsaParamsAttribute.getByteArrayValue();
            byte[] encodedPublicKeyValue =	ecPointAttribute.getByteArrayValue();

			ECDSAKeyFactory fact = new ECDSAKeyFactory();

            // encoding the algorithm ID with the parameters
			ObjectID OBJECT_ID_EC_KEY = new ObjectID("1.2.840.10045.2.1");
			AlgorithmID EC_ALGORITHM_ID = new AlgorithmID(OBJECT_ID_EC_KEY);

            
            ASN1 parametersASN1 = new ASN1(encodedParameters);
            
			EC_ALGORITHM_ID.setParameter(parametersASN1.toASN1Object());

            // encoding the X.509 subject public key info structure
            SEQUENCE publicKeyInfo = new SEQUENCE();
            
			publicKeyInfo.addComponent(EC_ALGORITHM_ID.toASN1Object());
            publicKeyInfo.addComponent(new BIT_STRING(encodedPublicKeyValue));

            x509encodedPublicKey = DerCoder.encode(publicKeyInfo);

          } catch (CodingException ex) {
          	ex.printStackTrace();
            throw new InvalidKeySpecException("Error during 	encoding of ECDSA public key: " + ex.toString());
          }

		  int size = 0;

          X509EncodedKeySpec keySpec = new X509EncodedKeySpec(x509encodedPublicKey);
          byte [] enc = keySpec.getEncoded();
          size = enc.length;
          
          BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ecdsakey.key"));
          bos.write(enc);
          bos.flush();
          bos.close();
          
          byte [] data = new byte[size];
          
          BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ecdsakey.key"));
          bis.read(data);
          bis.close();
	          
	          
          ASN1Object asn1 = DerCoder.decode(data);
          System.out.println("Objectcount:"+asn1.countComponents());
          ASN1Object asnobject1 = asn1.getComponentAt(0);
          System.out.println(asnobject1);
          
          ASN1Object asnobject1_1 = asnobject1.getComponentAt(0);
          System.out.println(asnobject1_1);
          
          ASN1Object asnobject1_2 = asnobject1.getComponentAt(1);
          System.out.println(asnobject1_2);
          
          ASN1Object asnobject2 = asn1.getComponentAt(1);
          System.out.println(asnobject2);*/
	          
		}
}