com.dyadicsec.provider.DYCryptoProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
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);
}
}
}