@@ -112,8 +112,7 @@ public void basicTls_succeeds() throws Exception {
112112 }
113113
114114 @ Test
115- public void perRpcAuthorityOverride_hostnameVerification_success ()
116- throws Exception {
115+ public void perRpcAuthorityOverride_hostnameVerifier_goodAuthority_succeeds () throws Exception {
117116 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
118117 try {
119118 ServerCredentials serverCreds ;
@@ -133,15 +132,15 @@ public void perRpcAuthorityOverride_hostnameVerification_success()
133132 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
134133
135134 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
136- CallOptions .DEFAULT .withAuthority ("foo .test.google.fr" ),
135+ CallOptions .DEFAULT .withAuthority ("good .test.google.fr" ),
137136 SimpleRequest .getDefaultInstance ());
138137 } finally {
139138 OkHttpClientTransport .enablePerRpcAuthorityCheck = false ;
140139 }
141140 }
142141
143142 @ Test
144- public void perRpcAuthorityOverride_hostnameVerification_failure_rpcFails ()
143+ public void perRpcAuthorityOverride_hostnameVerifier_badAuthority_fails ()
145144 throws Exception {
146145 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
147146 try {
@@ -177,7 +176,7 @@ public void perRpcAuthorityOverride_hostnameVerification_failure_rpcFails()
177176 }
178177
179178 @ Test
180- public void perRpcAuthorityOverride_hostnameVerification_failure_flagDisabled_rpcSucceeds ()
179+ public void perRpcAuthorityOverride_hostnameVerifier_badAuthority_flagDisabled_succeeds ()
181180 throws Exception {
182181 ServerCredentials serverCreds ;
183182 try (InputStream serverCert = TlsTesting .loadCert ("server1.pem" );
@@ -201,8 +200,7 @@ public void perRpcAuthorityOverride_hostnameVerification_failure_flagDisabled_rp
201200 }
202201
203202 @ Test
204- public void perRpcAuthorityOverride_noTlsCredentialsUsedToBuildChannel_disallowsRpc ()
205- throws Exception {
203+ public void perRpcAuthorityOverride_noTlsCredentialsUsedToBuildChannel_fails () throws Exception {
206204 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
207205 try {
208206 ServerCredentials serverCreds ;
@@ -238,14 +236,8 @@ public void perRpcAuthorityOverride_noTlsCredentialsUsedToBuildChannel_disallows
238236 }
239237 }
240238
241- /**
242- * Test to verify that checkServerTrusted is been called for the per-rpc authority
243- * verification. Could not verify this indirectly using an invalid authority in the test because
244- * the SSLParameters.setEndpointIdentificationAlgorithm (an Android 24+ API) is not set to HTTPS
245- * during the handshake and doesn't verify hostname during rpc call either.
246- */
247239 @ Test
248- public void perRpcAuthorityOverride_checkServerTrustedIsCalled () throws Exception {
240+ public void perRpcAuthorityOverride_trustManager_permitted_succeeds () throws Exception {
249241 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
250242 try {
251243 ServerCredentials serverCreds ;
@@ -255,28 +247,27 @@ public void perRpcAuthorityOverride_checkServerTrustedIsCalled() throws Exceptio
255247 .keyManager (serverCert , serverPrivateKey )
256248 .build ();
257249 }
258- FakeX509ExtendedTrustManager fakeX509ExtendedTrustManager =
259- getFakeX509ExtendedTrustManager ();
260- ChannelCredentials channelCreds = TlsChannelCredentials .newBuilder ()
261- .trustManager (fakeX509ExtendedTrustManager )
262- .build ();
250+ ChannelCredentials channelCreds ;
251+ try (InputStream caCert = TlsTesting .loadCert ("ca.pem" )) {
252+ X509ExtendedTrustManager regularTrustManager =
253+ (X509ExtendedTrustManager ) getX509ExtendedTrustManager (caCert ).get ();
254+ channelCreds = TlsChannelCredentials .newBuilder ()
255+ .trustManager (new HostnameCheckingX509ExtendedTrustManager (regularTrustManager ))
256+ .build ();
257+ }
263258 Server server = grpcCleanupRule .register (server (serverCreds ));
264259 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
265260
266261 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
267- CallOptions .DEFAULT .withAuthority ("foo .test.google.fr" ),
262+ CallOptions .DEFAULT .withAuthority ("good .test.google.fr" ),
268263 SimpleRequest .getDefaultInstance ());
269- assertThat (fakeX509ExtendedTrustManager .checkServerTrustedCalled ).isTrue ();
270264 } finally {
271265 OkHttpClientTransport .enablePerRpcAuthorityCheck = false ;
272266 }
273267 }
274268
275- /**
276- * Uses a fake Trust Manager to fail authority verification.
277- */
278269 @ Test
279- public void perRpcAuthorityOverride_peerVerificationFails_rpcFails () throws Exception {
270+ public void perRpcAuthorityOverride_trustManager_denied_fails () throws Exception {
280271 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
281272 try {
282273 ServerCredentials serverCreds ;
@@ -297,13 +288,9 @@ public void perRpcAuthorityOverride_peerVerificationFails_rpcFails() throws Exce
297288 Server server = grpcCleanupRule .register (server (serverCreds ));
298289 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
299290
300- // Regular RPC succeeds
301- ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
302- CallOptions .DEFAULT , SimpleRequest .getDefaultInstance ());
303291 try {
304- // But with an authority it fails
305292 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
306- CallOptions .DEFAULT .withAuthority ("moo .test.google.fr" ),
293+ CallOptions .DEFAULT .withAuthority ("bad .test.google.fr" ),
307294 SimpleRequest .getDefaultInstance ());
308295 fail ("Expected exception for authority verification failure." );
309296 } catch (StatusRuntimeException ex ) {
@@ -316,7 +303,7 @@ public void perRpcAuthorityOverride_peerVerificationFails_rpcFails() throws Exce
316303 }
317304
318305 @ Test
319- public void perRpcAuthorityOverride_peerVerificationFails_featureDisabled_rpcSucceeds ()
306+ public void perRpcAuthorityOverride_trustManager_denied_flagDisabled_succeeds ()
320307 throws Exception {
321308 ServerCredentials serverCreds ;
322309 try (InputStream serverCert = TlsTesting .loadCert ("server1.pem" );
@@ -337,17 +324,18 @@ public void perRpcAuthorityOverride_peerVerificationFails_featureDisabled_rpcSuc
337324 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
338325
339326 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
340- CallOptions .DEFAULT .withAuthority ("foo .test.google.fr" ),
327+ CallOptions .DEFAULT .withAuthority ("bad .test.google.fr" ),
341328 SimpleRequest .getDefaultInstance ());
342329 }
343330
344331 /**
345332 * This test simulates the absence of X509ExtendedTrustManager while still using the
346333 * real trust manager for the connection handshake to happen. When the TrustManager is not an
347- * X509ExtendedTrustManager, the per-rpc authority check is skipped.
334+ * X509ExtendedTrustManager, the per-rpc check ignores the trust manager. However, the
335+ * HostnameVerifier is still used, so only valid authorities are permitted.
348336 */
349337 @ Test
350- public void perRpcAuthorityOverride_tlsCreds_notX509ExtendedTrustManager_authorityNotChecked ()
338+ public void perRpcAuthorityOverride_notX509ExtendedTrustManager_goodAuthority_succeeds ()
351339 throws Exception {
352340 OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
353341 try {
@@ -370,16 +358,55 @@ public void perRpcAuthorityOverride_tlsCreds_notX509ExtendedTrustManager_authori
370358 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
371359
372360 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
373- CallOptions .DEFAULT .withAuthority ("moo .test.google.fr" ),
361+ CallOptions .DEFAULT .withAuthority ("foo .test.google.fr" ),
374362 SimpleRequest .getDefaultInstance ());
375363 } finally {
376364 OkHttpClientTransport .enablePerRpcAuthorityCheck = false ;
377365 }
378366 }
379367
380368 @ Test
381- public void perRpcAuthorityOverride_tlsCreds_noX509ExtendedTrustManager_flagDisabled ()
369+ public void perRpcAuthorityOverride_notX509ExtendedTrustManager_badAuthority_fails ()
382370 throws Exception {
371+ OkHttpClientTransport .enablePerRpcAuthorityCheck = true ;
372+ try {
373+ ServerCredentials serverCreds ;
374+ try (InputStream serverCert = TlsTesting .loadCert ("server1.pem" );
375+ InputStream serverPrivateKey = TlsTesting .loadCert ("server1.key" )) {
376+ serverCreds = TlsServerCredentials .newBuilder ()
377+ .keyManager (serverCert , serverPrivateKey )
378+ .build ();
379+ }
380+ ChannelCredentials channelCreds ;
381+ try (InputStream caCert = TlsTesting .loadCert ("ca.pem" )) {
382+ X509TrustManager x509ExtendedTrustManager =
383+ (X509TrustManager ) getX509ExtendedTrustManager (caCert ).get ();
384+ channelCreds = TlsChannelCredentials .newBuilder ()
385+ .trustManager (new FakeTrustManager (x509ExtendedTrustManager ))
386+ .build ();
387+ }
388+ Server server = grpcCleanupRule .register (server (serverCreds ));
389+ ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
390+
391+ try {
392+ ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
393+ CallOptions .DEFAULT .withAuthority ("disallowed.name.com" ),
394+ SimpleRequest .getDefaultInstance ());
395+ fail ("Expected exception for authority verification failure." );
396+ } catch (StatusRuntimeException ex ) {
397+ assertThat (ex .getStatus ().getCode ()).isEqualTo (Status .Code .UNAVAILABLE );
398+ assertThat (ex .getStatus ().getDescription ())
399+ .isEqualTo ("HostNameVerifier verification failed for authority 'disallowed.name.com'" );
400+ }
401+ } finally {
402+ OkHttpClientTransport .enablePerRpcAuthorityCheck = false ;
403+ }
404+ }
405+
406+ @ Test
407+ public void
408+ perRpcAuthorityOverride_notX509ExtendedTrustManager_badAuthority_flagDisabled_succeeds ()
409+ throws Exception {
383410 ServerCredentials serverCreds ;
384411 try (InputStream serverCert = TlsTesting .loadCert ("server1.pem" );
385412 InputStream serverPrivateKey = TlsTesting .loadCert ("server1.key" )) {
@@ -399,7 +426,7 @@ public void perRpcAuthorityOverride_tlsCreds_noX509ExtendedTrustManager_flagDisa
399426 ManagedChannel channel = grpcCleanupRule .register (clientChannel (server , channelCreds ));
400427
401428 ClientCalls .blockingUnaryCall (channel , SimpleServiceGrpc .getUnaryRpcMethod (),
402- CallOptions .DEFAULT .withAuthority ("foo.test.google.fr " ),
429+ CallOptions .DEFAULT .withAuthority ("disallowed.name.com " ),
403430 SimpleRequest .getDefaultInstance ());
404431 }
405432
@@ -620,15 +647,11 @@ public X509Certificate[] getAcceptedIssuers() {
620647 }
621648 }
622649
623- private FakeX509ExtendedTrustManager getFakeX509ExtendedTrustManager ()
624- throws GeneralSecurityException , IOException {
625- try (InputStream caCert = TlsTesting .loadCert ("ca.pem" )) {
626- X509ExtendedTrustManager x509ExtendedTrustManager =
627- (X509ExtendedTrustManager ) getX509ExtendedTrustManager (caCert ).get ();
628- return new FakeX509ExtendedTrustManager (x509ExtendedTrustManager );
629- }
630- }
631-
650+ /**
651+ * Checks against a limited set of hostnames. In production, EndpointIdentificationAlgorithm is
652+ * unset so the default trust manager will not fail based on the hostname. This class is used to
653+ * test user-provided trust managers that may have their own behavior.
654+ */
632655 private static class HostnameCheckingX509ExtendedTrustManager
633656 extends ForwardingX509ExtendedTrustManager {
634657 public HostnameCheckingX509ExtendedTrustManager (X509ExtendedTrustManager tm ) {
@@ -639,28 +662,13 @@ public HostnameCheckingX509ExtendedTrustManager(X509ExtendedTrustManager tm) {
639662 public void checkServerTrusted (X509Certificate [] chain , String authType , Socket socket )
640663 throws CertificateException {
641664 String peer = ((SSLSocket ) socket ).getHandshakeSession ().getPeerHost ();
642- if (!TestUtils . TEST_SERVER_HOST .equals (peer )) {
665+ if (!"foo.test.google.fr" . equals ( peer ) && ! "good.test.google.fr" .equals (peer )) {
643666 throw new CertificateException ("Peer verification failed." );
644667 }
645668 super .checkServerTrusted (chain , authType , socket );
646669 }
647670 }
648671
649- private static class FakeX509ExtendedTrustManager extends ForwardingX509ExtendedTrustManager {
650- private boolean checkServerTrustedCalled ;
651-
652- private FakeX509ExtendedTrustManager (X509ExtendedTrustManager delegate ) {
653- super (delegate );
654- }
655-
656- @ Override
657- public void checkServerTrusted (X509Certificate [] chain , String authType , Socket socket )
658- throws CertificateException {
659- this .checkServerTrustedCalled = true ;
660- super .checkServerTrusted (chain , authType , socket );
661- }
662- }
663-
664672 @ IgnoreJRERequirement
665673 private static class ForwardingX509ExtendedTrustManager extends X509ExtendedTrustManager {
666674 private final X509ExtendedTrustManager delegate ;
0 commit comments