1 /* 2 * Copyright (C) 2021 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 com.android.server.wifi; 18 19 import android.annotation.NonNull; 20 import android.hardware.wifi.supplicant.GsmRand; 21 import android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback; 22 import android.hardware.wifi.supplicant.NetworkRequestEapSimGsmAuthParams; 23 import android.hardware.wifi.supplicant.NetworkRequestEapSimUmtsAuthParams; 24 import android.hardware.wifi.supplicant.TransitionDisableIndication; 25 26 import com.android.server.wifi.util.NativeUtil; 27 28 import java.io.ByteArrayInputStream; 29 import java.io.InputStream; 30 import java.nio.ByteBuffer; 31 import java.nio.CharBuffer; 32 import java.nio.charset.CharacterCodingException; 33 import java.nio.charset.CharsetDecoder; 34 import java.nio.charset.StandardCharsets; 35 import java.security.cert.CertificateException; 36 import java.security.cert.CertificateFactory; 37 import java.security.cert.X509Certificate; 38 39 class SupplicantStaNetworkCallbackAidlImpl extends ISupplicantStaNetworkCallback.Stub { 40 private static final String TAG = "SupplicantStaNetworkCallbackAidlImpl"; 41 private final SupplicantStaNetworkHalAidlImpl mNetworkHal; 42 /** 43 * Current configured network's framework network id. 44 */ 45 private final int mFrameworkNetworkId; 46 /** 47 * Current configured network's ssid. 48 */ 49 private final String mSsid; 50 private final String mIfaceName; 51 private final WifiMonitor mWifiMonitor; 52 private final Object mLock; 53 SupplicantStaNetworkCallbackAidlImpl( @onNull SupplicantStaNetworkHalAidlImpl networkHal, int frameworkNetworkId, @NonNull String ssid, @NonNull String ifaceName, @NonNull Object lock, @NonNull WifiMonitor wifiMonitor)54 SupplicantStaNetworkCallbackAidlImpl( 55 @NonNull SupplicantStaNetworkHalAidlImpl networkHal, 56 int frameworkNetworkId, @NonNull String ssid, 57 @NonNull String ifaceName, @NonNull Object lock, @NonNull WifiMonitor wifiMonitor) { 58 mNetworkHal = networkHal; 59 mFrameworkNetworkId = frameworkNetworkId; 60 mSsid = ssid; 61 mIfaceName = ifaceName; 62 mLock = lock; 63 mWifiMonitor = wifiMonitor; 64 } 65 66 @Override onNetworkEapSimGsmAuthRequest(NetworkRequestEapSimGsmAuthParams params)67 public void onNetworkEapSimGsmAuthRequest(NetworkRequestEapSimGsmAuthParams params) { 68 synchronized (mLock) { 69 mNetworkHal.logCallback("onNetworkEapSimGsmAuthRequest"); 70 String[] data = new String[params.rands.length]; 71 int i = 0; 72 for (GsmRand rand : params.rands) { 73 data[i++] = NativeUtil.hexStringFromByteArray(rand.data); 74 } 75 mWifiMonitor.broadcastNetworkGsmAuthRequestEvent( 76 mIfaceName, mFrameworkNetworkId, mSsid, data); 77 } 78 } 79 80 @Override onNetworkEapSimUmtsAuthRequest(NetworkRequestEapSimUmtsAuthParams params)81 public void onNetworkEapSimUmtsAuthRequest(NetworkRequestEapSimUmtsAuthParams params) { 82 synchronized (mLock) { 83 mNetworkHal.logCallback("onNetworkEapSimUmtsAuthRequest"); 84 String randHex = NativeUtil.hexStringFromByteArray(params.rand); 85 String autnHex = NativeUtil.hexStringFromByteArray(params.autn); 86 String[] data = {randHex, autnHex}; 87 mWifiMonitor.broadcastNetworkUmtsAuthRequestEvent( 88 mIfaceName, mFrameworkNetworkId, mSsid, data); 89 } 90 } 91 92 @Override onNetworkEapIdentityRequest()93 public void onNetworkEapIdentityRequest() { 94 synchronized (mLock) { 95 mNetworkHal.logCallback("onNetworkEapIdentityRequest"); 96 mWifiMonitor.broadcastNetworkIdentityRequestEvent( 97 mIfaceName, mFrameworkNetworkId, mSsid); 98 } 99 } 100 101 @Override onTransitionDisable(int indicationBits)102 public void onTransitionDisable(int indicationBits) { 103 synchronized (mLock) { 104 mNetworkHal.logCallback("onTransitionDisable"); 105 int frameworkBits = 0; 106 if ((indicationBits & TransitionDisableIndication.USE_WPA3_PERSONAL) != 0) { 107 frameworkBits |= WifiMonitor.TDI_USE_WPA3_PERSONAL; 108 } 109 if ((indicationBits & TransitionDisableIndication.USE_SAE_PK) != 0) { 110 frameworkBits |= WifiMonitor.TDI_USE_SAE_PK; 111 } 112 if ((indicationBits & TransitionDisableIndication.USE_WPA3_ENTERPRISE) != 0) { 113 frameworkBits |= WifiMonitor.TDI_USE_WPA3_ENTERPRISE; 114 } 115 if ((indicationBits & TransitionDisableIndication.USE_ENHANCED_OPEN) != 0) { 116 frameworkBits |= WifiMonitor.TDI_USE_ENHANCED_OPEN; 117 } 118 if (frameworkBits == 0) { 119 return; 120 } 121 122 mWifiMonitor.broadcastTransitionDisableEvent( 123 mIfaceName, mFrameworkNetworkId, frameworkBits); 124 } 125 } 126 byteArrayToString(byte[] byteArray)127 private String byteArrayToString(byte[] byteArray) { 128 // Not a valid bytes for a string 129 if (byteArray == null) return null; 130 CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 131 try { 132 CharBuffer decoded = decoder.decode(ByteBuffer.wrap(byteArray)); 133 return decoded.toString(); 134 } catch (CharacterCodingException cce) { 135 } 136 return null; 137 } 138 139 @Override onServerCertificateAvailable( int depth, byte[] subjectBytes, byte[] certHashBytes, byte[] certBytes)140 public void onServerCertificateAvailable( 141 int depth, 142 byte[] subjectBytes, 143 byte[] certHashBytes, 144 byte[] certBytes) { 145 synchronized (mLock) { 146 // OpenSSL default maximum depth is 100. 147 if (depth < 0 || depth > 100) { 148 mNetworkHal.logCallback("onServerCertificateAvailable: invalid depth " + depth); 149 return; 150 } 151 if (null == subjectBytes) { 152 mNetworkHal.logCallback("onServerCertificateAvailable: subject is null."); 153 return; 154 } 155 if (null == certHashBytes) { 156 mNetworkHal.logCallback("onServerCertificateAvailable: cert hash is null."); 157 return; 158 } 159 if (null == certBytes) { 160 mNetworkHal.logCallback("onServerCertificateAvailable: cert is null."); 161 return; 162 } 163 164 mNetworkHal.logCallback("onServerCertificateAvailable: " 165 + " depth=" + depth 166 + " subjectBytes size=" + subjectBytes.length 167 + " certHashBytes size=" + certHashBytes.length 168 + " certBytes size=" + certBytes.length); 169 170 if (0 == certHashBytes.length) return; 171 if (0 == certBytes.length) return; 172 173 String subject = byteArrayToString(subjectBytes); 174 if (null == subject) { 175 mNetworkHal.logCallback( 176 "onServerCertificateAvailable: cannot convert subject bytes to string."); 177 return; 178 } 179 String certHash = byteArrayToString(certHashBytes); 180 if (null == certHash) { 181 mNetworkHal.logCallback( 182 "onServerCertificateAvailable: cannot convert cert hash bytes to string."); 183 return; 184 } 185 X509Certificate cert = null; 186 try { 187 CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); 188 InputStream in = new ByteArrayInputStream(certBytes); 189 cert = (X509Certificate) certFactory.generateCertificate(in); 190 } catch (CertificateException e) { 191 cert = null; 192 mNetworkHal.logCallback( 193 "onServerCertificateAvailable: " 194 + "Failed to get instance for CertificateFactory: " + e); 195 } catch (IllegalArgumentException e) { 196 cert = null; 197 mNetworkHal.logCallback( 198 "onServerCertificateAvailable: Failed to decode the data: " + e); 199 } 200 if (null == cert) { 201 mNetworkHal.logCallback( 202 "onServerCertificateAvailable: Failed to read certificate."); 203 return; 204 } 205 206 mNetworkHal.logCallback("onServerCertificateAvailable:" 207 + " depth=" + depth 208 + " subject=" + subject 209 + " certHash=" + certHash 210 + " cert=" + cert); 211 mWifiMonitor.broadcastCertificationEvent( 212 mIfaceName, mFrameworkNetworkId, mSsid, depth, 213 new CertificateEventInfo(cert, certHash)); 214 } 215 } 216 217 @Override onPermanentIdReqDenied()218 public void onPermanentIdReqDenied() { 219 mNetworkHal.logCallback("onPermanentIdReqDenied"); 220 221 mWifiMonitor.broadcastPermanentIdReqDenied( 222 mIfaceName, mFrameworkNetworkId, mSsid); 223 } 224 225 @Override getInterfaceHash()226 public String getInterfaceHash() { 227 return ISupplicantStaNetworkCallback.HASH; 228 } 229 230 @Override getInterfaceVersion()231 public int getInterfaceVersion() { 232 return ISupplicantStaNetworkCallback.VERSION; 233 } 234 } 235