2626import static org .junit .Assert .assertNull ;
2727import static org .junit .Assert .assertTrue ;
2828import static org .mockito .ArgumentMatchers .any ;
29+ import static org .mockito .ArgumentMatchers .argThat ;
2930import static org .mockito .Mockito .mock ;
31+ import static org .mockito .Mockito .never ;
3032import static org .mockito .Mockito .times ;
33+ import static org .mockito .Mockito .verify ;
3134
3235import io .grpc .Attributes ;
3336import io .grpc .CallCredentials ;
9497import io .netty .handler .ssl .SslContextBuilder ;
9598import io .netty .handler .ssl .SslHandler ;
9699import io .netty .handler .ssl .SslHandshakeCompletionEvent ;
100+ import io .netty .handler .ssl .SslMasterKeyHandler ;
97101import io .netty .handler .ssl .SupportedCipherSuiteFilter ;
98102import io .netty .handler .ssl .util .SelfSignedCertificate ;
103+ import io .netty .util .internal .logging .InternalLogger ;
104+ import io .netty .util .internal .logging .InternalLoggerFactory ;
99105import java .io .File ;
100106import java .net .InetSocketAddress ;
101107import java .net .SocketAddress ;
124130import org .junit .runner .RunWith ;
125131import org .junit .runners .JUnit4 ;
126132import org .mockito .ArgumentCaptor ;
133+ import org .mockito .ArgumentMatcher ;
127134import org .mockito .ArgumentMatchers ;
128135import org .mockito .Mockito ;
129136
@@ -160,6 +167,10 @@ public static void loadCerts() throws Exception {
160167 private SSLEngine engine ;
161168 private ChannelHandlerContext channelHandlerCtx ;
162169
170+ private InternalLogger mockLogger4KeyLog ;
171+ private InternalLogger mockLogger4Others ;
172+ private InternalLoggerFactory oldLoggerFactory ;
173+
163174 @ Before
164175 public void setUp () throws Exception {
165176 File serverCert = TestUtils .loadCert ("server1.pem" );
@@ -168,6 +179,11 @@ public void setUp() throws Exception {
168179 .ciphers (TestUtils .preferredTestCiphers (), SupportedCipherSuiteFilter .INSTANCE ).build ();
169180 engine = SSLContext .getDefault ().createSSLEngine ();
170181 engine .setUseClientMode (true );
182+
183+ oldLoggerFactory = InternalLoggerFactory .getDefaultFactory ();
184+ mockLogger4KeyLog = mock (InternalLogger .class );
185+ mockLogger4Others = mock (InternalLogger .class );
186+ InternalLoggerFactory .setDefaultFactory (new FakeLoggerFactory ());
171187 }
172188
173189 @ After
@@ -179,6 +195,10 @@ public void tearDown() {
179195 chan .close ();
180196 }
181197 group .shutdownGracefully ();
198+
199+ Mockito .reset (mockLogger4KeyLog );
200+ Mockito .reset (mockLogger4Others );
201+ InternalLoggerFactory .setDefaultFactory (oldLoggerFactory );
182202 }
183203
184204 @ Test
@@ -1190,4 +1210,81 @@ public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
11901210 ctx .pipeline ().fireUserEventTriggered (ProtocolNegotiationEvent .DEFAULT );
11911211 }
11921212 }
1213+
1214+ @ Test
1215+ public void clientTlsHandler_serverTlsHandler_sslMasterKeyLog () throws Exception {
1216+ // The master key log feature should be disabled
1217+ // when the "io.netty.ssl.masterKeyHandler" property is missing.
1218+ System .clearProperty (SslMasterKeyHandler .SYSTEM_PROP_KEY );
1219+ clientTlsHandler_firesNegotiation ();
1220+ verify (mockLogger4KeyLog , never ()).warn (argThat (new ArgumentMatcher <String >() {
1221+ @ Override
1222+ public boolean matches (String arg ) {
1223+ return arg .contains (" Master-Key:" );
1224+ }
1225+ }), argThat (new ArgumentMatcher <String >() {
1226+ @ Override
1227+ public boolean matches (String arg ) {
1228+ return true ;
1229+ }
1230+ }), argThat (new ArgumentMatcher <String >() {
1231+ @ Override
1232+ public boolean matches (String arg ) {
1233+ return true ;
1234+ }
1235+ }));
1236+
1237+ // The master key log feature should be disabled
1238+ // when the value of "io.netty.ssl.masterKeyHandler" property is not "true".
1239+ System .setProperty (SslMasterKeyHandler .SYSTEM_PROP_KEY , "false" );
1240+ clientTlsHandler_firesNegotiation ();
1241+ verify (mockLogger4KeyLog , never ()).warn (argThat (new ArgumentMatcher <String >() {
1242+ @ Override
1243+ public boolean matches (String arg ) {
1244+ return arg .contains (" Master-Key:" );
1245+ }
1246+ }), argThat (new ArgumentMatcher <String >() {
1247+ @ Override
1248+ public boolean matches (String arg ) {
1249+ return true ;
1250+ }
1251+ }), argThat (new ArgumentMatcher <String >() {
1252+ @ Override
1253+ public boolean matches (String arg ) {
1254+ return true ;
1255+ }
1256+ }));
1257+
1258+ // The master key log feature should be enabled
1259+ // when the value of "io.netty.ssl.masterKeyHandler" property is "true".
1260+ System .setProperty (SslMasterKeyHandler .SYSTEM_PROP_KEY , "true" );
1261+ clientTlsHandler_firesNegotiation ();
1262+ // writing key twice because both client and server will enable key log feature
1263+ verify (mockLogger4KeyLog , times (2 )).warn (argThat (new ArgumentMatcher <String >() {
1264+ @ Override
1265+ public boolean matches (String arg ) {
1266+ // writing key in one line each time, like:
1267+ // "RSA Session-ID:9da5b... Master-Key:5d74b...\n"
1268+ return arg .contains (" Master-Key:" );
1269+ }
1270+ }), argThat (new ArgumentMatcher <String >() {
1271+ @ Override
1272+ public boolean matches (String arg ) {
1273+ return true ;
1274+ }
1275+ }), argThat (new ArgumentMatcher <String >() {
1276+ @ Override
1277+ public boolean matches (String arg ) {
1278+ return true ;
1279+ }
1280+ }));
1281+ System .clearProperty (SslMasterKeyHandler .SYSTEM_PROP_KEY );
1282+ }
1283+
1284+ private class FakeLoggerFactory extends InternalLoggerFactory {
1285+ @ Override
1286+ protected InternalLogger newInstance (String name ) {
1287+ return name .equals ("io.netty.wireshark" ) ? mockLogger4KeyLog : mockLogger4Others ;
1288+ }
1289+ }
11931290}
0 commit comments