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

com.unbound.provider.UBKeyStore 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.unbound.provider;

import com.unbound.client.*;
import com.unbound.common.Log;

import javax.crypto.SecretKey;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPublicKey;
import java.time.Clock;
import java.util.*;

public final class UBKeyStore extends KeyStoreSpi
{
  private static final int CACHE_TIMEOUT = 30000; // milliseconds
  private static final Clock clock = Clock.systemUTC();

  private Partition partition;
  private Map cache = new HashMap<>();
  private long lastCacheClock = 0;

  public UBKeyStore(Partition partition)
  {
    this.partition = partition;
  }

  private UBEntry findEntry(String alias)
  {
    UBEntry entry = null;
    Log log = Log.func("UBKeyStore.findEntry").log("alias", alias).end(); try
    {
      synchronized (this)
      {
        entry = cache.get(alias.toUpperCase());
      }
      if (entry!=null) return entry;

      entry = UBEntry.locate(partition, alias);

      if (entry!=null)
      {
        synchronized (this)
        {
          cache.put(entry.getName().toUpperCase(), entry);
        }
      }
      return entry;
    }
    catch (Exception e) { log.failed(e); throw e; }
    finally
    {
      log = log.leavePrint();
      if (entry!=null) log.log("entry", entry.getName());
      log.end();
    }
  }

  private Enumeration getAliases()
  {
    LinkedList list = new LinkedList();
    for (String s : cache.keySet()) list.add(cache.get(s).getName());
    return Collections.enumeration(list);//Collections.enumeration(cache.keySet());
  }

  // -------------------- interface ------------------------

  @Override
  public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException
  {
    UBEntry entry;
    if (password!=null && password.length!=0) partition.login(password);
    entry = findEntry(alias);
    if (entry==null) return null;
    return entry.getKey();
  }

  @Override
  public Certificate[] engineGetCertificateChain(String alias)
  {
    UBEntry entry;
    try { entry = findEntry(alias); }
    catch (Exception e) { throw new ProviderException(e); }
    if (entry==null) return null;
    return entry.getChain();
  }

  @Override
  public Certificate engineGetCertificate(String alias)
  {
    UBEntry entry;
    try { entry = findEntry(alias); }
    catch (Exception e) { throw new ProviderException(e); }
    if (entry==null) return null;
    return entry.getCertificate();
  }

  @Override
  public Date engineGetCreationDate(String alias)
  {
    UBEntry entry;
    try { entry = findEntry(alias); }
    catch (Exception e) { throw new ProviderException(e); }
    if (entry==null) return null;
    return entry.object.getInitialDate();
  }

  private synchronized void deleteEntryCache(String alias)
  {
    cache.remove(alias.toUpperCase());
  }

  @Override
  public void engineDeleteEntry(String alias) throws KeyStoreException
  {
    Log log = Log.func("UBKeyStore.engineDeleteEntry").log("alias", alias).end(); try
    {
      UBEntry entry = findEntry(alias);
      if (entry==null) return;
      entry.delete();
      deleteEntryCache(alias);
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  @Override
  public boolean engineContainsAlias(String alias)
  {
    UBEntry entry = findEntry(alias);
    return entry!=null;
  }

  @Override
  public boolean engineIsKeyEntry(String alias)
  {
    UBEntry entry = findEntry(alias);
    return entry!=null && entry.getType()!=UBEntry.CERT;
  }

  @Override
  public boolean engineIsCertificateEntry(String alias)
  {
    UBEntry entry = findEntry(alias);
    return entry!=null && entry.getType()==UBEntry.CERT;
  }

  @Override
  public Enumeration engineAliases()
  {
    synchronized (this)
    {
      long now = clock.millis();
      if (now < lastCacheClock + CACHE_TIMEOUT) return getAliases();
    }

    Log log = Log.func("UBKeyStore.engineAliases").end(); try
    {
      ArrayList prvKeys = new ArrayList<>();
      prvKeys.addAll(partition.locate(ObjectType.RSAPrv));
      prvKeys.addAll(partition.locate(ObjectType.ECPrv));
      if (Client.isNative()) prvKeys.addAll(partition.locate(ObjectType.EDDSAPrv));

      ArrayList certs = partition.locate(ObjectType.Certificate);

      ArrayList secretKeys = new ArrayList<>();
      secretKeys.addAll(partition.locate(ObjectType.AES));
      secretKeys.addAll(partition.locate(ObjectType.GenericSecret));

      Map cache = new HashMap();

      int certsCount = certs.size();

      for (BaseObject prv : prvKeys)
      {
        PrivateKeyObject key = (PrivateKeyObject)prv;
        CertObject userCert = null;
        for (int i=0; i pub = partition.locate(ObjectType.RSAPub);
        for (BaseObject pubKey: pub) cache.put(pubKey.getName().toUpperCase(), new UBEntry((RSAPublicKeyObject)pubKey));
      }

      synchronized (this)
      {
        this.cache = cache;
        lastCacheClock = clock.millis();
        return getAliases();
      }
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  @Override
  public String engineGetCertificateAlias(Certificate cert)
  {
    String alias = null;
    Log log = Log.func("UBKeyStore.engineAliases").end(); try
    {
      if (!(cert instanceof X509Certificate)) return null;

      synchronized (this)
      {
        for (UBEntry entry: cache.values())
        {
          Certificate entryCert = entry.getCertificate();
          if (entryCert==null) return null;
          if (entryCert.equals(cert)) return alias = entry.getName();
        }
      }

      try
      {
        UBEntry entry = UBEntry.locateCertEntryByValue(partition, cert);
        if (entry==null) return null;

        synchronized (this)
        {
          cache.put(entry.getName().toUpperCase(), entry);
        }
        return alias = entry.getName();
      }
      catch (Exception e) { }
      return null;
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leavePrint().log("alias", alias).end(); }
  }

  @Override
  public void engineSetEntry(String alias, java.security.KeyStore.Entry entry, java.security.KeyStore.ProtectionParameter protParam) throws KeyStoreException
  {
    Log log = Log.func("UBKeyStore.engineSetEntry").log("allow", alias).end(); try
    {
      char[] password = null;
      if (protParam != null && (protParam instanceof java.security.KeyStore.PasswordProtection))
        password = ((java.security.KeyStore.PasswordProtection) protParam).getPassword();

      if (entry instanceof java.security.KeyStore.PrivateKeyEntry)
      {
        java.security.KeyStore.PrivateKeyEntry keyEntry = (java.security.KeyStore.PrivateKeyEntry) entry;
        engineSetKeyEntry(alias, keyEntry.getPrivateKey(), password, keyEntry.getCertificateChain());
        return;
      }

      if (entry instanceof java.security.KeyStore.SecretKeyEntry)
      {
        java.security.KeyStore.SecretKeyEntry secretKeyEntry = (java.security.KeyStore.SecretKeyEntry) entry;
        engineSetKeyEntry(alias, secretKeyEntry.getSecretKey(), password, null);
        return;
      }

      if (entry instanceof java.security.KeyStore.TrustedCertificateEntry)
      {
        java.security.KeyStore.TrustedCertificateEntry certEntry = (java.security.KeyStore.TrustedCertificateEntry) entry;
        engineSetCertificateEntry(alias, certEntry.getTrustedCertificate());
        return;
      }

      if (entry instanceof UBKeyStoreEntry)
      {
        UBKeyStoreEntry keyEntry = (UBKeyStoreEntry) entry;
        Key key = keyEntry.getPrivateKey();
        if (key!=null && !UBCryptoProvider.allowedPrivateKeyWithoutCertificate) throw new ProviderException("Orphan private key entry is not allowed");

        if (key==null)
        {
          key = keyEntry.getPublicKey();
          if (key!=null && !UBCryptoProvider.allowedPublicKey) throw new ProviderException("Public key entry is not allowed");
        }

        engineSetKeyEntry(alias, key, password, null, keyEntry.getKeyParameters());
        return;
      }

      throw new KeyStoreException(new UnsupportedOperationException("unsupported entry type: " + entry.getClass().getName()));
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  @Override
  public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException
  {
    engineSetKeyEntry(alias, key, password, chain, null);
  }

  public void engineSetKeyEntry(String alias, Key key,  char[] password, Certificate[] chain, KeyParameters kp) throws KeyStoreException
  {
    Log log = Log.func("UBKeyStore.engineSetKeyEntry").log("allow", alias).log("chain", chain!=null).end(); try
    {
      if (password!=null && password.length!=0) partition.login(password);

      UBEntry entry = findEntry(alias);
      if (entry!=null)
      {
        if (entry.getType()==UBEntry.CERT) throw new KeyStoreException("Trusted certificate entry present");

        if (key.getClass()!=entry.getKey().getClass()) engineDeleteEntry(alias);
        else
        {
          if (entry.userCert!=null) partition.deleteObject(entry.userCert);
          deleteEntryCache(entry.getName());
        }
      }

      X509Certificate userX509 = null;
      ArrayList  caChain = null;
      if (chain!=null)
      {
        userX509 = (X509Certificate)chain[0];
        if (chain.length>1)
        {
          caChain = new ArrayList();
          for (int i=1; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy