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

org.seppiko.commons.utils.http.TLSUtil Maven / Gradle / Ivy

There is a newer version: 2.11.0
Show newest version
/*
 * Copyright 2023 the original author or authors.
 *
 * 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.seppiko.commons.utils.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.util.Objects;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.KeyManagerFactorySpi;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLContextSpi;
import javax.net.ssl.TrustManager;
import org.seppiko.commons.utils.Environment;
import org.seppiko.commons.utils.StringUtil;
import org.seppiko.commons.utils.crypto.CryptoUtil;
import org.seppiko.commons.utils.crypto.KeyStoreAlgorithms;
import org.seppiko.commons.utils.crypto.KeyUtil;

/**
 * HTTP TLS (SSLContext) util
 *
 * @author Leonard Woo
 */
public class TLSUtil {

  /**
   * Default Trust Managers, with trust all certificates.
   *
   * @see DefaultX509TrustManager
   */
  public static final TrustManager[] DEFAULT_TRUST_MANAGERS =
      new TrustManager[] {new DefaultX509TrustManager()};

  /** Disable {@link SSLContext} */
  public static final SSLContext NULL_SSL_CONTEXT = null;

  private TLSUtil() {}

  /**
   * Returns a KeyManagerFactory object that acts as a factory for key managers. And
   * use standard name.
   *
   * @see Security
   *     Standard Algorithm Names
   * @see KeyManagerFactory
   * @param provider an instance of the provider.
   * @return KeyManagerFactory instance.
   * @throws NoSuchAlgorithmException if no {@link Provider} supports a {@link KeyManagerFactorySpi}
   *     implementation for the specified algorithm.
   */
  public static KeyManagerFactory keyManagerFactory(Provider provider)
      throws NoSuchAlgorithmException {
    return keyManagerFactory("PKIX", provider);
  }

  /**
   * Returns a KeyManagerFactory object that acts as a factory for key managers. If
   * algorithm is empty or null, use the default KeyManagerFactory algorithm name.
   *
   * @see KeyManagerFactory
   * @param algorithm the standard name of the requested algorithm.
   * @param provider an instance of the provider.
   * @return KeyManagerFactory instance.
   * @throws NoSuchAlgorithmException if no {@link Provider} supports a {@link KeyManagerFactorySpi}
   *     implementation for the specified algorithm.
   */
  public static KeyManagerFactory keyManagerFactory(String algorithm, Provider provider)
      throws NoSuchAlgorithmException {
    if (StringUtil.isNullOrEmpty(algorithm)) {
      algorithm = KeyManagerFactory.getDefaultAlgorithm();
    }
    if (provider == CryptoUtil.NONPROVIDER) {
      return KeyManagerFactory.getInstance(algorithm);
    }
    return KeyManagerFactory.getInstance(algorithm, provider);
  }

  /**
   * KeyManager array util
   *
   * @see KeyManager
   * @see KeyManagerFactory
   * @param store KeyStore instance.
   * @param password the password for recovering keys in the KeyStore.
   * @return KeyManager array
   * @throws NoSuchAlgorithmException if no {@link Provider} supports a {@link KeyManagerFactorySpi}
   *     implementation for the specified algorithm. Or the specified algorithm is not available
   *     from the specified provider.
   * @throws UnrecoverableKeyException if the key cannot be recovered (e.g. the given password is
   *     wrong).
   * @throws KeyStoreException if this operation fails.
   */
  public static KeyManager[] keyManagers(KeyStore store, char[] password)
      throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException {
    KeyManagerFactory kmf = keyManagerFactory(CryptoUtil.NONPROVIDER);
    kmf.init(store, password);
    return kmf.getKeyManagers();
  }

  /**
   * KeyManager array util
   *
   * @see KeyManager
   * @see KeyManagerFactory
   * @param spec an implementation of a provider-specific parameter specification.
   * @return KeyManager array
   * @throws NoSuchAlgorithmException if no {@link Provider} supports a {@link KeyManagerFactorySpi}
   *     implementation for the specified algorithm. Or the specified algorithm is not available
   *     from the specified provider.
   * @throws UnrecoverableKeyException if the key cannot be recovered (e.g. the given password is
   *     wrong).
   * @throws KeyStoreException if this operation fails.
   * @throws InvalidAlgorithmParameterException if an error is encountered.
   */
  public static KeyManager[] keyManagers(ManagerFactoryParameters spec)
      throws NoSuchAlgorithmException, UnrecoverableKeyException, KeyStoreException, InvalidAlgorithmParameterException {
    KeyManagerFactory kmf = keyManagerFactory(CryptoUtil.NONPROVIDER);
    kmf.init(spec);
    return kmf.getKeyManagers();
  }

  /**
   * HTTP TLS Factory with TLS v1.2 and PKCS 12
   *
   * @param certFile Certificate file.
   * @param certPass Certificate password.
   * @return SSLContext instance. if file is null or exception return null.
   */
  public static SSLContext getSSLContext(File certFile, String certPass) {
    try {
      return getSSLContext(TLSProtocol.TLSv12, KeyStoreAlgorithms.PKCS12,
          new FileInputStream(certFile), certPass,
          DEFAULT_TRUST_MANAGERS);
    } catch (FileNotFoundException | NullPointerException ignored) {
    }
    return NULL_SSL_CONTEXT;
  }

  /**
   * HTTP TLS Factory
   *
   * @param protocol TLS protocol.
   * @param storeAlgorithms KeyStore algorithm.
   * @param certIs Certificate InputStream.
   * @param password Certificate password.
   * @param tms the sources of peer authentication trust decisions or null.
   * @return SSLContext instance.
   * @throws HttpTLSException TLS key, provider, I/O or operation is fails.
   * @throws NullPointerException some parameter is null.
   */
  public static SSLContext getSSLContext(
      TLSProtocol protocol, KeyStoreAlgorithms storeAlgorithms, InputStream certIs,
      String password, TrustManager[] tms)
      throws HttpTLSException, NullPointerException {
    Objects.requireNonNull(protocol, "TLS protocol must be not null");
    Objects.requireNonNull(storeAlgorithms, "KeyStore algorithm must be not null");
    Objects.requireNonNull(certIs, "Certificate cannot found");
    try {
      return getSSLContext(
          protocol,
          keyManagers(
              KeyUtil.keyStore(storeAlgorithms, certIs, password.toCharArray()),
              password.toCharArray()),
          tms);
    } catch (GeneralSecurityException | IOException | RuntimeException ex) {
      throw new HttpTLSException(ex);
    }
  }

  /**
   * HTTP TLS Factory without cert file.
   *
   * @param protocol TLS protocol.
   * @param storeAlgorithms KeyStore algorithm.
   * @param tms the sources of peer authentication trust decisions or null.
   * @return SSLContext instance.
   * @throws HttpTLSException TLS key, provider, I/O or operation is fails.
   * @throws NullPointerException some parameter is null.
   */
  public static SSLContext getSSLContext(TLSProtocol protocol, KeyStoreAlgorithms storeAlgorithms, TrustManager[] tms) {
    Objects.requireNonNull(protocol, "TLS protocol must be not null");
    Objects.requireNonNull(storeAlgorithms, "KeyStore algorithm must be not null");
    try {
      return getSSLContext(
          protocol,
          keyManagers(
              KeyUtil.keyStore(storeAlgorithms, null),
              Environment.EMPTY_CHAR_ARRAY),
          tms);
    } catch (GeneralSecurityException | IOException | RuntimeException ex) {
      throw new HttpTLSException(ex);
    }
  }

  /**
   * HTTP TLS Factory
   *
   * @param protocol TLS protocol.
   * @param kms the sources of authentication key or null.
   * @param tms the sources of peer authentication trust decisions or null.
   * @return SSLContext instance.
   * @throws NoSuchAlgorithmException if this operation fails.
   * @throws KeyManagementException if no {@link Provider} supports a {@link SSLContextSpi}
   *     implementation for the specified protocol.
   */
  public static SSLContext getSSLContext(TLSProtocol protocol, KeyManager[] kms, TrustManager[] tms)
      throws NoSuchAlgorithmException, KeyManagementException {
    return getSSLContext(protocol, kms, tms, new SecureRandom());
  }

  /**
   * HTTP TLS Factory
   *
   * @param protocol TLS protocol.
   * @param kms the sources of authentication key or null.
   * @param tms the sources of peer authentication trust decisions or null.
   * @param secRand the source of randomness for this generator or null.
   * @return SSLContext instance.
   * @throws KeyManagementException if this operation fails.
   * @throws NoSuchAlgorithmException if no {@link Provider} supports a {@link SSLContextSpi}
   *     implementation for the specified protocol.
   */
  public static SSLContext getSSLContext(
      TLSProtocol protocol, KeyManager[] kms, TrustManager[] tms, SecureRandom secRand)
      throws KeyManagementException, NoSuchAlgorithmException {
    SSLContext sslContext = SSLContext.getInstance(protocol.getName());
    sslContext.init(kms, tms, secRand);
    return sslContext;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy