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

common.crypto.PKCS10 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.common.crypto;

import javax.security.auth.x500.X500Principal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class PKCS10
{
  private PublicKey publicKey;
  private String[] dns;
  private InetAddress[] ip;
  private String challengePassword;
  private byte[] signature;
  private String signHashOid;
  private Map subject = new HashMap<>();

  public PKCS10(PublicKey publicKey)
  {
    this.publicKey = publicKey;
  }

  public PKCS10(byte[] der) throws InvalidKeySpecException, UnknownHostException
  {
    DER.Parser parser = new DER.Parser(der);
    parser.beginSequence(); // CertificationRequest
      parser.beginSequence(); // CertificationRequestInfo
        parser.getBigInteger(); // version 0

        parser.beginSequence(); // subject
        for (;;)
        {
          parser.beginSet();
            parser.beginSequence();
              String oid = parser.getOid();
              String value = parser.getString();
              subject.put(X509.getRdnFromOid(oid), value);
            parser.end();
          parser.end();
          if (parser.endOfBlock()) break;
        }
        parser.end();

        byte[] publicKeyEncoded = parser.getFullTag();

        if (parser.isTag((byte)0xa0))
        {
          parser.begin((byte)0xa0);
            parser.beginSequence();
              parser.checkOid("1.2.840.113549.1.9.14"); // certificate extensions
              parser.beginSet();
                parser.beginSequence();
                  parser.beginSequence();
                    parser.checkOid("2.5.29.17"); // subject alternative name
                    parser.beginOctetString();
                      parser.beginSequence();

                        ArrayList dnsList = new ArrayList();
                        while (parser.isTag((byte)0x82)) dnsList.add(parser.getString((byte)0x82));
                        if (!dnsList.isEmpty()) { dns = new String[dnsList.size()]; dnsList.toArray(dns); }

                        ArrayList ipList = new ArrayList();
                        while (parser.isTag((byte)0x87)) ipList.add(InetAddress.getByAddress(parser.getTagBytes((byte)0x87)));
                        if (!ipList.isEmpty()) { ip = new InetAddress[ipList.size()]; ipList.toArray(ip); }

                      parser.end();
                    parser.end();
                  parser.end();
                parser.end();
              parser.end();
            parser.end();

            if (parser.isTag(DER.TAG_SEQUENCE))
            {
              parser.beginSequence();
                parser.checkOid("1.2.840.113549.1.9.7"); // challenge password
                parser.beginSet();
                  challengePassword = parser.getString();
                parser.end();
              parser.end();
            }
          parser.end();
        }

      parser.end();

      parser.beginSequence(); // AlgorithmIdentifier
        signHashOid = parser.getOid();
        parser.skipNull();
      parser.end();
      signature = parser.getBitString(); // signature
    parser.end();

    X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyEncoded);
    KeyFactory kf = SystemProvider.KeyFactory.getInstance("RSA");
    try { publicKey = kf.generatePublic(spec); }
    catch (InvalidKeySpecException e)
    {
      kf = SystemProvider.KeyFactory.getInstance("ECDSA");
      publicKey = kf.generatePublic(spec);
    }
  }

  public PublicKey getPublicKey() { return publicKey; }

  public X500Principal getSubject()
  {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry entry : subject.entrySet())
    {
      if (sb.length()>0) sb.append(", ");
      sb.append(entry.getKey());
      sb.append("=");
      sb.append(entry.getValue());
    }
    return new X500Principal(sb.toString());
  }

  public void verifySignature() throws NoSuchAlgorithmException, InvalidKeyException, SignatureException
  {
    Signature sig;
    String sigName;
    String hashType;
    if (publicKey.getAlgorithm().equalsIgnoreCase("RSA"))
    {
      if (signHashOid.equalsIgnoreCase(X509.OID_RSA_WITH_SHA256)) hashType = "SHA256";
      else if (signHashOid.equalsIgnoreCase(X509.OID_RSA_WITH_SHA1)) hashType = "SHA1";
      else throw new IllegalArgumentException("Unsupported hash type");
      sigName = hashType + "withRSA";
    }
    else
    {
      if (signHashOid.equalsIgnoreCase(X509.OID_ECDSA_WITH_SHA256)) hashType = "SHA256";
      else if (signHashOid.equalsIgnoreCase(X509.OID_ECDSA_WITH_SHA1)) hashType = "SHA1";
      else throw new IllegalArgumentException("Unsupported hash type");
      sigName = hashType + "withECDSA";
    }

    sig = Signature.getInstance(sigName);
    sig.initVerify(publicKey);
    sig.update(toBeSigned());
    boolean ok = sig.verify(signature);
    if (!ok) throw new SignatureException("Verification failed");
  }

  public void setAlternativeSubjectName(String[] dns, InetAddress[] ip)
  {
    this.dns = dns;
    this.ip = ip;
  }

  public void setSubjectName(String type, String name)
  {
    subject.put(type, name);
  }

  public void setChallengePassword(String challengePassword)
  {
    this.challengePassword = challengePassword;
  }

  public void sign(PrivateKey key, String hashType) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException
  {
    Signature sig;
    String sigName;
    if (key.getAlgorithm().equalsIgnoreCase("RSA"))
    {
      if (hashType.equals("SHA256")) signHashOid = X509.OID_RSA_WITH_SHA256;
      else if (hashType.equals("SHA1")) signHashOid = X509.OID_RSA_WITH_SHA1;
      else throw new IllegalArgumentException("Unsupported hash type");
      sigName = hashType + "withRSA";
    }
    else
    {
      if (hashType.equals("SHA256")) signHashOid = X509.OID_ECDSA_WITH_SHA256;
      else if (hashType.equals("SHA1")) signHashOid = X509.OID_ECDSA_WITH_SHA1;
      else throw new IllegalArgumentException("Unsupported hash type");
      sigName = hashType + "withECDSA";
    }

    sig = Signature.getInstance(sigName);
    sig.initSign(key);
    sig.update(toBeSigned());
    signature = sig.sign();
  }

  private DER.Builder encodeCertificationRequestInfo(DER.Builder builder)
  {
    builder.beginSequence(). // CertificationRequestInfo
      addInteger(0); // version 0
      X509.encode(builder, subject).
      add(publicKey.getEncoded());

      if (challengePassword!=null || dns!=null || ip!=null)
      {
        builder.begin((byte)0xa0);
        if (dns!=null || ip!=null)
        {
          builder.beginSequence().
            addOid("1.2.840.113549.1.9.14"). // certificate extensions
            beginSet().
              beginSequence().
                beginSequence().
                  addOid("2.5.29.17"). // subject alternative name
                  beginOctetString().
                    beginSequence();
                      if (dns!=null) for (String s : dns)  builder.add((byte)0x82, s);
                      if (ip!=null) for (InetAddress i : ip) builder.add((byte)0x87, i.getAddress());
                    builder.end().
                  end().
                end().
              end().
            end().
          end();
        }
        if (challengePassword!=null)
        {
          builder.beginSequence().
            addOid("1.2.840.113549.1.9.7"). // challenge password
            beginSet().
              add(DER.TAG_PRINTABLE_STRING, challengePassword).
            end().
          end();
        }
        builder.end();
      }

    return builder.end();
  }

  private byte[] toBeSigned()
  {
    return encodeCertificationRequestInfo(new DER.Builder()).toByteArray();
  }

  public byte[] exportDer()
  {
    DER.Builder builder = new DER.Builder();

    builder.beginSequence(); // CertificationRequest
      encodeCertificationRequestInfo(builder).
      beginSequence(). // AlgorithmIdentifier
        addOid(signHashOid).
        addNull().
      end().
      addBitString(signature). // signature
    end();

    return builder.toByteArray();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy