@Parameterized.Parameters(name = "{index}: caKeyType={0}, certKeyType={1}, keyPassword={2}, "
    + "validateClientHostnames={3}, testCase={4}, clientAuthMode={5}")
  public static List<Object[]> data() {
    List<Object[]> params = new ArrayList<>();
    for (X509KeyType caKeyType : X509KeyType.values()) {
      for (X509KeyType certKeyType : X509KeyType.values()) {
        for (String keyPassword : new String[] { "", "pa$$w0rd" }) {
          // we want to run with and without validating hostnames. we encode the expected success
          // criteria
          // in the TestCase config. See below.
          for (boolean validateClientHostnames : new Boolean[] { true, false }) {
            // ClientAuth.NONE should succeed in all cases, because it never requests the
            // certificate for verification
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
              validateClientHostnames, CertConfig.NO_CLIENT_CERT, X509Util.ClientAuth.NONE });
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
              validateClientHostnames, CertConfig.NON_VERIFIABLE_CERT, X509Util.ClientAuth.NONE });
            params.add(
              new Object[] { caKeyType, certKeyType, keyPassword, true, validateClientHostnames,
                CertConfig.VERIFIABLE_CERT_WITH_BAD_HOST, X509Util.ClientAuth.NONE });

            // ClientAuth.WANT should succeed if no cert, but if the cert is provided it is
            // validated. So should fail on bad cert or good cert with bad host when host
            // verification is enabled
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
              validateClientHostnames, CertConfig.NO_CLIENT_CERT, X509Util.ClientAuth.WANT });
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, false,
              validateClientHostnames, CertConfig.NON_VERIFIABLE_CERT, X509Util.ClientAuth.WANT });
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, !validateClientHostnames,
              validateClientHostnames, CertConfig.VERIFIABLE_CERT_WITH_BAD_HOST,
              X509Util.ClientAuth.WANT });

            // ClientAuth.NEED is most restrictive, failing in all cases except "good cert/bad host"
            // when host verification is disabled
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, false,
              validateClientHostnames, CertConfig.NO_CLIENT_CERT, X509Util.ClientAuth.NEED });
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, false,
              validateClientHostnames, CertConfig.NON_VERIFIABLE_CERT, X509Util.ClientAuth.NEED });
            params.add(new Object[] { caKeyType, certKeyType, keyPassword, !validateClientHostnames,
              validateClientHostnames, CertConfig.VERIFIABLE_CERT_WITH_BAD_HOST,
              X509Util.ClientAuth.NEED });

            // additionally ensure that all modes succeed when a good cert is presented
            for (X509Util.ClientAuth mode : X509Util.ClientAuth.values()) {
              params.add(new Object[] { caKeyType, certKeyType, keyPassword, true,
                validateClientHostnames, CertConfig.GOOD_CERT, mode });
            }
          }
        }
      }
    }
    return params;
  }
Comprehensively tests all permutations of ClientAuth modes and host verification
enabled/disabled. Tests each permutation of that against each relevant value of
{@link CertConfig}, i.e. passing no cert, a bad cert, etc. See inline comments in {@link #data()}
below for what the expectations are
hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestMutualTlsServerSide.java