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.cryptoki.Native;
import com.dyadicsec.pkcs11.*;
import com.unbound.provider.UBCryptoProvider;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigInteger;
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.HashMap;
import java.util.Map;

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
  {
    if (Native.loaded)
    {
      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);
  }

  static boolean allowedPrivateKeyWithoutCertificate = false;

  public static void allowPrivateKeyWithoutCertificate(boolean allow)
  {
    allowedPrivateKeyWithoutCertificate = allow;
    UBCryptoProvider.allowPrivateKeyWithoutCertificate(allow);
  }

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

    if ("1".equals(System.getenv("UKC_NO_NATIVE")) || !Native.loaded)
    {
      UBCryptoProvider proxyProvider = UBCryptoProvider.proxy(this, arg);
      if (proxyProvider==null) return; // wait to call for configure
      Service[] services = proxyProvider.register(this);
      for (Service service : services) putService(service);
      return;
    }

//        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_RSA_PKCS_PSS))
        {
          put("Signature.RSASSA-PSS", prefix + "RSASignature$PSS");
          put("Signature.RSASSA-PSS SupportedKeyClasses", rsaKeyClasses);
          put("Alg.Alias.Signature.1.2.840.113549.1.1.10",     "RSASSA-PSS");
          put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.10", "RSASSA-PSS");
        }
      }

      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 PrivateKey getPrivateKey() { return 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