private SSLContext createSSLContext(LDAPConnectionHandlerCfg config) throws DirectoryException {
    try {
      DN keyMgrDN = config.getKeyManagerProviderDN();
      KeyManagerProvider<?> keyManagerProvider = DirectoryServer.getKeyManagerProvider(keyMgrDN);
      if (keyManagerProvider == null) {
        logger.error(ERR_NULL_KEY_PROVIDER_MANAGER, keyMgrDN, friendlyName);
        disableAndWarnIfUseSSL(config);
        keyManagerProvider = new NullKeyManagerProvider();
        // The SSL connection is unusable without a key manager provider
      } else if (!keyManagerProvider.containsAtLeastOneKey()) {
        logger.error(ERR_INVALID_KEYSTORE, friendlyName);
        disableAndWarnIfUseSSL(config);
      }

      final SortedSet<String> aliases = new TreeSet<>(config.getSSLCertNickname());
      final KeyManager[] keyManagers;
      if (aliases.isEmpty()) {
        keyManagers = keyManagerProvider.getKeyManagers();
      } else {
        final Iterator<String> it = aliases.iterator();
        while (it.hasNext()) {
          if (!keyManagerProvider.containsKeyWithAlias(it.next())) {
            logger.error(ERR_KEYSTORE_DOES_NOT_CONTAIN_ALIAS, aliases, friendlyName);
            it.remove();
          }
        }

        if (aliases.isEmpty()) {
          disableAndWarnIfUseSSL(config);
        }
        keyManagers =
            SelectableCertificateKeyManager.wrap(
                keyManagerProvider.getKeyManagers(), aliases, friendlyName);
      }

      DN trustMgrDN = config.getTrustManagerProviderDN();
      TrustManagerProvider<?> trustManagerProvider =
          DirectoryServer.getTrustManagerProvider(trustMgrDN);
      if (trustManagerProvider == null) {
        trustManagerProvider = new NullTrustManagerProvider();
      }

      SSLContext sslContext = SSLContext.getInstance(SSL_CONTEXT_INSTANCE_NAME);
      sslContext.init(keyManagers, trustManagerProvider.getTrustManagers(), null);
      return sslContext;
    } catch (Exception e) {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      LocalizableMessage message =
          ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e));
      throw new DirectoryException(resCode, message, e);
    }
  }
  private SSLEngineConfigurator createSSLEngineConfigurator(HTTPConnectionHandlerCfg config)
      throws DirectoryException {
    if (!config.isUseSSL()) {
      return null;
    }

    try {
      SSLContext sslContext = createSSLContext(config);
      SSLEngineConfigurator configurator = new SSLEngineConfigurator(sslContext);
      configurator.setClientMode(false);

      // configure with defaults from the JVM
      final SSLEngine defaults = sslContext.createSSLEngine();
      configurator.setEnabledProtocols(defaults.getEnabledProtocols());
      configurator.setEnabledCipherSuites(defaults.getEnabledCipherSuites());

      final Set<String> protocols = config.getSSLProtocol();
      if (!protocols.isEmpty()) {
        configurator.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));
      }

      final Set<String> ciphers = config.getSSLCipherSuite();
      if (!ciphers.isEmpty()) {
        configurator.setEnabledCipherSuites(ciphers.toArray(new String[ciphers.size()]));
      }

      switch (config.getSSLClientAuthPolicy()) {
        case DISABLED:
          configurator.setNeedClientAuth(false);
          configurator.setWantClientAuth(false);
          break;
        case REQUIRED:
          configurator.setNeedClientAuth(true);
          configurator.setWantClientAuth(true);
          break;
        case OPTIONAL:
        default:
          configurator.setNeedClientAuth(false);
          configurator.setWantClientAuth(true);
          break;
      }

      return configurator;
    } catch (Exception e) {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      throw new DirectoryException(
          resCode, ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e)), e);
    }
  }
  private SSLEngine createSSLEngine(LDAPConnectionHandlerCfg config, SSLContext sslContext)
      throws DirectoryException {
    try {
      SSLEngine sslEngine = sslContext.createSSLEngine();
      sslEngine.setUseClientMode(false);

      final Set<String> protocols = config.getSSLProtocol();
      if (!protocols.isEmpty()) {
        sslEngine.setEnabledProtocols(protocols.toArray(new String[0]));
      }

      final Set<String> ciphers = config.getSSLCipherSuite();
      if (!ciphers.isEmpty()) {
        sslEngine.setEnabledCipherSuites(ciphers.toArray(new String[0]));
      }

      switch (config.getSSLClientAuthPolicy()) {
        case DISABLED:
          sslEngine.setNeedClientAuth(false);
          sslEngine.setWantClientAuth(false);
          break;
        case REQUIRED:
          sslEngine.setWantClientAuth(true);
          sslEngine.setNeedClientAuth(true);
          break;
        case OPTIONAL:
        default:
          sslEngine.setNeedClientAuth(false);
          sslEngine.setWantClientAuth(true);
          break;
      }

      return sslEngine;
    } catch (Exception e) {
      logger.traceException(e);
      ResultCode resCode = DirectoryServer.getServerErrorResultCode();
      LocalizableMessage message =
          ERR_CONNHANDLER_SSL_CANNOT_INITIALIZE.get(getExceptionMessage(e));
      throw new DirectoryException(resCode, message, e);
    }
  }