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

com.github.tomakehurst.wiremock.http.ssl.CompositeTrustManager Maven / Gradle / Ivy

There is a newer version: 3.9.1
Show newest version
/*
 * Copyright (C) 2020-2023 Thomas Akehurst
 *
 * 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 com.github.tomakehurst.wiremock.http.ssl;

import static java.util.Arrays.asList;
import static java.util.Arrays.copyOf;

import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * Implementation of {@link X509ExtendedTrustManager} that delegates to multiple nested
 * X509ExtendedTrustManagers.
 *
 * 

{@link javax.net.ssl.SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], * java.security.SecureRandom)} accepts an array of {@link javax.net.ssl.TrustManager} instances, * but {@link sun.security.ssl.SSLContextImpl#chooseTrustManager(javax.net.ssl.TrustManager[])} * chooses the first instance of X509TrustManager in the array. So in order to provide a composite * trust manager that will trust based on the decision of more than one X509TrustManager we need to * create a new implementation that delegates its decision to one or more real X509TrustManager * instances. * *

The contract of this class is that a check will pass if it passes against any of its trust * managers. If it passes against none of them, the {@link CertificateException} thrown by the last * of them is propagated. */ class CompositeTrustManager extends X509ExtendedTrustManager { private final List trustManagers; private final X509Certificate[] acceptedIssuers; CompositeTrustManager(List trustManagers) { if (trustManagers.isEmpty()) { throw new IllegalArgumentException("A trust manager must be provided"); } this.trustManagers = new ArrayList<>(trustManagers); this.acceptedIssuers = loadAcceptedIssuers(this.trustManagers); } private X509Certificate[] loadAcceptedIssuers(List trustManagers) { List result = new ArrayList<>(); for (X509TrustManager trustManager : trustManagers) { result.addAll(asList(trustManager.getAcceptedIssuers())); } return result.toArray(new X509Certificate[0]); } @Override public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { checkAllTrustManagers(tm -> tm.checkClientTrusted(chain, authType)); } @Override public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { checkAllTrustManagers(tm -> tm.checkServerTrusted(chain, authType)); } @Override public void checkClientTrusted( final X509Certificate[] chain, final String authType, final Socket socket) throws CertificateException { checkAllTrustManagers(tm -> tm.checkClientTrusted(chain, authType, socket)); } @Override public void checkServerTrusted( final X509Certificate[] chain, final String authType, final Socket socket) throws CertificateException { checkAllTrustManagers(tm -> tm.checkServerTrusted(chain, authType, socket)); } @Override public void checkClientTrusted( final X509Certificate[] chain, final String authType, final SSLEngine engine) throws CertificateException { checkAllTrustManagers(tm -> tm.checkClientTrusted(chain, authType, engine)); } @Override public void checkServerTrusted( final X509Certificate[] chain, final String authType, final SSLEngine engine) throws CertificateException { checkAllTrustManagers(tm -> tm.checkServerTrusted(chain, authType, engine)); } @Override public X509Certificate[] getAcceptedIssuers() { return copyOf(acceptedIssuers, acceptedIssuers.length); } private void checkAllTrustManagers(CertificateChecker certificateChecker) throws CertificateException { for (Iterator iterator = trustManagers.iterator(); iterator.hasNext(); ) { X509ExtendedTrustManager tm = iterator.next(); try { certificateChecker.check(tm); break; } catch (CertificateException e) { if (!iterator.hasNext()) { throw e; } } } } private interface CertificateChecker { void check(X509ExtendedTrustManager tm) throws CertificateException; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy