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

com.unbound.provider.Partition 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.common.Base64;
import com.unbound.common.JSON;
import com.unbound.common.Log;
import com.unbound.common.STR;
import com.unbound.common.crypto.X509;
import com.unbound.provider.kmip.KMIP;
import com.unbound.provider.kmip.attribute.Authentication;
import com.unbound.provider.kmip.request.*;
import com.unbound.provider.kmip.request.dy.DyLoginRequest;
import com.unbound.provider.kmip.response.*;
import com.unbound.provider.kmip.response.dy.DyLoginResponse;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.security.auth.x500.X500Principal;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.Clock;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class Partition
{
  private static HashMap partitions = new HashMap<>();
  private static final Clock clock = Clock.systemUTC();
  private static Partition simulator = null;

  KeyManager[] keyManagers;
  String name;
  //String clientName;
  UBKeyStore keyStore;
  private byte[] jwt = null;
  private long jwtValidityClock;

  private Partition(String name)
  {
    this.name = name;
    keyStore = new UBKeyStore(this);
  }

  private Partition(String name, KeyStore pfx, String pfxPass) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException
  {
    this(name);
    Log log = Log.func("Partition").log("name", name).end(); try
    {
      //clientName = getNameFromPfx(pfx, "CN");

      KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//"X.509");
      kmf.init(pfx, pfxPass.toCharArray());
      keyManagers = kmf.getKeyManagers();
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  private static KeyStore loadPfx(String pfxFileName, String pass) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException
  {
    Log log = Log.func("Partition.loadPfx").log("pfxFileName", pfxFileName).log("pass", pass!=null).end(); try
    {
      char[] passChars = pass == null ? null : pass.toCharArray();
      KeyStore ks = KeyStore.getInstance("pkcs12");
      ks.load(new FileInputStream(pfxFileName), passChars);
      return ks;
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  private static String getNameFromPfx(KeyStore pfx, String type) throws KeyStoreException
  {
    Enumeration aliases = pfx.aliases();
    if (!aliases.hasMoreElements()) throw new ProviderException("Empty store");
    X509Certificate cert = (X509Certificate) pfx.getCertificate(aliases.nextElement());
    if (cert == null) throw new ProviderException("Empty store");
    X500Principal principal = cert.getSubjectX500Principal();
    if (principal == null) throw new ProviderException("Invalid prinicpal");

    String ou = X509.getName(principal, type);
    if (ou==null) throw new ProviderException("Invalid prinicpal");
    return ou;

    /*X500Name x500name = new X500Name(principal.getName());
    if (x500name == null) throw new KeyStoreException("Invalid X500Name");
    return x500name.getOrganizationalUnit();*/
  }

  static synchronized Partition registerPfx(String pfxFileName, String pass) throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException, UnrecoverableKeyException
  {
    KeyStore pfx = loadPfx(pfxFileName, pass);
    return registerPfx(pfx, pass);
  }

  static synchronized Partition get(String name)
  {
    return partitions.get(name);
  }

  static synchronized Partition registerPfx(KeyStore pfx, String pass) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException
  {
    String name = getNameFromPfx(pfx, "OU");
    Partition partition = partitions.get(name);
    if (partition == null)
    {
      partition = new Partition(name, pfx, pass);
      partitions.put(name, partition);
    }
    return partition;
  }

  static synchronized Partition registerSimulator()
  {
    if (simulator==null) simulator = new Partition("sumulate");
    return simulator;
  }

  ResponseMessage transmit(RequestMessage req) throws IOException
  {
    Log log = Log.func("Partition.transmit").end(); try
    {
      byte[] jwt;
      long jwtValidityClock;
      synchronized (this)
      {
        jwt = this.jwt;
        jwtValidityClock = this.jwtValidityClock;
      }

      if (req.header.auth==null && jwt!=null)
      {
        if (jwtValidityClock < clock.millis())
        {
          loginRenew();
        }

        req.header.auth = new Authentication();
        req.header.auth.credType = KMIP.CredentialType.Attestation;
        req.header.auth.attestationType = KMIP.AttestationType.DyJwtAssertion;
        req.header.auth.attestationAssertion = jwt;
      }

      return Client.transmit(this, req);
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  ResponseItem transmit(RequestItem req) throws IOException
  {
    RequestMessage reqMsg = new RequestMessage();
    reqMsg.batch.add(req);
    ResponseMessage respMsg = transmit(reqMsg);
    return respMsg.batch.get(0);
  }

  private static GetAttributesRequest prepareGetAttrRequest(long uid)
  {
    GetAttributesRequest getAttr = new GetAttributesRequest();
    getAttr.uid = UBObject.uidToStr(uid);
    getAttr.names.add("Object Type");
    getAttr.names.add("Cryptographic Algorithm");
    getAttr.names.add("Name");
    getAttr.names.add("Initial Date");
    return getAttr;
  }

  ResponseMessage read(long[] uids, boolean get) throws IOException
  {
    RequestMessage reqMsg = new RequestMessage();
    for (long uid : uids)
    {
      GetAttributesRequest getAttr = prepareGetAttrRequest(uid);
      reqMsg.batch.add(getAttr);

      if (get)
      {
        GetRequest getReq = new GetRequest();
        getReq.uid = UBObject.uidToStr(uid);
        getReq.formatType = KMIP.KeyFormatType.X_509;
        reqMsg.batch.add(getReq);
      }
    }
    return transmit(reqMsg);
  }

  ResponseMessage read(long uid, boolean get) throws IOException
  {
    RequestMessage reqMsg = new RequestMessage();
    GetAttributesRequest getAttr = prepareGetAttrRequest(uid);
    reqMsg.batch.add(getAttr);

    if (get)
    {
      GetRequest getReq = new GetRequest();
      getReq.uid = UBObject.uidToStr(uid);
      getReq.formatType = KMIP.KeyFormatType.X_509;
      reqMsg.batch.add(getReq);
    }
    return transmit(reqMsg);
  }

  long[] locate(int kmipObjectType, int kmipAlg) throws IOException
  {
    Log log = Log.func("Partition.locate").log("kmipObjectType", kmipObjectType).log("kmipAlg", kmipAlg).end(); try
    {
      LocateRequest req = UBObject.locateRequest(kmipObjectType, kmipAlg, null);
      req.maxItems = 1024;

      LocateResponse resp = (LocateResponse) transmit(req);
      long[] result = new long[resp.list.size()];
      int index = 0;
      for (String s : resp.list)
      {
        long uid = UBObject.strToUid(s);
        Log.print("Object").logHex("uid", uid).end();
        result[index++] = uid;
      }
      return result;
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  long locate(LocateRequest req) throws IOException
  {
    long uid = 0;
    Log log = Log.func("Partition.locate").end(); try
    {
      LocateResponse resp = (LocateResponse)transmit(req);
      if (resp.list.isEmpty()) return 0;
      uid = UBObject.strToUid(resp.list.get(0));
      return uid;
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leavePrint().logHex("UID", uid).end(); }
  }

  long locate(int kmipObjectType, int kmipAlgType, String alias) throws IOException
  {
    long uid = 0;
    Log log = Log.func("Partition.locate").log("kmipObjectType", kmipObjectType).log("kmipAlgType", kmipAlgType).log("alias", alias).end(); try
    {
      LocateRequest req = UBObject.locateRequest(kmipObjectType, kmipAlgType, alias);
      uid = locate(req);
      return uid;
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leavePrint().logHex("uid", uid).end(); }
  }

  void login(String password) throws IOException
  {
    loginOrRenew(password, false);
  }

  private void loginRenew() throws IOException
  {
    loginOrRenew(null, true);
  }

  private void loginOrRenew(String password, boolean renewWjt) throws IOException
  {
    Log log = Log.func("Partition.login").log("renewWjt", renewWjt).log("password", password!=null && !password.isEmpty()).end(); try
    {
      RequestMessage reqMsg = new RequestMessage();

      reqMsg.header.auth = new Authentication();
      if (renewWjt)
      {
        reqMsg.header.auth = new Authentication();
        reqMsg.header.auth.credType = KMIP.CredentialType.Attestation;
        reqMsg.header.auth.attestationType = KMIP.AttestationType.DyJwtAssertion;
        reqMsg.header.auth.attestationAssertion = jwt;
      }
      else
      {
        reqMsg.header.auth.credType = KMIP.CredentialType.UsernameAndPassword;
        reqMsg.header.auth.username = "user";
        reqMsg.header.auth.password = "";

        if (password!=null)
        {
          String user;
          try
          {
            Map json = (Map) JSON.convert(password);
            user = (String) json.get("username");
            password = (String) json.get("password");
          }
          catch (Exception e)
          {
            user = "user";
          }
          reqMsg.header.auth.password = password;
          reqMsg.header.auth.username = user;
        }
      }

      DyLoginRequest req = new DyLoginRequest();
      req.doCreateWjt = true;
      reqMsg.batch.add(req);

      try
      {
        ResponseMessage respMsg = transmit(reqMsg);
        DyLoginResponse resp = (DyLoginResponse) respMsg.batch.get(0);
        if (resp.jwt!=null)
        {
          int validity = jwtTokenValidity(STR.utf8(resp.jwt));
          if (validity>0)
          {
            synchronized (this)
            {
              long now = clock.millis();
              jwt = resp.jwt;
              jwtValidityClock = now + validity*1000;
            }
          }
        }
      }
      catch (Exception e)
      {
        synchronized (this)
        {
          jwt = null;
        }
        throw e;
      }
    }
    catch (Exception e) { log.failed(e); throw e; } finally { log.leave(); }
  }

  private static int jwtTokenValidity(String jwt) throws IOException
  {
    String[] t = jwt.split("\\.");
    if (t.length!=3) return 0;

    byte[] t1 = Base64.decodeUrl(t[1]);
    String s = STR.utf8(t1);
    Map root = (Map) JSON.convert(s);
    Long iat = (Long)root.get("iat");
    Long exp = (Long)root.get("exp");
    return (int) (exp - iat - 30);
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy