code: /*
   * Copyright (c) 2019 the Eclipse Milo Authors
   *
   * This program and the accompanying materials are made
   * available under the terms of the Eclipse Public License 2.0
   * which is available at https://www.eclipse.org/legal/epl-2.0/
   *
   * SPDX-License-Identifier: EPL-2.0
   */
  
  package org.eclipse.milo.opcua.stack;
  
  import java.security.cert.X509Certificate;
  import java.util.List;
  import java.util.concurrent.CountDownLatch;
  import java.util.concurrent.TimeUnit;
  
  import org.eclipse.milo.opcua.stack.client.UaStackClientConfigBuilder;
  import org.eclipse.milo.opcua.stack.client.security.ClientCertificateValidator;
  import org.eclipse.milo.opcua.stack.core.UaException;
  import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
  import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.testng.annotations.Test;
  
  import static org.testng.Assert.assertTrue;
  
  public class ClientCertificateValidatorIT extends StackIntegrationTest {
  
      private final Logger logger = LoggerFactory.getLogger(getClass());
  
      private final CountDownLatch latch = new CountDownLatch(1);
  
      private final ClientCertificateValidator validator = new ClientCertificateValidator() {
  
          @Override
          public void validateCertificateChain(List<X509Certificate> certificateChain) throws UaException {
              X509Certificate certificate = certificateChain.get(0);
              logger.info("verifyTrustChain: {}", certificate.getSubjectX500Principal());
              latch.countDown();
          }
  
          @Override
          public void validateCertificateChain(
              List<X509Certificate> certificateChain,
              String applicationUri,
              String... validHostNames
          ) throws UaException {
  
              validateCertificateChain(certificateChain);
          }
  
      };
  
      @Test
      public void testClientCertificateValidatorIsCalled() throws InterruptedException {
          assertTrue(latch.await(10, TimeUnit.SECONDS), "latch not obtained!");
      }
  
      @Override
      protected UaStackClientConfigBuilder configureClient(UaStackClientConfigBuilder builder) {
          return builder
              .setCertificate(clientCertificate)
              .setCertificateValidator(validator);
      }
  
      @Override
      protected EndpointDescription selectEndpoint(List<EndpointDescription> endpoints) {
          return endpoints.stream()
              .filter(e -> !SecurityPolicy.None.getUri().equals(e.getSecurityPolicyUri()))
              .findFirst()
              .orElseThrow(() -> new RuntimeException("no secure endpoint found!"));
      }
  
  }
  