package ru.rutoken.samples.sunPkcs11Wrapper;

import sun.security.pkcs11.wrapper.*;

public class Info {
    static PKCS11 pkcs11Wrapper;

    public static void main(String[] args) {
        try {
            System.out.println("Example of acquiring info about library, tokens and mechanisms " +
                    "using rtpkcs11ecp via sun.security.pkcs11.wrapper");

            System.out.println("Library initialization and acquiring of function list");
            pkcs11Wrapper = PKCS11.getInstance("rtpkcs11ecp", "C_GetFunctionList", new CK_C_INITIALIZE_ARGS(), false);

            System.out.println("Library info:");

            CK_INFO LibInfo = pkcs11Wrapper.C_GetInfo();

            System.out.println(" Library description: \t" + new String(LibInfo.libraryDescription));
            System.out.println(" Library Ver: \t\t\t" + LibInfo.libraryVersion);
            System.out.println(" PKCS#11 Ver: \t\t\t" + LibInfo.cryptokiVersion);
            System.out.println(" Manufacturer: \t\t\t" + new String(LibInfo.manufacturerID));
            System.out.printf(" Flags: \t\t\t\t0x%08X\n", LibInfo.flags);

            System.out.println("Acquiring list of slots with connected tokens");
            long[] slotList = pkcs11Wrapper.C_GetSlotList(true);
            if (slotList.length == 0) {
                throw new Exception("No Rutoken is available!");
            }

            for (int i = 0; i < slotList.length; ++i) {
                CK_SLOT_INFO slotInfo = pkcs11Wrapper.C_GetSlotInfo(slotList[i]);
                CK_TOKEN_INFO tokenInfo = pkcs11Wrapper.C_GetTokenInfo(slotList[i]);

                System.out.printf("Slot number 0x%08X:\n", slotList[i]);
                System.out.println(" Slot description: \t" + new String(slotInfo.slotDescription));
                System.out.println(" Manufacturer: \t\t" + new String(slotInfo.manufacturerID));
                System.out.println(" Hardware Ver: \t\t" + slotInfo.hardwareVersion);
                System.out.println(" Firmware Ver: \t\t" + slotInfo.firmwareVersion);
                System.out.printf(" Flags: \t\t\t0x%08X\n", slotInfo.flags);

                System.out.println("Token info:");
                System.out.println(" Token label: \t" + new String(tokenInfo.label));
                System.out.println(" Manufacturer: \t" + new String(tokenInfo.manufacturerID));
                System.out.println(" Token model: \t" + new String(tokenInfo.model));
                System.out.println(" Token SN: \t\t" + new String(tokenInfo.serialNumber));
                System.out.printf(" Flags: \t\t0x%08X\n", tokenInfo.flags);

                System.out.printf(" Max session count: \t\t0x%08X\n", tokenInfo.ulMaxSessionCount);
                System.out.printf(" Current session count: \t0x%08X\n", tokenInfo.ulSessionCount);
                System.out.printf(" Max RW session count:  \t0x%08X\n", tokenInfo.ulMaxRwSessionCount);
                System.out.printf(" Current RW session count:  0x%08X\n", tokenInfo.ulRwSessionCount);
                System.out.printf(" Max PIN length: \t\t\t0x%08X\n", tokenInfo.ulMaxPinLen);
                System.out.printf(" Min PIN length: \t\t\t0x%08X\n", tokenInfo.ulMinPinLen);
                System.out.printf(" Total public memory: \t\t0x%08X\n", tokenInfo.ulTotalPublicMemory);
                System.out.printf(" Free public memory: \t\t0x%08X\n", tokenInfo.ulFreePublicMemory);
                System.out.printf(" Total private memory: \t\t0x%08X\n", tokenInfo.ulTotalPrivateMemory);
                System.out.printf(" Free private memory: \t\t0x%08X\n", tokenInfo.ulFreePrivateMemory);
                System.out.println(" Hardware Ver: \t\t\t\t" + tokenInfo.hardwareVersion);
                System.out.println(" Firmware Ver: \t\t\t\t" + tokenInfo.firmwareVersion);
                System.out.println(" Timer #: \t\t\t\t\t" + new String(tokenInfo.utcTime));

                long[] mechList = pkcs11Wrapper.C_GetMechanismList(slotList[i]);
                for (int j = 0; j < mechList.length; ++j) {
                    System.out.printf("Mechanism 0x%02X info:\n", j);
                    CK_MECHANISM_INFO mechInfo = pkcs11Wrapper.C_GetMechanismInfo(slotList[i], mechList[j]);
                    System.out.printf(" Mechanism type: \t0x%08X\n", mechList[j]);
                    System.out.printf(" Min key size: \t\t0x%08X\n", mechInfo.ulMinKeySize);
                    System.out.printf(" Max key size: \t\t0x%08X\n", mechInfo.ulMaxKeySize);
                    System.out.printf(" Flags: \t\t\t0x%08X\n", mechInfo.flags);
                }
            }
            System.out.println("Test has been completed successfully");
        }
        catch(Exception e){
            System.out.println("Some error occurred. Error code: " + e.getMessage());
        }
        try {
            pkcs11Wrapper.C_Finalize(null);
        }
        catch(Exception e) {}
    }
}
