util: Align AdvancedTlsX509{Key and Trust}Manager (#11385)

* Swap internal key/cert args

* Deprecate *FromFile methods

* Test for client trusted socket
This commit is contained in:
erm-g 2024-07-16 12:33:19 -04:00 committed by GitHub
parent 92f4fde61b
commit 516dec989a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 115 additions and 63 deletions

View File

@ -339,7 +339,7 @@ public class AdvancedTlsTest {
AdvancedTlsX509TrustManager serverTrustManager = AdvancedTlsX509TrustManager.newBuilder() AdvancedTlsX509TrustManager serverTrustManager = AdvancedTlsX509TrustManager.newBuilder()
.setVerification(Verification.CERTIFICATE_ONLY_VERIFICATION) .setVerification(Verification.CERTIFICATE_ONLY_VERIFICATION)
.build(); .build();
Closeable serverTrustShutdown = serverTrustManager.updateTrustCredentialsFromFile(caCertFile, Closeable serverTrustShutdown = serverTrustManager.updateTrustCredentials(caCertFile,
100, TimeUnit.MILLISECONDS, executor); 100, TimeUnit.MILLISECONDS, executor);
ServerCredentials serverCredentials = TlsServerCredentials.newBuilder() ServerCredentials serverCredentials = TlsServerCredentials.newBuilder()
.keyManager(serverKeyManager).trustManager(serverTrustManager) .keyManager(serverKeyManager).trustManager(serverTrustManager)
@ -349,11 +349,11 @@ public class AdvancedTlsTest {
// Create a client to connect. // Create a client to connect.
AdvancedTlsX509KeyManager clientKeyManager = new AdvancedTlsX509KeyManager(); AdvancedTlsX509KeyManager clientKeyManager = new AdvancedTlsX509KeyManager();
Closeable clientKeyShutdown = clientKeyManager.updateIdentityCredentials(clientCert0File, Closeable clientKeyShutdown = clientKeyManager.updateIdentityCredentials(clientCert0File,
clientKey0File,100, TimeUnit.MILLISECONDS, executor); clientKey0File, 100, TimeUnit.MILLISECONDS, executor);
AdvancedTlsX509TrustManager clientTrustManager = AdvancedTlsX509TrustManager.newBuilder() AdvancedTlsX509TrustManager clientTrustManager = AdvancedTlsX509TrustManager.newBuilder()
.setVerification(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION) .setVerification(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION)
.build(); .build();
Closeable clientTrustShutdown = clientTrustManager.updateTrustCredentialsFromFile(caCertFile, Closeable clientTrustShutdown = clientTrustManager.updateTrustCredentials(caCertFile,
100, TimeUnit.MILLISECONDS, executor); 100, TimeUnit.MILLISECONDS, executor);
ChannelCredentials channelCredentials = TlsChannelCredentials.newBuilder() ChannelCredentials channelCredentials = TlsChannelCredentials.newBuilder()
.keyManager(clientKeyManager).trustManager(clientTrustManager).build(); .keyManager(clientKeyManager).trustManager(clientTrustManager).build();
@ -385,7 +385,7 @@ public class AdvancedTlsTest {
AdvancedTlsX509TrustManager serverTrustManager = AdvancedTlsX509TrustManager.newBuilder() AdvancedTlsX509TrustManager serverTrustManager = AdvancedTlsX509TrustManager.newBuilder()
.setVerification(Verification.CERTIFICATE_ONLY_VERIFICATION) .setVerification(Verification.CERTIFICATE_ONLY_VERIFICATION)
.build(); .build();
serverTrustManager.updateTrustCredentialsFromFile(caCertFile); serverTrustManager.updateTrustCredentials(caCertFile);
ServerCredentials serverCredentials = TlsServerCredentials.newBuilder() ServerCredentials serverCredentials = TlsServerCredentials.newBuilder()
.keyManager(serverKeyManager).trustManager(serverTrustManager) .keyManager(serverKeyManager).trustManager(serverTrustManager)
.clientAuth(ClientAuth.REQUIRE).build(); .clientAuth(ClientAuth.REQUIRE).build();
@ -397,7 +397,7 @@ public class AdvancedTlsTest {
AdvancedTlsX509TrustManager clientTrustManager = AdvancedTlsX509TrustManager.newBuilder() AdvancedTlsX509TrustManager clientTrustManager = AdvancedTlsX509TrustManager.newBuilder()
.setVerification(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION) .setVerification(Verification.CERTIFICATE_AND_HOST_NAME_VERIFICATION)
.build(); .build();
clientTrustManager.updateTrustCredentialsFromFile(caCertFile); clientTrustManager.updateTrustCredentials(caCertFile);
ChannelCredentials channelCredentials = TlsChannelCredentials.newBuilder() ChannelCredentials channelCredentials = TlsChannelCredentials.newBuilder()
.keyManager(clientKeyManager).trustManager(clientTrustManager).build(); .keyManager(clientKeyManager).trustManager(clientTrustManager).build();
channel = Grpc.newChannelBuilderForAddress("localhost", server.getPort(), channelCredentials) channel = Grpc.newChannelBuilderForAddress("localhost", server.getPort(), channelCredentials)
@ -431,8 +431,8 @@ public class AdvancedTlsTest {
.build(); .build();
// We pass in a key as the trust certificates to intentionally create an exception. // We pass in a key as the trust certificates to intentionally create an exception.
assertThrows(GeneralSecurityException.class, assertThrows(GeneralSecurityException.class,
() -> trustManager.updateTrustCredentialsFromFile(serverKey0File, () -> trustManager.updateTrustCredentials(serverKey0File, 100, TimeUnit.MILLISECONDS,
100, TimeUnit.MILLISECONDS, executor)); executor));
} }
@Test @Test

View File

@ -116,7 +116,7 @@ public final class AdvancedTlsX509KeyManager extends X509ExtendedKeyManager {
* @param key the private key that is going to be used * @param key the private key that is going to be used
*/ */
public void updateIdentityCredentials(X509Certificate[] certs, PrivateKey key) { public void updateIdentityCredentials(X509Certificate[] certs, PrivateKey key) {
this.keyInfo = new KeyInfo(checkNotNull(key, "key"), checkNotNull(certs, "certs")); this.keyInfo = new KeyInfo(checkNotNull(certs, "certs"), checkNotNull(key, "key"));
} }
/** /**
@ -216,26 +216,26 @@ public final class AdvancedTlsX509KeyManager extends X509ExtendedKeyManager {
private static class KeyInfo { private static class KeyInfo {
// The private key and the cert chain we will use to send to peers to prove our identity. // The private key and the cert chain we will use to send to peers to prove our identity.
final PrivateKey key;
final X509Certificate[] certs; final X509Certificate[] certs;
final PrivateKey key;
public KeyInfo(PrivateKey key, X509Certificate[] certs) { public KeyInfo(X509Certificate[] certs, PrivateKey key) {
this.key = key;
this.certs = certs; this.certs = certs;
this.key = key;
} }
} }
private class LoadFilePathExecution implements Runnable { private class LoadFilePathExecution implements Runnable {
File keyFile; File keyFile;
File certFile; File certFile;
long currentKeyTime;
long currentCertTime; long currentCertTime;
long currentKeyTime;
public LoadFilePathExecution(File certFile, File keyFile) { public LoadFilePathExecution(File certFile, File keyFile) {
this.certFile = certFile; this.certFile = certFile;
this.keyFile = keyFile; this.keyFile = keyFile;
this.currentKeyTime = 0;
this.currentCertTime = 0; this.currentCertTime = 0;
this.currentKeyTime = 0;
} }
@Override @Override
@ -244,11 +244,11 @@ public final class AdvancedTlsX509KeyManager extends X509ExtendedKeyManager {
UpdateResult newResult = readAndUpdate(this.certFile, this.keyFile, this.currentKeyTime, UpdateResult newResult = readAndUpdate(this.certFile, this.keyFile, this.currentKeyTime,
this.currentCertTime); this.currentCertTime);
if (newResult.success) { if (newResult.success) {
this.currentKeyTime = newResult.keyTime;
this.currentCertTime = newResult.certTime; this.currentCertTime = newResult.certTime;
this.currentKeyTime = newResult.keyTime;
} }
} catch (IOException | GeneralSecurityException e) { } catch (IOException | GeneralSecurityException e) {
log.log(Level.SEVERE, String.format("Failed refreshing private key and certificate" log.log(Level.SEVERE, String.format("Failed refreshing certificate and private key"
+ " chain from files. Using previous ones (certFile lastModified = %s, keyFile " + " chain from files. Using previous ones (certFile lastModified = %s, keyFile "
+ "lastModified = %s)", certFile.lastModified(), keyFile.lastModified()), e); + "lastModified = %s)", certFile.lastModified(), keyFile.lastModified()), e);
} }
@ -257,13 +257,13 @@ public final class AdvancedTlsX509KeyManager extends X509ExtendedKeyManager {
private static class UpdateResult { private static class UpdateResult {
boolean success; boolean success;
long keyTime;
long certTime; long certTime;
long keyTime;
public UpdateResult(boolean success, long keyTime, long certTime) { public UpdateResult(boolean success, long certTime, long keyTime) {
this.success = success; this.success = success;
this.keyTime = keyTime;
this.certTime = certTime; this.certTime = certTime;
this.keyTime = keyTime;
} }
} }

View File

@ -18,6 +18,8 @@ package io.grpc.util;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.google.errorprone.annotations.InlineMe;
import io.grpc.ExperimentalApi;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -116,7 +118,7 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
/** /**
* Uses the default trust certificates stored on user's local system. * Uses the default trust certificates stored on user's local system.
* After this is used, functions that will provide new credential * After this is used, functions that will provide new credential
* data(e.g. updateTrustCredentials(), updateTrustCredentialsFromFile()) should not be called. * data(e.g. updateTrustCredentials) should not be called.
*/ */
public void useSystemDefaultTrustCerts() throws CertificateException, KeyStoreException, public void useSystemDefaultTrustCerts() throws CertificateException, KeyStoreException,
NoSuchAlgorithmException { NoSuchAlgorithmException {
@ -125,25 +127,6 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
this.delegateManager = createDelegateTrustManager(null); this.delegateManager = createDelegateTrustManager(null);
} }
/**
* Updates the current cached trust certificates as well as the key store.
*
* @param trustCerts the trust certificates that are going to be used
*/
public void updateTrustCredentials(X509Certificate[] trustCerts) throws IOException,
GeneralSecurityException {
checkNotNull(trustCerts, "trustCerts");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
int i = 1;
for (X509Certificate cert: trustCerts) {
String alias = Integer.toString(i);
keyStore.setCertificateEntry(alias, cert);
i++;
}
this.delegateManager = createDelegateTrustManager(keyStore);
}
private static X509ExtendedTrustManager createDelegateTrustManager(KeyStore keyStore) private static X509ExtendedTrustManager createDelegateTrustManager(KeyStore keyStore)
throws CertificateException, KeyStoreException, NoSuchAlgorithmException { throws CertificateException, KeyStoreException, NoSuchAlgorithmException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory tmf = TrustManagerFactory.getInstance(
@ -217,6 +200,39 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
} }
} }
/**
* Updates the current cached trust certificates as well as the key store.
*
* @param trustCerts the trust certificates that are going to be used
*/
public void updateTrustCredentials(X509Certificate[] trustCerts) throws IOException,
GeneralSecurityException {
checkNotNull(trustCerts, "trustCerts");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
int i = 1;
for (X509Certificate cert: trustCerts) {
String alias = Integer.toString(i);
keyStore.setCertificateEntry(alias, cert);
i++;
}
this.delegateManager = createDelegateTrustManager(keyStore);
}
/**
* Updates the trust certificates from a local file path.
*
* @param trustCertFile the file on disk holding the trust certificates
*/
public void updateTrustCredentials(File trustCertFile) throws IOException,
GeneralSecurityException {
long updatedTime = readAndUpdate(trustCertFile, 0);
if (updatedTime == 0) {
throw new GeneralSecurityException(
"Files were unmodified before their initial update. Probably a bug.");
}
}
/** /**
* Schedules a {@code ScheduledExecutorService} to read trust certificates from a local file path * Schedules a {@code ScheduledExecutorService} to read trust certificates from a local file path
* periodically, and updates the cached trust certs if there is an update. You must close the * periodically, and updates the cached trust certs if there is an update. You must close the
@ -233,7 +249,7 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
* @param executor the executor service we use to read and update the credentials * @param executor the executor service we use to read and update the credentials
* @return an object that caller should close when the file refreshes are not needed * @return an object that caller should close when the file refreshes are not needed
*/ */
public Closeable updateTrustCredentialsFromFile(File trustCertFile, long period, TimeUnit unit, public Closeable updateTrustCredentials(File trustCertFile, long period, TimeUnit unit,
ScheduledExecutorService executor) throws IOException, GeneralSecurityException { ScheduledExecutorService executor) throws IOException, GeneralSecurityException {
long updatedTime = readAndUpdate(trustCertFile, 0); long updatedTime = readAndUpdate(trustCertFile, 0);
if (updatedTime == 0) { if (updatedTime == 0) {
@ -253,18 +269,43 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
return () -> future.cancel(false); return () -> future.cancel(false);
} }
/**
* Schedules a {@code ScheduledExecutorService} to read trust certificates from a local file path
* periodically, and updates the cached trust certs if there is an update. You must close the
* returned Closeable before calling this method again or other update methods
* ({@link AdvancedTlsX509TrustManager#useSystemDefaultTrustCerts()},
* {@link AdvancedTlsX509TrustManager#updateTrustCredentials(X509Certificate[])},
* {@link AdvancedTlsX509TrustManager#updateTrustCredentialsFromFile(File)}).
* Before scheduling the task, the method synchronously reads and updates trust certificates once.
* If the provided period is less than 1 minute, it is automatically adjusted to 1 minute.
*
* @param trustCertFile the file on disk holding the trust certificates
* @param period the period between successive read-and-update executions
* @param unit the time unit of the initialDelay and period parameters
* @param executor the executor service we use to read and update the credentials
* @return an object that caller should close when the file refreshes are not needed
* @deprecated Use {@link #updateTrustCredentials(File, long ,TimeUnit, ScheduledExecutorService)}
*/
@Deprecated
@InlineMe(replacement = "this.updateTrustCredentials(trustCertFile, period, unit, executor)")
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8024")
public Closeable updateTrustCredentialsFromFile(File trustCertFile, long period, TimeUnit unit,
ScheduledExecutorService executor) throws IOException, GeneralSecurityException {
return updateTrustCredentials(trustCertFile, period, unit, executor);
}
/** /**
* Updates the trust certificates from a local file path. * Updates the trust certificates from a local file path.
* *
* @param trustCertFile the file on disk holding the trust certificates * @param trustCertFile the file on disk holding the trust certificates
* @deprecated Use {@link #updateTrustCredentials(File)}
*/ */
@Deprecated
@InlineMe(replacement = "this.updateTrustCredentials(trustCertFile)")
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8024")
public void updateTrustCredentialsFromFile(File trustCertFile) throws IOException, public void updateTrustCredentialsFromFile(File trustCertFile) throws IOException,
GeneralSecurityException { GeneralSecurityException {
long updatedTime = readAndUpdate(trustCertFile, 0); updateTrustCredentials(trustCertFile);
if (updatedTime == 0) {
throw new GeneralSecurityException(
"Files were unmodified before their initial update. Probably a bug.");
}
} }
private class LoadFilePathExecution implements Runnable { private class LoadFilePathExecution implements Runnable {
@ -383,8 +424,8 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
* Builds a new {@link AdvancedTlsX509TrustManager}. By default, no trust certificates are loaded * Builds a new {@link AdvancedTlsX509TrustManager}. By default, no trust certificates are loaded
* after the build. To load them, use one of the following methods: {@link * after the build. To load them, use one of the following methods: {@link
* AdvancedTlsX509TrustManager#updateTrustCredentials(X509Certificate[])}, {@link * AdvancedTlsX509TrustManager#updateTrustCredentials(X509Certificate[])}, {@link
* AdvancedTlsX509TrustManager#updateTrustCredentialsFromFile(File, long, TimeUnit, * AdvancedTlsX509TrustManager#updateTrustCredentials(File, long, TimeUnit,
* ScheduledExecutorService)}, {@link AdvancedTlsX509TrustManager#updateTrustCredentialsFromFile * ScheduledExecutorService)}, {@link AdvancedTlsX509TrustManager#updateTrustCredentials
* (File, long, TimeUnit, ScheduledExecutorService)}. * (File, long, TimeUnit, ScheduledExecutorService)}.
*/ */
public static final class Builder { public static final class Builder {

View File

@ -76,7 +76,7 @@ public class AdvancedTlsX509KeyManagerTest {
} }
@Test @Test
public void credentialSetting() throws Exception { public void updateTrustCredentials_replacesIssuers() throws Exception {
// Overall happy path checking of public API. // Overall happy path checking of public API.
AdvancedTlsX509KeyManager serverKeyManager = new AdvancedTlsX509KeyManager(); AdvancedTlsX509KeyManager serverKeyManager = new AdvancedTlsX509KeyManager();
serverKeyManager.updateIdentityCredentials(serverCert0, serverKey0); serverKeyManager.updateIdentityCredentials(serverCert0, serverKey0);
@ -91,6 +91,10 @@ public class AdvancedTlsX509KeyManagerTest {
TimeUnit.MINUTES, executor); TimeUnit.MINUTES, executor);
assertEquals(serverKey0, serverKeyManager.getPrivateKey(ALIAS)); assertEquals(serverKey0, serverKeyManager.getPrivateKey(ALIAS));
assertArrayEquals(serverCert0, serverKeyManager.getCertificateChain(ALIAS)); assertArrayEquals(serverCert0, serverKeyManager.getCertificateChain(ALIAS));
serverKeyManager.updateIdentityCredentials(serverCert0, serverKey0);
assertEquals(serverKey0, serverKeyManager.getPrivateKey(ALIAS));
assertArrayEquals(serverCert0, serverKeyManager.getCertificateChain(ALIAS));
} }
@Test @Test

View File

@ -20,11 +20,14 @@ import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import io.grpc.internal.FakeClock; import io.grpc.internal.FakeClock;
import io.grpc.internal.testing.TestUtils; import io.grpc.internal.testing.TestUtils;
import io.grpc.testing.TlsTesting; import io.grpc.testing.TlsTesting;
import io.grpc.util.AdvancedTlsX509TrustManager.Verification;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.Socket; import java.net.Socket;
@ -40,6 +43,7 @@ import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.net.ssl.SSLSocket;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -72,17 +76,17 @@ public class AdvancedTlsX509TrustManagerTest {
public void updateTrustCredentials_replacesIssuers() throws Exception { public void updateTrustCredentials_replacesIssuers() throws Exception {
// Overall happy path checking of public API. // Overall happy path checking of public API.
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build(); AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build();
trustManager.updateTrustCredentialsFromFile(serverCert0File); trustManager.updateTrustCredentials(serverCert0File);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers()); assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
trustManager.updateTrustCredentials(caCert); trustManager.updateTrustCredentials(caCert);
assertArrayEquals(caCert, trustManager.getAcceptedIssuers()); assertArrayEquals(caCert, trustManager.getAcceptedIssuers());
trustManager.updateTrustCredentialsFromFile(serverCert0File, 1, TimeUnit.MINUTES, trustManager.updateTrustCredentials(serverCert0File, 1, TimeUnit.MINUTES,
executor); executor);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers()); assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
trustManager.updateTrustCredentialsFromFile(serverCert0File); trustManager.updateTrustCredentials(serverCert0File);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers()); assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
} }
@ -101,23 +105,15 @@ public class AdvancedTlsX509TrustManagerTest {
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build(); AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build();
NullPointerException npe = assertThrows(NullPointerException.class, () -> trustManager NullPointerException npe = assertThrows(NullPointerException.class, () -> trustManager
.updateTrustCredentials(null)); .updateTrustCredentials(null, 1, null, null));
assertEquals("trustCerts", npe.getMessage());
npe = assertThrows(NullPointerException.class, () -> trustManager
.updateTrustCredentialsFromFile(null));
assertEquals("trustCertFile", npe.getMessage()); assertEquals("trustCertFile", npe.getMessage());
npe = assertThrows(NullPointerException.class, () -> trustManager npe = assertThrows(NullPointerException.class, () -> trustManager
.updateTrustCredentialsFromFile(null, 1, null, null)); .updateTrustCredentials(caCertFile, 1, null, null));
assertEquals("trustCertFile", npe.getMessage());
npe = assertThrows(NullPointerException.class, () -> trustManager
.updateTrustCredentialsFromFile(caCertFile, 1, null, null));
assertEquals("unit", npe.getMessage()); assertEquals("unit", npe.getMessage());
npe = assertThrows(NullPointerException.class, () -> trustManager npe = assertThrows(NullPointerException.class, () -> trustManager
.updateTrustCredentialsFromFile(caCertFile, 1, TimeUnit.MINUTES, null)); .updateTrustCredentials(caCertFile, 1, TimeUnit.MINUTES, null));
assertEquals("executor", npe.getMessage()); assertEquals("executor", npe.getMessage());
Logger log = Logger.getLogger(AdvancedTlsX509TrustManager.class.getName()); Logger log = Logger.getLogger(AdvancedTlsX509TrustManager.class.getName());
@ -125,8 +121,7 @@ public class AdvancedTlsX509TrustManagerTest {
log.addHandler(handler); log.addHandler(handler);
log.setUseParentHandlers(false); log.setUseParentHandlers(false);
log.setLevel(Level.FINE); log.setLevel(Level.FINE);
trustManager.updateTrustCredentialsFromFile(serverCert0File, -1, TimeUnit.SECONDS, trustManager.updateTrustCredentials(serverCert0File, -1, TimeUnit.SECONDS, executor);
executor);
log.removeHandler(handler); log.removeHandler(handler);
try { try {
LogRecord logRecord = Iterables.find(handler.getRecords(), LogRecord logRecord = Iterables.find(handler.getRecords(),
@ -137,6 +132,18 @@ public class AdvancedTlsX509TrustManagerTest {
} }
} }
@Test
public void clientTrustedWithSocketTest() throws Exception {
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder()
.setVerification(Verification.CERTIFICATE_ONLY_VERIFICATION).build();
trustManager.updateTrustCredentials(caCert);
SSLSocket sslSocket = mock(SSLSocket.class);
when(sslSocket.isConnected()).thenReturn(true);
when(sslSocket.getHandshakeSession()).thenReturn(null);
CertificateException ce = assertThrows(CertificateException.class, () -> trustManager
.checkClientTrusted(serverCert0, "RSA", sslSocket));
assertEquals("No handshake session", ce.getMessage());
}
private static class TestHandler extends Handler { private static class TestHandler extends Handler {
private final List<LogRecord> records = new ArrayList<>(); private final List<LogRecord> records = new ArrayList<>();