/** Create LockssKeystore from a config subtree */
  LockssKeyStore createLockssKeyStore(Configuration config) {
    log.debug2("Creating LockssKeyStore from config: " + config);
    String name = config.get(KEYSTORE_PARAM_NAME);
    LockssKeyStore lk = new LockssKeyStore(name);

    String file = config.get(KEYSTORE_PARAM_FILE);
    String resource = config.get(KEYSTORE_PARAM_RESOURCE);
    String url = config.get(KEYSTORE_PARAM_URL);

    if (!StringUtil.isNullString(file)) {
      lk.setLocation(file, LocationType.File);
    } else if (!StringUtil.isNullString(resource)) {
      lk.setLocation(resource, LocationType.Resource);
    } else if (!StringUtil.isNullString(url)) {
      lk.setLocation(url, LocationType.Url);
    }

    lk.setType(config.get(KEYSTORE_PARAM_TYPE, defaultKeyStoreType));
    lk.setProvider(config.get(KEYSTORE_PARAM_PROVIDER, defaultKeyStoreProvider));
    lk.setPassword(config.get(KEYSTORE_PARAM_PASSWORD));
    lk.setKeyPassword(config.get(KEYSTORE_PARAM_KEY_PASSWORD));
    lk.setKeyPasswordFile(config.get(KEYSTORE_PARAM_KEY_PASSWORD_FILE));
    lk.setMayCreate(config.getBoolean(KEYSTORE_PARAM_CREATE, DEFAULT_CREATE));
    return lk;
  }
  private void checkFact(Object fact, String name, String criticalServiceName, String message) {
    if (fact == null && criticalServiceName != null) {
      String msg =
          StringUtil.isNullString(name)
              ? ("No keystore name given for critical keystore"
                  + " needed for service "
                  + criticalServiceName
                  + ", daemon exiting")
              : ("Critical keystore "
                  + name
                  + " "
                  + ((message != null) ? message : "not found or not loadable")
                  + " for service "
                  + criticalServiceName
                  + ", daemon exiting");
      log.critical(msg);

      if (paramExitIfMissingKeyStore) {
        System.exit(Constants.EXIT_CODE_KEYSTORE_MISSING);
      } else {
        throw new IllegalArgumentException(msg);
      }
    }
  }
  public void testCreateSharedPLNKeyStores() throws Exception {
    List<String> hosts = ListUtil.list("host1", "host2.foo.bar", "host3");
    List<String> hosts2 = ListUtil.list("host3", "host4");
    File dir = getTempDir();
    File pub = new File(dir, "pub.ks");
    KeyStoreUtil.createSharedPLNKeyStores(
        dir, hosts, pub, "pubpass", MiscTestUtil.getSecureRandom());
    assertPubKs(pub, "pubpass", hosts);
    for (String host : hosts) {
      assertPrivateKs(
          new File(dir, host + ".jceks"), StringUtil.fromFile(new File(dir, host + ".pass")), host);
    }
    KeyStore pubks1 = loadKeyStore("jceks", new File(dir, "pub.ks"), "pubpass");

    Certificate host1cert1 = pubks1.getCertificate("host1.crt");
    Certificate host3cert1 = pubks1.getCertificate("host3.crt");

    String host1priv1 = StringUtil.fromFile(new File(dir, "host1.jceks"));
    String host3priv1 = StringUtil.fromFile(new File(dir, "host3.jceks"));

    // Now add host4 and generate a new key for host3
    KeyStoreUtil.createSharedPLNKeyStores(
        dir, hosts2, pub, "pubpass", MiscTestUtil.getSecureRandom());
    List<String> both = ListUtils.sum(hosts, hosts2);
    assertPubKs(pub, "pubpass", both);
    for (String host : both) {
      assertPrivateKs(
          new File(dir, host + ".jceks"), StringUtil.fromFile(new File(dir, host + ".pass")), host);
    }
    KeyStore pubks2 = loadKeyStore("jceks", new File(dir, "pub.ks"), "pubpass");
    // host1 should have the same cert, host3 not
    Certificate host1cert2 = pubks2.getCertificate("host1.crt");
    Certificate host3cert2 = pubks2.getCertificate("host3.crt");
    assertEquals(host1cert1, host1cert2);
    assertNotEquals(host3cert1, host3cert2);

    // host1's private key file should be the same, host3's not
    String host1priv2 = StringUtil.fromFile(new File(dir, "host1.jceks"));
    String host3priv2 = StringUtil.fromFile(new File(dir, "host3.jceks"));
    assertEquals(host1priv1, host1priv2);
    assertNotEquals(host3priv1, host3priv2);
  }