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

com.unbound.client.pkcs11.PKCS11Object 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.client.pkcs11;

import com.dyadicsec.cryptoki.CK;
import com.dyadicsec.cryptoki.CKR_Exception;
import com.dyadicsec.cryptoki.CK_ATTRIBUTE;
import com.dyadicsec.cryptoki.Library;
import com.unbound.client.*;
import com.unbound.common.HEX;
import com.unbound.provider.KeyParameters;

import java.nio.charset.StandardCharsets;
import java.security.ProviderException;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
import java.util.Date;


public class PKCS11Object implements BaseObject
{
  protected final ObjectType objectType;
  protected final int handle;

  protected PKCS11Partition partition;
  protected long uid = 0;
  protected long replacedUid = 0;
  protected byte[] cka_id = null;

  static byte[] strToId(String name)
  {
    if (name==null) return new byte[0];
    int nameSize = name.length();

    if (nameSize>=4 && name.charAt(0)=='0' && name.charAt(1)=='x')
    {
      int idSize = (nameSize-2)/2;
      byte[] id = new byte[idSize];
      int p = 2;
      for (int i=0; i= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) return true;
    switch (ch)
    {
      case ' ':       /* space */
      case '\'':      /* apostrophe */
      case '(':       /* left paren */
      case ')':       /* right paren */
      case '+':       /* plus */
      case ',':       /* comma */
      case '-':       /* hyphen */
      case '.':       /* period */
      case '/':       /* slash */
      case ':':       /* colon */
      case '=':       /* equals */
      case '?':       /* question mark */
        return true;
    }
    return false;
  }

  public static String idToStr(byte[] id)
  {
    if (id==null || id.length==0) return "0x000000000000000000"; // 0x00 + UID=0

    boolean printable = true;
    for (int i=0; printable && i>4) & 0x0f];
      name[o++] = HEX.chars[(id[i]) & 0x0f];
    }

    return String.valueOf(name);
  }

  public static PKCS11Object newObject(ObjectType type, PKCS11Session session, int handle)
  {
    switch (type.getPkcs11Class())
    {
      case CK.CKO_CERTIFICATE: return new PKCS11Cert(session, handle);
      case CK.CKO_SECRET_KEY: return new PKCS11SecretKey(type, session, handle);

      case CK.CKO_PUBLIC_KEY:
        switch (type.getPkcs11KeyType())
        {
          case CK.CKK_RSA: return new PKCS11RSAPublicKey(session, handle);
        }
        break;

      case CK.CKO_PRIVATE_KEY:
        switch (type.getPkcs11KeyType())
        {
          case CK.DYCKK_ADV_PRF: return new PKCS11ECPRFKey(session, handle);
          case CK.CKK_RSA: return new PKCS11RSAPrivateKey(session, handle);
          case CK.CKK_EC: return new PKCS11ECPrivateKey(session, handle);
          case CK.DYCKK_EDDSA: return new PKCS11EDDSAPrivateKey(session, handle);
        }
        break;
    }
    throw new ProviderException("Unsupported object type");
  }

  protected void getReadTemplate(ArrayList t)
  {
    t.add(new CK_ATTRIBUTE(CK.CKA_ID));
    t.add(new CK_ATTRIBUTE(CK.DYCKA_UID));
    t.add(new CK_ATTRIBUTE(CK.DYCKA_REPLACED_UID));
  }

  protected int acceptReadTempate(CK_ATTRIBUTE[] attrs) throws CKR_Exception
  {
    cka_id = (byte[])attrs[0].pValue;
    uid = attrs[1].getLongValue();
    replacedUid = attrs[2].getLongValue();
    return 3;
  }

  protected void read(PKCS11Session session)
  {
    try
    {
      this.partition = (PKCS11Partition)session.getPartition();
      ArrayList t = new ArrayList();
      getReadTemplate(t);

      CK_ATTRIBUTE[] attrs = getAttrs(t);
      Library.C_GetAttributeValue(session.getHandle(), handle, attrs);

      acceptReadTempate(attrs);
    }
    catch (CKR_Exception e) { throw new ProviderException(e); }

  }

  PKCS11Object(ObjectType objectType, int handle)
  {
    this.objectType = objectType;
    this.handle = handle;
  }

  @Override
  public ObjectType getType()
  {
    return objectType;
  }

  @Override
  public Partition getPartition()
  {
    return partition;
  }

  @Override
  public Date getInitialDate()
  {
    return null;
  }

  @Override
  public long getUid()
  {
    return uid;
  }

  @Override
  public long getReplacedUid() { return replacedUid; }

  @Override
  public String getName()
  {
    return idToStr(cka_id);
  }

  @Override
  public void changeName(Session session, String newName)
  {
    try
    {
      byte[] new_cka_id = strToId(newName);
      Library.C_SetAttributeValue(((PKCS11Session)session).getHandle(), handle, new CK_ATTRIBUTE[]
      {
        new CK_ATTRIBUTE(CK.CKA_ID, new_cka_id)
      });
      cka_id = new_cka_id;
    }
    catch (CKR_Exception e) { throw new ProviderException(e); }
  }

  @Override
  public void delete(Session session)
  {
    try { Library.C_DestroyObject(((PKCS11Session)session).getHandle(), handle); }
    catch (CKR_Exception e) { throw new ProviderException(e); }
  }

  @Override
  public void delete()
  {
    partition.deleteObject(this);
  }

  static CK_ATTRIBUTE[] getAttrs(ArrayList t)
  {
    CK_ATTRIBUTE[] attrs = new CK_ATTRIBUTE[t.size()];
    t.toArray(attrs);
    return attrs;
  }


  static ArrayList getNewTemplate(String name, ObjectType type, KeyParameters kp)
  {
    if (type == ObjectType.RSAPub) return PKCS11RSAPublicKey.getNewTemplate(name, kp);
    if (type == ObjectType.RSAPrv) return PKCS11RSAPrivateKey.getNewTemplate(name, kp);
    if (type == ObjectType.ECPrv) return PKCS11ECPrivateKey.getNewTemplate(name, kp);
    if (type == ObjectType.ECPrf) return PKCS11ECPRFKey.getNewTemplate(name, kp);
    //if (type == ObjectType.Certificate) return PKCS11Cert.getNewTemplate(name);
    if (type.isSecretKey()) return PKCS11SecretKey.getNewTemplate(name, type, kp);
    throw new ProviderException("Unsupported key type");
  }

  static BaseObject locate(PKCS11Session session, ObjectType type, LocateParams params)
  {
    try
    {
      ArrayList t = new ArrayList<>();
      if (params.uid!=0) t.add(new CK_ATTRIBUTE(CK.DYCKA_UID, params.uid));
      else
      {
        t.add(new CK_ATTRIBUTE(CK.CKA_CLASS, type.getPkcs11Class()));
        int keyType = type.getPkcs11KeyType();
        if (keyType!=-1) t.add(new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, keyType));

        if (params.name!=null) t.add(new CK_ATTRIBUTE(CK.CKA_ID, strToId(params.name)));
        if (params.privateKeyUid!=0) t.add(new CK_ATTRIBUTE(CK.DYCKA_PRIVATE_KEY_UID, params.privateKeyUid));
        if (params.subject!=null) t.add(new CK_ATTRIBUTE(CK.CKA_SUBJECT, params.subject.getEncoded()));

        if (params.x509!=null)
        {
          try { t.add(new CK_ATTRIBUTE(CK.CKA_VALUE, params.x509.getEncoded())); }
          catch (CertificateEncodingException e) { throw new ProviderException(e); }
        }
      }

      Library.C_FindObjectsInit(session.getHandle(), getAttrs(t));
      session.setOperationInProgress(true);
      int handles[] = Library.C_FindObjects(session.getHandle(), 1);
      Library.C_FindObjectsFinal(session.getHandle());
      session.setOperationInProgress(false);

      if (handles==null || handles.length==0) return null;
      return newObject(type, session, handles[0]);
    }
    catch (CKR_Exception e) { throw new ProviderException(e); }
  }

  static ArrayList locate(PKCS11Session session, ObjectType type)
  {
    try
    {
      ArrayList list = new ArrayList<>();
      ArrayList t = new ArrayList<>();
      t.add(new CK_ATTRIBUTE(CK.CKA_CLASS, type.getPkcs11Class()));
      int keyType = type.getPkcs11KeyType();
      if (keyType!=-1) t.add(new CK_ATTRIBUTE(CK.CKA_KEY_TYPE, keyType));

      Library.C_FindObjectsInit(session.getHandle(), getAttrs(t));
      session.setOperationInProgress(true);
      int handles[] = Library.C_FindObjects(session.getHandle(), 1024);
      Library.C_FindObjectsFinal(session.getHandle());
      session.setOperationInProgress(false);

      for (int handle : handles) list.add(newObject(type, session, handle));
      return list;
    }
    catch (CKR_Exception e) { throw new ProviderException(e); }
  }
  
  static void makeExportLevel(ArrayList t, KeyParameters kp)
  {
    try
    {
      switch (kp.getExportProtection())
      {
        case -1:
        case KeyParameters.EXPORT_NONE:
          break;

        case KeyParameters.EXPORT_WRAP:
          t.add(new CK_ATTRIBUTE(CK.CKA_EXTRACTABLE, true));
          break;

        case KeyParameters.EXPORT_WRAP_WITH_TRUSTED:
          t.add(new CK_ATTRIBUTE(CK.CKA_EXTRACTABLE, true));
          t.add(new CK_ATTRIBUTE(CK.CKA_WRAP_WITH_TRUSTED, true));
          break;

        case KeyParameters.EXPORT_PLAIN:
          t.add(new CK_ATTRIBUTE(CK.CKA_SENSITIVE, false));
          break;
      }
    }
    catch (CKR_Exception e) { throw new ProviderException(e); }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy