Add UnitTest to verify updateTrustCredentials rotate (#11798)

* Add lastUpdateTime to avoid read
This commit is contained in:
Albumen Kevin 2025-01-10 03:53:36 +08:00 committed by GitHub
parent e61b03cb9f
commit 73721acc0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 4 deletions

View File

@ -265,7 +265,7 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
} }
final ScheduledFuture<?> future = final ScheduledFuture<?> future =
checkNotNull(executor, "executor").scheduleWithFixedDelay( checkNotNull(executor, "executor").scheduleWithFixedDelay(
new LoadFilePathExecution(trustCertFile), period, period, unit); new LoadFilePathExecution(trustCertFile, updatedTime), period, period, unit);
return () -> future.cancel(false); return () -> future.cancel(false);
} }
@ -312,9 +312,9 @@ public final class AdvancedTlsX509TrustManager extends X509ExtendedTrustManager
File file; File file;
long currentTime; long currentTime;
public LoadFilePathExecution(File file) { public LoadFilePathExecution(File file, long currentTime) {
this.file = file; this.file = file;
this.currentTime = 0; this.currentTime = currentTime;
} }
@Override @Override

View File

@ -24,6 +24,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.io.Files;
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;
@ -57,21 +58,28 @@ public class AdvancedTlsX509TrustManagerTest {
private static final String CA_PEM_FILE = "ca.pem"; private static final String CA_PEM_FILE = "ca.pem";
private static final String SERVER_0_PEM_FILE = "server0.pem"; private static final String SERVER_0_PEM_FILE = "server0.pem";
private static final String SERVER_1_PEM_FILE = "server1.pem";
private File caCertFile; private File caCertFile;
private File serverCert0File; private File serverCert0File;
private File serverCert1File;
private X509Certificate[] caCert; private X509Certificate[] caCert;
private X509Certificate[] serverCert0; private X509Certificate[] serverCert0;
private X509Certificate[] serverCert1;
private FakeClock fakeClock;
private ScheduledExecutorService executor; private ScheduledExecutorService executor;
@Before @Before
public void setUp() throws IOException, GeneralSecurityException { public void setUp() throws IOException, GeneralSecurityException {
executor = new FakeClock().getScheduledExecutorService(); fakeClock = new FakeClock();
executor = fakeClock.getScheduledExecutorService();
caCertFile = TestUtils.loadCert(CA_PEM_FILE); caCertFile = TestUtils.loadCert(CA_PEM_FILE);
caCert = CertificateUtils.getX509Certificates(TlsTesting.loadCert(CA_PEM_FILE)); caCert = CertificateUtils.getX509Certificates(TlsTesting.loadCert(CA_PEM_FILE));
serverCert0File = TestUtils.loadCert(SERVER_0_PEM_FILE); serverCert0File = TestUtils.loadCert(SERVER_0_PEM_FILE);
serverCert0 = CertificateUtils.getX509Certificates(TlsTesting.loadCert(SERVER_0_PEM_FILE)); serverCert0 = CertificateUtils.getX509Certificates(TlsTesting.loadCert(SERVER_0_PEM_FILE));
serverCert1File = TestUtils.loadCert(SERVER_1_PEM_FILE);
serverCert1 = CertificateUtils.getX509Certificates(TlsTesting.loadCert(SERVER_1_PEM_FILE));
} }
@Test @Test
@ -147,6 +155,39 @@ public class AdvancedTlsX509TrustManagerTest {
assertEquals("No handshake session", ce.getMessage()); assertEquals("No handshake session", ce.getMessage());
} }
@Test
public void updateTrustCredentials_rotate() throws GeneralSecurityException, IOException {
AdvancedTlsX509TrustManager trustManager = AdvancedTlsX509TrustManager.newBuilder().build();
trustManager.updateTrustCredentials(serverCert0File);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
trustManager.updateTrustCredentials(serverCert0File, 1, TimeUnit.MINUTES,
executor);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
fakeClock.forwardTime(1, TimeUnit.MINUTES);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
serverCert0File.setLastModified(serverCert0File.lastModified() - 10);
fakeClock.forwardTime(1, TimeUnit.MINUTES);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
long beforeModify = serverCert0File.lastModified();
Files.copy(serverCert1File, serverCert0File);
serverCert0File.setLastModified(beforeModify);
// although file content changed, file modification time is not changed
fakeClock.forwardTime(1, TimeUnit.MINUTES);
assertArrayEquals(serverCert0, trustManager.getAcceptedIssuers());
serverCert0File.setLastModified(beforeModify + 10);
// file modification time changed
fakeClock.forwardTime(1, TimeUnit.MINUTES);
assertArrayEquals(serverCert1, trustManager.getAcceptedIssuers());
}
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<>();