WifiEnterpriseConfig.java revision dda5a7152fd6e5933503aba8e8badbbba0631839
19b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff/* 29b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Copyright (C) 2013 The Android Open Source Project 39b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 49b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Licensed under the Apache License, Version 2.0 (the "License"); 59b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * you may not use this file except in compliance with the License. 69b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * You may obtain a copy of the License at 79b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 89b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * http://www.apache.org/licenses/LICENSE-2.0 99b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Unless required by applicable law or agreed to in writing, software 119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * distributed under the License is distributed on an "AS IS" BASIS, 129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * See the License for the specific language governing permissions and 149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * limitations under the License. 159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffpackage android.net.wifi; 179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport android.os.Parcel; 199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport android.os.Parcelable; 208b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriffimport android.os.Process; 219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport android.security.Credentials; 22b2c0ff64d8ff92dab53e969a44fa12427d145952Kenny Rootimport android.security.KeyStore; 239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport android.text.TextUtils; 2426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 2526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.io.ByteArrayInputStream; 2626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.io.IOException; 2726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.KeyFactory; 2826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.NoSuchAlgorithmException; 2926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.PrivateKey; 3026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.Certificate; 3126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateEncodingException; 3226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateException; 3326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateFactory; 3426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.X509Certificate; 3526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.spec.InvalidKeySpecException; 3626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.spec.PKCS8EncodedKeySpec; 379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport java.util.HashMap; 389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport java.util.Map; 399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 40fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff/** 41fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * Enterprise configuration details for Wi-Fi. Stores details about the EAP method 42fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * and any associated credentials. 43fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff */ 449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffpublic class WifiEnterpriseConfig implements Parcelable { 459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String TAG = "WifiEnterpriseConfig"; 469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * In old configurations, the "private_key" field was used. However, newer 489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * configurations use the key_id field with the engine_id set to "keystore". 499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * If this field is found in the configuration, the migration code is 509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * triggered. 519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String OLD_PRIVATE_KEY_NAME = "private_key"; 539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String representing the keystore OpenSSL ENGINE's ID. 569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ID_KEYSTORE = "keystore"; 589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String representing the keystore URI used for wpa_supplicant. 619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String KEYSTORE_URI = "keystore://"; 639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String to set the engine value to when it should be enabled. 669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ENABLE = "1"; 689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String to set the engine value to when it should be disabled. 719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_DISABLE = "0"; 739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 749b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE; 759b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE; 769b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 779b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String EAP_KEY = "eap"; 789b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PHASE2_KEY = "phase2"; 799b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String IDENTITY_KEY = "identity"; 809b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ANON_IDENTITY_KEY = "anonymous_identity"; 819b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PASSWORD_KEY = "password"; 829b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CLIENT_CERT_KEY = "client_cert"; 839b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CA_CERT_KEY = "ca_cert"; 849b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String SUBJECT_MATCH_KEY = "subject_match"; 859b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_KEY = "engine"; 869b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ID_KEY = "engine_id"; 879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PRIVATE_KEY_ID_KEY = "key_id"; 888d06e430307d07e3d51f381b4c7c89f7d9155133Partha N private static final String OPP_KEY_CACHING = "proactive_key_caching"; 899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private HashMap<String, String> mFields = new HashMap<String, String>(); 9126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate mCaCert; 9226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private PrivateKey mClientPrivateKey; 9326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate mClientCertificate; 949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** This represents an empty value of an enterprise field. 969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * NULL is used at wpa_supplicant to indicate an empty value 979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 98e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff static final String EMPTY_VALUE = "NULL"; 999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig() { 101e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // Do not set defaults so that the enterprise fields that are not changed 102e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // by API are not changed underneath 103e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // This is essential because an app may not have all fields like password 104e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // available. It allows modification of subset of fields. 105e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff 1069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Copy constructor */ 1099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig(WifiEnterpriseConfig source) { 1109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (String key : source.mFields.keySet()) { 1119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, source.mFields.get(key)); 1129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff @Override 1169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int describeContents() { 1179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return 0; 1189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 12086ee9640ee6d6bd9bb655af830eea5515400f25bIrfan Sheriff @Override 1219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void writeToParcel(Parcel dest, int flags) { 1229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeInt(mFields.size()); 1239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (Map.Entry<String, String> entry : mFields.entrySet()) { 1249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeString(entry.getKey()); 1259b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeString(entry.getValue()); 1269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 12726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 12826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff writeCertificate(dest, mCaCert); 12926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 13026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientPrivateKey != null) { 13126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String algorithm = mClientPrivateKey.getAlgorithm(); 13226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] userKeyBytes = mClientPrivateKey.getEncoded(); 13326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(userKeyBytes.length); 13426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeByteArray(userKeyBytes); 13526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeString(algorithm); 13626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 13726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 13826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 13926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 14026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff writeCertificate(dest, mClientCertificate); 14126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 14226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 14326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private void writeCertificate(Parcel dest, X509Certificate cert) { 14426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (cert != null) { 14526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 14626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] certBytes = cert.getEncoded(); 14726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(certBytes.length); 14826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeByteArray(certBytes); 14926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateEncodingException e) { 15026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 15126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 15226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 15326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 15426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 1559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final Creator<WifiEnterpriseConfig> CREATOR = 1589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff new Creator<WifiEnterpriseConfig>() { 1599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig createFromParcel(Parcel in) { 1609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); 1619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff int count = in.readInt(); 1629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (int i = 0; i < count; i++) { 1639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String key = in.readString(); 1649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String value = in.readString(); 1659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff enterpriseConfig.mFields.put(key, value); 1669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 16726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 16826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mCaCert = readCertificate(in); 16926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 17026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff PrivateKey userKey = null; 17126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff int len = in.readInt(); 17226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (len > 0) { 17326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 17426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] bytes = new byte[len]; 17526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff in.readByteArray(bytes); 17626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String algorithm = in.readString(); 17726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff KeyFactory keyFactory = KeyFactory.getInstance(algorithm); 17826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes)); 17926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (NoSuchAlgorithmException e) { 18026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = null; 18126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (InvalidKeySpecException e) { 18226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = null; 18326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 18426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 18526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 18626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mClientPrivateKey = userKey; 18726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mClientCertificate = readCertificate(in); 1889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return enterpriseConfig; 1899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 19126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate readCertificate(Parcel in) { 19226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff X509Certificate cert = null; 19326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff int len = in.readInt(); 19426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (len > 0) { 19526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 19626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] bytes = new byte[len]; 19726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff in.readByteArray(bytes); 19826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff CertificateFactory cFactory = CertificateFactory.getInstance("X.509"); 19926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff cert = (X509Certificate) cFactory 20026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff .generateCertificate(new ByteArrayInputStream(bytes)); 20126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateException e) { 20226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff cert = null; 20326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 20426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 20526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return cert; 20626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 20726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 2089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig[] newArray(int size) { 2099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return new WifiEnterpriseConfig[size]; 2109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff }; 2129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 213fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** The Extensible Authentication Protocol method used */ 2149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final class Eap { 215fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** No EAP method used. Represents an empty config */ 216e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff public static final int NONE = -1; 217fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Protected EAP */ 2189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PEAP = 0; 219fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Transport Layer Security */ 2209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int TLS = 1; 221fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Tunneled Transport Layer Security */ 2229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int TTLS = 2; 223fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Password */ 2249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PWD = 3; 2259b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** @hide */ 2269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final String[] strings = { "PEAP", "TLS", "TTLS", "PWD" }; 22740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 22840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** Prevent initialization */ 22940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff private Eap() {} 2309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 232fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** The inner authentication method used */ 2339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final class Phase2 { 2349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int NONE = 0; 235fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Password Authentication Protocol */ 2369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PAP = 1; 237fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Microsoft Challenge Handshake Authentication Protocol */ 2389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int MSCHAP = 2; 239fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Microsoft Challenge Handshake Authentication Protocol v2 */ 2409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int MSCHAPV2 = 3; 241fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Generic Token Card */ 2429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int GTC = 4; 2439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PREFIX = "auth="; 2449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** @hide */ 2459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" }; 24640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 24740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** Prevent initialization */ 24840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff private Phase2() {} 2499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 25126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** Internal use only */ 25226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff HashMap<String, String> getFields() { 2539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return mFields; 2549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 25626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** Internal use only */ 25726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff static String[] getSupplicantKeys() { 258e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff return new String[] { EAP_KEY, PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY, 259e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff CLIENT_CERT_KEY, CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY, 260e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff PRIVATE_KEY_ID_KEY }; 261e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff } 262e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff 2639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the EAP authentication method. 2659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or 2669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Eap#PWD} 267fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException on an invalid eap method 2689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 2699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setEapMethod(int eapMethod) { 2709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff switch (eapMethod) { 2719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Valid methods */ 2729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.PEAP: 2739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.PWD: 2749b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.TLS: 2759b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.TTLS: 2769b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(EAP_KEY, Eap.strings[eapMethod]); 2778d06e430307d07e3d51f381b4c7c89f7d9155133Partha N mFields.put(OPP_KEY_CACHING, "1"); 2789b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 2799b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff default: 2809b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff throw new IllegalArgumentException("Unknown EAP method"); 2819b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2829b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2839b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 2849b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2859b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the eap method. 2869b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return eap method configured 2879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 2889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int getEapMethod() { 2899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String eapMethod = mFields.get(EAP_KEY); 290e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff return getStringIndex(Eap.strings, eapMethod, Eap.NONE); 2919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 2939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set Phase 2 authentication method. Sets the inner authentication method to be used in 2959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * phase 2 after setting up a secure channel 2969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param phase2Method is the inner authentication method and can be one of {@link Phase2#NONE}, 2979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Phase2#PAP}, {@link Phase2#MSCHAP}, {@link Phase2#MSCHAPV2}, 2989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Phase2#GTC} 299fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException on an invalid phase2 method 3009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 3019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setPhase2Method(int phase2Method) { 3039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff switch (phase2Method) { 3049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.NONE: 3059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PHASE2_KEY, EMPTY_VALUE); 3069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 3079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Valid methods */ 3089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.PAP: 3099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.MSCHAP: 3109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.MSCHAPV2: 3119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.GTC: 3129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PHASE2_KEY, convertToQuotedString( 3139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff Phase2.PREFIX + Phase2.strings[phase2Method])); 3149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 3159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff default: 3169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff throw new IllegalArgumentException("Unknown Phase 2 method"); 3179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the phase 2 authentication method. 3229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return a phase 2 method defined at {@link Phase2} 3239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * */ 3249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int getPhase2Method() { 325e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY)); 326e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // Remove auth= prefix 327e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff if (phase2Method.startsWith(Phase2.PREFIX)) { 328e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff phase2Method = phase2Method.substring(Phase2.PREFIX.length()); 329e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff } 3309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getStringIndex(Phase2.strings, phase2Method, Phase2.NONE); 3319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3329b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the identity 3359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param identity 3369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setIdentity(String identity) { 3389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(IDENTITY_KEY, identity, ""); 3399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the identity 3439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the identity 3449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getIdentity() { 3469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(IDENTITY_KEY, ""); 3479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set anonymous identity. This is used as the unencrypted identity with 3519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * certain EAP types 3529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param anonymousIdentity the anonymous identity 3539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setAnonymousIdentity(String anonymousIdentity) { 3559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, ""); 3569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Get the anonymous identity 3599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return anonymous identity 3609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getAnonymousIdentity() { 3629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(ANON_IDENTITY_KEY, ""); 3639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the password. 3679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param password the password 3689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setPassword(String password) { 3709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(PASSWORD_KEY, password, ""); 3719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 37440843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get the password. 37540843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 37640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Returns locally set password value. For networks fetched from 37740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * framework, returns "*". 37840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 37940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public String getPassword() { 38040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return getFieldValue(PASSWORD_KEY, ""); 38140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff } 38240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 38340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 3849b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set CA certificate alias. 3859b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 3869b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * <p> See the {@link android.security.KeyChain} for details on installing or choosing 3879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * a certificate 3889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * </p> 3899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param alias identifies the certificate 39026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 3919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 39226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setCaCertificateAlias(String alias) { 3939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX); 3949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get CA certificate alias 3989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return alias to the CA certificate 39926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 40126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public String getCaCertificateAlias() { 4029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 4039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 40626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * Specify a X.509 certificate that identifies the server. 40726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * 40826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * <p>A default name is automatically assigned to the certificate and used 409fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * with this configuration. The framework takes care of installing the 410fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * certificate when the config is saved and removing the certificate when 411fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * the config is removed. 412fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * 41326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param cert X.509 CA certificate 41426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @throws IllegalArgumentException if not a CA certificate 41526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff */ 41626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setCaCertificate(X509Certificate cert) { 4170b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (cert != null) { 4180b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (cert.getBasicConstraints() >= 0) { 4190b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff mCaCert = cert; 4200b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff } else { 4210b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff throw new IllegalArgumentException("Not a CA certificate"); 4220b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff } 42326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 4240b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff mCaCert = null; 42526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 42626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 42726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 42826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** 42940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get CA certificate 43040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 43140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * @return X.509 CA certificate 43240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 43340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public X509Certificate getCaCertificate() { 43440843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return mCaCert; 43540843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff } 43640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 43740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 4389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set Client certificate alias. 4399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 4409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * <p> See the {@link android.security.KeyChain} for details on installing or choosing 4419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * a certificate 4429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * </p> 4439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param alias identifies the certificate 44426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 44626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setClientCertificateAlias(String alias) { 4479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX); 4489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY); 4499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Also, set engine parameters 4509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(alias)) { 4519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_DISABLE); 4529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, EMPTY_VALUE); 4539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 4549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_ENABLE); 4559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE)); 4569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 4609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get client certificate alias 4619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return alias to the client certificate 46226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 46426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public String getClientCertificateAlias() { 4659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 4669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 46926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * Specify a private key and client certificate for client authorization. 47026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * 47126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * <p>A default name is automatically assigned to the key entry and used 472fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * with this configuration. The framework takes care of installing the 473fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * key entry when the config is saved and removing the key entry when 474fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * the config is removed. 475fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff 47626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param privateKey 47726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param clientCertificate 478fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException for an invalid key or certificate. 47926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff */ 48026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) { 48126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (clientCertificate != null) { 48226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (clientCertificate.getBasicConstraints() != -1) { 48326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Cannot be a CA certificate"); 48426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 48526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (privateKey == null) { 48626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Client cert without a private key"); 48726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 48826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (privateKey.getEncoded() == null) { 48926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Private key cannot be encoded"); 49026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 49326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientPrivateKey = privateKey; 49426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientCertificate = clientCertificate; 49526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 49740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 49840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get client certificate 49940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 50040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * @return X.509 client certificate 50140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 50240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public X509Certificate getClientCertificate() { 50340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return mClientCertificate; 50426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 50526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 50626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean needsKeyStore() { 50726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Has no keys to be installed 50826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate == null && mCaCert == null) return false; 50926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return true; 51026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 51126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 51226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean installKeys(android.security.KeyStore keyStore, String name) { 51326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean ret = true; 51426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String privKeyName = Credentials.USER_PRIVATE_KEY + name; 51526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String userCertName = Credentials.USER_CERTIFICATE + name; 51626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String caCertName = Credentials.CA_CERTIFICATE + name; 51726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 51826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] privKeyData = mClientPrivateKey.getEncoded(); 519b2c0ff64d8ff92dab53e969a44fa12427d145952Kenny Root ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID, 520b2c0ff64d8ff92dab53e969a44fa12427d145952Kenny Root KeyStore.FLAG_ENCRYPTED); 52126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 52226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 52326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 52426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 52526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff ret = putCertInKeyStore(keyStore, userCertName, mClientCertificate); 52626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 52726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Remove private key installed 5288b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(privKeyName, Process.WIFI_UID); 52926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 53026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 53126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 53226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 53326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mCaCert != null) { 53426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff ret = putCertInKeyStore(keyStore, caCertName, mCaCert); 53526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 53626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 53726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Remove client key+cert 5388b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(privKeyName, Process.WIFI_UID); 5398b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(userCertName, Process.WIFI_UID); 54026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 54226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 54526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Set alias names 54626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 54726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff setClientCertificateAlias(name); 54826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientPrivateKey = null; 54926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientCertificate = null; 55026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 55126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 55226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mCaCert != null) { 55326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff setCaCertificateAlias(name); 55426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mCaCert = null; 55526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 55626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 55726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 55826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 55926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 56026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private boolean putCertInKeyStore(android.security.KeyStore keyStore, String name, 56126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff Certificate cert) { 56226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 56326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] certData = Credentials.convertToPem(cert); 564b2c0ff64d8ff92dab53e969a44fa12427d145952Kenny Root return keyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_ENCRYPTED); 56526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (IOException e1) { 56626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return false; 56726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateException e2) { 56826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return false; 56926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 57026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 57126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 572b2c0ff64d8ff92dab53e969a44fa12427d145952Kenny Root void removeKeys(KeyStore keyStore) { 57326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 57426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // a valid client certificate is configured 57526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (!TextUtils.isEmpty(client)) { 5768b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID); 5778b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID); 57826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 57926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 58026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 58126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // a valid ca certificate is configured 58226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (!TextUtils.isEmpty(ca)) { 5838b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID); 58426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 58526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 58626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 58726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** 5889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set subject match. This is the substring to be matched against the subject of the 5899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * authentication server certificate. 5909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param subjectMatch substring to be matched 5919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 5929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setSubjectMatch(String subjectMatch) { 5939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(SUBJECT_MATCH_KEY, subjectMatch, ""); 5949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 5959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 5969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 5979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get subject match 5989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the subject match string 5999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getSubjectMatch() { 6019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(SUBJECT_MATCH_KEY, ""); 6029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 60426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */ 60526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String getKeyId(WifiEnterpriseConfig current) { 60626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String eap = mFields.get(EAP_KEY); 60726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String phase2 = mFields.get(PHASE2_KEY); 60826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 60926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // If either eap or phase2 are not initialized, use current config details 61026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty((eap))) { 61126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff eap = current.mFields.get(EAP_KEY); 61226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 61326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(phase2)) { 61426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff phase2 = current.mFields.get(PHASE2_KEY); 61526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 61626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return eap + "_" + phase2; 61726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 61826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 6199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Migrates the old style TLS config to the new config style. This should only be used 6209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * when restoring an old wpa_supplicant.conf or upgrading from a previous 6219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * platform version. 6229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return true if the config was updated 6239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @hide 6249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 62526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean migrateOldEapTlsNative(WifiNative wifiNative, int netId) { 6269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String oldPrivateKey = wifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME); 6279b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /* 6289b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * If the old configuration value is not present, then there is nothing 6299b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * to do. 6309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(oldPrivateKey)) { 6329b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return false; 6339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 6349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Also ignore it if it's empty quotes. 6359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff oldPrivateKey = removeDoubleQuotes(oldPrivateKey); 6369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(oldPrivateKey)) { 6379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return false; 6389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_ENABLE); 6429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE)); 6439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /* 6459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * The old key started with the keystore:// URI prefix, but we don't 6469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * need that anymore. Trim it off if it exists. 6479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff final String keyName; 6499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (oldPrivateKey.startsWith(KEYSTORE_URI)) { 6509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length())); 6519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 6529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff keyName = oldPrivateKey; 6539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PRIVATE_KEY_ID_KEY, convertToQuotedString(keyName)); 6559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, ENGINE_KEY, mFields.get(ENGINE_KEY)); 6579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, ENGINE_ID_KEY, mFields.get(ENGINE_ID_KEY)); 6589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY, mFields.get(PRIVATE_KEY_ID_KEY)); 6599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Remove old private_key string so we don't run this again. 6609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE); 6619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return true; 6629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6648b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff /** Migrate certs from global pool to wifi UID if not already done */ 6658b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff void migrateCerts(android.security.KeyStore keyStore) { 6668b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 6678b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff // a valid client certificate is configured 6688b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!TextUtils.isEmpty(client)) { 6698b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!keyStore.contains(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID)) { 6708b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.USER_PRIVATE_KEY + client, -1, 6718b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID); 6728b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.USER_CERTIFICATE + client, -1, 6738b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.USER_CERTIFICATE + client, Process.WIFI_UID); 6748b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6758b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6768b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff 6778b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 6788b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff // a valid ca certificate is configured 6798b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!TextUtils.isEmpty(ca)) { 6808b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!keyStore.contains(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID)) { 6818b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.CA_CERTIFICATE + ca, -1, 6828b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID); 6838b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6848b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6858b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6868b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff 6879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String removeDoubleQuotes(String string) { 6880b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (TextUtils.isEmpty(string)) return ""; 6899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff int length = string.length(); 6909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if ((length > 1) && (string.charAt(0) == '"') 6919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff && (string.charAt(length - 1) == '"')) { 6929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return string.substring(1, length - 1); 6939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return string; 6959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String convertToQuotedString(String string) { 6989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return "\"" + string + "\""; 6999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Returns the index at which the toBeFound string is found in the array. 7029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param arr array of strings 7039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param toBeFound string to be found 7049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param defaultIndex default index to be returned when string is not found 7059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the index into array 7069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private int getStringIndex(String arr[], String toBeFound, int defaultIndex) { 70826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(toBeFound)) return defaultIndex; 7099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (int i = 0; i < arr.length; i++) { 710e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff if (toBeFound.equals(arr[i])) return i; 7119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return defaultIndex; 7139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Returns the field value for the key. 7169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param key into the hash 7179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param prefix is the prefix that the value may have 7189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return value 7199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String getFieldValue(String key, String prefix) { 7219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String value = mFields.get(key); 72226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Uninitialized or known to be empty after reading from supplicant 72326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return ""; 724dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde 725dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde value = removeDoubleQuotes(value); 726dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde if (value.startsWith(prefix)) { 727dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde return value.substring(prefix.length()); 728dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde } else { 729dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde return value; 730dda5a7152fd6e5933503aba8e8badbbba0631839Vinit Deshapnde } 7319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7329b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Set a value with an optional prefix at key 7349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param key into the hash 7359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param value to be set 7369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param prefix an optional value to be prefixed to actual value 7379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private void setFieldValue(String key, String value, String prefix) { 7399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(value)) { 7409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, EMPTY_VALUE); 7419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 7429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, convertToQuotedString(prefix + value)); 7439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff @Override 7479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String toString() { 7489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff StringBuffer sb = new StringBuffer(); 7499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (String key : mFields.keySet()) { 7509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff sb.append(key).append(" ").append(mFields.get(key)).append("\n"); 7519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return sb.toString(); 7539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff} 755