• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.netty;
18 
19 import java.lang.reflect.Method;
20 import java.security.AccessController;
21 import java.security.PrivilegedExceptionAction;
22 import javax.net.ssl.SSLContext;
23 import javax.net.ssl.SSLEngine;
24 
25 /**
26  * Utility class for determining support for Jetty TLS ALPN/NPN.
27  */
28 final class JettyTlsUtil {
JettyTlsUtil()29   private JettyTlsUtil() {
30   }
31 
32   private static Throwable jettyAlpnUnavailabilityCause;
33   private static Throwable jettyNpnUnavailabilityCause;
34 
35   private static class Java9AlpnUnavailabilityCauseHolder {
36 
37     @SuppressWarnings("StaticAssignmentOfThrowable")
38     static final Throwable cause = checkAlpnAvailability();
39 
checkAlpnAvailability()40     static Throwable checkAlpnAvailability() {
41       try {
42         SSLContext context = SSLContext.getInstance("TLS");
43         context.init(null, null, null);
44         SSLEngine engine = context.createSSLEngine();
45         Method getApplicationProtocol =
46             AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
47               @Override
48               public Method run() throws Exception {
49                 return SSLEngine.class.getMethod("getApplicationProtocol");
50               }
51             });
52         getApplicationProtocol.invoke(engine);
53         return null;
54       } catch (Throwable t) {
55         return t;
56       }
57     }
58   }
59 
60   /** Indicates whether or not the Jetty ALPN jar is installed in the boot classloader. */
61   @SuppressWarnings("StaticAssignmentOfThrowable")
isJettyAlpnConfigured()62   static synchronized boolean isJettyAlpnConfigured() {
63     try {
64       Class.forName("org.eclipse.jetty.alpn.ALPN", true, null);
65       return true;
66     } catch (ClassNotFoundException e) {
67       jettyAlpnUnavailabilityCause = e;
68       return false;
69     }
70   }
71 
getJettyAlpnUnavailabilityCause()72   static synchronized Throwable getJettyAlpnUnavailabilityCause() {
73     // This case should be unlikely
74     if (jettyAlpnUnavailabilityCause == null) {
75       @SuppressWarnings("UnusedVariable")
76       boolean discard = isJettyAlpnConfigured();
77     }
78     return jettyAlpnUnavailabilityCause;
79   }
80 
81   /** Indicates whether or not the Jetty NPN jar is installed in the boot classloader. */
82   @SuppressWarnings("StaticAssignmentOfThrowable")
isJettyNpnConfigured()83   static synchronized boolean isJettyNpnConfigured() {
84     try {
85       Class.forName("org.eclipse.jetty.npn.NextProtoNego", true, null);
86       return true;
87     } catch (ClassNotFoundException e) {
88       jettyNpnUnavailabilityCause = e;
89       return false;
90     }
91   }
92 
getJettyNpnUnavailabilityCause()93   static synchronized Throwable getJettyNpnUnavailabilityCause() {
94     // This case should be unlikely
95     if (jettyNpnUnavailabilityCause == null) {
96       @SuppressWarnings("UnusedVariable")
97       boolean discard = isJettyNpnConfigured();
98     }
99     return jettyNpnUnavailabilityCause;
100   }
101 
102   /**
103    * Indicates whether Java 9 ALPN is available.
104    */
isJava9AlpnAvailable()105   static boolean isJava9AlpnAvailable() {
106     return getJava9AlpnUnavailabilityCause() == null;
107   }
108 
getJava9AlpnUnavailabilityCause()109   static Throwable getJava9AlpnUnavailabilityCause() {
110     return Java9AlpnUnavailabilityCauseHolder.cause;
111   }
112 }
113