package com.p6r.kmip;
import org.junit.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
public class JniCryptoKmip {
    private static final String _hostName = "kmiptest01.p6r.com";
    @BeforeClass
    public static void oneTimeSetUp() {
        
        System.out.println("@BeforeClass - oneTimeSetUp");
    }
    @AfterClass
    public static void oneTimeTearDown() {
        
        System.out.println("@AfterClass - oneTimeTearDown");
    }
    @Before
    public void setUp() {
        
        System.out.println("@Before - setUp");
    }
    @After
    public void tearDown() {
        
        System.out.println("@After - tearDown");
    }
    @Test
    public void JNICall_cryptoKMIP() {
        System.out.println("@Test - JNICall-cryptoKMIP");
        String uid = null;
        CryptoParams params = null;
        byte[] clearText = new byte[20];
        byte[] cipherText = null;
        byte[] IV = new byte[16];
        byte[] signData = new byte[16];
        P6KMIPClient kc = new P6KMIPClient();
        try {
            
            for (int i = 0; i < clearText.length; i++) clearText[i] = (byte) i;
            
            kc.initializeLibrary(P6KMIPClient.FLAGS_NONE);
            kc.open(_hostName, null);
            uid = kc.createSymmetricKey(KMIPConstants.ALG_AES, 128, (KMIPConstants.USAGE_MASK_ENCRYPT | KMIPConstants.USAGE_MASK_DECRYPT));
            System.out.println("UID of AES key for encryption: " + uid);
            
            kc.activate(uid);
            
            params = new CryptoParams();
            params.setBlockCipherMode(KMIPConstants.MODE_ECB);
            params.setPaddingMethod(KMIPConstants.PAD_PKCS5);
            cipherText = kc.encrypt(uid, params, clearText, null);
            assertNotEquals(null, cipherText);
            System.out.println("The encrypted bytes 1 [" + cipherText.length + "]");
            for (int i = 0; i < cipherText.length; i++) {
                System.out.print(cipherText[i] + ", ");
            }
            System.out.print("\n");
            
            for (int j = 0; j < IV.length; j++) IV[j] = (byte) (j + 0x05);
            params = new CryptoParams();
            params.setBlockCipherMode(KMIPConstants.MODE_CBC);
            params.setPaddingMethod(KMIPConstants.PAD_PKCS5);
            cipherText = kc.encrypt(uid, params, clearText, IV);
            assertNotEquals(null, cipherText);
            System.out.println("The encrypted bytes 2 using IV [" + cipherText.length + "]");
            for (int i = 0; i < cipherText.length; i++) {
                System.out.print(cipherText[i] + ", ");
            }
            System.out.print("\n");
            
            byte[] decryptedText = kc.decrypt(uid, params, cipherText, IV);
            assertEquals(decryptedText.length, clearText.length);
            for (int z = 0; z < clearText.length; z++) {
                assertEquals(clearText[z], decryptedText[z]);
            }
            
            kc.revoke(uid, KMIPConstants.REVOCATION_CESSATION_OF_OPERATION, "Done with test 1");
            kc.destroy(uid);
            
            KeyPairIds pi = kc.createKeyPair(KMIPConstants.ALG_RSA, 1024, KMIPConstants.USAGE_MASK_VERIFY, KMIPConstants.USAGE_MASK_SIGN);
            System.out.println("\nUID of new public key:  " + pi.getPublicKeyUID());
            System.out.println("UID of new private key: " + pi.getPrivateKeyUID());
            kc.activate(pi.getPublicKeyUID());
            kc.activate(pi.getPrivateKeyUID());
            for (int i = 0; i < signData.length; i++) {
                signData[i] = (byte) (i + 1);
            }
            SignData rawData = new SignData();
            rawData.setData(signData);
            params = new CryptoParams();
            params.setPaddingMethod(KMIPConstants.PAD_PSS);
            params.setHashAlgorithm(KMIPConstants.HASH_SHA256);
            params.setCryptoAlgorithm(KMIPConstants.ALG_RSA);
            byte[] signature = kc.sign(pi.getPrivateKeyUID(), params, rawData);
            assertNotEquals(signature, null);
            System.out.println("The signature bytes [" + signature.length + "]");
            for (int i = 0; i < signature.length; i++) {
                System.out.print(signature[i] + ", ");
            }
            System.out.print("\n");
            boolean isVerified = kc.signatureVerify(pi.getPublicKeyUID(), params, rawData, signature);
            assertEquals(isVerified, true);
            
            signData[3] = 0x00;
            isVerified = kc.signatureVerify(pi.getPublicKeyUID(), params, rawData, signature);
            assertEquals(isVerified, false);
            
            kc.revoke(pi.getPublicKeyUID(), KMIPConstants.REVOCATION_CESSATION_OF_OPERATION, "Done with test 2");
            kc.revoke(pi.getPrivateKeyUID(), KMIPConstants.REVOCATION_CESSATION_OF_OPERATION, "Done with test 2");
            kc.destroy(pi.getPublicKeyUID());
            kc.destroy(pi.getPrivateKeyUID());
            
            uid = kc.createSymmetricKey(KMIPConstants.ALG_AES, 256, (KMIPConstants.USAGE_MASK_MACGEN | KMIPConstants.USAGE_MASK_MACVERIFY));
            System.out.println("\nUID of AES key for MAC: " + uid);
            
            kc.activate(uid);
            for (int i = 0; i < signData.length; i++) {
                signData[i] = (byte) (i + 1);
            }
            params = new CryptoParams();
            params.setCryptoAlgorithm(KMIPConstants.ALG_HMAC_SHA256);
            byte[] MACData = kc.MAC(uid, params, signData);
            assertNotEquals(MACData, null);
            System.out.println("The MAC bytes [" + MACData.length + "]");
            for (int i = 0; i < MACData.length; i++) {
                System.out.print(MACData[i] + ", ");
            }
            System.out.print("\n");
            isVerified = kc.MACVerify(uid, params, signData, MACData);
            assertEquals(isVerified, true);
            
            signData[3] = 0x22;
            isVerified = kc.MACVerify(uid, params, signData, MACData);
            assertEquals(isVerified, false);
            kc.revoke(uid, KMIPConstants.REVOCATION_CESSATION_OF_OPERATION, "Done with test 3");
            kc.destroy(uid);
        } catch (Exception e) {
            System.out.println(e.toString());
            assertEquals(0, 1);
        }
        try {
            
            uid = kc.createSymmetricKey(KMIPConstants.ALG_AES, 128, (KMIPConstants.USAGE_MASK_ENCRYPT));
            System.out.println("\nUID of AES key for MAC 2: " + uid);
            
            kc.activate(uid);
            params = new CryptoParams();
            params.setCryptoAlgorithm(KMIPConstants.ALG_HMAC_SHA256);
            byte[] MACData = kc.MAC(uid, params, signData);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        try {
            kc.revoke(uid, KMIPConstants.REVOCATION_CESSATION_OF_OPERATION, "Done with test 4");
            kc.destroy(uid);
            kc.close();
            kc.freeLibrary();
        } catch (Exception e) {
            System.out.println(e.toString());
            assertEquals(0, 1);
        }
    }
}