• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The Android Open Source Project
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 org.conscrypt;
18 
19 import java.io.FileDescriptor;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.net.InetAddress;
23 import java.net.InetSocketAddress;
24 import java.net.Socket;
25 import java.net.SocketException;
26 import java.security.InvalidKeyException;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.PrivateKey;
29 import java.security.cert.CertificateException;
30 import java.security.cert.X509Certificate;
31 import java.security.spec.AlgorithmParameterSpec;
32 import java.security.spec.ECParameterSpec;
33 import java.util.Collections;
34 import java.util.List;
35 import javax.crypto.spec.GCMParameterSpec;
36 import javax.net.ssl.SNIHostName;
37 import javax.net.ssl.SNIServerName;
38 import javax.net.ssl.SSLEngine;
39 import javax.net.ssl.SSLParameters;
40 import javax.net.ssl.SSLSession;
41 import javax.net.ssl.SSLSocketFactory;
42 import javax.net.ssl.StandardConstants;
43 import javax.net.ssl.X509ExtendedTrustManager;
44 import javax.net.ssl.X509TrustManager;
45 import sun.security.x509.AlgorithmId;
46 
47 /**
48  *
49  */
50 public class Platform {
51     private static final String TAG = "Conscrypt";
52 
53     private static Method m_getCurveName;
54     static {
55         try {
56             m_getCurveName = ECParameterSpec.class.getDeclaredMethod("getCurveName");
57             m_getCurveName.setAccessible(true);
58         } catch (Exception ignored) {
59         }
60     }
61 
setup()62     public static void setup() {
63     }
64 
getFileDescriptor(Socket s)65     public static FileDescriptor getFileDescriptor(Socket s) {
66         try {
67             Field f_impl = Socket.class.getDeclaredField("impl");
68             f_impl.setAccessible(true);
69             Object socketImpl = f_impl.get(s);
70             Class<?> c_socketImpl = Class.forName("java.net.SocketImpl");
71             Field f_fd = c_socketImpl.getDeclaredField("fd");
72             f_fd.setAccessible(true);
73             return (FileDescriptor) f_fd.get(socketImpl);
74         } catch (Exception e) {
75             throw new RuntimeException("Can't get FileDescriptor from socket", e);
76         }
77     }
78 
getFileDescriptorFromSSLSocket(OpenSSLSocketImpl openSSLSocketImpl)79     public static FileDescriptor getFileDescriptorFromSSLSocket(OpenSSLSocketImpl openSSLSocketImpl) {
80         return getFileDescriptor(openSSLSocketImpl);
81     }
82 
getCurveName(ECParameterSpec spec)83     public static String getCurveName(ECParameterSpec spec) {
84         if (m_getCurveName == null) {
85             return null;
86         }
87         try {
88             return (String) m_getCurveName.invoke(spec);
89         } catch (Exception e) {
90             return null;
91         }
92     }
93 
setCurveName(ECParameterSpec spec, String curveName)94     public static void setCurveName(ECParameterSpec spec, String curveName) {
95         // This doesn't appear to be needed.
96     }
97 
98     /*
99      * Call Os.setsockoptTimeval via reflection.
100      */
setSocketWriteTimeout(Socket s, long timeoutMillis)101     public static void setSocketWriteTimeout(Socket s, long timeoutMillis) throws SocketException {
102         // TODO: figure this out on the RI
103     }
104 
setSSLParameters(SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket)105     public static void setSSLParameters(SSLParameters params, SSLParametersImpl impl,
106             OpenSSLSocketImpl socket) {
107         impl.setEndpointIdentificationAlgorithm(params.getEndpointIdentificationAlgorithm());
108         impl.setUseCipherSuitesOrder(params.getUseCipherSuitesOrder());
109         List<SNIServerName> serverNames = params.getServerNames();
110         if (serverNames != null) {
111             for (SNIServerName serverName : serverNames) {
112                 if (serverName.getType() == StandardConstants.SNI_HOST_NAME) {
113                     socket.setHostname(((SNIHostName) serverName).getAsciiName());
114                     break;
115                 }
116             }
117         }
118     }
119 
getSSLParameters(SSLParameters params, SSLParametersImpl impl, OpenSSLSocketImpl socket)120     public static void getSSLParameters(SSLParameters params, SSLParametersImpl impl,
121             OpenSSLSocketImpl socket) {
122         params.setEndpointIdentificationAlgorithm(impl.getEndpointIdentificationAlgorithm());
123         params.setUseCipherSuitesOrder(impl.getUseCipherSuitesOrder());
124         if (impl.getUseSni() && AddressUtils.isValidSniHostname(socket.getHostname())) {
125             params.setServerNames(Collections.<SNIServerName> singletonList(
126                     new SNIHostName(socket.getHostname())));
127         }
128     }
129 
130     /**
131      * Tries to return a Class reference of one of the supplied class names.
132      */
getClass(String... klasses)133     private static Class<?> getClass(String... klasses) {
134         for (String klass : klasses) {
135             try {
136                 return Class.forName(klass);
137             } catch (Exception ignored) {
138             }
139         }
140         return null;
141     }
142 
setEndpointIdentificationAlgorithm(SSLParameters params, String endpointIdentificationAlgorithm)143     public static void setEndpointIdentificationAlgorithm(SSLParameters params,
144             String endpointIdentificationAlgorithm) {
145         params.setEndpointIdentificationAlgorithm(endpointIdentificationAlgorithm);
146     }
147 
getEndpointIdentificationAlgorithm(SSLParameters params)148     public static String getEndpointIdentificationAlgorithm(SSLParameters params) {
149         return params.getEndpointIdentificationAlgorithm();
150     }
151 
checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType, OpenSSLSocketImpl socket)152     public static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain,
153             String authType, OpenSSLSocketImpl socket) throws CertificateException {
154         if (tm instanceof X509ExtendedTrustManager) {
155             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
156             x509etm.checkClientTrusted(chain, authType, socket);
157         } else {
158             tm.checkClientTrusted(chain, authType);
159         }
160     }
161 
checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType, OpenSSLSocketImpl socket)162     public static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain,
163             String authType, OpenSSLSocketImpl socket) throws CertificateException {
164         if (tm instanceof X509ExtendedTrustManager) {
165             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
166             x509etm.checkServerTrusted(chain, authType, socket);
167         } else {
168             tm.checkServerTrusted(chain, authType);
169         }
170     }
171 
checkClientTrusted(X509TrustManager tm, X509Certificate[] chain, String authType, OpenSSLEngineImpl engine)172     public static void checkClientTrusted(X509TrustManager tm, X509Certificate[] chain,
173             String authType, OpenSSLEngineImpl engine) throws CertificateException {
174         if (tm instanceof X509ExtendedTrustManager) {
175             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
176             x509etm.checkClientTrusted(chain, authType, engine);
177         } else {
178             tm.checkClientTrusted(chain, authType);
179         }
180     }
181 
checkServerTrusted(X509TrustManager tm, X509Certificate[] chain, String authType, OpenSSLEngineImpl engine)182     public static void checkServerTrusted(X509TrustManager tm, X509Certificate[] chain,
183             String authType, OpenSSLEngineImpl engine) throws CertificateException {
184         if (tm instanceof X509ExtendedTrustManager) {
185             X509ExtendedTrustManager x509etm = (X509ExtendedTrustManager) tm;
186             x509etm.checkServerTrusted(chain, authType, engine);
187         } else {
188             tm.checkServerTrusted(chain, authType);
189         }
190     }
191 
192     /**
193      * Wraps an old AndroidOpenSSL key instance. This is not needed on RI.
194      */
wrapRsaKey(PrivateKey javaKey)195     public static OpenSSLKey wrapRsaKey(PrivateKey javaKey) {
196         return null;
197     }
198 
199     /**
200      * Logs to the system EventLog system.
201      */
logEvent(String message)202     public static void logEvent(String message) {
203     }
204 
205     /**
206      * Returns true if the supplied hostname is an literal IP address.
207      */
isLiteralIpAddress(String hostname)208     public static boolean isLiteralIpAddress(String hostname) {
209         // TODO: any RI API to make this better?
210         return AddressUtils.isLiteralIpAddress(hostname);
211     }
212 
213     /**
214      * For unbundled versions, SNI is always enabled by default.
215      */
isSniEnabledByDefault()216     public static boolean isSniEnabledByDefault() {
217         return true;
218     }
219 
220     /**
221      * Currently we don't wrap anything from the RI.
222      */
wrapSocketFactoryIfNeeded(OpenSSLSocketFactoryImpl factory)223     public static SSLSocketFactory wrapSocketFactoryIfNeeded(OpenSSLSocketFactoryImpl factory) {
224         return factory;
225     }
226 
227     /**
228      * Convert from platform's GCMParameterSpec to our internal version.
229      */
fromGCMParameterSpec(AlgorithmParameterSpec params)230     public static GCMParameters fromGCMParameterSpec(AlgorithmParameterSpec params) {
231         if (params instanceof GCMParameterSpec) {
232             GCMParameterSpec gcmParams = (GCMParameterSpec) params;
233             return new GCMParameters(gcmParams.getTLen(), gcmParams.getIV());
234         }
235         return null;
236     }
237 
238     /**
239      * Creates a platform version of {@code GCMParameterSpec}.
240      */
toGCMParameterSpec(int tagLenInBits, byte[] iv)241     public static AlgorithmParameterSpec toGCMParameterSpec(int tagLenInBits, byte[] iv) {
242         return new GCMParameterSpec(tagLenInBits, iv);
243     }
244 
245     /*
246      * CloseGuard functions.
247      */
248 
closeGuardGet()249     public static Object closeGuardGet() {
250         return null;
251     }
252 
closeGuardOpen(Object guardObj, String message)253     public static void closeGuardOpen(Object guardObj, String message) {
254     }
255 
closeGuardClose(Object guardObj)256     public static void closeGuardClose(Object guardObj) {
257     }
258 
closeGuardWarnIfOpen(Object guardObj)259     public static void closeGuardWarnIfOpen(Object guardObj) {
260     }
261 
262     /*
263      * BlockGuard functions.
264      */
265 
blockGuardOnNetwork()266     public static void blockGuardOnNetwork() {
267     }
268 
269     /**
270      * OID to Algorithm Name mapping.
271      */
oidToAlgorithmName(String oid)272     public static String oidToAlgorithmName(String oid) {
273         try {
274             return AlgorithmId.get(oid).getName();
275         } catch (NoSuchAlgorithmException e) {
276             return oid;
277         }
278     }
279 
280     /*
281      * Pre-Java-8 backward compatibility.
282      */
283 
wrapSSLSession(OpenSSLSessionImpl sslSession)284     public static SSLSession wrapSSLSession(OpenSSLSessionImpl sslSession) {
285         return new OpenSSLExtendedSessionImpl(sslSession);
286     }
287 
288     /*
289      * Pre-Java-7 backward compatibility.
290      */
291 
getHostStringFromInetSocketAddress(InetSocketAddress addr)292     public static String getHostStringFromInetSocketAddress(InetSocketAddress addr) {
293         return addr.getHostString();
294     }
295 }
296