All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dyadicsec.provider.DYCryptoProvider Maven / Gradle / Ivy

Go to download

This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi

There is a newer version: 42761
Show newest version
package com.dyadicsec.provider;

//import com.dyadicsec.common.DYLog;

import com.dyadicsec.cryptoki.CK;
import com.dyadicsec.pkcs11.*;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.security.KeyStoreException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.ProviderException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

import static com.dyadicsec.cryptoki.CK.*;

//import static com.dyadicsec.common.DYErrorException.E_GENERAL;

/**
 * Created by valery.osheter on 19-Apr-16.
 */
public final class DYCryptoProvider extends Provider {
    public static final String NAME = "DYADIC";
    private static final long serialVersionUID = 1L;
    static KeyStore defaultKeyStore = null;
    private static Map stores = new HashMap();

    Slot slot = null;

    public DYCryptoProvider() {
        this(null);
    }

    static {
        Slot defaultSlot = Slot.getDefault();
        defaultKeyStore = new KeyStore(defaultSlot);
        stores.put(defaultSlot.getName(), defaultKeyStore);
    }

    public static KeyStore getDefaultKeyStore() {
        return defaultKeyStore;
    }

    private static CK_MECHANISM_INFO mechInfo = new CK_MECHANISM_INFO();

    private static boolean isHwMech(int[] mechList, int mechType) {
        //if (0!= Library.C_GetMechanismInfo(slot.getID(), mechType, mechInfo)) return false;
        //if ((mechInfo.flags & CKF_HW)==0) return false;
        //return true;
        for (int i = 0; i < mechList.length; i++) {
            if (mechList[i] == mechType) return true;
        }
        return false;
    }

    private static void appendMode(StringBuffer buf, String a) {
        if (buf.length() > 0) buf.append("|");
        buf.append(a);
    }


    public Provider configure(String configArg) {
        return new DYCryptoProvider(configArg);
    }

    public DYCryptoProvider(String arg) {
        super(NAME, 1.0, "DyadicSec EKM security provider");

//        Enumeration resources = null;
//        try {
//            resources = getClass().getClassLoader()
//                    .getResources("META-INF/MANIFEST.MF");
//        } catch (IOException e) {
//            //e.printStackTrace();
//        }
//        while (resources.hasMoreElements()) {
//            try {
//                Manifest manifest = new Manifest(resources.nextElement().openStream());
//                Attributes atts = manifest.getMainAttributes();
//                if (!atts.containsValue("Dyadic Security")) continue;
//                else {
//                    System.out.println("Unbound Java Provider:");
//                    System.out.println("\tOS :" + System.getProperty("os.name"));
//                    System.out.println("\tJDK :" + System.getProperty("java.version"));
//                    System.out.println("\tVersion: " + atts.getValue("Implementation-Version"));
//                    break;
//                }
//
//                // check that this is your manifest and do what you need or get the next one
//
//            } catch (IOException E) {
//                E.printStackTrace();
//            }
//        }

        //int rv = E_GENERAL;
        try {
            //DYLog.func("DYCryptoProvider").log("arg", arg).done();


            if (arg == null || arg.isEmpty()) arg = System.getProperty("ekm.partition");
            if (arg == null || arg.isEmpty()) arg = System.getenv().get("EKM_PARTITION");

            if (arg == null || arg.isEmpty()) slot = Slot.getDefault();
            else slot = Slot.find(arg);
            if (slot == null) throw new ProviderException(String.format("Partition %s not found", arg));

            defaultKeyStore = getKeyStoreBySlot(slot);

            final String prefix = getClass().getPackage().getName() + ".";

            //put("KeyStore.pkcs11", prefix + "KeyStore");

            long rvLen = Library.C_GetMechanismList(-1, null);
            int rv = Library.rvErr(rvLen);
            int mechCount = Library.rvValue(rvLen);
            if (rv != 0) mechCount = 0;
            int[] mechList = new int[mechCount];
            if (mechCount > 0) {
                Library.C_GetMechanismList(-1, mechList);
            }


            if (isHwMech(mechList, CKM_RSA_PKCS_KEY_PAIR_GEN)) {
                final String rsaKeyClasses = "java.security.interfaces.RSAPublicKey|java.security.interfaces.RSAPrivateKey";
                put("KeyFactory.RSA", prefix + "RSAKeyFactory");
                put("KeyPairGenerator.RSA", prefix + "RSAKeyPairGenerator");
                put("Alg.Alias.KeyPairGenerator.1.2.840.113549.1.1", "RSA");
                put("Alg.Alias.KeyPairGenerator.OID.1.2.840.113549.1.1", "RSA");

                boolean hwRsaPkcs1 = isHwMech(mechList, CKM_RSA_PKCS);

                StringBuffer modes = new StringBuffer();
                if (hwRsaPkcs1) appendMode(modes, "PKCS1PADDING");
                if (isHwMech(mechList, CKM_RSA_X_509)) appendMode(modes, "NOPADDING");
                if (isHwMech(mechList, CKM_RSA_PKCS_OAEP)) {
                    appendMode(modes, "OAEPPADDING"
                            + "|OAEPWITHSHA1ANDMGF1PADDING"
                            + "|OAEPWITHSHA-1ANDMGF1PADDING"
                            + "|OAEPWITHSHA-256ANDMGF1PADDING"
                            + "|OAEPWITHSHA-384ANDMGF1PADDING"
                            + "|OAEPWITHSHA-512ANDMGF1PADDING");
                }
                if (modes.length() > 0) {
                    put("Cipher.RSA", prefix + "RSACipher");
                    put("Cipher.RSA SupportedModes", "ECB");
                    put("Cipher.RSA SupportedKeyClasses", rsaKeyClasses);
                    put("Cipher.RSA SupportedPaddings", modes.toString());
                }

                if (hwRsaPkcs1) {
                    put("Signature.NONEwithRSA SupportedKeyClasses", rsaKeyClasses);
                    put("Signature.NONEwithRSA", prefix + "RSASignature$NONEwithRSA");
                }

                if (isHwMech(mechList, CKM_SHA1_RSA_PKCS)) {
                    put("Signature.SHA1withRSA SupportedKeyClasses", rsaKeyClasses);
                    put("Signature.SHA1withRSA", prefix + "RSASignature$SHA1withRSA");
                    put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA");
                    put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA");
                    put("Alg.Alias.Signature.1.3.14.3.2.29", "SHA1withRSA");
                }

                if (isHwMech(mechList, CKM_SHA256_RSA_PKCS)) {
                    put("Signature.SHA256withRSA SupportedKeyClasses", rsaKeyClasses);
                    put("Signature.SHA256withRSA", prefix + "RSASignature$SHA256withRSA");
                    put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA");
                    put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA");
                }

                if (isHwMech(mechList, CKM_SHA384_RSA_PKCS)) {
                    put("Signature.SHA384withRSA SupportedKeyClasses", rsaKeyClasses);
                    put("Signature.SHA384withRSA", prefix + "RSASignature$SHA384withRSA");
                    put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA");
                    put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA");
                }

                if (isHwMech(mechList, CKM_SHA512_RSA_PKCS)) {
                    put("Signature.SHA512withRSA SupportedKeyClasses", rsaKeyClasses);
                    put("Signature.SHA512withRSA", prefix + "RSASignature$SHA512withRSA");
                    put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA");
                    put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA");
                }
            }

            if (isHwMech(mechList, CKM_EC_KEY_PAIR_GEN)) {
                String ecKeyClasses = "java.security.interfaces.ECPublicKey|java.security.interfaces.ECPrivateKey";

                put("KeyFactory.EC", prefix + "ECKeyFactory");
                put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
                put("KeyPairGenerator.EC", prefix + "ECKeyPairGenerator");

                if (isHwMech(mechList, CKM_ECDSA)) {
                    put("Signature.NONEwithECDSA", prefix + "ECDSASignature$Raw");
                    put("Signature.NONEwithECDSA SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, CKM_ECDSA_SHA1)) {
                    put("Signature.SHA1withECDSA", prefix + "ECDSASignature$SHA1");
                    put("Signature.SHA1withECDSA SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, CKM_ECDSA_SHA256)) {
                    put("Signature.SHA256withECDSA", prefix + "ECDSASignature$SHA256");
                    put("Signature.SHA256withECDSA SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, CKM_ECDSA_SHA384)) {
                    put("Signature.SHA384withECDSA", prefix + "ECDSASignature$SHA384");
                    put("Signature.SHA384withECDSA SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, CKM_ECDSA_SHA512)) {
                    put("Signature.SHA512withECDSA", prefix + "ECDSASignature$SHA512");
                    put("Signature.SHA512withECDSA SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, CKM_ECDH1_DERIVE)) {
                    put("KeyAgreement.ECDH", prefix + "ECDHKeyAgreement");
                    put("KeyAgreement.ECDH SupportedKeyClasses", ecKeyClasses);
                }

                if (isHwMech(mechList, DYCKM_SCHNORR)) {
                    put("Signature.Schnorr", prefix + "SchnorrSignature");
                    put("Signature.Schnorr SupportedKeyClasses", ecKeyClasses);
                }

            }

            if (isHwMech(mechList, CKM_AES_KEY_GEN)) {
                put("KeyGenerator.AES", prefix + "SecretKeyGenerator$AES");
                put("SecretKeyFactory.AES", prefix + "SecretKeyFactory$AES");
                StringBuffer modes = new StringBuffer(); //"ECB|CBC|OFB128|CFB128|CTR|CCM|GCM|WRAP"
                if (isHwMech(mechList, CKM_AES_ECB)) appendMode(modes, "ECB");
                if (isHwMech(mechList, CKM_AES_CBC)) appendMode(modes, "CBC");
                if (isHwMech(mechList, CKM_AES_OFB)) appendMode(modes, "OFB128");
                if (isHwMech(mechList, CKM_AES_CFB128)) appendMode(modes, "CFB128");
                if (isHwMech(mechList, CKM_AES_CTR)) appendMode(modes, "CTR");
                if (isHwMech(mechList, CKM_AES_GCM)) appendMode(modes, "GCM");
                if (isHwMech(mechList, CKM_AES_CCM)) appendMode(modes, "CCM");
                if (isHwMech(mechList, CKM_AES_KEY_WRAP)) appendMode(modes, "WRAP");

                if (modes.length() > 0) {
                    put("Cipher.AES", prefix + "SecretKeyCipher$AES");
                    put("Cipher.AES SupportedModes", modes.toString());
                    put("Cipher.AES SupportedPaddings", "NOPADDING|PKCS5PADDING");
                    put("Cipher.AES SupportedKeyFormats", "RAW");
                }

                if (isHwMech(mechList, CKM_AES_CMAC)) put("Mac.CMAC", prefix + "Mac$CMAC");
                if (isHwMech(mechList, CKM_AES_GMAC)) put("Mac.GMAC", prefix + "Mac$GMAC");
            }

            if (isHwMech(mechList, DYCKM_AES_XTS_KEY_GEN)) {
                put("KeyGenerator.AESXTS", prefix + "SecretKeyGenerator$AESXTS");
                put("SecretKeyFactory.AESXTS", prefix + "SecretKeyFactory$AESXTS");
                if (isHwMech(mechList, DYCKM_AES_XTS)) {
                    put("Cipher.AESXTS", prefix + "SecretKeyCipher$AESXTS");
                    put("Cipher.AESXTS SupportedModes", "XTS");
                    put("Cipher.AESXTS SupportedPaddings", "NOPADDING");
                    put("Cipher.AESXTS SupportedKeyFormats", "RAW");
                }
            }

            if (isHwMech(mechList, DYCKM_AES_SIV_KEY_GEN)) {
                put("KeyGenerator.AESSIV", prefix + "SecretKeyGenerator$AESSIV");
                put("SecretKeyFactory.AESSIV", prefix + "SecretKeyFactory$AESSIV");
                if (isHwMech(mechList, DYCKM_AES_SIV)) {
                    put("Cipher.AESSIV", prefix + "SecretKeyCipher$AESSIV");
                    put("Cipher.AESSIV SupportedModes", "SIV");
                    put("Cipher.AESSIV SupportedPaddings", "NOPADDING");
                    put("Cipher.AESSIV SupportedKeyFormats", "RAW");
                }
            }

            if (isHwMech(mechList, CKM_DES3_KEY_GEN)) {
                put("KeyGenerator.DESede", prefix + "SecretKeyGenerator$DES3");
                put("SecretKeyFactory.DESede", prefix + "SecretKeyFactory$DES3");
                StringBuffer modes = new StringBuffer(); //"ECB|CBC|OFB64|CFB64"

                if (isHwMech(mechList, CKM_DES3_ECB)) appendMode(modes, "ECB");
                if (isHwMech(mechList, CKM_DES3_CBC)) appendMode(modes, "CBC");
                if (isHwMech(mechList, CKM_DES_OFB64)) appendMode(modes, "OFB64");
                if (isHwMech(mechList, CKM_DES_CFB64)) appendMode(modes, "CFB64");
                if (modes.length() > 0) {
                    put("Cipher.DESede", prefix + "SecretKeyCipher$DES3");
                    put("Cipher.DESede SupportedModes", modes.toString());
                    put("Cipher.DESede SupportedPaddings", "NOPADDING|PKCS5PADDING");
                    put("Cipher.DESede SupportedKeyFormats", "RAW");
                }
            }

            if (isHwMech(mechList, CKM_GENERIC_SECRET_KEY_GEN)) {
                put("KeyGenerator.Hmac", prefix + "SecretKeyGenerator$Hmac");
                put("SecretKeyFactory.Hmac", prefix + "SecretKeyFactory$Hmac");
                put("Mac.Hmac SupportedKeyFormats", "RAW");

                if (isHwMech(mechList, CKM_SHA_1_HMAC)) {
                    put("Mac.HmacSHA1", prefix + "Mac$HmacSHA1");
                    put("Alg.Alias.Mac.OID.1.2.840.113549.2.7", "HmacSHA1");
                    put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1");
                }
                if (isHwMech(mechList, CKM_SHA256_HMAC)) {
                    put("Mac.HmacSHA256", prefix + "Mac$HmacSHA256");
                    put("Alg.Alias.Mac.OID.1.2.840.113549.2.9", "HmacSHA256");
                    put("Alg.Alias.Mac.1.2.840.113549.2.9", "HmacSHA256");
                }
                if (isHwMech(mechList, CKM_SHA384_HMAC)) {
                    put("Mac.HmacSHA384", prefix + "Mac$HmacSHA384");
                    put("Alg.Alias.Mac.OID.1.2.840.113549.2.10", "HmacSHA384");
                    put("Alg.Alias.Mac.1.2.840.113549.2.10", "HmacSHA384");
                }
                if (isHwMech(mechList, CKM_SHA512_HMAC)) {
                    put("Mac.HmacSHA512", prefix + "Mac$HmacSHA512");
                    put("Alg.Alias.Mac.OID.1.2.840.113549.2.11", "HmacSHA512");
                    put("Alg.Alias.Mac.1.2.840.113549.2.11", "HmacSHA512");
                }
            }

            if (isHwMech(mechList, DYCKM_LIMA_KEY_GEN)) {
                put("KeyPairGenerator.LIMA", prefix + "LIMAKeyPairGenerator");
                put("Alg.Alias.KeyPairGenerator.LIMA", "LIMA");
                put("Cipher.LIMA", prefix + "LIMACipher");
                put("Cipher.LIMA SupportedKeyClasses", "java.security.PublicKey|java.security.PrivateKey");
            }


            if (isHwMech(mechList, DYCKM_EDDSA_KEY_GEN)) {
                put("KeyPairGenerator.EDDSA", prefix + "EDDSAKeyPairGenerator");
                put("Alg.Alias.KeyPairGenerator.EDDSA", "EDDSA");

                if (isHwMech(mechList, DYCKM_EDDSA)) {
                    put("Signature.NONEwithEDDSA", prefix + "EDDSASignature$Raw");
                    put("Signature.NONEwithEDDSA SupportedKeyClasses", "java.security.PublicKey|java.security.PrivateKey");
                }
            }

            put("MessageDigest.SHA", prefix + "MessageDigest$SHA1");
            put("Alg.Alias.MessageDigest.SHA-1", "SHA");
            put("Alg.Alias.MessageDigest.SHA1", "SHA");
            put("MessageDigest.SHA-256", prefix + "MessageDigest$SHA256");
            put("MessageDigest.SHA-384", prefix + "MessageDigest$SHA384");
            put("MessageDigest.SHA-512", prefix + "MessageDigest$SHA512");

            putService(new KeyStoreService(this, prefix + "KeyStore", slot.getName()));
            // putService(new NONEWithRSAService(this, prefix + "RSASignature$NONEwithRSA", 0));
            //rv = 0;
        } finally { //DYLog.leave(rv).done();
        }
    }


    public static synchronized KeyStore getKeyStoreBySlot(Slot slot) {
        String name = slot.getName();
        KeyStore store = stores.get(name);
        if (store == null) {
            store = new KeyStore(Slot.find(name));
            if (store != null) stores.put(name, store);
        }
        return store;
    }

    final class KeyStoreService extends Service {
        private String slotName;
        private int slotID;

        public KeyStoreService(Provider provider, String className, String slotName) {
            super(provider, "KeyStore", "PKCS11", className, null, null);
            this.slotName = slotName;
        }

        public KeyStoreService(Provider provider, String className, int slotID) {
            super(provider, "KeyStore", "PKCS11", className, null, null);
            this.slotID = slotID;
        }

        @Override
        public boolean supportsParameter(Object param) {
            return false;
        }

        @Override
        public Object newInstance(Object param) {
            Slot slot = (slotName == null) ? Slot.find(slotID) : Slot.find(slotName);
            if (slot == null) return null;
            return getKeyStoreBySlot(slot);
        }

    }

    public static final class KeyEntry implements java.security.KeyStore.Entry {
        PrivateKey key;

        public KeyEntry(PrivateKey key) {
            this.key = key;
        }
    }

    public X509Certificate SelfSign(java.security.PrivateKey key, String hashAlg, String subject, BigInteger serialNumber, int days)
            throws CertificateException {
        try {
            int hashMechansigm = 0;
            if (hashAlg == null || hashAlg.isEmpty()) hashMechansigm = CK.CKM_SHA256;
            else if (hashAlg.equalsIgnoreCase("SHA1") || subject.equalsIgnoreCase("SHA-1"))
                hashMechansigm = CK.CKM_SHA_1;
            else if (hashAlg.equalsIgnoreCase("SHA256") || subject.equalsIgnoreCase("SHA-256"))
                hashMechansigm = CK.CKM_SHA256;
            else if (hashAlg.equalsIgnoreCase("SHA384") || subject.equalsIgnoreCase("SHA-384"))
                hashMechansigm = CK.CKM_SHA384;
            else if (hashAlg.equalsIgnoreCase("SHA512") || subject.equalsIgnoreCase("SHA-512"))
                hashMechansigm = CK.CKM_SHA512;
            else throw new IllegalArgumentException("Invalid hashAlg");

            int privateHandle = 0;
            if (key instanceof ECPrivateKey) {
                ((ECPrivateKey) key).save(getKeyStoreBySlot(slot), null);
                privateHandle = ((ECPrivateKey) key).pkcs11Key.getHandle();
            } else if (key instanceof RSAPrivateKey) {
                ((RSAPrivateKey) key).save(getKeyStoreBySlot(slot), null);
                privateHandle = ((RSAPrivateKey) key).pkcs11Key.getHandle();
            } else {
                throw new IllegalArgumentException("Invalid key type");
            }

            char[] serialChars = subject.toCharArray();
            byte[] subjectBytes = serialNumber == null ? null : serialNumber.toByteArray();

            Session session = slot.getPersistentSession();
            byte[] bytes = session.DYC_SelfSignX509(privateHandle, hashMechansigm, serialChars, subjectBytes, days);

            CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
            InputStream in = new ByteArrayInputStream(bytes);
            return (X509Certificate) certFactory.generateCertificate(in);
        } catch (CKException e) {
            throw new ProviderException(e);
        } catch (KeyStoreException e) {
            throw new ProviderException(e);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy