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

common.crypto.X509 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.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Map;

public final class X509
{
  private X509() {}

  public static String OID_RSA_WITH_SHA1 =  "1.2.840.113549.1.1.5";
  public static String OID_RSA_WITH_SHA256 =  "1.2.840.113549.1.1.11";
  public static String OID_RSA_ENCRYPTION = "1.2.840.113549.1.1.1";
  public static String OID_ECDSA_WITH_SHA1 = "1.2.840.10045.4.1";
  public static String OID_ECDSA_WITH_SHA256 = "1.2.840.10045.4.3.2";
  public static String OID_ECC = "1.2.840.10045.2.1";


  public static X509Certificate get(byte[] value) throws CertificateException
  {
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    return (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(value));
  }

  public static String getOidFromRdn(String type)
  {
    if (type.equals("CN"))                                        return "2.5.4.3";  // common name
    if (type.equals("SN"))                                        return "2.5.4.4";  // surname
    if (type.equals("SERIALNUMBER"))                              return "2.5.4.5";  // serial number
    if (type.equals("C"))                                         return "2.5.4.6";  // country name
    if (type.equals("L"))                                         return "2.5.4.7";  // locality name
    if (type.equals("ST") | type.equals("SP") | type.equals("S")) return "2.5.4.8";  // state or province name
    if (type.equals("STREET"))                                    return "2.5.4.9";  // street address
    if (type.equals("O"))                                         return "2.5.4.10"; // organization name
    if (type.equals("OU"))                                        return "2.5.4.11"; // organizational unit
    if (type.equals("T") | type.equals("TITLE"))                  return "2.5.4.12"; // title
    if (type.equals("G") | type.equals("GN"))                     return "2.5.4.42"; // given name
    if (type.equals("E") | type.equals("MAIL"))                   return "1.2.840.113549.1.9.1"; // email address
    if (type.equals("UNSTRUCTUREDNAME"))                          return "1.2.840.113549.1.9.2"; // host name
    if (type.equals("UNSTRUCTUREDADDRESS"))                       return "1.2.840.113549.1.9.8"; // IP address
    if (type.equals("UID"))                                       return "0.9.2342.19200300.100.1.1"; // user ID
    if (type.equals("DC"))                                        return "0.9.2342.19200300.100.1.25"; // domain component
    return null;
  }

  public static String getRdnFromOid(String type)
  {
    if (type.equals("2.5.4.3"))                                   return "CN";  // common name
    if (type.equals("2.5.4.4"))                                   return "SN";  // surname
    if (type.equals("2.5.4.5"))                                   return"SERIALNUMBER" ;  // serial number
    if (type.equals("2.5.4.6"))                                   return "C";  // country name
    if (type.equals("2.5.4.7"))                                   return "L";  // locality name
    if (type.equals("2.5.4.8"))                                   return "ST";  // state or province name
    if (type.equals("2.5.4.9"))                                   return "STREET";  // street address
    if (type.equals("2.5.4.10"))                                  return "O"; // organization name
    if (type.equals("2.5.4.11"))                                  return "OU"; // organizational unit
    if (type.equals("2.5.4.12"))                                  return "TITLE"; // title
    if (type.equals("2.5.4.42"))                                  return "GN"; // given name
    if (type.equals("1.2.840.113549.1.9.1"))                      return "MAIL"; // email address
    if (type.equals("1.2.840.113549.1.9.2"))                      return "UNSTRUCTUREDNAME"; // host name
    if (type.equals("1.2.840.113549.1.9.8"))                      return "UNSTRUCTUREDADDRESS"; // IP address
    if (type.equals("0.9.2342.19200300.100.1.1"))                 return "UID"; // user ID
    if (type.equals("0.9.2342.19200300.100.1.25"))                return "DC"; // domain component
    return null;
  }


  public static String getName(X500Principal principal, String type)
  {
    String rdnOid = getOidFromRdn(type);

    DER.Parser parser = new DER.Parser(principal.getEncoded());
    parser.beginSequence();
    for (;;)
    {
      parser.beginSet();
        parser.beginSequence();
          String oid = parser.getOid();
          String value = parser.getString();
          if (oid.equals(type) || oid.equals(rdnOid)) return value;
        parser.end();
      parser.end();
      if (parser.endOfBlock()) break;
    }
    return null;
  }

  public static DER.Builder encode(DER.Builder builder, Map map)
  {
    builder.beginSequence();
    for (Map.Entry entry : map.entrySet())
    {
      builder.beginSet().
        beginSequence().
          addOid(getOidFromRdn(entry.getKey())).
          add(entry.getValue()).
        end().
      end();
    }
    return builder.end();
  }

  private static byte[] buildToBeSignedDER(PublicKey publicKey, X500Principal subject, X500Principal issuer, int days)
  {
    long startTime = java.lang.System.currentTimeMillis() / 1000;
    long endTime = startTime + days * 24 * 60 * 60;
    String oid = publicKey.getAlgorithm().equalsIgnoreCase("RSA") ? OID_RSA_WITH_SHA256 : OID_ECDSA_WITH_SHA256;
    BigInteger sn;
    try { sn = new BigInteger(128, SecureRandom.getInstanceStrong()); }
    catch (NoSuchAlgorithmException e) { throw new ProviderException(e); }

    return new DER.Builder().beginSequence().
      begin((byte)0xa0).addInteger(1).end().  // version v2
      add(sn).                                // serial number

      beginSequence().                        // ALG ID
        addOid(oid).
        addNull().
      end().

      add(issuer.getEncoded()).              // issuer

      beginSequence().                        // validity
        addTime(startTime).
        addTime(endTime).
      end().

      add(subject.getEncoded()).              // subject

      add(publicKey.getEncoded()).

    end().toByteArray();
  }

  private static byte[] buildCertDER(byte[] toBeSigned, PublicKey publicKey, byte[] sig)
  {
    String oid = publicKey.getAlgorithm().equalsIgnoreCase("RSA") ? OID_RSA_WITH_SHA256 : OID_ECDSA_WITH_SHA256;
    return new DER.Builder().beginSequence().
      add(toBeSigned).
      beginSequence(). // ALG ID
        addOid(oid).
        addNull().
      end().
      add(DER.TAG_BIT_STRING, sig).
    end().toByteArray();
  }

  public static X509Certificate getSelfSignCertificate(PrivateKey privateKey, PublicKey publicKey, X500Principal subject, int days) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, CertificateException
  {
    byte[] toBeSigned = buildToBeSignedDER(publicKey, subject, subject, days);
    String keyType = privateKey.getAlgorithm();
    String sigAlg = "SHA256With" + (keyType.equalsIgnoreCase("RSA") ? "RSA" : "ECDSA");
    Signature signature = Signature.getInstance(sigAlg);
    signature.initSign(privateKey);
    signature.update(toBeSigned);
    byte[] sig = signature.sign();
    byte[] certEncoded = buildCertDER(toBeSigned, publicKey, sig);
    return get(certEncoded);
  }

  public static X509Certificate signCertificate(PrivateKey privateKey, X509Certificate ca, PKCS10 csr, int days) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, CertificateException
  {
    csr.verifySignature();
    byte[] toBeSigned = buildToBeSignedDER(csr.getPublicKey(), csr.getSubject(), ca.getSubjectX500Principal(), days);
    String keyType = privateKey.getAlgorithm();
    String sigAlg = "SHA256With" + (keyType.equalsIgnoreCase("RSA") ? "RSA" : "ECDSA");
    Signature signature = Signature.getInstance(sigAlg);
    signature.initSign(privateKey);
    signature.update(toBeSigned);
    byte[] sig = signature.sign();
    byte[] certEncoded = buildCertDER(toBeSigned, ca.getPublicKey(), sig);
    return get(certEncoded);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy