WifiEnterpriseConfig.java revision 0b4732c2248fa2b92a44f045dfcadb3547076ef4
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; 229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport android.text.TextUtils; 2326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 2426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport com.android.org.bouncycastle.asn1.ASN1InputStream; 2526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport com.android.org.bouncycastle.asn1.ASN1Sequence; 2626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport com.android.org.bouncycastle.asn1.DEROctetString; 2726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport com.android.org.bouncycastle.asn1.x509.BasicConstraints; 2826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 2926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.io.ByteArrayInputStream; 3026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.io.IOException; 3126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.KeyFactory; 3226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.KeyStore; 3326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.NoSuchAlgorithmException; 3426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.PrivateKey; 3526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.Certificate; 3626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateEncodingException; 3726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateException; 3826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.CertificateFactory; 3926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.cert.X509Certificate; 4026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.spec.InvalidKeySpecException; 4126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriffimport java.security.spec.PKCS8EncodedKeySpec; 429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport java.util.HashMap; 439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffimport java.util.Map; 449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 45fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff/** 46fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * Enterprise configuration details for Wi-Fi. Stores details about the EAP method 47fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * and any associated credentials. 48fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff */ 499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriffpublic class WifiEnterpriseConfig implements Parcelable { 509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String TAG = "WifiEnterpriseConfig"; 519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * In old configurations, the "private_key" field was used. However, newer 539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * configurations use the key_id field with the engine_id set to "keystore". 549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * If this field is found in the configuration, the migration code is 559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * triggered. 569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String OLD_PRIVATE_KEY_NAME = "private_key"; 589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String representing the keystore OpenSSL ENGINE's ID. 619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ID_KEYSTORE = "keystore"; 639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String representing the keystore URI used for wpa_supplicant. 669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String KEYSTORE_URI = "keystore://"; 689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String to set the engine value to when it should be enabled. 719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ENABLE = "1"; 739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 749b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 759b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * String to set the engine value to when it should be disabled. 769b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 779b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_DISABLE = "0"; 789b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 799b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE; 809b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE; 819b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 829b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String EAP_KEY = "eap"; 839b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PHASE2_KEY = "phase2"; 849b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String IDENTITY_KEY = "identity"; 859b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ANON_IDENTITY_KEY = "anonymous_identity"; 869b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PASSWORD_KEY = "password"; 879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CLIENT_CERT_KEY = "client_cert"; 889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String CA_CERT_KEY = "ca_cert"; 899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String SUBJECT_MATCH_KEY = "subject_match"; 909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_KEY = "engine"; 919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String ENGINE_ID_KEY = "engine_id"; 929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PRIVATE_KEY_ID_KEY = "key_id"; 939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private HashMap<String, String> mFields = new HashMap<String, String>(); 9526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate mCaCert; 9626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private PrivateKey mClientPrivateKey; 9726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate mClientCertificate; 989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** This represents an empty value of an enterprise field. 1009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * NULL is used at wpa_supplicant to indicate an empty value 1019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 102e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff static final String EMPTY_VALUE = "NULL"; 1039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig() { 105e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // Do not set defaults so that the enterprise fields that are not changed 106e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // by API are not changed underneath 107e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // This is essential because an app may not have all fields like password 108e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // available. It allows modification of subset of fields. 109e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff 1109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Copy constructor */ 1139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig(WifiEnterpriseConfig source) { 1149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (String key : source.mFields.keySet()) { 1159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, source.mFields.get(key)); 1169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff @Override 1209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int describeContents() { 1219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return 0; 1229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 12486ee9640ee6d6bd9bb655af830eea5515400f25bIrfan Sheriff @Override 1259b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void writeToParcel(Parcel dest, int flags) { 1269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeInt(mFields.size()); 1279b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (Map.Entry<String, String> entry : mFields.entrySet()) { 1289b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeString(entry.getKey()); 1299b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff dest.writeString(entry.getValue()); 1309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 13126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 13226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff writeCertificate(dest, mCaCert); 13326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 13426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientPrivateKey != null) { 13526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String algorithm = mClientPrivateKey.getAlgorithm(); 13626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] userKeyBytes = mClientPrivateKey.getEncoded(); 13726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(userKeyBytes.length); 13826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeByteArray(userKeyBytes); 13926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeString(algorithm); 14026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 14126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 14226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 14326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 14426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff writeCertificate(dest, mClientCertificate); 14526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 14626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 14726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private void writeCertificate(Parcel dest, X509Certificate cert) { 14826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (cert != null) { 14926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 15026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] certBytes = cert.getEncoded(); 15126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(certBytes.length); 15226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeByteArray(certBytes); 15326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateEncodingException e) { 15426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 15526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 15626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 15726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff dest.writeInt(0); 15826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 1599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 1619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final Creator<WifiEnterpriseConfig> CREATOR = 1629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff new Creator<WifiEnterpriseConfig>() { 1639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig createFromParcel(Parcel in) { 1649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); 1659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff int count = in.readInt(); 1669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (int i = 0; i < count; i++) { 1679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String key = in.readString(); 1689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String value = in.readString(); 1699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff enterpriseConfig.mFields.put(key, value); 1709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 17126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 17226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mCaCert = readCertificate(in); 17326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 17426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff PrivateKey userKey = null; 17526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff int len = in.readInt(); 17626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (len > 0) { 17726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 17826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] bytes = new byte[len]; 17926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff in.readByteArray(bytes); 18026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String algorithm = in.readString(); 18126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff KeyFactory keyFactory = KeyFactory.getInstance(algorithm); 18226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes)); 18326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (NoSuchAlgorithmException e) { 18426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = null; 18526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (InvalidKeySpecException e) { 18626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff userKey = null; 18726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 18826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 18926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 19026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mClientPrivateKey = userKey; 19126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff enterpriseConfig.mClientCertificate = readCertificate(in); 1929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return enterpriseConfig; 1939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 1949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 19526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private X509Certificate readCertificate(Parcel in) { 19626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff X509Certificate cert = null; 19726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff int len = in.readInt(); 19826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (len > 0) { 19926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 20026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] bytes = new byte[len]; 20126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff in.readByteArray(bytes); 20226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff CertificateFactory cFactory = CertificateFactory.getInstance("X.509"); 20326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff cert = (X509Certificate) cFactory 20426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff .generateCertificate(new ByteArrayInputStream(bytes)); 20526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateException e) { 20626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff cert = null; 20726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 20826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 20926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return cert; 21026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 21126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 2129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public WifiEnterpriseConfig[] newArray(int size) { 2139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return new WifiEnterpriseConfig[size]; 2149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff }; 2169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 217fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** The Extensible Authentication Protocol method used */ 2189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final class Eap { 219fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** No EAP method used. Represents an empty config */ 220e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff public static final int NONE = -1; 221fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Protected EAP */ 2229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PEAP = 0; 223fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Transport Layer Security */ 2249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int TLS = 1; 225fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Tunneled Transport Layer Security */ 2269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int TTLS = 2; 227fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** EAP-Password */ 2289b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PWD = 3; 2299b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** @hide */ 2309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final String[] strings = { "PEAP", "TLS", "TTLS", "PWD" }; 23140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 23240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** Prevent initialization */ 23340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff private Eap() {} 2349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 236fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** The inner authentication method used */ 2379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final class Phase2 { 2389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int NONE = 0; 239fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Password Authentication Protocol */ 2409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int PAP = 1; 241fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Microsoft Challenge Handshake Authentication Protocol */ 2429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int MSCHAP = 2; 243fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Microsoft Challenge Handshake Authentication Protocol v2 */ 2449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int MSCHAPV2 = 3; 245fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff /** Generic Token Card */ 2469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final int GTC = 4; 2479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private static final String PREFIX = "auth="; 2489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** @hide */ 2499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" }; 25040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 25140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** Prevent initialization */ 25240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff private Phase2() {} 2539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 25526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** Internal use only */ 25626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff HashMap<String, String> getFields() { 2579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return mFields; 2589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 26026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** Internal use only */ 26126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff static String[] getSupplicantKeys() { 262e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff return new String[] { EAP_KEY, PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY, 263e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff CLIENT_CERT_KEY, CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY, 264e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff PRIVATE_KEY_ID_KEY }; 265e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff } 266e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff 2679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the EAP authentication method. 2699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or 2709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Eap#PWD} 271fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException on an invalid eap method 2729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 2739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setEapMethod(int eapMethod) { 2749b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff switch (eapMethod) { 2759b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Valid methods */ 2769b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.PEAP: 2779b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.PWD: 2789b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.TLS: 2799b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Eap.TTLS: 2809b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(EAP_KEY, Eap.strings[eapMethod]); 2819b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 2829b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff default: 2839b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff throw new IllegalArgumentException("Unknown EAP method"); 2849b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2859b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2869b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 2879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the eap method. 2899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return eap method configured 2909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 2919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int getEapMethod() { 2929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String eapMethod = mFields.get(EAP_KEY); 293e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff return getStringIndex(Eap.strings, eapMethod, Eap.NONE); 2949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 2959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 2969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 2979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set Phase 2 authentication method. Sets the inner authentication method to be used in 2989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * phase 2 after setting up a secure channel 2999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param phase2Method is the inner authentication method and can be one of {@link Phase2#NONE}, 3009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Phase2#PAP}, {@link Phase2#MSCHAP}, {@link Phase2#MSCHAPV2}, 3019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * {@link Phase2#GTC} 302fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException on an invalid phase2 method 3039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 3049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setPhase2Method(int phase2Method) { 3069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff switch (phase2Method) { 3079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.NONE: 3089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PHASE2_KEY, EMPTY_VALUE); 3099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 3109b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Valid methods */ 3119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.PAP: 3129b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.MSCHAP: 3139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.MSCHAPV2: 3149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff case Phase2.GTC: 3159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PHASE2_KEY, convertToQuotedString( 3169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff Phase2.PREFIX + Phase2.strings[phase2Method])); 3179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff break; 3189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff default: 3199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff throw new IllegalArgumentException("Unknown Phase 2 method"); 3209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the phase 2 authentication method. 3259b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return a phase 2 method defined at {@link Phase2} 3269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * */ 3279b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public int getPhase2Method() { 328e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY)); 329e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff // Remove auth= prefix 330e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff if (phase2Method.startsWith(Phase2.PREFIX)) { 331e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff phase2Method = phase2Method.substring(Phase2.PREFIX.length()); 332e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff } 3339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getStringIndex(Phase2.strings, phase2Method, Phase2.NONE); 3349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the identity 3389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param identity 3399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setIdentity(String identity) { 3419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(IDENTITY_KEY, identity, ""); 3429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get the identity 3469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the identity 3479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getIdentity() { 3499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(IDENTITY_KEY, ""); 3509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set anonymous identity. This is used as the unencrypted identity with 3549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * certain EAP types 3559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param anonymousIdentity the anonymous identity 3569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setAnonymousIdentity(String anonymousIdentity) { 3589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, ""); 3599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Get the anonymous identity 3629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return anonymous identity 3639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getAnonymousIdentity() { 3659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(ANON_IDENTITY_KEY, ""); 3669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3679b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 3699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set the password. 3709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param password the password 3719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 3729b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setPassword(String password) { 3739b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(PASSWORD_KEY, password, ""); 3749b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3759b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3769b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 37740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get the password. 37840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 37940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Returns locally set password value. For networks fetched from 38040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * framework, returns "*". 38140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 38240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public String getPassword() { 38340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return getFieldValue(PASSWORD_KEY, ""); 38440843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff } 38540843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 38640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 3879b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set CA certificate alias. 3889b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 3899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * <p> See the {@link android.security.KeyChain} for details on installing or choosing 3909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * a certificate 3919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * </p> 3929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param alias identifies the certificate 39326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 3949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 39526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setCaCertificateAlias(String alias) { 3969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX); 3979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 3989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 3999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 4009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get CA certificate alias 4019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return alias to the CA certificate 40226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 40426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public String getCaCertificateAlias() { 4059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 4069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 40926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * Specify a X.509 certificate that identifies the server. 41026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * 41126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * <p>A default name is automatically assigned to the certificate and used 412fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * with this configuration. The framework takes care of installing the 413fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * certificate when the config is saved and removing the certificate when 414fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * the config is removed. 415fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * 41626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param cert X.509 CA certificate 41726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @throws IllegalArgumentException if not a CA certificate 41826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff */ 41926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setCaCertificate(X509Certificate cert) { 4200b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (cert != null) { 4210b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (cert.getBasicConstraints() >= 0) { 4220b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff mCaCert = cert; 4230b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff } else { 4240b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff throw new IllegalArgumentException("Not a CA certificate"); 4250b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff } 42626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } else { 4270b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff mCaCert = null; 42826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 42926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 43026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 43126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** 43240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get CA certificate 43340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 43440843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * @return X.509 CA certificate 43540843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 43640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public X509Certificate getCaCertificate() { 43740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return mCaCert; 43840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff } 43940843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 44040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 4419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set Client certificate alias. 4429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * 4439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * <p> See the {@link android.security.KeyChain} for details on installing or choosing 4449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * a certificate 4459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * </p> 4469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param alias identifies the certificate 44726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 44926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setClientCertificateAlias(String alias) { 4509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX); 4519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY); 4529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Also, set engine parameters 4539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(alias)) { 4549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_DISABLE); 4559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, EMPTY_VALUE); 4569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 4579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_ENABLE); 4589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE)); 4599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 4639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get client certificate alias 4649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return alias to the client certificate 46526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @hide 4669b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 46726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public String getClientCertificateAlias() { 4689b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 4699b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 4709b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 4719b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 47226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * Specify a private key and client certificate for client authorization. 47326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * 47426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * <p>A default name is automatically assigned to the key entry and used 475fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * with this configuration. The framework takes care of installing the 476fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * key entry when the config is saved and removing the key entry when 477fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * the config is removed. 478fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff 47926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param privateKey 48026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff * @param clientCertificate 481fdc028383a01eaaa9bf93cb5d3ce50bd744eab52Irfan Sheriff * @throws IllegalArgumentException for an invalid key or certificate. 48226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff */ 48326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) { 48426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (clientCertificate != null) { 48526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (clientCertificate.getBasicConstraints() != -1) { 48626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Cannot be a CA certificate"); 48726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 48826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (privateKey == null) { 48926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Client cert without a private key"); 49026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (privateKey.getEncoded() == null) { 49226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff throw new IllegalArgumentException("Private key cannot be encoded"); 49326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 49626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientPrivateKey = privateKey; 49726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientCertificate = clientCertificate; 49826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 49926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 50040843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff /** 50140843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * Get client certificate 50240843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * 50340843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff * @return X.509 client certificate 50440843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff */ 50540843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff public X509Certificate getClientCertificate() { 50640843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff return mClientCertificate; 50740843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff } 50840843589c46164c90fde29ad1c58291f17d4d9e6Irfan Sheriff 50926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean needsKeyStore() { 51026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Has no keys to be installed 51126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate == null && mCaCert == null) return false; 51226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return true; 51326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 51426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 51526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean installKeys(android.security.KeyStore keyStore, String name) { 51626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean ret = true; 51726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String privKeyName = Credentials.USER_PRIVATE_KEY + name; 51826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String userCertName = Credentials.USER_CERTIFICATE + name; 51926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String caCertName = Credentials.CA_CERTIFICATE + name; 52026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 52126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] privKeyData = mClientPrivateKey.getEncoded(); 5228b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID); 52326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 52426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 52526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 52626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 52726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff ret = putCertInKeyStore(keyStore, userCertName, mClientCertificate); 52826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 52926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Remove private key installed 5308b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(privKeyName, Process.WIFI_UID); 53126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 53226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 53326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 53426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 53526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mCaCert != null) { 53626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff ret = putCertInKeyStore(keyStore, caCertName, mCaCert); 53726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (ret == false) { 53826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 53926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Remove client key+cert 5408b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(privKeyName, Process.WIFI_UID); 5418b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(userCertName, Process.WIFI_UID); 54226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 54426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 54626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 54726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Set alias names 54826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mClientCertificate != null) { 54926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff setClientCertificateAlias(name); 55026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientPrivateKey = null; 55126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mClientCertificate = null; 55226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 55326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 55426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (mCaCert != null) { 55526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff setCaCertificateAlias(name); 55626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff mCaCert = null; 55726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 55826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 55926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return ret; 56026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 56126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 56226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff private boolean putCertInKeyStore(android.security.KeyStore keyStore, String name, 56326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff Certificate cert) { 56426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff try { 56526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff byte[] certData = Credentials.convertToPem(cert); 5668b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff return keyStore.put(name, certData, Process.WIFI_UID); 56726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (IOException e1) { 56826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return false; 56926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } catch (CertificateException e2) { 57026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return false; 57126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 57226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 57326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 57426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff void removeKeys(android.security.KeyStore keyStore) { 57526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 57626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // a valid client certificate is configured 57726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (!TextUtils.isEmpty(client)) { 5788b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID); 5798b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID); 58026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 58126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 58226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 58326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // a valid ca certificate is configured 58426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (!TextUtils.isEmpty(ca)) { 5858b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID); 58626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 58726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 58826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 58926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** 5909b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Set subject match. This is the substring to be matched against the subject of the 5919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * authentication server certificate. 5929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param subjectMatch substring to be matched 5939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 5949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public void setSubjectMatch(String subjectMatch) { 5959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff setFieldValue(SUBJECT_MATCH_KEY, subjectMatch, ""); 5969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 5979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 5989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** 5999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * Get subject match 6009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the subject match string 6019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String getSubjectMatch() { 6039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return getFieldValue(SUBJECT_MATCH_KEY, ""); 6049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 60626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */ 60726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String getKeyId(WifiEnterpriseConfig current) { 60826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String eap = mFields.get(EAP_KEY); 60926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff String phase2 = mFields.get(PHASE2_KEY); 61026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 61126d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // If either eap or phase2 are not initialized, use current config details 61226d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty((eap))) { 61326d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff eap = current.mFields.get(EAP_KEY); 61426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 61526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(phase2)) { 61626d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff phase2 = current.mFields.get(PHASE2_KEY); 61726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 61826d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff return eap + "_" + phase2; 61926d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff } 62026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff 6219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Migrates the old style TLS config to the new config style. This should only be used 6229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * when restoring an old wpa_supplicant.conf or upgrading from a previous 6239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * platform version. 6249b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return true if the config was updated 6259b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @hide 6269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 62726d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff boolean migrateOldEapTlsNative(WifiNative wifiNative, int netId) { 6289b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String oldPrivateKey = wifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME); 6299b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /* 6309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * If the old configuration value is not present, then there is nothing 6319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * to do. 6329b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(oldPrivateKey)) { 6349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return false; 6359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 6369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Also ignore it if it's empty quotes. 6379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff oldPrivateKey = removeDoubleQuotes(oldPrivateKey); 6389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(oldPrivateKey)) { 6399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return false; 6409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_KEY, ENGINE_ENABLE); 6449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE)); 6459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /* 6479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * The old key started with the keystore:// URI prefix, but we don't 6489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * need that anymore. Trim it off if it exists. 6499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 6509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff final String keyName; 6519b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (oldPrivateKey.startsWith(KEYSTORE_URI)) { 6529b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length())); 6539b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 6549b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff keyName = oldPrivateKey; 6559b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6569b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(PRIVATE_KEY_ID_KEY, convertToQuotedString(keyName)); 6579b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6589b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, ENGINE_KEY, mFields.get(ENGINE_KEY)); 6599b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, ENGINE_ID_KEY, mFields.get(ENGINE_ID_KEY)); 6609b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY, mFields.get(PRIVATE_KEY_ID_KEY)); 6619b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff // Remove old private_key string so we don't run this again. 6629b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff wifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE); 6639b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return true; 6649b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6659b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6668b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff /** Migrate certs from global pool to wifi UID if not already done */ 6678b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff void migrateCerts(android.security.KeyStore keyStore) { 6688b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX); 6698b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff // a valid client certificate is configured 6708b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!TextUtils.isEmpty(client)) { 6718b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!keyStore.contains(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID)) { 6728b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.USER_PRIVATE_KEY + client, -1, 6738b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID); 6748b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.USER_CERTIFICATE + client, -1, 6758b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.USER_CERTIFICATE + client, Process.WIFI_UID); 6768b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6778b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6788b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff 6798b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX); 6808b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff // a valid ca certificate is configured 6818b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!TextUtils.isEmpty(ca)) { 6828b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff if (!keyStore.contains(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID)) { 6838b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff keyStore.duplicate(Credentials.CA_CERTIFICATE + ca, -1, 6848b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID); 6858b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6868b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6878b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff } 6888b643c13f97c0f304a45039b9d1fe6900940499eIrfan Sheriff 6899b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String removeDoubleQuotes(String string) { 6900b4732c2248fa2b92a44f045dfcadb3547076ef4Irfan Sheriff if (TextUtils.isEmpty(string)) return ""; 6919b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff int length = string.length(); 6929b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if ((length > 1) && (string.charAt(0) == '"') 6939b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff && (string.charAt(length - 1) == '"')) { 6949b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return string.substring(1, length - 1); 6959b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6969b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return string; 6979b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 6989b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 6999b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String convertToQuotedString(String string) { 7009b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return "\"" + string + "\""; 7019b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7029b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7039b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Returns the index at which the toBeFound string is found in the array. 7049b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param arr array of strings 7059b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param toBeFound string to be found 7069b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param defaultIndex default index to be returned when string is not found 7079b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return the index into array 7089b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7099b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private int getStringIndex(String arr[], String toBeFound, int defaultIndex) { 71026d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(toBeFound)) return defaultIndex; 7119b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (int i = 0; i < arr.length; i++) { 712e095675c872f40f630aa3f9189eb5c02f3cfee6dIrfan Sheriff if (toBeFound.equals(arr[i])) return i; 7139b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7149b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return defaultIndex; 7159b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7169b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7179b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Returns the field value for the key. 7189b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param key into the hash 7199b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param prefix is the prefix that the value may have 7209b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @return value 7219b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7229b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private String getFieldValue(String key, String prefix) { 7239b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff String value = mFields.get(key); 72426d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff // Uninitialized or known to be empty after reading from supplicant 72526d0076f0dbb021c4e5cc1b37b632b2223fd9278Irfan Sheriff if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return ""; 7269b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return removeDoubleQuotes(value).substring(prefix.length()); 7279b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7289b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7299b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff /** Set a value with an optional prefix at key 7309b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param key into the hash 7319b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param value to be set 7329b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff * @param prefix an optional value to be prefixed to actual value 7339b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff */ 7349b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff private void setFieldValue(String key, String value, String prefix) { 7359b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff if (TextUtils.isEmpty(value)) { 7369b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, EMPTY_VALUE); 7379b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } else { 7389b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff mFields.put(key, convertToQuotedString(prefix + value)); 7399b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7409b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7419b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff 7429b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff @Override 7439b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff public String toString() { 7449b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff StringBuffer sb = new StringBuffer(); 7459b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff for (String key : mFields.keySet()) { 7469b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff sb.append(key).append(" ").append(mFields.get(key)).append("\n"); 7479b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7489b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff return sb.toString(); 7499b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff } 7509b81319002634cf7118055f7aafaa26c27d4e5e8Irfan Sheriff} 751