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

org.xipki.security.util.AlgorithmUtil Maven / Gradle / Ivy

/*
 *
 * Copyright (c) 2013 - 2019 Lijun Liao
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.xipki.security.util;

import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.bsi.BSIObjectIdentifiers;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.interfaces.EdDSAKey;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.xipki.security.AlgorithmCode;
import org.xipki.security.EdECConstants;
import org.xipki.security.HashAlgo;
import org.xipki.security.ObjectIdentifiers.Xipki;
import org.xipki.security.SignatureAlgoControl;
import org.xipki.security.SignerConf;
import org.xipki.util.Args;
import org.xipki.util.StringUtil;

/**
 * Algorithm utility class.
 *
 * @author Lijun Liao
 * @since 2.0.0
 */

public class AlgorithmUtil {

  private static final List curveNames;

  private static final Map curveNameToOidMap;

  private static final Map curveOidToNameMap;

  private static final Map algOidToCodeMap;

  private static final Map sigAlgOidToDigestMap;

  private static final Map macAlgOidToDigestMap;

  private static final Map digestToECSigAlgMap;

  private static final Map digestToECPlainSigAlgMap;

  private static final Map digestToDSASigAlgMap;

  private static final Map digestToRSASigAlgMap;

  private static final Map macAlgOidToNameMap;

  private static final Map macAlgNameToOidMap;

  private static final Map sigAlgOidToNameMap;

  private static final Map sigAlgNameToOidMap;

  private static final Map digestToMgf1AlgCodeMap;

  private static final Map digestOidToMgf1SigNameMap;

  private static final Map mgf1SigNameToDigestOidMap;

  static {
    {
      //----- initialize the static fields curveNames, curveNameOidMap, curveOidNameMap
      Map nameOidMap = new HashMap<>();

      Enumeration names = ECNamedCurveTable.getNames();
      List nameList = new LinkedList<>();
      while (names.hasMoreElements()) {
        String name = ((String) names.nextElement()).toLowerCase();
        ASN1ObjectIdentifier oid = org.bouncycastle.asn1.x9.ECNamedCurveTable.getOID(name);
        if (oid == null) {
          continue;
        }

        nameList.add(name);
        nameOidMap.put(name, oid);
      }

      Map oidNameMap = new HashMap<>();

      for (String name : nameList) {
        ASN1ObjectIdentifier oid = nameOidMap.get(name);

        nameOidMap.put(name, oid);
        if (!oidNameMap.containsKey(oid)) {
          oidNameMap.put(oid, name);
        }
      }

      Collections.sort(nameList);
      curveNames = Collections.unmodifiableList(nameList);
      curveNameToOidMap = Collections.unmodifiableMap(nameOidMap);
      curveOidToNameMap = Collections.unmodifiableMap(oidNameMap);
    }

    //----- Initialize the static fields algNameCodeMap
    {
      Map map = new HashMap<>();
      // HMAC
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA1,   AlgorithmCode.HMAC_SHA1);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA224, AlgorithmCode.HMAC_SHA224);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA256, AlgorithmCode.HMAC_SHA256);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA384, AlgorithmCode.HMAC_SHA384);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA512, AlgorithmCode.HMAC_SHA512);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, AlgorithmCode.HMAC_SHA224);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, AlgorithmCode.HMAC_SHA256);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, AlgorithmCode.HMAC_SHA384);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, AlgorithmCode.HMAC_SHA512);
      map.put(Xipki.id_alg_dhPop_x25519_sha256, AlgorithmCode.DHPOP_X25519_SHA256);
      map.put(Xipki.id_alg_dhPop_x448_sha512, AlgorithmCode.DHPOP_X448_SHA512);

      // GMAC
      map.put(NISTObjectIdentifiers.id_aes128_GCM, AlgorithmCode.AES128_GMAC);
      map.put(NISTObjectIdentifiers.id_aes192_GCM, AlgorithmCode.AES192_GMAC);
      map.put(NISTObjectIdentifiers.id_aes256_GCM, AlgorithmCode.AES256_GMAC);

      // ECDSA
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA1,   AlgorithmCode.SHA1WITHECDSA);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA224, AlgorithmCode.SHA224WITHECDSA);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA256, AlgorithmCode.SHA256WITHECDSA);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA384, AlgorithmCode.SHA384WITHECDSA);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA512, AlgorithmCode.SHA512WITHECDSA);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, AlgorithmCode.SHA3_224WITHECDSA);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, AlgorithmCode.SHA3_256WITHECDSA);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, AlgorithmCode.SHA3_384WITHECDSA);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, AlgorithmCode.SHA3_512WITHECDSA);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA1, AlgorithmCode.SHA1WITHPLAIN_ECDSA);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, AlgorithmCode.SHA224WITHPLAIN_ECDSA);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, AlgorithmCode.SHA256WITHPLAIN_ECDSA);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, AlgorithmCode.SHA384WITHPLAIN_ECDSA);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, AlgorithmCode.SHA512WITHPLAIN_ECDSA);

      // DSA
      map.put(X9ObjectIdentifiers.id_dsa_with_sha1, AlgorithmCode.SHA1WITHDSA);
      map.put(NISTObjectIdentifiers.dsa_with_sha224, AlgorithmCode.SHA224WITHDSA);
      map.put(NISTObjectIdentifiers.dsa_with_sha256, AlgorithmCode.SHA256WITHDSA);
      map.put(NISTObjectIdentifiers.dsa_with_sha384, AlgorithmCode.SHA384WITHDSA);
      map.put(NISTObjectIdentifiers.dsa_with_sha512, AlgorithmCode.SHA512WITHDSA);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_224, AlgorithmCode.SHA3_224WITHDSA);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_256, AlgorithmCode.SHA3_256WITHDSA);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_384, AlgorithmCode.SHA3_384WITHDSA);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_512, AlgorithmCode.SHA3_512WITHDSA);
      // RSA
      map.put(PKCSObjectIdentifiers.sha1WithRSAEncryption, AlgorithmCode.SHA1WITHRSA);
      map.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, AlgorithmCode.SHA224WITHRSA);
      map.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, AlgorithmCode.SHA256WITHRSA);
      map.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, AlgorithmCode.SHA384WITHRSA);
      map.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, AlgorithmCode.SHA512WITHRSA);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224,
          AlgorithmCode.SHA3_224WITHRSA);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256,
          AlgorithmCode.SHA3_256WITHRSA);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384,
          AlgorithmCode.SHA3_384WITHRSA);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512,
          AlgorithmCode.SHA3_512WITHRSA);

      // SM2
      map.put(GMObjectIdentifiers.sm2sign_with_sm3, AlgorithmCode.SM2WITHSM3);

      // EDDSA
      map.put(EdECConstants.id_Ed25519, AlgorithmCode.ED25519);
      map.put(EdECConstants.id_Ed448, AlgorithmCode.ED448);

      // Hash
      for (HashAlgo hashAlgo : HashAlgo.values()) {
        map.put(hashAlgo.getOid(), hashAlgo.getAlgorithmCode());
      }
      algOidToCodeMap = Collections.unmodifiableMap(map);
    }

    //----- Initialize the static field digstMgf1AlgCodeMap
    {
      Map map = new HashMap<>();
      map.put(HashAlgo.SHA1.getOid(),   AlgorithmCode.SHA1WITHRSAANDMGF1);
      map.put(HashAlgo.SHA224.getOid(), AlgorithmCode.SHA224WITHRSAANDMGF1);
      map.put(HashAlgo.SHA256.getOid(), AlgorithmCode.SHA256WITHRSAANDMGF1);
      map.put(HashAlgo.SHA384.getOid(), AlgorithmCode.SHA384WITHRSAANDMGF1);
      map.put(HashAlgo.SHA512.getOid(), AlgorithmCode.SHA512WITHRSAANDMGF1);
      map.put(HashAlgo.SHA3_224.getOid(), AlgorithmCode.SHA3_224WITHRSAANDMGF1);
      map.put(HashAlgo.SHA3_256.getOid(), AlgorithmCode.SHA3_256WITHRSAANDMGF1);
      map.put(HashAlgo.SHA3_384.getOid(), AlgorithmCode.SHA3_384WITHRSAANDMGF1);
      map.put(HashAlgo.SHA3_512.getOid(), AlgorithmCode.SHA3_512WITHRSAANDMGF1);
      digestToMgf1AlgCodeMap = Collections.unmodifiableMap(map);
    }

    //----- Initialize the static fields digestECSigAlgMap, digestECPlainSigAlgMap,
    // digestDSASigAlgMap, digestRSASigAlgMap
    {
      // ECDSA
      Map map = new HashMap<>();
      map.put(HashAlgo.SHA1,   X9ObjectIdentifiers.ecdsa_with_SHA1);
      map.put(HashAlgo.SHA224, X9ObjectIdentifiers.ecdsa_with_SHA224);
      map.put(HashAlgo.SHA256, X9ObjectIdentifiers.ecdsa_with_SHA256);
      map.put(HashAlgo.SHA384, X9ObjectIdentifiers.ecdsa_with_SHA384);
      map.put(HashAlgo.SHA512, X9ObjectIdentifiers.ecdsa_with_SHA512);
      map.put(HashAlgo.SHA3_224, NISTObjectIdentifiers.id_ecdsa_with_sha3_224);
      map.put(HashAlgo.SHA3_256, NISTObjectIdentifiers.id_ecdsa_with_sha3_256);
      map.put(HashAlgo.SHA3_384, NISTObjectIdentifiers.id_ecdsa_with_sha3_384);
      map.put(HashAlgo.SHA3_512, NISTObjectIdentifiers.id_ecdsa_with_sha3_512);
      digestToECSigAlgMap = Collections.unmodifiableMap(map);

      // PlainECDSA
      map = new HashMap<>();
      map.put(HashAlgo.SHA1,   BSIObjectIdentifiers.ecdsa_plain_SHA1);
      map.put(HashAlgo.SHA224, BSIObjectIdentifiers.ecdsa_plain_SHA224);
      map.put(HashAlgo.SHA256, BSIObjectIdentifiers.ecdsa_plain_SHA256);
      map.put(HashAlgo.SHA384, BSIObjectIdentifiers.ecdsa_plain_SHA384);
      map.put(HashAlgo.SHA512, BSIObjectIdentifiers.ecdsa_plain_SHA512);
      digestToECPlainSigAlgMap = Collections.unmodifiableMap(map);

      // DSA
      map = new HashMap<>();
      map.put(HashAlgo.SHA1,   X9ObjectIdentifiers.id_dsa_with_sha1);
      map.put(HashAlgo.SHA224, NISTObjectIdentifiers.dsa_with_sha224);
      map.put(HashAlgo.SHA256, NISTObjectIdentifiers.dsa_with_sha256);
      map.put(HashAlgo.SHA384, NISTObjectIdentifiers.dsa_with_sha384);
      map.put(HashAlgo.SHA512, NISTObjectIdentifiers.dsa_with_sha512);
      map.put(HashAlgo.SHA3_224, NISTObjectIdentifiers.id_dsa_with_sha3_224);
      map.put(HashAlgo.SHA3_256, NISTObjectIdentifiers.id_dsa_with_sha3_256);
      map.put(HashAlgo.SHA3_384, NISTObjectIdentifiers.id_dsa_with_sha3_384);
      map.put(HashAlgo.SHA3_512, NISTObjectIdentifiers.id_dsa_with_sha3_512);
      digestToDSASigAlgMap = Collections.unmodifiableMap(map);

      // RSA
      map = new HashMap<>();
      map.put(HashAlgo.SHA1,   PKCSObjectIdentifiers.sha1WithRSAEncryption);
      map.put(HashAlgo.SHA224, PKCSObjectIdentifiers.sha224WithRSAEncryption);
      map.put(HashAlgo.SHA256, PKCSObjectIdentifiers.sha256WithRSAEncryption);
      map.put(HashAlgo.SHA384, PKCSObjectIdentifiers.sha384WithRSAEncryption);
      map.put(HashAlgo.SHA512, PKCSObjectIdentifiers.sha512WithRSAEncryption);
      map.put(HashAlgo.SHA3_224, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224);
      map.put(HashAlgo.SHA3_256, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256);
      map.put(HashAlgo.SHA3_384, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384);
      map.put(HashAlgo.SHA3_512, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512);
      digestToRSASigAlgMap = Collections.unmodifiableMap(map);
    }

    //----- Initialize the static fields sigAlgOidDigestMap
    {
      Map map = new HashMap<>();
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA1,   HashAlgo.SHA1);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA224, HashAlgo.SHA224);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA256, HashAlgo.SHA256);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA384, HashAlgo.SHA384);
      map.put(X9ObjectIdentifiers.ecdsa_with_SHA512, HashAlgo.SHA512);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, HashAlgo.SHA3_224);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, HashAlgo.SHA3_256);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, HashAlgo.SHA3_384);
      map.put(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, HashAlgo.SHA3_512);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA1,   HashAlgo.SHA1);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA224, HashAlgo.SHA224);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA256, HashAlgo.SHA256);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA384, HashAlgo.SHA384);
      map.put(BSIObjectIdentifiers.ecdsa_plain_SHA512, HashAlgo.SHA512);
      map.put(X9ObjectIdentifiers.id_dsa_with_sha1,  HashAlgo.SHA1);
      map.put(NISTObjectIdentifiers.dsa_with_sha224, HashAlgo.SHA224);
      map.put(NISTObjectIdentifiers.dsa_with_sha256, HashAlgo.SHA256);
      map.put(NISTObjectIdentifiers.dsa_with_sha384, HashAlgo.SHA384);
      map.put(NISTObjectIdentifiers.dsa_with_sha512, HashAlgo.SHA512);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_224, HashAlgo.SHA3_224);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_256, HashAlgo.SHA3_256);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_384, HashAlgo.SHA3_384);
      map.put(NISTObjectIdentifiers.id_dsa_with_sha3_512, HashAlgo.SHA3_512);
      map.put(PKCSObjectIdentifiers.sha1WithRSAEncryption,   HashAlgo.SHA1);
      map.put(PKCSObjectIdentifiers.sha224WithRSAEncryption, HashAlgo.SHA224);
      map.put(PKCSObjectIdentifiers.sha256WithRSAEncryption, HashAlgo.SHA256);
      map.put(PKCSObjectIdentifiers.sha384WithRSAEncryption, HashAlgo.SHA384);
      map.put(PKCSObjectIdentifiers.sha512WithRSAEncryption, HashAlgo.SHA512);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, HashAlgo.SHA3_224);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, HashAlgo.SHA3_256);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, HashAlgo.SHA3_384);
      map.put(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, HashAlgo.SHA3_512);
      map.put(GMObjectIdentifiers.sm2sign_with_sm3, HashAlgo.SM3);
      sigAlgOidToDigestMap = Collections.unmodifiableMap(map);
    }

    //----- Initialize the static field macAlgOidDigestMap
    {
      Map map = new HashMap<>();
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA1,   HashAlgo.SHA1);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA224, HashAlgo.SHA224);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA256, HashAlgo.SHA256);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA384, HashAlgo.SHA384);
      map.put(PKCSObjectIdentifiers.id_hmacWithSHA512, HashAlgo.SHA512);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_224, HashAlgo.SHA224);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_256, HashAlgo.SHA256);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_384, HashAlgo.SHA384);
      map.put(NISTObjectIdentifiers.id_hmacWithSHA3_512, HashAlgo.SHA512);
      macAlgOidToDigestMap = Collections.unmodifiableMap(map);
    }

    //----- Initialize the static field macAlgIdNameMap
    {
      Map m1 = new HashMap<>();
      Map m2 = new HashMap<>();

      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_aes128_GCM, "AES128GMAC");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_aes192_GCM, "AES192GMAC");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_aes256_GCM, "AES256GMAC");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.id_hmacWithSHA1,   "HMACSHA1");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.id_hmacWithSHA224, "HMACSHA224");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.id_hmacWithSHA256, "HMACSHA256");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.id_hmacWithSHA384, "HMACSHA384");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.id_hmacWithSHA512, "HMACSHA512");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_hmacWithSHA3_224, "HMACSHA3-224");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_hmacWithSHA3_256, "HMACSHA3-256");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_hmacWithSHA3_384, "HMACSHA3-384");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_hmacWithSHA3_512, "HMACSHA3-512");

      macAlgOidToNameMap = Collections.unmodifiableMap(m1);
      macAlgNameToOidMap = Collections.unmodifiableMap(m2);
    }

    //----- Initialize the static fields sigAlgOidNameMap, digestMgf1SigAlgNameMap.
    {
      Map m1 = new HashMap<>();
      Map m2 = new HashMap<>();

      addOidNameMap(m1, m2, X9ObjectIdentifiers.ecdsa_with_SHA1, "SHA1WITHECDSA",
          "ECDSAWITHSHA1");
      addOidNameMap(m1, m2, X9ObjectIdentifiers.ecdsa_with_SHA224, "SHA224WITHECDSA",
          "ECDSAWITHSHA224");
      addOidNameMap(m1, m2, X9ObjectIdentifiers.ecdsa_with_SHA256, "SHA256WITHECDSA",
          "ECDSAWITHSHA256");
      addOidNameMap(m1, m2, X9ObjectIdentifiers.ecdsa_with_SHA384, "SHA384WITHECDSA",
          "ECDSAWITHSHA384");
      addOidNameMap(m1, m2, X9ObjectIdentifiers.ecdsa_with_SHA512, "SHA512WITHECDSA",
          "ECDSAWITHSHA512");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_ecdsa_with_sha3_224,
          "SHA3-224WITHECDSA", "ECDSAWITHSHA3-224");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_ecdsa_with_sha3_256,
          "SHA3-256WITHECDSA", "ECDSAWITHSHA3-256");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_ecdsa_with_sha3_384,
          "SHA3-384WITHECDSA", "ECDSAWITHSHA3-384");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_ecdsa_with_sha3_512,
          "SHA3-512WITHECDSA", "ECDSAWITHSHA3-512");
      addOidNameMap(m1, m2, BSIObjectIdentifiers.ecdsa_plain_SHA1,
          "SHA1WITHPLAINECDSA", "PLAINECDSAWITHSHA1");
      addOidNameMap(m1, m2, BSIObjectIdentifiers.ecdsa_plain_SHA224,
          "SHA224WITHPLAIN-ECDSA", "PLAINECDSAWITHSHA224");
      addOidNameMap(m1, m2, BSIObjectIdentifiers.ecdsa_plain_SHA256,
          "SHA256WITHPLAINECDSA", "PLAINECDSAWITHSHA256");
      addOidNameMap(m1, m2, BSIObjectIdentifiers.ecdsa_plain_SHA384,
          "SHA384WITHPLAINECDSA", "PLAINECDSAWITHSHA384");
      addOidNameMap(m1, m2, BSIObjectIdentifiers.ecdsa_plain_SHA512,
          "SHA512WITHPLAINECDSA", "PLAINECDSAWITHSHA512");
      addOidNameMap(m1, m2, X9ObjectIdentifiers.id_dsa_with_sha1, "SHA1WITHDSA",
          "DSAWITHSHA1");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.dsa_with_sha224, "SHA224WITHDSA",
          "DSAWITHSHA224");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.dsa_with_sha256, "SHA256WITHDSA",
          "DSAWITHSHA256");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.dsa_with_sha384, "SHA384WITHDSA",
          "DSAWITHSHA384");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.dsa_with_sha512, "SHA512WITHDSA",
          "DSAWITHSHA512");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_dsa_with_sha3_224, "SHA3-224WITHDSA",
          "DSAWITHSHA3-224");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_dsa_with_sha3_256, "SHA3-256WITHDSA",
          "DSAWITHSHA3-256");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_dsa_with_sha3_384, "SHA3-384WITHDSA",
          "DSAWITHSHA3-384");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_dsa_with_sha3_512, "SHA3-512WITHDSA",
          "DSAWITHSHA3-512");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.sha1WithRSAEncryption, "SHA1WITHRSA",
          "RSAWITHSHA1");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.sha224WithRSAEncryption, "SHA224WITHRSA",
          "RSAWITHSHA224");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.sha256WithRSAEncryption, "SHA256WITHRSA",
          "RSAWITHSHA256");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.sha384WithRSAEncryption, "SHA384WITHRSA",
          "RSAWITHSHA384");
      addOidNameMap(m1, m2, PKCSObjectIdentifiers.sha512WithRSAEncryption, "SHA512WITHRSA",
          "RSAWITHSHA512");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224,
          "SHA3-224WITHRSA", "RSAWITHSHA3-224");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256,
          "SHA3-256WITHRSA", "RSAWITHSHA3-256");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384,
          "SHA3-384WITHRSA", "RSAWITHSHA3-384");
      addOidNameMap(m1, m2, NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512,
          "SHA3-512WITHRSA", "RSAWITHSHA3-512");
      addOidNameMap(m1, m2, GMObjectIdentifiers.sm2sign_with_sm3, "SM3WITHSM2", "SM2WITHSM3");
      addOidNameMap(m1, m2, EdECConstants.id_Ed25519, EdECConstants.Ed25519);
      addOidNameMap(m1, m2, EdECConstants.id_Ed448, EdECConstants.Ed448);

      // DH-Poc
      addOidNameMap(m1, m2, Xipki.id_alg_dhPop_x25519_sha256, "DHPOP-X25519-SHA256");
      addOidNameMap(m1, m2, Xipki.id_alg_dhPop_x448_sha512, "DHPOP-X448-SHA512");

      sigAlgOidToNameMap = Collections.unmodifiableMap(m1);
      sigAlgNameToOidMap = Collections.unmodifiableMap(m2);

      m1 = new HashMap<>();
      Map m3 = new HashMap<>();
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA1,   "SHA1WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA224, "SHA224WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA256, "SHA256WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA384, "SHA384WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA512, "SHA512WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA3_224, "SHA3-224WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA3_256, "SHA3-256WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA3_384, "SHA3-384WITHRSAANDMGF1");
      addHashAlgoNameMap(m1, m3, HashAlgo.SHA3_512, "SHA3-512WITHRSAANDMGF1");
      digestOidToMgf1SigNameMap = Collections.unmodifiableMap(m1);
      mgf1SigNameToDigestOidMap = Collections.unmodifiableMap(m3);
    }

  } // method static

  private static void addOidNameMap(Map oidNameMap,
      Map nameOidMap, ASN1ObjectIdentifier oid, String... names) {
    oidNameMap.put(oid, names[0].toUpperCase());
    nameOidMap.put(oid.getId(), oid);
    for (String name : names) {
      nameOidMap.put(name.toUpperCase(), oid);
    }
  } // method addOidNameMap

  private static void addHashAlgoNameMap(Map oidNameMap,
      Map nameOidMap, HashAlgo hashAlgo, String... names) {
    oidNameMap.put(hashAlgo.getOid(), names[0].toUpperCase());
    nameOidMap.put(hashAlgo.getOid().getId(), hashAlgo);
    for (String name : names) {
      nameOidMap.put(name.toUpperCase(), hashAlgo);
    }
  } // method addHashAlgoNameMap

  private AlgorithmUtil() {
  }

  public static ASN1ObjectIdentifier getHashAlg(String hashAlgName)
      throws NoSuchAlgorithmException {
    Args.notBlank(hashAlgName, "hashAlgName");
    HashAlgo hashAlgo = HashAlgo.getInstance(hashAlgName.toUpperCase());
    if (hashAlgo == null) {
      throw new NoSuchAlgorithmException("Unsupported hash algorithm " + hashAlgName);
    }
    return hashAlgo.getOid();
  } // method getHashAlg

  public static int getHashOutputSizeInOctets(ASN1ObjectIdentifier hashAlgo)
      throws NoSuchAlgorithmException {
    Args.notNull(hashAlgo, "hashAlgo");
    HashAlgo hashAlgoType = HashAlgo.getInstance(hashAlgo);
    if (hashAlgoType == null) {
      throw new NoSuchAlgorithmException("Unsupported hash algorithm " + hashAlgo.getId());
    }
    return hashAlgoType.getLength();
  } // method getHashOutputSizeInOctets

  public static AlgorithmCode getSigOrMacAlgoCode(AlgorithmIdentifier algId)
      throws NoSuchAlgorithmException {
    ASN1ObjectIdentifier oid = algId.getAlgorithm();
    AlgorithmCode code = algOidToCodeMap.get(oid);
    if (code != null) {
      return code;
    }

    if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(oid)) {
      RSASSAPSSparams param = RSASSAPSSparams.getInstance(algId.getParameters());
      ASN1ObjectIdentifier digestAlgOid = param.getHashAlgorithm().getAlgorithm();
      code = digestToMgf1AlgCodeMap.get(digestAlgOid);
      if (code == null) {
        throw new NoSuchAlgorithmException("unsupported digest algorithm " + digestAlgOid);
      }
      return code;
    } else {
      throw new NoSuchAlgorithmException("unsupported signature algorithm " + oid.getId());
    }
  } // method getSigOrMacAlgoCode

  public static String getSigOrMacAlgoName(AlgorithmIdentifier sigAlgId)
      throws NoSuchAlgorithmException {
    ASN1ObjectIdentifier algOid = Args.notNull(sigAlgId, "sigAlgId").getAlgorithm();
    String name = macAlgOidToNameMap.get(algOid);
    return (name != null) ? name : getSignatureAlgoName(sigAlgId);
  } // method getSigOrMacAlgoName

  public static String getSignatureAlgoName(AlgorithmIdentifier sigAlgId)
      throws NoSuchAlgorithmException {
    ASN1ObjectIdentifier algOid = Args.notNull(sigAlgId, "sigAlgId").getAlgorithm();
    String name = null;
    if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(algOid)) {
      RSASSAPSSparams param = RSASSAPSSparams.getInstance(sigAlgId.getParameters());
      ASN1ObjectIdentifier digestAlgOid = param.getHashAlgorithm().getAlgorithm();
      name = digestOidToMgf1SigNameMap.get(digestAlgOid);
      if (name == null) {
        throw new NoSuchAlgorithmException("unsupported digest algorithm " + digestAlgOid);
      }
    } else {
      name = sigAlgOidToNameMap.get(algOid);
    }

    if (name == null) {
      throw new NoSuchAlgorithmException("unsupported signature algorithm " + algOid.getId());
    }
    return name;
  } // method getSignatureAlgoName

  // CHECKSTYLE:SKIP
  public static boolean isDSAPlainSigAlg(AlgorithmIdentifier algId) {
    return isPlainECDSASigAlg(algId);
  } // method isDSAPlainSigAlg

  public static String canonicalizeSignatureAlgo(String algoName) throws NoSuchAlgorithmException {
    return getSignatureAlgoName(getSigAlgId(algoName));
  } // method canonicalizeSignatureAlgo

  public static AlgorithmIdentifier getMacAlgId(String macAlgName) throws NoSuchAlgorithmException {
    String algoS = Args.notNull(macAlgName, "macAlgName").toUpperCase();
    algoS = canonicalizeAlgoText(algoS);

    ASN1ObjectIdentifier oid = macAlgNameToOidMap.get(algoS);
    if (oid == null) {
      throw new NoSuchAlgorithmException("unsupported MAC algorithm " + algoS);
    }
    return new AlgorithmIdentifier(oid, DERNull.INSTANCE);
  } // method getMacAlgId

  public static AlgorithmIdentifier getSigAlgId(String sigAlgName) throws NoSuchAlgorithmException {
    String algoS = Args.notNull(sigAlgName, "sigAlgName").toUpperCase();
    algoS = canonicalizeAlgoText(algoS);

    AlgorithmIdentifier signatureAlgId;
    if (algoS.contains("MGF1")) {
      HashAlgo ha = mgf1SigNameToDigestOidMap.get(algoS);
      if (ha == null) {
        throw new NoSuchAlgorithmException("unknown algorithm " + algoS);
      }

      signatureAlgId = buildRSAPSSAlgId(ha);
    } else {
      ASN1ObjectIdentifier algOid = sigAlgNameToOidMap.get(algoS);
      if (algOid == null) {
        throw new NoSuchAlgorithmException("unknown algorithm " + algoS);
      }
      boolean withNullParam = algoS.contains("RSA");
      signatureAlgId = withNullParam ? new AlgorithmIdentifier(algOid, DERNull.INSTANCE)
          : new AlgorithmIdentifier(algOid);
    }

    return signatureAlgId;
  } // method getSigAlgId

  public static AlgorithmIdentifier getSigAlgId(PublicKey pubKey, SignerConf signerConf)
      throws NoSuchAlgorithmException {
    if (Args.notNull(signerConf, "signerConf").getHashAlgo() == null) {
      return getSigAlgId(signerConf.getConfValue("algo"));
    } else {
      SignatureAlgoControl algoControl = signerConf.getSignatureAlgoControl();
      HashAlgo hashAlgo = signerConf.getHashAlgo();

      if (pubKey instanceof RSAPublicKey) {
        boolean rsaMgf1 = (algoControl == null) ? false : algoControl.isRsaMgf1();
        return getRSASigAlgId(hashAlgo, rsaMgf1);
      } else if (pubKey instanceof ECPublicKey) {
        boolean dsaPlain = (algoControl == null) ? false : algoControl.isDsaPlain();
        boolean gm =  (algoControl == null) ? false : algoControl.isGm();
        return getECSigAlgId(hashAlgo, dsaPlain, gm);
      } else if (pubKey instanceof DSAPublicKey) {
        return getDSASigAlgId(hashAlgo);
      } else if (pubKey instanceof EdDSAKey) {
        String keyAlgo = pubKey.getAlgorithm();
        if (keyAlgo.equalsIgnoreCase(EdECConstants.Ed25519)) {
          return new AlgorithmIdentifier(EdECConstants.id_Ed25519);
        } else if (keyAlgo.equalsIgnoreCase(EdECConstants.Ed448)) {
          return new AlgorithmIdentifier(EdECConstants.id_Ed448);
        } else {
          throw new NoSuchAlgorithmException("Unknown Edwards public key " + keyAlgo);
        }
      } else {
        throw new NoSuchAlgorithmException("Unknown public key " + pubKey.getClass().getName());
      }
    }
  } // method getSigAlgId

  public static AlgorithmIdentifier getSigAlgId(PublicKey pubKey, HashAlgo hashAlgo,
      SignatureAlgoControl algoControl) throws NoSuchAlgorithmException {
    Args.notNull(hashAlgo, "hashAlgo");

    if (pubKey instanceof RSAPublicKey) {
      boolean rsaMgf1 = (algoControl == null) ? false : algoControl.isRsaMgf1();
      return getRSASigAlgId(hashAlgo, rsaMgf1);
    } else if (pubKey instanceof ECPublicKey) {
      boolean dsaPlain = (algoControl == null) ? false : algoControl.isDsaPlain();
      boolean gm =  (algoControl == null) ? false : algoControl.isGm();
      return getECSigAlgId(hashAlgo, dsaPlain, gm);
    } else if (pubKey instanceof DSAPublicKey) {
      return getDSASigAlgId(hashAlgo);
    } else {
      throw new NoSuchAlgorithmException("Unknown public key '" + pubKey.getClass().getName());
    }
  } // method getSigAlgId

  // CHECKSTYLE:SKIP
  public static boolean isRSASigAlgId(AlgorithmIdentifier algId) {
    ASN1ObjectIdentifier oid = Args.notNull(algId, "algId").getAlgorithm();
    if (PKCSObjectIdentifiers.sha1WithRSAEncryption.equals(oid)
        || PKCSObjectIdentifiers.sha224WithRSAEncryption.equals(oid)
        || PKCSObjectIdentifiers.sha256WithRSAEncryption.equals(oid)
        || PKCSObjectIdentifiers.sha384WithRSAEncryption.equals(oid)
        || PKCSObjectIdentifiers.sha512WithRSAEncryption.equals(oid)
        || NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224.equals(oid)
        || NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256.equals(oid)
        || NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384.equals(oid)
        || NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512.equals(oid)
        || PKCSObjectIdentifiers.id_RSASSA_PSS.equals(oid)) {
      return true;
    }

    return false;
  } // method isRSASigAlgId

  // CHECKSTYLE:SKIP
  public static boolean isECSigAlg(AlgorithmIdentifier algId) {
    return isECDSASigAlg(algId) || isPlainECDSASigAlg(algId);
  } // method isECSigAlg

  // CHECKSTYLE:SKIP
  private static boolean isECDSASigAlg(AlgorithmIdentifier algId) {
    ASN1ObjectIdentifier oid = Args.notNull(algId, "algId").getAlgorithm();
    if (X9ObjectIdentifiers.ecdsa_with_SHA1.equals(oid)
        || X9ObjectIdentifiers.ecdsa_with_SHA224.equals(oid)
        || X9ObjectIdentifiers.ecdsa_with_SHA256.equals(oid)
        || X9ObjectIdentifiers.ecdsa_with_SHA384.equals(oid)
        || X9ObjectIdentifiers.ecdsa_with_SHA512.equals(oid)
        || NISTObjectIdentifiers.id_ecdsa_with_sha3_224.equals(oid)
        || NISTObjectIdentifiers.id_ecdsa_with_sha3_256.equals(oid)
        || NISTObjectIdentifiers.id_ecdsa_with_sha3_384.equals(oid)
        || NISTObjectIdentifiers.id_ecdsa_with_sha3_512.equals(oid)) {
      return true;
    }

    return false;
  } // method isECDSASigAlg

  // CHECKSTYLE:SKIP
  public static boolean isPlainECDSASigAlg(AlgorithmIdentifier algId) {
    ASN1ObjectIdentifier oid = Args.notNull(algId, "algId").getAlgorithm();
    if (BSIObjectIdentifiers.ecdsa_plain_SHA1.equals(oid)
        || BSIObjectIdentifiers.ecdsa_plain_SHA224.equals(oid)
        || BSIObjectIdentifiers.ecdsa_plain_SHA256.equals(oid)
        || BSIObjectIdentifiers.ecdsa_plain_SHA384.equals(oid)
        || BSIObjectIdentifiers.ecdsa_plain_SHA512.equals(oid)) {
      return true;
    }

    return false;
  } // method isPlainECDSASigAlg

  // CHECKSTYLE:SKIP
  public static boolean isSM2SigAlg(AlgorithmIdentifier algId) {
    ASN1ObjectIdentifier oid = Args.notNull(algId, "algId").getAlgorithm();
    if (GMObjectIdentifiers.sm2sign_with_sm3.equals(oid)) {
      return true;
    }

    // other algorithms not supported yet.
    return false;
  } // method isSM2SigAlg

  // CHECKSTYLE:SKIP
  public static boolean isDSASigAlg(AlgorithmIdentifier algId) {
    ASN1ObjectIdentifier oid = Args.notNull(algId, "algId").getAlgorithm();
    if (X9ObjectIdentifiers.id_dsa_with_sha1.equals(oid)
        || NISTObjectIdentifiers.dsa_with_sha224.equals(oid)
        || NISTObjectIdentifiers.dsa_with_sha256.equals(oid)
        || NISTObjectIdentifiers.dsa_with_sha384.equals(oid)
        || NISTObjectIdentifiers.dsa_with_sha512.equals(oid)
        || NISTObjectIdentifiers.id_dsa_with_sha3_224.equals(oid)
        || NISTObjectIdentifiers.id_dsa_with_sha3_256.equals(oid)
        || NISTObjectIdentifiers.id_dsa_with_sha3_384.equals(oid)
        || NISTObjectIdentifiers.id_dsa_with_sha3_512.equals(oid)) {
      return true;
    }

    return false;
  } // method isDSASigAlg

  // CHECKSTYLE:SKIP
  private static AlgorithmIdentifier getRSASigAlgId(HashAlgo hashAlgo, boolean mgf1)
      throws NoSuchAlgorithmException {
    Args.notNull(hashAlgo, "hashAlgo");
    if (mgf1) {
      return buildRSAPSSAlgId(hashAlgo);
    }

    ASN1ObjectIdentifier sigAlgOid = digestToRSASigAlgMap.get(hashAlgo);
    if (sigAlgOid == null) {
      throw new NoSuchAlgorithmException("unsupported hash " + hashAlgo + " for RSA key");
    }

    return new AlgorithmIdentifier(sigAlgOid, DERNull.INSTANCE);
  } // method getRSASigAlgId

  // CHECKSTYLE:SKIP
  private static AlgorithmIdentifier getDSASigAlgId(HashAlgo hashAlgo)
      throws NoSuchAlgorithmException {
    Args.notNull(hashAlgo, "hashAlgo");

    ASN1ObjectIdentifier sigAlgOid  = digestToDSASigAlgMap.get(hashAlgo);
    if (sigAlgOid == null) {
      throw new NoSuchAlgorithmException("unsupported hash " + hashAlgo + " for DSA key");
    }

    return new AlgorithmIdentifier(sigAlgOid);
  } // method getDSASigAlgId

  // CHECKSTYLE:SKIP
  private static AlgorithmIdentifier getECSigAlgId(HashAlgo hashAlgo, boolean plainSignature,
      boolean gm) throws NoSuchAlgorithmException {
    Args.notNull(hashAlgo, "hashAlgo");
    if (gm && plainSignature) {
      throw new IllegalArgumentException("plainSignature and gm cannot be both true");
    }

    ASN1ObjectIdentifier sigAlgOid;

    if (gm) {
      switch (hashAlgo) {
        case SM3:
          sigAlgOid = GMObjectIdentifiers.sm2sign_with_sm3;
          break;
        default:
          throw new NoSuchAlgorithmException("unsupported hash " + hashAlgo + " for SM2 EC key");
      }
    } else if (plainSignature) {
      sigAlgOid = digestToECPlainSigAlgMap.get(hashAlgo);
      if (sigAlgOid == null) {
        throw new NoSuchAlgorithmException("unsupported hash " + hashAlgo + " for SM2 EC key");
      }
    } else {
      sigAlgOid = digestToECSigAlgMap.get(hashAlgo);
      if (sigAlgOid == null) {
        throw new NoSuchAlgorithmException("unsupported hash " + hashAlgo + " for EC key");
      }
    }

    return new AlgorithmIdentifier(sigAlgOid);
  } // method getECDSASigAlgId

  public static HashAlgo extractHashAlgoFromMacAlg(AlgorithmIdentifier macAlg) {
    ASN1ObjectIdentifier oid = macAlg.getAlgorithm();
    HashAlgo hashAlgo = macAlgOidToDigestMap.get(oid);
    if (hashAlgo == null) {
      throw new IllegalArgumentException("unknown algorithm identifier " + oid.getId());
    }
    return hashAlgo;
  } // method extractHashAlgoFromMacAlg

  public static AlgorithmIdentifier extractDigesetAlgFromSigAlg(AlgorithmIdentifier sigAlgId)
      throws NoSuchAlgorithmException {
    ASN1ObjectIdentifier algOid = sigAlgId.getAlgorithm();

    ASN1ObjectIdentifier digestAlgOid;
    if (PKCSObjectIdentifiers.id_RSASSA_PSS.equals(algOid)) {
      ASN1Encodable asn1Encodable = sigAlgId.getParameters();
      RSASSAPSSparams param = RSASSAPSSparams.getInstance(asn1Encodable);
      digestAlgOid = param.getHashAlgorithm().getAlgorithm();
    } else {
      HashAlgo digestAlg = sigAlgOidToDigestMap.get(algOid);
      if (digestAlg == null) {
        throw new NoSuchAlgorithmException("unknown signature algorithm " + algOid.getId());
      }
      digestAlgOid = digestAlg.getOid();
    }

    return new AlgorithmIdentifier(digestAlgOid, DERNull.INSTANCE);
  } // method extractDigesetAlgFromSigAlg

  public static boolean equalsAlgoName(String algoNameA, String algoNameB) {
    Args.notBlank(algoNameA, "algoNameA");
    Args.notBlank(algoNameB, "algoNameB");
    if (algoNameA.equalsIgnoreCase(algoNameB)) {
      return true;
    }

    String tmpA = algoNameA;
    if (tmpA.indexOf('-') != -1) {
      tmpA = tmpA.replace("-", "");
    }

    String tmpB = algoNameB;
    if (tmpB.indexOf('-') != -1) {
      tmpB = tmpB.replace("-", "");
    }

    if (tmpA.equalsIgnoreCase(tmpB)) {
      return true;
    }

    return splitAlgoNameTokens(tmpA).equals(splitAlgoNameTokens(tmpB));
  } // method equalsAlgoName

  private static Set splitAlgoNameTokens(String algoName) {
    Args.notBlank(algoName, "algoName");
    String tmpAlgoName = algoName.toUpperCase();
    int idx = tmpAlgoName.indexOf("AND");
    Set set = new HashSet<>();

    if (idx == -1) {
      set.add(tmpAlgoName);
      return set;
    }

    final int len = tmpAlgoName.length();

    int beginIndex = 0;
    int endIndex = idx;
    while (true) {
      String token = tmpAlgoName.substring(beginIndex, endIndex);
      if (StringUtil.isNotBlank(token)) {
        set.add(token);
      }

      if (endIndex >= len) {
        return set;
      }
      beginIndex = endIndex + 3; // 3 = "AND".length()
      endIndex = tmpAlgoName.indexOf("AND", beginIndex);
      if (endIndex == -1) {
        endIndex = len;
      }
    }
  } // method splitAlgoNameTokens

  // CHECKSTYLE:SKIP
  private static AlgorithmIdentifier buildRSAPSSAlgId(HashAlgo digestAlg)
      throws NoSuchAlgorithmException {
    RSASSAPSSparams params = createPSSRSAParams(digestAlg);
    return new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS, params);
  } // method buildRSAPSSAlgId

  // CHECKSTYLE:SKIP
  private static RSASSAPSSparams createPSSRSAParams(HashAlgo digestAlg)
      throws NoSuchAlgorithmException {
    int saltSize = Args.notNull(digestAlg, "digestAlg").getLength();
    AlgorithmIdentifier digAlgId = new AlgorithmIdentifier(digestAlg.getOid(), DERNull.INSTANCE);
    return new RSASSAPSSparams(digAlgId,
        new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, digAlgId),
        new ASN1Integer(saltSize), RSASSAPSSparams.DEFAULT_TRAILER_FIELD);
  } // method createPSSRSAParams

  private static ASN1ObjectIdentifier getCurveOidForName(String curveName) {
    return curveNameToOidMap.get(Args.toNonBlankLower(curveName, "curveName"));
  } // method getCurveOidForName

  // CHECKSTYLE:SKIP
  public static List getECCurveNames() {
    return curveNames;
  }

  public static String getCurveName(ASN1ObjectIdentifier curveOid) {
    Args.notNull(curveOid, "curveOid");
    return curveOidToNameMap.get(curveOid);
  }

  public static ASN1ObjectIdentifier getCurveOidForCurveNameOrOid(String curveNameOrOid) {
    Args.notBlank(curveNameOrOid, "curveNameOrOid");
    ASN1ObjectIdentifier oid;
    try {
      oid = new ASN1ObjectIdentifier(curveNameOrOid);
    } catch (Exception ex) {
      oid = getCurveOidForName(curveNameOrOid);
    }
    return oid;
  } // method getCurveOidForCurveNameOrOid

  private static String canonicalizeAlgoText(String algoText) {
    if (algoText.indexOf('-') == -1) {
      return algoText;
    }

    boolean bo = algoText.contains("SHA-") || algoText.contains("AES-")
                    || algoText.contains("RIPEMD-");
    if (bo) {
      algoText = algoText.replaceAll("SHA-", "SHA");
      algoText = algoText.replaceAll("RIPEMD-", "RIPEMD");
      algoText = algoText.replaceAll("AES-", "AES");
    }

    return algoText;
  } // method canonicalizeAlgoText

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy