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.dyadicsec.provider.DYCryptoProvider;
import com.unbound.common.Log;
import com.unbound.provider.kmip.KMIP;

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.spec.InvalidKeySpecException;
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();

  static final class Entry
  {
    UBPrivateKey prvKey = null;
    UBCertificate cert = null;
    Certificate[] chain = null;
    UBSecretKey secretKey = null;

    Entry(UBPrivateKey key, UBCertificate cert, Certificate[] chain) throws InvalidKeySpecException, CertificateException, IOException
    {
      this.prvKey = key;
      this.cert = cert;
      if (chain==null) chain = cert.getChain();
      this.chain = chain;
    }

    Entry(UBPrivateKey key) // orphan
    {
      this.prvKey = key;
    }

    Entry(UBCertificate cert)
    {
      this.cert = cert;
    }

    Entry(UBSecretKey secret)
    {
      this.secretKey = secret;
    }

    String getName()
    {
      if (secretKey !=null) return secretKey.name;
      return isTrustedCert() ? cert.name : prvKey.name;
    }

    boolean isTrustedCert()
    {
      return prvKey == null && secretKey == null;
    }

    boolean isOrphanPrvKey()
    {
      return prvKey != null && cert == null;
    }
  }

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

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

  private Entry findEntry(String alias) throws InvalidKeySpecException, CertificateException, IOException
  {
    Entry 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;

      UBPrivateKey key = UBPrivateKey.locate(partition, 0, alias);
      if (key==null)
      {
        UBCertificate cert = UBCertificate.locate(partition, alias);
        if (cert!=null) entry = new Entry(cert);
        else
        {
          UBSecretKey secret = UBSecretKey.locate(partition, alias);
          if (secret==null) return null;
          entry = new Entry(secret);
        }
      }
      else
      {
        UBCertificate cert = UBCertificate.locateByKeyUid(partition, key.uid);
        if (cert==null) entry = new Entry(key);
        else entry = new Entry(key, cert, null);
      }

      synchronized (this)
      {
        cache.put(entry.getName().toUpperCase(), entry);
      }

      if (!UBCryptoProvider.allowedPrivateKeyWithoutCertificate && entry!=null && entry.isOrphanPrvKey()) entry = null;
      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 final static class FilteredAliases implements Enumeration
  {
    private Iterator< Map.Entry > it;
    private Map.Entry next = null;

    FilteredAliases(Map map) { this.it = map.entrySet().iterator(); }

    private void findNext()
    {
      if (next != null) return;

      while (it.hasNext())
      {
        Map.Entry element = it.next();
        if (element.getValue().isOrphanPrvKey()) continue;
        next = element;
        break;
      }
    }

    public boolean hasMoreElements()
    {
      findNext();
      return next != null;
    }

    public String nextElement() throws NoSuchElementException
    {
      findNext();
      if (next == null) throw new NoSuchElementException();
      String result = next.getKey();
      next = null;
      return result;
    }
  }

  private Enumeration getAliases()
  {
    if (UBCryptoProvider.allowedPrivateKeyWithoutCertificate) return Collections.enumeration(cache.keySet());
    return new FilteredAliases(cache);
  }


  static void setKeyAlias(Key key, String alias) throws KeyStoreException
  {
    if (!(key instanceof UBPrivateKey) &&
        !(key instanceof UBSecretKey)) throw new  KeyStoreException("Key type is not supported");
    ((UBObject)key).partition.keyStore.engineSetKeyEntry(alias, key, null, null);
  }
  // -------------------- interface ------------------------

  @Override
  public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException, UnrecoverableKeyException
  {
    Entry entry;
    try
    {
      if (password!=null && password.length!=0) partition.login(new String(password));
      entry = findEntry(alias);
    }
    catch (CertificateException | InvalidKeySpecException | IOException e)
    {
      throw new ProviderException(e);
    }
    if (entry==null) return null;
    if (entry.secretKey !=null) return entry.secretKey;
    return entry.prvKey;
  }

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

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

  @Override
  public Date engineGetCreationDate(String alias)
  {
    Entry entry;
    try { entry = findEntry(alias); }
    catch (Exception e) { throw new ProviderException(e); }
    if (entry==null) return null;
    long initialDate = -1;
    if (entry.secretKey !=null) initialDate = entry.secretKey.initialDate;
    else if (entry.prvKey !=null) initialDate = entry.prvKey.initialDate;
    else initialDate = entry.cert.initialDate;
    if (initialDate<0) return null;
    return new Date(initialDate * 1000);
  }

    @Override
    public void engineSetEntry(String alias, java.security.KeyStore.Entry entry, java.security.KeyStore.ProtectionParameter protParam) throws KeyStoreException
    {
      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 DYCryptoProvider.KeyEntry)
      {
          DYCryptoProvider.KeyEntry keyEntry = (DYCryptoProvider.KeyEntry)entry;
          engineSetKeyEntry(alias, keyEntry.getPrivateKey(), password, null);
          return;
      }

      throw new KeyStoreException(new UnsupportedOperationException("unsupported entry type: " + entry.getClass().getName()));
  }

  @Override
  public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException
  {
    try
    {
      if (password!=null && password.length!=0) partition.login(new String(password));

      UBSecretKey secretKey = (key instanceof UBSecretKey) ? (UBSecretKey)key : null;
      UBPrivateKey privateKey = (key instanceof UBPrivateKey) ? (UBPrivateKey)key : null;

      Entry entry = findEntry(alias);
      if (entry!=null)
      {
        if (entry.isTrustedCert()) throw new KeyStoreException("Trusted certificate entry present");
        if (privateKey==null && secretKey==null) engineDeleteEntry(alias);
      }

      if (chain!=null)
      {
        if (privateKey==null) privateKey = UBPrivateKey.newPrivateKey(null, partition, alias, key);
        else privateKey.setName(alias);

        X509Certificate x509 = (X509Certificate)chain[0];
        UBCertificate cert = UBCertificate.locate(partition, x509);
        if (cert==null) cert = new UBCertificate(partition, alias, x509);
        else cert.setName(alias);

        for (int i=1; i engineAliases()
  {
    synchronized (this)
    {
      long now = clock.millis();
      if (now < lastCacheClock + CACHE_TIMEOUT) return getAliases();
    }

    try
    {
      long[] rsaIds = partition.locate(KMIP.ObjectType.PrivateKey, KMIP.CryptographicAlgorithm.RSA);
      long[] eccIds = partition.locate(KMIP.ObjectType.PrivateKey, KMIP.CryptographicAlgorithm.EC);
      long[] prvKeyIds = new long[rsaIds.length + eccIds.length];
      System.arraycopy(rsaIds, 0, prvKeyIds, 0, rsaIds.length);
      System.arraycopy(eccIds, 0, prvKeyIds, rsaIds.length, eccIds.length);
      long[] certIds = partition.locate(KMIP.ObjectType.Certificate, 0);

      UBObject[] prvKeys = UBObject.read(partition, prvKeyIds, true);
      UBObject[] certs = UBObject.read(partition, certIds, true);

      Map cache = new HashMap<>();

      for (UBObject object : prvKeys)
      {
        UBPrivateKey key = (UBPrivateKey)object;
        UBCertificate found = null;
        for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy