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

io.temporal.serviceclient.SimpleSslContextBuilder Maven / Gradle / Ivy

There is a newer version: 1.27.0
Show newest version
/*
 * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved.
 *
 * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Modifications copyright (C) 2017 Uber Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this material 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 io.temporal.serviceclient;

import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContext;
import io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder;
import io.grpc.netty.shaded.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import javax.annotation.Nullable;
import javax.net.ssl.*;

public class SimpleSslContextBuilder {

  private final @Nullable PKCS pkcs;
  private final @Nullable InputStream keyCertChain;
  private final @Nullable InputStream key;
  private TrustManager trustManager;
  private boolean useInsecureTrustManager;
  private String keyPassword;

  private enum PKCS {
    PKCS_8,
    PKCS_12
  }

  /**
   * @param keyCertChain - an input stream for an X.509 client certificate chain in PEM format.
   * @param key - an input stream for a PKCS#8 client private key in PEM format.
   * @deprecated use {@link #forPKCS8(InputStream, InputStream)} instead
   */
  @Deprecated
  public static SimpleSslContextBuilder newBuilder(InputStream keyCertChain, InputStream key) {
    return forPKCS8(keyCertChain, key);
  }

  /**
   * Explicitly creates a builder without a client private key or certificate chain.
   *
   * 

{@link #forPKCS8} and {@link #forPKCS12} support null inputs too for easier configuration * API */ public static SimpleSslContextBuilder noKeyOrCertChain() { return new SimpleSslContextBuilder(null, null, null); } /** * @param keyCertChain - an input stream for an X.509 client certificate chain in PEM format. * @param key - an input stream for a PKCS#8 client private key in PEM format. */ public static SimpleSslContextBuilder forPKCS8( @Nullable InputStream keyCertChain, @Nullable InputStream key) { return new SimpleSslContextBuilder(PKCS.PKCS_8, keyCertChain, key); } /** * @param pfxKeyArchive - an input stream for .pfx or .p12 PKCS12 archive file */ public static SimpleSslContextBuilder forPKCS12(@Nullable InputStream pfxKeyArchive) { return new SimpleSslContextBuilder(PKCS.PKCS_12, null, pfxKeyArchive); } private SimpleSslContextBuilder( @Nullable PKCS pkcs, @Nullable InputStream keyCertChain, @Nullable InputStream key) { this.pkcs = pkcs; this.keyCertChain = keyCertChain; this.key = key; } /** * Configures specified {@link SslContextBuilder} from the Builder parameters and for use with * Temporal GRPC server. {@link SslContext} built by the configured builder can be used with * {@link WorkflowServiceStubsOptions.Builder#setSslContext(SslContext)} * *

If trust manager is set then it will be used to verify server authority, otherwise system * default trust manager (or if {@link #useInsecureTrustManager} is set then insecure trust * manager) is going to be used. * * @return {@code sslContextBuilder} * @throws SSLException when it was unable to build the context */ public SslContextBuilder configure(SslContextBuilder sslContextBuilder) throws SSLException { if (trustManager != null && useInsecureTrustManager) throw new IllegalArgumentException( "Can not use insecure trust manager if custom trust manager is set."); GrpcSslContexts.configure(sslContextBuilder); sslContextBuilder.trustManager( trustManager != null ? trustManager : useInsecureTrustManager ? InsecureTrustManagerFactory.INSTANCE.getTrustManagers()[0] : getDefaultTrustManager()); if (pkcs != null && (key != null || keyCertChain != null)) { switch (pkcs) { case PKCS_8: // netty by default supports PKCS8 sslContextBuilder.keyManager(keyCertChain, key, keyPassword); break; case PKCS_12: sslContextBuilder.keyManager(createPKCS12KeyManager()); break; default: throw new IllegalArgumentException("PKCS " + pkcs + " is not implemented"); } } return sslContextBuilder; } /** * Configures {@link SslContext} from the Builder parameters and for use with Temporal GRPC * server. * *

If trust manager is set then it will be used to verify server authority, otherwise system * default trust manager (or if {@link #useInsecureTrustManager} is set then insecure trust * manager) is going to be used. * * @return {@link SslContext} that can be used with the {@link * WorkflowServiceStubsOptions.Builder#setSslContext(SslContext)} * @throws SSLException when it was unable to build the context */ public SslContext build() throws SSLException { return configure(SslContextBuilder.forClient()).build(); } /** * @param trustManager - custom trust manager that should be used with the SSLContext for * verifying server CA authority. * @return builder instance. */ public SimpleSslContextBuilder setTrustManager(TrustManager trustManager) { this.trustManager = trustManager; return this; } /** * @param useInsecureTrustManager - if set to true then insecure trust manager is going to be used * instead of the system default one. Note that this makes client vulnerable to man in the * middle attack. Use with caution. * @return builder instance. */ public SimpleSslContextBuilder setUseInsecureTrustManager(boolean useInsecureTrustManager) { this.useInsecureTrustManager = useInsecureTrustManager; return this; } /** * @param keyPassword - the password of the key, or null if it's not password-protected. * @return builder instance. */ public SimpleSslContextBuilder setKeyPassword(String keyPassword) { this.keyPassword = keyPassword; return this; } private KeyManagerFactory createPKCS12KeyManager() { char[] passwordChars = keyPassword != null ? keyPassword.toCharArray() : null; try { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(key, passwordChars); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, passwordChars); return kmf; } catch (Exception e) { throw new IllegalArgumentException("Input stream does not contain a valid PKCS12 key", e); } } /** * @return system default trust manager. * @throws UnknownDefaultTrustManagerException, which can be caused by {@link * NoSuchAlgorithmException} if {@link TrustManagerFactory#getInstance(String)} doesn't * support default algorithm, {@link KeyStoreException} in case if {@link KeyStore} * initialization failed or if no {@link X509TrustManager} has been found. */ private X509TrustManager getDefaultTrustManager() { TrustManagerFactory tmf; try { tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); // Using null here initialises the TMF with the default trust store. tmf.init((KeyStore) null); } catch (KeyStoreException | NoSuchAlgorithmException e) { throw new UnknownDefaultTrustManagerException(e); } for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { return (X509TrustManager) tm; } } throw new UnknownDefaultTrustManagerException( "Unable to find X509TrustManager in the list of default trust managers."); } /** * Exception that is thrown in case if builder was unable to derive default system trust manager. */ public static final class UnknownDefaultTrustManagerException extends RuntimeException { public UnknownDefaultTrustManagerException(Throwable cause) { super(cause); } public UnknownDefaultTrustManagerException(String message) { super(message); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy